Merge branch 'master' into pipe-video
[mesa.git] / src / gallium / winsys / g3dvl / dri / 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 #include <X11/Xlibint.h>
40 #include <X11/extensions/Xext.h>
41 #include <X11/extensions/extutil.h>
42 #include "xf86dristr.h"
43
44 static XExtensionInfo _xf86dri_info_data;
45 static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
46 static char xf86dri_extension_name[] = XF86DRINAME;
47
48 #define XF86DRICheckExtension(dpy,i,val) \
49 XextCheckExtension (dpy, i, xf86dri_extension_name, val)
50
51 /*****************************************************************************
52 * *
53 * private utility routines *
54 * *
55 *****************************************************************************/
56
57 static int close_display(Display *dpy, XExtCodes *extCodes);
58 static /* const */ XExtensionHooks xf86dri_extension_hooks = {
59 NULL, /* create_gc */
60 NULL, /* copy_gc */
61 NULL, /* flush_gc */
62 NULL, /* free_gc */
63 NULL, /* create_font */
64 NULL, /* free_font */
65 close_display, /* close_display */
66 NULL, /* wire_to_event */
67 NULL, /* event_to_wire */
68 NULL, /* error */
69 NULL, /* error_string */
70 };
71
72 static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86dri_info,
73 xf86dri_extension_name,
74 &xf86dri_extension_hooks,
75 0, NULL)
76
77 static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86dri_info)
78
79
80 /*****************************************************************************
81 * *
82 * public XFree86-DRI Extension routines *
83 * *
84 *****************************************************************************/
85
86 #if 0
87 #include <stdio.h>
88 #define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
89 #else
90 #define TRACE(msg)
91 #endif
92
93 #define PUBLIC
94
95 PUBLIC Bool XF86DRIQueryExtension (dpy, event_basep, error_basep)
96 Display *dpy;
97 int *event_basep, *error_basep;
98 {
99 XExtDisplayInfo *info = find_display (dpy);
100
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");
106 return True;
107 } else {
108 TRACE("QueryExtension... return False");
109 return False;
110 }
111 }
112
113 PUBLIC Bool XF86DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
114 Display* dpy;
115 int* majorVersion;
116 int* minorVersion;
117 int* patchVersion;
118 {
119 XExtDisplayInfo *info = find_display (dpy);
120 xXF86DRIQueryVersionReply rep;
121 xXF86DRIQueryVersionReq *req;
122
123 TRACE("QueryVersion...");
124 XF86DRICheckExtension (dpy, info, False);
125
126 LockDisplay(dpy);
127 GetReq(XF86DRIQueryVersion, req);
128 req->reqType = info->codes->major_opcode;
129 req->driReqType = X_XF86DRIQueryVersion;
130 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
131 UnlockDisplay(dpy);
132 SyncHandle();
133 TRACE("QueryVersion... return False");
134 return False;
135 }
136 *majorVersion = rep.majorVersion;
137 *minorVersion = rep.minorVersion;
138 *patchVersion = rep.patchVersion;
139 UnlockDisplay(dpy);
140 SyncHandle();
141 TRACE("QueryVersion... return True");
142 return True;
143 }
144
145 PUBLIC Bool XF86DRIQueryDirectRenderingCapable(dpy, screen, isCapable)
146 Display* dpy;
147 int screen;
148 Bool* isCapable;
149 {
150 XExtDisplayInfo *info = find_display (dpy);
151 xXF86DRIQueryDirectRenderingCapableReply rep;
152 xXF86DRIQueryDirectRenderingCapableReq *req;
153
154 TRACE("QueryDirectRenderingCapable...");
155 XF86DRICheckExtension (dpy, info, False);
156
157 LockDisplay(dpy);
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)) {
163 UnlockDisplay(dpy);
164 SyncHandle();
165 TRACE("QueryDirectRenderingCapable... return False");
166 return False;
167 }
168 *isCapable = rep.isCapable;
169 UnlockDisplay(dpy);
170 SyncHandle();
171 TRACE("QueryDirectRenderingCapable... return True");
172 return True;
173 }
174
175 PUBLIC Bool XF86DRIOpenConnection(dpy, screen, hSAREA, busIdString)
176 Display* dpy;
177 int screen;
178 drm_handle_t * hSAREA;
179 char **busIdString;
180 {
181 XExtDisplayInfo *info = find_display (dpy);
182 xXF86DRIOpenConnectionReply rep;
183 xXF86DRIOpenConnectionReq *req;
184
185 TRACE("OpenConnection...");
186 XF86DRICheckExtension (dpy, info, False);
187
188 LockDisplay(dpy);
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)) {
194 UnlockDisplay(dpy);
195 SyncHandle();
196 TRACE("OpenConnection... return False");
197 return False;
198 }
199
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;
204 }
205
206 if (rep.length) {
207 if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {
208 _XEatData(dpy, ((rep.busIdStringLength+3) & ~3));
209 UnlockDisplay(dpy);
210 SyncHandle();
211 TRACE("OpenConnection... return False");
212 return False;
213 }
214 _XReadPad(dpy, *busIdString, rep.busIdStringLength);
215 } else {
216 *busIdString = NULL;
217 }
218 UnlockDisplay(dpy);
219 SyncHandle();
220 TRACE("OpenConnection... return True");
221 return True;
222 }
223
224 PUBLIC Bool XF86DRIAuthConnection(dpy, screen, magic)
225 Display* dpy;
226 int screen;
227 drm_magic_t magic;
228 {
229 XExtDisplayInfo *info = find_display (dpy);
230 xXF86DRIAuthConnectionReq *req;
231 xXF86DRIAuthConnectionReply rep;
232
233 TRACE("AuthConnection...");
234 XF86DRICheckExtension (dpy, info, False);
235
236 LockDisplay(dpy);
237 GetReq(XF86DRIAuthConnection, req);
238 req->reqType = info->codes->major_opcode;
239 req->driReqType = X_XF86DRIAuthConnection;
240 req->screen = screen;
241 req->magic = magic;
242 rep.authenticated = 0;
243 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.authenticated) {
244 UnlockDisplay(dpy);
245 SyncHandle();
246 TRACE("AuthConnection... return False");
247 return False;
248 }
249 UnlockDisplay(dpy);
250 SyncHandle();
251 TRACE("AuthConnection... return True");
252 return True;
253 }
254
255 PUBLIC Bool XF86DRICloseConnection(dpy, screen)
256 Display* dpy;
257 int screen;
258 {
259 XExtDisplayInfo *info = find_display (dpy);
260 xXF86DRICloseConnectionReq *req;
261
262 TRACE("CloseConnection...");
263
264 XF86DRICheckExtension (dpy, info, False);
265
266 LockDisplay(dpy);
267 GetReq(XF86DRICloseConnection, req);
268 req->reqType = info->codes->major_opcode;
269 req->driReqType = X_XF86DRICloseConnection;
270 req->screen = screen;
271 UnlockDisplay(dpy);
272 SyncHandle();
273 TRACE("CloseConnection... return True");
274 return True;
275 }
276
277 PUBLIC Bool XF86DRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
278 ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName)
279 Display* dpy;
280 int screen;
281 int* ddxDriverMajorVersion;
282 int* ddxDriverMinorVersion;
283 int* ddxDriverPatchVersion;
284 char** clientDriverName;
285 {
286 XExtDisplayInfo *info = find_display (dpy);
287 xXF86DRIGetClientDriverNameReply rep;
288 xXF86DRIGetClientDriverNameReq *req;
289
290 TRACE("GetClientDriverName...");
291 XF86DRICheckExtension (dpy, info, False);
292
293 LockDisplay(dpy);
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)) {
299 UnlockDisplay(dpy);
300 SyncHandle();
301 TRACE("GetClientDriverName... return False");
302 return False;
303 }
304
305 *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
306 *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
307 *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
308
309 if (rep.length) {
310 if (!(*clientDriverName = (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
311 _XEatData(dpy, ((rep.clientDriverNameLength+3) & ~3));
312 UnlockDisplay(dpy);
313 SyncHandle();
314 TRACE("GetClientDriverName... return False");
315 return False;
316 }
317 _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
318 } else {
319 *clientDriverName = NULL;
320 }
321 UnlockDisplay(dpy);
322 SyncHandle();
323 TRACE("GetClientDriverName... return True");
324 return True;
325 }
326
327 PUBLIC Bool XF86DRICreateContextWithConfig(dpy, screen, configID, context,
328 hHWContext)
329 Display* dpy;
330 int screen;
331 int configID;
332 XID* context;
333 drm_context_t * hHWContext;
334 {
335 XExtDisplayInfo *info = find_display (dpy);
336 xXF86DRICreateContextReply rep;
337 xXF86DRICreateContextReq *req;
338
339 TRACE("CreateContext...");
340 XF86DRICheckExtension (dpy, info, False);
341
342 LockDisplay(dpy);
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)) {
351 UnlockDisplay(dpy);
352 SyncHandle();
353 TRACE("CreateContext... return False");
354 return False;
355 }
356 *hHWContext = rep.hHWContext;
357 UnlockDisplay(dpy);
358 SyncHandle();
359 TRACE("CreateContext... return True");
360 return True;
361 }
362
363 PUBLIC Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext)
364 Display* dpy;
365 int screen;
366 Visual* visual;
367 XID* context;
368 drm_context_t * hHWContext;
369 {
370 return XF86DRICreateContextWithConfig( dpy, screen, visual->visualid,
371 context, hHWContext );
372 }
373
374 PUBLIC Bool XF86DRIDestroyContext( Display * ndpy, int screen,
375 XID context )
376 {
377 Display * const dpy = (Display *) ndpy;
378 XExtDisplayInfo *info = find_display (dpy);
379 xXF86DRIDestroyContextReq *req;
380
381 TRACE("DestroyContext...");
382 XF86DRICheckExtension (dpy, info, False);
383
384 LockDisplay(dpy);
385 GetReq(XF86DRIDestroyContext, req);
386 req->reqType = info->codes->major_opcode;
387 req->driReqType = X_XF86DRIDestroyContext;
388 req->screen = screen;
389 req->context = context;
390 UnlockDisplay(dpy);
391 SyncHandle();
392 TRACE("DestroyContext... return True");
393 return True;
394 }
395
396 PUBLIC Bool XF86DRICreateDrawable( Display * ndpy, int screen,
397 Drawable drawable, drm_drawable_t * hHWDrawable )
398 {
399 Display * const dpy = (Display *) ndpy;
400 XExtDisplayInfo *info = find_display (dpy);
401 xXF86DRICreateDrawableReply rep;
402 xXF86DRICreateDrawableReq *req;
403
404 TRACE("CreateDrawable...");
405 XF86DRICheckExtension (dpy, info, False);
406
407 LockDisplay(dpy);
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)) {
414 UnlockDisplay(dpy);
415 SyncHandle();
416 TRACE("CreateDrawable... return False");
417 return False;
418 }
419 *hHWDrawable = rep.hHWDrawable;
420 UnlockDisplay(dpy);
421 SyncHandle();
422 TRACE("CreateDrawable... return True");
423 return True;
424 }
425
426 PUBLIC Bool XF86DRIDestroyDrawable( Display * ndpy, int screen,
427 Drawable drawable )
428 {
429 Display * const dpy = (Display *) ndpy;
430 XExtDisplayInfo *info = find_display (dpy);
431 xXF86DRIDestroyDrawableReq *req;
432
433 TRACE("DestroyDrawable...");
434 XF86DRICheckExtension (dpy, info, False);
435
436 LockDisplay(dpy);
437 GetReq(XF86DRIDestroyDrawable, req);
438 req->reqType = info->codes->major_opcode;
439 req->driReqType = X_XF86DRIDestroyDrawable;
440 req->screen = screen;
441 req->drawable = drawable;
442 UnlockDisplay(dpy);
443 SyncHandle();
444 TRACE("DestroyDrawable... return True");
445 return True;
446 }
447
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 )
454 {
455 XExtDisplayInfo *info = find_display (dpy);
456 xXF86DRIGetDrawableInfoReply rep;
457 xXF86DRIGetDrawableInfoReq *req;
458 int total_rects;
459
460 TRACE("GetDrawableInfo...");
461 XF86DRICheckExtension (dpy, info, False);
462
463 LockDisplay(dpy);
464 GetReq(XF86DRIGetDrawableInfo, req);
465 req->reqType = info->codes->major_opcode;
466 req->driReqType = X_XF86DRIGetDrawableInfo;
467 req->screen = screen;
468 req->drawable = drawable;
469
470 if (!_XReply(dpy, (xReply *)&rep, 1, xFalse))
471 {
472 UnlockDisplay(dpy);
473 SyncHandle();
474 TRACE("GetDrawableInfo... return False");
475 return False;
476 }
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;
485
486 *backX = rep.backX;
487 *backY = rep.backY;
488 *numBackClipRects = rep.numBackClipRects;
489 total_rects += *numBackClipRects;
490
491 #if 0
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.
495 */
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);
500 UnlockDisplay(dpy);
501 SyncHandle();
502 TRACE("GetDrawableInfo... return False");
503 return False;
504 }
505 #endif
506
507 if (*numClipRects) {
508 int len = sizeof(drm_clip_rect_t) * (*numClipRects);
509
510 *pClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
511 if (*pClipRects)
512 _XRead(dpy, (char*)*pClipRects, len);
513 } else {
514 *pClipRects = NULL;
515 }
516
517 if (*numBackClipRects) {
518 int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
519
520 *pBackClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
521 if (*pBackClipRects)
522 _XRead(dpy, (char*)*pBackClipRects, len);
523 } else {
524 *pBackClipRects = NULL;
525 }
526
527 UnlockDisplay(dpy);
528 SyncHandle();
529 TRACE("GetDrawableInfo... return True");
530 return True;
531 }
532
533 PUBLIC Bool XF86DRIGetDeviceInfo(dpy, screen, hFrameBuffer,
534 fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate)
535 Display* dpy;
536 int screen;
537 drm_handle_t * hFrameBuffer;
538 int* fbOrigin;
539 int* fbSize;
540 int* fbStride;
541 int* devPrivateSize;
542 void** pDevPrivate;
543 {
544 XExtDisplayInfo *info = find_display (dpy);
545 xXF86DRIGetDeviceInfoReply rep;
546 xXF86DRIGetDeviceInfoReq *req;
547
548 TRACE("GetDeviceInfo...");
549 XF86DRICheckExtension (dpy, info, False);
550
551 LockDisplay(dpy);
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)) {
557 UnlockDisplay(dpy);
558 SyncHandle();
559 TRACE("GetDeviceInfo... return False");
560 return False;
561 }
562
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;
567 }
568
569 *fbOrigin = rep.framebufferOrigin;
570 *fbSize = rep.framebufferSize;
571 *fbStride = rep.framebufferStride;
572 *devPrivateSize = rep.devPrivateSize;
573
574 if (rep.length) {
575 if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
576 _XEatData(dpy, ((rep.devPrivateSize+3) & ~3));
577 UnlockDisplay(dpy);
578 SyncHandle();
579 TRACE("GetDeviceInfo... return False");
580 return False;
581 }
582 _XRead(dpy, (char*)*pDevPrivate, rep.devPrivateSize);
583 } else {
584 *pDevPrivate = NULL;
585 }
586
587 UnlockDisplay(dpy);
588 SyncHandle();
589 TRACE("GetDeviceInfo... return True");
590 return True;
591 }
592
593 PUBLIC Bool XF86DRIOpenFullScreen(dpy, screen, drawable)
594 Display* dpy;
595 int screen;
596 Drawable drawable;
597 {
598 /* This function and the underlying X protocol are deprecated.
599 */
600 (void) dpy;
601 (void) screen;
602 (void) drawable;
603 return False;
604 }
605
606 PUBLIC Bool XF86DRICloseFullScreen(dpy, screen, drawable)
607 Display* dpy;
608 int screen;
609 Drawable drawable;
610 {
611 /* This function and the underlying X protocol are deprecated.
612 */
613 (void) dpy;
614 (void) screen;
615 (void) drawable;
616 return True;
617 }
618