1706f2543Smrg/************************************************************************** 2706f2543Smrg 3706f2543SmrgCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 4706f2543SmrgCopyright 2000 VA Linux Systems, Inc. 5706f2543SmrgAll Rights Reserved. 6706f2543Smrg 7706f2543SmrgPermission is hereby granted, free of charge, to any person obtaining a 8706f2543Smrgcopy of this software and associated documentation files (the 9706f2543Smrg"Software"), to deal in the Software without restriction, including 10706f2543Smrgwithout limitation the rights to use, copy, modify, merge, publish, 11706f2543Smrgdistribute, sub license, and/or sell copies of the Software, and to 12706f2543Smrgpermit persons to whom the Software is furnished to do so, subject to 13706f2543Smrgthe following conditions: 14706f2543Smrg 15706f2543SmrgThe above copyright notice and this permission notice (including the 16706f2543Smrgnext paragraph) shall be included in all copies or substantial portions 17706f2543Smrgof the Software. 18706f2543Smrg 19706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20706f2543SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21706f2543SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22706f2543SmrgIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 23706f2543SmrgANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24706f2543SmrgTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25706f2543SmrgSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26706f2543Smrg 27706f2543Smrg**************************************************************************/ 28706f2543Smrg 29706f2543Smrg/* 30706f2543Smrg * Authors: 31706f2543Smrg * Kevin E. Martin <martin@valinux.com> 32706f2543Smrg * Jens Owen <jens@tungstengraphics.com> 33706f2543Smrg * Rickard E. (Rik) Faith <faith@valinux.com> 34706f2543Smrg * 35706f2543Smrg */ 36706f2543Smrg 37706f2543Smrg#ifdef HAVE_XORG_CONFIG_H 38706f2543Smrg#include <xorg-config.h> 39706f2543Smrg#endif 40706f2543Smrg 41706f2543Smrg#include <string.h> 42706f2543Smrg 43706f2543Smrg#include "xf86.h" 44706f2543Smrg 45706f2543Smrg#include <X11/X.h> 46706f2543Smrg#include <X11/Xproto.h> 47706f2543Smrg#include "misc.h" 48706f2543Smrg#include "dixstruct.h" 49706f2543Smrg#include "extnsionst.h" 50706f2543Smrg#include "colormapst.h" 51706f2543Smrg#include "cursorstr.h" 52706f2543Smrg#include "scrnintstr.h" 53706f2543Smrg#include "servermd.h" 54706f2543Smrg#define _XF86DRI_SERVER_ 55706f2543Smrg#include <X11/dri/xf86driproto.h> 56706f2543Smrg#include "swaprep.h" 57706f2543Smrg#include "xf86str.h" 58706f2543Smrg#include "dri.h" 59706f2543Smrg#include "sarea.h" 60706f2543Smrg#include "dristruct.h" 61706f2543Smrg#include "xf86.h" 62706f2543Smrg#include "xf86drm.h" 63706f2543Smrg#include "protocol-versions.h" 64706f2543Smrg 65706f2543Smrgstatic int DRIErrorBase; 66706f2543Smrg 67706f2543Smrg 68706f2543Smrg 69706f2543Smrgstatic void XF86DRIResetProc(ExtensionEntry* extEntry); 70706f2543Smrg 71706f2543Smrgstatic unsigned char DRIReqCode = 0; 72706f2543Smrg 73706f2543Smrgextern void XFree86DRIExtensionInit(void); 74706f2543Smrg 75706f2543Smrg/*ARGSUSED*/ 76706f2543Smrgstatic void 77706f2543SmrgXF86DRIResetProc ( 78706f2543Smrg ExtensionEntry* extEntry 79706f2543Smrg) 80706f2543Smrg{ 81706f2543Smrg DRIReset(); 82706f2543Smrg} 83706f2543Smrg 84706f2543Smrgstatic int 85706f2543SmrgProcXF86DRIQueryVersion( 86706f2543Smrg register ClientPtr client 87706f2543Smrg) 88706f2543Smrg{ 89706f2543Smrg xXF86DRIQueryVersionReply rep; 90706f2543Smrg register int n; 91706f2543Smrg 92706f2543Smrg REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq); 93706f2543Smrg rep.type = X_Reply; 94706f2543Smrg rep.length = 0; 95706f2543Smrg rep.sequenceNumber = client->sequence; 96706f2543Smrg rep.majorVersion = SERVER_XF86DRI_MAJOR_VERSION; 97706f2543Smrg rep.minorVersion = SERVER_XF86DRI_MINOR_VERSION; 98706f2543Smrg rep.patchVersion = SERVER_XF86DRI_PATCH_VERSION; 99706f2543Smrg if (client->swapped) { 100706f2543Smrg swaps(&rep.sequenceNumber, n); 101706f2543Smrg swapl(&rep.length, n); 102706f2543Smrg swaps(&rep.majorVersion, n); 103706f2543Smrg swaps(&rep.minorVersion, n); 104706f2543Smrg swapl(&rep.patchVersion, n); 105706f2543Smrg } 106706f2543Smrg WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep); 107706f2543Smrg return Success; 108706f2543Smrg} 109706f2543Smrg 110706f2543Smrgstatic int 111706f2543SmrgProcXF86DRIQueryDirectRenderingCapable( 112706f2543Smrg register ClientPtr client 113706f2543Smrg) 114706f2543Smrg{ 115706f2543Smrg xXF86DRIQueryDirectRenderingCapableReply rep; 116706f2543Smrg Bool isCapable; 117706f2543Smrg register int n; 118706f2543Smrg 119706f2543Smrg REQUEST(xXF86DRIQueryDirectRenderingCapableReq); 120706f2543Smrg REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq); 121706f2543Smrg if (stuff->screen >= screenInfo.numScreens) { 122706f2543Smrg client->errorValue = stuff->screen; 123706f2543Smrg return BadValue; 124706f2543Smrg } 125706f2543Smrg 126706f2543Smrg rep.type = X_Reply; 127706f2543Smrg rep.length = 0; 128706f2543Smrg rep.sequenceNumber = client->sequence; 129706f2543Smrg 130706f2543Smrg if (!DRIQueryDirectRenderingCapable( screenInfo.screens[stuff->screen], 131706f2543Smrg &isCapable)) { 132706f2543Smrg return BadValue; 133706f2543Smrg } 134706f2543Smrg rep.isCapable = isCapable; 135706f2543Smrg 136706f2543Smrg if (!LocalClient(client) || client->swapped) 137706f2543Smrg rep.isCapable = 0; 138706f2543Smrg 139706f2543Smrg if (client->swapped) { 140706f2543Smrg swaps(&rep.sequenceNumber, n); 141706f2543Smrg swapl(&rep.length, n); 142706f2543Smrg } 143706f2543Smrg 144706f2543Smrg WriteToClient(client, 145706f2543Smrg sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep); 146706f2543Smrg return Success; 147706f2543Smrg} 148706f2543Smrg 149706f2543Smrgstatic int 150706f2543SmrgProcXF86DRIOpenConnection( 151706f2543Smrg register ClientPtr client 152706f2543Smrg) 153706f2543Smrg{ 154706f2543Smrg xXF86DRIOpenConnectionReply rep; 155706f2543Smrg drm_handle_t hSAREA; 156706f2543Smrg char* busIdString; 157706f2543Smrg 158706f2543Smrg REQUEST(xXF86DRIOpenConnectionReq); 159706f2543Smrg REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq); 160706f2543Smrg if (stuff->screen >= screenInfo.numScreens) { 161706f2543Smrg client->errorValue = stuff->screen; 162706f2543Smrg return BadValue; 163706f2543Smrg } 164706f2543Smrg 165706f2543Smrg if (!DRIOpenConnection( screenInfo.screens[stuff->screen], 166706f2543Smrg &hSAREA, 167706f2543Smrg &busIdString)) { 168706f2543Smrg return BadValue; 169706f2543Smrg } 170706f2543Smrg 171706f2543Smrg rep.type = X_Reply; 172706f2543Smrg rep.sequenceNumber = client->sequence; 173706f2543Smrg rep.busIdStringLength = 0; 174706f2543Smrg if (busIdString) 175706f2543Smrg rep.busIdStringLength = strlen(busIdString); 176706f2543Smrg rep.length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) + 177706f2543Smrg pad_to_int32(rep.busIdStringLength)); 178706f2543Smrg 179706f2543Smrg rep.hSAREALow = (CARD32)(hSAREA & 0xffffffff); 180706f2543Smrg#if defined(LONG64) && !defined(__linux__) 181706f2543Smrg rep.hSAREAHigh = (CARD32)(hSAREA >> 32); 182706f2543Smrg#else 183706f2543Smrg rep.hSAREAHigh = 0; 184706f2543Smrg#endif 185706f2543Smrg 186706f2543Smrg WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep); 187706f2543Smrg if (rep.busIdStringLength) 188706f2543Smrg WriteToClient(client, rep.busIdStringLength, busIdString); 189706f2543Smrg return Success; 190706f2543Smrg} 191706f2543Smrg 192706f2543Smrgstatic int 193706f2543SmrgProcXF86DRIAuthConnection( 194706f2543Smrg register ClientPtr client 195706f2543Smrg) 196706f2543Smrg{ 197706f2543Smrg xXF86DRIAuthConnectionReply rep; 198706f2543Smrg 199706f2543Smrg REQUEST(xXF86DRIAuthConnectionReq); 200706f2543Smrg REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq); 201706f2543Smrg if (stuff->screen >= screenInfo.numScreens) { 202706f2543Smrg client->errorValue = stuff->screen; 203706f2543Smrg return BadValue; 204706f2543Smrg } 205706f2543Smrg 206706f2543Smrg rep.type = X_Reply; 207706f2543Smrg rep.length = 0; 208706f2543Smrg rep.sequenceNumber = client->sequence; 209706f2543Smrg rep.authenticated = 1; 210706f2543Smrg 211706f2543Smrg if (!DRIAuthConnection( screenInfo.screens[stuff->screen], stuff->magic)) { 212706f2543Smrg ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic); 213706f2543Smrg rep.authenticated = 0; 214706f2543Smrg } 215706f2543Smrg WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep); 216706f2543Smrg return Success; 217706f2543Smrg} 218706f2543Smrg 219706f2543Smrgstatic int 220706f2543SmrgProcXF86DRICloseConnection( 221706f2543Smrg register ClientPtr client 222706f2543Smrg) 223706f2543Smrg{ 224706f2543Smrg REQUEST(xXF86DRICloseConnectionReq); 225706f2543Smrg REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq); 226706f2543Smrg if (stuff->screen >= screenInfo.numScreens) { 227706f2543Smrg client->errorValue = stuff->screen; 228706f2543Smrg return BadValue; 229706f2543Smrg } 230706f2543Smrg 231706f2543Smrg DRICloseConnection( screenInfo.screens[stuff->screen]); 232706f2543Smrg 233706f2543Smrg return Success; 234706f2543Smrg} 235706f2543Smrg 236706f2543Smrgstatic int 237706f2543SmrgProcXF86DRIGetClientDriverName( 238706f2543Smrg register ClientPtr client 239706f2543Smrg) 240706f2543Smrg{ 241706f2543Smrg xXF86DRIGetClientDriverNameReply rep; 242706f2543Smrg char* clientDriverName; 243706f2543Smrg 244706f2543Smrg REQUEST(xXF86DRIGetClientDriverNameReq); 245706f2543Smrg REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq); 246706f2543Smrg if (stuff->screen >= screenInfo.numScreens) { 247706f2543Smrg client->errorValue = stuff->screen; 248706f2543Smrg return BadValue; 249706f2543Smrg } 250706f2543Smrg 251706f2543Smrg DRIGetClientDriverName( screenInfo.screens[stuff->screen], 252706f2543Smrg (int *)&rep.ddxDriverMajorVersion, 253706f2543Smrg (int *)&rep.ddxDriverMinorVersion, 254706f2543Smrg (int *)&rep.ddxDriverPatchVersion, 255706f2543Smrg &clientDriverName); 256706f2543Smrg 257706f2543Smrg rep.type = X_Reply; 258706f2543Smrg rep.sequenceNumber = client->sequence; 259706f2543Smrg rep.clientDriverNameLength = 0; 260706f2543Smrg if (clientDriverName) 261706f2543Smrg rep.clientDriverNameLength = strlen(clientDriverName); 262706f2543Smrg rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) - 263706f2543Smrg SIZEOF(xGenericReply) + 264706f2543Smrg pad_to_int32(rep.clientDriverNameLength)); 265706f2543Smrg 266706f2543Smrg WriteToClient(client, 267706f2543Smrg sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep); 268706f2543Smrg if (rep.clientDriverNameLength) 269706f2543Smrg WriteToClient(client, 270706f2543Smrg rep.clientDriverNameLength, 271706f2543Smrg clientDriverName); 272706f2543Smrg return Success; 273706f2543Smrg} 274706f2543Smrg 275706f2543Smrgstatic int 276706f2543SmrgProcXF86DRICreateContext( 277706f2543Smrg register ClientPtr client 278706f2543Smrg) 279706f2543Smrg{ 280706f2543Smrg xXF86DRICreateContextReply rep; 281706f2543Smrg ScreenPtr pScreen; 282706f2543Smrg 283706f2543Smrg REQUEST(xXF86DRICreateContextReq); 284706f2543Smrg REQUEST_SIZE_MATCH(xXF86DRICreateContextReq); 285706f2543Smrg if (stuff->screen >= screenInfo.numScreens) { 286706f2543Smrg client->errorValue = stuff->screen; 287706f2543Smrg return BadValue; 288706f2543Smrg } 289706f2543Smrg 290706f2543Smrg rep.type = X_Reply; 291706f2543Smrg rep.length = 0; 292706f2543Smrg rep.sequenceNumber = client->sequence; 293706f2543Smrg 294706f2543Smrg pScreen = screenInfo.screens[stuff->screen]; 295706f2543Smrg 296706f2543Smrg if (!DRICreateContext( pScreen, 297706f2543Smrg NULL, 298706f2543Smrg stuff->context, 299706f2543Smrg (drm_context_t *)&rep.hHWContext)) { 300706f2543Smrg return BadValue; 301706f2543Smrg } 302706f2543Smrg 303706f2543Smrg WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep); 304706f2543Smrg return Success; 305706f2543Smrg} 306706f2543Smrg 307706f2543Smrgstatic int 308706f2543SmrgProcXF86DRIDestroyContext( 309706f2543Smrg register ClientPtr client 310706f2543Smrg) 311706f2543Smrg{ 312706f2543Smrg REQUEST(xXF86DRIDestroyContextReq); 313706f2543Smrg REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq); 314706f2543Smrg if (stuff->screen >= screenInfo.numScreens) { 315706f2543Smrg client->errorValue = stuff->screen; 316706f2543Smrg return BadValue; 317706f2543Smrg } 318706f2543Smrg 319706f2543Smrg if (!DRIDestroyContext( screenInfo.screens[stuff->screen], 320706f2543Smrg stuff->context)) { 321706f2543Smrg return BadValue; 322706f2543Smrg } 323706f2543Smrg 324706f2543Smrg return Success; 325706f2543Smrg} 326706f2543Smrg 327706f2543Smrgstatic int 328706f2543SmrgProcXF86DRICreateDrawable( 329706f2543Smrg ClientPtr client 330706f2543Smrg) 331706f2543Smrg{ 332706f2543Smrg xXF86DRICreateDrawableReply rep; 333706f2543Smrg DrawablePtr pDrawable; 334706f2543Smrg int rc; 335706f2543Smrg 336706f2543Smrg REQUEST(xXF86DRICreateDrawableReq); 337706f2543Smrg REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq); 338706f2543Smrg if (stuff->screen >= screenInfo.numScreens) { 339706f2543Smrg client->errorValue = stuff->screen; 340706f2543Smrg return BadValue; 341706f2543Smrg } 342706f2543Smrg 343706f2543Smrg rep.type = X_Reply; 344706f2543Smrg rep.length = 0; 345706f2543Smrg rep.sequenceNumber = client->sequence; 346706f2543Smrg 347706f2543Smrg rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 348706f2543Smrg DixReadAccess); 349706f2543Smrg if (rc != Success) 350706f2543Smrg return rc; 351706f2543Smrg 352706f2543Smrg if (!DRICreateDrawable(screenInfo.screens[stuff->screen], client, 353706f2543Smrg pDrawable, (drm_drawable_t *)&rep.hHWDrawable)) { 354706f2543Smrg return BadValue; 355706f2543Smrg } 356706f2543Smrg 357706f2543Smrg WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep); 358706f2543Smrg return Success; 359706f2543Smrg} 360706f2543Smrg 361706f2543Smrgstatic int 362706f2543SmrgProcXF86DRIDestroyDrawable( 363706f2543Smrg register ClientPtr client 364706f2543Smrg) 365706f2543Smrg{ 366706f2543Smrg REQUEST(xXF86DRIDestroyDrawableReq); 367706f2543Smrg DrawablePtr pDrawable; 368706f2543Smrg int rc; 369706f2543Smrg REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq); 370706f2543Smrg 371706f2543Smrg if (stuff->screen >= screenInfo.numScreens) { 372706f2543Smrg client->errorValue = stuff->screen; 373706f2543Smrg return BadValue; 374706f2543Smrg } 375706f2543Smrg 376706f2543Smrg rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 377706f2543Smrg DixReadAccess); 378706f2543Smrg if (rc != Success) 379706f2543Smrg return rc; 380706f2543Smrg 381706f2543Smrg if (!DRIDestroyDrawable(screenInfo.screens[stuff->screen], client, 382706f2543Smrg pDrawable)) { 383706f2543Smrg return BadValue; 384706f2543Smrg } 385706f2543Smrg 386706f2543Smrg return Success; 387706f2543Smrg} 388706f2543Smrg 389706f2543Smrgstatic int 390706f2543SmrgProcXF86DRIGetDrawableInfo( 391706f2543Smrg register ClientPtr client 392706f2543Smrg) 393706f2543Smrg{ 394706f2543Smrg xXF86DRIGetDrawableInfoReply rep; 395706f2543Smrg DrawablePtr pDrawable; 396706f2543Smrg int X, Y, W, H; 397706f2543Smrg drm_clip_rect_t * pClipRects, *pClippedRects; 398706f2543Smrg drm_clip_rect_t * pBackClipRects; 399706f2543Smrg int backX, backY, rc; 400706f2543Smrg 401706f2543Smrg REQUEST(xXF86DRIGetDrawableInfoReq); 402706f2543Smrg REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq); 403706f2543Smrg if (stuff->screen >= screenInfo.numScreens) { 404706f2543Smrg client->errorValue = stuff->screen; 405706f2543Smrg return BadValue; 406706f2543Smrg } 407706f2543Smrg 408706f2543Smrg rep.type = X_Reply; 409706f2543Smrg rep.length = 0; 410706f2543Smrg rep.sequenceNumber = client->sequence; 411706f2543Smrg 412706f2543Smrg rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 413706f2543Smrg DixReadAccess); 414706f2543Smrg if (rc != Success) 415706f2543Smrg return rc; 416706f2543Smrg 417706f2543Smrg if (!DRIGetDrawableInfo( screenInfo.screens[stuff->screen], 418706f2543Smrg pDrawable, 419706f2543Smrg (unsigned int*)&rep.drawableTableIndex, 420706f2543Smrg (unsigned int*)&rep.drawableTableStamp, 421706f2543Smrg (int*)&X, 422706f2543Smrg (int*)&Y, 423706f2543Smrg (int*)&W, 424706f2543Smrg (int*)&H, 425706f2543Smrg (int*)&rep.numClipRects, 426706f2543Smrg &pClipRects, 427706f2543Smrg &backX, 428706f2543Smrg &backY, 429706f2543Smrg (int*)&rep.numBackClipRects, 430706f2543Smrg &pBackClipRects)) { 431706f2543Smrg return BadValue; 432706f2543Smrg } 433706f2543Smrg 434706f2543Smrg rep.drawableX = X; 435706f2543Smrg rep.drawableY = Y; 436706f2543Smrg rep.drawableWidth = W; 437706f2543Smrg rep.drawableHeight = H; 438706f2543Smrg rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) - 439706f2543Smrg SIZEOF(xGenericReply)); 440706f2543Smrg 441706f2543Smrg rep.backX = backX; 442706f2543Smrg rep.backY = backY; 443706f2543Smrg 444706f2543Smrg if (rep.numBackClipRects) 445706f2543Smrg rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects; 446706f2543Smrg 447706f2543Smrg pClippedRects = pClipRects; 448706f2543Smrg 449706f2543Smrg if (rep.numClipRects) { 450706f2543Smrg /* Clip cliprects to screen dimensions (redirected windows) */ 451706f2543Smrg pClippedRects = malloc(rep.numClipRects * sizeof(drm_clip_rect_t)); 452706f2543Smrg 453706f2543Smrg if (pClippedRects) { 454706f2543Smrg ScreenPtr pScreen = screenInfo.screens[stuff->screen]; 455706f2543Smrg int i, j; 456706f2543Smrg 457706f2543Smrg for (i = 0, j = 0; i < rep.numClipRects; i++) { 458706f2543Smrg pClippedRects[j].x1 = max(pClipRects[i].x1, 0); 459706f2543Smrg pClippedRects[j].y1 = max(pClipRects[i].y1, 0); 460706f2543Smrg pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width); 461706f2543Smrg pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height); 462706f2543Smrg 463706f2543Smrg if (pClippedRects[j].x1 < pClippedRects[j].x2 && 464706f2543Smrg pClippedRects[j].y1 < pClippedRects[j].y2) { 465706f2543Smrg j++; 466706f2543Smrg } 467706f2543Smrg } 468706f2543Smrg 469706f2543Smrg rep.numClipRects = j; 470706f2543Smrg } else { 471706f2543Smrg rep.numClipRects = 0; 472706f2543Smrg } 473706f2543Smrg 474706f2543Smrg rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects; 475706f2543Smrg } 476706f2543Smrg 477706f2543Smrg rep.length = bytes_to_int32(rep.length); 478706f2543Smrg 479706f2543Smrg WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep); 480706f2543Smrg 481706f2543Smrg if (rep.numClipRects) { 482706f2543Smrg WriteToClient(client, 483706f2543Smrg sizeof(drm_clip_rect_t) * rep.numClipRects, 484706f2543Smrg (char *)pClippedRects); 485706f2543Smrg free(pClippedRects); 486706f2543Smrg } 487706f2543Smrg 488706f2543Smrg if (rep.numBackClipRects) { 489706f2543Smrg WriteToClient(client, 490706f2543Smrg sizeof(drm_clip_rect_t) * rep.numBackClipRects, 491706f2543Smrg (char *)pBackClipRects); 492706f2543Smrg } 493706f2543Smrg 494706f2543Smrg return Success; 495706f2543Smrg} 496706f2543Smrg 497706f2543Smrgstatic int 498706f2543SmrgProcXF86DRIGetDeviceInfo( 499706f2543Smrg register ClientPtr client 500706f2543Smrg) 501706f2543Smrg{ 502706f2543Smrg xXF86DRIGetDeviceInfoReply rep; 503706f2543Smrg drm_handle_t hFrameBuffer; 504706f2543Smrg void *pDevPrivate; 505706f2543Smrg 506706f2543Smrg REQUEST(xXF86DRIGetDeviceInfoReq); 507706f2543Smrg REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq); 508706f2543Smrg if (stuff->screen >= screenInfo.numScreens) { 509706f2543Smrg client->errorValue = stuff->screen; 510706f2543Smrg return BadValue; 511706f2543Smrg } 512706f2543Smrg 513706f2543Smrg rep.type = X_Reply; 514706f2543Smrg rep.length = 0; 515706f2543Smrg rep.sequenceNumber = client->sequence; 516706f2543Smrg 517706f2543Smrg if (!DRIGetDeviceInfo( screenInfo.screens[stuff->screen], 518706f2543Smrg &hFrameBuffer, 519706f2543Smrg (int*)&rep.framebufferOrigin, 520706f2543Smrg (int*)&rep.framebufferSize, 521706f2543Smrg (int*)&rep.framebufferStride, 522706f2543Smrg (int*)&rep.devPrivateSize, 523706f2543Smrg &pDevPrivate)) { 524706f2543Smrg return BadValue; 525706f2543Smrg } 526706f2543Smrg 527706f2543Smrg rep.hFrameBufferLow = (CARD32)(hFrameBuffer & 0xffffffff); 528706f2543Smrg#if defined(LONG64) && !defined(__linux__) 529706f2543Smrg rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32); 530706f2543Smrg#else 531706f2543Smrg rep.hFrameBufferHigh = 0; 532706f2543Smrg#endif 533706f2543Smrg 534706f2543Smrg rep.length = 0; 535706f2543Smrg if (rep.devPrivateSize) { 536706f2543Smrg rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) - 537706f2543Smrg SIZEOF(xGenericReply) + 538706f2543Smrg pad_to_int32(rep.devPrivateSize)); 539706f2543Smrg } 540706f2543Smrg 541706f2543Smrg WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep); 542706f2543Smrg if (rep.length) { 543706f2543Smrg WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate); 544706f2543Smrg } 545706f2543Smrg return Success; 546706f2543Smrg} 547706f2543Smrg 548706f2543Smrgstatic int 549706f2543SmrgProcXF86DRIDispatch ( 550706f2543Smrg register ClientPtr client 551706f2543Smrg) 552706f2543Smrg{ 553706f2543Smrg REQUEST(xReq); 554706f2543Smrg 555706f2543Smrg switch (stuff->data) 556706f2543Smrg { 557706f2543Smrg case X_XF86DRIQueryVersion: 558706f2543Smrg return ProcXF86DRIQueryVersion(client); 559706f2543Smrg case X_XF86DRIQueryDirectRenderingCapable: 560706f2543Smrg return ProcXF86DRIQueryDirectRenderingCapable(client); 561706f2543Smrg } 562706f2543Smrg 563706f2543Smrg if (!LocalClient(client)) 564706f2543Smrg return DRIErrorBase + XF86DRIClientNotLocal; 565706f2543Smrg 566706f2543Smrg switch (stuff->data) 567706f2543Smrg { 568706f2543Smrg case X_XF86DRIOpenConnection: 569706f2543Smrg return ProcXF86DRIOpenConnection(client); 570706f2543Smrg case X_XF86DRICloseConnection: 571706f2543Smrg return ProcXF86DRICloseConnection(client); 572706f2543Smrg case X_XF86DRIGetClientDriverName: 573706f2543Smrg return ProcXF86DRIGetClientDriverName(client); 574706f2543Smrg case X_XF86DRICreateContext: 575706f2543Smrg return ProcXF86DRICreateContext(client); 576706f2543Smrg case X_XF86DRIDestroyContext: 577706f2543Smrg return ProcXF86DRIDestroyContext(client); 578706f2543Smrg case X_XF86DRICreateDrawable: 579706f2543Smrg return ProcXF86DRICreateDrawable(client); 580706f2543Smrg case X_XF86DRIDestroyDrawable: 581706f2543Smrg return ProcXF86DRIDestroyDrawable(client); 582706f2543Smrg case X_XF86DRIGetDrawableInfo: 583706f2543Smrg return ProcXF86DRIGetDrawableInfo(client); 584706f2543Smrg case X_XF86DRIGetDeviceInfo: 585706f2543Smrg return ProcXF86DRIGetDeviceInfo(client); 586706f2543Smrg case X_XF86DRIAuthConnection: 587706f2543Smrg return ProcXF86DRIAuthConnection(client); 588706f2543Smrg /* {Open,Close}FullScreen are deprecated now */ 589706f2543Smrg default: 590706f2543Smrg return BadRequest; 591706f2543Smrg } 592706f2543Smrg} 593706f2543Smrg 594706f2543Smrgstatic int 595706f2543SmrgSProcXF86DRIQueryVersion( 596706f2543Smrg register ClientPtr client 597706f2543Smrg) 598706f2543Smrg{ 599706f2543Smrg register int n; 600706f2543Smrg REQUEST(xXF86DRIQueryVersionReq); 601706f2543Smrg swaps(&stuff->length, n); 602706f2543Smrg return ProcXF86DRIQueryVersion(client); 603706f2543Smrg} 604706f2543Smrg 605706f2543Smrgstatic int 606706f2543SmrgSProcXF86DRIQueryDirectRenderingCapable( 607706f2543Smrg register ClientPtr client 608706f2543Smrg) 609706f2543Smrg{ 610706f2543Smrg register int n; 611706f2543Smrg REQUEST(xXF86DRIQueryDirectRenderingCapableReq); 61248a68b89Smrg REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq); 613706f2543Smrg swaps(&stuff->length, n); 614706f2543Smrg swapl(&stuff->screen, n); 615706f2543Smrg return ProcXF86DRIQueryDirectRenderingCapable(client); 616706f2543Smrg} 617706f2543Smrg 618706f2543Smrgstatic int 619706f2543SmrgSProcXF86DRIDispatch ( 620706f2543Smrg register ClientPtr client 621706f2543Smrg) 622706f2543Smrg{ 623706f2543Smrg REQUEST(xReq); 624706f2543Smrg 625706f2543Smrg /* 626706f2543Smrg * Only local clients are allowed DRI access, but remote clients still need 627706f2543Smrg * these requests to find out cleanly. 628706f2543Smrg */ 629706f2543Smrg switch (stuff->data) 630706f2543Smrg { 631706f2543Smrg case X_XF86DRIQueryVersion: 632706f2543Smrg return SProcXF86DRIQueryVersion(client); 633706f2543Smrg case X_XF86DRIQueryDirectRenderingCapable: 634706f2543Smrg return SProcXF86DRIQueryDirectRenderingCapable(client); 635706f2543Smrg default: 636706f2543Smrg return DRIErrorBase + XF86DRIClientNotLocal; 637706f2543Smrg } 638706f2543Smrg} 639706f2543Smrg 640706f2543Smrgvoid 641706f2543SmrgXFree86DRIExtensionInit(void) 642706f2543Smrg{ 643706f2543Smrg ExtensionEntry* extEntry; 644706f2543Smrg 645706f2543Smrg#ifdef XF86DRI_EVENTS 646706f2543Smrg EventType = CreateNewResourceType(XF86DRIFreeEvents, "DRIEvent"); 647706f2543Smrg#endif 648706f2543Smrg 649706f2543Smrg if ( 650706f2543Smrg DRIExtensionInit() && 651706f2543Smrg#ifdef XF86DRI_EVENTS 652706f2543Smrg EventType && ScreenPrivateIndex != -1 && 653706f2543Smrg#endif 654706f2543Smrg (extEntry = AddExtension(XF86DRINAME, 655706f2543Smrg XF86DRINumberEvents, 656706f2543Smrg XF86DRINumberErrors, 657706f2543Smrg ProcXF86DRIDispatch, 658706f2543Smrg SProcXF86DRIDispatch, 659706f2543Smrg XF86DRIResetProc, 660706f2543Smrg StandardMinorOpcode))) { 661706f2543Smrg DRIReqCode = (unsigned char)extEntry->base; 662706f2543Smrg DRIErrorBase = extEntry->errorBase; 663706f2543Smrg } 664706f2543Smrg} 665