]> git.donarmstrong.com Git - tmk_firmware.git/blob - layer.c
improve layer switching
[tmk_firmware.git] / layer.c
1 #include "keymap_skel.h"
2 #include "usb_keyboard.h"
3 #include "debug.h"
4 #include "timer.h"
5 #include "layer.h"
6
7 /*
8  * LAYER_ENTER_DELAY: prevent from moving new layer
9  *                     press                release
10  * Fn key sate     ____|~~~~~~~~~~~~~~~~~~~|_______________
11  * 
12  * enter_delay         |======|
13  *                              new layer
14  * Layer sw        ___________|~~~~~~~~~~~~|_______________
15  */ 
16 #define LAYER_ENTER_DELAY 10
17
18 /*
19  * LAYER_SEND_FN_TERM: send keycode if release key in this term
20  *                     press          release(send)
21  * Fn key state    ____|~~~~~~~~~~~~~|_______________
22  *                     press         |       release(not send)
23  * Fn key state    ____|~~~~~~~~~~~~~|~~~~~~|__________
24  *                                   |      |
25  * send_fn_term        |=============o==|   x
26  */
27 #define LAYER_SEND_FN_TERM 30
28
29
30 static uint8_t current_layer = 0;
31 static bool layer_used = false;
32
33
34 uint8_t layer_get_keycode(uint8_t row, uint8_t col)
35 {
36     uint8_t code = keymap_get_keycode(current_layer, row, col);
37     // normal key or mouse key
38     if ((IS_KEY(code) || IS_MOUSE(code)))
39         layer_used = true;
40     return code;
41 }
42
43 void layer_switching(uint8_t fn_bits)
44 {
45     // layer switching
46     static uint8_t last_bits = 0;
47     static uint8_t last_mod = 0;
48     static uint16_t last_timer = 0; 
49
50     //uint16_t now_timer;
51
52     if (fn_bits == last_bits) {
53         // switch layer when specific time elapsed
54         if (current_layer != keymap_fn_layer(fn_bits) &&
55                 timer_elapsed(last_timer) > LAYER_ENTER_DELAY) {
56             current_layer = keymap_fn_layer(fn_bits);
57             debug("time_elapsed: "); debug_hex16(timer_elapsed(last_timer)); debug("\n"); 
58             debug("switch layer: "); debug_hex(current_layer); debug("\n");
59         }
60     } else if (fn_bits == 0) {
61         // send key when Fn key is released without using the layer and within specific time
62         if ((!layer_used || current_layer != keymap_fn_layer(last_bits)) &&
63                 timer_elapsed(last_timer) < LAYER_SEND_FN_TERM) {
64             uint8_t code = keymap_fn_keycode(last_bits);
65             if (code != KB_NO) {
66                 if (IS_MOD(code)) {
67                     keyboard_modifier_keys = last_mod | MOD_BIT(code);
68                 } else {
69                     keyboard_keys[0] = code;
70                     keyboard_modifier_keys = last_mod;
71                 }
72                 usb_keyboard_send();
73                 usb_keyboard_print();
74                 usb_keyboard_clear();
75             }
76         }
77         last_bits = 0;
78         last_mod = 0;
79         layer_used = false;
80         current_layer = 0; // default layer
81     } else if ((fn_bits & (fn_bits - 1)) == 0) {
82         // switch layer when just one Fn Key is pressed
83         if (!usb_keyboard_has_key()) {
84             last_bits = fn_bits;
85             last_mod = keyboard_modifier_keys;
86             last_timer = timer_read();
87             debug("last_bits: "); debug_bin(last_bits); debug("\n");
88             debug("last_mod: "); debug_hex(last_mod); debug("\n");
89             debug("last_timer: "); debug_hex16(last_timer); debug("\n");
90         }
91     }
92 }