restore FASTCALL stuff
[mesa.git] / src / glx / x11 / XF86dri.c
1 /* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */
2 /**************************************************************************
3
4 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5 Copyright 2000 VA Linux Systems, Inc.
6 All Rights Reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sub license, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial portions
18 of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
24 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 **************************************************************************/
29
30 /*
31 * Authors:
32 * Kevin E. Martin <martin@valinux.com>
33 * Jens Owen <jens@tungstengraphics.com>
34 * Rickard E. (Rik) Faith <faith@valinux.com>
35 *
36 */
37
38 /* THIS IS NOT AN X CONSORTIUM STANDARD */
39
40 #define NEED_REPLIES
41 #include <X11/Xlibint.h>
42 #include <X11/extensions/Xext.h>
43 #include <X11/extensions/extutil.h>
44 #include "glheader.h"
45 #include "xf86dristr.h"
46
47 static XExtensionInfo _xf86dri_info_data;
48 static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
49 static char xf86dri_extension_name[] = XF86DRINAME;
50
51 #define XF86DRICheckExtension(dpy,i,val) \
52 XextCheckExtension (dpy, i, xf86dri_extension_name, val)
53
54 /*****************************************************************************
55 * *
56 * private utility routines *
57 * *
58 *****************************************************************************/
59
60 static int close_display(Display *dpy, XExtCodes *extCodes);
61 static /* const */ XExtensionHooks xf86dri_extension_hooks = {
62 NULL, /* create_gc */
63 NULL, /* copy_gc */
64 NULL, /* flush_gc */
65 NULL, /* free_gc */
66 NULL, /* create_font */
67 NULL, /* free_font */
68 close_display, /* close_display */
69 NULL, /* wire_to_event */
70 NULL, /* event_to_wire */
71 NULL, /* error */
72 NULL, /* error_string */
73 };
74
75 static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86dri_info,
76 xf86dri_extension_name,
77 &xf86dri_extension_hooks,
78 0, NULL)
79
80 static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86dri_info)
81
82
83 /*****************************************************************************
84 * *
85 * public XFree86-DRI Extension routines *
86 * *
87 *****************************************************************************/
88
89 #if 0
90 #include <stdio.h>
91 #define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
92 #else
93 #define TRACE(msg)
94 #endif
95
96
97 PUBLIC Bool XF86DRIQueryExtension (dpy, event_basep, error_basep)
98 Display *dpy;
99 int *event_basep, *error_basep;
100 {
101 XExtDisplayInfo *info = find_display (dpy);
102
103 TRACE("QueryExtension...");
104 if (XextHasExtension(info)) {
105 *event_basep = info->codes->first_event;
106 *error_basep = info->codes->first_error;
107 TRACE("QueryExtension... return True");
108 return True;
109 } else {
110 TRACE("QueryExtension... return False");
111 return False;
112 }
113 }
114
115 PUBLIC Bool XF86DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
116 Display* dpy;
117 int* majorVersion;
118 int* minorVersion;
119 int* patchVersion;
120 {
121 XExtDisplayInfo *info = find_display (dpy);
122 xXF86DRIQueryVersionReply rep;
123 xXF86DRIQueryVersionReq *req;
124
125 TRACE("QueryVersion...");
126 XF86DRICheckExtension (dpy, info, False);
127
128 LockDisplay(dpy);
129 GetReq(XF86DRIQueryVersion, req);
130 req->reqType = info->codes->major_opcode;
131 req->driReqType = X_XF86DRIQueryVersion;
132 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
133 UnlockDisplay(dpy);
134 SyncHandle();
135 TRACE("QueryVersion... return False");
136 return False;
137 }
138 *majorVersion = rep.majorVersion;
139 *minorVersion = rep.minorVersion;
140 *patchVersion = rep.patchVersion;
141 UnlockDisplay(dpy);
142 SyncHandle();
143 TRACE("QueryVersion... return True");
144 return True;
145 }
146
147 PUBLIC Bool XF86DRIQueryDirectRenderingCapable(dpy, screen, isCapable)
148 Display* dpy;
149 int screen;
150 Bool* isCapable;
151 {
152 XExtDisplayInfo *info = find_display (dpy);
153 xXF86DRIQueryDirectRenderingCapableReply rep;
154 xXF86DRIQueryDirectRenderingCapableReq *req;
155
156 TRACE("QueryDirectRenderingCapable...");
157 XF86DRICheckExtension (dpy, info, False);
158
159 LockDisplay(dpy);
160 GetReq(XF86DRIQueryDirectRenderingCapable, req);
161 req->reqType = info->codes->major_opcode;
162 req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
163 req->screen = screen;
164 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
165 UnlockDisplay(dpy);
166 SyncHandle();
167 TRACE("QueryDirectRenderingCapable... return False");
168 return False;
169 }
170 *isCapable = rep.isCapable;
171 UnlockDisplay(dpy);
172 SyncHandle();
173 TRACE("QueryDirectRenderingCapable... return True");
174 return True;
175 }
176
177 PUBLIC Bool XF86DRIOpenConnection(dpy, screen, hSAREA, busIdString)
178 Display* dpy;
179 int screen;
180 drm_handle_t * hSAREA;
181 char **busIdString;
182 {
183 XExtDisplayInfo *info = find_display (dpy);
184 xXF86DRIOpenConnectionReply rep;
185 xXF86DRIOpenConnectionReq *req;
186
187 TRACE("OpenConnection...");
188 XF86DRICheckExtension (dpy, info, False);
189
190 LockDisplay(dpy);
191 GetReq(XF86DRIOpenConnection, req);
192 req->reqType = info->codes->major_opcode;
193 req->driReqType = X_XF86DRIOpenConnection;
194 req->screen = screen;
195 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
196 UnlockDisplay(dpy);
197 SyncHandle();
198 TRACE("OpenConnection... return False");
199 return False;
200 }
201
202 *hSAREA = rep.hSAREALow;
203 #ifdef LONG64
204 *hSAREA |= ((drm_handle_t)rep.hSAREAHigh) << 32;
205 #endif
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 GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen,
376 __DRIid 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 GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen,
398 __DRIid 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 GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen,
428 __DRIid 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 #ifdef LONG64
566 *hFrameBuffer |= ((drm_handle_t)rep.hFrameBufferHigh) << 32;
567 #endif
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 }