diff options
author | Ofer Plesser <plesserofer@gmail.com> | 2016-12-10 00:49:11 +0200 |
---|---|---|
committer | Ofer Plesser <plesserofer@gmail.com> | 2016-12-10 00:49:11 +0200 |
commit | eac8fa799909817bfc7cb4043448f85551154c6b (patch) | |
tree | 202951d31842163d6aa4899aa3c2647ff569e422 /quantum/process_keycode/process_combo.c | |
parent | d0c667c790479ac50804db0d212d0adf157c3e0b (diff) | |
download | qmk_firmware-eac8fa799909817bfc7cb4043448f85551154c6b.tar.gz qmk_firmware-eac8fa799909817bfc7cb4043448f85551154c6b.zip |
Implemented basic key combination feature
Diffstat (limited to 'quantum/process_keycode/process_combo.c')
-rw-r--r-- | quantum/process_keycode/process_combo.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c new file mode 100644 index 000000000..a6cfed11a --- /dev/null +++ b/quantum/process_keycode/process_combo.c | |||
@@ -0,0 +1,66 @@ | |||
1 | #include "process_combo.h" | ||
2 | #include "print.h" | ||
3 | |||
4 | // __attribute__ ((weak)) | ||
5 | // combo_t key_combos[] = { | ||
6 | |||
7 | // }; | ||
8 | |||
9 | #define SEND_KEY(key) \ | ||
10 | do { \ | ||
11 | register_code16(key); \ | ||
12 | send_keyboard_report(); \ | ||
13 | unregister_code16(key); \ | ||
14 | } while(0) | ||
15 | |||
16 | |||
17 | #define ALL_COMBO_KEYS_ARE_DOWN (((1<<count)-1) == combo->state) | ||
18 | static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record) | ||
19 | { | ||
20 | uint8_t count = 0; | ||
21 | bool is_combo_key = false; | ||
22 | // bool combo_key_released = false; | ||
23 | |||
24 | // Count the number of combo keys | ||
25 | for (const uint16_t *key = combo->keys; COMBO_END != pgm_read_word(key); ++key, ++count); | ||
26 | |||
27 | for (uint8_t i = 0; i < count; ++i) { | ||
28 | uint16_t key = pgm_read_word(&combo->keys[i]); | ||
29 | |||
30 | if (key == keycode) { | ||
31 | is_combo_key = true; | ||
32 | |||
33 | if (record->event.pressed) { | ||
34 | combo->state |= (1<<i); | ||
35 | } else { // Combo key released | ||
36 | if (!combo->state) { | ||
37 | // The combo was sent, no need to send released key | ||
38 | return true; | ||
39 | } | ||
40 | |||
41 | combo->state &= ~(1<<i); | ||
42 | SEND_KEY(key); | ||
43 | } | ||
44 | } | ||
45 | } | ||
46 | |||
47 | if (ALL_COMBO_KEYS_ARE_DOWN) { | ||
48 | SEND_KEY(combo->action); | ||
49 | combo->state = 0; | ||
50 | } | ||
51 | |||
52 | return is_combo_key; | ||
53 | } | ||
54 | |||
55 | |||
56 | bool process_combo(uint16_t keycode, keyrecord_t *record) | ||
57 | { | ||
58 | bool is_combo_key = false; | ||
59 | |||
60 | for (int i = 0; i < NUM_ELEMS(key_combos); ++i) { | ||
61 | combo_t *combo = &key_combos[i]; | ||
62 | is_combo_key |= process_single_combo(combo, keycode, record); | ||
63 | } | ||
64 | |||
65 | return !is_combo_key; | ||
66 | } \ No newline at end of file | ||