[PATCH libinput 13/24] tablet: Emit LIBINPUT_EVENT_POINTER_TOOL_UPDATE events on tool changes
Carlos Garnacho
carlosg at gnome.org
Mon Apr 21 10:11:22 PDT 2014
Tracking is done of serial/tool type, so it is only really notified on
tool changes.
Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
---
src/evdev-tablet.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++---
src/evdev-tablet.h | 10 +++++
2 files changed, 113 insertions(+), 6 deletions(-)
diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
index 02877d9..fcd3396 100644
--- a/src/evdev-tablet.c
+++ b/src/evdev-tablet.c
@@ -52,6 +52,85 @@ tablet_process_absolute(struct tablet_dispatch *tablet,
}
static void
+tablet_update_tool(struct tablet_dispatch *tablet,
+ uint32_t tool,
+ uint32_t enabled)
+{
+ assert(tool != LIBINPUT_TOOL_NONE);
+
+ if (enabled && tool != tablet->state.tool) {
+ tablet->state.tool = tool;
+ tablet_set_status(tablet, TABLET_INTERACTED);
+ } else if (!enabled && tool == tablet->state.tool) {
+ tablet->state.tool = LIBINPUT_TOOL_NONE;
+ tablet_unset_status(tablet, TABLET_INTERACTED);
+ }
+}
+
+static void
+tablet_process_key(struct tablet_dispatch *tablet,
+ struct evdev_device *device,
+ struct input_event *e,
+ uint32_t time)
+{
+ switch (e->code) {
+ case BTN_TOOL_PEN:
+ case BTN_TOOL_RUBBER:
+ case BTN_TOOL_BRUSH:
+ case BTN_TOOL_PENCIL:
+ case BTN_TOOL_AIRBRUSH:
+ case BTN_TOOL_FINGER:
+ case BTN_TOOL_MOUSE:
+ case BTN_TOOL_LENS:
+ /* These codes have an equivalent libinput_tool value */
+ tablet_update_tool(tablet, e->code, e->value);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+tablet_process_misc(struct tablet_dispatch *tablet,
+ struct evdev_device *device,
+ struct input_event *e,
+ uint32_t time)
+{
+ switch (e->code) {
+ case MSC_SERIAL:
+ tablet->state.tool_serial = e->value;
+ break;
+ default:
+ log_info("Unhandled MSC event code 0x%x\n", e->code);
+ break;
+ }
+}
+
+static void
+tablet_check_notify_tool(struct tablet_dispatch *tablet,
+ struct evdev_device *device,
+ uint32_t time,
+ int post_check)
+{
+ struct libinput_device *base = &device->base;
+
+ if (tablet->state.tool == tablet->prev_state.tool)
+ return;
+
+ if (tablet->state.tool == LIBINPUT_TOOL_NONE) {
+ /* Wait for post-check */
+ if (post_check)
+ return;
+ } else if (post_check) {
+ /* Already handled in pre-check */
+ return;
+ }
+
+ pointer_notify_tool_update(
+ base, time, tablet->state.tool, tablet->state.tool_serial);
+}
+
+static void
tablet_flush(struct tablet_dispatch *tablet,
struct evdev_device *device,
uint32_t time)
@@ -59,14 +138,25 @@ tablet_flush(struct tablet_dispatch *tablet,
struct libinput_device *base = &device->base;
li_fixed_t x, y;
- if (tablet_has_status(tablet, TABLET_UPDATED)) {
- /* FIXME: apply hysteresis, calibration */
- x = li_fixed_from_int(device->abs.x);
- y = li_fixed_from_int(device->abs.y);
+ /* pre-update notifications */
+ tablet_check_notify_tool(tablet, device, time, 0);
+
+ if (tablet->state.tool != LIBINPUT_TOOL_NONE) {
+ if (tablet_has_status(tablet, TABLET_UPDATED)) {
+ /* FIXME: apply hysteresis, calibration */
+ x = li_fixed_from_int(device->abs.x);
+ y = li_fixed_from_int(device->abs.y);
- pointer_notify_motion_absolute(base, time, x, y);
- tablet_unset_status(tablet, TABLET_UPDATED);
+ pointer_notify_motion_absolute(base, time, x, y);
+ tablet_unset_status(tablet, TABLET_UPDATED);
+ }
}
+
+ /* post-update notifications */
+ tablet_check_notify_tool(tablet, device, time, 1);
+
+ /* replace previous state */
+ tablet->prev_state = tablet->state;
}
static void
@@ -82,6 +172,12 @@ tablet_process(struct evdev_dispatch *dispatch,
case EV_ABS:
tablet_process_absolute(tablet, device, e, time);
break;
+ case EV_KEY:
+ tablet_process_key(tablet, device, e, time);
+ break;
+ case EV_MSC:
+ tablet_process_misc(tablet, device, e, time);
+ break;
case EV_SYN:
tablet_flush(tablet, device, time);
break;
@@ -112,6 +208,7 @@ tablet_init(struct tablet_dispatch *tablet,
tablet->base.interface = &tablet_interface;
tablet->device = device;
tablet->status = TABLET_NONE;
+ tablet->state.tool = LIBINPUT_TOOL_NONE;
return 0;
}
diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h
index e1479fa..7b7b066 100644
--- a/src/evdev-tablet.h
+++ b/src/evdev-tablet.h
@@ -29,11 +29,21 @@
enum tablet_status {
TABLET_NONE = 0,
TABLET_UPDATED = 1 << 0,
+ TABLET_INTERACTED = 1 << 1,
+};
+
+struct device_state {
+ enum libinput_tool tool;
+ int32_t tool_serial;
};
struct tablet_dispatch {
struct evdev_dispatch base;
struct evdev_device *device;
+
+ struct device_state state;
+ struct device_state prev_state;
+
enum tablet_status status;
};
--
1.9.0
More information about the wayland-devel
mailing list