diff options
author | skullY <skullydazed@gmail.com> | 2019-08-30 11:19:03 -0700 |
---|---|---|
committer | skullydazed <skullydazed@users.noreply.github.com> | 2019-08-30 15:01:52 -0700 |
commit | b624f32f944acdc59dcb130674c09090c5c404cb (patch) | |
tree | bc13adbba137d122d9a2c2fb2fafcbb08ac10e25 /quantum/process_keycode/process_combo.c | |
parent | 61af76a10d00aba185b8338604171de490a13e3b (diff) | |
download | qmk_firmware-b624f32f944acdc59dcb130674c09090c5c404cb.tar.gz qmk_firmware-b624f32f944acdc59dcb130674c09090c5c404cb.zip |
clang-format changes
Diffstat (limited to 'quantum/process_keycode/process_combo.c')
-rw-r--r-- | quantum/process_keycode/process_combo.c | 259 |
1 files changed, 124 insertions, 135 deletions
diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c index d3c3b1673..f40ca7452 100644 --- a/quantum/process_keycode/process_combo.c +++ b/quantum/process_keycode/process_combo.c | |||
@@ -21,14 +21,13 @@ __attribute__((weak)) combo_t key_combos[COMBO_COUNT] = { | |||
21 | 21 | ||
22 | }; | 22 | }; |
23 | 23 | ||
24 | __attribute__((weak)) void process_combo_event(uint8_t combo_index, | 24 | __attribute__((weak)) void process_combo_event(uint8_t combo_index, bool pressed) {} |
25 | bool pressed) {} | ||
26 | 25 | ||
27 | static uint16_t timer = 0; | 26 | static uint16_t timer = 0; |
28 | static uint8_t current_combo_index = 0; | 27 | static uint8_t current_combo_index = 0; |
29 | static bool drop_buffer = false; | 28 | static bool drop_buffer = false; |
30 | static bool is_active = false; | 29 | static bool is_active = false; |
31 | static bool b_combo_enable = true; // defaults to enabled | 30 | static bool b_combo_enable = true; // defaults to enabled |
32 | 31 | ||
33 | static uint8_t buffer_size = 0; | 32 | static uint8_t buffer_size = 0; |
34 | #ifdef COMBO_ALLOW_ACTION_KEYS | 33 | #ifdef COMBO_ALLOW_ACTION_KEYS |
@@ -38,171 +37,163 @@ static uint16_t key_buffer[MAX_COMBO_LENGTH]; | |||
38 | #endif | 37 | #endif |
39 | 38 | ||
40 | static inline void send_combo(uint16_t action, bool pressed) { | 39 | static inline void send_combo(uint16_t action, bool pressed) { |
41 | if (action) { | 40 | if (action) { |
42 | if (pressed) { | 41 | if (pressed) { |
43 | register_code16(action); | 42 | register_code16(action); |
43 | } else { | ||
44 | unregister_code16(action); | ||
45 | } | ||
44 | } else { | 46 | } else { |
45 | unregister_code16(action); | 47 | process_combo_event(current_combo_index, pressed); |
46 | } | 48 | } |
47 | } else { | ||
48 | process_combo_event(current_combo_index, pressed); | ||
49 | } | ||
50 | } | 49 | } |
51 | 50 | ||
52 | static inline void dump_key_buffer(bool emit) { | 51 | static inline void dump_key_buffer(bool emit) { |
53 | if (buffer_size == 0) { | 52 | if (buffer_size == 0) { |
54 | return; | 53 | return; |
55 | } | 54 | } |
56 | 55 | ||
57 | if (emit) { | 56 | if (emit) { |
58 | for (uint8_t i = 0; i < buffer_size; i++) { | 57 | for (uint8_t i = 0; i < buffer_size; i++) { |
59 | #ifdef COMBO_ALLOW_ACTION_KEYS | 58 | #ifdef COMBO_ALLOW_ACTION_KEYS |
60 | const action_t action = store_or_get_action(key_buffer[i].event.pressed, | 59 | const action_t action = store_or_get_action(key_buffer[i].event.pressed, key_buffer[i].event.key); |
61 | key_buffer[i].event.key); | 60 | process_action(&(key_buffer[i]), action); |
62 | process_action(&(key_buffer[i]), action); | ||
63 | #else | 61 | #else |
64 | register_code16(key_buffer[i]); | 62 | register_code16(key_buffer[i]); |
65 | send_keyboard_report(); | 63 | send_keyboard_report(); |
66 | #endif | 64 | #endif |
65 | } | ||
67 | } | 66 | } |
68 | } | ||
69 | 67 | ||
70 | buffer_size = 0; | 68 | buffer_size = 0; |
71 | } | 69 | } |
72 | 70 | ||
73 | #define ALL_COMBO_KEYS_ARE_DOWN (((1 << count) - 1) == combo->state) | 71 | #define ALL_COMBO_KEYS_ARE_DOWN (((1 << count) - 1) == combo->state) |
74 | #define KEY_STATE_DOWN(key) \ | 72 | #define KEY_STATE_DOWN(key) \ |
75 | do { \ | 73 | do { \ |
76 | combo->state |= (1 << key); \ | 74 | combo->state |= (1 << key); \ |
77 | } while (0) | 75 | } while (0) |
78 | #define KEY_STATE_UP(key) \ | 76 | #define KEY_STATE_UP(key) \ |
79 | do { \ | 77 | do { \ |
80 | combo->state &= ~(1 << key); \ | 78 | combo->state &= ~(1 << key); \ |
81 | } while (0) | 79 | } while (0) |
82 | 80 | ||
83 | static bool process_single_combo(combo_t *combo, uint16_t keycode, | 81 | static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record) { |
84 | keyrecord_t *record) { | 82 | uint8_t count = 0; |
85 | uint8_t count = 0; | 83 | uint8_t index = -1; |
86 | uint8_t index = -1; | 84 | /* Find index of keycode and number of combo keys */ |
87 | /* Find index of keycode and number of combo keys */ | 85 | for (const uint16_t *keys = combo->keys;; ++count) { |
88 | for (const uint16_t *keys = combo->keys;; ++count) { | 86 | uint16_t key = pgm_read_word(&keys[count]); |
89 | uint16_t key = pgm_read_word(&keys[count]); | 87 | if (keycode == key) index = count; |
90 | if (keycode == key) | 88 | if (COMBO_END == key) break; |
91 | index = count; | ||
92 | if (COMBO_END == key) | ||
93 | break; | ||
94 | } | ||
95 | |||
96 | /* Continue processing if not a combo key */ | ||
97 | if (-1 == (int8_t)index) | ||
98 | return false; | ||
99 | |||
100 | bool is_combo_active = is_active; | ||
101 | |||
102 | if (record->event.pressed) { | ||
103 | KEY_STATE_DOWN(index); | ||
104 | |||
105 | if (is_combo_active) { | ||
106 | if (ALL_COMBO_KEYS_ARE_DOWN) { /* Combo was pressed */ | ||
107 | send_combo(combo->keycode, true); | ||
108 | drop_buffer = true; | ||
109 | } | ||
110 | } | 89 | } |
111 | } else { | 90 | |
112 | if (ALL_COMBO_KEYS_ARE_DOWN) { /* Combo was released */ | 91 | /* Continue processing if not a combo key */ |
113 | send_combo(combo->keycode, false); | 92 | if (-1 == (int8_t)index) return false; |
93 | |||
94 | bool is_combo_active = is_active; | ||
95 | |||
96 | if (record->event.pressed) { | ||
97 | KEY_STATE_DOWN(index); | ||
98 | |||
99 | if (is_combo_active) { | ||
100 | if (ALL_COMBO_KEYS_ARE_DOWN) { /* Combo was pressed */ | ||
101 | send_combo(combo->keycode, true); | ||
102 | drop_buffer = true; | ||
103 | } | ||
104 | } | ||
114 | } else { | 105 | } else { |
115 | /* continue processing without immediately returning */ | 106 | if (ALL_COMBO_KEYS_ARE_DOWN) { /* Combo was released */ |
116 | is_combo_active = false; | 107 | send_combo(combo->keycode, false); |
108 | } else { | ||
109 | /* continue processing without immediately returning */ | ||
110 | is_combo_active = false; | ||
111 | } | ||
112 | |||
113 | KEY_STATE_UP(index); | ||
117 | } | 114 | } |
118 | 115 | ||
119 | KEY_STATE_UP(index); | 116 | return is_combo_active; |
120 | } | ||
121 | |||
122 | return is_combo_active; | ||
123 | } | 117 | } |
124 | 118 | ||
125 | #define NO_COMBO_KEYS_ARE_DOWN (0 == combo->state) | 119 | #define NO_COMBO_KEYS_ARE_DOWN (0 == combo->state) |
126 | 120 | ||
127 | bool process_combo(uint16_t keycode, keyrecord_t *record) { | 121 | bool process_combo(uint16_t keycode, keyrecord_t *record) { |
128 | bool is_combo_key = false; | 122 | bool is_combo_key = false; |
129 | drop_buffer = false; | 123 | drop_buffer = false; |
130 | bool no_combo_keys_pressed = true; | 124 | bool no_combo_keys_pressed = true; |
131 | 125 | ||
132 | if (keycode == CMB_ON && record->event.pressed) { | 126 | if (keycode == CMB_ON && record->event.pressed) { |
133 | combo_enable(); | 127 | combo_enable(); |
134 | return true; | 128 | return true; |
135 | } | 129 | } |
136 | |||
137 | if (keycode == CMB_OFF && record->event.pressed) { | ||
138 | combo_disable(); | ||
139 | return true; | ||
140 | } | ||
141 | |||
142 | if (keycode == CMB_TOG && record->event.pressed) { | ||
143 | combo_toggle(); | ||
144 | return true; | ||
145 | } | ||
146 | |||
147 | if (!is_combo_enabled()) { return true; } | ||
148 | |||
149 | for (current_combo_index = 0; current_combo_index < COMBO_COUNT; | ||
150 | ++current_combo_index) { | ||
151 | combo_t *combo = &key_combos[current_combo_index]; | ||
152 | is_combo_key |= process_single_combo(combo, keycode, record); | ||
153 | no_combo_keys_pressed = no_combo_keys_pressed && NO_COMBO_KEYS_ARE_DOWN; | ||
154 | } | ||
155 | |||
156 | if (drop_buffer) { | ||
157 | /* buffer is only dropped when we complete a combo, so we refresh the timer | ||
158 | * here */ | ||
159 | timer = timer_read(); | ||
160 | dump_key_buffer(false); | ||
161 | } else if (!is_combo_key) { | ||
162 | /* if no combos claim the key we need to emit the keybuffer */ | ||
163 | dump_key_buffer(true); | ||
164 | 130 | ||
165 | // reset state if there are no combo keys pressed at all | 131 | if (keycode == CMB_OFF && record->event.pressed) { |
166 | if (no_combo_keys_pressed) { | 132 | combo_disable(); |
167 | timer = 0; | 133 | return true; |
168 | is_active = true; | ||
169 | } | 134 | } |
170 | } else if (record->event.pressed && is_active) { | ||
171 | /* otherwise the key is consumed and placed in the buffer */ | ||
172 | timer = timer_read(); | ||
173 | 135 | ||
174 | if (buffer_size < MAX_COMBO_LENGTH) { | 136 | if (keycode == CMB_TOG && record->event.pressed) { |
137 | combo_toggle(); | ||
138 | return true; | ||
139 | } | ||
140 | |||
141 | if (!is_combo_enabled()) { | ||
142 | return true; | ||
143 | } | ||
144 | |||
145 | for (current_combo_index = 0; current_combo_index < COMBO_COUNT; ++current_combo_index) { | ||
146 | combo_t *combo = &key_combos[current_combo_index]; | ||
147 | is_combo_key |= process_single_combo(combo, keycode, record); | ||
148 | no_combo_keys_pressed = no_combo_keys_pressed && NO_COMBO_KEYS_ARE_DOWN; | ||
149 | } | ||
150 | |||
151 | if (drop_buffer) { | ||
152 | /* buffer is only dropped when we complete a combo, so we refresh the timer | ||
153 | * here */ | ||
154 | timer = timer_read(); | ||
155 | dump_key_buffer(false); | ||
156 | } else if (!is_combo_key) { | ||
157 | /* if no combos claim the key we need to emit the keybuffer */ | ||
158 | dump_key_buffer(true); | ||
159 | |||
160 | // reset state if there are no combo keys pressed at all | ||
161 | if (no_combo_keys_pressed) { | ||
162 | timer = 0; | ||
163 | is_active = true; | ||
164 | } | ||
165 | } else if (record->event.pressed && is_active) { | ||
166 | /* otherwise the key is consumed and placed in the buffer */ | ||
167 | timer = timer_read(); | ||
168 | |||
169 | if (buffer_size < MAX_COMBO_LENGTH) { | ||
175 | #ifdef COMBO_ALLOW_ACTION_KEYS | 170 | #ifdef COMBO_ALLOW_ACTION_KEYS |
176 | key_buffer[buffer_size++] = *record; | 171 | key_buffer[buffer_size++] = *record; |
177 | #else | 172 | #else |
178 | key_buffer[buffer_size++] = keycode; | 173 | key_buffer[buffer_size++] = keycode; |
179 | #endif | 174 | #endif |
175 | } | ||
180 | } | 176 | } |
181 | } | ||
182 | 177 | ||
183 | return !is_combo_key; | 178 | return !is_combo_key; |
184 | } | 179 | } |
185 | 180 | ||
186 | void matrix_scan_combo(void) { | 181 | void matrix_scan_combo(void) { |
187 | if (b_combo_enable && is_active && timer && timer_elapsed(timer) > COMBO_TERM) { | 182 | if (b_combo_enable && is_active && timer && timer_elapsed(timer) > COMBO_TERM) { |
188 | 183 | /* This disables the combo, meaning key events for this | |
189 | /* This disables the combo, meaning key events for this | 184 | * combo will be handled by the next processors in the chain |
190 | * combo will be handled by the next processors in the chain | 185 | */ |
191 | */ | 186 | is_active = false; |
192 | is_active = false; | 187 | dump_key_buffer(true); |
193 | dump_key_buffer(true); | 188 | } |
194 | } | ||
195 | } | 189 | } |
196 | 190 | ||
197 | void combo_enable(void) { | 191 | void combo_enable(void) { b_combo_enable = true; } |
198 | b_combo_enable = true; | ||
199 | } | ||
200 | 192 | ||
201 | void combo_disable(void) { | 193 | void combo_disable(void) { |
202 | b_combo_enable = is_active = false; | 194 | b_combo_enable = is_active = false; |
203 | timer = 0; | 195 | timer = 0; |
204 | dump_key_buffer(true); | 196 | dump_key_buffer(true); |
205 | |||
206 | } | 197 | } |
207 | 198 | ||
208 | void combo_toggle(void) { | 199 | void combo_toggle(void) { |
@@ -213,6 +204,4 @@ void combo_toggle(void) { | |||
213 | } | 204 | } |
214 | } | 205 | } |
215 | 206 | ||
216 | bool is_combo_enabled(void) { | 207 | bool is_combo_enabled(void) { return b_combo_enable; } |
217 | return b_combo_enable; | ||
218 | } | ||