aboutsummaryrefslogtreecommitdiff
path: root/quantum/process_keycode/process_unicode_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/process_keycode/process_unicode_common.c')
-rw-r--r--quantum/process_keycode/process_unicode_common.c321
1 files changed, 158 insertions, 163 deletions
diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c
index 21ac2291d..94383f19b 100644
--- a/quantum/process_keycode/process_unicode_common.c
+++ b/quantum/process_keycode/process_unicode_common.c
@@ -23,220 +23,215 @@ unicode_config_t unicode_config;
23uint8_t unicode_saved_mods; 23uint8_t unicode_saved_mods;
24 24
25#if UNICODE_SELECTED_MODES != -1 25#if UNICODE_SELECTED_MODES != -1
26static uint8_t selected[] = { UNICODE_SELECTED_MODES }; 26static uint8_t selected[] = {UNICODE_SELECTED_MODES};
27static uint8_t selected_count = sizeof selected / sizeof *selected; 27static uint8_t selected_count = sizeof selected / sizeof *selected;
28static uint8_t selected_index; 28static uint8_t selected_index;
29#endif 29#endif
30 30
31void unicode_input_mode_init(void) { 31void unicode_input_mode_init(void) {
32 unicode_config.raw = eeprom_read_byte(EECONFIG_UNICODEMODE); 32 unicode_config.raw = eeprom_read_byte(EECONFIG_UNICODEMODE);
33#if UNICODE_SELECTED_MODES != -1 33#if UNICODE_SELECTED_MODES != -1
34 #if UNICODE_CYCLE_PERSIST 34# if UNICODE_CYCLE_PERSIST
35 // Find input_mode in selected modes 35 // Find input_mode in selected modes
36 uint8_t i; 36 uint8_t i;
37 for (i = 0; i < selected_count; i++) { 37 for (i = 0; i < selected_count; i++) {
38 if (selected[i] == unicode_config.input_mode) { 38 if (selected[i] == unicode_config.input_mode) {
39 selected_index = i; 39 selected_index = i;
40 break; 40 break;
41 }
41 } 42 }
42 } 43 if (i == selected_count) {
43 if (i == selected_count) { 44 // Not found: input_mode isn't selected, change to one that is
44 // Not found: input_mode isn't selected, change to one that is 45 unicode_config.input_mode = selected[selected_index = 0];
46 }
47# else
48 // Always change to the first selected input mode
45 unicode_config.input_mode = selected[selected_index = 0]; 49 unicode_config.input_mode = selected[selected_index = 0];
46 } 50# endif
47 #else
48 // Always change to the first selected input mode
49 unicode_config.input_mode = selected[selected_index = 0];
50 #endif
51#endif 51#endif
52 dprintf("Unicode input mode init to: %u\n", unicode_config.input_mode); 52 dprintf("Unicode input mode init to: %u\n", unicode_config.input_mode);
53} 53}
54 54
55uint8_t get_unicode_input_mode(void) { 55uint8_t get_unicode_input_mode(void) { return unicode_config.input_mode; }
56 return unicode_config.input_mode;
57}
58 56
59void set_unicode_input_mode(uint8_t mode) { 57void set_unicode_input_mode(uint8_t mode) {
60 unicode_config.input_mode = mode; 58 unicode_config.input_mode = mode;
61 persist_unicode_input_mode(); 59 persist_unicode_input_mode();
62 dprintf("Unicode input mode set to: %u\n", unicode_config.input_mode); 60 dprintf("Unicode input mode set to: %u\n", unicode_config.input_mode);
63} 61}
64 62
65void cycle_unicode_input_mode(uint8_t offset) { 63void cycle_unicode_input_mode(uint8_t offset) {
66#if UNICODE_SELECTED_MODES != -1 64#if UNICODE_SELECTED_MODES != -1
67 selected_index = (selected_index + offset) % selected_count; 65 selected_index = (selected_index + offset) % selected_count;
68 unicode_config.input_mode = selected[selected_index]; 66 unicode_config.input_mode = selected[selected_index];
69 #if UNICODE_CYCLE_PERSIST 67# if UNICODE_CYCLE_PERSIST
70 persist_unicode_input_mode(); 68 persist_unicode_input_mode();
71 #endif 69# endif
72 dprintf("Unicode input mode cycle to: %u\n", unicode_config.input_mode); 70 dprintf("Unicode input mode cycle to: %u\n", unicode_config.input_mode);
73#endif 71#endif
74} 72}
75 73
76void persist_unicode_input_mode(void) { 74void persist_unicode_input_mode(void) { eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config.input_mode); }
77 eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config.input_mode); 75
78} 76__attribute__((weak)) void unicode_input_start(void) {
77 unicode_saved_mods = get_mods(); // Save current mods
78 clear_mods(); // Unregister mods to start from a clean state
79
80 switch (unicode_config.input_mode) {
81 case UC_OSX:
82 register_code(UNICODE_KEY_OSX);
83 break;
84 case UC_LNX:
85 tap_code16(UNICODE_KEY_LNX);
86 break;
87 case UC_WIN:
88 register_code(KC_LALT);
89 tap_code(KC_PPLS);
90 break;
91 case UC_WINC:
92 tap_code(UNICODE_KEY_WINC);
93 tap_code(KC_U);
94 break;
95 }
79 96
80__attribute__((weak)) 97 wait_ms(UNICODE_TYPE_DELAY);
81void unicode_input_start(void) {
82 unicode_saved_mods = get_mods(); // Save current mods
83 clear_mods(); // Unregister mods to start from a clean state
84
85 switch (unicode_config.input_mode) {
86 case UC_OSX:
87 register_code(UNICODE_KEY_OSX);
88 break;
89 case UC_LNX:
90 tap_code16(UNICODE_KEY_LNX);
91 break;
92 case UC_WIN:
93 register_code(KC_LALT);
94 tap_code(KC_PPLS);
95 break;
96 case UC_WINC:
97 tap_code(UNICODE_KEY_WINC);
98 tap_code(KC_U);
99 break;
100 }
101
102 wait_ms(UNICODE_TYPE_DELAY);
103} 98}
104 99
105__attribute__((weak)) 100__attribute__((weak)) void unicode_input_finish(void) {
106void unicode_input_finish(void) { 101 switch (unicode_config.input_mode) {
107 switch (unicode_config.input_mode) { 102 case UC_OSX:
108 case UC_OSX: 103 unregister_code(UNICODE_KEY_OSX);
109 unregister_code(UNICODE_KEY_OSX); 104 break;
110 break; 105 case UC_LNX:
111 case UC_LNX: 106 tap_code(KC_SPC);
112 tap_code(KC_SPC); 107 break;
113 break; 108 case UC_WIN:
114 case UC_WIN: 109 unregister_code(KC_LALT);
115 unregister_code(KC_LALT); 110 break;
116 break; 111 case UC_WINC:
117 case UC_WINC: 112 tap_code(KC_ENTER);
118 tap_code(KC_ENTER); 113 break;
119 break; 114 }
120 } 115
121 116 set_mods(unicode_saved_mods); // Reregister previously set mods
122 set_mods(unicode_saved_mods); // Reregister previously set mods
123} 117}
124 118
125__attribute__((weak)) 119__attribute__((weak)) void unicode_input_cancel(void) {
126void unicode_input_cancel(void) { 120 switch (unicode_config.input_mode) {
127 switch (unicode_config.input_mode) { 121 case UC_OSX:
128 case UC_OSX: 122 unregister_code(UNICODE_KEY_OSX);
129 unregister_code(UNICODE_KEY_OSX); 123 break;
130 break; 124 case UC_LNX:
131 case UC_LNX: 125 case UC_WINC:
132 case UC_WINC: 126 tap_code(KC_ESC);
133 tap_code(KC_ESC); 127 break;
134 break; 128 case UC_WIN:
135 case UC_WIN: 129 unregister_code(KC_LALT);
136 unregister_code(KC_LALT); 130 break;
137 break; 131 }
138 } 132
139 133 set_mods(unicode_saved_mods); // Reregister previously set mods
140 set_mods(unicode_saved_mods); // Reregister previously set mods
141} 134}
142 135
143__attribute__((weak)) 136__attribute__((weak)) uint16_t hex_to_keycode(uint8_t hex) {
144uint16_t hex_to_keycode(uint8_t hex) { 137 if (hex == 0x0) {
145 if (hex == 0x0) { 138 return KC_0;
146 return KC_0; 139 } else if (hex < 0xA) {
147 } else if (hex < 0xA) { 140 return KC_1 + (hex - 0x1);
148 return KC_1 + (hex - 0x1); 141 } else {
149 } else { 142 return KC_A + (hex - 0xA);
150 return KC_A + (hex - 0xA); 143 }
151 }
152} 144}
153 145
154void register_hex(uint16_t hex) { 146void register_hex(uint16_t hex) {
155 for(int i = 3; i >= 0; i--) { 147 for (int i = 3; i >= 0; i--) {
156 uint8_t digit = ((hex >> (i*4)) & 0xF); 148 uint8_t digit = ((hex >> (i * 4)) & 0xF);
157 tap_code(hex_to_keycode(digit)); 149 tap_code(hex_to_keycode(digit));
158 } 150 }
159} 151}
160 152
161void send_unicode_hex_string(const char *str) { 153void send_unicode_hex_string(const char *str) {
162 if (!str) { return; } 154 if (!str) {
163 155 return;
164 while (*str) {
165 // Find the next code point (token) in the string
166 for (; *str == ' '; str++);
167 size_t n = strcspn(str, " "); // Length of the current token
168 char code_point[n+1];
169 strncpy(code_point, str, n);
170 code_point[n] = '\0'; // Make sure it's null-terminated
171
172 // Normalize the code point: make all hex digits lowercase
173 for (char *p = code_point; *p; p++) {
174 *p = tolower((unsigned char)*p);
175 } 156 }
176 157
177 // Send the code point as a Unicode input string 158 while (*str) {
178 unicode_input_start(); 159 // Find the next code point (token) in the string
179 send_string(code_point); 160 for (; *str == ' '; str++)
180 unicode_input_finish(); 161 ;
181 162 size_t n = strcspn(str, " "); // Length of the current token
182 str += n; // Move to the first ' ' (or '\0') after the current token 163 char code_point[n + 1];
183 } 164 strncpy(code_point, str, n);
165 code_point[n] = '\0'; // Make sure it's null-terminated
166
167 // Normalize the code point: make all hex digits lowercase
168 for (char *p = code_point; *p; p++) {
169 *p = tolower((unsigned char)*p);
170 }
171
172 // Send the code point as a Unicode input string
173 unicode_input_start();
174 send_string(code_point);
175 unicode_input_finish();
176
177 str += n; // Move to the first ' ' (or '\0') after the current token
178 }
184} 179}
185 180
186bool process_unicode_common(uint16_t keycode, keyrecord_t *record) { 181bool process_unicode_common(uint16_t keycode, keyrecord_t *record) {
187 if (record->event.pressed) { 182 if (record->event.pressed) {
188 switch (keycode) { 183 switch (keycode) {
189 case UNICODE_MODE_FORWARD: 184 case UNICODE_MODE_FORWARD:
190 cycle_unicode_input_mode(+1); 185 cycle_unicode_input_mode(+1);
191 break; 186 break;
192 case UNICODE_MODE_REVERSE: 187 case UNICODE_MODE_REVERSE:
193 cycle_unicode_input_mode(-1); 188 cycle_unicode_input_mode(-1);
194 break; 189 break;
195 190
196 case UNICODE_MODE_OSX: 191 case UNICODE_MODE_OSX:
197 set_unicode_input_mode(UC_OSX); 192 set_unicode_input_mode(UC_OSX);
198#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_OSX) 193#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_OSX)
199 static float song_osx[][2] = UNICODE_SONG_OSX; 194 static float song_osx[][2] = UNICODE_SONG_OSX;
200 PLAY_SONG(song_osx); 195 PLAY_SONG(song_osx);
201#endif 196#endif
202 break; 197 break;
203 case UNICODE_MODE_LNX: 198 case UNICODE_MODE_LNX:
204 set_unicode_input_mode(UC_LNX); 199 set_unicode_input_mode(UC_LNX);
205#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_LNX) 200#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_LNX)
206 static float song_lnx[][2] = UNICODE_SONG_LNX; 201 static float song_lnx[][2] = UNICODE_SONG_LNX;
207 PLAY_SONG(song_lnx); 202 PLAY_SONG(song_lnx);
208#endif 203#endif
209 break; 204 break;
210 case UNICODE_MODE_WIN: 205 case UNICODE_MODE_WIN:
211 set_unicode_input_mode(UC_WIN); 206 set_unicode_input_mode(UC_WIN);
212#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WIN) 207#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WIN)
213 static float song_win[][2] = UNICODE_SONG_WIN; 208 static float song_win[][2] = UNICODE_SONG_WIN;
214 PLAY_SONG(song_win); 209 PLAY_SONG(song_win);
215#endif 210#endif
216 break; 211 break;
217 case UNICODE_MODE_BSD: 212 case UNICODE_MODE_BSD:
218 set_unicode_input_mode(UC_BSD); 213 set_unicode_input_mode(UC_BSD);
219#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_BSD) 214#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_BSD)
220 static float song_bsd[][2] = UNICODE_SONG_BSD; 215 static float song_bsd[][2] = UNICODE_SONG_BSD;
221 PLAY_SONG(song_bsd); 216 PLAY_SONG(song_bsd);
222#endif 217#endif
223 break; 218 break;
224 case UNICODE_MODE_WINC: 219 case UNICODE_MODE_WINC:
225 set_unicode_input_mode(UC_WINC); 220 set_unicode_input_mode(UC_WINC);
226#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WINC) 221#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WINC)
227 static float song_winc[][2] = UNICODE_SONG_WINC; 222 static float song_winc[][2] = UNICODE_SONG_WINC;
228 PLAY_SONG(song_winc); 223 PLAY_SONG(song_winc);
229#endif 224#endif
230 break; 225 break;
226 }
231 } 227 }
232 } 228#if defined(UNICODE_ENABLE)
233#if defined(UNICODE_ENABLE) 229 return process_unicode(keycode, record);
234 return process_unicode(keycode, record);
235#elif defined(UNICODEMAP_ENABLE) 230#elif defined(UNICODEMAP_ENABLE)
236 return process_unicodemap(keycode, record); 231 return process_unicodemap(keycode, record);
237#elif defined(UCIS_ENABLE) 232#elif defined(UCIS_ENABLE)
238 return process_ucis(keycode, record); 233 return process_ucis(keycode, record);
239#else 234#else
240 return true; 235 return true;
241#endif 236#endif
242} 237}