1fa225cbcSrjs/* 2fa225cbcSrjs * Copyright © 2008 Red Hat, Inc. 3fa225cbcSrjs * 4fa225cbcSrjs * Permission is hereby granted, free of charge, to any person obtaining a 5fa225cbcSrjs * copy of this software and associated documentation files (the "Soft- 6fa225cbcSrjs * ware"), to deal in the Software without restriction, including without 7fa225cbcSrjs * limitation the rights to use, copy, modify, merge, publish, distribute, 8fa225cbcSrjs * and/or sell copies of the Software, and to permit persons to whom the 9fa225cbcSrjs * Software is furnished to do so, provided that the above copyright 10fa225cbcSrjs * notice(s) and this permission notice appear in all copies of the Soft- 11fa225cbcSrjs * ware and that both the above copyright notice(s) and this permission 12fa225cbcSrjs * notice appear in supporting documentation. 13fa225cbcSrjs * 14fa225cbcSrjs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15fa225cbcSrjs * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- 16fa225cbcSrjs * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY 17fa225cbcSrjs * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN 18fa225cbcSrjs * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- 19fa225cbcSrjs * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 20fa225cbcSrjs * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 21fa225cbcSrjs * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- 22fa225cbcSrjs * MANCE OF THIS SOFTWARE. 23fa225cbcSrjs * 24fa225cbcSrjs * Except as contained in this notice, the name of a copyright holder shall 25fa225cbcSrjs * not be used in advertising or otherwise to promote the sale, use or 26fa225cbcSrjs * other dealings in this Software without prior written authorization of 27fa225cbcSrjs * the copyright holder. 28fa225cbcSrjs * 29fa225cbcSrjs * Authors: 30fa225cbcSrjs * Kristian Høgsberg (krh@redhat.com) 31fa225cbcSrjs */ 32fa225cbcSrjs 33fa225cbcSrjs 34fa225cbcSrjs#define NEED_REPLIES 35fa225cbcSrjs#include <X11/Xlibint.h> 36fa225cbcSrjs#include <X11/extensions/Xext.h> 37fa225cbcSrjs#include <X11/extensions/extutil.h> 38fa225cbcSrjs#include <X11/extensions/dri2proto.h> 39fa225cbcSrjs#include "xf86drm.h" 40fa225cbcSrjs#include "dri2.h" 41fa225cbcSrjs 42fa225cbcSrjsstatic char dri2ExtensionName[] = DRI2_NAME; 43fa225cbcSrjsstatic XExtensionInfo *dri2Info; 44fa225cbcSrjsstatic XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info) 45fa225cbcSrjsstatic /* const */ XExtensionHooks dri2ExtensionHooks = { 46fa225cbcSrjs NULL, /* create_gc */ 47fa225cbcSrjs NULL, /* copy_gc */ 48fa225cbcSrjs NULL, /* flush_gc */ 49fa225cbcSrjs NULL, /* free_gc */ 50fa225cbcSrjs NULL, /* create_font */ 51fa225cbcSrjs NULL, /* free_font */ 52fa225cbcSrjs DRI2CloseDisplay, /* close_display */ 53fa225cbcSrjs NULL, /* wire_to_event */ 54fa225cbcSrjs NULL, /* event_to_wire */ 55fa225cbcSrjs NULL, /* error */ 56fa225cbcSrjs NULL, /* error_string */ 57fa225cbcSrjs}; 58fa225cbcSrjs 59fa225cbcSrjsstatic XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, dri2Info, 60fa225cbcSrjs dri2ExtensionName, 61fa225cbcSrjs &dri2ExtensionHooks, 62fa225cbcSrjs 0, NULL) 63fa225cbcSrjs 64fa225cbcSrjsBool DRI2QueryExtension(Display *dpy, int *eventBase, int *errorBase) 65fa225cbcSrjs{ 66fa225cbcSrjs XExtDisplayInfo *info = DRI2FindDisplay(dpy); 67fa225cbcSrjs 68fa225cbcSrjs if (XextHasExtension(info)) { 69fa225cbcSrjs *eventBase = info->codes->first_event; 70fa225cbcSrjs *errorBase = info->codes->first_error; 71fa225cbcSrjs return True; 72fa225cbcSrjs } 73fa225cbcSrjs 74fa225cbcSrjs return False; 75fa225cbcSrjs} 76fa225cbcSrjs 77fa225cbcSrjsBool DRI2QueryVersion(Display *dpy, int *major, int *minor) 78fa225cbcSrjs{ 79fa225cbcSrjs XExtDisplayInfo *info = DRI2FindDisplay (dpy); 80fa225cbcSrjs xDRI2QueryVersionReply rep; 81fa225cbcSrjs xDRI2QueryVersionReq *req; 82fa225cbcSrjs 83fa225cbcSrjs XextCheckExtension (dpy, info, dri2ExtensionName, False); 84fa225cbcSrjs 85fa225cbcSrjs LockDisplay(dpy); 86fa225cbcSrjs GetReq(DRI2QueryVersion, req); 87fa225cbcSrjs req->reqType = info->codes->major_opcode; 88fa225cbcSrjs req->dri2ReqType = X_DRI2QueryVersion; 89fa225cbcSrjs req->majorVersion = DRI2_MAJOR; 90fa225cbcSrjs req->minorVersion = DRI2_MINOR; 91fa225cbcSrjs if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 92fa225cbcSrjs UnlockDisplay(dpy); 93fa225cbcSrjs SyncHandle(); 94fa225cbcSrjs return False; 95fa225cbcSrjs } 96fa225cbcSrjs *major = rep.majorVersion; 97fa225cbcSrjs *minor = rep.minorVersion; 98fa225cbcSrjs UnlockDisplay(dpy); 99fa225cbcSrjs SyncHandle(); 100fa225cbcSrjs 101fa225cbcSrjs return True; 102fa225cbcSrjs} 103fa225cbcSrjs 104fa225cbcSrjsBool DRI2Connect(Display *dpy, XID window, 105fa225cbcSrjs char **driverName, char **deviceName) 106fa225cbcSrjs{ 107fa225cbcSrjs XExtDisplayInfo *info = DRI2FindDisplay(dpy); 108fa225cbcSrjs xDRI2ConnectReply rep; 109fa225cbcSrjs xDRI2ConnectReq *req; 110fa225cbcSrjs 111fa225cbcSrjs XextCheckExtension (dpy, info, dri2ExtensionName, False); 112fa225cbcSrjs 113fa225cbcSrjs LockDisplay(dpy); 114fa225cbcSrjs GetReq(DRI2Connect, req); 115fa225cbcSrjs req->reqType = info->codes->major_opcode; 116fa225cbcSrjs req->dri2ReqType = X_DRI2Connect; 117fa225cbcSrjs req->window = window; 118fa225cbcSrjs req->driverType = DRI2DriverDRI; 119fa225cbcSrjs if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 120fa225cbcSrjs UnlockDisplay(dpy); 121fa225cbcSrjs SyncHandle(); 122fa225cbcSrjs return False; 123fa225cbcSrjs } 124fa225cbcSrjs 125fa225cbcSrjs if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) { 126fa225cbcSrjs UnlockDisplay(dpy); 127fa225cbcSrjs SyncHandle(); 128fa225cbcSrjs return False; 129fa225cbcSrjs } 130fa225cbcSrjs 131fa225cbcSrjs *driverName = Xmalloc(rep.driverNameLength + 1); 132fa225cbcSrjs if (*driverName == NULL) { 133fa225cbcSrjs _XEatData(dpy, 134fa225cbcSrjs ((rep.driverNameLength + 3) & ~3) + 135fa225cbcSrjs ((rep.deviceNameLength + 3) & ~3)); 136fa225cbcSrjs UnlockDisplay(dpy); 137fa225cbcSrjs SyncHandle(); 138fa225cbcSrjs return False; 139fa225cbcSrjs } 140fa225cbcSrjs _XReadPad(dpy, *driverName, rep.driverNameLength); 141fa225cbcSrjs (*driverName)[rep.driverNameLength] = '\0'; 142fa225cbcSrjs 143fa225cbcSrjs *deviceName = Xmalloc(rep.deviceNameLength + 1); 144fa225cbcSrjs if (*deviceName == NULL) { 145fa225cbcSrjs Xfree(*driverName); 146fa225cbcSrjs _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3)); 147fa225cbcSrjs UnlockDisplay(dpy); 148fa225cbcSrjs SyncHandle(); 149fa225cbcSrjs return False; 150fa225cbcSrjs } 151fa225cbcSrjs _XReadPad(dpy, *deviceName, rep.deviceNameLength); 152fa225cbcSrjs (*deviceName)[rep.deviceNameLength] = '\0'; 153fa225cbcSrjs 154fa225cbcSrjs UnlockDisplay(dpy); 155fa225cbcSrjs SyncHandle(); 156fa225cbcSrjs 157fa225cbcSrjs return True; 158fa225cbcSrjs} 159fa225cbcSrjs 160fa225cbcSrjsBool DRI2Authenticate(Display *dpy, XID window, drm_magic_t magic) 161fa225cbcSrjs{ 162fa225cbcSrjs XExtDisplayInfo *info = DRI2FindDisplay(dpy); 163fa225cbcSrjs xDRI2AuthenticateReq *req; 164fa225cbcSrjs xDRI2AuthenticateReply rep; 165fa225cbcSrjs 166fa225cbcSrjs XextCheckExtension (dpy, info, dri2ExtensionName, False); 167fa225cbcSrjs 168fa225cbcSrjs LockDisplay(dpy); 169fa225cbcSrjs GetReq(DRI2Authenticate, req); 170fa225cbcSrjs req->reqType = info->codes->major_opcode; 171fa225cbcSrjs req->dri2ReqType = X_DRI2Authenticate; 172fa225cbcSrjs req->window = window; 173fa225cbcSrjs req->magic = magic; 174fa225cbcSrjs 175fa225cbcSrjs if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 176fa225cbcSrjs UnlockDisplay(dpy); 177fa225cbcSrjs SyncHandle(); 178fa225cbcSrjs return False; 179fa225cbcSrjs } 180fa225cbcSrjs 181fa225cbcSrjs UnlockDisplay(dpy); 182fa225cbcSrjs SyncHandle(); 183fa225cbcSrjs 184fa225cbcSrjs return rep.authenticated; 185fa225cbcSrjs} 186fa225cbcSrjs 187fa225cbcSrjsvoid DRI2CreateDrawable(Display *dpy, XID drawable) 188fa225cbcSrjs{ 189fa225cbcSrjs XExtDisplayInfo *info = DRI2FindDisplay(dpy); 190fa225cbcSrjs xDRI2CreateDrawableReq *req; 191fa225cbcSrjs 192fa225cbcSrjs XextSimpleCheckExtension (dpy, info, dri2ExtensionName); 193fa225cbcSrjs 194fa225cbcSrjs LockDisplay(dpy); 195fa225cbcSrjs GetReq(DRI2CreateDrawable, req); 196fa225cbcSrjs req->reqType = info->codes->major_opcode; 197fa225cbcSrjs req->dri2ReqType = X_DRI2CreateDrawable; 198fa225cbcSrjs req->drawable = drawable; 199fa225cbcSrjs UnlockDisplay(dpy); 200fa225cbcSrjs SyncHandle(); 201fa225cbcSrjs} 202fa225cbcSrjs 203fa225cbcSrjsvoid DRI2DestroyDrawable(Display *dpy, XID drawable) 204fa225cbcSrjs{ 205fa225cbcSrjs XExtDisplayInfo *info = DRI2FindDisplay(dpy); 206fa225cbcSrjs xDRI2DestroyDrawableReq *req; 207fa225cbcSrjs 208fa225cbcSrjs XextSimpleCheckExtension (dpy, info, dri2ExtensionName); 209fa225cbcSrjs 210fa225cbcSrjs XSync(dpy, False); 211fa225cbcSrjs 212fa225cbcSrjs LockDisplay(dpy); 213fa225cbcSrjs GetReq(DRI2DestroyDrawable, req); 214fa225cbcSrjs req->reqType = info->codes->major_opcode; 215fa225cbcSrjs req->dri2ReqType = X_DRI2DestroyDrawable; 216fa225cbcSrjs req->drawable = drawable; 217fa225cbcSrjs UnlockDisplay(dpy); 218fa225cbcSrjs SyncHandle(); 219fa225cbcSrjs} 220fa225cbcSrjs 221fa225cbcSrjsDRI2Buffer *DRI2GetBuffers(Display *dpy, XID drawable, 222fa225cbcSrjs int *width, int *height, 223fa225cbcSrjs unsigned int *attachments, int count, 224fa225cbcSrjs int *outCount) 225fa225cbcSrjs{ 226fa225cbcSrjs XExtDisplayInfo *info = DRI2FindDisplay(dpy); 227fa225cbcSrjs xDRI2GetBuffersReply rep; 228fa225cbcSrjs xDRI2GetBuffersReq *req; 229fa225cbcSrjs DRI2Buffer *buffers; 230fa225cbcSrjs xDRI2Buffer repBuffer; 231fa225cbcSrjs CARD32 *p; 232fa225cbcSrjs int i; 233fa225cbcSrjs 234fa225cbcSrjs XextCheckExtension (dpy, info, dri2ExtensionName, False); 235fa225cbcSrjs 236fa225cbcSrjs LockDisplay(dpy); 237fa225cbcSrjs GetReqExtra(DRI2GetBuffers, count * 4, req); 238fa225cbcSrjs req->reqType = info->codes->major_opcode; 239fa225cbcSrjs req->dri2ReqType = X_DRI2GetBuffers; 240fa225cbcSrjs req->drawable = drawable; 241fa225cbcSrjs req->count = count; 242fa225cbcSrjs p = (CARD32 *) &req[1]; 243fa225cbcSrjs for (i = 0; i < count; i++) 244fa225cbcSrjs p[i] = attachments[i]; 245fa225cbcSrjs 246fa225cbcSrjs if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 247fa225cbcSrjs UnlockDisplay(dpy); 248fa225cbcSrjs SyncHandle(); 249fa225cbcSrjs return NULL; 250fa225cbcSrjs } 251fa225cbcSrjs 252fa225cbcSrjs *width = rep.width; 253fa225cbcSrjs *height = rep.height; 254fa225cbcSrjs *outCount = rep.count; 255fa225cbcSrjs 256fa225cbcSrjs buffers = Xmalloc(rep.count * sizeof buffers[0]); 257fa225cbcSrjs if (buffers == NULL) { 258fa225cbcSrjs _XEatData(dpy, rep.count * sizeof repBuffer); 259fa225cbcSrjs UnlockDisplay(dpy); 260fa225cbcSrjs SyncHandle(); 261fa225cbcSrjs return NULL; 262fa225cbcSrjs } 263fa225cbcSrjs 264fa225cbcSrjs for (i = 0; i < rep.count; i++) { 265fa225cbcSrjs _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); 266fa225cbcSrjs buffers[i].attachment = repBuffer.attachment; 267fa225cbcSrjs buffers[i].name = repBuffer.name; 268fa225cbcSrjs buffers[i].pitch = repBuffer.pitch; 269fa225cbcSrjs buffers[i].cpp = repBuffer.cpp; 270fa225cbcSrjs buffers[i].flags = repBuffer.flags; 271fa225cbcSrjs } 272fa225cbcSrjs 273fa225cbcSrjs UnlockDisplay(dpy); 274fa225cbcSrjs SyncHandle(); 275fa225cbcSrjs 276fa225cbcSrjs return buffers; 277fa225cbcSrjs} 278fa225cbcSrjs 279fa225cbcSrjsvoid DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region, 280fa225cbcSrjs CARD32 dest, CARD32 src) 281fa225cbcSrjs{ 282fa225cbcSrjs XExtDisplayInfo *info = DRI2FindDisplay(dpy); 283fa225cbcSrjs xDRI2CopyRegionReq *req; 284fa225cbcSrjs xDRI2CopyRegionReply rep; 285fa225cbcSrjs 286fa225cbcSrjs XextSimpleCheckExtension (dpy, info, dri2ExtensionName); 287fa225cbcSrjs 288fa225cbcSrjs LockDisplay(dpy); 289fa225cbcSrjs GetReq(DRI2CopyRegion, req); 290fa225cbcSrjs req->reqType = info->codes->major_opcode; 291fa225cbcSrjs req->dri2ReqType = X_DRI2CopyRegion; 292fa225cbcSrjs req->drawable = drawable; 293fa225cbcSrjs req->region = region; 294fa225cbcSrjs req->dest = dest; 295fa225cbcSrjs req->src = src; 296fa225cbcSrjs 297fa225cbcSrjs _XReply(dpy, (xReply *)&rep, 0, xFalse); 298fa225cbcSrjs 299fa225cbcSrjs UnlockDisplay(dpy); 300fa225cbcSrjs SyncHandle(); 301fa225cbcSrjs} 302