~ruther/qmk_firmware

7e3975e0ef00b2095e32595597ba054d408f249c — tmk 15 years ago d3b1af9
add mouse wheel function.
8 files changed, 256 insertions(+), 59 deletions(-)

M keymap.c
A mouse_report.txt
M mykey.c
M usb.c
M usb.h
M usb_keycodes.h
M usb_mouse.c
M usb_mouse.h
M keymap.c => keymap.c +13 -13
@@ 5,7 5,7 @@
#include "matrix.h"
#include "keymap.h"

int current_layer = 1;
int current_layer = 0;

static const uint8_t PROGMEM Keymap[][MATRIX_ROWS][MATRIX_COLS] = {
    // 0: default


@@ 20,7 20,7 @@ static const uint8_t PROGMEM Keymap[][MATRIX_ROWS][MATRIX_COLS] = {
        { KB_9,    KB_NO,     KB_NO,      KB_O,  KB_L,      FN_2,       KB_DOT,   KB_NO },
        { KB_0,    KB_MINUS,  KB_LBRACKET,KB_P,  KB_SCOLON, KB_QUOTE,   KB_NO,    KB_SLASH }
    },
    // 1: FN_0
    // 1: FN_0(RIGHT ALT)
    {
        { KB_LALT, KB_NO,     KB_DELETE,  KB_NO, KB_NO,     KB_NO,      KB_BSLASH,KB_NO },
        { KB_F1,   KB_GRAVE,  KB_BSLASH,  KB_NO, KB_NO,     KB_LCTRL,   KB_NO,    KB_NO },


@@ 32,7 32,7 @@ static const uint8_t PROGMEM Keymap[][MATRIX_ROWS][MATRIX_COLS] = {
        { KB_F9,   KB_NO,     KB_NO,      KB_NO, KB_RIGHT,  KB_NO,      KB_END,   KB_NO },
        { KB_F10,  KB_F11,    KB_NO,      KB_NO, KB_NO,     KB_NO,      KB_NO,    KB_NO }
    },
    // 2: FN_1
    // 2: FN_1(HHKB Fn)
    {
        { KB_LALT, KB_NO,     KB_DELETE,  KB_NO, KB_NO,     KB_NO,      KB_BSLASH,KB_NO },
        { KB_F1,   KB_GRAVE,  KB_BSLASH,  KB_NO, KB_VOLDOWN,KB_LCTRL,   KB_NO,    KB_NO },


@@ 44,17 44,17 @@ static const uint8_t PROGMEM Keymap[][MATRIX_ROWS][MATRIX_COLS] = {
        { KB_F9,   KB_NO,     KB_NO,      KB_NO, KB_PGUP,   KB_NO,      KB_PGDOWN,KB_NO },
        { KB_F10,  KB_F11,    KB_UP,      KB_NO, KB_LEFT,   KB_RIGHT,   KB_NO,    KB_DOWN }
    },
    // 3: FN_2
    // 3: FN_2(LEFT Bottom)
    {
        { KB_LALT, KB_NO,     KB_DELETE,  KB_NO, KB_NO,     KB_NO,      KB_BSLASH,KB_NO },
        { KB_F1,   KB_GRAVE,  KB_BSLASH,  KB_NO, KB_NO,     KB_LCTRL,   KB_NO,    KB_NO },
        { KB_F2,   KB_NO,     KB_LGUI,    KB_NO, KB_NO,     KB_NO,      KB_NO,    KB_NO },
        { KB_F3,   KB_NO,     KB_RSHIFT,  KB_NO, KB_NO,     KB_NO,      KB_NO,    KB_NO },
        { KB_F4,   KB_F5,     KB_NO,      KB_NO, KB_NO,     KB_NO,      KB_NO,    KB_NO },
        { KB_F7,   KB_F6,     KB_NO,      KB_NO, KB_DOWN,   KB_LEFT,    KB_PGDOWN,KB_HOME },
        { KB_F8,   KB_F12,    KB_NO,      KB_NO, KB_UP,     KB_NO,      KB_PGUP,  KB_LSHIFT },
        { KB_F9,   KB_NO,     KB_NO,      KB_NO, KB_RIGHT,  KB_NO,      KB_END,   KB_NO },
        { KB_F10,  KB_F11,    KB_NO,      KB_NO, KB_NO,     KB_NO,      KB_NO,    KB_NO }
        { KB_LALT, KB_NO,     KB_DELETE,  KB_NO, MS_LEFT,   KB_NO,      KB_BSLASH,  MS_BTN1 },
        { KB_F1,   KB_GRAVE,  KB_BSLASH,  KB_NO, MS_BTN1,   KB_LCTRL,   KB_NO,      MS_RIGHT },
        { KB_F2,   MS_BTN2,   KB_LGUI,    KB_NO, MS_BTN2,   KB_NO,      KB_NO,      MS_UP },
        { KB_F3,   KB_NO,     KB_RSHIFT,  KB_NO, MS_BTN3,   KB_NO,      KB_NO,      MS_DOWN },
        { KB_F4,   KB_F5,     KB_NO,      KB_NO, KB_NO,     KB_NO,      KB_NO,      KB_NO },
        { KB_F7,   KB_F6,     KB_NO,      KB_NO, MS_DOWN,   MS_LEFT,    MS_WH_UP,   MS_WH_LEFT },
        { KB_F8,   KB_F12,    MS_BTN5,    KB_NO, MS_UP,     KB_NO,      MS_WH_DOWN, KB_LSHIFT },
        { KB_F9,   KB_NO,     KB_NO,      KB_NO, MS_RIGHT,  KB_NO,      MS_WH_RIGHT,KB_NO },
        { KB_F10,  KB_F11,    MS_BTN4,    KB_NO, KB_NO,     KB_NO,      KB_NO,      KB_NO }
    },
};


A mouse_report.txt => mouse_report.txt +141 -0
@@ 0,0 1,141 @@
/*
    0x05, 0x01,        // USAGE_PAGE (Generic Desktop)
    0x09, 0x02,        // USAGE (Mouse)
    0xa1, 0x01,        // COLLECTION (Application)
    0x09, 0x02,        //   USAGE (Mouse)
    0xa1, 0x02,        //   COLLECTION (Logical)
    0x09, 0x01,        //     USAGE (Pointer)
    0xa1, 0x00,        //     COLLECTION (Physical)
                       // ------------------------------  Buttons
    0x05, 0x09,        //       USAGE_PAGE (Button)
    0x19, 0x01,        //       USAGE_MINIMUM (Button 1)
    0x29, 0x05,        //       USAGE_MAXIMUM (Button 5)
    0x15, 0x00,        //       LOGICAL_MINIMUM (0)
    0x25, 0x01,        //       LOGICAL_MAXIMUM (1)
    0x75, 0x01,        //       REPORT_SIZE (1)
    0x95, 0x05,        //       REPORT_COUNT (5)
    0x81, 0x02,        //       INPUT (Data,Var,Abs)
                       // ------------------------------  Padding
    0x75, 0x03,        //       REPORT_SIZE (3)
    0x95, 0x01,        //       REPORT_COUNT (1)
    0x81, 0x03,        //       INPUT (Cnst,Var,Abs)
                       // ------------------------------  X,Y position
    0x05, 0x01,        //       USAGE_PAGE (Generic Desktop)
    0x09, 0x30,        //       USAGE (X)
    0x09, 0x31,        //       USAGE (Y)
    0x15, 0x81,        //       LOGICAL_MINIMUM (-127)
    0x25, 0x7f,        //       LOGICAL_MAXIMUM (127)
    0x75, 0x08,        //       REPORT_SIZE (8)
    0x95, 0x02,        //       REPORT_COUNT (2)
    0x81, 0x06,        //       INPUT (Data,Var,Rel)
    0xa1, 0x02,        //       COLLECTION (Logical)
                       // ------------------------------  Vertical wheel res multiplier
    0x09, 0x48,        //         USAGE (Resolution Multiplier)
    0x15, 0x00,        //         LOGICAL_MINIMUM (0)
    0x25, 0x01,        //         LOGICAL_MAXIMUM (1)
    0x35, 0x01,        //         PHYSICAL_MINIMUM (1)
    0x45, 0x04,        //         PHYSICAL_MAXIMUM (4)
    0x75, 0x02,        //         REPORT_SIZE (2)
    0x95, 0x01,        //         REPORT_COUNT (1)
    0xa4,              //         PUSH
    0xb1, 0x02,        //         FEATURE (Data,Var,Abs)
                       // ------------------------------  Vertical wheel
    0x09, 0x38,        //         USAGE (Wheel)
    0x15, 0x81,        //         LOGICAL_MINIMUM (-127)
    0x25, 0x7f,        //         LOGICAL_MAXIMUM (127)
    0x35, 0x00,        //         PHYSICAL_MINIMUM (0)        - reset physical
    0x45, 0x00,        //         PHYSICAL_MAXIMUM (0)
    0x75, 0x08,        //         REPORT_SIZE (8)
    0x81, 0x06,        //         INPUT (Data,Var,Rel)
    0xc0,              //       END_COLLECTION
    0xa1, 0x02,        //       COLLECTION (Logical)
                       // ------------------------------  Horizontal wheel res multiplier
    0x09, 0x48,        //         USAGE (Resolution Multiplier)
    0xb4,              //         POP
    0xb1, 0x02,        //         FEATURE (Data,Var,Abs)
                       // ------------------------------  Padding for Feature report
    0x35, 0x00,        //         PHYSICAL_MINIMUM (0)        - reset physical
    0x45, 0x00,        //         PHYSICAL_MAXIMUM (0)
    0x75, 0x04,        //         REPORT_SIZE (4)
    0xb1, 0x03,        //         FEATURE (Cnst,Var,Abs)
                       // ------------------------------  Horizontal wheel
    0x05, 0x0c,        //         USAGE_PAGE (Consumer Devices)
    0x0a, 0x38, 0x02,  //         USAGE (AC Pan)
    0x15, 0x81,        //         LOGICAL_MINIMUM (-127)
    0x25, 0x7f,        //         LOGICAL_MAXIMUM (127)
    0x75, 0x08,        //         REPORT_SIZE (8)
    0x81, 0x06,        //         INPUT (Data,Var,Rel)
    0xc0,              //       END_COLLECTION
    0xc0,              //     END_COLLECTION
    0xc0,              //   END_COLLECTION
    0xc0               // END_COLLECTION
*/

/*
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x02,                    // USAGE (Mouse)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x09, 0x02,                    //   USAGE (Mouse)
    0xa1, 0x02,                    //   COLLECTION (Logical)
    0x09, 0x01,                    //     USAGE (Pointer)
    0xa1, 0x00,                    //     COLLECTION (Physical)
    0x05, 0x09,                    //       USAGE_PAGE (Button)
    0x19, 0x01,                    //       USAGE_MINIMUM (Button 1)
    0x29, 0x05,                    //       USAGE_MAXIMUM (Button 5)
    0x15, 0x00,                    //       LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //       LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //       REPORT_SIZE (1)
    0x95, 0x05,                    //       REPORT_COUNT (5)
    0x81, 0x02,                    //       INPUT (Data,Var,Abs)
    0x75, 0x03,                    //       REPORT_SIZE (3)
    0x95, 0x01,                    //       REPORT_COUNT (1)
    0x81, 0x03,                    //       INPUT (Cnst,Var,Abs)
    0x05, 0x01,                    //       USAGE_PAGE (Generic Desktop)
    0x09, 0x30,                    //       USAGE (X)
    0x09, 0x31,                    //       USAGE (Y)
    0x15, 0x81,                    //       LOGICAL_MINIMUM (-127)
    0x25, 0x7f,                    //       LOGICAL_MAXIMUM (127)
    0x75, 0x08,                    //       REPORT_SIZE (8)
    0x95, 0x02,                    //       REPORT_COUNT (2)
    0x81, 0x06,                    //       INPUT (Data,Var,Rel)
    0xa1, 0x02,                    //       COLLECTION (Logical)
    0x09, 0x48,                    //         USAGE (Resolution Multiplier)
    0x15, 0x00,                    //         LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //         LOGICAL_MAXIMUM (1)
    0x35, 0x01,                    //         PHYSICAL_MINIMUM (1)
    0x45, 0x04,                    //         PHYSICAL_MAXIMUM (4)
    0x75, 0x02,                    //         REPORT_SIZE (2)
    0x95, 0x01,                    //         REPORT_COUNT (1)
    0xb1, 0x02,                    //         FEATURE (Data,Var,Abs)
    0x09, 0x38,                    //         USAGE (Wheel)
    0x15, 0x81,                    //         LOGICAL_MINIMUM (-127)
    0x25, 0x7f,                    //         LOGICAL_MAXIMUM (127)
    0x35, 0x00,                    //         PHYSICAL_MINIMUM (0)
    0x45, 0x00,                    //         PHYSICAL_MAXIMUM (0)
    0x75, 0x08,                    //         REPORT_SIZE (8)
    0x81, 0x06,                    //         INPUT (Data,Var,Rel)
    0xc0,                          //       END_COLLECTION
    0xa1, 0x02,                    //       COLLECTION (Logical)
    0x09, 0x48,                    //         USAGE (Resolution Multiplier)
    0x15, 0x00,                    //         LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //         LOGICAL_MAXIMUM (1)
    0x35, 0x01,                    //         PHYSICAL_MINIMUM (1)
    0x45, 0x04,                    //         PHYSICAL_MAXIMUM (4)
    0x75, 0x02,                    //         REPORT_SIZE (2)
    0xb1, 0x02,                    //         FEATURE (Data,Var,Abs)
    0x35, 0x00,                    //         PHYSICAL_MINIMUM (0)
    0x45, 0x00,                    //         PHYSICAL_MAXIMUM (0)
    0x75, 0x04,                    //         REPORT_SIZE (4)
    0xb1, 0x03,                    //         FEATURE (Cnst,Var,Abs)
    0x05, 0x0c,                    //         USAGE_PAGE (Consumer Devices)
    0x0a, 0x38, 0x02,              //         USAGE (AC Pan)
    0x15, 0x81,                    //         LOGICAL_MINIMUM (-127)
    0x25, 0x7f,                    //         LOGICAL_MAXIMUM (127)
    0x75, 0x08,                    //         REPORT_SIZE (8)
    0x81, 0x06,                    //         INPUT (Data,Var,Rel)
    0xc0,                          //       END_COLLECTION
    0xc0,                          //     END_COLLECTION
    0xc0,                          //   END_COLLECTION
    0xc0                           // END_COLLECTION
*/


M mykey.c => mykey.c +38 -15
@@ 75,18 75,22 @@ int main(void)


    matrix_init();
    print("firmware 0.2 for t.m.k.\n");
    print("firmware 0.3 for t.m.k.\n");

    bool modified = false;
    bool has_ghost = false;
    int key_index = 0;
    int loop_count = 0;
    int layer = 0;
    int key_index = 0;
    uint8_t mouse_x = 0;
    uint8_t mouse_y = 0;
    uint8_t mouse_btn = 0;
    int8_t mouse_wheel = 0;
    int8_t mouse_hwheel = 0;
    while (1) {
        matrix_scan();
        layer = get_layer();
        modified = matrix_is_modified();
        has_ghost = matrix_has_ghost();
        layer = get_layer();

        // print matrix state for debug
        if (modified) {


@@ 97,10 101,16 @@ int main(void)
            PORTD |= 1<<PD6;
        }

        // set matrix state to keyboard_keys, keyboard_modifier_keys
        key_index = 0;
        keyboard_modifier_keys = 0;
        for (int i = 0; i < 6; i++) keyboard_keys[i] = KB_NO;
        key_index = 0;
        mouse_x = 0;
        mouse_y = 0;
        mouse_btn = 0;
        mouse_wheel = 0;
        mouse_hwheel = 0;

        // convert matrix state to HID report
        for (int row = 0; row < MATRIX_ROWS; row++) {
            for (int col = 0; col < MATRIX_COLS; col++) {
                if (matrix[row] & 1<<col) continue;


@@ 111,6 121,21 @@ int main(void)
                } else if (KB_LCTRL <= code && code <= KB_RGUI) {
                    // modifier keycode: 0xE0-0xE7
                    keyboard_modifier_keys |= 1<<(code & 0x07);
                } else if (code >= MS_UP) {
                    // mouse
                    if (code == MS_UP)    mouse_y -= 15;
                    if (code == MS_DOWN)  mouse_y += 15;
                    if (code == MS_LEFT)  mouse_x -= 15;
                    if (code == MS_RIGHT) mouse_x += 15;
                    if (code == MS_BTN1)  mouse_btn |= 1<<0;
                    if (code == MS_BTN2)  mouse_btn |= 1<<1;
                    if (code == MS_BTN3)  mouse_btn |= 1<<2;
                    if (code == MS_BTN4)  mouse_btn |= 1<<3;
                    if (code == MS_BTN5)  mouse_btn |= 1<<4;
                    if (code == MS_WH_UP)  mouse_wheel -= 1;
                    if (code == MS_WH_DOWN)  mouse_wheel += 1;
                    if (code == MS_WH_LEFT)  mouse_hwheel -= 1;
                    if (code == MS_WH_RIGHT) mouse_hwheel += 1;
                } else {
                    if (key_index < 6)
                        keyboard_keys[key_index] = code;


@@ 127,18 152,17 @@ int main(void)
                for (int i = 0; i < 6; i++) keyboard_keys[i] = KB_NO;
                usb_keyboard_send();

                /*
                print("jump to bootloader...\n");
                _delay_ms(1000);
                jump_bootloader();
                */

                // mouse
                print("usb_mouse_move\n");
                usb_mouse_move(10, 0, 0);
                jump_bootloader(); // not return
            }

            if (mouse_x || mouse_y || mouse_wheel || mouse_hwheel || mouse_btn != mouse_buttons) {
                mouse_buttons = mouse_btn;
                print("mouse_buttons: 0b"); pbin(mouse_buttons); print("\n");
                print("mouse_wheel: 0x"); phex(mouse_wheel); print("\n");
                usb_mouse_move(mouse_x, mouse_y, mouse_wheel, mouse_hwheel);
                _delay_ms(100);
                continue;
            }




@@ 150,7 174,6 @@ int main(void)
                usb_keyboard_send();
            }
        }
        loop_count++;
        _delay_ms(2);
    }
}

M usb.c => usb.c +42 -26
@@ 28,6 28,7 @@
#include "usb_keyboard.h"
#include "usb_mouse.h"
#include "usb_debug.h"
#include "print.h"


/**************************************************************************


@@ 145,33 146,36 @@ static uint8_t PROGMEM keyboard_hid_report_desc[] = {
};

// Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
// http://www.microchip.com/forums/tm.aspx?high=&m=391435&mpage=1#391521
// http://www.keil.com/forum/15671/
// http://www.microsoft.com/whdc/device/input/wheel.mspx
static uint8_t PROGMEM mouse_hid_report_desc[] = {
	0x05, 0x01,			// Usage Page (Generic Desktop)
	0x09, 0x02,			// Usage (Mouse)
	0xA1, 0x01,			// Collection (Application)
	0x05, 0x09,			//   Usage Page (Button)
	0x19, 0x01,			//   Usage Minimum (Button #1)
	0x29, 0x03,			//   Usage Maximum (Button #3)
	0x15, 0x00,			//   Logical Minimum (0)
	0x25, 0x01,			//   Logical Maximum (1)
	0x95, 0x03,			//   Report Count (3)
	0x75, 0x01,			//   Report Size (1)
	0x81, 0x02,			//   Input (Data, Variable, Absolute)
	0x95, 0x01,			//   Report Count (1)
	0x75, 0x05,			//   Report Size (5)
	0x81, 0x03,			//   Input (Constant)
	0x05, 0x01,			//   Usage Page (Generic Desktop)
	0x09, 0x30,			//   Usage (X)
	0x09, 0x31,			//   Usage (Y)
	0x15, 0x81,			//   Logical Minimum (-127)
	0x25, 0x7F,			//   Logical Maximum (127)
	0x75, 0x08,			//   Report Size (8),
	0x95, 0x02,			//   Report Count (2),
	0x81, 0x06,			//   Input (Data, Variable, Relative)
	0x09, 0x38,			//   Usage (Wheel)
	0x95, 0x01,			//   Report Count (1),
	0x81, 0x06,			//   Input (Data, Variable, Relative)
	0xC0				// End Collection
    0x05, 0x01,                     // Usage Page (Generic Desktop)
    0x09, 0x02,                     // Usage (Mouse)
    0xA1, 0x01,                     // Collection (Application)
    0x05, 0x09,                     //   Usage Page (Button)
    0x19, 0x01,                     //   Usage Minimum (Button #1)
    0x29, 0x03,                     //   Usage Maximum (Button #3)
    0x15, 0x00,                     //   Logical Minimum (0)
    0x25, 0x01,                     //   Logical Maximum (1)
    0x95, 0x03,                     //   Report Count (3)
    0x75, 0x01,                     //   Report Size (1)
    0x81, 0x02,                     //   Input (Data, Variable, Absolute)
    0x95, 0x01,                     //   Report Count (1)
    0x75, 0x05,                     //   Report Size (5)
    0x81, 0x03,                     //   Input (Constant)
    0x05, 0x01,                     //   Usage Page (Generic Desktop)
    0x09, 0x30,                     //   Usage (X)
    0x09, 0x31,                     //   Usage (Y)
    0x15, 0x81,                     //   Logical Minimum (-127)
    0x25, 0x7F,                     //   Logical Maximum (127)
    0x75, 0x08,                     //   Report Size (8),
    0x95, 0x02,                     //   Report Count (2),
    0x81, 0x06,                     //   Input (Data, Variable, Relative)
    0x09, 0x38,                     //   Usage (Wheel)
    0x95, 0x01,                     //   Report Count (1),
    0x81, 0x06,                     //   Input (Data, Variable, Relative)
    0xC0                            // End Collection
};

static uint8_t PROGMEM debug_hid_report_desc[] = {


@@ 642,7 646,10 @@ ISR(USB_COM_vect)
		}
		if (wIndex == MOUSE_INTERFACE) {
			if (bmRequestType == 0xA1) {
print("mouse: 0xA1\n");
				if (bRequest == HID_GET_REPORT) {
                                    if (wValue == HID_REPORT_INPUT) {
print("mouse: HID_GET_REPORT: input\n");
					usb_wait_in_ready();
					UEDATX = mouse_buttons;
					UEDATX = 0;


@@ 650,6 657,14 @@ ISR(USB_COM_vect)
					UEDATX = 0;
					usb_send_in();
					return;
                                    }
                                    if (wValue == HID_REPORT_FEATURE) {
print("mouse: HID_GET_REPORT: feature\n");
					usb_wait_in_ready();
					UEDATX = 0x05;
					usb_send_in();
					return;
                                    }
				}
				if (bRequest == HID_GET_PROTOCOL) {
					usb_wait_in_ready();


@@ 659,6 674,7 @@ ISR(USB_COM_vect)
				}
			}
			if (bmRequestType == 0x21) {
print("mouse: 0x21\n");
				if (bRequest == HID_SET_PROTOCOL) {
					mouse_protocol = wValue;
					usb_send_in();

M usb.h => usb.h +3 -0
@@ 71,6 71,9 @@ uint8_t usb_configured(void);		// is the USB port configured
#define HID_SET_REPORT			9
#define HID_SET_IDLE			10
#define HID_SET_PROTOCOL		11
#define HID_REPORT_INPUT		1
#define HID_REPORT_OUTPUT		2
#define HID_REPORT_FEATURE		3
// CDC (communication class device)
#define CDC_SET_LINE_CODING		0x20
#define CDC_GET_LINE_CODING		0x21

M usb_keycodes.h => usb_keycodes.h +14 -1
@@ 262,10 262,23 @@ enum keycodes {
    KB_RGUI,            /* 0x80 */

    /* extensions for internal use */
    FN_0 = 0xF0,
    FN_0 = 0xE8,
    FN_1,
    FN_2,
    FN_3,
    MS_UP = 0xF0,
    MS_DOWN,
    MS_LEFT,
    MS_RIGHT,
    MS_BTN1 = 0xF4,
    MS_BTN2,
    MS_BTN3,
    MS_BTN4,
    MS_BTN5,
    MS_WH_UP,
    MS_WH_DOWN,
    MS_WH_LEFT,
    MS_WH_RIGHT,
};

#endif /* USB_KEYCODES_H */

M usb_mouse.c => usb_mouse.c +4 -3
@@ 22,11 22,11 @@ int8_t usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right)
	if (middle) mask |= 4;
	if (right) mask |= 2;
	mouse_buttons = mask;
	return usb_mouse_move(0, 0, 0);
	return usb_mouse_move(0, 0, 0, 0);
}

// Move the mouse.  x, y and wheel are -127 to 127.  Use 0 for no movement.
int8_t usb_mouse_move(int8_t x, int8_t y, int8_t wheel)
int8_t usb_mouse_move(int8_t x, int8_t y, int8_t wheel, int8_t hwheel)
{
	uint8_t intr_state, timeout;



@@ 34,6 34,7 @@ int8_t usb_mouse_move(int8_t x, int8_t y, int8_t wheel)
	if (x == -128) x = -127;
	if (y == -128) y = -127;
	if (wheel == -128) wheel = -127;
	if (hwheel == -128) hwheel = -127;
	intr_state = SREG;
	cli();
	UENUM = MOUSE_ENDPOINT;


@@ 55,8 56,8 @@ int8_t usb_mouse_move(int8_t x, int8_t y, int8_t wheel)
	UEDATX = x;
	UEDATX = y;
	UEDATX = wheel;
	//UEDATX = hwheel;
	UEINTX = 0x3A;
	SREG = intr_state;
	return 0;
}


M usb_mouse.h => usb_mouse.h +1 -1
@@ 15,6 15,6 @@ extern uint8_t mouse_protocol;


int8_t usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right);
int8_t usb_mouse_move(int8_t x, int8_t y, int8_t wheel);
int8_t usb_mouse_move(int8_t x, int8_t y, int8_t wheel, int8_t hwheel);

#endif