Beispiel #1
0
static void
ephyrProcessExpose(xcb_generic_event_t *xev)
{
    xcb_expose_event_t *expose = (xcb_expose_event_t *)xev;
    KdScreenInfo *screen = screen_from_window(expose->window);
    EphyrScrPriv *scrpriv = screen->driver;

    /* Wait for the last expose event in a series of cliprects
     * to actually paint our screen.
     */
    if (expose->count != 0)
        return;

    if (scrpriv) {
        hostx_paint_rect(scrpriv->screen, 0, 0, 0, 0,
                         scrpriv->win_width,
                         scrpriv->win_height);
    } else {
        EPHYR_LOG_ERROR("failed to get host screen\n");
#ifdef XF86DRI
        /*
         * We only receive expose events when the expose event
         * have be generated for a drawable that is a host X
         * window managed by Xephyr. Host X windows managed by
         * Xephyr exists for instance when Xephyr is asked to
         * create a GL drawable in a DRI environment.
         */
        ephyrExposePairedWindow(expose->window);
#endif                          /* XF86DRI */
    }
}
Beispiel #2
0
static void
ephyrProcessButtonPress(xcb_generic_event_t *xev)
{
    xcb_button_press_event_t *button = (xcb_button_press_event_t *)xev;

    if (!ephyrMouse ||
        !((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) {
        EPHYR_LOG("skipping mouse press:%d\n", screen_from_window(button->event)->pScreen->myNum);
        return;
    }

    ephyrUpdateModifierState(button->state);
    /* This is a bit hacky. will break for button 5 ( defined as 0x10 )
     * Check KD_BUTTON defines in kdrive.h
     */
    mouseState |= 1 << (button->detail - 1);

    EPHYR_LOG("enqueuing mouse press:%d\n", screen_from_window(button->event)->pScreen->myNum);
    KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0, 0);
}
Beispiel #3
0
static void
ephyrProcessMouseMotion(xcb_generic_event_t *xev)
{
    xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *)xev;
    KdScreenInfo *screen = screen_from_window(motion->event);

    if (!ephyrMouse ||
        !((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) {
        EPHYR_LOG("skipping mouse motion:%d\n", screen->pScreen->myNum);
        return;
    }

    if (ephyrCursorScreen != screen->pScreen) {
        EPHYR_LOG("warping mouse cursor. "
                  "cur_screen:%d, motion_screen:%d\n",
                  ephyrCursorScreen->myNum, screen->pScreen->myNum);
        ephyrWarpCursor(inputInfo.pointer, screen->pScreen,
                        motion->event_x, motion->event_y);
    }
    else {
        int x = 0, y = 0;

#ifdef XF86DRI
        EphyrWindowPair *pair = NULL;
#endif
        EPHYR_LOG("enqueuing mouse motion:%d\n", screen->pScreen->myNum);
        x = motion->event_x;
        y = motion->event_y;
        EPHYR_LOG("initial (x,y):(%d,%d)\n", x, y);
#ifdef XF86DRI
        EPHYR_LOG("is this window peered by a gl drawable ?\n");
        if (findWindowPairFromRemote(motion->event, &pair)) {
            EPHYR_LOG("yes, it is peered\n");
            x += pair->local->drawable.x;
            y += pair->local->drawable.y;
        }
        else {
            EPHYR_LOG("no, it is not peered\n");
        }
        EPHYR_LOG("final (x,y):(%d,%d)\n", x, y);
#endif

        /* convert coords into desktop-wide coordinates.
         * fill_pointer_events will convert that back to
         * per-screen coordinates where needed */
        x += screen->pScreen->x;
        y += screen->pScreen->y;

        KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_POINTER_DESKTOP, x, y, 0);
    }
}
Beispiel #4
0
static void
ephyrProcessButtonRelease(xcb_generic_event_t *xev)
{
    xcb_button_press_event_t *button = (xcb_button_press_event_t *)xev;

    if (!ephyrMouse ||
        !((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) {
        return;
    }

    ephyrUpdateModifierState(button->state);
    mouseState &= ~(1 << (button->detail - 1));

    EPHYR_LOG("enqueuing mouse release:%d\n", screen_from_window(button->event)->pScreen->myNum);
    KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0, 0);
}
Beispiel #5
0
static void
ephyrProcessConfigureNotify(xcb_generic_event_t *xev)
{
    xcb_configure_notify_event_t *configure =
        (xcb_configure_notify_event_t *)xev;
    KdScreenInfo *screen = screen_from_window(configure->window);
    EphyrScrPriv *scrpriv = screen->driver;

    if (!scrpriv ||
        (scrpriv->win_pre_existing == None && !EphyrWantResize)) {
        return;
    }

#ifdef RANDR
    ephyrResizeScreen(screen->pScreen, configure->width, configure->height);
#endif /* RANDR */
}
Beispiel #6
0
static void
ephyrProcessExpose(xcb_generic_event_t *xev)
{
    xcb_expose_event_t *expose = (xcb_expose_event_t *)xev;
    KdScreenInfo *screen = screen_from_window(expose->window);
    EphyrScrPriv *scrpriv = screen->driver;

    /* Wait for the last expose event in a series of cliprects
     * to actually paint our screen.
     */
    if (expose->count != 0)
        return;

    if (scrpriv) {
        hostx_paint_rect(scrpriv->screen, 0, 0, 0, 0,
                         scrpriv->win_width,
                         scrpriv->win_height);
    } else {
        EPHYR_LOG_ERROR("failed to get host screen\n");
    }
}
Beispiel #7
0
static void
ephyrProcessMouseMotion(xcb_generic_event_t *xev)
{
    xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *)xev;
    KdScreenInfo *screen = screen_from_window(motion->event);

    if (!ephyrMouse ||
        !((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) {
        EPHYR_LOG("skipping mouse motion:%d\n", screen->pScreen->myNum);
        return;
    }

    if (ephyrCursorScreen != screen->pScreen) {
        EPHYR_LOG("warping mouse cursor. "
                  "cur_screen:%d, motion_screen:%d\n",
                  ephyrCursorScreen->myNum, screen->pScreen->myNum);
        ephyrWarpCursor(inputInfo.pointer, screen->pScreen,
                        motion->event_x, motion->event_y);
    }
    else {
        int x = 0, y = 0;

        EPHYR_LOG("enqueuing mouse motion:%d\n", screen->pScreen->myNum);
        x = motion->event_x;
        y = motion->event_y;
        EPHYR_LOG("initial (x,y):(%d,%d)\n", x, y);

        /* convert coords into desktop-wide coordinates.
         * fill_pointer_events will convert that back to
         * per-screen coordinates where needed */
        x += screen->pScreen->x;
        y += screen->pScreen->y;

        KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_POINTER_DESKTOP, x, y, 0);
    }
}
Beispiel #8
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);
}