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; 5601e04c3fSmrgstatic XExtensionInfo _dri2Info_data; 5701e04c3fSmrgstatic XExtensionInfo *dri2Info = &_dri2Info_data; 58cdc920a0Smrgstatic XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info) 59cdc920a0Smrg 60cdc920a0Smrgstatic Bool 61cdc920a0SmrgDRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire); 62cdc920a0Smrgstatic Status 63cdc920a0SmrgDRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire); 64cdc920a0Smrgstatic int 65cdc920a0SmrgDRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code); 66cdc920a0Smrg 67cdc920a0Smrgstatic /* const */ XExtensionHooks dri2ExtensionHooks = { 68cdc920a0Smrg NULL, /* create_gc */ 69cdc920a0Smrg NULL, /* copy_gc */ 70cdc920a0Smrg NULL, /* flush_gc */ 71cdc920a0Smrg NULL, /* free_gc */ 72cdc920a0Smrg NULL, /* create_font */ 73cdc920a0Smrg NULL, /* free_font */ 74cdc920a0Smrg DRI2CloseDisplay, /* close_display */ 75cdc920a0Smrg DRI2WireToEvent, /* wire_to_event */ 76cdc920a0Smrg DRI2EventToWire, /* event_to_wire */ 77cdc920a0Smrg DRI2Error, /* error */ 78cdc920a0Smrg NULL, /* error_string */ 79cdc920a0Smrg}; 80cdc920a0Smrg 81cdc920a0Smrgstatic XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, 82cdc920a0Smrg dri2Info, 83cdc920a0Smrg dri2ExtensionName, 84cdc920a0Smrg &dri2ExtensionHooks, 85cdc920a0Smrg 0, NULL) 86cdc920a0Smrg 87cdc920a0Smrgstatic Bool 88cdc920a0SmrgDRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) 89cdc920a0Smrg{ 90cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 91af69d88dSmrg struct glx_drawable *glxDraw; 92cdc920a0Smrg 93cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 94cdc920a0Smrg 95cdc920a0Smrg switch ((wire->u.u.type & 0x7f) - info->codes->first_event) { 96cdc920a0Smrg 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 case DRI2_InvalidateBuffers: 146cdc920a0Smrg { 147cdc920a0Smrg xDRI2InvalidateBuffers *awire = (xDRI2InvalidateBuffers *)wire; 148cdc920a0Smrg 149cdc920a0Smrg dri2InvalidateBuffers(dpy, awire->drawable); 150cdc920a0Smrg return False; 151cdc920a0Smrg } 152cdc920a0Smrg default: 153cdc920a0Smrg /* client doesn't support server event */ 154cdc920a0Smrg break; 155cdc920a0Smrg } 156cdc920a0Smrg 157cdc920a0Smrg return False; 158cdc920a0Smrg} 159cdc920a0Smrg 160cdc920a0Smrg/* We don't actually support this. It doesn't make sense for clients to 161cdc920a0Smrg * send each other DRI2 events. 162cdc920a0Smrg */ 163cdc920a0Smrgstatic Status 164cdc920a0SmrgDRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire) 165cdc920a0Smrg{ 166cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 167cdc920a0Smrg 168cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 169cdc920a0Smrg 170cdc920a0Smrg switch (event->type) { 171cdc920a0Smrg default: 172cdc920a0Smrg /* client doesn't support server event */ 173cdc920a0Smrg break; 174cdc920a0Smrg } 175cdc920a0Smrg 176cdc920a0Smrg return Success; 177cdc920a0Smrg} 178cdc920a0Smrg 179cdc920a0Smrgstatic int 180cdc920a0SmrgDRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code) 181cdc920a0Smrg{ 182cdc920a0Smrg if (err->majorCode == codes->major_opcode && 183cdc920a0Smrg err->errorCode == BadDrawable && 184cdc920a0Smrg err->minorCode == X_DRI2CopyRegion) 185cdc920a0Smrg return True; 186cdc920a0Smrg 1873464ebd5Sriastradh /* If the X drawable was destroyed before the GLX drawable, the 1883464ebd5Sriastradh * DRI2 drawble will be gone by the time we call 1893464ebd5Sriastradh * DRI2DestroyDrawable. So just ignore BadDrawable here. */ 1903464ebd5Sriastradh if (err->majorCode == codes->major_opcode && 1913464ebd5Sriastradh err->errorCode == BadDrawable && 1923464ebd5Sriastradh err->minorCode == X_DRI2DestroyDrawable) 1933464ebd5Sriastradh return True; 1943464ebd5Sriastradh 1953464ebd5Sriastradh /* If the server is non-local DRI2Connect will raise BadRequest. 1963464ebd5Sriastradh * Swallow this so that DRI2Connect can signal this in its return code */ 1973464ebd5Sriastradh if (err->majorCode == codes->major_opcode && 1983464ebd5Sriastradh err->minorCode == X_DRI2Connect && 1993464ebd5Sriastradh err->errorCode == BadRequest) { 2003464ebd5Sriastradh *ret_code = False; 2013464ebd5Sriastradh return True; 2023464ebd5Sriastradh } 2033464ebd5Sriastradh 204cdc920a0Smrg return False; 205cdc920a0Smrg} 206cdc920a0Smrg 207cdc920a0SmrgBool 208cdc920a0SmrgDRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase) 209cdc920a0Smrg{ 210cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 211cdc920a0Smrg 212cdc920a0Smrg if (XextHasExtension(info)) { 213cdc920a0Smrg *eventBase = info->codes->first_event; 214cdc920a0Smrg *errorBase = info->codes->first_error; 215cdc920a0Smrg return True; 216cdc920a0Smrg } 217cdc920a0Smrg 218cdc920a0Smrg return False; 219cdc920a0Smrg} 220cdc920a0Smrg 221cdc920a0SmrgBool 222cdc920a0SmrgDRI2QueryVersion(Display * dpy, int *major, int *minor) 223cdc920a0Smrg{ 224cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 225cdc920a0Smrg xDRI2QueryVersionReply rep; 226cdc920a0Smrg xDRI2QueryVersionReq *req; 227cdc920a0Smrg int i, nevents; 228cdc920a0Smrg 229cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 230cdc920a0Smrg 231cdc920a0Smrg LockDisplay(dpy); 232cdc920a0Smrg GetReq(DRI2QueryVersion, req); 233cdc920a0Smrg req->reqType = info->codes->major_opcode; 234cdc920a0Smrg req->dri2ReqType = X_DRI2QueryVersion; 235cdc920a0Smrg req->majorVersion = DRI2_MAJOR; 236cdc920a0Smrg req->minorVersion = DRI2_MINOR; 237cdc920a0Smrg if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { 238cdc920a0Smrg UnlockDisplay(dpy); 239cdc920a0Smrg SyncHandle(); 240cdc920a0Smrg return False; 241cdc920a0Smrg } 242cdc920a0Smrg *major = rep.majorVersion; 243cdc920a0Smrg *minor = rep.minorVersion; 244cdc920a0Smrg UnlockDisplay(dpy); 245cdc920a0Smrg SyncHandle(); 246cdc920a0Smrg 247cdc920a0Smrg switch (rep.minorVersion) { 248cdc920a0Smrg case 1: 249cdc920a0Smrg nevents = 0; 250cdc920a0Smrg break; 251cdc920a0Smrg case 2: 252cdc920a0Smrg nevents = 1; 253cdc920a0Smrg break; 254cdc920a0Smrg case 3: 255cdc920a0Smrg default: 256cdc920a0Smrg nevents = 2; 257cdc920a0Smrg break; 258cdc920a0Smrg } 259cdc920a0Smrg 260cdc920a0Smrg for (i = 0; i < nevents; i++) { 261cdc920a0Smrg XESetWireToEvent (dpy, info->codes->first_event + i, DRI2WireToEvent); 262cdc920a0Smrg XESetEventToWire (dpy, info->codes->first_event + i, DRI2EventToWire); 263cdc920a0Smrg } 264cdc920a0Smrg 265cdc920a0Smrg return True; 266cdc920a0Smrg} 267cdc920a0Smrg 268cdc920a0SmrgBool 269cdc920a0SmrgDRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName) 270cdc920a0Smrg{ 271cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 272cdc920a0Smrg xDRI2ConnectReply rep; 273cdc920a0Smrg xDRI2ConnectReq *req; 274cdc920a0Smrg 275cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 276cdc920a0Smrg 277cdc920a0Smrg LockDisplay(dpy); 278cdc920a0Smrg GetReq(DRI2Connect, req); 279cdc920a0Smrg req->reqType = info->codes->major_opcode; 280cdc920a0Smrg req->dri2ReqType = X_DRI2Connect; 281cdc920a0Smrg req->window = window; 282af69d88dSmrg 283cdc920a0Smrg req->driverType = DRI2DriverDRI; 284af69d88dSmrg { 285af69d88dSmrg char *prime = getenv("DRI_PRIME"); 286af69d88dSmrg if (prime) { 287af69d88dSmrg uint32_t primeid; 288af69d88dSmrg errno = 0; 289af69d88dSmrg primeid = strtoul(prime, NULL, 0); 290af69d88dSmrg if (errno == 0) 291af69d88dSmrg req->driverType |= 292af69d88dSmrg ((primeid & DRI2DriverPrimeMask) << DRI2DriverPrimeShift); 293af69d88dSmrg } 294af69d88dSmrg } 295af69d88dSmrg 296cdc920a0Smrg if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { 297cdc920a0Smrg UnlockDisplay(dpy); 298cdc920a0Smrg SyncHandle(); 299cdc920a0Smrg return False; 300cdc920a0Smrg } 301cdc920a0Smrg 302cdc920a0Smrg if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) { 303cdc920a0Smrg UnlockDisplay(dpy); 304cdc920a0Smrg SyncHandle(); 305cdc920a0Smrg return False; 306cdc920a0Smrg } 307cdc920a0Smrg 308af69d88dSmrg *driverName = malloc(rep.driverNameLength + 1); 309cdc920a0Smrg if (*driverName == NULL) { 310cdc920a0Smrg _XEatData(dpy, 311cdc920a0Smrg ((rep.driverNameLength + 3) & ~3) + 312cdc920a0Smrg ((rep.deviceNameLength + 3) & ~3)); 313cdc920a0Smrg UnlockDisplay(dpy); 314cdc920a0Smrg SyncHandle(); 315cdc920a0Smrg return False; 316cdc920a0Smrg } 317cdc920a0Smrg _XReadPad(dpy, *driverName, rep.driverNameLength); 318cdc920a0Smrg (*driverName)[rep.driverNameLength] = '\0'; 319cdc920a0Smrg 320af69d88dSmrg *deviceName = malloc(rep.deviceNameLength + 1); 321cdc920a0Smrg if (*deviceName == NULL) { 322af69d88dSmrg free(*driverName); 323cdc920a0Smrg _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3)); 324cdc920a0Smrg UnlockDisplay(dpy); 325cdc920a0Smrg SyncHandle(); 326cdc920a0Smrg return False; 327cdc920a0Smrg } 328cdc920a0Smrg _XReadPad(dpy, *deviceName, rep.deviceNameLength); 329cdc920a0Smrg (*deviceName)[rep.deviceNameLength] = '\0'; 330cdc920a0Smrg 331cdc920a0Smrg UnlockDisplay(dpy); 332cdc920a0Smrg SyncHandle(); 333cdc920a0Smrg 334cdc920a0Smrg return True; 335cdc920a0Smrg} 336cdc920a0Smrg 337cdc920a0SmrgBool 338cdc920a0SmrgDRI2Authenticate(Display * dpy, XID window, drm_magic_t magic) 339cdc920a0Smrg{ 340cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 341cdc920a0Smrg xDRI2AuthenticateReq *req; 342cdc920a0Smrg xDRI2AuthenticateReply rep; 343cdc920a0Smrg 344cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 345cdc920a0Smrg 346cdc920a0Smrg LockDisplay(dpy); 347cdc920a0Smrg GetReq(DRI2Authenticate, req); 348cdc920a0Smrg req->reqType = info->codes->major_opcode; 349cdc920a0Smrg req->dri2ReqType = X_DRI2Authenticate; 350cdc920a0Smrg req->window = window; 351cdc920a0Smrg req->magic = magic; 352cdc920a0Smrg 353cdc920a0Smrg if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { 354cdc920a0Smrg UnlockDisplay(dpy); 355cdc920a0Smrg SyncHandle(); 356cdc920a0Smrg return False; 357cdc920a0Smrg } 358cdc920a0Smrg 359cdc920a0Smrg UnlockDisplay(dpy); 360cdc920a0Smrg SyncHandle(); 361cdc920a0Smrg 362cdc920a0Smrg return rep.authenticated; 363cdc920a0Smrg} 364cdc920a0Smrg 365cdc920a0Smrgvoid 366cdc920a0SmrgDRI2CreateDrawable(Display * dpy, XID drawable) 367cdc920a0Smrg{ 368cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 369cdc920a0Smrg xDRI2CreateDrawableReq *req; 370cdc920a0Smrg 371cdc920a0Smrg XextSimpleCheckExtension(dpy, info, dri2ExtensionName); 372cdc920a0Smrg 373cdc920a0Smrg LockDisplay(dpy); 374cdc920a0Smrg GetReq(DRI2CreateDrawable, req); 375cdc920a0Smrg req->reqType = info->codes->major_opcode; 376cdc920a0Smrg req->dri2ReqType = X_DRI2CreateDrawable; 377cdc920a0Smrg req->drawable = drawable; 378cdc920a0Smrg UnlockDisplay(dpy); 379cdc920a0Smrg SyncHandle(); 380cdc920a0Smrg} 381cdc920a0Smrg 382cdc920a0Smrgvoid 383cdc920a0SmrgDRI2DestroyDrawable(Display * dpy, XID drawable) 384cdc920a0Smrg{ 385cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 386cdc920a0Smrg xDRI2DestroyDrawableReq *req; 387cdc920a0Smrg 388cdc920a0Smrg XextSimpleCheckExtension(dpy, info, dri2ExtensionName); 389cdc920a0Smrg 390cdc920a0Smrg XSync(dpy, False); 391cdc920a0Smrg 392cdc920a0Smrg LockDisplay(dpy); 393cdc920a0Smrg GetReq(DRI2DestroyDrawable, req); 394cdc920a0Smrg req->reqType = info->codes->major_opcode; 395cdc920a0Smrg req->dri2ReqType = X_DRI2DestroyDrawable; 396cdc920a0Smrg req->drawable = drawable; 397cdc920a0Smrg UnlockDisplay(dpy); 398cdc920a0Smrg SyncHandle(); 399cdc920a0Smrg} 400cdc920a0Smrg 401cdc920a0SmrgDRI2Buffer * 402cdc920a0SmrgDRI2GetBuffers(Display * dpy, XID drawable, 403cdc920a0Smrg int *width, int *height, 404cdc920a0Smrg unsigned int *attachments, int count, int *outCount) 405cdc920a0Smrg{ 406cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 407cdc920a0Smrg xDRI2GetBuffersReply rep; 408cdc920a0Smrg xDRI2GetBuffersReq *req; 409cdc920a0Smrg DRI2Buffer *buffers; 410cdc920a0Smrg xDRI2Buffer repBuffer; 411cdc920a0Smrg CARD32 *p; 412cdc920a0Smrg int i; 413cdc920a0Smrg 414cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 415cdc920a0Smrg 416cdc920a0Smrg LockDisplay(dpy); 417cdc920a0Smrg GetReqExtra(DRI2GetBuffers, count * 4, req); 418cdc920a0Smrg req->reqType = info->codes->major_opcode; 419cdc920a0Smrg req->dri2ReqType = X_DRI2GetBuffers; 420cdc920a0Smrg req->drawable = drawable; 421cdc920a0Smrg req->count = count; 422cdc920a0Smrg p = (CARD32 *) & req[1]; 423cdc920a0Smrg for (i = 0; i < count; i++) 424cdc920a0Smrg p[i] = attachments[i]; 425cdc920a0Smrg 426cdc920a0Smrg if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { 427cdc920a0Smrg UnlockDisplay(dpy); 428cdc920a0Smrg SyncHandle(); 429cdc920a0Smrg return NULL; 430cdc920a0Smrg } 431cdc920a0Smrg 432cdc920a0Smrg *width = rep.width; 433cdc920a0Smrg *height = rep.height; 434cdc920a0Smrg *outCount = rep.count; 435cdc920a0Smrg 436af69d88dSmrg buffers = malloc(rep.count * sizeof buffers[0]); 437cdc920a0Smrg if (buffers == NULL) { 438cdc920a0Smrg _XEatData(dpy, rep.count * sizeof repBuffer); 439cdc920a0Smrg UnlockDisplay(dpy); 440cdc920a0Smrg SyncHandle(); 441cdc920a0Smrg return NULL; 442cdc920a0Smrg } 443cdc920a0Smrg 444cdc920a0Smrg for (i = 0; i < rep.count; i++) { 445cdc920a0Smrg _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); 446cdc920a0Smrg buffers[i].attachment = repBuffer.attachment; 447cdc920a0Smrg buffers[i].name = repBuffer.name; 448cdc920a0Smrg buffers[i].pitch = repBuffer.pitch; 449cdc920a0Smrg buffers[i].cpp = repBuffer.cpp; 450cdc920a0Smrg buffers[i].flags = repBuffer.flags; 451cdc920a0Smrg } 452cdc920a0Smrg 453cdc920a0Smrg UnlockDisplay(dpy); 454cdc920a0Smrg SyncHandle(); 455cdc920a0Smrg 456cdc920a0Smrg return buffers; 457cdc920a0Smrg} 458cdc920a0Smrg 459cdc920a0Smrg 460cdc920a0SmrgDRI2Buffer * 461cdc920a0SmrgDRI2GetBuffersWithFormat(Display * dpy, XID drawable, 462cdc920a0Smrg int *width, int *height, 463cdc920a0Smrg unsigned int *attachments, int count, int *outCount) 464cdc920a0Smrg{ 465cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 466cdc920a0Smrg xDRI2GetBuffersReply rep; 467cdc920a0Smrg xDRI2GetBuffersReq *req; 468cdc920a0Smrg DRI2Buffer *buffers; 469cdc920a0Smrg xDRI2Buffer repBuffer; 470cdc920a0Smrg CARD32 *p; 471cdc920a0Smrg int i; 472cdc920a0Smrg 473cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 474cdc920a0Smrg 475cdc920a0Smrg LockDisplay(dpy); 476cdc920a0Smrg GetReqExtra(DRI2GetBuffers, count * (4 * 2), req); 477cdc920a0Smrg req->reqType = info->codes->major_opcode; 478cdc920a0Smrg req->dri2ReqType = X_DRI2GetBuffersWithFormat; 479cdc920a0Smrg req->drawable = drawable; 480cdc920a0Smrg req->count = count; 481cdc920a0Smrg p = (CARD32 *) & req[1]; 482cdc920a0Smrg for (i = 0; i < (count * 2); i++) 483cdc920a0Smrg p[i] = attachments[i]; 484cdc920a0Smrg 485cdc920a0Smrg if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { 486cdc920a0Smrg UnlockDisplay(dpy); 487cdc920a0Smrg SyncHandle(); 488cdc920a0Smrg return NULL; 489cdc920a0Smrg } 490cdc920a0Smrg 491cdc920a0Smrg *width = rep.width; 492cdc920a0Smrg *height = rep.height; 493cdc920a0Smrg *outCount = rep.count; 494cdc920a0Smrg 495af69d88dSmrg buffers = malloc(rep.count * sizeof buffers[0]); 496cdc920a0Smrg if (buffers == NULL) { 497cdc920a0Smrg _XEatData(dpy, rep.count * sizeof repBuffer); 498cdc920a0Smrg UnlockDisplay(dpy); 499cdc920a0Smrg SyncHandle(); 500cdc920a0Smrg return NULL; 501cdc920a0Smrg } 502cdc920a0Smrg 503cdc920a0Smrg for (i = 0; i < rep.count; i++) { 504cdc920a0Smrg _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); 505cdc920a0Smrg buffers[i].attachment = repBuffer.attachment; 506cdc920a0Smrg buffers[i].name = repBuffer.name; 507cdc920a0Smrg buffers[i].pitch = repBuffer.pitch; 508cdc920a0Smrg buffers[i].cpp = repBuffer.cpp; 509cdc920a0Smrg buffers[i].flags = repBuffer.flags; 510cdc920a0Smrg } 511cdc920a0Smrg 512cdc920a0Smrg UnlockDisplay(dpy); 513cdc920a0Smrg SyncHandle(); 514cdc920a0Smrg 515cdc920a0Smrg return buffers; 516cdc920a0Smrg} 517cdc920a0Smrg 518cdc920a0Smrg 519cdc920a0Smrgvoid 520cdc920a0SmrgDRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region, 521cdc920a0Smrg CARD32 dest, CARD32 src) 522cdc920a0Smrg{ 523cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 524cdc920a0Smrg xDRI2CopyRegionReq *req; 525cdc920a0Smrg xDRI2CopyRegionReply rep; 526cdc920a0Smrg 527cdc920a0Smrg XextSimpleCheckExtension(dpy, info, dri2ExtensionName); 528cdc920a0Smrg 529cdc920a0Smrg LockDisplay(dpy); 530cdc920a0Smrg GetReq(DRI2CopyRegion, req); 531cdc920a0Smrg req->reqType = info->codes->major_opcode; 532cdc920a0Smrg req->dri2ReqType = X_DRI2CopyRegion; 533cdc920a0Smrg req->drawable = drawable; 534cdc920a0Smrg req->region = region; 535cdc920a0Smrg req->dest = dest; 536cdc920a0Smrg req->src = src; 537cdc920a0Smrg 538cdc920a0Smrg _XReply(dpy, (xReply *) & rep, 0, xFalse); 539cdc920a0Smrg 540cdc920a0Smrg UnlockDisplay(dpy); 541cdc920a0Smrg SyncHandle(); 542cdc920a0Smrg} 543cdc920a0Smrg 544cdc920a0Smrg#endif /* GLX_DIRECT_RENDERING */ 545