]> git.friedersdorff.com Git - max/tmk_keyboard.git/commitdiff
FIX: layer switching bug when Fn has no keycode.
authortmk <nobody@nowhere>
Sun, 27 May 2012 05:04:28 +0000 (14:04 +0900)
committertmk <nobody@nowhere>
Sun, 27 May 2012 05:04:28 +0000 (14:04 +0900)
- Fn without keycode doesn't need LAYER_SWITCH_DELAY.

host.c
host.h
layer.c [changed mode: 0755->0644]

diff --git a/host.c b/host.c
index c5383ed4242c705c703a79fe1e9f3cc2852de923..cc26d55c22b94b9d85f06503fad3160ccadafaf7 100644 (file)
--- a/host.c
+++ b/host.c
@@ -35,7 +35,9 @@ report_keyboard_t *keyboard_report_prev = &report1;
 
 
 static inline void add_key_byte(uint8_t code);
+static inline void del_key_byte(uint8_t code);
 static inline void add_key_bit(uint8_t code);
+static inline void del_key_bit(uint8_t code);
 
 
 void host_set_driver(host_driver_t *d)
@@ -66,11 +68,27 @@ void host_add_key(uint8_t key)
     add_key_byte(key);
 }
 
+void host_del_key(uint8_t key)
+{
+#ifdef NKRO_ENABLE
+    if (keyboard_nkro) {
+        del_key_bit(key);
+        return;
+    }
+#endif
+    del_key_byte(key);
+}
+
 void host_add_mod_bit(uint8_t mod)
 {
     keyboard_report->mods |= mod;
 }
 
+void host_del_mod_bit(uint8_t mod)
+{
+    keyboard_report->mods &= ~mod;
+}
+
 void host_set_mods(uint8_t mods)
 {
     keyboard_report->mods = mods;
@@ -85,6 +103,15 @@ void host_add_code(uint8_t code)
     }
 }
 
+void host_del_code(uint8_t code)
+{
+    if (IS_MOD(code)) {
+        host_del_mod_bit(MOD_BIT(code));
+    } else {
+        host_del_key(code);
+    }
+}
+
 void host_swap_keyboard_report(void)
 {
     uint8_t sreg = SREG;
@@ -180,6 +207,17 @@ static inline void add_key_byte(uint8_t code)
     }
 }
 
+static inline void del_key_byte(uint8_t code)
+{
+    int i = 0;
+    for (; i < REPORT_KEYS; i++) {
+        if (keyboard_report->keys[i] == code) {
+            keyboard_report->keys[i] = 0;
+            break;
+        }
+    }
+}
+
 static inline void add_key_bit(uint8_t code)
 {
     if ((code>>3) < REPORT_KEYS) {
@@ -188,3 +226,12 @@ static inline void add_key_bit(uint8_t code)
         debug("add_key_bit: can't add: "); phex(code); debug("\n");
     }
 }
+
+static inline void del_key_bit(uint8_t code)
+{
+    if ((code>>3) < REPORT_KEYS) {
+        keyboard_report->keys[code>>3] &= ~(1<<(code&7));
+    } else {
+        debug("del_key_bit: can't del: "); phex(code); debug("\n");
+    }
+}
diff --git a/host.h b/host.h
index 06f1311ab04cec8ad5e1fceb52759995d0e37905..11b9aacd7cc50f89537ea3c614952dee72ac32f0 100644 (file)
--- a/host.h
+++ b/host.h
@@ -37,9 +37,12 @@ uint8_t host_keyboard_leds(void);
 
 /* keyboard report operations */
 void host_add_key(uint8_t key);
+void host_del_key(uint8_t key);
 void host_add_mod_bit(uint8_t mod);
+void host_del_mod_bit(uint8_t mod);
 void host_set_mods(uint8_t mods);
 void host_add_code(uint8_t code);
+void host_del_code(uint8_t code);
 void host_swap_keyboard_report(void);
 void host_clear_keyboard_report(void);
 uint8_t host_has_anykey(void);
diff --git a/layer.c b/layer.c
old mode 100755 (executable)
new mode 100644 (file)
index 40b4d7b..0854eed
--- a/layer.c
+++ b/layer.c
@@ -25,7 +25,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 /*
  * Parameters:
- *     ENTER_DELAY         |=======|
+ *     SWITCH_DELAY        |=======|
  *     SEND_FN_TERM        |================|
  *
  * Fn key processing cases:
@@ -49,7 +49,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *     other key press  _____________|~~|__________
  *     other key send   _____________|~~|__________
  *
- * 4. press other key during ENTER_DELAY.
+ * 4. press other key during SWITCH_DELAY.
  *     Layer sw         ___________________________
  *     Fn key press     ___|~~~~~~~~~|_____________
  *     Fn key send      ______|~~~~~~|_____________
@@ -69,11 +69,15 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *     Fn key send      _____|~|__|~~~~~~~~~~~~~~~~
  */
 
-// LAYER_ENTER_DELAY: prevent from moving new layer
-#define LAYER_ENTER_DELAY 150
+// LAYER_SWITCH_DELAY: prevent from moving to new layer
+#ifndef LAYER_SWITCH_DELAY
+#   define LAYER_SWITCH_DELAY 150
+#endif
 
 // LAYER_SEND_FN_TERM: send keycode if release key in this term
-#define LAYER_SEND_FN_TERM 500
+#ifndef LAYER_SEND_FN_TERM
+#   define LAYER_SEND_FN_TERM 500
+#endif
 
 
 uint8_t default_layer = 0;
@@ -107,10 +111,11 @@ void layer_switching(uint8_t fn_bits)
         if (fn_bits == 0) {
             // do nothing
         } else {
-            if (timer_elapsed(last_timer) > LAYER_ENTER_DELAY) {
+            if (!keymap_fn_keycode(BIT_SUBST(fn_bits, sent_fn)) ||
+                    timer_elapsed(last_timer) > LAYER_SWITCH_DELAY) {
                 uint8_t _layer_to_switch = new_layer(BIT_SUBST(fn_bits, sent_fn));
                 if (current_layer != _layer_to_switch) { // not switch layer yet
-                    debug("Fn case: 1,2,3(LAYER_ENTER_DELAY passed)\n");
+                    debug("Fn case: 1,2,3(LAYER_SWITCH_DELAY passed)\n");
                     debug("Switch Layer: "); debug_hex(current_layer);
                     current_layer = _layer_to_switch;
                     layer_used = false;
@@ -120,14 +125,14 @@ void layer_switching(uint8_t fn_bits)
                 if (host_has_anykey()) { // other keys is pressed
                     uint8_t _fn_to_send = BIT_SUBST(fn_bits, sent_fn);
                     if (_fn_to_send) {
-                        debug("Fn case: 4(send Fn before other key pressed)\n");
+                        debug("Fn case: 4(press other key during SWITCH_DELAY.)\n");
                         // send only Fn key first
-                        host_swap_keyboard_report();
-                        host_clear_keyboard_report();
+                        uint8_t tmp_mods = keyboard_report->mods;
+                        host_add_code(keymap_fn_keycode(_fn_to_send));
                         host_set_mods(last_mods);
-                        host_add_code(keymap_fn_keycode(_fn_to_send));   // TODO: do all Fn keys
                         host_send_keyboard_report();
-                        host_swap_keyboard_report();
+                        host_set_mods(tmp_mods);
+                        host_del_code(keymap_fn_keycode(_fn_to_send));
                         sent_fn |= _fn_to_send;
                     }
                 }
@@ -143,15 +148,16 @@ void layer_switching(uint8_t fn_bits)
         debug("last_fn: "); debug_bin(last_fn); debug("\n");
         debug("last_mods: "); debug_hex(last_mods); debug("\n");
         debug("last_timer: "); debug_hex16(last_timer); debug("\n");
+        debug("timer_count: "); debug_hex16(timer_count); debug("\n");
 
         // pressed Fn
         if ((fn_changed = BIT_SUBST(fn_bits, last_fn))) {
-        debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
+            debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
             if (host_has_anykey()) {
                 debug("Fn case: 5(pressed Fn with other key)\n");
                 sent_fn |= fn_changed;
             } else if (fn_changed & sent_fn) { // pressed same Fn in a row
-                if (timer_elapsed(last_timer) > LAYER_ENTER_DELAY) {
+                if (timer_elapsed(last_timer) > LAYER_SEND_FN_TERM) {
                     debug("Fn case: 6(not repeat)\n");
                     // time passed: not repeate
                     sent_fn &= ~fn_changed;
@@ -162,17 +168,17 @@ void layer_switching(uint8_t fn_bits)
         }
         // released Fn
         if ((fn_changed = BIT_SUBST(last_fn, fn_bits))) {
-        debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
+            debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
             if (timer_elapsed(last_timer) < LAYER_SEND_FN_TERM) {
                 if (!layer_used && BIT_SUBST(fn_changed, sent_fn)) {
                     debug("Fn case: 2(send Fn one shot: released Fn during LAYER_SEND_FN_TERM)\n");
                     // send only Fn key first
-                    host_swap_keyboard_report();
-                    host_clear_keyboard_report();
+                    uint8_t tmp_mods = keyboard_report->mods;
+                    host_add_code(keymap_fn_keycode(fn_changed));
                     host_set_mods(last_mods);
-                    host_add_code(keymap_fn_keycode(fn_changed));   // TODO: do all Fn keys
                     host_send_keyboard_report();
-                    host_swap_keyboard_report();
+                    host_set_mods(tmp_mods);
+                    host_del_code(keymap_fn_keycode(fn_changed));
                     sent_fn |= fn_changed;
                 }
             }