Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xquartz / xpr / appledri.c
CommitLineData
a09e091a
JB
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
61static int DRIErrorBase = 0;
62
63static void
64AppleDRIResetProc(ExtensionEntry* extEntry);
65static int
66ProcAppleDRICreatePixmap(ClientPtr client);
67
68static unsigned char DRIReqCode = 0;
69static int DRIEventBase = 0;
70
71static void
72SNotifyEvent(xAppleDRINotifyEvent *from, xAppleDRINotifyEvent *to);
73
74typedef struct _DRIEvent *DRIEventPtr;
75typedef struct _DRIEvent {
76 DRIEventPtr next;
77 ClientPtr client;
78 XID clientResource;
79 unsigned int mask;
80} DRIEventRec;
81
82/*ARGSUSED*/
83static void
84AppleDRIResetProc(ExtensionEntry* extEntry)
85{
86 DRIReset();
87}
88
89static int
90ProcAppleDRIQueryVersion(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
114static int
115ProcAppleDRIQueryDirectRenderingCapable(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
150static int
151ProcAppleDRIAuthConnection(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
179static void
180surface_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
197static int
198ProcAppleDRICreateSurface(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
243static int
244ProcAppleDRIDestroySurface(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
265static int
266ProcAppleDRICreatePixmap(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
327static int
328ProcAppleDRIDestroyPixmap(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
348static int
349ProcAppleDRIDispatch(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
385static void
386SNotifyEvent(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
396static int
397SProcAppleDRIQueryVersion(register ClientPtr client)
398{
399 REQUEST(xAppleDRIQueryVersionReq);
400 swaps(&stuff->length);
401 return ProcAppleDRIQueryVersion(client);
402}
403
404static int
405SProcAppleDRIQueryDirectRenderingCapable(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
414static int
415SProcAppleDRIAuthConnection(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
425static int
426SProcAppleDRICreateSurface(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
437static int
438SProcAppleDRIDestroySurface(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
448static int
449SProcAppleDRICreatePixmap(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
459static int
460SProcAppleDRIDestroyPixmap(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
469static int
470SProcAppleDRIDispatch(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
506void
507AppleDRIExtensionInit(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}