1 /* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
2 /**************************************************************************
4 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5 Copyright 2000 VA Linux Systems, Inc.
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sub license, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial portions
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
24 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
32 * Kevin E. Martin <martin@valinux.com>
33 * Jens Owen <jens@tungstengraphics.com>
34 * Rickard E. (Rik) Faith <faith@valinux.com>
38 /* THIS IS NOT AN X CONSORTIUM STANDARD */
40 #ifdef GLX_DIRECT_RENDERING
43 #include <X11/Xlibint.h>
44 #include <X11/extensions/Xext.h>
45 #include <X11/extensions/extutil.h>
46 #include "xf86dristr.h"
49 #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303
50 # define PUBLIC __attribute__((visibility("default")))
51 # define USED __attribute__((used))
59 static XExtensionInfo _xf86dri_info_data
;
60 static XExtensionInfo
*xf86dri_info
= &_xf86dri_info_data
;
61 static char xf86dri_extension_name
[] = XF86DRINAME
;
63 #define XF86DRICheckExtension(dpy,i,val) \
64 XextCheckExtension (dpy, i, xf86dri_extension_name, val)
66 /*****************************************************************************
68 * private utility routines *
70 *****************************************************************************/
72 static int close_display(Display
* dpy
, XExtCodes
* extCodes
);
73 static /* const */ XExtensionHooks xf86dri_extension_hooks
= {
78 NULL
, /* create_font */
80 close_display
, /* close_display */
81 NULL
, /* wire_to_event */
82 NULL
, /* event_to_wire */
84 NULL
, /* error_string */
88 XEXT_GENERATE_FIND_DISPLAY(find_display
, xf86dri_info
,
89 xf86dri_extension_name
,
90 &xf86dri_extension_hooks
, 0, NULL
)
93 XEXT_GENERATE_CLOSE_DISPLAY(close_display
, xf86dri_info
)
96 /*****************************************************************************
98 * public XFree86-DRI Extension routines *
100 *****************************************************************************/
103 #define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
109 XF86DRIQueryExtension(Display
* dpy
, int *event_basep
,
112 XExtDisplayInfo
*info
= find_display(dpy
);
114 TRACE("QueryExtension...");
115 if (XextHasExtension(info
)) {
116 *event_basep
= info
->codes
->first_event
;
117 *error_basep
= info
->codes
->first_error
;
118 TRACE("QueryExtension... return True");
122 TRACE("QueryExtension... return False");
128 XF86DRIQueryVersion(Display
* dpy
, int *majorVersion
, int *minorVersion
,
131 XExtDisplayInfo
*info
= find_display(dpy
);
132 xXF86DRIQueryVersionReply rep
;
133 xXF86DRIQueryVersionReq
*req
;
135 TRACE("QueryVersion...");
136 XF86DRICheckExtension(dpy
, info
, False
);
139 GetReq(XF86DRIQueryVersion
, req
);
140 req
->reqType
= info
->codes
->major_opcode
;
141 req
->driReqType
= X_XF86DRIQueryVersion
;
142 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
145 TRACE("QueryVersion... return False");
148 *majorVersion
= rep
.majorVersion
;
149 *minorVersion
= rep
.minorVersion
;
150 *patchVersion
= rep
.patchVersion
;
153 TRACE("QueryVersion... return True");
158 XF86DRIQueryDirectRenderingCapable(Display
* dpy
, int screen
,
161 XExtDisplayInfo
*info
= find_display(dpy
);
162 xXF86DRIQueryDirectRenderingCapableReply rep
;
163 xXF86DRIQueryDirectRenderingCapableReq
*req
;
165 TRACE("QueryDirectRenderingCapable...");
166 XF86DRICheckExtension(dpy
, info
, False
);
169 GetReq(XF86DRIQueryDirectRenderingCapable
, req
);
170 req
->reqType
= info
->codes
->major_opcode
;
171 req
->driReqType
= X_XF86DRIQueryDirectRenderingCapable
;
172 req
->screen
= screen
;
173 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
176 TRACE("QueryDirectRenderingCapable... return False");
179 *isCapable
= rep
.isCapable
;
182 TRACE("QueryDirectRenderingCapable... return True");
187 XF86DRIOpenConnection(Display
* dpy
, int screen
, drm_handle_t
* hSAREA
,
190 XExtDisplayInfo
*info
= find_display(dpy
);
191 xXF86DRIOpenConnectionReply rep
;
192 xXF86DRIOpenConnectionReq
*req
;
194 TRACE("OpenConnection...");
195 XF86DRICheckExtension(dpy
, info
, False
);
198 GetReq(XF86DRIOpenConnection
, req
);
199 req
->reqType
= info
->codes
->major_opcode
;
200 req
->driReqType
= X_XF86DRIOpenConnection
;
201 req
->screen
= screen
;
202 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
205 TRACE("OpenConnection... return False");
209 *hSAREA
= rep
.hSAREALow
;
210 if (sizeof(drm_handle_t
) == 8) {
211 int shift
= 32; /* var to prevent warning on next line */
212 *hSAREA
|= ((drm_handle_t
) rep
.hSAREAHigh
) << shift
;
216 if (!(*busIdString
= (char *) Xcalloc(rep
.busIdStringLength
+ 1, 1))) {
217 _XEatData(dpy
, ((rep
.busIdStringLength
+ 3) & ~3));
220 TRACE("OpenConnection... return False");
223 _XReadPad(dpy
, *busIdString
, rep
.busIdStringLength
);
230 TRACE("OpenConnection... return True");
235 XF86DRIAuthConnection(Display
* dpy
, int screen
, drm_magic_t magic
)
237 XExtDisplayInfo
*info
= find_display(dpy
);
238 xXF86DRIAuthConnectionReq
*req
;
239 xXF86DRIAuthConnectionReply rep
;
241 TRACE("AuthConnection...");
242 XF86DRICheckExtension(dpy
, info
, False
);
245 GetReq(XF86DRIAuthConnection
, req
);
246 req
->reqType
= info
->codes
->major_opcode
;
247 req
->driReqType
= X_XF86DRIAuthConnection
;
248 req
->screen
= screen
;
250 rep
.authenticated
= 0;
251 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
) || !rep
.authenticated
) {
254 TRACE("AuthConnection... return False");
259 TRACE("AuthConnection... return True");
264 XF86DRICloseConnection(Display
* dpy
, int screen
)
266 XExtDisplayInfo
*info
= find_display(dpy
);
267 xXF86DRICloseConnectionReq
*req
;
269 TRACE("CloseConnection...");
271 XF86DRICheckExtension(dpy
, info
, False
);
274 GetReq(XF86DRICloseConnection
, req
);
275 req
->reqType
= info
->codes
->major_opcode
;
276 req
->driReqType
= X_XF86DRICloseConnection
;
277 req
->screen
= screen
;
280 TRACE("CloseConnection... return True");
285 XF86DRIGetClientDriverName(Display
* dpy
, int screen
,
286 int *ddxDriverMajorVersion
,
287 int *ddxDriverMinorVersion
,
288 int *ddxDriverPatchVersion
,
289 char **clientDriverName
)
291 XExtDisplayInfo
*info
= find_display(dpy
);
292 xXF86DRIGetClientDriverNameReply rep
;
293 xXF86DRIGetClientDriverNameReq
*req
;
295 TRACE("GetClientDriverName...");
296 XF86DRICheckExtension(dpy
, info
, False
);
299 GetReq(XF86DRIGetClientDriverName
, req
);
300 req
->reqType
= info
->codes
->major_opcode
;
301 req
->driReqType
= X_XF86DRIGetClientDriverName
;
302 req
->screen
= screen
;
303 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
306 TRACE("GetClientDriverName... return False");
310 *ddxDriverMajorVersion
= rep
.ddxDriverMajorVersion
;
311 *ddxDriverMinorVersion
= rep
.ddxDriverMinorVersion
;
312 *ddxDriverPatchVersion
= rep
.ddxDriverPatchVersion
;
317 (char *) Xcalloc(rep
.clientDriverNameLength
+ 1, 1))) {
318 _XEatData(dpy
, ((rep
.clientDriverNameLength
+ 3) & ~3));
321 TRACE("GetClientDriverName... return False");
324 _XReadPad(dpy
, *clientDriverName
, rep
.clientDriverNameLength
);
327 *clientDriverName
= NULL
;
331 TRACE("GetClientDriverName... return True");
336 XF86DRICreateContextWithConfig(Display
* dpy
, int screen
, int configID
,
337 XID
* context
, drm_context_t
* hHWContext
)
339 XExtDisplayInfo
*info
= find_display(dpy
);
340 xXF86DRICreateContextReply rep
;
341 xXF86DRICreateContextReq
*req
;
343 TRACE("CreateContext...");
344 XF86DRICheckExtension(dpy
, info
, False
);
347 GetReq(XF86DRICreateContext
, req
);
348 req
->reqType
= info
->codes
->major_opcode
;
349 req
->driReqType
= X_XF86DRICreateContext
;
350 req
->visual
= configID
;
351 req
->screen
= screen
;
352 *context
= XAllocID(dpy
);
353 req
->context
= *context
;
354 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
357 TRACE("CreateContext... return False");
360 *hHWContext
= rep
.hHWContext
;
363 TRACE("CreateContext... return True");
368 XF86DRICreateContext(Display
* dpy
, int screen
, Visual
* visual
,
369 XID
* context
, drm_context_t
* hHWContext
)
371 return XF86DRICreateContextWithConfig(dpy
, screen
, visual
->visualid
,
372 context
, hHWContext
);
376 XF86DRIDestroyContext(Display
* dpy
, int screen
, XID context
)
378 XExtDisplayInfo
*info
= find_display(dpy
);
379 xXF86DRIDestroyContextReq
*req
;
381 TRACE("DestroyContext...");
382 XF86DRICheckExtension(dpy
, info
, False
);
385 GetReq(XF86DRIDestroyContext
, req
);
386 req
->reqType
= info
->codes
->major_opcode
;
387 req
->driReqType
= X_XF86DRIDestroyContext
;
388 req
->screen
= screen
;
389 req
->context
= context
;
392 TRACE("DestroyContext... return True");
397 XF86DRICreateDrawable(Display
* dpy
, int screen
,
398 XID drawable
, drm_drawable_t
* hHWDrawable
)
400 XExtDisplayInfo
*info
= find_display(dpy
);
401 xXF86DRICreateDrawableReply rep
;
402 xXF86DRICreateDrawableReq
*req
;
404 TRACE("CreateDrawable...");
405 XF86DRICheckExtension(dpy
, info
, False
);
408 GetReq(XF86DRICreateDrawable
, req
);
409 req
->reqType
= info
->codes
->major_opcode
;
410 req
->driReqType
= X_XF86DRICreateDrawable
;
411 req
->screen
= screen
;
412 req
->drawable
= drawable
;
413 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
416 TRACE("CreateDrawable... return False");
419 *hHWDrawable
= rep
.hHWDrawable
;
422 TRACE("CreateDrawable... return True");
427 noopErrorHandler(Display
* dpy
, XErrorEvent
* xerr
)
433 XF86DRIDestroyDrawable(Display
* dpy
, int screen
, XID drawable
)
435 XExtDisplayInfo
*info
= find_display(dpy
);
436 xXF86DRIDestroyDrawableReq
*req
;
437 int (*oldXErrorHandler
) (Display
*, XErrorEvent
*);
439 TRACE("DestroyDrawable...");
440 XF86DRICheckExtension(dpy
, info
, False
);
442 /* This is called from the DRI driver, which used call it like this
444 * if (windowExists(drawable))
445 * destroyDrawable(drawable);
447 * which is a textbook race condition - the window may disappear
448 * from the server between checking for its existance and
449 * destroying it. Instead we change the semantics of
450 * __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if
451 * the windows is gone, by wrapping the destroy call in an error
455 oldXErrorHandler
= XSetErrorHandler(noopErrorHandler
);
458 GetReq(XF86DRIDestroyDrawable
, req
);
459 req
->reqType
= info
->codes
->major_opcode
;
460 req
->driReqType
= X_XF86DRIDestroyDrawable
;
461 req
->screen
= screen
;
462 req
->drawable
= drawable
;
466 XSetErrorHandler(oldXErrorHandler
);
468 TRACE("DestroyDrawable... return True");
473 XF86DRIGetDrawableInfo(Display
* dpy
, int screen
, Drawable drawable
,
474 unsigned int *index
, unsigned int *stamp
,
475 int *X
, int *Y
, int *W
, int *H
,
476 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
477 int *backX
, int *backY
,
478 int *numBackClipRects
,
479 drm_clip_rect_t
** pBackClipRects
)
481 XExtDisplayInfo
*info
= find_display(dpy
);
482 xXF86DRIGetDrawableInfoReply rep
;
483 xXF86DRIGetDrawableInfoReq
*req
;
486 TRACE("GetDrawableInfo...");
487 XF86DRICheckExtension(dpy
, info
, False
);
490 GetReq(XF86DRIGetDrawableInfo
, req
);
491 req
->reqType
= info
->codes
->major_opcode
;
492 req
->driReqType
= X_XF86DRIGetDrawableInfo
;
493 req
->screen
= screen
;
494 req
->drawable
= drawable
;
496 if (!_XReply(dpy
, (xReply
*) & rep
, 1, xFalse
)) {
499 TRACE("GetDrawableInfo... return False");
502 *index
= rep
.drawableTableIndex
;
503 *stamp
= rep
.drawableTableStamp
;
504 *X
= (int) rep
.drawableX
;
505 *Y
= (int) rep
.drawableY
;
506 *W
= (int) rep
.drawableWidth
;
507 *H
= (int) rep
.drawableHeight
;
508 *numClipRects
= rep
.numClipRects
;
509 total_rects
= *numClipRects
;
513 *numBackClipRects
= rep
.numBackClipRects
;
514 total_rects
+= *numBackClipRects
;
517 /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
518 * backwards compatibility (Because of the >> 2 shift) but the fix
519 * enables multi-threaded apps to work.
521 if (rep
.length
!= ((((SIZEOF(xXF86DRIGetDrawableInfoReply
) -
522 SIZEOF(xGenericReply
) +
523 total_rects
* sizeof(drm_clip_rect_t
)) +
525 _XEatData(dpy
, rep
.length
);
528 TRACE("GetDrawableInfo... return False");
534 int len
= sizeof(drm_clip_rect_t
) * (*numClipRects
);
536 *pClipRects
= (drm_clip_rect_t
*) Xcalloc(len
, 1);
538 _XRead(dpy
, (char *) *pClipRects
, len
);
544 if (*numBackClipRects
) {
545 int len
= sizeof(drm_clip_rect_t
) * (*numBackClipRects
);
547 *pBackClipRects
= (drm_clip_rect_t
*) Xcalloc(len
, 1);
549 _XRead(dpy
, (char *) *pBackClipRects
, len
);
552 *pBackClipRects
= NULL
;
557 TRACE("GetDrawableInfo... return True");
562 XF86DRIGetDeviceInfo(Display
* dpy
, int screen
, drm_handle_t
* hFrameBuffer
,
563 int *fbOrigin
, int *fbSize
, int *fbStride
,
564 int *devPrivateSize
, void **pDevPrivate
)
566 XExtDisplayInfo
*info
= find_display(dpy
);
567 xXF86DRIGetDeviceInfoReply rep
;
568 xXF86DRIGetDeviceInfoReq
*req
;
570 TRACE("GetDeviceInfo...");
571 XF86DRICheckExtension(dpy
, info
, False
);
574 GetReq(XF86DRIGetDeviceInfo
, req
);
575 req
->reqType
= info
->codes
->major_opcode
;
576 req
->driReqType
= X_XF86DRIGetDeviceInfo
;
577 req
->screen
= screen
;
578 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
581 TRACE("GetDeviceInfo... return False");
585 *hFrameBuffer
= rep
.hFrameBufferLow
;
586 if (sizeof(drm_handle_t
) == 8) {
587 int shift
= 32; /* var to prevent warning on next line */
588 *hFrameBuffer
|= ((drm_handle_t
) rep
.hFrameBufferHigh
) << shift
;
591 *fbOrigin
= rep
.framebufferOrigin
;
592 *fbSize
= rep
.framebufferSize
;
593 *fbStride
= rep
.framebufferStride
;
594 *devPrivateSize
= rep
.devPrivateSize
;
597 if (!(*pDevPrivate
= (void *) Xcalloc(rep
.devPrivateSize
, 1))) {
598 _XEatData(dpy
, ((rep
.devPrivateSize
+ 3) & ~3));
601 TRACE("GetDeviceInfo... return False");
604 _XRead(dpy
, (char *) *pDevPrivate
, rep
.devPrivateSize
);
612 TRACE("GetDeviceInfo... return True");
617 XF86DRIOpenFullScreen(Display
* dpy
, int screen
, Drawable drawable
)
619 /* This function and the underlying X protocol are deprecated.
628 XF86DRICloseFullScreen(Display
* dpy
, int screen
, Drawable drawable
)
630 /* This function and the underlying X protocol are deprecated.
638 #endif /* GLX_DIRECT_RENDERING */