diff --git a/src/evdev.c b/src/evdev.c index 46bd35ae..cb83a1f8 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -86,6 +86,24 @@ transform_absolute(struct evdev_device *device, int32_t *x, int32_t *y) } } +li_fixed_t +evdev_device_transform_x(struct evdev_device *device, + li_fixed_t x, + uint32_t width) +{ + return (x - device->abs.min_x) * width / + (device->abs.max_x - device->abs.min_x); +} + +li_fixed_t +evdev_device_transform_y(struct evdev_device *device, + li_fixed_t y, + uint32_t height) +{ + return (y - device->abs.min_y) * height / + (device->abs.max_y - device->abs.min_y); +} + static void evdev_flush_pending_event(struct evdev_device *device, uint32_t time) { @@ -242,16 +260,6 @@ evdev_process_touch(struct evdev_device *device, struct input_event *e, uint32_t time) { - struct libinput *libinput = device->base.seat->libinput; - int screen_width; - int screen_height; - - libinput->interface->get_current_screen_dimensions( - &device->base, - &screen_width, - &screen_height, - libinput->user_data); - switch (e->code) { case ABS_MT_SLOT: evdev_flush_pending_event(device, time); @@ -267,16 +275,12 @@ evdev_process_touch(struct evdev_device *device, device->pending_event = EVDEV_ABSOLUTE_MT_UP; break; case ABS_MT_POSITION_X: - device->mt.slots[device->mt.slot].x = - (e->value - device->abs.min_x) * screen_width / - (device->abs.max_x - device->abs.min_x); + device->mt.slots[device->mt.slot].x = e->value; if (device->pending_event == EVDEV_NONE) device->pending_event = EVDEV_ABSOLUTE_MT_MOTION; break; case ABS_MT_POSITION_Y: - device->mt.slots[device->mt.slot].y = - (e->value - device->abs.min_y) * screen_height / - (device->abs.max_y - device->abs.min_y); + device->mt.slots[device->mt.slot].y = e->value; if (device->pending_event == EVDEV_NONE) device->pending_event = EVDEV_ABSOLUTE_MT_MOTION; break; @@ -287,28 +291,14 @@ static inline void evdev_process_absolute_motion(struct evdev_device *device, struct input_event *e) { - struct libinput *libinput = device->base.seat->libinput; - int screen_width; - int screen_height; - - libinput->interface->get_current_screen_dimensions( - &device->base, - &screen_width, - &screen_height, - libinput->user_data); - switch (e->code) { case ABS_X: - device->abs.x = - (e->value - device->abs.min_x) * screen_width / - (device->abs.max_x - device->abs.min_x); + device->abs.x = e->value; if (device->pending_event == EVDEV_NONE) device->pending_event = EVDEV_ABSOLUTE_MOTION; break; case ABS_Y: - device->abs.y = - (e->value - device->abs.min_y) * screen_height / - (device->abs.max_y - device->abs.min_y); + device->abs.y = e->value; if (device->pending_event == EVDEV_NONE) device->pending_event = EVDEV_ABSOLUTE_MOTION; break; diff --git a/src/evdev.h b/src/evdev.h index 58ae5525..37c32e5b 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -146,6 +146,16 @@ int evdev_device_has_capability(struct evdev_device *device, enum libinput_device_capability capability); +li_fixed_t +evdev_device_transform_x(struct evdev_device *device, + li_fixed_t x, + uint32_t width); + +li_fixed_t +evdev_device_transform_y(struct evdev_device *device, + li_fixed_t y, + uint32_t height); + void evdev_device_remove(struct evdev_device *device); diff --git a/src/libinput.c b/src/libinput.c index a77f165a..cfce2c5f 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -245,6 +245,28 @@ libinput_event_pointer_get_absolute_y( return event->y; } +LIBINPUT_EXPORT li_fixed_t +libinput_event_pointer_get_absolute_x_transformed( + struct libinput_event_pointer *event, + uint32_t width) +{ + struct evdev_device *device = + (struct evdev_device *) event->base.device; + + return evdev_device_transform_x(device, event->x, width); +} + +LIBINPUT_EXPORT li_fixed_t +libinput_event_pointer_get_absolute_y_transformed( + struct libinput_event_pointer *event, + uint32_t height) +{ + struct evdev_device *device = + (struct evdev_device *) event->base.device; + + return evdev_device_transform_y(device, event->y, height); +} + LIBINPUT_EXPORT uint32_t libinput_event_pointer_get_button( struct libinput_event_pointer *event) @@ -294,6 +316,28 @@ libinput_event_touch_get_x( return event->x; } +LIBINPUT_EXPORT li_fixed_t +libinput_event_touch_get_x_transformed( + struct libinput_event_touch *event, + uint32_t width) +{ + struct evdev_device *device = + (struct evdev_device *) event->base.device; + + return evdev_device_transform_x(device, event->x, width); +} + +LIBINPUT_EXPORT li_fixed_t +libinput_event_touch_get_y_transformed( + struct libinput_event_touch *event, + uint32_t height) +{ + struct evdev_device *device = + (struct evdev_device *) event->base.device; + + return evdev_device_transform_y(device, event->y, height); +} + LIBINPUT_EXPORT li_fixed_t libinput_event_touch_get_y( struct libinput_event_touch *event) diff --git a/src/libinput.h b/src/libinput.h index ddaeb738..8d347b9e 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -395,16 +395,19 @@ libinput_event_pointer_get_dy( /** * @ingroup event_pointer * - * Return the absolute x coordinate of the device, scaled to screen - * coordinates. - * The axes' positive direction is device-specific. For pointer events that - * are not of type LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, this function - * returns 0. + * Return the current absolute x coordinate of the pointer event. + * + * The coordinate is in a device specific coordinate space; to get the + * corresponding output screen coordinate, use + * libinput_event_pointer_get_x_transformed(). + * + * For pointer events that are not of type + * LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, this function returns 0. * * @note It is an application bug to call this function for events other than * LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE. * - * @return the current absolute x coordinate scaled to screen coordinates. + * @return the current absolute x coordinate */ li_fixed_t libinput_event_pointer_get_absolute_x( @@ -413,20 +416,68 @@ libinput_event_pointer_get_absolute_x( /** * @ingroup event_pointer * - * Return the absolute y coordinate of the device, scaled to screen coordinates. - * The axes' positive direction is device-specific. For pointer events that - * are not of type LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, this function - * returns 0. + * Return the current absolute y coordinate of the pointer event. + * + * The coordinate is in a device specific coordinate space; to get the + * corresponding output screen coordinate, use + * libinput_event_pointer_get_y_transformed(). + * + * For pointer events that are not of type + * LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, this function returns 0. * * @note It is an application bug to call this function for events other than * LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE. * - * @return the current absolute y coordinate scaled to screen coordinates. + * @return the current absolute y coordinate */ li_fixed_t libinput_event_pointer_get_absolute_y( struct libinput_event_pointer *event); +/** + * @ingroup event_pointer + * + * Return the current absolute x coordinate of the pointer event, transformed to + * screen coordinates. + * + * For pointer events that are not of type + * LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, the return value of this function is + * undefined. + * + * @note It is an application bug to call this function for events other than + * LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE. + * + * @param event The libinput pointer event + * @param width The current output screen width + * @return the current absolute x coordinate transformed to a screen coordinate + */ +li_fixed_t +libinput_event_pointer_get_absolute_x_transformed( + struct libinput_event_pointer *event, + uint32_t width); + +/** + * @ingroup event_pointer + * + * Return the current absolute y coordinate of the pointer event, transformed to + * screen coordinates. + * + * For pointer events that are not of type + * LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, the return value of this function is + * undefined. + * + * @note It is an application bug to call this function for events other than + * LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE. + * + * @param event The libinput pointer event + * @param height The current output screen height + * @return the current absolute y coordinate transformed to a screen coordinate + */ +li_fixed_t +libinput_event_pointer_get_absolute_y_transformed( + struct libinput_event_pointer *event, + uint32_t height); + /** * @ingroup event_pointer * @@ -531,9 +582,16 @@ libinput_event_touch_get_slot( /** * @ingroup event_touch * + * Return the current absolute x coordinate of the touch event. + * + * The coordinate is in a device specific coordinate space; to get the + * corresponding output screen coordinate, use + * libinput_event_touch_get_x_transformed(). + * * @note this function should not be called for LIBINPUT_EVENT_TOUCH_FRAME. * - * @return the absolute X coordinate on this touch device, scaled to screen coordinates. + * @param event The libinput touch event + * @return the current absolute x coordinate */ li_fixed_t libinput_event_touch_get_x( @@ -542,14 +600,53 @@ libinput_event_touch_get_x( /** * @ingroup event_touch * + * Return the current absolute y coordinate of the touch event. + * + * The coordinate is in a device specific coordinate space; to get the + * corresponding output screen coordinate, use + * libinput_event_touch_get_y_transformed(). + * * @note this function should not be called for LIBINPUT_EVENT_TOUCH_FRAME. * - * @return the absolute X coordinate on this touch device, scaled to screen coordinates. + * @param event The libinput touch event + * @return the current absolute y coordinate */ li_fixed_t libinput_event_touch_get_y( struct libinput_event_touch *event); +/** + * @ingroup event_touch + * + * Return the current absolute x coordinate of the touch event, transformed to + * screen coordinates. + * + * @note this function should not be called for LIBINPUT_EVENT_TOUCH_FRAME. + * + * @param event The libinput touch event + * @param width The current output screen width + * @return the current absolute x coordinate transformed to a screen coordinate + */ +li_fixed_t +libinput_event_touch_get_x_transformed(struct libinput_event_touch *event, + uint32_t width); + +/** + * @ingroup event_touch + * + * Return the current absolute y coordinate of the touch event, transformed to + * screen coordinates. + * + * @note this function should not be called for LIBINPUT_EVENT_TOUCH_FRAME. + * + * @param event The libinput touch event + * @param height The current output screen height + * @return the current absolute y coordinate transformed to a screen coordinate + */ +li_fixed_t +libinput_event_touch_get_y_transformed(struct libinput_event_touch *event, + uint32_t height); + /** * @ingroup event_touch * @@ -586,11 +683,6 @@ struct libinput_interface { * libinput_create_from_udev() */ void (*close_restricted)(int fd, void *user_data); - - void (*get_current_screen_dimensions)(struct libinput_device *device, - int *width, - int *height, - void *user_data); }; /** diff --git a/test/litest.c b/test/litest.c index 5235e3c2..216e1a0b 100644 --- a/test/litest.c +++ b/test/litest.c @@ -318,20 +318,9 @@ close_restricted(int fd, void *userdata) close(fd); } -static void -get_current_screen_dimensions(struct libinput_device *device, - int *width, - int *height, - void *user_data) -{ - *width = 1024; - *height = 768; -} - const struct libinput_interface interface = { .open_restricted = open_restricted, .close_restricted = close_restricted, - .get_current_screen_dimensions = get_current_screen_dimensions, }; struct litest_device * diff --git a/tools/event-debug.c b/tools/event-debug.c index 10246678..bbb358bb 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -44,6 +44,8 @@ static const char *device; static const char *seat = "seat0"; static struct udev *udev; uint32_t start_time; +static const uint32_t screen_width = 100; +static const uint32_t screen_height = 100; static void usage(void) @@ -123,20 +125,9 @@ close_restricted(int fd, void *user_data) close(fd); } -static void get_current_screen_dimensions(struct libinput_device *device, - int *width, - int *height, - void *user_data) -{ - /* display absdata in % of the screen */ - *width = 100; - *height = 100; -} - const static struct libinput_interface interface = { .open_restricted = open_restricted, .close_restricted = close_restricted, - .get_current_screen_dimensions = get_current_screen_dimensions, }; static int @@ -257,8 +248,10 @@ static void print_absmotion_event(struct libinput_event *ev) { struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev); - li_fixed_t x = libinput_event_pointer_get_absolute_x(p), - y = libinput_event_pointer_get_absolute_y(p); + li_fixed_t x = libinput_event_pointer_get_absolute_x_transformed( + p, screen_width); + li_fixed_t y = libinput_event_pointer_get_absolute_y_transformed( + p, screen_height); print_event_time(libinput_event_pointer_get_time(p)); printf("%6.2f/%6.2f\n", @@ -318,8 +311,8 @@ static void print_touch_event(struct libinput_event *ev) { struct libinput_event_touch *t = libinput_event_get_touch_event(ev); - li_fixed_t x = libinput_event_touch_get_x(t), - y = libinput_event_touch_get_y(t); + li_fixed_t x = libinput_event_touch_get_x_transformed(t, screen_width), + y = libinput_event_touch_get_y_transformed(t, screen_height); const char *type; switch (libinput_event_touch_get_touch_type(t)) {