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 <jens@tungstengraphics.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/extensions/Xext.h>
43 #include <X11/extensions/extutil.h>
44 #include "xf86dristr.h"
48 # define PUBLIC __attribute__((visibility("default")))
49 # define USED __attribute__((used))
57 static XExtensionInfo _xf86dri_info_data
;
58 static XExtensionInfo
*xf86dri_info
= &_xf86dri_info_data
;
59 static char xf86dri_extension_name
[] = XF86DRINAME
;
61 #define XF86DRICheckExtension(dpy,i,val) \
62 XextCheckExtension (dpy, i, xf86dri_extension_name, val)
64 /*****************************************************************************
66 * private utility routines *
68 *****************************************************************************/
70 static int close_display(Display
* dpy
, XExtCodes
* extCodes
);
71 static /* const */ XExtensionHooks xf86dri_extension_hooks
= {
76 NULL
, /* create_font */
78 close_display
, /* close_display */
79 NULL
, /* wire_to_event */
80 NULL
, /* event_to_wire */
82 NULL
, /* error_string */
86 XEXT_GENERATE_FIND_DISPLAY(find_display
, xf86dri_info
,
87 xf86dri_extension_name
,
88 &xf86dri_extension_hooks
, 0, NULL
)
91 XEXT_GENERATE_CLOSE_DISPLAY(close_display
, xf86dri_info
)
94 /*****************************************************************************
96 * public XFree86-DRI Extension routines *
98 *****************************************************************************/
101 #define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
107 XF86DRIQueryExtension(Display
* dpy
, int *event_basep
,
110 XExtDisplayInfo
*info
= find_display(dpy
);
112 TRACE("QueryExtension...");
113 if (XextHasExtension(info
)) {
114 *event_basep
= info
->codes
->first_event
;
115 *error_basep
= info
->codes
->first_error
;
116 TRACE("QueryExtension... return True");
120 TRACE("QueryExtension... return False");
126 XF86DRIQueryVersion(Display
* dpy
, int *majorVersion
, int *minorVersion
,
129 XExtDisplayInfo
*info
= find_display(dpy
);
130 xXF86DRIQueryVersionReply rep
;
131 xXF86DRIQueryVersionReq
*req
;
133 TRACE("QueryVersion...");
134 XF86DRICheckExtension(dpy
, info
, False
);
137 GetReq(XF86DRIQueryVersion
, req
);
138 req
->reqType
= info
->codes
->major_opcode
;
139 req
->driReqType
= X_XF86DRIQueryVersion
;
140 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
143 TRACE("QueryVersion... return False");
146 *majorVersion
= rep
.majorVersion
;
147 *minorVersion
= rep
.minorVersion
;
148 *patchVersion
= rep
.patchVersion
;
151 TRACE("QueryVersion... return True");
156 XF86DRIQueryDirectRenderingCapable(Display
* dpy
, int screen
,
159 XExtDisplayInfo
*info
= find_display(dpy
);
160 xXF86DRIQueryDirectRenderingCapableReply rep
;
161 xXF86DRIQueryDirectRenderingCapableReq
*req
;
163 TRACE("QueryDirectRenderingCapable...");
164 XF86DRICheckExtension(dpy
, info
, False
);
167 GetReq(XF86DRIQueryDirectRenderingCapable
, req
);
168 req
->reqType
= info
->codes
->major_opcode
;
169 req
->driReqType
= X_XF86DRIQueryDirectRenderingCapable
;
170 req
->screen
= screen
;
171 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
174 TRACE("QueryDirectRenderingCapable... return False");
177 *isCapable
= rep
.isCapable
;
180 TRACE("QueryDirectRenderingCapable... return True");
185 XF86DRIOpenConnection(Display
* dpy
, int screen
, drm_handle_t
* hSAREA
,
188 XExtDisplayInfo
*info
= find_display(dpy
);
189 xXF86DRIOpenConnectionReply rep
;
190 xXF86DRIOpenConnectionReq
*req
;
192 TRACE("OpenConnection...");
193 XF86DRICheckExtension(dpy
, info
, False
);
196 GetReq(XF86DRIOpenConnection
, req
);
197 req
->reqType
= info
->codes
->major_opcode
;
198 req
->driReqType
= X_XF86DRIOpenConnection
;
199 req
->screen
= screen
;
200 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
203 TRACE("OpenConnection... return False");
207 *hSAREA
= rep
.hSAREALow
;
208 if (sizeof(drm_handle_t
) == 8) {
209 int shift
= 32; /* var to prevent warning on next line */
210 *hSAREA
|= ((drm_handle_t
) rep
.hSAREAHigh
) << shift
;
214 if (!(*busIdString
= (char *) Xcalloc(rep
.busIdStringLength
+ 1, 1))) {
215 _XEatData(dpy
, ((rep
.busIdStringLength
+ 3) & ~3));
218 TRACE("OpenConnection... return False");
221 _XReadPad(dpy
, *busIdString
, rep
.busIdStringLength
);
228 TRACE("OpenConnection... return True");
233 XF86DRIAuthConnection(Display
* dpy
, int screen
, drm_magic_t magic
)
235 XExtDisplayInfo
*info
= find_display(dpy
);
236 xXF86DRIAuthConnectionReq
*req
;
237 xXF86DRIAuthConnectionReply rep
;
239 TRACE("AuthConnection...");
240 XF86DRICheckExtension(dpy
, info
, False
);
243 GetReq(XF86DRIAuthConnection
, req
);
244 req
->reqType
= info
->codes
->major_opcode
;
245 req
->driReqType
= X_XF86DRIAuthConnection
;
246 req
->screen
= screen
;
248 rep
.authenticated
= 0;
249 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
) || !rep
.authenticated
) {
252 TRACE("AuthConnection... return False");
257 TRACE("AuthConnection... return True");
262 XF86DRICloseConnection(Display
* dpy
, int screen
)
264 XExtDisplayInfo
*info
= find_display(dpy
);
265 xXF86DRICloseConnectionReq
*req
;
267 TRACE("CloseConnection...");
269 XF86DRICheckExtension(dpy
, info
, False
);
272 GetReq(XF86DRICloseConnection
, req
);
273 req
->reqType
= info
->codes
->major_opcode
;
274 req
->driReqType
= X_XF86DRICloseConnection
;
275 req
->screen
= screen
;
278 TRACE("CloseConnection... return True");
283 XF86DRIGetClientDriverName(Display
* dpy
, int screen
,
284 int *ddxDriverMajorVersion
,
285 int *ddxDriverMinorVersion
,
286 int *ddxDriverPatchVersion
,
287 char **clientDriverName
)
289 XExtDisplayInfo
*info
= find_display(dpy
);
290 xXF86DRIGetClientDriverNameReply rep
;
291 xXF86DRIGetClientDriverNameReq
*req
;
293 TRACE("GetClientDriverName...");
294 XF86DRICheckExtension(dpy
, info
, False
);
297 GetReq(XF86DRIGetClientDriverName
, req
);
298 req
->reqType
= info
->codes
->major_opcode
;
299 req
->driReqType
= X_XF86DRIGetClientDriverName
;
300 req
->screen
= screen
;
301 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
304 TRACE("GetClientDriverName... return False");
308 *ddxDriverMajorVersion
= rep
.ddxDriverMajorVersion
;
309 *ddxDriverMinorVersion
= rep
.ddxDriverMinorVersion
;
310 *ddxDriverPatchVersion
= rep
.ddxDriverPatchVersion
;
315 (char *) Xcalloc(rep
.clientDriverNameLength
+ 1, 1))) {
316 _XEatData(dpy
, ((rep
.clientDriverNameLength
+ 3) & ~3));
319 TRACE("GetClientDriverName... return False");
322 _XReadPad(dpy
, *clientDriverName
, rep
.clientDriverNameLength
);
325 *clientDriverName
= NULL
;
329 TRACE("GetClientDriverName... return True");
334 XF86DRICreateContextWithConfig(Display
* dpy
, int screen
, int configID
,
335 XID
* context
, drm_context_t
* hHWContext
)
337 XExtDisplayInfo
*info
= find_display(dpy
);
338 xXF86DRICreateContextReply rep
;
339 xXF86DRICreateContextReq
*req
;
341 TRACE("CreateContext...");
342 XF86DRICheckExtension(dpy
, info
, False
);
345 GetReq(XF86DRICreateContext
, req
);
346 req
->reqType
= info
->codes
->major_opcode
;
347 req
->driReqType
= X_XF86DRICreateContext
;
348 req
->visual
= configID
;
349 req
->screen
= screen
;
350 *context
= XAllocID(dpy
);
351 req
->context
= *context
;
352 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
355 TRACE("CreateContext... return False");
358 *hHWContext
= rep
.hHWContext
;
361 TRACE("CreateContext... return True");
366 XF86DRICreateContext(Display
* dpy
, int screen
, Visual
* visual
,
367 XID
* context
, drm_context_t
* hHWContext
)
369 return XF86DRICreateContextWithConfig(dpy
, screen
, visual
->visualid
,
370 context
, hHWContext
);
374 XF86DRIDestroyContext(Display
* dpy
, int screen
, XID context
)
376 XExtDisplayInfo
*info
= find_display(dpy
);
377 xXF86DRIDestroyContextReq
*req
;
379 TRACE("DestroyContext...");
380 XF86DRICheckExtension(dpy
, info
, False
);
383 GetReq(XF86DRIDestroyContext
, req
);
384 req
->reqType
= info
->codes
->major_opcode
;
385 req
->driReqType
= X_XF86DRIDestroyContext
;
386 req
->screen
= screen
;
387 req
->context
= context
;
390 TRACE("DestroyContext... return True");
395 XF86DRICreateDrawable(Display
* dpy
, int screen
,
396 XID drawable
, drm_drawable_t
* hHWDrawable
)
398 XExtDisplayInfo
*info
= find_display(dpy
);
399 xXF86DRICreateDrawableReply rep
;
400 xXF86DRICreateDrawableReq
*req
;
402 TRACE("CreateDrawable...");
403 XF86DRICheckExtension(dpy
, info
, False
);
406 GetReq(XF86DRICreateDrawable
, req
);
407 req
->reqType
= info
->codes
->major_opcode
;
408 req
->driReqType
= X_XF86DRICreateDrawable
;
409 req
->screen
= screen
;
410 req
->drawable
= drawable
;
411 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
414 TRACE("CreateDrawable... return False");
417 *hHWDrawable
= rep
.hHWDrawable
;
420 TRACE("CreateDrawable... return True");
425 noopErrorHandler(Display
* dpy
, XErrorEvent
* xerr
)
431 XF86DRIDestroyDrawable(Display
* dpy
, int screen
, XID drawable
)
433 XExtDisplayInfo
*info
= find_display(dpy
);
434 xXF86DRIDestroyDrawableReq
*req
;
435 int (*oldXErrorHandler
) (Display
*, XErrorEvent
*);
437 TRACE("DestroyDrawable...");
438 XF86DRICheckExtension(dpy
, info
, False
);
440 /* This is called from the DRI driver, which used call it like this
442 * if (windowExists(drawable))
443 * destroyDrawable(drawable);
445 * which is a textbook race condition - the window may disappear
446 * from the server between checking for its existance and
447 * destroying it. Instead we change the semantics of
448 * __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if
449 * the windows is gone, by wrapping the destroy call in an error
453 oldXErrorHandler
= XSetErrorHandler(noopErrorHandler
);
456 GetReq(XF86DRIDestroyDrawable
, req
);
457 req
->reqType
= info
->codes
->major_opcode
;
458 req
->driReqType
= X_XF86DRIDestroyDrawable
;
459 req
->screen
= screen
;
460 req
->drawable
= drawable
;
464 XSetErrorHandler(oldXErrorHandler
);
466 TRACE("DestroyDrawable... return True");
471 XF86DRIGetDrawableInfo(Display
* dpy
, int screen
, Drawable drawable
,
472 unsigned int *index
, unsigned int *stamp
,
473 int *X
, int *Y
, int *W
, int *H
,
474 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
475 int *backX
, int *backY
,
476 int *numBackClipRects
,
477 drm_clip_rect_t
** pBackClipRects
)
479 XExtDisplayInfo
*info
= find_display(dpy
);
480 xXF86DRIGetDrawableInfoReply rep
;
481 xXF86DRIGetDrawableInfoReq
*req
;
484 TRACE("GetDrawableInfo...");
485 XF86DRICheckExtension(dpy
, info
, False
);
488 GetReq(XF86DRIGetDrawableInfo
, req
);
489 req
->reqType
= info
->codes
->major_opcode
;
490 req
->driReqType
= X_XF86DRIGetDrawableInfo
;
491 req
->screen
= screen
;
492 req
->drawable
= drawable
;
494 if (!_XReply(dpy
, (xReply
*) & rep
, 1, xFalse
)) {
497 TRACE("GetDrawableInfo... return False");
500 *index
= rep
.drawableTableIndex
;
501 *stamp
= rep
.drawableTableStamp
;
502 *X
= (int) rep
.drawableX
;
503 *Y
= (int) rep
.drawableY
;
504 *W
= (int) rep
.drawableWidth
;
505 *H
= (int) rep
.drawableHeight
;
506 *numClipRects
= rep
.numClipRects
;
507 total_rects
= *numClipRects
;
511 *numBackClipRects
= rep
.numBackClipRects
;
512 total_rects
+= *numBackClipRects
;
515 /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
516 * backwards compatibility (Because of the >> 2 shift) but the fix
517 * enables multi-threaded apps to work.
519 if (rep
.length
!= ((((SIZEOF(xXF86DRIGetDrawableInfoReply
) -
520 SIZEOF(xGenericReply
) +
521 total_rects
* sizeof(drm_clip_rect_t
)) +
523 _XEatData(dpy
, rep
.length
);
526 TRACE("GetDrawableInfo... return False");
532 int len
= sizeof(drm_clip_rect_t
) * (*numClipRects
);
534 *pClipRects
= (drm_clip_rect_t
*) Xcalloc(len
, 1);
536 _XRead(dpy
, (char *) *pClipRects
, len
);
542 if (*numBackClipRects
) {
543 int len
= sizeof(drm_clip_rect_t
) * (*numBackClipRects
);
545 *pBackClipRects
= (drm_clip_rect_t
*) Xcalloc(len
, 1);
547 _XRead(dpy
, (char *) *pBackClipRects
, len
);
550 *pBackClipRects
= NULL
;
555 TRACE("GetDrawableInfo... return True");
560 XF86DRIGetDeviceInfo(Display
* dpy
, int screen
, drm_handle_t
* hFrameBuffer
,
561 int *fbOrigin
, int *fbSize
, int *fbStride
,
562 int *devPrivateSize
, void **pDevPrivate
)
564 XExtDisplayInfo
*info
= find_display(dpy
);
565 xXF86DRIGetDeviceInfoReply rep
;
566 xXF86DRIGetDeviceInfoReq
*req
;
568 TRACE("GetDeviceInfo...");
569 XF86DRICheckExtension(dpy
, info
, False
);
572 GetReq(XF86DRIGetDeviceInfo
, req
);
573 req
->reqType
= info
->codes
->major_opcode
;
574 req
->driReqType
= X_XF86DRIGetDeviceInfo
;
575 req
->screen
= screen
;
576 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
579 TRACE("GetDeviceInfo... return False");
583 *hFrameBuffer
= rep
.hFrameBufferLow
;
584 if (sizeof(drm_handle_t
) == 8) {
585 int shift
= 32; /* var to prevent warning on next line */
586 *hFrameBuffer
|= ((drm_handle_t
) rep
.hFrameBufferHigh
) << shift
;
589 *fbOrigin
= rep
.framebufferOrigin
;
590 *fbSize
= rep
.framebufferSize
;
591 *fbStride
= rep
.framebufferStride
;
592 *devPrivateSize
= rep
.devPrivateSize
;
595 if (!(*pDevPrivate
= (void *) Xcalloc(rep
.devPrivateSize
, 1))) {
596 _XEatData(dpy
, ((rep
.devPrivateSize
+ 3) & ~3));
599 TRACE("GetDeviceInfo... return False");
602 _XRead(dpy
, (char *) *pDevPrivate
, rep
.devPrivateSize
);
610 TRACE("GetDeviceInfo... return True");
615 XF86DRIOpenFullScreen(Display
* dpy
, int screen
, Drawable drawable
)
617 /* This function and the underlying X protocol are deprecated.
626 XF86DRICloseFullScreen(Display
* dpy
, int screen
, Drawable drawable
)
628 /* This function and the underlying X protocol are deprecated.
636 #endif /* GLX_DIRECT_RENDERING */