diff options
Diffstat (limited to 'quantum/keycode_string.h')
| -rw-r--r-- | quantum/keycode_string.h | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/quantum/keycode_string.h b/quantum/keycode_string.h new file mode 100644 index 0000000000..1315613a80 --- /dev/null +++ b/quantum/keycode_string.h | |||
| @@ -0,0 +1,134 @@ | |||
| 1 | // Copyright 2024-2025 Google LLC | ||
| 2 | // | ||
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | // you may not use this file except in compliance with the License. | ||
| 5 | // You may obtain a copy of the License at | ||
| 6 | // | ||
| 7 | // https://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | // | ||
| 9 | // Unless required by applicable law or agreed to in writing, software | ||
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | // See the License for the specific language governing permissions and | ||
| 13 | // limitations under the License. | ||
| 14 | |||
| 15 | #pragma once | ||
| 16 | |||
| 17 | #include <stdint.h> | ||
| 18 | |||
| 19 | #if KEYCODE_STRING_ENABLE | ||
| 20 | |||
| 21 | /** | ||
| 22 | * @brief Formats a QMK keycode as a human-readable string. | ||
| 23 | * | ||
| 24 | * Given a keycode, like `KC_A`, this function returns a formatted string, like | ||
| 25 | * "KC_A". This is useful for debugging and diagnostics so that keys are more | ||
| 26 | * easily identified than they would be by raw numerical codes. | ||
| 27 | * | ||
| 28 | * @note The returned char* string should be used right away. The string memory | ||
| 29 | * is reused and will be overwritten by the next call to `keycode_string()`. | ||
| 30 | * | ||
| 31 | * Many common QMK keycodes are understood by this function, but not all. | ||
| 32 | * Recognized keycodes include: | ||
| 33 | * | ||
| 34 | * - Most basic keycodes, including letters `KC_A` - `KC_Z`, digits `KC_0` - | ||
| 35 | * `KC_9`, function keys `KC_F1` - `KC_F24`, and modifiers like `KC_LSFT`. | ||
| 36 | * | ||
| 37 | * - Modified basic keycodes, like `S(KC_1)` (Shift + 1 = !). | ||
| 38 | * | ||
| 39 | * - `MO`, `TO`, `TG`, `OSL`, `LM(layer,mod)`, `LT(layer,kc)` layer switches. | ||
| 40 | * | ||
| 41 | * - One-shot mod `OSM(mod)` keycodes. | ||
| 42 | * | ||
| 43 | * - Mod-tap `MT(mod, kc)` keycodes. | ||
| 44 | * | ||
| 45 | * - Tap dance keycodes `TD(i)`. | ||
| 46 | * | ||
| 47 | * - Swap hands keycodes `SH_T(kc)`, `SH_TOGG`, etc. | ||
| 48 | * | ||
| 49 | * - Joystick keycodes `JS_n`. | ||
| 50 | * | ||
| 51 | * - Programmable button keycodes `PB_n`. | ||
| 52 | * | ||
| 53 | * - Unicode `UC(codepoint)` and Unicode Map `UM(i)` and `UP(i,j)` keycodes. | ||
| 54 | * | ||
| 55 | * - Keyboard range keycodes `QK_KB_*`. | ||
| 56 | * | ||
| 57 | * - User range (SAFE_RANGE) keycodes `QK_USER_*`. | ||
| 58 | * | ||
| 59 | * Keycodes involving mods like `OSM`, `LM`, `MT` are fully supported only where | ||
| 60 | * a single mod is applied. | ||
| 61 | * | ||
| 62 | * Unrecognized keycodes are printed numerically as hex values like `0x1ABC`. | ||
| 63 | * | ||
| 64 | * Optionally, use `keycode_string_names_user` or `keycode_string_names_kb` to | ||
| 65 | * define names for additional keycodes or override how any of the above are | ||
| 66 | * formatted. | ||
| 67 | * | ||
| 68 | * @param keycode QMK keycode. | ||
| 69 | * @return Stringified keycode. | ||
| 70 | */ | ||
| 71 | const char* get_keycode_string(uint16_t keycode); | ||
| 72 | |||
| 73 | /** Defines a human-readable name for a keycode. */ | ||
| 74 | typedef struct { | ||
| 75 | uint16_t keycode; | ||
| 76 | const char* name; | ||
| 77 | } keycode_string_name_t; | ||
| 78 | |||
| 79 | // clang-format off | ||
| 80 | /** | ||
| 81 | * @brief Defines names for additional keycodes for `get_keycode_string()`. | ||
| 82 | * | ||
| 83 | * Define `KEYCODE_STRING_NAMES_USER` in your keymap.c to add names for | ||
| 84 | * additional keycodes to `keycode_string()`. This table may also be used to | ||
| 85 | * override how `keycode_string()` formats a keycode. For example, supposing | ||
| 86 | * keymap.c defines `MYMACRO1` and `MYMACRO2` as custom keycodes: | ||
| 87 | * | ||
| 88 | * KEYCODE_STRING_NAMES_USER( | ||
| 89 | * KEYCODE_STRING_NAME(MYMACRO1), | ||
| 90 | * KEYCODE_STRING_NAME(MYMACRO2), | ||
| 91 | * KEYCODE_STRING_NAME(KC_EXLM), | ||
| 92 | * ); | ||
| 93 | * | ||
| 94 | * The above defines names for `MYMACRO1` and `MYMACRO2`, and overrides | ||
| 95 | * `KC_EXLM` to format as "KC_EXLM" instead of the default "S(KC_1)". | ||
| 96 | */ | ||
| 97 | # define KEYCODE_STRING_NAMES_USER(...) \ | ||
| 98 | static const keycode_string_name_t keycode_string_names_user[] = {__VA_ARGS__}; \ | ||
| 99 | uint16_t keycode_string_names_size_user = \ | ||
| 100 | sizeof(keycode_string_names_user) / sizeof(keycode_string_name_t); \ | ||
| 101 | const keycode_string_name_t* keycode_string_names_data_user = \ | ||
| 102 | keycode_string_names_user | ||
| 103 | |||
| 104 | /** Same as above, but defines keycode string names at the keyboard level. */ | ||
| 105 | # define KEYCODE_STRING_NAMES_KB(...) \ | ||
| 106 | static const keycode_string_name_t keycode_string_names_kb[] = {__VA_ARGS__}; \ | ||
| 107 | uint16_t keycode_string_names_size_kb = \ | ||
| 108 | sizeof(keycode_string_names_kb) / sizeof(keycode_string_name_t); \ | ||
| 109 | const keycode_string_name_t* keycode_string_names_data_kb = \ | ||
| 110 | keycode_string_names_kb | ||
| 111 | |||
| 112 | /** Helper to define a keycode_string_name_t. */ | ||
| 113 | # define KEYCODE_STRING_NAME(kc) \ | ||
| 114 | { (kc), #kc } | ||
| 115 | // clang-format on | ||
| 116 | |||
| 117 | extern const keycode_string_name_t* keycode_string_names_data_user; | ||
| 118 | extern uint16_t keycode_string_names_size_user; | ||
| 119 | extern const keycode_string_name_t* keycode_string_names_data_kb; | ||
| 120 | extern uint16_t keycode_string_names_size_kb; | ||
| 121 | |||
| 122 | #else | ||
| 123 | |||
| 124 | // When keycode_string is disabled, fall back to printing keycodes numerically | ||
| 125 | // as decimal values, using get_u16_str() from quantum.c. | ||
| 126 | # define get_keycode_string(kc) get_u16_str(kc, ' ') | ||
| 127 | |||
| 128 | const char* get_u16_str(uint16_t curr_num, char curr_pad); | ||
| 129 | |||
| 130 | # define KEYCODE_STRING_NAMES_USER(...) | ||
| 131 | # define KEYCODE_STRING_NAMES_KB(...) | ||
| 132 | # define KEYCODE_STRING_NAME(kc) | ||
| 133 | |||
| 134 | #endif // KEYCODE_STRING_ENABLE | ||
