mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-09 00:31:31 +00:00
[client] input: forward extended mouse buttons
Map the remaining Linux mouse buttons through Wayland and evdev. Use one X11 translation for cooked and raw press and release events. Ignore unsupported horizontal scrolling and extended SPICE buttons.
This commit is contained in:
@@ -149,29 +149,37 @@ static void pointerAxisHandler(void * data, struct wl_pointer * pointer,
|
|||||||
app_handleWheelMotion(delta / WL_SCROLL_STEP);
|
app_handleWheelMotion(delta / WL_SCROLL_STEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mapWaylandToSpiceButton(uint32_t button)
|
static int mapWaylandButton(uint32_t button)
|
||||||
{
|
{
|
||||||
switch (button)
|
switch (button)
|
||||||
{
|
{
|
||||||
case BTN_LEFT:
|
case BTN_LEFT:
|
||||||
return 1; // SPICE_MOUSE_BUTTON_LEFT
|
return 1;
|
||||||
case BTN_MIDDLE:
|
case BTN_MIDDLE:
|
||||||
return 2; // SPICE_MOUSE_BUTTON_MIDDLE
|
return 2;
|
||||||
case BTN_RIGHT:
|
case BTN_RIGHT:
|
||||||
return 3; // SPICE_MOUSE_BUTTON_RIGHT
|
return 3;
|
||||||
case BTN_SIDE:
|
case BTN_SIDE:
|
||||||
return 6; // SPICE_MOUSE_BUTTON_SIDE
|
return 6;
|
||||||
case BTN_EXTRA:
|
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,
|
static void pointerButtonHandler(void *data, struct wl_pointer *pointer,
|
||||||
uint32_t serial, uint32_t time, uint32_t button, uint32_t stateW)
|
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)
|
if (stateW == WL_POINTER_BUTTON_STATE_PRESSED)
|
||||||
app_handleButtonPress(button);
|
app_handleButtonPress(button);
|
||||||
|
|||||||
@@ -1196,6 +1196,18 @@ static void x11UpdateKeyboardGroup(void)
|
|||||||
atomic_store(&x11.keyboardGroup, state.group);
|
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)
|
static void setFocus(bool focused, double x, double y)
|
||||||
{
|
{
|
||||||
if (x11.focused == focused)
|
if (x11.focused == focused)
|
||||||
@@ -1226,7 +1238,7 @@ static bool x11GetKeyLabel(int sc, char * label, size_t size)
|
|||||||
|
|
||||||
static void x11XInputEvent(XGenericEventCookie *cookie)
|
static void x11XInputEvent(XGenericEventCookie *cookie)
|
||||||
{
|
{
|
||||||
static int button_state = 0;
|
static uint32_t button_state = 0;
|
||||||
|
|
||||||
switch(cookie->evtype)
|
switch(cookie->evtype)
|
||||||
{
|
{
|
||||||
@@ -1455,13 +1467,13 @@ static void x11XInputEvent(XGenericEventCookie *cookie)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
XIDeviceEvent *device = cookie->data;
|
XIDeviceEvent *device = cookie->data;
|
||||||
if (device->detail == 4)
|
const int button = x11MapButton(device->detail);
|
||||||
|
if (button == 4)
|
||||||
app_handleWheelMotion(-0.5);
|
app_handleWheelMotion(-0.5);
|
||||||
else if (device->detail == 5)
|
else if (button == 5)
|
||||||
app_handleWheelMotion(0.5);
|
app_handleWheelMotion(0.5);
|
||||||
else
|
else if (button)
|
||||||
app_handleButtonPress(
|
app_handleButtonPress(button);
|
||||||
device->detail > 5 ? device->detail - 2 : device->detail);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1472,7 +1484,9 @@ static void x11XInputEvent(XGenericEventCookie *cookie)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
XIDeviceEvent *device = cookie->data;
|
XIDeviceEvent *device = cookie->data;
|
||||||
app_handleButtonRelease(device->detail);
|
const int button = x11MapButton(device->detail);
|
||||||
|
if (button && button != 4 && button != 5)
|
||||||
|
app_handleButtonRelease(button);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1482,6 +1496,9 @@ static void x11XInputEvent(XGenericEventCookie *cookie)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
XIRawEvent *raw = cookie->data;
|
XIRawEvent *raw = cookie->data;
|
||||||
|
const int button = x11MapButton(raw->detail);
|
||||||
|
if (!button)
|
||||||
|
return;
|
||||||
|
|
||||||
/* filter out duplicate events */
|
/* filter out duplicate events */
|
||||||
static Time prev_time = 0;
|
static Time prev_time = 0;
|
||||||
@@ -1491,10 +1508,9 @@ static void x11XInputEvent(XGenericEventCookie *cookie)
|
|||||||
|
|
||||||
prev_time = raw->time;
|
prev_time = raw->time;
|
||||||
prev_detail = raw->detail;
|
prev_detail = raw->detail;
|
||||||
button_state |= (1 << raw->detail);
|
button_state |= UINT32_C(1) << button;
|
||||||
|
|
||||||
app_handleButtonPress(
|
app_handleButtonPress(button);
|
||||||
raw->detail > 5 ? raw->detail - 2 : raw->detail);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1504,6 +1520,9 @@ static void x11XInputEvent(XGenericEventCookie *cookie)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
XIRawEvent *raw = cookie->data;
|
XIRawEvent *raw = cookie->data;
|
||||||
|
const int button = x11MapButton(raw->detail);
|
||||||
|
if (!button)
|
||||||
|
return;
|
||||||
|
|
||||||
/* filter out duplicate events */
|
/* filter out duplicate events */
|
||||||
static Time prev_time = 0;
|
static Time prev_time = 0;
|
||||||
@@ -1513,10 +1532,9 @@ static void x11XInputEvent(XGenericEventCookie *cookie)
|
|||||||
|
|
||||||
prev_time = raw->time;
|
prev_time = raw->time;
|
||||||
prev_detail = raw->detail;
|
prev_detail = raw->detail;
|
||||||
button_state &= ~(1 << raw->detail);
|
button_state &= ~(UINT32_C(1) << button);
|
||||||
|
|
||||||
app_handleButtonRelease(
|
app_handleButtonRelease(button);
|
||||||
raw->detail > 5 ? raw->detail - 2 : raw->detail);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ typedef struct LG_InputOps
|
|||||||
/* Position is in guest pixels and must be within the supplied dimensions. */
|
/* Position is in guest pixels and must be within the supplied dimensions. */
|
||||||
bool (*mousePosition)(void * opaque, uint32_t x, uint32_t y,
|
bool (*mousePosition)(void * opaque, uint32_t x, uint32_t y,
|
||||||
uint32_t width, uint32_t height);
|
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 (*mousePress)(void * opaque, unsigned int button);
|
||||||
bool (*mouseRelease)(void * opaque, unsigned int button);
|
bool (*mouseRelease)(void * opaque, unsigned int button);
|
||||||
|
|
||||||
|
|||||||
@@ -211,8 +211,9 @@ static int evdev_thread(void * opaque)
|
|||||||
{
|
{
|
||||||
case EV_KEY:
|
case EV_KEY:
|
||||||
{
|
{
|
||||||
bool isMouseBtn = ev->code >= BTN_MOUSE && ev->code <= BTN_BACK;
|
bool isMouseBtn =
|
||||||
static const int mouseBtnMap[] = {1, 3, 2, 6, 7, 0, 0};
|
ev->code >= BTN_MOUSE && ev->code <= BTN_TASK;
|
||||||
|
static const int mouseBtnMap[] = {1, 3, 2, 6, 7, 8, 9, 10};
|
||||||
|
|
||||||
if (ev->value == 1)
|
if (ev->value == 1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -59,11 +59,17 @@ static bool spiceMouseMotion(void * opaque, int32_t x, int32_t y)
|
|||||||
|
|
||||||
static bool spiceMousePress(void * opaque, unsigned int button)
|
static bool spiceMousePress(void * opaque, unsigned int button)
|
||||||
{
|
{
|
||||||
|
if (button > 7)
|
||||||
|
return true;
|
||||||
|
|
||||||
return purespice_mousePress(button);
|
return purespice_mousePress(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool spiceMouseRelease(void * opaque, unsigned int button)
|
static bool spiceMouseRelease(void * opaque, unsigned int button)
|
||||||
{
|
{
|
||||||
|
if (button > 7)
|
||||||
|
return true;
|
||||||
|
|
||||||
return purespice_mouseRelease(button);
|
return purespice_mouseRelease(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user