aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrashna Jaelre <drashna@live.com>2018-12-19 08:39:24 -0800
committerMechMerlin <30334081+mechmerlin@users.noreply.github.com>2018-12-19 08:39:24 -0800
commitfdeec296369c0995bad1117e50946b2df84f35e4 (patch)
treec20ca5d0e302b189298d37b3abb97c4f37f5b606
parent40bf3a2ce9ec781cc2ff7218f909ffdbece44e97 (diff)
downloadqmk_firmware-fdeec296369c0995bad1117e50946b2df84f35e4.tar.gz
qmk_firmware-fdeec296369c0995bad1117e50946b2df84f35e4.zip
Overhaul Unicode Common functionality (#4325)
* Standardize the Unicode EEPROM code * Remove unicode init from process_record_* functions * Add unicode init to where it belongs: matrix_init_quantum * Move Unicode proccessing to unicode common * Add audio feedback to input mode keys to drive konstantin up a wall * Tap_code cleanup * Update keycodes * Update unicode documentation * Update unicode keycodes for consistency/easier merge * Add Audio Feedback section * Remove Functions from feature page And link to the file instead. Link to specific lines later on. * Fix spacing Co-Authored-By: drashna <drashna@live.com> * Because I missed it! Co-Authored-By: drashna <drashna@live.com> * Fix spacing Co-Authored-By: drashna <drashna@live.com> * SPAAAAAAAAAACing Co-Authored-By: drashna <drashna@live.com> * Add BSD for future compatibility * Thought I fixed that! Co-Authored-By: drashna <drashna@live.com> * non-breaking Co-Authored-By: drashna <drashna@live.com> * Considered that Co-Authored-By: drashna <drashna@live.com> * Yuuup Co-Authored-By: drashna <drashna@live.com> * consistency Co-Authored-By: drashna <drashna@live.com> * white spaces .... copied from elsewhere Co-Authored-By: drashna <drashna@live.com> * white spaces Co-Authored-By: drashna <drashna@live.com> * white spaces Co-Authored-By: drashna <drashna@live.com> * Update keycode defines * Fix Linux Song * Update all of the songs * Cleanup * Move and update check to ensure only one unicode method is enabled * Update quantum/quantum_keycodes.h * Update documentation * Wordsmithing and cleanup * Format unicode_common (#13) * case alignment * process_record_unicode_common → process_unicode_common * Move song arrays into function where they're used, align preprocessor directives * Swap the order of UC_WIN and UC_BSD * Update Unicode docs * Reorder Unicode mode stuff to match the order of input mode constants * Fix capitalization in doc subtitle * Readd BSD and OSX_RALT songs * Reword BSD note in docs * Readd BSD keycode description * Reword explanation of input on different platforms * Steal vomindoraan's input mode documentation Co-Authored-By: vomindoraan (vomindoraan@gmail.com) * Willingly give Drashna the rest of my Unicode doc improvements * Wordsmithing Co-Authored-By: drashna <drashna@live.com> * remove merge artifacts * Unicode common cleanup (#17) * Standardize the Unicode EEPROM code * Remove unicode init from process_record_* functions * Add unicode init to where it belongs: matrix_init_quantum * Move Unicode proccessing to unicode common * Add audio feedback to input mode keys to drive konstantin up a wall * Tap_code cleanup * Update keycodes * Update unicode documentation * Update unicode keycodes for consistency/easier merge * Add Audio Feedback section * Remove Functions from feature page And link to the file instead. Link to specific lines later on. * Fix white spaces Co-Authored-By: drashna <drashna@live.com> * Fix spacing Co-Authored-By: drashna <drashna@live.com> * Because I missed it! Co-Authored-By: drashna <drashna@live.com> * Fix spacing Co-Authored-By: drashna <drashna@live.com> * SPAAAAAAAAAACing Co-Authored-By: drashna <drashna@live.com> * white spaces Co-Authored-By: drashna <drashna@live.com> * Add BSD for future compatibility * Thought I fixed that! Co-Authored-By: drashna <drashna@live.com> * non-breaking Co-Authored-By: drashna <drashna@live.com> * Considered that Co-Authored-By: drashna <drashna@live.com> * Yuuup Co-Authored-By: drashna <drashna@live.com> * consistency Co-Authored-By: drashna <drashna@live.com> * white spaces .... copied from elsewhere Co-Authored-By: drashna <drashna@live.com> * white spaces Co-Authored-By: drashna <drashna@live.com> * white spaces Co-Authored-By: drashna <drashna@live.com> * Update keycode defines * Fix Linux Song * Update all of the songs * Cleanup * Move and update check to ensure only one unicode method is enabled * Update quantum/quantum_keycodes.h * Update documentation * Wordsmithing and cleanup * Format unicode_common (#13) * case alignment * process_record_unicode_common → process_unicode_common * Move song arrays into function where they're used, align preprocessor directives * Swap the order of UC_WIN and UC_BSD * Update Unicode docs * Reorder Unicode mode stuff to match the order of input mode constants * Fix capitalization in doc subtitle * Readd BSD and OSX_RALT songs * Reword BSD note in docs * Readd BSD keycode description * Reword explanation of input on different platforms * Steal vomindoraan's input mode documentation Co-Authored-By: vomindoraan (vomindoraan@gmail.com) * Willingly give Drashna the rest of my Unicode doc improvements * Wordsmithing Co-Authored-By: drashna <drashna@live.com> * Rearrange process_unicode_common functions * Make Unicode input mode constants (UC_*) an enum * Simplify unicode_input_start/finish code * Make the key used for WinCompose configurable * Remove UC_OSX_RALT in favor of setting the key with UNICODE_OSX_KEY * Update Unicode input mode doc * Add descriptions and rearrange definitions in process_unicode_common.h * Add registry command to Unicode docs + misc updates * Reword an explanation in Unicode docs * Add TODO comment * Remove trailing whitespace * Improve Cycling documentation * Add Unicode Input method Cycling support (#19) * Standardize the Unicode EEPROM code * Remove unicode init from process_record_* functions * Add unicode init to where it belongs: matrix_init_quantum * Move Unicode proccessing to unicode common * Add audio feedback to input mode keys to drive konstantin up a wall * Tap_code cleanup * Update keycodes * Update unicode documentation * Update unicode keycodes for consistency/easier merge * Add Audio Feedback section * Remove Functions from feature page And link to the file instead. Link to specific lines later on. * Fix white spaces Co-Authored-By: drashna <drashna@live.com> * Fix spacing Co-Authored-By: drashna <drashna@live.com> * Because I missed it! Co-Authored-By: drashna <drashna@live.com> * Fix spacing Co-Authored-By: drashna <drashna@live.com> * SPAAAAAAAAAACing Co-Authored-By: drashna <drashna@live.com> * white spaces Co-Authored-By: drashna <drashna@live.com> * Add BSD for future compatibility * Thought I fixed that! Co-Authored-By: drashna <drashna@live.com> * non-breaking Co-Authored-By: drashna <drashna@live.com> * Considered that Co-Authored-By: drashna <drashna@live.com> * Yuuup Co-Authored-By: drashna <drashna@live.com> * consistency Co-Authored-By: drashna <drashna@live.com> * white spaces .... copied from elsewhere Co-Authored-By: drashna <drashna@live.com> * white spaces Co-Authored-By: drashna <drashna@live.com> * white spaces Co-Authored-By: drashna <drashna@live.com> * Update keycode defines * Fix Linux Song * Update all of the songs * Cleanup * Move and update check to ensure only one unicode method is enabled * Update quantum/quantum_keycodes.h * Update documentation * Wordsmithing and cleanup * Format unicode_common (#13) * case alignment * process_record_unicode_common → process_unicode_common * Move song arrays into function where they're used, align preprocessor directives * Swap the order of UC_WIN and UC_BSD * Update Unicode docs * Reorder Unicode mode stuff to match the order of input mode constants * Fix capitalization in doc subtitle * Readd BSD and OSX_RALT songs * Reword BSD note in docs * Readd BSD keycode description * Reword explanation of input on different platforms * Steal vomindoraan's input mode documentation Co-Authored-By: vomindoraan (vomindoraan@gmail.com) * Willingly give Drashna the rest of my Unicode doc improvements * Wordsmithing Co-Authored-By: drashna <drashna@live.com> * Rearrange process_unicode_common functions * Make Unicode input mode constants (UC_*) an enum * Simplify unicode_input_start/finish code * Make the key used for WinCompose configurable * Remove UC_OSX_RALT in favor of setting the key with UNICODE_OSX_KEY * Update Unicode input mode doc * Add descriptions and rearrange definitions in process_unicode_common.h * Add registry command to Unicode docs + misc updates * Reword an explanation in Unicode docs * Add TODO comment * Add cycle_unicode_input_mode and UNICODE_SELECTED_MODES macro * Add an option for making cycle changes persistent * Add debug prints to functions that change input_mode * Use cycle_unicode_input_mode in whitefox/konstantin * Add persist_unicode_input_mode function * Add offset to cycle to allow stepping in reverse * Add keycodes: UNICODE_MODE_FORWARD, UNICODE_MODE_REVERSE Aliases: UC_MOD, UC_RMOD (respectively) * REVERT ME: Undo changes to whitefox/konstantin to avoid conflicts * Fix wrong constant name * Revert "REVERT ME: Undo changes to whitefox/konstantin to avoid conflicts" This reverts commit 42676bf251fc8e3823f5e614dad6e510ba47a2f3. * Change dprintf text * Give selected modes priority over EEPROM when !UNICODE_CYCLE_PERSIST * Remove trailing whitespace * Cleanup of RALT code and unicode compilation stuff * Remove else for unicode handling
-rw-r--r--docs/feature_unicode.md133
-rw-r--r--keyboards/whitefox/keymaps/konstantin/config.h4
-rw-r--r--keyboards/whitefox/keymaps/konstantin/keymap.c8
-rw-r--r--quantum/process_keycode/process_ucis.c2
-rw-r--r--quantum/process_keycode/process_ucis.h5
-rw-r--r--quantum/process_keycode/process_unicode.c2
-rw-r--r--quantum/process_keycode/process_unicode.h5
-rw-r--r--quantum/process_keycode/process_unicode_common.c200
-rw-r--r--quantum/process_keycode/process_unicode_common.h66
-rw-r--r--quantum/process_keycode/process_unicodemap.c5
-rw-r--r--quantum/process_keycode/process_unicodemap.h4
-rw-r--r--quantum/quantum.c19
-rw-r--r--quantum/quantum_keycodes.h21
13 files changed, 319 insertions, 155 deletions
diff --git a/docs/feature_unicode.md b/docs/feature_unicode.md
index c98a40228..1b083896a 100644
--- a/docs/feature_unicode.md
+++ b/docs/feature_unicode.md
@@ -1,28 +1,28 @@
1# Unicode Support 1# Unicode Support
2 2
3There are three Unicode keymap definition method available in QMK: 3There are three Unicode keymap definition methods available in QMK:
4 4
5## UNICODE_ENABLE 5## UNICODE_ENABLE
6 6
7Supports Unicode input up to 0xFFFF. The keycode function is `UC(n)` in keymap file, where *n* is a 4 digit hexadecimal. 7Supports Unicode up to `0xFFFF`. The keycode function is `UC(n)` in the keymap file, where _n_ is a 4 digit hexadecimal number.
8 8
9## UNICODEMAP_ENABLE 9## UNICODEMAP_ENABLE
10 10
11Supports Unicode up to 0xFFFFFFFF. You need to maintain a separate mapping table `const uint32_t PROGMEM unicode_map[] = {...}` in your keymap file. The keycode function is `X(n)` where *n* is the array index of the mapping table. 11Supports Unicode up to `0x10FFFF` (all possible code points). You need to maintain a separate mapping table `const uint32_t PROGMEM unicode_map[] = {...}` in your keymap file. The keycode function is `X(n)`, where _n_ is an array index into the mapping table.
12 12
13And you may want to have an enum to make reference easier. So you'd want to add something like this to your keymap: 13And you may want to have an enum to make reference easier. So you'd want to add something like this to your keymap:
14 14
15```c 15```c
16enum unicode_name { 16enum unicode_names {
17 BANG, // ‽ 17 BANG,
18 IRONY, // ⸮ 18 IRONY,
19 SNEK // snke 🐍 19 SNEK,
20}; 20};
21 21
22const uint32_t PROGMEM unicode_map[] = { 22const uint32_t PROGMEM unicode_map[] = {
23 [BANG] = 0x0203D, // ‽ 23 [BANG] = 0x203D, // ‽
24 [IRONY] = 0x02E2E, // ⸮ 24 [IRONY] = 0x2E2E, // ⸮
25 [SNEK] = 0x1F40D // snke 🐍 25 [SNEK] = 0x1F40D, // 🐍
26}: 26}:
27``` 27```
28 28
@@ -30,7 +30,7 @@ Make sure that the order for both matches.
30 30
31## UCIS_ENABLE 31## UCIS_ENABLE
32 32
33Supports Unicode up to 0xFFFFFFFF. As with `UNICODE_MAP`, you may want to maintain a mapping table in your keymap file. However, there is no keycodes for this feature, you will have to add a keycode or function to call `qk_ucis_start()`. Once you've run that, you can just type the text for your unicode, and then hit space or enter to complete it, or ESC to cancel it. And if it matches an entry in your table, it will automatically "backspace" the trigger word (from your table) and then will input the unicode sequence. 33Supports Unicode up to `0x10FFFF` (all possible code points). As with `UNICODEMAP`, you may want to maintain a mapping table in your keymap file. However, there are no built-in keycodes for this feature — you will have to add a keycode or function that calls `qk_ucis_start()`. Once it's been called, you can type the mnemonic for your character, then hit Space or Enter to complete it or Esc to cancel. If the mnemonic matches an entry in your table, the typed text will automatically be erased and the corresponding Unicode sequence inserted.
34 34
35For instance, you would need to have a table like this in your keymap: 35For instance, you would need to have a table like this in your keymap:
36 36
@@ -53,42 +53,103 @@ There are several functions that you can add to your keymap to customize the fun
53* `void qk_ucis_success(uint8_t symbol_index)` - This runs when the unicode input has matched something, and has completed. Default doesn't do anything. 53* `void qk_ucis_success(uint8_t symbol_index)` - This runs when the unicode input has matched something, and has completed. Default doesn't do anything.
54* `void qk_ucis_symbol_fallback (void)` - This runs if the input text doesn't match anything. The default function falls back to trying that input as a unicode code. 54* `void qk_ucis_symbol_fallback (void)` - This runs if the input text doesn't match anything. The default function falls back to trying that input as a unicode code.
55 55
56The default code for these are: 56You can find the default implementations of these functions in [`process_ucis.c`](https://github.com/qmk/qmk_firmware/blob/master/quantum/process_keycode/process_ucis.c).
57
58## Input Modes
59
60Unicode input in QMK works by inputting a sequence of characters to the OS, sort of like a macro. Unfortunately, the way this is done differs for each platform. Specifically, each platform requires a different combination of keys to trigger Unicode input. Therefore, a corresponding input mode has to be set in QMK.
61
62The following input modes are available:
63
64* **`UC_OSX`**: Mac OS X built-in Unicode hex input. Supports code points up to `0xFFFF` (`0x10FFFF` with `UNICODEMAP`).
65
66 To enable, go to _System Preferences > Keyboard > Input Sources_, add _Unicode Hex Input_ to the list (it's under _Other_), then activate it from the input dropdown in the Menu Bar.
67 By default, this mode uses the left Option key (`KC_LALT`), but this can be changed by defining [`UNICODE_OSX_KEY`](#input-key-configuration) with another keycode.
68
69* **`UC_LNX`**: Linux built-in IBus Unicode input. Supports all possible code points (`0x10FFFF`).
70
71 Enabled by default and works almost anywhere on IBus-enabled distros. Without IBus, this mode works under GTK apps, but rarely anywhere else.
72
73* **`UC_WIN`**: _(not recommended)_ Windows built-in hex numpad Unicode input. Supports code points up to `0xFFFF`.
74
75 To enable, create a registry key under `HKEY_CURRENT_USER\Control Panel\Input Method\EnableHexNumpad` of type `REG_SZ` called `EnableHexNumpad` and set its value to `1`. This can be done from the Command Prompt by running `reg add "HKCU\Control Panel\Input Method" -v EnableHexNumpad -t REG_SZ -d 1` with administrator privileges. Afterwards, reboot.
76 This mode is not recommended because of reliability and compatibility issues; use the `UC_WINC` mode instead.
77
78* **`UC_BSD`**: _(non implemented)_ Unicode input under BSD. Not implemented at this time. If you're a BSD user and want to help add support for it, please [open an issue on GitHub](https://github.com/qmk/qmk_firmware/issues).
79
80* **`UC_WINC`**: Windows Unicode input using [WinCompose](https://github.com/samhocevar/wincompose). As of v0.8.2, supports code points up to `0xFFFFF`.
81
82 To enable, install the [latest release](https://github.com/samhocevar/wincompose/releases/latest). Once installed, WinCompose will automatically run on startup. Works reliably under all version of Windows supported by the app.
83 By default, this mode uses the right Alt key (`KC_RALT`), but this can be changed in the WinCompose settings and by defining [`UNICODE_WINC_KEY`](#input-key-configuration) with another keycode.
84
85### Switching Input Modes
86
87There are two ways to set the input mode for Unicode: by keycode or by function. Keep in mind that both methods write to persistent storage (EEPROM), and are loaded each time the keyboard starts. So once you've set it the first time, you don't need to set it again unless you want to change it, or you've reset the EEPROM settings.
88
89You can switch the input mode at any time by using one of the following keycodes. The easiest way is to add the ones you use to your keymap.
90
91|Keycode |Alias |Input mode |Description |
92|-----------------------|---------|-------------|-----------------------------------------|
93|`UNICODE_MODE_FORWARD` |`UC_MOD` | |Cycles forwards through the available modes. [(Disabled by default)](#input-method-cycling)|
94|`UNICODE_MODE_REVERSE` |`UC_RMOD`| |Cycles forwards through the available modes. [(Disabled by default)](#input-method-cycling)|
95|`UNICODE_MODE_OSX` |`UC_M_OS`|`UC_OSX` |Switch to Mac OS X input. |
96|`UNICODE_MODE_LNX` |`UC_M_LN`|`UC_LNX` |Switch to Linux input. |
97|`UNICODE_MODE_WIN` |`UC_M_WI`|`UC_WIN` |Switch to Windows input. |
98|`UNICODE_MODE_BSD` |`UC_M_BS`|`UC_BSD` |Switch to BSD input (not implemented). |
99|`UNICODE_MODE_WINC` |`UC_M_WC`|`UC_WINC` |Switch to Windows input using WinCompose.|
100
101You can also switch the input mode by calling `set_unicode_input_mode(x)` in your code, where _x_ is one of the above input mode constants (e.g. `UC_LNX`). Since the function only needs to be called once, it's recommended that you do it in `eeconfig_init_user` (or a similar function). For example:
57 102
58```c 103```c
59void qk_ucis_start_user(void) { // outputs keyboard emoji 104void eeconfig_init_user(void) {
60 unicode_input_start(); 105 set_unicode_input_mode(UC_LNX);
61 register_hex(0x2328);
62 unicode_input_finish();
63} 106}
107```
64 108
65void qk_ucis_success(uint8_t symbol_index) { 109### Audio Feedback
66}
67 110
68void qk_ucis_symbol_fallback (void) { // falls back to manual unicode entry 111If you have the [Audio feature](feature_audio.md) enabled on the board, you can set melodies to be played when you press the above keys. That way you can have some audio feedback when switching input modes.
69 for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) { 112
70 uint8_t code = qk_ucis_state.codes[i]; 113For instance, you can add these definitions to your `config.h` file:
71 register_code(code); 114
72 unregister_code(code); 115```c
73 wait_ms(UNICODE_TYPE_DELAY); 116#define UNICODE_SONG_OSX COIN_SOUND
74 } 117#define UNICODE_SONG_LNX UNICODE_LINUX
75} 118#define UNICODE_SONG_BSD MARIO_GAMEOVER
119#define UNICODE_SONG_WIN UNICODE_WINDOWS
120#define UNICODE_SONG_WINC UNICODE_WINDOWS
76``` 121```
77 122
78## Unicode Input methods 123### Additional Customization
124
125Because Unicode is such a large and variable feature, there are a number of options that you can customize to work better on your system.
126
127#### Start and Finish input functions
128
129The functions for starting and finishing Unicode input on your platform can be overridden locally. Possible uses include customizing input mode behavior if you don't use the default keys, or adding extra visual/audio feedback to Unicode input.
130
131* `void unicode_input_start(void)` – This sends the initial sequence that tells your platform to enter Unicode input mode. For example, it presses Ctrl+Shift+U on Linux and holds the Option key on Mac.
132* `void unicode_input_finish(void)` – This is called to exit Unicode input mode, for example by pressing Space or releasing the Option key.
79 133
80Unicode input in QMK works by inputting a sequence of characters to the OS, 134You can find the default implementations of these functions in [`process_unicode_common.c`](https://github.com/qmk/qmk_firmware/blob/master/quantum/process_keycode/process_unicode_common.c).
81sort of like macro. Unfortunately, each OS has different ideas on how Unicode is input.
82 135
83This is the current list of Unicode input method in QMK:
84 136
85* __UC_OSX__: MacOS Unicode Hex Input support. Works only up to 0xFFFF. Disabled by default. To enable: go to System Preferences -> Keyboard -> Input Sources, and enable Unicode Hex. 137#### Input Key Configuration
86* __UC_OSX_RALT__: Same as UC_OSX, but sends the Right Alt key for unicode input
87* __UC_LNX__: Unicode input method under Linux. Works up to 0xFFFFF. Should work almost anywhere on ibus enabled distros. Without ibus, this works under GTK apps, but rarely anywhere else.
88* __UC_WIN__: (not recommended) Windows built-in Unicode input. To enable: create registry key under `HKEY_CURRENT_USER\Control Panel\Input Method\EnableHexNumpad` of type `REG_SZ` called `EnableHexNumpad`, set its value to 1, and reboot. This method is not recommended because of reliability and compatibility issue, use WinCompose method below instead.
89* __UC_WINC__: Windows Unicode input using WinCompose. Requires [WinCompose](https://github.com/samhocevar/wincompose). Works reliably under many (all?) variations of Windows.
90 138
91At some point, you need to call `set_unicode_input_mode(x)` to set the correct unicode method. This sets the method that is used to send the unicode, and stores it in EEPROM, so you only need to call this once. 139Additionally, you can customize the keys used to trigger the unicode input for macOS and WinCompose by adding defines to your `config.h`
140
141```c
142#define UNICODE_OSX_KEY KC_LALT
143#define UNICODE_WINC_KEY KC_RALT
144```
145
146#### Input Method Cycling
147
148Also, you can choose which input methods are availble for cycling through. By default, this is disabled. But if you want to enabled it, then limiting it to just those modes makes sense. Note that `UNICODE_SELECTED_MODES` define is comma delimited.
149
150```c
151#define UNICODE_SELECTED_MODES UC_OSX, UC_LNX, UC_WIN, UC_BSD, UC_WINC
152```
92 153
93## `send_unicode_hex_string` 154## `send_unicode_hex_string`
94 155
diff --git a/keyboards/whitefox/keymaps/konstantin/config.h b/keyboards/whitefox/keymaps/konstantin/config.h
index ee30dbece..ab920a50b 100644
--- a/keyboards/whitefox/keymaps/konstantin/config.h
+++ b/keyboards/whitefox/keymaps/konstantin/config.h
@@ -21,3 +21,7 @@
21#define PERMISSIVE_HOLD 21#define PERMISSIVE_HOLD
22#define TAPPING_TERM 200 22#define TAPPING_TERM 200
23#define TAPPING_TOGGLE 2 23#define TAPPING_TOGGLE 2
24
25#define UNICODE_CYCLE_PERSIST false
26#define UNICODE_SELECTED_MODES UC_WINC, UC_LNX
27#define UNICODE_WINC_KEY KC_RGUI
diff --git a/keyboards/whitefox/keymaps/konstantin/keymap.c b/keyboards/whitefox/keymaps/konstantin/keymap.c
index 55db5ca6b..54777cfe0 100644
--- a/keyboards/whitefox/keymaps/konstantin/keymap.c
+++ b/keyboards/whitefox/keymaps/konstantin/keymap.c
@@ -23,10 +23,6 @@
23#define DIVIDE UC(0x00F7) 23#define DIVIDE UC(0x00F7)
24#define MINUS UC(0x2212) 24#define MINUS UC(0x2212)
25 25
26void eeconfig_init_user(void) {
27 set_unicode_input_mode(UC_WINC);
28}
29
30enum layers { 26enum layers {
31 L_BASE, 27 L_BASE,
32 L_FN, 28 L_FN,
@@ -162,7 +158,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
162 * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ 158 * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
163 * │ │F1 │F2 │F3 │F4 │F5 │F6 │F7 │F8 │F9 │F10│F11│F12│Num│Scr│Pau│ 159 * │ │F1 │F2 │F3 │F4 │F5 │F6 │F7 │F8 │F9 │F10│F11│F12│Num│Scr│Pau│
164 * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┼───┤ 160 * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┼───┤
165 * │ M4 │M2 │M↑ │M1 │M3 │M5 │ │ │ │Stp│Ply│Prv│Nxt│Clear│Ins│ 161 * │ M4 │M2 │M↑ │M1 │M3 │M5 │ │UCM│ │Stp│Ply│Prv│Nxt│Clear│Ins│
166 * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤ 162 * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
167 * │ │M← │M↓ │M→ │MW↑│ │ │ │ │ │ │ │ │Top│ 163 * │ │M← │M↓ │M→ │MW↑│ │ │ │ │ │ │ │ │Top│
168 * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤ 164 * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
@@ -173,7 +169,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
173 */ 169 */
174 [L_FN] = LAYOUT_truefox( \ 170 [L_FN] = LAYOUT_truefox( \
175 _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, NUMPAD, KC_SLCK, KC_PAUS, \ 171 _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, NUMPAD, KC_SLCK, KC_PAUS, \
176 KC_BTN4, KC_BTN2, KC_MS_U, KC_BTN1, KC_BTN3, KC_BTN5, _______, _______, _______, KC_MSTP, KC_MPLY, KC_MPRV, KC_MNXT, CLEAR, KC_INS, \ 172 KC_BTN4, KC_BTN2, KC_MS_U, KC_BTN1, KC_BTN3, KC_BTN5, _______, UC_MOD, _______, KC_MSTP, KC_MPLY, KC_MPRV, KC_MNXT, CLEAR, KC_INS, \
177 _______, KC_MS_L, KC_MS_D, KC_MS_R, KC_WH_U, _______, _______, _______, _______, _______, _______, _______, _______, TOP, \ 173 _______, KC_MS_L, KC_MS_D, KC_MS_R, KC_WH_U, _______, _______, _______, _______, _______, _______, _______, _______, TOP, \
178 _______, KC_ACL0, KC_ACL2, KC_WH_L, KC_WH_R, _______, _______, _______, KC_VOLD, KC_VOLU, KC_MUTE, KC_APP, KC_PGUP, BOTTOM, \ 174 _______, KC_ACL0, KC_ACL2, KC_WH_L, KC_WH_R, _______, _______, _______, KC_VOLD, KC_VOLU, KC_MUTE, KC_APP, KC_PGUP, BOTTOM, \
179 _______, DESKTOP, DSKTP_L, KC_WH_D, DSKTP_R, _______, KC_HOME, KC_PGDN, KC_END \ 175 _______, DESKTOP, DSKTP_L, KC_WH_D, DSKTP_R, _______, KC_HOME, KC_PGDN, KC_END \
diff --git a/quantum/process_keycode/process_ucis.c b/quantum/process_keycode/process_ucis.c
index 8deb24a86..5de2e41fc 100644
--- a/quantum/process_keycode/process_ucis.c
+++ b/quantum/process_keycode/process_ucis.c
@@ -95,8 +95,6 @@ void register_ucis(const char *hex) {
95bool process_ucis (uint16_t keycode, keyrecord_t *record) { 95bool process_ucis (uint16_t keycode, keyrecord_t *record) {
96 uint8_t i; 96 uint8_t i;
97 97
98 unicode_input_mode_init();
99
100 if (!qk_ucis_state.in_progress) 98 if (!qk_ucis_state.in_progress)
101 return true; 99 return true;
102 100
diff --git a/quantum/process_keycode/process_ucis.h b/quantum/process_keycode/process_ucis.h
index d4aa34cde..b114d839a 100644
--- a/quantum/process_keycode/process_ucis.h
+++ b/quantum/process_keycode/process_ucis.h
@@ -14,8 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#ifndef PROCESS_UCIS_H 17#pragma once
18#define PROCESS_UCIS_H
19 18
20#include "quantum.h" 19#include "quantum.h"
21#include "process_unicode_common.h" 20#include "process_unicode_common.h"
@@ -48,5 +47,3 @@ void qk_ucis_symbol_fallback (void);
48void qk_ucis_success(uint8_t symbol_index); 47void qk_ucis_success(uint8_t symbol_index);
49void register_ucis(const char *hex); 48void register_ucis(const char *hex);
50bool process_ucis (uint16_t keycode, keyrecord_t *record); 49bool process_ucis (uint16_t keycode, keyrecord_t *record);
51
52#endif
diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c
index f39c4a36e..19beb8452 100644
--- a/quantum/process_keycode/process_unicode.c
+++ b/quantum/process_keycode/process_unicode.c
@@ -20,11 +20,9 @@
20bool process_unicode(uint16_t keycode, keyrecord_t *record) { 20bool process_unicode(uint16_t keycode, keyrecord_t *record) {
21 if (keycode > QK_UNICODE && record->event.pressed) { 21 if (keycode > QK_UNICODE && record->event.pressed) {
22 uint16_t unicode = keycode & 0x7FFF; 22 uint16_t unicode = keycode & 0x7FFF;
23 unicode_input_mode_init();
24 unicode_input_start(); 23 unicode_input_start();
25 register_hex(unicode); 24 register_hex(unicode);
26 unicode_input_finish(); 25 unicode_input_finish();
27 } 26 }
28 return true; 27 return true;
29} 28}
30
diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h
index c525b74f0..0913e9910 100644
--- a/quantum/process_keycode/process_unicode.h
+++ b/quantum/process_keycode/process_unicode.h
@@ -13,12 +13,9 @@
13 * You should have received a copy of the GNU General Public License 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/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16#ifndef PROCESS_UNICODE_H 16#pragma once
17#define PROCESS_UNICODE_H
18 17
19#include "quantum.h" 18#include "quantum.h"
20#include "process_unicode_common.h" 19#include "process_unicode_common.h"
21 20
22bool process_unicode(uint16_t keycode, keyrecord_t *record); 21bool process_unicode(uint16_t keycode, keyrecord_t *record);
23
24#endif
diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c
index 4285d20a1..3286f45b5 100644
--- a/quantum/process_keycode/process_unicode_common.c
+++ b/quantum/process_keycode/process_unicode_common.c
@@ -16,98 +16,111 @@
16 16
17#include "process_unicode_common.h" 17#include "process_unicode_common.h"
18#include "eeprom.h" 18#include "eeprom.h"
19#include <string.h>
20#include <ctype.h> 19#include <ctype.h>
20#include <string.h>
21 21
22static uint8_t input_mode; 22unicode_config_t unicode_config;
23uint8_t mods; 23#if UNICODE_SELECTED_MODES != -1
24static uint8_t selected[] = { UNICODE_SELECTED_MODES };
25static uint8_t selected_count = sizeof selected / sizeof *selected;
26static uint8_t selected_index;
27#endif
24 28
25void set_unicode_input_mode(uint8_t os_target) { 29void unicode_input_mode_init(void) {
26 input_mode = os_target; 30 unicode_config.raw = eeprom_read_byte(EECONFIG_UNICODEMODE);
27 eeprom_update_byte(EECONFIG_UNICODEMODE, os_target); 31#if UNICODE_SELECTED_MODES != -1
32 #if UNICODE_CYCLE_PERSIST
33 // Find input_mode in selected modes
34 uint8_t i;
35 for (i = 0; i < selected_count; i++) {
36 if (selected[i] == unicode_config.input_mode) {
37 selected_index = i;
38 break;
39 }
40 }
41 if (i == selected_count) {
42 // Not found: input_mode isn't selected, change to one that is
43 unicode_config.input_mode = selected[selected_index = 0];
44 }
45 #else
46 // Always change to the first selected input mode
47 unicode_config.input_mode = selected[selected_index = 0];
48 #endif
49#endif
50 dprintf("Unicode input mode init to: %u\n", unicode_config.input_mode);
28} 51}
29 52
30uint8_t get_unicode_input_mode(void) { 53uint8_t get_unicode_input_mode(void) {
31 return input_mode; 54 return unicode_config.input_mode;
32} 55}
33 56
34void unicode_input_mode_init(void) { 57void set_unicode_input_mode(uint8_t mode) {
35 static bool first_flag = false; 58 unicode_config.input_mode = mode;
36 if (!first_flag) { 59 persist_unicode_input_mode();
37 input_mode = eeprom_read_byte(EECONFIG_UNICODEMODE); 60 dprintf("Unicode input mode set to: %u\n", unicode_config.input_mode);
38 first_flag = true; 61}
39 } 62
63void cycle_unicode_input_mode(uint8_t offset) {
64#if UNICODE_SELECTED_MODES != -1
65 selected_index = (selected_index + offset) % selected_count;
66 unicode_config.input_mode = selected[selected_index];
67 #if UNICODE_CYCLE_PERSIST
68 persist_unicode_input_mode();
69 #endif
70 dprintf("Unicode input mode cycle to: %u\n", unicode_config.input_mode);
71#endif
72}
73
74void persist_unicode_input_mode(void) {
75 eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config.input_mode);
40} 76}
41 77
78static uint8_t saved_mods;
79
42__attribute__((weak)) 80__attribute__((weak))
43void unicode_input_start (void) { 81void unicode_input_start(void) {
44 // save current mods 82 saved_mods = get_mods(); // Save current mods
45 mods = keyboard_report->mods; 83 clear_mods(); // Unregister mods to start from a clean state
46 84
47 // unregister all mods to start from clean state 85 switch (unicode_config.input_mode) {
48 if (mods & MOD_BIT(KC_LSFT)) unregister_code(KC_LSFT);
49 if (mods & MOD_BIT(KC_RSFT)) unregister_code(KC_RSFT);
50 if (mods & MOD_BIT(KC_LCTL)) unregister_code(KC_LCTL);
51 if (mods & MOD_BIT(KC_RCTL)) unregister_code(KC_RCTL);
52 if (mods & MOD_BIT(KC_LALT)) unregister_code(KC_LALT);
53 if (mods & MOD_BIT(KC_RALT)) unregister_code(KC_RALT);
54 if (mods & MOD_BIT(KC_LGUI)) unregister_code(KC_LGUI);
55 if (mods & MOD_BIT(KC_RGUI)) unregister_code(KC_RGUI);
56
57 switch(input_mode) {
58 case UC_OSX: 86 case UC_OSX:
59 register_code(KC_LALT); 87 register_code(UNICODE_OSX_KEY);
60 break;
61 case UC_OSX_RALT:
62 register_code(KC_RALT);
63 break; 88 break;
64 case UC_LNX: 89 case UC_LNX:
65 register_code(KC_LCTL); 90 register_code(KC_LCTL);
66 register_code(KC_LSFT); 91 register_code(KC_LSFT);
67 register_code(KC_U); 92 tap_code(KC_U); // TODO: Replace with tap_code16(LCTL(LSFT(KC_U))); and test
68 unregister_code(KC_U);
69 unregister_code(KC_LSFT); 93 unregister_code(KC_LSFT);
70 unregister_code(KC_LCTL); 94 unregister_code(KC_LCTL);
71 break; 95 break;
72 case UC_WIN: 96 case UC_WIN:
73 register_code(KC_LALT); 97 register_code(KC_LALT);
74 register_code(KC_PPLS); 98 tap_code(KC_PPLS);
75 unregister_code(KC_PPLS);
76 break; 99 break;
77 case UC_WINC: 100 case UC_WINC:
78 register_code(KC_RALT); 101 tap_code(UNICODE_WINC_KEY);
79 unregister_code(KC_RALT); 102 tap_code(KC_U);
80 register_code(KC_U); 103 break;
81 unregister_code(KC_U);
82 } 104 }
105
83 wait_ms(UNICODE_TYPE_DELAY); 106 wait_ms(UNICODE_TYPE_DELAY);
84} 107}
85 108
86__attribute__((weak)) 109__attribute__((weak))
87void unicode_input_finish (void) { 110void unicode_input_finish(void) {
88 switch(input_mode) { 111 switch (unicode_config.input_mode) {
89 case UC_OSX: 112 case UC_OSX:
90 case UC_WIN: 113 unregister_code(UNICODE_OSX_KEY);
91 unregister_code(KC_LALT); 114 break;
92 break; 115 case UC_LNX:
93 case UC_OSX_RALT: 116 tap_code(KC_SPC);
94 unregister_code(KC_RALT); 117 break;
95 break; 118 case UC_WIN:
96 case UC_LNX: 119 unregister_code(KC_LALT);
97 register_code(KC_SPC); 120 break;
98 unregister_code(KC_SPC);
99 break;
100 } 121 }
101 122
102 // reregister previously set mods 123 set_mods(saved_mods); // Reregister previously set mods
103 if (mods & MOD_BIT(KC_LSFT)) register_code(KC_LSFT);
104 if (mods & MOD_BIT(KC_RSFT)) register_code(KC_RSFT);
105 if (mods & MOD_BIT(KC_LCTL)) register_code(KC_LCTL);
106 if (mods & MOD_BIT(KC_RCTL)) register_code(KC_RCTL);
107 if (mods & MOD_BIT(KC_LALT)) register_code(KC_LALT);
108 if (mods & MOD_BIT(KC_RALT)) register_code(KC_RALT);
109 if (mods & MOD_BIT(KC_LGUI)) register_code(KC_LGUI);
110 if (mods & MOD_BIT(KC_RGUI)) register_code(KC_RGUI);
111} 124}
112 125
113__attribute__((weak)) 126__attribute__((weak))
@@ -124,13 +137,12 @@ uint16_t hex_to_keycode(uint8_t hex) {
124void register_hex(uint16_t hex) { 137void register_hex(uint16_t hex) {
125 for(int i = 3; i >= 0; i--) { 138 for(int i = 3; i >= 0; i--) {
126 uint8_t digit = ((hex >> (i*4)) & 0xF); 139 uint8_t digit = ((hex >> (i*4)) & 0xF);
127 register_code(hex_to_keycode(digit)); 140 tap_code(hex_to_keycode(digit));
128 unregister_code(hex_to_keycode(digit));
129 } 141 }
130} 142}
131 143
132void send_unicode_hex_string(const char *str) { 144void send_unicode_hex_string(const char *str) {
133 if (!str) { return; } // Safety net 145 if (!str) { return; }
134 146
135 while (*str) { 147 while (*str) {
136 // Find the next code point (token) in the string 148 // Find the next code point (token) in the string
@@ -153,3 +165,61 @@ void send_unicode_hex_string(const char *str) {
153 str += n; // Move to the first ' ' (or '\0') after the current token 165 str += n; // Move to the first ' ' (or '\0') after the current token
154 } 166 }
155} 167}
168
169bool process_unicode_common(uint16_t keycode, keyrecord_t *record) {
170 if (record->event.pressed) {
171 switch (keycode) {
172 case UNICODE_MODE_FORWARD:
173 cycle_unicode_input_mode(+1);
174 break;
175 case UNICODE_MODE_REVERSE:
176 cycle_unicode_input_mode(-1);
177 break;
178
179 case UNICODE_MODE_OSX:
180 set_unicode_input_mode(UC_OSX);
181#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_OSX)
182 static float song_osx[][2] = UNICODE_SONG_OSX;
183 PLAY_SONG(song_osx);
184#endif
185 break;
186 case UNICODE_MODE_LNX:
187 set_unicode_input_mode(UC_LNX);
188#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_LNX)
189 static float song_lnx[][2] = UNICODE_SONG_LNX;
190 PLAY_SONG(song_lnx);
191#endif
192 break;
193 case UNICODE_MODE_WIN:
194 set_unicode_input_mode(UC_WIN);
195#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WIN)
196 static float song_win[][2] = UNICODE_SONG_WIN;
197 PLAY_SONG(song_win);
198#endif
199 break;
200 case UNICODE_MODE_BSD:
201 set_unicode_input_mode(UC_BSD);
202#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_BSD)
203 static float song_bsd[][2] = UNICODE_SONG_BSD;
204 PLAY_SONG(song_bsd);
205#endif
206 break;
207 case UNICODE_MODE_WINC:
208 set_unicode_input_mode(UC_WINC);
209#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WINC)
210 static float song_winc[][2] = UNICODE_SONG_WINC;
211 PLAY_SONG(song_winc);
212#endif
213 break;
214 }
215 }
216#if defined(UNICODE_ENABLE)
217 return process_unicode(keycode, record);
218#elif defined(UNICODEMAP_ENABLE)
219 return process_unicode_map(keycode, record);
220#elif defined(UCIS_ENABLE)
221 return process_ucis(keycode, record);
222#else
223 return true;
224#endif
225}
diff --git a/quantum/process_keycode/process_unicode_common.h b/quantum/process_keycode/process_unicode_common.h
index e78e1cec6..e608ab76b 100644
--- a/quantum/process_keycode/process_unicode_common.h
+++ b/quantum/process_keycode/process_unicode_common.h
@@ -14,35 +14,71 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#ifndef PROCESS_UNICODE_COMMON_H 17#pragma once
18#define PROCESS_UNICODE_COMMON_H
19 18
20#include "quantum.h" 19#include "quantum.h"
21 20
21#if defined(UNICODE_ENABLE) + defined(UNICODEMAP_ENABLE) + defined(UCIS_ENABLE) > 1
22 #error "Cannot enable more than one Unicode method (UNICODE, UNICODEMAP, UCIS) at the same time"
23#endif
24
25// Keycodes used for starting Unicode input on different platforms
26#ifndef UNICODE_OSX_KEY
27 #define UNICODE_OSX_KEY KC_LALT
28#endif
29#ifndef UNICODE_WINC_KEY
30 #define UNICODE_WINC_KEY KC_RALT
31#endif
32
33// Comma-delimited, ordered list of input modes selected for use (e.g. in cycle)
34// Example: #define UNICODE_SELECTED_MODES UC_WINC, UC_LNX
35#ifndef UNICODE_SELECTED_MODES
36 #define UNICODE_SELECTED_MODES -1
37#endif
38
39// Whether input mode changes in cycle should be written to EEPROM
40#ifndef UNICODE_CYCLE_PERSIST
41 #define UNICODE_CYCLE_PERSIST true
42#endif
43
44// Delay between starting Unicode input and sending a sequence, in ms
22#ifndef UNICODE_TYPE_DELAY 45#ifndef UNICODE_TYPE_DELAY
23#define UNICODE_TYPE_DELAY 10 46 #define UNICODE_TYPE_DELAY 10
24#endif 47#endif
25 48
26__attribute__ ((unused)) 49enum unicode_input_modes {
27static uint8_t input_mode; 50 UC_OSX, // Mac OS X using Unicode Hex Input
51 UC_LNX, // Linux using IBus
52 UC_WIN, // Windows using EnableHexNumpad
53 UC_BSD, // BSD (not implemented)
54 UC_WINC, // Windows using WinCompose (https://github.com/samhocevar/wincompose)
55 UC__COUNT // Number of available input modes (always leave at the end)
56};
57
58typedef union {
59 uint32_t raw;
60 struct {
61 uint8_t input_mode : 8;
62 };
63} unicode_config_t;
64
65extern unicode_config_t unicode_config;
28 66
29void set_unicode_input_mode(uint8_t os_target);
30uint8_t get_unicode_input_mode(void);
31void unicode_input_mode_init(void); 67void unicode_input_mode_init(void);
68uint8_t get_unicode_input_mode(void);
69void set_unicode_input_mode(uint8_t mode);
70void cycle_unicode_input_mode(uint8_t offset);
71void persist_unicode_input_mode(void);
72
32void unicode_input_start(void); 73void unicode_input_start(void);
33void unicode_input_finish(void); 74void unicode_input_finish(void);
75
34void register_hex(uint16_t hex); 76void register_hex(uint16_t hex);
35void send_unicode_hex_string(const char *str); 77void send_unicode_hex_string(const char *str);
36 78
37#define UC_OSX 0 // Mac OS X 79bool process_unicode_common(uint16_t keycode, keyrecord_t *record);
38#define UC_LNX 1 // Linux
39#define UC_WIN 2 // Windows 'HexNumpad'
40#define UC_BSD 3 // BSD (not implemented)
41#define UC_WINC 4 // WinCompose https://github.com/samhocevar/wincompose
42#define UC_OSX_RALT 5 // Mac OS X using Right Alt key for Unicode Compose
43 80
44#define UC_BSPC UC(0x0008) 81#define UC_BSPC UC(0x0008)
45
46#define UC_SPC UC(0x0020) 82#define UC_SPC UC(0x0020)
47 83
48#define UC_EXLM UC(0x0021) 84#define UC_EXLM UC(0x0021)
@@ -147,5 +183,3 @@ void send_unicode_hex_string(const char *str);
147#define UC_RCBR UC(0x007D) 183#define UC_RCBR UC(0x007D)
148#define UC_TILD UC(0x007E) 184#define UC_TILD UC(0x007E)
149#define UC_DEL UC(0x007F) 185#define UC_DEL UC(0x007F)
150
151#endif
diff --git a/quantum/process_keycode/process_unicodemap.c b/quantum/process_keycode/process_unicodemap.c
index ab5717ba3..75f35112b 100644
--- a/quantum/process_keycode/process_unicodemap.c
+++ b/quantum/process_keycode/process_unicodemap.c
@@ -45,13 +45,12 @@ __attribute__((weak))
45void unicode_map_input_error() {} 45void unicode_map_input_error() {}
46 46
47bool process_unicode_map(uint16_t keycode, keyrecord_t *record) { 47bool process_unicode_map(uint16_t keycode, keyrecord_t *record) {
48 unicode_input_mode_init();
49 uint8_t input_mode = get_unicode_input_mode(); 48 uint8_t input_mode = get_unicode_input_mode();
50 if ((keycode & QK_UNICODE_MAP) == QK_UNICODE_MAP && record->event.pressed) { 49 if ((keycode & QK_UNICODE_MAP) == QK_UNICODE_MAP && record->event.pressed) {
51 const uint32_t* map = unicode_map; 50 const uint32_t* map = unicode_map;
52 uint16_t index = keycode - QK_UNICODE_MAP; 51 uint16_t index = keycode - QK_UNICODE_MAP;
53 uint32_t code = pgm_read_dword(&map[index]); 52 uint32_t code = pgm_read_dword(&map[index]);
54 if (code > 0xFFFF && code <= 0x10ffff && (input_mode == UC_OSX || input_mode == UC_OSX_RALT)) { 53 if (code > 0xFFFF && code <= 0x10ffff && input_mode == UC_OSX) {
55 // Convert to UTF-16 surrogate pair 54 // Convert to UTF-16 surrogate pair
56 code -= 0x10000; 55 code -= 0x10000;
57 uint32_t lo = code & 0x3ff; 56 uint32_t lo = code & 0x3ff;
@@ -60,7 +59,7 @@ bool process_unicode_map(uint16_t keycode, keyrecord_t *record) {
60 register_hex32(hi + 0xd800); 59 register_hex32(hi + 0xd800);
61 register_hex32(lo + 0xdc00); 60 register_hex32(lo + 0xdc00);
62 unicode_input_finish(); 61 unicode_input_finish();
63 } else if ((code > 0x10ffff && (input_mode == UC_OSX || input_mode == UC_OSX_RALT)) || (code > 0xFFFFF && input_mode == UC_LNX)) { 62 } else if ((code > 0x10ffff && input_mode == UC_OSX) || (code > 0xFFFFF && input_mode == UC_LNX)) {
64 // when character is out of range supported by the OS 63 // when character is out of range supported by the OS
65 unicode_map_input_error(); 64 unicode_map_input_error();
66 } else { 65 } else {
diff --git a/quantum/process_keycode/process_unicodemap.h b/quantum/process_keycode/process_unicodemap.h
index 929c88c0b..f6d64bb86 100644
--- a/quantum/process_keycode/process_unicodemap.h
+++ b/quantum/process_keycode/process_unicodemap.h
@@ -14,12 +14,10 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#ifndef PROCESS_UNICODEMAP_H 17#pragma once
18#define PROCESS_UNICODEMAP_H
19 18
20#include "quantum.h" 19#include "quantum.h"
21#include "process_unicode_common.h" 20#include "process_unicode_common.h"
22 21
23void unicode_map_input_error(void); 22void unicode_map_input_error(void);
24bool process_unicode_map(uint16_t keycode, keyrecord_t *record); 23bool process_unicode_map(uint16_t keycode, keyrecord_t *record);
25#endif
diff --git a/quantum/quantum.c b/quantum/quantum.c
index a57d4f89f..85db100ab 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -243,7 +243,7 @@ bool process_record_quantum(keyrecord_t *record) {
243 process_key_lock(&keycode, record) && 243 process_key_lock(&keycode, record) &&
244 #endif 244 #endif
245 #if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY) 245 #if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY)
246 process_clicky(keycode, record) && 246 process_clicky(keycode, record) &&
247 #endif //AUDIO_CLICKY 247 #endif //AUDIO_CLICKY
248 process_record_kb(keycode, record) && 248 process_record_kb(keycode, record) &&
249 #if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_KEYPRESSES) 249 #if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_KEYPRESSES)
@@ -258,33 +258,27 @@ bool process_record_quantum(keyrecord_t *record) {
258 #ifdef STENO_ENABLE 258 #ifdef STENO_ENABLE
259 process_steno(keycode, record) && 259 process_steno(keycode, record) &&
260 #endif 260 #endif
261 #if ( defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE) 261 #if (defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE)
262 process_music(keycode, record) && 262 process_music(keycode, record) &&
263 #endif 263 #endif
264 #ifdef TAP_DANCE_ENABLE 264 #ifdef TAP_DANCE_ENABLE
265 process_tap_dance(keycode, record) && 265 process_tap_dance(keycode, record) &&
266 #endif 266 #endif
267 #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
268 process_unicode_common(keycode, record) &&
269 #endif
267 #ifdef LEADER_ENABLE 270 #ifdef LEADER_ENABLE
268 process_leader(keycode, record) && 271 process_leader(keycode, record) &&
269 #endif 272 #endif
270 #ifdef COMBO_ENABLE 273 #ifdef COMBO_ENABLE
271 process_combo(keycode, record) && 274 process_combo(keycode, record) &&
272 #endif 275 #endif
273 #ifdef UNICODE_ENABLE
274 process_unicode(keycode, record) &&
275 #endif
276 #ifdef UCIS_ENABLE
277 process_ucis(keycode, record) &&
278 #endif
279 #ifdef PRINTING_ENABLE 276 #ifdef PRINTING_ENABLE
280 process_printer(keycode, record) && 277 process_printer(keycode, record) &&
281 #endif 278 #endif
282 #ifdef AUTO_SHIFT_ENABLE 279 #ifdef AUTO_SHIFT_ENABLE
283 process_auto_shift(keycode, record) && 280 process_auto_shift(keycode, record) &&
284 #endif 281 #endif
285 #ifdef UNICODEMAP_ENABLE
286 process_unicode_map(keycode, record) &&
287 #endif
288 #ifdef TERMINAL_ENABLE 282 #ifdef TERMINAL_ENABLE
289 process_terminal(keycode, record) && 283 process_terminal(keycode, record) &&
290 #endif 284 #endif
@@ -1010,6 +1004,9 @@ void matrix_init_quantum() {
1010 #ifdef ENCODER_ENABLE 1004 #ifdef ENCODER_ENABLE
1011 encoder_init(); 1005 encoder_init();
1012 #endif 1006 #endif
1007 #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
1008 unicode_input_mode_init();
1009 #endif
1013 matrix_init_kb(); 1010 matrix_init_kb();
1014} 1011}
1015 1012
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index 283b4a65c..2b309f4d5 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -81,9 +81,6 @@ enum quantum_keycodes {
81#endif 81#endif
82 QK_MOD_TAP = 0x6000, 82 QK_MOD_TAP = 0x6000,
83 QK_MOD_TAP_MAX = 0x7FFF, 83 QK_MOD_TAP_MAX = 0x7FFF,
84#if defined(UNICODEMAP_ENABLE) && defined(UNICODE_ENABLE)
85 #error "Cannot enable both UNICODEMAP && UNICODE"
86#endif
87#ifdef UNICODE_ENABLE 84#ifdef UNICODE_ENABLE
88 QK_UNICODE = 0x8000, 85 QK_UNICODE = 0x8000,
89 QK_UNICODE_MAX = 0xFFFF, 86 QK_UNICODE_MAX = 0xFFFF,
@@ -456,6 +453,15 @@ enum quantum_keycodes {
456 453
457 EEPROM_RESET, 454 EEPROM_RESET,
458 455
456 UNICODE_MODE_FORWARD,
457 UNICODE_MODE_REVERSE,
458
459 UNICODE_MODE_OSX,
460 UNICODE_MODE_LNX,
461 UNICODE_MODE_WIN,
462 UNICODE_MODE_BSD,
463 UNICODE_MODE_WINC,
464
459 // always leave at the end 465 // always leave at the end
460 SAFE_RANGE 466 SAFE_RANGE
461}; 467};
@@ -684,6 +690,15 @@ enum quantum_keycodes {
684 #define X(n) (QK_UNICODE_MAP | (n)) 690 #define X(n) (QK_UNICODE_MAP | (n))
685#endif 691#endif
686 692
693#define UC_MOD UNICODE_MODE_FORWARD
694#define UC_RMOD UNICODE_MODE_REVERSE
695
696#define UC_M_OS UNICODE_MODE_OSX
697#define UC_M_LN UNICODE_MODE_LNX
698#define UC_M_WI UNICODE_MODE_WIN
699#define UC_M_BS UNICODE_MODE_BSD
700#define UC_M_WC UNICODE_MODE_WINC
701
687#ifdef SWAP_HANDS_ENABLE 702#ifdef SWAP_HANDS_ENABLE
688 #define SH_T(kc) (QK_SWAP_HANDS | (kc)) 703 #define SH_T(kc) (QK_SWAP_HANDS | (kc))
689 #define SH_TG (QK_SWAP_HANDS | OP_SH_TOGGLE) 704 #define SH_TG (QK_SWAP_HANDS | OP_SH_TOGGLE)