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/Xfuncproto.h>
43 #include <X11/extensions/Xext.h>
44 #include <X11/extensions/extutil.h>
45 #include "xf86dristr.h"
47 static XExtensionInfo _xf86dri_info_data
;
48 static XExtensionInfo
*xf86dri_info
= &_xf86dri_info_data
;
49 static char xf86dri_extension_name
[] = XF86DRINAME
;
51 #define XF86DRICheckExtension(dpy,i,val) \
52 XextCheckExtension (dpy, i, xf86dri_extension_name, val)
54 /*****************************************************************************
56 * private utility routines *
58 *****************************************************************************/
60 static int close_display(Display
* dpy
, XExtCodes
* extCodes
);
61 static /* const */ XExtensionHooks xf86dri_extension_hooks
= {
66 NULL
, /* create_font */
68 close_display
, /* close_display */
69 NULL
, /* wire_to_event */
70 NULL
, /* event_to_wire */
72 NULL
, /* error_string */
76 XEXT_GENERATE_FIND_DISPLAY(find_display
, xf86dri_info
,
77 xf86dri_extension_name
,
78 &xf86dri_extension_hooks
, 0, NULL
)
81 XEXT_GENERATE_CLOSE_DISPLAY(close_display
, xf86dri_info
)
84 /*****************************************************************************
86 * public XFree86-DRI Extension routines *
88 *****************************************************************************/
91 #define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
97 XF86DRIQueryExtension(Display
* dpy
, int *event_basep
,
100 XExtDisplayInfo
*info
= find_display(dpy
);
102 TRACE("QueryExtension...");
103 if (XextHasExtension(info
)) {
104 *event_basep
= info
->codes
->first_event
;
105 *error_basep
= info
->codes
->first_error
;
106 TRACE("QueryExtension... return True");
110 TRACE("QueryExtension... return False");
116 XF86DRIQueryVersion(Display
* dpy
, int *majorVersion
, int *minorVersion
,
119 XExtDisplayInfo
*info
= find_display(dpy
);
120 xXF86DRIQueryVersionReply rep
;
121 xXF86DRIQueryVersionReq
*req
;
123 TRACE("QueryVersion...");
124 XF86DRICheckExtension(dpy
, info
, False
);
127 GetReq(XF86DRIQueryVersion
, req
);
128 req
->reqType
= info
->codes
->major_opcode
;
129 req
->driReqType
= X_XF86DRIQueryVersion
;
130 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
133 TRACE("QueryVersion... return False");
136 *majorVersion
= rep
.majorVersion
;
137 *minorVersion
= rep
.minorVersion
;
138 *patchVersion
= rep
.patchVersion
;
141 TRACE("QueryVersion... return True");
146 XF86DRIQueryDirectRenderingCapable(Display
* dpy
, int screen
,
149 XExtDisplayInfo
*info
= find_display(dpy
);
150 xXF86DRIQueryDirectRenderingCapableReply rep
;
151 xXF86DRIQueryDirectRenderingCapableReq
*req
;
153 TRACE("QueryDirectRenderingCapable...");
154 XF86DRICheckExtension(dpy
, info
, False
);
157 GetReq(XF86DRIQueryDirectRenderingCapable
, req
);
158 req
->reqType
= info
->codes
->major_opcode
;
159 req
->driReqType
= X_XF86DRIQueryDirectRenderingCapable
;
160 req
->screen
= screen
;
161 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
164 TRACE("QueryDirectRenderingCapable... return False");
167 *isCapable
= rep
.isCapable
;
170 TRACE("QueryDirectRenderingCapable... return True");
175 XF86DRIOpenConnection(Display
* dpy
, int screen
, drm_handle_t
* hSAREA
,
178 XExtDisplayInfo
*info
= find_display(dpy
);
179 xXF86DRIOpenConnectionReply rep
;
180 xXF86DRIOpenConnectionReq
*req
;
182 TRACE("OpenConnection...");
183 XF86DRICheckExtension(dpy
, info
, False
);
186 GetReq(XF86DRIOpenConnection
, req
);
187 req
->reqType
= info
->codes
->major_opcode
;
188 req
->driReqType
= X_XF86DRIOpenConnection
;
189 req
->screen
= screen
;
190 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
193 TRACE("OpenConnection... return False");
197 *hSAREA
= rep
.hSAREALow
;
198 if (sizeof(drm_handle_t
) == 8) {
199 int shift
= 32; /* var to prevent warning on next line */
200 *hSAREA
|= ((drm_handle_t
) rep
.hSAREAHigh
) << shift
;
204 if (!(*busIdString
= (char *) Xcalloc(rep
.busIdStringLength
+ 1, 1))) {
205 _XEatData(dpy
, ((rep
.busIdStringLength
+ 3) & ~3));
208 TRACE("OpenConnection... return False");
211 _XReadPad(dpy
, *busIdString
, rep
.busIdStringLength
);
218 TRACE("OpenConnection... return True");
223 XF86DRIAuthConnection(Display
* dpy
, int screen
, drm_magic_t magic
)
225 XExtDisplayInfo
*info
= find_display(dpy
);
226 xXF86DRIAuthConnectionReq
*req
;
227 xXF86DRIAuthConnectionReply rep
;
229 TRACE("AuthConnection...");
230 XF86DRICheckExtension(dpy
, info
, False
);
233 GetReq(XF86DRIAuthConnection
, req
);
234 req
->reqType
= info
->codes
->major_opcode
;
235 req
->driReqType
= X_XF86DRIAuthConnection
;
236 req
->screen
= screen
;
238 rep
.authenticated
= 0;
239 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
) || !rep
.authenticated
) {
242 TRACE("AuthConnection... return False");
247 TRACE("AuthConnection... return True");
252 XF86DRICloseConnection(Display
* dpy
, int screen
)
254 XExtDisplayInfo
*info
= find_display(dpy
);
255 xXF86DRICloseConnectionReq
*req
;
257 TRACE("CloseConnection...");
259 XF86DRICheckExtension(dpy
, info
, False
);
262 GetReq(XF86DRICloseConnection
, req
);
263 req
->reqType
= info
->codes
->major_opcode
;
264 req
->driReqType
= X_XF86DRICloseConnection
;
265 req
->screen
= screen
;
268 TRACE("CloseConnection... return True");
273 XF86DRIGetClientDriverName(Display
* dpy
, int screen
,
274 int *ddxDriverMajorVersion
,
275 int *ddxDriverMinorVersion
,
276 int *ddxDriverPatchVersion
,
277 char **clientDriverName
)
279 XExtDisplayInfo
*info
= find_display(dpy
);
280 xXF86DRIGetClientDriverNameReply rep
;
281 xXF86DRIGetClientDriverNameReq
*req
;
283 TRACE("GetClientDriverName...");
284 XF86DRICheckExtension(dpy
, info
, False
);
287 GetReq(XF86DRIGetClientDriverName
, req
);
288 req
->reqType
= info
->codes
->major_opcode
;
289 req
->driReqType
= X_XF86DRIGetClientDriverName
;
290 req
->screen
= screen
;
291 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
294 TRACE("GetClientDriverName... return False");
298 *ddxDriverMajorVersion
= rep
.ddxDriverMajorVersion
;
299 *ddxDriverMinorVersion
= rep
.ddxDriverMinorVersion
;
300 *ddxDriverPatchVersion
= rep
.ddxDriverPatchVersion
;
305 (char *) Xcalloc(rep
.clientDriverNameLength
+ 1, 1))) {
306 _XEatData(dpy
, ((rep
.clientDriverNameLength
+ 3) & ~3));
309 TRACE("GetClientDriverName... return False");
312 _XReadPad(dpy
, *clientDriverName
, rep
.clientDriverNameLength
);
315 *clientDriverName
= NULL
;
319 TRACE("GetClientDriverName... return True");
324 XF86DRICreateContextWithConfig(Display
* dpy
, int screen
, int configID
,
325 XID
* context
, drm_context_t
* hHWContext
)
327 XExtDisplayInfo
*info
= find_display(dpy
);
328 xXF86DRICreateContextReply rep
;
329 xXF86DRICreateContextReq
*req
;
331 TRACE("CreateContext...");
332 XF86DRICheckExtension(dpy
, info
, False
);
335 GetReq(XF86DRICreateContext
, req
);
336 req
->reqType
= info
->codes
->major_opcode
;
337 req
->driReqType
= X_XF86DRICreateContext
;
338 req
->visual
= configID
;
339 req
->screen
= screen
;
340 *context
= XAllocID(dpy
);
341 req
->context
= *context
;
342 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
345 TRACE("CreateContext... return False");
348 *hHWContext
= rep
.hHWContext
;
351 TRACE("CreateContext... return True");
356 XF86DRICreateContext(Display
* dpy
, int screen
, Visual
* visual
,
357 XID
* context
, drm_context_t
* hHWContext
)
359 return XF86DRICreateContextWithConfig(dpy
, screen
, visual
->visualid
,
360 context
, hHWContext
);
364 XF86DRIDestroyContext(Display
* dpy
, int screen
, XID context
)
366 XExtDisplayInfo
*info
= find_display(dpy
);
367 xXF86DRIDestroyContextReq
*req
;
369 TRACE("DestroyContext...");
370 XF86DRICheckExtension(dpy
, info
, False
);
373 GetReq(XF86DRIDestroyContext
, req
);
374 req
->reqType
= info
->codes
->major_opcode
;
375 req
->driReqType
= X_XF86DRIDestroyContext
;
376 req
->screen
= screen
;
377 req
->context
= context
;
380 TRACE("DestroyContext... return True");
385 XF86DRICreateDrawable(Display
* dpy
, int screen
,
386 XID drawable
, drm_drawable_t
* hHWDrawable
)
388 XExtDisplayInfo
*info
= find_display(dpy
);
389 xXF86DRICreateDrawableReply rep
;
390 xXF86DRICreateDrawableReq
*req
;
392 TRACE("CreateDrawable...");
393 XF86DRICheckExtension(dpy
, info
, False
);
396 GetReq(XF86DRICreateDrawable
, req
);
397 req
->reqType
= info
->codes
->major_opcode
;
398 req
->driReqType
= X_XF86DRICreateDrawable
;
399 req
->screen
= screen
;
400 req
->drawable
= drawable
;
401 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
404 TRACE("CreateDrawable... return False");
407 *hHWDrawable
= rep
.hHWDrawable
;
410 TRACE("CreateDrawable... return True");
415 noopErrorHandler(Display
* dpy
, XErrorEvent
* xerr
)
421 XF86DRIDestroyDrawable(Display
* dpy
, int screen
, XID drawable
)
423 XExtDisplayInfo
*info
= find_display(dpy
);
424 xXF86DRIDestroyDrawableReq
*req
;
425 int (*oldXErrorHandler
) (Display
*, XErrorEvent
*);
427 TRACE("DestroyDrawable...");
428 XF86DRICheckExtension(dpy
, info
, False
);
430 /* This is called from the DRI driver, which used call it like this
432 * if (windowExists(drawable))
433 * destroyDrawable(drawable);
435 * which is a textbook race condition - the window may disappear
436 * from the server between checking for its existance and
437 * destroying it. Instead we change the semantics of
438 * __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if
439 * the windows is gone, by wrapping the destroy call in an error
443 oldXErrorHandler
= XSetErrorHandler(noopErrorHandler
);
446 GetReq(XF86DRIDestroyDrawable
, req
);
447 req
->reqType
= info
->codes
->major_opcode
;
448 req
->driReqType
= X_XF86DRIDestroyDrawable
;
449 req
->screen
= screen
;
450 req
->drawable
= drawable
;
454 XSetErrorHandler(oldXErrorHandler
);
456 TRACE("DestroyDrawable... return True");
461 XF86DRIGetDrawableInfo(Display
* dpy
, int screen
, Drawable drawable
,
462 unsigned int *index
, unsigned int *stamp
,
463 int *X
, int *Y
, int *W
, int *H
,
464 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
465 int *backX
, int *backY
,
466 int *numBackClipRects
,
467 drm_clip_rect_t
** pBackClipRects
)
469 XExtDisplayInfo
*info
= find_display(dpy
);
470 xXF86DRIGetDrawableInfoReply rep
;
471 xXF86DRIGetDrawableInfoReq
*req
;
474 TRACE("GetDrawableInfo...");
475 XF86DRICheckExtension(dpy
, info
, False
);
478 GetReq(XF86DRIGetDrawableInfo
, req
);
479 req
->reqType
= info
->codes
->major_opcode
;
480 req
->driReqType
= X_XF86DRIGetDrawableInfo
;
481 req
->screen
= screen
;
482 req
->drawable
= drawable
;
484 if (!_XReply(dpy
, (xReply
*) & rep
, 1, xFalse
)) {
487 TRACE("GetDrawableInfo... return False");
490 *index
= rep
.drawableTableIndex
;
491 *stamp
= rep
.drawableTableStamp
;
492 *X
= (int) rep
.drawableX
;
493 *Y
= (int) rep
.drawableY
;
494 *W
= (int) rep
.drawableWidth
;
495 *H
= (int) rep
.drawableHeight
;
496 *numClipRects
= rep
.numClipRects
;
497 total_rects
= *numClipRects
;
501 *numBackClipRects
= rep
.numBackClipRects
;
502 total_rects
+= *numBackClipRects
;
505 /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
506 * backwards compatibility (Because of the >> 2 shift) but the fix
507 * enables multi-threaded apps to work.
509 if (rep
.length
!= ((((SIZEOF(xXF86DRIGetDrawableInfoReply
) -
510 SIZEOF(xGenericReply
) +
511 total_rects
* sizeof(drm_clip_rect_t
)) +
513 _XEatData(dpy
, rep
.length
);
516 TRACE("GetDrawableInfo... return False");
522 int len
= sizeof(drm_clip_rect_t
) * (*numClipRects
);
524 *pClipRects
= (drm_clip_rect_t
*) Xcalloc(len
, 1);
526 _XRead(dpy
, (char *) *pClipRects
, len
);
532 if (*numBackClipRects
) {
533 int len
= sizeof(drm_clip_rect_t
) * (*numBackClipRects
);
535 *pBackClipRects
= (drm_clip_rect_t
*) Xcalloc(len
, 1);
537 _XRead(dpy
, (char *) *pBackClipRects
, len
);
540 *pBackClipRects
= NULL
;
545 TRACE("GetDrawableInfo... return True");
550 XF86DRIGetDeviceInfo(Display
* dpy
, int screen
, drm_handle_t
* hFrameBuffer
,
551 int *fbOrigin
, int *fbSize
, int *fbStride
,
552 int *devPrivateSize
, void **pDevPrivate
)
554 XExtDisplayInfo
*info
= find_display(dpy
);
555 xXF86DRIGetDeviceInfoReply rep
;
556 xXF86DRIGetDeviceInfoReq
*req
;
558 TRACE("GetDeviceInfo...");
559 XF86DRICheckExtension(dpy
, info
, False
);
562 GetReq(XF86DRIGetDeviceInfo
, req
);
563 req
->reqType
= info
->codes
->major_opcode
;
564 req
->driReqType
= X_XF86DRIGetDeviceInfo
;
565 req
->screen
= screen
;
566 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
569 TRACE("GetDeviceInfo... return False");
573 *hFrameBuffer
= rep
.hFrameBufferLow
;
574 if (sizeof(drm_handle_t
) == 8) {
575 int shift
= 32; /* var to prevent warning on next line */
576 *hFrameBuffer
|= ((drm_handle_t
) rep
.hFrameBufferHigh
) << shift
;
579 *fbOrigin
= rep
.framebufferOrigin
;
580 *fbSize
= rep
.framebufferSize
;
581 *fbStride
= rep
.framebufferStride
;
582 *devPrivateSize
= rep
.devPrivateSize
;
585 if (!(*pDevPrivate
= (void *) Xcalloc(rep
.devPrivateSize
, 1))) {
586 _XEatData(dpy
, ((rep
.devPrivateSize
+ 3) & ~3));
589 TRACE("GetDeviceInfo... return False");
592 _XRead(dpy
, (char *) *pDevPrivate
, rep
.devPrivateSize
);
600 TRACE("GetDeviceInfo... return True");
605 XF86DRIOpenFullScreen(Display
* dpy
, int screen
, Drawable drawable
)
607 /* This function and the underlying X protocol are deprecated.
616 XF86DRICloseFullScreen(Display
* dpy
, int screen
, Drawable drawable
)
618 /* This function and the underlying X protocol are deprecated.
626 #endif /* GLX_DIRECT_RENDERING */