support a AUX code events generated from EV_ABS
authorJengHyun Kang <jhyuni.kang@samsung.com>
Tue, 25 Apr 2017 09:51:02 +0000 (18:51 +0900)
committerduna.oh <duna.oh@samsung.com>
Fri, 27 Jan 2023 05:15:20 +0000 (14:15 +0900)
Change-Id: I144282f5ddc330eb77b73b3da5a36cedb6af069f

src/evdev-fallback.c
src/evdev-fallback.h
src/evdev.c
src/evdev.h
src/libinput-private.h
src/libinput.c
src/libinput.h
src/libinput.sym

index 64a3fbf..a49e654 100644 (file)
@@ -168,6 +168,23 @@ fallback_rotate_relative(struct fallback_dispatch *dispatch,
 }
 
 static void
+fallback_flush_extra_aux_data(struct fallback_dispatch *dispatch,
+                                   struct evdev_device *device,
+                                   uint64_t time, int32_t type,
+                                   int32_t slot, int32_t seat_slot)
+{
+       struct libinput_device *base = &device->base;
+       struct mt_aux_data *aux_data;
+
+       list_for_each(aux_data, &dispatch->mt.aux_data_list[slot], link) {
+               if (aux_data->changed) {
+                       touch_notify_aux_data(base, time, slot, seat_slot, aux_data->code, aux_data->value);
+                       aux_data->changed = false;
+               }
+       }
+}
+
+static void
 fallback_flush_relative_motion(struct fallback_dispatch *dispatch,
                               struct evdev_device *device,
                               uint64_t time)
@@ -258,6 +275,8 @@ fallback_flush_mt_down(struct fallback_dispatch *dispatch,
        slot->hysteresis_center = point;
        evdev_transform_absolute(device, &point);
 
+       fallback_flush_extra_aux_data(dispatch, device, time,
+                               dispatch->pending_event, slot_idx, seat_slot);
        touch_notify_touch_down(base, time, slot_idx, seat_slot,
                                &point, &slot->area, slot->pressure);
 
@@ -289,6 +308,9 @@ fallback_flush_mt_motion(struct fallback_dispatch *dispatch,
                return false;
 
        evdev_transform_absolute(device, &point);
+
+       fallback_flush_extra_aux_data(dispatch, device, time,
+                                 dispatch->pending_event, slot_idx, seat_slot);
        touch_notify_touch_motion(base, time, slot_idx, seat_slot,
                                  &point, &slot->area, slot->pressure);
 
@@ -318,6 +340,8 @@ fallback_flush_mt_up(struct fallback_dispatch *dispatch,
 
        seat->slot_map &= ~bit(seat_slot);
 
+       fallback_flush_extra_aux_data(dispatch, device, time,
+                               dispatch->pending_event, slot_idx, seat_slot);
        touch_notify_touch_up(base, time, slot_idx, seat_slot);
 
        return true;
@@ -469,6 +493,32 @@ fallback_flush_st_cancel(struct fallback_dispatch *dispatch,
 }
 
 static void
+fallback_process_touch_extra_aux_data(struct fallback_dispatch *dispatch,
+                   struct evdev_device *device,
+                   struct input_event *e)
+{
+       struct mt_aux_data *aux_data;
+       struct list *current_axis_list;
+
+       if (!dispatch->mt.aux_data_list) return false;
+
+       current_axis_list = &dispatch->mt.aux_data_list[dispatch->mt.slot];
+       if (!current_axis_list) return false;
+
+       if (list_empty(current_axis_list)) return false;
+
+       list_for_each(aux_data, current_axis_list, link) {
+               if (aux_data->code == e->code) {
+                       if (aux_data->value != e->value) {
+                               aux_data->changed = true;
+                               aux_data->value = e->value;
+                       }
+                       break;
+               }
+       }
+}
+
+static void
 fallback_process_touch_button(struct fallback_dispatch *dispatch,
                              struct evdev_device *device,
                              uint64_t time, int value)
@@ -632,6 +682,7 @@ fallback_process_touch(struct fallback_dispatch *dispatch,
                        dispatch->pending_event = EVDEV_ABSOLUTE_MT;
                break;
        default:
+               fallback_process_touch_extra_aux_data(dispatch, device, e);
                break;
        }
 }
@@ -1445,6 +1496,42 @@ struct evdev_dispatch_interface fallback_interface = {
 };
 
 static void
+fallback_device_interface_set_aux_data(struct evdev_dispatch *evdev_dispatch, uint32_t code)
+{
+       int i;
+       struct fallback_dispatch *dispatch;
+       struct mt_aux_data *aux_data;
+
+       dispatch = fallback_dispatch(evdev_dispatch);
+
+       if (!list_empty(&dispatch->mt.aux_data_list[0])) {
+               list_for_each(aux_data, &dispatch->mt.aux_data_list[0], link) {
+                       if (code == aux_data->code) return;
+               }
+       }
+
+       for (i = 0; i < (int)dispatch->mt.slots_len; i++) {
+               aux_data = calloc(1, sizeof(struct mt_aux_data));
+               if (!aux_data) goto failed;
+               aux_data->code = code;
+               list_insert(&dispatch->mt.aux_data_list[i], &aux_data->link);
+       }
+
+       return;
+failed:
+       for (i = i-1; i >= 0; i--) {
+               list_for_each_safe(aux_data, &dispatch->mt.aux_data_list[i], link) {
+                       list_remove(&aux_data->link);
+                       free(aux_data);
+               }
+       }
+}
+
+struct evdev_dispatch_device_interface fallback_device_interface = {
+       .set_aux_data = fallback_device_interface_set_aux_data
+};
+
+static void
 fallback_change_to_left_handed(struct evdev_device *device)
 {
        struct fallback_dispatch *dispatch = fallback_dispatch(device->dispatch);
@@ -1594,6 +1681,16 @@ fallback_dispatch_init_slots(struct fallback_dispatch *dispatch,
                                                        EV_ABS,
                                                        ABS_MT_TOOL_TYPE);
 
+       dispatch->mt.aux_data_list = calloc(num_slots, sizeof(struct list));
+       if (device->mt.aux_data_list) {
+               int i;
+               for (i = 0; i < num_slots; i++) {
+                       list_init(&device->mt.aux_data_list[i]);
+               }
+       }
+       else
+               return -1;
+
        if (device->abs.absinfo_x->fuzz || device->abs.absinfo_y->fuzz) {
                dispatch->mt.want_hysteresis = true;
                dispatch->mt.hysteresis_margin.x = device->abs.absinfo_x->fuzz/2;
@@ -1734,5 +1831,7 @@ fallback_dispatch_create(struct libinput_device *libinput_device)
        fallback_init_debounce(dispatch);
        fallback_init_arbitration(dispatch, device);
 
+       dispatch->base.device_interface = &fallback_device_interface;
+
        return &dispatch->base;
 }
index 3d6d272..1a935d0 100644 (file)
@@ -84,6 +84,13 @@ struct mt_slot {
        int32_t pressure;
 };
 
+struct mt_aux_data {
+       uint32_t code;
+       int32_t value;
+       bool changed;
+       struct list link;
+};
+
 struct fallback_dispatch {
        struct evdev_dispatch base;
        struct evdev_device *device;
@@ -109,6 +116,7 @@ struct fallback_dispatch {
                bool want_hysteresis;
                struct device_coords hysteresis_margin;
                bool has_palm;
+               struct list *aux_data_list;
        } mt;
 
        struct device_coords rel;
index efc48ab..642b9a5 100644 (file)
@@ -3248,3 +3248,24 @@ out:
 #endif
        return has_left_handed;
 }
+
+int
+evdev_device_has_aux_data(struct evdev_device *device, uint32_t code)
+{
+       const struct input_absinfo *absinfo_aux_data;
+       absinfo_aux_data = libevdev_get_abs_info(device->evdev, code);
+
+       return !!absinfo_aux_data;
+}
+
+void
+evdev_device_set_aux_data(struct evdev_device *device, uint32_t code)
+{
+       struct evdev_dispatch *dispatch = device->dispatch;
+       if (!dispatch) return;
+       if (!dispatch->device_interface) return;
+
+       if (dispatch->device_interface->set_auxdata) {
+               dispatch->device_interface->set_auxdata(dispatch, code);
+       }
+}
index 154add7..97d8ffd 100644 (file)
@@ -355,6 +355,10 @@ struct evdev_dispatch_interface {
                                   bool left_handed_enabled);
 };
 
+struct evdev_dispatch_device_interface {
+       void (*set_aux_data) (struct evdev_dispatch *dispatch, uint32_t code);
+};
+
 enum evdev_dispatch_type {
        DISPATCH_FALLBACK,
        DISPATCH_TOUCHPAD,
@@ -371,6 +375,8 @@ struct evdev_dispatch {
                struct libinput_device_config_send_events config;
                enum libinput_config_send_events_mode current_mode;
        } sendevents;
+
+       struct evdev_dispatch_device_interface *device_interface;
 };
 
 static inline void
@@ -1066,4 +1072,10 @@ evdev_paired_keyboard_destroy(struct evdev_paired_keyboard *kbd)
        free(kbd);
 }
 
+int
+evdev_device_has_aux_data(struct evdev_device *device, uint32_t code);
+
+void
+evdev_device_set_aux_data(struct evdev_device *device, uint32_t code);
+
 #endif /* EVDEV_H */
index 8f21616..31ecd80 100644 (file)
@@ -669,6 +669,14 @@ touch_notify_frame(struct libinput_device *device,
                   uint64_t time);
 
 void
+touch_notify_aux_data(struct libinput_device *device,
+                         uint64_t time,
+                         int32_t slot,
+                         int32_t seat_slot,
+                         uint32_t code,
+                         int32_t value);
+
+void
 gesture_notify_swipe(struct libinput_device *device,
                     uint64_t time,
                     enum libinput_event_type type,
index 4c2ce15..637c5d5 100644 (file)
@@ -77,6 +77,10 @@ ASSERT_INT_SIZE(enum libinput_config_scroll_method);
 ASSERT_INT_SIZE(enum libinput_config_dwt_state);
 ASSERT_INT_SIZE(enum libinput_config_dwtp_state);
 
+#ifndef ABS_MT_PALM
+#define ABS_MT_PALM 0x3e
+#endif
+
 static inline const char *
 event_type_to_str(enum libinput_event_type type)
 {
@@ -253,6 +257,15 @@ struct libinput_event_switch {
        enum libinput_switch_state state;
 };
 
+struct libinput_event_touch_aux_data {
+       struct libinput_event base;
+       uint32_t time;
+       int32_t slot;
+       int32_t seat_slot;
+       uint32_t code;
+       int32_t value;
+};
+
 LIBINPUT_ATTRIBUTE_PRINTF(3, 0)
 static void
 libinput_default_log_func(struct libinput *libinput,
@@ -1955,6 +1968,135 @@ libinput_event_switch_get_time_usec(struct libinput_event_switch *event)
        return event->time;
 }
 
+LIBINPUT_EXPORT struct libinput_event_touch_aux_data *
+libinput_event_get_touch_aux_data(struct libinput_event *event)
+{
+       switch (event->type) {
+       case LIBINPUT_EVENT_NONE:
+               abort(); /* not used as actual event type */
+       case LIBINPUT_EVENT_DEVICE_ADDED:
+       case LIBINPUT_EVENT_DEVICE_REMOVED:
+       case LIBINPUT_EVENT_KEYBOARD_KEY:
+       case LIBINPUT_EVENT_POINTER_MOTION:
+       case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
+       case LIBINPUT_EVENT_POINTER_BUTTON:
+       case LIBINPUT_EVENT_POINTER_AXIS:
+       case LIBINPUT_EVENT_TOUCH_DOWN:
+       case LIBINPUT_EVENT_TOUCH_UP:
+       case LIBINPUT_EVENT_TOUCH_MOTION:
+       case LIBINPUT_EVENT_TOUCH_CANCEL:
+       case LIBINPUT_EVENT_TOUCH_FRAME:
+               break;
+       case LIBINPUT_EVENT_TOUCH_AUX_DATA:
+               return (struct libinput_event_touch_aux_data *) event;
+       }
+
+       return NULL;
+}
+
+LIBINPUT_EXPORT int
+libinput_event_touch_aux_data_get_code(struct libinput_event_touch_aux_data *event)
+{
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TOUCH_AUX_DATA);
+
+       return event->code;
+}
+
+LIBINPUT_EXPORT int
+libinput_event_touch_aux_data_get_value(struct libinput_event_touch_aux_data *event)
+{
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TOUCH_AUX_DATA);
+
+       return event->value;
+}
+
+LIBINPUT_EXPORT int
+libinput_event_touch_aux_data_get_slot(struct libinput_event_touch_aux_data *event)
+{
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TOUCH_AUX_DATA);
+
+       return event->slot;
+}
+
+LIBINPUT_EXPORT int
+libinput_event_touch_aux_data_get_seat_slot(struct libinput_event_touch_aux_data *event)
+{
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TOUCH_AUX_DATA);
+
+       return event->seat_slot;
+}
+
+LIBINPUT_EXPORT int
+libinput_event_touch_aux_data_get_time(struct libinput_event_touch_aux_data *event)
+{
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TOUCH_AUX_DATA);
+
+       return event->time;
+}
+
+LIBINPUT_EXPORT unsigned int
+libinput_event_touch_aux_data_get_type(struct libinput_event_touch_aux_data *event)
+{
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TOUCH_AUX_DATA);
+
+       if (event->code == ABS_MT_PALM) {
+               return LIBINPUT_TOUCH_AUX_DATA_TYPE_PALM;
+       }
+
+       return LIBINPUT_TOUCH_AUX_DATA_TYPE_UNKNOWN;
+}
+
+
+LIBINPUT_EXPORT int
+libinput_device_touch_has_aux_data(struct libinput_device *device, uint32_t aux_data)
+{
+       if (!evdev_device_has_capability((struct evdev_device *)device,
+                       LIBINPUT_DEVICE_CAP_TOUCH))
+               return 0;
+
+       return evdev_device_has_aux_data((struct evdev_device *)device, aux_data);
+}
+
+LIBINPUT_EXPORT int
+libinput_device_touch_set_aux_data(struct libinput_device *device, uint32_t aux_data)
+{
+       if (!evdev_device_has_capability((struct evdev_device *)device,
+                       LIBINPUT_DEVICE_CAP_TOUCH))
+               return 0;
+
+       evdev_device_set_aux_data((struct evdev_device *)device, aux_data);
+       return 1;
+}
+
+LIBINPUT_EXPORT unsigned int
+libinput_device_touch_aux_data_get_code(enum libinput_touch_aux_data_type type)
+{
+       switch (type) {
+       case LIBINPUT_TOUCH_AUX_DATA_TYPE_PALM:
+               return ABS_MT_PALM;
+       default:
+               return 0;
+       }
+}
+
 struct libinput_source *
 libinput_add_fd(struct libinput *libinput,
                int fd,
@@ -3335,6 +3477,39 @@ switch_notify_toggle(struct libinput_device *device,
 #endif
 }
 
+void
+touch_notify_aux_data(struct libinput_device *device,
+                     uint64_t time,
+                     int32_t slot,
+                     int32_t seat_slot,
+                     uint32_t code,
+                     int32_t value)
+{
+       struct libinput_event_touch_aux_data *touch_aux_data_event;
+
+       TRACE_INPUT_BEGIN(touch_notify_aux_data);
+
+       touch_aux_data_event = zalloc(sizeof *touch_aux_data_event);
+       if (!touch_aux_data_event) {
+               TRACE_INPUT_END();
+               return;
+       }
+
+       *touch_aux_data_event = (struct libinput_event_touch_aux_data) {
+               .time = time,
+               .slot = slot,
+               .seat_slot = seat_slot,
+               .code = code,
+               .value = value,
+       };
+
+       post_device_event(device, time,
+                         LIBINPUT_EVENT_TOUCH_AUX_DATA,
+                         &touch_aux_data_event->base);
+
+       TRACE_INPUT_END();
+}
+
 static void
 libinput_post_event(struct libinput *libinput,
                    struct libinput_event *event)
index 22f9ebc..9a59cbe 100644 (file)
@@ -145,6 +145,14 @@ struct libinput_event_pointer;
 struct libinput_event_touch;
 
 /**
+ * @ingroup event_touch_aux_data
+ * @struct libinput_event_touch_aux_data
+ *
+ * Support extra touch axis
+ */
+struct libinput_event_touch_aux_data;
+
+/**
  * @ingroup event_tablet
  * @struct libinput_event_tablet_tool
  *
@@ -286,6 +294,11 @@ enum libinput_pointer_axis_source {
        LIBINPUT_POINTER_AXIS_SOURCE_WHEEL_TILT,
 };
 
+enum libinput_touch_aux_data_type {
+       LIBINPUT_TOUCH_AUX_DATA_TYPE_UNKNOWN,
+       LIBINPUT_TOUCH_AUX_DATA_TYPE_PALM,
+};
+
 /**
  * @ingroup event_tablet_pad
  *
@@ -832,6 +845,9 @@ enum libinput_event_type {
         */
        LIBINPUT_EVENT_TOUCH_FRAME,
 
+       LIBINPUT_EVENT_TOUCH_LAST = LIBINPUT_EVENT_TOUCH_FRAME,
+       LIBINPUT_EVENT_TOUCH_AUX_DATA = LIBINPUT_EVENT_TOUCH_LAST + 1,
+
        /**
         * One or more axes have changed state on a device with the @ref
         * LIBINPUT_DEVICE_CAP_TABLET_TOOL capability. This event is only sent
@@ -1081,6 +1097,7 @@ libinput_event_get_keyboard_event(struct libinput_event *event);
 struct libinput_event_touch *
 libinput_event_get_touch_event(struct libinput_event *event);
 
+
 /**
  * @ingroup event
  *
@@ -3667,6 +3684,36 @@ libinput_event_switch_get_switch(struct libinput_event_switch *event);
 enum libinput_switch_state
 libinput_event_switch_get_switch_state(struct libinput_event_switch *event);
 
+struct libinput_event_touch_aux_data *
+libinput_event_get_touch_aux_data(struct libinput_event *event);
+
+int
+libinput_device_touch_has_aux_data(struct libinput_device *device, uint32_t axis);
+
+int
+libinput_device_touch_set_aux_data(struct libinput_device *device, uint32_t axis);
+
+unsigned int
+libinput_device_touch_aux_data_get_code(enum libinput_touch_aux_data_type type);
+
+int
+libinput_event_touch_aux_data_get_code(struct libinput_event_touch_aux_data *event);
+
+int
+libinput_event_touch_aux_data_get_value(struct libinput_event_touch_aux_data *event);
+
+int
+libinput_event_touch_aux_data_get_slot(struct libinput_event_touch_aux_data *event);
+
+int
+libinput_event_touch_aux_data_get_seat_slot(struct libinput_event_touch_aux_data *event);
+
+int
+libinput_event_touch_aux_data_get_time(struct libinput_event_touch_aux_data *event);
+
+unsigned int
+libinput_event_touch_aux_data_get_type(struct libinput_event_touch_aux_data *event);
+
 /**
  * @ingroup event_switch
  *
index 989d6d8..08ab6d1 100644 (file)
@@ -190,6 +190,16 @@ LIBINPUT_1.1 {
        libinput_event_touch_has_minor;
        libinput_event_touch_has_orientation;
        libinput_event_touch_has_pressure;
+       libinput_event_get_touch_aux_data;
+       libinput_device_touch_has_aux_data;
+       libinput_device_touch_set_aux_data;
+       libinput_event_touch_aux_data_get_code;
+       libinput_event_touch_aux_data_get_value;
+       libinput_event_touch_aux_data_get_slot;
+       libinput_event_touch_aux_data_get_seat_slot;
+       libinput_event_touch_aux_data_get_time;
+       libinput_event_touch_aux_data_get_type;
+       libinput_device_touch_aux_data_get_code;
 } LIBINPUT_0.21.0;
 
 LIBINPUT_1.2 {