1 /**************************************************************************
3 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4 Copyright 2000 VA Linux Systems, Inc.
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sub license, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice (including the
16 next paragraph) shall be included in all copies or substantial portions
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
23 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
31 * Kevin E. Martin <martin@valinux.com>
32 * Jens Owen <jowen@vmware.com>
33 * Rickard E. (Rik) Faith <faith@valinux.com>
37 /* THIS IS NOT AN X CONSORTIUM STANDARD */
39 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
41 #include <X11/Xlibint.h>
42 #include <X11/Xfuncproto.h>
43 #include <X11/extensions/Xext.h>
44 #include <X11/extensions/extutil.h>
45 #include "xf86dristr.h"
48 static XExtensionInfo _xf86dri_info_data
;
49 static XExtensionInfo
*xf86dri_info
= &_xf86dri_info_data
;
50 static char xf86dri_extension_name
[] = XF86DRINAME
;
52 #define XF86DRICheckExtension(dpy,i,val) \
53 XextCheckExtension (dpy, i, xf86dri_extension_name, val)
55 /*****************************************************************************
57 * private utility routines *
59 *****************************************************************************/
61 static int close_display(Display
* dpy
, XExtCodes
* extCodes
);
62 static /* const */ XExtensionHooks xf86dri_extension_hooks
= {
67 NULL
, /* create_font */
69 close_display
, /* close_display */
70 NULL
, /* wire_to_event */
71 NULL
, /* event_to_wire */
73 NULL
, /* error_string */
77 XEXT_GENERATE_FIND_DISPLAY(find_display
, xf86dri_info
,
78 xf86dri_extension_name
,
79 &xf86dri_extension_hooks
, 0, NULL
)
82 XEXT_GENERATE_CLOSE_DISPLAY(close_display
, xf86dri_info
)
85 /*****************************************************************************
87 * public XFree86-DRI Extension routines *
89 *****************************************************************************/
92 #define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
98 XF86DRIQueryExtension(Display
* dpy
, int *event_basep
,
101 XExtDisplayInfo
*info
= find_display(dpy
);
103 TRACE("QueryExtension...");
104 if (XextHasExtension(info
)) {
105 *event_basep
= info
->codes
->first_event
;
106 *error_basep
= info
->codes
->first_error
;
107 TRACE("QueryExtension... return True");
111 TRACE("QueryExtension... return False");
117 XF86DRIQueryVersion(Display
* dpy
, int *majorVersion
, int *minorVersion
,
120 XExtDisplayInfo
*info
= find_display(dpy
);
121 xXF86DRIQueryVersionReply rep
;
122 xXF86DRIQueryVersionReq
*req
;
124 TRACE("QueryVersion...");
125 XF86DRICheckExtension(dpy
, info
, False
);
128 GetReq(XF86DRIQueryVersion
, req
);
129 req
->reqType
= info
->codes
->major_opcode
;
130 req
->driReqType
= X_XF86DRIQueryVersion
;
131 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
134 TRACE("QueryVersion... return False");
137 *majorVersion
= rep
.majorVersion
;
138 *minorVersion
= rep
.minorVersion
;
139 *patchVersion
= rep
.patchVersion
;
142 TRACE("QueryVersion... return True");
147 XF86DRIQueryDirectRenderingCapable(Display
* dpy
, int screen
,
150 XExtDisplayInfo
*info
= find_display(dpy
);
151 xXF86DRIQueryDirectRenderingCapableReply rep
;
152 xXF86DRIQueryDirectRenderingCapableReq
*req
;
154 TRACE("QueryDirectRenderingCapable...");
155 XF86DRICheckExtension(dpy
, info
, False
);
158 GetReq(XF86DRIQueryDirectRenderingCapable
, req
);
159 req
->reqType
= info
->codes
->major_opcode
;
160 req
->driReqType
= X_XF86DRIQueryDirectRenderingCapable
;
161 req
->screen
= screen
;
162 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
165 TRACE("QueryDirectRenderingCapable... return False");
168 *isCapable
= rep
.isCapable
;
171 TRACE("QueryDirectRenderingCapable... return True");
176 XF86DRIOpenConnection(Display
* dpy
, int screen
, drm_handle_t
* hSAREA
,
179 XExtDisplayInfo
*info
= find_display(dpy
);
180 xXF86DRIOpenConnectionReply rep
;
181 xXF86DRIOpenConnectionReq
*req
;
183 TRACE("OpenConnection...");
184 XF86DRICheckExtension(dpy
, info
, False
);
187 GetReq(XF86DRIOpenConnection
, req
);
188 req
->reqType
= info
->codes
->major_opcode
;
189 req
->driReqType
= X_XF86DRIOpenConnection
;
190 req
->screen
= screen
;
191 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
194 TRACE("OpenConnection... return False");
198 *hSAREA
= rep
.hSAREALow
;
199 if (sizeof(drm_handle_t
) == 8) {
200 int shift
= 32; /* var to prevent warning on next line */
201 *hSAREA
|= ((drm_handle_t
) rep
.hSAREAHigh
) << shift
;
205 if (rep
.busIdStringLength
< INT_MAX
)
206 *busIdString
= calloc(rep
.busIdStringLength
+ 1, 1);
209 if (*busIdString
== NULL
) {
210 _XEatData(dpy
, ((rep
.busIdStringLength
+ 3) & ~3));
213 TRACE("OpenConnection... return False");
216 _XReadPad(dpy
, *busIdString
, rep
.busIdStringLength
);
223 TRACE("OpenConnection... return True");
228 XF86DRIAuthConnection(Display
* dpy
, int screen
, drm_magic_t magic
)
230 XExtDisplayInfo
*info
= find_display(dpy
);
231 xXF86DRIAuthConnectionReq
*req
;
232 xXF86DRIAuthConnectionReply rep
;
234 TRACE("AuthConnection...");
235 XF86DRICheckExtension(dpy
, info
, False
);
238 GetReq(XF86DRIAuthConnection
, req
);
239 req
->reqType
= info
->codes
->major_opcode
;
240 req
->driReqType
= X_XF86DRIAuthConnection
;
241 req
->screen
= screen
;
243 rep
.authenticated
= 0;
244 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
) || !rep
.authenticated
) {
247 TRACE("AuthConnection... return False");
252 TRACE("AuthConnection... return True");
257 XF86DRICloseConnection(Display
* dpy
, int screen
)
259 XExtDisplayInfo
*info
= find_display(dpy
);
260 xXF86DRICloseConnectionReq
*req
;
262 TRACE("CloseConnection...");
264 XF86DRICheckExtension(dpy
, info
, False
);
267 GetReq(XF86DRICloseConnection
, req
);
268 req
->reqType
= info
->codes
->major_opcode
;
269 req
->driReqType
= X_XF86DRICloseConnection
;
270 req
->screen
= screen
;
273 TRACE("CloseConnection... return True");
278 XF86DRIGetClientDriverName(Display
* dpy
, int screen
,
279 int *ddxDriverMajorVersion
,
280 int *ddxDriverMinorVersion
,
281 int *ddxDriverPatchVersion
,
282 char **clientDriverName
)
284 XExtDisplayInfo
*info
= find_display(dpy
);
285 xXF86DRIGetClientDriverNameReply rep
;
286 xXF86DRIGetClientDriverNameReq
*req
;
288 TRACE("GetClientDriverName...");
289 XF86DRICheckExtension(dpy
, info
, False
);
292 GetReq(XF86DRIGetClientDriverName
, req
);
293 req
->reqType
= info
->codes
->major_opcode
;
294 req
->driReqType
= X_XF86DRIGetClientDriverName
;
295 req
->screen
= screen
;
296 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
299 TRACE("GetClientDriverName... return False");
303 *ddxDriverMajorVersion
= rep
.ddxDriverMajorVersion
;
304 *ddxDriverMinorVersion
= rep
.ddxDriverMinorVersion
;
305 *ddxDriverPatchVersion
= rep
.ddxDriverPatchVersion
;
308 if (rep
.clientDriverNameLength
< INT_MAX
)
309 *clientDriverName
= calloc(rep
.clientDriverNameLength
+ 1, 1);
311 *clientDriverName
= NULL
;
312 if (*clientDriverName
== NULL
) {
313 _XEatData(dpy
, ((rep
.clientDriverNameLength
+ 3) & ~3));
316 TRACE("GetClientDriverName... return False");
319 _XReadPad(dpy
, *clientDriverName
, rep
.clientDriverNameLength
);
322 *clientDriverName
= NULL
;
326 TRACE("GetClientDriverName... return True");
331 XF86DRICreateContextWithConfig(Display
* dpy
, int screen
, int configID
,
332 XID
* context
, drm_context_t
* hHWContext
)
334 XExtDisplayInfo
*info
= find_display(dpy
);
335 xXF86DRICreateContextReply rep
;
336 xXF86DRICreateContextReq
*req
;
338 TRACE("CreateContext...");
339 XF86DRICheckExtension(dpy
, info
, False
);
342 GetReq(XF86DRICreateContext
, req
);
343 req
->reqType
= info
->codes
->major_opcode
;
344 req
->driReqType
= X_XF86DRICreateContext
;
345 req
->visual
= configID
;
346 req
->screen
= screen
;
347 *context
= XAllocID(dpy
);
348 req
->context
= *context
;
349 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
352 TRACE("CreateContext... return False");
355 *hHWContext
= rep
.hHWContext
;
358 TRACE("CreateContext... return True");
363 XF86DRICreateContext(Display
* dpy
, int screen
, Visual
* visual
,
364 XID
* context
, drm_context_t
* hHWContext
)
366 return XF86DRICreateContextWithConfig(dpy
, screen
, visual
->visualid
,
367 context
, hHWContext
);
371 XF86DRIDestroyContext(Display
* dpy
, int screen
, XID context
)
373 XExtDisplayInfo
*info
= find_display(dpy
);
374 xXF86DRIDestroyContextReq
*req
;
376 TRACE("DestroyContext...");
377 XF86DRICheckExtension(dpy
, info
, False
);
380 GetReq(XF86DRIDestroyContext
, req
);
381 req
->reqType
= info
->codes
->major_opcode
;
382 req
->driReqType
= X_XF86DRIDestroyContext
;
383 req
->screen
= screen
;
384 req
->context
= context
;
387 TRACE("DestroyContext... return True");
392 XF86DRICreateDrawable(Display
* dpy
, int screen
,
393 XID drawable
, drm_drawable_t
* hHWDrawable
)
395 XExtDisplayInfo
*info
= find_display(dpy
);
396 xXF86DRICreateDrawableReply rep
;
397 xXF86DRICreateDrawableReq
*req
;
399 TRACE("CreateDrawable...");
400 XF86DRICheckExtension(dpy
, info
, False
);
403 GetReq(XF86DRICreateDrawable
, req
);
404 req
->reqType
= info
->codes
->major_opcode
;
405 req
->driReqType
= X_XF86DRICreateDrawable
;
406 req
->screen
= screen
;
407 req
->drawable
= drawable
;
408 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
411 TRACE("CreateDrawable... return False");
414 *hHWDrawable
= rep
.hHWDrawable
;
417 TRACE("CreateDrawable... return True");
422 noopErrorHandler(Display
* dpy
, XErrorEvent
* xerr
)
428 XF86DRIDestroyDrawable(Display
* dpy
, int screen
, XID drawable
)
430 XExtDisplayInfo
*info
= find_display(dpy
);
431 xXF86DRIDestroyDrawableReq
*req
;
432 int (*oldXErrorHandler
) (Display
*, XErrorEvent
*);
434 TRACE("DestroyDrawable...");
435 XF86DRICheckExtension(dpy
, info
, False
);
437 /* This is called from the DRI driver, which used call it like this
439 * if (windowExists(drawable))
440 * destroyDrawable(drawable);
442 * which is a textbook race condition - the window may disappear
443 * from the server between checking for its existence and
444 * destroying it. Instead we change the semantics of
445 * __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if
446 * the windows is gone, by wrapping the destroy call in an error
450 oldXErrorHandler
= XSetErrorHandler(noopErrorHandler
);
453 GetReq(XF86DRIDestroyDrawable
, req
);
454 req
->reqType
= info
->codes
->major_opcode
;
455 req
->driReqType
= X_XF86DRIDestroyDrawable
;
456 req
->screen
= screen
;
457 req
->drawable
= drawable
;
461 XSetErrorHandler(oldXErrorHandler
);
463 TRACE("DestroyDrawable... return True");
468 XF86DRIGetDrawableInfo(Display
* dpy
, int screen
, Drawable drawable
,
469 unsigned int *index
, unsigned int *stamp
,
470 int *X
, int *Y
, int *W
, int *H
,
471 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
472 int *backX
, int *backY
,
473 int *numBackClipRects
,
474 drm_clip_rect_t
** pBackClipRects
)
476 XExtDisplayInfo
*info
= find_display(dpy
);
477 xXF86DRIGetDrawableInfoReply rep
;
478 xXF86DRIGetDrawableInfoReq
*req
;
481 TRACE("GetDrawableInfo...");
482 XF86DRICheckExtension(dpy
, info
, False
);
485 GetReq(XF86DRIGetDrawableInfo
, req
);
486 req
->reqType
= info
->codes
->major_opcode
;
487 req
->driReqType
= X_XF86DRIGetDrawableInfo
;
488 req
->screen
= screen
;
489 req
->drawable
= drawable
;
491 if (!_XReply(dpy
, (xReply
*) & rep
, 1, xFalse
)) {
494 TRACE("GetDrawableInfo... return False");
497 *index
= rep
.drawableTableIndex
;
498 *stamp
= rep
.drawableTableStamp
;
499 *X
= (int) rep
.drawableX
;
500 *Y
= (int) rep
.drawableY
;
501 *W
= (int) rep
.drawableWidth
;
502 *H
= (int) rep
.drawableHeight
;
503 *numClipRects
= rep
.numClipRects
;
504 total_rects
= *numClipRects
;
508 *numBackClipRects
= rep
.numBackClipRects
;
509 total_rects
+= *numBackClipRects
;
512 /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
513 * backwards compatibility (Because of the >> 2 shift) but the fix
514 * enables multi-threaded apps to work.
516 if (rep
.length
!= ((((SIZEOF(xXF86DRIGetDrawableInfoReply
) -
517 SIZEOF(xGenericReply
) +
518 total_rects
* sizeof(drm_clip_rect_t
)) +
520 _XEatData(dpy
, rep
.length
);
523 TRACE("GetDrawableInfo... return False");
529 int len
= sizeof(drm_clip_rect_t
) * (*numClipRects
);
531 *pClipRects
= calloc(len
, 1);
533 _XRead(dpy
, (char *) *pClipRects
, len
);
539 if (*numBackClipRects
) {
540 int len
= sizeof(drm_clip_rect_t
) * (*numBackClipRects
);
542 *pBackClipRects
= calloc(len
, 1);
544 _XRead(dpy
, (char *) *pBackClipRects
, len
);
547 *pBackClipRects
= NULL
;
552 TRACE("GetDrawableInfo... return True");
557 XF86DRIGetDeviceInfo(Display
* dpy
, int screen
, drm_handle_t
* hFrameBuffer
,
558 int *fbOrigin
, int *fbSize
, int *fbStride
,
559 int *devPrivateSize
, void **pDevPrivate
)
561 XExtDisplayInfo
*info
= find_display(dpy
);
562 xXF86DRIGetDeviceInfoReply rep
;
563 xXF86DRIGetDeviceInfoReq
*req
;
565 TRACE("GetDeviceInfo...");
566 XF86DRICheckExtension(dpy
, info
, False
);
569 GetReq(XF86DRIGetDeviceInfo
, req
);
570 req
->reqType
= info
->codes
->major_opcode
;
571 req
->driReqType
= X_XF86DRIGetDeviceInfo
;
572 req
->screen
= screen
;
573 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
576 TRACE("GetDeviceInfo... return False");
580 *hFrameBuffer
= rep
.hFrameBufferLow
;
581 if (sizeof(drm_handle_t
) == 8) {
582 int shift
= 32; /* var to prevent warning on next line */
583 *hFrameBuffer
|= ((drm_handle_t
) rep
.hFrameBufferHigh
) << shift
;
586 *fbOrigin
= rep
.framebufferOrigin
;
587 *fbSize
= rep
.framebufferSize
;
588 *fbStride
= rep
.framebufferStride
;
589 *devPrivateSize
= rep
.devPrivateSize
;
592 if (!(*pDevPrivate
= calloc(rep
.devPrivateSize
, 1))) {
593 _XEatData(dpy
, ((rep
.devPrivateSize
+ 3) & ~3));
596 TRACE("GetDeviceInfo... return False");
599 _XRead(dpy
, (char *) *pDevPrivate
, rep
.devPrivateSize
);
607 TRACE("GetDeviceInfo... return True");
612 XF86DRIOpenFullScreen(Display
* dpy
, int screen
, Drawable drawable
)
614 /* This function and the underlying X protocol are deprecated.
623 XF86DRICloseFullScreen(Display
* dpy
, int screen
, Drawable drawable
)
625 /* This function and the underlying X protocol are deprecated.
633 #endif /* GLX_DIRECT_RENDERING */