13 static void process(keyevent_t event, action_t action);
14 static void register_code(uint8_t code);
15 static void unregister_code(uint8_t code);
16 static void add_mods(uint8_t mods);
17 static void del_mods(uint8_t mods);
18 static void set_mods(uint8_t mods);
19 static void clear_keyboard(void);
20 static void clear_keyboard_but_mods(void);
21 static bool sending_anykey(void);
22 static void layer_switch(uint8_t new_layer);
27 static keyevent_t last_event = {};
28 static uint8_t tap_count = 0;
31 uint8_t default_layer = 0;
32 uint8_t current_layer = 0;
33 keyrecord_t delaying_layer = {};
35 /* waiting keys buffer */
36 #define WAITING_KEYS_BUFFER 3
37 static keyrecord_t waiting_keys[WAITING_KEYS_BUFFER] = {};
38 static uint8_t waiting_keys_head = 0;
39 static bool waiting_keys_enqueue(keyevent_t event, action_t action)
41 debug("waiting_keys["); debug_dec(waiting_keys_head); debug("] = ");
42 debug_hex16(action.code); debug("\n");
43 if (waiting_keys_head < WAITING_KEYS_BUFFER) {
44 waiting_keys[waiting_keys_head++] = (keyrecord_t){ .event = event,
46 .mods = host_get_mods() };
51 static void waiting_keys_clear(void)
53 waiting_keys_head = 0;
55 static bool waiting_keys_has(keypos_t key)
57 for (uint8_t i = 0; i < waiting_keys_head; i++) {
58 if KEYEQ(key, waiting_keys[i].event.key) return true;
62 static void waiting_keys_process_in_current_layer(void)
64 // TODO: in case of including layer key in waiting keys
65 uint8_t tmp_mods = host_get_mods();
66 for (uint8_t i = 0; i < waiting_keys_head; i++) {
67 /* revive status of mods */
68 host_set_mods(waiting_keys[i].mods);
69 process(waiting_keys[i].event, keymap_get_action(current_layer,
70 waiting_keys[i].event.key.row,
71 waiting_keys[i].event.key.col));
72 debug("waiting_keys_process_in_current_layer["); debug_dec(i); debug("]\n");
74 host_set_mods(tmp_mods);
79 void action_exec(keyevent_t event)
81 /* When delaying layer switch */
82 if (delaying_layer.action.code) {
83 /* Layer switch when tap time elapses or waiting key is released */
84 if ((timer_elapsed(delaying_layer.event.time) > TAP_TIME) ||
85 (!event.pressed && waiting_keys_has(event.key))) {
87 switch (delaying_layer.action.kind.id) {
88 case ACT_LAYER_PRESSED:
89 layer_switch(delaying_layer.action.layer.opt);
92 layer_switch(current_layer | delaying_layer.action.layer.opt);
95 delaying_layer = (keyrecord_t){};
97 /* Process waiting keys in new layer */
98 waiting_keys_process_in_current_layer();
100 /* when delaying layer key is released within delay term */
101 else if (!event.pressed && KEYEQ(event.key, delaying_layer.event.key)) {
103 debug("tap[delaying_layer](register): fist\n");
104 uint8_t tmp_mods = host_get_mods();
105 host_set_mods(delaying_layer.mods);
106 register_code(delaying_layer.action.layer.code);
107 delaying_layer = (keyrecord_t){};
108 host_set_mods(tmp_mods);
110 /* process waiting keys */
111 waiting_keys_process_in_current_layer();
115 // not real event. event just to update delaying layer.
116 if (IS_NOEVENT(event)) {
120 /* count tap when key is up */
121 if (KEYEQ(event.key, last_event.key) && timer_elapsed(last_event.time) <= TAP_TIME) {
122 if (!event.pressed) tap_count++;
127 action_t action = keymap_get_action(current_layer, event.key.row, event.key.col);
129 // TODO: all key events(pressed, released) should be recorded?
130 /* postpone key-down events while delaying layer */
131 if (delaying_layer.action.code) {
133 waiting_keys_enqueue(event, action);
135 process(event, action);
138 process(event, action);
146 static void process(keyevent_t event, action_t action)
148 //action_t action = keymap_get_action(current_layer, event.key.row, event.key.col);
149 debug("action: "); debug_hex16(action.code);
150 if (event.pressed) debug("[down]\n"); else debug("[up]\n");
152 switch (action.kind.id) {
155 // |pressed |released
156 // --------------+---------------------------------+------------
157 // key |down(key) |up(key)
158 // mods |add(mods) |del(mods)
159 // key with mods |add(mods), down(key), unset(mods)|up(key)
161 uint8_t tmp_mods = host_get_mods();
162 if (action.key.mods) {
163 host_add_mods(action.key.mods);
164 host_send_keyboard_report();
166 register_code(action.key.code);
167 if (action.key.mods && action.key.code) {
168 host_set_mods(tmp_mods);
169 host_send_keyboard_report();
172 if (action.key.mods && !action.key.code) {
173 host_del_mods(action.key.mods);
174 host_send_keyboard_report();
176 unregister_code(action.key.code);
180 // |pressed |released
181 // --------------+---------------------------------+------------
182 // key |down(key) |up(key)
183 // mods |add(mods) |del(mods)
184 // key with mods |add(mods), down(key), unset(mods)|up(key)
186 uint8_t tmp_mods = host_get_mods();
187 if (action.key.mods) {
188 host_add_mods(action.key.mods<<4);
189 host_send_keyboard_report();
191 register_code(action.key.code);
192 if (action.key.mods && action.key.code) {
193 host_set_mods(tmp_mods);
194 host_send_keyboard_report();
197 if (action.key.mods && !action.key.code) {
198 host_del_mods(action.key.mods<<4);
199 host_send_keyboard_report();
201 unregister_code(action.key.code);
206 if (tap_count == 0) {
207 add_mods(action.key.mods);
209 debug("tap[lmods](register): "); debug_hex(tap_count); debug("\n");
210 register_code(action.key.code);
213 if (tap_count == 0) {
214 del_mods(action.key.mods);
215 } else if (tap_count == 1) {
216 debug("tap[lmods](register/unregister): "); debug_hex(tap_count); debug("\n");
217 del_mods(action.key.mods);
218 register_code(action.key.code);
219 unregister_code(action.key.code);
221 debug("tap[lmods](unregister): "); debug_hex(tap_count); debug("\n");
222 unregister_code(action.key.code);
228 if (tap_count == 0) {
229 add_mods(action.key.mods<<4);
231 debug("tap[rmods](register): "); debug_hex(tap_count); debug("\n");
232 register_code(action.key.code);
235 if (tap_count == 0) {
236 del_mods(action.key.mods<<4);
237 } else if (tap_count == 1) {
238 debug("tap[rmods](register/unregister): "); debug_hex(tap_count); debug("\n");
239 del_mods(action.key.mods<<4);
240 register_code(action.key.code);
241 unregister_code(action.key.code);
243 debug("tap[rmods](unregister): "); debug_hex(tap_count); debug("\n");
244 unregister_code(action.key.code);
249 /* other HID usage */
251 #ifdef EXTRAKEY_ENABLE
252 switch (action.usage.page) {
253 case ACTION_USAGE_PAGE_SYSTEM:
255 host_system_send(action.usage.code);
260 case ACTION_USAGE_PAGE_CONSUMER:
262 host_consumer_send(action.usage.code);
264 host_consumer_send(0);
273 #ifdef MOUSEKEY_ENABLE
275 mousekey_on(action.key.code);
278 mousekey_off(action.key.code);
285 case ACT_LAYER_PRESSED:
286 // layer action when pressed
287 switch (action.layer.code) {
290 layer_switch(action.layer.opt);
298 default_layer = action.layer.opt;
299 layer_switch(default_layer);
305 if (tap_count == 0) {
307 if (host_has_anykey()) {
308 register_code(action.layer.code);
310 debug("Delay switching layer("); debug_hex8(action.layer.opt); debug(")\n");
311 delaying_layer = (keyrecord_t){
314 .mods = host_get_mods()
317 } else if (tap_count > 0) {
318 // pressed after tapping
319 debug("tap[layer](register): "); debug_hex(tap_count); debug("\n");
320 register_code(action.layer.code);
323 // released after tapping
324 debug("tap[layer](unregister): "); debug_hex(tap_count); debug("\n");
325 unregister_code(action.layer.code);
330 case ACT_LAYER_RELEASED:
331 switch (action.layer.code) {
333 if (!event.pressed) {
334 layer_switch(action.layer.opt);
338 // Ignored. LAYER_RELEASED with tap toggle is invalid action.
341 if (!event.pressed) {
342 default_layer = action.layer.opt;
343 layer_switch(default_layer);
347 // Ignored. LAYER_RELEASED with tap key is invalid action.
352 switch (action.layer.code) {
355 layer_switch(current_layer | action.layer.opt);
357 layer_switch(current_layer & ~action.layer.opt);
364 // change default layer
366 default_layer = current_layer | action.layer.opt;
367 layer_switch(default_layer);
369 default_layer = current_layer & ~action.layer.opt;
370 layer_switch(default_layer);
376 if (tap_count == 0) {
377 if (host_has_anykey()) {
378 register_code(action.layer.code);
380 delaying_layer = (keyrecord_t){
383 .mods = keyboard_report->mods
386 } else if (tap_count > 0) {
387 debug("tap[layer_bit](register): "); debug_hex(tap_count); debug("\n");
388 register_code(action.layer.code);
391 if (tap_count == 0) {
393 layer_switch(current_layer & ~action.layer.opt);
394 } else if (tap_count == 1) {
396 register_code(action.layer.code);
398 unregister_code(action.layer.code);
403 switch (action.layer.opt) {
405 // set default layer when pressed
406 switch (action.layer.code) {
409 layer_switch(default_layer);
417 default_layer = current_layer;
418 layer_switch(default_layer);
427 // set default layer when released
428 switch (action.layer.code) {
430 if (!event.pressed) {
431 layer_switch(default_layer);
435 if (!event.pressed) {
436 default_layer = current_layer;
437 layer_switch(default_layer);
443 if (!event.pressed) {
444 layer_switch(default_layer);
461 static void register_code(uint8_t code)
466 else if IS_KEY(code) {
467 // TODO: should push command_proc out of this block?
468 if (!command_proc(code)) {
470 host_send_keyboard_report();
473 else if IS_MOD(code) {
474 host_add_mods(MOD_BIT(code));
475 host_send_keyboard_report();
479 static void unregister_code(uint8_t code)
483 host_send_keyboard_report();
485 else if IS_MOD(code) {
486 host_del_mods(MOD_BIT(code));
487 host_send_keyboard_report();
491 static void add_mods(uint8_t mods)
495 host_send_keyboard_report();
499 static void del_mods(uint8_t mods)
503 host_send_keyboard_report();
507 static void set_mods(uint8_t mods)
510 host_send_keyboard_report();
513 static void clear_keyboard(void)
516 clear_keyboard_but_mods();
519 static void clear_keyboard_but_mods(void)
522 host_send_keyboard_report();
523 #ifdef MOUSEKEY_ENABLE
527 #ifdef EXTRAKEY_ENABLE
529 host_consumer_send(0);
533 static bool sending_anykey(void)
535 return (host_has_anykey() || host_mouse_in_use() ||
536 host_last_sysytem_report() || host_last_consumer_report());
539 static void layer_switch(uint8_t new_layer)
541 if (current_layer != new_layer) {
542 debug("Layer Switch: "); debug_hex(current_layer);
543 debug(" -> "); debug_hex(new_layer); debug("\n");
545 current_layer = new_layer;
546 clear_keyboard_but_mods(); // To avoid stuck keys
547 // TODO: update mods with full scan of matrix? if modifier changes between layers