Use floating point numbers instead of fixed point numbers

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 <jadahl@gmail.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Jonas Ådahl 2014-06-02 23:09:27 +02:00
parent 14a1d189ff
commit f3084e2c0d
10 changed files with 92 additions and 176 deletions

View file

@ -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);
}
}

View file

@ -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:

View file

@ -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

View file

@ -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,

View file

@ -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 *

View file

@ -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;

View file

@ -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);

View file

@ -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);
}

View file

@ -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;

View file

@ -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