[PATCH libinput 15/24] tablet: Add infrastructure to store and notify axis states.

Carlos Garnacho carlosg at gnome.org
Mon Apr 21 10:11:24 PDT 2014


An axis_frame event is sent too to notify a set of simultaneous axis
changes. Only the infrastructure is added, No axes are managed at the
moment.

Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
---
 src/evdev-tablet.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/evdev-tablet.h |  10 +++++
 2 files changed, 117 insertions(+)

diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
index 0682563..70f3210 100644
--- a/src/evdev-tablet.c
+++ b/src/evdev-tablet.c
@@ -35,6 +35,63 @@
 #define tablet_get_disabled_buttons(tablet,field) \
 	(tablet->prev_state.field & ~(tablet->state.field))
 
+static struct axis_info *
+tablet_get_axis(struct tablet_dispatch *tablet,
+		int32_t evcode)
+{
+	int pos;
+
+	for (pos = 0; pos < tablet->n_axes; pos++) {
+		if (tablet->axes[pos].code == evcode)
+			return &tablet->axes[pos];
+	}
+
+	return NULL;
+}
+
+static int
+tablet_add_axis(struct tablet_dispatch *tablet,
+		struct evdev_device *device,
+		uint32_t evcode,
+		uint32_t axis)
+{
+	const struct input_absinfo *absinfo;
+	int current;
+
+	if (tablet->n_axes == MAX_AXES)
+		return 0;
+
+	if (!(absinfo = libevdev_get_abs_info(device->evdev, evcode)))
+		return 0;
+
+	current = tablet->n_axes++;
+	tablet->axes[current].code = evcode;
+	tablet->axes[current].axis = axis;
+	tablet->axes[current].abs = *absinfo;
+	tablet->axes[current].updated = 0;
+
+	return 1;
+}
+
+static void
+tablet_update_axis(struct tablet_dispatch *tablet,
+		   int32_t code,
+		   int32_t value)
+{
+	struct axis_info *axis_info;
+
+	if (!(axis_info = tablet_get_axis(tablet, code)))
+		return;
+
+	value = max(axis_info->abs.minimum, min(value, axis_info->abs.maximum));
+
+	if (value == axis_info->abs.value)
+		return;
+
+	axis_info->abs.value = value;
+	axis_info->updated = 1;
+}
+
 static void
 tablet_process_absolute(struct tablet_dispatch *tablet,
 			struct evdev_device *device,
@@ -50,6 +107,17 @@ tablet_process_absolute(struct tablet_dispatch *tablet,
 		device->abs.y = e->value;
 		tablet_set_status(tablet, TABLET_UPDATED);
 		break;
+	case ABS_PRESSURE:
+	case ABS_DISTANCE:
+	case ABS_TILT_X:
+	case ABS_TILT_Y:
+	case ABS_RX:
+	case ABS_RY:
+	case ABS_RZ:
+	case ABS_WHEEL:
+	case ABS_THROTTLE:
+		tablet_update_axis(tablet, e->code, e->value);
+		break;
 	default:
 		log_info("Unhandled ABS event code 0x%x\n", e->code);
 		break;
@@ -171,6 +239,43 @@ tablet_check_notify_tool(struct tablet_dispatch *tablet,
 		base, time, tablet->state.tool, tablet->state.tool_serial);
 }
 
+static double
+normalize_axis(const struct axis_info *axis_info)
+{
+	double range = axis_info->abs.maximum - axis_info->abs.minimum;
+	double value = (axis_info->abs.value + axis_info->abs.minimum) / range;
+
+	return value;
+}
+
+static void
+tablet_notify_axes(struct tablet_dispatch *tablet,
+		   struct evdev_device *device,
+		   uint32_t time)
+{
+	struct libinput_device *base = &device->base;
+	int i, need_frame = 0;
+
+	for (i = 0; i < tablet->n_axes; i++) {
+		struct axis_info *axis = &tablet->axes[i];
+		double value;
+
+		if (!axis->updated)
+			continue;
+
+		need_frame = 1;
+		axis->updated = 0;
+		value = normalize_axis(axis);
+		pointer_notify_axis(base,
+				    time,
+				    axis->axis,
+				    li_fixed_from_double(value));
+	}
+
+	if (need_frame)
+		pointer_notify_axis_frame(base, time);
+}
+
 static void
 tablet_notify_button_mask(struct tablet_dispatch *tablet,
 			  struct evdev_device *device,
@@ -253,6 +358,8 @@ tablet_flush(struct tablet_dispatch *tablet,
 			pointer_notify_motion_absolute(base, time, x, y);
 			tablet_unset_status(tablet, TABLET_UPDATED);
 		}
+
+		tablet_notify_axes(tablet, device, time);
 	}
 
 	/* post-update notifications */
diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h
index d81c878..808dab1 100644
--- a/src/evdev-tablet.h
+++ b/src/evdev-tablet.h
@@ -26,6 +26,9 @@
 
 #include "evdev.h"
 
+/* Completely unscientific, but there should be plenty of room most commonly */
+#define MAX_AXES 20
+
 enum tablet_status {
 	TABLET_NONE = 0,
 	TABLET_UPDATED = 1 << 0,
@@ -33,6 +36,11 @@ enum tablet_status {
 	TABLET_HAS_CONTACT = 1 << 2,
 };
 
+struct axis_info {
+	int32_t code, axis, updated;
+	struct input_absinfo abs;
+};
+
 struct device_state {
 	uint32_t pad_buttons; /* bitmask of evcode - BTN_MISC */
 	uint32_t stylus_buttons; /* bitmask of evcode - BTN_TOUCH */
@@ -47,7 +55,9 @@ struct tablet_dispatch {
 	struct device_state state;
 	struct device_state prev_state;
 
+	struct axis_info axes[MAX_AXES];
 	enum tablet_status status;
+	int n_axes;
 };
 
 #endif
-- 
1.9.0



More information about the wayland-devel mailing list