appledri.c revision 35c4bbdf
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} 527