diff options
author | Joel Challis <git@zvecr.com> | 2021-08-18 00:18:58 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-18 00:18:58 +0100 |
commit | b8e913c8db73ebf890e4604ee41991a34354a600 (patch) | |
tree | 258035f8fda9f83f08a309f6cd608b9c61476678 /tmk_core/common | |
parent | 96e2b13d1de227cdc2b918fb0292bd832d346a25 (diff) | |
download | qmk_firmware-b8e913c8db73ebf890e4604ee41991a34354a600.tar.gz qmk_firmware-b8e913c8db73ebf890e4604ee41991a34354a600.zip |
Migrate platform independent code from tmk_core -> quantum (#13673)
* Migrate action|keyboard|keycode|eeconfig from tmk_core -> quantum
Diffstat (limited to 'tmk_core/common')
-rw-r--r-- | tmk_core/common/action.c | 1126 | ||||
-rw-r--r-- | tmk_core/common/action.h | 132 | ||||
-rw-r--r-- | tmk_core/common/action_code.h | 308 | ||||
-rw-r--r-- | tmk_core/common/action_layer.c | 279 | ||||
-rw-r--r-- | tmk_core/common/action_layer.h | 147 | ||||
-rw-r--r-- | tmk_core/common/action_macro.c | 93 | ||||
-rw-r--r-- | tmk_core/common/action_macro.h | 123 | ||||
-rw-r--r-- | tmk_core/common/action_tapping.c | 456 | ||||
-rw-r--r-- | tmk_core/common/action_tapping.h | 42 | ||||
-rw-r--r-- | tmk_core/common/action_util.c | 455 | ||||
-rw-r--r-- | tmk_core/common/action_util.h | 105 | ||||
-rw-r--r-- | tmk_core/common/eeconfig.c | 211 | ||||
-rw-r--r-- | tmk_core/common/eeconfig.h | 113 | ||||
-rw-r--r-- | tmk_core/common/keyboard.c | 565 | ||||
-rw-r--r-- | tmk_core/common/keyboard.h | 90 | ||||
-rw-r--r-- | tmk_core/common/keycode.h | 560 |
16 files changed, 0 insertions, 4805 deletions
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c deleted file mode 100644 index d19fd2a04..000000000 --- a/tmk_core/common/action.c +++ /dev/null | |||
@@ -1,1126 +0,0 @@ | |||
1 | /* | ||
2 | Copyright 2012,2013 Jun Wako <wakojun@gmail.com> | ||
3 | |||
4 | This program is free software: you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation, either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | #include "host.h" | ||
18 | #include "keycode.h" | ||
19 | #include "keyboard.h" | ||
20 | #include "mousekey.h" | ||
21 | #include "command.h" | ||
22 | #include "led.h" | ||
23 | #include "action_layer.h" | ||
24 | #include "action_tapping.h" | ||
25 | #include "action_macro.h" | ||
26 | #include "action_util.h" | ||
27 | #include "action.h" | ||
28 | #include "wait.h" | ||
29 | |||
30 | #ifdef BACKLIGHT_ENABLE | ||
31 | # include "backlight.h" | ||
32 | #endif | ||
33 | |||
34 | #ifdef DEBUG_ACTION | ||
35 | # include "debug.h" | ||
36 | #else | ||
37 | # include "nodebug.h" | ||
38 | #endif | ||
39 | |||
40 | #ifdef POINTING_DEVICE_ENABLE | ||
41 | # include "pointing_device.h" | ||
42 | #endif | ||
43 | |||
44 | int tp_buttons; | ||
45 | |||
46 | #if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) | ||
47 | int retro_tapping_counter = 0; | ||
48 | #endif | ||
49 | |||
50 | #ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY | ||
51 | __attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { return false; } | ||
52 | #endif | ||
53 | |||
54 | #ifdef RETRO_TAPPING_PER_KEY | ||
55 | __attribute__((weak)) bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) { return false; } | ||
56 | #endif | ||
57 | |||
58 | __attribute__((weak)) bool pre_process_record_quantum(keyrecord_t *record) { return true; } | ||
59 | |||
60 | #ifndef TAP_CODE_DELAY | ||
61 | # define TAP_CODE_DELAY 0 | ||
62 | #endif | ||
63 | #ifndef TAP_HOLD_CAPS_DELAY | ||
64 | # define TAP_HOLD_CAPS_DELAY 80 | ||
65 | #endif | ||
66 | /** \brief Called to execute an action. | ||
67 | * | ||
68 | * FIXME: Needs documentation. | ||
69 | */ | ||
70 | void action_exec(keyevent_t event) { | ||
71 | if (!IS_NOEVENT(event)) { | ||
72 | dprint("\n---- action_exec: start -----\n"); | ||
73 | dprint("EVENT: "); | ||
74 | debug_event(event); | ||
75 | dprintln(); | ||
76 | #if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) | ||
77 | retro_tapping_counter++; | ||
78 | #endif | ||
79 | } | ||
80 | |||
81 | if (event.pressed) { | ||
82 | // clear the potential weak mods left by previously pressed keys | ||
83 | clear_weak_mods(); | ||
84 | } | ||
85 | |||
86 | #ifdef SWAP_HANDS_ENABLE | ||
87 | if (!IS_NOEVENT(event)) { | ||
88 | process_hand_swap(&event); | ||
89 | } | ||
90 | #endif | ||
91 | |||
92 | keyrecord_t record = {.event = event}; | ||
93 | |||
94 | #ifndef NO_ACTION_ONESHOT | ||
95 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
96 | if (has_oneshot_layer_timed_out()) { | ||
97 | clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); | ||
98 | } | ||
99 | if (has_oneshot_mods_timed_out()) { | ||
100 | clear_oneshot_mods(); | ||
101 | } | ||
102 | # ifdef SWAP_HANDS_ENABLE | ||
103 | if (has_oneshot_swaphands_timed_out()) { | ||
104 | clear_oneshot_swaphands(); | ||
105 | } | ||
106 | # endif | ||
107 | # endif | ||
108 | #endif | ||
109 | |||
110 | #ifndef NO_ACTION_TAPPING | ||
111 | if (IS_NOEVENT(record.event) || pre_process_record_quantum(&record)) { | ||
112 | action_tapping_process(record); | ||
113 | } | ||
114 | #else | ||
115 | if (IS_NOEVENT(record.event) || pre_process_record_quantum(&record)) { | ||
116 | process_record(&record); | ||
117 | } | ||
118 | if (!IS_NOEVENT(record.event)) { | ||
119 | dprint("processed: "); | ||
120 | debug_record(record); | ||
121 | dprintln(); | ||
122 | } | ||
123 | #endif | ||
124 | } | ||
125 | |||
126 | #ifdef SWAP_HANDS_ENABLE | ||
127 | bool swap_hands = false; | ||
128 | bool swap_held = false; | ||
129 | |||
130 | /** \brief Process Hand Swap | ||
131 | * | ||
132 | * FIXME: Needs documentation. | ||
133 | */ | ||
134 | void process_hand_swap(keyevent_t *event) { | ||
135 | static swap_state_row_t swap_state[MATRIX_ROWS]; | ||
136 | |||
137 | keypos_t pos = event->key; | ||
138 | swap_state_row_t col_bit = (swap_state_row_t)1 << pos.col; | ||
139 | bool do_swap = event->pressed ? swap_hands : swap_state[pos.row] & (col_bit); | ||
140 | |||
141 | if (do_swap) { | ||
142 | event->key.row = pgm_read_byte(&hand_swap_config[pos.row][pos.col].row); | ||
143 | event->key.col = pgm_read_byte(&hand_swap_config[pos.row][pos.col].col); | ||
144 | swap_state[pos.row] |= col_bit; | ||
145 | } else { | ||
146 | swap_state[pos.row] &= ~(col_bit); | ||
147 | } | ||
148 | } | ||
149 | #endif | ||
150 | |||
151 | #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) | ||
152 | bool disable_action_cache = false; | ||
153 | |||
154 | void process_record_nocache(keyrecord_t *record) { | ||
155 | disable_action_cache = true; | ||
156 | process_record(record); | ||
157 | disable_action_cache = false; | ||
158 | } | ||
159 | #else | ||
160 | void process_record_nocache(keyrecord_t *record) { process_record(record); } | ||
161 | #endif | ||
162 | |||
163 | __attribute__((weak)) bool process_record_quantum(keyrecord_t *record) { return true; } | ||
164 | |||
165 | __attribute__((weak)) void post_process_record_quantum(keyrecord_t *record) {} | ||
166 | |||
167 | #ifndef NO_ACTION_TAPPING | ||
168 | /** \brief Allows for handling tap-hold actions immediately instead of waiting for TAPPING_TERM or another keypress. | ||
169 | * | ||
170 | * FIXME: Needs documentation. | ||
171 | */ | ||
172 | void process_record_tap_hint(keyrecord_t *record) { | ||
173 | action_t action = layer_switch_get_action(record->event.key); | ||
174 | |||
175 | switch (action.kind.id) { | ||
176 | # ifdef SWAP_HANDS_ENABLE | ||
177 | case ACT_SWAP_HANDS: | ||
178 | switch (action.swap.code) { | ||
179 | case OP_SH_ONESHOT: | ||
180 | break; | ||
181 | case OP_SH_TAP_TOGGLE: | ||
182 | default: | ||
183 | swap_hands = !swap_hands; | ||
184 | swap_held = true; | ||
185 | } | ||
186 | break; | ||
187 | # endif | ||
188 | } | ||
189 | } | ||
190 | #endif | ||
191 | |||
192 | /** \brief Take a key event (key press or key release) and processes it. | ||
193 | * | ||
194 | * FIXME: Needs documentation. | ||
195 | */ | ||
196 | void process_record(keyrecord_t *record) { | ||
197 | if (IS_NOEVENT(record->event)) { | ||
198 | return; | ||
199 | } | ||
200 | |||
201 | if (!process_record_quantum(record)) { | ||
202 | #ifndef NO_ACTION_ONESHOT | ||
203 | if (is_oneshot_layer_active() && record->event.pressed) { | ||
204 | clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); | ||
205 | } | ||
206 | #endif | ||
207 | return; | ||
208 | } | ||
209 | |||
210 | process_record_handler(record); | ||
211 | post_process_record_quantum(record); | ||
212 | } | ||
213 | |||
214 | void process_record_handler(keyrecord_t *record) { | ||
215 | #ifdef COMBO_ENABLE | ||
216 | action_t action; | ||
217 | if (record->keycode) { | ||
218 | action = action_for_keycode(record->keycode); | ||
219 | } else { | ||
220 | action = store_or_get_action(record->event.pressed, record->event.key); | ||
221 | } | ||
222 | #else | ||
223 | action_t action = store_or_get_action(record->event.pressed, record->event.key); | ||
224 | #endif | ||
225 | dprint("ACTION: "); | ||
226 | debug_action(action); | ||
227 | #ifndef NO_ACTION_LAYER | ||
228 | dprint(" layer_state: "); | ||
229 | layer_debug(); | ||
230 | dprint(" default_layer_state: "); | ||
231 | default_layer_debug(); | ||
232 | #endif | ||
233 | dprintln(); | ||
234 | |||
235 | process_action(record, action); | ||
236 | } | ||
237 | |||
238 | #if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE) | ||
239 | void register_button(bool pressed, enum mouse_buttons button) { | ||
240 | # ifdef PS2_MOUSE_ENABLE | ||
241 | tp_buttons = pressed ? tp_buttons | button : tp_buttons & ~button; | ||
242 | # endif | ||
243 | # ifdef POINTING_DEVICE_ENABLE | ||
244 | report_mouse_t currentReport = pointing_device_get_report(); | ||
245 | currentReport.buttons = pressed ? currentReport.buttons | button : currentReport.buttons & ~button; | ||
246 | pointing_device_set_report(currentReport); | ||
247 | # endif | ||
248 | } | ||
249 | #endif | ||
250 | |||
251 | /** \brief Take an action and processes it. | ||
252 | * | ||
253 | * FIXME: Needs documentation. | ||
254 | */ | ||
255 | void process_action(keyrecord_t *record, action_t action) { | ||
256 | keyevent_t event = record->event; | ||
257 | #ifndef NO_ACTION_TAPPING | ||
258 | uint8_t tap_count = record->tap.count; | ||
259 | #endif | ||
260 | |||
261 | #ifndef NO_ACTION_ONESHOT | ||
262 | bool do_release_oneshot = false; | ||
263 | // notice we only clear the one shot layer if the pressed key is not a modifier. | ||
264 | if (is_oneshot_layer_active() && event.pressed && (action.kind.id == ACT_USAGE || !IS_MOD(action.key.code)) | ||
265 | # ifdef SWAP_HANDS_ENABLE | ||
266 | && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT) | ||
267 | # endif | ||
268 | ) { | ||
269 | clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); | ||
270 | do_release_oneshot = !is_oneshot_layer_active(); | ||
271 | } | ||
272 | #endif | ||
273 | |||
274 | switch (action.kind.id) { | ||
275 | /* Key and Mods */ | ||
276 | case ACT_LMODS: | ||
277 | case ACT_RMODS: { | ||
278 | uint8_t mods = (action.kind.id == ACT_LMODS) ? action.key.mods : action.key.mods << 4; | ||
279 | if (event.pressed) { | ||
280 | if (mods) { | ||
281 | if (IS_MOD(action.key.code) || action.key.code == KC_NO) { | ||
282 | // e.g. LSFT(KC_LGUI): we don't want the LSFT to be weak as it would make it useless. | ||
283 | // This also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT). | ||
284 | // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO). | ||
285 | add_mods(mods); | ||
286 | } else { | ||
287 | add_weak_mods(mods); | ||
288 | } | ||
289 | send_keyboard_report(); | ||
290 | } | ||
291 | register_code(action.key.code); | ||
292 | } else { | ||
293 | unregister_code(action.key.code); | ||
294 | if (mods) { | ||
295 | if (IS_MOD(action.key.code) || action.key.code == KC_NO) { | ||
296 | del_mods(mods); | ||
297 | } else { | ||
298 | del_weak_mods(mods); | ||
299 | } | ||
300 | send_keyboard_report(); | ||
301 | } | ||
302 | } | ||
303 | } break; | ||
304 | #ifndef NO_ACTION_TAPPING | ||
305 | case ACT_LMODS_TAP: | ||
306 | case ACT_RMODS_TAP: { | ||
307 | uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ? action.key.mods : action.key.mods << 4; | ||
308 | switch (action.layer_tap.code) { | ||
309 | # ifndef NO_ACTION_ONESHOT | ||
310 | case MODS_ONESHOT: | ||
311 | // Oneshot modifier | ||
312 | if (event.pressed) { | ||
313 | if (tap_count == 0) { | ||
314 | dprint("MODS_TAP: Oneshot: 0\n"); | ||
315 | register_mods(mods | get_oneshot_mods()); | ||
316 | } else if (tap_count == 1) { | ||
317 | dprint("MODS_TAP: Oneshot: start\n"); | ||
318 | set_oneshot_mods(mods | get_oneshot_mods()); | ||
319 | # if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 | ||
320 | } else if (tap_count == ONESHOT_TAP_TOGGLE) { | ||
321 | dprint("MODS_TAP: Toggling oneshot"); | ||
322 | clear_oneshot_mods(); | ||
323 | set_oneshot_locked_mods(mods); | ||
324 | register_mods(mods); | ||
325 | # endif | ||
326 | } else { | ||
327 | register_mods(mods | get_oneshot_mods()); | ||
328 | } | ||
329 | } else { | ||
330 | if (tap_count == 0) { | ||
331 | clear_oneshot_mods(); | ||
332 | unregister_mods(mods); | ||
333 | } else if (tap_count == 1) { | ||
334 | // Retain Oneshot mods | ||
335 | # if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 | ||
336 | if (mods & get_mods()) { | ||
337 | clear_oneshot_locked_mods(); | ||
338 | clear_oneshot_mods(); | ||
339 | unregister_mods(mods); | ||
340 | } | ||
341 | } else if (tap_count == ONESHOT_TAP_TOGGLE) { | ||
342 | // Toggle Oneshot Layer | ||
343 | # endif | ||
344 | } else { | ||
345 | clear_oneshot_mods(); | ||
346 | unregister_mods(mods); | ||
347 | } | ||
348 | } | ||
349 | break; | ||
350 | # endif | ||
351 | case MODS_TAP_TOGGLE: | ||
352 | if (event.pressed) { | ||
353 | if (tap_count <= TAPPING_TOGGLE) { | ||
354 | register_mods(mods); | ||
355 | } | ||
356 | } else { | ||
357 | if (tap_count < TAPPING_TOGGLE) { | ||
358 | unregister_mods(mods); | ||
359 | } | ||
360 | } | ||
361 | break; | ||
362 | default: | ||
363 | if (event.pressed) { | ||
364 | if (tap_count > 0) { | ||
365 | # if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY) | ||
366 | if ( | ||
367 | # ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY | ||
368 | !get_ignore_mod_tap_interrupt(get_event_keycode(record->event, false), record) && | ||
369 | # endif | ||
370 | record->tap.interrupted) { | ||
371 | dprint("mods_tap: tap: cancel: add_mods\n"); | ||
372 | // ad hoc: set 0 to cancel tap | ||
373 | record->tap.count = 0; | ||
374 | register_mods(mods); | ||
375 | } else | ||
376 | # endif | ||
377 | { | ||
378 | dprint("MODS_TAP: Tap: register_code\n"); | ||
379 | register_code(action.key.code); | ||
380 | } | ||
381 | } else { | ||
382 | dprint("MODS_TAP: No tap: add_mods\n"); | ||
383 | register_mods(mods); | ||
384 | } | ||
385 | } else { | ||
386 | if (tap_count > 0) { | ||
387 | dprint("MODS_TAP: Tap: unregister_code\n"); | ||
388 | if (action.layer_tap.code == KC_CAPS) { | ||
389 | wait_ms(TAP_HOLD_CAPS_DELAY); | ||
390 | } else { | ||
391 | wait_ms(TAP_CODE_DELAY); | ||
392 | } | ||
393 | unregister_code(action.key.code); | ||
394 | } else { | ||
395 | dprint("MODS_TAP: No tap: add_mods\n"); | ||
396 | unregister_mods(mods); | ||
397 | } | ||
398 | } | ||
399 | break; | ||
400 | } | ||
401 | } break; | ||
402 | #endif | ||
403 | #ifdef EXTRAKEY_ENABLE | ||
404 | /* other HID usage */ | ||
405 | case ACT_USAGE: | ||
406 | switch (action.usage.page) { | ||
407 | case PAGE_SYSTEM: | ||
408 | if (event.pressed) { | ||
409 | host_system_send(action.usage.code); | ||
410 | } else { | ||
411 | host_system_send(0); | ||
412 | } | ||
413 | break; | ||
414 | case PAGE_CONSUMER: | ||
415 | if (event.pressed) { | ||
416 | host_consumer_send(action.usage.code); | ||
417 | } else { | ||
418 | host_consumer_send(0); | ||
419 | } | ||
420 | break; | ||
421 | } | ||
422 | break; | ||
423 | #endif | ||
424 | #ifdef MOUSEKEY_ENABLE | ||
425 | /* Mouse key */ | ||
426 | case ACT_MOUSEKEY: | ||
427 | if (event.pressed) { | ||
428 | mousekey_on(action.key.code); | ||
429 | } else { | ||
430 | mousekey_off(action.key.code); | ||
431 | } | ||
432 | switch (action.key.code) { | ||
433 | # if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE) | ||
434 | # ifdef POINTING_DEVICE_ENABLE | ||
435 | case KC_MS_BTN1 ... KC_MS_BTN8: | ||
436 | # else | ||
437 | case KC_MS_BTN1 ... KC_MS_BTN3: | ||
438 | # endif | ||
439 | register_button(event.pressed, MOUSE_BTN_MASK(action.key.code - KC_MS_BTN1)); | ||
440 | break; | ||
441 | # endif | ||
442 | default: | ||
443 | mousekey_send(); | ||
444 | break; | ||
445 | } | ||
446 | break; | ||
447 | #endif | ||
448 | #ifndef NO_ACTION_LAYER | ||
449 | case ACT_LAYER: | ||
450 | if (action.layer_bitop.on == 0) { | ||
451 | /* Default Layer Bitwise Operation */ | ||
452 | if (!event.pressed) { | ||
453 | uint8_t shift = action.layer_bitop.part * 4; | ||
454 | layer_state_t bits = ((layer_state_t)action.layer_bitop.bits) << shift; | ||
455 | layer_state_t mask = (action.layer_bitop.xbit) ? ~(((layer_state_t)0xf) << shift) : 0; | ||
456 | switch (action.layer_bitop.op) { | ||
457 | case OP_BIT_AND: | ||
458 | default_layer_and(bits | mask); | ||
459 | break; | ||
460 | case OP_BIT_OR: | ||
461 | default_layer_or(bits | mask); | ||
462 | break; | ||
463 | case OP_BIT_XOR: | ||
464 | default_layer_xor(bits | mask); | ||
465 | break; | ||
466 | case OP_BIT_SET: | ||
467 | default_layer_set(bits | mask); | ||
468 | break; | ||
469 | } | ||
470 | } | ||
471 | } else { | ||
472 | /* Layer Bitwise Operation */ | ||
473 | if (event.pressed ? (action.layer_bitop.on & ON_PRESS) : (action.layer_bitop.on & ON_RELEASE)) { | ||
474 | uint8_t shift = action.layer_bitop.part * 4; | ||
475 | layer_state_t bits = ((layer_state_t)action.layer_bitop.bits) << shift; | ||
476 | layer_state_t mask = (action.layer_bitop.xbit) ? ~(((layer_state_t)0xf) << shift) : 0; | ||
477 | switch (action.layer_bitop.op) { | ||
478 | case OP_BIT_AND: | ||
479 | layer_and(bits | mask); | ||
480 | break; | ||
481 | case OP_BIT_OR: | ||
482 | layer_or(bits | mask); | ||
483 | break; | ||
484 | case OP_BIT_XOR: | ||
485 | layer_xor(bits | mask); | ||
486 | break; | ||
487 | case OP_BIT_SET: | ||
488 | layer_state_set(bits | mask); | ||
489 | break; | ||
490 | } | ||
491 | } | ||
492 | } | ||
493 | break; | ||
494 | case ACT_LAYER_MODS: | ||
495 | if (event.pressed) { | ||
496 | layer_on(action.layer_mods.layer); | ||
497 | register_mods(action.layer_mods.mods); | ||
498 | } else { | ||
499 | unregister_mods(action.layer_mods.mods); | ||
500 | layer_off(action.layer_mods.layer); | ||
501 | } | ||
502 | break; | ||
503 | # ifndef NO_ACTION_TAPPING | ||
504 | case ACT_LAYER_TAP: | ||
505 | case ACT_LAYER_TAP_EXT: | ||
506 | switch (action.layer_tap.code) { | ||
507 | case OP_TAP_TOGGLE: | ||
508 | /* tap toggle */ | ||
509 | if (event.pressed) { | ||
510 | if (tap_count < TAPPING_TOGGLE) { | ||
511 | layer_invert(action.layer_tap.val); | ||
512 | } | ||
513 | } else { | ||
514 | if (tap_count <= TAPPING_TOGGLE) { | ||
515 | layer_invert(action.layer_tap.val); | ||
516 | } | ||
517 | } | ||
518 | break; | ||
519 | case OP_ON_OFF: | ||
520 | event.pressed ? layer_on(action.layer_tap.val) : layer_off(action.layer_tap.val); | ||
521 | break; | ||
522 | case OP_OFF_ON: | ||
523 | event.pressed ? layer_off(action.layer_tap.val) : layer_on(action.layer_tap.val); | ||
524 | break; | ||
525 | case OP_SET_CLEAR: | ||
526 | event.pressed ? layer_move(action.layer_tap.val) : layer_clear(); | ||
527 | break; | ||
528 | # ifndef NO_ACTION_ONESHOT | ||
529 | case OP_ONESHOT: | ||
530 | // Oneshot modifier | ||
531 | # if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 | ||
532 | do_release_oneshot = false; | ||
533 | if (event.pressed) { | ||
534 | del_mods(get_oneshot_locked_mods()); | ||
535 | if (get_oneshot_layer_state() == ONESHOT_TOGGLED) { | ||
536 | reset_oneshot_layer(); | ||
537 | layer_off(action.layer_tap.val); | ||
538 | break; | ||
539 | } else if (tap_count < ONESHOT_TAP_TOGGLE) { | ||
540 | layer_on(action.layer_tap.val); | ||
541 | set_oneshot_layer(action.layer_tap.val, ONESHOT_START); | ||
542 | } | ||
543 | } else { | ||
544 | add_mods(get_oneshot_locked_mods()); | ||
545 | if (tap_count >= ONESHOT_TAP_TOGGLE) { | ||
546 | reset_oneshot_layer(); | ||
547 | clear_oneshot_locked_mods(); | ||
548 | set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED); | ||
549 | } else { | ||
550 | clear_oneshot_layer_state(ONESHOT_PRESSED); | ||
551 | } | ||
552 | } | ||
553 | # else | ||
554 | if (event.pressed) { | ||
555 | layer_on(action.layer_tap.val); | ||
556 | set_oneshot_layer(action.layer_tap.val, ONESHOT_START); | ||
557 | } else { | ||
558 | clear_oneshot_layer_state(ONESHOT_PRESSED); | ||
559 | if (tap_count > 1) { | ||
560 | clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); | ||
561 | } | ||
562 | } | ||
563 | # endif | ||
564 | break; | ||
565 | # endif | ||
566 | default: | ||
567 | /* tap key */ | ||
568 | if (event.pressed) { | ||
569 | if (tap_count > 0) { | ||
570 | dprint("KEYMAP_TAP_KEY: Tap: register_code\n"); | ||
571 | register_code(action.layer_tap.code); | ||
572 | } else { | ||
573 | dprint("KEYMAP_TAP_KEY: No tap: On on press\n"); | ||
574 | layer_on(action.layer_tap.val); | ||
575 | } | ||
576 | } else { | ||
577 | if (tap_count > 0) { | ||
578 | dprint("KEYMAP_TAP_KEY: Tap: unregister_code\n"); | ||
579 | if (action.layer_tap.code == KC_CAPS) { | ||
580 | wait_ms(TAP_HOLD_CAPS_DELAY); | ||
581 | } else { | ||
582 | wait_ms(TAP_CODE_DELAY); | ||
583 | } | ||
584 | unregister_code(action.layer_tap.code); | ||
585 | } else { | ||
586 | dprint("KEYMAP_TAP_KEY: No tap: Off on release\n"); | ||
587 | layer_off(action.layer_tap.val); | ||
588 | } | ||
589 | } | ||
590 | break; | ||
591 | } | ||
592 | break; | ||
593 | # endif | ||
594 | #endif | ||
595 | /* Extentions */ | ||
596 | #ifndef NO_ACTION_MACRO | ||
597 | case ACT_MACRO: | ||
598 | action_macro_play(action_get_macro(record, action.func.id, action.func.opt)); | ||
599 | break; | ||
600 | #endif | ||
601 | #ifdef SWAP_HANDS_ENABLE | ||
602 | case ACT_SWAP_HANDS: | ||
603 | switch (action.swap.code) { | ||
604 | case OP_SH_TOGGLE: | ||
605 | if (event.pressed) { | ||
606 | swap_hands = !swap_hands; | ||
607 | } | ||
608 | break; | ||
609 | case OP_SH_ON_OFF: | ||
610 | swap_hands = event.pressed; | ||
611 | break; | ||
612 | case OP_SH_OFF_ON: | ||
613 | swap_hands = !event.pressed; | ||
614 | break; | ||
615 | case OP_SH_ON: | ||
616 | if (!event.pressed) { | ||
617 | swap_hands = true; | ||
618 | } | ||
619 | break; | ||
620 | case OP_SH_OFF: | ||
621 | if (!event.pressed) { | ||
622 | swap_hands = false; | ||
623 | } | ||
624 | break; | ||
625 | # ifndef NO_ACTION_ONESHOT | ||
626 | case OP_SH_ONESHOT: | ||
627 | if (event.pressed) { | ||
628 | set_oneshot_swaphands(); | ||
629 | } else { | ||
630 | release_oneshot_swaphands(); | ||
631 | } | ||
632 | break; | ||
633 | # endif | ||
634 | |||
635 | # ifndef NO_ACTION_TAPPING | ||
636 | case OP_SH_TAP_TOGGLE: | ||
637 | /* tap toggle */ | ||
638 | |||
639 | if (event.pressed) { | ||
640 | if (swap_held) { | ||
641 | swap_held = false; | ||
642 | } else { | ||
643 | swap_hands = !swap_hands; | ||
644 | } | ||
645 | } else { | ||
646 | if (tap_count < TAPPING_TOGGLE) { | ||
647 | swap_hands = !swap_hands; | ||
648 | } | ||
649 | } | ||
650 | break; | ||
651 | default: | ||
652 | /* tap key */ | ||
653 | if (tap_count > 0) { | ||
654 | if (swap_held) { | ||
655 | swap_hands = !swap_hands; // undo hold set up in _tap_hint | ||
656 | swap_held = false; | ||
657 | } | ||
658 | if (event.pressed) { | ||
659 | register_code(action.swap.code); | ||
660 | } else { | ||
661 | wait_ms(TAP_CODE_DELAY); | ||
662 | unregister_code(action.swap.code); | ||
663 | *record = (keyrecord_t){}; // hack: reset tap mode | ||
664 | } | ||
665 | } else { | ||
666 | if (swap_held && !event.pressed) { | ||
667 | swap_hands = !swap_hands; // undo hold set up in _tap_hint | ||
668 | swap_held = false; | ||
669 | } | ||
670 | } | ||
671 | # endif | ||
672 | } | ||
673 | #endif | ||
674 | #ifndef NO_ACTION_FUNCTION | ||
675 | case ACT_FUNCTION: | ||
676 | action_function(record, action.func.id, action.func.opt); | ||
677 | break; | ||
678 | #endif | ||
679 | default: | ||
680 | break; | ||
681 | } | ||
682 | |||
683 | #ifndef NO_ACTION_LAYER | ||
684 | // if this event is a layer action, update the leds | ||
685 | switch (action.kind.id) { | ||
686 | case ACT_LAYER: | ||
687 | case ACT_LAYER_MODS: | ||
688 | # ifndef NO_ACTION_TAPPING | ||
689 | case ACT_LAYER_TAP: | ||
690 | case ACT_LAYER_TAP_EXT: | ||
691 | # endif | ||
692 | led_set(host_keyboard_leds()); | ||
693 | break; | ||
694 | default: | ||
695 | break; | ||
696 | } | ||
697 | #endif | ||
698 | |||
699 | #ifndef NO_ACTION_TAPPING | ||
700 | # if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) | ||
701 | if (!is_tap_action(action)) { | ||
702 | retro_tapping_counter = 0; | ||
703 | } else { | ||
704 | if (event.pressed) { | ||
705 | if (tap_count > 0) { | ||
706 | retro_tapping_counter = 0; | ||
707 | } | ||
708 | } else { | ||
709 | if (tap_count > 0) { | ||
710 | retro_tapping_counter = 0; | ||
711 | } else { | ||
712 | if ( | ||
713 | # ifdef RETRO_TAPPING_PER_KEY | ||
714 | get_retro_tapping(get_event_keycode(record->event, false), record) && | ||
715 | # endif | ||
716 | retro_tapping_counter == 2) { | ||
717 | tap_code(action.layer_tap.code); | ||
718 | } | ||
719 | retro_tapping_counter = 0; | ||
720 | } | ||
721 | } | ||
722 | } | ||
723 | # endif | ||
724 | #endif | ||
725 | |||
726 | #ifdef SWAP_HANDS_ENABLE | ||
727 | # ifndef NO_ACTION_ONESHOT | ||
728 | if (event.pressed && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT)) { | ||
729 | use_oneshot_swaphands(); | ||
730 | } | ||
731 | # endif | ||
732 | #endif | ||
733 | |||
734 | #ifndef NO_ACTION_ONESHOT | ||
735 | /* Because we switch layers after a oneshot event, we need to release the | ||
736 | * key before we leave the layer or no key up event will be generated. | ||
737 | */ | ||
738 | if (do_release_oneshot && !(get_oneshot_layer_state() & ONESHOT_PRESSED)) { | ||
739 | record->event.pressed = false; | ||
740 | layer_on(get_oneshot_layer()); | ||
741 | process_record(record); | ||
742 | layer_off(get_oneshot_layer()); | ||
743 | } | ||
744 | #endif | ||
745 | } | ||
746 | |||
747 | /** \brief Utilities for actions. (FIXME: Needs better description) | ||
748 | * | ||
749 | * FIXME: Needs documentation. | ||
750 | */ | ||
751 | void register_code(uint8_t code) { | ||
752 | if (code == KC_NO) { | ||
753 | return; | ||
754 | } | ||
755 | #ifdef LOCKING_SUPPORT_ENABLE | ||
756 | else if (KC_LOCKING_CAPS == code) { | ||
757 | # ifdef LOCKING_RESYNC_ENABLE | ||
758 | // Resync: ignore if caps lock already is on | ||
759 | if (host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK)) return; | ||
760 | # endif | ||
761 | add_key(KC_CAPSLOCK); | ||
762 | send_keyboard_report(); | ||
763 | wait_ms(100); | ||
764 | del_key(KC_CAPSLOCK); | ||
765 | send_keyboard_report(); | ||
766 | } | ||
767 | |||
768 | else if (KC_LOCKING_NUM == code) { | ||
769 | # ifdef LOCKING_RESYNC_ENABLE | ||
770 | if (host_keyboard_leds() & (1 << USB_LED_NUM_LOCK)) return; | ||
771 | # endif | ||
772 | add_key(KC_NUMLOCK); | ||
773 | send_keyboard_report(); | ||
774 | wait_ms(100); | ||
775 | del_key(KC_NUMLOCK); | ||
776 | send_keyboard_report(); | ||
777 | } | ||
778 | |||
779 | else if (KC_LOCKING_SCROLL == code) { | ||
780 | # ifdef LOCKING_RESYNC_ENABLE | ||
781 | if (host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK)) return; | ||
782 | # endif | ||
783 | add_key(KC_SCROLLLOCK); | ||
784 | send_keyboard_report(); | ||
785 | wait_ms(100); | ||
786 | del_key(KC_SCROLLLOCK); | ||
787 | send_keyboard_report(); | ||
788 | } | ||
789 | #endif | ||
790 | |||
791 | else if IS_KEY (code) { | ||
792 | // TODO: should push command_proc out of this block? | ||
793 | if (command_proc(code)) return; | ||
794 | |||
795 | #ifndef NO_ACTION_ONESHOT | ||
796 | /* TODO: remove | ||
797 | if (oneshot_state.mods && !oneshot_state.disabled) { | ||
798 | uint8_t tmp_mods = get_mods(); | ||
799 | add_mods(oneshot_state.mods); | ||
800 | |||
801 | add_key(code); | ||
802 | send_keyboard_report(); | ||
803 | |||
804 | set_mods(tmp_mods); | ||
805 | send_keyboard_report(); | ||
806 | oneshot_cancel(); | ||
807 | } else | ||
808 | */ | ||
809 | #endif | ||
810 | { | ||
811 | // Force a new key press if the key is already pressed | ||
812 | // without this, keys with the same keycode, but different | ||
813 | // modifiers will be reported incorrectly, see issue #1708 | ||
814 | if (is_key_pressed(keyboard_report, code)) { | ||
815 | del_key(code); | ||
816 | send_keyboard_report(); | ||
817 | } | ||
818 | add_key(code); | ||
819 | send_keyboard_report(); | ||
820 | } | ||
821 | } else if IS_MOD (code) { | ||
822 | add_mods(MOD_BIT(code)); | ||
823 | send_keyboard_report(); | ||
824 | } | ||
825 | #ifdef EXTRAKEY_ENABLE | ||
826 | else if IS_SYSTEM (code) { | ||
827 | host_system_send(KEYCODE2SYSTEM(code)); | ||
828 | } else if IS_CONSUMER (code) { | ||
829 | host_consumer_send(KEYCODE2CONSUMER(code)); | ||
830 | } | ||
831 | #endif | ||
832 | #ifdef MOUSEKEY_ENABLE | ||
833 | else if IS_MOUSEKEY (code) { | ||
834 | mousekey_on(code); | ||
835 | mousekey_send(); | ||
836 | } | ||
837 | #endif | ||
838 | } | ||
839 | |||
840 | /** \brief Utilities for actions. (FIXME: Needs better description) | ||
841 | * | ||
842 | * FIXME: Needs documentation. | ||
843 | */ | ||
844 | void unregister_code(uint8_t code) { | ||
845 | if (code == KC_NO) { | ||
846 | return; | ||
847 | } | ||
848 | #ifdef LOCKING_SUPPORT_ENABLE | ||
849 | else if (KC_LOCKING_CAPS == code) { | ||
850 | # ifdef LOCKING_RESYNC_ENABLE | ||
851 | // Resync: ignore if caps lock already is off | ||
852 | if (!(host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK))) return; | ||
853 | # endif | ||
854 | add_key(KC_CAPSLOCK); | ||
855 | send_keyboard_report(); | ||
856 | del_key(KC_CAPSLOCK); | ||
857 | send_keyboard_report(); | ||
858 | } | ||
859 | |||
860 | else if (KC_LOCKING_NUM == code) { | ||
861 | # ifdef LOCKING_RESYNC_ENABLE | ||
862 | if (!(host_keyboard_leds() & (1 << USB_LED_NUM_LOCK))) return; | ||
863 | # endif | ||
864 | add_key(KC_NUMLOCK); | ||
865 | send_keyboard_report(); | ||
866 | del_key(KC_NUMLOCK); | ||
867 | send_keyboard_report(); | ||
868 | } | ||
869 | |||
870 | else if (KC_LOCKING_SCROLL == code) { | ||
871 | # ifdef LOCKING_RESYNC_ENABLE | ||
872 | if (!(host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK))) return; | ||
873 | # endif | ||
874 | add_key(KC_SCROLLLOCK); | ||
875 | send_keyboard_report(); | ||
876 | del_key(KC_SCROLLLOCK); | ||
877 | send_keyboard_report(); | ||
878 | } | ||
879 | #endif | ||
880 | |||
881 | else if IS_KEY (code) { | ||
882 | del_key(code); | ||
883 | send_keyboard_report(); | ||
884 | } else if IS_MOD (code) { | ||
885 | del_mods(MOD_BIT(code)); | ||
886 | send_keyboard_report(); | ||
887 | } else if IS_SYSTEM (code) { | ||
888 | host_system_send(0); | ||
889 | } else if IS_CONSUMER (code) { | ||
890 | host_consumer_send(0); | ||
891 | } | ||
892 | #ifdef MOUSEKEY_ENABLE | ||
893 | else if IS_MOUSEKEY (code) { | ||
894 | mousekey_off(code); | ||
895 | mousekey_send(); | ||
896 | } | ||
897 | #endif | ||
898 | } | ||
899 | |||
900 | /** \brief Tap a keycode with a delay. | ||
901 | * | ||
902 | * \param code The basic keycode to tap. | ||
903 | * \param delay The amount of time in milliseconds to leave the keycode registered, before unregistering it. | ||
904 | */ | ||
905 | void tap_code_delay(uint8_t code, uint16_t delay) { | ||
906 | register_code(code); | ||
907 | for (uint16_t i = delay; i > 0; i--) { | ||
908 | wait_ms(1); | ||
909 | } | ||
910 | unregister_code(code); | ||
911 | } | ||
912 | |||
913 | /** \brief Tap a keycode with the default delay. | ||
914 | * | ||
915 | * \param code The basic keycode to tap. If `code` is `KC_CAPS`, the delay will be `TAP_HOLD_CAPS_DELAY`, otherwise `TAP_CODE_DELAY`, if defined. | ||
916 | */ | ||
917 | void tap_code(uint8_t code) { tap_code_delay(code, code == KC_CAPS ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY); } | ||
918 | |||
919 | /** \brief Adds the given physically pressed modifiers and sends a keyboard report immediately. | ||
920 | * | ||
921 | * \param mods A bitfield of modifiers to register. | ||
922 | */ | ||
923 | void register_mods(uint8_t mods) { | ||
924 | if (mods) { | ||
925 | add_mods(mods); | ||
926 | send_keyboard_report(); | ||
927 | } | ||
928 | } | ||
929 | |||
930 | /** \brief Removes the given physically pressed modifiers and sends a keyboard report immediately. | ||
931 | * | ||
932 | * \param mods A bitfield of modifiers to unregister. | ||
933 | */ | ||
934 | void unregister_mods(uint8_t mods) { | ||
935 | if (mods) { | ||
936 | del_mods(mods); | ||
937 | send_keyboard_report(); | ||
938 | } | ||
939 | } | ||
940 | |||
941 | /** \brief Adds the given weak modifiers and sends a keyboard report immediately. | ||
942 | * | ||
943 | * \param mods A bitfield of modifiers to register. | ||
944 | */ | ||
945 | void register_weak_mods(uint8_t mods) { | ||
946 | if (mods) { | ||
947 | add_weak_mods(mods); | ||
948 | send_keyboard_report(); | ||
949 | } | ||
950 | } | ||
951 | |||
952 | /** \brief Removes the given weak modifiers and sends a keyboard report immediately. | ||
953 | * | ||
954 | * \param mods A bitfield of modifiers to unregister. | ||
955 | */ | ||
956 | void unregister_weak_mods(uint8_t mods) { | ||
957 | if (mods) { | ||
958 | del_weak_mods(mods); | ||
959 | send_keyboard_report(); | ||
960 | } | ||
961 | } | ||
962 | |||
963 | /** \brief Utilities for actions. (FIXME: Needs better description) | ||
964 | * | ||
965 | * FIXME: Needs documentation. | ||
966 | */ | ||
967 | void clear_keyboard(void) { | ||
968 | clear_mods(); | ||
969 | clear_keyboard_but_mods(); | ||
970 | } | ||
971 | |||
972 | /** \brief Utilities for actions. (FIXME: Needs better description) | ||
973 | * | ||
974 | * FIXME: Needs documentation. | ||
975 | */ | ||
976 | void clear_keyboard_but_mods(void) { | ||
977 | clear_keys(); | ||
978 | clear_keyboard_but_mods_and_keys(); | ||
979 | } | ||
980 | |||
981 | /** \brief Utilities for actions. (FIXME: Needs better description) | ||
982 | * | ||
983 | * FIXME: Needs documentation. | ||
984 | */ | ||
985 | void clear_keyboard_but_mods_and_keys() { | ||
986 | #ifdef EXTRAKEY_ENABLE | ||
987 | host_system_send(0); | ||
988 | host_consumer_send(0); | ||
989 | #endif | ||
990 | clear_weak_mods(); | ||
991 | clear_macro_mods(); | ||
992 | send_keyboard_report(); | ||
993 | #ifdef MOUSEKEY_ENABLE | ||
994 | mousekey_clear(); | ||
995 | mousekey_send(); | ||
996 | #endif | ||
997 | } | ||
998 | |||
999 | /** \brief Utilities for actions. (FIXME: Needs better description) | ||
1000 | * | ||
1001 | * FIXME: Needs documentation. | ||
1002 | */ | ||
1003 | bool is_tap_key(keypos_t key) { | ||
1004 | action_t action = layer_switch_get_action(key); | ||
1005 | return is_tap_action(action); | ||
1006 | } | ||
1007 | |||
1008 | /** \brief Utilities for actions. (FIXME: Needs better description) | ||
1009 | * | ||
1010 | * FIXME: Needs documentation. | ||
1011 | */ | ||
1012 | bool is_tap_record(keyrecord_t *record) { | ||
1013 | #ifdef COMBO_ENABLE | ||
1014 | action_t action; | ||
1015 | if (record->keycode) { | ||
1016 | action = action_for_keycode(record->keycode); | ||
1017 | } else { | ||
1018 | action = layer_switch_get_action(record->event.key); | ||
1019 | } | ||
1020 | #else | ||
1021 | action_t action = layer_switch_get_action(record->event.key); | ||
1022 | #endif | ||
1023 | return is_tap_action(action); | ||
1024 | } | ||
1025 | |||
1026 | /** \brief Utilities for actions. (FIXME: Needs better description) | ||
1027 | * | ||
1028 | * FIXME: Needs documentation. | ||
1029 | */ | ||
1030 | bool is_tap_action(action_t action) { | ||
1031 | switch (action.kind.id) { | ||
1032 | case ACT_LMODS_TAP: | ||
1033 | case ACT_RMODS_TAP: | ||
1034 | case ACT_LAYER_TAP: | ||
1035 | case ACT_LAYER_TAP_EXT: | ||
1036 | switch (action.layer_tap.code) { | ||
1037 | case KC_NO ... KC_RGUI: | ||
1038 | case OP_TAP_TOGGLE: | ||
1039 | case OP_ONESHOT: | ||
1040 | return true; | ||
1041 | } | ||
1042 | return false; | ||
1043 | case ACT_SWAP_HANDS: | ||
1044 | switch (action.swap.code) { | ||
1045 | case KC_NO ... KC_RGUI: | ||
1046 | case OP_SH_TAP_TOGGLE: | ||
1047 | return true; | ||
1048 | } | ||
1049 | return false; | ||
1050 | case ACT_MACRO: | ||
1051 | case ACT_FUNCTION: | ||
1052 | if (action.func.opt & FUNC_TAP) { | ||
1053 | return true; | ||
1054 | } | ||
1055 | return false; | ||
1056 | } | ||
1057 | return false; | ||
1058 | } | ||
1059 | |||
1060 | /** \brief Debug print (FIXME: Needs better description) | ||
1061 | * | ||
1062 | * FIXME: Needs documentation. | ||
1063 | */ | ||
1064 | void debug_event(keyevent_t event) { dprintf("%04X%c(%u)", (event.key.row << 8 | event.key.col), (event.pressed ? 'd' : 'u'), event.time); } | ||
1065 | /** \brief Debug print (FIXME: Needs better description) | ||
1066 | * | ||
1067 | * FIXME: Needs documentation. | ||
1068 | */ | ||
1069 | void debug_record(keyrecord_t record) { | ||
1070 | debug_event(record.event); | ||
1071 | #ifndef NO_ACTION_TAPPING | ||
1072 | dprintf(":%u%c", record.tap.count, (record.tap.interrupted ? '-' : ' ')); | ||
1073 | #endif | ||
1074 | } | ||
1075 | |||
1076 | /** \brief Debug print (FIXME: Needs better description) | ||
1077 | * | ||
1078 | * FIXME: Needs documentation. | ||
1079 | */ | ||
1080 | void debug_action(action_t action) { | ||
1081 | switch (action.kind.id) { | ||
1082 | case ACT_LMODS: | ||
1083 | dprint("ACT_LMODS"); | ||
1084 | break; | ||
1085 | case ACT_RMODS: | ||
1086 | dprint("ACT_RMODS"); | ||
1087 | break; | ||
1088 | case ACT_LMODS_TAP: | ||
1089 | dprint("ACT_LMODS_TAP"); | ||
1090 | break; | ||
1091 | case ACT_RMODS_TAP: | ||
1092 | dprint("ACT_RMODS_TAP"); | ||
1093 | break; | ||
1094 | case ACT_USAGE: | ||
1095 | dprint("ACT_USAGE"); | ||
1096 | break; | ||
1097 | case ACT_MOUSEKEY: | ||
1098 | dprint("ACT_MOUSEKEY"); | ||
1099 | break; | ||
1100 | case ACT_LAYER: | ||
1101 | dprint("ACT_LAYER"); | ||
1102 | break; | ||
1103 | case ACT_LAYER_MODS: | ||
1104 | dprint("ACT_LAYER_MODS"); | ||
1105 | break; | ||
1106 | case ACT_LAYER_TAP: | ||
1107 | dprint("ACT_LAYER_TAP"); | ||
1108 | break; | ||
1109 | case ACT_LAYER_TAP_EXT: | ||
1110 | dprint("ACT_LAYER_TAP_EXT"); | ||
1111 | break; | ||
1112 | case ACT_MACRO: | ||
1113 | dprint("ACT_MACRO"); | ||
1114 | break; | ||
1115 | case ACT_FUNCTION: | ||
1116 | dprint("ACT_FUNCTION"); | ||
1117 | break; | ||
1118 | case ACT_SWAP_HANDS: | ||
1119 | dprint("ACT_SWAP_HANDS"); | ||
1120 | break; | ||
1121 | default: | ||
1122 | dprint("UNKNOWN"); | ||
1123 | break; | ||
1124 | } | ||
1125 | dprintf("[%X:%02X]", action.kind.param >> 8, action.kind.param & 0xff); | ||
1126 | } | ||
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h deleted file mode 100644 index 3d357b33b..000000000 --- a/tmk_core/common/action.h +++ /dev/null | |||
@@ -1,132 +0,0 @@ | |||
1 | /* | ||
2 | Copyright 2012,2013 Jun Wako <wakojun@gmail.com> | ||
3 | |||
4 | This program is free software: you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation, either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #pragma once | ||
19 | |||
20 | #include <stdint.h> | ||
21 | #include <stdbool.h> | ||
22 | #include "keyboard.h" | ||
23 | #include "keycode.h" | ||
24 | #include "action_code.h" | ||
25 | #include "action_macro.h" | ||
26 | |||
27 | #ifdef __cplusplus | ||
28 | extern "C" { | ||
29 | #endif | ||
30 | |||
31 | /* Disable macro and function features when LTO is enabled, since they break */ | ||
32 | #ifdef LTO_ENABLE | ||
33 | # ifndef NO_ACTION_MACRO | ||
34 | # define NO_ACTION_MACRO | ||
35 | # endif | ||
36 | # ifndef NO_ACTION_FUNCTION | ||
37 | # define NO_ACTION_FUNCTION | ||
38 | # endif | ||
39 | #endif | ||
40 | |||
41 | /* tapping count and state */ | ||
42 | typedef struct { | ||
43 | bool interrupted : 1; | ||
44 | bool reserved2 : 1; | ||
45 | bool reserved1 : 1; | ||
46 | bool reserved0 : 1; | ||
47 | uint8_t count : 4; | ||
48 | } tap_t; | ||
49 | |||
50 | /* Key event container for recording */ | ||
51 | typedef struct { | ||
52 | keyevent_t event; | ||
53 | #ifndef NO_ACTION_TAPPING | ||
54 | tap_t tap; | ||
55 | #endif | ||
56 | #ifdef COMBO_ENABLE | ||
57 | uint16_t keycode; | ||
58 | #endif | ||
59 | } keyrecord_t; | ||
60 | |||
61 | /* Execute action per keyevent */ | ||
62 | void action_exec(keyevent_t event); | ||
63 | |||
64 | /* action for key */ | ||
65 | action_t action_for_key(uint8_t layer, keypos_t key); | ||
66 | action_t action_for_keycode(uint16_t keycode); | ||
67 | |||
68 | /* macro */ | ||
69 | const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt); | ||
70 | |||
71 | /* user defined special function */ | ||
72 | void action_function(keyrecord_t *record, uint8_t id, uint8_t opt); | ||
73 | |||
74 | /* keyboard-specific key event (pre)processing */ | ||
75 | bool process_record_quantum(keyrecord_t *record); | ||
76 | |||
77 | /* Utilities for actions. */ | ||
78 | #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) | ||
79 | extern bool disable_action_cache; | ||
80 | #endif | ||
81 | |||
82 | /* Code for handling one-handed key modifiers. */ | ||
83 | #ifdef SWAP_HANDS_ENABLE | ||
84 | extern bool swap_hands; | ||
85 | extern const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS]; | ||
86 | # if (MATRIX_COLS <= 8) | ||
87 | typedef uint8_t swap_state_row_t; | ||
88 | # elif (MATRIX_COLS <= 16) | ||
89 | typedef uint16_t swap_state_row_t; | ||
90 | # elif (MATRIX_COLS <= 32) | ||
91 | typedef uint32_t swap_state_row_t; | ||
92 | # else | ||
93 | # error "MATRIX_COLS: invalid value" | ||
94 | # endif | ||
95 | |||
96 | void process_hand_swap(keyevent_t *record); | ||
97 | #endif | ||
98 | |||
99 | void process_record_nocache(keyrecord_t *record); | ||
100 | void process_record(keyrecord_t *record); | ||
101 | void process_record_handler(keyrecord_t *record); | ||
102 | void post_process_record_quantum(keyrecord_t *record); | ||
103 | void process_action(keyrecord_t *record, action_t action); | ||
104 | void register_code(uint8_t code); | ||
105 | void unregister_code(uint8_t code); | ||
106 | void tap_code(uint8_t code); | ||
107 | void tap_code_delay(uint8_t code, uint16_t delay); | ||
108 | void register_mods(uint8_t mods); | ||
109 | void unregister_mods(uint8_t mods); | ||
110 | void register_weak_mods(uint8_t mods); | ||
111 | void unregister_weak_mods(uint8_t mods); | ||
112 | // void set_mods(uint8_t mods); | ||
113 | void clear_keyboard(void); | ||
114 | void clear_keyboard_but_mods(void); | ||
115 | void clear_keyboard_but_mods_and_keys(void); | ||
116 | void layer_switch(uint8_t new_layer); | ||
117 | bool is_tap_key(keypos_t key); | ||
118 | bool is_tap_record(keyrecord_t *record); | ||
119 | bool is_tap_action(action_t action); | ||
120 | |||
121 | #ifndef NO_ACTION_TAPPING | ||
122 | void process_record_tap_hint(keyrecord_t *record); | ||
123 | #endif | ||
124 | |||
125 | /* debug */ | ||
126 | void debug_event(keyevent_t event); | ||
127 | void debug_record(keyrecord_t record); | ||
128 | void debug_action(action_t action); | ||
129 | |||
130 | #ifdef __cplusplus | ||
131 | } | ||
132 | #endif | ||
diff --git a/tmk_core/common/action_code.h b/tmk_core/common/action_code.h deleted file mode 100644 index eb18c36ae..000000000 --- a/tmk_core/common/action_code.h +++ /dev/null | |||
@@ -1,308 +0,0 @@ | |||
1 | /* | ||
2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
3 | |||
4 | This program is free software: you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation, either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #pragma once | ||
19 | |||
20 | /** \brief Action codes | ||
21 | * | ||
22 | * 16bit code: action_kind(4bit) + action_parameter(12bit) | ||
23 | * | ||
24 | * Key Actions(00xx) | ||
25 | * ----------------- | ||
26 | * ACT_MODS(000r): | ||
27 | * 000r|0000|0000 0000 No action code | ||
28 | * 000r|0000|0000 0001 Transparent code | ||
29 | * 000r|0000| keycode Key | ||
30 | * 000r|mods|0000 0000 Modifiers | ||
31 | * 000r|mods| keycode Modifiers+Key(Modified key) | ||
32 | * r: Left/Right flag(Left:0, Right:1) | ||
33 | * | ||
34 | * ACT_MODS_TAP(001r): | ||
35 | * 001r|mods|0000 0000 Modifiers with OneShot | ||
36 | * 001r|mods|0000 0001 Modifiers with tap toggle | ||
37 | * 001r|mods|0000 00xx (reserved) | ||
38 | * 001r|mods| keycode Modifiers with Tap Key(Dual role) | ||
39 | * | ||
40 | * Other Keys(01xx) | ||
41 | * ---------------- | ||
42 | * ACT_USAGE(0100): TODO: Not needed? | ||
43 | * 0100|00| usage(10) System control(0x80) - General Desktop page(0x01) | ||
44 | * 0100|01| usage(10) Consumer control(0x01) - Consumer page(0x0C) | ||
45 | * 0100|10| usage(10) (reserved) | ||
46 | * 0100|11| usage(10) (reserved) | ||
47 | * | ||
48 | * ACT_MOUSEKEY(0101): TODO: Merge these two actions to conserve space? | ||
49 | * 0101|xxxx| keycode Mouse key | ||
50 | * | ||
51 | * ACT_SWAP_HANDS(0110): | ||
52 | * 0110|xxxx| keycode Swap hands (keycode on tap, or options) | ||
53 | * | ||
54 | * 0111|xxxx xxxx xxxx (reserved) | ||
55 | * | ||
56 | * Layer Actions(10xx) | ||
57 | * ------------------- | ||
58 | * ACT_LAYER(1000): | ||
59 | * 1000|oo00|pppE BBBB Default Layer Bitwise operation | ||
60 | * oo: operation(00:AND, 01:OR, 10:XOR, 11:SET) | ||
61 | * ppp: 4-bit chunk part(0-7) | ||
62 | * EBBBB: bits and extra bit | ||
63 | * 1000|ooee|pppE BBBB Layer Bitwise Operation | ||
64 | * oo: operation(00:AND, 01:OR, 10:XOR, 11:SET) | ||
65 | * ppp: 4-bit chunk part(0-7) | ||
66 | * EBBBB: bits and extra bit | ||
67 | * ee: on event(01:press, 10:release, 11:both) | ||
68 | * | ||
69 | * ACT_LAYER_MODS(1001): | ||
70 | * 1001|LLLL| mods Layer with modifiers held | ||
71 | * | ||
72 | * ACT_LAYER_TAP(101x): | ||
73 | * 101E|LLLL| keycode On/Off with tap key (0x00-DF)[TAP] | ||
74 | * 101E|LLLL|1110 mods On/Off with modifiers (0xE0-EF)[NOT TAP] | ||
75 | * 101E|LLLL|1111 0000 Invert with tap toggle (0xF0) [TAP] | ||
76 | * 101E|LLLL|1111 0001 On/Off (0xF1) [NOT TAP] | ||
77 | * 101E|LLLL|1111 0010 Off/On (0xF2) [NOT TAP] | ||
78 | * 101E|LLLL|1111 0011 Set/Clear (0xF3) [NOT TAP] | ||
79 | * 101E|LLLL|1111 0100 One Shot Layer (0xF4) [TAP] | ||
80 | * 101E|LLLL|1111 xxxx Reserved (0xF5-FF) | ||
81 | * ELLLL: layer 0-31(E: extra bit for layer 16-31) | ||
82 | * | ||
83 | * Extensions(11xx) | ||
84 | * ---------------- | ||
85 | * ACT_MACRO(1100): | ||
86 | * 1100|opt | id(8) Macro play? | ||
87 | * 1100|1111| id(8) Macro record? | ||
88 | * | ||
89 | * 1101|xxxx xxxx xxxx (reserved) | ||
90 | * 1110|xxxx xxxx xxxx (reserved) | ||
91 | * | ||
92 | * ACT_FUNCTION(1111): | ||
93 | * 1111| address(12) Function? | ||
94 | * 1111|opt | id(8) Function? | ||
95 | */ | ||
96 | enum action_kind_id { | ||
97 | /* Key Actions */ | ||
98 | ACT_MODS = 0b0000, | ||
99 | ACT_LMODS = 0b0000, | ||
100 | ACT_RMODS = 0b0001, | ||
101 | ACT_MODS_TAP = 0b0010, | ||
102 | ACT_LMODS_TAP = 0b0010, | ||
103 | ACT_RMODS_TAP = 0b0011, | ||
104 | /* Other Keys */ | ||
105 | ACT_USAGE = 0b0100, | ||
106 | ACT_MOUSEKEY = 0b0101, | ||
107 | /* One-hand Support */ | ||
108 | ACT_SWAP_HANDS = 0b0110, | ||
109 | /* Layer Actions */ | ||
110 | ACT_LAYER = 0b1000, | ||
111 | ACT_LAYER_MODS = 0b1001, | ||
112 | ACT_LAYER_TAP = 0b1010, /* Layer 0-15 */ | ||
113 | ACT_LAYER_TAP_EXT = 0b1011, /* Layer 16-31 */ | ||
114 | /* Extensions */ | ||
115 | ACT_MACRO = 0b1100, | ||
116 | ACT_FUNCTION = 0b1111 | ||
117 | }; | ||
118 | |||
119 | /** \brief Action Code Struct | ||
120 | * | ||
121 | * NOTE: | ||
122 | * In avr-gcc bit field seems to be assigned from LSB(bit0) to MSB(bit15). | ||
123 | * AVR looks like a little endian in avr-gcc. | ||
124 | * Not portable across compiler/endianness? | ||
125 | * | ||
126 | * Byte order and bit order of 0x1234: | ||
127 | * Big endian: Little endian: | ||
128 | * -------------------- -------------------- | ||
129 | * FEDC BA98 7654 3210 0123 4567 89AB CDEF | ||
130 | * 0001 0010 0011 0100 0010 1100 0100 1000 | ||
131 | * 0x12 0x34 0x34 0x12 | ||
132 | */ | ||
133 | typedef union { | ||
134 | uint16_t code; | ||
135 | struct action_kind { | ||
136 | uint16_t param : 12; | ||
137 | uint8_t id : 4; | ||
138 | } kind; | ||
139 | struct action_key { | ||
140 | uint8_t code : 8; | ||
141 | uint8_t mods : 4; | ||
142 | uint8_t kind : 4; | ||
143 | } key; | ||
144 | struct action_layer_bitop { | ||
145 | uint8_t bits : 4; | ||
146 | uint8_t xbit : 1; | ||
147 | uint8_t part : 3; | ||
148 | uint8_t on : 2; | ||
149 | uint8_t op : 2; | ||
150 | uint8_t kind : 4; | ||
151 | } layer_bitop; | ||
152 | struct action_layer_mods { | ||
153 | uint8_t mods : 8; | ||
154 | uint8_t layer : 4; | ||
155 | uint8_t kind : 4; | ||
156 | } layer_mods; | ||
157 | struct action_layer_tap { | ||
158 | uint8_t code : 8; | ||
159 | uint8_t val : 5; | ||
160 | uint8_t kind : 3; | ||
161 | } layer_tap; | ||
162 | struct action_usage { | ||
163 | uint16_t code : 10; | ||
164 | uint8_t page : 2; | ||
165 | uint8_t kind : 4; | ||
166 | } usage; | ||
167 | struct action_function { | ||
168 | uint8_t id : 8; | ||
169 | uint8_t opt : 4; | ||
170 | uint8_t kind : 4; | ||
171 | } func; | ||
172 | struct action_swap { | ||
173 | uint8_t code : 8; | ||
174 | uint8_t opt : 4; | ||
175 | uint8_t kind : 4; | ||
176 | } swap; | ||
177 | } action_t; | ||
178 | |||
179 | /* action utility */ | ||
180 | #define ACTION_NO 0 | ||
181 | #define ACTION_TRANSPARENT 1 | ||
182 | #define ACTION(kind, param) ((kind) << 12 | (param)) | ||
183 | |||
184 | /** \brief Key Actions | ||
185 | * | ||
186 | * Mod bits: 43210 | ||
187 | * bit 0 ||||+- Control | ||
188 | * bit 1 |||+-- Shift | ||
189 | * bit 2 ||+--- Alt | ||
190 | * bit 3 |+---- Gui | ||
191 | * bit 4 +----- LR flag(Left:0, Right:1) | ||
192 | */ | ||
193 | enum mods_bit { | ||
194 | MOD_LCTL = 0x01, | ||
195 | MOD_LSFT = 0x02, | ||
196 | MOD_LALT = 0x04, | ||
197 | MOD_LGUI = 0x08, | ||
198 | MOD_RCTL = 0x11, | ||
199 | MOD_RSFT = 0x12, | ||
200 | MOD_RALT = 0x14, | ||
201 | MOD_RGUI = 0x18, | ||
202 | }; | ||
203 | enum mods_codes { | ||
204 | MODS_ONESHOT = 0x00, | ||
205 | MODS_TAP_TOGGLE = 0x01, | ||
206 | }; | ||
207 | #define ACTION_KEY(key) ACTION(ACT_MODS, (key)) | ||
208 | #define ACTION_MODS(mods) ACTION(ACT_MODS, ((mods)&0x1f) << 8 | 0) | ||
209 | #define ACTION_MODS_KEY(mods, key) ACTION(ACT_MODS, ((mods)&0x1f) << 8 | (key)) | ||
210 | #define ACTION_MODS_TAP_KEY(mods, key) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | (key)) | ||
211 | #define ACTION_MODS_ONESHOT(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | MODS_ONESHOT) | ||
212 | #define ACTION_MODS_TAP_TOGGLE(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | MODS_TAP_TOGGLE) | ||
213 | |||
214 | /** \brief Other Keys | ||
215 | */ | ||
216 | enum usage_pages { PAGE_SYSTEM, PAGE_CONSUMER }; | ||
217 | #define ACTION_USAGE_SYSTEM(id) ACTION(ACT_USAGE, PAGE_SYSTEM << 10 | (id)) | ||
218 | #define ACTION_USAGE_CONSUMER(id) ACTION(ACT_USAGE, PAGE_CONSUMER << 10 | (id)) | ||
219 | #define ACTION_MOUSEKEY(key) ACTION(ACT_MOUSEKEY, key) | ||
220 | |||
221 | /** \brief Layer Actions | ||
222 | */ | ||
223 | enum layer_param_on { | ||
224 | ON_PRESS = 1, | ||
225 | ON_RELEASE = 2, | ||
226 | ON_BOTH = 3, | ||
227 | }; | ||
228 | |||
229 | /** \brief Layer Actions | ||
230 | */ | ||
231 | enum layer_param_bit_op { | ||
232 | OP_BIT_AND = 0, | ||
233 | OP_BIT_OR = 1, | ||
234 | OP_BIT_XOR = 2, | ||
235 | OP_BIT_SET = 3, | ||
236 | }; | ||
237 | |||
238 | /** \brief Layer Actions | ||
239 | */ | ||
240 | enum layer_param_tap_op { | ||
241 | OP_TAP_TOGGLE = 0xF0, | ||
242 | OP_ON_OFF, | ||
243 | OP_OFF_ON, | ||
244 | OP_SET_CLEAR, | ||
245 | OP_ONESHOT, | ||
246 | }; | ||
247 | #define ACTION_LAYER_BITOP(op, part, bits, on) ACTION(ACT_LAYER, (op) << 10 | (on) << 8 | (part) << 5 | ((bits)&0x1f)) | ||
248 | #define ACTION_LAYER_TAP(layer, key) ACTION(ACT_LAYER_TAP, (layer) << 8 | (key)) | ||
249 | /* Default Layer */ | ||
250 | #define ACTION_DEFAULT_LAYER_SET(layer) ACTION_DEFAULT_LAYER_BIT_SET((layer) / 4, 1 << ((layer) % 4)) | ||
251 | /* Layer Operation */ | ||
252 | #define ACTION_LAYER_CLEAR(on) ACTION_LAYER_BIT_AND(0, 0, (on)) | ||
253 | #define ACTION_LAYER_MOMENTARY(layer) ACTION_LAYER_ON_OFF(layer) | ||
254 | #define ACTION_LAYER_TOGGLE(layer) ACTION_LAYER_INVERT(layer, ON_RELEASE) | ||
255 | #define ACTION_LAYER_INVERT(layer, on) ACTION_LAYER_BIT_XOR((layer) / 4, 1 << ((layer) % 4), (on)) | ||
256 | #define ACTION_LAYER_ON(layer, on) ACTION_LAYER_BIT_OR((layer) / 4, 1 << ((layer) % 4), (on)) | ||
257 | #define ACTION_LAYER_OFF(layer, on) ACTION_LAYER_BIT_AND((layer) / 4, ~(1 << ((layer) % 4)), (on)) | ||
258 | #define ACTION_LAYER_SET(layer, on) ACTION_LAYER_BIT_SET((layer) / 4, 1 << ((layer) % 4), (on)) | ||
259 | #define ACTION_LAYER_ON_OFF(layer) ACTION_LAYER_TAP((layer), OP_ON_OFF) | ||
260 | #define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON) | ||
261 | #define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR) | ||
262 | #define ACTION_LAYER_ONESHOT(layer) ACTION_LAYER_TAP((layer), OP_ONESHOT) | ||
263 | #define ACTION_LAYER_MODS(layer, mods) ACTION(ACT_LAYER_MODS, (layer) << 8 | (mods)) | ||
264 | /* With Tapping */ | ||
265 | #define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key)) | ||
266 | #define ACTION_LAYER_TAP_TOGGLE(layer) ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE) | ||
267 | /* Bitwise Operation */ | ||
268 | #define ACTION_LAYER_BIT_AND(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_AND, (part), (bits), (on)) | ||
269 | #define ACTION_LAYER_BIT_OR(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_OR, (part), (bits), (on)) | ||
270 | #define ACTION_LAYER_BIT_XOR(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_XOR, (part), (bits), (on)) | ||
271 | #define ACTION_LAYER_BIT_SET(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_SET, (part), (bits), (on)) | ||
272 | /* Default Layer Bitwise Operation */ | ||
273 | #define ACTION_DEFAULT_LAYER_BIT_AND(part, bits) ACTION_LAYER_BITOP(OP_BIT_AND, (part), (bits), 0) | ||
274 | #define ACTION_DEFAULT_LAYER_BIT_OR(part, bits) ACTION_LAYER_BITOP(OP_BIT_OR, (part), (bits), 0) | ||
275 | #define ACTION_DEFAULT_LAYER_BIT_XOR(part, bits) ACTION_LAYER_BITOP(OP_BIT_XOR, (part), (bits), 0) | ||
276 | #define ACTION_DEFAULT_LAYER_BIT_SET(part, bits) ACTION_LAYER_BITOP(OP_BIT_SET, (part), (bits), 0) | ||
277 | |||
278 | /* Macro */ | ||
279 | #define ACTION_MACRO(id) ACTION(ACT_MACRO, (id)) | ||
280 | #define ACTION_MACRO_TAP(id) ACTION(ACT_MACRO, FUNC_TAP << 8 | (id)) | ||
281 | #define ACTION_MACRO_OPT(id, opt) ACTION(ACT_MACRO, (opt) << 8 | (id)) | ||
282 | /* Function */ | ||
283 | enum function_opts { | ||
284 | FUNC_TAP = 0x8, /* indciates function is tappable */ | ||
285 | }; | ||
286 | #define ACTION_FUNCTION(id) ACTION(ACT_FUNCTION, (id)) | ||
287 | #define ACTION_FUNCTION_TAP(id) ACTION(ACT_FUNCTION, FUNC_TAP << 8 | (id)) | ||
288 | #define ACTION_FUNCTION_OPT(id, opt) ACTION(ACT_FUNCTION, (opt) << 8 | (id)) | ||
289 | /* OneHand Support */ | ||
290 | enum swap_hands_param_tap_op { | ||
291 | OP_SH_TOGGLE = 0xF0, | ||
292 | OP_SH_TAP_TOGGLE, | ||
293 | OP_SH_ON_OFF, | ||
294 | OP_SH_OFF_ON, | ||
295 | OP_SH_OFF, | ||
296 | OP_SH_ON, | ||
297 | OP_SH_ONESHOT, | ||
298 | }; | ||
299 | |||
300 | #define ACTION_SWAP_HANDS() ACTION_SWAP_HANDS_ON_OFF() | ||
301 | #define ACTION_SWAP_HANDS_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TOGGLE) | ||
302 | #define ACTION_SWAP_HANDS_TAP_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TAP_TOGGLE) | ||
303 | #define ACTION_SWAP_HANDS_ONESHOT() ACTION(ACT_SWAP_HANDS, OP_SH_ONESHOT) | ||
304 | #define ACTION_SWAP_HANDS_TAP_KEY(key) ACTION(ACT_SWAP_HANDS, key) | ||
305 | #define ACTION_SWAP_HANDS_ON_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_ON_OFF) | ||
306 | #define ACTION_SWAP_HANDS_OFF_ON() ACTION(ACT_SWAP_HANDS, OP_SH_OFF_ON) | ||
307 | #define ACTION_SWAP_HANDS_ON() ACTION(ACT_SWAP_HANDS, OP_SH_ON) | ||
308 | #define ACTION_SWAP_HANDS_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_OFF) | ||
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c deleted file mode 100644 index ed1a4bd20..000000000 --- a/tmk_core/common/action_layer.c +++ /dev/null | |||
@@ -1,279 +0,0 @@ | |||
1 | #include <stdint.h> | ||
2 | #include "keyboard.h" | ||
3 | #include "action.h" | ||
4 | #include "util.h" | ||
5 | #include "action_layer.h" | ||
6 | |||
7 | #ifdef DEBUG_ACTION | ||
8 | # include "debug.h" | ||
9 | #else | ||
10 | # include "nodebug.h" | ||
11 | #endif | ||
12 | |||
13 | /** \brief Default Layer State | ||
14 | */ | ||
15 | layer_state_t default_layer_state = 0; | ||
16 | |||
17 | /** \brief Default Layer State Set At user Level | ||
18 | * | ||
19 | * Run user code on default layer state change | ||
20 | */ | ||
21 | __attribute__((weak)) layer_state_t default_layer_state_set_user(layer_state_t state) { return state; } | ||
22 | |||
23 | /** \brief Default Layer State Set At Keyboard Level | ||
24 | * | ||
25 | * Run keyboard code on default layer state change | ||
26 | */ | ||
27 | __attribute__((weak)) layer_state_t default_layer_state_set_kb(layer_state_t state) { return default_layer_state_set_user(state); } | ||
28 | |||
29 | /** \brief Default Layer State Set | ||
30 | * | ||
31 | * Static function to set the default layer state, prints debug info and clears keys | ||
32 | */ | ||
33 | static void default_layer_state_set(layer_state_t state) { | ||
34 | state = default_layer_state_set_kb(state); | ||
35 | debug("default_layer_state: "); | ||
36 | default_layer_debug(); | ||
37 | debug(" to "); | ||
38 | default_layer_state = state; | ||
39 | default_layer_debug(); | ||
40 | debug("\n"); | ||
41 | #ifdef STRICT_LAYER_RELEASE | ||
42 | clear_keyboard_but_mods(); // To avoid stuck keys | ||
43 | #else | ||
44 | clear_keyboard_but_mods_and_keys(); // Don't reset held keys | ||
45 | #endif | ||
46 | } | ||
47 | |||
48 | /** \brief Default Layer Print | ||
49 | * | ||
50 | * Print out the hex value of the 32-bit default layer state, as well as the value of the highest bit. | ||
51 | */ | ||
52 | void default_layer_debug(void) { dprintf("%08lX(%u)", default_layer_state, get_highest_layer(default_layer_state)); } | ||
53 | |||
54 | /** \brief Default Layer Set | ||
55 | * | ||
56 | * Sets the default layer state. | ||
57 | */ | ||
58 | void default_layer_set(layer_state_t state) { default_layer_state_set(state); } | ||
59 | |||
60 | #ifndef NO_ACTION_LAYER | ||
61 | /** \brief Default Layer Or | ||
62 | * | ||
63 | * Turns on the default layer based on matching bits between specifed layer and existing layer state | ||
64 | */ | ||
65 | void default_layer_or(layer_state_t state) { default_layer_state_set(default_layer_state | state); } | ||
66 | /** \brief Default Layer And | ||
67 | * | ||
68 | * Turns on default layer based on matching enabled bits between specifed layer and existing layer state | ||
69 | */ | ||
70 | void default_layer_and(layer_state_t state) { default_layer_state_set(default_layer_state & state); } | ||
71 | /** \brief Default Layer Xor | ||
72 | * | ||
73 | * Turns on default layer based on non-matching bits between specifed layer and existing layer state | ||
74 | */ | ||
75 | void default_layer_xor(layer_state_t state) { default_layer_state_set(default_layer_state ^ state); } | ||
76 | #endif | ||
77 | |||
78 | #ifndef NO_ACTION_LAYER | ||
79 | /** \brief Keymap Layer State | ||
80 | */ | ||
81 | layer_state_t layer_state = 0; | ||
82 | |||
83 | /** \brief Layer state set user | ||
84 | * | ||
85 | * Runs user code on layer state change | ||
86 | */ | ||
87 | __attribute__((weak)) layer_state_t layer_state_set_user(layer_state_t state) { return state; } | ||
88 | |||
89 | /** \brief Layer state set keyboard | ||
90 | * | ||
91 | * Runs keyboard code on layer state change | ||
92 | */ | ||
93 | __attribute__((weak)) layer_state_t layer_state_set_kb(layer_state_t state) { return layer_state_set_user(state); } | ||
94 | |||
95 | /** \brief Layer state set | ||
96 | * | ||
97 | * Sets the layer to match the specifed state (a bitmask) | ||
98 | */ | ||
99 | void layer_state_set(layer_state_t state) { | ||
100 | state = layer_state_set_kb(state); | ||
101 | dprint("layer_state: "); | ||
102 | layer_debug(); | ||
103 | dprint(" to "); | ||
104 | layer_state = state; | ||
105 | layer_debug(); | ||
106 | dprintln(); | ||
107 | # ifdef STRICT_LAYER_RELEASE | ||
108 | clear_keyboard_but_mods(); // To avoid stuck keys | ||
109 | # else | ||
110 | clear_keyboard_but_mods_and_keys(); // Don't reset held keys | ||
111 | # endif | ||
112 | } | ||
113 | |||
114 | /** \brief Layer clear | ||
115 | * | ||
116 | * Turn off all layers | ||
117 | */ | ||
118 | void layer_clear(void) { layer_state_set(0); } | ||
119 | |||
120 | /** \brief Layer state is | ||
121 | * | ||
122 | * Return whether the given state is on (it might still be shadowed by a higher state, though) | ||
123 | */ | ||
124 | bool layer_state_is(uint8_t layer) { return layer_state_cmp(layer_state, layer); } | ||
125 | |||
126 | /** \brief Layer state compare | ||
127 | * | ||
128 | * Used for comparing layers {mostly used for unit testing} | ||
129 | */ | ||
130 | bool layer_state_cmp(layer_state_t cmp_layer_state, uint8_t layer) { | ||
131 | if (!cmp_layer_state) { | ||
132 | return layer == 0; | ||
133 | } | ||
134 | return (cmp_layer_state & ((layer_state_t)1 << layer)) != 0; | ||
135 | } | ||
136 | |||
137 | /** \brief Layer move | ||
138 | * | ||
139 | * Turns on the given layer and turn off all other layers | ||
140 | */ | ||
141 | void layer_move(uint8_t layer) { layer_state_set((layer_state_t)1 << layer); } | ||
142 | |||
143 | /** \brief Layer on | ||
144 | * | ||
145 | * Turns on given layer | ||
146 | */ | ||
147 | void layer_on(uint8_t layer) { layer_state_set(layer_state | ((layer_state_t)1 << layer)); } | ||
148 | |||
149 | /** \brief Layer off | ||
150 | * | ||
151 | * Turns off given layer | ||
152 | */ | ||
153 | void layer_off(uint8_t layer) { layer_state_set(layer_state & ~((layer_state_t)1 << layer)); } | ||
154 | |||
155 | /** \brief Layer invert | ||
156 | * | ||
157 | * Toggle the given layer (set it if it's unset, or unset it if it's set) | ||
158 | */ | ||
159 | void layer_invert(uint8_t layer) { layer_state_set(layer_state ^ ((layer_state_t)1 << layer)); } | ||
160 | |||
161 | /** \brief Layer or | ||
162 | * | ||
163 | * Turns on layers based on matching bits between specifed layer and existing layer state | ||
164 | */ | ||
165 | void layer_or(layer_state_t state) { layer_state_set(layer_state | state); } | ||
166 | /** \brief Layer and | ||
167 | * | ||
168 | * Turns on layers based on matching enabled bits between specifed layer and existing layer state | ||
169 | */ | ||
170 | void layer_and(layer_state_t state) { layer_state_set(layer_state & state); } | ||
171 | /** \brief Layer xor | ||
172 | * | ||
173 | * Turns on layers based on non-matching bits between specifed layer and existing layer state | ||
174 | */ | ||
175 | void layer_xor(layer_state_t state) { layer_state_set(layer_state ^ state); } | ||
176 | |||
177 | /** \brief Layer debug printing | ||
178 | * | ||
179 | * Print out the hex value of the 32-bit layer state, as well as the value of the highest bit. | ||
180 | */ | ||
181 | void layer_debug(void) { dprintf("%08lX(%u)", layer_state, get_highest_layer(layer_state)); } | ||
182 | #endif | ||
183 | |||
184 | #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) | ||
185 | /** \brief source layer cache | ||
186 | */ | ||
187 | |||
188 | uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS] = {{0}}; | ||
189 | |||
190 | /** \brief update source layers cache | ||
191 | * | ||
192 | * Updates the cached keys when changing layers | ||
193 | */ | ||
194 | void update_source_layers_cache(keypos_t key, uint8_t layer) { | ||
195 | const uint8_t key_number = key.col + (key.row * MATRIX_COLS); | ||
196 | const uint8_t storage_row = key_number / 8; | ||
197 | const uint8_t storage_bit = key_number % 8; | ||
198 | |||
199 | for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) { | ||
200 | source_layers_cache[storage_row][bit_number] ^= (-((layer & (1U << bit_number)) != 0) ^ source_layers_cache[storage_row][bit_number]) & (1U << storage_bit); | ||
201 | } | ||
202 | } | ||
203 | |||
204 | /** \brief read source layers cache | ||
205 | * | ||
206 | * reads the cached keys stored when the layer was changed | ||
207 | */ | ||
208 | uint8_t read_source_layers_cache(keypos_t key) { | ||
209 | const uint8_t key_number = key.col + (key.row * MATRIX_COLS); | ||
210 | const uint8_t storage_row = key_number / 8; | ||
211 | const uint8_t storage_bit = key_number % 8; | ||
212 | uint8_t layer = 0; | ||
213 | |||
214 | for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) { | ||
215 | layer |= ((source_layers_cache[storage_row][bit_number] & (1U << storage_bit)) != 0) << bit_number; | ||
216 | } | ||
217 | |||
218 | return layer; | ||
219 | } | ||
220 | #endif | ||
221 | |||
222 | /** \brief Store or get action (FIXME: Needs better summary) | ||
223 | * | ||
224 | * Make sure the action triggered when the key is released is the same | ||
225 | * one as the one triggered on press. It's important for the mod keys | ||
226 | * when the layer is switched after the down event but before the up | ||
227 | * event as they may get stuck otherwise. | ||
228 | */ | ||
229 | action_t store_or_get_action(bool pressed, keypos_t key) { | ||
230 | #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) | ||
231 | if (disable_action_cache) { | ||
232 | return layer_switch_get_action(key); | ||
233 | } | ||
234 | |||
235 | uint8_t layer; | ||
236 | |||
237 | if (pressed) { | ||
238 | layer = layer_switch_get_layer(key); | ||
239 | update_source_layers_cache(key, layer); | ||
240 | } else { | ||
241 | layer = read_source_layers_cache(key); | ||
242 | } | ||
243 | return action_for_key(layer, key); | ||
244 | #else | ||
245 | return layer_switch_get_action(key); | ||
246 | #endif | ||
247 | } | ||
248 | |||
249 | /** \brief Layer switch get layer | ||
250 | * | ||
251 | * Gets the layer based on key info | ||
252 | */ | ||
253 | uint8_t layer_switch_get_layer(keypos_t key) { | ||
254 | #ifndef NO_ACTION_LAYER | ||
255 | action_t action; | ||
256 | action.code = ACTION_TRANSPARENT; | ||
257 | |||
258 | layer_state_t layers = layer_state | default_layer_state; | ||
259 | /* check top layer first */ | ||
260 | for (int8_t i = MAX_LAYER - 1; i >= 0; i--) { | ||
261 | if (layers & ((layer_state_t)1 << i)) { | ||
262 | action = action_for_key(i, key); | ||
263 | if (action.code != ACTION_TRANSPARENT) { | ||
264 | return i; | ||
265 | } | ||
266 | } | ||
267 | } | ||
268 | /* fall back to layer 0 */ | ||
269 | return 0; | ||
270 | #else | ||
271 | return get_highest_layer(default_layer_state); | ||
272 | #endif | ||
273 | } | ||
274 | |||
275 | /** \brief Layer switch get layer | ||
276 | * | ||
277 | * Gets action code based on key position | ||
278 | */ | ||
279 | action_t layer_switch_get_action(keypos_t key) { return action_for_key(layer_switch_get_layer(key), key); } | ||
diff --git a/tmk_core/common/action_layer.h b/tmk_core/common/action_layer.h deleted file mode 100644 index b87d096ee..000000000 --- a/tmk_core/common/action_layer.h +++ /dev/null | |||
@@ -1,147 +0,0 @@ | |||
1 | /* | ||
2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
3 | |||
4 | This program is free software: you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation, either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #pragma once | ||
19 | |||
20 | #include <stdint.h> | ||
21 | #include "keyboard.h" | ||
22 | #include "action.h" | ||
23 | |||
24 | #ifdef DYNAMIC_KEYMAP_ENABLE | ||
25 | # ifndef DYNAMIC_KEYMAP_LAYER_COUNT | ||
26 | # define DYNAMIC_KEYMAP_LAYER_COUNT 4 | ||
27 | # endif | ||
28 | # if DYNAMIC_KEYMAP_LAYER_COUNT <= 8 | ||
29 | # ifndef LAYER_STATE_8BIT | ||
30 | # define LAYER_STATE_8BIT | ||
31 | # endif | ||
32 | # elif DYNAMIC_KEYMAP_LAYER_COUNT <= 16 | ||
33 | # ifndef LAYER_STATE_16BIT | ||
34 | # define LAYER_STATE_16BIT | ||
35 | # endif | ||
36 | # else | ||
37 | # ifndef LAYER_STATE_32BIT | ||
38 | # define LAYER_STATE_32BIT | ||
39 | # endif | ||
40 | # endif | ||
41 | #endif | ||
42 | |||
43 | #if !defined(LAYER_STATE_8BIT) && !defined(LAYER_STATE_16BIT) && !defined(LAYER_STATE_32BIT) | ||
44 | # define LAYER_STATE_32BIT | ||
45 | #endif | ||
46 | |||
47 | #if defined(LAYER_STATE_8BIT) | ||
48 | typedef uint8_t layer_state_t; | ||
49 | # define MAX_LAYER_BITS 3 | ||
50 | # ifndef MAX_LAYER | ||
51 | # define MAX_LAYER 8 | ||
52 | # endif | ||
53 | # define get_highest_layer(state) biton(state) | ||
54 | #elif defined(LAYER_STATE_16BIT) | ||
55 | typedef uint16_t layer_state_t; | ||
56 | # define MAX_LAYER_BITS 4 | ||
57 | # ifndef MAX_LAYER | ||
58 | # define MAX_LAYER 16 | ||
59 | # endif | ||
60 | # define get_highest_layer(state) biton16(state) | ||
61 | #elif defined(LAYER_STATE_32BIT) | ||
62 | typedef uint32_t layer_state_t; | ||
63 | # define MAX_LAYER_BITS 5 | ||
64 | # ifndef MAX_LAYER | ||
65 | # define MAX_LAYER 32 | ||
66 | # endif | ||
67 | # define get_highest_layer(state) biton32(state) | ||
68 | #else | ||
69 | # error Layer Mask size not specified. HOW?! | ||
70 | #endif | ||
71 | |||
72 | /* | ||
73 | * Default Layer | ||
74 | */ | ||
75 | extern layer_state_t default_layer_state; | ||
76 | void default_layer_debug(void); | ||
77 | void default_layer_set(layer_state_t state); | ||
78 | |||
79 | __attribute__((weak)) layer_state_t default_layer_state_set_kb(layer_state_t state); | ||
80 | __attribute__((weak)) layer_state_t default_layer_state_set_user(layer_state_t state); | ||
81 | |||
82 | #ifndef NO_ACTION_LAYER | ||
83 | /* bitwise operation */ | ||
84 | void default_layer_or(layer_state_t state); | ||
85 | void default_layer_and(layer_state_t state); | ||
86 | void default_layer_xor(layer_state_t state); | ||
87 | #else | ||
88 | # define default_layer_or(state) | ||
89 | # define default_layer_and(state) | ||
90 | # define default_layer_xor(state) | ||
91 | #endif | ||
92 | |||
93 | /* | ||
94 | * Keymap Layer | ||
95 | */ | ||
96 | #ifndef NO_ACTION_LAYER | ||
97 | extern layer_state_t layer_state; | ||
98 | |||
99 | void layer_state_set(layer_state_t state); | ||
100 | bool layer_state_is(uint8_t layer); | ||
101 | bool layer_state_cmp(layer_state_t layer1, uint8_t layer2); | ||
102 | |||
103 | void layer_debug(void); | ||
104 | void layer_clear(void); | ||
105 | void layer_move(uint8_t layer); | ||
106 | void layer_on(uint8_t layer); | ||
107 | void layer_off(uint8_t layer); | ||
108 | void layer_invert(uint8_t layer); | ||
109 | /* bitwise operation */ | ||
110 | void layer_or(layer_state_t state); | ||
111 | void layer_and(layer_state_t state); | ||
112 | void layer_xor(layer_state_t state); | ||
113 | layer_state_t layer_state_set_user(layer_state_t state); | ||
114 | layer_state_t layer_state_set_kb(layer_state_t state); | ||
115 | #else | ||
116 | # define layer_state 0 | ||
117 | |||
118 | # define layer_state_set(layer) | ||
119 | # define layer_state_is(layer) (layer == 0) | ||
120 | # define layer_state_cmp(state, layer) (state == 0 ? layer == 0 : (state & (layer_state_t)1 << layer) != 0) | ||
121 | |||
122 | # define layer_debug() | ||
123 | # define layer_clear() | ||
124 | # define layer_move(layer) (void)layer | ||
125 | # define layer_on(layer) (void)layer | ||
126 | # define layer_off(layer) (void)layer | ||
127 | # define layer_invert(layer) (void)layer | ||
128 | # define layer_or(state) (void)state | ||
129 | # define layer_and(state) (void)state | ||
130 | # define layer_xor(state) (void)state | ||
131 | # define layer_state_set_kb(state) (void)state | ||
132 | # define layer_state_set_user(state) (void)state | ||
133 | #endif | ||
134 | |||
135 | /* pressed actions cache */ | ||
136 | #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) | ||
137 | |||
138 | void update_source_layers_cache(keypos_t key, uint8_t layer); | ||
139 | uint8_t read_source_layers_cache(keypos_t key); | ||
140 | #endif | ||
141 | action_t store_or_get_action(bool pressed, keypos_t key); | ||
142 | |||
143 | /* return the topmost non-transparent layer currently associated with key */ | ||
144 | uint8_t layer_switch_get_layer(keypos_t key); | ||
145 | |||
146 | /* return action depending on current layer status */ | ||
147 | action_t layer_switch_get_action(keypos_t key); | ||
diff --git a/tmk_core/common/action_macro.c b/tmk_core/common/action_macro.c deleted file mode 100644 index 92228c0ba..000000000 --- a/tmk_core/common/action_macro.c +++ /dev/null | |||
@@ -1,93 +0,0 @@ | |||
1 | /* | ||
2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
3 | |||
4 | This program is free software: you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation, either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | #include "action.h" | ||
18 | #include "action_util.h" | ||
19 | #include "action_macro.h" | ||
20 | #include "wait.h" | ||
21 | |||
22 | #ifdef DEBUG_ACTION | ||
23 | # include "debug.h" | ||
24 | #else | ||
25 | # include "nodebug.h" | ||
26 | #endif | ||
27 | |||
28 | #ifndef NO_ACTION_MACRO | ||
29 | |||
30 | # define MACRO_READ() (macro = MACRO_GET(macro_p++)) | ||
31 | /** \brief Action Macro Play | ||
32 | * | ||
33 | * FIXME: Needs doc | ||
34 | */ | ||
35 | void action_macro_play(const macro_t *macro_p) { | ||
36 | macro_t macro = END; | ||
37 | uint8_t interval = 0; | ||
38 | |||
39 | if (!macro_p) return; | ||
40 | while (true) { | ||
41 | switch (MACRO_READ()) { | ||
42 | case KEY_DOWN: | ||
43 | MACRO_READ(); | ||
44 | dprintf("KEY_DOWN(%02X)\n", macro); | ||
45 | if (IS_MOD(macro)) { | ||
46 | add_macro_mods(MOD_BIT(macro)); | ||
47 | send_keyboard_report(); | ||
48 | } else { | ||
49 | register_code(macro); | ||
50 | } | ||
51 | break; | ||
52 | case KEY_UP: | ||
53 | MACRO_READ(); | ||
54 | dprintf("KEY_UP(%02X)\n", macro); | ||
55 | if (IS_MOD(macro)) { | ||
56 | del_macro_mods(MOD_BIT(macro)); | ||
57 | send_keyboard_report(); | ||
58 | } else { | ||
59 | unregister_code(macro); | ||
60 | } | ||
61 | break; | ||
62 | case WAIT: | ||
63 | MACRO_READ(); | ||
64 | dprintf("WAIT(%u)\n", macro); | ||
65 | { | ||
66 | uint8_t ms = macro; | ||
67 | while (ms--) wait_ms(1); | ||
68 | } | ||
69 | break; | ||
70 | case INTERVAL: | ||
71 | interval = MACRO_READ(); | ||
72 | dprintf("INTERVAL(%u)\n", interval); | ||
73 | break; | ||
74 | case 0x04 ... 0x73: | ||
75 | dprintf("DOWN(%02X)\n", macro); | ||
76 | register_code(macro); | ||
77 | break; | ||
78 | case 0x84 ... 0xF3: | ||
79 | dprintf("UP(%02X)\n", macro); | ||
80 | unregister_code(macro & 0x7F); | ||
81 | break; | ||
82 | case END: | ||
83 | default: | ||
84 | return; | ||
85 | } | ||
86 | // interval | ||
87 | { | ||
88 | uint8_t ms = interval; | ||
89 | while (ms--) wait_ms(1); | ||
90 | } | ||
91 | } | ||
92 | } | ||
93 | #endif | ||
diff --git a/tmk_core/common/action_macro.h b/tmk_core/common/action_macro.h deleted file mode 100644 index 685e2c6ff..000000000 --- a/tmk_core/common/action_macro.h +++ /dev/null | |||
@@ -1,123 +0,0 @@ | |||
1 | /* | ||
2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
3 | |||
4 | This program is free software: you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation, either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #pragma once | ||
19 | |||
20 | #include <stdint.h> | ||
21 | #include "progmem.h" | ||
22 | |||
23 | typedef uint8_t macro_t; | ||
24 | |||
25 | #define MACRO_NONE (macro_t *)0 | ||
26 | #define MACRO(...) \ | ||
27 | ({ \ | ||
28 | static const macro_t __m[] PROGMEM = {__VA_ARGS__}; \ | ||
29 | &__m[0]; \ | ||
30 | }) | ||
31 | #define MACRO_GET(p) pgm_read_byte(p) | ||
32 | |||
33 | // Sends press when the macro key is pressed, release when release, or tap_macro when the key has been tapped | ||
34 | #define MACRO_TAP_HOLD(record, press, release, tap_macro) (((record)->event.pressed) ? (((record)->tap.count <= 0 || (record)->tap.interrupted) ? (press) : MACRO_NONE) : (((record)->tap.count > 0 && !((record)->tap.interrupted)) ? (tap_macro) : (release))) | ||
35 | |||
36 | // Holds down the modifier mod when the macro key is held, or sends macro instead when tapped | ||
37 | #define MACRO_TAP_HOLD_MOD(record, macro, mod) MACRO_TAP_HOLD(record, (MACRO(D(mod), END)), MACRO(U(mod), END), macro) | ||
38 | |||
39 | // Holds down the modifier mod when the macro key is held, or pressed a shifted key when tapped (eg: shift+3 for #) | ||
40 | #define MACRO_TAP_SHFT_KEY_HOLD_MOD(record, key, mod) MACRO_TAP_HOLD_MOD(record, (MACRO(I(10), D(LSFT), T(key), U(LSFT), END)), mod) | ||
41 | |||
42 | // Momentary switch layer when held, sends macro if tapped | ||
43 | #define MACRO_TAP_HOLD_LAYER(record, macro, layer) \ | ||
44 | (((record)->event.pressed) ? (((record)->tap.count <= 0 || (record)->tap.interrupted) ? ({ \ | ||
45 | layer_on((layer)); \ | ||
46 | MACRO_NONE; \ | ||
47 | }) \ | ||
48 | : MACRO_NONE) \ | ||
49 | : (((record)->tap.count > 0 && !((record)->tap.interrupted)) ? (macro) : ({ \ | ||
50 | layer_off((layer)); \ | ||
51 | MACRO_NONE; \ | ||
52 | }))) | ||
53 | |||
54 | // Momentary switch layer when held, presses a shifted key when tapped (eg: shift+3 for #) | ||
55 | #define MACRO_TAP_SHFT_KEY_HOLD_LAYER(record, key, layer) MACRO_TAP_HOLD_LAYER(record, MACRO(I(10), D(LSFT), T(key), U(LSFT), END), layer) | ||
56 | |||
57 | #ifndef NO_ACTION_MACRO | ||
58 | void action_macro_play(const macro_t *macro_p); | ||
59 | #else | ||
60 | # define action_macro_play(macro) | ||
61 | #endif | ||
62 | |||
63 | /* Macro commands | ||
64 | * code(0x04-73) // key down(1byte) | ||
65 | * code(0x04-73) | 0x80 // key up(1byte) | ||
66 | * { KEY_DOWN, code(0x04-0xff) } // key down(2bytes) | ||
67 | * { KEY_UP, code(0x04-0xff) } // key up(2bytes) | ||
68 | * WAIT // wait milli-seconds | ||
69 | * INTERVAL // set interval between macro commands | ||
70 | * END // stop macro execution | ||
71 | * | ||
72 | * Ideas(Not implemented): | ||
73 | * modifiers | ||
74 | * system usage | ||
75 | * consumer usage | ||
76 | * unicode usage | ||
77 | * function call | ||
78 | * conditionals | ||
79 | * loop | ||
80 | */ | ||
81 | enum macro_command_id { | ||
82 | /* 0x00 - 0x03 */ | ||
83 | END = 0x00, | ||
84 | KEY_DOWN, | ||
85 | KEY_UP, | ||
86 | |||
87 | /* 0x04 - 0x73 (reserved for keycode down) */ | ||
88 | |||
89 | /* 0x74 - 0x83 */ | ||
90 | WAIT = 0x74, | ||
91 | INTERVAL, | ||
92 | |||
93 | /* 0x84 - 0xf3 (reserved for keycode up) */ | ||
94 | |||
95 | /* 0xf4 - 0xff */ | ||
96 | }; | ||
97 | |||
98 | /* TODO: keycode:0x04-0x73 can be handled by 1byte command else 2bytes are needed | ||
99 | * if keycode between 0x04 and 0x73 | ||
100 | * keycode / (keycode|0x80) | ||
101 | * else | ||
102 | * {KEY_DOWN, keycode} / {KEY_UP, keycode} | ||
103 | */ | ||
104 | #define DOWN(key) KEY_DOWN, (key) | ||
105 | #define UP(key) KEY_UP, (key) | ||
106 | #define TYPE(key) DOWN(key), UP(key) | ||
107 | #define WAIT(ms) WAIT, (ms) | ||
108 | #define INTERVAL(ms) INTERVAL, (ms) | ||
109 | |||
110 | /* key down */ | ||
111 | #define D(key) DOWN(KC_##key) | ||
112 | /* key up */ | ||
113 | #define U(key) UP(KC_##key) | ||
114 | /* key type */ | ||
115 | #define T(key) TYPE(KC_##key) | ||
116 | /* wait */ | ||
117 | #define W(ms) WAIT(ms) | ||
118 | /* interval */ | ||
119 | #define I(ms) INTERVAL(ms) | ||
120 | |||
121 | /* for backward comaptibility */ | ||
122 | #define MD(key) DOWN(KC_##key) | ||
123 | #define MU(key) UP(KC_##key) | ||
diff --git a/tmk_core/common/action_tapping.c b/tmk_core/common/action_tapping.c deleted file mode 100644 index 36839f9fa..000000000 --- a/tmk_core/common/action_tapping.c +++ /dev/null | |||
@@ -1,456 +0,0 @@ | |||
1 | #include <stdint.h> | ||
2 | #include <stdbool.h> | ||
3 | #include "action.h" | ||
4 | #include "action_layer.h" | ||
5 | #include "action_tapping.h" | ||
6 | #include "keycode.h" | ||
7 | #include "timer.h" | ||
8 | |||
9 | #ifdef DEBUG_ACTION | ||
10 | # include "debug.h" | ||
11 | #else | ||
12 | # include "nodebug.h" | ||
13 | #endif | ||
14 | |||
15 | #ifndef NO_ACTION_TAPPING | ||
16 | |||
17 | # define IS_TAPPING() !IS_NOEVENT(tapping_key.event) | ||
18 | # define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed) | ||
19 | # define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed) | ||
20 | # define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k))) | ||
21 | #ifndef COMBO_ENABLE | ||
22 | # define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key))) | ||
23 | #else | ||
24 | # define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key)) && tapping_key.keycode == r->keycode) | ||
25 | #endif | ||
26 | |||
27 | __attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { return TAPPING_TERM; } | ||
28 | |||
29 | # ifdef TAPPING_TERM_PER_KEY | ||
30 | # define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < get_tapping_term(get_record_keycode(&tapping_key, false), &tapping_key)) | ||
31 | # else | ||
32 | # define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAPPING_TERM) | ||
33 | # endif | ||
34 | |||
35 | # ifdef TAPPING_FORCE_HOLD_PER_KEY | ||
36 | __attribute__((weak)) bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record) { return false; } | ||
37 | # endif | ||
38 | |||
39 | # ifdef PERMISSIVE_HOLD_PER_KEY | ||
40 | __attribute__((weak)) bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) { return false; } | ||
41 | # endif | ||
42 | |||
43 | # ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY | ||
44 | __attribute__((weak)) bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { return false; } | ||
45 | # endif | ||
46 | |||
47 | static keyrecord_t tapping_key = {}; | ||
48 | static keyrecord_t waiting_buffer[WAITING_BUFFER_SIZE] = {}; | ||
49 | static uint8_t waiting_buffer_head = 0; | ||
50 | static uint8_t waiting_buffer_tail = 0; | ||
51 | |||
52 | static bool process_tapping(keyrecord_t *record); | ||
53 | static bool waiting_buffer_enq(keyrecord_t record); | ||
54 | static void waiting_buffer_clear(void); | ||
55 | static bool waiting_buffer_typed(keyevent_t event); | ||
56 | static bool waiting_buffer_has_anykey_pressed(void); | ||
57 | static void waiting_buffer_scan_tap(void); | ||
58 | static void debug_tapping_key(void); | ||
59 | static void debug_waiting_buffer(void); | ||
60 | |||
61 | /** \brief Action Tapping Process | ||
62 | * | ||
63 | * FIXME: Needs doc | ||
64 | */ | ||
65 | void action_tapping_process(keyrecord_t record) { | ||
66 | if (process_tapping(&record)) { | ||
67 | if (!IS_NOEVENT(record.event)) { | ||
68 | debug("processed: "); | ||
69 | debug_record(record); | ||
70 | debug("\n"); | ||
71 | } | ||
72 | } else { | ||
73 | if (!waiting_buffer_enq(record)) { | ||
74 | // clear all in case of overflow. | ||
75 | debug("OVERFLOW: CLEAR ALL STATES\n"); | ||
76 | clear_keyboard(); | ||
77 | waiting_buffer_clear(); | ||
78 | tapping_key = (keyrecord_t){}; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | // process waiting_buffer | ||
83 | if (!IS_NOEVENT(record.event) && waiting_buffer_head != waiting_buffer_tail) { | ||
84 | debug("---- action_exec: process waiting_buffer -----\n"); | ||
85 | } | ||
86 | for (; waiting_buffer_tail != waiting_buffer_head; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) { | ||
87 | if (process_tapping(&waiting_buffer[waiting_buffer_tail])) { | ||
88 | debug("processed: waiting_buffer["); | ||
89 | debug_dec(waiting_buffer_tail); | ||
90 | debug("] = "); | ||
91 | debug_record(waiting_buffer[waiting_buffer_tail]); | ||
92 | debug("\n\n"); | ||
93 | } else { | ||
94 | break; | ||
95 | } | ||
96 | } | ||
97 | if (!IS_NOEVENT(record.event)) { | ||
98 | debug("\n"); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | /** \brief Tapping | ||
103 | * | ||
104 | * Rule: Tap key is typed(pressed and released) within TAPPING_TERM. | ||
105 | * (without interfering by typing other key) | ||
106 | */ | ||
107 | /* return true when key event is processed or consumed. */ | ||
108 | bool process_tapping(keyrecord_t *keyp) { | ||
109 | keyevent_t event = keyp->event; | ||
110 | |||
111 | // if tapping | ||
112 | if (IS_TAPPING_PRESSED()) { | ||
113 | if (WITHIN_TAPPING_TERM(event)) { | ||
114 | if (tapping_key.tap.count == 0) { | ||
115 | if (IS_TAPPING_RECORD(keyp) && !event.pressed) { | ||
116 | // first tap! | ||
117 | debug("Tapping: First tap(0->1).\n"); | ||
118 | tapping_key.tap.count = 1; | ||
119 | debug_tapping_key(); | ||
120 | process_record(&tapping_key); | ||
121 | |||
122 | // copy tapping state | ||
123 | keyp->tap = tapping_key.tap; | ||
124 | // enqueue | ||
125 | return false; | ||
126 | } | ||
127 | /* Process a key typed within TAPPING_TERM | ||
128 | * This can register the key before settlement of tapping, | ||
129 | * useful for long TAPPING_TERM but may prevent fast typing. | ||
130 | */ | ||
131 | # if defined(TAPPING_TERM_PER_KEY) || (TAPPING_TERM >= 500) || defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY) | ||
132 | else if ((( | ||
133 | # ifdef TAPPING_TERM_PER_KEY | ||
134 | get_tapping_term(get_record_keycode(&tapping_key, false), keyp) | ||
135 | # else | ||
136 | TAPPING_TERM | ||
137 | # endif | ||
138 | >= 500) | ||
139 | |||
140 | # ifdef PERMISSIVE_HOLD_PER_KEY | ||
141 | || get_permissive_hold(get_record_keycode(&tapping_key, false), keyp) | ||
142 | # elif defined(PERMISSIVE_HOLD) | ||
143 | || true | ||
144 | # endif | ||
145 | ) && | ||
146 | IS_RELEASED(event) && waiting_buffer_typed(event)) { | ||
147 | debug("Tapping: End. No tap. Interfered by typing key\n"); | ||
148 | process_record(&tapping_key); | ||
149 | tapping_key = (keyrecord_t){}; | ||
150 | debug_tapping_key(); | ||
151 | // enqueue | ||
152 | return false; | ||
153 | } | ||
154 | # endif | ||
155 | /* Process release event of a key pressed before tapping starts | ||
156 | * Without this unexpected repeating will occur with having fast repeating setting | ||
157 | * https://github.com/tmk/tmk_keyboard/issues/60 | ||
158 | */ | ||
159 | else if (IS_RELEASED(event) && !waiting_buffer_typed(event)) { | ||
160 | // Modifier should be retained till end of this tapping. | ||
161 | action_t action = layer_switch_get_action(event.key); | ||
162 | switch (action.kind.id) { | ||
163 | case ACT_LMODS: | ||
164 | case ACT_RMODS: | ||
165 | if (action.key.mods && !action.key.code) return false; | ||
166 | if (IS_MOD(action.key.code)) return false; | ||
167 | break; | ||
168 | case ACT_LMODS_TAP: | ||
169 | case ACT_RMODS_TAP: | ||
170 | if (action.key.mods && keyp->tap.count == 0) return false; | ||
171 | if (IS_MOD(action.key.code)) return false; | ||
172 | break; | ||
173 | } | ||
174 | // Release of key should be process immediately. | ||
175 | debug("Tapping: release event of a key pressed before tapping\n"); | ||
176 | process_record(keyp); | ||
177 | return true; | ||
178 | } else { | ||
179 | // set interrupted flag when other key preesed during tapping | ||
180 | if (event.pressed) { | ||
181 | tapping_key.tap.interrupted = true; | ||
182 | # if defined(HOLD_ON_OTHER_KEY_PRESS) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) | ||
183 | # if defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) | ||
184 | if (get_hold_on_other_key_press(get_record_keycode(&tapping_key, false), keyp)) | ||
185 | # endif | ||
186 | { | ||
187 | debug("Tapping: End. No tap. Interfered by pressed key\n"); | ||
188 | process_record(&tapping_key); | ||
189 | tapping_key = (keyrecord_t){}; | ||
190 | debug_tapping_key(); | ||
191 | // enqueue | ||
192 | return false; | ||
193 | } | ||
194 | # endif | ||
195 | } | ||
196 | // enqueue | ||
197 | return false; | ||
198 | } | ||
199 | } | ||
200 | // tap_count > 0 | ||
201 | else { | ||
202 | if (IS_TAPPING_RECORD(keyp) && !event.pressed) { | ||
203 | debug("Tapping: Tap release("); | ||
204 | debug_dec(tapping_key.tap.count); | ||
205 | debug(")\n"); | ||
206 | keyp->tap = tapping_key.tap; | ||
207 | process_record(keyp); | ||
208 | tapping_key = *keyp; | ||
209 | debug_tapping_key(); | ||
210 | return true; | ||
211 | } else if (is_tap_record(keyp) && event.pressed) { | ||
212 | if (tapping_key.tap.count > 1) { | ||
213 | debug("Tapping: Start new tap with releasing last tap(>1).\n"); | ||
214 | // unregister key | ||
215 | process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false, | ||
216 | #ifdef COMBO_ENABLE | ||
217 | .keycode = tapping_key.keycode, | ||
218 | #endif | ||
219 | }); | ||
220 | } else { | ||
221 | debug("Tapping: Start while last tap(1).\n"); | ||
222 | } | ||
223 | tapping_key = *keyp; | ||
224 | waiting_buffer_scan_tap(); | ||
225 | debug_tapping_key(); | ||
226 | return true; | ||
227 | } else { | ||
228 | if (!IS_NOEVENT(event)) { | ||
229 | debug("Tapping: key event while last tap(>0).\n"); | ||
230 | } | ||
231 | process_record(keyp); | ||
232 | return true; | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | // after TAPPING_TERM | ||
237 | else { | ||
238 | if (tapping_key.tap.count == 0) { | ||
239 | debug("Tapping: End. Timeout. Not tap(0): "); | ||
240 | debug_event(event); | ||
241 | debug("\n"); | ||
242 | process_record(&tapping_key); | ||
243 | tapping_key = (keyrecord_t){}; | ||
244 | debug_tapping_key(); | ||
245 | return false; | ||
246 | } else { | ||
247 | if (IS_TAPPING_RECORD(keyp) && !event.pressed) { | ||
248 | debug("Tapping: End. last timeout tap release(>0)."); | ||
249 | keyp->tap = tapping_key.tap; | ||
250 | process_record(keyp); | ||
251 | tapping_key = (keyrecord_t){}; | ||
252 | return true; | ||
253 | } else if (is_tap_record(keyp) && event.pressed) { | ||
254 | if (tapping_key.tap.count > 1) { | ||
255 | debug("Tapping: Start new tap with releasing last timeout tap(>1).\n"); | ||
256 | // unregister key | ||
257 | process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false, | ||
258 | #ifdef COMBO_ENABLE | ||
259 | .keycode = tapping_key.keycode, | ||
260 | #endif | ||
261 | }); | ||
262 | } else { | ||
263 | debug("Tapping: Start while last timeout tap(1).\n"); | ||
264 | } | ||
265 | tapping_key = *keyp; | ||
266 | waiting_buffer_scan_tap(); | ||
267 | debug_tapping_key(); | ||
268 | return true; | ||
269 | } else { | ||
270 | if (!IS_NOEVENT(event)) { | ||
271 | debug("Tapping: key event while last timeout tap(>0).\n"); | ||
272 | } | ||
273 | process_record(keyp); | ||
274 | return true; | ||
275 | } | ||
276 | } | ||
277 | } | ||
278 | } else if (IS_TAPPING_RELEASED()) { | ||
279 | if (WITHIN_TAPPING_TERM(event)) { | ||
280 | if (event.pressed) { | ||
281 | if (IS_TAPPING_RECORD(keyp)) { | ||
282 | //# ifndef TAPPING_FORCE_HOLD | ||
283 | # if !defined(TAPPING_FORCE_HOLD) || defined(TAPPING_FORCE_HOLD_PER_KEY) | ||
284 | if ( | ||
285 | # ifdef TAPPING_FORCE_HOLD_PER_KEY | ||
286 | !get_tapping_force_hold(get_record_keycode(&tapping_key, false), keyp) && | ||
287 | # endif | ||
288 | !tapping_key.tap.interrupted && tapping_key.tap.count > 0) { | ||
289 | // sequential tap. | ||
290 | keyp->tap = tapping_key.tap; | ||
291 | if (keyp->tap.count < 15) keyp->tap.count += 1; | ||
292 | debug("Tapping: Tap press("); | ||
293 | debug_dec(keyp->tap.count); | ||
294 | debug(")\n"); | ||
295 | process_record(keyp); | ||
296 | tapping_key = *keyp; | ||
297 | debug_tapping_key(); | ||
298 | return true; | ||
299 | } | ||
300 | # endif | ||
301 | // FIX: start new tap again | ||
302 | tapping_key = *keyp; | ||
303 | return true; | ||
304 | } else if (is_tap_record(keyp)) { | ||
305 | // Sequential tap can be interfered with other tap key. | ||
306 | debug("Tapping: Start with interfering other tap.\n"); | ||
307 | tapping_key = *keyp; | ||
308 | waiting_buffer_scan_tap(); | ||
309 | debug_tapping_key(); | ||
310 | return true; | ||
311 | } else { | ||
312 | // should none in buffer | ||
313 | // FIX: interrupted when other key is pressed | ||
314 | tapping_key.tap.interrupted = true; | ||
315 | process_record(keyp); | ||
316 | return true; | ||
317 | } | ||
318 | } else { | ||
319 | if (!IS_NOEVENT(event)) debug("Tapping: other key just after tap.\n"); | ||
320 | process_record(keyp); | ||
321 | return true; | ||
322 | } | ||
323 | } else { | ||
324 | // FIX: process_action here? | ||
325 | // timeout. no sequential tap. | ||
326 | debug("Tapping: End(Timeout after releasing last tap): "); | ||
327 | debug_event(event); | ||
328 | debug("\n"); | ||
329 | tapping_key = (keyrecord_t){}; | ||
330 | debug_tapping_key(); | ||
331 | return false; | ||
332 | } | ||
333 | } | ||
334 | // not tapping state | ||
335 | else { | ||
336 | if (event.pressed && is_tap_record(keyp)) { | ||
337 | debug("Tapping: Start(Press tap key).\n"); | ||
338 | tapping_key = *keyp; | ||
339 | process_record_tap_hint(&tapping_key); | ||
340 | waiting_buffer_scan_tap(); | ||
341 | debug_tapping_key(); | ||
342 | return true; | ||
343 | } else { | ||
344 | process_record(keyp); | ||
345 | return true; | ||
346 | } | ||
347 | } | ||
348 | } | ||
349 | |||
350 | /** \brief Waiting buffer enq | ||
351 | * | ||
352 | * FIXME: Needs docs | ||
353 | */ | ||
354 | bool waiting_buffer_enq(keyrecord_t record) { | ||
355 | if (IS_NOEVENT(record.event)) { | ||
356 | return true; | ||
357 | } | ||
358 | |||
359 | if ((waiting_buffer_head + 1) % WAITING_BUFFER_SIZE == waiting_buffer_tail) { | ||
360 | debug("waiting_buffer_enq: Over flow.\n"); | ||
361 | return false; | ||
362 | } | ||
363 | |||
364 | waiting_buffer[waiting_buffer_head] = record; | ||
365 | waiting_buffer_head = (waiting_buffer_head + 1) % WAITING_BUFFER_SIZE; | ||
366 | |||
367 | debug("waiting_buffer_enq: "); | ||
368 | debug_waiting_buffer(); | ||
369 | return true; | ||
370 | } | ||
371 | |||
372 | /** \brief Waiting buffer clear | ||
373 | * | ||
374 | * FIXME: Needs docs | ||
375 | */ | ||
376 | void waiting_buffer_clear(void) { | ||
377 | waiting_buffer_head = 0; | ||
378 | waiting_buffer_tail = 0; | ||
379 | } | ||
380 | |||
381 | /** \brief Waiting buffer typed | ||
382 | * | ||
383 | * FIXME: Needs docs | ||
384 | */ | ||
385 | bool waiting_buffer_typed(keyevent_t event) { | ||
386 | for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) { | ||
387 | if (KEYEQ(event.key, waiting_buffer[i].event.key) && event.pressed != waiting_buffer[i].event.pressed) { | ||
388 | return true; | ||
389 | } | ||
390 | } | ||
391 | return false; | ||
392 | } | ||
393 | |||
394 | /** \brief Waiting buffer has anykey pressed | ||
395 | * | ||
396 | * FIXME: Needs docs | ||
397 | */ | ||
398 | __attribute__((unused)) bool waiting_buffer_has_anykey_pressed(void) { | ||
399 | for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) { | ||
400 | if (waiting_buffer[i].event.pressed) return true; | ||
401 | } | ||
402 | return false; | ||
403 | } | ||
404 | |||
405 | /** \brief Scan buffer for tapping | ||
406 | * | ||
407 | * FIXME: Needs docs | ||
408 | */ | ||
409 | void waiting_buffer_scan_tap(void) { | ||
410 | // tapping already is settled | ||
411 | if (tapping_key.tap.count > 0) return; | ||
412 | // invalid state: tapping_key released && tap.count == 0 | ||
413 | if (!tapping_key.event.pressed) return; | ||
414 | |||
415 | for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) { | ||
416 | if (IS_TAPPING_KEY(waiting_buffer[i].event.key) && !waiting_buffer[i].event.pressed && WITHIN_TAPPING_TERM(waiting_buffer[i].event)) { | ||
417 | tapping_key.tap.count = 1; | ||
418 | waiting_buffer[i].tap.count = 1; | ||
419 | process_record(&tapping_key); | ||
420 | |||
421 | debug("waiting_buffer_scan_tap: found at ["); | ||
422 | debug_dec(i); | ||
423 | debug("]\n"); | ||
424 | debug_waiting_buffer(); | ||
425 | return; | ||
426 | } | ||
427 | } | ||
428 | } | ||
429 | |||
430 | /** \brief Tapping key debug print | ||
431 | * | ||
432 | * FIXME: Needs docs | ||
433 | */ | ||
434 | static void debug_tapping_key(void) { | ||
435 | debug("TAPPING_KEY="); | ||
436 | debug_record(tapping_key); | ||
437 | debug("\n"); | ||
438 | } | ||
439 | |||
440 | /** \brief Waiting buffer debug print | ||
441 | * | ||
442 | * FIXME: Needs docs | ||
443 | */ | ||
444 | static void debug_waiting_buffer(void) { | ||
445 | debug("{ "); | ||
446 | for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) { | ||
447 | debug("["); | ||
448 | debug_dec(i); | ||
449 | debug("]="); | ||
450 | debug_record(waiting_buffer[i]); | ||
451 | debug(" "); | ||
452 | } | ||
453 | debug("}\n"); | ||
454 | } | ||
455 | |||
456 | #endif | ||
diff --git a/tmk_core/common/action_tapping.h b/tmk_core/common/action_tapping.h deleted file mode 100644 index 7de8049c7..000000000 --- a/tmk_core/common/action_tapping.h +++ /dev/null | |||
@@ -1,42 +0,0 @@ | |||
1 | /* | ||
2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
3 | |||
4 | This program is free software: you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation, either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #pragma once | ||
19 | |||
20 | /* period of tapping(ms) */ | ||
21 | #ifndef TAPPING_TERM | ||
22 | # define TAPPING_TERM 200 | ||
23 | #endif | ||
24 | |||
25 | /* tap count needed for toggling a feature */ | ||
26 | #ifndef TAPPING_TOGGLE | ||
27 | # define TAPPING_TOGGLE 5 | ||
28 | #endif | ||
29 | |||
30 | #define WAITING_BUFFER_SIZE 8 | ||
31 | |||
32 | #ifndef NO_ACTION_TAPPING | ||
33 | uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache); | ||
34 | uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache); | ||
35 | void action_tapping_process(keyrecord_t record); | ||
36 | |||
37 | uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record); | ||
38 | bool get_permissive_hold(uint16_t keycode, keyrecord_t *record); | ||
39 | bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record); | ||
40 | bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record); | ||
41 | bool get_retro_tapping(uint16_t keycode, keyrecord_t *record); | ||
42 | #endif | ||
diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c deleted file mode 100644 index 2b3c00cba..000000000 --- a/tmk_core/common/action_util.c +++ /dev/null | |||
@@ -1,455 +0,0 @@ | |||
1 | /* | ||
2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
3 | |||
4 | This program is free software: you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation, either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | #include "host.h" | ||
18 | #include "report.h" | ||
19 | #include "debug.h" | ||
20 | #include "action_util.h" | ||
21 | #include "action_layer.h" | ||
22 | #include "timer.h" | ||
23 | #include "keycode_config.h" | ||
24 | |||
25 | extern keymap_config_t keymap_config; | ||
26 | |||
27 | static uint8_t real_mods = 0; | ||
28 | static uint8_t weak_mods = 0; | ||
29 | static uint8_t macro_mods = 0; | ||
30 | #ifdef KEY_OVERRIDE_ENABLE | ||
31 | static uint8_t weak_override_mods = 0; | ||
32 | static uint8_t suppressed_mods = 0; | ||
33 | #endif | ||
34 | |||
35 | #ifdef USB_6KRO_ENABLE | ||
36 | # define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS) | ||
37 | # define RO_SUB(a, b) ((a - b + KEYBOARD_REPORT_KEYS) % KEYBOARD_REPORT_KEYS) | ||
38 | # define RO_INC(a) RO_ADD(a, 1) | ||
39 | # define RO_DEC(a) RO_SUB(a, 1) | ||
40 | static int8_t cb_head = 0; | ||
41 | static int8_t cb_tail = 0; | ||
42 | static int8_t cb_count = 0; | ||
43 | #endif | ||
44 | |||
45 | // TODO: pointer variable is not needed | ||
46 | // report_keyboard_t keyboard_report = {}; | ||
47 | report_keyboard_t *keyboard_report = &(report_keyboard_t){}; | ||
48 | |||
49 | extern inline void add_key(uint8_t key); | ||
50 | extern inline void del_key(uint8_t key); | ||
51 | extern inline void clear_keys(void); | ||
52 | |||
53 | #ifndef NO_ACTION_ONESHOT | ||
54 | static uint8_t oneshot_mods = 0; | ||
55 | static uint8_t oneshot_locked_mods = 0; | ||
56 | uint8_t get_oneshot_locked_mods(void) { return oneshot_locked_mods; } | ||
57 | void set_oneshot_locked_mods(uint8_t mods) { | ||
58 | if (mods != oneshot_locked_mods) { | ||
59 | oneshot_locked_mods = mods; | ||
60 | oneshot_locked_mods_changed_kb(oneshot_locked_mods); | ||
61 | } | ||
62 | } | ||
63 | void clear_oneshot_locked_mods(void) { | ||
64 | if (oneshot_locked_mods) { | ||
65 | oneshot_locked_mods = 0; | ||
66 | oneshot_locked_mods_changed_kb(oneshot_locked_mods); | ||
67 | } | ||
68 | } | ||
69 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
70 | static uint16_t oneshot_time = 0; | ||
71 | bool has_oneshot_mods_timed_out(void) { return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT; } | ||
72 | # else | ||
73 | bool has_oneshot_mods_timed_out(void) { return false; } | ||
74 | # endif | ||
75 | #endif | ||
76 | |||
77 | /* oneshot layer */ | ||
78 | #ifndef NO_ACTION_ONESHOT | ||
79 | /** \brief oneshot_layer_data bits | ||
80 | * LLLL LSSS | ||
81 | * where: | ||
82 | * L => are layer bits | ||
83 | * S => oneshot state bits | ||
84 | */ | ||
85 | static int8_t oneshot_layer_data = 0; | ||
86 | |||
87 | inline uint8_t get_oneshot_layer(void) { return oneshot_layer_data >> 3; } | ||
88 | inline uint8_t get_oneshot_layer_state(void) { return oneshot_layer_data & 0b111; } | ||
89 | |||
90 | # ifdef SWAP_HANDS_ENABLE | ||
91 | enum { | ||
92 | SHO_OFF, | ||
93 | SHO_ACTIVE, // Swap hands button was pressed, and we didn't send any swapped keys yet | ||
94 | SHO_PRESSED, // Swap hands button is currently pressed | ||
95 | SHO_USED, // Swap hands button is still pressed, and we already sent swapped keys | ||
96 | } swap_hands_oneshot = SHO_OFF; | ||
97 | # endif | ||
98 | |||
99 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
100 | static uint16_t oneshot_layer_time = 0; | ||
101 | inline bool has_oneshot_layer_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT && !(get_oneshot_layer_state() & ONESHOT_TOGGLED); } | ||
102 | # ifdef SWAP_HANDS_ENABLE | ||
103 | static uint16_t oneshot_swaphands_time = 0; | ||
104 | inline bool has_oneshot_swaphands_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_swaphands_time) >= ONESHOT_TIMEOUT && (swap_hands_oneshot == SHO_ACTIVE); } | ||
105 | # endif | ||
106 | # endif | ||
107 | |||
108 | # ifdef SWAP_HANDS_ENABLE | ||
109 | |||
110 | void set_oneshot_swaphands(void) { | ||
111 | swap_hands_oneshot = SHO_PRESSED; | ||
112 | swap_hands = true; | ||
113 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
114 | oneshot_swaphands_time = timer_read(); | ||
115 | if (oneshot_layer_time != 0) { | ||
116 | oneshot_layer_time = oneshot_swaphands_time; | ||
117 | } | ||
118 | # endif | ||
119 | } | ||
120 | |||
121 | void release_oneshot_swaphands(void) { | ||
122 | if (swap_hands_oneshot == SHO_PRESSED) { | ||
123 | swap_hands_oneshot = SHO_ACTIVE; | ||
124 | } | ||
125 | if (swap_hands_oneshot == SHO_USED) { | ||
126 | clear_oneshot_swaphands(); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | void use_oneshot_swaphands(void) { | ||
131 | if (swap_hands_oneshot == SHO_PRESSED) { | ||
132 | swap_hands_oneshot = SHO_USED; | ||
133 | } | ||
134 | if (swap_hands_oneshot == SHO_ACTIVE) { | ||
135 | clear_oneshot_swaphands(); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | void clear_oneshot_swaphands(void) { | ||
140 | swap_hands_oneshot = SHO_OFF; | ||
141 | swap_hands = false; | ||
142 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
143 | oneshot_swaphands_time = 0; | ||
144 | # endif | ||
145 | } | ||
146 | |||
147 | # endif | ||
148 | |||
149 | /** \brief Set oneshot layer | ||
150 | * | ||
151 | * FIXME: needs doc | ||
152 | */ | ||
153 | void set_oneshot_layer(uint8_t layer, uint8_t state) { | ||
154 | if (!keymap_config.oneshot_disable) { | ||
155 | oneshot_layer_data = layer << 3 | state; | ||
156 | layer_on(layer); | ||
157 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
158 | oneshot_layer_time = timer_read(); | ||
159 | # endif | ||
160 | oneshot_layer_changed_kb(get_oneshot_layer()); | ||
161 | } else { | ||
162 | layer_on(layer); | ||
163 | } | ||
164 | } | ||
165 | /** \brief Reset oneshot layer | ||
166 | * | ||
167 | * FIXME: needs doc | ||
168 | */ | ||
169 | void reset_oneshot_layer(void) { | ||
170 | oneshot_layer_data = 0; | ||
171 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
172 | oneshot_layer_time = 0; | ||
173 | # endif | ||
174 | oneshot_layer_changed_kb(get_oneshot_layer()); | ||
175 | } | ||
176 | /** \brief Clear oneshot layer | ||
177 | * | ||
178 | * FIXME: needs doc | ||
179 | */ | ||
180 | void clear_oneshot_layer_state(oneshot_fullfillment_t state) { | ||
181 | uint8_t start_state = oneshot_layer_data; | ||
182 | oneshot_layer_data &= ~state; | ||
183 | if ((!get_oneshot_layer_state() && start_state != oneshot_layer_data) || keymap_config.oneshot_disable) { | ||
184 | layer_off(get_oneshot_layer()); | ||
185 | reset_oneshot_layer(); | ||
186 | } | ||
187 | } | ||
188 | /** \brief Is oneshot layer active | ||
189 | * | ||
190 | * FIXME: needs doc | ||
191 | */ | ||
192 | bool is_oneshot_layer_active(void) { return get_oneshot_layer_state(); } | ||
193 | |||
194 | /** \brief set oneshot | ||
195 | * | ||
196 | * FIXME: needs doc | ||
197 | */ | ||
198 | void oneshot_set(bool active) { | ||
199 | if (keymap_config.oneshot_disable != active) { | ||
200 | keymap_config.oneshot_disable = active; | ||
201 | eeconfig_update_keymap(keymap_config.raw); | ||
202 | dprintf("Oneshot: active: %d\n", active); | ||
203 | } | ||
204 | } | ||
205 | |||
206 | /** \brief toggle oneshot | ||
207 | * | ||
208 | * FIXME: needs doc | ||
209 | */ | ||
210 | void oneshot_toggle(void) { oneshot_set(!keymap_config.oneshot_disable); } | ||
211 | |||
212 | /** \brief enable oneshot | ||
213 | * | ||
214 | * FIXME: needs doc | ||
215 | */ | ||
216 | void oneshot_enable(void) { oneshot_set(true); } | ||
217 | |||
218 | /** \brief disable oneshot | ||
219 | * | ||
220 | * FIXME: needs doc | ||
221 | */ | ||
222 | void oneshot_disable(void) { oneshot_set(false); } | ||
223 | |||
224 | bool is_oneshot_enabled(void) { return keymap_config.oneshot_disable; } | ||
225 | |||
226 | #endif | ||
227 | |||
228 | /** \brief Send keyboard report | ||
229 | * | ||
230 | * FIXME: needs doc | ||
231 | */ | ||
232 | void send_keyboard_report(void) { | ||
233 | keyboard_report->mods = real_mods; | ||
234 | keyboard_report->mods |= weak_mods; | ||
235 | keyboard_report->mods |= macro_mods; | ||
236 | |||
237 | #ifndef NO_ACTION_ONESHOT | ||
238 | if (oneshot_mods) { | ||
239 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
240 | if (has_oneshot_mods_timed_out()) { | ||
241 | dprintf("Oneshot: timeout\n"); | ||
242 | clear_oneshot_mods(); | ||
243 | } | ||
244 | # endif | ||
245 | keyboard_report->mods |= oneshot_mods; | ||
246 | if (has_anykey(keyboard_report)) { | ||
247 | clear_oneshot_mods(); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | #endif | ||
252 | |||
253 | #ifdef KEY_OVERRIDE_ENABLE | ||
254 | // These need to be last to be able to properly control key overrides | ||
255 | keyboard_report->mods &= ~suppressed_mods; | ||
256 | keyboard_report->mods |= weak_override_mods; | ||
257 | #endif | ||
258 | |||
259 | host_keyboard_send(keyboard_report); | ||
260 | } | ||
261 | |||
262 | /** \brief Get mods | ||
263 | * | ||
264 | * FIXME: needs doc | ||
265 | */ | ||
266 | uint8_t get_mods(void) { return real_mods; } | ||
267 | /** \brief add mods | ||
268 | * | ||
269 | * FIXME: needs doc | ||
270 | */ | ||
271 | void add_mods(uint8_t mods) { real_mods |= mods; } | ||
272 | /** \brief del mods | ||
273 | * | ||
274 | * FIXME: needs doc | ||
275 | */ | ||
276 | void del_mods(uint8_t mods) { real_mods &= ~mods; } | ||
277 | /** \brief set mods | ||
278 | * | ||
279 | * FIXME: needs doc | ||
280 | */ | ||
281 | void set_mods(uint8_t mods) { real_mods = mods; } | ||
282 | /** \brief clear mods | ||
283 | * | ||
284 | * FIXME: needs doc | ||
285 | */ | ||
286 | void clear_mods(void) { real_mods = 0; } | ||
287 | |||
288 | /** \brief get weak mods | ||
289 | * | ||
290 | * FIXME: needs doc | ||
291 | */ | ||
292 | uint8_t get_weak_mods(void) { return weak_mods; } | ||
293 | /** \brief add weak mods | ||
294 | * | ||
295 | * FIXME: needs doc | ||
296 | */ | ||
297 | void add_weak_mods(uint8_t mods) { weak_mods |= mods; } | ||
298 | /** \brief del weak mods | ||
299 | * | ||
300 | * FIXME: needs doc | ||
301 | */ | ||
302 | void del_weak_mods(uint8_t mods) { weak_mods &= ~mods; } | ||
303 | /** \brief set weak mods | ||
304 | * | ||
305 | * FIXME: needs doc | ||
306 | */ | ||
307 | void set_weak_mods(uint8_t mods) { weak_mods = mods; } | ||
308 | /** \brief clear weak mods | ||
309 | * | ||
310 | * FIXME: needs doc | ||
311 | */ | ||
312 | void clear_weak_mods(void) { weak_mods = 0; } | ||
313 | |||
314 | #ifdef KEY_OVERRIDE_ENABLE | ||
315 | /** \brief set weak mods used by key overrides. DO not call this manually | ||
316 | */ | ||
317 | void set_weak_override_mods(uint8_t mods) { weak_override_mods = mods; } | ||
318 | /** \brief clear weak mods used by key overrides. DO not call this manually | ||
319 | */ | ||
320 | void clear_weak_override_mods(void) { weak_override_mods = 0; } | ||
321 | |||
322 | /** \brief set suppressed mods used by key overrides. DO not call this manually | ||
323 | */ | ||
324 | void set_suppressed_override_mods(uint8_t mods) { suppressed_mods = mods; } | ||
325 | /** \brief clear suppressed mods used by key overrides. DO not call this manually | ||
326 | */ | ||
327 | void clear_suppressed_override_mods(void) { suppressed_mods = 0; } | ||
328 | #endif | ||
329 | |||
330 | /* macro modifier */ | ||
331 | /** \brief get macro mods | ||
332 | * | ||
333 | * FIXME: needs doc | ||
334 | */ | ||
335 | uint8_t get_macro_mods(void) { return macro_mods; } | ||
336 | /** \brief add macro mods | ||
337 | * | ||
338 | * FIXME: needs doc | ||
339 | */ | ||
340 | void add_macro_mods(uint8_t mods) { macro_mods |= mods; } | ||
341 | /** \brief del macro mods | ||
342 | * | ||
343 | * FIXME: needs doc | ||
344 | */ | ||
345 | void del_macro_mods(uint8_t mods) { macro_mods &= ~mods; } | ||
346 | /** \brief set macro mods | ||
347 | * | ||
348 | * FIXME: needs doc | ||
349 | */ | ||
350 | void set_macro_mods(uint8_t mods) { macro_mods = mods; } | ||
351 | /** \brief clear macro mods | ||
352 | * | ||
353 | * FIXME: needs doc | ||
354 | */ | ||
355 | void clear_macro_mods(void) { macro_mods = 0; } | ||
356 | |||
357 | #ifndef NO_ACTION_ONESHOT | ||
358 | /** \brief get oneshot mods | ||
359 | * | ||
360 | * FIXME: needs doc | ||
361 | */ | ||
362 | uint8_t get_oneshot_mods(void) { return oneshot_mods; } | ||
363 | |||
364 | void add_oneshot_mods(uint8_t mods) { | ||
365 | if ((oneshot_mods & mods) != mods) { | ||
366 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
367 | oneshot_time = timer_read(); | ||
368 | # endif | ||
369 | oneshot_mods |= mods; | ||
370 | oneshot_mods_changed_kb(mods); | ||
371 | } | ||
372 | } | ||
373 | |||
374 | void del_oneshot_mods(uint8_t mods) { | ||
375 | if (oneshot_mods & mods) { | ||
376 | oneshot_mods &= ~mods; | ||
377 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
378 | oneshot_time = oneshot_mods ? timer_read() : 0; | ||
379 | # endif | ||
380 | oneshot_mods_changed_kb(oneshot_mods); | ||
381 | } | ||
382 | } | ||
383 | |||
384 | /** \brief set oneshot mods | ||
385 | * | ||
386 | * FIXME: needs doc | ||
387 | */ | ||
388 | void set_oneshot_mods(uint8_t mods) { | ||
389 | if (!keymap_config.oneshot_disable) { | ||
390 | if (oneshot_mods != mods) { | ||
391 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
392 | oneshot_time = timer_read(); | ||
393 | # endif | ||
394 | oneshot_mods = mods; | ||
395 | oneshot_mods_changed_kb(mods); | ||
396 | } | ||
397 | } | ||
398 | } | ||
399 | |||
400 | /** \brief clear oneshot mods | ||
401 | * | ||
402 | * FIXME: needs doc | ||
403 | */ | ||
404 | void clear_oneshot_mods(void) { | ||
405 | if (oneshot_mods) { | ||
406 | oneshot_mods = 0; | ||
407 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
408 | oneshot_time = 0; | ||
409 | # endif | ||
410 | oneshot_mods_changed_kb(oneshot_mods); | ||
411 | } | ||
412 | } | ||
413 | #endif | ||
414 | |||
415 | /** \brief Called when the one shot modifiers have been changed. | ||
416 | * | ||
417 | * \param mods Contains the active modifiers active after the change. | ||
418 | */ | ||
419 | __attribute__((weak)) void oneshot_locked_mods_changed_user(uint8_t mods) {} | ||
420 | |||
421 | /** \brief Called when the locked one shot modifiers have been changed. | ||
422 | * | ||
423 | * \param mods Contains the active modifiers active after the change. | ||
424 | */ | ||
425 | __attribute__((weak)) void oneshot_locked_mods_changed_kb(uint8_t mods) { oneshot_locked_mods_changed_user(mods); } | ||
426 | |||
427 | /** \brief Called when the one shot modifiers have been changed. | ||
428 | * | ||
429 | * \param mods Contains the active modifiers active after the change. | ||
430 | */ | ||
431 | __attribute__((weak)) void oneshot_mods_changed_user(uint8_t mods) {} | ||
432 | |||
433 | /** \brief Called when the one shot modifiers have been changed. | ||
434 | * | ||
435 | * \param mods Contains the active modifiers active after the change. | ||
436 | */ | ||
437 | __attribute__((weak)) void oneshot_mods_changed_kb(uint8_t mods) { oneshot_mods_changed_user(mods); } | ||
438 | |||
439 | /** \brief Called when the one shot layers have been changed. | ||
440 | * | ||
441 | * \param layer Contains the layer that is toggled on, or zero when toggled off. | ||
442 | */ | ||
443 | __attribute__((weak)) void oneshot_layer_changed_user(uint8_t layer) {} | ||
444 | |||
445 | /** \brief Called when the one shot layers have been changed. | ||
446 | * | ||
447 | * \param layer Contains the layer that is toggled on, or zero when toggled off. | ||
448 | */ | ||
449 | __attribute__((weak)) void oneshot_layer_changed_kb(uint8_t layer) { oneshot_layer_changed_user(layer); } | ||
450 | |||
451 | /** \brief inspect keyboard state | ||
452 | * | ||
453 | * FIXME: needs doc | ||
454 | */ | ||
455 | uint8_t has_anymod(void) { return bitpop(real_mods); } | ||
diff --git a/tmk_core/common/action_util.h b/tmk_core/common/action_util.h deleted file mode 100644 index f2b3897ae..000000000 --- a/tmk_core/common/action_util.h +++ /dev/null | |||
@@ -1,105 +0,0 @@ | |||
1 | /* | ||
2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
3 | |||
4 | This program is free software: you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation, either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #pragma once | ||
19 | |||
20 | #include <stdint.h> | ||
21 | #include "report.h" | ||
22 | |||
23 | #ifdef __cplusplus | ||
24 | extern "C" { | ||
25 | #endif | ||
26 | |||
27 | extern report_keyboard_t *keyboard_report; | ||
28 | |||
29 | void send_keyboard_report(void); | ||
30 | |||
31 | /* key */ | ||
32 | inline void add_key(uint8_t key) { add_key_to_report(keyboard_report, key); } | ||
33 | |||
34 | inline void del_key(uint8_t key) { del_key_from_report(keyboard_report, key); } | ||
35 | |||
36 | inline void clear_keys(void) { clear_keys_from_report(keyboard_report); } | ||
37 | |||
38 | /* modifier */ | ||
39 | uint8_t get_mods(void); | ||
40 | void add_mods(uint8_t mods); | ||
41 | void del_mods(uint8_t mods); | ||
42 | void set_mods(uint8_t mods); | ||
43 | void clear_mods(void); | ||
44 | |||
45 | /* weak modifier */ | ||
46 | uint8_t get_weak_mods(void); | ||
47 | void add_weak_mods(uint8_t mods); | ||
48 | void del_weak_mods(uint8_t mods); | ||
49 | void set_weak_mods(uint8_t mods); | ||
50 | void clear_weak_mods(void); | ||
51 | |||
52 | /* macro modifier */ | ||
53 | uint8_t get_macro_mods(void); | ||
54 | void add_macro_mods(uint8_t mods); | ||
55 | void del_macro_mods(uint8_t mods); | ||
56 | void set_macro_mods(uint8_t mods); | ||
57 | void clear_macro_mods(void); | ||
58 | |||
59 | /* oneshot modifier */ | ||
60 | uint8_t get_oneshot_mods(void); | ||
61 | void add_oneshot_mods(uint8_t mods); | ||
62 | void del_oneshot_mods(uint8_t mods); | ||
63 | void set_oneshot_mods(uint8_t mods); | ||
64 | void clear_oneshot_mods(void); | ||
65 | bool has_oneshot_mods_timed_out(void); | ||
66 | |||
67 | uint8_t get_oneshot_locked_mods(void); | ||
68 | void set_oneshot_locked_mods(uint8_t mods); | ||
69 | void clear_oneshot_locked_mods(void); | ||
70 | |||
71 | typedef enum { ONESHOT_PRESSED = 0b01, ONESHOT_OTHER_KEY_PRESSED = 0b10, ONESHOT_START = 0b11, ONESHOT_TOGGLED = 0b100 } oneshot_fullfillment_t; | ||
72 | void set_oneshot_layer(uint8_t layer, uint8_t state); | ||
73 | uint8_t get_oneshot_layer(void); | ||
74 | void clear_oneshot_layer_state(oneshot_fullfillment_t state); | ||
75 | void reset_oneshot_layer(void); | ||
76 | bool is_oneshot_layer_active(void); | ||
77 | uint8_t get_oneshot_layer_state(void); | ||
78 | bool has_oneshot_layer_timed_out(void); | ||
79 | bool has_oneshot_swaphands_timed_out(void); | ||
80 | |||
81 | void oneshot_locked_mods_changed_user(uint8_t mods); | ||
82 | void oneshot_locked_mods_changed_kb(uint8_t mods); | ||
83 | void oneshot_mods_changed_user(uint8_t mods); | ||
84 | void oneshot_mods_changed_kb(uint8_t mods); | ||
85 | void oneshot_layer_changed_user(uint8_t layer); | ||
86 | void oneshot_layer_changed_kb(uint8_t layer); | ||
87 | |||
88 | void oneshot_toggle(void); | ||
89 | void oneshot_enable(void); | ||
90 | void oneshot_disable(void); | ||
91 | bool is_oneshot_enabled(void); | ||
92 | |||
93 | /* inspect */ | ||
94 | uint8_t has_anymod(void); | ||
95 | |||
96 | #ifdef SWAP_HANDS_ENABLE | ||
97 | void set_oneshot_swaphands(void); | ||
98 | void release_oneshot_swaphands(void); | ||
99 | void use_oneshot_swaphands(void); | ||
100 | void clear_oneshot_swaphands(void); | ||
101 | #endif | ||
102 | |||
103 | #ifdef __cplusplus | ||
104 | } | ||
105 | #endif | ||
diff --git a/tmk_core/common/eeconfig.c b/tmk_core/common/eeconfig.c deleted file mode 100644 index ffa56ab56..000000000 --- a/tmk_core/common/eeconfig.c +++ /dev/null | |||
@@ -1,211 +0,0 @@ | |||
1 | #include <stdint.h> | ||
2 | #include <stdbool.h> | ||
3 | #include "eeprom.h" | ||
4 | #include "eeconfig.h" | ||
5 | #include "action_layer.h" | ||
6 | |||
7 | #ifdef STM32_EEPROM_ENABLE | ||
8 | # include <hal.h> | ||
9 | # include "eeprom_stm32.h" | ||
10 | #endif | ||
11 | |||
12 | #if defined(EEPROM_DRIVER) | ||
13 | # include "eeprom_driver.h" | ||
14 | #endif | ||
15 | |||
16 | #if defined(HAPTIC_ENABLE) | ||
17 | # include "haptic.h" | ||
18 | #endif | ||
19 | |||
20 | /** \brief eeconfig enable | ||
21 | * | ||
22 | * FIXME: needs doc | ||
23 | */ | ||
24 | __attribute__((weak)) void eeconfig_init_user(void) { | ||
25 | // Reset user EEPROM value to blank, rather than to a set value | ||
26 | eeconfig_update_user(0); | ||
27 | } | ||
28 | |||
29 | __attribute__((weak)) void eeconfig_init_kb(void) { | ||
30 | // Reset Keyboard EEPROM value to blank, rather than to a set value | ||
31 | eeconfig_update_kb(0); | ||
32 | |||
33 | eeconfig_init_user(); | ||
34 | } | ||
35 | |||
36 | /* | ||
37 | * FIXME: needs doc | ||
38 | */ | ||
39 | void eeconfig_init_quantum(void) { | ||
40 | #ifdef STM32_EEPROM_ENABLE | ||
41 | EEPROM_Erase(); | ||
42 | #endif | ||
43 | #if defined(EEPROM_DRIVER) | ||
44 | eeprom_driver_erase(); | ||
45 | #endif | ||
46 | eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); | ||
47 | eeprom_update_byte(EECONFIG_DEBUG, 0); | ||
48 | eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0); | ||
49 | default_layer_state = 0; | ||
50 | eeprom_update_byte(EECONFIG_KEYMAP_LOWER_BYTE, 0); | ||
51 | eeprom_update_byte(EECONFIG_KEYMAP_UPPER_BYTE, 0); | ||
52 | eeprom_update_byte(EECONFIG_MOUSEKEY_ACCEL, 0); | ||
53 | eeprom_update_byte(EECONFIG_BACKLIGHT, 0); | ||
54 | eeprom_update_byte(EECONFIG_AUDIO, 0xFF); // On by default | ||
55 | eeprom_update_dword(EECONFIG_RGBLIGHT, 0); | ||
56 | eeprom_update_byte(EECONFIG_STENOMODE, 0); | ||
57 | eeprom_update_dword(EECONFIG_HAPTIC, 0); | ||
58 | eeprom_update_byte(EECONFIG_VELOCIKEY, 0); | ||
59 | eeprom_update_dword(EECONFIG_RGB_MATRIX, 0); | ||
60 | eeprom_update_word(EECONFIG_RGB_MATRIX_EXTENDED, 0); | ||
61 | |||
62 | // TODO: Remove once ARM has a way to configure EECONFIG_HANDEDNESS | ||
63 | // within the emulated eeprom via dfu-util or another tool | ||
64 | #if defined INIT_EE_HANDS_LEFT | ||
65 | # pragma message "Faking EE_HANDS for left hand" | ||
66 | eeprom_update_byte(EECONFIG_HANDEDNESS, 1); | ||
67 | #elif defined INIT_EE_HANDS_RIGHT | ||
68 | # pragma message "Faking EE_HANDS for right hand" | ||
69 | eeprom_update_byte(EECONFIG_HANDEDNESS, 0); | ||
70 | #endif | ||
71 | |||
72 | #if defined(HAPTIC_ENABLE) | ||
73 | haptic_reset(); | ||
74 | #else | ||
75 | // this is used in case haptic is disabled, but we still want sane defaults | ||
76 | // in the haptic configuration eeprom. All zero will trigger a haptic_reset | ||
77 | // when a haptic-enabled firmware is loaded onto the keyboard. | ||
78 | eeprom_update_dword(EECONFIG_HAPTIC, 0); | ||
79 | #endif | ||
80 | |||
81 | eeconfig_init_kb(); | ||
82 | } | ||
83 | |||
84 | /** \brief eeconfig initialization | ||
85 | * | ||
86 | * FIXME: needs doc | ||
87 | */ | ||
88 | void eeconfig_init(void) { eeconfig_init_quantum(); } | ||
89 | |||
90 | /** \brief eeconfig enable | ||
91 | * | ||
92 | * FIXME: needs doc | ||
93 | */ | ||
94 | void eeconfig_enable(void) { eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); } | ||
95 | |||
96 | /** \brief eeconfig disable | ||
97 | * | ||
98 | * FIXME: needs doc | ||
99 | */ | ||
100 | void eeconfig_disable(void) { | ||
101 | #ifdef STM32_EEPROM_ENABLE | ||
102 | EEPROM_Erase(); | ||
103 | #endif | ||
104 | #if defined(EEPROM_DRIVER) | ||
105 | eeprom_driver_erase(); | ||
106 | #endif | ||
107 | eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF); | ||
108 | } | ||
109 | |||
110 | /** \brief eeconfig is enabled | ||
111 | * | ||
112 | * FIXME: needs doc | ||
113 | */ | ||
114 | bool eeconfig_is_enabled(void) { return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER); } | ||
115 | |||
116 | /** \brief eeconfig is disabled | ||
117 | * | ||
118 | * FIXME: needs doc | ||
119 | */ | ||
120 | bool eeconfig_is_disabled(void) { return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF); } | ||
121 | |||
122 | /** \brief eeconfig read debug | ||
123 | * | ||
124 | * FIXME: needs doc | ||
125 | */ | ||
126 | uint8_t eeconfig_read_debug(void) { return eeprom_read_byte(EECONFIG_DEBUG); } | ||
127 | /** \brief eeconfig update debug | ||
128 | * | ||
129 | * FIXME: needs doc | ||
130 | */ | ||
131 | void eeconfig_update_debug(uint8_t val) { eeprom_update_byte(EECONFIG_DEBUG, val); } | ||
132 | |||
133 | /** \brief eeconfig read default layer | ||
134 | * | ||
135 | * FIXME: needs doc | ||
136 | */ | ||
137 | uint8_t eeconfig_read_default_layer(void) { return eeprom_read_byte(EECONFIG_DEFAULT_LAYER); } | ||
138 | /** \brief eeconfig update default layer | ||
139 | * | ||
140 | * FIXME: needs doc | ||
141 | */ | ||
142 | void eeconfig_update_default_layer(uint8_t val) { eeprom_update_byte(EECONFIG_DEFAULT_LAYER, val); } | ||
143 | |||
144 | /** \brief eeconfig read keymap | ||
145 | * | ||
146 | * FIXME: needs doc | ||
147 | */ | ||
148 | uint16_t eeconfig_read_keymap(void) { return (eeprom_read_byte(EECONFIG_KEYMAP_LOWER_BYTE) | (eeprom_read_byte(EECONFIG_KEYMAP_UPPER_BYTE) << 8)); } | ||
149 | /** \brief eeconfig update keymap | ||
150 | * | ||
151 | * FIXME: needs doc | ||
152 | */ | ||
153 | void eeconfig_update_keymap(uint16_t val) { | ||
154 | eeprom_update_byte(EECONFIG_KEYMAP_LOWER_BYTE, val & 0xFF); | ||
155 | eeprom_update_byte(EECONFIG_KEYMAP_UPPER_BYTE, (val >> 8) & 0xFF); | ||
156 | } | ||
157 | |||
158 | /** \brief eeconfig read audio | ||
159 | * | ||
160 | * FIXME: needs doc | ||
161 | */ | ||
162 | uint8_t eeconfig_read_audio(void) { return eeprom_read_byte(EECONFIG_AUDIO); } | ||
163 | /** \brief eeconfig update audio | ||
164 | * | ||
165 | * FIXME: needs doc | ||
166 | */ | ||
167 | void eeconfig_update_audio(uint8_t val) { eeprom_update_byte(EECONFIG_AUDIO, val); } | ||
168 | |||
169 | /** \brief eeconfig read kb | ||
170 | * | ||
171 | * FIXME: needs doc | ||
172 | */ | ||
173 | uint32_t eeconfig_read_kb(void) { return eeprom_read_dword(EECONFIG_KEYBOARD); } | ||
174 | /** \brief eeconfig update kb | ||
175 | * | ||
176 | * FIXME: needs doc | ||
177 | */ | ||
178 | void eeconfig_update_kb(uint32_t val) { eeprom_update_dword(EECONFIG_KEYBOARD, val); } | ||
179 | |||
180 | /** \brief eeconfig read user | ||
181 | * | ||
182 | * FIXME: needs doc | ||
183 | */ | ||
184 | uint32_t eeconfig_read_user(void) { return eeprom_read_dword(EECONFIG_USER); } | ||
185 | /** \brief eeconfig update user | ||
186 | * | ||
187 | * FIXME: needs doc | ||
188 | */ | ||
189 | void eeconfig_update_user(uint32_t val) { eeprom_update_dword(EECONFIG_USER, val); } | ||
190 | |||
191 | /** \brief eeconfig read haptic | ||
192 | * | ||
193 | * FIXME: needs doc | ||
194 | */ | ||
195 | uint32_t eeconfig_read_haptic(void) { return eeprom_read_dword(EECONFIG_HAPTIC); } | ||
196 | /** \brief eeconfig update haptic | ||
197 | * | ||
198 | * FIXME: needs doc | ||
199 | */ | ||
200 | void eeconfig_update_haptic(uint32_t val) { eeprom_update_dword(EECONFIG_HAPTIC, val); } | ||
201 | |||
202 | /** \brief eeconfig read split handedness | ||
203 | * | ||
204 | * FIXME: needs doc | ||
205 | */ | ||
206 | bool eeconfig_read_handedness(void) { return !!eeprom_read_byte(EECONFIG_HANDEDNESS); } | ||
207 | /** \brief eeconfig update split handedness | ||
208 | * | ||
209 | * FIXME: needs doc | ||
210 | */ | ||
211 | void eeconfig_update_handedness(bool val) { eeprom_update_byte(EECONFIG_HANDEDNESS, !!val); } | ||
diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h deleted file mode 100644 index a88071729..000000000 --- a/tmk_core/common/eeconfig.h +++ /dev/null | |||
@@ -1,113 +0,0 @@ | |||
1 | /* | ||
2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
3 | |||
4 | This program is free software: you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation, either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #pragma once | ||
19 | |||
20 | #include <stdint.h> | ||
21 | #include <stdbool.h> | ||
22 | |||
23 | #ifndef EECONFIG_MAGIC_NUMBER | ||
24 | # define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEEA // When changing, decrement this value to avoid future re-init issues | ||
25 | #endif | ||
26 | #define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF | ||
27 | |||
28 | /* EEPROM parameter address */ | ||
29 | #define EECONFIG_MAGIC (uint16_t *)0 | ||
30 | #define EECONFIG_DEBUG (uint8_t *)2 | ||
31 | #define EECONFIG_DEFAULT_LAYER (uint8_t *)3 | ||
32 | #define EECONFIG_KEYMAP (uint8_t *)4 | ||
33 | #define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)5 | ||
34 | #define EECONFIG_BACKLIGHT (uint8_t *)6 | ||
35 | #define EECONFIG_AUDIO (uint8_t *)7 | ||
36 | #define EECONFIG_RGBLIGHT (uint32_t *)8 | ||
37 | #define EECONFIG_UNICODEMODE (uint8_t *)12 | ||
38 | #define EECONFIG_STENOMODE (uint8_t *)13 | ||
39 | // EEHANDS for two handed boards | ||
40 | #define EECONFIG_HANDEDNESS (uint8_t *)14 | ||
41 | #define EECONFIG_KEYBOARD (uint32_t *)15 | ||
42 | #define EECONFIG_USER (uint32_t *)19 | ||
43 | #define EECONFIG_VELOCIKEY (uint8_t *)23 | ||
44 | |||
45 | #define EECONFIG_HAPTIC (uint32_t *)24 | ||
46 | |||
47 | // Mutually exclusive | ||
48 | #define EECONFIG_LED_MATRIX (uint32_t *)28 | ||
49 | #define EECONFIG_RGB_MATRIX (uint32_t *)28 | ||
50 | // Speed & Flags | ||
51 | #define EECONFIG_LED_MATRIX_EXTENDED (uint16_t *)32 | ||
52 | #define EECONFIG_RGB_MATRIX_EXTENDED (uint16_t *)32 | ||
53 | |||
54 | // TODO: Combine these into a single word and single block of EEPROM | ||
55 | #define EECONFIG_KEYMAP_UPPER_BYTE (uint8_t *)34 | ||
56 | // Size of EEPROM being used, other code can refer to this for available EEPROM | ||
57 | #define EECONFIG_SIZE 35 | ||
58 | /* debug bit */ | ||
59 | #define EECONFIG_DEBUG_ENABLE (1 << 0) | ||
60 | #define EECONFIG_DEBUG_MATRIX (1 << 1) | ||
61 | #define EECONFIG_DEBUG_KEYBOARD (1 << 2) | ||
62 | #define EECONFIG_DEBUG_MOUSE (1 << 3) | ||
63 | |||
64 | /* keyconf bit */ | ||
65 | #define EECONFIG_KEYMAP_SWAP_CONTROL_CAPSLOCK (1 << 0) | ||
66 | #define EECONFIG_KEYMAP_CAPSLOCK_TO_CONTROL (1 << 1) | ||
67 | #define EECONFIG_KEYMAP_SWAP_LALT_LGUI (1 << 2) | ||
68 | #define EECONFIG_KEYMAP_SWAP_RALT_RGUI (1 << 3) | ||
69 | #define EECONFIG_KEYMAP_NO_GUI (1 << 4) | ||
70 | #define EECONFIG_KEYMAP_SWAP_GRAVE_ESC (1 << 5) | ||
71 | #define EECONFIG_KEYMAP_SWAP_BACKSLASH_BACKSPACE (1 << 6) | ||
72 | #define EECONFIG_KEYMAP_NKRO (1 << 7) | ||
73 | |||
74 | #define EECONFIG_KEYMAP_LOWER_BYTE EECONFIG_KEYMAP | ||
75 | |||
76 | bool eeconfig_is_enabled(void); | ||
77 | bool eeconfig_is_disabled(void); | ||
78 | |||
79 | void eeconfig_init(void); | ||
80 | void eeconfig_init_quantum(void); | ||
81 | void eeconfig_init_kb(void); | ||
82 | void eeconfig_init_user(void); | ||
83 | |||
84 | void eeconfig_enable(void); | ||
85 | |||
86 | void eeconfig_disable(void); | ||
87 | |||
88 | uint8_t eeconfig_read_debug(void); | ||
89 | void eeconfig_update_debug(uint8_t val); | ||
90 | |||
91 | uint8_t eeconfig_read_default_layer(void); | ||
92 | void eeconfig_update_default_layer(uint8_t val); | ||
93 | |||
94 | uint16_t eeconfig_read_keymap(void); | ||
95 | void eeconfig_update_keymap(uint16_t val); | ||
96 | |||
97 | #ifdef AUDIO_ENABLE | ||
98 | uint8_t eeconfig_read_audio(void); | ||
99 | void eeconfig_update_audio(uint8_t val); | ||
100 | #endif | ||
101 | |||
102 | uint32_t eeconfig_read_kb(void); | ||
103 | void eeconfig_update_kb(uint32_t val); | ||
104 | uint32_t eeconfig_read_user(void); | ||
105 | void eeconfig_update_user(uint32_t val); | ||
106 | |||
107 | #ifdef HAPTIC_ENABLE | ||
108 | uint32_t eeconfig_read_haptic(void); | ||
109 | void eeconfig_update_haptic(uint32_t val); | ||
110 | #endif | ||
111 | |||
112 | bool eeconfig_read_handedness(void); | ||
113 | void eeconfig_update_handedness(bool val); | ||
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c deleted file mode 100644 index fcc51973f..000000000 --- a/tmk_core/common/keyboard.c +++ /dev/null | |||
@@ -1,565 +0,0 @@ | |||
1 | /* | ||
2 | Copyright 2011, 2012, 2013 Jun Wako <wakojun@gmail.com> | ||
3 | |||
4 | This program is free software: you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation, either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #include <stdint.h> | ||
19 | #include "keyboard.h" | ||
20 | #include "matrix.h" | ||
21 | #include "keymap.h" | ||
22 | #include "host.h" | ||
23 | #include "led.h" | ||
24 | #include "keycode.h" | ||
25 | #include "timer.h" | ||
26 | #include "sync_timer.h" | ||
27 | #include "print.h" | ||
28 | #include "debug.h" | ||
29 | #include "command.h" | ||
30 | #include "util.h" | ||
31 | #include "sendchar.h" | ||
32 | #include "eeconfig.h" | ||
33 | #include "action_layer.h" | ||
34 | #ifdef BACKLIGHT_ENABLE | ||
35 | # include "backlight.h" | ||
36 | #endif | ||
37 | #ifdef MOUSEKEY_ENABLE | ||
38 | # include "mousekey.h" | ||
39 | #endif | ||
40 | #ifdef PS2_MOUSE_ENABLE | ||
41 | # include "ps2_mouse.h" | ||
42 | #endif | ||
43 | #ifdef SERIAL_MOUSE_ENABLE | ||
44 | # include "serial_mouse.h" | ||
45 | #endif | ||
46 | #ifdef ADB_MOUSE_ENABLE | ||
47 | # include "adb.h" | ||
48 | #endif | ||
49 | #ifdef RGBLIGHT_ENABLE | ||
50 | # include "rgblight.h" | ||
51 | #endif | ||
52 | #ifdef LED_MATRIX_ENABLE | ||
53 | # include "led_matrix.h" | ||
54 | #endif | ||
55 | #ifdef RGB_MATRIX_ENABLE | ||
56 | # include "rgb_matrix.h" | ||
57 | #endif | ||
58 | #ifdef ENCODER_ENABLE | ||
59 | # include "encoder.h" | ||
60 | #endif | ||
61 | #ifdef STENO_ENABLE | ||
62 | # include "process_steno.h" | ||
63 | #endif | ||
64 | #ifdef SERIAL_LINK_ENABLE | ||
65 | # include "serial_link/system/serial_link.h" | ||
66 | #endif | ||
67 | #ifdef VISUALIZER_ENABLE | ||
68 | # include "visualizer/visualizer.h" | ||
69 | #endif | ||
70 | #ifdef POINTING_DEVICE_ENABLE | ||
71 | # include "pointing_device.h" | ||
72 | #endif | ||
73 | #ifdef MIDI_ENABLE | ||
74 | # include "process_midi.h" | ||
75 | #endif | ||
76 | #ifdef JOYSTICK_ENABLE | ||
77 | # include "process_joystick.h" | ||
78 | #endif | ||
79 | #ifdef HD44780_ENABLE | ||
80 | # include "hd44780.h" | ||
81 | #endif | ||
82 | #ifdef QWIIC_ENABLE | ||
83 | # include "qwiic.h" | ||
84 | #endif | ||
85 | #ifdef OLED_DRIVER_ENABLE | ||
86 | # include "oled_driver.h" | ||
87 | #endif | ||
88 | #ifdef ST7565_ENABLE | ||
89 | # include "st7565.h" | ||
90 | #endif | ||
91 | #ifdef VELOCIKEY_ENABLE | ||
92 | # include "velocikey.h" | ||
93 | #endif | ||
94 | #ifdef VIA_ENABLE | ||
95 | # include "via.h" | ||
96 | #endif | ||
97 | #ifdef DIP_SWITCH_ENABLE | ||
98 | # include "dip_switch.h" | ||
99 | #endif | ||
100 | #ifdef STM32_EEPROM_ENABLE | ||
101 | # include "eeprom_stm32.h" | ||
102 | #endif | ||
103 | #ifdef EEPROM_DRIVER | ||
104 | # include "eeprom_driver.h" | ||
105 | #endif | ||
106 | #if defined(CRC_ENABLE) | ||
107 | # include "crc.h" | ||
108 | #endif | ||
109 | #ifdef DIGITIZER_ENABLE | ||
110 | # include "digitizer.h" | ||
111 | #endif | ||
112 | |||
113 | static uint32_t last_input_modification_time = 0; | ||
114 | uint32_t last_input_activity_time(void) { return last_input_modification_time; } | ||
115 | uint32_t last_input_activity_elapsed(void) { return timer_elapsed32(last_input_modification_time); } | ||
116 | |||
117 | static uint32_t last_matrix_modification_time = 0; | ||
118 | uint32_t last_matrix_activity_time(void) { return last_matrix_modification_time; } | ||
119 | uint32_t last_matrix_activity_elapsed(void) { return timer_elapsed32(last_matrix_modification_time); } | ||
120 | void last_matrix_activity_trigger(void) { last_matrix_modification_time = last_input_modification_time = timer_read32(); } | ||
121 | |||
122 | static uint32_t last_encoder_modification_time = 0; | ||
123 | uint32_t last_encoder_activity_time(void) { return last_encoder_modification_time; } | ||
124 | uint32_t last_encoder_activity_elapsed(void) { return timer_elapsed32(last_encoder_modification_time); } | ||
125 | void last_encoder_activity_trigger(void) { last_encoder_modification_time = last_input_modification_time = timer_read32(); } | ||
126 | |||
127 | // Only enable this if console is enabled to print to | ||
128 | #if defined(DEBUG_MATRIX_SCAN_RATE) | ||
129 | static uint32_t matrix_timer = 0; | ||
130 | static uint32_t matrix_scan_count = 0; | ||
131 | static uint32_t last_matrix_scan_count = 0; | ||
132 | |||
133 | void matrix_scan_perf_task(void) { | ||
134 | matrix_scan_count++; | ||
135 | |||
136 | uint32_t timer_now = timer_read32(); | ||
137 | if (TIMER_DIFF_32(timer_now, matrix_timer) > 1000) { | ||
138 | # if defined(CONSOLE_ENABLE) | ||
139 | dprintf("matrix scan frequency: %lu\n", matrix_scan_count); | ||
140 | # endif | ||
141 | last_matrix_scan_count = matrix_scan_count; | ||
142 | matrix_timer = timer_now; | ||
143 | matrix_scan_count = 0; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | uint32_t get_matrix_scan_rate(void) { return last_matrix_scan_count; } | ||
148 | #else | ||
149 | # define matrix_scan_perf_task() | ||
150 | #endif | ||
151 | |||
152 | #ifdef MATRIX_HAS_GHOST | ||
153 | extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; | ||
154 | static matrix_row_t get_real_keys(uint8_t row, matrix_row_t rowdata) { | ||
155 | matrix_row_t out = 0; | ||
156 | for (uint8_t col = 0; col < MATRIX_COLS; col++) { | ||
157 | // read each key in the row data and check if the keymap defines it as a real key | ||
158 | if (pgm_read_byte(&keymaps[0][row][col]) && (rowdata & (1 << col))) { | ||
159 | // this creates new row data, if a key is defined in the keymap, it will be set here | ||
160 | out |= 1 << col; | ||
161 | } | ||
162 | } | ||
163 | return out; | ||
164 | } | ||
165 | |||
166 | static inline bool popcount_more_than_one(matrix_row_t rowdata) { | ||
167 | rowdata &= rowdata - 1; // if there are less than two bits (keys) set, rowdata will become zero | ||
168 | return rowdata; | ||
169 | } | ||
170 | |||
171 | static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata) { | ||
172 | /* No ghost exists when less than 2 keys are down on the row. | ||
173 | If there are "active" blanks in the matrix, the key can't be pressed by the user, | ||
174 | there is no doubt as to which keys are really being pressed. | ||
175 | The ghosts will be ignored, they are KC_NO. */ | ||
176 | rowdata = get_real_keys(row, rowdata); | ||
177 | if ((popcount_more_than_one(rowdata)) == 0) { | ||
178 | return false; | ||
179 | } | ||
180 | /* Ghost occurs when the row shares a column line with other row, | ||
181 | and two columns are read on each row. Blanks in the matrix don't matter, | ||
182 | so they are filtered out. | ||
183 | If there are two or more real keys pressed and they match columns with | ||
184 | at least two of another row's real keys, the row will be ignored. Keep in mind, | ||
185 | we are checking one row at a time, not all of them at once. | ||
186 | */ | ||
187 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | ||
188 | if (i != row && popcount_more_than_one(get_real_keys(i, matrix_get_row(i)) & rowdata)) { | ||
189 | return true; | ||
190 | } | ||
191 | } | ||
192 | return false; | ||
193 | } | ||
194 | |||
195 | #endif | ||
196 | |||
197 | void disable_jtag(void) { | ||
198 | // To use PF4-7 (PC2-5 on ATmega32A), disable JTAG by writing JTD bit twice within four cycles. | ||
199 | #if (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) | ||
200 | MCUCR |= _BV(JTD); | ||
201 | MCUCR |= _BV(JTD); | ||
202 | #elif defined(__AVR_ATmega32A__) | ||
203 | MCUCSR |= _BV(JTD); | ||
204 | MCUCSR |= _BV(JTD); | ||
205 | #endif | ||
206 | } | ||
207 | |||
208 | /** \brief matrix_setup | ||
209 | * | ||
210 | * FIXME: needs doc | ||
211 | */ | ||
212 | __attribute__((weak)) void matrix_setup(void) {} | ||
213 | |||
214 | /** \brief keyboard_pre_init_user | ||
215 | * | ||
216 | * FIXME: needs doc | ||
217 | */ | ||
218 | __attribute__((weak)) void keyboard_pre_init_user(void) {} | ||
219 | |||
220 | /** \brief keyboard_pre_init_kb | ||
221 | * | ||
222 | * FIXME: needs doc | ||
223 | */ | ||
224 | __attribute__((weak)) void keyboard_pre_init_kb(void) { keyboard_pre_init_user(); } | ||
225 | |||
226 | /** \brief keyboard_post_init_user | ||
227 | * | ||
228 | * FIXME: needs doc | ||
229 | */ | ||
230 | |||
231 | __attribute__((weak)) void keyboard_post_init_user() {} | ||
232 | |||
233 | /** \brief keyboard_post_init_kb | ||
234 | * | ||
235 | * FIXME: needs doc | ||
236 | */ | ||
237 | |||
238 | __attribute__((weak)) void keyboard_post_init_kb(void) { keyboard_post_init_user(); } | ||
239 | |||
240 | /** \brief keyboard_setup | ||
241 | * | ||
242 | * FIXME: needs doc | ||
243 | */ | ||
244 | void keyboard_setup(void) { | ||
245 | #ifndef NO_JTAG_DISABLE | ||
246 | disable_jtag(); | ||
247 | #endif | ||
248 | print_set_sendchar(sendchar); | ||
249 | #ifdef STM32_EEPROM_ENABLE | ||
250 | EEPROM_Init(); | ||
251 | #endif | ||
252 | #ifdef EEPROM_DRIVER | ||
253 | eeprom_driver_init(); | ||
254 | #endif | ||
255 | matrix_setup(); | ||
256 | keyboard_pre_init_kb(); | ||
257 | } | ||
258 | |||
259 | /** \brief is_keyboard_master | ||
260 | * | ||
261 | * FIXME: needs doc | ||
262 | */ | ||
263 | __attribute__((weak)) bool is_keyboard_master(void) { return true; } | ||
264 | |||
265 | /** \brief is_keyboard_left | ||
266 | * | ||
267 | * FIXME: needs doc | ||
268 | */ | ||
269 | __attribute__((weak)) bool is_keyboard_left(void) { return true; } | ||
270 | |||
271 | /** \brief should_process_keypress | ||
272 | * | ||
273 | * Override this function if you have a condition where keypresses processing should change: | ||
274 | * - splits where the slave side needs to process for rgb/oled functionality | ||
275 | */ | ||
276 | __attribute__((weak)) bool should_process_keypress(void) { return is_keyboard_master(); } | ||
277 | |||
278 | /** \brief housekeeping_task_kb | ||
279 | * | ||
280 | * Override this function if you have a need to execute code for every keyboard main loop iteration. | ||
281 | * This is specific to keyboard-level functionality. | ||
282 | */ | ||
283 | __attribute__((weak)) void housekeeping_task_kb(void) {} | ||
284 | |||
285 | /** \brief housekeeping_task_user | ||
286 | * | ||
287 | * Override this function if you have a need to execute code for every keyboard main loop iteration. | ||
288 | * This is specific to user/keymap-level functionality. | ||
289 | */ | ||
290 | __attribute__((weak)) void housekeeping_task_user(void) {} | ||
291 | |||
292 | /** \brief housekeeping_task | ||
293 | * | ||
294 | * Invokes hooks for executing code after QMK is done after each loop iteration. | ||
295 | */ | ||
296 | void housekeeping_task(void) { | ||
297 | housekeeping_task_kb(); | ||
298 | housekeeping_task_user(); | ||
299 | } | ||
300 | |||
301 | /** \brief keyboard_init | ||
302 | * | ||
303 | * FIXME: needs doc | ||
304 | */ | ||
305 | void keyboard_init(void) { | ||
306 | timer_init(); | ||
307 | sync_timer_init(); | ||
308 | matrix_init(); | ||
309 | #if defined(CRC_ENABLE) | ||
310 | crc_init(); | ||
311 | #endif | ||
312 | #ifdef VIA_ENABLE | ||
313 | via_init(); | ||
314 | #endif | ||
315 | #ifdef QWIIC_ENABLE | ||
316 | qwiic_init(); | ||
317 | #endif | ||
318 | #ifdef OLED_DRIVER_ENABLE | ||
319 | oled_init(OLED_ROTATION_0); | ||
320 | #endif | ||
321 | #ifdef ST7565_ENABLE | ||
322 | st7565_init(DISPLAY_ROTATION_0); | ||
323 | #endif | ||
324 | #ifdef PS2_MOUSE_ENABLE | ||
325 | ps2_mouse_init(); | ||
326 | #endif | ||
327 | #ifdef SERIAL_MOUSE_ENABLE | ||
328 | serial_mouse_init(); | ||
329 | #endif | ||
330 | #ifdef ADB_MOUSE_ENABLE | ||
331 | adb_mouse_init(); | ||
332 | #endif | ||
333 | #ifdef BACKLIGHT_ENABLE | ||
334 | backlight_init(); | ||
335 | #endif | ||
336 | #ifdef RGBLIGHT_ENABLE | ||
337 | rgblight_init(); | ||
338 | #endif | ||
339 | #ifdef ENCODER_ENABLE | ||
340 | encoder_init(); | ||
341 | #endif | ||
342 | #ifdef STENO_ENABLE | ||
343 | steno_init(); | ||
344 | #endif | ||
345 | #ifdef POINTING_DEVICE_ENABLE | ||
346 | pointing_device_init(); | ||
347 | #endif | ||
348 | #if defined(NKRO_ENABLE) && defined(FORCE_NKRO) | ||
349 | keymap_config.nkro = 1; | ||
350 | eeconfig_update_keymap(keymap_config.raw); | ||
351 | #endif | ||
352 | #ifdef DIP_SWITCH_ENABLE | ||
353 | dip_switch_init(); | ||
354 | #endif | ||
355 | |||
356 | #if defined(DEBUG_MATRIX_SCAN_RATE) && defined(CONSOLE_ENABLE) | ||
357 | debug_enable = true; | ||
358 | #endif | ||
359 | |||
360 | keyboard_post_init_kb(); /* Always keep this last */ | ||
361 | } | ||
362 | |||
363 | /** \brief key_event_task | ||
364 | * | ||
365 | * This function is responsible for calling into other systems when they need to respond to electrical switch press events. | ||
366 | * This is differnet than keycode events as no layer processing, or filtering occurs. | ||
367 | */ | ||
368 | void switch_events(uint8_t row, uint8_t col, bool pressed) { | ||
369 | #if defined(LED_MATRIX_ENABLE) | ||
370 | process_led_matrix(row, col, pressed); | ||
371 | #endif | ||
372 | #if defined(RGB_MATRIX_ENABLE) | ||
373 | process_rgb_matrix(row, col, pressed); | ||
374 | #endif | ||
375 | } | ||
376 | |||
377 | /** \brief Keyboard task: Do keyboard routine jobs | ||
378 | * | ||
379 | * Do routine keyboard jobs: | ||
380 | * | ||
381 | * * scan matrix | ||
382 | * * handle mouse movements | ||
383 | * * run visualizer code | ||
384 | * * handle midi commands | ||
385 | * * light LEDs | ||
386 | * | ||
387 | * This is repeatedly called as fast as possible. | ||
388 | */ | ||
389 | void keyboard_task(void) { | ||
390 | static matrix_row_t matrix_prev[MATRIX_ROWS]; | ||
391 | static uint8_t led_status = 0; | ||
392 | matrix_row_t matrix_row = 0; | ||
393 | matrix_row_t matrix_change = 0; | ||
394 | #ifdef QMK_KEYS_PER_SCAN | ||
395 | uint8_t keys_processed = 0; | ||
396 | #endif | ||
397 | #ifdef ENCODER_ENABLE | ||
398 | bool encoders_changed = false; | ||
399 | #endif | ||
400 | |||
401 | uint8_t matrix_changed = matrix_scan(); | ||
402 | if (matrix_changed) last_matrix_activity_trigger(); | ||
403 | |||
404 | for (uint8_t r = 0; r < MATRIX_ROWS; r++) { | ||
405 | matrix_row = matrix_get_row(r); | ||
406 | matrix_change = matrix_row ^ matrix_prev[r]; | ||
407 | if (matrix_change) { | ||
408 | #ifdef MATRIX_HAS_GHOST | ||
409 | if (has_ghost_in_row(r, matrix_row)) { | ||
410 | continue; | ||
411 | } | ||
412 | #endif | ||
413 | if (debug_matrix) matrix_print(); | ||
414 | matrix_row_t col_mask = 1; | ||
415 | for (uint8_t c = 0; c < MATRIX_COLS; c++, col_mask <<= 1) { | ||
416 | if (matrix_change & col_mask) { | ||
417 | if (should_process_keypress()) { | ||
418 | action_exec((keyevent_t){ | ||
419 | .key = (keypos_t){.row = r, .col = c}, .pressed = (matrix_row & col_mask), .time = (timer_read() | 1) /* time should not be 0 */ | ||
420 | }); | ||
421 | } | ||
422 | // record a processed key | ||
423 | matrix_prev[r] ^= col_mask; | ||
424 | |||
425 | switch_events(r, c, (matrix_row & col_mask)); | ||
426 | |||
427 | #ifdef QMK_KEYS_PER_SCAN | ||
428 | // only jump out if we have processed "enough" keys. | ||
429 | if (++keys_processed >= QMK_KEYS_PER_SCAN) | ||
430 | #endif | ||
431 | // process a key per task call | ||
432 | goto MATRIX_LOOP_END; | ||
433 | } | ||
434 | } | ||
435 | } | ||
436 | } | ||
437 | // call with pseudo tick event when no real key event. | ||
438 | #ifdef QMK_KEYS_PER_SCAN | ||
439 | // we can get here with some keys processed now. | ||
440 | if (!keys_processed) | ||
441 | #endif | ||
442 | action_exec(TICK); | ||
443 | |||
444 | MATRIX_LOOP_END: | ||
445 | |||
446 | #ifdef DEBUG_MATRIX_SCAN_RATE | ||
447 | matrix_scan_perf_task(); | ||
448 | #endif | ||
449 | |||
450 | #if defined(RGBLIGHT_ENABLE) | ||
451 | rgblight_task(); | ||
452 | #endif | ||
453 | |||
454 | #ifdef LED_MATRIX_ENABLE | ||
455 | led_matrix_task(); | ||
456 | #endif | ||
457 | #ifdef RGB_MATRIX_ENABLE | ||
458 | rgb_matrix_task(); | ||
459 | #endif | ||
460 | |||
461 | #if defined(BACKLIGHT_ENABLE) | ||
462 | # if defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS) | ||
463 | backlight_task(); | ||
464 | # endif | ||
465 | #endif | ||
466 | |||
467 | #ifdef ENCODER_ENABLE | ||
468 | encoders_changed = encoder_read(); | ||
469 | if (encoders_changed) last_encoder_activity_trigger(); | ||
470 | #endif | ||
471 | |||
472 | #ifdef QWIIC_ENABLE | ||
473 | qwiic_task(); | ||
474 | #endif | ||
475 | |||
476 | #ifdef OLED_DRIVER_ENABLE | ||
477 | oled_task(); | ||
478 | # ifndef OLED_DISABLE_TIMEOUT | ||
479 | // Wake up oled if user is using those fabulous keys or spinning those encoders! | ||
480 | # ifdef ENCODER_ENABLE | ||
481 | if (matrix_changed || encoders_changed) oled_on(); | ||
482 | # else | ||
483 | if (matrix_changed) oled_on(); | ||
484 | # endif | ||
485 | # endif | ||
486 | #endif | ||
487 | |||
488 | #ifdef ST7565_ENABLE | ||
489 | st7565_task(); | ||
490 | # ifndef ST7565_DISABLE_TIMEOUT | ||
491 | // Wake up display if user is using those fabulous keys or spinning those encoders! | ||
492 | # ifdef ENCODER_ENABLE | ||
493 | if (matrix_changed || encoders_changed) st7565_on(); | ||
494 | # else | ||
495 | if (matrix_changed) st7565_on(); | ||
496 | # endif | ||
497 | # endif | ||
498 | #endif | ||
499 | |||
500 | #ifdef MOUSEKEY_ENABLE | ||
501 | // mousekey repeat & acceleration | ||
502 | mousekey_task(); | ||
503 | #endif | ||
504 | |||
505 | #ifdef PS2_MOUSE_ENABLE | ||
506 | ps2_mouse_task(); | ||
507 | #endif | ||
508 | |||
509 | #ifdef SERIAL_MOUSE_ENABLE | ||
510 | serial_mouse_task(); | ||
511 | #endif | ||
512 | |||
513 | #ifdef ADB_MOUSE_ENABLE | ||
514 | adb_mouse_task(); | ||
515 | #endif | ||
516 | |||
517 | #ifdef SERIAL_LINK_ENABLE | ||
518 | serial_link_update(); | ||
519 | #endif | ||
520 | |||
521 | #ifdef VISUALIZER_ENABLE | ||
522 | visualizer_update(default_layer_state, layer_state, visualizer_get_mods(), host_keyboard_leds()); | ||
523 | #endif | ||
524 | |||
525 | #ifdef POINTING_DEVICE_ENABLE | ||
526 | pointing_device_task(); | ||
527 | #endif | ||
528 | |||
529 | #ifdef MIDI_ENABLE | ||
530 | midi_task(); | ||
531 | #endif | ||
532 | |||
533 | #ifdef VELOCIKEY_ENABLE | ||
534 | if (velocikey_enabled()) { | ||
535 | velocikey_decelerate(); | ||
536 | } | ||
537 | #endif | ||
538 | |||
539 | #ifdef JOYSTICK_ENABLE | ||
540 | joystick_task(); | ||
541 | #endif | ||
542 | |||
543 | #ifdef DIGITIZER_ENABLE | ||
544 | digitizer_task(); | ||
545 | #endif | ||
546 | |||
547 | // update LED | ||
548 | if (led_status != host_keyboard_leds()) { | ||
549 | led_status = host_keyboard_leds(); | ||
550 | keyboard_set_leds(led_status); | ||
551 | } | ||
552 | } | ||
553 | |||
554 | /** \brief keyboard set leds | ||
555 | * | ||
556 | * FIXME: needs doc | ||
557 | */ | ||
558 | void keyboard_set_leds(uint8_t leds) { | ||
559 | if (debug_keyboard) { | ||
560 | debug("keyboard_set_led: "); | ||
561 | debug_hex8(leds); | ||
562 | debug("\n"); | ||
563 | } | ||
564 | led_set(leds); | ||
565 | } | ||
diff --git a/tmk_core/common/keyboard.h b/tmk_core/common/keyboard.h deleted file mode 100644 index 08f4e84f9..000000000 --- a/tmk_core/common/keyboard.h +++ /dev/null | |||
@@ -1,90 +0,0 @@ | |||
1 | /* | ||
2 | Copyright 2011,2012,2013 Jun Wako <wakojun@gmail.com> | ||
3 | |||
4 | This program is free software: you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation, either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #pragma once | ||
19 | |||
20 | #include <stdbool.h> | ||
21 | #include <stdint.h> | ||
22 | |||
23 | #ifdef __cplusplus | ||
24 | extern "C" { | ||
25 | #endif | ||
26 | |||
27 | /* key matrix position */ | ||
28 | typedef struct { | ||
29 | uint8_t col; | ||
30 | uint8_t row; | ||
31 | } keypos_t; | ||
32 | |||
33 | /* key event */ | ||
34 | typedef struct { | ||
35 | keypos_t key; | ||
36 | bool pressed; | ||
37 | uint16_t time; | ||
38 | } keyevent_t; | ||
39 | |||
40 | /* equivalent test of keypos_t */ | ||
41 | #define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col) | ||
42 | |||
43 | /* Rules for No Event: | ||
44 | * 1) (time == 0) to handle (keyevent_t){} as empty event | ||
45 | * 2) Matrix(255, 255) to make TICK event available | ||
46 | */ | ||
47 | static inline bool IS_NOEVENT(keyevent_t event) { return event.time == 0 || (event.key.row == 255 && event.key.col == 255); } | ||
48 | static inline bool IS_PRESSED(keyevent_t event) { return (!IS_NOEVENT(event) && event.pressed); } | ||
49 | static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) && !event.pressed); } | ||
50 | |||
51 | /* Tick event */ | ||
52 | #define TICK \ | ||
53 | (keyevent_t) { .key = (keypos_t){.row = 255, .col = 255}, .pressed = false, .time = (timer_read() | 1) } | ||
54 | |||
55 | /* it runs once at early stage of startup before keyboard_init. */ | ||
56 | void keyboard_setup(void); | ||
57 | /* it runs once after initializing host side protocol, debug and MCU peripherals. */ | ||
58 | void keyboard_init(void); | ||
59 | /* it runs repeatedly in main loop */ | ||
60 | void keyboard_task(void); | ||
61 | /* it runs when host LED status is updated */ | ||
62 | void keyboard_set_leds(uint8_t leds); | ||
63 | /* it runs whenever code has to behave differently on a slave */ | ||
64 | bool is_keyboard_master(void); | ||
65 | /* it runs whenever code has to behave differently on left vs right split */ | ||
66 | bool is_keyboard_left(void); | ||
67 | |||
68 | void keyboard_pre_init_kb(void); | ||
69 | void keyboard_pre_init_user(void); | ||
70 | void keyboard_post_init_kb(void); | ||
71 | void keyboard_post_init_user(void); | ||
72 | |||
73 | void housekeeping_task(void); // To be executed by the main loop in each backend TMK protocol | ||
74 | void housekeeping_task_kb(void); // To be overridden by keyboard-level code | ||
75 | void housekeeping_task_user(void); // To be overridden by user/keymap-level code | ||
76 | |||
77 | uint32_t last_input_activity_time(void); // Timestamp of the last matrix or encoder activity | ||
78 | uint32_t last_input_activity_elapsed(void); // Number of milliseconds since the last matrix or encoder activity | ||
79 | |||
80 | uint32_t last_matrix_activity_time(void); // Timestamp of the last matrix activity | ||
81 | uint32_t last_matrix_activity_elapsed(void); // Number of milliseconds since the last matrix activity | ||
82 | |||
83 | uint32_t last_encoder_activity_time(void); // Timestamp of the last encoder activity | ||
84 | uint32_t last_encoder_activity_elapsed(void); // Number of milliseconds since the last encoder activity | ||
85 | |||
86 | uint32_t get_matrix_scan_rate(void); | ||
87 | |||
88 | #ifdef __cplusplus | ||
89 | } | ||
90 | #endif | ||
diff --git a/tmk_core/common/keycode.h b/tmk_core/common/keycode.h deleted file mode 100644 index 8facabd81..000000000 --- a/tmk_core/common/keycode.h +++ /dev/null | |||
@@ -1,560 +0,0 @@ | |||
1 | /* | ||
2 | Copyright 2011,2012 Jun Wako <wakojun@gmail.com> | ||
3 | |||
4 | This program is free software: you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation, either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | /* | ||
19 | * Keycodes based on HID Keyboard/Keypad Usage Page (0x07) plus media keys from Generic Desktop Page (0x01) and Consumer Page (0x0C) | ||
20 | * | ||
21 | * See https://web.archive.org/web/20060218214400/http://www.usb.org/developers/devclass_docs/Hut1_12.pdf | ||
22 | * or http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (older) | ||
23 | */ | ||
24 | |||
25 | #pragma once | ||
26 | |||
27 | /* FIXME: Add doxygen comments here */ | ||
28 | |||
29 | #define IS_ERROR(code) (KC_ROLL_OVER <= (code) && (code) <= KC_UNDEFINED) | ||
30 | #define IS_ANY(code) (KC_A <= (code) && (code) <= 0xFF) | ||
31 | #define IS_KEY(code) (KC_A <= (code) && (code) <= KC_EXSEL) | ||
32 | #define IS_MOD(code) (KC_LCTRL <= (code) && (code) <= KC_RGUI) | ||
33 | |||
34 | #define IS_SPECIAL(code) ((0xA5 <= (code) && (code) <= 0xDF) || (0xE8 <= (code) && (code) <= 0xFF)) | ||
35 | #define IS_SYSTEM(code) (KC_PWR <= (code) && (code) <= KC_WAKE) | ||
36 | #define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_BRID) | ||
37 | |||
38 | #define IS_FN(code) (KC_FN0 <= (code) && (code) <= KC_FN31) | ||
39 | |||
40 | #define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2) | ||
41 | #define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT) | ||
42 | #define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN8) | ||
43 | #define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT) | ||
44 | #define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2) | ||
45 | |||
46 | #define MOD_BIT(code) (1 << MOD_INDEX(code)) | ||
47 | #define MOD_INDEX(code) ((code)&0x07) | ||
48 | |||
49 | #define MOD_MASK_CTRL (MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RCTRL)) | ||
50 | #define MOD_MASK_SHIFT (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) | ||
51 | #define MOD_MASK_ALT (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT)) | ||
52 | #define MOD_MASK_GUI (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI)) | ||
53 | #define MOD_MASK_CS (MOD_MASK_CTRL | MOD_MASK_SHIFT) | ||
54 | #define MOD_MASK_CA (MOD_MASK_CTRL | MOD_MASK_ALT) | ||
55 | #define MOD_MASK_CG (MOD_MASK_CTRL | MOD_MASK_GUI) | ||
56 | #define MOD_MASK_SA (MOD_MASK_SHIFT | MOD_MASK_ALT) | ||
57 | #define MOD_MASK_SG (MOD_MASK_SHIFT | MOD_MASK_GUI) | ||
58 | #define MOD_MASK_AG (MOD_MASK_ALT | MOD_MASK_GUI) | ||
59 | #define MOD_MASK_CSA (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT) | ||
60 | #define MOD_MASK_CSG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_GUI) | ||
61 | #define MOD_MASK_CAG (MOD_MASK_CTRL | MOD_MASK_ALT | MOD_MASK_GUI) | ||
62 | #define MOD_MASK_SAG (MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI) | ||
63 | #define MOD_MASK_CSAG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI) | ||
64 | |||
65 | #define FN_BIT(code) (1 << FN_INDEX(code)) | ||
66 | #define FN_INDEX(code) ((code)-KC_FN0) | ||
67 | #define FN_MIN KC_FN0 | ||
68 | #define FN_MAX KC_FN31 | ||
69 | |||
70 | /* | ||
71 | * Short names for ease of definition of keymap | ||
72 | */ | ||
73 | /* Transparent */ | ||
74 | #define KC_TRANSPARENT 0x01 | ||
75 | #define KC_TRNS KC_TRANSPARENT | ||
76 | |||
77 | /* Punctuation */ | ||
78 | #define KC_ENT KC_ENTER | ||
79 | #define KC_ESC KC_ESCAPE | ||
80 | #define KC_BSPC KC_BSPACE | ||
81 | #define KC_SPC KC_SPACE | ||
82 | #define KC_MINS KC_MINUS | ||
83 | #define KC_EQL KC_EQUAL | ||
84 | #define KC_LBRC KC_LBRACKET | ||
85 | #define KC_RBRC KC_RBRACKET | ||
86 | #define KC_BSLS KC_BSLASH | ||
87 | #define KC_NUHS KC_NONUS_HASH | ||
88 | #define KC_SCLN KC_SCOLON | ||
89 | #define KC_QUOT KC_QUOTE | ||
90 | #define KC_GRV KC_GRAVE | ||
91 | #define KC_COMM KC_COMMA | ||
92 | #define KC_SLSH KC_SLASH | ||
93 | #define KC_NUBS KC_NONUS_BSLASH | ||
94 | |||
95 | /* Lock Keys */ | ||
96 | #define KC_CLCK KC_CAPSLOCK | ||
97 | #define KC_CAPS KC_CAPSLOCK | ||
98 | #define KC_SLCK KC_SCROLLLOCK | ||
99 | #define KC_NLCK KC_NUMLOCK | ||
100 | #define KC_LCAP KC_LOCKING_CAPS | ||
101 | #define KC_LNUM KC_LOCKING_NUM | ||
102 | #define KC_LSCR KC_LOCKING_SCROLL | ||
103 | |||
104 | /* Commands */ | ||
105 | #define KC_PSCR KC_PSCREEN | ||
106 | #define KC_PAUS KC_PAUSE | ||
107 | #define KC_BRK KC_PAUSE | ||
108 | #define KC_INS KC_INSERT | ||
109 | #define KC_DEL KC_DELETE | ||
110 | #define KC_PGDN KC_PGDOWN | ||
111 | #define KC_RGHT KC_RIGHT | ||
112 | #define KC_APP KC_APPLICATION | ||
113 | #define KC_EXEC KC_EXECUTE | ||
114 | #define KC_SLCT KC_SELECT | ||
115 | #define KC_AGIN KC_AGAIN | ||
116 | #define KC_PSTE KC_PASTE | ||
117 | #define KC_ERAS KC_ALT_ERASE | ||
118 | #define KC_CLR KC_CLEAR | ||
119 | |||
120 | /* Keypad */ | ||
121 | #define KC_PSLS KC_KP_SLASH | ||
122 | #define KC_PAST KC_KP_ASTERISK | ||
123 | #define KC_PMNS KC_KP_MINUS | ||
124 | #define KC_PPLS KC_KP_PLUS | ||
125 | #define KC_PENT KC_KP_ENTER | ||
126 | #define KC_P1 KC_KP_1 | ||
127 | #define KC_P2 KC_KP_2 | ||
128 | #define KC_P3 KC_KP_3 | ||
129 | #define KC_P4 KC_KP_4 | ||
130 | #define KC_P5 KC_KP_5 | ||
131 | #define KC_P6 KC_KP_6 | ||
132 | #define KC_P7 KC_KP_7 | ||
133 | #define KC_P8 KC_KP_8 | ||
134 | #define KC_P9 KC_KP_9 | ||
135 | #define KC_P0 KC_KP_0 | ||
136 | #define KC_PDOT KC_KP_DOT | ||
137 | #define KC_PEQL KC_KP_EQUAL | ||
138 | #define KC_PCMM KC_KP_COMMA | ||
139 | |||
140 | /* Japanese specific */ | ||
141 | #define KC_ZKHK KC_GRAVE | ||
142 | #define KC_RO KC_INT1 | ||
143 | #define KC_KANA KC_INT2 | ||
144 | #define KC_JYEN KC_INT3 | ||
145 | #define KC_HENK KC_INT4 | ||
146 | #define KC_MHEN KC_INT5 | ||
147 | |||
148 | /* Korean specific */ | ||
149 | #define KC_HAEN KC_LANG1 | ||
150 | #define KC_HANJ KC_LANG2 | ||
151 | |||
152 | /* Modifiers */ | ||
153 | #define KC_LCTL KC_LCTRL | ||
154 | #define KC_LSFT KC_LSHIFT | ||
155 | #define KC_LOPT KC_LALT | ||
156 | #define KC_LCMD KC_LGUI | ||
157 | #define KC_LWIN KC_LGUI | ||
158 | #define KC_RCTL KC_RCTRL | ||
159 | #define KC_RSFT KC_RSHIFT | ||
160 | #define KC_ALGR KC_RALT | ||
161 | #define KC_ROPT KC_RALT | ||
162 | #define KC_RCMD KC_RGUI | ||
163 | #define KC_RWIN KC_RGUI | ||
164 | |||
165 | /* Generic Desktop Page (0x01) */ | ||
166 | #define KC_PWR KC_SYSTEM_POWER | ||
167 | #define KC_SLEP KC_SYSTEM_SLEEP | ||
168 | #define KC_WAKE KC_SYSTEM_WAKE | ||
169 | |||
170 | /* Consumer Page (0x0C) */ | ||
171 | #define KC_MUTE KC_AUDIO_MUTE | ||
172 | #define KC_VOLU KC_AUDIO_VOL_UP | ||
173 | #define KC_VOLD KC_AUDIO_VOL_DOWN | ||
174 | #define KC_MNXT KC_MEDIA_NEXT_TRACK | ||
175 | #define KC_MPRV KC_MEDIA_PREV_TRACK | ||
176 | #define KC_MSTP KC_MEDIA_STOP | ||
177 | #define KC_MPLY KC_MEDIA_PLAY_PAUSE | ||
178 | #define KC_MSEL KC_MEDIA_SELECT | ||
179 | #define KC_EJCT KC_MEDIA_EJECT | ||
180 | #define KC_CALC KC_CALCULATOR | ||
181 | #define KC_MYCM KC_MY_COMPUTER | ||
182 | #define KC_WSCH KC_WWW_SEARCH | ||
183 | #define KC_WHOM KC_WWW_HOME | ||
184 | #define KC_WBAK KC_WWW_BACK | ||
185 | #define KC_WFWD KC_WWW_FORWARD | ||
186 | #define KC_WSTP KC_WWW_STOP | ||
187 | #define KC_WREF KC_WWW_REFRESH | ||
188 | #define KC_WFAV KC_WWW_FAVORITES | ||
189 | #define KC_MFFD KC_MEDIA_FAST_FORWARD | ||
190 | #define KC_MRWD KC_MEDIA_REWIND | ||
191 | #define KC_BRIU KC_BRIGHTNESS_UP | ||
192 | #define KC_BRID KC_BRIGHTNESS_DOWN | ||
193 | |||
194 | /* System Specific */ | ||
195 | #define KC_BRMU KC_PAUSE | ||
196 | #define KC_BRMD KC_SCROLLLOCK | ||
197 | |||
198 | /* Mouse Keys */ | ||
199 | #define KC_MS_U KC_MS_UP | ||
200 | #define KC_MS_D KC_MS_DOWN | ||
201 | #define KC_MS_L KC_MS_LEFT | ||
202 | #define KC_MS_R KC_MS_RIGHT | ||
203 | #define KC_BTN1 KC_MS_BTN1 | ||
204 | #define KC_BTN2 KC_MS_BTN2 | ||
205 | #define KC_BTN3 KC_MS_BTN3 | ||
206 | #define KC_BTN4 KC_MS_BTN4 | ||
207 | #define KC_BTN5 KC_MS_BTN5 | ||
208 | #define KC_BTN6 KC_MS_BTN6 | ||
209 | #define KC_BTN7 KC_MS_BTN7 | ||
210 | #define KC_BTN8 KC_MS_BTN8 | ||
211 | #define KC_WH_U KC_MS_WH_UP | ||
212 | #define KC_WH_D KC_MS_WH_DOWN | ||
213 | #define KC_WH_L KC_MS_WH_LEFT | ||
214 | #define KC_WH_R KC_MS_WH_RIGHT | ||
215 | #define KC_ACL0 KC_MS_ACCEL0 | ||
216 | #define KC_ACL1 KC_MS_ACCEL1 | ||
217 | #define KC_ACL2 KC_MS_ACCEL2 | ||
218 | |||
219 | /* Keyboard/Keypad Page (0x07) */ | ||
220 | enum hid_keyboard_keypad_usage { | ||
221 | KC_NO = 0x00, | ||
222 | KC_ROLL_OVER, | ||
223 | KC_POST_FAIL, | ||
224 | KC_UNDEFINED, | ||
225 | KC_A, | ||
226 | KC_B, | ||
227 | KC_C, | ||
228 | KC_D, | ||
229 | KC_E, | ||
230 | KC_F, | ||
231 | KC_G, | ||
232 | KC_H, | ||
233 | KC_I, | ||
234 | KC_J, | ||
235 | KC_K, | ||
236 | KC_L, | ||
237 | KC_M, // 0x10 | ||
238 | KC_N, | ||
239 | KC_O, | ||
240 | KC_P, | ||
241 | KC_Q, | ||
242 | KC_R, | ||
243 | KC_S, | ||
244 | KC_T, | ||
245 | KC_U, | ||
246 | KC_V, | ||
247 | KC_W, | ||
248 | KC_X, | ||
249 | KC_Y, | ||
250 | KC_Z, | ||
251 | KC_1, | ||
252 | KC_2, | ||
253 | KC_3, // 0x20 | ||
254 | KC_4, | ||
255 | KC_5, | ||
256 | KC_6, | ||
257 | KC_7, | ||
258 | KC_8, | ||
259 | KC_9, | ||
260 | KC_0, | ||
261 | KC_ENTER, | ||
262 | KC_ESCAPE, | ||
263 | KC_BSPACE, | ||
264 | KC_TAB, | ||
265 | KC_SPACE, | ||
266 | KC_MINUS, | ||
267 | KC_EQUAL, | ||
268 | KC_LBRACKET, | ||
269 | KC_RBRACKET, // 0x30 | ||
270 | KC_BSLASH, | ||
271 | KC_NONUS_HASH, | ||
272 | KC_SCOLON, | ||
273 | KC_QUOTE, | ||
274 | KC_GRAVE, | ||
275 | KC_COMMA, | ||
276 | KC_DOT, | ||
277 | KC_SLASH, | ||
278 | KC_CAPSLOCK, | ||
279 | KC_F1, | ||
280 | KC_F2, | ||
281 | KC_F3, | ||
282 | KC_F4, | ||
283 | KC_F5, | ||
284 | KC_F6, | ||
285 | KC_F7, // 0x40 | ||
286 | KC_F8, | ||
287 | KC_F9, | ||
288 | KC_F10, | ||
289 | KC_F11, | ||
290 | KC_F12, | ||
291 | KC_PSCREEN, | ||
292 | KC_SCROLLLOCK, | ||
293 | KC_PAUSE, | ||
294 | KC_INSERT, | ||
295 | KC_HOME, | ||
296 | KC_PGUP, | ||
297 | KC_DELETE, | ||
298 | KC_END, | ||
299 | KC_PGDOWN, | ||
300 | KC_RIGHT, | ||
301 | KC_LEFT, // 0x50 | ||
302 | KC_DOWN, | ||
303 | KC_UP, | ||
304 | KC_NUMLOCK, | ||
305 | KC_KP_SLASH, | ||
306 | KC_KP_ASTERISK, | ||
307 | KC_KP_MINUS, | ||
308 | KC_KP_PLUS, | ||
309 | KC_KP_ENTER, | ||
310 | KC_KP_1, | ||
311 | KC_KP_2, | ||
312 | KC_KP_3, | ||
313 | KC_KP_4, | ||
314 | KC_KP_5, | ||
315 | KC_KP_6, | ||
316 | KC_KP_7, | ||
317 | KC_KP_8, // 0x60 | ||
318 | KC_KP_9, | ||
319 | KC_KP_0, | ||
320 | KC_KP_DOT, | ||
321 | KC_NONUS_BSLASH, | ||
322 | KC_APPLICATION, | ||
323 | KC_POWER, | ||
324 | KC_KP_EQUAL, | ||
325 | KC_F13, | ||
326 | KC_F14, | ||
327 | KC_F15, | ||
328 | KC_F16, | ||
329 | KC_F17, | ||
330 | KC_F18, | ||
331 | KC_F19, | ||
332 | KC_F20, | ||
333 | KC_F21, // 0x70 | ||
334 | KC_F22, | ||
335 | KC_F23, | ||
336 | KC_F24, | ||
337 | KC_EXECUTE, | ||
338 | KC_HELP, | ||
339 | KC_MENU, | ||
340 | KC_SELECT, | ||
341 | KC_STOP, | ||
342 | KC_AGAIN, | ||
343 | KC_UNDO, | ||
344 | KC_CUT, | ||
345 | KC_COPY, | ||
346 | KC_PASTE, | ||
347 | KC_FIND, | ||
348 | KC__MUTE, | ||
349 | KC__VOLUP, // 0x80 | ||
350 | KC__VOLDOWN, | ||
351 | KC_LOCKING_CAPS, | ||
352 | KC_LOCKING_NUM, | ||
353 | KC_LOCKING_SCROLL, | ||
354 | KC_KP_COMMA, | ||
355 | KC_KP_EQUAL_AS400, | ||
356 | KC_INT1, | ||
357 | KC_INT2, | ||
358 | KC_INT3, | ||
359 | KC_INT4, | ||
360 | KC_INT5, | ||
361 | KC_INT6, | ||
362 | KC_INT7, | ||
363 | KC_INT8, | ||
364 | KC_INT9, | ||
365 | KC_LANG1, // 0x90 | ||
366 | KC_LANG2, | ||
367 | KC_LANG3, | ||
368 | KC_LANG4, | ||
369 | KC_LANG5, | ||
370 | KC_LANG6, | ||
371 | KC_LANG7, | ||
372 | KC_LANG8, | ||
373 | KC_LANG9, | ||
374 | KC_ALT_ERASE, | ||
375 | KC_SYSREQ, | ||
376 | KC_CANCEL, | ||
377 | KC_CLEAR, | ||
378 | KC_PRIOR, | ||
379 | KC_RETURN, | ||
380 | KC_SEPARATOR, | ||
381 | KC_OUT, // 0xA0 | ||
382 | KC_OPER, | ||
383 | KC_CLEAR_AGAIN, | ||
384 | KC_CRSEL, | ||
385 | KC_EXSEL, | ||
386 | |||
387 | #if 0 | ||
388 | // *************************************************************** | ||
389 | // These keycodes are present in the HID spec, but are * | ||
390 | // nonfunctional on modern OSes. QMK uses this range (0xA5-0xDF) * | ||
391 | // for the media and function keys instead - see below. * | ||
392 | // *************************************************************** | ||
393 | |||
394 | KC_KP_00 = 0xB0, | ||
395 | KC_KP_000, | ||
396 | KC_THOUSANDS_SEPARATOR, | ||
397 | KC_DECIMAL_SEPARATOR, | ||
398 | KC_CURRENCY_UNIT, | ||
399 | KC_CURRENCY_SUB_UNIT, | ||
400 | KC_KP_LPAREN, | ||
401 | KC_KP_RPAREN, | ||
402 | KC_KP_LCBRACKET, | ||
403 | KC_KP_RCBRACKET, | ||
404 | KC_KP_TAB, | ||
405 | KC_KP_BSPACE, | ||
406 | KC_KP_A, | ||
407 | KC_KP_B, | ||
408 | KC_KP_C, | ||
409 | KC_KP_D, | ||
410 | KC_KP_E, //0xC0 | ||
411 | KC_KP_F, | ||
412 | KC_KP_XOR, | ||
413 | KC_KP_HAT, | ||
414 | KC_KP_PERC, | ||
415 | KC_KP_LT, | ||
416 | KC_KP_GT, | ||
417 | KC_KP_AND, | ||
418 | KC_KP_LAZYAND, | ||
419 | KC_KP_OR, | ||
420 | KC_KP_LAZYOR, | ||
421 | KC_KP_COLON, | ||
422 | KC_KP_HASH, | ||
423 | KC_KP_SPACE, | ||
424 | KC_KP_ATMARK, | ||
425 | KC_KP_EXCLAMATION, | ||
426 | KC_KP_MEM_STORE, //0xD0 | ||
427 | KC_KP_MEM_RECALL, | ||
428 | KC_KP_MEM_CLEAR, | ||
429 | KC_KP_MEM_ADD, | ||
430 | KC_KP_MEM_SUB, | ||
431 | KC_KP_MEM_MUL, | ||
432 | KC_KP_MEM_DIV, | ||
433 | KC_KP_PLUS_MINUS, | ||
434 | KC_KP_CLEAR, | ||
435 | KC_KP_CLEAR_ENTRY, | ||
436 | KC_KP_BINARY, | ||
437 | KC_KP_OCTAL, | ||
438 | KC_KP_DECIMAL, | ||
439 | KC_KP_HEXADECIMAL, | ||
440 | #endif | ||
441 | |||
442 | /* Modifiers */ | ||
443 | KC_LCTRL = 0xE0, | ||
444 | KC_LSHIFT, | ||
445 | KC_LALT, | ||
446 | KC_LGUI, | ||
447 | KC_RCTRL, | ||
448 | KC_RSHIFT, | ||
449 | KC_RALT, | ||
450 | KC_RGUI | ||
451 | |||
452 | // ********************************************** | ||
453 | // * 0xF0-0xFF are unallocated in the HID spec. * | ||
454 | // * QMK uses these for Mouse Keys - see below. * | ||
455 | // ********************************************** | ||
456 | }; | ||
457 | |||
458 | /* Media and Function keys */ | ||
459 | enum internal_special_keycodes { | ||
460 | /* Generic Desktop Page (0x01) */ | ||
461 | KC_SYSTEM_POWER = 0xA5, | ||
462 | KC_SYSTEM_SLEEP, | ||
463 | KC_SYSTEM_WAKE, | ||
464 | |||
465 | /* Consumer Page (0x0C) */ | ||
466 | KC_AUDIO_MUTE, | ||
467 | KC_AUDIO_VOL_UP, | ||
468 | KC_AUDIO_VOL_DOWN, | ||
469 | KC_MEDIA_NEXT_TRACK, | ||
470 | KC_MEDIA_PREV_TRACK, | ||
471 | KC_MEDIA_STOP, | ||
472 | KC_MEDIA_PLAY_PAUSE, | ||
473 | KC_MEDIA_SELECT, | ||
474 | KC_MEDIA_EJECT, // 0xB0 | ||
475 | KC_MAIL, | ||
476 | KC_CALCULATOR, | ||
477 | KC_MY_COMPUTER, | ||
478 | KC_WWW_SEARCH, | ||
479 | KC_WWW_HOME, | ||
480 | KC_WWW_BACK, | ||
481 | KC_WWW_FORWARD, | ||
482 | KC_WWW_STOP, | ||
483 | KC_WWW_REFRESH, | ||
484 | KC_WWW_FAVORITES, | ||
485 | KC_MEDIA_FAST_FORWARD, | ||
486 | KC_MEDIA_REWIND, | ||
487 | KC_BRIGHTNESS_UP, | ||
488 | KC_BRIGHTNESS_DOWN, | ||
489 | |||
490 | /* Fn keys */ | ||
491 | KC_FN0 = 0xC0, | ||
492 | KC_FN1, | ||
493 | KC_FN2, | ||
494 | KC_FN3, | ||
495 | KC_FN4, | ||
496 | KC_FN5, | ||
497 | KC_FN6, | ||
498 | KC_FN7, | ||
499 | KC_FN8, | ||
500 | KC_FN9, | ||
501 | KC_FN10, | ||
502 | KC_FN11, | ||
503 | KC_FN12, | ||
504 | KC_FN13, | ||
505 | KC_FN14, | ||
506 | KC_FN15, | ||
507 | KC_FN16, // 0xD0 | ||
508 | KC_FN17, | ||
509 | KC_FN18, | ||
510 | KC_FN19, | ||
511 | KC_FN20, | ||
512 | KC_FN21, | ||
513 | KC_FN22, | ||
514 | KC_FN23, | ||
515 | KC_FN24, | ||
516 | KC_FN25, | ||
517 | KC_FN26, | ||
518 | KC_FN27, | ||
519 | KC_FN28, | ||
520 | KC_FN29, | ||
521 | KC_FN30, | ||
522 | KC_FN31 | ||
523 | }; | ||
524 | |||
525 | enum mouse_keys { | ||
526 | /* Mouse Buttons */ | ||
527 | #ifdef VIA_ENABLE | ||
528 | KC_MS_UP = 0xF0, | ||
529 | #else | ||
530 | KC_MS_UP = 0xED, | ||
531 | #endif | ||
532 | KC_MS_DOWN, | ||
533 | KC_MS_LEFT, | ||
534 | KC_MS_RIGHT, // 0xF0 | ||
535 | KC_MS_BTN1, | ||
536 | KC_MS_BTN2, | ||
537 | KC_MS_BTN3, | ||
538 | KC_MS_BTN4, | ||
539 | KC_MS_BTN5, | ||
540 | #ifdef VIA_ENABLE | ||
541 | KC_MS_BTN6 = KC_MS_BTN5, | ||
542 | KC_MS_BTN7 = KC_MS_BTN5, | ||
543 | KC_MS_BTN8 = KC_MS_BTN5, | ||
544 | #else | ||
545 | KC_MS_BTN6, | ||
546 | KC_MS_BTN7, | ||
547 | KC_MS_BTN8, | ||
548 | #endif | ||
549 | |||
550 | /* Mouse Wheel */ | ||
551 | KC_MS_WH_UP, | ||
552 | KC_MS_WH_DOWN, | ||
553 | KC_MS_WH_LEFT, | ||
554 | KC_MS_WH_RIGHT, | ||
555 | |||
556 | /* Acceleration */ | ||
557 | KC_MS_ACCEL0, | ||
558 | KC_MS_ACCEL1, | ||
559 | KC_MS_ACCEL2 // 0xFF | ||
560 | }; | ||