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 #include <X11/Xlibint.h>
40 #include <X11/extensions/Xext.h>
41 #include <X11/extensions/extutil.h>
42 #include "xf86dristr.h"
44 static XExtensionInfo _xf86dri_info_data
;
45 static XExtensionInfo
*xf86dri_info
= &_xf86dri_info_data
;
46 static char xf86dri_extension_name
[] = XF86DRINAME
;
48 #define XF86DRICheckExtension(dpy,i,val) \
49 XextCheckExtension (dpy, i, xf86dri_extension_name, val)
51 /*****************************************************************************
53 * private utility routines *
55 *****************************************************************************/
57 static int close_display(Display
*dpy
, XExtCodes
*extCodes
);
58 static /* const */ XExtensionHooks xf86dri_extension_hooks
= {
63 NULL
, /* create_font */
65 close_display
, /* close_display */
66 NULL
, /* wire_to_event */
67 NULL
, /* event_to_wire */
69 NULL
, /* error_string */
72 static XEXT_GENERATE_FIND_DISPLAY (find_display
, xf86dri_info
,
73 xf86dri_extension_name
,
74 &xf86dri_extension_hooks
,
77 static XEXT_GENERATE_CLOSE_DISPLAY (close_display
, xf86dri_info
)
80 /*****************************************************************************
82 * public XFree86-DRI Extension routines *
84 *****************************************************************************/
88 #define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
95 PUBLIC Bool
XF86DRIQueryExtension (dpy
, event_basep
, error_basep
)
97 int *event_basep
, *error_basep
;
99 XExtDisplayInfo
*info
= find_display (dpy
);
101 TRACE("QueryExtension...");
102 if (XextHasExtension(info
)) {
103 *event_basep
= info
->codes
->first_event
;
104 *error_basep
= info
->codes
->first_error
;
105 TRACE("QueryExtension... return True");
108 TRACE("QueryExtension... return False");
113 PUBLIC Bool
XF86DRIQueryVersion(dpy
, majorVersion
, minorVersion
, patchVersion
)
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");
145 PUBLIC Bool
XF86DRIQueryDirectRenderingCapable(dpy
, screen
, isCapable
)
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");
175 PUBLIC Bool
XF86DRIOpenConnection(dpy
, screen
, hSAREA
, busIdString
)
178 drm_handle_t
* hSAREA
;
181 XExtDisplayInfo
*info
= find_display (dpy
);
182 xXF86DRIOpenConnectionReply rep
;
183 xXF86DRIOpenConnectionReq
*req
;
185 TRACE("OpenConnection...");
186 XF86DRICheckExtension (dpy
, info
, False
);
189 GetReq(XF86DRIOpenConnection
, req
);
190 req
->reqType
= info
->codes
->major_opcode
;
191 req
->driReqType
= X_XF86DRIOpenConnection
;
192 req
->screen
= screen
;
193 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
)) {
196 TRACE("OpenConnection... return False");
200 *hSAREA
= rep
.hSAREALow
;
201 if (sizeof(drm_handle_t
) == 8) {
202 int shift
= 32; /* var to prevent warning on next line */
203 *hSAREA
|= ((drm_handle_t
) rep
.hSAREAHigh
) << shift
;
207 if (!(*busIdString
= (char *)Xcalloc(rep
.busIdStringLength
+ 1, 1))) {
208 _XEatData(dpy
, ((rep
.busIdStringLength
+3) & ~3));
211 TRACE("OpenConnection... return False");
214 _XReadPad(dpy
, *busIdString
, rep
.busIdStringLength
);
220 TRACE("OpenConnection... return True");
224 PUBLIC Bool
XF86DRIAuthConnection(dpy
, screen
, magic
)
229 XExtDisplayInfo
*info
= find_display (dpy
);
230 xXF86DRIAuthConnectionReq
*req
;
231 xXF86DRIAuthConnectionReply rep
;
233 TRACE("AuthConnection...");
234 XF86DRICheckExtension (dpy
, info
, False
);
237 GetReq(XF86DRIAuthConnection
, req
);
238 req
->reqType
= info
->codes
->major_opcode
;
239 req
->driReqType
= X_XF86DRIAuthConnection
;
240 req
->screen
= screen
;
242 rep
.authenticated
= 0;
243 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
) || !rep
.authenticated
) {
246 TRACE("AuthConnection... return False");
251 TRACE("AuthConnection... return True");
255 PUBLIC Bool
XF86DRICloseConnection(dpy
, 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");
277 PUBLIC Bool
XF86DRIGetClientDriverName(dpy
, screen
, ddxDriverMajorVersion
,
278 ddxDriverMinorVersion
, ddxDriverPatchVersion
, clientDriverName
)
281 int* ddxDriverMajorVersion
;
282 int* ddxDriverMinorVersion
;
283 int* ddxDriverPatchVersion
;
284 char** clientDriverName
;
286 XExtDisplayInfo
*info
= find_display (dpy
);
287 xXF86DRIGetClientDriverNameReply rep
;
288 xXF86DRIGetClientDriverNameReq
*req
;
290 TRACE("GetClientDriverName...");
291 XF86DRICheckExtension (dpy
, info
, False
);
294 GetReq(XF86DRIGetClientDriverName
, req
);
295 req
->reqType
= info
->codes
->major_opcode
;
296 req
->driReqType
= X_XF86DRIGetClientDriverName
;
297 req
->screen
= screen
;
298 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
)) {
301 TRACE("GetClientDriverName... return False");
305 *ddxDriverMajorVersion
= rep
.ddxDriverMajorVersion
;
306 *ddxDriverMinorVersion
= rep
.ddxDriverMinorVersion
;
307 *ddxDriverPatchVersion
= rep
.ddxDriverPatchVersion
;
310 if (!(*clientDriverName
= (char *)Xcalloc(rep
.clientDriverNameLength
+ 1, 1))) {
311 _XEatData(dpy
, ((rep
.clientDriverNameLength
+3) & ~3));
314 TRACE("GetClientDriverName... return False");
317 _XReadPad(dpy
, *clientDriverName
, rep
.clientDriverNameLength
);
319 *clientDriverName
= NULL
;
323 TRACE("GetClientDriverName... return True");
327 PUBLIC Bool
XF86DRICreateContextWithConfig(dpy
, screen
, configID
, context
,
333 drm_context_t
* hHWContext
;
335 XExtDisplayInfo
*info
= find_display (dpy
);
336 xXF86DRICreateContextReply rep
;
337 xXF86DRICreateContextReq
*req
;
339 TRACE("CreateContext...");
340 XF86DRICheckExtension (dpy
, info
, False
);
343 GetReq(XF86DRICreateContext
, req
);
344 req
->reqType
= info
->codes
->major_opcode
;
345 req
->driReqType
= X_XF86DRICreateContext
;
346 req
->visual
= configID
;
347 req
->screen
= screen
;
348 *context
= XAllocID(dpy
);
349 req
->context
= *context
;
350 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
)) {
353 TRACE("CreateContext... return False");
356 *hHWContext
= rep
.hHWContext
;
359 TRACE("CreateContext... return True");
363 PUBLIC Bool
XF86DRICreateContext(dpy
, screen
, visual
, context
, hHWContext
)
368 drm_context_t
* hHWContext
;
370 return XF86DRICreateContextWithConfig( dpy
, screen
, visual
->visualid
,
371 context
, hHWContext
);
374 PUBLIC Bool
XF86DRIDestroyContext( Display
* ndpy
, int screen
,
377 Display
* const dpy
= (Display
*) ndpy
;
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");
396 PUBLIC Bool
XF86DRICreateDrawable( Display
* ndpy
, int screen
,
397 Drawable drawable
, drm_drawable_t
* hHWDrawable
)
399 Display
* const dpy
= (Display
*) ndpy
;
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");
426 PUBLIC Bool
XF86DRIDestroyDrawable( Display
* ndpy
, int screen
,
429 Display
* const dpy
= (Display
*) ndpy
;
430 XExtDisplayInfo
*info
= find_display (dpy
);
431 xXF86DRIDestroyDrawableReq
*req
;
433 TRACE("DestroyDrawable...");
434 XF86DRICheckExtension (dpy
, info
, False
);
437 GetReq(XF86DRIDestroyDrawable
, req
);
438 req
->reqType
= info
->codes
->major_opcode
;
439 req
->driReqType
= X_XF86DRIDestroyDrawable
;
440 req
->screen
= screen
;
441 req
->drawable
= drawable
;
444 TRACE("DestroyDrawable... return True");
448 PUBLIC Bool
XF86DRIGetDrawableInfo(Display
* dpy
, int screen
, Drawable drawable
,
449 unsigned int* index
, unsigned int* stamp
,
450 int* X
, int* Y
, int* W
, int* H
,
451 int* numClipRects
, drm_clip_rect_t
** pClipRects
,
452 int* backX
, int* backY
,
453 int* numBackClipRects
, drm_clip_rect_t
** pBackClipRects
)
455 XExtDisplayInfo
*info
= find_display (dpy
);
456 xXF86DRIGetDrawableInfoReply rep
;
457 xXF86DRIGetDrawableInfoReq
*req
;
460 TRACE("GetDrawableInfo...");
461 XF86DRICheckExtension (dpy
, info
, False
);
464 GetReq(XF86DRIGetDrawableInfo
, req
);
465 req
->reqType
= info
->codes
->major_opcode
;
466 req
->driReqType
= X_XF86DRIGetDrawableInfo
;
467 req
->screen
= screen
;
468 req
->drawable
= drawable
;
470 if (!_XReply(dpy
, (xReply
*)&rep
, 1, xFalse
))
474 TRACE("GetDrawableInfo... return False");
477 *index
= rep
.drawableTableIndex
;
478 *stamp
= rep
.drawableTableStamp
;
479 *X
= (int)rep
.drawableX
;
480 *Y
= (int)rep
.drawableY
;
481 *W
= (int)rep
.drawableWidth
;
482 *H
= (int)rep
.drawableHeight
;
483 *numClipRects
= rep
.numClipRects
;
484 total_rects
= *numClipRects
;
488 *numBackClipRects
= rep
.numBackClipRects
;
489 total_rects
+= *numBackClipRects
;
492 /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
493 * backwards compatibility (Because of the >> 2 shift) but the fix
494 * enables multi-threaded apps to work.
496 if (rep
.length
!= ((((SIZEOF(xXF86DRIGetDrawableInfoReply
) -
497 SIZEOF(xGenericReply
) +
498 total_rects
* sizeof(drm_clip_rect_t
)) + 3) & ~3) >> 2)) {
499 _XEatData(dpy
, rep
.length
);
502 TRACE("GetDrawableInfo... return False");
508 int len
= sizeof(drm_clip_rect_t
) * (*numClipRects
);
510 *pClipRects
= (drm_clip_rect_t
*)Xcalloc(len
, 1);
512 _XRead(dpy
, (char*)*pClipRects
, len
);
517 if (*numBackClipRects
) {
518 int len
= sizeof(drm_clip_rect_t
) * (*numBackClipRects
);
520 *pBackClipRects
= (drm_clip_rect_t
*)Xcalloc(len
, 1);
522 _XRead(dpy
, (char*)*pBackClipRects
, len
);
524 *pBackClipRects
= NULL
;
529 TRACE("GetDrawableInfo... return True");
533 PUBLIC Bool
XF86DRIGetDeviceInfo(dpy
, screen
, hFrameBuffer
,
534 fbOrigin
, fbSize
, fbStride
, devPrivateSize
, pDevPrivate
)
537 drm_handle_t
* hFrameBuffer
;
544 XExtDisplayInfo
*info
= find_display (dpy
);
545 xXF86DRIGetDeviceInfoReply rep
;
546 xXF86DRIGetDeviceInfoReq
*req
;
548 TRACE("GetDeviceInfo...");
549 XF86DRICheckExtension (dpy
, info
, False
);
552 GetReq(XF86DRIGetDeviceInfo
, req
);
553 req
->reqType
= info
->codes
->major_opcode
;
554 req
->driReqType
= X_XF86DRIGetDeviceInfo
;
555 req
->screen
= screen
;
556 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
)) {
559 TRACE("GetDeviceInfo... return False");
563 *hFrameBuffer
= rep
.hFrameBufferLow
;
564 if (sizeof(drm_handle_t
) == 8) {
565 int shift
= 32; /* var to prevent warning on next line */
566 *hFrameBuffer
|= ((drm_handle_t
) rep
.hFrameBufferHigh
) << shift
;
569 *fbOrigin
= rep
.framebufferOrigin
;
570 *fbSize
= rep
.framebufferSize
;
571 *fbStride
= rep
.framebufferStride
;
572 *devPrivateSize
= rep
.devPrivateSize
;
575 if (!(*pDevPrivate
= (void *)Xcalloc(rep
.devPrivateSize
, 1))) {
576 _XEatData(dpy
, ((rep
.devPrivateSize
+3) & ~3));
579 TRACE("GetDeviceInfo... return False");
582 _XRead(dpy
, (char*)*pDevPrivate
, rep
.devPrivateSize
);
589 TRACE("GetDeviceInfo... return True");