aboutsummaryrefslogtreecommitdiff
path: root/quantum/process_keycode
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/process_keycode')
-rw-r--r--quantum/process_keycode/process_unicode.c6
-rw-r--r--quantum/process_keycode/process_unicode.h2
-rw-r--r--quantum/process_keycode/process_unicode_common.c38
-rw-r--r--quantum/process_keycode/process_unicode_common.h13
-rw-r--r--quantum/process_keycode/process_unicodemap.c36
-rw-r--r--quantum/process_keycode/process_unicodemap.h4
6 files changed, 64 insertions, 35 deletions
diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c
index 19beb8452..2c914013a 100644
--- a/quantum/process_keycode/process_unicode.c
+++ b/quantum/process_keycode/process_unicode.c
@@ -13,15 +13,15 @@
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
16#include "process_unicode.h" 17#include "process_unicode.h"
17#include "action_util.h" 18#include "action_util.h"
18#include "eeprom.h" 19#include "eeprom.h"
19 20
20bool process_unicode(uint16_t keycode, keyrecord_t *record) { 21bool process_unicode(uint16_t keycode, keyrecord_t *record) {
21 if (keycode > QK_UNICODE && record->event.pressed) { 22 if (keycode >= QK_UNICODE && keycode <= QK_UNICODE_MAX && record->event.pressed) {
22 uint16_t unicode = keycode & 0x7FFF;
23 unicode_input_start(); 23 unicode_input_start();
24 register_hex(unicode); 24 register_hex(keycode & 0x7FFF);
25 unicode_input_finish(); 25 unicode_input_finish();
26 } 26 }
27 return true; 27 return true;
diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h
index 0913e9910..22765ad56 100644
--- a/quantum/process_keycode/process_unicode.h
+++ b/quantum/process_keycode/process_unicode.h
@@ -13,9 +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
16#pragma once 17#pragma once
17 18
18#include "quantum.h"
19#include "process_unicode_common.h" 19#include "process_unicode_common.h"
20 20
21bool process_unicode(uint16_t keycode, keyrecord_t *record); 21bool process_unicode(uint16_t keycode, keyrecord_t *record);
diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c
index d0a9cf232..21ac2291d 100644
--- a/quantum/process_keycode/process_unicode_common.c
+++ b/quantum/process_keycode/process_unicode_common.c
@@ -20,6 +20,8 @@
20#include <string.h> 20#include <string.h>
21 21
22unicode_config_t unicode_config; 22unicode_config_t unicode_config;
23uint8_t unicode_saved_mods;
24
23#if UNICODE_SELECTED_MODES != -1 25#if UNICODE_SELECTED_MODES != -1
24static uint8_t selected[] = { UNICODE_SELECTED_MODES }; 26static uint8_t selected[] = { UNICODE_SELECTED_MODES };
25static uint8_t selected_count = sizeof selected / sizeof *selected; 27static uint8_t selected_count = sizeof selected / sizeof *selected;
@@ -75,30 +77,24 @@ void persist_unicode_input_mode(void) {
75 eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config.input_mode); 77 eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config.input_mode);
76} 78}
77 79
78static uint8_t saved_mods;
79
80__attribute__((weak)) 80__attribute__((weak))
81void unicode_input_start(void) { 81void unicode_input_start(void) {
82 saved_mods = get_mods(); // Save current mods 82 unicode_saved_mods = get_mods(); // Save current mods
83 clear_mods(); // Unregister mods to start from a clean state 83 clear_mods(); // Unregister mods to start from a clean state
84 84
85 switch (unicode_config.input_mode) { 85 switch (unicode_config.input_mode) {
86 case UC_OSX: 86 case UC_OSX:
87 register_code(UNICODE_OSX_KEY); 87 register_code(UNICODE_KEY_OSX);
88 break; 88 break;
89 case UC_LNX: 89 case UC_LNX:
90 register_code(KC_LCTL); 90 tap_code16(UNICODE_KEY_LNX);
91 register_code(KC_LSFT);
92 tap_code(KC_U); // TODO: Replace with tap_code16(LCTL(LSFT(KC_U))); and test
93 unregister_code(KC_LSFT);
94 unregister_code(KC_LCTL);
95 break; 91 break;
96 case UC_WIN: 92 case UC_WIN:
97 register_code(KC_LALT); 93 register_code(KC_LALT);
98 tap_code(KC_PPLS); 94 tap_code(KC_PPLS);
99 break; 95 break;
100 case UC_WINC: 96 case UC_WINC:
101 tap_code(UNICODE_WINC_KEY); 97 tap_code(UNICODE_KEY_WINC);
102 tap_code(KC_U); 98 tap_code(KC_U);
103 break; 99 break;
104 } 100 }
@@ -110,7 +106,7 @@ __attribute__((weak))
110void unicode_input_finish(void) { 106void unicode_input_finish(void) {
111 switch (unicode_config.input_mode) { 107 switch (unicode_config.input_mode) {
112 case UC_OSX: 108 case UC_OSX:
113 unregister_code(UNICODE_OSX_KEY); 109 unregister_code(UNICODE_KEY_OSX);
114 break; 110 break;
115 case UC_LNX: 111 case UC_LNX:
116 tap_code(KC_SPC); 112 tap_code(KC_SPC);
@@ -123,7 +119,25 @@ void unicode_input_finish(void) {
123 break; 119 break;
124 } 120 }
125 121
126 set_mods(saved_mods); // Reregister previously set mods 122 set_mods(unicode_saved_mods); // Reregister previously set mods
123}
124
125__attribute__((weak))
126void unicode_input_cancel(void) {
127 switch (unicode_config.input_mode) {
128 case UC_OSX:
129 unregister_code(UNICODE_KEY_OSX);
130 break;
131 case UC_LNX:
132 case UC_WINC:
133 tap_code(KC_ESC);
134 break;
135 case UC_WIN:
136 unregister_code(KC_LALT);
137 break;
138 }
139
140 set_mods(unicode_saved_mods); // Reregister previously set mods
127} 141}
128 142
129__attribute__((weak)) 143__attribute__((weak))
diff --git a/quantum/process_keycode/process_unicode_common.h b/quantum/process_keycode/process_unicode_common.h
index e608ab76b..7340800e5 100644
--- a/quantum/process_keycode/process_unicode_common.h
+++ b/quantum/process_keycode/process_unicode_common.h
@@ -23,11 +23,14 @@
23#endif 23#endif
24 24
25// Keycodes used for starting Unicode input on different platforms 25// Keycodes used for starting Unicode input on different platforms
26#ifndef UNICODE_OSX_KEY 26#ifndef UNICODE_KEY_OSX
27 #define UNICODE_OSX_KEY KC_LALT 27 #define UNICODE_KEY_OSX KC_LALT
28#endif 28#endif
29#ifndef UNICODE_WINC_KEY 29#ifndef UNICODE_KEY_LNX
30 #define UNICODE_WINC_KEY KC_RALT 30 #define UNICODE_KEY_LNX LCTL(LSFT(KC_U))
31#endif
32#ifndef UNICODE_KEY_WINC
33 #define UNICODE_KEY_WINC KC_RALT
31#endif 34#endif
32 35
33// Comma-delimited, ordered list of input modes selected for use (e.g. in cycle) 36// Comma-delimited, ordered list of input modes selected for use (e.g. in cycle)
@@ -63,6 +66,7 @@ typedef union {
63} unicode_config_t; 66} unicode_config_t;
64 67
65extern unicode_config_t unicode_config; 68extern unicode_config_t unicode_config;
69extern uint8_t unicode_saved_mods;
66 70
67void unicode_input_mode_init(void); 71void unicode_input_mode_init(void);
68uint8_t get_unicode_input_mode(void); 72uint8_t get_unicode_input_mode(void);
@@ -72,6 +76,7 @@ void persist_unicode_input_mode(void);
72 76
73void unicode_input_start(void); 77void unicode_input_start(void);
74void unicode_input_finish(void); 78void unicode_input_finish(void);
79void unicode_input_cancel(void);
75 80
76void register_hex(uint16_t hex); 81void register_hex(uint16_t hex);
77void send_unicode_hex_string(const char *str); 82void send_unicode_hex_string(const char *str);
diff --git a/quantum/process_keycode/process_unicodemap.c b/quantum/process_keycode/process_unicodemap.c
index 327402761..b88787986 100644
--- a/quantum/process_keycode/process_unicodemap.c
+++ b/quantum/process_keycode/process_unicodemap.c
@@ -15,7 +15,6 @@
15 */ 15 */
16 16
17#include "process_unicodemap.h" 17#include "process_unicodemap.h"
18#include "process_unicode_common.h"
19 18
20void register_hex32(uint32_t hex) { 19void register_hex32(uint32_t hex) {
21 bool onzerostart = true; 20 bool onzerostart = true;
@@ -38,28 +37,39 @@ void register_hex32(uint32_t hex) {
38} 37}
39 38
40__attribute__((weak)) 39__attribute__((weak))
41void unicodemap_input_error() {} 40uint16_t unicodemap_index(uint16_t keycode) {
41 if (keycode >= QK_UNICODEMAP_PAIR) {
42 // Keycode is a pair: extract index based on Shift / Caps Lock state
43 uint16_t index = keycode - QK_UNICODEMAP_PAIR;
44
45 bool shift = unicode_saved_mods & MOD_MASK_SHIFT, caps = IS_HOST_LED_ON(USB_LED_CAPS_LOCK);
46 if (shift ^ caps) { index >>= 7; }
47
48 return index & 0x7F;
49 } else {
50 // Keycode is a regular index
51 return keycode - QK_UNICODEMAP;
52 }
53}
42 54
43bool process_unicodemap(uint16_t keycode, keyrecord_t *record) { 55bool process_unicodemap(uint16_t keycode, keyrecord_t *record) {
44 if ((keycode & QK_UNICODEMAP) == QK_UNICODEMAP && record->event.pressed) { 56 if (keycode >= QK_UNICODEMAP && keycode <= QK_UNICODEMAP_PAIR_MAX && record->event.pressed) {
45 uint16_t index = keycode - QK_UNICODEMAP; 57 unicode_input_start();
46 uint32_t code = pgm_read_dword(unicode_map + index); 58
59 uint32_t code = pgm_read_dword(unicode_map + unicodemap_index(keycode));
47 uint8_t input_mode = get_unicode_input_mode(); 60 uint8_t input_mode = get_unicode_input_mode();
48 61
49 if (code > 0xFFFF && code <= 0x10FFFF && input_mode == UC_OSX) { 62 if (code > 0x10FFFF || (code > 0xFFFF && input_mode == UC_WIN)) {
50 // Convert to UTF-16 surrogate pair 63 // Character is out of range supported by the platform
64 unicode_input_cancel();
65 } else if (code > 0xFFFF && input_mode == UC_OSX) {
66 // Convert to UTF-16 surrogate pair on Mac
51 code -= 0x10000; 67 code -= 0x10000;
52 uint32_t lo = code & 0x3FF, hi = (code & 0xFFC00) >> 10; 68 uint32_t lo = code & 0x3FF, hi = (code & 0xFFC00) >> 10;
53
54 unicode_input_start();
55 register_hex32(hi + 0xD800); 69 register_hex32(hi + 0xD800);
56 register_hex32(lo + 0xDC00); 70 register_hex32(lo + 0xDC00);
57 unicode_input_finish(); 71 unicode_input_finish();
58 } else if ((code > 0x10FFFF && input_mode == UC_OSX) || (code > 0xFFFFF && input_mode == UC_LNX)) {
59 // Character is out of range supported by the OS
60 unicodemap_input_error();
61 } else { 72 } else {
62 unicode_input_start();
63 register_hex32(code); 73 register_hex32(code);
64 unicode_input_finish(); 74 unicode_input_finish();
65 } 75 }
diff --git a/quantum/process_keycode/process_unicodemap.h b/quantum/process_keycode/process_unicodemap.h
index fe4f97915..51709c5dc 100644
--- a/quantum/process_keycode/process_unicodemap.h
+++ b/quantum/process_keycode/process_unicodemap.h
@@ -16,10 +16,10 @@
16 16
17#pragma once 17#pragma once
18 18
19#include "quantum.h"
20#include "process_unicode_common.h" 19#include "process_unicode_common.h"
21 20
22extern const uint32_t PROGMEM unicode_map[]; 21extern const uint32_t PROGMEM unicode_map[];
23 22
24void unicodemap_input_error(void); 23void register_hex32(uint32_t hex);
24uint16_t unicodemap_index(uint16_t keycode);
25bool process_unicodemap(uint16_t keycode, keyrecord_t *record); 25bool process_unicodemap(uint16_t keycode, keyrecord_t *record);