]> git.donarmstrong.com Git - qmk_firmware.git/blob - quantum/process_keycode/process_combo.c
Implemented basic key combination feature
[qmk_firmware.git] / quantum / process_keycode / process_combo.c
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 }