}
}
+static void
+evdev_flush_extra_aux_data(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, &device->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
evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
{
x = slot_data->x;
y = slot_data->y;
transform_absolute(device, &x, &y);
-
+ evdev_flush_extra_aux_data(device, time, device->pending_event, slot, seat_slot);
touch_notify_touch_down(base, time, slot, seat_slot, x, y, &slot_data->area, slot_data->pressure);
break;
case EVDEV_ABSOLUTE_MT_MOTION:
break;
transform_absolute(device, &x, &y);
+ evdev_flush_extra_aux_data(device, time, device->pending_event, slot, seat_slot);
touch_notify_touch_motion(base, time, slot, seat_slot, x, y, &slot_data->area, slot_data->pressure);
break;
case EVDEV_ABSOLUTE_MT_UP:
seat->slot_map &= ~(1 << seat_slot);
+ evdev_flush_extra_aux_data(device, time, device->pending_event, slot, seat_slot);
touch_notify_touch_up(base, time, slot, seat_slot);
break;
case EVDEV_ABSOLUTE_TOUCH_DOWN:
cx = device->abs.x;
cy = device->abs.y;
transform_absolute(device, &cx, &cy);
-
touch_notify_touch_down(base, time, -1, seat_slot, cx, cy, &default_touch, DEFAULT_TOUCH_PRESSURE);
break;
case EVDEV_ABSOLUTE_MOTION:
}
}
+static bool
+evdev_process_touch_extra_aux_data(struct evdev_device *device,
+ struct input_event *e)
+{
+ struct mt_aux_data *aux_data;
+ struct list *current_axis_list;
+ bool res = false;
+
+ if (!device->mt.aux_data_list) return false;
+
+ current_axis_list = &device->mt.aux_data_list[device->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;
+ }
+ res = true;
+ break;
+ }
+ }
+
+ return res;
+}
+
static void
evdev_process_touch(struct evdev_device *device,
struct input_event *e,
current_slot->area.orientation = e->value;
break;
default:
- needs_wake = false;
+ if (!evdev_process_touch_extra_aux_data(device, e))
+ needs_wake = false;
break;
}
if (needs_wake && device->pending_event == EVDEV_NONE)
device->mt.slots = slots;
device->mt.slots_len = num_slots;
device->mt.slot = active_slot;
+
+ device->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;
}
}
free(device->mt.slots);
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)
+{
+ int i;
+ struct mt_aux_data *aux_data, *aux_data_tmp;
+
+ if (!list_empty(&device->mt.aux_data_list[0])) {
+ list_for_each(aux_data, &device->mt.aux_data_list[0], link) {
+ if (code == aux_data->code) return;
+ }
+ }
+
+ for (i = 0; i < (int)device->mt.slots_len; i++) {
+ aux_data = calloc(1, sizeof(struct mt_aux_data));
+ if (!aux_data) goto failed;
+ aux_data->code = code;
+ list_insert(&device->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, &device->mt.aux_data_list[i], link) {
+ list_remove(&aux_data->link);
+ free(aux_data);
+ }
+ }
+}
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;
struct {
int slot;
struct mt_slot *slots;
+ struct list *aux_data_list;
size_t slots_len;
} mt;
struct mtdev *mtdev;
return button;
}
+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 */
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);
+
static inline uint64_t
libinput_now(struct libinput *libinput)
{
if (!check_event_type(li_, __func__, type_, __VA_ARGS__, -1)) \
return retval_; \
+#ifndef ABS_MT_PALM
+#define ABS_MT_PALM 0x3e
+#endif
+
static inline bool
check_event_type(struct libinput *libinput,
const char *function_name,
int32_t pressure;
};
+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;
+};
+
static void
libinput_default_log_func(struct libinput *libinput,
enum libinput_log_priority priority,
case LIBINPUT_EVENT_TOUCH_MOTION:
case LIBINPUT_EVENT_TOUCH_CANCEL:
case LIBINPUT_EVENT_TOUCH_FRAME:
+ case LIBINPUT_EVENT_TOUCH_AUX_DATA:
break;
}
case LIBINPUT_EVENT_TOUCH_MOTION:
case LIBINPUT_EVENT_TOUCH_CANCEL:
case LIBINPUT_EVENT_TOUCH_FRAME:
+ case LIBINPUT_EVENT_TOUCH_AUX_DATA:
break;
}
case LIBINPUT_EVENT_TOUCH_CANCEL:
case LIBINPUT_EVENT_TOUCH_FRAME:
return (struct libinput_event_touch *) event;
+ case LIBINPUT_EVENT_TOUCH_AUX_DATA:
+ break;
}
return NULL;
case LIBINPUT_EVENT_TOUCH_MOTION:
case LIBINPUT_EVENT_TOUCH_CANCEL:
case LIBINPUT_EVENT_TOUCH_FRAME:
+ case LIBINPUT_EVENT_TOUCH_AUX_DATA:
break;
}
return device->abs.absinfo_pressure != 0;
}
+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,
TRACE_INPUT_END();
}
+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)
LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
};
+enum libinput_touch_aux_data_type {
+ LIBINPUT_TOUCH_AUX_DATA_TYPE_UNKNOWN,
+ LIBINPUT_TOUCH_AUX_DATA_TYPE_PALM,
+};
+
/**
* @ingroup base
*
* Signals the end of a set of touchpoints at one device sample
* time. This event has no coordinate information attached.
*/
- LIBINPUT_EVENT_TOUCH_FRAME
+ LIBINPUT_EVENT_TOUCH_FRAME,
+ LIBINPUT_EVENT_TOUCH_LAST = LIBINPUT_EVENT_TOUCH_FRAME,
+ LIBINPUT_EVENT_TOUCH_AUX_DATA = LIBINPUT_EVENT_TOUCH_LAST + 1,
};
/**
*/
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;
+
/**
* @defgroup event Accessing and destruction of events
*/
struct libinput_event_touch *
libinput_event_get_touch_event(struct libinput_event *event);
+
/**
* @ingroup event
*
int
libinput_event_touch_has_orientation(struct libinput_event_touch *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_touch
*
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.9.0;