dri2.c revision af69d88d
1cdc920a0Smrg/* 2cdc920a0Smrg * Copyright © 2008 Red Hat, Inc. 3cdc920a0Smrg * 4cdc920a0Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5cdc920a0Smrg * copy of this software and associated documentation files (the "Soft- 6cdc920a0Smrg * ware"), to deal in the Software without restriction, including without 7cdc920a0Smrg * limitation the rights to use, copy, modify, merge, publish, distribute, 8cdc920a0Smrg * and/or sell copies of the Software, and to permit persons to whom the 9cdc920a0Smrg * Software is furnished to do so, provided that the above copyright 10cdc920a0Smrg * notice(s) and this permission notice appear in all copies of the Soft- 11cdc920a0Smrg * ware and that both the above copyright notice(s) and this permission 12cdc920a0Smrg * notice appear in supporting documentation. 13cdc920a0Smrg * 14cdc920a0Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15cdc920a0Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- 16cdc920a0Smrg * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY 17cdc920a0Smrg * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN 18cdc920a0Smrg * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- 19cdc920a0Smrg * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 20cdc920a0Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 21cdc920a0Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- 22cdc920a0Smrg * MANCE OF THIS SOFTWARE. 23cdc920a0Smrg * 24cdc920a0Smrg * Except as contained in this notice, the name of a copyright holder shall 25cdc920a0Smrg * not be used in advertising or otherwise to promote the sale, use or 26cdc920a0Smrg * other dealings in this Software without prior written authorization of 27cdc920a0Smrg * the copyright holder. 28cdc920a0Smrg * 29cdc920a0Smrg * Authors: 30cdc920a0Smrg * Kristian Høgsberg (krh@redhat.com) 31cdc920a0Smrg */ 32cdc920a0Smrg 33cdc920a0Smrg 34cdc920a0Smrg#ifdef GLX_DIRECT_RENDERING 35cdc920a0Smrg 36cdc920a0Smrg#include <stdio.h> 37cdc920a0Smrg#include <X11/Xlibint.h> 38cdc920a0Smrg#include <X11/extensions/Xext.h> 39cdc920a0Smrg#include <X11/extensions/extutil.h> 40cdc920a0Smrg#include <X11/extensions/dri2proto.h> 41cdc920a0Smrg#include "dri2.h" 42cdc920a0Smrg#include "glxclient.h" 43cdc920a0Smrg#include "GL/glxext.h" 44cdc920a0Smrg 45cdc920a0Smrg/* Allow the build to work with an older versions of dri2proto.h and 46cdc920a0Smrg * dri2tokens.h. 47cdc920a0Smrg */ 48cdc920a0Smrg#if DRI2_MINOR < 1 49cdc920a0Smrg#undef DRI2_MINOR 50cdc920a0Smrg#define DRI2_MINOR 1 51cdc920a0Smrg#define X_DRI2GetBuffersWithFormat 7 52cdc920a0Smrg#endif 53cdc920a0Smrg 54cdc920a0Smrg 55cdc920a0Smrgstatic char dri2ExtensionName[] = DRI2_NAME; 56cdc920a0Smrgstatic XExtensionInfo *dri2Info; 57cdc920a0Smrgstatic XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info) 58cdc920a0Smrg 59cdc920a0Smrgstatic Bool 60cdc920a0SmrgDRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire); 61cdc920a0Smrgstatic Status 62cdc920a0SmrgDRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire); 63cdc920a0Smrgstatic int 64cdc920a0SmrgDRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code); 65cdc920a0Smrg 66cdc920a0Smrgstatic /* const */ XExtensionHooks dri2ExtensionHooks = { 67cdc920a0Smrg NULL, /* create_gc */ 68cdc920a0Smrg NULL, /* copy_gc */ 69cdc920a0Smrg NULL, /* flush_gc */ 70cdc920a0Smrg NULL, /* free_gc */ 71cdc920a0Smrg NULL, /* create_font */ 72cdc920a0Smrg NULL, /* free_font */ 73cdc920a0Smrg DRI2CloseDisplay, /* close_display */ 74cdc920a0Smrg DRI2WireToEvent, /* wire_to_event */ 75cdc920a0Smrg DRI2EventToWire, /* event_to_wire */ 76cdc920a0Smrg DRI2Error, /* error */ 77cdc920a0Smrg NULL, /* error_string */ 78cdc920a0Smrg}; 79cdc920a0Smrg 80cdc920a0Smrgstatic XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, 81cdc920a0Smrg dri2Info, 82cdc920a0Smrg dri2ExtensionName, 83cdc920a0Smrg &dri2ExtensionHooks, 84cdc920a0Smrg 0, NULL) 85cdc920a0Smrg 86cdc920a0Smrgstatic Bool 87cdc920a0SmrgDRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) 88cdc920a0Smrg{ 89cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 90af69d88dSmrg struct glx_drawable *glxDraw; 91cdc920a0Smrg 92cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 93cdc920a0Smrg 94cdc920a0Smrg switch ((wire->u.u.type & 0x7f) - info->codes->first_event) { 95cdc920a0Smrg 96cdc920a0Smrg#ifdef X_DRI2SwapBuffers 97cdc920a0Smrg case DRI2_BufferSwapComplete: 98cdc920a0Smrg { 99cdc920a0Smrg GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event; 100af69d88dSmrg xDRI2BufferSwapComplete2 *awire = (xDRI2BufferSwapComplete2 *)wire; 101af69d88dSmrg __GLXDRIdrawable *pdraw; 102af69d88dSmrg 103af69d88dSmrg pdraw = dri2GetGlxDrawableFromXDrawableId(dpy, awire->drawable); 104af69d88dSmrg if (pdraw == NULL) 105af69d88dSmrg return False; 1063464ebd5Sriastradh 1073464ebd5Sriastradh /* Ignore swap events if we're not looking for them */ 1083464ebd5Sriastradh aevent->type = dri2GetSwapEventType(dpy, awire->drawable); 1093464ebd5Sriastradh if(!aevent->type) 1103464ebd5Sriastradh return False; 1113464ebd5Sriastradh 112cdc920a0Smrg aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire); 113cdc920a0Smrg aevent->send_event = (awire->type & 0x80) != 0; 114cdc920a0Smrg aevent->display = dpy; 115cdc920a0Smrg aevent->drawable = awire->drawable; 116cdc920a0Smrg switch (awire->event_type) { 117cdc920a0Smrg case DRI2_EXCHANGE_COMPLETE: 118cdc920a0Smrg aevent->event_type = GLX_EXCHANGE_COMPLETE_INTEL; 119cdc920a0Smrg break; 120cdc920a0Smrg case DRI2_BLIT_COMPLETE: 121cdc920a0Smrg aevent->event_type = GLX_COPY_COMPLETE_INTEL; 122cdc920a0Smrg break; 123cdc920a0Smrg case DRI2_FLIP_COMPLETE: 124cdc920a0Smrg aevent->event_type = GLX_FLIP_COMPLETE_INTEL; 125cdc920a0Smrg break; 126cdc920a0Smrg default: 127cdc920a0Smrg /* unknown swap completion type */ 128cdc920a0Smrg return False; 129cdc920a0Smrg } 130cdc920a0Smrg aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo; 131cdc920a0Smrg aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo; 132af69d88dSmrg 133af69d88dSmrg glxDraw = GetGLXDrawable(dpy, pdraw->drawable); 134af69d88dSmrg if (glxDraw != NULL) { 135af69d88dSmrg if (awire->sbc < glxDraw->lastEventSbc) 136af69d88dSmrg glxDraw->eventSbcWrap += 0x100000000; 137af69d88dSmrg glxDraw->lastEventSbc = awire->sbc; 138af69d88dSmrg aevent->sbc = awire->sbc + glxDraw->eventSbcWrap; 139af69d88dSmrg } else { 140af69d88dSmrg aevent->sbc = awire->sbc; 141af69d88dSmrg } 142af69d88dSmrg 143cdc920a0Smrg return True; 144cdc920a0Smrg } 145cdc920a0Smrg#endif 146cdc920a0Smrg#ifdef DRI2_InvalidateBuffers 147cdc920a0Smrg case DRI2_InvalidateBuffers: 148cdc920a0Smrg { 149cdc920a0Smrg xDRI2InvalidateBuffers *awire = (xDRI2InvalidateBuffers *)wire; 150cdc920a0Smrg 151cdc920a0Smrg dri2InvalidateBuffers(dpy, awire->drawable); 152cdc920a0Smrg return False; 153cdc920a0Smrg } 154cdc920a0Smrg#endif 155cdc920a0Smrg default: 156cdc920a0Smrg /* client doesn't support server event */ 157cdc920a0Smrg break; 158cdc920a0Smrg } 159cdc920a0Smrg 160cdc920a0Smrg return False; 161cdc920a0Smrg} 162cdc920a0Smrg 163cdc920a0Smrg/* We don't actually support this. It doesn't make sense for clients to 164cdc920a0Smrg * send each other DRI2 events. 165cdc920a0Smrg */ 166cdc920a0Smrgstatic Status 167cdc920a0SmrgDRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire) 168cdc920a0Smrg{ 169cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 170cdc920a0Smrg 171cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 172cdc920a0Smrg 173cdc920a0Smrg switch (event->type) { 174cdc920a0Smrg default: 175cdc920a0Smrg /* client doesn't support server event */ 176cdc920a0Smrg break; 177cdc920a0Smrg } 178cdc920a0Smrg 179cdc920a0Smrg return Success; 180cdc920a0Smrg} 181cdc920a0Smrg 182cdc920a0Smrgstatic int 183cdc920a0SmrgDRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code) 184cdc920a0Smrg{ 185cdc920a0Smrg if (err->majorCode == codes->major_opcode && 186cdc920a0Smrg err->errorCode == BadDrawable && 187cdc920a0Smrg err->minorCode == X_DRI2CopyRegion) 188cdc920a0Smrg return True; 189cdc920a0Smrg 1903464ebd5Sriastradh /* If the X drawable was destroyed before the GLX drawable, the 1913464ebd5Sriastradh * DRI2 drawble will be gone by the time we call 1923464ebd5Sriastradh * DRI2DestroyDrawable. So just ignore BadDrawable here. */ 1933464ebd5Sriastradh if (err->majorCode == codes->major_opcode && 1943464ebd5Sriastradh err->errorCode == BadDrawable && 1953464ebd5Sriastradh err->minorCode == X_DRI2DestroyDrawable) 1963464ebd5Sriastradh return True; 1973464ebd5Sriastradh 1983464ebd5Sriastradh /* If the server is non-local DRI2Connect will raise BadRequest. 1993464ebd5Sriastradh * Swallow this so that DRI2Connect can signal this in its return code */ 2003464ebd5Sriastradh if (err->majorCode == codes->major_opcode && 2013464ebd5Sriastradh err->minorCode == X_DRI2Connect && 2023464ebd5Sriastradh err->errorCode == BadRequest) { 2033464ebd5Sriastradh *ret_code = False; 2043464ebd5Sriastradh return True; 2053464ebd5Sriastradh } 2063464ebd5Sriastradh 207cdc920a0Smrg return False; 208cdc920a0Smrg} 209cdc920a0Smrg 210cdc920a0SmrgBool 211cdc920a0SmrgDRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase) 212cdc920a0Smrg{ 213cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 214cdc920a0Smrg 215cdc920a0Smrg if (XextHasExtension(info)) { 216cdc920a0Smrg *eventBase = info->codes->first_event; 217cdc920a0Smrg *errorBase = info->codes->first_error; 218cdc920a0Smrg return True; 219cdc920a0Smrg } 220cdc920a0Smrg 221cdc920a0Smrg return False; 222cdc920a0Smrg} 223cdc920a0Smrg 224cdc920a0SmrgBool 225cdc920a0SmrgDRI2QueryVersion(Display * dpy, int *major, int *minor) 226cdc920a0Smrg{ 227cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 228cdc920a0Smrg xDRI2QueryVersionReply rep; 229cdc920a0Smrg xDRI2QueryVersionReq *req; 230cdc920a0Smrg int i, nevents; 231cdc920a0Smrg 232cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 233cdc920a0Smrg 234cdc920a0Smrg LockDisplay(dpy); 235cdc920a0Smrg GetReq(DRI2QueryVersion, req); 236cdc920a0Smrg req->reqType = info->codes->major_opcode; 237cdc920a0Smrg req->dri2ReqType = X_DRI2QueryVersion; 238cdc920a0Smrg req->majorVersion = DRI2_MAJOR; 239cdc920a0Smrg req->minorVersion = DRI2_MINOR; 240cdc920a0Smrg if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { 241cdc920a0Smrg UnlockDisplay(dpy); 242cdc920a0Smrg SyncHandle(); 243cdc920a0Smrg return False; 244cdc920a0Smrg } 245cdc920a0Smrg *major = rep.majorVersion; 246cdc920a0Smrg *minor = rep.minorVersion; 247cdc920a0Smrg UnlockDisplay(dpy); 248cdc920a0Smrg SyncHandle(); 249cdc920a0Smrg 250cdc920a0Smrg switch (rep.minorVersion) { 251cdc920a0Smrg case 1: 252cdc920a0Smrg nevents = 0; 253cdc920a0Smrg break; 254cdc920a0Smrg case 2: 255cdc920a0Smrg nevents = 1; 256cdc920a0Smrg break; 257cdc920a0Smrg case 3: 258cdc920a0Smrg default: 259cdc920a0Smrg nevents = 2; 260cdc920a0Smrg break; 261cdc920a0Smrg } 262cdc920a0Smrg 263cdc920a0Smrg for (i = 0; i < nevents; i++) { 264cdc920a0Smrg XESetWireToEvent (dpy, info->codes->first_event + i, DRI2WireToEvent); 265cdc920a0Smrg XESetEventToWire (dpy, info->codes->first_event + i, DRI2EventToWire); 266cdc920a0Smrg } 267cdc920a0Smrg 268cdc920a0Smrg return True; 269cdc920a0Smrg} 270cdc920a0Smrg 271cdc920a0SmrgBool 272cdc920a0SmrgDRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName) 273cdc920a0Smrg{ 274cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 275cdc920a0Smrg xDRI2ConnectReply rep; 276cdc920a0Smrg xDRI2ConnectReq *req; 277cdc920a0Smrg 278cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 279cdc920a0Smrg 280cdc920a0Smrg LockDisplay(dpy); 281cdc920a0Smrg GetReq(DRI2Connect, req); 282cdc920a0Smrg req->reqType = info->codes->major_opcode; 283cdc920a0Smrg req->dri2ReqType = X_DRI2Connect; 284cdc920a0Smrg req->window = window; 285af69d88dSmrg 286cdc920a0Smrg req->driverType = DRI2DriverDRI; 287af69d88dSmrg#ifdef DRI2DriverPrimeShift 288af69d88dSmrg { 289af69d88dSmrg char *prime = getenv("DRI_PRIME"); 290af69d88dSmrg if (prime) { 291af69d88dSmrg uint32_t primeid; 292af69d88dSmrg errno = 0; 293af69d88dSmrg primeid = strtoul(prime, NULL, 0); 294af69d88dSmrg if (errno == 0) 295af69d88dSmrg req->driverType |= 296af69d88dSmrg ((primeid & DRI2DriverPrimeMask) << DRI2DriverPrimeShift); 297af69d88dSmrg } 298af69d88dSmrg } 299af69d88dSmrg#endif 300af69d88dSmrg 301cdc920a0Smrg if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { 302cdc920a0Smrg UnlockDisplay(dpy); 303cdc920a0Smrg SyncHandle(); 304cdc920a0Smrg return False; 305cdc920a0Smrg } 306cdc920a0Smrg 307cdc920a0Smrg if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) { 308cdc920a0Smrg UnlockDisplay(dpy); 309cdc920a0Smrg SyncHandle(); 310cdc920a0Smrg return False; 311cdc920a0Smrg } 312cdc920a0Smrg 313af69d88dSmrg *driverName = malloc(rep.driverNameLength + 1); 314cdc920a0Smrg if (*driverName == NULL) { 315cdc920a0Smrg _XEatData(dpy, 316cdc920a0Smrg ((rep.driverNameLength + 3) & ~3) + 317cdc920a0Smrg ((rep.deviceNameLength + 3) & ~3)); 318cdc920a0Smrg UnlockDisplay(dpy); 319cdc920a0Smrg SyncHandle(); 320cdc920a0Smrg return False; 321cdc920a0Smrg } 322cdc920a0Smrg _XReadPad(dpy, *driverName, rep.driverNameLength); 323cdc920a0Smrg (*driverName)[rep.driverNameLength] = '\0'; 324cdc920a0Smrg 325af69d88dSmrg *deviceName = malloc(rep.deviceNameLength + 1); 326cdc920a0Smrg if (*deviceName == NULL) { 327af69d88dSmrg free(*driverName); 328cdc920a0Smrg _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3)); 329cdc920a0Smrg UnlockDisplay(dpy); 330cdc920a0Smrg SyncHandle(); 331cdc920a0Smrg return False; 332cdc920a0Smrg } 333cdc920a0Smrg _XReadPad(dpy, *deviceName, rep.deviceNameLength); 334cdc920a0Smrg (*deviceName)[rep.deviceNameLength] = '\0'; 335cdc920a0Smrg 336cdc920a0Smrg UnlockDisplay(dpy); 337cdc920a0Smrg SyncHandle(); 338cdc920a0Smrg 339cdc920a0Smrg return True; 340cdc920a0Smrg} 341cdc920a0Smrg 342cdc920a0SmrgBool 343cdc920a0SmrgDRI2Authenticate(Display * dpy, XID window, drm_magic_t magic) 344cdc920a0Smrg{ 345cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 346cdc920a0Smrg xDRI2AuthenticateReq *req; 347cdc920a0Smrg xDRI2AuthenticateReply rep; 348cdc920a0Smrg 349cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 350cdc920a0Smrg 351cdc920a0Smrg LockDisplay(dpy); 352cdc920a0Smrg GetReq(DRI2Authenticate, req); 353cdc920a0Smrg req->reqType = info->codes->major_opcode; 354cdc920a0Smrg req->dri2ReqType = X_DRI2Authenticate; 355cdc920a0Smrg req->window = window; 356cdc920a0Smrg req->magic = magic; 357cdc920a0Smrg 358cdc920a0Smrg if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { 359cdc920a0Smrg UnlockDisplay(dpy); 360cdc920a0Smrg SyncHandle(); 361cdc920a0Smrg return False; 362cdc920a0Smrg } 363cdc920a0Smrg 364cdc920a0Smrg UnlockDisplay(dpy); 365cdc920a0Smrg SyncHandle(); 366cdc920a0Smrg 367cdc920a0Smrg return rep.authenticated; 368cdc920a0Smrg} 369cdc920a0Smrg 370cdc920a0Smrgvoid 371cdc920a0SmrgDRI2CreateDrawable(Display * dpy, XID drawable) 372cdc920a0Smrg{ 373cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 374cdc920a0Smrg xDRI2CreateDrawableReq *req; 375cdc920a0Smrg 376cdc920a0Smrg XextSimpleCheckExtension(dpy, info, dri2ExtensionName); 377cdc920a0Smrg 378cdc920a0Smrg LockDisplay(dpy); 379cdc920a0Smrg GetReq(DRI2CreateDrawable, req); 380cdc920a0Smrg req->reqType = info->codes->major_opcode; 381cdc920a0Smrg req->dri2ReqType = X_DRI2CreateDrawable; 382cdc920a0Smrg req->drawable = drawable; 383cdc920a0Smrg UnlockDisplay(dpy); 384cdc920a0Smrg SyncHandle(); 385cdc920a0Smrg} 386cdc920a0Smrg 387cdc920a0Smrgvoid 388cdc920a0SmrgDRI2DestroyDrawable(Display * dpy, XID drawable) 389cdc920a0Smrg{ 390cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 391cdc920a0Smrg xDRI2DestroyDrawableReq *req; 392cdc920a0Smrg 393cdc920a0Smrg XextSimpleCheckExtension(dpy, info, dri2ExtensionName); 394cdc920a0Smrg 395cdc920a0Smrg XSync(dpy, False); 396cdc920a0Smrg 397cdc920a0Smrg LockDisplay(dpy); 398cdc920a0Smrg GetReq(DRI2DestroyDrawable, req); 399cdc920a0Smrg req->reqType = info->codes->major_opcode; 400cdc920a0Smrg req->dri2ReqType = X_DRI2DestroyDrawable; 401cdc920a0Smrg req->drawable = drawable; 402cdc920a0Smrg UnlockDisplay(dpy); 403cdc920a0Smrg SyncHandle(); 404cdc920a0Smrg} 405cdc920a0Smrg 406cdc920a0SmrgDRI2Buffer * 407cdc920a0SmrgDRI2GetBuffers(Display * dpy, XID drawable, 408cdc920a0Smrg int *width, int *height, 409cdc920a0Smrg unsigned int *attachments, int count, int *outCount) 410cdc920a0Smrg{ 411cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 412cdc920a0Smrg xDRI2GetBuffersReply rep; 413cdc920a0Smrg xDRI2GetBuffersReq *req; 414cdc920a0Smrg DRI2Buffer *buffers; 415cdc920a0Smrg xDRI2Buffer repBuffer; 416cdc920a0Smrg CARD32 *p; 417cdc920a0Smrg int i; 418cdc920a0Smrg 419cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 420cdc920a0Smrg 421cdc920a0Smrg LockDisplay(dpy); 422cdc920a0Smrg GetReqExtra(DRI2GetBuffers, count * 4, req); 423cdc920a0Smrg req->reqType = info->codes->major_opcode; 424cdc920a0Smrg req->dri2ReqType = X_DRI2GetBuffers; 425cdc920a0Smrg req->drawable = drawable; 426cdc920a0Smrg req->count = count; 427cdc920a0Smrg p = (CARD32 *) & req[1]; 428cdc920a0Smrg for (i = 0; i < count; i++) 429cdc920a0Smrg p[i] = attachments[i]; 430cdc920a0Smrg 431cdc920a0Smrg if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { 432cdc920a0Smrg UnlockDisplay(dpy); 433cdc920a0Smrg SyncHandle(); 434cdc920a0Smrg return NULL; 435cdc920a0Smrg } 436cdc920a0Smrg 437cdc920a0Smrg *width = rep.width; 438cdc920a0Smrg *height = rep.height; 439cdc920a0Smrg *outCount = rep.count; 440cdc920a0Smrg 441af69d88dSmrg buffers = malloc(rep.count * sizeof buffers[0]); 442cdc920a0Smrg if (buffers == NULL) { 443cdc920a0Smrg _XEatData(dpy, rep.count * sizeof repBuffer); 444cdc920a0Smrg UnlockDisplay(dpy); 445cdc920a0Smrg SyncHandle(); 446cdc920a0Smrg return NULL; 447cdc920a0Smrg } 448cdc920a0Smrg 449cdc920a0Smrg for (i = 0; i < rep.count; i++) { 450cdc920a0Smrg _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); 451cdc920a0Smrg buffers[i].attachment = repBuffer.attachment; 452cdc920a0Smrg buffers[i].name = repBuffer.name; 453cdc920a0Smrg buffers[i].pitch = repBuffer.pitch; 454cdc920a0Smrg buffers[i].cpp = repBuffer.cpp; 455cdc920a0Smrg buffers[i].flags = repBuffer.flags; 456cdc920a0Smrg } 457cdc920a0Smrg 458cdc920a0Smrg UnlockDisplay(dpy); 459cdc920a0Smrg SyncHandle(); 460cdc920a0Smrg 461cdc920a0Smrg return buffers; 462cdc920a0Smrg} 463cdc920a0Smrg 464cdc920a0Smrg 465cdc920a0SmrgDRI2Buffer * 466cdc920a0SmrgDRI2GetBuffersWithFormat(Display * dpy, XID drawable, 467cdc920a0Smrg int *width, int *height, 468cdc920a0Smrg unsigned int *attachments, int count, int *outCount) 469cdc920a0Smrg{ 470cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 471cdc920a0Smrg xDRI2GetBuffersReply rep; 472cdc920a0Smrg xDRI2GetBuffersReq *req; 473cdc920a0Smrg DRI2Buffer *buffers; 474cdc920a0Smrg xDRI2Buffer repBuffer; 475cdc920a0Smrg CARD32 *p; 476cdc920a0Smrg int i; 477cdc920a0Smrg 478cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 479cdc920a0Smrg 480cdc920a0Smrg LockDisplay(dpy); 481cdc920a0Smrg GetReqExtra(DRI2GetBuffers, count * (4 * 2), req); 482cdc920a0Smrg req->reqType = info->codes->major_opcode; 483cdc920a0Smrg req->dri2ReqType = X_DRI2GetBuffersWithFormat; 484cdc920a0Smrg req->drawable = drawable; 485cdc920a0Smrg req->count = count; 486cdc920a0Smrg p = (CARD32 *) & req[1]; 487cdc920a0Smrg for (i = 0; i < (count * 2); i++) 488cdc920a0Smrg p[i] = attachments[i]; 489cdc920a0Smrg 490cdc920a0Smrg if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { 491cdc920a0Smrg UnlockDisplay(dpy); 492cdc920a0Smrg SyncHandle(); 493cdc920a0Smrg return NULL; 494cdc920a0Smrg } 495cdc920a0Smrg 496cdc920a0Smrg *width = rep.width; 497cdc920a0Smrg *height = rep.height; 498cdc920a0Smrg *outCount = rep.count; 499cdc920a0Smrg 500af69d88dSmrg buffers = malloc(rep.count * sizeof buffers[0]); 501cdc920a0Smrg if (buffers == NULL) { 502cdc920a0Smrg _XEatData(dpy, rep.count * sizeof repBuffer); 503cdc920a0Smrg UnlockDisplay(dpy); 504cdc920a0Smrg SyncHandle(); 505cdc920a0Smrg return NULL; 506cdc920a0Smrg } 507cdc920a0Smrg 508cdc920a0Smrg for (i = 0; i < rep.count; i++) { 509cdc920a0Smrg _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); 510cdc920a0Smrg buffers[i].attachment = repBuffer.attachment; 511cdc920a0Smrg buffers[i].name = repBuffer.name; 512cdc920a0Smrg buffers[i].pitch = repBuffer.pitch; 513cdc920a0Smrg buffers[i].cpp = repBuffer.cpp; 514cdc920a0Smrg buffers[i].flags = repBuffer.flags; 515cdc920a0Smrg } 516cdc920a0Smrg 517cdc920a0Smrg UnlockDisplay(dpy); 518cdc920a0Smrg SyncHandle(); 519cdc920a0Smrg 520cdc920a0Smrg return buffers; 521cdc920a0Smrg} 522cdc920a0Smrg 523cdc920a0Smrg 524cdc920a0Smrgvoid 525cdc920a0SmrgDRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region, 526cdc920a0Smrg CARD32 dest, CARD32 src) 527cdc920a0Smrg{ 528cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 529cdc920a0Smrg xDRI2CopyRegionReq *req; 530cdc920a0Smrg xDRI2CopyRegionReply rep; 531cdc920a0Smrg 532cdc920a0Smrg XextSimpleCheckExtension(dpy, info, dri2ExtensionName); 533cdc920a0Smrg 534cdc920a0Smrg LockDisplay(dpy); 535cdc920a0Smrg GetReq(DRI2CopyRegion, req); 536cdc920a0Smrg req->reqType = info->codes->major_opcode; 537cdc920a0Smrg req->dri2ReqType = X_DRI2CopyRegion; 538cdc920a0Smrg req->drawable = drawable; 539cdc920a0Smrg req->region = region; 540cdc920a0Smrg req->dest = dest; 541cdc920a0Smrg req->src = src; 542cdc920a0Smrg 543cdc920a0Smrg _XReply(dpy, (xReply *) & rep, 0, xFalse); 544cdc920a0Smrg 545cdc920a0Smrg UnlockDisplay(dpy); 546cdc920a0Smrg SyncHandle(); 547cdc920a0Smrg} 548cdc920a0Smrg 549cdc920a0Smrg#endif /* GLX_DIRECT_RENDERING */ 550