diff options
Diffstat (limited to 'users/drashna/keyrecords/unicode.c')
-rw-r--r-- | users/drashna/keyrecords/unicode.c | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/users/drashna/keyrecords/unicode.c b/users/drashna/keyrecords/unicode.c new file mode 100644 index 000000000..88df2c9df --- /dev/null +++ b/users/drashna/keyrecords/unicode.c | |||
@@ -0,0 +1,287 @@ | |||
1 | /* Copyright 2020 @ridingqwerty | ||
2 | * Copyright 2020 @tzarc | ||
3 | * Copyright 2021 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | ||
4 | * | ||
5 | * This program is free software: you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation, either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #include "drashna.h" | ||
20 | #include "process_unicode_common.h" | ||
21 | |||
22 | uint16_t typing_mode; | ||
23 | |||
24 | void tap_code16_nomods(uint8_t kc) { | ||
25 | uint8_t temp_mod = get_mods(); | ||
26 | clear_mods(); | ||
27 | clear_oneshot_mods(); | ||
28 | tap_code16(kc); | ||
29 | set_mods(temp_mod); | ||
30 | } | ||
31 | |||
32 | void tap_unicode_glyph_nomods(uint32_t glyph) { | ||
33 | uint8_t temp_mod = get_mods(); | ||
34 | clear_mods(); | ||
35 | clear_oneshot_mods(); | ||
36 | register_unicode(glyph); | ||
37 | set_mods(temp_mod); | ||
38 | } | ||
39 | |||
40 | typedef uint32_t (*translator_function_t)(bool is_shifted, uint32_t keycode); | ||
41 | |||
42 | #define DEFINE_UNICODE_RANGE_TRANSLATOR(translator_name, lower_alpha, upper_alpha, zero_glyph, number_one, space_glyph) \ | ||
43 | static inline uint32_t translator_name(bool is_shifted, uint32_t keycode) { \ | ||
44 | switch (keycode) { \ | ||
45 | case KC_A ... KC_Z: \ | ||
46 | return (is_shifted ? upper_alpha : lower_alpha) + keycode - KC_A; \ | ||
47 | case KC_0: \ | ||
48 | return zero_glyph; \ | ||
49 | case KC_1 ... KC_9: \ | ||
50 | return (number_one + keycode - KC_1); \ | ||
51 | case KC_SPACE: \ | ||
52 | return space_glyph; \ | ||
53 | } \ | ||
54 | return keycode; \ | ||
55 | } | ||
56 | |||
57 | #define DEFINE_UNICODE_LUT_TRANSLATOR(translator_name, ...) \ | ||
58 | static inline uint32_t translator_name(bool is_shifted, uint32_t keycode) { \ | ||
59 | static const uint32_t translation[] = {__VA_ARGS__}; \ | ||
60 | uint32_t ret = keycode; \ | ||
61 | if ((keycode - KC_A) < (sizeof(translation) / sizeof(uint32_t))) { \ | ||
62 | ret = translation[keycode - KC_A]; \ | ||
63 | } \ | ||
64 | return ret; \ | ||
65 | } | ||
66 | |||
67 | bool process_record_glyph_replacement(uint16_t keycode, keyrecord_t *record, translator_function_t translator) { | ||
68 | uint8_t temp_mod = get_mods(); | ||
69 | uint8_t temp_osm = get_oneshot_mods(); | ||
70 | bool is_shifted = (temp_mod | temp_osm) & MOD_MASK_SHIFT; | ||
71 | if (((temp_mod | temp_osm) & (MOD_MASK_CTRL | MOD_MASK_ALT | MOD_MASK_GUI)) == 0) { | ||
72 | if (KC_A <= keycode && keycode <= KC_Z) { | ||
73 | if (record->event.pressed) { | ||
74 | tap_unicode_glyph_nomods(translator(is_shifted, keycode)); | ||
75 | } | ||
76 | return false; | ||
77 | } else if (KC_1 <= keycode && keycode <= KC_0) { | ||
78 | if (is_shifted) { // skip shifted numbers, so that we can still use symbols etc. | ||
79 | return process_record_keymap(keycode, record); | ||
80 | } | ||
81 | if (record->event.pressed) { | ||
82 | register_unicode(translator(is_shifted, keycode)); | ||
83 | } | ||
84 | return false; | ||
85 | } else if (keycode == KC_SPACE) { | ||
86 | if (record->event.pressed) { | ||
87 | register_unicode(translator(is_shifted, keycode)); | ||
88 | } | ||
89 | return false; | ||
90 | } | ||
91 | } | ||
92 | return true; | ||
93 | } | ||
94 | |||
95 | DEFINE_UNICODE_RANGE_TRANSLATOR(unicode_range_translator_wide, 0xFF41, 0xFF21, 0xFF10, 0xFF11, 0x2003); | ||
96 | DEFINE_UNICODE_RANGE_TRANSLATOR(unicode_range_translator_script, 0x1D4EA, 0x1D4D0, 0x1D7CE, 0x1D7C1, 0x2002); | ||
97 | DEFINE_UNICODE_RANGE_TRANSLATOR(unicode_range_translator_boxes, 0x1F170, 0x1F170, '0', '1', 0x2002); | ||
98 | DEFINE_UNICODE_RANGE_TRANSLATOR(unicode_range_translator_regional, 0x1F1E6, 0x1F1E6, '0', '1', 0x2003); | ||
99 | |||
100 | DEFINE_UNICODE_LUT_TRANSLATOR(unicode_lut_translator_aussie, | ||
101 | 0x0250, // a | ||
102 | 'q', // b | ||
103 | 0x0254, // c | ||
104 | 'p', // d | ||
105 | 0x01DD, // e | ||
106 | 0x025F, // f | ||
107 | 0x0183, // g | ||
108 | 0x0265, // h | ||
109 | 0x1D09, // i | ||
110 | 0x027E, // j | ||
111 | 0x029E, // k | ||
112 | 'l', // l | ||
113 | 0x026F, // m | ||
114 | 'u', // n | ||
115 | 'o', // o | ||
116 | 'd', // p | ||
117 | 'b', // q | ||
118 | 0x0279, // r | ||
119 | 's', // s | ||
120 | 0x0287, // t | ||
121 | 'n', // u | ||
122 | 0x028C, // v | ||
123 | 0x028D, // w | ||
124 | 0x2717, // x | ||
125 | 0x028E, // y | ||
126 | 'z', // z | ||
127 | 0x0269, // 1 | ||
128 | 0x3139, // 2 | ||
129 | 0x0190, // 3 | ||
130 | 0x3123, // 4 | ||
131 | 0x03DB, // 5 | ||
132 | '9', // 6 | ||
133 | 0x3125, // 7 | ||
134 | '8', // 8 | ||
135 | '6', // 9 | ||
136 | '0' // 0 | ||
137 | ); | ||
138 | |||
139 | bool process_record_aussie(uint16_t keycode, keyrecord_t *record) { | ||
140 | bool is_shifted = (get_mods() | get_oneshot_mods()) & MOD_MASK_SHIFT; | ||
141 | if ((KC_A <= keycode) && (keycode <= KC_0)) { | ||
142 | if (record->event.pressed) { | ||
143 | if (!process_record_glyph_replacement(keycode, record, unicode_lut_translator_aussie)) { | ||
144 | tap_code16_nomods(KC_LEFT); | ||
145 | return false; | ||
146 | } | ||
147 | } | ||
148 | } else if (record->event.pressed && keycode == KC_SPACE) { | ||
149 | tap_code16_nomods(KC_SPACE); | ||
150 | tap_code16_nomods(KC_LEFT); | ||
151 | return false; | ||
152 | } else if (record->event.pressed && keycode == KC_ENTER) { | ||
153 | tap_code16_nomods(KC_END); | ||
154 | tap_code16_nomods(KC_ENTER); | ||
155 | return false; | ||
156 | } else if (record->event.pressed && keycode == KC_HOME) { | ||
157 | tap_code16_nomods(KC_END); | ||
158 | return false; | ||
159 | } else if (record->event.pressed && keycode == KC_END) { | ||
160 | tap_code16_nomods(KC_HOME); | ||
161 | return false; | ||
162 | } else if (record->event.pressed && keycode == KC_BSPC) { | ||
163 | tap_code16_nomods(KC_DELT); | ||
164 | return false; | ||
165 | } else if (record->event.pressed && keycode == KC_DELT) { | ||
166 | tap_code16_nomods(KC_BSPC); | ||
167 | return false; | ||
168 | } else if (record->event.pressed && keycode == KC_QUOT) { | ||
169 | tap_unicode_glyph_nomods(is_shifted ? 0x201E : 0x201A); | ||
170 | tap_code16_nomods(KC_LEFT); | ||
171 | return false; | ||
172 | } else if (record->event.pressed && keycode == KC_COMMA) { | ||
173 | tap_unicode_glyph_nomods(is_shifted ? '<' : 0x2018); | ||
174 | tap_code16_nomods(KC_LEFT); | ||
175 | return false; | ||
176 | } else if (record->event.pressed && keycode == KC_DOT) { | ||
177 | tap_unicode_glyph_nomods(is_shifted ? '>' : 0x02D9); | ||
178 | tap_code16_nomods(KC_LEFT); | ||
179 | return false; | ||
180 | } else if (record->event.pressed && keycode == KC_SLASH) { | ||
181 | tap_unicode_glyph_nomods(is_shifted ? 0x00BF : '/'); | ||
182 | tap_code16_nomods(KC_LEFT); | ||
183 | return false; | ||
184 | } | ||
185 | return true; | ||
186 | } | ||
187 | |||
188 | bool process_record_zalgo(uint16_t keycode, keyrecord_t *record) { | ||
189 | if ((KC_A <= keycode) && (keycode <= KC_0)) { | ||
190 | if (record->event.pressed) { | ||
191 | tap_code16_nomods(keycode); | ||
192 | |||
193 | int number = (rand() % (8 + 1 - 2)) + 2; | ||
194 | for (int index = 0; index < number; index++) { | ||
195 | uint16_t hex = (rand() % (0x036F + 1 - 0x0300)) + 0x0300; | ||
196 | register_unicode(hex); | ||
197 | } | ||
198 | |||
199 | return false; | ||
200 | } | ||
201 | } | ||
202 | return true; | ||
203 | } | ||
204 | |||
205 | bool process_record_unicode(uint16_t keycode, keyrecord_t *record) { | ||
206 | switch (keycode) { | ||
207 | case UC_FLIP: // (ノಠ痊ಠ)ノ彡┻━┻ | ||
208 | if (record->event.pressed) { | ||
209 | send_unicode_string("(ノಠ痊ಠ)ノ彡┻━┻"); | ||
210 | } | ||
211 | break; | ||
212 | |||
213 | case UC_TABL: // ┬─┬ノ( º _ ºノ) | ||
214 | if (record->event.pressed) { | ||
215 | send_unicode_string("┬─┬ノ( º _ ºノ)"); | ||
216 | } | ||
217 | break; | ||
218 | |||
219 | case UC_SHRG: // ¯\_(ツ)_/¯ | ||
220 | if (record->event.pressed) { | ||
221 | send_unicode_string("¯\\_(ツ)_/¯"); | ||
222 | } | ||
223 | break; | ||
224 | |||
225 | case UC_DISA: // ಠ_ಠ | ||
226 | if (record->event.pressed) { | ||
227 | send_unicode_string("ಠ_ಠ"); | ||
228 | } | ||
229 | break; | ||
230 | |||
231 | case UC_IRNY: // ⸮ | ||
232 | if (record->event.pressed) { | ||
233 | register_unicode(0x2E2E); | ||
234 | } | ||
235 | break; | ||
236 | case UC_CLUE: // ‽ | ||
237 | if (record->event.pressed) { | ||
238 | register_unicode(0x203D); | ||
239 | } | ||
240 | break; | ||
241 | case KC_NOMODE ... KC_ZALGO: | ||
242 | if (record->event.pressed) { | ||
243 | if (typing_mode != keycode) { | ||
244 | typing_mode = keycode; | ||
245 | } else { | ||
246 | typing_mode = 0; | ||
247 | } | ||
248 | } | ||
249 | break; | ||
250 | |||
251 | break; | ||
252 | } | ||
253 | if (((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) && record->tap.count) { | ||
254 | keycode &= 0xFF; | ||
255 | } | ||
256 | |||
257 | if (typing_mode == KC_WIDE) { | ||
258 | if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) { | ||
259 | return process_record_glyph_replacement(keycode, record, unicode_range_translator_wide); | ||
260 | } | ||
261 | } else if (typing_mode == KC_SCRIPT) { | ||
262 | if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) { | ||
263 | return process_record_glyph_replacement(keycode, record, unicode_range_translator_script); | ||
264 | } | ||
265 | } else if (typing_mode == KC_BLOCKS) { | ||
266 | if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) { | ||
267 | return process_record_glyph_replacement(keycode, record, unicode_range_translator_boxes); | ||
268 | } | ||
269 | } else if (typing_mode == KC_REGIONAL) { | ||
270 | if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) { | ||
271 | if (!process_record_glyph_replacement(keycode, record, unicode_range_translator_regional)) { | ||
272 | wait_us(500); | ||
273 | tap_unicode_glyph_nomods(0x200C); | ||
274 | return false; | ||
275 | } | ||
276 | } | ||
277 | } else if (typing_mode == KC_AUSSIE) { | ||
278 | return process_record_aussie(keycode, record); | ||
279 | } else if (typing_mode == KC_ZALGO) { | ||
280 | return process_record_zalgo(keycode, record); | ||
281 | } | ||
282 | return process_unicode_common(keycode, record); | ||
283 | } | ||
284 | |||
285 | void matrix_init_unicode(void) { | ||
286 | unicode_input_mode_init(); | ||
287 | } | ||