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 */
40 #include <X11/Xlibint.h>
41 #include <X11/extensions/Xext.h>
42 #include <X11/extensions/extutil.h>
43 #include "xf86dristr.h"
45 static XExtensionInfo _xf86dri_info_data
;
46 static XExtensionInfo
*xf86dri_info
= &_xf86dri_info_data
;
47 static char xf86dri_extension_name
[] = XF86DRINAME
;
49 #define XF86DRICheckExtension(dpy,i,val) \
50 XextCheckExtension (dpy, i, xf86dri_extension_name, val)
52 /*****************************************************************************
54 * private utility routines *
56 *****************************************************************************/
58 static int close_display(Display
*dpy
, XExtCodes
*extCodes
);
59 static /* const */ XExtensionHooks xf86dri_extension_hooks
= {
64 NULL
, /* create_font */
66 close_display
, /* close_display */
67 NULL
, /* wire_to_event */
68 NULL
, /* event_to_wire */
70 NULL
, /* error_string */
73 static XEXT_GENERATE_FIND_DISPLAY (find_display
, xf86dri_info
,
74 xf86dri_extension_name
,
75 &xf86dri_extension_hooks
,
78 static XEXT_GENERATE_CLOSE_DISPLAY (close_display
, xf86dri_info
)
81 /*****************************************************************************
83 * public XFree86-DRI Extension routines *
85 *****************************************************************************/
89 #define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
96 PUBLIC Bool
XF86DRIQueryExtension (dpy
, event_basep
, error_basep
)
98 int *event_basep
, *error_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");
109 TRACE("QueryExtension... return False");
114 PUBLIC Bool
XF86DRIQueryVersion(dpy
, majorVersion
, minorVersion
, patchVersion
)
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");
146 PUBLIC Bool
XF86DRIQueryDirectRenderingCapable(dpy
, screen
, isCapable
)
151 XExtDisplayInfo
*info
= find_display (dpy
);
152 xXF86DRIQueryDirectRenderingCapableReply rep
;
153 xXF86DRIQueryDirectRenderingCapableReq
*req
;
155 TRACE("QueryDirectRenderingCapable...");
156 XF86DRICheckExtension (dpy
, info
, False
);
159 GetReq(XF86DRIQueryDirectRenderingCapable
, req
);
160 req
->reqType
= info
->codes
->major_opcode
;
161 req
->driReqType
= X_XF86DRIQueryDirectRenderingCapable
;
162 req
->screen
= screen
;
163 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
)) {
166 TRACE("QueryDirectRenderingCapable... return False");
169 *isCapable
= rep
.isCapable
;
172 TRACE("QueryDirectRenderingCapable... return True");
176 PUBLIC Bool
XF86DRIOpenConnection(dpy
, screen
, hSAREA
, busIdString
)
179 drm_handle_t
* hSAREA
;
182 XExtDisplayInfo
*info
= find_display (dpy
);
183 xXF86DRIOpenConnectionReply rep
;
184 xXF86DRIOpenConnectionReq
*req
;
186 TRACE("OpenConnection...");
187 XF86DRICheckExtension (dpy
, info
, False
);
190 GetReq(XF86DRIOpenConnection
, req
);
191 req
->reqType
= info
->codes
->major_opcode
;
192 req
->driReqType
= X_XF86DRIOpenConnection
;
193 req
->screen
= screen
;
194 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
)) {
197 TRACE("OpenConnection... return False");
201 *hSAREA
= rep
.hSAREALow
;
202 if (sizeof(drm_handle_t
) == 8) {
203 int shift
= 32; /* var to prevent warning on next line */
204 *hSAREA
|= ((drm_handle_t
) rep
.hSAREAHigh
) << shift
;
208 if (!(*busIdString
= (char *)Xcalloc(rep
.busIdStringLength
+ 1, 1))) {
209 _XEatData(dpy
, ((rep
.busIdStringLength
+3) & ~3));
212 TRACE("OpenConnection... return False");
215 _XReadPad(dpy
, *busIdString
, rep
.busIdStringLength
);
221 TRACE("OpenConnection... return True");
225 PUBLIC Bool
XF86DRIAuthConnection(dpy
, screen
, 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");
256 PUBLIC Bool
XF86DRICloseConnection(dpy
, screen
)
260 XExtDisplayInfo
*info
= find_display (dpy
);
261 xXF86DRICloseConnectionReq
*req
;
263 TRACE("CloseConnection...");
265 XF86DRICheckExtension (dpy
, info
, False
);
268 GetReq(XF86DRICloseConnection
, req
);
269 req
->reqType
= info
->codes
->major_opcode
;
270 req
->driReqType
= X_XF86DRICloseConnection
;
271 req
->screen
= screen
;
274 TRACE("CloseConnection... return True");
278 PUBLIC Bool
XF86DRIGetClientDriverName(dpy
, screen
, ddxDriverMajorVersion
,
279 ddxDriverMinorVersion
, ddxDriverPatchVersion
, clientDriverName
)
282 int* ddxDriverMajorVersion
;
283 int* ddxDriverMinorVersion
;
284 int* ddxDriverPatchVersion
;
285 char** clientDriverName
;
287 XExtDisplayInfo
*info
= find_display (dpy
);
288 xXF86DRIGetClientDriverNameReply rep
;
289 xXF86DRIGetClientDriverNameReq
*req
;
291 TRACE("GetClientDriverName...");
292 XF86DRICheckExtension (dpy
, info
, False
);
295 GetReq(XF86DRIGetClientDriverName
, req
);
296 req
->reqType
= info
->codes
->major_opcode
;
297 req
->driReqType
= X_XF86DRIGetClientDriverName
;
298 req
->screen
= screen
;
299 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
)) {
302 TRACE("GetClientDriverName... return False");
306 *ddxDriverMajorVersion
= rep
.ddxDriverMajorVersion
;
307 *ddxDriverMinorVersion
= rep
.ddxDriverMinorVersion
;
308 *ddxDriverPatchVersion
= rep
.ddxDriverPatchVersion
;
311 if (!(*clientDriverName
= (char *)Xcalloc(rep
.clientDriverNameLength
+ 1, 1))) {
312 _XEatData(dpy
, ((rep
.clientDriverNameLength
+3) & ~3));
315 TRACE("GetClientDriverName... return False");
318 _XReadPad(dpy
, *clientDriverName
, rep
.clientDriverNameLength
);
320 *clientDriverName
= NULL
;
324 TRACE("GetClientDriverName... return True");
328 PUBLIC Bool
XF86DRICreateContextWithConfig(dpy
, screen
, configID
, context
,
334 drm_context_t
* hHWContext
;
336 XExtDisplayInfo
*info
= find_display (dpy
);
337 xXF86DRICreateContextReply rep
;
338 xXF86DRICreateContextReq
*req
;
340 TRACE("CreateContext...");
341 XF86DRICheckExtension (dpy
, info
, False
);
344 GetReq(XF86DRICreateContext
, req
);
345 req
->reqType
= info
->codes
->major_opcode
;
346 req
->driReqType
= X_XF86DRICreateContext
;
347 req
->visual
= configID
;
348 req
->screen
= screen
;
349 *context
= XAllocID(dpy
);
350 req
->context
= *context
;
351 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
)) {
354 TRACE("CreateContext... return False");
357 *hHWContext
= rep
.hHWContext
;
360 TRACE("CreateContext... return True");
364 PUBLIC Bool
XF86DRICreateContext(dpy
, screen
, visual
, context
, hHWContext
)
369 drm_context_t
* hHWContext
;
371 return XF86DRICreateContextWithConfig( dpy
, screen
, visual
->visualid
,
372 context
, hHWContext
);
375 PUBLIC Bool
XF86DRIDestroyContext( Display
* ndpy
, int screen
,
378 Display
* const dpy
= (Display
*) ndpy
;
379 XExtDisplayInfo
*info
= find_display (dpy
);
380 xXF86DRIDestroyContextReq
*req
;
382 TRACE("DestroyContext...");
383 XF86DRICheckExtension (dpy
, info
, False
);
386 GetReq(XF86DRIDestroyContext
, req
);
387 req
->reqType
= info
->codes
->major_opcode
;
388 req
->driReqType
= X_XF86DRIDestroyContext
;
389 req
->screen
= screen
;
390 req
->context
= context
;
393 TRACE("DestroyContext... return True");
397 PUBLIC Bool
XF86DRICreateDrawable( Display
* ndpy
, int screen
,
398 Drawable drawable
, drm_drawable_t
* hHWDrawable
)
400 Display
* const dpy
= (Display
*) ndpy
;
401 XExtDisplayInfo
*info
= find_display (dpy
);
402 xXF86DRICreateDrawableReply rep
;
403 xXF86DRICreateDrawableReq
*req
;
405 TRACE("CreateDrawable...");
406 XF86DRICheckExtension (dpy
, info
, False
);
409 GetReq(XF86DRICreateDrawable
, req
);
410 req
->reqType
= info
->codes
->major_opcode
;
411 req
->driReqType
= X_XF86DRICreateDrawable
;
412 req
->screen
= screen
;
413 req
->drawable
= drawable
;
414 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
)) {
417 TRACE("CreateDrawable... return False");
420 *hHWDrawable
= rep
.hHWDrawable
;
423 TRACE("CreateDrawable... return True");
427 PUBLIC Bool
XF86DRIDestroyDrawable( Display
* ndpy
, int screen
,
430 Display
* const dpy
= (Display
*) ndpy
;
431 XExtDisplayInfo
*info
= find_display (dpy
);
432 xXF86DRIDestroyDrawableReq
*req
;
434 TRACE("DestroyDrawable...");
435 XF86DRICheckExtension (dpy
, info
, False
);
438 GetReq(XF86DRIDestroyDrawable
, req
);
439 req
->reqType
= info
->codes
->major_opcode
;
440 req
->driReqType
= X_XF86DRIDestroyDrawable
;
441 req
->screen
= screen
;
442 req
->drawable
= drawable
;
445 TRACE("DestroyDrawable... return True");
449 PUBLIC Bool
XF86DRIGetDrawableInfo(Display
* dpy
, int screen
, Drawable drawable
,
450 unsigned int* index
, unsigned int* stamp
,
451 int* X
, int* Y
, int* W
, int* H
,
452 int* numClipRects
, drm_clip_rect_t
** pClipRects
,
453 int* backX
, int* backY
,
454 int* numBackClipRects
, drm_clip_rect_t
** pBackClipRects
)
456 XExtDisplayInfo
*info
= find_display (dpy
);
457 xXF86DRIGetDrawableInfoReply rep
;
458 xXF86DRIGetDrawableInfoReq
*req
;
461 TRACE("GetDrawableInfo...");
462 XF86DRICheckExtension (dpy
, info
, False
);
465 GetReq(XF86DRIGetDrawableInfo
, req
);
466 req
->reqType
= info
->codes
->major_opcode
;
467 req
->driReqType
= X_XF86DRIGetDrawableInfo
;
468 req
->screen
= screen
;
469 req
->drawable
= drawable
;
471 if (!_XReply(dpy
, (xReply
*)&rep
, 1, xFalse
))
475 TRACE("GetDrawableInfo... return False");
478 *index
= rep
.drawableTableIndex
;
479 *stamp
= rep
.drawableTableStamp
;
480 *X
= (int)rep
.drawableX
;
481 *Y
= (int)rep
.drawableY
;
482 *W
= (int)rep
.drawableWidth
;
483 *H
= (int)rep
.drawableHeight
;
484 *numClipRects
= rep
.numClipRects
;
485 total_rects
= *numClipRects
;
489 *numBackClipRects
= rep
.numBackClipRects
;
490 total_rects
+= *numBackClipRects
;
493 /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
494 * backwards compatibility (Because of the >> 2 shift) but the fix
495 * enables multi-threaded apps to work.
497 if (rep
.length
!= ((((SIZEOF(xXF86DRIGetDrawableInfoReply
) -
498 SIZEOF(xGenericReply
) +
499 total_rects
* sizeof(drm_clip_rect_t
)) + 3) & ~3) >> 2)) {
500 _XEatData(dpy
, rep
.length
);
503 TRACE("GetDrawableInfo... return False");
509 int len
= sizeof(drm_clip_rect_t
) * (*numClipRects
);
511 *pClipRects
= (drm_clip_rect_t
*)Xcalloc(len
, 1);
513 _XRead(dpy
, (char*)*pClipRects
, len
);
518 if (*numBackClipRects
) {
519 int len
= sizeof(drm_clip_rect_t
) * (*numBackClipRects
);
521 *pBackClipRects
= (drm_clip_rect_t
*)Xcalloc(len
, 1);
523 _XRead(dpy
, (char*)*pBackClipRects
, len
);
525 *pBackClipRects
= NULL
;
530 TRACE("GetDrawableInfo... return True");
534 PUBLIC Bool
XF86DRIGetDeviceInfo(dpy
, screen
, hFrameBuffer
,
535 fbOrigin
, fbSize
, fbStride
, devPrivateSize
, pDevPrivate
)
538 drm_handle_t
* hFrameBuffer
;
545 XExtDisplayInfo
*info
= find_display (dpy
);
546 xXF86DRIGetDeviceInfoReply rep
;
547 xXF86DRIGetDeviceInfoReq
*req
;
549 TRACE("GetDeviceInfo...");
550 XF86DRICheckExtension (dpy
, info
, False
);
553 GetReq(XF86DRIGetDeviceInfo
, req
);
554 req
->reqType
= info
->codes
->major_opcode
;
555 req
->driReqType
= X_XF86DRIGetDeviceInfo
;
556 req
->screen
= screen
;
557 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
)) {
560 TRACE("GetDeviceInfo... return False");
564 *hFrameBuffer
= rep
.hFrameBufferLow
;
565 if (sizeof(drm_handle_t
) == 8) {
566 int shift
= 32; /* var to prevent warning on next line */
567 *hFrameBuffer
|= ((drm_handle_t
) rep
.hFrameBufferHigh
) << shift
;
570 *fbOrigin
= rep
.framebufferOrigin
;
571 *fbSize
= rep
.framebufferSize
;
572 *fbStride
= rep
.framebufferStride
;
573 *devPrivateSize
= rep
.devPrivateSize
;
576 if (!(*pDevPrivate
= (void *)Xcalloc(rep
.devPrivateSize
, 1))) {
577 _XEatData(dpy
, ((rep
.devPrivateSize
+3) & ~3));
580 TRACE("GetDeviceInfo... return False");
583 _XRead(dpy
, (char*)*pDevPrivate
, rep
.devPrivateSize
);
590 TRACE("GetDeviceInfo... return True");
594 PUBLIC Bool
XF86DRIOpenFullScreen(dpy
, screen
, drawable
)
599 /* This function and the underlying X protocol are deprecated.
607 PUBLIC Bool
XF86DRICloseFullScreen(dpy
, screen
, drawable
)
612 /* This function and the underlying X protocol are deprecated.