diff options
Diffstat (limited to 'common/mousekey.c')
-rw-r--r-- | common/mousekey.c | 202 |
1 files changed, 133 insertions, 69 deletions
diff --git a/common/mousekey.c b/common/mousekey.c index 1d35355b49..b8af3e59c7 100644 --- a/common/mousekey.c +++ b/common/mousekey.c @@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include <stdint.h> #include <util/delay.h> -#include "usb_keycodes.h" +#include "keycode.h" #include "host.h" #include "timer.h" #include "print.h" @@ -25,108 +25,172 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "mousekey.h" -static report_mouse_t report; -static report_mouse_t report_prev; static uint8_t mousekey_repeat = 0; +static uint8_t mousekey_accel = 0; static void mousekey_debug(void); /* - * TODO: fix acceleration algorithm - * see wikipedia http://en.wikipedia.org/wiki/Mouse_keys + * Mouse keys acceleration algorithm + * http://en.wikipedia.org/wiki/Mouse_keys + * + * speed = delta * max_speed * (repeat / time_to_max)**((1000+curve)/1000) */ -#ifndef MOUSEKEY_DELAY_TIME -# define MOUSEKEY_DELAY_TIME 255 -#endif +/* milliseconds between the initial key press and first repeated motion event (0-2550) */ +uint8_t mk_delay = MOUSEKEY_DELAY/10; +/* milliseconds between repeated motion events (0-255) */ +uint8_t mk_interval = MOUSEKEY_INTERVAL; +/* steady speed (in action_delta units) applied each event (0-255) */ +uint8_t mk_max_speed = MOUSEKEY_MAX_SPEED; +/* number of events (count) accelerating to steady speed (0-255) */ +uint8_t mk_time_to_max = MOUSEKEY_TIME_TO_MAX; +/* ramp used to reach maximum pointer speed (NOT SUPPORTED) */ +//int8_t mk_curve = 0; +/* wheel params */ +uint8_t mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED; +uint8_t mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX; -// acceleration parameters -uint8_t mousekey_move_unit = 2; -uint8_t mousekey_resolution = 5; +static uint16_t last_timer = 0; -static inline uint8_t move_unit(void) -{ - uint16_t unit = 5 + mousekey_repeat*2; - return (unit > 63 ? 63 : unit); -} -void mousekey_decode(uint8_t code) +static uint8_t move_unit(void) { - if (code == KB_MS_UP) report.y = -move_unit(); - else if (code == KB_MS_DOWN) report.y = move_unit(); - else if (code == KB_MS_LEFT) report.x = -move_unit(); - else if (code == KB_MS_RIGHT) report.x = move_unit(); - else if (code == KB_MS_BTN1) report.buttons |= MOUSE_BTN1; - else if (code == KB_MS_BTN2) report.buttons |= MOUSE_BTN2; - else if (code == KB_MS_BTN3) report.buttons |= MOUSE_BTN3; - else if (code == KB_MS_BTN4) report.buttons |= MOUSE_BTN4; - else if (code == KB_MS_BTN5) report.buttons |= MOUSE_BTN5; - else if (code == KB_MS_WH_UP) report.v += move_unit()/4; - else if (code == KB_MS_WH_DOWN) report.v -= move_unit()/4; - else if (code == KB_MS_WH_LEFT) report.h -= move_unit()/4; - else if (code == KB_MS_WH_RIGHT)report.h += move_unit()/4; + uint16_t unit; + if (mousekey_accel & (1<<0)) { + unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed)/4; + } else if (mousekey_accel & (1<<1)) { + unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed)/2; + } else if (mousekey_accel & (1<<2)) { + unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed); + } else if (mousekey_repeat == 0) { + unit = MOUSEKEY_MOVE_DELTA; + } else if (mousekey_repeat >= mk_time_to_max) { + unit = MOUSEKEY_MOVE_DELTA * mk_max_speed; + } else { + unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed * mousekey_repeat) / mk_time_to_max; + } + return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit)); } -bool mousekey_changed(void) +static uint8_t wheel_unit(void) { - return (report.buttons != report_prev.buttons || - report.x || report.y || report.v || report.h); + uint16_t unit; + if (mousekey_accel & (1<<0)) { + unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed)/4; + } else if (mousekey_accel & (1<<1)) { + unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed)/2; + } else if (mousekey_accel & (1<<2)) { + unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed); + } else if (mousekey_repeat == 0) { + unit = MOUSEKEY_WHEEL_DELTA; + } else if (mousekey_repeat >= mk_time_to_max) { + unit = MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed; + } else { + unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_repeat) / mk_wheel_time_to_max; + } + return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit)); } -void mousekey_send(void) +void mousekey_task(void) { - static uint16_t last_timer = 0; - - if (!mousekey_changed()) { - mousekey_repeat = 0; - mousekey_clear_report(); + if (timer_elapsed(last_timer) < (mousekey_repeat ? mk_interval : mk_delay*10)) return; - } - // send immediately when buttun state is changed - if (report.buttons == report_prev.buttons) { - if (timer_elapsed(last_timer) < 100) { - mousekey_clear_report(); - return; - } - } + if (mouse_report.x == 0 && mouse_report.y == 0 && mouse_report.v == 0 && mouse_report.h == 0) + return; - if (mousekey_repeat != 0xFF) { + if (mousekey_repeat != UINT8_MAX) mousekey_repeat++; - } - if (report.x && report.y) { - report.x *= 0.7; - report.y *= 0.7; + + if (mouse_report.x > 0) mouse_report.x = move_unit(); + if (mouse_report.x < 0) mouse_report.x = move_unit() * -1; + if (mouse_report.y > 0) mouse_report.y = move_unit(); + if (mouse_report.y < 0) mouse_report.y = move_unit() * -1; + + /* diagonal move [1/sqrt(2) = 0.7] */ + if (mouse_report.x && mouse_report.y) { + mouse_report.x *= 0.7; + mouse_report.y *= 0.7; } + if (mouse_report.v > 0) mouse_report.v = wheel_unit(); + if (mouse_report.v < 0) mouse_report.v = wheel_unit() * -1; + if (mouse_report.h > 0) mouse_report.h = wheel_unit(); + if (mouse_report.h < 0) mouse_report.h = wheel_unit() * -1; + + mousekey_send(); +} + +void mousekey_on(uint8_t code) +{ + if (code == KC_MS_UP) mouse_report.y = move_unit() * -1; + else if (code == KC_MS_DOWN) mouse_report.y = move_unit(); + else if (code == KC_MS_LEFT) mouse_report.x = move_unit() * -1; + else if (code == KC_MS_RIGHT) mouse_report.x = move_unit(); + else if (code == KC_MS_WH_UP) mouse_report.v = wheel_unit(); + else if (code == KC_MS_WH_DOWN) mouse_report.v = wheel_unit() * -1; + else if (code == KC_MS_WH_LEFT) mouse_report.h = wheel_unit() * -1; + else if (code == KC_MS_WH_RIGHT) mouse_report.h = wheel_unit(); + else if (code == KC_MS_BTN1) mouse_report.buttons |= MOUSE_BTN1; + else if (code == KC_MS_BTN2) mouse_report.buttons |= MOUSE_BTN2; + else if (code == KC_MS_BTN3) mouse_report.buttons |= MOUSE_BTN3; + else if (code == KC_MS_BTN4) mouse_report.buttons |= MOUSE_BTN4; + else if (code == KC_MS_BTN5) mouse_report.buttons |= MOUSE_BTN5; + else if (code == KC_MS_ACCEL0) mousekey_accel |= (1<<0); + else if (code == KC_MS_ACCEL1) mousekey_accel |= (1<<1); + else if (code == KC_MS_ACCEL2) mousekey_accel |= (1<<2); +} + +void mousekey_off(uint8_t code) +{ + if (code == KC_MS_UP && mouse_report.y < 0) mouse_report.y = 0; + else if (code == KC_MS_DOWN && mouse_report.y > 0) mouse_report.y = 0; + else if (code == KC_MS_LEFT && mouse_report.x < 0) mouse_report.x = 0; + else if (code == KC_MS_RIGHT && mouse_report.x > 0) mouse_report.x = 0; + else if (code == KC_MS_WH_UP && mouse_report.v > 0) mouse_report.v = 0; + else if (code == KC_MS_WH_DOWN && mouse_report.v < 0) mouse_report.v = 0; + else if (code == KC_MS_WH_LEFT && mouse_report.h < 0) mouse_report.h = 0; + else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0) mouse_report.h = 0; + else if (code == KC_MS_BTN1) mouse_report.buttons &= ~MOUSE_BTN1; + else if (code == KC_MS_BTN2) mouse_report.buttons &= ~MOUSE_BTN2; + else if (code == KC_MS_BTN3) mouse_report.buttons &= ~MOUSE_BTN3; + else if (code == KC_MS_BTN4) mouse_report.buttons &= ~MOUSE_BTN4; + else if (code == KC_MS_BTN5) mouse_report.buttons &= ~MOUSE_BTN5; + else if (code == KC_MS_ACCEL0) mousekey_accel &= ~(1<<0); + else if (code == KC_MS_ACCEL1) mousekey_accel &= ~(1<<1); + else if (code == KC_MS_ACCEL2) mousekey_accel &= ~(1<<2); + + if (mouse_report.x == 0 && mouse_report.y == 0 && mouse_report.v == 0 && mouse_report.h == 0) + mousekey_repeat = 0; +} + +void mousekey_send(void) +{ mousekey_debug(); - host_mouse_send(&report); - report_prev = report; + host_mouse_send(&mouse_report); last_timer = timer_read(); - mousekey_clear_report(); } -void mousekey_clear_report(void) +void mousekey_clear(void) { - report.buttons = 0; - report.x = 0; - report.y = 0; - report.v = 0; - report.h = 0; + mouse_report = (report_mouse_t){}; + mousekey_repeat = 0; + mousekey_accel = 0; } static void mousekey_debug(void) { if (!debug_mouse) return; - print("mousekey [btn|x y v h]rep: ["); - phex(report.buttons); print("|"); - phex(report.x); print(" "); - phex(report.y); print(" "); - phex(report.v); print(" "); - phex(report.h); print("]"); - phex(mousekey_repeat); - print("\n"); + print("mousekey [btn|x y v h](rep/acl): ["); + phex(mouse_report.buttons); print("|"); + phex(mouse_report.x); print(" "); + phex(mouse_report.y); print(" "); + phex(mouse_report.v); print(" "); + phex(mouse_report.h); print("]("); + phex(mousekey_repeat); print("/"); + phex(mousekey_accel); print(")\n"); } |