[PATCH 7/7] evdev: track which touch point properties are available

Andreas Pokorny andreas.pokorny at canonical.com
Wed Jun 10 07:09:17 PDT 2015


This change adds flags to track which property of a touch point is set.
With that reasonable default values can be provided when an information
is not available.
---
 src/evdev.c    | 29 ++++++++++++++++++++---------
 src/evdev.h    | 10 ++++++++++
 src/libinput.c |  4 ++++
 test/touch.c   | 42 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 76 insertions(+), 9 deletions(-)

diff --git a/src/evdev.c b/src/evdev.c
index f75e1c3..5720c8c 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -315,10 +315,9 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
 		point = slot_data->point;
 		transform_absolute(device, &point);
 
-		touch_notify_touch_down(base, time, slot, seat_slot,
-					&point, slot_data->touch_major,
-					slot_data->touch_minor, slot_data->orientation,
-					slot_data->pressure);
+		touch_notify_touch_down(base, time, slot, seat_slot, &point,
+					slot_data->touch_major, slot_data->touch_minor,
+					slot_data->orientation, slot_data->pressure);
 		break;
 	case EVDEV_ABSOLUTE_MT_MOTION:
 		if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
@@ -333,10 +332,9 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
 			break;
 
 		transform_absolute(device, &point);
-		touch_notify_touch_motion(base, time, slot, seat_slot,
-					  &point, slot_data->touch_major,
-					  slot_data->touch_minor, slot_data->orientation,
-					  slot_data->pressure);
+		touch_notify_touch_motion(base, time, slot, seat_slot, &point,
+					  slot_data->touch_major, slot_data->touch_minor,
+					  slot_data->orientation, slot_data->pressure);
 		break;
 	case EVDEV_ABSOLUTE_MT_UP:
 		if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
@@ -572,8 +570,15 @@ evdev_process_touch(struct evdev_device *device,
 		if (device->pending_event != EVDEV_NONE &&
 		    device->pending_event != EVDEV_ABSOLUTE_MT_MOTION)
 			evdev_flush_pending_event(device, time);
-		if (e->value >= 0)
+		if (e->value >= 0) {
+			struct mt_slot *current_slot = &device->mt.slots[device->mt.slot];
 			device->pending_event = EVDEV_ABSOLUTE_MT_DOWN;
+			current_slot->available_data = TOUCH_SLOT_DATA_NONE;
+			current_slot->pressure = DEFAULT_TOUCH_PRESSURE;
+			current_slot->orientation = DEFAULT_TOUCH_ORIENTATION;
+			current_slot->touch_major = DEFAULT_TOUCH_MAJOR;
+			current_slot->touch_minor = DEFAULT_TOUCH_MINOR;
+		}
 		else
 			device->pending_event = EVDEV_ABSOLUTE_MT_UP;
 	} else {
@@ -589,18 +594,24 @@ evdev_process_touch(struct evdev_device *device,
 			wake_device_on_mt_motion(device);
 			break;
 		case ABS_MT_TOUCH_MAJOR:
+			current_slot->available_data |= TOUCH_SLOT_DATA_TOUCH_MAJOR;
 			current_slot->touch_major = e->value;
+			if (!(current_slot->available_data & TOUCH_SLOT_DATA_TOUCH_MINOR))
+				current_slot->touch_minor = e->value;
 			wake_device_on_mt_motion(device);
 			break;
 		case ABS_MT_TOUCH_MINOR:
+			current_slot->available_data |= TOUCH_SLOT_DATA_TOUCH_MINOR;
 			current_slot->touch_minor = e->value;
 			wake_device_on_mt_motion(device);
 			break;
 		case ABS_MT_ORIENTATION:
+			current_slot->available_data |= TOUCH_SLOT_DATA_ORIENTATION;
 			current_slot->orientation = e->value;
 			wake_device_on_mt_motion(device);
 			break;
 		case ABS_MT_PRESSURE:
+			current_slot->available_data |= TOUCH_SLOT_DATA_PRESSURE;
 			current_slot->pressure = e->value;
 			wake_device_on_mt_motion(device);
 			break;
diff --git a/src/evdev.h b/src/evdev.h
index c7d762b..68c4c5a 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -105,9 +105,19 @@ enum evdev_device_model {
 	EVDEV_MODEL_CLEVO_W740SU,
 };
 
+/* optional slot data */
+enum touch_slot_data {
+	TOUCH_SLOT_DATA_NONE = 0,
+	TOUCH_SLOT_DATA_TOUCH_MAJOR = (1 << 1),
+	TOUCH_SLOT_DATA_TOUCH_MINOR = (1 << 2),
+	TOUCH_SLOT_DATA_ORIENTATION = (1 << 3),
+	TOUCH_SLOT_DATA_PRESSURE = (1 << 4),
+};
+
 struct mt_slot {
 	int32_t seat_slot;
 	struct device_coords point;
+	enum touch_slot_data available_data;
 	int32_t touch_major;
 	int32_t touch_minor;
 	int32_t orientation;
diff --git a/src/libinput.c b/src/libinput.c
index 9357c01..afb1e8f 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -676,6 +676,8 @@ libinput_event_touch_get_orientation(struct libinput_event_touch *event)
 			   LIBINPUT_EVENT_TOUCH_DOWN,
 			   LIBINPUT_EVENT_TOUCH_MOTION);
 
+	if (!device->abs.absinfo_orientation)
+		return 0.0;
 	if (device->abs.absinfo_orientation->minimum < 0)
 		return evdev_scale_axis(device->abs.absinfo_orientation, event->orientation, 2.0) - 1.0;
 	else /* this branch assume a simplisitic orientation calculation which either only yields 0 or 1
@@ -695,6 +697,8 @@ libinput_event_touch_get_pressure(struct libinput_event_touch *event)
 			   LIBINPUT_EVENT_TOUCH_DOWN,
 			   LIBINPUT_EVENT_TOUCH_MOTION);
 
+	if (!device->abs.absinfo_pressure)
+		return 1.0;
 	return evdev_scale_axis(device->abs.absinfo_pressure, event->pressure, 1.0);
 }
 
diff --git a/test/touch.c b/test/touch.c
index 10c4e2d..06fee1a 100644
--- a/test/touch.c
+++ b/test/touch.c
@@ -700,6 +700,46 @@ START_TEST(touch_point_properties)
 }
 END_TEST
 
+START_TEST(touch_point_default_values)
+{
+	struct litest_device *dev = litest_current_device();
+	struct libinput *li = dev->libinput;
+	struct libinput_event *ev;
+	struct libinput_event_touch *tev;
+
+	litest_drain_events(li);
+
+	litest_push_event_frame(dev);
+	litest_touch_down(dev, 0, 5, 95);
+	litest_touch_major(dev, 0, 9);
+	litest_pop_event_frame(dev);
+
+	litest_wait_for_event_of_type(li, LIBINPUT_EVENT_TOUCH_DOWN, -1);
+
+	ev = libinput_get_event(li);
+	tev = libinput_event_get_touch_event(ev);
+
+	litest_assert_double_eq(libinput_event_touch_get_orientation(tev), 0.0);
+	ck_assert_int_eq(libinput_event_touch_get_touch_major(tev), 9);
+	ck_assert_int_eq(libinput_event_touch_get_touch_minor(tev), 9);
+
+	libinput_event_destroy(ev);
+
+	litest_push_event_frame(dev);
+	litest_touch_major(dev, 0, 12);
+	litest_pop_event_frame(dev);
+	litest_wait_for_event_of_type(li, LIBINPUT_EVENT_TOUCH_MOTION, -1);
+
+	ev = libinput_get_event(li);
+	tev = libinput_event_get_touch_event(ev);
+
+	ck_assert_int_eq(libinput_event_touch_get_touch_major(tev), 12);
+	ck_assert_int_eq(libinput_event_touch_get_touch_minor(tev), 12);
+
+	libinput_event_destroy(ev);
+}
+END_TEST
+
 void
 litest_setup_tests(void)
 {
@@ -726,6 +766,8 @@ litest_setup_tests(void)
 	litest_add("touch:protocol a", touch_protocol_a_2fg_touch, LITEST_PROTOCOL_A, LITEST_ANY);
 	litest_add("touch:touch point properties", touch_point_properties, LITEST_TOUCH | LITEST_ELLIPSE_SIZE |
                    LITEST_ELLIPSE_ORIENTATION | LITEST_PRESSURE, LITEST_ANY);
+	litest_add("touch:default values", touch_point_default_values, LITEST_TOUCH | LITEST_ELLIPSE_SIZE |
+                   LITEST_PRESSURE, LITEST_ELLIPSE_ORIENTATION );
 
 	litest_add_ranged("touch:state", touch_initial_state, LITEST_TOUCH, LITEST_PROTOCOL_A, &axes);
 }
-- 
2.1.4



More information about the wayland-devel mailing list