From: Kristian Høgsberg Date: Thu, 22 Dec 2011 03:18:36 +0000 (-0500) Subject: evdev: Store positions for all touch points in the evdev device X-Git-Tag: upstream/0.1.8~3098 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3937354eef0a86a67fe3649254a0fcd094a4ab13;p=profile%2Fivi%2Fweston-ivi-shell.git evdev: Store positions for all touch points in the evdev device We need to store all touchpoint positions so that if we just get an ABS_MT_POSITION_X or Y event, we can pull the other coordinate from the cache. And we need this across invocations of evdev_input_device_data(), so the accumulator approach doesn't work. Instead, we go back to the approach of storing all this state in the evdev device struct and we might as well just move the rel and abs state there too. --- diff --git a/compositor/evdev.c b/compositor/evdev.c index 11f7f5e..c065b33 100644 --- a/compositor/evdev.c +++ b/compositor/evdev.c @@ -37,6 +37,8 @@ struct evdev_input { char *seat_id; }; +#define MAX_SLOTS 10 + struct evdev_input_device { struct evdev_input *master; struct wl_list link; @@ -47,8 +49,21 @@ struct evdev_input_device { struct { int min_x, max_x, min_y, max_y; int old_x, old_y, reset_x, reset_y; - int slot_mt; + int32_t x, y; } abs; + + struct { + int slot; + int32_t x[MAX_SLOTS]; + int32_t y[MAX_SLOTS]; + } mt; + + struct { + int dx, dy; + } rel; + + int type; /* event type flags */ + int is_touchpad, is_mt; }; @@ -59,13 +74,6 @@ struct evdev_input_device { #define EVDEV_ABSOLUTE_MT_UP (1 << 3) #define EVDEV_RELATIVE_MOTION (1 << 4) -struct evdev_motion_accumulator { - int x, y; - int dx, dy; - int mt_x, mt_y; - int type; /* event type flags */ -}; - static inline void evdev_process_key(struct evdev_input_device *device, struct input_event *e, int time) @@ -121,63 +129,66 @@ evdev_process_key(struct evdev_input_device *device, static void evdev_process_touch(struct evdev_input_device *device, - struct input_event *e, int time, - struct evdev_motion_accumulator *accum) + struct input_event *e) { const int screen_width = device->output->current->width; const int screen_height = device->output->current->height; switch (e->code) { case ABS_MT_SLOT: - device->abs.slot_mt = e->value; + device->mt.slot = e->value; break; case ABS_MT_TRACKING_ID: if (e->value >= 0) - accum->type |= EVDEV_ABSOLUTE_MT_DOWN; + device->type |= EVDEV_ABSOLUTE_MT_DOWN; else - accum->type |= EVDEV_ABSOLUTE_MT_UP; + device->type |= EVDEV_ABSOLUTE_MT_UP; break; case ABS_MT_POSITION_X: - accum->mt_x = (e->value - device->abs.min_x) * screen_width / + device->mt.x[device->mt.slot] = + (e->value - device->abs.min_x) * screen_width / (device->abs.max_x - device->abs.min_x) + device->output->x; - accum->type |= EVDEV_ABSOLUTE_MT_MOTION; + device->type |= EVDEV_ABSOLUTE_MT_MOTION; break; case ABS_MT_POSITION_Y: - accum->mt_y = (e->value - device->abs.min_y) * screen_height / + device->mt.y[device->mt.slot] = + (e->value - device->abs.min_y) * screen_height / (device->abs.max_y - device->abs.min_y) + device->output->y; - accum->type |= EVDEV_ABSOLUTE_MT_MOTION; + device->type |= EVDEV_ABSOLUTE_MT_MOTION; break; } } static inline void evdev_process_absolute_motion(struct evdev_input_device *device, - struct input_event *e, struct evdev_motion_accumulator *accum) + struct input_event *e) { const int screen_width = device->output->current->width; const int screen_height = device->output->current->height; switch (e->code) { case ABS_X: - accum->x = (e->value - device->abs.min_x) * screen_width / + device->abs.x = + (e->value - device->abs.min_x) * screen_width / (device->abs.max_x - device->abs.min_x) + device->output->x; - accum->type |= EVDEV_ABSOLUTE_MOTION; + device->type |= EVDEV_ABSOLUTE_MOTION; break; case ABS_Y: - accum->y = (e->value - device->abs.min_y) * screen_height / + device->abs.y = + (e->value - device->abs.min_y) * screen_height / (device->abs.max_y - device->abs.min_y) + device->output->y; - accum->type |= EVDEV_ABSOLUTE_MOTION; + device->type |= EVDEV_ABSOLUTE_MOTION; break; } } static inline void evdev_process_absolute_motion_touchpad(struct evdev_input_device *device, - struct input_event *e, struct evdev_motion_accumulator *accum) + struct input_event *e) { /* FIXME: Make this configurable somehow. */ const int touchpad_speed = 700; @@ -188,56 +199,57 @@ evdev_process_absolute_motion_touchpad(struct evdev_input_device *device, if (device->abs.reset_x) device->abs.reset_x = 0; else { - accum->dx = (e->value - device->abs.old_x) * + device->rel.dx = + (e->value - device->abs.old_x) * touchpad_speed / (device->abs.max_x - device->abs.min_x); } device->abs.old_x = e->value; - accum->type |= EVDEV_RELATIVE_MOTION; + device->type |= EVDEV_RELATIVE_MOTION; break; case ABS_Y: e->value -= device->abs.min_y; if (device->abs.reset_y) device->abs.reset_y = 0; else { - accum->dy = (e->value - device->abs.old_y) * + device->rel.dy = + (e->value - device->abs.old_y) * touchpad_speed / /* maybe use x size here to have the same scale? */ (device->abs.max_y - device->abs.min_y); } device->abs.old_y = e->value; - accum->type |= EVDEV_RELATIVE_MOTION; + device->type |= EVDEV_RELATIVE_MOTION; break; } } static inline void -evdev_process_relative_motion(struct input_event *e, - struct evdev_motion_accumulator *accum) +evdev_process_relative_motion(struct evdev_input_device *device, + struct input_event *e) { switch (e->code) { case REL_X: - accum->dx += e->value; - accum->type |= EVDEV_RELATIVE_MOTION; + device->rel.dx += e->value; + device->type |= EVDEV_RELATIVE_MOTION; break; case REL_Y: - accum->dy += e->value; - accum->type |= EVDEV_RELATIVE_MOTION; + device->rel.dy += e->value; + device->type |= EVDEV_RELATIVE_MOTION; break; } } static inline void evdev_process_absolute(struct evdev_input_device *device, - struct input_event *e, int time, - struct evdev_motion_accumulator *accum) + struct input_event *e) { if (device->is_touchpad) { - evdev_process_absolute_motion_touchpad(device, e, accum); + evdev_process_absolute_motion_touchpad(device, e); } else if (device->is_mt) { - evdev_process_touch(device, e, time, accum); + evdev_process_touch(device, e); } else { - evdev_process_absolute_motion(device, e, accum); + evdev_process_absolute_motion(device, e); } } @@ -265,39 +277,48 @@ is_motion_event(struct input_event *e) } static void -evdev_flush_motion(struct wl_input_device *device, uint32_t time, - struct evdev_motion_accumulator *accum, int slot_mt) +evdev_flush_motion(struct evdev_input_device *device, uint32_t time) { - if (!accum->type) + struct wl_input_device *master = + &device->master->base.input_device; + + if (!device->type) return; - if (accum->type & EVDEV_RELATIVE_MOTION) { - notify_motion(device, time, - device->x + accum->dx, device->y + accum->dy); - accum->type &= ~EVDEV_RELATIVE_MOTION; - accum->dx = 0; - accum->dy = 0; + if (device->type & EVDEV_RELATIVE_MOTION) { + notify_motion(master, time, + master->x + device->rel.dx, + master->y + device->rel.dy); + device->type &= ~EVDEV_RELATIVE_MOTION; + device->rel.dx = 0; + device->rel.dy = 0; } - if (accum->type & EVDEV_ABSOLUTE_MT_DOWN) { - notify_touch(device, time, slot_mt, accum->mt_x, accum->mt_y, + if (device->type & EVDEV_ABSOLUTE_MT_DOWN) { + notify_touch(master, time, + device->mt.slot, + device->mt.x[device->mt.slot], + device->mt.y[device->mt.slot], WL_INPUT_DEVICE_TOUCH_DOWN); - accum->type &= ~EVDEV_ABSOLUTE_MT_DOWN; - accum->type &= ~EVDEV_ABSOLUTE_MT_MOTION; + device->type &= ~EVDEV_ABSOLUTE_MT_DOWN; + device->type &= ~EVDEV_ABSOLUTE_MT_MOTION; } - if (accum->type & EVDEV_ABSOLUTE_MT_MOTION) { - notify_touch(device, time, slot_mt, accum->mt_x, accum->mt_y, - WL_INPUT_DEVICE_TOUCH_MOTION); - accum->type &= ~EVDEV_ABSOLUTE_MT_DOWN; - accum->type &= ~EVDEV_ABSOLUTE_MT_MOTION; + if (device->type & EVDEV_ABSOLUTE_MT_MOTION) { + notify_touch(master, time, + device->mt.slot, + device->mt.x[device->mt.slot], + device->mt.y[device->mt.slot], + WL_INPUT_DEVICE_TOUCH_MOTION); + device->type &= ~EVDEV_ABSOLUTE_MT_DOWN; + device->type &= ~EVDEV_ABSOLUTE_MT_MOTION; } - if (accum->type & EVDEV_ABSOLUTE_MT_UP) { - notify_touch(device, time, slot_mt, 0, 0, + if (device->type & EVDEV_ABSOLUTE_MT_UP) { + notify_touch(master, time, device->mt.slot, 0, 0, WL_INPUT_DEVICE_TOUCH_UP); - accum->type &= ~EVDEV_ABSOLUTE_MT_UP; + device->type &= ~EVDEV_ABSOLUTE_MT_UP; } - if (accum->type & EVDEV_ABSOLUTE_MOTION) { - notify_motion(device, time, accum->x, accum->y); - accum->type &= ~EVDEV_ABSOLUTE_MOTION; + if (device->type & EVDEV_ABSOLUTE_MOTION) { + notify_motion(master, time, device->abs.x, device->abs.y); + device->type &= ~EVDEV_ABSOLUTE_MOTION; } } @@ -308,7 +329,6 @@ evdev_input_device_data(int fd, uint32_t mask, void *data) struct evdev_input_device *device = data; struct input_event ev[8], *e, *end; int len; - struct evdev_motion_accumulator accumulator; uint32_t time = 0; ec = device->master->base.compositor; @@ -321,10 +341,6 @@ evdev_input_device_data(int fd, uint32_t mask, void *data) return 1; } - accumulator.type = 0; - accumulator.mt_x = accumulator.x = device->master->base.input_device.x; - accumulator.mt_y = accumulator.y = device->master->base.input_device.y; - e = ev; end = (void *) ev + len; for (e = ev; e < end; e++) { @@ -334,15 +350,13 @@ evdev_input_device_data(int fd, uint32_t mask, void *data) * forwarded to the compositor, so we accumulate motion * events and send as a bunch */ if (!is_motion_event(e)) - evdev_flush_motion(&device->master->base.input_device, - time, &accumulator, - device->abs.slot_mt); + evdev_flush_motion(device, time); switch (e->type) { case EV_REL: - evdev_process_relative_motion(e, &accumulator); + evdev_process_relative_motion(device, e); break; case EV_ABS: - evdev_process_absolute(device, e, time, &accumulator); + evdev_process_absolute(device, e); break; case EV_KEY: evdev_process_key(device, e, time); @@ -350,8 +364,7 @@ evdev_input_device_data(int fd, uint32_t mask, void *data) } } - evdev_flush_motion(&device->master->base.input_device, time, - &accumulator, device->abs.slot_mt); + evdev_flush_motion(device, time); return 1; } @@ -397,7 +410,7 @@ evdev_configure_device(struct evdev_input_device *device) } if (TEST_BIT(abs_bits, ABS_MT_SLOT)) { device->is_mt = 1; - device->abs.slot_mt = 0; + device->mt.slot = 0; } } if (TEST_BIT(ev_bits, EV_KEY)) { @@ -438,7 +451,9 @@ evdev_input_device_create(struct evdev_input *master, device->is_touchpad = 0; device->is_mt = 0; device->devnode = strdup(path); - device->abs.slot_mt = -1; + device->mt.slot = -1; + device->rel.dx = 0; + device->rel.dy = 0; device->fd = open(path, O_RDONLY); if (device->fd < 0)