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 #ifdef GLX_DIRECT_RENDERING
42 #include <X11/Xlibint.h>
43 #include <X11/extensions/Xext.h>
44 #include <X11/extensions/extutil.h>
45 #include "xf86dristr.h"
49 # define PUBLIC __attribute__((visibility("default")))
50 # define USED __attribute__((used))
58 static XExtensionInfo _xf86dri_info_data
;
59 static XExtensionInfo
*xf86dri_info
= &_xf86dri_info_data
;
60 static char xf86dri_extension_name
[] = XF86DRINAME
;
62 #define XF86DRICheckExtension(dpy,i,val) \
63 XextCheckExtension (dpy, i, xf86dri_extension_name, val)
65 /*****************************************************************************
67 * private utility routines *
69 *****************************************************************************/
71 static int close_display(Display
* dpy
, XExtCodes
* extCodes
);
72 static /* const */ XExtensionHooks xf86dri_extension_hooks
= {
77 NULL
, /* create_font */
79 close_display
, /* close_display */
80 NULL
, /* wire_to_event */
81 NULL
, /* event_to_wire */
83 NULL
, /* error_string */
87 XEXT_GENERATE_FIND_DISPLAY(find_display
, xf86dri_info
,
88 xf86dri_extension_name
,
89 &xf86dri_extension_hooks
, 0, NULL
)
92 XEXT_GENERATE_CLOSE_DISPLAY(close_display
, xf86dri_info
)
95 /*****************************************************************************
97 * public XFree86-DRI Extension routines *
99 *****************************************************************************/
102 #define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
108 XF86DRIQueryExtension(Display
* dpy
, int *event_basep
,
111 XExtDisplayInfo
*info
= find_display(dpy
);
113 TRACE("QueryExtension...");
114 if (XextHasExtension(info
)) {
115 *event_basep
= info
->codes
->first_event
;
116 *error_basep
= info
->codes
->first_error
;
117 TRACE("QueryExtension... return True");
121 TRACE("QueryExtension... return False");
127 XF86DRIQueryVersion(Display
* dpy
, int *majorVersion
, int *minorVersion
,
130 XExtDisplayInfo
*info
= find_display(dpy
);
131 xXF86DRIQueryVersionReply rep
;
132 xXF86DRIQueryVersionReq
*req
;
134 TRACE("QueryVersion...");
135 XF86DRICheckExtension(dpy
, info
, False
);
138 GetReq(XF86DRIQueryVersion
, req
);
139 req
->reqType
= info
->codes
->major_opcode
;
140 req
->driReqType
= X_XF86DRIQueryVersion
;
141 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
144 TRACE("QueryVersion... return False");
147 *majorVersion
= rep
.majorVersion
;
148 *minorVersion
= rep
.minorVersion
;
149 *patchVersion
= rep
.patchVersion
;
152 TRACE("QueryVersion... return True");
157 XF86DRIQueryDirectRenderingCapable(Display
* dpy
, int screen
,
160 XExtDisplayInfo
*info
= find_display(dpy
);
161 xXF86DRIQueryDirectRenderingCapableReply rep
;
162 xXF86DRIQueryDirectRenderingCapableReq
*req
;
164 TRACE("QueryDirectRenderingCapable...");
165 XF86DRICheckExtension(dpy
, info
, False
);
168 GetReq(XF86DRIQueryDirectRenderingCapable
, req
);
169 req
->reqType
= info
->codes
->major_opcode
;
170 req
->driReqType
= X_XF86DRIQueryDirectRenderingCapable
;
171 req
->screen
= screen
;
172 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
175 TRACE("QueryDirectRenderingCapable... return False");
178 *isCapable
= rep
.isCapable
;
181 TRACE("QueryDirectRenderingCapable... return True");
186 XF86DRIOpenConnection(Display
* dpy
, int screen
, drm_handle_t
* hSAREA
,
189 XExtDisplayInfo
*info
= find_display(dpy
);
190 xXF86DRIOpenConnectionReply rep
;
191 xXF86DRIOpenConnectionReq
*req
;
193 TRACE("OpenConnection...");
194 XF86DRICheckExtension(dpy
, info
, False
);
197 GetReq(XF86DRIOpenConnection
, req
);
198 req
->reqType
= info
->codes
->major_opcode
;
199 req
->driReqType
= X_XF86DRIOpenConnection
;
200 req
->screen
= screen
;
201 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
204 TRACE("OpenConnection... return False");
208 *hSAREA
= rep
.hSAREALow
;
209 if (sizeof(drm_handle_t
) == 8) {
210 int shift
= 32; /* var to prevent warning on next line */
211 *hSAREA
|= ((drm_handle_t
) rep
.hSAREAHigh
) << shift
;
215 if (!(*busIdString
= (char *) Xcalloc(rep
.busIdStringLength
+ 1, 1))) {
216 _XEatData(dpy
, ((rep
.busIdStringLength
+ 3) & ~3));
219 TRACE("OpenConnection... return False");
222 _XReadPad(dpy
, *busIdString
, rep
.busIdStringLength
);
229 TRACE("OpenConnection... return True");
234 XF86DRIAuthConnection(Display
* dpy
, int screen
, drm_magic_t magic
)
236 XExtDisplayInfo
*info
= find_display(dpy
);
237 xXF86DRIAuthConnectionReq
*req
;
238 xXF86DRIAuthConnectionReply rep
;
240 TRACE("AuthConnection...");
241 XF86DRICheckExtension(dpy
, info
, False
);
244 GetReq(XF86DRIAuthConnection
, req
);
245 req
->reqType
= info
->codes
->major_opcode
;
246 req
->driReqType
= X_XF86DRIAuthConnection
;
247 req
->screen
= screen
;
249 rep
.authenticated
= 0;
250 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
) || !rep
.authenticated
) {
253 TRACE("AuthConnection... return False");
258 TRACE("AuthConnection... return True");
263 XF86DRICloseConnection(Display
* dpy
, int screen
)
265 XExtDisplayInfo
*info
= find_display(dpy
);
266 xXF86DRICloseConnectionReq
*req
;
268 TRACE("CloseConnection...");
270 XF86DRICheckExtension(dpy
, info
, False
);
273 GetReq(XF86DRICloseConnection
, req
);
274 req
->reqType
= info
->codes
->major_opcode
;
275 req
->driReqType
= X_XF86DRICloseConnection
;
276 req
->screen
= screen
;
279 TRACE("CloseConnection... return True");
284 XF86DRIGetClientDriverName(Display
* dpy
, int screen
,
285 int *ddxDriverMajorVersion
,
286 int *ddxDriverMinorVersion
,
287 int *ddxDriverPatchVersion
,
288 char **clientDriverName
)
290 XExtDisplayInfo
*info
= find_display(dpy
);
291 xXF86DRIGetClientDriverNameReply rep
;
292 xXF86DRIGetClientDriverNameReq
*req
;
294 TRACE("GetClientDriverName...");
295 XF86DRICheckExtension(dpy
, info
, False
);
298 GetReq(XF86DRIGetClientDriverName
, req
);
299 req
->reqType
= info
->codes
->major_opcode
;
300 req
->driReqType
= X_XF86DRIGetClientDriverName
;
301 req
->screen
= screen
;
302 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
305 TRACE("GetClientDriverName... return False");
309 *ddxDriverMajorVersion
= rep
.ddxDriverMajorVersion
;
310 *ddxDriverMinorVersion
= rep
.ddxDriverMinorVersion
;
311 *ddxDriverPatchVersion
= rep
.ddxDriverPatchVersion
;
316 (char *) Xcalloc(rep
.clientDriverNameLength
+ 1, 1))) {
317 _XEatData(dpy
, ((rep
.clientDriverNameLength
+ 3) & ~3));
320 TRACE("GetClientDriverName... return False");
323 _XReadPad(dpy
, *clientDriverName
, rep
.clientDriverNameLength
);
326 *clientDriverName
= NULL
;
330 TRACE("GetClientDriverName... return True");
335 XF86DRICreateContextWithConfig(Display
* dpy
, int screen
, int configID
,
336 XID
* context
, drm_context_t
* hHWContext
)
338 XExtDisplayInfo
*info
= find_display(dpy
);
339 xXF86DRICreateContextReply rep
;
340 xXF86DRICreateContextReq
*req
;
342 TRACE("CreateContext...");
343 XF86DRICheckExtension(dpy
, info
, False
);
346 GetReq(XF86DRICreateContext
, req
);
347 req
->reqType
= info
->codes
->major_opcode
;
348 req
->driReqType
= X_XF86DRICreateContext
;
349 req
->visual
= configID
;
350 req
->screen
= screen
;
351 *context
= XAllocID(dpy
);
352 req
->context
= *context
;
353 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
356 TRACE("CreateContext... return False");
359 *hHWContext
= rep
.hHWContext
;
362 TRACE("CreateContext... return True");
367 XF86DRICreateContext(Display
* dpy
, int screen
, Visual
* visual
,
368 XID
* context
, drm_context_t
* hHWContext
)
370 return XF86DRICreateContextWithConfig(dpy
, screen
, visual
->visualid
,
371 context
, hHWContext
);
375 XF86DRIDestroyContext(Display
* dpy
, int screen
, XID context
)
377 XExtDisplayInfo
*info
= find_display(dpy
);
378 xXF86DRIDestroyContextReq
*req
;
380 TRACE("DestroyContext...");
381 XF86DRICheckExtension(dpy
, info
, False
);
384 GetReq(XF86DRIDestroyContext
, req
);
385 req
->reqType
= info
->codes
->major_opcode
;
386 req
->driReqType
= X_XF86DRIDestroyContext
;
387 req
->screen
= screen
;
388 req
->context
= context
;
391 TRACE("DestroyContext... return True");
396 XF86DRICreateDrawable(Display
* dpy
, int screen
,
397 XID drawable
, drm_drawable_t
* hHWDrawable
)
399 XExtDisplayInfo
*info
= find_display(dpy
);
400 xXF86DRICreateDrawableReply rep
;
401 xXF86DRICreateDrawableReq
*req
;
403 TRACE("CreateDrawable...");
404 XF86DRICheckExtension(dpy
, info
, False
);
407 GetReq(XF86DRICreateDrawable
, req
);
408 req
->reqType
= info
->codes
->major_opcode
;
409 req
->driReqType
= X_XF86DRICreateDrawable
;
410 req
->screen
= screen
;
411 req
->drawable
= drawable
;
412 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
415 TRACE("CreateDrawable... return False");
418 *hHWDrawable
= rep
.hHWDrawable
;
421 TRACE("CreateDrawable... return True");
426 noopErrorHandler(Display
* dpy
, XErrorEvent
* xerr
)
432 XF86DRIDestroyDrawable(Display
* dpy
, int screen
, XID drawable
)
434 XExtDisplayInfo
*info
= find_display(dpy
);
435 xXF86DRIDestroyDrawableReq
*req
;
436 int (*oldXErrorHandler
) (Display
*, XErrorEvent
*);
438 TRACE("DestroyDrawable...");
439 XF86DRICheckExtension(dpy
, info
, False
);
441 /* This is called from the DRI driver, which used call it like this
443 * if (windowExists(drawable))
444 * destroyDrawable(drawable);
446 * which is a textbook race condition - the window may disappear
447 * from the server between checking for its existance and
448 * destroying it. Instead we change the semantics of
449 * __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if
450 * the windows is gone, by wrapping the destroy call in an error
454 oldXErrorHandler
= XSetErrorHandler(noopErrorHandler
);
457 GetReq(XF86DRIDestroyDrawable
, req
);
458 req
->reqType
= info
->codes
->major_opcode
;
459 req
->driReqType
= X_XF86DRIDestroyDrawable
;
460 req
->screen
= screen
;
461 req
->drawable
= drawable
;
465 XSetErrorHandler(oldXErrorHandler
);
467 TRACE("DestroyDrawable... return True");
472 XF86DRIGetDrawableInfo(Display
* dpy
, int screen
, Drawable drawable
,
473 unsigned int *index
, unsigned int *stamp
,
474 int *X
, int *Y
, int *W
, int *H
,
475 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
476 int *backX
, int *backY
,
477 int *numBackClipRects
,
478 drm_clip_rect_t
** pBackClipRects
)
480 XExtDisplayInfo
*info
= find_display(dpy
);
481 xXF86DRIGetDrawableInfoReply rep
;
482 xXF86DRIGetDrawableInfoReq
*req
;
485 TRACE("GetDrawableInfo...");
486 XF86DRICheckExtension(dpy
, info
, False
);
489 GetReq(XF86DRIGetDrawableInfo
, req
);
490 req
->reqType
= info
->codes
->major_opcode
;
491 req
->driReqType
= X_XF86DRIGetDrawableInfo
;
492 req
->screen
= screen
;
493 req
->drawable
= drawable
;
495 if (!_XReply(dpy
, (xReply
*) & rep
, 1, xFalse
)) {
498 TRACE("GetDrawableInfo... return False");
501 *index
= rep
.drawableTableIndex
;
502 *stamp
= rep
.drawableTableStamp
;
503 *X
= (int) rep
.drawableX
;
504 *Y
= (int) rep
.drawableY
;
505 *W
= (int) rep
.drawableWidth
;
506 *H
= (int) rep
.drawableHeight
;
507 *numClipRects
= rep
.numClipRects
;
508 total_rects
= *numClipRects
;
512 *numBackClipRects
= rep
.numBackClipRects
;
513 total_rects
+= *numBackClipRects
;
516 /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
517 * backwards compatibility (Because of the >> 2 shift) but the fix
518 * enables multi-threaded apps to work.
520 if (rep
.length
!= ((((SIZEOF(xXF86DRIGetDrawableInfoReply
) -
521 SIZEOF(xGenericReply
) +
522 total_rects
* sizeof(drm_clip_rect_t
)) +
524 _XEatData(dpy
, rep
.length
);
527 TRACE("GetDrawableInfo... return False");
533 int len
= sizeof(drm_clip_rect_t
) * (*numClipRects
);
535 *pClipRects
= (drm_clip_rect_t
*) Xcalloc(len
, 1);
537 _XRead(dpy
, (char *) *pClipRects
, len
);
543 if (*numBackClipRects
) {
544 int len
= sizeof(drm_clip_rect_t
) * (*numBackClipRects
);
546 *pBackClipRects
= (drm_clip_rect_t
*) Xcalloc(len
, 1);
548 _XRead(dpy
, (char *) *pBackClipRects
, len
);
551 *pBackClipRects
= NULL
;
556 TRACE("GetDrawableInfo... return True");
561 XF86DRIGetDeviceInfo(Display
* dpy
, int screen
, drm_handle_t
* hFrameBuffer
,
562 int *fbOrigin
, int *fbSize
, int *fbStride
,
563 int *devPrivateSize
, void **pDevPrivate
)
565 XExtDisplayInfo
*info
= find_display(dpy
);
566 xXF86DRIGetDeviceInfoReply rep
;
567 xXF86DRIGetDeviceInfoReq
*req
;
569 TRACE("GetDeviceInfo...");
570 XF86DRICheckExtension(dpy
, info
, False
);
573 GetReq(XF86DRIGetDeviceInfo
, req
);
574 req
->reqType
= info
->codes
->major_opcode
;
575 req
->driReqType
= X_XF86DRIGetDeviceInfo
;
576 req
->screen
= screen
;
577 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
580 TRACE("GetDeviceInfo... return False");
584 *hFrameBuffer
= rep
.hFrameBufferLow
;
585 if (sizeof(drm_handle_t
) == 8) {
586 int shift
= 32; /* var to prevent warning on next line */
587 *hFrameBuffer
|= ((drm_handle_t
) rep
.hFrameBufferHigh
) << shift
;
590 *fbOrigin
= rep
.framebufferOrigin
;
591 *fbSize
= rep
.framebufferSize
;
592 *fbStride
= rep
.framebufferStride
;
593 *devPrivateSize
= rep
.devPrivateSize
;
596 if (!(*pDevPrivate
= (void *) Xcalloc(rep
.devPrivateSize
, 1))) {
597 _XEatData(dpy
, ((rep
.devPrivateSize
+ 3) & ~3));
600 TRACE("GetDeviceInfo... return False");
603 _XRead(dpy
, (char *) *pDevPrivate
, rep
.devPrivateSize
);
611 TRACE("GetDeviceInfo... return True");
616 XF86DRIOpenFullScreen(Display
* dpy
, int screen
, Drawable drawable
)
618 /* This function and the underlying X protocol are deprecated.
627 XF86DRICloseFullScreen(Display
* dpy
, int screen
, Drawable drawable
)
629 /* This function and the underlying X protocol are deprecated.
637 #endif /* GLX_DIRECT_RENDERING */