3d667f09705fa780bd5881cfa3b3cb10fa41b1fe

Author
Ryan <fauxpark@gmail.com>
Committer
GitHub <noreply@github.com>
Date

Message

Refactor Unicode feature (#18333)

Diff

This diff is truncated to protect this page.

  1diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk
  2index f9618709c9ef580f7426df778fe1234a7296bc09..3d34c673d3aa3b24f649c83c5990e74c6bee6174 100644
  3--- a/builddefs/common_features.mk
  4+++ b/builddefs/common_features.mk
  5@@ -773,8 +773,10 @@ endif
  6 
  7 ifeq ($(strip $(UNICODE_COMMON)), yes)
  8     OPT_DEFS += -DUNICODE_COMMON_ENABLE
  9+    COMMON_VPATH += $(QUANTUM_DIR)/unicode
 10     SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c \
 11-           $(QUANTUM_DIR)/utf8.c
 12+           $(QUANTUM_DIR)/unicode/unicode.c \
 13+           $(QUANTUM_DIR)/unicode/utf8.c
 14 endif
 15 
 16 MAGIC_ENABLE ?= yes
 17diff --git a/quantum/painter/rules.mk b/quantum/painter/rules.mk
 18index 91787dfe0eb2ee16107c01ac990f0c6a53ace8be..4420bccf63ce64acb67ce6e30adcc2008e28ae6a 100644
 19--- a/quantum/painter/rules.mk
 20+++ b/quantum/painter/rules.mk
 21@@ -8,9 +8,10 @@ VALID_QUANTUM_PAINTER_DRIVERS := ili9163_spi ili9341_spi ili9488_spi st7789_spi
 22 #-------------------------------------------------------------------------------
 23 
 24 OPT_DEFS += -DQUANTUM_PAINTER_ENABLE
 25-COMMON_VPATH += $(QUANTUM_DIR)/painter
 26+COMMON_VPATH += $(QUANTUM_DIR)/painter \
 27+                $(QUANTUM_DIR)/unicode
 28 SRC += \
 29-    $(QUANTUM_DIR)/utf8.c \
 30+    $(QUANTUM_DIR)/unicode/utf8.c \
 31     $(QUANTUM_DIR)/color.c \
 32     $(QUANTUM_DIR)/painter/qp.c \
 33     $(QUANTUM_DIR)/painter/qp_stream.c \
 34diff --git a/quantum/process_keycode/process_ucis.c b/quantum/process_keycode/process_ucis.c
 35index 6a8d8f0ff6a465e96066a37ae96c491216474aeb..646471bc4d9aed9de85a03013016902466b12eae 100644
 36--- a/quantum/process_keycode/process_ucis.c
 37+++ b/quantum/process_keycode/process_ucis.c
 38@@ -15,6 +15,9 @@
 39  */
 40 
 41 #include "process_ucis.h"
 42+#include "unicode.h"
 43+#include "keycode.h"
 44+#include "wait.h"
 45 
 46 qk_ucis_state_t qk_ucis_state;
 47 
 48@@ -26,9 +29,7 @@ void qk_ucis_start(void) {
 49 }
 50 
 51 __attribute__((weak)) void qk_ucis_start_user(void) {
 52-    unicode_input_start();
 53-    register_hex(0x2328); // ⌨
 54-    unicode_input_finish();
 55+    register_unicode(0x2328); // ⌨
 56 }
 57 
 58 __attribute__((weak)) void qk_ucis_success(uint8_t symbol_index) {}
 59@@ -51,10 +52,7 @@ static bool is_uni_seq(char *seq) {
 60 
 61 __attribute__((weak)) void qk_ucis_symbol_fallback(void) {
 62     for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) {
 63-        uint8_t keycode = qk_ucis_state.codes[i];
 64-        register_code(keycode);
 65-        unregister_code(keycode);
 66-        wait_ms(UNICODE_TYPE_DELAY);
 67+        tap_code(qk_ucis_state.codes[i]);
 68     }
 69 }
 70 
 71@@ -63,7 +61,6 @@ __attribute__((weak)) void qk_ucis_cancel(void) {}
 72 void register_ucis(const uint32_t *code_points) {
 73     for (int i = 0; i < UCIS_MAX_CODE_POINTS && code_points[i]; i++) {
 74         register_unicode(code_points[i]);
 75-        wait_ms(UNICODE_TYPE_DELAY);
 76     }
 77 }
 78 
 79@@ -94,9 +91,7 @@ bool process_ucis(uint16_t keycode, keyrecord_t *record) {
 80         case KC_ENTER:
 81         case KC_ESCAPE:
 82             for (uint8_t i = 0; i < qk_ucis_state.count; i++) {
 83-                register_code(KC_BACKSPACE);
 84-                unregister_code(KC_BACKSPACE);
 85-                wait_ms(UNICODE_TYPE_DELAY);
 86+                tap_code(KC_BACKSPACE);
 87             }
 88 
 89             if (keycode == KC_ESCAPE) {
 90diff --git a/quantum/process_keycode/process_ucis.h b/quantum/process_keycode/process_ucis.h
 91index a667430bdace9624ff462c9e7ef224a23d1a4111..3de0707762fc3f8f03a7e853c07cd4d3c9fdfc59 100644
 92--- a/quantum/process_keycode/process_ucis.h
 93+++ b/quantum/process_keycode/process_ucis.h
 94@@ -16,8 +16,10 @@
 95 
 96 #pragma once
 97 
 98-#include "quantum.h"
 99-#include "process_unicode_common.h"
100+#include <stdbool.h>
101+#include <stdint.h>
102+
103+#include "action.h"
104 
105 #ifndef UCIS_MAX_SYMBOL_LENGTH
106 #    define UCIS_MAX_SYMBOL_LENGTH 32
107diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c
108index 18a1d8bc1f0df0e79ce5c4091494b201e7d3d1bb..99cc2f5f26de11864bdb7795ef68d55a9f525433 100644
109--- a/quantum/process_keycode/process_unicode.c
110+++ b/quantum/process_keycode/process_unicode.c
111@@ -15,14 +15,14 @@
112  */
113 
114 #include "process_unicode.h"
115-#include "action_util.h"
116-#include "eeprom.h"
117+#include "unicode.h"
118+#include "quantum_keycodes.h"
119 
120 bool process_unicode(uint16_t keycode, keyrecord_t *record) {
121-    if (keycode >= QK_UNICODE && keycode <= QK_UNICODE_MAX && record->event.pressed) {
122-        unicode_input_start();
123-        register_hex(keycode & 0x7FFF);
124-        unicode_input_finish();
125+    if (record->event.pressed) {
126+        if (keycode >= QK_UNICODE && keycode <= QK_UNICODE_MAX) {
127+            register_unicode(keycode & 0x7FFF);
128+        }
129     }
130     return true;
131 }
132diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h
133index 22765ad5604aaa9cabf9bf730fbba7d79577aace..341bc8d861dcd5968f1d5d2b51f60521365096ab 100644
134--- a/quantum/process_keycode/process_unicode.h
135+++ b/quantum/process_keycode/process_unicode.h
136@@ -16,6 +16,9 @@
137 
138 #pragma once
139 
140-#include "process_unicode_common.h"
141+#include <stdbool.h>
142+#include <stdint.h>
143+
144+#include "action.h"
145 
146 bool process_unicode(uint16_t keycode, keyrecord_t *record);
147diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c
148index 94809cf0297935baea240abaaf70380e9c98ec47..bd5fc560f3df1040622374fddda47b672f383581 100644
149--- a/quantum/process_keycode/process_unicode_common.c
150+++ b/quantum/process_keycode/process_unicode_common.c
151@@ -15,306 +15,17 @@
152  */
153 
154 #include "process_unicode_common.h"
155-#include "eeprom.h"
156-#include "utf8.h"
157+#include "unicode.h"
158+#include "action_util.h"
159+#include "keycode.h"
160 
161-unicode_config_t unicode_config;
162-uint8_t          unicode_saved_mods;
163-bool             unicode_saved_caps_lock;
164-bool             unicode_saved_num_lock;
165-
166-#if UNICODE_SELECTED_MODES != -1
167-static uint8_t selected[]     = {UNICODE_SELECTED_MODES};
168-static int8_t  selected_count = ARRAY_SIZE(selected);
169-static int8_t  selected_index;
170-#endif
171-
172-/** \brief Uunicode input mode set at user level
173- *
174- * Run user code on unicode input mode change
175- */
176-__attribute__((weak)) void unicode_input_mode_set_user(uint8_t input_mode) {}
177-
178-/** \brief unicode input mode set at keyboard level
179- *
180- *  Run keyboard code on unicode input mode change
181- */
182-__attribute__((weak)) void unicode_input_mode_set_kb(uint8_t input_mode) {
183-    unicode_input_mode_set_user(input_mode);
184-}
185-
186-void unicode_input_mode_init(void) {
187-    unicode_config.raw = eeprom_read_byte(EECONFIG_UNICODEMODE);
188-#if UNICODE_SELECTED_MODES != -1
189-#    if UNICODE_CYCLE_PERSIST
190-    // Find input_mode in selected modes
191-    int8_t i;
192-    for (i = 0; i < selected_count; i++) {
193-        if (selected[i] == unicode_config.input_mode) {
194-            selected_index = i;
195-            break;
196-        }
197-    }
198-    if (i == selected_count) {
199-        // Not found: input_mode isn't selected, change to one that is
200-        unicode_config.input_mode = selected[selected_index = 0];
201-    }
202-#    else
203-    // Always change to the first selected input mode
204-    unicode_config.input_mode = selected[selected_index = 0];
205-#    endif
206-#endif
207-    unicode_input_mode_set_kb(unicode_config.input_mode);
208-    dprintf("Unicode input mode init to: %u\n", unicode_config.input_mode);
209-}
210-
211-uint8_t get_unicode_input_mode(void) {
212-    return unicode_config.input_mode;
213-}
214-
215-void set_unicode_input_mode(uint8_t mode) {
216-    unicode_config.input_mode = mode;
217-    persist_unicode_input_mode();
218-    unicode_input_mode_set_kb(mode);
219-    dprintf("Unicode input mode set to: %u\n", unicode_config.input_mode);
220-}
221-
222-void cycle_unicode_input_mode(int8_t offset) {
223-#if UNICODE_SELECTED_MODES != -1
224-    selected_index = (selected_index + offset) % selected_count;
225-    if (selected_index < 0) {
226-        selected_index += selected_count;
227-    }
228-    unicode_config.input_mode = selected[selected_index];
229-#    if UNICODE_CYCLE_PERSIST
230-    persist_unicode_input_mode();
231-#    endif
232-    unicode_input_mode_set_kb(unicode_config.input_mode);
233-    dprintf("Unicode input mode cycle to: %u\n", unicode_config.input_mode);
234-#endif
235-}
236-
237-void persist_unicode_input_mode(void) {
238-    eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config.input_mode);
239-}
240-
241-__attribute__((weak)) void unicode_input_start(void) {
242-    unicode_saved_caps_lock = host_keyboard_led_state().caps_lock;
243-    unicode_saved_num_lock  = host_keyboard_led_state().num_lock;
244-
245-    // Note the order matters here!
246-    // Need to do this before we mess around with the mods, or else
247-    // UNICODE_KEY_LNX (which is usually Ctrl-Shift-U) might not work
248-    // correctly in the shifted case.
249-    if (unicode_config.input_mode == UC_LNX && unicode_saved_caps_lock) {
250-        tap_code(KC_CAPS_LOCK);
251diff --git a/quantum/process_keycode/process_unicode_common.h b/quantum/process_keycode/process_unicode_common.h
252index 0fe672d26a5f17c5eb0c6822fcd12e9e040b0a50..fd09a41818f93a895af2ce77798feed9f12d0b78 100644
253--- a/quantum/process_keycode/process_unicode_common.h
254+++ b/quantum/process_keycode/process_unicode_common.h
255@@ -16,181 +16,9 @@
256 
257 #pragma once
258 
259-#include "quantum.h"
260+#include <stdbool.h>
261+#include <stdint.h>
262 
263-#if defined(UNICODE_ENABLE) + defined(UNICODEMAP_ENABLE) + defined(UCIS_ENABLE) > 1
264-#    error "Cannot enable more than one Unicode method (UNICODE, UNICODEMAP, UCIS) at the same time"
265-#endif
266-
267-// Keycodes used for starting Unicode input on different platforms
268-#ifndef UNICODE_KEY_MAC
269-#    define UNICODE_KEY_MAC KC_LEFT_ALT
270-#endif
271-#ifndef UNICODE_KEY_LNX
272-#    define UNICODE_KEY_LNX LCTL(LSFT(KC_U))
273-#endif
274-#ifndef UNICODE_KEY_WINC
275-#    define UNICODE_KEY_WINC KC_RIGHT_ALT
276-#endif
277-
278-// Comma-delimited, ordered list of input modes selected for use (e.g. in cycle)
279-// Example: #define UNICODE_SELECTED_MODES UC_WINC, UC_LNX
280-#ifndef UNICODE_SELECTED_MODES
281-#    define UNICODE_SELECTED_MODES -1
282-#endif
283-
284-// Whether input mode changes in cycle should be written to EEPROM
285-#ifndef UNICODE_CYCLE_PERSIST
286-#    define UNICODE_CYCLE_PERSIST true
287-#endif
288-
289-// Delay between starting Unicode input and sending a sequence, in ms
290-#ifndef UNICODE_TYPE_DELAY
291-#    define UNICODE_TYPE_DELAY 10
292-#endif
293-
294-enum unicode_input_modes {
295-    UC_MAC,   // macOS using Unicode Hex Input
296-    UC_LNX,   // Linux using IBus
297-    UC_WIN,   // Windows using EnableHexNumpad
298-    UC_BSD,   // BSD (not implemented)
299-    UC_WINC,  // Windows using WinCompose (https://github.com/samhocevar/wincompose)
300-    UC_EMACS, // Emacs is an operating system in search of a good text editor
301-    UC__COUNT // Number of available input modes (always leave at the end)
302-};
303-
304-typedef union {
305-    uint32_t raw;
306-    struct {
307-        uint8_t input_mode : 8;
308-    };
309-} unicode_config_t;
310-
311-extern unicode_config_t unicode_config;
312-
313-void    unicode_input_mode_init(void);
314-uint8_t get_unicode_input_mode(void);
315-void    set_unicode_input_mode(uint8_t mode);
316-void    cycle_unicode_input_mode(int8_t offset);
317-void    persist_unicode_input_mode(void);
318-
319-void unicode_input_start(void);
320-void unicode_input_finish(void);
321-void unicode_input_cancel(void);
322-
323-void unicode_input_mode_set_user(uint8_t input_mode);
324-void unicode_input_mode_set_kb(uint8_t input_mode);
325-
326-void register_hex(uint16_t hex);
327-void register_hex32(uint32_t hex);
328-void register_unicode(uint32_t code_point);
329-
330-void send_unicode_string(const char *str);
331+#include "action.h"
332 
333 bool process_unicode_common(uint16_t keycode, keyrecord_t *record);
334-
335-#define UC_BSPC UC(0x0008)
336-#define UC_SPC UC(0x0020)
337-
338-#define UC_EXLM UC(0x0021)
339-#define UC_DQUT UC(0x0022)
340-#define UC_HASH UC(0x0023)
341-#define UC_DLR UC(0x0024)
342-#define UC_PERC UC(0x0025)
343-#define UC_AMPR UC(0x0026)
344-#define UC_QUOT UC(0x0027)
345-#define UC_LPRN UC(0x0028)
346-#define UC_RPRN UC(0x0029)
347-#define UC_ASTR UC(0x002A)
348-#define UC_PLUS UC(0x002B)
349-#define UC_COMM UC(0x002C)
350-#define UC_DASH UC(0x002D)
351-#define UC_DOT UC(0x002E)
352-#define UC_SLSH UC(0x002F)
353-
354-#define UC_0 UC(0x0030)
355diff --git a/quantum/process_keycode/process_unicodemap.c b/quantum/process_keycode/process_unicodemap.c
356index 459397014d253a99a21f13abbd0cb40a22740341..979d773b051fadccc91935a7e3ba6aa4402baad5 100644
357--- a/quantum/process_keycode/process_unicodemap.c
358+++ b/quantum/process_keycode/process_unicodemap.c
359@@ -15,6 +15,11 @@
360  */
361 
362 #include "process_unicodemap.h"
363+#include "unicode.h"
364+#include "quantum_keycodes.h"
365+#include "keycode.h"
366+#include "action_util.h"
367+#include "host.h"
368 
369 __attribute__((weak)) uint16_t unicodemap_index(uint16_t keycode) {
370     if (keycode >= QK_UNICODEMAP_PAIR) {
371diff --git a/quantum/process_keycode/process_unicodemap.h b/quantum/process_keycode/process_unicodemap.h
372index c429859bbb6ab42585bb6ea0e3502ba9baa5904c..73f544986400212f4712f77f0e8be62449d0c4b7 100644
373--- a/quantum/process_keycode/process_unicodemap.h
374+++ b/quantum/process_keycode/process_unicodemap.h
375@@ -16,7 +16,11 @@
376 
377 #pragma once
378 
379-#include "process_unicode_common.h"
380+#include <stdbool.h>
381+#include <stdint.h>
382+
383+#include "action.h"
384+#include "progmem.h"
385 
386 extern const uint32_t PROGMEM unicode_map[];
387 
388diff --git a/quantum/quantum.h b/quantum/quantum.h
389index 8d74f2be38f6266db1a36eef34414d910aaa9468..51360c3d2a1c6b65812cc682bccf1abc9d8db2fa 100644
390--- a/quantum/quantum.h
391+++ b/quantum/quantum.h
392@@ -109,6 +109,7 @@ extern layer_state_t layer_state;
393 #endif
394 
395 #ifdef UNICODE_COMMON_ENABLE
396+#    include "unicode.h"
397 #    include "process_unicode_common.h"
398 #endif
399 
400diff --git a/quantum/unicode/unicode.c b/quantum/unicode/unicode.c
401new file mode 100644
402index 0000000000000000000000000000000000000000..f9f429e7afb5d5ab55fcca22c7d08e01c42da395
403--- /dev/null
404+++ b/quantum/unicode/unicode.c
405@@ -0,0 +1,376 @@
406+/* Copyright 2022
407+ *
408+ * This program is free software: you can redistribute it and/or modify
409+ * it under the terms of the GNU General Public License as published by
410+ * the Free Software Foundation, either version 2 of the License, or
411+ * (at your option) any later version.
412+ *
413+ * This program is distributed in the hope that it will be useful,
414+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
415+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
416+ * GNU General Public License for more details.
417+ *
418+ * You should have received a copy of the GNU General Public License
419+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
420+ */
421+
422+#include "unicode.h"
423+
424+#include "eeprom.h"
425+#include "eeconfig.h"
426+#include "action.h"
427+#include "action_util.h"
428+#include "host.h"
429+#include "keycode.h"
430+#include "wait.h"
431+#include "audio.h"
432+#include "send_string.h"
433+#include "utf8.h"
434+
435+#if defined(UNICODE_ENABLE) + defined(UNICODEMAP_ENABLE) + defined(UCIS_ENABLE) > 1
436+#    error "Cannot enable more than one Unicode method (UNICODE, UNICODEMAP, UCIS) at the same time"
437+#endif
438+
439+// Keycodes used for starting Unicode input on different platforms
440+#ifndef UNICODE_KEY_MAC
441+#    define UNICODE_KEY_MAC KC_LEFT_ALT
442+#endif
443+#ifndef UNICODE_KEY_LNX
444+#    define UNICODE_KEY_LNX LCTL(LSFT(KC_U))
445+#endif
446+#ifndef UNICODE_KEY_WINC
447+#    define UNICODE_KEY_WINC KC_RIGHT_ALT
448+#endif
449+
450+// Comma-delimited, ordered list of input modes selected for use (e.g. in cycle)
451+// Example: #define UNICODE_SELECTED_MODES UC_WINC, UC_LNX
452+#ifndef UNICODE_SELECTED_MODES
453+#    define UNICODE_SELECTED_MODES -1
454+#endif
455+
456+// Whether input mode changes in cycle should be written to EEPROM
457+#ifndef UNICODE_CYCLE_PERSIST
458+#    define UNICODE_CYCLE_PERSIST true
459+#endif
460+
461+// Delay between starting Unicode input and sending a sequence, in ms
462+#ifndef UNICODE_TYPE_DELAY
463+#    define UNICODE_TYPE_DELAY 10
464+#endif
465+
466+unicode_config_t unicode_config;
467+uint8_t          unicode_saved_mods;
468+led_t            unicode_saved_led_state;
469+
470+#if UNICODE_SELECTED_MODES != -1
471+static uint8_t selected[]     = {UNICODE_SELECTED_MODES};
472+static int8_t  selected_count = ARRAY_SIZE(selected);
473+static int8_t  selected_index;
474+#endif
475+
476+/** \brief unicode input mode set at user level
477+ *
478+ * Run user code on unicode input mode change
479+ */
480+__attribute__((weak)) void unicode_input_mode_set_user(uint8_t input_mode) {}
481+
482+/** \brief unicode input mode set at keyboard level
483+ *
484+ *  Run keyboard code on unicode input mode change
485+ */
486+__attribute__((weak)) void unicode_input_mode_set_kb(uint8_t input_mode) {
487+    unicode_input_mode_set_user(input_mode);
488+}
489+
490+#ifdef AUDIO_ENABLE
491+#    ifdef UNICODE_SONG_MAC
492+static float song_mac[][2] = UNICODE_SONG_MAC;
493+#    endif
494+#    ifdef UNICODE_SONG_LNX
495+static float song_lnx[][2] = UNICODE_SONG_LNX;
496+#    endif
497+#    ifdef UNICODE_SONG_WIN
498+static float song_win[][2] = UNICODE_SONG_WIN;
499+#    endif
500+#    ifdef UNICODE_SONG_BSD
501+static float song_bsd[][2] = UNICODE_SONG_BSD;
502+#    endif
503+#    ifdef UNICODE_SONG_WINC
504+static float song_winc[][2] = UNICODE_SONG_WINC;
505diff --git a/quantum/unicode/unicode.h b/quantum/unicode/unicode.h
506new file mode 100644
507index 0000000000000000000000000000000000000000..b3e43799ffae6b0dc51d62c07a0f34cab1627bf4
508--- /dev/null
509+++ b/quantum/unicode/unicode.h
510@@ -0,0 +1,165 @@
511+/* Copyright 2022
512+ *
513+ * This program is free software: you can redistribute it and/or modify
514+ * it under the terms of the GNU General Public License as published by
515+ * the Free Software Foundation, either version 2 of the License, or
516+ * (at your option) any later version.
517+ *
518+ * This program is distributed in the hope that it will be useful,
519+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
520+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
521+ * GNU General Public License for more details.
522+ *
523+ * You should have received a copy of the GNU General Public License
524+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
525+ */
526+
527+#pragma once
528+
529+#include <stdint.h>
530+
531+#include "quantum.h"
532+
533+typedef union {
534+    uint32_t raw;
535+    struct {
536+        uint8_t input_mode : 8;
537+    };
538+} unicode_config_t;
539+
540+extern unicode_config_t unicode_config;
541+
542+enum unicode_input_modes {
543+    UC_MAC,   // macOS using Unicode Hex Input
544+    UC_LNX,   // Linux using IBus
545+    UC_WIN,   // Windows using EnableHexNumpad
546+    UC_BSD,   // BSD (not implemented)
547+    UC_WINC,  // Windows using WinCompose (https://github.com/samhocevar/wincompose)
548+    UC_EMACS, // Emacs is an operating system in search of a good text editor
549+    UC__COUNT // Number of available input modes (always leave at the end)
550+};
551+
552+void    unicode_input_mode_init(void);
553+uint8_t get_unicode_input_mode(void);
554+void    set_unicode_input_mode(uint8_t mode);
555+void    cycle_unicode_input_mode(int8_t offset);
556+void    persist_unicode_input_mode(void);
557+
558+void unicode_input_mode_set_user(uint8_t input_mode);
559+void unicode_input_mode_set_kb(uint8_t input_mode);
560+
561+void unicode_input_start(void);
562+void unicode_input_finish(void);
563+void unicode_input_cancel(void);
564+
565+void register_hex(uint16_t hex);
566+void register_hex32(uint32_t hex);
567+void register_unicode(uint32_t code_point);
568+
569+void send_unicode_string(const char *str);
570+
571+// clang-format off
572+
573+#define UC_BSPC UC(0x0008) // (backspace)
574+
575+#define UC_SPC  UC(0x0020) // (space)
576+#define UC_EXLM UC(0x0021) // !
577+#define UC_DQUT UC(0x0022) // "
578+#define UC_HASH UC(0x0023) // #
579+#define UC_DLR  UC(0x0024) // $
580+#define UC_PERC UC(0x0025) // %
581+#define UC_AMPR UC(0x0026) // &
582+#define UC_QUOT UC(0x0027) // '
583+#define UC_LPRN UC(0x0028) // (
584+#define UC_RPRN UC(0x0029) // )
585+#define UC_ASTR UC(0x002A) // *
586+#define UC_PLUS UC(0x002B) // +
587+#define UC_COMM UC(0x002C) // ,
588+#define UC_DASH UC(0x002D) // -
589+#define UC_DOT  UC(0x002E) // .
590+#define UC_SLSH UC(0x002F) // /
591+
592+#define UC_0    UC(0x0030) // 0
593+#define UC_1    UC(0x0031) // 1
594+#define UC_2    UC(0x0032) // 2
595+#define UC_3    UC(0x0033) // 3
596+#define UC_4    UC(0x0034) // 4
597+#define UC_5    UC(0x0035) // 5
598+#define UC_6    UC(0x0036) // 6
599+#define UC_7    UC(0x0037) // 7
600+#define UC_8    UC(0x0038) // 8
601+#define UC_9    UC(0x0039) // 9
602+#define UC_COLN UC(0x003A) // :
603+#define UC_SCLN UC(0x003B) // ;
604+#define UC_LT   UC(0x003C) // <
605+#define UC_EQL  UC(0x003D) // =
606+#define UC_GT   UC(0x003E) // >
607+#define UC_QUES UC(0x003F) // ?
608+
609+#define UC_AT   UC(0x0040) // @
610diff --git a/quantum/utf8.c b/quantum/unicode/utf8.c
611rename from quantum/utf8.c
612rename to quantum/unicode/utf8.c
613diff --git a/quantum/utf8.h b/quantum/unicode/utf8.h
614rename from quantum/utf8.h
615rename to quantum/unicode/utf8.h
616index fb10910944c2425622c5f3aee7b25b7ff82cae5c..521dd1918c36df1875354a422982461f39dea268 100644
617--- a/quantum/utf8.h
618+++ b/quantum/unicode/utf8.h
619@@ -18,4 +18,4 @@
620 
621 #include <stdint.h>
622 
623-const char *decode_utf8(const char *str, int32_t *code_point);
624+const char *decode_utf8(const char *str, int32_t *code_point);