appledri.c revision 6747b715
1/************************************************************************** 2 3Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 4Copyright 2000 VA Linux Systems, Inc. 5Copyright (c) 2002, 2009 Apple Computer, 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 62static DISPATCH_PROC(ProcAppleDRIDispatch); 63static DISPATCH_PROC(SProcAppleDRIDispatch); 64 65static void AppleDRIResetProc(ExtensionEntry* extEntry); 66static int ProcAppleDRICreatePixmap(ClientPtr client); 67 68static unsigned char DRIReqCode = 0; 69static int DRIEventBase = 0; 70 71static void SNotifyEvent(xAppleDRINotifyEvent *from, xAppleDRINotifyEvent *to); 72 73typedef struct _DRIEvent *DRIEventPtr; 74typedef struct _DRIEvent { 75 DRIEventPtr next; 76 ClientPtr client; 77 XID clientResource; 78 unsigned int mask; 79} DRIEventRec; 80 81 82void 83AppleDRIExtensionInit(void) 84{ 85 ExtensionEntry* extEntry; 86 87 if (DRIExtensionInit() && 88 (extEntry = AddExtension(APPLEDRINAME, 89 AppleDRINumberEvents, 90 AppleDRINumberErrors, 91 ProcAppleDRIDispatch, 92 SProcAppleDRIDispatch, 93 AppleDRIResetProc, 94 StandardMinorOpcode))) { 95 DRIReqCode = (unsigned char)extEntry->base; 96 DRIErrorBase = extEntry->errorBase; 97 DRIEventBase = extEntry->eventBase; 98 EventSwapVector[DRIEventBase] = (EventSwapPtr) SNotifyEvent; 99 } 100} 101 102/*ARGSUSED*/ 103static void 104AppleDRIResetProc ( 105 ExtensionEntry* extEntry 106) 107{ 108 DRIReset(); 109} 110 111static int 112ProcAppleDRIQueryVersion( 113 register ClientPtr client 114) 115{ 116 xAppleDRIQueryVersionReply rep; 117 register int n; 118 119 REQUEST_SIZE_MATCH(xAppleDRIQueryVersionReq); 120 rep.type = X_Reply; 121 rep.length = 0; 122 rep.sequenceNumber = client->sequence; 123 rep.majorVersion = SERVER_APPLEDRI_MAJOR_VERSION; 124 rep.minorVersion = SERVER_APPLEDRI_MINOR_VERSION; 125 rep.patchVersion = SERVER_APPLEDRI_PATCH_VERSION; 126 if (client->swapped) { 127 swaps(&rep.sequenceNumber, n); 128 swapl(&rep.length, n); 129 } 130 WriteToClient(client, sizeof(xAppleDRIQueryVersionReply), (char *)&rep); 131 return Success; 132} 133 134 135/* surfaces */ 136 137static int 138ProcAppleDRIQueryDirectRenderingCapable( 139 register ClientPtr client 140) 141{ 142 xAppleDRIQueryDirectRenderingCapableReply rep; 143 Bool isCapable; 144 145 REQUEST(xAppleDRIQueryDirectRenderingCapableReq); 146 REQUEST_SIZE_MATCH(xAppleDRIQueryDirectRenderingCapableReq); 147 rep.type = X_Reply; 148 rep.length = 0; 149 rep.sequenceNumber = client->sequence; 150 151 if (!DRIQueryDirectRenderingCapable( screenInfo.screens[stuff->screen], 152 &isCapable)) { 153 return BadValue; 154 } 155 rep.isCapable = isCapable; 156 157 if (!LocalClient(client)) 158 rep.isCapable = 0; 159 160 WriteToClient(client, 161 sizeof(xAppleDRIQueryDirectRenderingCapableReply), (char *)&rep); 162 return Success; 163} 164 165static int 166ProcAppleDRIAuthConnection( 167 register ClientPtr client 168) 169{ 170 xAppleDRIAuthConnectionReply rep; 171 172 REQUEST(xAppleDRIAuthConnectionReq); 173 REQUEST_SIZE_MATCH(xAppleDRIAuthConnectionReq); 174 175 rep.type = X_Reply; 176 rep.length = 0; 177 rep.sequenceNumber = client->sequence; 178 rep.authenticated = 1; 179 180 if (!DRIAuthConnection( screenInfo.screens[stuff->screen], stuff->magic)) { 181 ErrorF("Failed to authenticate %u\n", (unsigned int)stuff->magic); 182 rep.authenticated = 0; 183 } 184 WriteToClient(client, sizeof(xAppleDRIAuthConnectionReply), (char *)&rep); 185 return Success; 186} 187 188static void surface_notify( 189 void *_arg, 190 void *data 191) 192{ 193 DRISurfaceNotifyArg *arg = _arg; 194 int client_index = (int) x_cvt_vptr_to_uint(data); 195 xAppleDRINotifyEvent se; 196 197 if (client_index < 0 || client_index >= currentMaxClients) 198 return; 199 200 se.type = DRIEventBase + AppleDRISurfaceNotify; 201 se.kind = arg->kind; 202 se.arg = arg->id; 203 se.time = currentTime.milliseconds; 204 WriteEventsToClient (clients[client_index], 1, (xEvent *) &se); 205} 206 207static int 208ProcAppleDRICreateSurface( 209 ClientPtr client 210) 211{ 212 xAppleDRICreateSurfaceReply rep; 213 DrawablePtr pDrawable; 214 xp_surface_id sid; 215 unsigned int key[2]; 216 int rc; 217 218 REQUEST(xAppleDRICreateSurfaceReq); 219 REQUEST_SIZE_MATCH(xAppleDRICreateSurfaceReq); 220 rep.type = X_Reply; 221 rep.length = 0; 222 rep.sequenceNumber = client->sequence; 223 224 rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 225 DixReadAccess); 226 if (rc != Success) 227 return rc; 228 229 rep.key_0 = rep.key_1 = rep.uid = 0; 230 231 if (!DRICreateSurface( screenInfo.screens[stuff->screen], 232 (Drawable)stuff->drawable, pDrawable, 233 stuff->client_id, &sid, key, 234 surface_notify, 235 x_cvt_uint_to_vptr(client->index))) { 236 return BadValue; 237 } 238 239 rep.key_0 = key[0]; 240 rep.key_1 = key[1]; 241 rep.uid = sid; 242 243 WriteToClient(client, sizeof(xAppleDRICreateSurfaceReply), (char *)&rep); 244 return Success; 245} 246 247static int 248ProcAppleDRIDestroySurface( 249 register ClientPtr client 250) 251{ 252 int rc; 253 REQUEST(xAppleDRIDestroySurfaceReq); 254 DrawablePtr pDrawable; 255 REQUEST_SIZE_MATCH(xAppleDRIDestroySurfaceReq); 256 257 rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 258 DixReadAccess); 259 if (rc != Success) 260 return rc; 261 262 if (!DRIDestroySurface( screenInfo.screens[stuff->screen], 263 (Drawable)stuff->drawable, 264 pDrawable, NULL, NULL)) { 265 return BadValue; 266 } 267 268 return Success; 269} 270 271static int 272ProcAppleDRICreatePixmap(ClientPtr client) 273{ 274 REQUEST(xAppleDRICreatePixmapReq); 275 DrawablePtr pDrawable; 276 int rc; 277 char path[PATH_MAX]; 278 xAppleDRICreatePixmapReply rep; 279 int width, height, pitch, bpp; 280 void *ptr; 281 282 REQUEST_SIZE_MATCH(xAppleDRICreatePixmapReq); 283 284 rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 285 DixReadAccess); 286 287 if(rc != Success) 288 return rc; 289 290 if(!DRICreatePixmap(screenInfo.screens[stuff->screen], 291 (Drawable)stuff->drawable, 292 pDrawable, 293 path, PATH_MAX)) { 294 return BadValue; 295 } 296 297 if(!DRIGetPixmapData(pDrawable, &width, &height, 298 &pitch, &bpp, &ptr)) { 299 return BadValue; 300 } 301 302 rep.stringLength = strlen(path) + 1; 303 304 /* No need for swapping, because this only runs if LocalClient is true. */ 305 rep.type = X_Reply; 306 rep.length = sizeof(rep) + rep.stringLength; 307 rep.sequenceNumber = client->sequence; 308 rep.width = width; 309 rep.height = height; 310 rep.pitch = pitch; 311 rep.bpp = bpp; 312 rep.size = pitch * height; 313 314 if(sizeof(rep) != sz_xAppleDRICreatePixmapReply) 315 ErrorF("error sizeof(rep) is %zu\n", sizeof(rep)); 316 317 WriteReplyToClient(client, sizeof(rep), &rep); 318 (void)WriteToClient(client, rep.stringLength, path); 319 320 return Success; 321} 322 323static int 324ProcAppleDRIDestroyPixmap(ClientPtr client) 325{ 326 DrawablePtr pDrawable; 327 int rc; 328 REQUEST(xAppleDRIDestroyPixmapReq); 329 REQUEST_SIZE_MATCH(xAppleDRIDestroyPixmapReq); 330 331 rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 332 DixReadAccess); 333 334 if(rc != Success) 335 return rc; 336 337 DRIDestroyPixmap(pDrawable); 338 339 return Success; 340} 341 342/* dispatch */ 343 344static int 345ProcAppleDRIDispatch ( 346 register ClientPtr client 347) 348{ 349 REQUEST(xReq); 350 351 switch (stuff->data) 352 { 353 case X_AppleDRIQueryVersion: 354 return ProcAppleDRIQueryVersion(client); 355 case X_AppleDRIQueryDirectRenderingCapable: 356 return ProcAppleDRIQueryDirectRenderingCapable(client); 357 } 358 359 if (!LocalClient(client)) 360 return DRIErrorBase + AppleDRIClientNotLocal; 361 362 switch (stuff->data) 363 { 364 case X_AppleDRIAuthConnection: 365 return ProcAppleDRIAuthConnection(client); 366 case X_AppleDRICreateSurface: 367 return ProcAppleDRICreateSurface(client); 368 case X_AppleDRIDestroySurface: 369 return ProcAppleDRIDestroySurface(client); 370 case X_AppleDRICreatePixmap: 371 return ProcAppleDRICreatePixmap(client); 372 case X_AppleDRIDestroyPixmap: 373 return ProcAppleDRIDestroyPixmap(client); 374 375 default: 376 return BadRequest; 377 } 378} 379 380static void 381SNotifyEvent( 382 xAppleDRINotifyEvent *from, 383 xAppleDRINotifyEvent *to 384) 385{ 386 to->type = from->type; 387 to->kind = from->kind; 388 cpswaps (from->sequenceNumber, to->sequenceNumber); 389 cpswapl (from->time, to->time); 390 cpswapl (from->arg, to->arg); 391} 392 393static int 394SProcAppleDRIQueryVersion( 395 register ClientPtr client 396) 397{ 398 register int n; 399 REQUEST(xAppleDRIQueryVersionReq); 400 swaps(&stuff->length, n); 401 return ProcAppleDRIQueryVersion(client); 402} 403 404static int 405SProcAppleDRIDispatch ( 406 register ClientPtr client 407) 408{ 409 REQUEST(xReq); 410 411 /* It is bound to be non-local when there is byte swapping */ 412 if (!LocalClient(client)) 413 return DRIErrorBase + AppleDRIClientNotLocal; 414 415 /* only local clients are allowed DRI access */ 416 switch (stuff->data) 417 { 418 case X_AppleDRIQueryVersion: 419 return SProcAppleDRIQueryVersion(client); 420 default: 421 return BadRequest; 422 } 423} 424