Remove CVS keywords.
[mesa.git] / src / glx / x11 / XF86dri.c
1 /**************************************************************************
2
3 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4 Copyright 2000 VA Linux Systems, Inc.
5 All Rights Reserved.
6
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:
14
15 The above copyright notice and this permission notice (including the
16 next paragraph) shall be included in all copies or substantial portions
17 of the Software.
18
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.
26
27 **************************************************************************/
28
29 /*
30 * Authors:
31 * Kevin E. Martin <martin@valinux.com>
32 * Jens Owen <jens@tungstengraphics.com>
33 * Rickard E. (Rik) Faith <faith@valinux.com>
34 *
35 */
36
37 /* THIS IS NOT AN X CONSORTIUM STANDARD */
38
39 #ifdef GLX_DIRECT_RENDERING
40
41 #define NEED_REPLIES
42 #include <X11/Xlibint.h>
43 #include <X11/extensions/Xext.h>
44 #include <X11/extensions/extutil.h>
45 #include "glheader.h"
46 #include "xf86dristr.h"
47
48 static XExtensionInfo _xf86dri_info_data;
49 static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
50 static char xf86dri_extension_name[] = XF86DRINAME;
51
52 #define XF86DRICheckExtension(dpy,i,val) \
53 XextCheckExtension (dpy, i, xf86dri_extension_name, val)
54
55 /*****************************************************************************
56 * *
57 * private utility routines *
58 * *
59 *****************************************************************************/
60
61 static int close_display(Display *dpy, XExtCodes *extCodes);
62 static /* const */ XExtensionHooks xf86dri_extension_hooks = {
63 NULL, /* create_gc */
64 NULL, /* copy_gc */
65 NULL, /* flush_gc */
66 NULL, /* free_gc */
67 NULL, /* create_font */
68 NULL, /* free_font */
69 close_display, /* close_display */
70 NULL, /* wire_to_event */
71 NULL, /* event_to_wire */
72 NULL, /* error */
73 NULL, /* error_string */
74 };
75
76 static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86dri_info,
77 xf86dri_extension_name,
78 &xf86dri_extension_hooks,
79 0, NULL)
80
81 static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86dri_info)
82
83
84 /*****************************************************************************
85 * *
86 * public XFree86-DRI Extension routines *
87 * *
88 *****************************************************************************/
89
90 #if 0
91 #include <stdio.h>
92 #define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
93 #else
94 #define TRACE(msg)
95 #endif
96
97
98 PUBLIC Bool XF86DRIQueryExtension (dpy, event_basep, error_basep)
99 Display *dpy;
100 int *event_basep, *error_basep;
101 {
102 XExtDisplayInfo *info = find_display (dpy);
103
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");
109 return True;
110 } else {
111 TRACE("QueryExtension... return False");
112 return False;
113 }
114 }
115
116 PUBLIC Bool XF86DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
117 Display* dpy;
118 int* majorVersion;
119 int* minorVersion;
120 int* patchVersion;
121 {
122 XExtDisplayInfo *info = find_display (dpy);
123 xXF86DRIQueryVersionReply rep;
124 xXF86DRIQueryVersionReq *req;
125
126 TRACE("QueryVersion...");
127 XF86DRICheckExtension (dpy, info, False);
128
129 LockDisplay(dpy);
130 GetReq(XF86DRIQueryVersion, req);
131 req->reqType = info->codes->major_opcode;
132 req->driReqType = X_XF86DRIQueryVersion;
133 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
134 UnlockDisplay(dpy);
135 SyncHandle();
136 TRACE("QueryVersion... return False");
137 return False;
138 }
139 *majorVersion = rep.majorVersion;
140 *minorVersion = rep.minorVersion;
141 *patchVersion = rep.patchVersion;
142 UnlockDisplay(dpy);
143 SyncHandle();
144 TRACE("QueryVersion... return True");
145 return True;
146 }
147
148 PUBLIC Bool XF86DRIQueryDirectRenderingCapable(dpy, screen, isCapable)
149 Display* dpy;
150 int screen;
151 Bool* isCapable;
152 {
153 XExtDisplayInfo *info = find_display (dpy);
154 xXF86DRIQueryDirectRenderingCapableReply rep;
155 xXF86DRIQueryDirectRenderingCapableReq *req;
156
157 TRACE("QueryDirectRenderingCapable...");
158 XF86DRICheckExtension (dpy, info, False);
159
160 LockDisplay(dpy);
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)) {
166 UnlockDisplay(dpy);
167 SyncHandle();
168 TRACE("QueryDirectRenderingCapable... return False");
169 return False;
170 }
171 *isCapable = rep.isCapable;
172 UnlockDisplay(dpy);
173 SyncHandle();
174 TRACE("QueryDirectRenderingCapable... return True");
175 return True;
176 }
177
178 PUBLIC Bool XF86DRIOpenConnection(dpy, screen, hSAREA, busIdString)
179 Display* dpy;
180 int screen;
181 drm_handle_t * hSAREA;
182 char **busIdString;
183 {
184 XExtDisplayInfo *info = find_display (dpy);
185 xXF86DRIOpenConnectionReply rep;
186 xXF86DRIOpenConnectionReq *req;
187
188 TRACE("OpenConnection...");
189 XF86DRICheckExtension (dpy, info, False);
190
191 LockDisplay(dpy);
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)) {
197 UnlockDisplay(dpy);
198 SyncHandle();
199 TRACE("OpenConnection... return False");
200 return False;
201 }
202
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;
207 }
208
209 if (rep.length) {
210 if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {
211 _XEatData(dpy, ((rep.busIdStringLength+3) & ~3));
212 UnlockDisplay(dpy);
213 SyncHandle();
214 TRACE("OpenConnection... return False");
215 return False;
216 }
217 _XReadPad(dpy, *busIdString, rep.busIdStringLength);
218 } else {
219 *busIdString = NULL;
220 }
221 UnlockDisplay(dpy);
222 SyncHandle();
223 TRACE("OpenConnection... return True");
224 return True;
225 }
226
227 PUBLIC Bool XF86DRIAuthConnection(dpy, screen, magic)
228 Display* dpy;
229 int screen;
230 drm_magic_t magic;
231 {
232 XExtDisplayInfo *info = find_display (dpy);
233 xXF86DRIAuthConnectionReq *req;
234 xXF86DRIAuthConnectionReply rep;
235
236 TRACE("AuthConnection...");
237 XF86DRICheckExtension (dpy, info, False);
238
239 LockDisplay(dpy);
240 GetReq(XF86DRIAuthConnection, req);
241 req->reqType = info->codes->major_opcode;
242 req->driReqType = X_XF86DRIAuthConnection;
243 req->screen = screen;
244 req->magic = magic;
245 rep.authenticated = 0;
246 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.authenticated) {
247 UnlockDisplay(dpy);
248 SyncHandle();
249 TRACE("AuthConnection... return False");
250 return False;
251 }
252 UnlockDisplay(dpy);
253 SyncHandle();
254 TRACE("AuthConnection... return True");
255 return True;
256 }
257
258 PUBLIC Bool XF86DRICloseConnection(dpy, screen)
259 Display* dpy;
260 int screen;
261 {
262 XExtDisplayInfo *info = find_display (dpy);
263 xXF86DRICloseConnectionReq *req;
264
265 TRACE("CloseConnection...");
266
267 XF86DRICheckExtension (dpy, info, False);
268
269 LockDisplay(dpy);
270 GetReq(XF86DRICloseConnection, req);
271 req->reqType = info->codes->major_opcode;
272 req->driReqType = X_XF86DRICloseConnection;
273 req->screen = screen;
274 UnlockDisplay(dpy);
275 SyncHandle();
276 TRACE("CloseConnection... return True");
277 return True;
278 }
279
280 PUBLIC Bool XF86DRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
281 ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName)
282 Display* dpy;
283 int screen;
284 int* ddxDriverMajorVersion;
285 int* ddxDriverMinorVersion;
286 int* ddxDriverPatchVersion;
287 char** clientDriverName;
288 {
289 XExtDisplayInfo *info = find_display (dpy);
290 xXF86DRIGetClientDriverNameReply rep;
291 xXF86DRIGetClientDriverNameReq *req;
292
293 TRACE("GetClientDriverName...");
294 XF86DRICheckExtension (dpy, info, False);
295
296 LockDisplay(dpy);
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)) {
302 UnlockDisplay(dpy);
303 SyncHandle();
304 TRACE("GetClientDriverName... return False");
305 return False;
306 }
307
308 *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
309 *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
310 *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
311
312 if (rep.length) {
313 if (!(*clientDriverName = (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
314 _XEatData(dpy, ((rep.clientDriverNameLength+3) & ~3));
315 UnlockDisplay(dpy);
316 SyncHandle();
317 TRACE("GetClientDriverName... return False");
318 return False;
319 }
320 _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
321 } else {
322 *clientDriverName = NULL;
323 }
324 UnlockDisplay(dpy);
325 SyncHandle();
326 TRACE("GetClientDriverName... return True");
327 return True;
328 }
329
330 PUBLIC Bool XF86DRICreateContextWithConfig(dpy, screen, configID, context,
331 hHWContext)
332 Display* dpy;
333 int screen;
334 int configID;
335 XID* context;
336 drm_context_t * hHWContext;
337 {
338 XExtDisplayInfo *info = find_display (dpy);
339 xXF86DRICreateContextReply rep;
340 xXF86DRICreateContextReq *req;
341
342 TRACE("CreateContext...");
343 XF86DRICheckExtension (dpy, info, False);
344
345 LockDisplay(dpy);
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)) {
354 UnlockDisplay(dpy);
355 SyncHandle();
356 TRACE("CreateContext... return False");
357 return False;
358 }
359 *hHWContext = rep.hHWContext;
360 UnlockDisplay(dpy);
361 SyncHandle();
362 TRACE("CreateContext... return True");
363 return True;
364 }
365
366 PUBLIC Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext)
367 Display* dpy;
368 int screen;
369 Visual* visual;
370 XID* context;
371 drm_context_t * hHWContext;
372 {
373 return XF86DRICreateContextWithConfig( dpy, screen, visual->visualid,
374 context, hHWContext );
375 }
376
377 PUBLIC GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen,
378 __DRIid context )
379 {
380 Display * const dpy = (Display *) ndpy;
381 XExtDisplayInfo *info = find_display (dpy);
382 xXF86DRIDestroyContextReq *req;
383
384 TRACE("DestroyContext...");
385 XF86DRICheckExtension (dpy, info, False);
386
387 LockDisplay(dpy);
388 GetReq(XF86DRIDestroyContext, req);
389 req->reqType = info->codes->major_opcode;
390 req->driReqType = X_XF86DRIDestroyContext;
391 req->screen = screen;
392 req->context = context;
393 UnlockDisplay(dpy);
394 SyncHandle();
395 TRACE("DestroyContext... return True");
396 return True;
397 }
398
399 PUBLIC GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen,
400 __DRIid drawable, drm_drawable_t * hHWDrawable )
401 {
402 Display * const dpy = (Display *) ndpy;
403 XExtDisplayInfo *info = find_display (dpy);
404 xXF86DRICreateDrawableReply rep;
405 xXF86DRICreateDrawableReq *req;
406
407 TRACE("CreateDrawable...");
408 XF86DRICheckExtension (dpy, info, False);
409
410 LockDisplay(dpy);
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)) {
417 UnlockDisplay(dpy);
418 SyncHandle();
419 TRACE("CreateDrawable... return False");
420 return False;
421 }
422 *hHWDrawable = rep.hHWDrawable;
423 UnlockDisplay(dpy);
424 SyncHandle();
425 TRACE("CreateDrawable... return True");
426 return True;
427 }
428
429 PUBLIC GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen,
430 __DRIid drawable )
431 {
432 Display * const dpy = (Display *) ndpy;
433 XExtDisplayInfo *info = find_display (dpy);
434 xXF86DRIDestroyDrawableReq *req;
435
436 TRACE("DestroyDrawable...");
437 XF86DRICheckExtension (dpy, info, False);
438
439 LockDisplay(dpy);
440 GetReq(XF86DRIDestroyDrawable, req);
441 req->reqType = info->codes->major_opcode;
442 req->driReqType = X_XF86DRIDestroyDrawable;
443 req->screen = screen;
444 req->drawable = drawable;
445 UnlockDisplay(dpy);
446 SyncHandle();
447 TRACE("DestroyDrawable... return True");
448 return True;
449 }
450
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 )
457 {
458 XExtDisplayInfo *info = find_display (dpy);
459 xXF86DRIGetDrawableInfoReply rep;
460 xXF86DRIGetDrawableInfoReq *req;
461 int total_rects;
462
463 TRACE("GetDrawableInfo...");
464 XF86DRICheckExtension (dpy, info, False);
465
466 LockDisplay(dpy);
467 GetReq(XF86DRIGetDrawableInfo, req);
468 req->reqType = info->codes->major_opcode;
469 req->driReqType = X_XF86DRIGetDrawableInfo;
470 req->screen = screen;
471 req->drawable = drawable;
472
473 if (!_XReply(dpy, (xReply *)&rep, 1, xFalse))
474 {
475 UnlockDisplay(dpy);
476 SyncHandle();
477 TRACE("GetDrawableInfo... return False");
478 return False;
479 }
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;
488
489 *backX = rep.backX;
490 *backY = rep.backY;
491 *numBackClipRects = rep.numBackClipRects;
492 total_rects += *numBackClipRects;
493
494 #if 0
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.
498 */
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);
503 UnlockDisplay(dpy);
504 SyncHandle();
505 TRACE("GetDrawableInfo... return False");
506 return False;
507 }
508 #endif
509
510 if (*numClipRects) {
511 int len = sizeof(drm_clip_rect_t) * (*numClipRects);
512
513 *pClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
514 if (*pClipRects)
515 _XRead(dpy, (char*)*pClipRects, len);
516 } else {
517 *pClipRects = NULL;
518 }
519
520 if (*numBackClipRects) {
521 int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
522
523 *pBackClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
524 if (*pBackClipRects)
525 _XRead(dpy, (char*)*pBackClipRects, len);
526 } else {
527 *pBackClipRects = NULL;
528 }
529
530 UnlockDisplay(dpy);
531 SyncHandle();
532 TRACE("GetDrawableInfo... return True");
533 return True;
534 }
535
536 PUBLIC Bool XF86DRIGetDeviceInfo(dpy, screen, hFrameBuffer,
537 fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate)
538 Display* dpy;
539 int screen;
540 drm_handle_t * hFrameBuffer;
541 int* fbOrigin;
542 int* fbSize;
543 int* fbStride;
544 int* devPrivateSize;
545 void** pDevPrivate;
546 {
547 XExtDisplayInfo *info = find_display (dpy);
548 xXF86DRIGetDeviceInfoReply rep;
549 xXF86DRIGetDeviceInfoReq *req;
550
551 TRACE("GetDeviceInfo...");
552 XF86DRICheckExtension (dpy, info, False);
553
554 LockDisplay(dpy);
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)) {
560 UnlockDisplay(dpy);
561 SyncHandle();
562 TRACE("GetDeviceInfo... return False");
563 return False;
564 }
565
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;
570 }
571
572 *fbOrigin = rep.framebufferOrigin;
573 *fbSize = rep.framebufferSize;
574 *fbStride = rep.framebufferStride;
575 *devPrivateSize = rep.devPrivateSize;
576
577 if (rep.length) {
578 if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
579 _XEatData(dpy, ((rep.devPrivateSize+3) & ~3));
580 UnlockDisplay(dpy);
581 SyncHandle();
582 TRACE("GetDeviceInfo... return False");
583 return False;
584 }
585 _XRead(dpy, (char*)*pDevPrivate, rep.devPrivateSize);
586 } else {
587 *pDevPrivate = NULL;
588 }
589
590 UnlockDisplay(dpy);
591 SyncHandle();
592 TRACE("GetDeviceInfo... return True");
593 return True;
594 }
595
596 PUBLIC Bool XF86DRIOpenFullScreen(dpy, screen, drawable)
597 Display* dpy;
598 int screen;
599 Drawable drawable;
600 {
601 /* This function and the underlying X protocol are deprecated.
602 */
603 (void) dpy;
604 (void) screen;
605 (void) drawable;
606 return False;
607 }
608
609 PUBLIC Bool XF86DRICloseFullScreen(dpy, screen, drawable)
610 Display* dpy;
611 int screen;
612 Drawable drawable;
613 {
614 /* This function and the underlying X protocol are deprecated.
615 */
616 (void) dpy;
617 (void) screen;
618 (void) drawable;
619 return True;
620 }
621
622 #endif /* GLX_DIRECT_RENDERING */