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 */
44 #include <X11/Xlibint.h>
45 #include <X11/extensions/Xext.h>
46 #include <X11/extensions/extutil.h>
47 #include "xf86dristr.h"
49 static XExtensionInfo _xf86dri_info_data
;
50 static XExtensionInfo
*xf86dri_info
= &_xf86dri_info_data
;
51 static char xf86dri_extension_name
[] = XF86DRINAME
;
53 #define uniDRICheckExtension(dpy,i,val) \
54 XextCheckExtension (dpy, i, xf86dri_extension_name, val)
56 /*****************************************************************************
58 * private utility routines *
60 *****************************************************************************/
62 static int close_display(Display
* dpy
, XExtCodes
* extCodes
);
63 static /* const */ XExtensionHooks xf86dri_extension_hooks
= {
68 NULL
, /* create_font */
70 close_display
, /* close_display */
71 NULL
, /* wire_to_event */
72 NULL
, /* event_to_wire */
74 NULL
, /* error_string */
78 XEXT_GENERATE_FIND_DISPLAY(find_display
, xf86dri_info
,
79 xf86dri_extension_name
, &xf86dri_extension_hooks
,
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
,
288 int *ddxDriverMajorVersion
;
289 int *ddxDriverMinorVersion
;
290 int *ddxDriverPatchVersion
;
291 char **clientDriverName
;
293 XExtDisplayInfo
*info
= find_display(dpy
);
294 xXF86DRIGetClientDriverNameReply rep
;
295 xXF86DRIGetClientDriverNameReq
*req
;
297 TRACE("GetClientDriverName...");
298 uniDRICheckExtension(dpy
, info
, False
);
301 GetReq(XF86DRIGetClientDriverName
, req
);
302 req
->reqType
= info
->codes
->major_opcode
;
303 req
->driReqType
= X_XF86DRIGetClientDriverName
;
304 req
->screen
= screen
;
305 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
308 TRACE("GetClientDriverName... return False");
312 *ddxDriverMajorVersion
= rep
.ddxDriverMajorVersion
;
313 *ddxDriverMinorVersion
= rep
.ddxDriverMinorVersion
;
314 *ddxDriverPatchVersion
= rep
.ddxDriverPatchVersion
;
317 if (!(*clientDriverName
=
318 (char *)Xcalloc(rep
.clientDriverNameLength
+ 1, 1))) {
319 _XEatData(dpy
, ((rep
.clientDriverNameLength
+ 3) & ~3));
322 TRACE("GetClientDriverName... return False");
325 _XReadPad(dpy
, *clientDriverName
, rep
.clientDriverNameLength
);
327 *clientDriverName
= NULL
;
331 TRACE("GetClientDriverName... return True");
336 uniDRICreateContextWithConfig(dpy
, screen
, configID
, context
, hHWContext
)
341 drm_context_t
*hHWContext
;
343 XExtDisplayInfo
*info
= find_display(dpy
);
344 xXF86DRICreateContextReply rep
;
345 xXF86DRICreateContextReq
*req
;
347 TRACE("CreateContext...");
348 uniDRICheckExtension(dpy
, info
, False
);
351 GetReq(XF86DRICreateContext
, req
);
352 req
->reqType
= info
->codes
->major_opcode
;
353 req
->driReqType
= X_XF86DRICreateContext
;
354 req
->visual
= configID
;
355 req
->screen
= screen
;
356 *context
= XAllocID(dpy
);
357 req
->context
= *context
;
358 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
361 TRACE("CreateContext... return False");
364 *hHWContext
= rep
.hHWContext
;
367 TRACE("CreateContext... return True");
372 uniDRICreateContext(dpy
, screen
, visual
, context
, hHWContext
)
377 drm_context_t
*hHWContext
;
379 return uniDRICreateContextWithConfig(dpy
, screen
, visual
->visualid
,
380 context
, hHWContext
);
384 uniDRIDestroyContext(Display
* ndpy
, int screen
, XID context
)
386 Display
*const dpy
= (Display
*) ndpy
;
387 XExtDisplayInfo
*info
= find_display(dpy
);
388 xXF86DRIDestroyContextReq
*req
;
390 TRACE("DestroyContext...");
391 uniDRICheckExtension(dpy
, info
, False
);
394 GetReq(XF86DRIDestroyContext
, req
);
395 req
->reqType
= info
->codes
->major_opcode
;
396 req
->driReqType
= X_XF86DRIDestroyContext
;
397 req
->screen
= screen
;
398 req
->context
= context
;
401 TRACE("DestroyContext... return True");
406 uniDRICreateDrawable(Display
* ndpy
, int screen
,
407 Drawable drawable
, drm_drawable_t
* hHWDrawable
)
409 Display
*const dpy
= (Display
*) ndpy
;
410 XExtDisplayInfo
*info
= find_display(dpy
);
411 xXF86DRICreateDrawableReply rep
;
412 xXF86DRICreateDrawableReq
*req
;
414 TRACE("CreateDrawable...");
415 uniDRICheckExtension(dpy
, info
, False
);
418 GetReq(XF86DRICreateDrawable
, req
);
419 req
->reqType
= info
->codes
->major_opcode
;
420 req
->driReqType
= X_XF86DRICreateDrawable
;
421 req
->screen
= screen
;
422 req
->drawable
= drawable
;
423 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
426 TRACE("CreateDrawable... return False");
429 *hHWDrawable
= rep
.hHWDrawable
;
432 TRACE("CreateDrawable... return True");
437 uniDRIDestroyDrawable(Display
* ndpy
, int screen
, Drawable drawable
)
439 Display
*const dpy
= (Display
*) ndpy
;
440 XExtDisplayInfo
*info
= find_display(dpy
);
441 xXF86DRIDestroyDrawableReq
*req
;
443 TRACE("DestroyDrawable...");
444 uniDRICheckExtension(dpy
, info
, False
);
447 GetReq(XF86DRIDestroyDrawable
, req
);
448 req
->reqType
= info
->codes
->major_opcode
;
449 req
->driReqType
= X_XF86DRIDestroyDrawable
;
450 req
->screen
= screen
;
451 req
->drawable
= drawable
;
454 TRACE("DestroyDrawable... return True");
459 uniDRIGetDrawableInfo(Display
* dpy
, int screen
, Drawable drawable
,
460 unsigned int *index
, unsigned int *stamp
,
461 int *X
, int *Y
, int *W
, int *H
,
462 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
463 int *backX
, int *backY
,
464 int *numBackClipRects
,
465 drm_clip_rect_t
** pBackClipRects
)
467 XExtDisplayInfo
*info
= find_display(dpy
);
468 xXF86DRIGetDrawableInfoReply rep
;
469 xXF86DRIGetDrawableInfoReq
*req
;
472 TRACE("GetDrawableInfo...");
473 uniDRICheckExtension(dpy
, info
, False
);
476 GetReq(XF86DRIGetDrawableInfo
, req
);
477 req
->reqType
= info
->codes
->major_opcode
;
478 req
->driReqType
= X_XF86DRIGetDrawableInfo
;
479 req
->screen
= screen
;
480 req
->drawable
= drawable
;
482 if (!_XReply(dpy
, (xReply
*) & rep
, 1, xFalse
)) {
485 TRACE("GetDrawableInfo... return False");
488 *index
= rep
.drawableTableIndex
;
489 *stamp
= rep
.drawableTableStamp
;
490 *X
= (int)rep
.drawableX
;
491 *Y
= (int)rep
.drawableY
;
492 *W
= (int)rep
.drawableWidth
;
493 *H
= (int)rep
.drawableHeight
;
494 *numClipRects
= rep
.numClipRects
;
495 total_rects
= *numClipRects
;
499 *numBackClipRects
= rep
.numBackClipRects
;
500 total_rects
+= *numBackClipRects
;
503 /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
504 * backwards compatibility (Because of the >> 2 shift) but the fix
505 * enables multi-threaded apps to work.
507 if (rep
.length
!= ((((SIZEOF(xXF86DRIGetDrawableInfoReply
) -
508 SIZEOF(xGenericReply
) +
509 total_rects
* sizeof(drm_clip_rect_t
)) +
511 _XEatData(dpy
, rep
.length
);
514 TRACE("GetDrawableInfo... return False");
520 int len
= sizeof(drm_clip_rect_t
) * (*numClipRects
);
522 *pClipRects
= (drm_clip_rect_t
*) Xcalloc(len
, 1);
524 _XRead(dpy
, (char *)*pClipRects
, len
);
529 if (*numBackClipRects
) {
530 int len
= sizeof(drm_clip_rect_t
) * (*numBackClipRects
);
532 *pBackClipRects
= (drm_clip_rect_t
*) Xcalloc(len
, 1);
534 _XRead(dpy
, (char *)*pBackClipRects
, len
);
536 *pBackClipRects
= NULL
;
541 TRACE("GetDrawableInfo... return True");
546 uniDRIGetDeviceInfo(dpy
, screen
, hFrameBuffer
,
547 fbOrigin
, fbSize
, fbStride
, devPrivateSize
, pDevPrivate
)
550 drm_handle_t
*hFrameBuffer
;
557 XExtDisplayInfo
*info
= find_display(dpy
);
558 xXF86DRIGetDeviceInfoReply rep
;
559 xXF86DRIGetDeviceInfoReq
*req
;
561 TRACE("GetDeviceInfo...");
562 uniDRICheckExtension(dpy
, info
, False
);
565 GetReq(XF86DRIGetDeviceInfo
, req
);
566 req
->reqType
= info
->codes
->major_opcode
;
567 req
->driReqType
= X_XF86DRIGetDeviceInfo
;
568 req
->screen
= screen
;
569 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xFalse
)) {
572 TRACE("GetDeviceInfo... return False");
576 *hFrameBuffer
= rep
.hFrameBufferLow
;
578 if (sizeof(drm_handle_t
) == 8) {
579 *hFrameBuffer
|= ((unsigned long)rep
.hFrameBufferHigh
) << 32;
583 *fbOrigin
= rep
.framebufferOrigin
;
584 *fbSize
= rep
.framebufferSize
;
585 *fbStride
= rep
.framebufferStride
;
586 *devPrivateSize
= rep
.devPrivateSize
;
589 if (!(*pDevPrivate
= (void *)Xcalloc(rep
.devPrivateSize
, 1))) {
590 _XEatData(dpy
, ((rep
.devPrivateSize
+ 3) & ~3));
593 TRACE("GetDeviceInfo... return False");
596 _XRead(dpy
, (char *)*pDevPrivate
, rep
.devPrivateSize
);
603 TRACE("GetDeviceInfo... return True");