1 /* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */
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 */
44 #include <X11/Xlibint.h>
45 #include <X11/extensions/Xext.h>
46 #include <X11/extensions/extutil.h>
48 #include "xf86dristr.h"
50 static XExtensionInfo _xf86dri_info_data
;
51 static XExtensionInfo
*xf86dri_info
= &_xf86dri_info_data
;
52 static char xf86dri_extension_name
[] = XF86DRINAME
;
54 #define uniDRICheckExtension(dpy,i,val) \
55 XextCheckExtension (dpy, i, xf86dri_extension_name, val)
57 /*****************************************************************************
59 * private utility routines *
61 *****************************************************************************/
63 static int close_display(Display
* dpy
, XExtCodes
* extCodes
);
64 static /* const */ XExtensionHooks xf86dri_extension_hooks
= {
69 NULL
, /* create_font */
71 close_display
, /* close_display */
72 NULL
, /* wire_to_event */
73 NULL
, /* event_to_wire */
75 NULL
, /* error_string */
79 XEXT_GENERATE_FIND_DISPLAY(find_display
, xf86dri_info
,
80 xf86dri_extension_name
, &xf86dri_extension_hooks
, 0, NULL
)
82 static XEXT_GENERATE_CLOSE_DISPLAY(close_display
, xf86dri_info
)
84 /*****************************************************************************
86 * public XFree86-DRI Extension routines *
88 *****************************************************************************/
91 #define TRACE(msg) fprintf(stderr,"uniDRI%s\n", msg);
95 Bool
uniDRIQueryExtension(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");
114 uniDRIQueryVersion(dpy
, majorVersion
, minorVersion
, patchVersion
)
120 XExtDisplayInfo
*info
= find_display(dpy
);
121 xXF86DRIQueryVersionReply rep
;
122 xXF86DRIQueryVersionReq
*req
;
124 TRACE("QueryVersion...");
125 uniDRICheckExtension(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 uniDRIQueryDirectRenderingCapable(dpy
, screen
, isCapable
)
152 XExtDisplayInfo
*info
= find_display(dpy
);
153 xXF86DRIQueryDirectRenderingCapableReply rep
;
154 xXF86DRIQueryDirectRenderingCapableReq
*req
;
156 TRACE("QueryDirectRenderingCapable...");
157 uniDRICheckExtension(dpy
, info
, False
);
160 GetReq(XF86DRIQueryDirectRenderingCapable
, req
);
161 req
->reqType
= info
->codes
->major_opcode
;
162 req
->driReqType
= X_XF86DRIQueryDirectRenderingCapable
;
163 req
->screen
= screen
;
164 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
167 TRACE("QueryDirectRenderingCapable... return False");
170 *isCapable
= rep
.isCapable
;
173 TRACE("QueryDirectRenderingCapable... return True");
178 uniDRIOpenConnection(dpy
, screen
, hSAREA
, busIdString
)
181 drm_handle_t
*hSAREA
;
184 XExtDisplayInfo
*info
= find_display(dpy
);
185 xXF86DRIOpenConnectionReply rep
;
186 xXF86DRIOpenConnectionReq
*req
;
188 TRACE("OpenConnection...");
189 uniDRICheckExtension(dpy
, info
, False
);
192 GetReq(XF86DRIOpenConnection
, req
);
193 req
->reqType
= info
->codes
->major_opcode
;
194 req
->driReqType
= X_XF86DRIOpenConnection
;
195 req
->screen
= screen
;
196 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
199 TRACE("OpenConnection... return False");
203 *hSAREA
= rep
.hSAREALow
;
205 if (sizeof(drm_handle_t
) == 8) {
206 *hSAREA
|= ((unsigned long)rep
.hSAREAHigh
) << 32;
210 if (!(*busIdString
= (char *)Xcalloc(rep
.busIdStringLength
+ 1, 1))) {
211 _XEatData(dpy
, ((rep
.busIdStringLength
+ 3) & ~3));
214 TRACE("OpenConnection... return False");
217 _XReadPad(dpy
, *busIdString
, rep
.busIdStringLength
);
223 TRACE("OpenConnection... return True");
228 uniDRIAuthConnection(dpy
, screen
, magic
)
233 XExtDisplayInfo
*info
= find_display(dpy
);
234 xXF86DRIAuthConnectionReq
*req
;
235 xXF86DRIAuthConnectionReply rep
;
237 TRACE("AuthConnection...");
238 uniDRICheckExtension(dpy
, info
, False
);
241 GetReq(XF86DRIAuthConnection
, req
);
242 req
->reqType
= info
->codes
->major_opcode
;
243 req
->driReqType
= X_XF86DRIAuthConnection
;
244 req
->screen
= screen
;
246 rep
.authenticated
= 0;
247 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
) || !rep
.authenticated
) {
250 TRACE("AuthConnection... return False");
255 TRACE("AuthConnection... return True");
260 uniDRICloseConnection(dpy
, screen
)
264 XExtDisplayInfo
*info
= find_display(dpy
);
265 xXF86DRICloseConnectionReq
*req
;
267 TRACE("CloseConnection...");
269 uniDRICheckExtension(dpy
, info
, False
);
272 GetReq(XF86DRICloseConnection
, req
);
273 req
->reqType
= info
->codes
->major_opcode
;
274 req
->driReqType
= X_XF86DRICloseConnection
;
275 req
->screen
= screen
;
278 TRACE("CloseConnection... return True");
283 uniDRIGetClientDriverName(dpy
, screen
, ddxDriverMajorVersion
,
284 ddxDriverMinorVersion
, ddxDriverPatchVersion
, clientDriverName
)
287 int *ddxDriverMajorVersion
;
288 int *ddxDriverMinorVersion
;
289 int *ddxDriverPatchVersion
;
290 char **clientDriverName
;
292 XExtDisplayInfo
*info
= find_display(dpy
);
293 xXF86DRIGetClientDriverNameReply rep
;
294 xXF86DRIGetClientDriverNameReq
*req
;
296 TRACE("GetClientDriverName...");
297 uniDRICheckExtension(dpy
, info
, False
);
300 GetReq(XF86DRIGetClientDriverName
, req
);
301 req
->reqType
= info
->codes
->major_opcode
;
302 req
->driReqType
= X_XF86DRIGetClientDriverName
;
303 req
->screen
= screen
;
304 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
307 TRACE("GetClientDriverName... return False");
311 *ddxDriverMajorVersion
= rep
.ddxDriverMajorVersion
;
312 *ddxDriverMinorVersion
= rep
.ddxDriverMinorVersion
;
313 *ddxDriverPatchVersion
= rep
.ddxDriverPatchVersion
;
316 if (!(*clientDriverName
=
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
);
326 *clientDriverName
= NULL
;
330 TRACE("GetClientDriverName... return True");
335 uniDRICreateContextWithConfig(dpy
, screen
, configID
, context
, hHWContext
)
340 drm_context_t
*hHWContext
;
342 XExtDisplayInfo
*info
= find_display(dpy
);
343 xXF86DRICreateContextReply rep
;
344 xXF86DRICreateContextReq
*req
;
346 TRACE("CreateContext...");
347 uniDRICheckExtension(dpy
, info
, False
);
350 GetReq(XF86DRICreateContext
, req
);
351 req
->reqType
= info
->codes
->major_opcode
;
352 req
->driReqType
= X_XF86DRICreateContext
;
353 req
->visual
= configID
;
354 req
->screen
= screen
;
355 *context
= XAllocID(dpy
);
356 req
->context
= *context
;
357 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
360 TRACE("CreateContext... return False");
363 *hHWContext
= rep
.hHWContext
;
366 TRACE("CreateContext... return True");
371 uniDRICreateContext(dpy
, screen
, visual
, context
, hHWContext
)
376 drm_context_t
*hHWContext
;
378 return uniDRICreateContextWithConfig(dpy
, screen
, visual
->visualid
,
379 context
, hHWContext
);
383 uniDRIDestroyContext(Display
* ndpy
, int screen
, XID context
)
385 Display
*const dpy
= (Display
*) ndpy
;
386 XExtDisplayInfo
*info
= find_display(dpy
);
387 xXF86DRIDestroyContextReq
*req
;
389 TRACE("DestroyContext...");
390 uniDRICheckExtension(dpy
, info
, False
);
393 GetReq(XF86DRIDestroyContext
, req
);
394 req
->reqType
= info
->codes
->major_opcode
;
395 req
->driReqType
= X_XF86DRIDestroyContext
;
396 req
->screen
= screen
;
397 req
->context
= context
;
400 TRACE("DestroyContext... return True");
405 uniDRICreateDrawable(Display
* ndpy
, int screen
,
406 Drawable drawable
, drm_drawable_t
* hHWDrawable
)
408 Display
*const dpy
= (Display
*) ndpy
;
409 XExtDisplayInfo
*info
= find_display(dpy
);
410 xXF86DRICreateDrawableReply rep
;
411 xXF86DRICreateDrawableReq
*req
;
413 TRACE("CreateDrawable...");
414 uniDRICheckExtension(dpy
, info
, False
);
417 GetReq(XF86DRICreateDrawable
, req
);
418 req
->reqType
= info
->codes
->major_opcode
;
419 req
->driReqType
= X_XF86DRICreateDrawable
;
420 req
->screen
= screen
;
421 req
->drawable
= drawable
;
422 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
425 TRACE("CreateDrawable... return False");
428 *hHWDrawable
= rep
.hHWDrawable
;
431 TRACE("CreateDrawable... return True");
436 uniDRIDestroyDrawable(Display
* ndpy
, int screen
, Drawable drawable
)
438 Display
*const dpy
= (Display
*) ndpy
;
439 XExtDisplayInfo
*info
= find_display(dpy
);
440 xXF86DRIDestroyDrawableReq
*req
;
442 TRACE("DestroyDrawable...");
443 uniDRICheckExtension(dpy
, info
, False
);
446 GetReq(XF86DRIDestroyDrawable
, req
);
447 req
->reqType
= info
->codes
->major_opcode
;
448 req
->driReqType
= X_XF86DRIDestroyDrawable
;
449 req
->screen
= screen
;
450 req
->drawable
= drawable
;
453 TRACE("DestroyDrawable... return True");
458 uniDRIGetDrawableInfo(Display
* dpy
, int screen
, Drawable drawable
,
459 unsigned int *index
, unsigned int *stamp
,
460 int *X
, int *Y
, int *W
, int *H
,
461 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
462 int *backX
, int *backY
,
463 int *numBackClipRects
, drm_clip_rect_t
** pBackClipRects
)
465 XExtDisplayInfo
*info
= find_display(dpy
);
466 xXF86DRIGetDrawableInfoReply rep
;
467 xXF86DRIGetDrawableInfoReq
*req
;
470 TRACE("GetDrawableInfo...");
471 uniDRICheckExtension(dpy
, info
, False
);
474 GetReq(XF86DRIGetDrawableInfo
, req
);
475 req
->reqType
= info
->codes
->major_opcode
;
476 req
->driReqType
= X_XF86DRIGetDrawableInfo
;
477 req
->screen
= screen
;
478 req
->drawable
= drawable
;
480 if (!_XReply(dpy
, (xReply
*) & rep
, 1, xFalse
)) {
483 TRACE("GetDrawableInfo... return False");
486 *index
= rep
.drawableTableIndex
;
487 *stamp
= rep
.drawableTableStamp
;
488 *X
= (int)rep
.drawableX
;
489 *Y
= (int)rep
.drawableY
;
490 *W
= (int)rep
.drawableWidth
;
491 *H
= (int)rep
.drawableHeight
;
492 *numClipRects
= rep
.numClipRects
;
493 total_rects
= *numClipRects
;
497 *numBackClipRects
= rep
.numBackClipRects
;
498 total_rects
+= *numBackClipRects
;
501 /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
502 * backwards compatibility (Because of the >> 2 shift) but the fix
503 * enables multi-threaded apps to work.
505 if (rep
.length
!= ((((SIZEOF(xXF86DRIGetDrawableInfoReply
) -
506 SIZEOF(xGenericReply
) +
507 total_rects
* sizeof(drm_clip_rect_t
)) +
509 _XEatData(dpy
, rep
.length
);
512 TRACE("GetDrawableInfo... return False");
518 int len
= sizeof(drm_clip_rect_t
) * (*numClipRects
);
520 *pClipRects
= (drm_clip_rect_t
*) Xcalloc(len
, 1);
522 _XRead(dpy
, (char *)*pClipRects
, len
);
527 if (*numBackClipRects
) {
528 int len
= sizeof(drm_clip_rect_t
) * (*numBackClipRects
);
530 *pBackClipRects
= (drm_clip_rect_t
*) Xcalloc(len
, 1);
532 _XRead(dpy
, (char *)*pBackClipRects
, len
);
534 *pBackClipRects
= NULL
;
539 TRACE("GetDrawableInfo... return True");
544 uniDRIGetDeviceInfo(dpy
, screen
, hFrameBuffer
,
545 fbOrigin
, fbSize
, fbStride
, devPrivateSize
, pDevPrivate
)
548 drm_handle_t
*hFrameBuffer
;
555 XExtDisplayInfo
*info
= find_display(dpy
);
556 xXF86DRIGetDeviceInfoReply rep
;
557 xXF86DRIGetDeviceInfoReq
*req
;
559 TRACE("GetDeviceInfo...");
560 uniDRICheckExtension(dpy
, info
, False
);
563 GetReq(XF86DRIGetDeviceInfo
, req
);
564 req
->reqType
= info
->codes
->major_opcode
;
565 req
->driReqType
= X_XF86DRIGetDeviceInfo
;
566 req
->screen
= screen
;
567 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
570 TRACE("GetDeviceInfo... return False");
574 *hFrameBuffer
= rep
.hFrameBufferLow
;
576 if (sizeof(drm_handle_t
) == 8) {
577 *hFrameBuffer
|= ((unsigned long)rep
.hFrameBufferHigh
) << 32;
581 *fbOrigin
= rep
.framebufferOrigin
;
582 *fbSize
= rep
.framebufferSize
;
583 *fbStride
= rep
.framebufferStride
;
584 *devPrivateSize
= rep
.devPrivateSize
;
587 if (!(*pDevPrivate
= (void *)Xcalloc(rep
.devPrivateSize
, 1))) {
588 _XEatData(dpy
, ((rep
.devPrivateSize
+ 3) & ~3));
591 TRACE("GetDeviceInfo... return False");
594 _XRead(dpy
, (char *)*pDevPrivate
, rep
.devPrivateSize
);
601 TRACE("GetDeviceInfo... return True");