The branch main has been updated by wulf:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=059360287e3344f48f5a7839e2d6d54016b18b19

commit 059360287e3344f48f5a7839e2d6d54016b18b19
Author:     Vladimir Kondratyev <w...@freebsd.org>
AuthorDate: 2021-08-24 22:47:34 +0000
Commit:     Vladimir Kondratyev <w...@freebsd.org>
CommitDate: 2021-08-24 22:47:34 +0000

    evdev: Give short aliases to items of evdev_mt_slot array
    
    with using of unioned anonymous structure.
    
    Access to the same data by using different members of union generally
    works despite it is not supported by C specs.
    
    Also add helper function to report entire slot state.
    
    MFC after:      2 weeks
---
 sys/dev/evdev/evdev.h    | 24 ++++++++++++++++++
 sys/dev/evdev/evdev_mt.c | 63 +++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 73 insertions(+), 14 deletions(-)

diff --git a/sys/dev/evdev/evdev.h b/sys/dev/evdev/evdev.h
index fe21f8cea4c2..64bf75f04efd 100644
--- a/sys/dev/evdev/evdev.h
+++ b/sys/dev/evdev/evdev.h
@@ -102,6 +102,29 @@ struct evdev_methods
        evdev_keycode_t         *ev_set_keycode;
 };
 
+union evdev_mt_slot {
+       int32_t         val[MT_CNT];
+       struct {
+               int32_t maj;            /* ABS_MT_TOUCH_MAJOR */
+               int32_t min;            /* ABS_MT_TOUCH_MINOR */
+               int32_t w_maj;          /* ABS_MT_WIDTH_MAJOR */
+               int32_t w_min;          /* ABS_MT_WIDTH_MINOR */
+               int32_t ori;            /* ABS_MT_ORIENTATION */
+               int32_t x;              /* ABS_MT_POSITION_X */
+               int32_t y;              /* ABS_MT_POSITION_Y */
+               int32_t type;           /* ABS_MT_TOOL_TYPE */
+               int32_t blob_id;        /* ABS_MT_BLOB_ID */
+               int32_t id;             /* ABS_MT_TRACKING_ID */
+               int32_t p;              /* ABS_MT_PRESSURE */
+               int32_t dist;           /* ABS_MT_DISTANCE */
+               int32_t tool_x;         /* ABS_MT_TOOL_X */
+               int32_t tool_y;         /* ABS_MT_TOOL_Y */
+       };
+};
+_Static_assert(offsetof(union evdev_mt_slot, tool_y) ==
+    offsetof(union evdev_mt_slot, val[ABS_MT_INDEX(ABS_MT_TOOL_Y)]),
+    "evdev_mt_slot array members does not match their structure aliases");
+
 /* Input device interface: */
 struct evdev_dev *evdev_alloc(void);
 void evdev_free(struct evdev_dev *);
@@ -134,6 +157,7 @@ void *evdev_get_softc(struct evdev_dev *);
 int evdev_get_mt_slot_by_tracking_id(struct evdev_dev *, int32_t);
 void evdev_support_mt_compat(struct evdev_dev *);
 void evdev_push_mt_compat(struct evdev_dev *);
+int evdev_mt_push_slot(struct evdev_dev *, int, union evdev_mt_slot *);
 void evdev_mt_push_autorel(struct evdev_dev *);
 static inline int
 evdev_mt_id_to_slot(struct evdev_dev *evdev, int32_t id)
diff --git a/sys/dev/evdev/evdev_mt.c b/sys/dev/evdev/evdev_mt.c
index a3600e837960..6f5cce4a008d 100644
--- a/sys/dev/evdev/evdev_mt.c
+++ b/sys/dev/evdev/evdev_mt.c
@@ -60,10 +60,6 @@ struct {
        { ABS_MT_TOUCH_MAJOR,   ABS_TOOL_WIDTH, 15 },
 };
 
-struct evdev_mt_slot {
-       int32_t         val[MT_CNT];
-};
-
 struct evdev_mt {
        int                     last_reported_slot;
        u_int                   mtst_events;
@@ -71,7 +67,7 @@ struct evdev_mt {
        slotset_t               touches;
        /* the set of slots with unsynchronized state */
        slotset_t               frame;
-       struct evdev_mt_slot    slots[];
+       union evdev_mt_slot     slots[];
 };
 
 static void    evdev_mt_send_st_compat(struct evdev_dev *);
@@ -91,12 +87,11 @@ evdev_mt_init(struct evdev_dev *evdev)
        slots = MAXIMAL_MT_SLOT(evdev) + 1;
 
        evdev->ev_mt = malloc(offsetof(struct evdev_mt, slots) +
-            sizeof(struct evdev_mt_slot) * slots, M_EVDEV, M_WAITOK | M_ZERO);
+            sizeof(union evdev_mt_slot) * slots, M_EVDEV, M_WAITOK | M_ZERO);
 
        /* Initialize multitouch protocol type B states */
        for (slot = 0; slot < slots; slot++)
-               evdev->ev_mt->slots[slot].val[ABS_MT_INDEX(ABS_MT_TRACKING_ID)]
-                   = -1;
+               evdev->ev_mt->slots[slot].id = -1;
 
        if (bit_test(evdev->ev_flags, EVDEV_FLAG_MT_STCOMPAT))
                evdev_support_mt_compat(evdev);
@@ -119,6 +114,49 @@ evdev_mt_sync_frame(struct evdev_dev *evdev)
        evdev->ev_mt->frame = 0;
 }
 
+static void
+evdev_mt_send_slot(struct evdev_dev *evdev, int slot,
+    union evdev_mt_slot *state)
+{
+       int i;
+       bool type_a = !bit_test(evdev->ev_abs_flags, ABS_MT_SLOT);
+
+       EVDEV_LOCK_ASSERT(evdev);
+       MPASS(type_a || (slot >= 0 && slot <= MAXIMAL_MT_SLOT(evdev)));
+       MPASS(!type_a || state != NULL);
+
+       if (!type_a) {
+               evdev_send_event(evdev, EV_ABS, ABS_MT_SLOT, slot);
+               if (state == NULL) {
+                       evdev_send_event(evdev, EV_ABS, ABS_MT_TRACKING_ID, -1);
+                       return;
+               }
+       }
+       bit_foreach_at(evdev->ev_abs_flags, ABS_MT_FIRST, ABS_MT_LAST + 1, i)
+               evdev_send_event(evdev, EV_ABS, i,
+                   state->val[ABS_MT_INDEX(i)]);
+       if (type_a)
+               evdev_send_event(evdev, EV_SYN, SYN_MT_REPORT, 1);
+}
+
+int
+evdev_mt_push_slot(struct evdev_dev *evdev, int slot,
+    union evdev_mt_slot *state)
+{
+       bool type_a = !bit_test(evdev->ev_abs_flags, ABS_MT_SLOT);
+
+       if (type_a && state == NULL)
+               return (EINVAL);
+       if (!type_a && (slot < 0 || slot > MAXIMAL_MT_SLOT(evdev)))
+               return (EINVAL);
+
+       EVDEV_ENTER(evdev);
+       evdev_mt_send_slot(evdev, slot, state);
+       EVDEV_EXIT(evdev);
+
+       return (0);
+}
+
 int
 evdev_mt_get_last_slot(struct evdev_dev *evdev)
 {
@@ -170,8 +208,7 @@ evdev_get_mt_slot_by_tracking_id(struct evdev_dev *evdev, 
int32_t tracking_id)
        int slot;
 
        FOREACHBIT(mt->touches, slot)
-               if (evdev_mt_get_value(evdev, slot, ABS_MT_TRACKING_ID) ==
-                   tracking_id)
+               if (mt->slots[slot].id == tracking_id)
                        return (slot);
        /*
         * Do not allow allocation of new slot in a place of just
@@ -278,10 +315,8 @@ evdev_mt_send_autorel(struct evdev_dev *evdev)
 
        EVDEV_LOCK_ASSERT(evdev);
 
-       FOREACHBIT(mt->touches & ~mt->frame, slot) {
-               evdev_send_event(evdev, EV_ABS, ABS_MT_SLOT, slot);
-               evdev_send_event(evdev, EV_ABS, ABS_MT_TRACKING_ID, -1);
-       }
+       FOREACHBIT(mt->touches & ~mt->frame, slot)
+               evdev_mt_send_slot(evdev, slot, NULL);
 }
 
 void
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to