diff --git a/src/input/x11.c b/src/input/x11.c index 88d64702..93ca7d6a 100644 --- a/src/input/x11.c +++ b/src/input/x11.c @@ -36,6 +36,7 @@ static Display *display; static Window window; +static XEvent event; static Atom wm_deletemessage; @@ -46,101 +47,122 @@ static const char data[1] = {0}; static Cursor cursor; static bool grabbed = True; +static int motion_x, motion_y; + +static int x11_handle_motion_notify() { + motion_x = 0; + motion_y = 0; + int i; + for ( + i = 0; + i < 100 && + XPending(display) && + XCheckMaskEvent(display, PointerMotionMask, &event); + ++i + ) { + motion_x = event.xmotion.x - last_x; + motion_y = event.xmotion.y - last_y; + if (abs(motion_x) > 0 || abs(motion_y) > 0) { + if (last_x >= 0 && last_y >= 0) + LiSendMouseMoveEvent(motion_x, motion_y); + + last_x = event.xmotion.x; + last_y = event.xmotion.y; + } + } + + if (i == 0 && grabbed) { + XWarpPointer(display, None, window, 0, 0, 0, 0, 640, 360); + last_x = 640; + last_y = 360; + } + return i; +} + static int x11_handler(int fd) { - XEvent event; int button = 0; - int motion_x, motion_y; while (XPending(display)) { - XNextEvent(display, &event); - switch (event.type) { - case KeyPress: - case KeyRelease: - if (event.xkey.keycode >= 8 && event.xkey.keycode < (sizeof(keyCodes)/sizeof(keyCodes[0]) + 8)) { - if ((keyboard_modifiers & ACTION_MODIFIERS) == ACTION_MODIFIERS && event.type == KeyRelease) { - if (event.xkey.keycode == QUIT_KEY) - return LOOP_RETURN; - else { - grabbed = !grabbed; - XDefineCursor(display, window, grabbed ? cursor : 0); + XPeekEvent(display, &event); + while (x11_handle_motion_notify() > 0) {} + if (XCheckMaskEvent(display, ~PointerMotionMask, &event)) { + switch (event.type) { + case KeyPress: + case KeyRelease: + if (event.xkey.keycode >= 8 && event.xkey.keycode < (sizeof(keyCodes)/sizeof(keyCodes[0]) + 8)) { + if ((keyboard_modifiers & ACTION_MODIFIERS) == ACTION_MODIFIERS && event.type == KeyRelease) { + if (event.xkey.keycode == QUIT_KEY) + return LOOP_RETURN; + else { + grabbed = !grabbed; + XDefineCursor(display, window, grabbed ? cursor : 0); + } + } + + int modifier = 0; + switch (event.xkey.keycode) { + case 0x32: + case 0x3e: + modifier = MODIFIER_SHIFT; + break; + case 0x40: + case 0x6c: + modifier = MODIFIER_ALT; + break; + case 0x25: + case 0x69: + modifier = MODIFIER_CTRL; + break; + } + + if (modifier != 0) { + if (event.type == KeyPress) + keyboard_modifiers |= modifier; + else + keyboard_modifiers &= ~modifier; } - } - int modifier = 0; - switch (event.xkey.keycode) { - case 0x32: - case 0x3e: - modifier = MODIFIER_SHIFT; + short code = 0x80 << 8 | keyCodes[event.xkey.keycode - 8]; + LiSendKeyboardEvent(code, event.type == KeyPress ? KEY_ACTION_DOWN : KEY_ACTION_UP, keyboard_modifiers); + } + break; + case ButtonPress: + case ButtonRelease: + switch (event.xbutton.button) { + case Button1: + button = BUTTON_LEFT; break; - case 0x40: - case 0x6c: - modifier = MODIFIER_ALT; + case Button2: + button = BUTTON_MIDDLE; break; - case 0x25: - case 0x69: - modifier = MODIFIER_CTRL; + case Button3: + button = BUTTON_RIGHT; + break; + case Button4: + LiSendScrollEvent(1); + break; + case Button5: + LiSendScrollEvent(-1); + break; + case 8: + button = BUTTON_X1; + break; + case 9: + button = BUTTON_X2; break; } - if (modifier != 0) { - if (event.type == KeyPress) - keyboard_modifiers |= modifier; - else - keyboard_modifiers &= ~modifier; - } - - short code = 0x80 << 8 | keyCodes[event.xkey.keycode - 8]; - LiSendKeyboardEvent(code, event.type == KeyPress ? KEY_ACTION_DOWN : KEY_ACTION_UP, keyboard_modifiers); - } - break; - case ButtonPress: - case ButtonRelease: - switch (event.xbutton.button) { - case Button1: - button = BUTTON_LEFT; - break; - case Button2: - button = BUTTON_MIDDLE; - break; - case Button3: - button = BUTTON_RIGHT; + if (button != 0) + LiSendMouseButtonEvent(event.type==ButtonPress ? BUTTON_ACTION_PRESS : BUTTON_ACTION_RELEASE, button); break; - case Button4: - LiSendScrollEvent(1); + case MotionNotify: //will never happen break; - case Button5: - LiSendScrollEvent(-1); - break; - case 8: - button = BUTTON_X1; - break; - case 9: - button = BUTTON_X2; - break; - } + case ClientMessage: + if (event.xclient.data.l[0] == wm_deletemessage) + return LOOP_RETURN; - if (button != 0) - LiSendMouseButtonEvent(event.type==ButtonPress ? BUTTON_ACTION_PRESS : BUTTON_ACTION_RELEASE, button); - break; - case MotionNotify: - motion_x = event.xmotion.x - last_x; - motion_y = event.xmotion.y - last_y; - if (abs(motion_x) > 0 || abs(motion_y) > 0) { - if (last_x >= 0 && last_y >= 0) - LiSendMouseMoveEvent(motion_x, motion_y); - - if (grabbed) - XWarpPointer(display, None, window, 0, 0, 0, 0, 640, 360); + break; } - - last_x = grabbed ? 640 : event.xmotion.x; - last_y = grabbed ? 360 : event.xmotion.y; - break; - case ClientMessage: - if (event.xclient.data.l[0] == wm_deletemessage) - return LOOP_RETURN; - - break; } }