diff options
| author | Ryan <fauxpark@gmail.com> | 2022-07-02 22:10:08 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-07-02 22:10:08 +1000 |
| commit | 3ecb0a80af9e4ce4194a34032642933641730706 (patch) | |
| tree | 3d4b0e24336762dc9b45a746334ebc09a5c59db1 /quantum/send_string | |
| parent | 7e41eb02773207dd4a014575fe750f8d511bfb5b (diff) | |
Feature-ify Send String (#17275)
Diffstat (limited to 'quantum/send_string')
| -rw-r--r-- | quantum/send_string/send_string.c | 324 | ||||
| -rw-r--r-- | quantum/send_string/send_string.h | 152 | ||||
| -rw-r--r-- | quantum/send_string/send_string_keycodes.h | 434 |
3 files changed, 910 insertions, 0 deletions
diff --git a/quantum/send_string/send_string.c b/quantum/send_string/send_string.c new file mode 100644 index 0000000000..818a52f6dc --- /dev/null +++ b/quantum/send_string/send_string.c | |||
| @@ -0,0 +1,324 @@ | |||
| 1 | /* Copyright 2021 | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <ctype.h> | ||
| 18 | |||
| 19 | #include "quantum.h" | ||
| 20 | |||
| 21 | #include "send_string.h" | ||
| 22 | |||
| 23 | #if defined(AUDIO_ENABLE) && defined(SENDSTRING_BELL) | ||
| 24 | # include "audio.h" | ||
| 25 | # ifndef BELL_SOUND | ||
| 26 | # define BELL_SOUND TERMINAL_SOUND | ||
| 27 | # endif | ||
| 28 | float bell_song[][2] = SONG(BELL_SOUND); | ||
| 29 | #endif | ||
| 30 | |||
| 31 | // clang-format off | ||
| 32 | |||
| 33 | /* Bit-Packed look-up table to convert an ASCII character to whether | ||
| 34 | * [Shift] needs to be sent with the keycode. | ||
| 35 | */ | ||
| 36 | __attribute__((weak)) const uint8_t ascii_to_shift_lut[16] PROGMEM = { | ||
| 37 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 38 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 39 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 40 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 41 | |||
| 42 | KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 0), | ||
| 43 | KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 0), | ||
| 44 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 45 | KCLUT_ENTRY(0, 0, 1, 0, 1, 0, 1, 1), | ||
| 46 | KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), | ||
| 47 | KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), | ||
| 48 | KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), | ||
| 49 | KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), | ||
| 50 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 51 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 52 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 53 | KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) | ||
| 54 | }; | ||
| 55 | |||
| 56 | /* Bit-Packed look-up table to convert an ASCII character to whether | ||
| 57 | * [AltGr] needs to be sent with the keycode. | ||
| 58 | */ | ||
| 59 | __attribute__((weak)) const uint8_t ascii_to_altgr_lut[16] PROGMEM = { | ||
| 60 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 61 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 62 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 63 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 64 | |||
| 65 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 66 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 67 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 68 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 69 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 70 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 71 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 72 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 73 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 74 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 75 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 76 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) | ||
| 77 | }; | ||
| 78 | |||
| 79 | /* Bit-Packed look-up table to convert an ASCII character to whether | ||
| 80 | * [Space] needs to be sent after the keycode | ||
| 81 | */ | ||
| 82 | __attribute__((weak)) const uint8_t ascii_to_dead_lut[16] PROGMEM = { | ||
| 83 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 84 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 85 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 86 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 87 | |||
| 88 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 89 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 90 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 91 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 92 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 93 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 94 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 95 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 96 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 97 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 98 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), | ||
| 99 | KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) | ||
| 100 | }; | ||
| 101 | |||
| 102 | /* Look-up table to convert an ASCII character to a keycode. | ||
| 103 | */ | ||
| 104 | __attribute__((weak)) const uint8_t ascii_to_keycode_lut[128] PROGMEM = { | ||
| 105 | // NUL SOH STX ETX EOT ENQ ACK BEL | ||
| 106 | XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | ||
| 107 | // BS TAB LF VT FF CR SO SI | ||
| 108 | KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | ||
| 109 | // DLE DC1 DC2 DC3 DC4 NAK SYN ETB | ||
| 110 | XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | ||
| 111 | // CAN EM SUB ESC FS GS RS US | ||
| 112 | XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | ||
| 113 | |||
| 114 | // ! " # $ % & ' | ||
| 115 | KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT, | ||
| 116 | // ( ) * + , - . / | ||
| 117 | KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH, | ||
| 118 | // 0 1 2 3 4 5 6 7 | ||
| 119 | KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, | ||
| 120 | // 8 9 : ; < = > ? | ||
| 121 | KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH, | ||
| 122 | // @ A B C D E F G | ||
| 123 | KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, | ||
| 124 | // H I J K L M N O | ||
| 125 | KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, | ||
| 126 | // P Q R S T U V W | ||
| 127 | KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, | ||
| 128 | // X Y Z [ \ ] ^ _ | ||
| 129 | KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS, | ||
| 130 | // ` a b c d e f g | ||
| 131 | KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, | ||
| 132 | // h i j k l m n o | ||
| 133 | KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, | ||
| 134 | // p q r s t u v w | ||
| 135 | KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, | ||
| 136 | // x y z { | } ~ DEL | ||
| 137 | KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL | ||
| 138 | }; | ||
| 139 | |||
| 140 | // clang-format on | ||
| 141 | |||
| 142 | // Note: we bit-pack in "reverse" order to optimize loading | ||
| 143 | #define PGM_LOADBIT(mem, pos) ((pgm_read_byte(&((mem)[(pos) / 8])) >> ((pos) % 8)) & 0x01) | ||
| 144 | |||
| 145 | void send_string(const char *string) { | ||
| 146 | send_string_with_delay(string, 0); | ||
| 147 | } | ||
| 148 | |||
| 149 | void send_string_with_delay(const char *string, uint8_t interval) { | ||
| 150 | while (1) { | ||
| 151 | char ascii_code = *string; | ||
| 152 | if (!ascii_code) break; | ||
| 153 | if (ascii_code == SS_QMK_PREFIX) { | ||
| 154 | ascii_code = *(++string); | ||
| 155 | if (ascii_code == SS_TAP_CODE) { | ||
| 156 | // tap | ||
| 157 | uint8_t keycode = *(++string); | ||
| 158 | tap_code(keycode); | ||
| 159 | } else if (ascii_code == SS_DOWN_CODE) { | ||
| 160 | // down | ||
| 161 | uint8_t keycode = *(++string); | ||
| 162 | register_code(keycode); | ||
| 163 | } else if (ascii_code == SS_UP_CODE) { | ||
| 164 | // up | ||
| 165 | uint8_t keycode = *(++string); | ||
| 166 | unregister_code(keycode); | ||
| 167 | } else if (ascii_code == SS_DELAY_CODE) { | ||
| 168 | // delay | ||
| 169 | int ms = 0; | ||
| 170 | uint8_t keycode = *(++string); | ||
| 171 | while (isdigit(keycode)) { | ||
| 172 | ms *= 10; | ||
| 173 | ms += keycode - '0'; | ||
| 174 | keycode = *(++string); | ||
| 175 | } | ||
| 176 | while (ms--) | ||
| 177 | wait_ms(1); | ||
| 178 | } | ||
| 179 | } else { | ||
| 180 | send_char(ascii_code); | ||
| 181 | } | ||
| 182 | ++string; | ||
| 183 | // interval | ||
| 184 | { | ||
| 185 | uint8_t ms = interval; | ||
| 186 | while (ms--) | ||
| 187 | wait_ms(1); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | } | ||
| 191 | |||
| 192 | void send_char(char ascii_code) { | ||
| 193 | #if defined(AUDIO_ENABLE) && defined(SENDSTRING_BELL) | ||
| 194 | if (ascii_code == '\a') { // BEL | ||
| 195 | PLAY_SONG(bell_song); | ||
| 196 | return; | ||
| 197 | } | ||
| 198 | #endif | ||
| 199 | |||
| 200 | uint8_t keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]); | ||
| 201 | bool is_shifted = PGM_LOADBIT(ascii_to_shift_lut, (uint8_t)ascii_code); | ||
| 202 | bool is_altgred = PGM_LOADBIT(ascii_to_altgr_lut, (uint8_t)ascii_code); | ||
| 203 | bool is_dead = PGM_LOADBIT(ascii_to_dead_lut, (uint8_t)ascii_code); | ||
| 204 | |||
| 205 | if (is_shifted) { | ||
| 206 | register_code(KC_LEFT_SHIFT); | ||
| 207 | } | ||
| 208 | if (is_altgred) { | ||
| 209 | register_code(KC_RIGHT_ALT); | ||
| 210 | } | ||
| 211 | tap_code(keycode); | ||
| 212 | if (is_altgred) { | ||
| 213 | unregister_code(KC_RIGHT_ALT); | ||
| 214 | } | ||
| 215 | if (is_shifted) { | ||
| 216 | unregister_code(KC_LEFT_SHIFT); | ||
| 217 | } | ||
| 218 | if (is_dead) { | ||
| 219 | tap_code(KC_SPACE); | ||
| 220 | } | ||
| 221 | } | ||
| 222 | |||
| 223 | void send_dword(uint32_t number) { | ||
| 224 | send_word(number >> 16); | ||
| 225 | send_word(number & 0xFFFFUL); | ||
| 226 | } | ||
| 227 | |||
| 228 | void send_word(uint16_t number) { | ||
| 229 | send_byte(number >> 8); | ||
| 230 | send_byte(number & 0xFF); | ||
| 231 | } | ||
| 232 | |||
| 233 | void send_byte(uint8_t number) { | ||
| 234 | send_nibble(number >> 4); | ||
| 235 | send_nibble(number & 0xF); | ||
| 236 | } | ||
| 237 | |||
| 238 | void send_nibble(uint8_t number) { | ||
| 239 | switch (number & 0xF) { | ||
| 240 | case 0 ... 9: | ||
| 241 | send_char(number + '0'); | ||
| 242 | break; | ||
| 243 | case 10 ... 15: | ||
| 244 | send_char(number - 10 + 'a'); | ||
| 245 | break; | ||
| 246 | } | ||
| 247 | } | ||
| 248 | |||
| 249 | void tap_random_base64(void) { | ||
| 250 | #if defined(__AVR_ATmega32U4__) | ||
| 251 | uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64; | ||
| 252 | #else | ||
| 253 | uint8_t key = rand() % 64; | ||
| 254 | #endif | ||
| 255 | switch (key) { | ||
| 256 | case 0 ... 25: | ||
| 257 | send_char(key + 'A'); | ||
| 258 | break; | ||
| 259 | case 26 ... 51: | ||
| 260 | send_char(key - 26 + 'a'); | ||
| 261 | break; | ||
| 262 | case 52: | ||
| 263 | send_char('0'); | ||
| 264 | break; | ||
| 265 | case 53 ... 61: | ||
| 266 | send_char(key - 53 + '1'); | ||
| 267 | break; | ||
| 268 | case 62: | ||
| 269 | send_char('+'); | ||
| 270 | break; | ||
| 271 | case 63: | ||
| 272 | send_char('/'); | ||
| 273 | break; | ||
| 274 | } | ||
| 275 | } | ||
| 276 | |||
| 277 | #if defined(__AVR__) | ||
| 278 | void send_string_P(const char *string) { | ||
| 279 | send_string_with_delay_P(string, 0); | ||
| 280 | } | ||
| 281 | |||
| 282 | void send_string_with_delay_P(const char *string, uint8_t interval) { | ||
| 283 | while (1) { | ||
| 284 | char ascii_code = pgm_read_byte(string); | ||
| 285 | if (!ascii_code) break; | ||
| 286 | if (ascii_code == SS_QMK_PREFIX) { | ||
| 287 | ascii_code = pgm_read_byte(++string); | ||
| 288 | if (ascii_code == SS_TAP_CODE) { | ||
| 289 | // tap | ||
| 290 | uint8_t keycode = pgm_read_byte(++string); | ||
| 291 | tap_code(keycode); | ||
| 292 | } else if (ascii_code == SS_DOWN_CODE) { | ||
| 293 | // down | ||
| 294 | uint8_t keycode = pgm_read_byte(++string); | ||
| 295 | register_code(keycode); | ||
| 296 | } else if (ascii_code == SS_UP_CODE) { | ||
| 297 | // up | ||
| 298 | uint8_t keycode = pgm_read_byte(++string); | ||
| 299 | unregister_code(keycode); | ||
| 300 | } else if (ascii_code == SS_DELAY_CODE) { | ||
| 301 | // delay | ||
| 302 | int ms = 0; | ||
| 303 | uint8_t keycode = pgm_read_byte(++string); | ||
| 304 | while (isdigit(keycode)) { | ||
| 305 | ms *= 10; | ||
| 306 | ms += keycode - '0'; | ||
| 307 | keycode = pgm_read_byte(++string); | ||
| 308 | } | ||
| 309 | while (ms--) | ||
| 310 | wait_ms(1); | ||
| 311 | } | ||
| 312 | } else { | ||
| 313 | send_char(ascii_code); | ||
| 314 | } | ||
| 315 | ++string; | ||
| 316 | // interval | ||
| 317 | { | ||
| 318 | uint8_t ms = interval; | ||
| 319 | while (ms--) | ||
| 320 | wait_ms(1); | ||
| 321 | } | ||
| 322 | } | ||
| 323 | } | ||
| 324 | #endif | ||
diff --git a/quantum/send_string/send_string.h b/quantum/send_string/send_string.h new file mode 100644 index 0000000000..4eb55b88dc --- /dev/null +++ b/quantum/send_string/send_string.h | |||
| @@ -0,0 +1,152 @@ | |||
| 1 | /* Copyright 2021 | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | /** | ||
| 18 | * \defgroup send_string | ||
| 19 | * | ||
| 20 | * Send String API. These functions allow you to create macros by typing out sequences of keystrokes. | ||
| 21 | * \{ | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include <stdint.h> | ||
| 25 | |||
| 26 | #include "progmem.h" | ||
| 27 | #include "send_string_keycodes.h" | ||
| 28 | |||
| 29 | // Look-Up Tables (LUTs) to convert ASCII character to keycode sequence. | ||
| 30 | extern const uint8_t ascii_to_shift_lut[16]; | ||
| 31 | extern const uint8_t ascii_to_altgr_lut[16]; | ||
| 32 | extern const uint8_t ascii_to_dead_lut[16]; | ||
| 33 | extern const uint8_t ascii_to_keycode_lut[128]; | ||
| 34 | |||
| 35 | // clang-format off | ||
| 36 | #define KCLUT_ENTRY(a, b, c, d, e, f, g, h) \ | ||
| 37 | ( ((a) ? 1 : 0) << 0 \ | ||
| 38 | | ((b) ? 1 : 0) << 1 \ | ||
| 39 | | ((c) ? 1 : 0) << 2 \ | ||
| 40 | | ((d) ? 1 : 0) << 3 \ | ||
| 41 | | ((e) ? 1 : 0) << 4 \ | ||
| 42 | | ((f) ? 1 : 0) << 5 \ | ||
| 43 | | ((g) ? 1 : 0) << 6 \ | ||
| 44 | | ((h) ? 1 : 0) << 7 ) | ||
| 45 | // clang-format on | ||
| 46 | |||
| 47 | /** | ||
| 48 | * \brief Type out a string of ASCII characters. | ||
| 49 | * | ||
| 50 | * This function simply calls `send_string_with_delay(string, 0)`. | ||
| 51 | * | ||
| 52 | * Most keycodes from the basic keycode range are also supported by way of a special sequence - see `send_string_keycodes.h`. | ||
| 53 | * | ||
| 54 | * \param string The string to type out. | ||
| 55 | */ | ||
| 56 | void send_string(const char *string); | ||
| 57 | |||
| 58 | /** | ||
| 59 | * \brief Type out a string of ASCII characters, with a delay between each character. | ||
| 60 | * | ||
| 61 | * \param string The string to type out. | ||
| 62 | * \param interval The amount of time, in milliseconds, to wait before typing the next character. | ||
| 63 | */ | ||
| 64 | void send_string_with_delay(const char *string, uint8_t interval); | ||
| 65 | |||
| 66 | /** | ||
| 67 | * \brief Type out an ASCII character. | ||
| 68 | * | ||
| 69 | * \param ascii_code The character to type. | ||
| 70 | */ | ||
| 71 | void send_char(char ascii_code); | ||
| 72 | |||
| 73 | /** | ||
| 74 | * \brief Type out an eight digit (unsigned 32-bit) hexadecimal value. | ||
| 75 | * | ||
| 76 | * The format is `[0-9a-f]{8}`, eg. `00000000` through `ffffffff`. | ||
| 77 | * | ||
| 78 | * \param number The value to type, from 0 to 4,294,967,295. | ||
| 79 | */ | ||
| 80 | void send_dword(uint32_t number); | ||
| 81 | |||
| 82 | /** | ||
| 83 | * \brief Type out a four digit (unsigned 16-bit) hexadecimal value. | ||
| 84 | * | ||
| 85 | * The format is `[0-9a-f]{4}`, eg. `0000` through `ffff`. | ||
| 86 | * | ||
| 87 | * \param number The value to type, from 0 to 65,535. | ||
| 88 | */ | ||
| 89 | void send_word(uint16_t number); | ||
| 90 | |||
| 91 | /** | ||
| 92 | * \brief Type out a two digit (8-bit) hexadecimal value. | ||
| 93 | * | ||
| 94 | * The format is `[0-9a-f]{2}`, eg. `00` through `ff`. | ||
| 95 | * | ||
| 96 | * \param number The value to type, from 0 to 255. | ||
| 97 | */ | ||
| 98 | void send_byte(uint8_t number); | ||
| 99 | |||
| 100 | /** | ||
| 101 | * \brief Type out a single hexadecimal digit. | ||
| 102 | * | ||
| 103 | * The format is `[0-9a-f]{1}`, eg. `0` through `f`. | ||
| 104 | * | ||
| 105 | * \param number The value to type, from 0 to 15. | ||
| 106 | */ | ||
| 107 | void send_nibble(uint8_t number); | ||
| 108 | |||
| 109 | /** | ||
| 110 | * \brief Type a pseudorandom character from the set `A-Z`, `a-z`, `0-9`, `+` and `/`. | ||
| 111 | */ | ||
| 112 | void tap_random_base64(void); | ||
| 113 | |||
| 114 | #if defined(__AVR__) || defined(__DOXYGEN__) | ||
| 115 | /** | ||
| 116 | * \brief Type out a PROGMEM string of ASCII characters. | ||
| 117 | * | ||
| 118 | * On ARM devices, this function is simply an alias for send_string_with_delay(string, 0). | ||
| 119 | * | ||
| 120 | * \param string The string to type out. | ||
| 121 | */ | ||
| 122 | void send_string_P(const char *string); | ||
| 123 | |||
| 124 | /** | ||
| 125 | * \brief Type out a PROGMEM string of ASCII characters, with a delay between each character. | ||
| 126 | * | ||
| 127 | * On ARM devices, this function is simply an alias for send_string_with_delay(string, interval). | ||
| 128 | * | ||
| 129 | * \param string The string to type out. | ||
| 130 | * \param interval The amount of time, in milliseconds, to wait before typing the next character. | ||
| 131 | */ | ||
| 132 | void send_string_with_delay_P(const char *string, uint8_t interval); | ||
| 133 | #else | ||
| 134 | # define send_string_P(string) send_string_with_delay(string, 0) | ||
| 135 | # define send_string_with_delay_P(string, interval) send_string_with_delay(string, interval) | ||
| 136 | #endif | ||
| 137 | |||
| 138 | /** | ||
| 139 | * \brief Shortcut macro for send_string_with_delay_P(PSTR(string), 0). | ||
| 140 | * | ||
| 141 | * On ARM devices, this define evaluates to send_string_with_delay(string, 0). | ||
| 142 | */ | ||
| 143 | #define SEND_STRING(string) send_string_with_delay_P(PSTR(string), 0) | ||
| 144 | |||
| 145 | /** | ||
| 146 | * \brief Shortcut macro for send_string_with_delay_P(PSTR(string), interval). | ||
| 147 | * | ||
| 148 | * On ARM devices, this define evaluates to send_string_with_delay(string, interval). | ||
| 149 | */ | ||
| 150 | #define SEND_STRING_DELAY(string, interval) send_string_with_delay_P(PSTR(string), interval) | ||
| 151 | |||
| 152 | /** \} */ | ||
diff --git a/quantum/send_string/send_string_keycodes.h b/quantum/send_string/send_string_keycodes.h new file mode 100644 index 0000000000..7017e03d5a --- /dev/null +++ b/quantum/send_string/send_string_keycodes.h | |||
| @@ -0,0 +1,434 @@ | |||
| 1 | /* Copyright 2019 | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #pragma once | ||
| 18 | |||
| 19 | // clang-format off | ||
| 20 | |||
| 21 | /* Punctuation */ | ||
| 22 | #define X_ENT X_ENTER | ||
| 23 | #define X_ESC X_ESCAPE | ||
| 24 | #define X_BSPC X_BSPACE | ||
| 25 | #define X_SPC X_SPACE | ||
| 26 | #define X_MINS X_MINUS | ||
| 27 | #define X_EQL X_EQUAL | ||
| 28 | #define X_LBRC X_LBRACKET | ||
| 29 | #define X_RBRC X_RBRACKET | ||
| 30 | #define X_BSLS X_BSLASH | ||
| 31 | #define X_NUHS X_NONUS_HASH | ||
| 32 | #define X_SCLN X_SCOLON | ||
| 33 | #define X_QUOT X_QUOTE | ||
| 34 | #define X_GRV X_GRAVE | ||
| 35 | #define X_COMM X_COMMA | ||
| 36 | #define X_SLSH X_SLASH | ||
| 37 | #define X_NUBS X_NONUS_BSLASH | ||
| 38 | |||
| 39 | /* Lock Keys */ | ||
| 40 | #define X_CLCK X_CAPSLOCK | ||
| 41 | #define X_CAPS X_CAPSLOCK | ||
| 42 | #define X_SLCK X_SCROLLLOCK | ||
| 43 | #define X_NLCK X_NUMLOCK | ||
| 44 | #define X_LCAP X_LOCKING_CAPS | ||
| 45 | #define X_LNUM X_LOCKING_NUM | ||
| 46 | #define X_LSCR X_LOCKING_SCROLL | ||
| 47 | |||
| 48 | /* Commands */ | ||
| 49 | #define X_PSCR X_PSCREEN | ||
| 50 | #define X_PAUS X_PAUSE | ||
| 51 | #define X_BRK X_PAUSE | ||
| 52 | #define X_INS X_INSERT | ||
| 53 | #define X_DEL X_DELETE | ||
| 54 | #define X_PGDN X_PGDOWN | ||
| 55 | #define X_RGHT X_RIGHT | ||
| 56 | #define X_APP X_APPLICATION | ||
| 57 | #define X_EXEC X_EXECUTE | ||
| 58 | #define X_SLCT X_SELECT | ||
| 59 | #define X_AGIN X_AGAIN | ||
| 60 | #define X_PSTE X_PASTE | ||
| 61 | #define X_ERAS X_ALT_ERASE | ||
| 62 | #define X_CLR X_CLEAR | ||
| 63 | |||
| 64 | /* Keypad */ | ||
| 65 | #define X_PSLS X_KP_SLASH | ||
| 66 | #define X_PAST X_KP_ASTERISK | ||
| 67 | #define X_PMNS X_KP_MINUS | ||
| 68 | #define X_PPLS X_KP_PLUS | ||
| 69 | #define X_PENT X_KP_ENTER | ||
| 70 | #define X_P1 X_KP_1 | ||
| 71 | #define X_P2 X_KP_2 | ||
| 72 | #define X_P3 X_KP_3 | ||
| 73 | #define X_P4 X_KP_4 | ||
| 74 | #define X_P5 X_KP_5 | ||
| 75 | #define X_P6 X_KP_6 | ||
| 76 | #define X_P7 X_KP_7 | ||
| 77 | #define X_P8 X_KP_8 | ||
| 78 | #define X_P9 X_KP_9 | ||
| 79 | #define X_P0 X_KP_0 | ||
| 80 | #define X_PDOT X_KP_DOT | ||
| 81 | #define X_PEQL X_KP_EQUAL | ||
| 82 | #define X_PCMM X_KP_COMMA | ||
| 83 | |||
| 84 | /* Japanese specific */ | ||
| 85 | #define X_ZKHK X_GRAVE | ||
| 86 | #define X_RO X_INT1 | ||
| 87 | #define X_KANA X_INT2 | ||
| 88 | #define X_JYEN X_INT3 | ||
| 89 | #define X_HENK X_INT4 | ||
| 90 | #define X_MHEN X_INT5 | ||
| 91 | |||
| 92 | /* Korean specific */ | ||
| 93 | #define X_HAEN X_LANG1 | ||
| 94 | #define X_HANJ X_LANG2 | ||
| 95 | |||
| 96 | /* Modifiers */ | ||
| 97 | #define X_LCTL X_LCTRL | ||
| 98 | #define X_LSFT X_LSHIFT | ||
| 99 | #define X_LOPT X_LALT | ||
| 100 | #define X_LCMD X_LGUI | ||
| 101 | #define X_LWIN X_LGUI | ||
| 102 | #define X_RCTL X_RCTRL | ||
| 103 | #define X_RSFT X_RSHIFT | ||
| 104 | #define X_ALGR X_RALT | ||
| 105 | #define X_ROPT X_RALT | ||
| 106 | #define X_RCMD X_RGUI | ||
| 107 | #define X_RWIN X_RGUI | ||
| 108 | |||
| 109 | /* Generic Desktop Page (0x01) */ | ||
| 110 | #define X_PWR X_SYSTEM_POWER | ||
| 111 | #define X_SLEP X_SYSTEM_SLEEP | ||
| 112 | #define X_WAKE X_SYSTEM_WAKE | ||
| 113 | |||
| 114 | /* Consumer Page (0x0C) */ | ||
| 115 | #define X_MUTE X_AUDIO_MUTE | ||
| 116 | #define X_VOLU X_AUDIO_VOL_UP | ||
| 117 | #define X_VOLD X_AUDIO_VOL_DOWN | ||
| 118 | #define X_MNXT X_MEDIA_NEXT_TRACK | ||
| 119 | #define X_MPRV X_MEDIA_PREV_TRACK | ||
| 120 | #define X_MSTP X_MEDIA_STOP | ||
| 121 | #define X_MPLY X_MEDIA_PLAY_PAUSE | ||
| 122 | #define X_MSEL X_MEDIA_SELECT | ||
| 123 | #define X_EJCT X_MEDIA_EJECT | ||
| 124 | #define X_CALC X_CALCULATOR | ||
| 125 | #define X_MYCM X_MY_COMPUTER | ||
| 126 | #define X_WSCH X_WWW_SEARCH | ||
| 127 | #define X_WHOM X_WWW_HOME | ||
| 128 | #define X_WBAK X_WWW_BACK | ||
| 129 | #define X_WFWD X_WWW_FORWARD | ||
| 130 | #define X_WSTP X_WWW_STOP | ||
| 131 | #define X_WREF X_WWW_REFRESH | ||
| 132 | #define X_WFAV X_WWW_FAVORITES | ||
| 133 | #define X_MFFD X_MEDIA_FAST_FORWARD | ||
| 134 | #define X_MRWD X_MEDIA_REWIND | ||
| 135 | #define X_BRIU X_BRIGHTNESS_UP | ||
| 136 | #define X_BRID X_BRIGHTNESS_DOWN | ||
| 137 | |||
| 138 | /* System Specific */ | ||
| 139 | #define X_BRMU X_PAUSE | ||
| 140 | #define X_BRMD X_SCROLLLOCK | ||
| 141 | |||
| 142 | /* Mouse Keys */ | ||
| 143 | #define X_MS_U X_MS_UP | ||
| 144 | #define X_MS_D X_MS_DOWN | ||
| 145 | #define X_MS_L X_MS_LEFT | ||
| 146 | #define X_MS_R X_MS_RIGHT | ||
| 147 | #define X_BTN1 X_MS_BTN1 | ||
| 148 | #define X_BTN2 X_MS_BTN2 | ||
| 149 | #define X_BTN3 X_MS_BTN3 | ||
| 150 | #define X_BTN4 X_MS_BTN4 | ||
| 151 | #define X_BTN5 X_MS_BTN5 | ||
| 152 | #define X_WH_U X_MS_WH_UP | ||
| 153 | #define X_WH_D X_MS_WH_DOWN | ||
| 154 | #define X_WH_L X_MS_WH_LEFT | ||
| 155 | #define X_WH_R X_MS_WH_RIGHT | ||
| 156 | #define X_ACL0 X_MS_ACCEL0 | ||
| 157 | #define X_ACL1 X_MS_ACCEL1 | ||
| 158 | #define X_ACL2 X_MS_ACCEL2 | ||
| 159 | |||
| 160 | /* Keyboard/Keypad Page (0x07) */ | ||
| 161 | #define X_A 04 | ||
| 162 | #define X_B 05 | ||
| 163 | #define X_C 06 | ||
| 164 | #define X_D 07 | ||
| 165 | #define X_E 08 | ||
| 166 | #define X_F 09 | ||
| 167 | #define X_G 0a | ||
| 168 | #define X_H 0b | ||
| 169 | #define X_I 0c | ||
| 170 | #define X_J 0d | ||
| 171 | #define X_K 0e | ||
| 172 | #define X_L 0f | ||
| 173 | #define X_M 10 | ||
| 174 | #define X_N 11 | ||
| 175 | #define X_O 12 | ||
| 176 | #define X_P 13 | ||
| 177 | #define X_Q 14 | ||
| 178 | #define X_R 15 | ||
| 179 | #define X_S 16 | ||
| 180 | #define X_T 17 | ||
| 181 | #define X_U 18 | ||
| 182 | #define X_V 19 | ||
| 183 | #define X_W 1a | ||
| 184 | #define X_X 1b | ||
| 185 | #define X_Y 1c | ||
| 186 | #define X_Z 1d | ||
| 187 | #define X_1 1e | ||
| 188 | #define X_2 1f | ||
| 189 | #define X_3 20 | ||
| 190 | #define X_4 21 | ||
| 191 | #define X_5 22 | ||
| 192 | #define X_6 23 | ||
| 193 | #define X_7 24 | ||
| 194 | #define X_8 25 | ||
| 195 | #define X_9 26 | ||
| 196 | #define X_0 27 | ||
| 197 | #define X_ENTER 28 | ||
| 198 | #define X_ESCAPE 29 | ||
| 199 | #define X_BSPACE 2a | ||
| 200 | #define X_TAB 2b | ||
| 201 | #define X_SPACE 2c | ||
| 202 | #define X_MINUS 2d | ||
| 203 | #define X_EQUAL 2e | ||
| 204 | #define X_LBRACKET 2f | ||
| 205 | #define X_RBRACKET 30 | ||
| 206 | #define X_BSLASH 31 | ||
| 207 | #define X_NONUS_HASH 32 | ||
| 208 | #define X_SCOLON 33 | ||
| 209 | #define X_QUOTE 34 | ||
| 210 | #define X_GRAVE 35 | ||
| 211 | #define X_COMMA 36 | ||
| 212 | #define X_DOT 37 | ||
| 213 | #define X_SLASH 38 | ||
| 214 | #define X_CAPSLOCK 39 | ||
| 215 | #define X_F1 3a | ||
| 216 | #define X_F2 3b | ||
| 217 | #define X_F3 3c | ||
| 218 | #define X_F4 3d | ||
| 219 | #define X_F5 3e | ||
| 220 | #define X_F6 3f | ||
| 221 | #define X_F7 40 | ||
| 222 | #define X_F8 41 | ||
| 223 | #define X_F9 42 | ||
| 224 | #define X_F10 43 | ||
| 225 | #define X_F11 44 | ||
| 226 | #define X_F12 45 | ||
| 227 | #define X_PSCREEN 46 | ||
| 228 | #define X_SCROLLLOCK 47 | ||
| 229 | #define X_PAUSE 48 | ||
| 230 | #define X_INSERT 49 | ||
| 231 | #define X_HOME 4a | ||
| 232 | #define X_PGUP 4b | ||
| 233 | #define X_DELETE 4c | ||
| 234 | #define X_END 4d | ||
| 235 | #define X_PGDOWN 4e | ||
| 236 | #define X_RIGHT 4f | ||
| 237 | #define X_LEFT 50 | ||
| 238 | #define X_DOWN 51 | ||
| 239 | #define X_UP 52 | ||
| 240 | #define X_NUMLOCK 53 | ||
| 241 | #define X_KP_SLASH 54 | ||
| 242 | #define X_KP_ASTERISK 55 | ||
| 243 | #define X_KP_MINUS 56 | ||
| 244 | #define X_KP_PLUS 57 | ||
| 245 | #define X_KP_ENTER 58 | ||
| 246 | #define X_KP_1 59 | ||
| 247 | #define X_KP_2 5a | ||
| 248 | #define X_KP_3 5b | ||
| 249 | #define X_KP_4 5c | ||
| 250 | #define X_KP_5 5d | ||
| 251 | #define X_KP_6 5e | ||
| 252 | #define X_KP_7 5f | ||
| 253 | #define X_KP_8 60 | ||
| 254 | #define X_KP_9 61 | ||
| 255 | #define X_KP_0 62 | ||
| 256 | #define X_KP_DOT 63 | ||
| 257 | #define X_NONUS_BSLASH 64 | ||
| 258 | #define X_APPLICATION 65 | ||
| 259 | #define X_POWER 66 | ||
| 260 | #define X_KP_EQUAL 67 | ||
| 261 | #define X_F13 68 | ||
| 262 | #define X_F14 69 | ||
| 263 | #define X_F15 6a | ||
| 264 | #define X_F16 6b | ||
| 265 | #define X_F17 6c | ||
| 266 | #define X_F18 6d | ||
| 267 | #define X_F19 6e | ||
| 268 | #define X_F20 6f | ||
| 269 | #define X_F21 70 | ||
| 270 | #define X_F22 71 | ||
| 271 | #define X_F23 72 | ||
| 272 | #define X_F24 73 | ||
| 273 | #define X_EXECUTE 74 | ||
| 274 | #define X_HELP 75 | ||
| 275 | #define X_MENU 76 | ||
| 276 | #define X_SELECT 77 | ||
| 277 | #define X_STOP 78 | ||
| 278 | #define X_AGAIN 79 | ||
| 279 | #define X_UNDO 7a | ||
| 280 | #define X_CUT 7b | ||
| 281 | #define X_COPY 7c | ||
| 282 | #define X_PASTE 7d | ||
| 283 | #define X_FIND 7e | ||
| 284 | #define X__MUTE 7f | ||
| 285 | #define X__VOLUP 80 | ||
| 286 | #define X__VOLDOWN 81 | ||
| 287 | #define X_LOCKING_CAPS 82 | ||
| 288 | #define X_LOCKING_NUM 83 | ||
| 289 | #define X_LOCKING_SCROLL 84 | ||
| 290 | #define X_KP_COMMA 85 | ||
| 291 | #define X_KP_EQUAL_AS400 86 | ||
| 292 | #define X_INT1 87 | ||
| 293 | #define X_INT2 88 | ||
| 294 | #define X_INT3 89 | ||
| 295 | #define X_INT4 8a | ||
| 296 | #define X_INT5 8b | ||
| 297 | #define X_INT6 8c | ||
| 298 | #define X_INT7 8d | ||
| 299 | #define X_INT8 8e | ||
| 300 | #define X_INT9 8f | ||
| 301 | #define X_LANG1 90 | ||
| 302 | #define X_LANG2 91 | ||
| 303 | #define X_LANG3 92 | ||
| 304 | #define X_LANG4 93 | ||
| 305 | #define X_LANG5 94 | ||
| 306 | #define X_LANG6 95 | ||
| 307 | #define X_LANG7 96 | ||
| 308 | #define X_LANG8 97 | ||
| 309 | #define X_LANG9 98 | ||
| 310 | #define X_ALT_ERASE 99 | ||
| 311 | #define X_SYSREQ 9a | ||
| 312 | #define X_CANCEL 9b | ||
| 313 | #define X_CLEAR 9c | ||
| 314 | #define X_PRIOR 9d | ||
| 315 | #define X_RETURN 9e | ||
| 316 | #define X_SEPARATOR 9f | ||
| 317 | #define X_OUT a0 | ||
| 318 | #define X_OPER a1 | ||
| 319 | #define X_CLEAR_AGAIN a2 | ||
| 320 | #define X_CRSEL a3 | ||
| 321 | #define X_EXSEL a4 | ||
| 322 | |||
| 323 | /* Modifiers */ | ||
| 324 | #define X_LCTRL e0 | ||
| 325 | #define X_LSHIFT e1 | ||
| 326 | #define X_LALT e2 | ||
| 327 | #define X_LGUI e3 | ||
| 328 | #define X_RCTRL e4 | ||
| 329 | #define X_RSHIFT e5 | ||
| 330 | #define X_RALT e6 | ||
| 331 | #define X_RGUI e7 | ||
| 332 | |||
| 333 | /* Media and Function keys */ | ||
| 334 | /* Generic Desktop Page (0x01) */ | ||
| 335 | #define X_SYSTEM_POWER a5 | ||
| 336 | #define X_SYSTEM_SLEEP a6 | ||
| 337 | #define X_SYSTEM_WAKE a7 | ||
| 338 | |||
| 339 | /* Consumer Page (0x0C) */ | ||
| 340 | #define X_AUDIO_MUTE a8 | ||
| 341 | #define X_AUDIO_VOL_UP a9 | ||
| 342 | #define X_AUDIO_VOL_DOWN aa | ||
| 343 | #define X_MEDIA_NEXT_TRACK ab | ||
| 344 | #define X_MEDIA_PREV_TRACK ac | ||
| 345 | #define X_MEDIA_STOP ad | ||
| 346 | #define X_MEDIA_PLAY_PAUSE ae | ||
| 347 | #define X_MEDIA_SELECT af | ||
| 348 | #define X_MEDIA_EJECT b0 | ||
| 349 | #define X_MAIL b1 | ||
| 350 | #define X_CALCULATOR b2 | ||
| 351 | #define X_MY_COMPUTER b3 | ||
| 352 | #define X_WWW_SEARCH b4 | ||
| 353 | #define X_WWW_HOME b5 | ||
| 354 | #define X_WWW_BACK b6 | ||
| 355 | #define X_WWW_FORWARD b7 | ||
| 356 | #define X_WWW_STOP b8 | ||
| 357 | #define X_WWW_REFRESH b9 | ||
| 358 | #define X_WWW_FAVORITES ba | ||
| 359 | #define X_MEDIA_FAST_FORWARD bb | ||
| 360 | #define X_MEDIA_REWIND bc | ||
| 361 | #define X_BRIGHTNESS_UP bd | ||
| 362 | #define X_BRIGHTNESS_DOWN be | ||
| 363 | |||
| 364 | /* Mouse Buttons (unallocated range in HID spec) */ | ||
| 365 | #ifdef VIA_ENABLE | ||
| 366 | #define X_MS_UP f0 | ||
| 367 | #define X_MS_DOWN f1 | ||
| 368 | #define X_MS_LEFT f2 | ||
| 369 | #define X_MS_RIGHT f3 | ||
| 370 | #define X_MS_BTN1 f4 | ||
| 371 | #define X_MS_BTN2 f5 | ||
| 372 | #define X_MS_BTN3 f6 | ||
| 373 | #define X_MS_BTN4 f7 | ||
| 374 | #define X_MS_BTN5 f8 | ||
| 375 | #define X_MS_BTN6 f8 | ||
| 376 | #define X_MS_BTN7 f8 | ||
| 377 | #define X_MS_BTN8 f8 | ||
| 378 | #else | ||
| 379 | #define X_MS_UP ed | ||
| 380 | #define X_MS_DOWN ee | ||
| 381 | #define X_MS_LEFT ef | ||
| 382 | #define X_MS_RIGHT f0 | ||
| 383 | #define X_MS_BTN1 f1 | ||
| 384 | #define X_MS_BTN2 f2 | ||
| 385 | #define X_MS_BTN3 f3 | ||
| 386 | #define X_MS_BTN4 f4 | ||
| 387 | #define X_MS_BTN5 f5 | ||
| 388 | #define X_MS_BTN6 f6 | ||
| 389 | #define X_MS_BTN7 f7 | ||
| 390 | #define X_MS_BTN8 f8 | ||
| 391 | #endif | ||
| 392 | #define X_MS_WH_UP f9 | ||
| 393 | #define X_MS_WH_DOWN fa | ||
| 394 | #define X_MS_WH_LEFT fb | ||
| 395 | #define X_MS_WH_RIGHT fc | ||
| 396 | #define X_MS_ACCEL0 fd | ||
| 397 | #define X_MS_ACCEL1 fe | ||
| 398 | #define X_MS_ACCEL2 ff | ||
| 399 | |||
| 400 | // Send string macros | ||
| 401 | #define STRINGIZE(z) #z | ||
| 402 | #define ADD_SLASH_X(y) STRINGIZE(\x##y) | ||
| 403 | #define SYMBOL_STR(x) ADD_SLASH_X(x) | ||
| 404 | |||
| 405 | #define SS_QMK_PREFIX 1 | ||
| 406 | |||
| 407 | #define SS_TAP_CODE 1 | ||
| 408 | #define SS_DOWN_CODE 2 | ||
| 409 | #define SS_UP_CODE 3 | ||
| 410 | #define SS_DELAY_CODE 4 | ||
| 411 | |||
| 412 | #define SS_TAP(keycode) "\1\1" SYMBOL_STR(keycode) | ||
| 413 | #define SS_DOWN(keycode) "\1\2" SYMBOL_STR(keycode) | ||
| 414 | #define SS_UP(keycode) "\1\3" SYMBOL_STR(keycode) | ||
| 415 | #define SS_DELAY(msecs) "\1\4" STRINGIZE(msecs) "|" | ||
| 416 | |||
| 417 | // `string` arguments must not be parenthesized | ||
| 418 | #define SS_LCTL(string) SS_DOWN(X_LCTL) string SS_UP(X_LCTL) | ||
| 419 | #define SS_LSFT(string) SS_DOWN(X_LSFT) string SS_UP(X_LSFT) | ||
| 420 | #define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT) | ||
| 421 | #define SS_LGUI(string) SS_DOWN(X_LGUI) string SS_UP(X_LGUI) | ||
| 422 | #define SS_LCMD(string) SS_LGUI(string) | ||
| 423 | #define SS_LWIN(string) SS_LGUI(string) | ||
| 424 | |||
| 425 | #define SS_RCTL(string) SS_DOWN(X_RCTL) string SS_UP(X_RCTL) | ||
| 426 | #define SS_RSFT(string) SS_DOWN(X_RSFT) string SS_UP(X_RSFT) | ||
| 427 | #define SS_RALT(string) SS_DOWN(X_RALT) string SS_UP(X_RALT) | ||
| 428 | #define SS_RGUI(string) SS_DOWN(X_RGUI) string SS_UP(X_RGUI) | ||
| 429 | #define SS_ALGR(string) SS_RALT(string) | ||
| 430 | #define SS_RCMD(string) SS_RGUI(string) | ||
| 431 | #define SS_RWIN(string) SS_RGUI(string) | ||
| 432 | |||
| 433 | // DEPRECATED | ||
| 434 | #define SS_LCTRL(string) SS_LCTL(string) | ||
