aboutsummaryrefslogtreecommitdiff
path: root/quantum/process_keycode/process_unicode.c
diff options
context:
space:
mode:
authorRyan Ascheman <rascheman@groupon.com>2016-10-18 12:42:02 -0700
committerRyan Ascheman <rascheman@groupon.com>2016-10-18 12:42:02 -0700
commit55b8b8477cc6aee82dfe6792eea4e589cac433d5 (patch)
treece5bfbd1b0ee59dbffdc2044bcf90c89614392ed /quantum/process_keycode/process_unicode.c
parentd1c70328f8d8ded6ce1e5422b468fc41ef315e7d (diff)
parent04df74f6360464661bcc1e6794e9fd3549084390 (diff)
downloadqmk_firmware-55b8b8477cc6aee82dfe6792eea4e589cac433d5.tar.gz
qmk_firmware-55b8b8477cc6aee82dfe6792eea4e589cac433d5.zip
Merge remote-tracking branch 'upstream/master'
* upstream/master: (1239 commits) Update ez.c removes planck/rev3 temporarily Move hand_swap_config to ez.c, removes error for infinity Update Makefile ergodox: Update algernon's keymap to v1.9 Added VS Code dir to .gitignore Support the Pegasus Hoof controller. [Jack & Erez] Simplifies and documents TO add readme use wait_ms instead of _delay_ms add messenger init keymap Add example keymap Adding whiskey_tango_foxtrot_capslock ergodox keymap Unicode map framework. Allow unicode up to 0xFFFFF using separate mapping table CIE 1931 dim curve Apply the dim curve to the RGB output Update the Cluecard readme files Tune snake and knight intervals for Cluecard Tunable RGB light intervals ...
Diffstat (limited to 'quantum/process_keycode/process_unicode.c')
-rw-r--r--quantum/process_keycode/process_unicode.c239
1 files changed, 239 insertions, 0 deletions
diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c
new file mode 100644
index 000000000..37dd471ff
--- /dev/null
+++ b/quantum/process_keycode/process_unicode.c
@@ -0,0 +1,239 @@
1#include "process_unicode.h"
2
3static uint8_t input_mode;
4
5__attribute__((weak))
6uint16_t hex_to_keycode(uint8_t hex)
7{
8 if (hex == 0x0) {
9 return KC_0;
10 } else if (hex < 0xA) {
11 return KC_1 + (hex - 0x1);
12 } else {
13 return KC_A + (hex - 0xA);
14 }
15}
16
17void set_unicode_input_mode(uint8_t os_target)
18{
19 input_mode = os_target;
20}
21
22uint8_t get_unicode_input_mode(void) {
23 return input_mode;
24}
25
26__attribute__((weak))
27void unicode_input_start (void) {
28 switch(input_mode) {
29 case UC_OSX:
30 register_code(KC_LALT);
31 break;
32 case UC_LNX:
33 register_code(KC_LCTL);
34 register_code(KC_LSFT);
35 register_code(KC_U);
36 unregister_code(KC_U);
37 unregister_code(KC_LSFT);
38 unregister_code(KC_LCTL);
39 break;
40 case UC_WIN:
41 register_code(KC_LALT);
42 register_code(KC_PPLS);
43 unregister_code(KC_PPLS);
44 break;
45 }
46 wait_ms(UNICODE_TYPE_DELAY);
47}
48
49__attribute__((weak))
50void unicode_input_finish (void) {
51 switch(input_mode) {
52 case UC_OSX:
53 case UC_WIN:
54 unregister_code(KC_LALT);
55 break;
56 case UC_LNX:
57 register_code(KC_SPC);
58 unregister_code(KC_SPC);
59 break;
60 }
61}
62
63void register_hex(uint16_t hex) {
64 for(int i = 3; i >= 0; i--) {
65 uint8_t digit = ((hex >> (i*4)) & 0xF);
66 register_code(hex_to_keycode(digit));
67 unregister_code(hex_to_keycode(digit));
68 }
69}
70
71bool process_unicode(uint16_t keycode, keyrecord_t *record) {
72 if (keycode > QK_UNICODE && record->event.pressed) {
73 uint16_t unicode = keycode & 0x7FFF;
74 unicode_input_start();
75 register_hex(unicode);
76 unicode_input_finish();
77 }
78 return true;
79}
80
81#ifdef UNICODEMAP_ENABLE
82__attribute__((weak))
83const uint32_t PROGMEM unicode_map[] = {
84};
85
86// 5 digit max because of linux limitation
87void register_hex32(uint32_t hex) {
88 for(int i = 4; i >= 0; i--) {
89 uint8_t digit = ((hex >> (i*4)) & 0xF);
90 register_code(hex_to_keycode(digit));
91 unregister_code(hex_to_keycode(digit));
92 }
93}
94
95bool process_unicode_map(uint16_t keycode, keyrecord_t *record) {
96 if ((keycode & QK_UNICODE_MAP) == QK_UNICODE_MAP && record->event.pressed) {
97 const uint32_t* map = unicode_map;
98 uint16_t index = keycode & 0x7FF;
99 unicode_input_start();
100 register_hex32(pgm_read_dword_far(&map[index]));
101 unicode_input_finish();
102 }
103 return true;
104}
105#endif
106
107#ifdef UCIS_ENABLE
108qk_ucis_state_t qk_ucis_state;
109
110void qk_ucis_start(void) {
111 qk_ucis_state.count = 0;
112 qk_ucis_state.in_progress = true;
113
114 qk_ucis_start_user();
115}
116
117__attribute__((weak))
118void qk_ucis_start_user(void) {
119 unicode_input_start();
120 register_hex(0x2328);
121 unicode_input_finish();
122}
123
124static bool is_uni_seq(char *seq) {
125 uint8_t i;
126
127 for (i = 0; seq[i]; i++) {
128 uint16_t code;
129 if (('1' <= seq[i]) && (seq[i] <= '0'))
130 code = seq[i] - '1' + KC_1;
131 else
132 code = seq[i] - 'a' + KC_A;
133
134 if (i > qk_ucis_state.count || qk_ucis_state.codes[i] != code)
135 return false;
136 }
137
138 return (qk_ucis_state.codes[i] == KC_ENT ||
139 qk_ucis_state.codes[i] == KC_SPC);
140}
141
142__attribute__((weak))
143void qk_ucis_symbol_fallback (void) {
144 for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) {
145 uint8_t code = qk_ucis_state.codes[i];
146 register_code(code);
147 unregister_code(code);
148 wait_ms(UNICODE_TYPE_DELAY);
149 }
150}
151
152void register_ucis(const char *hex) {
153 for(int i = 0; hex[i]; i++) {
154 uint8_t kc = 0;
155 char c = hex[i];
156
157 switch (c) {
158 case '0':
159 kc = KC_0;
160 break;
161 case '1' ... '9':
162 kc = c - '1' + KC_1;
163 break;
164 case 'a' ... 'f':
165 kc = c - 'a' + KC_A;
166 break;
167 case 'A' ... 'F':
168 kc = c - 'A' + KC_A;
169 break;
170 }
171
172 if (kc) {
173 register_code (kc);
174 unregister_code (kc);
175 wait_ms (UNICODE_TYPE_DELAY);
176 }
177 }
178}
179
180bool process_ucis (uint16_t keycode, keyrecord_t *record) {
181 uint8_t i;
182
183 if (!qk_ucis_state.in_progress)
184 return true;
185
186 if (qk_ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH &&
187 !(keycode == KC_BSPC || keycode == KC_ESC || keycode == KC_SPC || keycode == KC_ENT)) {
188 return false;
189 }
190
191 if (!record->event.pressed)
192 return true;
193
194 qk_ucis_state.codes[qk_ucis_state.count] = keycode;
195 qk_ucis_state.count++;
196
197 if (keycode == KC_BSPC) {
198 if (qk_ucis_state.count >= 2) {
199 qk_ucis_state.count -= 2;
200 return true;
201 } else {
202 qk_ucis_state.count--;
203 return false;
204 }
205 }
206
207 if (keycode == KC_ENT || keycode == KC_SPC || keycode == KC_ESC) {
208 bool symbol_found = false;
209
210 for (i = qk_ucis_state.count; i > 0; i--) {
211 register_code (KC_BSPC);
212 unregister_code (KC_BSPC);
213 wait_ms(UNICODE_TYPE_DELAY);
214 }
215
216 if (keycode == KC_ESC) {
217 qk_ucis_state.in_progress = false;
218 return false;
219 }
220
221 unicode_input_start();
222 for (i = 0; ucis_symbol_table[i].symbol; i++) {
223 if (is_uni_seq (ucis_symbol_table[i].symbol)) {
224 symbol_found = true;
225 register_ucis(ucis_symbol_table[i].code + 2);
226 break;
227 }
228 }
229 if (!symbol_found) {
230 qk_ucis_symbol_fallback();
231 }
232 unicode_input_finish();
233
234 qk_ucis_state.in_progress = false;
235 return false;
236 }
237 return true;
238}
239#endif