[PATCH libinput] tablet: up the reference count for the tool in the event

Peter Hutterer peter.hutterer at who-t.net
Wed May 25 22:45:38 UTC 2016


Make sure that the tool is valid while the event is valid, even if the device
gets destroyed before the event is destroyed.

This cannot actually be triggered right now, the event has a ref to the device
and the tools do not get removed until the device is destroyed. But for future
implementations (e.g. where the tool is otherwise automatically destroyed on
proximity out) we need to ensure the tool remains valid for the event
lifetime.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/libinput.c | 26 ++++++++++++++++++++++----
 test/tablet.c  |  4 ++--
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/src/libinput.c b/src/libinput.c
index 7a9199d..89fa594 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -1658,12 +1658,30 @@ libinput_unref(struct libinput *libinput)
 	return NULL;
 }
 
+static void
+libinput_event_tablet_tool_destroy(struct libinput_event_tablet_tool *event)
+{
+	libinput_tablet_tool_unref(event->tool);
+}
+
 LIBINPUT_EXPORT void
 libinput_event_destroy(struct libinput_event *event)
 {
 	if (event == NULL)
 		return;
 
+	switch(event->type) {
+	case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY:
+	case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
+	case LIBINPUT_EVENT_TABLET_TOOL_TIP:
+	case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
+		libinput_event_tablet_tool_destroy(
+		   libinput_event_get_tablet_tool_event(event));
+		break;
+	default:
+		break;
+	}
+
 	if (event->device)
 		libinput_device_unref(event->device);
 
@@ -2261,7 +2279,7 @@ tablet_notify_axis(struct libinput_device *device,
 
 	*axis_event = (struct libinput_event_tablet_tool) {
 		.time = time,
-		.tool = tool,
+		.tool = libinput_tablet_tool_ref(tool),
 		.proximity_state = LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN,
 		.tip_state = tip_state,
 		.axes = *axes,
@@ -2293,7 +2311,7 @@ tablet_notify_proximity(struct libinput_device *device,
 
 	*proximity_event = (struct libinput_event_tablet_tool) {
 		.time = time,
-		.tool = tool,
+		.tool = libinput_tablet_tool_ref(tool),
 		.tip_state = LIBINPUT_TABLET_TOOL_TIP_UP,
 		.proximity_state = proximity_state,
 		.axes = *axes,
@@ -2324,7 +2342,7 @@ tablet_notify_tip(struct libinput_device *device,
 
 	*tip_event = (struct libinput_event_tablet_tool) {
 		.time = time,
-		.tool = tool,
+		.tool = libinput_tablet_tool_ref(tool),
 		.tip_state = tip_state,
 		.proximity_state = LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN,
 		.axes = *axes,
@@ -2361,7 +2379,7 @@ tablet_notify_button(struct libinput_device *device,
 
 	*button_event = (struct libinput_event_tablet_tool) {
 		.time = time,
-		.tool = tool,
+		.tool = libinput_tablet_tool_ref(tool),
 		.button = button,
 		.state = state,
 		.seat_button_count = seat_button_count,
diff --git a/test/tablet.c b/test/tablet.c
index e30705b..04eb307 100644
--- a/test/tablet.c
+++ b/test/tablet.c
@@ -2012,9 +2012,9 @@ START_TEST(tool_ref)
 	ck_assert_notnull(tool);
 	ck_assert(tool == libinput_tablet_tool_ref(tool));
 	ck_assert(tool == libinput_tablet_tool_unref(tool));
+	libinput_event_destroy(event);
+
 	ck_assert(libinput_tablet_tool_unref(tool) == NULL);
-
-	libinput_event_destroy(event);
 }
 END_TEST
 
-- 
2.7.4



More information about the wayland-devel mailing list