1/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.12 2001/08/27 17:40:57 dawes Exp $ */
2/**************************************************************************
3
4Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5Copyright 2000 VA Linux Systems, Inc.
6Copyright (c) 2002, 2008 Apple Computer, Inc.
7All Rights Reserved.
8
9Permission is hereby granted, free of charge, to any person obtaining a
10copy of this software and associated documentation files (the
11"Software"), to deal in the Software without restriction, including
12without limitation the rights to use, copy, modify, merge, publish,
13distribute, sub license, and/or sell copies of the Software, and to
14permit persons to whom the Software is furnished to do so, subject to
15the following conditions:
16
17The above copyright notice and this permission notice (including the
18next paragraph) shall be included in all copies or substantial portions
19of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27SOFTWARE 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
47static XExtensionInfo _appledri_info_data;
48static XExtensionInfo *appledri_info = &_appledri_info_data;
49static 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
60static int close_display(Display * dpy, XExtCodes * extCodes);
61static Bool wire_to_event(Display * dpy, XEvent * re, xEvent * event);
62
63static /* 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
77static
78XEXT_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
87     void *XAppleDRISetSurfaceNotifyHandler(void (*fun) ())
88{
89   void *old = surface_notify_handler;
90   surface_notify_handler = fun;
91   return old;
92}
93
94static Bool
95wire_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
128Bool
129XAppleDRIQueryExtension(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
148Bool
149XAppleDRIQueryVersion(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
181Bool
182XAppleDRIQueryDirectRenderingCapable(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
212Bool
213XAppleDRIAuthConnection(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
244Bool
245XAppleDRICreateSurface(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
283Bool
284XAppleDRIDestroySurface(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
307Bool
308XAppleDRICreateSharedBuffer(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
356Bool
357XAppleDRISwapBuffers(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
376Bool
377XAppleDRICreatePixmap(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 */
433Bool
434XAppleDRIDestroyPixmap(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