+static uint32_t
+evdev_sendevents_get_modes(struct libinput_device *device)
+{
+ return LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
+}
+
+static enum libinput_config_status
+evdev_sendevents_set_mode(struct libinput_device *device,
+ enum libinput_config_send_events_mode mode)
+{
+ struct evdev_device *evdev = (struct evdev_device*)device;
+ struct evdev_dispatch *dispatch = evdev->dispatch;
+
+ if (mode == dispatch->sendevents.current_mode)
+ return LIBINPUT_CONFIG_STATUS_SUCCESS;
+
+ switch(mode) {
+ case LIBINPUT_CONFIG_SEND_EVENTS_ENABLED:
+ evdev_device_resume(evdev);
+ break;
+ case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED:
+ evdev_device_suspend(evdev);
+ break;
+ default: /* no support for combined modes yet */
+ return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
+ }
+
+ dispatch->sendevents.current_mode = mode;
+
+ return LIBINPUT_CONFIG_STATUS_SUCCESS;
+}
+
+static enum libinput_config_send_events_mode
+evdev_sendevents_get_mode(struct libinput_device *device)
+{
+ struct evdev_device *evdev = (struct evdev_device*)device;
+ struct evdev_dispatch *dispatch = evdev->dispatch;
+
+ return dispatch->sendevents.current_mode;
+}
+
+static enum libinput_config_send_events_mode
+evdev_sendevents_get_default_mode(struct libinput_device *device)
+{
+ return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
+}
+
+static int
+evdev_left_handed_has(struct libinput_device *device)
+{
+ /* This is only hooked up when we have left-handed configuration, so we
+ * can hardcode 1 here */
+ return 1;
+}
+
+static void
+evdev_change_to_left_handed(struct evdev_device *device)
+{
+ if (device->buttons.want_left_handed == device->buttons.left_handed)
+ return;
+
+ if (evdev_any_button_down(device))
+ return;
+
+ device->buttons.left_handed = device->buttons.want_left_handed;
+}
+
+static enum libinput_config_status
+evdev_left_handed_set(struct libinput_device *device, int left_handed)
+{
+ struct evdev_device *evdev_device = (struct evdev_device *)device;
+
+ evdev_device->buttons.want_left_handed = left_handed ? true : false;
+
+ evdev_device->buttons.change_to_left_handed(evdev_device);
+
+ return LIBINPUT_CONFIG_STATUS_SUCCESS;
+}
+
+static int
+evdev_left_handed_get(struct libinput_device *device)
+{
+ struct evdev_device *evdev_device = (struct evdev_device *)device;
+
+ /* return the wanted configuration, even if it hasn't taken
+ * effect yet! */
+ return evdev_device->buttons.want_left_handed;
+}
+
+static int
+evdev_left_handed_get_default(struct libinput_device *device)
+{
+ return 0;
+}
+
+int
+evdev_init_left_handed(struct evdev_device *device,
+ void (*change_to_left_handed)(struct evdev_device *))
+{
+ device->buttons.config_left_handed.has = evdev_left_handed_has;
+ device->buttons.config_left_handed.set = evdev_left_handed_set;
+ device->buttons.config_left_handed.get = evdev_left_handed_get;
+ device->buttons.config_left_handed.get_default = evdev_left_handed_get_default;
+ device->base.config.left_handed = &device->buttons.config_left_handed;
+ device->buttons.left_handed = false;
+ device->buttons.want_left_handed = false;
+ device->buttons.change_to_left_handed = change_to_left_handed;
+
+ return 0;
+}
+
+static uint32_t
+evdev_scroll_get_methods(struct libinput_device *device)
+{
+ return LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
+}
+
+static void
+evdev_change_scroll_method(struct evdev_device *device)
+{
+ if (device->scroll.want_method == device->scroll.method &&
+ device->scroll.want_button == device->scroll.button)
+ return;
+
+ if (evdev_any_button_down(device))
+ return;
+
+ device->scroll.method = device->scroll.want_method;
+ device->scroll.button = device->scroll.want_button;
+}
+
+static enum libinput_config_status
+evdev_scroll_set_method(struct libinput_device *device,
+ enum libinput_config_scroll_method method)
+{
+ struct evdev_device *evdev = (struct evdev_device*)device;
+
+ evdev->scroll.want_method = method;
+ evdev->scroll.change_scroll_method(evdev);
+
+ return LIBINPUT_CONFIG_STATUS_SUCCESS;
+}
+
+static enum libinput_config_scroll_method
+evdev_scroll_get_method(struct libinput_device *device)
+{
+ struct evdev_device *evdev = (struct evdev_device *)device;
+
+ /* return the wanted configuration, even if it hasn't taken
+ * effect yet! */
+ return evdev->scroll.want_method;
+}
+
+static enum libinput_config_scroll_method
+evdev_scroll_get_default_method(struct libinput_device *device)
+{
+ struct evdev_device *evdev = (struct evdev_device *)device;
+
+ if (libevdev_has_property(evdev->evdev, INPUT_PROP_POINTING_STICK))
+ return LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
+ else
+ return LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
+}
+
+static enum libinput_config_status
+evdev_scroll_set_button(struct libinput_device *device,
+ uint32_t button)
+{
+ struct evdev_device *evdev = (struct evdev_device*)device;
+
+ evdev->scroll.want_button = button;
+ evdev->scroll.change_scroll_method(evdev);
+
+ return LIBINPUT_CONFIG_STATUS_SUCCESS;
+}
+
+static uint32_t
+evdev_scroll_get_button(struct libinput_device *device)
+{
+ struct evdev_device *evdev = (struct evdev_device *)device;
+
+ /* return the wanted configuration, even if it hasn't taken
+ * effect yet! */
+ return evdev->scroll.want_button;
+}
+
+static uint32_t
+evdev_scroll_get_default_button(struct libinput_device *device)
+{
+ struct evdev_device *evdev = (struct evdev_device *)device;
+
+ if (libevdev_has_property(evdev->evdev, INPUT_PROP_POINTING_STICK))
+ return BTN_MIDDLE;
+ else
+ return 0;
+}
+
+static int
+evdev_init_button_scroll(struct evdev_device *device,
+ void (*change_scroll_method)(struct evdev_device *))
+{
+ libinput_timer_init(&device->scroll.timer, device->base.seat->libinput,
+ evdev_button_scroll_timeout, device);
+ device->scroll.config.get_methods = evdev_scroll_get_methods;
+ device->scroll.config.set_method = evdev_scroll_set_method;
+ device->scroll.config.get_method = evdev_scroll_get_method;
+ device->scroll.config.get_default_method = evdev_scroll_get_default_method;
+ device->scroll.config.set_button = evdev_scroll_set_button;
+ device->scroll.config.get_button = evdev_scroll_get_button;
+ device->scroll.config.get_default_button = evdev_scroll_get_default_button;
+ device->base.config.scroll_method = &device->scroll.config;
+ device->scroll.method = evdev_scroll_get_default_method((struct libinput_device *)device);
+ device->scroll.want_method = device->scroll.method;
+ device->scroll.button = evdev_scroll_get_default_button((struct libinput_device *)device);
+ device->scroll.want_button = device->scroll.button;
+ device->scroll.change_scroll_method = change_scroll_method;
+
+ return 0;
+}
+
+static void
+evdev_init_calibration(struct evdev_device *device,
+ struct evdev_dispatch *dispatch)
+{
+ device->base.config.calibration = &dispatch->calibration;
+
+ dispatch->calibration.has_matrix = evdev_calibration_has_matrix;
+ dispatch->calibration.set_matrix = evdev_calibration_set_matrix;
+ dispatch->calibration.get_matrix = evdev_calibration_get_matrix;
+ dispatch->calibration.get_default_matrix = evdev_calibration_get_default_matrix;
+}
+
+static void
+evdev_init_sendevents(struct evdev_device *device,
+ struct evdev_dispatch *dispatch)
+{
+ device->base.config.sendevents = &dispatch->sendevents.config;
+
+ dispatch->sendevents.current_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
+ dispatch->sendevents.config.get_modes = evdev_sendevents_get_modes;
+ dispatch->sendevents.config.set_mode = evdev_sendevents_set_mode;
+ dispatch->sendevents.config.get_mode = evdev_sendevents_get_mode;
+ dispatch->sendevents.config.get_default_mode = evdev_sendevents_get_default_mode;
+}
+
+static int
+evdev_scroll_config_natural_has(struct libinput_device *device)
+{
+ return 1;
+}
+
+static enum libinput_config_status
+evdev_scroll_config_natural_set(struct libinput_device *device,
+ int enabled)
+{
+ struct evdev_device *dev = (struct evdev_device *)device;
+
+ dev->scroll.natural_scrolling_enabled = enabled ? true : false;
+
+ return LIBINPUT_CONFIG_STATUS_SUCCESS;
+}
+
+static int
+evdev_scroll_config_natural_get(struct libinput_device *device)
+{
+ struct evdev_device *dev = (struct evdev_device *)device;
+
+ return dev->scroll.natural_scrolling_enabled ? 1 : 0;
+}
+
+static int
+evdev_scroll_config_natural_get_default(struct libinput_device *device)
+{
+ /* could enable this on Apple touchpads. could do that, could
+ * very well do that... */
+ return 0;
+}
+
+void
+evdev_init_natural_scroll(struct evdev_device *device)
+{
+ device->scroll.config_natural.has = evdev_scroll_config_natural_has;
+ device->scroll.config_natural.set_enabled = evdev_scroll_config_natural_set;
+ device->scroll.config_natural.get_enabled = evdev_scroll_config_natural_get;
+ device->scroll.config_natural.get_default_enabled = evdev_scroll_config_natural_get_default;
+ device->scroll.natural_scrolling_enabled = false;
+ device->base.config.natural_scroll = &device->scroll.config_natural;
+}
+