Esempio n. 1
0
/**
 * 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);
}
Esempio n. 2
0
File: Xge.c Progetto: aosm/X11libs
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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
        }
    }
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
/*
 * 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;
}
Esempio n. 8
0
/*
** 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;
}
Esempio n. 9
0
/*
 * 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;
}