From 11f087002052be0aab285a77362085008e853be6 Mon Sep 17 00:00:00 2001 From: tmk Date: Sun, 27 May 2012 14:04:28 +0900 Subject: [PATCH] FIX: layer switching bug when Fn has no keycode. - Fn without keycode doesn't need LAYER_SWITCH_DELAY. --- host.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ host.h | 3 +++ layer.c | 44 +++++++++++++++++++++++++------------------- 3 files changed, 75 insertions(+), 19 deletions(-) mode change 100755 => 100644 layer.c diff --git a/host.c b/host.c index c5383ed4..cc26d55c 100644 --- 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 06f1311a..11b9aacd 100644 --- 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 new mode 100644 index 40b4d7b3..0854eede --- a/layer.c +++ b/layer.c @@ -25,7 +25,7 @@ along with this program. If not, see . /* * Parameters: - * ENTER_DELAY |=======| + * SWITCH_DELAY |=======| * SEND_FN_TERM |================| * * Fn key processing cases: @@ -49,7 +49,7 @@ along with this program. If not, see . * 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 . * 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; } }