Tizen 2.1 base
[sdk/emulator/qemu.git] / gl / mesa / 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