From: JengHyun Kang Date: Tue, 25 Apr 2017 09:51:02 +0000 (+0900) Subject: support a AUX code events generated from EV_ABS X-Git-Tag: accepted/tizen/unified/20250205.095548~53 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a8fc943546360de6424558c7fde4e996b93d3529;p=platform%2Fupstream%2Flibinput.git support a AUX code events generated from EV_ABS Change-Id: I144282f5ddc330eb77b73b3da5a36cedb6af069f --- diff --git a/src/evdev-fallback.c b/src/evdev-fallback.c index 38e3c92e..d6630585 100644 --- a/src/evdev-fallback.c +++ b/src/evdev-fallback.c @@ -165,6 +165,23 @@ fallback_rotate_relative(struct fallback_dispatch *dispatch, return rel; } +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, @@ -253,6 +270,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); @@ -284,6 +303,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); @@ -313,6 +335,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; @@ -463,6 +487,32 @@ fallback_flush_st_cancel(struct fallback_dispatch *dispatch, return true; } +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, @@ -627,6 +677,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; } } @@ -1465,6 +1516,42 @@ static struct evdev_dispatch_interface fallback_interface = { .get_switch_state = fallback_interface_get_switch_state, }; +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) { @@ -1614,6 +1701,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; @@ -1756,5 +1853,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; } diff --git a/src/evdev-fallback.h b/src/evdev-fallback.h index fd01c752..6c453ca4 100644 --- a/src/evdev-fallback.h +++ b/src/evdev-fallback.h @@ -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; @@ -108,6 +115,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; diff --git a/src/evdev.c b/src/evdev.c index 99ef7aa8..9ccefd30 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -3204,3 +3204,24 @@ evdev_device_destroy(struct evdev_device *device) udev_device_unref(device->udev_device); free(device); } + +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); + } +} diff --git a/src/evdev.h b/src/evdev.h index 441d92ff..1da180e2 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -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 @@ -1062,4 +1068,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 */ diff --git a/src/libinput-private.h b/src/libinput-private.h index 4f9ed6a4..451b3b6f 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -758,6 +758,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, diff --git a/src/libinput.c b/src/libinput.c index 853d951a..d58e0de0 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -79,6 +79,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) { @@ -264,6 +268,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, @@ -3380,6 +3522,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) diff --git a/src/libinput.h b/src/libinput.h index d789e073..e0ec4a76 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -144,6 +144,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 @@ -289,6 +297,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 * @@ -852,6 +865,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 @@ -1109,6 +1125,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 * @@ -3741,6 +3758,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 * diff --git a/src/libinput.sym b/src/libinput.sym index de9d7434..a8266634 100644 --- a/src/libinput.sym +++ b/src/libinput.sym @@ -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 {