From f3084e2c0dbc89238112ef0ed4ffd4ebb059ece6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 2 Jun 2014 23:09:27 +0200 Subject: [PATCH] Use floating point numbers instead of fixed point numbers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed point numbers can easily overflow, and double to fixed point conversion is lossy. Use floating point (double) where fixed point numbers where previously used and remove the li_fixed_t type. Signed-off-by: Jonas Ã…dahl Reviewed-by: Peter Hutterer --- src/evdev-mt-touchpad.c | 11 +++---- src/evdev.c | 47 +++++++++++++--------------- src/evdev.h | 10 +++--- src/libinput-private.h | 18 +++++------ src/libinput-util.h | 23 -------------- src/libinput.c | 50 +++++++++++++++--------------- src/libinput.h | 68 +++++++---------------------------------- test/pointer.c | 7 ++--- test/touch.c | 6 ++-- tools/event-debug.c | 28 +++++++---------- 10 files changed, 92 insertions(+), 176 deletions(-) diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index a5e7d186..6e651b11 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -485,7 +485,7 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time) pointer_notify_axis(&tp->device->base, time, LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL, - li_fixed_from_double(dy)); + dy); } if (dx != 0.0 && @@ -493,7 +493,7 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time) pointer_notify_axis(&tp->device->base, time, LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL, - li_fixed_from_double(dx)); + dx); } } @@ -573,11 +573,8 @@ tp_post_events(struct tp_dispatch *tp, uint64_t time) tp_get_delta(t, &dx, &dy); tp_filter_motion(tp, &dx, &dy, time); - if (dx != 0 || dy != 0) - pointer_notify_motion(&tp->device->base, - time, - li_fixed_from_double(dx), - li_fixed_from_double(dy)); + if (dx != 0.0 || dy != 0.0) + pointer_notify_motion(&tp->device->base, time, dx, dy); } } diff --git a/src/evdev.c b/src/evdev.c index d2f48b82..e4dc3b08 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -39,7 +39,7 @@ #include "filter.h" #include "libinput-private.h" -#define DEFAULT_AXIS_STEP_DISTANCE li_fixed_from_int(10) +#define DEFAULT_AXIS_STEP_DISTANCE 10 void evdev_device_led_update(struct evdev_device *device, enum libinput_led leds) @@ -89,21 +89,21 @@ transform_absolute(struct evdev_device *device, int32_t *x, int32_t *y) } } -li_fixed_t +double evdev_device_transform_x(struct evdev_device *device, - li_fixed_t x, + double x, uint32_t width) { - return ((uint64_t)x - li_fixed_from_int(device->abs.min_x)) * width / + return (x - device->abs.min_x) * width / (device->abs.max_x - device->abs.min_x + 1); } -li_fixed_t +double evdev_device_transform_y(struct evdev_device *device, - li_fixed_t y, + double y, uint32_t height) { - return ((uint64_t)y - li_fixed_from_int(device->abs.min_y)) * height / + return (y - device->abs.min_y) * height / (device->abs.max_y - device->abs.min_y + 1); } @@ -112,8 +112,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time) { struct motion_params motion; int32_t cx, cy; - li_fixed_t x, y; - li_fixed_t dx, dy; + double x, y; int slot; int seat_slot; struct libinput_device *base = &device->base; @@ -125,20 +124,18 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time) case EVDEV_NONE: return; case EVDEV_RELATIVE_MOTION: - motion.dx = li_fixed_to_double(device->rel.dx); - motion.dy = li_fixed_to_double(device->rel.dy); + motion.dx = device->rel.dx; + motion.dy = device->rel.dy; device->rel.dx = 0; device->rel.dy = 0; /* Apply pointer acceleration. */ filter_dispatch(device->pointer.filter, &motion, device, time); - dx = li_fixed_from_double(motion.dx); - dy = li_fixed_from_double(motion.dy); - if (dx == 0 && dy == 0) + if (motion.dx == 0.0 && motion.dy == 0.0) break; - pointer_notify_motion(base, time, dx, dy); + pointer_notify_motion(base, time, motion.dx, motion.dy); break; case EVDEV_ABSOLUTE_MT_DOWN: if (!(device->seat_caps & EVDEV_DEVICE_TOUCH)) @@ -157,8 +154,8 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time) break; seat->slot_map |= 1 << seat_slot; - x = li_fixed_from_int(device->mt.slots[slot].x); - y = li_fixed_from_int(device->mt.slots[slot].y); + x = device->mt.slots[slot].x; + y = device->mt.slots[slot].y; touch_notify_touch_down(base, time, slot, seat_slot, x, y); break; @@ -167,8 +164,8 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time) break; seat_slot = device->mt.slots[slot].seat_slot; - x = li_fixed_from_int(device->mt.slots[slot].x); - y = li_fixed_from_int(device->mt.slots[slot].y); + x = device->mt.slots[slot].x; + y = device->mt.slots[slot].y; if (seat_slot == -1) break; @@ -208,15 +205,13 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time) seat->slot_map |= 1 << seat_slot; transform_absolute(device, &cx, &cy); - x = li_fixed_from_int(cx); - y = li_fixed_from_int(cy); - touch_notify_touch_down(base, time, -1, seat_slot, x, y); + touch_notify_touch_down(base, time, -1, seat_slot, cx, cy); break; case EVDEV_ABSOLUTE_MOTION: transform_absolute(device, &cx, &cy); - x = li_fixed_from_int(cx); - y = li_fixed_from_int(cy); + x = cx; + y = cy; if (device->seat_caps & EVDEV_DEVICE_TOUCH) { seat_slot = device->abs.seat_slot; @@ -374,13 +369,13 @@ evdev_process_relative(struct evdev_device *device, case REL_X: if (device->pending_event != EVDEV_RELATIVE_MOTION) evdev_flush_pending_event(device, time); - device->rel.dx += li_fixed_from_int(e->value); + device->rel.dx += e->value; device->pending_event = EVDEV_RELATIVE_MOTION; break; case REL_Y: if (device->pending_event != EVDEV_RELATIVE_MOTION) evdev_flush_pending_event(device, time); - device->rel.dy += li_fixed_from_int(e->value); + device->rel.dy += e->value; device->pending_event = EVDEV_RELATIVE_MOTION; break; case REL_WHEEL: diff --git a/src/evdev.h b/src/evdev.h index 63b42601..d057010b 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -83,7 +83,7 @@ struct evdev_device { struct mtdev *mtdev; struct { - li_fixed_t dx, dy; + int dx, dy; } rel; enum evdev_event_type pending_event; @@ -148,14 +148,14 @@ int evdev_device_has_capability(struct evdev_device *device, enum libinput_device_capability capability); -li_fixed_t +double evdev_device_transform_x(struct evdev_device *device, - li_fixed_t x, + double x, uint32_t width); -li_fixed_t +double evdev_device_transform_y(struct evdev_device *device, - li_fixed_t y, + double y, uint32_t height); void diff --git a/src/libinput-private.h b/src/libinput-private.h index 0e92e688..b9645080 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -140,14 +140,14 @@ keyboard_notify_key(struct libinput_device *device, void pointer_notify_motion(struct libinput_device *device, uint32_t time, - li_fixed_t dx, - li_fixed_t dy); + double dx, + double dy); void pointer_notify_motion_absolute(struct libinput_device *device, uint32_t time, - li_fixed_t x, - li_fixed_t y); + double x, + double y); void pointer_notify_button(struct libinput_device *device, @@ -159,23 +159,23 @@ void pointer_notify_axis(struct libinput_device *device, uint32_t time, enum libinput_pointer_axis axis, - li_fixed_t value); + double value); void touch_notify_touch_down(struct libinput_device *device, uint32_t time, int32_t slot, int32_t seat_slot, - li_fixed_t x, - li_fixed_t y); + double x, + double y); void touch_notify_touch_motion(struct libinput_device *device, uint32_t time, int32_t slot, int32_t seat_slot, - li_fixed_t x, - li_fixed_t y); + double x, + double y); void touch_notify_touch_up(struct libinput_device *device, diff --git a/src/libinput-util.h b/src/libinput-util.h index c9205686..11c4f5c2 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -76,29 +76,6 @@ int list_empty(const struct list *list); #define min(a, b) (((a) < (b)) ? (a) : (b)) #define max(a, b) (((a) > (b)) ? (a) : (b)) -/* - * This fixed point implementation is a verbatim copy from wayland-util.h from - * the Wayland project, with the wl_ prefix renamed li_. - */ - -static inline li_fixed_t li_fixed_from_int(int i) -{ - return i * 256; -} - -static inline li_fixed_t -li_fixed_from_double(double d) -{ - union { - double d; - int64_t i; - } u; - - u.d = d + (3LL << (51 - 8)); - - return u.i; -} - #define LIBINPUT_EXPORT __attribute__ ((visibility("default"))) static inline void * diff --git a/src/libinput.c b/src/libinput.c index 6b7e8b88..048200cd 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -61,13 +61,13 @@ struct libinput_event_keyboard { struct libinput_event_pointer { struct libinput_event base; uint32_t time; - li_fixed_t x; - li_fixed_t y; + double x; + double y; uint32_t button; uint32_t seat_button_count; enum libinput_pointer_button_state state; enum libinput_pointer_axis axis; - li_fixed_t value; + double value; }; struct libinput_event_touch { @@ -75,8 +75,8 @@ struct libinput_event_touch { uint32_t time; int32_t slot; int32_t seat_slot; - li_fixed_t x; - li_fixed_t y; + double x; + double y; }; static void @@ -296,31 +296,31 @@ libinput_event_pointer_get_time(struct libinput_event_pointer *event) return event->time; } -LIBINPUT_EXPORT li_fixed_t +LIBINPUT_EXPORT double libinput_event_pointer_get_dx(struct libinput_event_pointer *event) { return event->x; } -LIBINPUT_EXPORT li_fixed_t +LIBINPUT_EXPORT double libinput_event_pointer_get_dy(struct libinput_event_pointer *event) { return event->y; } -LIBINPUT_EXPORT li_fixed_t +LIBINPUT_EXPORT double libinput_event_pointer_get_absolute_x(struct libinput_event_pointer *event) { return event->x; } -LIBINPUT_EXPORT li_fixed_t +LIBINPUT_EXPORT double libinput_event_pointer_get_absolute_y(struct libinput_event_pointer *event) { return event->y; } -LIBINPUT_EXPORT li_fixed_t +LIBINPUT_EXPORT double libinput_event_pointer_get_absolute_x_transformed( struct libinput_event_pointer *event, uint32_t width) @@ -331,7 +331,7 @@ libinput_event_pointer_get_absolute_x_transformed( return evdev_device_transform_x(device, event->x, width); } -LIBINPUT_EXPORT li_fixed_t +LIBINPUT_EXPORT double libinput_event_pointer_get_absolute_y_transformed( struct libinput_event_pointer *event, uint32_t height) @@ -367,7 +367,7 @@ libinput_event_pointer_get_axis(struct libinput_event_pointer *event) return event->axis; } -LIBINPUT_EXPORT li_fixed_t +LIBINPUT_EXPORT double libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event) { return event->value; @@ -391,13 +391,13 @@ libinput_event_touch_get_seat_slot(struct libinput_event_touch *event) return event->seat_slot; } -LIBINPUT_EXPORT li_fixed_t +LIBINPUT_EXPORT double libinput_event_touch_get_x(struct libinput_event_touch *event) { return event->x; } -LIBINPUT_EXPORT li_fixed_t +LIBINPUT_EXPORT double libinput_event_touch_get_x_transformed(struct libinput_event_touch *event, uint32_t width) { @@ -407,7 +407,7 @@ libinput_event_touch_get_x_transformed(struct libinput_event_touch *event, return evdev_device_transform_x(device, event->x, width); } -LIBINPUT_EXPORT li_fixed_t +LIBINPUT_EXPORT double libinput_event_touch_get_y_transformed(struct libinput_event_touch *event, uint32_t height) { @@ -417,7 +417,7 @@ libinput_event_touch_get_y_transformed(struct libinput_event_touch *event, return evdev_device_transform_y(device, event->y, height); } -LIBINPUT_EXPORT li_fixed_t +LIBINPUT_EXPORT double libinput_event_touch_get_y(struct libinput_event_touch *event) { return event->y; @@ -816,8 +816,8 @@ keyboard_notify_key(struct libinput_device *device, void pointer_notify_motion(struct libinput_device *device, uint32_t time, - li_fixed_t dx, - li_fixed_t dy) + double dx, + double dy) { struct libinput_event_pointer *motion_event; @@ -839,8 +839,8 @@ pointer_notify_motion(struct libinput_device *device, void pointer_notify_motion_absolute(struct libinput_device *device, uint32_t time, - li_fixed_t x, - li_fixed_t y) + double x, + double y) { struct libinput_event_pointer *motion_absolute_event; @@ -892,7 +892,7 @@ void pointer_notify_axis(struct libinput_device *device, uint32_t time, enum libinput_pointer_axis axis, - li_fixed_t value) + double value) { struct libinput_event_pointer *axis_event; @@ -916,8 +916,8 @@ touch_notify_touch_down(struct libinput_device *device, uint32_t time, int32_t slot, int32_t seat_slot, - li_fixed_t x, - li_fixed_t y) + double x, + double y) { struct libinput_event_touch *touch_event; @@ -943,8 +943,8 @@ touch_notify_touch_motion(struct libinput_device *device, uint32_t time, int32_t slot, int32_t seat_slot, - li_fixed_t x, - li_fixed_t y) + double x, + double y) { struct libinput_event_touch *touch_event; diff --git a/src/libinput.h b/src/libinput.h index d771e21c..d88140f3 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -78,13 +78,6 @@ extern "C" { * middle button click. */ -/** - * @ingroup fixed_point - * - * libinput 24.8 fixed point real number. - */ -typedef int32_t li_fixed_t; - /** * Log priority for internal logging messages. */ @@ -219,45 +212,6 @@ struct libinput_event_pointer; */ struct libinput_event_touch; -/** - * @defgroup fixed_point Fixed point utilities - */ - -/** - * @ingroup fixed_point - * - * Convert li_fixed_t to a double - * - * @param f fixed point number - * @return Converted double - */ -static inline double -li_fixed_to_double (li_fixed_t f) -{ - union { - double d; - int64_t i; - } u; - - u.i = ((1023LL + 44LL) << 52) + (1LL << 51) + f; - - return u.d - (3LL << 43); -} - -/** - * @ingroup fixed_point - * - * Convert li_fixed_t to a int. The fraction part is discarded. - * - * @param f fixed point number - * @return Converted int - */ -static inline int -li_fixed_to_int(li_fixed_t f) -{ - return f / 256; -} - /** * @defgroup event Acessing and destruction of events */ @@ -453,7 +407,7 @@ libinput_event_pointer_get_time(struct libinput_event_pointer *event); * * @return the relative x movement since the last event */ -li_fixed_t +double libinput_event_pointer_get_dx(struct libinput_event_pointer *event); /** @@ -468,7 +422,7 @@ libinput_event_pointer_get_dx(struct libinput_event_pointer *event); * * @return the relative y movement since the last event */ -li_fixed_t +double libinput_event_pointer_get_dy(struct libinput_event_pointer *event); /** @@ -488,7 +442,7 @@ libinput_event_pointer_get_dy(struct libinput_event_pointer *event); * * @return the current absolute x coordinate */ -li_fixed_t +double libinput_event_pointer_get_absolute_x(struct libinput_event_pointer *event); /** @@ -508,7 +462,7 @@ libinput_event_pointer_get_absolute_x(struct libinput_event_pointer *event); * * @return the current absolute y coordinate */ -li_fixed_t +double libinput_event_pointer_get_absolute_y(struct libinput_event_pointer *event); /** @@ -528,7 +482,7 @@ libinput_event_pointer_get_absolute_y(struct libinput_event_pointer *event); * @param width The current output screen width * @return the current absolute x coordinate transformed to a screen coordinate */ -li_fixed_t +double libinput_event_pointer_get_absolute_x_transformed( struct libinput_event_pointer *event, uint32_t width); @@ -550,7 +504,7 @@ libinput_event_pointer_get_absolute_x_transformed( * @param height The current output screen height * @return the current absolute y coordinate transformed to a screen coordinate */ -li_fixed_t +double libinput_event_pointer_get_absolute_y_transformed( struct libinput_event_pointer *event, uint32_t height); @@ -636,7 +590,7 @@ libinput_event_pointer_get_axis(struct libinput_event_pointer *event); * * @return the axis value of this event */ -li_fixed_t +double libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event); /** @@ -711,7 +665,7 @@ libinput_event_touch_get_seat_slot(struct libinput_event_touch *event); * @param event The libinput touch event * @return the current absolute x coordinate */ -li_fixed_t +double libinput_event_touch_get_x(struct libinput_event_touch *event); /** @@ -731,7 +685,7 @@ libinput_event_touch_get_x(struct libinput_event_touch *event); * @param event The libinput touch event * @return the current absolute y coordinate */ -li_fixed_t +double libinput_event_touch_get_y(struct libinput_event_touch *event); /** @@ -747,7 +701,7 @@ libinput_event_touch_get_y(struct libinput_event_touch *event); * @param width The current output screen width * @return the current absolute x coordinate transformed to a screen coordinate */ -li_fixed_t +double libinput_event_touch_get_x_transformed(struct libinput_event_touch *event, uint32_t width); @@ -764,7 +718,7 @@ libinput_event_touch_get_x_transformed(struct libinput_event_touch *event, * @param height The current output screen height * @return the current absolute y coordinate transformed to a screen coordinate */ -li_fixed_t +double libinput_event_touch_get_y_transformed(struct libinput_event_touch *event, uint32_t height); diff --git a/test/pointer.c b/test/pointer.c index f47e0949..3a2386cb 100644 --- a/test/pointer.c +++ b/test/pointer.c @@ -66,8 +66,8 @@ test_relative_event(struct litest_device *dev, int dx, int dy) expected_length = sqrt(dx*dx + dy*dy); expected_dir = atan2(dx, dy); - ev_dx = li_fixed_to_double(libinput_event_pointer_get_dx(ptrev)); - ev_dy = li_fixed_to_double(libinput_event_pointer_get_dy(ptrev)); + ev_dx = libinput_event_pointer_get_dx(ptrev); + ev_dy = libinput_event_pointer_get_dy(ptrev); actual_length = sqrt(ev_dx*ev_dx + ev_dy*ev_dy); actual_dir = atan2(ev_dx, ev_dy); @@ -183,8 +183,7 @@ test_wheel_event(struct litest_device *dev, int which, int amount) which == REL_WHEEL ? LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL : LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL); - ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev), - li_fixed_from_int(expected)); + ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev), expected); libinput_event_destroy(event); } diff --git a/test/touch.c b/test/touch.c index 41ecc18d..2a7c966a 100644 --- a/test/touch.c +++ b/test/touch.c @@ -68,7 +68,7 @@ START_TEST(touch_abs_transform) struct libinput *libinput; struct libinput_event *ev; struct libinput_event_touch *tev; - li_fixed_t fx, fy; + double fx, fy; bool tested = false; struct input_absinfo abs[] = { @@ -97,9 +97,9 @@ START_TEST(touch_abs_transform) tev = libinput_event_get_touch_event(ev); fx = libinput_event_touch_get_x_transformed(tev, 1920); - ck_assert_int_eq(li_fixed_to_int(fx), 1919); + ck_assert_int_eq(fx, 1919.0); fy = libinput_event_touch_get_y_transformed(tev, 720); - ck_assert_int_eq(li_fixed_to_int(fy), 719); + ck_assert_int_eq(fy, 719.0); tested = true; diff --git a/tools/event-debug.c b/tools/event-debug.c index 8dbca4b0..e41da05a 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -254,29 +254,25 @@ static void print_motion_event(struct libinput_event *ev) { struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev); - li_fixed_t x = libinput_event_pointer_get_dx(p), - y = libinput_event_pointer_get_dy(p); + double x = libinput_event_pointer_get_dx(p); + double y = libinput_event_pointer_get_dy(p); print_event_time(libinput_event_pointer_get_time(p)); - printf("%6.2f/%6.2f\n", - li_fixed_to_double(x), - li_fixed_to_double(y)); + printf("%6.2f/%6.2f\n", x, y); } 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_transformed( + double x = libinput_event_pointer_get_absolute_x_transformed( p, screen_width); - li_fixed_t y = libinput_event_pointer_get_absolute_y_transformed( + double 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", - li_fixed_to_double(x), - li_fixed_to_double(y)); + printf("%6.2f/%6.2f\n", x, y); } static void @@ -300,7 +296,7 @@ print_axis_event(struct libinput_event *ev) struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev); enum libinput_pointer_axis axis = libinput_event_pointer_get_axis(p); const char *ax; - li_fixed_t val; + double val; switch (axis) { case LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL: @@ -315,8 +311,7 @@ print_axis_event(struct libinput_event *ev) print_event_time(libinput_event_pointer_get_time(p)); val = libinput_event_pointer_get_axis_value(p); - printf("%s %.2f\n", - ax, li_fixed_to_double(val)); + printf("%s %.2f\n", ax, val); } static void @@ -332,16 +327,15 @@ static void print_touch_event_with_coords(struct libinput_event *ev) { struct libinput_event_touch *t = libinput_event_get_touch_event(ev); - li_fixed_t x = libinput_event_touch_get_x_transformed(t, screen_width), - y = libinput_event_touch_get_y_transformed(t, screen_height); + double x = libinput_event_touch_get_x_transformed(t, screen_width); + double y = libinput_event_touch_get_y_transformed(t, screen_height); print_event_time(libinput_event_touch_get_time(t)); printf("%d (%d) %5.2f/%5.2f\n", libinput_event_touch_get_slot(t), libinput_event_touch_get_seat_slot(t), - li_fixed_to_double(x), - li_fixed_to_double(y)); + x, y); } static int