]> git.gir.st - tmk_keyboard.git/blob - layer.c
improve layer switching
[tmk_keyboard.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 }
Imprint / Impressum