From: Jason Gerecke <[email protected]> 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.
FIXME: Note the fixme in tablet_tool_proximity_in... Signed-off-by: Jason Gerecke <[email protected]> Signed-off-by: Carlos Garnacho <[email protected]> --- hw/xwayland/xwayland-input.c | 314 +++++++++++++++++++++++++++++++++++++++++++ hw/xwayland/xwayland.h | 9 ++ 2 files changed, 323 insertions(+) diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index cdebfe0..041ac4b 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -1316,6 +1316,309 @@ static const struct zwp_tablet_v2_listener tablet_listener = { tablet_handle_removed }; +static void +tablet_tool_handle_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->xwl_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_handle_hardware_serial(void *data, struct zwp_tablet_tool_v2 *tool, + uint32_t hi, uint32_t low) +{ +} + +static void +tablet_tool_handle_hardware_id_wacom(void *data, struct zwp_tablet_tool_v2 *tool, + uint32_t hi, uint32_t low) +{ +} + +static void +tablet_tool_handle_capability(void *data, struct zwp_tablet_tool_v2 *tool, + uint32_t capability) +{ +} + +static void +tablet_tool_handle_done(void *data, struct zwp_tablet_tool_v2 *tool) +{ +} + +static void +tablet_tool_handle_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(xwl_tablet_tool->tool); + free(xwl_tablet_tool); +} + +static void +tablet_tool_handle_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->xwl_seat; + + //FIXME: Do we need the same NULL check used by the pointer? + xwl_seat->focus_window = wl_surface_get_user_data(wl_surface); +} + +static void +tablet_tool_handle_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->xwl_seat; + + xwl_seat->focus_window = NULL; +} + +static void +tablet_tool_handle_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->xwl_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_handle_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); + + 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_handle_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->xwl_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_handle_pressure(void *data, struct zwp_tablet_tool_v2 *tool, + uint32_t pressure_raw) +{ + struct xwl_tablet_tool *xwl_tablet_tool = data; + struct xwl_seat *xwl_seat = xwl_tablet_tool->xwl_seat; + float pressure = pressure_raw / 65535.0; + + if (!xwl_seat->focus_window) + return; + + xwl_tablet_tool->pressure = (pressure * 2047.0); +} + +static void +tablet_tool_handle_distance(void *data, struct zwp_tablet_tool_v2 *tool, + uint32_t distance_raw) +{ +} + +static void +tablet_tool_handle_tilt(void *data, struct zwp_tablet_tool_v2 *tool, + int32_t tilt_x, int32_t tilt_y) +{ + struct xwl_tablet_tool *xwl_tablet_tool = data; + struct xwl_seat *xwl_seat = xwl_tablet_tool->xwl_seat; + + if (!xwl_seat->focus_window) + return; + + xwl_tablet_tool->tilt_x = tilt_x / 100.0f; + xwl_tablet_tool->tilt_y = tilt_y / 100.0f; +} + +static void +tablet_tool_handle_rotation(void *data, struct zwp_tablet_tool_v2 *tool, + int32_t angle) +{ + struct xwl_tablet_tool *xwl_tablet_tool = data; + struct xwl_seat *xwl_seat = xwl_tablet_tool->xwl_seat; + float rotation = angle / 100.0f; + + 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_handle_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->xwl_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_handle_wheel(void *data, struct zwp_tablet_tool_v2 *tool, + int32_t degrees, int32_t clicks) +{ +} + +static void +tablet_tool_handle_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->xwl_seat; + int xbtn = 0; + ValuatorMask mask; + + if (button >= BTN_0 && button <= BTN_9) + { + xbtn = button - BTN_0 + 1; + } + else if (button >= BTN_A && button <= BTN_Z) + { + xbtn = button - BTN_A + 10; + } + else if (button >= BTN_BASE && button <= BTN_BASE6) + { + xbtn = button - BTN_BASE + 16; + } + else + { + switch (button) + { + case BTN_LEFT: + case BTN_TOUCH: + xbtn = 1; + break; + + case BTN_MIDDLE: + case BTN_STYLUS: + xbtn = 2; + break; + + case BTN_RIGHT: + case BTN_STYLUS2: + xbtn = 3; + break; + + case BTN_SIDE: + case BTN_BACK: + xbtn = 8; + break; + + case BTN_EXTRA: + case 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_handle_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_handle_type, + tablet_tool_handle_hardware_serial, + tablet_tool_handle_hardware_id_wacom, + tablet_tool_handle_capability, + tablet_tool_handle_done, + tablet_tool_handle_removed, + tablet_tool_handle_proximity_in, + tablet_tool_handle_proximity_out, + tablet_tool_handle_down, + tablet_tool_handle_up, + tablet_tool_handle_motion, + tablet_tool_handle_pressure, + tablet_tool_handle_distance, + tablet_tool_handle_tilt, + tablet_tool_handle_rotation, + tablet_tool_handle_slider, + tablet_tool_handle_wheel, + tablet_tool_handle_button_state, + tablet_tool_handle_frame +}; static void tablet_seat_handle_add_tablet(void *data, @@ -1354,11 +1657,22 @@ tablet_seat_handle_add_tool(void *data, struct zwp_tablet_seat_v2 *tablet_seat, xwl_tablet_tool->xwl_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 +tablet_seat_handle_add_pad(void *data, struct zwp_tablet_seat_v2 *tablet_seat, + struct zwp_tablet_pad_v2 *pad) +{ + /* FIXME: handle pads, probably unused by clients themselves anyway */ + zwp_tablet_pad_v2_destroy (pad); } static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = { tablet_seat_handle_add_tablet, tablet_seat_handle_add_tool, + tablet_seat_handle_add_pad, }; static void diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index 7ee57c1..d3d8f1d 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 *xwl_seat; + + DeviceIntPtr xdevice; + uint32_t x; + uint32_t y; + float pressure; + float tilt_x; + float tilt_y; + float rotation; + float slider; }; struct xwl_output { -- 2.9.3 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
