diff --git a/compositor/evdev.c b/compositor/evdev.c index 11f7f5e4..c065b33c 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)