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 | ||
