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 */ } }
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); }
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); } }
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); }
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 */ }
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"); } }
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); } }
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); }