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 #ifdef GLX_DIRECT_RENDERING
42 #include <X11/Xlibint.h>
43 #include <X11/extensions/Xext.h>
44 #include <X11/extensions/extutil.h>
46 #include "xf86dristr.h"
48 static XExtensionInfo _xf86dri_info_data
;
49 static XExtensionInfo
*xf86dri_info
= &_xf86dri_info_data
;
50 static char xf86dri_extension_name
[] = XF86DRINAME
;
52 #define XF86DRICheckExtension(dpy,i,val) \
53 XextCheckExtension (dpy, i, xf86dri_extension_name, val)
55 /*****************************************************************************
57 * private utility routines *
59 *****************************************************************************/
61 static int close_display(Display
*dpy
, XExtCodes
*extCodes
);
62 static /* const */ XExtensionHooks xf86dri_extension_hooks
= {
67 NULL
, /* create_font */
69 close_display
, /* close_display */
70 NULL
, /* wire_to_event */
71 NULL
, /* event_to_wire */
73 NULL
, /* error_string */
76 static XEXT_GENERATE_FIND_DISPLAY (find_display
, xf86dri_info
,
77 xf86dri_extension_name
,
78 &xf86dri_extension_hooks
,
81 static XEXT_GENERATE_CLOSE_DISPLAY (close_display
, xf86dri_info
)
84 /*****************************************************************************
86 * public XFree86-DRI Extension routines *
88 *****************************************************************************/
92 #define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
98 PUBLIC Bool
XF86DRIQueryExtension (dpy
, event_basep
, error_basep
)
100 int *event_basep
, *error_basep
;
102 XExtDisplayInfo
*info
= find_display (dpy
);
104 TRACE("QueryExtension...");
105 if (XextHasExtension(info
)) {
106 *event_basep
= info
->codes
->first_event
;
107 *error_basep
= info
->codes
->first_error
;
108 TRACE("QueryExtension... return True");
111 TRACE("QueryExtension... return False");
116 PUBLIC Bool
XF86DRIQueryVersion(dpy
, majorVersion
, minorVersion
, patchVersion
)
122 XExtDisplayInfo
*info
= find_display (dpy
);
123 xXF86DRIQueryVersionReply rep
;
124 xXF86DRIQueryVersionReq
*req
;
126 TRACE("QueryVersion...");
127 XF86DRICheckExtension (dpy
, info
, False
);
130 GetReq(XF86DRIQueryVersion
, req
);
131 req
->reqType
= info
->codes
->major_opcode
;
132 req
->driReqType
= X_XF86DRIQueryVersion
;
133 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
)) {
136 TRACE("QueryVersion... return False");
139 *majorVersion
= rep
.majorVersion
;
140 *minorVersion
= rep
.minorVersion
;
141 *patchVersion
= rep
.patchVersion
;
144 TRACE("QueryVersion... return True");
148 PUBLIC Bool
XF86DRIQueryDirectRenderingCapable(dpy
, screen
, isCapable
)
153 XExtDisplayInfo
*info
= find_display (dpy
);
154 xXF86DRIQueryDirectRenderingCapableReply rep
;
155 xXF86DRIQueryDirectRenderingCapableReq
*req
;
157 TRACE("QueryDirectRenderingCapable...");
158 XF86DRICheckExtension (dpy
, info
, False
);
161 GetReq(XF86DRIQueryDirectRenderingCapable
, req
);
162 req
->reqType
= info
->codes
->major_opcode
;
163 req
->driReqType
= X_XF86DRIQueryDirectRenderingCapable
;
164 req
->screen
= screen
;
165 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
)) {
168 TRACE("QueryDirectRenderingCapable... return False");
171 *isCapable
= rep
.isCapable
;
174 TRACE("QueryDirectRenderingCapable... return True");
178 PUBLIC Bool
XF86DRIOpenConnection(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 XF86DRICheckExtension (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
;
204 if (sizeof(drm_handle_t
) == 8) {
205 int shift
= 32; /* var to prevent warning on next line */
206 *hSAREA
|= ((drm_handle_t
) rep
.hSAREAHigh
) << shift
;
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");
227 PUBLIC Bool
XF86DRIAuthConnection(dpy
, screen
, magic
)
232 XExtDisplayInfo
*info
= find_display (dpy
);
233 xXF86DRIAuthConnectionReq
*req
;
234 xXF86DRIAuthConnectionReply rep
;
236 TRACE("AuthConnection...");
237 XF86DRICheckExtension (dpy
, info
, False
);
240 GetReq(XF86DRIAuthConnection
, req
);
241 req
->reqType
= info
->codes
->major_opcode
;
242 req
->driReqType
= X_XF86DRIAuthConnection
;
243 req
->screen
= screen
;
245 rep
.authenticated
= 0;
246 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
) || !rep
.authenticated
) {
249 TRACE("AuthConnection... return False");
254 TRACE("AuthConnection... return True");
258 PUBLIC Bool
XF86DRICloseConnection(dpy
, screen
)
262 XExtDisplayInfo
*info
= find_display (dpy
);
263 xXF86DRICloseConnectionReq
*req
;
265 TRACE("CloseConnection...");
267 XF86DRICheckExtension (dpy
, info
, False
);
270 GetReq(XF86DRICloseConnection
, req
);
271 req
->reqType
= info
->codes
->major_opcode
;
272 req
->driReqType
= X_XF86DRICloseConnection
;
273 req
->screen
= screen
;
276 TRACE("CloseConnection... return True");
280 PUBLIC Bool
XF86DRIGetClientDriverName(dpy
, screen
, ddxDriverMajorVersion
,
281 ddxDriverMinorVersion
, ddxDriverPatchVersion
, clientDriverName
)
284 int* ddxDriverMajorVersion
;
285 int* ddxDriverMinorVersion
;
286 int* ddxDriverPatchVersion
;
287 char** clientDriverName
;
289 XExtDisplayInfo
*info
= find_display (dpy
);
290 xXF86DRIGetClientDriverNameReply rep
;
291 xXF86DRIGetClientDriverNameReq
*req
;
293 TRACE("GetClientDriverName...");
294 XF86DRICheckExtension (dpy
, info
, False
);
297 GetReq(XF86DRIGetClientDriverName
, req
);
298 req
->reqType
= info
->codes
->major_opcode
;
299 req
->driReqType
= X_XF86DRIGetClientDriverName
;
300 req
->screen
= screen
;
301 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
)) {
304 TRACE("GetClientDriverName... return False");
308 *ddxDriverMajorVersion
= rep
.ddxDriverMajorVersion
;
309 *ddxDriverMinorVersion
= rep
.ddxDriverMinorVersion
;
310 *ddxDriverPatchVersion
= rep
.ddxDriverPatchVersion
;
313 if (!(*clientDriverName
= (char *)Xcalloc(rep
.clientDriverNameLength
+ 1, 1))) {
314 _XEatData(dpy
, ((rep
.clientDriverNameLength
+3) & ~3));
317 TRACE("GetClientDriverName... return False");
320 _XReadPad(dpy
, *clientDriverName
, rep
.clientDriverNameLength
);
322 *clientDriverName
= NULL
;
326 TRACE("GetClientDriverName... return True");
330 PUBLIC Bool
XF86DRICreateContextWithConfig(dpy
, screen
, configID
, context
,
336 drm_context_t
* hHWContext
;
338 XExtDisplayInfo
*info
= find_display (dpy
);
339 xXF86DRICreateContextReply rep
;
340 xXF86DRICreateContextReq
*req
;
342 TRACE("CreateContext...");
343 XF86DRICheckExtension (dpy
, info
, False
);
346 GetReq(XF86DRICreateContext
, req
);
347 req
->reqType
= info
->codes
->major_opcode
;
348 req
->driReqType
= X_XF86DRICreateContext
;
349 req
->visual
= configID
;
350 req
->screen
= screen
;
351 *context
= XAllocID(dpy
);
352 req
->context
= *context
;
353 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
)) {
356 TRACE("CreateContext... return False");
359 *hHWContext
= rep
.hHWContext
;
362 TRACE("CreateContext... return True");
366 PUBLIC Bool
XF86DRICreateContext(dpy
, screen
, visual
, context
, hHWContext
)
371 drm_context_t
* hHWContext
;
373 return XF86DRICreateContextWithConfig( dpy
, screen
, visual
->visualid
,
374 context
, hHWContext
);
377 PUBLIC GLboolean
XF86DRIDestroyContext( __DRInativeDisplay
* ndpy
, int screen
,
380 Display
* const dpy
= (Display
*) ndpy
;
381 XExtDisplayInfo
*info
= find_display (dpy
);
382 xXF86DRIDestroyContextReq
*req
;
384 TRACE("DestroyContext...");
385 XF86DRICheckExtension (dpy
, info
, False
);
388 GetReq(XF86DRIDestroyContext
, req
);
389 req
->reqType
= info
->codes
->major_opcode
;
390 req
->driReqType
= X_XF86DRIDestroyContext
;
391 req
->screen
= screen
;
392 req
->context
= context
;
395 TRACE("DestroyContext... return True");
399 PUBLIC GLboolean
XF86DRICreateDrawable( __DRInativeDisplay
* ndpy
, int screen
,
400 __DRIid drawable
, drm_drawable_t
* hHWDrawable
)
402 Display
* const dpy
= (Display
*) ndpy
;
403 XExtDisplayInfo
*info
= find_display (dpy
);
404 xXF86DRICreateDrawableReply rep
;
405 xXF86DRICreateDrawableReq
*req
;
407 TRACE("CreateDrawable...");
408 XF86DRICheckExtension (dpy
, info
, False
);
411 GetReq(XF86DRICreateDrawable
, req
);
412 req
->reqType
= info
->codes
->major_opcode
;
413 req
->driReqType
= X_XF86DRICreateDrawable
;
414 req
->screen
= screen
;
415 req
->drawable
= drawable
;
416 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
)) {
419 TRACE("CreateDrawable... return False");
422 *hHWDrawable
= rep
.hHWDrawable
;
425 TRACE("CreateDrawable... return True");
429 PUBLIC GLboolean
XF86DRIDestroyDrawable( __DRInativeDisplay
* ndpy
, int screen
,
432 Display
* const dpy
= (Display
*) ndpy
;
433 XExtDisplayInfo
*info
= find_display (dpy
);
434 xXF86DRIDestroyDrawableReq
*req
;
436 TRACE("DestroyDrawable...");
437 XF86DRICheckExtension (dpy
, info
, False
);
440 GetReq(XF86DRIDestroyDrawable
, req
);
441 req
->reqType
= info
->codes
->major_opcode
;
442 req
->driReqType
= X_XF86DRIDestroyDrawable
;
443 req
->screen
= screen
;
444 req
->drawable
= drawable
;
447 TRACE("DestroyDrawable... return True");
451 PUBLIC Bool
XF86DRIGetDrawableInfo(Display
* dpy
, int screen
, Drawable drawable
,
452 unsigned int* index
, unsigned int* stamp
,
453 int* X
, int* Y
, int* W
, int* H
,
454 int* numClipRects
, drm_clip_rect_t
** pClipRects
,
455 int* backX
, int* backY
,
456 int* numBackClipRects
, drm_clip_rect_t
** pBackClipRects
)
458 XExtDisplayInfo
*info
= find_display (dpy
);
459 xXF86DRIGetDrawableInfoReply rep
;
460 xXF86DRIGetDrawableInfoReq
*req
;
463 TRACE("GetDrawableInfo...");
464 XF86DRICheckExtension (dpy
, info
, False
);
467 GetReq(XF86DRIGetDrawableInfo
, req
);
468 req
->reqType
= info
->codes
->major_opcode
;
469 req
->driReqType
= X_XF86DRIGetDrawableInfo
;
470 req
->screen
= screen
;
471 req
->drawable
= drawable
;
473 if (!_XReply(dpy
, (xReply
*)&rep
, 1, xFalse
))
477 TRACE("GetDrawableInfo... return False");
480 *index
= rep
.drawableTableIndex
;
481 *stamp
= rep
.drawableTableStamp
;
482 *X
= (int)rep
.drawableX
;
483 *Y
= (int)rep
.drawableY
;
484 *W
= (int)rep
.drawableWidth
;
485 *H
= (int)rep
.drawableHeight
;
486 *numClipRects
= rep
.numClipRects
;
487 total_rects
= *numClipRects
;
491 *numBackClipRects
= rep
.numBackClipRects
;
492 total_rects
+= *numBackClipRects
;
495 /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
496 * backwards compatibility (Because of the >> 2 shift) but the fix
497 * enables multi-threaded apps to work.
499 if (rep
.length
!= ((((SIZEOF(xXF86DRIGetDrawableInfoReply
) -
500 SIZEOF(xGenericReply
) +
501 total_rects
* sizeof(drm_clip_rect_t
)) + 3) & ~3) >> 2)) {
502 _XEatData(dpy
, rep
.length
);
505 TRACE("GetDrawableInfo... return False");
511 int len
= sizeof(drm_clip_rect_t
) * (*numClipRects
);
513 *pClipRects
= (drm_clip_rect_t
*)Xcalloc(len
, 1);
515 _XRead(dpy
, (char*)*pClipRects
, len
);
520 if (*numBackClipRects
) {
521 int len
= sizeof(drm_clip_rect_t
) * (*numBackClipRects
);
523 *pBackClipRects
= (drm_clip_rect_t
*)Xcalloc(len
, 1);
525 _XRead(dpy
, (char*)*pBackClipRects
, len
);
527 *pBackClipRects
= NULL
;
532 TRACE("GetDrawableInfo... return True");
536 PUBLIC Bool
XF86DRIGetDeviceInfo(dpy
, screen
, hFrameBuffer
,
537 fbOrigin
, fbSize
, fbStride
, devPrivateSize
, pDevPrivate
)
540 drm_handle_t
* hFrameBuffer
;
547 XExtDisplayInfo
*info
= find_display (dpy
);
548 xXF86DRIGetDeviceInfoReply rep
;
549 xXF86DRIGetDeviceInfoReq
*req
;
551 TRACE("GetDeviceInfo...");
552 XF86DRICheckExtension (dpy
, info
, False
);
555 GetReq(XF86DRIGetDeviceInfo
, req
);
556 req
->reqType
= info
->codes
->major_opcode
;
557 req
->driReqType
= X_XF86DRIGetDeviceInfo
;
558 req
->screen
= screen
;
559 if (!_XReply(dpy
, (xReply
*)&rep
, 0, xFalse
)) {
562 TRACE("GetDeviceInfo... return False");
566 *hFrameBuffer
= rep
.hFrameBufferLow
;
567 if (sizeof(drm_handle_t
) == 8) {
568 int shift
= 32; /* var to prevent warning on next line */
569 *hFrameBuffer
|= ((drm_handle_t
) rep
.hFrameBufferHigh
) << shift
;
572 *fbOrigin
= rep
.framebufferOrigin
;
573 *fbSize
= rep
.framebufferSize
;
574 *fbStride
= rep
.framebufferStride
;
575 *devPrivateSize
= rep
.devPrivateSize
;
578 if (!(*pDevPrivate
= (void *)Xcalloc(rep
.devPrivateSize
, 1))) {
579 _XEatData(dpy
, ((rep
.devPrivateSize
+3) & ~3));
582 TRACE("GetDeviceInfo... return False");
585 _XRead(dpy
, (char*)*pDevPrivate
, rep
.devPrivateSize
);
592 TRACE("GetDeviceInfo... return True");
596 PUBLIC Bool
XF86DRIOpenFullScreen(dpy
, screen
, drawable
)
601 /* This function and the underlying X protocol are deprecated.
609 PUBLIC Bool
XF86DRICloseFullScreen(dpy
, screen
, drawable
)
614 /* This function and the underlying X protocol are deprecated.
622 #endif /* GLX_DIRECT_RENDERING */