]> git.gir.st - tmk_keyboard.git/blob - common/layer.c
Add submodule USB_Host_Shield_2.0 from my repositry.
[tmk_keyboard.git] / common / layer.c
1 /*
2 Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "keymap.h"
19 #include "host.h"
20 #include "debug.h"
21 #include "timer.h"
22 #include "usb_keycodes.h"
23 #include "layer.h"
24
25
26 /*
27 * Parameters:
28 * SWITCH_DELAY |=======|
29 * SEND_FN_TERM |================|
30 *
31 * Fn key processing cases:
32 * 1. release Fn after SEND_FN_TERM.
33 * Layer sw ___________|~~~~~~~~~~~|___
34 * Fn press ___|~~~~~~~~~~~~~~~~~~~|___
35 * Fn send ___________________________
36 *
37 * 2. release Fn during SEND_FN_TERM.(not layer used)
38 * Layer sw ___________|~~~~~~|________
39 * Fn press ___|~~~~~~~~~~~~~~|________
40 * Fn key send __________________|~|______
41 * other key press ___________________________
42 * other key send ___________________________
43 *
44 * 3. release Fn during SEND_FN_TERM.(layer used)
45 * Layer sw ___________|~~~~~~|________
46 * Fn press ___|~~~~~~~~~~~~~~|________
47 * Fn key send ___________________________
48 * Fn send ___________________________
49 * other key press _____________|~~|__________
50 * other key send _____________|~~|__________
51 *
52 * 4. press other key during SWITCH_DELAY.
53 * Layer sw ___________________________
54 * Fn key press ___|~~~~~~~~~|_____________
55 * Fn key send ______|~~~~~~|_____________
56 * other key press ______|~~~|________________
57 * other key send _______|~~|________________
58 *
59 * 5. press Fn while press other key.
60 * Layer sw ___________________________
61 * Fn key press ___|~~~~~~~~~|_____________
62 * Fn key send ___|~~~~~~~~~|_____________
63 * other key press ~~~~~~~|___________________
64 * other key send ~~~~~~~|___________________
65 *
66 * 6. press Fn twice quickly and keep holding down.(repeat)
67 * Layer sw ___________________________
68 * Fn key press ___|~|____|~~~~~~~~~~~~~~~~
69 * Fn key send _____|~|__|~~~~~~~~~~~~~~~~
70 */
71
72 // LAYER_SWITCH_DELAY: prevent from moving to new layer
73 #ifndef LAYER_SWITCH_DELAY
74 # define LAYER_SWITCH_DELAY 150
75 #endif
76
77 // LAYER_SEND_FN_TERM: send keycode if release key in this term
78 #ifndef LAYER_SEND_FN_TERM
79 # define LAYER_SEND_FN_TERM 500
80 #endif
81
82
83 uint8_t default_layer = 0;
84 uint8_t current_layer = 0;
85
86 static bool layer_used = false;
87 static uint8_t new_layer(uint8_t fn_bits);
88
89
90 uint8_t layer_get_keycode(uint8_t row, uint8_t col)
91 {
92 uint8_t code = keymap_get_keycode(current_layer, row, col);
93 // normal key or mouse key
94 if ((IS_KEY(code) || IS_MOUSEKEY(code))) {
95 layer_used = true;
96 }
97 return code;
98 }
99
100 // bit substract b from a
101 #define BIT_SUBST(a, b) (a&(a^b))
102 void layer_switching(uint8_t fn_bits)
103 {
104 // layer switching
105 static uint8_t last_fn = 0;
106 static uint8_t last_mods = 0;
107 static uint16_t last_timer = 0;
108 static uint8_t sent_fn = 0;
109
110 if (fn_bits == last_fn) { // Fn state is not changed
111 if (fn_bits == 0) {
112 // do nothing
113 } else {
114 if (!keymap_fn_keycode(BIT_SUBST(fn_bits, sent_fn)) ||
115 timer_elapsed(last_timer) > LAYER_SWITCH_DELAY) {
116 uint8_t _layer_to_switch = new_layer(BIT_SUBST(fn_bits, sent_fn));
117 if (current_layer != _layer_to_switch) { // not switch layer yet
118 debug("Fn case: 1,2,3(LAYER_SWITCH_DELAY passed)\n");
119 debug("Switch Layer: "); debug_hex(current_layer);
120 current_layer = _layer_to_switch;
121 layer_used = false;
122 debug(" -> "); debug_hex(current_layer); debug("\n");
123 }
124 } else {
125 if (host_has_anykey()) { // other keys is pressed
126 uint8_t _fn_to_send = BIT_SUBST(fn_bits, sent_fn);
127 if (_fn_to_send) {
128 debug("Fn case: 4(press other key during SWITCH_DELAY.)\n");
129 // send only Fn key first
130 uint8_t tmp_mods = keyboard_report->mods;
131 host_add_code(keymap_fn_keycode(_fn_to_send));
132 host_set_mods(last_mods);
133 host_send_keyboard_report();
134 host_set_mods(tmp_mods);
135 host_del_code(keymap_fn_keycode(_fn_to_send));
136 sent_fn |= _fn_to_send;
137 }
138 }
139 }
140 // add Fn keys to send
141 //host_add_code(keymap_fn_keycode(fn_bits&sent_fn)); // TODO: do all Fn keys
142 }
143 } else { // Fn state is changed(edge)
144 uint8_t fn_changed = 0;
145
146 debug("fn_bits: "); debug_bin(fn_bits); debug("\n");
147 debug("sent_fn: "); debug_bin(sent_fn); debug("\n");
148 debug("last_fn: "); debug_bin(last_fn); debug("\n");
149 debug("last_mods: "); debug_hex(last_mods); debug("\n");
150 debug("last_timer: "); debug_hex16(last_timer); debug("\n");
151 debug("timer_count: "); debug_hex16(timer_count); debug("\n");
152
153 // pressed Fn
154 if ((fn_changed = BIT_SUBST(fn_bits, last_fn))) {
155 debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
156 if (host_has_anykey()) {
157 debug("Fn case: 5(pressed Fn with other key)\n");
158 sent_fn |= fn_changed;
159 } else if (fn_changed & sent_fn) { // pressed same Fn in a row
160 if (timer_elapsed(last_timer) > LAYER_SEND_FN_TERM) {
161 debug("Fn case: 6(not repeat)\n");
162 // time passed: not repeate
163 sent_fn &= ~fn_changed;
164 } else {
165 debug("Fn case: 6(repeat)\n");
166 }
167 }
168 }
169 // released Fn
170 if ((fn_changed = BIT_SUBST(last_fn, fn_bits))) {
171 debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
172 if (timer_elapsed(last_timer) < LAYER_SEND_FN_TERM) {
173 if (!layer_used && BIT_SUBST(fn_changed, sent_fn)) {
174 debug("Fn case: 2(send Fn one shot: released Fn during LAYER_SEND_FN_TERM)\n");
175 // send only Fn key first
176 uint8_t tmp_mods = keyboard_report->mods;
177 host_add_code(keymap_fn_keycode(fn_changed));
178 host_set_mods(last_mods);
179 host_send_keyboard_report();
180 host_set_mods(tmp_mods);
181 host_del_code(keymap_fn_keycode(fn_changed));
182 sent_fn |= fn_changed;
183 }
184 }
185 debug("Switch Layer(released Fn): "); debug_hex(current_layer);
186 current_layer = new_layer(BIT_SUBST(fn_bits, sent_fn));
187 debug(" -> "); debug_hex(current_layer); debug("\n");
188 }
189
190 layer_used = false;
191 last_fn = fn_bits;
192 last_mods = keyboard_report->mods;
193 last_timer = timer_read();
194 }
195 // send Fn keys
196 for (uint8_t i = 0; i < 8; i++) {
197 if ((sent_fn & fn_bits) & (1<<i)) {
198 host_add_code(keymap_fn_keycode(1<<i));
199 }
200 }
201 }
202
203 inline
204 static uint8_t new_layer(uint8_t fn_bits)
205 {
206 return (fn_bits ? keymap_fn_layer(fn_bits) : default_layer);
207 }
Imprint / Impressum