diff --git a/client/displayservers/Wayland/input.c b/client/displayservers/Wayland/input.c index 45fc672e..4e9c5595 100644 --- a/client/displayservers/Wayland/input.c +++ b/client/displayservers/Wayland/input.c @@ -149,29 +149,37 @@ static void pointerAxisHandler(void * data, struct wl_pointer * pointer, app_handleWheelMotion(delta / WL_SCROLL_STEP); } -static int mapWaylandToSpiceButton(uint32_t button) +static int mapWaylandButton(uint32_t button) { switch (button) { case BTN_LEFT: - return 1; // SPICE_MOUSE_BUTTON_LEFT + return 1; case BTN_MIDDLE: - return 2; // SPICE_MOUSE_BUTTON_MIDDLE + return 2; case BTN_RIGHT: - return 3; // SPICE_MOUSE_BUTTON_RIGHT + return 3; case BTN_SIDE: - return 6; // SPICE_MOUSE_BUTTON_SIDE + return 6; case BTN_EXTRA: - return 7; // SPICE_MOUSE_BUTTON_EXTRA + return 7; + case BTN_FORWARD: + return 8; + case BTN_BACK: + return 9; + case BTN_TASK: + return 10; } - return 0; // SPICE_MOUSE_BUTTON_INVALID + return 0; } static void pointerButtonHandler(void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t stateW) { - button = mapWaylandToSpiceButton(button); + button = mapWaylandButton(button); + if (!button) + return; if (stateW == WL_POINTER_BUTTON_STATE_PRESSED) app_handleButtonPress(button); diff --git a/client/displayservers/X11/x11.c b/client/displayservers/X11/x11.c index 8c45d579..d5c544fb 100644 --- a/client/displayservers/X11/x11.c +++ b/client/displayservers/X11/x11.c @@ -1196,6 +1196,18 @@ static void x11UpdateKeyboardGroup(void) atomic_store(&x11.keyboardGroup, state.group); } +static int x11MapButton(unsigned int button) +{ + if (button >= 1 && button <= 5) + return button; + + /* X11 reserves buttons 6 and 7 for horizontal scrolling. */ + if (button >= 8 && button < 34) + return button - 2; + + return 0; +} + static void setFocus(bool focused, double x, double y) { if (x11.focused == focused) @@ -1226,7 +1238,7 @@ static bool x11GetKeyLabel(int sc, char * label, size_t size) static void x11XInputEvent(XGenericEventCookie *cookie) { - static int button_state = 0; + static uint32_t button_state = 0; switch(cookie->evtype) { @@ -1455,13 +1467,13 @@ static void x11XInputEvent(XGenericEventCookie *cookie) return; XIDeviceEvent *device = cookie->data; - if (device->detail == 4) + const int button = x11MapButton(device->detail); + if (button == 4) app_handleWheelMotion(-0.5); - else if (device->detail == 5) + else if (button == 5) app_handleWheelMotion(0.5); - else - app_handleButtonPress( - device->detail > 5 ? device->detail - 2 : device->detail); + else if (button) + app_handleButtonPress(button); return; } @@ -1472,7 +1484,9 @@ static void x11XInputEvent(XGenericEventCookie *cookie) return; XIDeviceEvent *device = cookie->data; - app_handleButtonRelease(device->detail); + const int button = x11MapButton(device->detail); + if (button && button != 4 && button != 5) + app_handleButtonRelease(button); return; } @@ -1482,6 +1496,9 @@ static void x11XInputEvent(XGenericEventCookie *cookie) return; XIRawEvent *raw = cookie->data; + const int button = x11MapButton(raw->detail); + if (!button) + return; /* filter out duplicate events */ static Time prev_time = 0; @@ -1491,10 +1508,9 @@ static void x11XInputEvent(XGenericEventCookie *cookie) prev_time = raw->time; prev_detail = raw->detail; - button_state |= (1 << raw->detail); + button_state |= UINT32_C(1) << button; - app_handleButtonPress( - raw->detail > 5 ? raw->detail - 2 : raw->detail); + app_handleButtonPress(button); return; } @@ -1504,6 +1520,9 @@ static void x11XInputEvent(XGenericEventCookie *cookie) return; XIRawEvent *raw = cookie->data; + const int button = x11MapButton(raw->detail); + if (!button) + return; /* filter out duplicate events */ static Time prev_time = 0; @@ -1513,10 +1532,9 @@ static void x11XInputEvent(XGenericEventCookie *cookie) prev_time = raw->time; prev_detail = raw->detail; - button_state &= ~(1 << raw->detail); + button_state &= ~(UINT32_C(1) << button); - app_handleButtonRelease( - raw->detail > 5 ? raw->detail - 2 : raw->detail); + app_handleButtonRelease(button); return; } diff --git a/client/include/interface/input.h b/client/include/interface/input.h index 8b491ce9..3d8ee4a1 100644 --- a/client/include/interface/input.h +++ b/client/include/interface/input.h @@ -62,7 +62,7 @@ typedef struct LG_InputOps /* Position is in guest pixels and must be within the supplied dimensions. */ bool (*mousePosition)(void * opaque, uint32_t x, uint32_t y, uint32_t width, uint32_t height); - /* Button order: left, middle, right, wheel up/down, side, extra. */ + /* Button order: left, middle, right, wheel up/down, then HID buttons 4+. */ bool (*mousePress)(void * opaque, unsigned int button); bool (*mouseRelease)(void * opaque, unsigned int button); diff --git a/client/src/evdev.c b/client/src/evdev.c index 2aaae55d..9909962a 100644 --- a/client/src/evdev.c +++ b/client/src/evdev.c @@ -211,8 +211,9 @@ static int evdev_thread(void * opaque) { case EV_KEY: { - bool isMouseBtn = ev->code >= BTN_MOUSE && ev->code <= BTN_BACK; - static const int mouseBtnMap[] = {1, 3, 2, 6, 7, 0, 0}; + bool isMouseBtn = + ev->code >= BTN_MOUSE && ev->code <= BTN_TASK; + static const int mouseBtnMap[] = {1, 3, 2, 6, 7, 8, 9, 10}; if (ev->value == 1) { diff --git a/client/src/input_spice.c b/client/src/input_spice.c index efaec2c9..10acb715 100644 --- a/client/src/input_spice.c +++ b/client/src/input_spice.c @@ -59,11 +59,17 @@ static bool spiceMouseMotion(void * opaque, int32_t x, int32_t y) static bool spiceMousePress(void * opaque, unsigned int button) { + if (button > 7) + return true; + return purespice_mousePress(button); } static bool spiceMouseRelease(void * opaque, unsigned int button) { + if (button > 7) + return true; + return purespice_mouseRelease(button); }