free(tp);
}
+static void
+tp_suspend(struct tp_dispatch *tp, struct evdev_device *device)
+{
+ uint64_t now = libinput_now(tp->device->base.seat->libinput);
+ struct tp_touch *t;
+
+ /* Unroll the touchpad state.
+ * Release buttons first. If tp is a clickpad, the button event
+ * must come before the touch up. If it isn't, the order doesn't
+ * matter anyway
+ *
+ * Then cancel all timeouts on the taps, triggering the last set
+ * of events.
+ *
+ * Then lift all touches so the touchpad is in a neutral state.
+ *
+ */
+ tp_release_all_buttons(tp, now);
+ tp_release_all_taps(tp, now);
+
+ tp_for_each_touch(tp, t) {
+ tp_end_touch(tp, t, now);
+ }
+
+ tp_handle_state(tp, now);
+
+ evdev_device_suspend(device);
+}
+
+static void
+tp_resume(struct tp_dispatch *tp, struct evdev_device *device)
+{
+ evdev_device_resume(device);
+}
+
static struct evdev_dispatch_interface tp_interface = {
tp_process,
tp_destroy
return 0;
}
+static uint32_t
+tp_sendevents_get_modes(struct libinput_device *device)
+{
+ return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED |
+ LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
+}
+
+static enum libinput_config_status
+tp_sendevents_set_mode(struct libinput_device *device,
+ enum libinput_config_send_events_mode mode)
+{
+ struct evdev_device *evdev = (struct evdev_device*)device;
+ struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
+
+ if (mode == tp->sendevents.current_mode)
+ return LIBINPUT_CONFIG_STATUS_SUCCESS;
+
+ switch(mode) {
+ case LIBINPUT_CONFIG_SEND_EVENTS_ENABLED:
+ tp_resume(tp, evdev);
+ break;
+ case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED:
+ tp_suspend(tp, evdev);
+ break;
+ default:
+ return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
+ }
+
+ tp->sendevents.current_mode = mode;
+
+ return LIBINPUT_CONFIG_STATUS_SUCCESS;
+}
+
+static enum libinput_config_send_events_mode
+tp_sendevents_get_mode(struct libinput_device *device)
+{
+ struct evdev_device *evdev = (struct evdev_device*)device;
+ struct tp_dispatch *dispatch = (struct tp_dispatch*)evdev->dispatch;
+
+ return dispatch->sendevents.current_mode;
+}
+
+static enum libinput_config_send_events_mode
+tp_sendevents_get_default_mode(struct libinput_device *device)
+{
+ return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
+}
+
struct evdev_dispatch *
evdev_mt_touchpad_create(struct evdev_device *device)
{
return NULL;
}
+ device->base.config.sendevents = &tp->sendevents.config;
+
+ tp->sendevents.current_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
+ tp->sendevents.config.get_modes = tp_sendevents_get_modes;
+ tp->sendevents.config.set_mode = tp_sendevents_set_mode;
+ tp->sendevents.config.get_mode = tp_sendevents_get_mode;
+ tp->sendevents.config.get_default_mode = tp_sendevents_get_default_mode;
+
return &tp->base;
}
int32_t right_edge;
int32_t left_edge;
} palm;
+
+ struct {
+ struct libinput_device_config_send_events config;
+ enum libinput_config_send_events_mode current_mode;
+ } sendevents;
};
#define tp_for_each_touch(_tp, _t) \
const struct input_event *e,
uint64_t time);
+void
+tp_release_all_buttons(struct tp_dispatch *tp,
+ uint64_t time);
+
int
tp_post_button_events(struct tp_dispatch *tp, uint64_t time);
bool
tp_button_is_inside_softbutton_area(struct tp_dispatch *tp, struct tp_touch *t);
+void
+tp_release_all_taps(struct tp_dispatch *tp,
+ uint64_t time);
+
#endif
int main (int argc, char **argv)
{
- litest_add("device:sendevents", device_sendevents_config, LITEST_ANY, LITEST_TOUCHPAD);
- litest_add("device:sendevents", device_sendevents_config_default, LITEST_ANY, LITEST_TOUCHPAD);
- litest_add("device:sendevents", device_disable, LITEST_POINTER, LITEST_TOUCHPAD);
+ litest_add("device:sendevents", device_sendevents_config, LITEST_ANY, LITEST_ANY);
+ litest_add("device:sendevents", device_sendevents_config_default, LITEST_ANY, LITEST_ANY);
+ litest_add("device:sendevents", device_disable, LITEST_POINTER, LITEST_ANY);
litest_add("device:sendevents", device_disable_events_pending, LITEST_POINTER, LITEST_TOUCHPAD);
- litest_add("device:sendevents", device_double_disable, LITEST_ANY, LITEST_TOUCHPAD);
- litest_add("device:sendevents", device_double_enable, LITEST_ANY, LITEST_TOUCHPAD);
+ litest_add("device:sendevents", device_double_disable, LITEST_ANY, LITEST_ANY);
+ litest_add("device:sendevents", device_double_enable, LITEST_ANY, LITEST_ANY);
litest_add_no_device("device:sendevents", device_reenable_syspath_changed);
litest_add_no_device("device:sendevents", device_reenable_device_removed);