/** * Xlib-based handling of xcb events for glamor. * * We need to let the Xlib event filtering run on the event so that * Mesa's dri2_glx.c userspace event mangling gets run, and we * correctly get our invalidate events propagated into the driver. */ void ephyr_glamor_process_event(xcb_generic_event_t *xev) { uint32_t response_type = xev->response_type & 0x7f; /* Note the types on wire_to_event: there's an Xlib XEvent (with * the broken types) that it returns, and a protocol xEvent that * it inspects. */ Bool (*wire_to_event)(Display *dpy, XEvent *ret, xEvent *event); XLockDisplay(dpy); /* Set the event handler to NULL to get access to the current one. */ wire_to_event = XESetWireToEvent(dpy, response_type, NULL); if (wire_to_event) { XEvent processed_event; /* OK they had an event handler. Plug it back in, and call * through to it. */ XESetWireToEvent(dpy, response_type, wire_to_event); xev->sequence = LastKnownRequestProcessed(dpy); wire_to_event(dpy, &processed_event, (xEvent *)xev); } XUnlockDisplay(dpy); }
static XExtDisplayInfo *_xgeFindDisplay(Display *dpy) { XExtDisplayInfo *dpyinfo; if (!xge_info) { if (!(xge_info = XextCreateExtension())) return NULL; } if (!(dpyinfo = XextFindDisplay (xge_info, dpy))) { dpyinfo = XextAddDisplay (xge_info, dpy, xge_extension_name, &xge_extension_hooks, 0 /* no events, see below */, NULL); /* We don't use an extension opcode, so we have to set the handlers * directly. If GenericEvent would be > 64, the job would be done by * XExtAddDisplay */ XESetWireToEvent (dpy, GenericEvent, xge_extension_hooks.wire_to_event); XESetEventToWire (dpy, GenericEvent, xge_extension_hooks.event_to_wire); } return dpyinfo; }
static XExtDisplayInfo *_xgeFindDisplay(Display *dpy) { XExtDisplayInfo *dpyinfo; if (!xge_info) { if (!(xge_info = XextCreateExtension())) return NULL; } if (!(dpyinfo = XextFindDisplay (xge_info, dpy))) { dpyinfo = XextAddDisplay (xge_info, dpy, xge_extension_name, &xge_extension_hooks, 0 /* no events, see below */, NULL); /* dpyinfo->codes is only null if the server claims not to suppport XGE. Don't set up the hooks then, so that an XGE event from the server doesn't crash our client */ if (dpyinfo && dpyinfo->codes) { /* We don't use an extension opcode, so we have to set the handlers * directly. If GenericEvent would be > 64, the job would be done by * XExtAddDisplay */ XESetWireToEvent (dpy, GenericEvent, xge_extension_hooks.wire_to_event); XESetEventToWire (dpy, GenericEvent, xge_extension_hooks.event_to_wire); } } return dpyinfo; }
bool QXcbGlxIntegration::handleXcbEvent(xcb_generic_event_t *event, uint responseType) { bool handled = false; // Check if a custom XEvent constructor was registered in xlib for this event type, and call it discarding the constructed XEvent if any. // XESetWireToEvent might be used by libraries to intercept messages from the X server e.g. the OpenGL lib waiting for DRI2 events. Display *xdisplay = static_cast<Display *>(m_connection->xlib_display()); XLockDisplay(xdisplay); bool locked = true; Bool (*proc)(Display*, XEvent*, xEvent*) = XESetWireToEvent(xdisplay, responseType, 0); if (proc) { XESetWireToEvent(xdisplay, responseType, proc); XEvent dummy; event->sequence = LastKnownRequestProcessed(xdisplay); if (proc(xdisplay, &dummy, (xEvent*)event)) { #ifdef XCB_HAS_XCB_GLX // DRI2 clients don't receive GLXBufferSwapComplete events on the wire. // Instead the GLX event is synthesized from the DRI2BufferSwapComplete event // by DRI2WireToEvent(). For an application to be able to see the event // we have to convert it to an xcb_glx_buffer_swap_complete_event_t and // pass it to the native event filter. const uint swap_complete = m_glx_first_event + XCB_GLX_BUFFER_SWAP_COMPLETE; QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance(); if (dispatcher && uint(dummy.type) == swap_complete && responseType != swap_complete) { QGLXBufferSwapComplete *xev = reinterpret_cast<QGLXBufferSwapComplete *>(&dummy); xcb_glx_buffer_swap_complete_event_t ev; memset(&ev, 0, sizeof(xcb_glx_buffer_swap_complete_event_t)); ev.response_type = xev->type; ev.sequence = xev->serial; ev.event_type = xev->event_type; ev.drawable = xev->drawable; ev.ust_hi = xev->ust >> 32; ev.ust_lo = xev->ust & 0xffffffff; ev.msc_hi = xev->msc >> 32; ev.msc_lo = xev->msc & 0xffffffff; ev.sbc = xev->sbc & 0xffffffff; // Unlock the display before calling the native event filter XUnlockDisplay(xdisplay); locked = false; QByteArray genericEventFilterType = m_connection->nativeInterface()->genericEventFilterType(); long result = 0; handled = dispatcher->filterNativeEvent(genericEventFilterType, &ev, &result); } #endif } }
Bool DRI2QueryVersion(Display * dpy, int *major, int *minor) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2QueryVersionReply rep; xDRI2QueryVersionReq *req; int i, nevents; XextCheckExtension(dpy, info, dri2ExtensionName, False); LockDisplay(dpy); GetReq(DRI2QueryVersion, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2QueryVersion; req->majorVersion = DRI2_MAJOR; req->minorVersion = DRI2_MINOR; if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return False; } *major = rep.majorVersion; *minor = rep.minorVersion; UnlockDisplay(dpy); SyncHandle(); switch (rep.minorVersion) { case 1: nevents = 0; break; case 2: nevents = 1; break; case 3: default: nevents = 2; break; } for (i = 0; i < nevents; i++) { XESetWireToEvent (dpy, info->codes->first_event + i, DRI2WireToEvent); XESetEventToWire (dpy, info->codes->first_event + i, DRI2EventToWire); } return True; }
Bool XDGAQueryVersion( Display *dpy, int *majorVersion, int *minorVersion ){ XExtDisplayInfo *info = xdga_find_display (dpy); xXDGAQueryVersionReply rep; xXDGAQueryVersionReq *req; XDGACheckExtension (dpy, info, False); LockDisplay(dpy); GetReq(XDGAQueryVersion, req); req->reqType = info->codes->major_opcode; req->dgaReqType = X_XDGAQueryVersion; if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return False; } *majorVersion = rep.majorVersion; *minorVersion = rep.minorVersion; UnlockDisplay(dpy); SyncHandle(); if (*majorVersion >= 2) { int i, j; for (i = 0, j = info->codes->first_event; i < XF86DGANumberEvents; i++, j++) { XESetWireToEvent (dpy, j, xdga_wire_to_event); XESetEventToWire (dpy, j, xdga_event_to_wire); } XDGASetClientVersion(dpy); } return True; }
/* * XDamageExtAddDisplay - add a display to this extension. (Replaces * XextAddDisplay) */ static XDamageExtDisplayInfo * XDamageExtAddDisplay (XDamageExtInfo *extinfo, Display *dpy, const char *ext_name) { XDamageExtDisplayInfo *info; int ev; info = (XDamageExtDisplayInfo *) Xmalloc (sizeof (XDamageExtDisplayInfo)); if (!info) return NULL; info->display = dpy; info->codes = XInitExtension (dpy, ext_name); /* * if the server has the extension, then we can initialize the * appropriate function vectors */ if (info->codes) { xDamageQueryVersionReply rep; xDamageQueryVersionReq *req; XESetCloseDisplay (dpy, info->codes->extension, XDamageCloseDisplay); for (ev = info->codes->first_event; ev < info->codes->first_event + XDamageNumberEvents; ev++) { XESetWireToEvent (dpy, ev, XDamageWireToEvent); XESetEventToWire (dpy, ev, XDamageEventToWire); } /* * Get the version info */ LockDisplay (dpy); GetReq (DamageQueryVersion, req); req->reqType = info->codes->major_opcode; req->damageReqType = X_DamageQueryVersion; req->majorVersion = DAMAGE_MAJOR; req->minorVersion = DAMAGE_MINOR; if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { UnlockDisplay (dpy); SyncHandle (); Xfree(info); return NULL; } info->major_version = rep.majorVersion; info->minor_version = rep.minorVersion; UnlockDisplay (dpy); SyncHandle (); } else { /* The server doesn't have this extension. * Use a private Xlib-internal extension to hang the close_display * hook on so that the "cache" (extinfo->cur) is properly cleaned. * (XBUG 7955) */ XExtCodes *codes = XAddExtension(dpy); if (!codes) { XFree(info); return NULL; } XESetCloseDisplay (dpy, codes->extension, XDamageCloseDisplay); } /* * now, chain it onto the list */ _XLockMutex(_Xglobal_lock); info->next = extinfo->head; extinfo->head = info; extinfo->cur = info; extinfo->ndisplays++; _XUnlockMutex(_Xglobal_lock); return info; }
/* ** Initialize the client side extension code. */ _X_HIDDEN struct glx_display * __glXInitialize(Display * dpy) { struct glx_display *dpyPriv, *d; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) Bool glx_direct, glx_accel; #endif int i; _XLockMutex(_Xglobal_lock); for (dpyPriv = glx_displays; dpyPriv; dpyPriv = dpyPriv->next) { if (dpyPriv->dpy == dpy) { _XUnlockMutex(_Xglobal_lock); return dpyPriv; } } /* Drop the lock while we create the display private. */ _XUnlockMutex(_Xglobal_lock); dpyPriv = calloc(1, sizeof *dpyPriv); if (!dpyPriv) return NULL; dpyPriv->codes = XInitExtension(dpy, __glXExtensionName); if (!dpyPriv->codes) { free(dpyPriv); _XUnlockMutex(_Xglobal_lock); return NULL; } dpyPriv->dpy = dpy; dpyPriv->majorOpcode = dpyPriv->codes->major_opcode; dpyPriv->serverGLXvendor = 0x0; dpyPriv->serverGLXversion = 0x0; /* See if the versions are compatible. This GLX implementation does not * work with servers that only support GLX 1.0. */ if (!QueryVersion(dpy, dpyPriv->majorOpcode, &dpyPriv->majorVersion, &dpyPriv->minorVersion) || (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion < 1)) { free(dpyPriv); _XUnlockMutex(_Xglobal_lock); return NULL; } for (i = 0; i < __GLX_NUMBER_EVENTS; i++) { XESetWireToEvent(dpy, dpyPriv->codes->first_event + i, __glXWireToEvent); XESetEventToWire(dpy, dpyPriv->codes->first_event + i, __glXEventToWire); } XESetCloseDisplay(dpy, dpyPriv->codes->extension, __glXCloseDisplay); XESetErrorString (dpy, dpyPriv->codes->extension,__glXErrorString); dpyPriv->glXDrawHash = __glxHashCreate(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) glx_direct = (getenv("LIBGL_ALWAYS_INDIRECT") == NULL); glx_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL); dpyPriv->drawHash = __glxHashCreate(); /* ** Initialize the direct rendering per display data and functions. ** Note: This _must_ be done before calling any other DRI routines ** (e.g., those called in AllocAndFetchScreenConfigs). */ if (glx_direct && glx_accel) { #if defined(HAVE_DRI3) if (!getenv("LIBGL_DRI3_DISABLE")) dpyPriv->dri3Display = dri3_create_display(dpy); #endif dpyPriv->dri2Display = dri2CreateDisplay(dpy); dpyPriv->driDisplay = driCreateDisplay(dpy); } if (glx_direct) dpyPriv->driswDisplay = driswCreateDisplay(dpy); #endif #ifdef GLX_USE_APPLEGL if (!applegl_create_display(dpyPriv)) { free(dpyPriv); return NULL; } #endif if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) { free(dpyPriv); return NULL; } __glX_send_client_info(dpyPriv); /* Grab the lock again and add the dispay private, unless somebody * beat us to initializing on this display in the meantime. */ _XLockMutex(_Xglobal_lock); for (d = glx_displays; d; d = d->next) { if (d->dpy == dpy) { _XUnlockMutex(_Xglobal_lock); glx_display_free(dpyPriv); return d; } } dpyPriv->next = glx_displays; glx_displays = dpyPriv; _XUnlockMutex(_Xglobal_lock); return dpyPriv; }
/* * XextAddDisplay - add a display to this extension */ XExtDisplayInfo *XextAddDisplay ( XExtensionInfo *extinfo, Display *dpy, _Xconst char *ext_name, XExtensionHooks *hooks, int nevents, XPointer data) { XExtDisplayInfo *dpyinfo; dpyinfo = (XExtDisplayInfo *) Xmalloc (sizeof (XExtDisplayInfo)); if (!dpyinfo) return NULL; dpyinfo->display = dpy; dpyinfo->data = data; dpyinfo->codes = XInitExtension (dpy, ext_name); /* * if the server has the extension, then we can initialize the * appropriate function vectors */ if (dpyinfo->codes) { int i, j; for (i = 0, j = dpyinfo->codes->first_event; i < nevents; i++, j++) { XESetWireToEvent (dpy, j, hooks->wire_to_event); XESetEventToWire (dpy, j, hooks->event_to_wire); } /* register extension for XGE */ if (strcmp(ext_name, GE_NAME)) xgeExtRegister(dpy, dpyinfo->codes->major_opcode, hooks); if (hooks->create_gc) XESetCreateGC (dpy, dpyinfo->codes->extension, hooks->create_gc); if (hooks->copy_gc) XESetCopyGC (dpy, dpyinfo->codes->extension, hooks->copy_gc); if (hooks->flush_gc) XESetFlushGC (dpy, dpyinfo->codes->extension, hooks->flush_gc); if (hooks->free_gc) XESetFreeGC (dpy, dpyinfo->codes->extension, hooks->free_gc); if (hooks->create_font) XESetCreateFont (dpy, dpyinfo->codes->extension, hooks->create_font); if (hooks->free_font) XESetFreeFont (dpy, dpyinfo->codes->extension, hooks->free_font); if (hooks->close_display) XESetCloseDisplay (dpy, dpyinfo->codes->extension, hooks->close_display); if (hooks->error) XESetError (dpy, dpyinfo->codes->extension, hooks->error); if (hooks->error_string) XESetErrorString (dpy, dpyinfo->codes->extension, hooks->error_string); } else if (hooks->close_display) { /* The server doesn't have this extension. * Use a private Xlib-internal extension to hang the close_display * hook on so that the "cache" (extinfo->cur) is properly cleaned. * (XBUG 7955) */ XExtCodes *codes = XAddExtension(dpy); if (!codes) { XFree(dpyinfo); return NULL; } XESetCloseDisplay (dpy, codes->extension, hooks->close_display); } /* * now, chain it onto the list */ _XLockMutex(_Xglobal_lock); dpyinfo->next = extinfo->head; extinfo->head = dpyinfo; extinfo->cur = dpyinfo; extinfo->ndisplays++; _XUnlockMutex(_Xglobal_lock); return dpyinfo; }