diff options
| -rw-r--r-- | build_keyboard.mk | 5 | ||||
| -rw-r--r-- | quantum/process_keycode/process_combo.c | 66 | ||||
| -rw-r--r-- | quantum/process_keycode/process_combo.h | 25 | ||||
| -rw-r--r-- | quantum/quantum.c | 3 | ||||
| -rw-r--r-- | quantum/quantum.h | 4 |
5 files changed, 103 insertions, 0 deletions
diff --git a/build_keyboard.mk b/build_keyboard.mk index ce505de12..14f4f36bc 100644 --- a/build_keyboard.mk +++ b/build_keyboard.mk | |||
| @@ -144,6 +144,11 @@ ifeq ($(strip $(MIDI_ENABLE)), yes) | |||
| 144 | SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c | 144 | SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c |
| 145 | endif | 145 | endif |
| 146 | 146 | ||
| 147 | ifeq ($(strip $(COMBO_ENABLE)), yes) | ||
| 148 | OPT_DEFS += -DCOMBO_ENABLE | ||
| 149 | SRC += $(QUANTUM_DIR)/process_keycode/process_combo.c | ||
| 150 | endif | ||
| 151 | |||
| 147 | ifeq ($(strip $(VIRTSER_ENABLE)), yes) | 152 | ifeq ($(strip $(VIRTSER_ENABLE)), yes) |
| 148 | OPT_DEFS += -DVIRTSER_ENABLE | 153 | OPT_DEFS += -DVIRTSER_ENABLE |
| 149 | endif | 154 | endif |
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 | ||
diff --git a/quantum/process_keycode/process_combo.h b/quantum/process_keycode/process_combo.h new file mode 100644 index 000000000..68786c0f1 --- /dev/null +++ b/quantum/process_keycode/process_combo.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | #ifndef PROCESS_COMBO_H | ||
| 2 | #define PROCESS_COMBO_H | ||
| 3 | |||
| 4 | #include <stdint.h> | ||
| 5 | #include "progmem.h" | ||
| 6 | #include "quantum.h" | ||
| 7 | |||
| 8 | |||
| 9 | typedef struct | ||
| 10 | { | ||
| 11 | const uint16_t *keys; | ||
| 12 | uint16_t action; | ||
| 13 | uint32_t state; | ||
| 14 | } combo_t; | ||
| 15 | |||
| 16 | |||
| 17 | #define COMBO_END 0 | ||
| 18 | #define NUM_ELEMS(a) (sizeof(a)/sizeof 0[a]) | ||
| 19 | |||
| 20 | |||
| 21 | extern combo_t key_combos[1]; | ||
| 22 | |||
| 23 | bool process_combo(uint16_t keycode, keyrecord_t *record); | ||
| 24 | |||
| 25 | #endif \ No newline at end of file | ||
diff --git a/quantum/quantum.c b/quantum/quantum.c index f653564a6..eabeacff8 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c | |||
| @@ -113,6 +113,9 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 113 | 113 | ||
| 114 | if (!( | 114 | if (!( |
| 115 | process_record_kb(keycode, record) && | 115 | process_record_kb(keycode, record) && |
| 116 | #ifdef COMBO_ENABLE | ||
| 117 | process_combo(keycode, record) && | ||
| 118 | #endif | ||
| 116 | #ifdef MIDI_ENABLE | 119 | #ifdef MIDI_ENABLE |
| 117 | process_midi(keycode, record) && | 120 | process_midi(keycode, record) && |
| 118 | #endif | 121 | #endif |
diff --git a/quantum/quantum.h b/quantum/quantum.h index e6adf974a..8614c053a 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h | |||
| @@ -63,6 +63,10 @@ extern uint32_t default_layer_state; | |||
| 63 | #include "process_printer.h" | 63 | #include "process_printer.h" |
| 64 | #endif | 64 | #endif |
| 65 | 65 | ||
| 66 | #ifdef COMBO_ENABLE | ||
| 67 | #include "process_combo.h" | ||
| 68 | #endif | ||
| 69 | |||
| 66 | #define SEND_STRING(str) send_string(PSTR(str)) | 70 | #define SEND_STRING(str) send_string(PSTR(str)) |
| 67 | void send_string(const char *str); | 71 | void send_string(const char *str); |
| 68 | 72 | ||
