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"
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
;
310 calloc(rep
.clientDriverNameLength
+ 1, 1))) {
311 _XEatData(dpy
, ((rep
.clientDriverNameLength
+ 3) & ~3));
314 TRACE("GetClientDriverName... return False");
317 _XReadPad(dpy
, *clientDriverName
, rep
.clientDriverNameLength
);
320 *clientDriverName
= NULL
;
324 TRACE("GetClientDriverName... return True");
329 XF86DRICreateContextWithConfig(Display
* dpy
, int screen
, int configID
,
330 XID
* context
, drm_context_t
* hHWContext
)
332 XExtDisplayInfo
*info
= find_display(dpy
);
333 xXF86DRICreateContextReply rep
;
334 xXF86DRICreateContextReq
*req
;
336 TRACE("CreateContext...");
337 XF86DRICheckExtension(dpy
, info
, False
);
340 GetReq(XF86DRICreateContext
, req
);
341 req
->reqType
= info
->codes
->major_opcode
;
342 req
->driReqType
= X_XF86DRICreateContext
;
343 req
->visual
= configID
;
344 req
->screen
= screen
;
345 *context
= XAllocID(dpy
);
346 req
->context
= *context
;
347 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
350 TRACE("CreateContext... return False");
353 *hHWContext
= rep
.hHWContext
;
356 TRACE("CreateContext... return True");
361 XF86DRICreateContext(Display
* dpy
, int screen
, Visual
* visual
,
362 XID
* context
, drm_context_t
* hHWContext
)
364 return XF86DRICreateContextWithConfig(dpy
, screen
, visual
->visualid
,
365 context
, hHWContext
);
369 XF86DRIDestroyContext(Display
* dpy
, int screen
, XID context
)
371 XExtDisplayInfo
*info
= find_display(dpy
);
372 xXF86DRIDestroyContextReq
*req
;
374 TRACE("DestroyContext...");
375 XF86DRICheckExtension(dpy
, info
, False
);
378 GetReq(XF86DRIDestroyContext
, req
);
379 req
->reqType
= info
->codes
->major_opcode
;
380 req
->driReqType
= X_XF86DRIDestroyContext
;
381 req
->screen
= screen
;
382 req
->context
= context
;
385 TRACE("DestroyContext... return True");
390 XF86DRICreateDrawable(Display
* dpy
, int screen
,
391 XID drawable
, drm_drawable_t
* hHWDrawable
)
393 XExtDisplayInfo
*info
= find_display(dpy
);
394 xXF86DRICreateDrawableReply rep
;
395 xXF86DRICreateDrawableReq
*req
;
397 TRACE("CreateDrawable...");
398 XF86DRICheckExtension(dpy
, info
, False
);
401 GetReq(XF86DRICreateDrawable
, req
);
402 req
->reqType
= info
->codes
->major_opcode
;
403 req
->driReqType
= X_XF86DRICreateDrawable
;
404 req
->screen
= screen
;
405 req
->drawable
= drawable
;
406 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
409 TRACE("CreateDrawable... return False");
412 *hHWDrawable
= rep
.hHWDrawable
;
415 TRACE("CreateDrawable... return True");
420 noopErrorHandler(Display
* dpy
, XErrorEvent
* xerr
)
426 XF86DRIDestroyDrawable(Display
* dpy
, int screen
, XID drawable
)
428 XExtDisplayInfo
*info
= find_display(dpy
);
429 xXF86DRIDestroyDrawableReq
*req
;
430 int (*oldXErrorHandler
) (Display
*, XErrorEvent
*);
432 TRACE("DestroyDrawable...");
433 XF86DRICheckExtension(dpy
, info
, False
);
435 /* This is called from the DRI driver, which used call it like this
437 * if (windowExists(drawable))
438 * destroyDrawable(drawable);
440 * which is a textbook race condition - the window may disappear
441 * from the server between checking for its existance and
442 * destroying it. Instead we change the semantics of
443 * __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if
444 * the windows is gone, by wrapping the destroy call in an error
448 oldXErrorHandler
= XSetErrorHandler(noopErrorHandler
);
451 GetReq(XF86DRIDestroyDrawable
, req
);
452 req
->reqType
= info
->codes
->major_opcode
;
453 req
->driReqType
= X_XF86DRIDestroyDrawable
;
454 req
->screen
= screen
;
455 req
->drawable
= drawable
;
459 XSetErrorHandler(oldXErrorHandler
);
461 TRACE("DestroyDrawable... return True");
466 XF86DRIGetDrawableInfo(Display
* dpy
, int screen
, Drawable drawable
,
467 unsigned int *index
, unsigned int *stamp
,
468 int *X
, int *Y
, int *W
, int *H
,
469 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
470 int *backX
, int *backY
,
471 int *numBackClipRects
,
472 drm_clip_rect_t
** pBackClipRects
)
474 XExtDisplayInfo
*info
= find_display(dpy
);
475 xXF86DRIGetDrawableInfoReply rep
;
476 xXF86DRIGetDrawableInfoReq
*req
;
479 TRACE("GetDrawableInfo...");
480 XF86DRICheckExtension(dpy
, info
, False
);
483 GetReq(XF86DRIGetDrawableInfo
, req
);
484 req
->reqType
= info
->codes
->major_opcode
;
485 req
->driReqType
= X_XF86DRIGetDrawableInfo
;
486 req
->screen
= screen
;
487 req
->drawable
= drawable
;
489 if (!_XReply(dpy
, (xReply
*) & rep
, 1, xFalse
)) {
492 TRACE("GetDrawableInfo... return False");
495 *index
= rep
.drawableTableIndex
;
496 *stamp
= rep
.drawableTableStamp
;
497 *X
= (int) rep
.drawableX
;
498 *Y
= (int) rep
.drawableY
;
499 *W
= (int) rep
.drawableWidth
;
500 *H
= (int) rep
.drawableHeight
;
501 *numClipRects
= rep
.numClipRects
;
502 total_rects
= *numClipRects
;
506 *numBackClipRects
= rep
.numBackClipRects
;
507 total_rects
+= *numBackClipRects
;
510 /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
511 * backwards compatibility (Because of the >> 2 shift) but the fix
512 * enables multi-threaded apps to work.
514 if (rep
.length
!= ((((SIZEOF(xXF86DRIGetDrawableInfoReply
) -
515 SIZEOF(xGenericReply
) +
516 total_rects
* sizeof(drm_clip_rect_t
)) +
518 _XEatData(dpy
, rep
.length
);
521 TRACE("GetDrawableInfo... return False");
527 int len
= sizeof(drm_clip_rect_t
) * (*numClipRects
);
529 *pClipRects
= calloc(len
, 1);
531 _XRead(dpy
, (char *) *pClipRects
, len
);
537 if (*numBackClipRects
) {
538 int len
= sizeof(drm_clip_rect_t
) * (*numBackClipRects
);
540 *pBackClipRects
= calloc(len
, 1);
542 _XRead(dpy
, (char *) *pBackClipRects
, len
);
545 *pBackClipRects
= NULL
;
550 TRACE("GetDrawableInfo... return True");
555 XF86DRIGetDeviceInfo(Display
* dpy
, int screen
, drm_handle_t
* hFrameBuffer
,
556 int *fbOrigin
, int *fbSize
, int *fbStride
,
557 int *devPrivateSize
, void **pDevPrivate
)
559 XExtDisplayInfo
*info
= find_display(dpy
);
560 xXF86DRIGetDeviceInfoReply rep
;
561 xXF86DRIGetDeviceInfoReq
*req
;
563 TRACE("GetDeviceInfo...");
564 XF86DRICheckExtension(dpy
, info
, False
);
567 GetReq(XF86DRIGetDeviceInfo
, req
);
568 req
->reqType
= info
->codes
->major_opcode
;
569 req
->driReqType
= X_XF86DRIGetDeviceInfo
;
570 req
->screen
= screen
;
571 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
574 TRACE("GetDeviceInfo... return False");
578 *hFrameBuffer
= rep
.hFrameBufferLow
;
579 if (sizeof(drm_handle_t
) == 8) {
580 int shift
= 32; /* var to prevent warning on next line */
581 *hFrameBuffer
|= ((drm_handle_t
) rep
.hFrameBufferHigh
) << shift
;
584 *fbOrigin
= rep
.framebufferOrigin
;
585 *fbSize
= rep
.framebufferSize
;
586 *fbStride
= rep
.framebufferStride
;
587 *devPrivateSize
= rep
.devPrivateSize
;
590 if (!(*pDevPrivate
= calloc(rep
.devPrivateSize
, 1))) {
591 _XEatData(dpy
, ((rep
.devPrivateSize
+ 3) & ~3));
594 TRACE("GetDeviceInfo... return False");
597 _XRead(dpy
, (char *) *pDevPrivate
, rep
.devPrivateSize
);
605 TRACE("GetDeviceInfo... return True");
610 XF86DRIOpenFullScreen(Display
* dpy
, int screen
, Drawable drawable
)
612 /* This function and the underlying X protocol are deprecated.
621 XF86DRICloseFullScreen(Display
* dpy
, int screen
, Drawable drawable
)
623 /* This function and the underlying X protocol are deprecated.
631 #endif /* GLX_DIRECT_RENDERING */