summaryrefslogtreecommitdiffstats
path: root/mousekey.c
blob: 38a8c2e4740674f047a47e7dafa1fbd72441ca4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <stdint.h>
#include <util/delay.h>
#include "usb_keycodes.h"
#include "usb_mouse.h"
#include "mousekey.h"


static int8_t mousekey_x = 0;
static int8_t mousekey_y = 0;
static int8_t mousekey_v = 0;
static int8_t mousekey_h = 0;
static uint8_t mousekey_btn = 0;
static uint8_t mousekey_btn_prev = 0;
static uint8_t mousekey_repeat =  0;


/*
 * TODO: fix acceleration algorithm
 * see wikipedia http://en.wikipedia.org/wiki/Mouse_keys
 */
#ifndef MOUSEKEY_DELAY_TIME
#   define MOUSEKEY_DELAY_TIME 255
#endif


static inline uint8_t move_unit(void)
{
    return 10 + (mousekey_repeat < 50 ? mousekey_repeat/5 : 10);
}

void mousekey_decode(uint8_t code)
{
    if      (code == KB_MS_UP)   mousekey_y -= move_unit();
    else if (code == KB_MS_DOWN) mousekey_y += move_unit();
    else if (code == KB_MS_LEFT) mousekey_x -= move_unit();
    else if (code == KB_MS_RIGHT) mousekey_x += move_unit();
    else if (code == KB_MS_BTN1) mousekey_btn |= MOUSE_BTN1;
    else if (code == KB_MS_BTN2) mousekey_btn |= MOUSE_BTN2;
    else if (code == KB_MS_BTN3) mousekey_btn |= MOUSE_BTN3;
    else if (code == KB_MS_BTN4) mousekey_btn |= MOUSE_BTN4;
    else if (code == KB_MS_BTN5) mousekey_btn |= MOUSE_BTN5;
    else if (code == KB_MS_WH_UP) mousekey_v += 1;
    else if (code == KB_MS_WH_DOWN) mousekey_v -= 1;
    else if (code == KB_MS_WH_LEFT) mousekey_h -= 1;
    else if (code == KB_MS_WH_RIGHT) mousekey_h += 1;
}

bool mousekey_changed(void)
{
    return (mousekey_x || mousekey_y || mousekey_v || mousekey_h || mousekey_btn != mousekey_btn_prev);
}

void mousekey_usb_send(void)
{
    if (mousekey_changed()) {
        mousekey_btn_prev = mousekey_btn;
        if (mousekey_x && mousekey_y)
            usb_mouse_send(mousekey_x*0.7, mousekey_y*0.7, mousekey_v, mousekey_h, mousekey_btn);
        else
            usb_mouse_send(mousekey_x, mousekey_y, mousekey_v, mousekey_h, mousekey_btn);

        usb_mouse_print(mousekey_x, mousekey_y, mousekey_v, mousekey_h, mousekey_btn);

        if (mousekey_x || mousekey_y || mousekey_v || mousekey_h)
            _delay_ms(MOUSEKEY_DELAY_TIME >> (mousekey_repeat < 5 ? mousekey_repeat : 4));
        mousekey_repeat++;
    } else {
        mousekey_repeat = 0;
    }
    mousekey_x = 0;
    mousekey_y = 0;
    mousekey_v = 0;
    mousekey_h = 0;
    mousekey_btn = 0;
}