]> git.gir.st - tmk_keyboard.git/blob - layer.c
added protocol stack: pjrc, vusb
[tmk_keyboard.git] / layer.c
1 #include "keymap_skel.h"
2 #include "keyboard.h"
3 #include "debug.h"
4 #include "timer.h"
5 #include "layer.h"
6
7 /*
8 * Parameters:
9 * ENTER_DELAY |=======|
10 * SEND_FN_TERM |================|
11 *
12 * Fn key processing cases:
13 * 1. release Fn after SEND_FN_TERM.
14 * Layer sw ___________|~~~~~~~~~~~|___
15 * Fn press ___|~~~~~~~~~~~~~~~~~~~|___
16 * Fn send ___________________________
17 *
18 * 2. release Fn during SEND_FN_TERM.(not layer used)
19 * Layer sw ___________|~~~~~~|________
20 * Fn press ___|~~~~~~~~~~~~~~|________
21 * Fn key send __________________|~|______
22 * other key press ___________________________
23 * other key send ___________________________
24 *
25 * 3. release Fn during SEND_FN_TERM.(layer used)
26 * Layer sw ___________|~~~~~~|________
27 * Fn press ___|~~~~~~~~~~~~~~|________
28 * Fn key send ___________________________
29 * Fn send ___________________________
30 * other key press _____________|~~|__________
31 * other key send _____________|~~|__________
32 *
33 * 4. press other key during ENTER_DELAY.
34 * Layer sw ___________________________
35 * Fn key press ___|~~~~~~~~~|_____________
36 * Fn key send ______|~~~~~~|_____________
37 * other key press ______|~~~|________________
38 * other key send _______|~~|________________
39 *
40 * 5. press Fn while press other key.
41 * Layer sw ___________________________
42 * Fn key press ___|~~~~~~~~~|_____________
43 * Fn key send ___|~~~~~~~~~|_____________
44 * other key press ~~~~~~~|___________________
45 * other key send ~~~~~~~|___________________
46 *
47 * 6. press Fn twice quickly and keep holding down.(repeat)
48 * Layer sw ___________________________
49 * Fn key press ___|~|____|~~~~~~~~~~~~~~~~
50 * Fn key send _____|~|__|~~~~~~~~~~~~~~~~
51 */
52
53 // LAYER_ENTER_DELAY: prevent from moving new layer
54 #define LAYER_ENTER_DELAY 10
55
56 // LAYER_SEND_FN_TERM: send keycode if release key in this term
57 #define LAYER_SEND_FN_TERM 40
58
59
60 uint8_t default_layer = 0;
61 uint8_t current_layer = 0;
62
63 static bool layer_used = false;
64 static uint8_t new_layer(uint8_t fn_bits);
65
66
67 uint8_t layer_get_keycode(uint8_t row, uint8_t col)
68 {
69 uint8_t code = keymap_get_keycode(current_layer, row, col);
70 // normal key or mouse key
71 if ((IS_KEY(code) || IS_MOUSEKEY(code))) {
72 layer_used = true;
73 }
74 return code;
75 }
76
77 // bit substract b from a
78 #define BIT_SUBT(a, b) (a&(a^b))
79 void layer_switching(uint8_t fn_bits)
80 {
81 // layer switching
82 static uint8_t last_fn = 0;
83 static uint8_t last_mods = 0;
84 static uint16_t last_timer = 0;
85 static uint8_t sent_fn = 0;
86
87 if (fn_bits == last_fn) { // Fn state is not changed
88 if (fn_bits == 0) {
89 // do nothing
90 } else {
91 if (timer_elapsed(last_timer) > LAYER_ENTER_DELAY) {
92 uint8_t _layer_to_switch = new_layer(BIT_SUBT(fn_bits, sent_fn));
93 if (current_layer != _layer_to_switch) { // not switch layer yet
94 debug("Fn case: 1,2,3(LAYER_ENTER_DELAY passed)\n");
95 debug("Switch Layer: "); debug_hex(current_layer);
96 current_layer = _layer_to_switch;
97 layer_used = false;
98 debug(" -> "); debug_hex(current_layer); debug("\n");
99 }
100 } else {
101 if (keyboard_has_anykey()) { // other keys is pressed
102 uint8_t _fn_to_send = BIT_SUBT(fn_bits, sent_fn);
103 if (_fn_to_send) {
104 debug("Fn case: 4(send Fn before other key pressed)\n");
105 // send only Fn key first
106 keyboard_swap_report();
107 keyboard_clear_report();
108 keyboard_add_code(keymap_fn_keycode(_fn_to_send)); // TODO: do all Fn keys
109 keyboard_set_mods(last_mods);
110 keyboard_send();
111 keyboard_swap_report();
112 sent_fn |= _fn_to_send;
113 }
114 }
115 }
116 // add Fn keys to send
117 //keyboard_add_code(keymap_fn_keycode(fn_bits&sent_fn)); // TODO: do all Fn keys
118 }
119 } else { // Fn state is changed(edge)
120 uint8_t fn_changed = 0;
121
122 debug("fn_bits: "); debug_bin(fn_bits); debug("\n");
123 debug("sent_fn: "); debug_bin(sent_fn); debug("\n");
124 debug("last_fn: "); debug_bin(last_fn); debug("\n");
125 debug("last_mods: "); debug_hex(last_mods); debug("\n");
126 debug("last_timer: "); debug_hex16(last_timer); debug("\n");
127
128 // pressed Fn
129 if ((fn_changed = BIT_SUBT(fn_bits, last_fn))) {
130 debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
131 if (keyboard_has_anykey()) {
132 debug("Fn case: 5(pressed Fn with other key)\n");
133 sent_fn |= fn_changed;
134 } else if (fn_changed & sent_fn) { // pressed same Fn in a row
135 if (timer_elapsed(last_timer) > LAYER_ENTER_DELAY) {
136 debug("Fn case: 6(repate2)\n");
137 // time passed: not repeate
138 sent_fn &= ~fn_changed;
139 } else {
140 debug("Fn case: 6(repate)\n");
141 }
142 }
143 }
144 // released Fn
145 if ((fn_changed = BIT_SUBT(last_fn, fn_bits))) {
146 debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
147 if (timer_elapsed(last_timer) < LAYER_SEND_FN_TERM) {
148 //if (!layer_used && BIT_SUBT(fn_changed, sent_fn)) { // layer not used && Fn not sent
149 if (BIT_SUBT(fn_changed, sent_fn)) { // layer not used && Fn not sent
150 debug("Fn case: 2(send Fn one shot: released Fn during LAYER_SEND_FN_TERM)\n");
151 // send only Fn key first
152 keyboard_swap_report();
153 keyboard_clear_report();
154 keyboard_add_code(keymap_fn_keycode(fn_changed)); // TODO: do all Fn keys
155 keyboard_set_mods(last_mods);
156 keyboard_send();
157 keyboard_swap_report();
158 sent_fn |= fn_changed;
159 }
160 }
161 debug("Switch Layer(released Fn): "); debug_hex(current_layer);
162 current_layer = new_layer(BIT_SUBT(fn_bits, sent_fn));
163 layer_used = false;
164 debug(" -> "); debug_hex(current_layer); debug("\n");
165 }
166
167 last_fn = fn_bits;
168 last_mods = keyboard_report->mods;
169 last_timer = timer_read();
170 }
171 // send Fn keys
172 for (uint8_t i = 0; i < 8; i++) {
173 if ((sent_fn & fn_bits) & (1<<i)) {
174 keyboard_add_code(keymap_fn_keycode(1<<i));
175 }
176 }
177 }
178
179 inline
180 static uint8_t new_layer(uint8_t fn_bits)
181 {
182 return (fn_bits ? keymap_fn_layer(fn_bits) : default_layer);
183 }
Imprint / Impressum