1 /* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.12 2001/08/27 17:40:57 dawes Exp $ */
2 /**************************************************************************
3 
4 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5 Copyright 2000 VA Linux Systems, Inc.
6 Copyright (c) 2002, 2008 Apple Computer, Inc.
7 All Rights Reserved.
8 
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16 
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
19 of the Software.
20 
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 
29 **************************************************************************/
30 
31 /*
32  * Authors:
33  *   Kevin E. Martin <martin@valinux.com>
34  *   Jens Owen <jens@valinux.com>
35  *   Rickard E. (Rik) Faith <faith@valinux.com>
36  *
37  */
38 
39 /* THIS IS NOT AN X CONSORTIUM STANDARD */
40 
41 #include <X11/Xlibint.h>
42 #include "appledristr.h"
43 #include <X11/extensions/Xext.h>
44 #include <X11/extensions/extutil.h>
45 #include <stdio.h>
46 
47 static XExtensionInfo _appledri_info_data;
48 static XExtensionInfo *appledri_info = &_appledri_info_data;
49 static char *appledri_extension_name = APPLEDRINAME;
50 
51 #define AppleDRICheckExtension(dpy,i,val) \
52   XextCheckExtension (dpy, i, appledri_extension_name, val)
53 
54 /*****************************************************************************
55  *                                                                           *
56  *			   private utility routines                          *
57  *                                                                           *
58  *****************************************************************************/
59 
60 static int close_display(Display * dpy, XExtCodes * extCodes);
61 static Bool wire_to_event(Display * dpy, XEvent * re, xEvent * event);
62 
63 static /* const */ XExtensionHooks appledri_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    wire_to_event,               /* 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, appledri_info,
79                            appledri_extension_name,
80                            &appledri_extension_hooks,
81                            AppleDRINumberEvents, NULL)
82 
83      static XEXT_GENERATE_CLOSE_DISPLAY(close_display, appledri_info)
84 
85      static void (*surface_notify_handler) ();
86 
XAppleDRISetSurfaceNotifyHandler(void (* fun)())87      void *XAppleDRISetSurfaceNotifyHandler(void (*fun) ())
88 {
89    void *old = surface_notify_handler;
90    surface_notify_handler = fun;
91    return old;
92 }
93 
94 static Bool
wire_to_event(Display * dpy,XEvent * re,xEvent * event)95 wire_to_event(Display *dpy, XEvent *re, xEvent *event)
96 {
97    XExtDisplayInfo *info = find_display(dpy);
98    xAppleDRINotifyEvent *sevent;
99 
100    AppleDRICheckExtension(dpy, info, False);
101 
102    switch ((event->u.u.type & 0x7f) - info->codes->first_event) {
103    case AppleDRISurfaceNotify:
104       sevent = (xAppleDRINotifyEvent *) event;
105       if (surface_notify_handler != NULL) {
106          (*surface_notify_handler) (dpy, (unsigned int) sevent->arg,
107                                     (int) sevent->kind);
108       }
109       return False;
110    }
111    return False;
112 }
113 
114 /*****************************************************************************
115  *                                                                           *
116  *		    public Apple-DRI Extension routines                      *
117  *                                                                           *
118  *****************************************************************************/
119 
120 #if 0
121 #include <stdio.h>
122 #define TRACE(msg)  fprintf(stderr, "AppleDRI%s\n", msg);
123 #else
124 #define TRACE(msg)
125 #endif
126 
127 
128 Bool
XAppleDRIQueryExtension(dpy,event_basep,error_basep)129 XAppleDRIQueryExtension(dpy, event_basep, error_basep)
130      Display *dpy;
131      int *event_basep, *error_basep;
132 {
133    XExtDisplayInfo *info = find_display(dpy);
134 
135    TRACE("QueryExtension...");
136    if (XextHasExtension(info)) {
137       *event_basep = info->codes->first_event;
138       *error_basep = info->codes->first_error;
139       TRACE("QueryExtension... return True");
140       return True;
141    }
142    else {
143       TRACE("QueryExtension... return False");
144       return False;
145    }
146 }
147 
148 Bool
XAppleDRIQueryVersion(dpy,majorVersion,minorVersion,patchVersion)149 XAppleDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
150      Display *dpy;
151      int *majorVersion;
152      int *minorVersion;
153      int *patchVersion;
154 {
155    XExtDisplayInfo *info = find_display(dpy);
156    xAppleDRIQueryVersionReply rep;
157    xAppleDRIQueryVersionReq *req;
158 
159    TRACE("QueryVersion...");
160    AppleDRICheckExtension(dpy, info, False);
161 
162    LockDisplay(dpy);
163    GetReq(AppleDRIQueryVersion, req);
164    req->reqType = info->codes->major_opcode;
165    req->driReqType = X_AppleDRIQueryVersion;
166    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
167       UnlockDisplay(dpy);
168       SyncHandle();
169       TRACE("QueryVersion... return False");
170       return False;
171    }
172    *majorVersion = rep.majorVersion;
173    *minorVersion = rep.minorVersion;
174    *patchVersion = rep.patchVersion;
175    UnlockDisplay(dpy);
176    SyncHandle();
177    TRACE("QueryVersion... return True");
178    return True;
179 }
180 
181 Bool
XAppleDRIQueryDirectRenderingCapable(dpy,screen,isCapable)182 XAppleDRIQueryDirectRenderingCapable(dpy, screen, isCapable)
183      Display *dpy;
184      int screen;
185      Bool *isCapable;
186 {
187    XExtDisplayInfo *info = find_display(dpy);
188    xAppleDRIQueryDirectRenderingCapableReply rep;
189    xAppleDRIQueryDirectRenderingCapableReq *req;
190 
191    TRACE("QueryDirectRenderingCapable...");
192    AppleDRICheckExtension(dpy, info, False);
193 
194    LockDisplay(dpy);
195    GetReq(AppleDRIQueryDirectRenderingCapable, req);
196    req->reqType = info->codes->major_opcode;
197    req->driReqType = X_AppleDRIQueryDirectRenderingCapable;
198    req->screen = screen;
199    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
200       UnlockDisplay(dpy);
201       SyncHandle();
202       TRACE("QueryDirectRenderingCapable... return False");
203       return False;
204    }
205    *isCapable = rep.isCapable;
206    UnlockDisplay(dpy);
207    SyncHandle();
208    TRACE("QueryDirectRenderingCapable... return True");
209    return True;
210 }
211 
212 Bool
XAppleDRIAuthConnection(dpy,screen,magic)213 XAppleDRIAuthConnection(dpy, screen, magic)
214      Display *dpy;
215      int screen;
216      unsigned int magic;
217 {
218    XExtDisplayInfo *info = find_display(dpy);
219    xAppleDRIAuthConnectionReq *req;
220    xAppleDRIAuthConnectionReply rep;
221 
222    TRACE("AuthConnection...");
223    AppleDRICheckExtension(dpy, info, False);
224 
225    LockDisplay(dpy);
226    GetReq(AppleDRIAuthConnection, req);
227    req->reqType = info->codes->major_opcode;
228    req->driReqType = X_AppleDRIAuthConnection;
229    req->screen = screen;
230    req->magic = magic;
231    rep.authenticated = 0;
232    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.authenticated) {
233       UnlockDisplay(dpy);
234       SyncHandle();
235       TRACE("AuthConnection... return False");
236       return False;
237    }
238    UnlockDisplay(dpy);
239    SyncHandle();
240    TRACE("AuthConnection... return True");
241    return True;
242 }
243 
244 Bool
XAppleDRICreateSurface(dpy,screen,drawable,client_id,key,uid)245 XAppleDRICreateSurface(dpy, screen, drawable, client_id, key, uid)
246      Display *dpy;
247      int screen;
248      Drawable drawable;
249      unsigned int client_id;
250      unsigned int *key;
251      unsigned int *uid;
252 {
253    XExtDisplayInfo *info = find_display(dpy);
254    xAppleDRICreateSurfaceReply rep;
255    xAppleDRICreateSurfaceReq *req;
256 
257    TRACE("CreateSurface...");
258    AppleDRICheckExtension(dpy, info, False);
259 
260    LockDisplay(dpy);
261    GetReq(AppleDRICreateSurface, req);
262    req->reqType = info->codes->major_opcode;
263    req->driReqType = X_AppleDRICreateSurface;
264    req->screen = screen;
265    req->drawable = drawable;
266    req->client_id = client_id;
267    rep.key_0 = rep.key_1 = rep.uid = 0;
268    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.key_0) {
269       UnlockDisplay(dpy);
270       SyncHandle();
271       TRACE("CreateSurface... return False");
272       return False;
273    }
274    key[0] = rep.key_0;
275    key[1] = rep.key_1;
276    *uid = rep.uid;
277    UnlockDisplay(dpy);
278    SyncHandle();
279    TRACE("CreateSurface... return True");
280    return True;
281 }
282 
283 Bool
XAppleDRIDestroySurface(dpy,screen,drawable)284 XAppleDRIDestroySurface(dpy, screen, drawable)
285      Display *dpy;
286      int screen;
287      Drawable drawable;
288 {
289    XExtDisplayInfo *info = find_display(dpy);
290    xAppleDRIDestroySurfaceReq *req;
291 
292    TRACE("DestroySurface...");
293    AppleDRICheckExtension(dpy, info, False);
294 
295    LockDisplay(dpy);
296    GetReq(AppleDRIDestroySurface, req);
297    req->reqType = info->codes->major_opcode;
298    req->driReqType = X_AppleDRIDestroySurface;
299    req->screen = screen;
300    req->drawable = drawable;
301    UnlockDisplay(dpy);
302    SyncHandle();
303    TRACE("DestroySurface... return True");
304    return True;
305 }
306 
307 Bool
XAppleDRICreateSharedBuffer(Display * dpy,int screen,Drawable drawable,Bool doubleSwap,char * path,size_t pathlen,int * width,int * height)308 XAppleDRICreateSharedBuffer(Display * dpy, int screen, Drawable drawable,
309                             Bool doubleSwap, char *path, size_t pathlen,
310                             int *width, int *height)
311 {
312    XExtDisplayInfo *info = find_display(dpy);
313    xAppleDRICreateSharedBufferReq *req;
314    xAppleDRICreateSharedBufferReply rep;
315 
316    AppleDRICheckExtension(dpy, info, False);
317 
318    LockDisplay(dpy);
319    GetReq(AppleDRICreateSharedBuffer, req);
320    req->reqType = info->codes->major_opcode;
321    req->driReqType = X_AppleDRICreateSharedBuffer;
322    req->screen = screen;
323    req->drawable = drawable;
324    req->doubleSwap = doubleSwap;
325 
326 
327    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
328       puts("REPLY ERROR");
329 
330       UnlockDisplay(dpy);
331       SyncHandle();
332       return False;
333    }
334 
335    /* printf("rep.stringLength %d\n", (int) rep.stringLength); */
336 
337    if (rep.stringLength > 0 && rep.stringLength <= pathlen) {
338       _XReadPad(dpy, path, rep.stringLength);
339 
340       /* printf("path: %s\n", path); */
341 
342       *width = rep.width;
343       *height = rep.height;
344 
345       UnlockDisplay(dpy);
346       SyncHandle();
347       return True;
348    }
349 
350    UnlockDisplay(dpy);
351    SyncHandle();
352 
353    return False;
354 }
355 
356 Bool
XAppleDRISwapBuffers(Display * dpy,int screen,Drawable drawable)357 XAppleDRISwapBuffers(Display * dpy, int screen, Drawable drawable)
358 {
359    XExtDisplayInfo *info = find_display(dpy);
360    xAppleDRISwapBuffersReq *req;
361 
362    AppleDRICheckExtension(dpy, info, False);
363 
364    LockDisplay(dpy);
365    GetReq(AppleDRISwapBuffers, req);
366    req->reqType = info->codes->major_opcode;
367    req->driReqType = X_AppleDRISwapBuffers;
368    req->screen = screen;
369    req->drawable = drawable;
370    UnlockDisplay(dpy);
371    SyncHandle();
372 
373    return True;
374 }
375 
376 Bool
XAppleDRICreatePixmap(Display * dpy,int screen,Drawable drawable,int * width,int * height,int * pitch,int * bpp,size_t * size,char * bufname,size_t bufnamesize)377 XAppleDRICreatePixmap(Display * dpy, int screen, Drawable drawable,
378                       int *width, int *height, int *pitch, int *bpp,
379                       size_t * size, char *bufname, size_t bufnamesize)
380 {
381    XExtDisplayInfo *info = find_display(dpy);
382    xAppleDRICreatePixmapReq *req;
383    xAppleDRICreatePixmapReply rep;
384 
385    AppleDRICheckExtension(dpy, info, False);
386 
387    LockDisplay(dpy);
388    GetReq(AppleDRICreatePixmap, req);
389    req->reqType = info->codes->major_opcode;
390    req->driReqType = X_AppleDRICreatePixmap;
391    req->screen = screen;
392    req->drawable = drawable;
393 
394    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
395       UnlockDisplay(dpy);
396       SyncHandle();
397       return False;
398    }
399 
400    /*
401       printf("rep.stringLength %d\n", (int) rep.stringLength);
402     */
403 
404    if (rep.stringLength > 0 && rep.stringLength <= bufnamesize) {
405       _XReadPad(dpy, bufname, rep.stringLength);
406 
407       /* printf("path: %s\n", bufname); */
408 
409       *width = rep.width;
410       *height = rep.height;
411       *pitch = rep.pitch;
412       *bpp = rep.bpp;
413       *size = rep.size;
414 
415       UnlockDisplay(dpy);
416       SyncHandle();
417       return True;
418    }
419    else if (rep.stringLength > 0) {
420       _XEatData(dpy, rep.stringLength);
421    }
422 
423    UnlockDisplay(dpy);
424    SyncHandle();
425 
426    return True;
427 }
428 
429 /*
430  * Call it a drawable, because we really don't know what it is
431  * until it reaches the server, and we should keep that in mind.
432  */
433 Bool
XAppleDRIDestroyPixmap(Display * dpy,Pixmap drawable)434 XAppleDRIDestroyPixmap(Display * dpy, Pixmap drawable)
435 {
436    XExtDisplayInfo *info = find_display(dpy);
437    xAppleDRIDestroyPixmapReq *req;
438 
439    AppleDRICheckExtension(dpy, info, False);
440 
441    LockDisplay(dpy);
442    GetReq(AppleDRIDestroyPixmap, req);
443    req->reqType = info->codes->major_opcode;
444    req->driReqType = X_AppleDRIDestroyPixmap;
445    req->drawable = drawable;
446    UnlockDisplay(dpy);
447    SyncHandle();
448 
449    return True;
450 }
451