Hi Martin, By and large this looks good to me, although the main comment I have is that this should probably be using the acceleration mechanism in src/filter.c.
Cheers, Daniel On 29 March 2013 20:47, Martin Minarik <minari...@student.fiit.stuba.sk> wrote: > Acceleration: After examining, I don't like the X acceleration > approach. X employs a so called velocity approximation (?) > algorithm. It is quite a complex way to get an approximation of > a simple thing, the velocity, when we can compute the velocity > directly. > > Configuring: Please, tune the values in mouse_init(). > > The tune speed coefficient is simply a multiplier of how fast > the mouse moves. The 1.0 is the real (raw) device speed. > These tune speed coefficients feel very natural to use: > > 0.03125 0.0625 0.25 0.5 0.75 1.0 1.5 2.0 2.5 3.0 3.5 > > The acceleration boost factor (at 1.0 speed coefficient): > > 0.01 - NO effect > 0.02 - small effect > 0.06 - medium effect > 0.10 - pretty strong > 0.13 - TOO strong > > This patch does not introduce smoothing. > --- > src/Makefile.am | 4 + > src/evdev-mouse.c | 240 > +++++++++++++++++++++++++++++++++++++++++++++++++++++ > src/evdev.c | 3 + > src/evdev.h | 3 + > 4 files changed, 250 insertions(+) > create mode 100644 src/evdev-mouse.c > > diff --git a/src/Makefile.am b/src/Makefile.am > index d56daa0..2c8b3eb 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -138,6 +138,7 @@ drm_backend_la_SOURCES = \ > udev-seat.h \ > evdev.c \ > evdev.h \ > + evdev-mouse.c \ > evdev-touchpad.c \ > launcher-util.c \ > launcher-util.h \ > @@ -177,7 +178,9 @@ rpi_backend_la_SOURCES = \ > tty.c \ > evdev.c \ > evdev.h \ > + evdev-mouse.c \ > evdev-touchpad.c > + > endif > > if ENABLE_HEADLESS_COMPOSITOR > @@ -211,6 +214,7 @@ fbdev_backend_la_SOURCES = \ > evdev.c \ > evdev.h \ > evdev-touchpad.c \ > + evdev-mouse.c \ > launcher-util.c > endif > > diff --git a/src/evdev-mouse.c b/src/evdev-mouse.c > new file mode 100644 > index 0000000..b4915cd > --- /dev/null > +++ b/src/evdev-mouse.c > @@ -0,0 +1,240 @@ > +#include <stdlib.h> > +#include <stdbool.h> > + > +#include "compositor.h" > +#include "evdev.h" > + > +#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int(10) > +#define MOUSE_VELOCITY_SAMPLING_INTERVAL 20 > + > +struct mouse_motion { > + int32_t dx; > + int32_t dy; > +}; > + > +struct mouse_dispatch { > + struct evdev_dispatch base; > + struct evdev_device *device; > + > + double actual_speed; > + > + struct mouse_motion motion_sample; > + uint32_t motion_time_next_sample; > + uint32_t motion_time_out; > + unsigned long int last_velocity_sq; > + > + /* tuneable */ > + bool tune_is_acceleration; > + double tune_acceleration_boost; > + double tune_speed_coefficient; > +}; > + > +static inline void > +mouse_process_relative(struct mouse_dispatch *mouse, > + struct evdev_device *device, > + struct input_event *event, uint32_t time) > +{ > + switch (event->code) { > + case REL_X: > + if (mouse->tune_is_acceleration) > + mouse->motion_sample.dx += event->value; > + device->rel.dx += wl_fixed_from_double( > + (double) event->value * mouse->actual_speed); > + > + device->pending_events |= EVDEV_RELATIVE_MOTION; > + break; > + case REL_Y: > + if (mouse->tune_is_acceleration) > + mouse->motion_sample.dy += event->value; > + device->rel.dy += wl_fixed_from_double( > + (double) event->value * mouse->actual_speed); > + > + device->pending_events |= EVDEV_RELATIVE_MOTION; > + break; > + case REL_WHEEL: > + switch (event->value) { > + case -1: > + /* Scroll down */ > + case 1: > + /* Scroll up */ > + notify_axis(device->seat, > + time, > + WL_POINTER_AXIS_VERTICAL_SCROLL, > + -1 * event->value * > DEFAULT_AXIS_STEP_DISTANCE); > + break; > + default: > + break; > + } > + break; > + case REL_HWHEEL: > + switch (event->value) { > + case -1: > + /* Scroll left */ > + case 1: > + /* Scroll right */ > + notify_axis(device->seat, > + time, > + WL_POINTER_AXIS_HORIZONTAL_SCROLL, > + event->value * > DEFAULT_AXIS_STEP_DISTANCE); > + break; > + default: > + break; > + > + } > + } > +} > + > +static inline void > +mouse_process_key(struct mouse_dispatch *mouse, > + struct evdev_device *device, > + struct input_event *e, > + uint32_t time) > +{ > + if (e->value == 2) > + return; > + > + switch (e->code) { > + case BTN_LEFT: > + case BTN_RIGHT: > + case BTN_MIDDLE: > + case BTN_SIDE: > + case BTN_EXTRA: > + case BTN_FORWARD: > + case BTN_BACK: > + case BTN_TASK: > + notify_button(device->seat, > + time, e->code, > + e->value ? WL_POINTER_BUTTON_STATE_PRESSED : > + WL_POINTER_BUTTON_STATE_RELEASED); > + break; > + > + default: > + notify_key(device->seat, > + time, e->code, > + e->value ? WL_KEYBOARD_KEY_STATE_PRESSED : > + WL_KEYBOARD_KEY_STATE_RELEASED, > + STATE_UPDATE_AUTOMATIC); > + break; > + } > +} > + > +static void > +mouse_reset_acceleration(struct mouse_dispatch *mouse, uint32_t time) > +{ > + struct mouse_motion *m = &mouse->motion_sample; > + unsigned const int interval = MOUSE_VELOCITY_SAMPLING_INTERVAL; > + > + mouse->last_velocity_sq = 0; > + mouse->actual_speed = mouse->tune_speed_coefficient; > + mouse->motion_time_out = 2 * interval + time; > + mouse->motion_time_next_sample = interval + time; > + > + m->dx = 0; > + m->dy = 0; > +} > + > +static void > +mouse_recompute_acceleration(struct mouse_dispatch *mouse, uint32_t time) > +{ > + struct mouse_motion *m = &mouse->motion_sample; > + unsigned const int interval = MOUSE_VELOCITY_SAMPLING_INTERVAL; > + > + unsigned long int velocity_sq; > + const double no_decceleration = 1.0; > + double acceleration; > + > + velocity_sq = m->dx * m->dx + m->dy * m->dy; > + > + if (velocity_sq > mouse->last_velocity_sq) > + acceleration = pow(velocity_sq - mouse->last_velocity_sq, > + mouse->tune_acceleration_boost); > + else > + acceleration = no_decceleration; > + > + mouse->last_velocity_sq = velocity_sq; > + mouse->actual_speed = mouse->tune_speed_coefficient * acceleration; > + mouse->motion_time_out += interval; > + mouse->motion_time_next_sample += interval; > + > + m->dx = 0; > + m->dy = 0; > +} > + > +static void > +mouse_process(struct evdev_dispatch *dispatch, > + struct evdev_device *device, > + struct input_event *event, > + uint32_t time) > +{ > + struct mouse_dispatch *mouse = > + (struct mouse_dispatch *) dispatch; > + > + switch (event->type) { > + case EV_REL: > + mouse_process_relative(mouse, device, event, time); > + break; > + case EV_KEY: > + mouse_process_key(mouse, device, event, time); > + break; > + case EV_SYN: > + device->pending_events |= EVDEV_SYN; > + > + if ((mouse->tune_is_acceleration) && > + (time > mouse->motion_time_next_sample)) { > + if (time > mouse->motion_time_out) > + mouse_reset_acceleration(mouse, time); > + else > + mouse_recompute_acceleration(mouse, time); > + } > + break; > + } > +} > + > +static void > +mouse_destroy(struct evdev_dispatch *dispatch) > +{ > + struct mouse_dispatch *mouse = > + (struct mouse_dispatch *) dispatch; > + > + free(mouse); > +} > + > +struct evdev_dispatch_interface mouse_interface = { > + mouse_process, > + mouse_destroy > +}; > + > +static int > +mouse_init(struct mouse_dispatch *mouse, > + struct evdev_device *device) > +{ > + mouse->base.interface = &mouse_interface; > + mouse->device = device; > + > + /* Configure mouse velocity, acceleration */ > + mouse->tune_is_acceleration = true; > + mouse->tune_acceleration_boost = 0.03; > + mouse->tune_speed_coefficient = 2.00; > + > + /* Prepare velocity tracking */ > + mouse_reset_acceleration(mouse, 0); > + > + return 0; > +} > + > +struct evdev_dispatch * > +evdev_mouse_create(struct evdev_device *device) > +{ > + struct mouse_dispatch *mouse; > + > + mouse = malloc(sizeof *mouse); > + if (mouse == NULL) > + return NULL; > + > + if (mouse_init(mouse, device) != 0) { > + free(mouse); > + return NULL; > + } > + > + return &mouse->base; > +} > diff --git a/src/evdev.c b/src/evdev.c > index d2954b5..bbad5ad 100644 > --- a/src/evdev.c > +++ b/src/evdev.c > @@ -459,6 +459,9 @@ evdev_handle_device(struct evdev_device *device) > !TEST_BIT(key_bits, BTN_TOOL_PEN) && > has_abs) > device->dispatch = evdev_touchpad_create(device); > + else if (TEST_BIT(key_bits, BTN_LEFT) && !has_abs) > + device->dispatch = evdev_mouse_create(device); > + > for (i = KEY_ESC; i < KEY_MAX; i++) { > if (i >= BTN_MISC && i < KEY_OK) > continue; > diff --git a/src/evdev.h b/src/evdev.h > index eb5c868..f670682 100644 > --- a/src/evdev.h > +++ b/src/evdev.h > @@ -111,6 +111,9 @@ struct evdev_dispatch { > struct evdev_dispatch * > evdev_touchpad_create(struct evdev_device *device); > > +struct evdev_dispatch * > +evdev_mouse_create(struct evdev_device *device); > + > void > evdev_led_update(struct evdev_device *device, enum weston_led leds); > > -- > 1.7.10.4 > > _______________________________________________ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel