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