report.h (10410B)
1 /* 2 Copyright 2011,2012 Jun Wako <wakojun@gmail.com> 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #pragma once 19 20 #include <stdint.h> 21 #include <stdbool.h> 22 #include "keycode.h" 23 #include "util.h" 24 25 #ifdef JOYSTICK_ENABLE 26 # include "joystick.h" 27 #endif 28 29 // clang-format off 30 31 /* HID report IDs */ 32 enum hid_report_ids { 33 REPORT_ID_ALL = 0, 34 REPORT_ID_KEYBOARD = 1, 35 REPORT_ID_MOUSE, 36 REPORT_ID_SYSTEM, 37 REPORT_ID_CONSUMER, 38 REPORT_ID_PROGRAMMABLE_BUTTON, 39 REPORT_ID_NKRO, 40 REPORT_ID_JOYSTICK, 41 REPORT_ID_DIGITIZER, 42 REPORT_ID_COUNT = REPORT_ID_DIGITIZER 43 }; 44 45 #define IS_VALID_REPORT_ID(id) ((id) >= REPORT_ID_ALL && (id) <= REPORT_ID_COUNT) 46 47 /* Mouse buttons */ 48 #define MOUSE_BTN_MASK(n) (1 << (n)) 49 enum mouse_buttons { 50 MOUSE_BTN1 = MOUSE_BTN_MASK(0), 51 MOUSE_BTN2 = MOUSE_BTN_MASK(1), 52 MOUSE_BTN3 = MOUSE_BTN_MASK(2), 53 MOUSE_BTN4 = MOUSE_BTN_MASK(3), 54 MOUSE_BTN5 = MOUSE_BTN_MASK(4), 55 MOUSE_BTN6 = MOUSE_BTN_MASK(5), 56 MOUSE_BTN7 = MOUSE_BTN_MASK(6), 57 MOUSE_BTN8 = MOUSE_BTN_MASK(7) 58 }; 59 60 /* Consumer Page (0x0C) 61 * 62 * See https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf#page=75 63 */ 64 enum consumer_usages { 65 // 15.5 Display Controls 66 SNAPSHOT = 0x065, 67 BRIGHTNESS_UP = 0x06F, // https://www.usb.org/sites/default/files/hutrr41_0.pdf 68 BRIGHTNESS_DOWN = 0x070, 69 // 15.7 Transport Controls 70 TRANSPORT_RECORD = 0x0B2, 71 TRANSPORT_FAST_FORWARD = 0x0B3, 72 TRANSPORT_REWIND = 0x0B4, 73 TRANSPORT_NEXT_TRACK = 0x0B5, 74 TRANSPORT_PREV_TRACK = 0x0B6, 75 TRANSPORT_STOP = 0x0B7, 76 TRANSPORT_EJECT = 0x0B8, 77 TRANSPORT_RANDOM_PLAY = 0x0B9, 78 TRANSPORT_STOP_EJECT = 0x0CC, 79 TRANSPORT_PLAY_PAUSE = 0x0CD, 80 // 15.9.1 Audio Controls - Volume 81 AUDIO_MUTE = 0x0E2, 82 AUDIO_VOL_UP = 0x0E9, 83 AUDIO_VOL_DOWN = 0x0EA, 84 // 15.15 Application Launch Buttons 85 AL_CC_CONFIG = 0x183, 86 AL_EMAIL = 0x18A, 87 AL_CALCULATOR = 0x192, 88 AL_LOCAL_BROWSER = 0x194, 89 AL_LOCK = 0x19E, 90 AL_CONTROL_PANEL = 0x19F, 91 AL_ASSISTANT = 0x1CB, 92 AL_KEYBOARD_LAYOUT = 0x1AE, 93 // 15.16 Generic GUI Application Controls 94 AC_NEW = 0x201, 95 AC_OPEN = 0x202, 96 AC_CLOSE = 0x203, 97 AC_EXIT = 0x204, 98 AC_MAXIMIZE = 0x205, 99 AC_MINIMIZE = 0x206, 100 AC_SAVE = 0x207, 101 AC_PRINT = 0x208, 102 AC_PROPERTIES = 0x209, 103 AC_UNDO = 0x21A, 104 AC_COPY = 0x21B, 105 AC_CUT = 0x21C, 106 AC_PASTE = 0x21D, 107 AC_SELECT_ALL = 0x21E, 108 AC_FIND = 0x21F, 109 AC_SEARCH = 0x221, 110 AC_HOME = 0x223, 111 AC_BACK = 0x224, 112 AC_FORWARD = 0x225, 113 AC_STOP = 0x226, 114 AC_REFRESH = 0x227, 115 AC_BOOKMARKS = 0x22A, 116 AC_NEXT_KEYBOARD_LAYOUT_SELECT = 0x29D, 117 AC_DESKTOP_SHOW_ALL_WINDOWS = 0x29F, 118 AC_SOFT_KEY_LEFT = 0x2A0 119 }; 120 121 /* Generic Desktop Page (0x01) 122 * 123 * See https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf#page=26 124 */ 125 enum desktop_usages { 126 // 4.5.1 System Controls - Power Controls 127 SYSTEM_POWER_DOWN = 0x81, 128 SYSTEM_SLEEP = 0x82, 129 SYSTEM_WAKE_UP = 0x83, 130 SYSTEM_RESTART = 0x8F, 131 // 4.10 System Display Controls 132 SYSTEM_DISPLAY_TOGGLE_INT_EXT = 0xB5 133 }; 134 135 // clang-format on 136 137 #define NKRO_REPORT_BITS 30 138 139 #ifdef KEYBOARD_SHARED_EP 140 # define KEYBOARD_REPORT_SIZE 9 141 #else 142 # define KEYBOARD_REPORT_SIZE 8 143 #endif 144 145 #define KEYBOARD_REPORT_KEYS 6 146 147 #ifdef __cplusplus 148 extern "C" { 149 #endif 150 151 /* 152 * keyboard report is 8-byte array retains state of 8 modifiers and 6 keys. 153 * 154 * byte |0 |1 |2 |3 |4 |5 |6 |7 155 * -----+--------+--------+--------+--------+--------+--------+--------+-------- 156 * desc |mods |reserved|keys[0] |keys[1] |keys[2] |keys[3] |keys[4] |keys[5] 157 * 158 * It is exended to 16 bytes to retain 120keys+8mods when NKRO mode. 159 * 160 * byte |0 |1 |2 |3 |4 |5 |6 |7 ... |15 161 * -----+--------+--------+--------+--------+--------+--------+--------+-------- +-------- 162 * desc |mods |bits[0] |bits[1] |bits[2] |bits[3] |bits[4] |bits[5] |bits[6] ... |bit[14] 163 * 164 * mods retains state of 8 modifiers. 165 * 166 * bit |0 |1 |2 |3 |4 |5 |6 |7 167 * -----+--------+--------+--------+--------+--------+--------+--------+-------- 168 * desc |Lcontrol|Lshift |Lalt |Lgui |Rcontrol|Rshift |Ralt |Rgui 169 * 170 */ 171 typedef struct { 172 #ifdef KEYBOARD_SHARED_EP 173 uint8_t report_id; 174 #endif 175 uint8_t mods; 176 uint8_t reserved; 177 uint8_t keys[KEYBOARD_REPORT_KEYS]; 178 } PACKED report_keyboard_t; 179 180 typedef struct { 181 uint8_t report_id; 182 uint8_t mods; 183 uint8_t bits[NKRO_REPORT_BITS]; 184 } PACKED report_nkro_t; 185 186 typedef struct { 187 uint8_t report_id; 188 uint16_t usage; 189 } PACKED report_extra_t; 190 191 typedef struct { 192 uint8_t report_id; 193 uint32_t usage; 194 } PACKED report_programmable_button_t; 195 196 #ifdef MOUSE_EXTENDED_REPORT 197 # define MOUSE_REPORT_XY_MIN INT16_MIN 198 # define MOUSE_REPORT_XY_MAX INT16_MAX 199 typedef int16_t mouse_xy_report_t; 200 #else 201 # define MOUSE_REPORT_XY_MIN INT8_MIN 202 # define MOUSE_REPORT_XY_MAX INT8_MAX 203 typedef int8_t mouse_xy_report_t; 204 #endif 205 206 #ifdef WHEEL_EXTENDED_REPORT 207 # define MOUSE_REPORT_HV_MIN INT16_MIN 208 # define MOUSE_REPORT_HV_MAX INT16_MAX 209 typedef int16_t mouse_hv_report_t; 210 #else 211 # define MOUSE_REPORT_HV_MIN INT8_MIN 212 # define MOUSE_REPORT_HV_MAX INT8_MAX 213 typedef int8_t mouse_hv_report_t; 214 #endif 215 216 typedef struct { 217 #ifdef MOUSE_SHARED_EP 218 uint8_t report_id; 219 #endif 220 uint8_t buttons; 221 #ifdef MOUSE_EXTENDED_REPORT 222 int8_t boot_x; 223 int8_t boot_y; 224 #endif 225 mouse_xy_report_t x; 226 mouse_xy_report_t y; 227 mouse_hv_report_t v; 228 mouse_hv_report_t h; 229 } PACKED report_mouse_t; 230 231 typedef struct { 232 #ifdef DIGITIZER_SHARED_EP 233 uint8_t report_id; 234 #endif 235 bool in_range : 1; 236 bool tip : 1; 237 bool barrel : 1; 238 uint8_t reserved : 5; 239 uint16_t x; 240 uint16_t y; 241 } PACKED report_digitizer_t; 242 243 #if JOYSTICK_AXIS_RESOLUTION > 8 244 typedef int16_t joystick_axis_t; 245 #else 246 typedef int8_t joystick_axis_t; 247 #endif 248 249 typedef struct { 250 #ifdef JOYSTICK_SHARED_EP 251 uint8_t report_id; 252 #endif 253 #if JOYSTICK_AXIS_COUNT > 0 254 joystick_axis_t axes[JOYSTICK_AXIS_COUNT]; 255 #endif 256 257 #ifdef JOYSTICK_HAS_HAT 258 int8_t hat : 4; 259 uint8_t reserved : 4; 260 #endif 261 262 #if JOYSTICK_BUTTON_COUNT > 0 263 uint8_t buttons[(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1]; 264 #endif 265 } PACKED report_joystick_t; 266 267 /* keycode to system usage */ 268 static inline uint16_t KEYCODE2SYSTEM(uint8_t key) { 269 switch (key) { 270 case KC_SYSTEM_POWER: 271 return SYSTEM_POWER_DOWN; 272 case KC_SYSTEM_SLEEP: 273 return SYSTEM_SLEEP; 274 case KC_SYSTEM_WAKE: 275 return SYSTEM_WAKE_UP; 276 default: 277 return 0; 278 } 279 } 280 281 /* keycode to consumer usage */ 282 static inline uint16_t KEYCODE2CONSUMER(uint8_t key) { 283 switch (key) { 284 case KC_AUDIO_MUTE: 285 return AUDIO_MUTE; 286 case KC_AUDIO_VOL_UP: 287 return AUDIO_VOL_UP; 288 case KC_AUDIO_VOL_DOWN: 289 return AUDIO_VOL_DOWN; 290 case KC_MEDIA_NEXT_TRACK: 291 return TRANSPORT_NEXT_TRACK; 292 case KC_MEDIA_PREV_TRACK: 293 return TRANSPORT_PREV_TRACK; 294 case KC_MEDIA_FAST_FORWARD: 295 return TRANSPORT_FAST_FORWARD; 296 case KC_MEDIA_REWIND: 297 return TRANSPORT_REWIND; 298 case KC_MEDIA_STOP: 299 return TRANSPORT_STOP; 300 case KC_MEDIA_EJECT: 301 return TRANSPORT_STOP_EJECT; 302 case KC_MEDIA_PLAY_PAUSE: 303 return TRANSPORT_PLAY_PAUSE; 304 case KC_MEDIA_SELECT: 305 return AL_CC_CONFIG; 306 case KC_MAIL: 307 return AL_EMAIL; 308 case KC_CALCULATOR: 309 return AL_CALCULATOR; 310 case KC_MY_COMPUTER: 311 return AL_LOCAL_BROWSER; 312 case KC_CONTROL_PANEL: 313 return AL_CONTROL_PANEL; 314 case KC_ASSISTANT: 315 return AL_ASSISTANT; 316 case KC_WWW_SEARCH: 317 return AC_SEARCH; 318 case KC_WWW_HOME: 319 return AC_HOME; 320 case KC_WWW_BACK: 321 return AC_BACK; 322 case KC_WWW_FORWARD: 323 return AC_FORWARD; 324 case KC_WWW_STOP: 325 return AC_STOP; 326 case KC_WWW_REFRESH: 327 return AC_REFRESH; 328 case KC_BRIGHTNESS_UP: 329 return BRIGHTNESS_UP; 330 case KC_BRIGHTNESS_DOWN: 331 return BRIGHTNESS_DOWN; 332 case KC_WWW_FAVORITES: 333 return AC_BOOKMARKS; 334 case KC_MISSION_CONTROL: 335 return AC_DESKTOP_SHOW_ALL_WINDOWS; 336 case KC_LAUNCHPAD: 337 return AC_SOFT_KEY_LEFT; 338 default: 339 return 0; 340 } 341 } 342 343 uint8_t has_anykey(void); 344 uint8_t get_first_key(void); 345 bool is_key_pressed(uint8_t key); 346 347 void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code); 348 void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code); 349 #ifdef NKRO_ENABLE 350 void add_key_bit(report_nkro_t* nkro_report, uint8_t code); 351 void del_key_bit(report_nkro_t* nkro_report, uint8_t code); 352 #endif 353 354 void add_key_to_report(uint8_t key); 355 void del_key_from_report(uint8_t key); 356 void clear_keys_from_report(void); 357 358 #ifdef MOUSE_ENABLE 359 bool has_mouse_report_changed(report_mouse_t* new_report, report_mouse_t* old_report); 360 #endif 361 362 #ifdef __cplusplus 363 } 364 #endif