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/process_unicode_common.c | |
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/process_unicode_common.c')
-rw-r--r-- | quantum/process_keycode/process_unicode_common.c | 49 |
1 files changed, 49 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) { |