]> git.donarmstrong.com Git - qmk_firmware.git/blob - quantum/process_keycode/process_unicode.c
- Updated dbroqua layout for kc60
[qmk_firmware.git] / quantum / process_keycode / process_unicode.c
1 #include "process_unicode.h"
2
3 static uint8_t input_mode;
4
5 uint16_t hex_to_keycode(uint8_t hex)
6 {
7   if (hex == 0x0) {
8     return KC_0;
9   } else if (hex < 0xA) {
10     return KC_1 + (hex - 0x1);
11   } else {
12     return KC_A + (hex - 0xA);
13   }
14 }
15
16 void set_unicode_input_mode(uint8_t os_target)
17 {
18   input_mode = os_target;
19 }
20
21 __attribute__((weak))
22 void unicode_input_start (void) {
23   switch(input_mode) {
24   case UC_OSX:
25     register_code(KC_LALT);
26     break;
27   case UC_LNX:
28     register_code(KC_LCTL);
29     register_code(KC_LSFT);
30     register_code(KC_U);
31     unregister_code(KC_U);
32     unregister_code(KC_LSFT);
33     unregister_code(KC_LCTL);
34     break;
35   case UC_WIN:
36     register_code(KC_LALT);
37     register_code(KC_PPLS);
38     unregister_code(KC_PPLS);
39     break;
40   }
41   wait_ms(UNICODE_TYPE_DELAY);
42 }
43
44 __attribute__((weak))
45 void unicode_input_finish (void) {
46   switch(input_mode) {
47   case UC_OSX:
48   case UC_WIN:
49     unregister_code(KC_LALT);
50     break;
51   case UC_LNX:
52     register_code(KC_SPC);
53     unregister_code(KC_SPC);
54     break;
55   }
56 }
57
58 void register_hex(uint16_t hex) {
59   for(int i = 3; i >= 0; i--) {
60     uint8_t digit = ((hex >> (i*4)) & 0xF);
61     register_code(hex_to_keycode(digit));
62     unregister_code(hex_to_keycode(digit));
63   }
64 }
65
66 bool process_unicode(uint16_t keycode, keyrecord_t *record) {
67   if (keycode > QK_UNICODE && record->event.pressed) {
68     uint16_t unicode = keycode & 0x7FFF;
69     unicode_input_start();
70     register_hex(unicode);
71     unicode_input_finish();
72   }
73   return true;
74 }
75
76 #ifdef UCIS_ENABLE
77 qk_ucis_state_t qk_ucis_state;
78
79 void qk_ucis_start(void) {
80   qk_ucis_state.count = 0;
81   qk_ucis_state.in_progress = true;
82
83   qk_ucis_start_user();
84 }
85
86 __attribute__((weak))
87 void qk_ucis_start_user(void) {
88   unicode_input_start();
89   register_hex(0x2328);
90   unicode_input_finish();
91 }
92
93 static bool is_uni_seq(char *seq) {
94   uint8_t i;
95
96   for (i = 0; seq[i]; i++) {
97     uint16_t code;
98     if (('1' <= seq[i]) && (seq[i] <= '0'))
99       code = seq[i] - '1' + KC_1;
100     else
101       code = seq[i] - 'a' + KC_A;
102
103     if (i > qk_ucis_state.count || qk_ucis_state.codes[i] != code)
104       return false;
105   }
106
107   return (qk_ucis_state.codes[i] == KC_ENT ||
108           qk_ucis_state.codes[i] == KC_SPC);
109 }
110
111 __attribute__((weak))
112 void qk_ucis_symbol_fallback (void) {
113   for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) {
114     uint8_t code = qk_ucis_state.codes[i];
115     register_code(code);
116     unregister_code(code);
117     wait_ms(UNICODE_TYPE_DELAY);
118   }
119 }
120
121 void register_ucis(const char *hex) {
122   for(int i = 0; hex[i]; i++) {
123     uint8_t kc = 0;
124     char c = hex[i];
125
126     switch (c) {
127     case '0':
128       kc = KC_0;
129       break;
130     case '1' ... '9':
131       kc = c - '1' + KC_1;
132       break;
133     case 'a' ... 'f':
134       kc = c - 'a' + KC_A;
135       break;
136     case 'A' ... 'F':
137       kc = c - 'A' + KC_A;
138       break;
139     }
140
141     if (kc) {
142       register_code (kc);
143       unregister_code (kc);
144       wait_ms (UNICODE_TYPE_DELAY);
145     }
146   }
147 }
148
149 bool process_ucis (uint16_t keycode, keyrecord_t *record) {
150   uint8_t i;
151
152   if (!qk_ucis_state.in_progress)
153     return true;
154
155   if (qk_ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH &&
156       !(keycode == KC_BSPC || keycode == KC_ESC || keycode == KC_SPC || keycode == KC_ENT)) {
157     return false;
158   }
159
160   if (!record->event.pressed)
161     return true;
162
163   qk_ucis_state.codes[qk_ucis_state.count] = keycode;
164   qk_ucis_state.count++;
165
166   if (keycode == KC_BSPC) {
167     if (qk_ucis_state.count >= 2) {
168       qk_ucis_state.count -= 2;
169       return true;
170     } else {
171       qk_ucis_state.count--;
172       return false;
173     }
174   }
175
176   if (keycode == KC_ENT || keycode == KC_SPC || keycode == KC_ESC) {
177     bool symbol_found = false;
178
179     for (i = qk_ucis_state.count; i > 0; i--) {
180       register_code (KC_BSPC);
181       unregister_code (KC_BSPC);
182       wait_ms(UNICODE_TYPE_DELAY);
183     }
184
185     if (keycode == KC_ESC) {
186       qk_ucis_state.in_progress = false;
187       return false;
188     }
189
190     unicode_input_start();
191     for (i = 0; ucis_symbol_table[i].symbol; i++) {
192       if (is_uni_seq (ucis_symbol_table[i].symbol)) {
193         symbol_found = true;
194         register_ucis(ucis_symbol_table[i].code + 2);
195         break;
196       }
197     }
198     if (!symbol_found) {
199       qk_ucis_symbol_fallback();
200     }
201     unicode_input_finish();
202
203     qk_ucis_state.in_progress = false;
204     return false;
205   }
206   return true;
207 }
208 #endif