diff options
| author | Ryan <fauxpark@gmail.com> | 2020-02-24 10:27:25 +1100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-02-24 10:27:25 +1100 |
| commit | 371ff9dd6f9c4feada34622d9a43480495b07e50 (patch) | |
| tree | 785ba3038f5e431f1192c09f11d022c2c6850555 /quantum/process_keycode | |
| parent | 716c29881c0f91e3998e1fc5c49740bd6e65876f (diff) | |
| download | qmk_firmware-371ff9dd6f9c4feada34622d9a43480495b07e50.tar.gz qmk_firmware-371ff9dd6f9c4feada34622d9a43480495b07e50.zip | |
A proper `send_string()` for the Unicode feature (#8155)
Diffstat (limited to 'quantum/process_keycode')
| -rw-r--r-- | quantum/process_keycode/process_unicode_common.c | 49 | ||||
| -rw-r--r-- | quantum/process_keycode/process_unicode_common.h | 1 |
2 files changed, 50 insertions, 0 deletions
diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c index 94383f19b..4ac305e66 100644 --- a/quantum/process_keycode/process_unicode_common.c +++ b/quantum/process_keycode/process_unicode_common.c | |||
| @@ -178,6 +178,55 @@ void send_unicode_hex_string(const char *str) { | |||
| 178 | } | 178 | } |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | // Borrowed from https://nullprogram.com/blog/2017/10/06/ | ||
| 182 | const char *decode_utf8(const char *str, int32_t *code_point) { | ||
| 183 | const char *next; | ||
| 184 | |||
| 185 | if (str[0] < 0x80) { // U+0000-007F | ||
| 186 | *code_point = str[0]; | ||
| 187 | next = str + 1; | ||
| 188 | } else if ((str[0] & 0xE0) == 0xC0) { // U+0080-07FF | ||
| 189 | *code_point = ((int32_t)(str[0] & 0x1F) << 6) | ((int32_t)(str[1] & 0x3F) << 0); | ||
| 190 | next = str + 2; | ||
| 191 | } else if ((str[0] & 0xF0) == 0xE0) { // U+0800-FFFF | ||
| 192 | *code_point = ((int32_t)(str[0] & 0x0F) << 12) | ((int32_t)(str[1] & 0x3F) << 6) | ((int32_t)(str[2] & 0x3F) << 0); | ||
| 193 | next = str + 3; | ||
| 194 | } else if ((str[0] & 0xF8) == 0xF0 && (str[0] <= 0xF4)) { // U+10000-10FFFF | ||
| 195 | // Skip for now - register_hex() only takes a uint16 | ||
| 196 | //*code_point = ((int32_t)(str[0] & 0x07) << 18) | ((int32_t)(str[1] & 0x3F) << 12) | ((int32_t)(str[2] & 0x3F) << 6) | ((int32_t)(str[3] & 0x3F) << 0); | ||
| 197 | *code_point = -1; | ||
| 198 | next = str + 4; | ||
| 199 | } else { | ||
| 200 | *code_point = -1; | ||
| 201 | next = str + 1; | ||
| 202 | } | ||
| 203 | |||
| 204 | // part of a UTF-16 surrogate pair - invalid | ||
| 205 | if (*code_point >= 0xD800 && *code_point <= 0xDFFF) { | ||
| 206 | *code_point = -1; | ||
| 207 | } | ||
| 208 | |||
| 209 | return next; | ||
| 210 | } | ||
| 211 | |||
| 212 | void send_unicode_string(const char *str) { | ||
| 213 | if (!str) { | ||
| 214 | return; | ||
| 215 | } | ||
| 216 | |||
| 217 | int32_t code_point = 0; | ||
| 218 | |||
| 219 | while (*str) { | ||
| 220 | str = decode_utf8(str, &code_point); | ||
| 221 | |||
| 222 | if (code_point >= 0) { | ||
| 223 | unicode_input_start(); | ||
| 224 | register_hex(code_point); | ||
| 225 | unicode_input_finish(); | ||
| 226 | } | ||
| 227 | } | ||
| 228 | } | ||
| 229 | |||
| 181 | bool process_unicode_common(uint16_t keycode, keyrecord_t *record) { | 230 | bool process_unicode_common(uint16_t keycode, keyrecord_t *record) { |
| 182 | if (record->event.pressed) { | 231 | if (record->event.pressed) { |
| 183 | switch (keycode) { | 232 | switch (keycode) { |
diff --git a/quantum/process_keycode/process_unicode_common.h b/quantum/process_keycode/process_unicode_common.h index cab6eea6e..393db2d99 100644 --- a/quantum/process_keycode/process_unicode_common.h +++ b/quantum/process_keycode/process_unicode_common.h | |||
| @@ -80,6 +80,7 @@ void unicode_input_cancel(void); | |||
| 80 | 80 | ||
| 81 | void register_hex(uint16_t hex); | 81 | void register_hex(uint16_t hex); |
| 82 | void send_unicode_hex_string(const char *str); | 82 | void send_unicode_hex_string(const char *str); |
| 83 | void send_unicode_string(const char *str); | ||
| 83 | 84 | ||
| 84 | bool process_unicode_common(uint16_t keycode, keyrecord_t *record); | 85 | bool process_unicode_common(uint16_t keycode, keyrecord_t *record); |
| 85 | 86 | ||
