logo

oasis

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