Esempio n. 1
0
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);
    }
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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);
    }
}