summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2016-05-24 14:37:54 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2016-05-30 16:10:12 +1000
commitcf707baace3f87360ece667f25ba45acc87e9a18 (patch)
treead7c1a17eadeae488084a36f5793526716274e6b
parent83b0f3c4f3792bbba55f10901583b56f45ad81e0 (diff)
tablet: up the reference count for the tool in the event
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@who-t.net>
-rw-r--r--src/libinput.c26
-rw-r--r--test/tablet.c4
2 files changed, 24 insertions, 6 deletions
diff --git a/src/libinput.c b/src/libinput.c
index 7a9199dd..89fa5942 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 e30705bb..04eb3078 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));
- ck_assert(libinput_tablet_tool_unref(tool) == NULL);
-
libinput_event_destroy(event);
+
+ ck_assert(libinput_tablet_tool_unref(tool) == NULL);
}
END_TEST