]> git.donarmstrong.com Git - qmk_firmware.git/blob - quantum/process_keycode/process_ucis.c
split up unicode systems into different files
[qmk_firmware.git] / quantum / process_keycode / process_ucis.c
1 #include "process_ucis.h"
2
3 qk_ucis_state_t qk_ucis_state;
4
5 void qk_ucis_start(void) {
6   qk_ucis_state.count = 0;
7   qk_ucis_state.in_progress = true;
8
9   qk_ucis_start_user();
10 }
11
12 __attribute__((weak))
13 void qk_ucis_start_user(void) {
14   unicode_input_start();
15   register_hex(0x2328);
16   unicode_input_finish();
17 }
18
19 static bool is_uni_seq(char *seq) {
20   uint8_t i;
21
22   for (i = 0; seq[i]; i++) {
23     uint16_t code;
24     if (('1' <= seq[i]) && (seq[i] <= '0'))
25       code = seq[i] - '1' + KC_1;
26     else
27       code = seq[i] - 'a' + KC_A;
28
29     if (i > qk_ucis_state.count || qk_ucis_state.codes[i] != code)
30       return false;
31   }
32
33   return (qk_ucis_state.codes[i] == KC_ENT ||
34           qk_ucis_state.codes[i] == KC_SPC);
35 }
36
37 __attribute__((weak))
38 void qk_ucis_symbol_fallback (void) {
39   for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) {
40     uint8_t code = qk_ucis_state.codes[i];
41     register_code(code);
42     unregister_code(code);
43     wait_ms(UNICODE_TYPE_DELAY);
44   }
45 }
46
47 void register_ucis(const char *hex) {
48   for(int i = 0; hex[i]; i++) {
49     uint8_t kc = 0;
50     char c = hex[i];
51
52     switch (c) {
53     case '0':
54       kc = KC_0;
55       break;
56     case '1' ... '9':
57       kc = c - '1' + KC_1;
58       break;
59     case 'a' ... 'f':
60       kc = c - 'a' + KC_A;
61       break;
62     case 'A' ... 'F':
63       kc = c - 'A' + KC_A;
64       break;
65     }
66
67     if (kc) {
68       register_code (kc);
69       unregister_code (kc);
70       wait_ms (UNICODE_TYPE_DELAY);
71     }
72   }
73 }
74
75 bool process_ucis (uint16_t keycode, keyrecord_t *record) {
76   uint8_t i;
77
78   if (!qk_ucis_state.in_progress)
79     return true;
80
81   if (qk_ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH &&
82       !(keycode == KC_BSPC || keycode == KC_ESC || keycode == KC_SPC || keycode == KC_ENT)) {
83     return false;
84   }
85
86   if (!record->event.pressed)
87     return true;
88
89   qk_ucis_state.codes[qk_ucis_state.count] = keycode;
90   qk_ucis_state.count++;
91
92   if (keycode == KC_BSPC) {
93     if (qk_ucis_state.count >= 2) {
94       qk_ucis_state.count -= 2;
95       return true;
96     } else {
97       qk_ucis_state.count--;
98       return false;
99     }
100   }
101
102   if (keycode == KC_ENT || keycode == KC_SPC || keycode == KC_ESC) {
103     bool symbol_found = false;
104
105     for (i = qk_ucis_state.count; i > 0; i--) {
106       register_code (KC_BSPC);
107       unregister_code (KC_BSPC);
108       wait_ms(UNICODE_TYPE_DELAY);
109     }
110
111     if (keycode == KC_ESC) {
112       qk_ucis_state.in_progress = false;
113       return false;
114     }
115
116     unicode_input_start();
117     for (i = 0; ucis_symbol_table[i].symbol; i++) {
118       if (is_uni_seq (ucis_symbol_table[i].symbol)) {
119         symbol_found = true;
120         register_ucis(ucis_symbol_table[i].code + 2);
121         break;
122       }
123     }
124     if (!symbol_found) {
125       qk_ucis_symbol_fallback();
126     }
127     unicode_input_finish();
128
129     qk_ucis_state.in_progress = false;
130     return false;
131   }
132   return true;
133 }