aboutsummaryrefslogtreecommitdiff
path: root/quantum/process_keycode/process_ucis.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/process_keycode/process_ucis.c')
-rw-r--r--quantum/process_keycode/process_ucis.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/quantum/process_keycode/process_ucis.c b/quantum/process_keycode/process_ucis.c
new file mode 100644
index 000000000..86c0937f5
--- /dev/null
+++ b/quantum/process_keycode/process_ucis.c
@@ -0,0 +1,149 @@
1/* Copyright 2017 Jack Humbert
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
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/>.
15 */
16
17#include "process_ucis.h"
18
19qk_ucis_state_t qk_ucis_state;
20
21void qk_ucis_start(void) {
22 qk_ucis_state.count = 0;
23 qk_ucis_state.in_progress = true;
24
25 qk_ucis_start_user();
26}
27
28__attribute__((weak))
29void qk_ucis_start_user(void) {
30 unicode_input_start();
31 register_hex(0x2328);
32 unicode_input_finish();
33}
34
35static bool is_uni_seq(char *seq) {
36 uint8_t i;
37
38 for (i = 0; seq[i]; i++) {
39 uint16_t code;
40 if (('1' <= seq[i]) && (seq[i] <= '0'))
41 code = seq[i] - '1' + KC_1;
42 else
43 code = seq[i] - 'a' + KC_A;
44
45 if (i > qk_ucis_state.count || qk_ucis_state.codes[i] != code)
46 return false;
47 }
48
49 return (qk_ucis_state.codes[i] == KC_ENT ||
50 qk_ucis_state.codes[i] == KC_SPC);
51}
52
53__attribute__((weak))
54void qk_ucis_symbol_fallback (void) {
55 for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) {
56 uint8_t code = qk_ucis_state.codes[i];
57 register_code(code);
58 unregister_code(code);
59 wait_ms(UNICODE_TYPE_DELAY);
60 }
61}
62
63void register_ucis(const char *hex) {
64 for(int i = 0; hex[i]; i++) {
65 uint8_t kc = 0;
66 char c = hex[i];
67
68 switch (c) {
69 case '0':
70 kc = KC_0;
71 break;
72 case '1' ... '9':
73 kc = c - '1' + KC_1;
74 break;
75 case 'a' ... 'f':
76 kc = c - 'a' + KC_A;
77 break;
78 case 'A' ... 'F':
79 kc = c - 'A' + KC_A;
80 break;
81 }
82
83 if (kc) {
84 register_code (kc);
85 unregister_code (kc);
86 wait_ms (UNICODE_TYPE_DELAY);
87 }
88 }
89}
90
91bool process_ucis (uint16_t keycode, keyrecord_t *record) {
92 uint8_t i;
93
94 if (!qk_ucis_state.in_progress)
95 return true;
96
97 if (qk_ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH &&
98 !(keycode == KC_BSPC || keycode == KC_ESC || keycode == KC_SPC || keycode == KC_ENT)) {
99 return false;
100 }
101
102 if (!record->event.pressed)
103 return true;
104
105 qk_ucis_state.codes[qk_ucis_state.count] = keycode;
106 qk_ucis_state.count++;
107
108 if (keycode == KC_BSPC) {
109 if (qk_ucis_state.count >= 2) {
110 qk_ucis_state.count -= 2;
111 return true;
112 } else {
113 qk_ucis_state.count--;
114 return false;
115 }
116 }
117
118 if (keycode == KC_ENT || keycode == KC_SPC || keycode == KC_ESC) {
119 bool symbol_found = false;
120
121 for (i = qk_ucis_state.count; i > 0; i--) {
122 register_code (KC_BSPC);
123 unregister_code (KC_BSPC);
124 wait_ms(UNICODE_TYPE_DELAY);
125 }
126
127 if (keycode == KC_ESC) {
128 qk_ucis_state.in_progress = false;
129 return false;
130 }
131
132 unicode_input_start();
133 for (i = 0; ucis_symbol_table[i].symbol; i++) {
134 if (is_uni_seq (ucis_symbol_table[i].symbol)) {
135 symbol_found = true;
136 register_ucis(ucis_symbol_table[i].code + 2);
137 break;
138 }
139 }
140 if (!symbol_found) {
141 qk_ucis_symbol_fallback();
142 }
143 unicode_input_finish();
144
145 qk_ucis_state.in_progress = false;
146 return false;
147 }
148 return true;
149}