static void ephyrXcbNotify(int fd, int ready, void *data) { xcb_connection_t *conn = hostx_get_xcbconn(); while (TRUE) { xcb_generic_event_t *xev = xcb_poll_for_event(conn); if (!xev) { /* If our XCB connection has died (for example, our window was * closed), exit now. */ if (xcb_connection_has_error(conn)) { CloseWellKnownConnections(); OsCleanup(1); exit(1); } break; } switch (xev->response_type & 0x7f) { case 0: ephyrProcessErrorEvent(xev); break; case XCB_EXPOSE: ephyrProcessExpose(xev); break; case XCB_MOTION_NOTIFY: ephyrProcessMouseMotion(xev); break; case XCB_KEY_PRESS: ephyrProcessKeyPress(xev); break; case XCB_KEY_RELEASE: ephyrProcessKeyRelease(xev); break; case XCB_BUTTON_PRESS: ephyrProcessButtonPress(xev); break; case XCB_BUTTON_RELEASE: ephyrProcessButtonRelease(xev); break; case XCB_CONFIGURE_NOTIFY: ephyrProcessConfigureNotify(xev); break; } if (ephyr_glamor) ephyr_glamor_process_event(xev); free(xev); } }
Bool host_has_extension(xcb_extension_t *extension) { const xcb_query_extension_reply_t *rep; rep = xcb_get_extension_data(hostx_get_xcbconn(), extension); return rep && rep->present; }
static void ephyrProcessKeyRelease(xcb_generic_event_t *xev) { xcb_connection_t *conn = hostx_get_xcbconn(); xcb_key_release_event_t *key = (xcb_key_release_event_t *)xev; static xcb_key_symbols_t *keysyms; static int grabbed_screen = -1; int mod1_down = ephyrUpdateGrabModifierState(key->state); if (!keysyms) keysyms = xcb_key_symbols_alloc(conn); if (!EphyrWantNoHostGrab && (((xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Shift_L || xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Shift_R) && (key->state & XCB_MOD_MASK_CONTROL)) || ((xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Control_L || xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Control_R) && (key->state & XCB_MOD_MASK_SHIFT)))) { KdScreenInfo *screen = screen_from_window(key->event); EphyrScrPriv *scrpriv = screen->driver; if (grabbed_screen != -1) { xcb_ungrab_keyboard(conn, XCB_TIME_CURRENT_TIME); xcb_ungrab_pointer(conn, XCB_TIME_CURRENT_TIME); grabbed_screen = -1; hostx_set_win_title(screen, "(ctrl+shift grabs mouse and keyboard)"); } else if (!mod1_down) { /* Attempt grab */ xcb_grab_keyboard_cookie_t kbgrabc = xcb_grab_keyboard(conn, TRUE, scrpriv->win, XCB_TIME_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); xcb_grab_keyboard_reply_t *kbgrabr; xcb_grab_pointer_cookie_t pgrabc = xcb_grab_pointer(conn, TRUE, scrpriv->win, 0, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, scrpriv->win, XCB_NONE, XCB_TIME_CURRENT_TIME); xcb_grab_pointer_reply_t *pgrabr; kbgrabr = xcb_grab_keyboard_reply(conn, kbgrabc, NULL); if (!kbgrabr || kbgrabr->status != XCB_GRAB_STATUS_SUCCESS) { xcb_discard_reply(conn, pgrabc.sequence); xcb_ungrab_pointer(conn, XCB_TIME_CURRENT_TIME); } else { pgrabr = xcb_grab_pointer_reply(conn, pgrabc, NULL); if (!pgrabr || pgrabr->status != XCB_GRAB_STATUS_SUCCESS) { xcb_ungrab_keyboard(conn, XCB_TIME_CURRENT_TIME); } else { grabbed_screen = scrpriv->mynum; hostx_set_win_title (screen, "(ctrl+shift releases mouse and keyboard)"); } } } } if (!ephyrKbd || !((EphyrKbdPrivate *) ephyrKbd->driverPrivate)->enabled) { return; } /* Still send the release event even if above has happened server * will get confused with just an up event. Maybe it would be * better to just block shift+ctrls getting to kdrive all * together. */ ephyrUpdateModifierState(key->state); KdEnqueueKeyboardEvent(ephyrKbd, key->detail, TRUE); }
static void ephyrXcbProcessEvents(Bool queued_only) { xcb_connection_t *conn = hostx_get_xcbconn(); xcb_generic_event_t *expose = NULL, *configure = NULL; while (TRUE) { xcb_generic_event_t *xev = hostx_get_event(queued_only); if (!xev) { /* If our XCB connection has died (for example, our window was * closed), exit now. */ if (xcb_connection_has_error(conn)) { CloseWellKnownConnections(); OsCleanup(1); exit(1); } break; } switch (xev->response_type & 0x7f) { case 0: ephyrProcessErrorEvent(xev); break; case XCB_EXPOSE: free(expose); expose = xev; xev = NULL; break; case XCB_MOTION_NOTIFY: ephyrProcessMouseMotion(xev); break; case XCB_KEY_PRESS: ephyrProcessKeyPress(xev); break; case XCB_KEY_RELEASE: ephyrProcessKeyRelease(xev); break; case XCB_BUTTON_PRESS: ephyrProcessButtonPress(xev); break; case XCB_BUTTON_RELEASE: ephyrProcessButtonRelease(xev); break; case XCB_CONFIGURE_NOTIFY: free(configure); configure = xev; xev = NULL; break; } if (xev) { if (ephyr_glamor) ephyr_glamor_process_event(xev); free(xev); } } if (configure) { ephyrProcessConfigureNotify(configure); free(configure); } if (expose) { ephyrProcessExpose(expose); free(expose); } }