You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
374 lines
11 KiB
374 lines
11 KiB
From 4354336014ca0c29270a6cdf83e9f9e5fe16080e Mon Sep 17 00:00:00 2001 |
|
From: Jason Gerecke <killertofu@gmail.com> |
|
Date: Fri, 14 Oct 2016 14:31:46 -0700 |
|
Subject: [PATCH xserver 05/12] xwayland: Handle tablet_tool events |
|
|
|
Translates Wayland tablet events into corresponding X11 tablet events. As |
|
with the prior commit, these events are modeled after those created by the |
|
xf86-input-wacom driver to maximize compatibility with existing applications. |
|
|
|
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com> |
|
Signed-off-by: Carlos Garnacho <carlosg@gnome.org> |
|
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> |
|
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> |
|
Acked-by: Ping Cheng <ping.cheng@wacom.com> |
|
(cherry picked from commit 8a1defcc634daddbb3570519d69ec5c9e39a8b56) |
|
--- |
|
hw/xwayland/xwayland-input.c | 313 +++++++++++++++++++++++++++++++++++++++++++ |
|
hw/xwayland/xwayland.h | 9 ++ |
|
2 files changed, 322 insertions(+) |
|
|
|
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c |
|
index 64655de5f..142862f7e 100644 |
|
--- a/hw/xwayland/xwayland-input.c |
|
+++ b/hw/xwayland/xwayland-input.c |
|
@@ -1331,6 +1331,317 @@ static const struct zwp_tablet_v2_listener tablet_listener = { |
|
}; |
|
|
|
static void |
|
+tablet_tool_receive_type(void *data, struct zwp_tablet_tool_v2 *tool, |
|
+ uint32_t type) |
|
+{ |
|
+ struct xwl_tablet_tool *xwl_tablet_tool = data; |
|
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; |
|
+ |
|
+ switch (type) { |
|
+ case ZWP_TABLET_TOOL_V2_TYPE_ERASER: |
|
+ xwl_tablet_tool->xdevice = xwl_seat->eraser; |
|
+ break; |
|
+ case ZWP_TABLET_TOOL_V2_TYPE_MOUSE: |
|
+ case ZWP_TABLET_TOOL_V2_TYPE_LENS: |
|
+ xwl_tablet_tool->xdevice = xwl_seat->puck; |
|
+ break; |
|
+ default: |
|
+ xwl_tablet_tool->xdevice = xwl_seat->stylus; |
|
+ break; |
|
+ } |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_receive_hardware_serial(void *data, struct zwp_tablet_tool_v2 *tool, |
|
+ uint32_t hi, uint32_t low) |
|
+{ |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_receive_hardware_id_wacom(void *data, struct zwp_tablet_tool_v2 *tool, |
|
+ uint32_t hi, uint32_t low) |
|
+{ |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_receive_capability(void *data, struct zwp_tablet_tool_v2 *tool, |
|
+ uint32_t capability) |
|
+{ |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_receive_done(void *data, struct zwp_tablet_tool_v2 *tool) |
|
+{ |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_receive_removed(void *data, struct zwp_tablet_tool_v2 *tool) |
|
+{ |
|
+ struct xwl_tablet_tool *xwl_tablet_tool = data; |
|
+ |
|
+ xorg_list_del(&xwl_tablet_tool->link); |
|
+ zwp_tablet_tool_v2_destroy(tool); |
|
+ free(xwl_tablet_tool); |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_proximity_in(void *data, struct zwp_tablet_tool_v2 *tool, |
|
+ uint32_t serial, struct zwp_tablet_v2 *tablet, |
|
+ struct wl_surface *wl_surface) |
|
+{ |
|
+ struct xwl_tablet_tool *xwl_tablet_tool = data; |
|
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; |
|
+ |
|
+ /* There's a race here where if we create and then immediately |
|
+ * destroy a surface, we might end up in a state where the Wayland |
|
+ * compositor sends us an event for a surface that doesn't exist. |
|
+ * |
|
+ * Don't process enter events in this case. |
|
+ * |
|
+ * see pointer_handle_enter() |
|
+ */ |
|
+ if (wl_surface == NULL) |
|
+ return; |
|
+ |
|
+ xwl_seat->focus_window = wl_surface_get_user_data(wl_surface); |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_proximity_out(void *data, struct zwp_tablet_tool_v2 *tool) |
|
+{ |
|
+ struct xwl_tablet_tool *xwl_tablet_tool = data; |
|
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; |
|
+ |
|
+ xwl_seat->focus_window = NULL; |
|
+ |
|
+ xwl_tablet_tool->pressure = 0; |
|
+ xwl_tablet_tool->tilt_x = 0; |
|
+ xwl_tablet_tool->tilt_y = 0; |
|
+ xwl_tablet_tool->rotation = 0; |
|
+ xwl_tablet_tool->slider = 0; |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_down(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t serial) |
|
+{ |
|
+ struct xwl_tablet_tool *xwl_tablet_tool = data; |
|
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; |
|
+ ValuatorMask mask; |
|
+ |
|
+ xwl_seat->xwl_screen->serial = serial; |
|
+ |
|
+ valuator_mask_zero(&mask); |
|
+ QueuePointerEvents(xwl_tablet_tool->xdevice, ButtonPress, 1, 0, &mask); |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_up(void *data, struct zwp_tablet_tool_v2 *tool) |
|
+{ |
|
+ struct xwl_tablet_tool *xwl_tablet_tool = data; |
|
+ ValuatorMask mask; |
|
+ |
|
+ valuator_mask_zero(&mask); |
|
+ QueuePointerEvents(xwl_tablet_tool->xdevice, ButtonRelease, 1, 0, &mask); |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_motion(void *data, struct zwp_tablet_tool_v2 *tool, |
|
+ wl_fixed_t x, wl_fixed_t y) |
|
+{ |
|
+ struct xwl_tablet_tool *xwl_tablet_tool = data; |
|
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; |
|
+ int32_t dx, dy; |
|
+ int sx = wl_fixed_to_int(x); |
|
+ int sy = wl_fixed_to_int(y); |
|
+ |
|
+ if (!xwl_seat->focus_window) |
|
+ return; |
|
+ |
|
+ dx = xwl_seat->focus_window->window->drawable.x; |
|
+ dy = xwl_seat->focus_window->window->drawable.y; |
|
+ |
|
+ xwl_tablet_tool->x = dx + sx; |
|
+ xwl_tablet_tool->y = dy + sy; |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_pressure(void *data, struct zwp_tablet_tool_v2 *tool, |
|
+ uint32_t pressure) |
|
+{ |
|
+ struct xwl_tablet_tool *xwl_tablet_tool = data; |
|
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; |
|
+ |
|
+ if (!xwl_seat->focus_window) |
|
+ return; |
|
+ |
|
+ /* normalized to 65535 already */ |
|
+ xwl_tablet_tool->pressure = pressure; |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_distance(void *data, struct zwp_tablet_tool_v2 *tool, |
|
+ uint32_t distance_raw) |
|
+{ |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_tilt(void *data, struct zwp_tablet_tool_v2 *tool, |
|
+ wl_fixed_t tilt_x, wl_fixed_t tilt_y) |
|
+{ |
|
+ struct xwl_tablet_tool *xwl_tablet_tool = data; |
|
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; |
|
+ |
|
+ if (!xwl_seat->focus_window) |
|
+ return; |
|
+ |
|
+ xwl_tablet_tool->tilt_x = wl_fixed_to_double(tilt_x); |
|
+ xwl_tablet_tool->tilt_y = wl_fixed_to_double(tilt_y); |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_rotation(void *data, struct zwp_tablet_tool_v2 *tool, |
|
+ wl_fixed_t angle) |
|
+{ |
|
+ struct xwl_tablet_tool *xwl_tablet_tool = data; |
|
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; |
|
+ double rotation = wl_fixed_to_double(angle); |
|
+ |
|
+ if (!xwl_seat->focus_window) |
|
+ return; |
|
+ |
|
+ /* change origin (buttons facing right [libinput +90 degrees]) and |
|
+ * scaling (5 points per degree) to match wacom driver behavior |
|
+ */ |
|
+ rotation = remainderf(rotation + 90.0f, 360.0f); |
|
+ rotation *= 5.0f; |
|
+ xwl_tablet_tool->rotation = rotation; |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_slider(void *data, struct zwp_tablet_tool_v2 *tool, |
|
+ int32_t position_raw) |
|
+{ |
|
+ struct xwl_tablet_tool *xwl_tablet_tool = data; |
|
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; |
|
+ float position = position_raw / 65535.0; |
|
+ |
|
+ if (!xwl_seat->focus_window) |
|
+ return; |
|
+ |
|
+ xwl_tablet_tool->slider = (position * 1799.0f) - 900.0f; |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_wheel(void *data, struct zwp_tablet_tool_v2 *tool, |
|
+ wl_fixed_t degrees, int32_t clicks) |
|
+{ |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_button_state(void *data, struct zwp_tablet_tool_v2 *tool, |
|
+ uint32_t serial, uint32_t button, uint32_t state) |
|
+{ |
|
+ struct xwl_tablet_tool *xwl_tablet_tool = data; |
|
+ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; |
|
+ int xbtn = 0; |
|
+ ValuatorMask mask; |
|
+ |
|
+ /* BTN_0 .. BTN_9 */ |
|
+ if (button >= 0x100 && button <= 0x109) { |
|
+ xbtn = button - 0x100 + 1; |
|
+ } |
|
+ /* BTN_A .. BTN_Z */ |
|
+ else if (button >= 0x130 && button <= 0x135) { |
|
+ xbtn = button - 0x130 + 10; |
|
+ } |
|
+ /* BTN_BASE .. BTN_BASE6 */ |
|
+ else if (button >= 0x126 && button <= 0x12b) { |
|
+ xbtn = button - 0x126 + 16; |
|
+ } |
|
+ else { |
|
+ switch (button) { |
|
+ case 0x110: /* BTN_LEFT */ |
|
+ case 0x14a: /* BTN_TOUCH */ |
|
+ xbtn = 1; |
|
+ break; |
|
+ |
|
+ case 0x112: /* BTN_MIDDLE */ |
|
+ case 0x14b: /* BTN_STYLUS */ |
|
+ xbtn = 2; |
|
+ break; |
|
+ |
|
+ case 0x111: /* BTN_RIGHT */ |
|
+ case 0x14c: /* BTN_STYLUS2 */ |
|
+ xbtn = 3; |
|
+ break; |
|
+ |
|
+ case 0x113: /* BTN_SIDE */ |
|
+ case 0x116: /* BTN_BACK */ |
|
+ xbtn = 8; |
|
+ break; |
|
+ |
|
+ case 0x114: /* BTN_EXTRA */ |
|
+ case 0x115: /* BTN_FORWARD */ |
|
+ xbtn = 9; |
|
+ break; |
|
+ } |
|
+ } |
|
+ |
|
+ if (!xbtn) { |
|
+ ErrorF("unknown tablet button number %d\n", button); |
|
+ return; |
|
+ } |
|
+ |
|
+ xwl_seat->xwl_screen->serial = serial; |
|
+ |
|
+ valuator_mask_zero(&mask); |
|
+ QueuePointerEvents(xwl_tablet_tool->xdevice, |
|
+ state ? ButtonPress : ButtonRelease, xbtn, 0, &mask); |
|
+} |
|
+ |
|
+static void |
|
+tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time) |
|
+{ |
|
+ struct xwl_tablet_tool *xwl_tablet_tool = data; |
|
+ ValuatorMask mask; |
|
+ |
|
+ valuator_mask_zero(&mask); |
|
+ valuator_mask_set(&mask, 0, xwl_tablet_tool->x); |
|
+ valuator_mask_set(&mask, 1, xwl_tablet_tool->y); |
|
+ valuator_mask_set(&mask, 2, xwl_tablet_tool->pressure); |
|
+ valuator_mask_set(&mask, 3, xwl_tablet_tool->tilt_x); |
|
+ valuator_mask_set(&mask, 4, xwl_tablet_tool->tilt_y); |
|
+ valuator_mask_set(&mask, 5, xwl_tablet_tool->rotation + xwl_tablet_tool->slider); |
|
+ |
|
+ /* FIXME: Store button mask in xwl_tablet_tool and send events *HERE* if |
|
+ changed */ |
|
+ QueuePointerEvents(xwl_tablet_tool->xdevice, MotionNotify, 0, |
|
+ POINTER_ABSOLUTE | POINTER_SCREEN, &mask); |
|
+} |
|
+ |
|
+static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = { |
|
+ tablet_tool_receive_type, |
|
+ tablet_tool_receive_hardware_serial, |
|
+ tablet_tool_receive_hardware_id_wacom, |
|
+ tablet_tool_receive_capability, |
|
+ tablet_tool_receive_done, |
|
+ tablet_tool_receive_removed, |
|
+ tablet_tool_proximity_in, |
|
+ tablet_tool_proximity_out, |
|
+ tablet_tool_down, |
|
+ tablet_tool_up, |
|
+ tablet_tool_motion, |
|
+ tablet_tool_pressure, |
|
+ tablet_tool_distance, |
|
+ tablet_tool_tilt, |
|
+ tablet_tool_rotation, |
|
+ tablet_tool_slider, |
|
+ tablet_tool_wheel, |
|
+ tablet_tool_button_state, |
|
+ tablet_tool_frame |
|
+}; |
|
+ |
|
+static void |
|
tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat, |
|
struct zwp_tablet_v2 *tablet) |
|
{ |
|
@@ -1368,6 +1679,8 @@ tablet_seat_handle_add_tool(void *data, struct zwp_tablet_seat_v2 *tablet_seat, |
|
xwl_tablet_tool->seat = xwl_seat; |
|
|
|
xorg_list_add(&xwl_tablet_tool->link, &xwl_seat->tablet_tools); |
|
+ |
|
+ zwp_tablet_tool_v2_add_listener(tool, &tablet_tool_listener, xwl_tablet_tool); |
|
} |
|
|
|
static void |
|
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h |
|
index e7e62882b..fb9ac4804 100644 |
|
--- a/hw/xwayland/xwayland.h |
|
+++ b/hw/xwayland/xwayland.h |
|
@@ -193,6 +193,15 @@ struct xwl_tablet_tool { |
|
struct xorg_list link; |
|
struct zwp_tablet_tool_v2 *tool; |
|
struct xwl_seat *seat; |
|
+ |
|
+ DeviceIntPtr xdevice; |
|
+ uint32_t x; |
|
+ uint32_t y; |
|
+ uint32_t pressure; |
|
+ float tilt_x; |
|
+ float tilt_y; |
|
+ float rotation; |
|
+ float slider; |
|
}; |
|
|
|
struct xwl_tablet_pad { |
|
-- |
|
2.13.5 |
|
|
|
|