DRI2: report swap events correctly in direct rendered case
[mesa.git] / src / gallium / winsys / drm / radeon / python / 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 HAVE_CONFIG_H
40 #include "config.h"
41 #endif
42
43 #define NEED_REPLIES
44 #include <X11/Xlibint.h>
45 #include <X11/extensions/Xext.h>
46 #include <X11/extensions/extutil.h>
47 #include "xf86dristr.h"
48
49 static XExtensionInfo _xf86dri_info_data;
50 static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
51 static char xf86dri_extension_name[] = XF86DRINAME;
52
53 #define uniDRICheckExtension(dpy,i,val) \
54 XextCheckExtension (dpy, i, xf86dri_extension_name, val)
55
56 /*****************************************************************************
57 * *
58 * private utility routines *
59 * *
60 *****************************************************************************/
61
62 static int close_display(Display * dpy, XExtCodes * extCodes);
63 static /* const */ XExtensionHooks xf86dri_extension_hooks = {
64 NULL, /* create_gc */
65 NULL, /* copy_gc */
66 NULL, /* flush_gc */
67 NULL, /* free_gc */
68 NULL, /* create_font */
69 NULL, /* free_font */
70 close_display, /* close_display */
71 NULL, /* wire_to_event */
72 NULL, /* event_to_wire */
73 NULL, /* error */
74 NULL, /* error_string */
75 };
76
77 static
78 XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info,
79 xf86dri_extension_name, &xf86dri_extension_hooks,
80 0, NULL)
81
82 static XEXT_GENERATE_CLOSE_DISPLAY(close_display, xf86dri_info)
83
84 /*****************************************************************************
85 * *
86 * public XFree86-DRI Extension routines *
87 * *
88 *****************************************************************************/
89 #if 0
90 #include <stdio.h>
91 #define TRACE(msg) fprintf(stderr,"uniDRI%s\n", msg);
92 #else
93 #define TRACE(msg)
94 #endif
95 Bool uniDRIQueryExtension(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 Bool
114 uniDRIQueryVersion(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 uniDRICheckExtension(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 Bool
147 uniDRIQueryDirectRenderingCapable(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 uniDRICheckExtension(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 Bool
178 uniDRIOpenConnection(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 uniDRICheckExtension(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 #ifdef LONG64
205 if (sizeof(drm_handle_t) == 8) {
206 *hSAREA |= ((unsigned long)rep.hSAREAHigh) << 32;
207 }
208 #endif
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 Bool
228 uniDRIAuthConnection(dpy, screen, magic)
229 Display *dpy;
230 int screen;
231 drm_magic_t magic;
232 {
233 XExtDisplayInfo *info = find_display(dpy);
234 xXF86DRIAuthConnectionReq *req;
235 xXF86DRIAuthConnectionReply rep;
236
237 TRACE("AuthConnection...");
238 uniDRICheckExtension(dpy, info, False);
239
240 LockDisplay(dpy);
241 GetReq(XF86DRIAuthConnection, req);
242 req->reqType = info->codes->major_opcode;
243 req->driReqType = X_XF86DRIAuthConnection;
244 req->screen = screen;
245 req->magic = magic;
246 rep.authenticated = 0;
247 if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.authenticated) {
248 UnlockDisplay(dpy);
249 SyncHandle();
250 TRACE("AuthConnection... return False");
251 return False;
252 }
253 UnlockDisplay(dpy);
254 SyncHandle();
255 TRACE("AuthConnection... return True");
256 return True;
257 }
258
259 Bool
260 uniDRICloseConnection(dpy, screen)
261 Display *dpy;
262 int screen;
263 {
264 XExtDisplayInfo *info = find_display(dpy);
265 xXF86DRICloseConnectionReq *req;
266
267 TRACE("CloseConnection...");
268
269 uniDRICheckExtension(dpy, info, False);
270
271 LockDisplay(dpy);
272 GetReq(XF86DRICloseConnection, req);
273 req->reqType = info->codes->major_opcode;
274 req->driReqType = X_XF86DRICloseConnection;
275 req->screen = screen;
276 UnlockDisplay(dpy);
277 SyncHandle();
278 TRACE("CloseConnection... return True");
279 return True;
280 }
281
282 Bool
283 uniDRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
284 ddxDriverMinorVersion, ddxDriverPatchVersion,
285 clientDriverName)
286 Display *dpy;
287 int screen;
288 int *ddxDriverMajorVersion;
289 int *ddxDriverMinorVersion;
290 int *ddxDriverPatchVersion;
291 char **clientDriverName;
292 {
293 XExtDisplayInfo *info = find_display(dpy);
294 xXF86DRIGetClientDriverNameReply rep;
295 xXF86DRIGetClientDriverNameReq *req;
296
297 TRACE("GetClientDriverName...");
298 uniDRICheckExtension(dpy, info, False);
299
300 LockDisplay(dpy);
301 GetReq(XF86DRIGetClientDriverName, req);
302 req->reqType = info->codes->major_opcode;
303 req->driReqType = X_XF86DRIGetClientDriverName;
304 req->screen = screen;
305 if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
306 UnlockDisplay(dpy);
307 SyncHandle();
308 TRACE("GetClientDriverName... return False");
309 return False;
310 }
311
312 *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
313 *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
314 *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
315
316 if (rep.length) {
317 if (!(*clientDriverName =
318 (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
319 _XEatData(dpy, ((rep.clientDriverNameLength + 3) & ~3));
320 UnlockDisplay(dpy);
321 SyncHandle();
322 TRACE("GetClientDriverName... return False");
323 return False;
324 }
325 _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
326 } else {
327 *clientDriverName = NULL;
328 }
329 UnlockDisplay(dpy);
330 SyncHandle();
331 TRACE("GetClientDriverName... return True");
332 return True;
333 }
334
335 Bool
336 uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext)
337 Display *dpy;
338 int screen;
339 int configID;
340 XID *context;
341 drm_context_t *hHWContext;
342 {
343 XExtDisplayInfo *info = find_display(dpy);
344 xXF86DRICreateContextReply rep;
345 xXF86DRICreateContextReq *req;
346
347 TRACE("CreateContext...");
348 uniDRICheckExtension(dpy, info, False);
349
350 LockDisplay(dpy);
351 GetReq(XF86DRICreateContext, req);
352 req->reqType = info->codes->major_opcode;
353 req->driReqType = X_XF86DRICreateContext;
354 req->visual = configID;
355 req->screen = screen;
356 *context = XAllocID(dpy);
357 req->context = *context;
358 if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
359 UnlockDisplay(dpy);
360 SyncHandle();
361 TRACE("CreateContext... return False");
362 return False;
363 }
364 *hHWContext = rep.hHWContext;
365 UnlockDisplay(dpy);
366 SyncHandle();
367 TRACE("CreateContext... return True");
368 return True;
369 }
370
371 Bool
372 uniDRICreateContext(dpy, screen, visual, context, hHWContext)
373 Display *dpy;
374 int screen;
375 Visual *visual;
376 XID *context;
377 drm_context_t *hHWContext;
378 {
379 return uniDRICreateContextWithConfig(dpy, screen, visual->visualid,
380 context, hHWContext);
381 }
382
383 Bool
384 uniDRIDestroyContext(Display * ndpy, int screen, XID context)
385 {
386 Display *const dpy = (Display *) ndpy;
387 XExtDisplayInfo *info = find_display(dpy);
388 xXF86DRIDestroyContextReq *req;
389
390 TRACE("DestroyContext...");
391 uniDRICheckExtension(dpy, info, False);
392
393 LockDisplay(dpy);
394 GetReq(XF86DRIDestroyContext, req);
395 req->reqType = info->codes->major_opcode;
396 req->driReqType = X_XF86DRIDestroyContext;
397 req->screen = screen;
398 req->context = context;
399 UnlockDisplay(dpy);
400 SyncHandle();
401 TRACE("DestroyContext... return True");
402 return True;
403 }
404
405 Bool
406 uniDRICreateDrawable(Display * ndpy, int screen,
407 Drawable drawable, drm_drawable_t * hHWDrawable)
408 {
409 Display *const dpy = (Display *) ndpy;
410 XExtDisplayInfo *info = find_display(dpy);
411 xXF86DRICreateDrawableReply rep;
412 xXF86DRICreateDrawableReq *req;
413
414 TRACE("CreateDrawable...");
415 uniDRICheckExtension(dpy, info, False);
416
417 LockDisplay(dpy);
418 GetReq(XF86DRICreateDrawable, req);
419 req->reqType = info->codes->major_opcode;
420 req->driReqType = X_XF86DRICreateDrawable;
421 req->screen = screen;
422 req->drawable = drawable;
423 if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
424 UnlockDisplay(dpy);
425 SyncHandle();
426 TRACE("CreateDrawable... return False");
427 return False;
428 }
429 *hHWDrawable = rep.hHWDrawable;
430 UnlockDisplay(dpy);
431 SyncHandle();
432 TRACE("CreateDrawable... return True");
433 return True;
434 }
435
436 Bool
437 uniDRIDestroyDrawable(Display * ndpy, int screen, Drawable drawable)
438 {
439 Display *const dpy = (Display *) ndpy;
440 XExtDisplayInfo *info = find_display(dpy);
441 xXF86DRIDestroyDrawableReq *req;
442
443 TRACE("DestroyDrawable...");
444 uniDRICheckExtension(dpy, info, False);
445
446 LockDisplay(dpy);
447 GetReq(XF86DRIDestroyDrawable, req);
448 req->reqType = info->codes->major_opcode;
449 req->driReqType = X_XF86DRIDestroyDrawable;
450 req->screen = screen;
451 req->drawable = drawable;
452 UnlockDisplay(dpy);
453 SyncHandle();
454 TRACE("DestroyDrawable... return True");
455 return True;
456 }
457
458 Bool
459 uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
460 unsigned int *index, unsigned int *stamp,
461 int *X, int *Y, int *W, int *H,
462 int *numClipRects, drm_clip_rect_t ** pClipRects,
463 int *backX, int *backY,
464 int *numBackClipRects,
465 drm_clip_rect_t ** pBackClipRects)
466 {
467 XExtDisplayInfo *info = find_display(dpy);
468 xXF86DRIGetDrawableInfoReply rep;
469 xXF86DRIGetDrawableInfoReq *req;
470 int total_rects;
471
472 TRACE("GetDrawableInfo...");
473 uniDRICheckExtension(dpy, info, False);
474
475 LockDisplay(dpy);
476 GetReq(XF86DRIGetDrawableInfo, req);
477 req->reqType = info->codes->major_opcode;
478 req->driReqType = X_XF86DRIGetDrawableInfo;
479 req->screen = screen;
480 req->drawable = drawable;
481
482 if (!_XReply(dpy, (xReply *) & rep, 1, xFalse)) {
483 UnlockDisplay(dpy);
484 SyncHandle();
485 TRACE("GetDrawableInfo... return False");
486 return False;
487 }
488 *index = rep.drawableTableIndex;
489 *stamp = rep.drawableTableStamp;
490 *X = (int)rep.drawableX;
491 *Y = (int)rep.drawableY;
492 *W = (int)rep.drawableWidth;
493 *H = (int)rep.drawableHeight;
494 *numClipRects = rep.numClipRects;
495 total_rects = *numClipRects;
496
497 *backX = rep.backX;
498 *backY = rep.backY;
499 *numBackClipRects = rep.numBackClipRects;
500 total_rects += *numBackClipRects;
501
502 #if 0
503 /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
504 * backwards compatibility (Because of the >> 2 shift) but the fix
505 * enables multi-threaded apps to work.
506 */
507 if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) -
508 SIZEOF(xGenericReply) +
509 total_rects * sizeof(drm_clip_rect_t)) +
510 3) & ~3) >> 2)) {
511 _XEatData(dpy, rep.length);
512 UnlockDisplay(dpy);
513 SyncHandle();
514 TRACE("GetDrawableInfo... return False");
515 return False;
516 }
517 #endif
518
519 if (*numClipRects) {
520 int len = sizeof(drm_clip_rect_t) * (*numClipRects);
521
522 *pClipRects = (drm_clip_rect_t *) Xcalloc(len, 1);
523 if (*pClipRects)
524 _XRead(dpy, (char *)*pClipRects, len);
525 } else {
526 *pClipRects = NULL;
527 }
528
529 if (*numBackClipRects) {
530 int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
531
532 *pBackClipRects = (drm_clip_rect_t *) Xcalloc(len, 1);
533 if (*pBackClipRects)
534 _XRead(dpy, (char *)*pBackClipRects, len);
535 } else {
536 *pBackClipRects = NULL;
537 }
538
539 UnlockDisplay(dpy);
540 SyncHandle();
541 TRACE("GetDrawableInfo... return True");
542 return True;
543 }
544
545 Bool
546 uniDRIGetDeviceInfo(dpy, screen, hFrameBuffer,
547 fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate)
548 Display *dpy;
549 int screen;
550 drm_handle_t *hFrameBuffer;
551 int *fbOrigin;
552 int *fbSize;
553 int *fbStride;
554 int *devPrivateSize;
555 void **pDevPrivate;
556 {
557 XExtDisplayInfo *info = find_display(dpy);
558 xXF86DRIGetDeviceInfoReply rep;
559 xXF86DRIGetDeviceInfoReq *req;
560
561 TRACE("GetDeviceInfo...");
562 uniDRICheckExtension(dpy, info, False);
563
564 LockDisplay(dpy);
565 GetReq(XF86DRIGetDeviceInfo, req);
566 req->reqType = info->codes->major_opcode;
567 req->driReqType = X_XF86DRIGetDeviceInfo;
568 req->screen = screen;
569 if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
570 UnlockDisplay(dpy);
571 SyncHandle();
572 TRACE("GetDeviceInfo... return False");
573 return False;
574 }
575
576 *hFrameBuffer = rep.hFrameBufferLow;
577 #ifdef LONG64
578 if (sizeof(drm_handle_t) == 8) {
579 *hFrameBuffer |= ((unsigned long)rep.hFrameBufferHigh) << 32;
580 }
581 #endif
582
583 *fbOrigin = rep.framebufferOrigin;
584 *fbSize = rep.framebufferSize;
585 *fbStride = rep.framebufferStride;
586 *devPrivateSize = rep.devPrivateSize;
587
588 if (rep.length) {
589 if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
590 _XEatData(dpy, ((rep.devPrivateSize + 3) & ~3));
591 UnlockDisplay(dpy);
592 SyncHandle();
593 TRACE("GetDeviceInfo... return False");
594 return False;
595 }
596 _XRead(dpy, (char *)*pDevPrivate, rep.devPrivateSize);
597 } else {
598 *pDevPrivate = NULL;
599 }
600
601 UnlockDisplay(dpy);
602 SyncHandle();
603 TRACE("GetDeviceInfo... return True");
604 return True;
605 }