Add support for 8 buttons to mouse report (#10807)

* Add support for 8 buttons to mouse report

This includes support for 8 buttons in mousekeys.  However, this does move the keys around due to the fact that the last mousekey keycode is already 0xFF, so any past that would not work with register_code and the like, breaking them for tap hold keys, encoders, and other features.

* Update mouse key docs

* Add changes based on feedback

* Fix VUSB report size comment

Because drashna red gud

* Fix typo in action.c

* Fix IS_MOUSE_BUTTON check

* Change start range for mousekeys so that the end is 0xFF properly

* condense mousekeys check
This commit is contained in:
Drashna Jaelre 2021-01-27 09:38:34 -08:00 committed by GitHub
parent bab9849a8b
commit 99f3df2893
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 54 additions and 61 deletions

View File

@ -29,6 +29,9 @@ In your keymap you can use the following keycodes to map key presses to mouse ac
|`KC_MS_BTN3` |`KC_BTN3`|Press button 3 | |`KC_MS_BTN3` |`KC_BTN3`|Press button 3 |
|`KC_MS_BTN4` |`KC_BTN4`|Press button 4 | |`KC_MS_BTN4` |`KC_BTN4`|Press button 4 |
|`KC_MS_BTN5` |`KC_BTN5`|Press button 5 | |`KC_MS_BTN5` |`KC_BTN5`|Press button 5 |
|`KC_MS_BTN6` |`KC_BTN6`|Press button 6 |
|`KC_MS_BTN7` |`KC_BTN7`|Press button 7 |
|`KC_MS_BTN8` |`KC_BTN8`|Press button 8 |
|`KC_MS_WH_UP` |`KC_WH_U`|Move wheel up | |`KC_MS_WH_UP` |`KC_WH_U`|Move wheel up |
|`KC_MS_WH_DOWN` |`KC_WH_D`|Move wheel down | |`KC_MS_WH_DOWN` |`KC_WH_D`|Move wheel down |
|`KC_MS_WH_LEFT` |`KC_WH_L`|Move wheel left | |`KC_MS_WH_LEFT` |`KC_WH_L`|Move wheel left |

View File

@ -19,7 +19,7 @@ Keep in mind that a report_mouse_t (here "mouseReport") has the following proper
* `mouseReport.y` - this is a signed int from -127 to 127 (not 128, this is defined in USB HID spec) representing movement (+ upward, - downward) on the y axis. * `mouseReport.y` - this is a signed int from -127 to 127 (not 128, this is defined in USB HID spec) representing movement (+ upward, - downward) on the y axis.
* `mouseReport.v` - this is a signed int from -127 to 127 (not 128, this is defined in USB HID spec) representing vertical scrolling (+ upward, - downward). * `mouseReport.v` - this is a signed int from -127 to 127 (not 128, this is defined in USB HID spec) representing vertical scrolling (+ upward, - downward).
* `mouseReport.h` - this is a signed int from -127 to 127 (not 128, this is defined in USB HID spec) representing horizontal scrolling (+ right, - left). * `mouseReport.h` - this is a signed int from -127 to 127 (not 128, this is defined in USB HID spec) representing horizontal scrolling (+ right, - left).
* `mouseReport.buttons` - this is a uint8_t in which the last 5 bits are used. These bits represent the mouse button state - bit 3 is mouse button 5, and bit 7 is mouse button 1. * `mouseReport.buttons` - this is a uint8_t in which all 8 bits are used. These bits represent the mouse button state - bit 0 is mouse button 1, and bit 7 is mouse button 8.
Once you have made the necessary changes to the mouse report, you need to send it: Once you have made the necessary changes to the mouse report, you need to send it:

View File

@ -34,6 +34,9 @@ MOUSEKEY_ENABLE = yes
| `KC_MS_BTN3` | `KC_BTN3` | ボタン3を押す | | `KC_MS_BTN3` | `KC_BTN3` | ボタン3を押す |
| `KC_MS_BTN4` | `KC_BTN4` | ボタン4を押す | | `KC_MS_BTN4` | `KC_BTN4` | ボタン4を押す |
| `KC_MS_BTN5` | `KC_BTN5` | ボタン5を押す | | `KC_MS_BTN5` | `KC_BTN5` | ボタン5を押す |
| `KC_MS_BTN6` | `KC_BTN6` | ボタン6を押す |
| `KC_MS_BTN7` | `KC_BTN7` | ボタン7を押す |
| `KC_MS_BTN8` | `KC_BTN8` | ボタン8を押す |
| `KC_MS_WH_UP` | `KC_WH_U` | ホイールを向こう側に回転 | | `KC_MS_WH_UP` | `KC_WH_U` | ホイールを向こう側に回転 |
| `KC_MS_WH_DOWN` | `KC_WH_D` | ホイールを手前側に回転 | | `KC_MS_WH_DOWN` | `KC_WH_D` | ホイールを手前側に回転 |
| `KC_MS_WH_LEFT` | `KC_WH_L` | ホイールを左に倒す | | `KC_MS_WH_LEFT` | `KC_WH_L` | ホイールを左に倒す |

View File

@ -443,6 +443,15 @@ void process_action(keyrecord_t *record, action_t action) {
case KC_MS_BTN5: case KC_MS_BTN5:
register_button(true, MOUSE_BTN5); register_button(true, MOUSE_BTN5);
break; break;
case KC_MS_BTN6:
register_button(true, MOUSE_BTN6);
break;
case KC_MS_BTN7:
register_button(true, MOUSE_BTN7);
break;
case KC_MS_BTN8:
register_button(true, MOUSE_BTN8);
break;
# endif # endif
default: default:
mousekey_send(); mousekey_send();
@ -469,6 +478,15 @@ void process_action(keyrecord_t *record, action_t action) {
case KC_MS_BTN5: case KC_MS_BTN5:
register_button(false, MOUSE_BTN5); register_button(false, MOUSE_BTN5);
break; break;
case KC_MS_BTN6:
register_button(false, MOUSE_BTN6);
break;
case KC_MS_BTN7:
register_button(false, MOUSE_BTN7);
break;
case KC_MS_BTN8:
register_button(false, MOUSE_BTN8);
break;
# endif # endif
default: default:
mousekey_send(); mousekey_send();

View File

@ -39,7 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2) #define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2)
#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT) #define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT)
#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN5) #define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN8)
#define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT) #define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT)
#define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2) #define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2)
@ -205,6 +205,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define KC_BTN3 KC_MS_BTN3 #define KC_BTN3 KC_MS_BTN3
#define KC_BTN4 KC_MS_BTN4 #define KC_BTN4 KC_MS_BTN4
#define KC_BTN5 KC_MS_BTN5 #define KC_BTN5 KC_MS_BTN5
#define KC_BTN6 KC_MS_BTN6
#define KC_BTN7 KC_MS_BTN7
#define KC_BTN8 KC_MS_BTN8
#define KC_WH_U KC_MS_WH_UP #define KC_WH_U KC_MS_WH_UP
#define KC_WH_D KC_MS_WH_DOWN #define KC_WH_D KC_MS_WH_DOWN
#define KC_WH_L KC_MS_WH_LEFT #define KC_WH_L KC_MS_WH_LEFT
@ -521,15 +524,18 @@ enum internal_special_keycodes {
enum mouse_keys { enum mouse_keys {
/* Mouse Buttons */ /* Mouse Buttons */
KC_MS_UP = 0xF0, KC_MS_UP = 0xED,
KC_MS_DOWN, KC_MS_DOWN,
KC_MS_LEFT, KC_MS_LEFT,
KC_MS_RIGHT, KC_MS_RIGHT, // 0xF0
KC_MS_BTN1, KC_MS_BTN1,
KC_MS_BTN2, KC_MS_BTN2,
KC_MS_BTN3, KC_MS_BTN3,
KC_MS_BTN4, KC_MS_BTN4,
KC_MS_BTN5, KC_MS_BTN5,
KC_MS_BTN6,
KC_MS_BTN7,
KC_MS_BTN8,
/* Mouse Wheel */ /* Mouse Wheel */
KC_MS_WH_UP, KC_MS_WH_UP,
@ -540,5 +546,5 @@ enum mouse_keys {
/* Acceleration */ /* Acceleration */
KC_MS_ACCEL0, KC_MS_ACCEL0,
KC_MS_ACCEL1, KC_MS_ACCEL1,
KC_MS_ACCEL2 KC_MS_ACCEL2 // 0xFF
}; };

View File

@ -278,16 +278,8 @@ void mousekey_on(uint8_t code) {
mouse_report.h = wheel_unit() * -1; mouse_report.h = wheel_unit() * -1;
else if (code == KC_MS_WH_RIGHT) else if (code == KC_MS_WH_RIGHT)
mouse_report.h = wheel_unit(); mouse_report.h = wheel_unit();
else if (code == KC_MS_BTN1) else if (IS_MOUSEKEY_BUTTON(code))
mouse_report.buttons |= MOUSE_BTN1; mouse_report.buttons |= 1 << (code - KC_MS_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) else if (code == KC_MS_ACCEL0)
mousekey_accel |= (1 << 0); mousekey_accel |= (1 << 0);
else if (code == KC_MS_ACCEL1) else if (code == KC_MS_ACCEL1)
@ -313,16 +305,8 @@ void mousekey_off(uint8_t code) {
mouse_report.h = 0; mouse_report.h = 0;
else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0) else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0)
mouse_report.h = 0; mouse_report.h = 0;
else if (code == KC_MS_BTN1) else if (IS_MOUSEKEY_BUTTON(code))
mouse_report.buttons &= ~MOUSE_BTN1; mouse_report.buttons &= ~(1 << (code - KC_MS_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) else if (code == KC_MS_ACCEL0)
mousekey_accel &= ~(1 << 0); mousekey_accel &= ~(1 << 0);
else if (code == KC_MS_ACCEL1) else if (code == KC_MS_ACCEL1)
@ -423,16 +407,8 @@ void mousekey_on(uint8_t code) {
mouse_report.h = w_offset * -1; mouse_report.h = w_offset * -1;
else if (code == KC_MS_WH_RIGHT) else if (code == KC_MS_WH_RIGHT)
mouse_report.h = w_offset; mouse_report.h = w_offset;
else if (code == KC_MS_BTN1) else if (IS_MOUSEKEY_BUTTON(code))
mouse_report.buttons |= MOUSE_BTN1; mouse_report.buttons |= 1 << (code - KC_MS_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) else if (code == KC_MS_ACCEL0)
mk_speed = mkspd_0; mk_speed = mkspd_0;
else if (code == KC_MS_ACCEL1) else if (code == KC_MS_ACCEL1)
@ -462,16 +438,8 @@ void mousekey_off(uint8_t code) {
mouse_report.h = 0; mouse_report.h = 0;
else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0) else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0)
mouse_report.h = 0; mouse_report.h = 0;
else if (code == KC_MS_BTN1) else if (IS_MOUSEKEY_BUTTON(code))
mouse_report.buttons &= ~MOUSE_BTN1; mouse_report.buttons &= ~(1 << (code - KC_MS_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;
# ifdef MK_MOMENTARY_ACCEL # ifdef MK_MOMENTARY_ACCEL
else if (code == KC_MS_ACCEL0) else if (code == KC_MS_ACCEL0)
mk_speed = mkspd_DEFAULT; mk_speed = mkspd_DEFAULT;

View File

@ -39,7 +39,10 @@ enum mouse_buttons {
MOUSE_BTN2 = (1 << 1), MOUSE_BTN2 = (1 << 1),
MOUSE_BTN3 = (1 << 2), MOUSE_BTN3 = (1 << 2),
MOUSE_BTN4 = (1 << 3), MOUSE_BTN4 = (1 << 3),
MOUSE_BTN5 = (1 << 4) MOUSE_BTN5 = (1 << 4),
MOUSE_BTN6 = (1 << 5),
MOUSE_BTN7 = (1 << 6),
MOUSE_BTN8 = (1 << 7)
}; };
/* Consumer Page (0x0C) /* Consumer Page (0x0C)

View File

@ -116,19 +116,15 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
# endif # endif
HID_RI_USAGE(8, 0x01), // Pointer HID_RI_USAGE(8, 0x01), // Pointer
HID_RI_COLLECTION(8, 0x00), // Physical HID_RI_COLLECTION(8, 0x00), // Physical
// Buttons (5 bits) // Buttons (8 bits)
HID_RI_USAGE_PAGE(8, 0x09), // Button HID_RI_USAGE_PAGE(8, 0x09), // Button
HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1 HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1
HID_RI_USAGE_MAXIMUM(8, 0x05), // Button 5 HID_RI_USAGE_MAXIMUM(8, 0x08), // Button 8
HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0x01), HID_RI_LOGICAL_MAXIMUM(8, 0x01),
HID_RI_REPORT_COUNT(8, 0x05), HID_RI_REPORT_COUNT(8, 0x08),
HID_RI_REPORT_SIZE(8, 0x01), HID_RI_REPORT_SIZE(8, 0x01),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
// Button padding (3 bits)
HID_RI_REPORT_COUNT(8, 0x01),
HID_RI_REPORT_SIZE(8, 0x03),
HID_RI_INPUT(8, HID_IOF_CONSTANT),
// X/Y position (2 bytes) // X/Y position (2 bytes)
HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop

View File

@ -444,19 +444,15 @@ const PROGMEM uchar shared_hid_report[] = {
0x85, REPORT_ID_MOUSE, // Report ID 0x85, REPORT_ID_MOUSE, // Report ID
0x09, 0x01, // Usage (Pointer) 0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection (Physical) 0xA1, 0x00, // Collection (Physical)
// Buttons (5 bits) // Buttons (8 bits)
0x05, 0x09, // Usage Page (Button) 0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button 1) 0x19, 0x01, // Usage Minimum (Button 1)
0x29, 0x05, // Usage Maximum (Button 5) 0x29, 0x08, // Usage Maximum (Button 8)
0x15, 0x00, // Logical Minimum (0) 0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1) 0x25, 0x01, // Logical Maximum (1)
0x95, 0x05, // Report Count (5) 0x95, 0x08, // Report Count (8)
0x75, 0x01, // Report Size (1) 0x75, 0x01, // Report Size (1)
0x81, 0x02, // Input (Data, Variable, Absolute) 0x81, 0x02, // Input (Data, Variable, Absolute)
// Button padding (3 bits)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x81, 0x03, // Input (Constant)
// X/Y position (2 bytes) // X/Y position (2 bytes)
0x05, 0x01, // Usage Page (Generic Desktop) 0x05, 0x01, // Usage Page (Generic Desktop)