linux-qubasis
linux oasis port as a qubes template
git clone https://9o.is/git/linux-qubasis.git
0001-Revert-switch-to-VLAs-for-multitouch-state.patch
(8181B)
1 From 20dd0f459d92805cdd33a7622382f118acf3c07d Mon Sep 17 00:00:00 2001
2 From: Michael Forney <mforney@mforney.org>
3 Date: Tue, 3 Mar 2020 14:17:37 -0800
4 Subject: [PATCH libevdev] Revert switch to VLAs for multitouch state
5
6 Signed-off-by: Michael Forney <mforney@mforney.org>
7 ---
8 libevdev/libevdev-int.h | 28 +++++++++++++
9 libevdev/libevdev.c | 87 +++++++++++++++++++----------------------
10 2 files changed, 68 insertions(+), 47 deletions(-)
11
12 diff --git a/libevdev/libevdev-int.h b/libevdev/libevdev-int.h
13 index 8e2518e..bc291ea 100644
14 --- a/libevdev/libevdev-int.h
15 +++ b/libevdev/libevdev-int.h
16 @@ -7,6 +7,7 @@
17 #define LIBEVDEV_INT_H
18
19 #include "config.h"
20 +#include <stdint.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdbool.h>
24 @@ -38,6 +39,26 @@ enum SyncState {
25 SYNC_IN_PROGRESS,
26 };
27
28 +struct mt_sync_state {
29 + uint32_t code;
30 + int32_t val[];
31 +};
32 +
33 +/* Keeps a record of touches during SYN_DROPPED */
34 +enum touch_state {
35 + TOUCH_OFF,
36 + TOUCH_STARTED, /* Started during SYN_DROPPED */
37 + TOUCH_STOPPED, /* Stopped during SYN_DROPPED */
38 + TOUCH_ONGOING, /* Existed before, still have same tracking ID */
39 + TOUCH_CHANGED, /* Existed before but have new tracking ID now, so
40 + stopped + started in that slot */
41 +};
42 +
43 +struct slot_change_state {
44 + enum touch_state state;
45 + unsigned long axes[NLONGS(ABS_CNT)]; /* bitmask for updated axes */
46 +};
47 +
48 /**
49 * Internal only: log data used to send messages to the respective log
50 * handler. We re-use the same struct for a global and inside
51 @@ -90,6 +111,13 @@ struct libevdev {
52
53 struct timeval last_event_time;
54
55 + struct {
56 + struct mt_sync_state *mt_state;
57 + size_t mt_state_sz; /* in bytes */
58 + struct slot_change_state *changes;
59 + size_t changes_sz; /* in bytes */
60 + } mt_sync;
61 +
62 struct logdata log;
63 };
64
65 diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c
66 index b941cfb..1cc912c 100644
67 --- a/libevdev/libevdev.c
68 +++ b/libevdev/libevdev.c
69 @@ -28,23 +28,7 @@ enum event_filter_status {
70 EVENT_FILTER_DISCARD, /**< Discard current event */
71 };
72
73 -/* Keeps a record of touches during SYN_DROPPED */
74 -enum touch_state {
75 - TOUCH_OFF,
76 - TOUCH_STARTED, /* Started during SYN_DROPPED */
77 - TOUCH_STOPPED, /* Stopped during SYN_DROPPED */
78 - TOUCH_ONGOING, /* Existed before, still have same tracking ID */
79 - TOUCH_CHANGED, /* Existed before but have new tracking ID now, so
80 - stopped + started in that slot */
81 -};
82 -
83 -struct slot_change_state {
84 - enum touch_state state;
85 - unsigned long axes[NLONGS(ABS_CNT)]; /* bitmask for updated axes */
86 -};
87 -
88 -static int sync_mt_state(struct libevdev *dev,
89 - struct slot_change_state *changes_out);
90 +static int sync_mt_state(struct libevdev *dev);
91 static int
92 update_key_state(struct libevdev *dev, const struct input_event *e);
93
94 @@ -203,6 +187,8 @@ libevdev_reset(struct libevdev *dev)
95 free(dev->phys);
96 free(dev->uniq);
97 free(dev->mt_slot_vals);
98 + free(dev->mt_sync.mt_state);
99 + free(dev->mt_sync.changes);
100 memset(dev, 0, sizeof(*dev));
101 dev->fd = -1;
102 dev->initialized = false;
103 @@ -331,7 +317,11 @@ free_slots(struct libevdev *dev)
104 {
105 dev->num_slots = -1;
106 free(dev->mt_slot_vals);
107 + free(dev->mt_sync.changes);
108 + free(dev->mt_sync.mt_state);
109 dev->mt_slot_vals = NULL;
110 + dev->mt_sync.changes = NULL;
111 + dev->mt_sync.mt_state = NULL;
112 }
113
114 static int
115 @@ -341,7 +331,11 @@ init_slots(struct libevdev *dev)
116 int rc = 0;
117
118 free(dev->mt_slot_vals);
119 + free(dev->mt_sync.changes);
120 + free(dev->mt_sync.mt_state);
121 dev->mt_slot_vals = NULL;
122 + dev->mt_sync.changes = NULL;
123 + dev->mt_sync.mt_state = NULL;
124
125 /* devices with ABS_RESERVED aren't MT devices,
126 see the documentation for multitouch-related
127 @@ -365,6 +359,19 @@ init_slots(struct libevdev *dev)
128 }
129 dev->current_slot = abs_info->value;
130
131 + dev->mt_sync.mt_state_sz = sizeof(*dev->mt_sync.mt_state) +
132 + dev->num_slots * sizeof(int32_t);
133 + dev->mt_sync.mt_state = calloc(1, dev->mt_sync.mt_state_sz);
134 +
135 + dev->mt_sync.changes_sz = dev->num_slots *
136 + sizeof(dev->mt_sync.changes[0]);
137 + dev->mt_sync.changes = malloc(dev->mt_sync.changes_sz);
138 +
139 + if (!dev->mt_sync.changes || !dev->mt_sync.mt_state) {
140 + rc = -ENOMEM;
141 + goto out;
142 + }
143 +
144 reset_tracking_ids(dev);
145 out:
146 return rc;
147 @@ -523,10 +530,8 @@ libevdev_set_fd(struct libevdev* dev, int fd)
148 if (rc != 0)
149 goto out;
150
151 - if (dev->num_slots != -1) {
152 - struct slot_change_state unused[dev->num_slots];
153 - sync_mt_state(dev, unused);
154 - }
155 + if (dev->num_slots != -1)
156 + sync_mt_state(dev);
157
158 rc = init_event_queue(dev);
159 if (rc < 0) {
160 @@ -661,33 +666,27 @@ out:
161 }
162
163 static int
164 -sync_mt_state(struct libevdev *dev,
165 - struct slot_change_state changes_out[dev->num_slots])
166 +sync_mt_state(struct libevdev *dev)
167 {
168 -#define MAX_SLOTS 256
169 int rc = 0;
170 - struct slot_change_state changes[MAX_SLOTS] = {0};
171 - unsigned int nslots = min(MAX_SLOTS, dev->num_slots);
172 + struct mt_sync_state *mt_state = dev->mt_sync.mt_state;
173 + struct slot_change_state *changes = dev->mt_sync.changes;
174
175 - for (int axis = ABS_MT_MIN; axis <= ABS_MT_MAX; axis++) {
176 - /* EVIOCGMTSLOTS required format */
177 - struct mt_sync_state {
178 - uint32_t code;
179 - int32_t val[MAX_SLOTS];
180 - } mt_state;
181 + memset(dev->mt_sync.changes, 0, dev->mt_sync.changes_sz);
182
183 + for (int axis = ABS_MT_MIN; axis <= ABS_MT_MAX; axis++) {
184 if (axis == ABS_MT_SLOT ||
185 !libevdev_has_event_code(dev, EV_ABS, axis))
186 continue;
187
188 - mt_state.code = axis;
189 - rc = ioctl(dev->fd, EVIOCGMTSLOTS(sizeof(mt_state)), &mt_state);
190 + mt_state->code = axis;
191 + rc = ioctl(dev->fd, EVIOCGMTSLOTS(dev->mt_sync.mt_state_sz), mt_state);
192 if (rc < 0)
193 goto out;
194
195 - for (unsigned int slot = 0; slot < nslots; slot++) {
196 + for (int slot = 0; slot < dev->num_slots; slot++) {
197 int val_before = *slot_value(dev, slot, axis),
198 - val_after = mt_state.val[slot];
199 + val_after = mt_state->val[slot];
200
201 if (axis == ABS_MT_TRACKING_ID) {
202 if (val_before == -1 && val_after != -1) {
203 @@ -716,17 +715,12 @@ sync_mt_state(struct libevdev *dev,
204 }
205 }
206
207 - if (dev->num_slots > MAX_SLOTS)
208 - memset(changes_out, 0, sizeof(*changes) * dev->num_slots);
209 -
210 - memcpy(changes_out, changes, sizeof(*changes) * nslots);
211 out:
212 return rc;
213 }
214
215 static void
216 terminate_slots(struct libevdev *dev,
217 - const struct slot_change_state changes[dev->num_slots],
218 int *last_reported_slot)
219 {
220 const unsigned int map[] = {BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP,
221 @@ -734,6 +728,7 @@ terminate_slots(struct libevdev *dev,
222 BTN_TOOL_QUINTTAP};
223 bool touches_stopped = false;
224 int ntouches_before = 0, ntouches_after = 0;
225 + struct slot_change_state *changes = dev->mt_sync.changes;
226
227 /* For BTN_TOOL_* emulation, we need to know how many touches we had
228 * before and how many we have left once we terminate all the ones
229 @@ -797,10 +792,10 @@ terminate_slots(struct libevdev *dev,
230
231 static int
232 push_mt_sync_events(struct libevdev *dev,
233 - const struct slot_change_state changes[dev->num_slots],
234 int last_reported_slot)
235 {
236 struct input_absinfo abs_info;
237 + struct slot_change_state *changes = dev->mt_sync.changes;
238 int rc;
239
240 for (int slot = 0; slot < dev->num_slots; slot++) {
241 @@ -909,8 +904,6 @@ sync_state(struct libevdev *dev)
242 int rc = 0;
243 bool want_mt_sync = false;
244 int last_reported_slot = 0;
245 - struct slot_change_state changes[dev->num_slots > 0 ? dev->num_slots : 1];
246 - memset(changes, 0, sizeof(changes));
247
248 /* see section "Discarding events before synchronizing" in
249 * libevdev/libevdev.h */
250 @@ -928,9 +921,9 @@ sync_state(struct libevdev *dev)
251 if (dev->num_slots > -1 &&
252 libevdev_has_event_code(dev, EV_ABS, ABS_MT_SLOT)) {
253 want_mt_sync = true;
254 - rc = sync_mt_state(dev, changes);
255 + rc = sync_mt_state(dev);
256 if (rc == 0)
257 - terminate_slots(dev, changes, &last_reported_slot);
258 + terminate_slots(dev, &last_reported_slot);
259 else
260 want_mt_sync = false;
261 }
262 @@ -944,7 +937,7 @@ sync_state(struct libevdev *dev)
263 if (rc == 0 && libevdev_has_event_type(dev, EV_ABS))
264 rc = sync_abs_state(dev);
265 if (rc == 0 && want_mt_sync)
266 - push_mt_sync_events(dev, changes, last_reported_slot);
267 + push_mt_sync_events(dev, last_reported_slot);
268
269 dev->queue_nsync = queue_num_elements(dev);
270
271 --
272 2.30.0
273