appledri.c (14119B)
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 84 AppleDRIResetProc(ExtensionEntry* extEntry) 85 { 86 DRIReset(); 87 } 88 89 static int 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 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 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 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 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 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 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 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 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 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 397 SProcAppleDRIQueryVersion(register ClientPtr client) 398 { 399 REQUEST(xAppleDRIQueryVersionReq); 400 swaps(&stuff->length); 401 return ProcAppleDRIQueryVersion(client); 402 } 403 404 static int 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 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 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 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 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 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 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 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 }