summaryrefslogtreecommitdiff
path: root/quantum/send_string
diff options
context:
space:
mode:
authorRyan <fauxpark@gmail.com>2022-07-02 22:10:08 +1000
committerGitHub <noreply@github.com>2022-07-02 22:10:08 +1000
commit3ecb0a80af9e4ce4194a34032642933641730706 (patch)
tree3d4b0e24336762dc9b45a746334ebc09a5c59db1 /quantum/send_string
parent7e41eb02773207dd4a014575fe750f8d511bfb5b (diff)
Feature-ify Send String (#17275)
Diffstat (limited to 'quantum/send_string')
-rw-r--r--quantum/send_string/send_string.c324
-rw-r--r--quantum/send_string/send_string.h152
-rw-r--r--quantum/send_string/send_string_keycodes.h434
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
28float 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
145void send_string(const char *string) {
146 send_string_with_delay(string, 0);
147}
148
149void 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
192void 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
223void send_dword(uint32_t number) {
224 send_word(number >> 16);
225 send_word(number & 0xFFFFUL);
226}
227
228void send_word(uint16_t number) {
229 send_byte(number >> 8);
230 send_byte(number & 0xFF);
231}
232
233void send_byte(uint8_t number) {
234 send_nibble(number >> 4);
235 send_nibble(number & 0xF);
236}
237
238void 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
249void 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__)
278void send_string_P(const char *string) {
279 send_string_with_delay_P(string, 0);
280}
281
282void 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.
30extern const uint8_t ascii_to_shift_lut[16];
31extern const uint8_t ascii_to_altgr_lut[16];
32extern const uint8_t ascii_to_dead_lut[16];
33extern 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 */
56void 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 */
64void 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 */
71void 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 */
80void 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 */
89void 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 */
98void 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 */
107void send_nibble(uint8_t number);
108
109/**
110 * \brief Type a pseudorandom character from the set `A-Z`, `a-z`, `0-9`, `+` and `/`.
111 */
112void 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 */
122void 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 */
132void 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)