Hi, Did anything happen with these? Additionally, the tuning seems a little hostile: if we have a subset of known-good values, we should probably mostly stick to those. Really, I'd just love to see a 1-10 'speed' configuration item that just does the right thing, rather than having to guess the magic number.
Cheers, Daniel On 3 April 2013 05:17, Daniel Stone <dan...@fooishbar.org> wrote: > 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