ephyr: Move event processing into ephyr.c.
No more extra event structure to translate between hostx.c and ephyr.c! Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Julien Cristau <jcristau@debian.org>
This commit is contained in:
parent
847c856eff
commit
46cf6bf569
|
@ -27,6 +27,9 @@
|
|||
#include <kdrive-config.h>
|
||||
#endif
|
||||
|
||||
#include <xcb/xcb_keysyms.h>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
#include "ephyr.h"
|
||||
|
||||
#include "inputstr.h"
|
||||
|
@ -799,13 +802,13 @@ ephyrCrossScreen(ScreenPtr pScreen, Bool entering)
|
|||
{
|
||||
}
|
||||
|
||||
int ephyrCurScreen; /*current event screen */
|
||||
ScreenPtr ephyrCursorScreen; /* screen containing the cursor */
|
||||
|
||||
static void
|
||||
ephyrWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
|
||||
{
|
||||
OsBlockSIGIO();
|
||||
ephyrCurScreen = pScreen->myNum;
|
||||
ephyrCursorScreen = pScreen;
|
||||
miPointerWarpCursor(inputInfo.pointer, pScreen, x, y);
|
||||
|
||||
OsReleaseSIGIO();
|
||||
|
@ -853,123 +856,324 @@ ephyrExposePairedWindow(int a_remote)
|
|||
}
|
||||
#endif /* XF86DRI */
|
||||
|
||||
static KdScreenInfo *
|
||||
screen_from_window(Window w)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < screenInfo.numScreens; i++) {
|
||||
ScreenPtr pScreen = screenInfo.screens[i];
|
||||
KdPrivScreenPtr kdscrpriv = KdGetScreenPriv(pScreen);
|
||||
KdScreenInfo *screen = kdscrpriv->screen;
|
||||
EphyrScrPriv *scrpriv = screen->driver;
|
||||
|
||||
if (scrpriv->win == w
|
||||
|| scrpriv->peer_win == w
|
||||
|| scrpriv->win_pre_existing == w) {
|
||||
return screen;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
ephyrProcessErrorEvent(xcb_generic_event_t *xev)
|
||||
{
|
||||
xcb_generic_error_t *e = (xcb_generic_error_t *)xev;
|
||||
|
||||
FatalError("X11 error\n"
|
||||
"Error code: %hhu\n"
|
||||
"Sequence number: %hu\n"
|
||||
"Major code: %hhu\tMinor code: %hu\n"
|
||||
"Error value: %u\n",
|
||||
e->error_code,
|
||||
e->sequence,
|
||||
e->major_code, e->minor_code,
|
||||
e->resource_id);
|
||||
}
|
||||
|
||||
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
|
||||
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, 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", ephyrCurScreen);
|
||||
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
|
||||
KdEnqueuePointerEvent(ephyrMouse, mouseState, x, y, 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", ephyrCurScreen);
|
||||
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", ephyrCurScreen);
|
||||
KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0, 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", ephyrCurScreen);
|
||||
KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
ephyrProcessKeyPress(xcb_generic_event_t *xev)
|
||||
{
|
||||
xcb_key_press_event_t *key = (xcb_key_press_event_t *)xev;
|
||||
|
||||
if (!ephyrKbd ||
|
||||
!((EphyrKbdPrivate *) ephyrKbd->driverPrivate)->enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
ephyrUpdateModifierState(key->state);
|
||||
KdEnqueueKeyboardEvent(ephyrKbd, key->detail, FALSE);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!keysyms)
|
||||
keysyms = xcb_key_symbols_alloc(conn);
|
||||
|
||||
if ((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)) {
|
||||
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 {
|
||||
/* 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
|
||||
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 */
|
||||
}
|
||||
|
||||
void
|
||||
ephyrPoll(void)
|
||||
{
|
||||
EphyrHostXEvent ev;
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
|
||||
while (hostx_get_event(&ev)) {
|
||||
switch (ev.type) {
|
||||
case EPHYR_EV_MOUSE_MOTION:
|
||||
if (!ephyrMouse ||
|
||||
!((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) {
|
||||
EPHYR_LOG("skipping mouse motion:%d\n", ephyrCurScreen);
|
||||
continue;
|
||||
}
|
||||
{
|
||||
if (ev.data.mouse_motion.screen >= 0
|
||||
&& (ephyrCurScreen != ev.data.mouse_motion.screen)) {
|
||||
EPHYR_LOG("warping mouse cursor. "
|
||||
"cur_screen%d, motion_screen:%d\n",
|
||||
ephyrCurScreen, ev.data.mouse_motion.screen);
|
||||
if (ev.data.mouse_motion.screen >= 0) {
|
||||
ephyrWarpCursor
|
||||
(inputInfo.pointer,
|
||||
screenInfo.screens[ev.data.mouse_motion.screen],
|
||||
ev.data.mouse_motion.x, ev.data.mouse_motion.y);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int x = 0, y = 0;
|
||||
|
||||
#ifdef XF86DRI
|
||||
EphyrWindowPair *pair = NULL;
|
||||
#endif
|
||||
EPHYR_LOG("enqueuing mouse motion:%d\n", ephyrCurScreen);
|
||||
x = ev.data.mouse_motion.x;
|
||||
y = ev.data.mouse_motion.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(ev.data.mouse_motion.window,
|
||||
&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
|
||||
KdEnqueuePointerEvent(ephyrMouse, mouseState, x, y, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EPHYR_EV_MOUSE_PRESS:
|
||||
if (!ephyrMouse ||
|
||||
!((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) {
|
||||
EPHYR_LOG("skipping mouse press:%d\n", ephyrCurScreen);
|
||||
continue;
|
||||
}
|
||||
EPHYR_LOG("enqueuing mouse press:%d\n", ephyrCurScreen);
|
||||
ephyrUpdateModifierState(ev.key_state);
|
||||
mouseState |= ev.data.mouse_down.button_num;
|
||||
KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0,
|
||||
0);
|
||||
break;
|
||||
|
||||
case EPHYR_EV_MOUSE_RELEASE:
|
||||
if (!ephyrMouse ||
|
||||
!((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled)
|
||||
continue;
|
||||
ephyrUpdateModifierState(ev.key_state);
|
||||
mouseState &= ~ev.data.mouse_up.button_num;
|
||||
EPHYR_LOG("enqueuing mouse release:%d\n", ephyrCurScreen);
|
||||
KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0,
|
||||
0);
|
||||
break;
|
||||
|
||||
case EPHYR_EV_KEY_PRESS:
|
||||
if (!ephyrKbd ||
|
||||
!((EphyrKbdPrivate *) ephyrKbd->driverPrivate)->enabled)
|
||||
continue;
|
||||
ephyrUpdateModifierState(ev.key_state);
|
||||
KdEnqueueKeyboardEvent(ephyrKbd, ev.data.key_down.scancode, FALSE);
|
||||
break;
|
||||
|
||||
case EPHYR_EV_KEY_RELEASE:
|
||||
if (!ephyrKbd ||
|
||||
!((EphyrKbdPrivate *) ephyrKbd->driverPrivate)->enabled)
|
||||
continue;
|
||||
ephyrUpdateModifierState(ev.key_state);
|
||||
KdEnqueueKeyboardEvent(ephyrKbd, ev.data.key_up.scancode, TRUE);
|
||||
break;
|
||||
|
||||
#ifdef XF86DRI
|
||||
case EPHYR_EV_EXPOSE:
|
||||
/*
|
||||
* 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.
|
||||
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.
|
||||
*/
|
||||
ephyrExposePairedWindow(ev.data.expose.window);
|
||||
break;
|
||||
#endif /* XF86DRI */
|
||||
if (xcb_connection_has_error(conn)) {
|
||||
CloseWellKnownConnections();
|
||||
OsCleanup(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef RANDR
|
||||
case EPHYR_EV_CONFIGURE:
|
||||
ephyrResizeScreen(screenInfo.screens[ev.data.configure.screen],
|
||||
ev.data.configure.width,
|
||||
ev.data.configure.height);
|
||||
break;
|
||||
#endif /* RANDR */
|
||||
|
||||
default:
|
||||
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;
|
||||
}
|
||||
|
||||
free(xev);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -853,231 +853,6 @@ hostx_load_keymap(void)
|
|||
ephyrKeySyms.maxKeyCode = max_keycode;
|
||||
}
|
||||
|
||||
static KdScreenInfo *
|
||||
screen_from_window(Window w)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
for (index = 0; index < HostX.n_screens; index++) {
|
||||
EphyrScrPriv *scrpriv = HostX.screens[index]->driver;
|
||||
if (scrpriv->win == w
|
||||
|| scrpriv->peer_win == w
|
||||
|| scrpriv->win_pre_existing == w) {
|
||||
return HostX.screens[index];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
hostx_get_event(EphyrHostXEvent * ev)
|
||||
{
|
||||
xcb_generic_event_t *xev;
|
||||
static int grabbed_screen = -1;
|
||||
static xcb_key_symbols_t *keysyms;
|
||||
|
||||
if (!keysyms)
|
||||
keysyms = xcb_key_symbols_alloc(HostX.conn);
|
||||
|
||||
xev = xcb_poll_for_event(HostX.conn);
|
||||
if (!xev) {
|
||||
/* If our XCB connection has died (for example, our window was
|
||||
* closed), exit now.
|
||||
*/
|
||||
if (xcb_connection_has_error(HostX.conn)) {
|
||||
CloseWellKnownConnections();
|
||||
OsCleanup(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (xev->response_type & 0x7f) {
|
||||
case 0: { /* error */
|
||||
xcb_generic_error_t *e = (xcb_generic_error_t *)xev;
|
||||
fprintf(stderr, "X11 error\n"
|
||||
"Error code: %hhu\n"
|
||||
"Sequence number: %hu\n"
|
||||
"Major code: %hhu\tMinor code: %hu\n"
|
||||
"Error value: %u\n",
|
||||
e->error_code,
|
||||
e->sequence,
|
||||
e->major_code, e->minor_code,
|
||||
e->resource_id);
|
||||
free(xev);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
case XCB_EXPOSE: {
|
||||
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)
|
||||
break;
|
||||
|
||||
if (scrpriv) {
|
||||
hostx_paint_rect(screen, 0, 0, 0, 0,
|
||||
scrpriv->win_width,
|
||||
scrpriv->win_height);
|
||||
}
|
||||
else {
|
||||
EPHYR_LOG_ERROR("failed to get host screen\n");
|
||||
ev->type = EPHYR_EV_EXPOSE;
|
||||
ev->data.expose.window = expose->window;
|
||||
free(xev);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case XCB_MOTION_NOTIFY: {
|
||||
xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *)xev;
|
||||
KdScreenInfo *screen = screen_from_window(motion->event);
|
||||
EphyrScrPriv *scrpriv = screen->driver;
|
||||
|
||||
ev->type = EPHYR_EV_MOUSE_MOTION;
|
||||
ev->data.mouse_motion.x = motion->event_x;
|
||||
ev->data.mouse_motion.y = motion->event_y;
|
||||
ev->data.mouse_motion.window = motion->event;
|
||||
ev->data.mouse_motion.screen = scrpriv ? scrpriv->mynum : -1;
|
||||
free(xev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case XCB_BUTTON_PRESS: {
|
||||
xcb_button_press_event_t *button = (xcb_button_press_event_t *)xev;
|
||||
ev->type = EPHYR_EV_MOUSE_PRESS;
|
||||
ev->key_state = button->state;
|
||||
/*
|
||||
* This is a bit hacky. will break for button 5 ( defined as 0x10 )
|
||||
* Check KD_BUTTON defines in kdrive.h
|
||||
*/
|
||||
ev->data.mouse_down.button_num = 1 << (button->detail - 1);
|
||||
free(xev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case XCB_BUTTON_RELEASE: {
|
||||
xcb_button_release_event_t *button = (xcb_button_release_event_t *)xev;
|
||||
ev->type = EPHYR_EV_MOUSE_RELEASE;
|
||||
ev->key_state = button->state;
|
||||
ev->data.mouse_up.button_num = 1 << (button->detail-1);
|
||||
free(xev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case XCB_KEY_PRESS: {
|
||||
xcb_key_press_event_t *key = (xcb_key_press_event_t *)xev;
|
||||
ev->type = EPHYR_EV_KEY_PRESS;
|
||||
ev->key_state = key->state;
|
||||
ev->data.key_down.scancode = key->detail;
|
||||
free(xev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case XCB_KEY_RELEASE: {
|
||||
xcb_key_release_event_t *key = (xcb_key_release_event_t *)xev;
|
||||
if ((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)) {
|
||||
KdScreenInfo *screen = screen_from_window(key->event);
|
||||
EphyrScrPriv *scrpriv = screen->driver;
|
||||
|
||||
if (grabbed_screen != -1) {
|
||||
xcb_ungrab_keyboard(HostX.conn, XCB_TIME_CURRENT_TIME);
|
||||
xcb_ungrab_pointer(HostX.conn, XCB_TIME_CURRENT_TIME);
|
||||
grabbed_screen = -1;
|
||||
hostx_set_win_title(screen,
|
||||
"(ctrl+shift grabs mouse and keyboard)");
|
||||
}
|
||||
else {
|
||||
/* Attempt grab */
|
||||
xcb_grab_keyboard_cookie_t kbgrabc =
|
||||
xcb_grab_keyboard(HostX.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(HostX.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(HostX.conn, kbgrabc, NULL);
|
||||
if (!kbgrabr || kbgrabr->status != XCB_GRAB_STATUS_SUCCESS) {
|
||||
xcb_discard_reply(HostX.conn, pgrabc.sequence);
|
||||
xcb_ungrab_pointer(HostX.conn, XCB_TIME_CURRENT_TIME);
|
||||
} else {
|
||||
pgrabr = xcb_grab_pointer_reply(HostX.conn, pgrabc, NULL);
|
||||
if (!pgrabr || pgrabr->status != XCB_GRAB_STATUS_SUCCESS)
|
||||
{
|
||||
xcb_ungrab_keyboard(HostX.conn,
|
||||
XCB_TIME_CURRENT_TIME);
|
||||
} else {
|
||||
grabbed_screen = scrpriv->mynum;
|
||||
hostx_set_win_title
|
||||
(screen,
|
||||
"(ctrl+shift releases mouse and keyboard)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 togeather.
|
||||
*/
|
||||
ev->type = EPHYR_EV_KEY_RELEASE;
|
||||
ev->key_state = key->state;
|
||||
ev->data.key_up.scancode = key->detail;
|
||||
return 1;
|
||||
}
|
||||
|
||||
case ConfigureNotify:
|
||||
{
|
||||
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)) {
|
||||
free(xev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ev->type = EPHYR_EV_CONFIGURE;
|
||||
ev->data.configure.width = configure->width;
|
||||
ev->data.configure.height = configure->height;
|
||||
ev->data.configure.window = configure->window;
|
||||
ev->data.configure.screen = scrpriv->mynum;
|
||||
free(xev);
|
||||
|
||||
return 1;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
free(xev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
xcb_connection_t *
|
||||
hostx_get_xcbconn(void)
|
||||
{
|
||||
|
|
|
@ -41,65 +41,12 @@
|
|||
#endif
|
||||
|
||||
typedef struct EphyrHostXVars EphyrHostXVars;
|
||||
typedef struct EphyrHostXEvent EphyrHostXEvent;
|
||||
typedef enum EphyrHostXEventType {
|
||||
EPHYR_EV_MOUSE_MOTION,
|
||||
EPHYR_EV_MOUSE_PRESS,
|
||||
EPHYR_EV_MOUSE_RELEASE,
|
||||
EPHYR_EV_KEY_PRESS,
|
||||
EPHYR_EV_KEY_RELEASE,
|
||||
EPHYR_EV_EXPOSE,
|
||||
EPHYR_EV_CONFIGURE,
|
||||
} EphyrHostXEventType;
|
||||
|
||||
typedef struct {
|
||||
int minKeyCode;
|
||||
int maxKeyCode;
|
||||
} EphyrKeySyms;
|
||||
|
||||
struct EphyrHostXEvent {
|
||||
EphyrHostXEventType type;
|
||||
|
||||
union {
|
||||
struct mouse_motion {
|
||||
int x;
|
||||
int y;
|
||||
int screen;
|
||||
int window;
|
||||
} mouse_motion;
|
||||
|
||||
struct mouse_down {
|
||||
int button_num;
|
||||
} mouse_down;
|
||||
|
||||
struct mouse_up {
|
||||
int button_num;
|
||||
} mouse_up;
|
||||
|
||||
struct key_up {
|
||||
int scancode;
|
||||
} key_up;
|
||||
|
||||
struct key_down {
|
||||
int scancode;
|
||||
} key_down;
|
||||
|
||||
struct expose {
|
||||
int window;
|
||||
} expose;
|
||||
|
||||
struct configure {
|
||||
int width;
|
||||
int height;
|
||||
int screen;
|
||||
int window;
|
||||
} configure;
|
||||
|
||||
} data;
|
||||
|
||||
int key_state;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
VisualID visualid;
|
||||
int screen;
|
||||
|
@ -199,9 +146,6 @@ hostx_paint_rect(KdScreenInfo *screen,
|
|||
void
|
||||
hostx_load_keymap(void);
|
||||
|
||||
int
|
||||
hostx_get_event(EphyrHostXEvent * ev);
|
||||
|
||||
xcb_connection_t *
|
||||
hostx_get_xcbconn(void);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user