down_count = update_key_down_count(device, button, state);
if ((state == LIBINPUT_BUTTON_STATE_PRESSED && down_count == 1) ||
- (state == LIBINPUT_BUTTON_STATE_RELEASED && down_count == 0))
+ (state == LIBINPUT_BUTTON_STATE_RELEASED && down_count == 0)) {
pointer_notify_button(&device->base, time, button, state);
+
+ if (state == LIBINPUT_BUTTON_STATE_RELEASED &&
+ device->buttons.change_to_left_handed)
+ device->buttons.change_to_left_handed(device);
+ }
+
}
void
evdev_pointer_notify_button(
device,
time,
- e->code,
+ evdev_to_left_handed(device, e->code),
e->value ? LIBINPUT_BUTTON_STATE_PRESSED :
LIBINPUT_BUTTON_STATE_RELEASED);
break;
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)
+{
+ unsigned int button;
+
+ if (device->buttons.want_left_handed == device->buttons.left_handed)
+ return;
+
+ for (button = BTN_LEFT; button < BTN_JOYSTICK; button++) {
+ if (libevdev_has_event_code(device->evdev, EV_KEY, button) &&
+ hw_is_key_down(device, button))
+ 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 struct evdev_dispatch *
fallback_dispatch_create(struct libinput_device *device)
{
struct evdev_dispatch *dispatch = zalloc(sizeof *dispatch);
+ struct evdev_device *evdev_device = (struct evdev_device *)device;
+
if (dispatch == NULL)
return NULL;
dispatch->interface = &fallback_interface;
+ if (evdev_device->buttons.want_left_handed &&
+ evdev_init_left_handed(evdev_device,
+ evdev_change_to_left_handed) == -1) {
+ free(dispatch);
+ return NULL;
+ }
+
device->config.calibration = &dispatch->calibration;
dispatch->calibration.has_matrix = evdev_calibration_has_matrix;
has_abs ? " absolute-motion" : "",
has_rel ? " relative-motion": "",
has_button ? " button" : "");
+
+ /* want left-handed config option */
+ device->buttons.want_left_handed = true;
}
if (has_keyboard) {
device->seat_caps |= EVDEV_DEVICE_KEYBOARD;
evdev_pointer_notify_button(
device,
time,
- code,
+ evdev_to_left_handed(device, code),
LIBINPUT_BUTTON_STATE_RELEASED);
break;
}
/* Key counter used for multiplexing button events internally in
* libinput. */
uint8_t key_count[KEY_CNT];
+
+ struct {
+ struct libinput_device_config_left_handed config_left_handed;
+ /* left-handed currently enabled */
+ bool left_handed;
+ /* set during device init if we want left_handed config,
+ * used at runtime to delay the effect until buttons are up */
+ bool want_left_handed;
+ /* Checks if buttons are down and commits the setting */
+ void (*change_to_left_handed)(struct evdev_device *device);
+ } buttons;
};
#define EVDEV_UNHANDLED_DEVICE ((struct evdev_device *) 1)
return value/absinfo->resolution;
}
+int
+evdev_init_left_handed(struct evdev_device *device,
+ void (*change_to_left_handed)(struct evdev_device *));
+
+static inline uint32_t
+evdev_to_left_handed(struct evdev_device *device,
+ uint32_t button)
+{
+ if (device->buttons.left_handed) {
+ if (button == BTN_LEFT)
+ return BTN_RIGHT;
+ else if (button == BTN_RIGHT)
+ return BTN_LEFT;
+ }
+ return button;
+}
+
#endif /* EVDEV_H */