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)
committerJengHyun Kang <jhyuni.kang@samsung.com>
Tue, 24 Oct 2017 07:04:33 +0000 (16:04 +0900)
Change-Id: I144282f5ddc330eb77b73b3da5a36cedb6af069f

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

index d0794408657bdc0f7a388f6235faea28b708a528..b60d27df0b148c77fd515eeb30fdd874fc4048dc 100644 (file)
@@ -550,6 +550,23 @@ evdev_device_transform_pressure(struct evdev_device *device,
        }
 }
 
+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,
@@ -642,6 +659,7 @@ 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);
 
@@ -673,6 +691,8 @@ 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);
 
@@ -702,6 +722,7 @@ fallback_flush_mt_up(struct fallback_dispatch *dispatch,
 
        seat->slot_map &= ~(1 << 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;
@@ -982,6 +1003,32 @@ fallback_process_key(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(struct fallback_dispatch *dispatch,
                       struct evdev_device *device,
@@ -1037,6 +1084,7 @@ fallback_process_touch(struct fallback_dispatch *dispatch,
                        dispatch->pending_event = EVDEV_ABSOLUTE_MT_MOTION;
                break;
        default:
+               fallback_process_touch_extra_aux_data(dispatch, device, e);
                break;
        }
 }
@@ -1934,6 +1982,16 @@ fallback_dispatch_init_slots(struct fallback_dispatch *dispatch,
        dispatch->mt.slots_len = num_slots;
        dispatch->mt.slot = active_slot;
 
+       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;
@@ -3730,3 +3788,44 @@ 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)
+{
+       int i;
+       struct fallback_dispatch *dispatch;
+       struct mt_aux_data *aux_data, *aux_data_tmp;
+
+       dispatch = fallback_dispatch(device->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, aux_data_tmp, &dispatch->mt.aux_data_list[i], link) {
+                       list_remove(&aux_data->link);
+                       free(aux_data);
+               }
+       }
+}
index 96a2e1cc24c8108d09fbfa981d909194d0477287..e916e7b80edee4c8013ce474d921c970e5f08e5b 100644 (file)
@@ -143,6 +143,13 @@ struct mt_slot {
        int32_t pressure;
 };
 
+struct mt_aux_data {
+       uint32_t code;
+       int32_t value;
+       bool changed;
+       struct list link;
+};
+
 struct evdev_device {
        struct libinput_device base;
 
@@ -354,6 +361,7 @@ struct fallback_dispatch {
                size_t slots_len;
                bool want_hysteresis;
                struct device_coords hysteresis_margin;
+               struct list *aux_data_list;
        } mt;
 
        struct device_coords rel;
@@ -894,4 +902,9 @@ evdev_device_check_abs_axis_range(struct evdev_device *device,
        }
 }
 
+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 6593b074281d8234ca9fb850f1186c8f6da66dd3..3c0047c299229460c57b55cf04780d2f2c644ff6 100644 (file)
@@ -573,6 +573,14 @@ void
 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,
index dc73c69b98a8c6a89235c2228cbc3c794d9d5677..5013615accbdcc1cfdfede3260438ed7ce4fd902 100644 (file)
@@ -74,6 +74,10 @@ ASSERT_INT_SIZE(enum libinput_config_middle_emulation_state);
 ASSERT_INT_SIZE(enum libinput_config_scroll_method);
 ASSERT_INT_SIZE(enum libinput_config_dwt_state);
 
+#ifndef ABS_MT_PALM
+#define ABS_MT_PALM 0x3e
+#endif
+
 static inline bool
 check_event_type(struct libinput *libinput,
                 const char *function_name,
@@ -237,6 +241,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,
@@ -1861,6 +1874,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,
@@ -3073,6 +3215,39 @@ switch_notify_toggle(struct libinput_device *device,
                          &switch_event->base);
 }
 
+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 c7fbf8cea25265773b6efc72e86c4db2b59f9f9b..3496a47fa69a90ac3ae551e85307126c6711ce2c 100644 (file)
@@ -140,6 +140,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
@@ -268,6 +276,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
  *
@@ -680,6 +693,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
@@ -888,6 +904,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
  *
@@ -3046,6 +3063,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 8afe8b20a57b2eaa5e24960bca7a36a4680c646d..f72e13f58dbd3b1ded02e6ee32d7def25b0a583b 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 {