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