xref: /OK3568_Linux_fs/external/xserver/hw/xquartz/xpr/appledri.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /**************************************************************************
2 
3    Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4    Copyright 2000 VA Linux Systems, Inc.
5    Copyright (c) 2002, 2009-2012 Apple 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@valinux.com>
34  *   Rickard E. (Rik) Faith <faith@valinux.com>
35  *   Jeremy Huddleston <jeremyhu@apple.com>
36  *
37  */
38 
39 #ifdef HAVE_DIX_CONFIG_H
40 #include <dix-config.h>
41 #endif
42 
43 #include <X11/X.h>
44 #include <X11/Xproto.h>
45 #include "misc.h"
46 #include "dixstruct.h"
47 #include "extnsionst.h"
48 #include "colormapst.h"
49 #include "cursorstr.h"
50 #include "scrnintstr.h"
51 #include "servermd.h"
52 #define _APPLEDRI_SERVER_
53 #include "appledristr.h"
54 #include "swaprep.h"
55 #include "dri.h"
56 #include "dristruct.h"
57 #include "xpr.h"
58 #include "x-hash.h"
59 #include "protocol-versions.h"
60 
61 static int DRIErrorBase = 0;
62 
63 static void
64 AppleDRIResetProc(ExtensionEntry* extEntry);
65 static int
66 ProcAppleDRICreatePixmap(ClientPtr client);
67 
68 static unsigned char DRIReqCode = 0;
69 static int DRIEventBase = 0;
70 
71 static void
72 SNotifyEvent(xAppleDRINotifyEvent *from, xAppleDRINotifyEvent *to);
73 
74 typedef struct _DRIEvent *DRIEventPtr;
75 typedef struct _DRIEvent {
76     DRIEventPtr next;
77     ClientPtr client;
78     XID clientResource;
79     unsigned int mask;
80 } DRIEventRec;
81 
82 /*ARGSUSED*/
83 static void
AppleDRIResetProc(ExtensionEntry * extEntry)84 AppleDRIResetProc(ExtensionEntry* extEntry)
85 {
86     DRIReset();
87 }
88 
89 static int
ProcAppleDRIQueryVersion(register ClientPtr client)90 ProcAppleDRIQueryVersion(register ClientPtr client)
91 {
92     xAppleDRIQueryVersionReply rep;
93 
94     REQUEST_SIZE_MATCH(xAppleDRIQueryVersionReq);
95     rep.type = X_Reply;
96     rep.length = 0;
97     rep.sequenceNumber = client->sequence;
98     rep.majorVersion = SERVER_APPLEDRI_MAJOR_VERSION;
99     rep.minorVersion = SERVER_APPLEDRI_MINOR_VERSION;
100     rep.patchVersion = SERVER_APPLEDRI_PATCH_VERSION;
101     if (client->swapped) {
102         swaps(&rep.sequenceNumber);
103         swapl(&rep.length);
104         swaps(&rep.majorVersion);
105         swaps(&rep.minorVersion);
106         swapl(&rep.patchVersion);
107     }
108     WriteToClient(client, sizeof(xAppleDRIQueryVersionReply), &rep);
109     return Success;
110 }
111 
112 /* surfaces */
113 
114 static int
ProcAppleDRIQueryDirectRenderingCapable(register ClientPtr client)115 ProcAppleDRIQueryDirectRenderingCapable(register ClientPtr client)
116 {
117     xAppleDRIQueryDirectRenderingCapableReply rep;
118     Bool isCapable;
119 
120     REQUEST(xAppleDRIQueryDirectRenderingCapableReq);
121     REQUEST_SIZE_MATCH(xAppleDRIQueryDirectRenderingCapableReq);
122     rep.type = X_Reply;
123     rep.length = 0;
124     rep.sequenceNumber = client->sequence;
125 
126     if (stuff->screen >= screenInfo.numScreens) {
127         return BadValue;
128     }
129 
130     if (!DRIQueryDirectRenderingCapable(screenInfo.screens[stuff->screen],
131                                         &isCapable)) {
132         return BadValue;
133     }
134     rep.isCapable = isCapable;
135 
136     if (!client->local)
137         rep.isCapable = 0;
138 
139     if (client->swapped) {
140         swaps(&rep.sequenceNumber);
141         swapl(&rep.length);
142     }
143 
144     WriteToClient(client,
145                   sizeof(xAppleDRIQueryDirectRenderingCapableReply),
146                   &rep);
147     return Success;
148 }
149 
150 static int
ProcAppleDRIAuthConnection(register ClientPtr client)151 ProcAppleDRIAuthConnection(register ClientPtr client)
152 {
153     xAppleDRIAuthConnectionReply rep;
154 
155     REQUEST(xAppleDRIAuthConnectionReq);
156     REQUEST_SIZE_MATCH(xAppleDRIAuthConnectionReq);
157 
158     rep.type = X_Reply;
159     rep.length = 0;
160     rep.sequenceNumber = client->sequence;
161     rep.authenticated = 1;
162 
163     if (!DRIAuthConnection(screenInfo.screens[stuff->screen],
164                            stuff->magic)) {
165         ErrorF("Failed to authenticate %u\n", (unsigned int)stuff->magic);
166         rep.authenticated = 0;
167     }
168 
169     if (client->swapped) {
170         swaps(&rep.sequenceNumber);
171         swapl(&rep.length);
172         swapl(&rep.authenticated); /* Yes, this is a CARD32 ... sigh */
173     }
174 
175     WriteToClient(client, sizeof(xAppleDRIAuthConnectionReply), &rep);
176     return Success;
177 }
178 
179 static void
surface_notify(void * _arg,void * data)180 surface_notify(void *_arg,
181                void *data)
182 {
183     DRISurfaceNotifyArg *arg = _arg;
184     int client_index = (int)x_cvt_vptr_to_uint(data);
185     xAppleDRINotifyEvent se;
186 
187     if (client_index < 0 || client_index >= currentMaxClients)
188         return;
189 
190     se.type = DRIEventBase + AppleDRISurfaceNotify;
191     se.kind = arg->kind;
192     se.arg = arg->id;
193     se.time = currentTime.milliseconds;
194     WriteEventsToClient(clients[client_index], 1, (xEvent *)&se);
195 }
196 
197 static int
ProcAppleDRICreateSurface(ClientPtr client)198 ProcAppleDRICreateSurface(ClientPtr client)
199 {
200     xAppleDRICreateSurfaceReply rep;
201     DrawablePtr pDrawable;
202     xp_surface_id sid;
203     unsigned int key[2];
204     int rc;
205 
206     REQUEST(xAppleDRICreateSurfaceReq);
207     REQUEST_SIZE_MATCH(xAppleDRICreateSurfaceReq);
208     rep.type = X_Reply;
209     rep.length = 0;
210     rep.sequenceNumber = client->sequence;
211 
212     rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
213                            DixReadAccess);
214     if (rc != Success)
215         return rc;
216 
217     rep.key_0 = rep.key_1 = rep.uid = 0;
218 
219     if (!DRICreateSurface(screenInfo.screens[stuff->screen],
220                           (Drawable)stuff->drawable, pDrawable,
221                           stuff->client_id, &sid, key,
222                           surface_notify,
223                           x_cvt_uint_to_vptr(client->index))) {
224         return BadValue;
225     }
226 
227     rep.key_0 = key[0];
228     rep.key_1 = key[1];
229     rep.uid = sid;
230 
231     if (client->swapped) {
232         swaps(&rep.sequenceNumber);
233         swapl(&rep.length);
234         swapl(&rep.key_0);
235         swapl(&rep.key_1);
236         swapl(&rep.uid);
237     }
238 
239     WriteToClient(client, sizeof(xAppleDRICreateSurfaceReply), &rep);
240     return Success;
241 }
242 
243 static int
ProcAppleDRIDestroySurface(register ClientPtr client)244 ProcAppleDRIDestroySurface(register ClientPtr client)
245 {
246     int rc;
247     REQUEST(xAppleDRIDestroySurfaceReq);
248     DrawablePtr pDrawable;
249     REQUEST_SIZE_MATCH(xAppleDRIDestroySurfaceReq);
250 
251     rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
252                            DixReadAccess);
253     if (rc != Success)
254         return rc;
255 
256     if (!DRIDestroySurface(screenInfo.screens[stuff->screen],
257                            (Drawable)stuff->drawable,
258                            pDrawable, NULL, NULL)) {
259         return BadValue;
260     }
261 
262     return Success;
263 }
264 
265 static int
ProcAppleDRICreatePixmap(ClientPtr client)266 ProcAppleDRICreatePixmap(ClientPtr client)
267 {
268     REQUEST(xAppleDRICreatePixmapReq);
269     DrawablePtr pDrawable;
270     int rc;
271     char path[PATH_MAX];
272     xAppleDRICreatePixmapReply rep;
273     int width, height, pitch, bpp;
274     void *ptr;
275 
276     REQUEST_SIZE_MATCH(xAppleDRICreatePixmapReq);
277 
278     rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
279                            DixReadAccess);
280 
281     if (rc != Success)
282         return rc;
283 
284     if (!DRICreatePixmap(screenInfo.screens[stuff->screen],
285                          (Drawable)stuff->drawable,
286                          pDrawable,
287                          path, PATH_MAX)) {
288         return BadValue;
289     }
290 
291     if (!DRIGetPixmapData(pDrawable, &width, &height,
292                           &pitch, &bpp, &ptr)) {
293         return BadValue;
294     }
295 
296     rep.stringLength = strlen(path) + 1;
297 
298     rep.type = X_Reply;
299     rep.length = bytes_to_int32(rep.stringLength);
300     rep.sequenceNumber = client->sequence;
301     rep.width = width;
302     rep.height = height;
303     rep.pitch = pitch;
304     rep.bpp = bpp;
305     rep.size = pitch * height;
306 
307     if (sizeof(rep) != sz_xAppleDRICreatePixmapReply)
308         ErrorF("error sizeof(rep) is %zu\n", sizeof(rep));
309 
310     if (client->swapped) {
311         swaps(&rep.sequenceNumber);
312         swapl(&rep.length);
313         swapl(&rep.stringLength);
314         swapl(&rep.width);
315         swapl(&rep.height);
316         swapl(&rep.pitch);
317         swapl(&rep.bpp);
318         swapl(&rep.size);
319     }
320 
321     WriteToClient(client, sizeof(rep), &rep);
322     WriteToClient(client, rep.stringLength, path);
323 
324     return Success;
325 }
326 
327 static int
ProcAppleDRIDestroyPixmap(ClientPtr client)328 ProcAppleDRIDestroyPixmap(ClientPtr client)
329 {
330     DrawablePtr pDrawable;
331     int rc;
332     REQUEST(xAppleDRIDestroyPixmapReq);
333     REQUEST_SIZE_MATCH(xAppleDRIDestroyPixmapReq);
334 
335     rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
336                            DixReadAccess);
337 
338     if (rc != Success)
339         return rc;
340 
341     DRIDestroyPixmap(pDrawable);
342 
343     return Success;
344 }
345 
346 /* dispatch */
347 
348 static int
ProcAppleDRIDispatch(register ClientPtr client)349 ProcAppleDRIDispatch(register ClientPtr client)
350 {
351     REQUEST(xReq);
352 
353     switch (stuff->data) {
354     case X_AppleDRIQueryVersion:
355         return ProcAppleDRIQueryVersion(client);
356 
357     case X_AppleDRIQueryDirectRenderingCapable:
358         return ProcAppleDRIQueryDirectRenderingCapable(client);
359     }
360 
361     if (!client->local)
362         return DRIErrorBase + AppleDRIClientNotLocal;
363 
364     switch (stuff->data) {
365     case X_AppleDRIAuthConnection:
366         return ProcAppleDRIAuthConnection(client);
367 
368     case X_AppleDRICreateSurface:
369         return ProcAppleDRICreateSurface(client);
370 
371     case X_AppleDRIDestroySurface:
372         return ProcAppleDRIDestroySurface(client);
373 
374     case X_AppleDRICreatePixmap:
375         return ProcAppleDRICreatePixmap(client);
376 
377     case X_AppleDRIDestroyPixmap:
378         return ProcAppleDRIDestroyPixmap(client);
379 
380     default:
381         return BadRequest;
382     }
383 }
384 
385 static void
SNotifyEvent(xAppleDRINotifyEvent * from,xAppleDRINotifyEvent * to)386 SNotifyEvent(xAppleDRINotifyEvent *from,
387              xAppleDRINotifyEvent *to)
388 {
389     to->type = from->type;
390     to->kind = from->kind;
391     cpswaps(from->sequenceNumber, to->sequenceNumber);
392     cpswapl(from->time, to->time);
393     cpswapl(from->arg, to->arg);
394 }
395 
396 static int
SProcAppleDRIQueryVersion(register ClientPtr client)397 SProcAppleDRIQueryVersion(register ClientPtr client)
398 {
399     REQUEST(xAppleDRIQueryVersionReq);
400     swaps(&stuff->length);
401     return ProcAppleDRIQueryVersion(client);
402 }
403 
404 static int
SProcAppleDRIQueryDirectRenderingCapable(register ClientPtr client)405 SProcAppleDRIQueryDirectRenderingCapable(register ClientPtr client)
406 {
407     REQUEST(xAppleDRIQueryDirectRenderingCapableReq);
408     swaps(&stuff->length);
409     REQUEST_SIZE_MATCH(xAppleDRIQueryDirectRenderingCapableReq);
410     swapl(&stuff->screen);
411     return ProcAppleDRIQueryDirectRenderingCapable(client);
412 }
413 
414 static int
SProcAppleDRIAuthConnection(register ClientPtr client)415 SProcAppleDRIAuthConnection(register ClientPtr client)
416 {
417     REQUEST(xAppleDRIAuthConnectionReq);
418     swaps(&stuff->length);
419     REQUEST_SIZE_MATCH(xAppleDRIAuthConnectionReq);
420     swapl(&stuff->screen);
421     swapl(&stuff->magic);
422     return ProcAppleDRIAuthConnection(client);
423 }
424 
425 static int
SProcAppleDRICreateSurface(register ClientPtr client)426 SProcAppleDRICreateSurface(register ClientPtr client)
427 {
428     REQUEST(xAppleDRICreateSurfaceReq);
429     swaps(&stuff->length);
430     REQUEST_SIZE_MATCH(xAppleDRICreateSurfaceReq);
431     swapl(&stuff->screen);
432     swapl(&stuff->drawable);
433     swapl(&stuff->client_id);
434     return ProcAppleDRICreateSurface(client);
435 }
436 
437 static int
SProcAppleDRIDestroySurface(register ClientPtr client)438 SProcAppleDRIDestroySurface(register ClientPtr client)
439 {
440     REQUEST(xAppleDRIDestroySurfaceReq);
441     swaps(&stuff->length);
442     REQUEST_SIZE_MATCH(xAppleDRIDestroySurfaceReq);
443     swapl(&stuff->screen);
444     swapl(&stuff->drawable);
445     return ProcAppleDRIDestroySurface(client);
446 }
447 
448 static int
SProcAppleDRICreatePixmap(register ClientPtr client)449 SProcAppleDRICreatePixmap(register ClientPtr client)
450 {
451     REQUEST(xAppleDRICreatePixmapReq);
452     swaps(&stuff->length);
453     REQUEST_SIZE_MATCH(xAppleDRICreatePixmapReq);
454     swapl(&stuff->screen);
455     swapl(&stuff->drawable);
456     return ProcAppleDRICreatePixmap(client);
457 }
458 
459 static int
SProcAppleDRIDestroyPixmap(register ClientPtr client)460 SProcAppleDRIDestroyPixmap(register ClientPtr client)
461 {
462     REQUEST(xAppleDRIDestroyPixmapReq);
463     swaps(&stuff->length);
464     REQUEST_SIZE_MATCH(xAppleDRIDestroyPixmapReq);
465     swapl(&stuff->drawable);
466     return ProcAppleDRIDestroyPixmap(client);
467 }
468 
469 static int
SProcAppleDRIDispatch(register ClientPtr client)470 SProcAppleDRIDispatch(register ClientPtr client)
471 {
472     REQUEST(xReq);
473 
474     switch (stuff->data) {
475     case X_AppleDRIQueryVersion:
476         return SProcAppleDRIQueryVersion(client);
477 
478     case X_AppleDRIQueryDirectRenderingCapable:
479         return SProcAppleDRIQueryDirectRenderingCapable(client);
480     }
481 
482     if (!client->local)
483         return DRIErrorBase + AppleDRIClientNotLocal;
484 
485     switch (stuff->data) {
486     case X_AppleDRIAuthConnection:
487         return SProcAppleDRIAuthConnection(client);
488 
489     case X_AppleDRICreateSurface:
490         return SProcAppleDRICreateSurface(client);
491 
492     case X_AppleDRIDestroySurface:
493         return SProcAppleDRIDestroySurface(client);
494 
495     case X_AppleDRICreatePixmap:
496         return SProcAppleDRICreatePixmap(client);
497 
498     case X_AppleDRIDestroyPixmap:
499         return SProcAppleDRIDestroyPixmap(client);
500 
501     default:
502         return BadRequest;
503     }
504 }
505 
506 void
AppleDRIExtensionInit(void)507 AppleDRIExtensionInit(void)
508 {
509     ExtensionEntry* extEntry;
510 
511     if (DRIExtensionInit() &&
512         (extEntry = AddExtension(APPLEDRINAME,
513                                  AppleDRINumberEvents,
514                                  AppleDRINumberErrors,
515                                  ProcAppleDRIDispatch,
516                                  SProcAppleDRIDispatch,
517                                  AppleDRIResetProc,
518                                  StandardMinorOpcode))) {
519         size_t i;
520         DRIReqCode = (unsigned char)extEntry->base;
521         DRIErrorBase = extEntry->errorBase;
522         DRIEventBase = extEntry->eventBase;
523         for (i = 0; i < AppleDRINumberEvents; i++)
524             EventSwapVector[DRIEventBase + i] = (EventSwapPtr)SNotifyEvent;
525     }
526 }
527