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");
593
PUBLIC Bool XF86DRIOpenFullScreen(dpy, screen, drawable)
598
/* This function and the underlying X protocol are deprecated.
606
PUBLIC Bool XF86DRICloseFullScreen(dpy, screen, drawable)
611
/* This function and the underlying X protocol are deprecated.