appledri.c revision 4642e01f
1/************************************************************************** 2 3Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 4Copyright 2000 VA Linux Systems, Inc. 5Copyright (c) 2002 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#define NEED_REPLIES 43#define NEED_EVENTS 44#include <X11/X.h> 45#include <X11/Xproto.h> 46#include "misc.h" 47#include "dixstruct.h" 48#include "extnsionst.h" 49#include "colormapst.h" 50#include "cursorstr.h" 51#include "scrnintstr.h" 52#include "servermd.h" 53#define _APPLEDRI_SERVER_ 54#include "appledristr.h" 55#include "swaprep.h" 56#include "dri.h" 57#include "dristruct.h" 58#include "xpr.h" 59#include "x-hash.h" 60 61static int DRIErrorBase = 0; 62 63static DISPATCH_PROC(ProcAppleDRIDispatch); 64static DISPATCH_PROC(SProcAppleDRIDispatch); 65 66static void AppleDRIResetProc(ExtensionEntry* extEntry); 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 = APPLE_DRI_MAJOR_VERSION; 124 rep.minorVersion = APPLE_DRI_MINOR_VERSION; 125 rep.patchVersion = APPLE_DRI_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 (client->noClientException); 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 (client->noClientException); 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 (client->noClientException); 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 ClientPtr client; 196 xAppleDRINotifyEvent se; 197 198 if (client_index < 0 || client_index >= currentMaxClients) 199 return; 200 201 client = clients[client_index]; 202 if (client == NULL || client == serverClient || client->clientGone) 203 return; 204 205 se.type = DRIEventBase + AppleDRISurfaceNotify; 206 se.kind = arg->kind; 207 se.arg = arg->id; 208 se.sequenceNumber = client->sequence; 209 se.time = currentTime.milliseconds; 210 WriteEventsToClient (client, 1, (xEvent *) &se); 211} 212 213static int 214ProcAppleDRICreateSurface( 215 ClientPtr client 216) 217{ 218 xAppleDRICreateSurfaceReply rep; 219 DrawablePtr pDrawable; 220 xp_surface_id sid; 221 unsigned int key[2]; 222 int rc; 223 224 REQUEST(xAppleDRICreateSurfaceReq); 225 REQUEST_SIZE_MATCH(xAppleDRICreateSurfaceReq); 226 rep.type = X_Reply; 227 rep.length = 0; 228 rep.sequenceNumber = client->sequence; 229 230 rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 231 DixReadAccess); 232 if (rc != Success) 233 return rc; 234 235 rep.key_0 = rep.key_1 = rep.uid = 0; 236 237 if (!DRICreateSurface( screenInfo.screens[stuff->screen], 238 (Drawable)stuff->drawable, pDrawable, 239 stuff->client_id, &sid, key, 240 surface_notify, 241 x_cvt_uint_to_vptr(client->index))) { 242 return BadValue; 243 } 244 245 rep.key_0 = key[0]; 246 rep.key_1 = key[1]; 247 rep.uid = sid; 248 249 WriteToClient(client, sizeof(xAppleDRICreateSurfaceReply), (char *)&rep); 250 return (client->noClientException); 251} 252 253static int 254ProcAppleDRIDestroySurface( 255 register ClientPtr client 256) 257{ 258 REQUEST(xAppleDRIDestroySurfaceReq); 259 DrawablePtr pDrawable; 260 REQUEST_SIZE_MATCH(xAppleDRIDestroySurfaceReq); 261 int rc; 262 263 rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 264 DixReadAccess); 265 if (rc != Success) 266 return rc; 267 268 if (!DRIDestroySurface( screenInfo.screens[stuff->screen], 269 (Drawable)stuff->drawable, 270 pDrawable, NULL, NULL)) { 271 return BadValue; 272 } 273 274 return (client->noClientException); 275} 276 277 278/* dispatch */ 279 280static int 281ProcAppleDRIDispatch ( 282 register ClientPtr client 283) 284{ 285 REQUEST(xReq); 286 287 switch (stuff->data) 288 { 289 case X_AppleDRIQueryVersion: 290 return ProcAppleDRIQueryVersion(client); 291 case X_AppleDRIQueryDirectRenderingCapable: 292 return ProcAppleDRIQueryDirectRenderingCapable(client); 293 } 294 295 if (!LocalClient(client)) 296 return DRIErrorBase + AppleDRIClientNotLocal; 297 298 switch (stuff->data) 299 { 300 case X_AppleDRIAuthConnection: 301 return ProcAppleDRIAuthConnection(client); 302 case X_AppleDRICreateSurface: 303 return ProcAppleDRICreateSurface(client); 304 case X_AppleDRIDestroySurface: 305 return ProcAppleDRIDestroySurface(client); 306 default: 307 return BadRequest; 308 } 309} 310 311static void 312SNotifyEvent( 313 xAppleDRINotifyEvent *from, 314 xAppleDRINotifyEvent *to 315) 316{ 317 to->type = from->type; 318 to->kind = from->kind; 319 cpswaps (from->sequenceNumber, to->sequenceNumber); 320 cpswapl (from->time, to->time); 321 cpswapl (from->arg, to->arg); 322} 323 324static int 325SProcAppleDRIQueryVersion( 326 register ClientPtr client 327) 328{ 329 register int n; 330 REQUEST(xAppleDRIQueryVersionReq); 331 swaps(&stuff->length, n); 332 return ProcAppleDRIQueryVersion(client); 333} 334 335static int 336SProcAppleDRIDispatch ( 337 register ClientPtr client 338) 339{ 340 REQUEST(xReq); 341 342 /* It is bound to be non-local when there is byte swapping */ 343 if (!LocalClient(client)) 344 return DRIErrorBase + AppleDRIClientNotLocal; 345 346 /* only local clients are allowed DRI access */ 347 switch (stuff->data) 348 { 349 case X_AppleDRIQueryVersion: 350 return SProcAppleDRIQueryVersion(client); 351 default: 352 return BadRequest; 353 } 354} 355