}
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)
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);
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);
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;
}
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)
dispatch->pending_event = EVDEV_ABSOLUTE_MT;
break;
default:
+ fallback_process_touch_extra_aux_data(dispatch, device, e);
break;
}
}
};
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);
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;
fallback_init_debounce(dispatch);
fallback_init_arbitration(dispatch, device);
+ dispatch->base.device_interface = &fallback_device_interface;
+
return &dispatch->base;
}
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;
bool want_hysteresis;
struct device_coords hysteresis_margin;
bool has_palm;
+ struct list *aux_data_list;
} mt;
struct device_coords rel;
#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);
+ }
+}
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,
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
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 */
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,
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)
{
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,
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,
#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)
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
*
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
*
*/
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
struct libinput_event_touch *
libinput_event_get_touch_event(struct libinput_event *event);
+
/**
* @ingroup 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
*
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 {