X-Git-Url: https://git.friedersdorff.com/?a=blobdiff_plain;f=common%2Fkeyboard.c;h=b0e0ed7935278f5b97f617822bfb2b12944951b6;hb=f291c2279eb9f656ed2a2e3152bab155470c4ef9;hp=37d3b06ba2b672102890cbc3e682f0cdd37d4853;hpb=71ac82337f803e8ec0c081b3221ac0ccf61035b0;p=max%2Ftmk_keyboard.git diff --git a/common/keyboard.c b/common/keyboard.c index 37d3b06b..b0e0ed79 100644 --- a/common/keyboard.c +++ b/common/keyboard.c @@ -28,11 +28,12 @@ along with this program. If not, see . #ifdef MOUSEKEY_ENABLE #include "mousekey.h" #endif -#ifdef EXTRAKEY_ENABLE -#include -#endif +#define Kdebug(s) do { if (debug_keyboard) debug(s); } while(0) +#define Kdebug_P(s) do { if (debug_keyboard) debug_P(s); } while(0) +#define Kdebug_hex(s) do { if (debug_keyboard) debug_hex(s); } while(0) + #define LAYER_DELAY 250 typedef enum keykind { @@ -46,8 +47,13 @@ typedef enum keykind { typedef enum { IDLE, DELAYING, WAITING, PRESSING } kbdstate_t; -uint8_t current_layer = 0; +#ifdef KEYMAP_DEFAULT_LAYER +uint8_t default_layer = KEYMAP_DEFAULT_LAYER; +uint8_t current_layer = KEYMAP_DEFAULT_LAYER; +#else uint8_t default_layer = 0; +uint8_t current_layer = 0; +#endif /* keyboard internal states */ static kbdstate_t kbdstate = IDLE; @@ -90,8 +96,10 @@ static void clear_keyboard(void) host_system_send(0); host_consumer_send(0); +#ifdef MOUSEKEY_ENABLE mousekey_clear(); mousekey_send(); +#endif } static void clear_keyboard_but_mods(void) @@ -102,48 +110,44 @@ static void clear_keyboard_but_mods(void) host_system_send(0); host_consumer_send(0); +#ifdef MOUSEKEY_ENABLE mousekey_clear(); mousekey_send(); +#endif +} + +static bool anykey_sent_to_host(void) +{ + return (host_has_anykey() || host_mouse_in_use() || + host_last_sysytem_report() || host_last_consumer_report()); } static void layer_switch_on(uint8_t code) { if (!IS_FN(code)) return; fn_state_bits |= FN_BIT(code); - if (current_layer != keymap_fn_layer(FN_INDEX(code))) { - clear_keyboard_but_mods(); + uint8_t new_layer = (fn_state_bits ? keymap_fn_layer(biton(fn_state_bits)) : default_layer); + if (current_layer != new_layer) { + Kdebug("Layer Switch(on): "); Kdebug_hex(current_layer); + Kdebug(" -> "); Kdebug_hex(new_layer); Kdebug("\n"); - debug("Layer Switch(on): "); debug_hex(current_layer); - current_layer = keymap_fn_layer(FN_INDEX(code)); - debug(" -> "); debug_hex(current_layer); debug("\n"); + clear_keyboard_but_mods(); + current_layer = new_layer; } } -static void layer_switch_off(uint8_t code) +static bool layer_switch_off(uint8_t code) { - if (!IS_FN(code)) return; + if (!IS_FN(code)) return false; fn_state_bits &= ~FN_BIT(code); - if (current_layer != keymap_fn_layer(biton(fn_state_bits))) { - clear_keyboard_but_mods(); + uint8_t new_layer = (fn_state_bits ? keymap_fn_layer(biton(fn_state_bits)) : default_layer); + if (current_layer != new_layer) { + Kdebug("Layer Switch(off): "); Kdebug_hex(current_layer); + Kdebug(" -> "); Kdebug_hex(new_layer); Kdebug("\n"); - debug("Layer Switch(off): "); debug_hex(current_layer); - current_layer = keymap_fn_layer(biton(fn_state_bits)); - debug(" -> "); debug_hex(current_layer); debug("\n"); - } -} - -// whether any key except modifier is down or not -static inline bool is_anykey_down(void) -{ - for (int r = 0; r < MATRIX_ROWS; r++) { - matrix_row_t matrix_row = matrix_get_row(r); - for (int c = 0; c < MATRIX_COLS; c++) { - if (matrix_row && (1< "); print_P(state_str(kbdstate)); debug("\n"); \ + Kdebug(" -> "); Kdebug_P(state_str(kbdstate)); Kdebug("\n"); \ } while (0) static inline void process_key(keyevent_t event) @@ -317,11 +347,11 @@ static inline void process_key(keyevent_t event) uint8_t tmp_mods; - debug("state: "); print_P(state_str(kbdstate)); - debug(" kind: "); debug_hex(kind); - debug(" code: "); debug_hex(code); - if (event.pressed) { debug("d"); } else { debug("u"); } - debug("\n"); + Kdebug("state: "); Kdebug_P(state_str(kbdstate)); + Kdebug(" kind: "); Kdebug_hex(kind); + Kdebug(" code: "); Kdebug_hex(code); + if (event.pressed) { Kdebug("d"); } else { Kdebug("u"); } + Kdebug("\n"); switch (kbdstate) { case IDLE: @@ -336,7 +366,7 @@ static inline void process_key(keyevent_t event) // repeat Fn alt key when press Fn key down, up then down again quickly if (KEYEQ(delayed_fn.event.key, event.key) && timer_elapsed(delayed_fn.time) < LAYER_DELAY) { - register_code(keymap_fn_keycode(FN_INDEX(code))); + register_code(code); NEXT(PRESSING); } else { delayed_fn = (keyrecord_t) { @@ -372,16 +402,20 @@ static inline void process_key(keyevent_t event) // ignored when any key is pressed break; case FN_UP: - layer_switch_off(code); - NEXT(IDLE); + if (layer_switch_off(code)) + NEXT(IDLE); break; case FNK_DOWN: - register_code(keymap_fn_keycode(FN_INDEX(code))); + register_code(code); break; case FNK_UP: - // can't know whether layer switched or not - layer_switch_off(code); - unregister_code(keymap_fn_keycode(FN_INDEX(code))); + if (layer_switch_off(code)) { + NEXT(IDLE); + } else { + unregister_code(code); + if (!anykey_sent_to_host()) + NEXT(IDLE); + } break; case KEY_DOWN: case MOD_DOWN: @@ -390,8 +424,7 @@ static inline void process_key(keyevent_t event) case KEY_UP: case MOD_UP: unregister_code(code); - // no key registered? mousekey, mediakey, systemkey - if (!host_has_anykey()) + if (!anykey_sent_to_host()) NEXT(IDLE); break; default: @@ -415,8 +448,8 @@ static inline void process_key(keyevent_t event) register_code(code); break; case FN_UP: - layer_switch_off(code); - NEXT(IDLE); + if (layer_switch_off(code)) + NEXT(IDLE); break; case FNK_UP: if (code == delayed_fn.code) { @@ -424,19 +457,16 @@ static inline void process_key(keyevent_t event) // restore the mod status at the time of pressing Fn key tmp_mods = keyboard_report->mods; host_set_mods(delayed_fn.mods); - register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code))); - unregister_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code))); + register_code(delayed_fn.code); + unregister_code(delayed_fn.code); host_set_mods(tmp_mods); NEXT(IDLE); } else { - layer_switch_off(code); - NEXT(IDLE); + if (layer_switch_off(code)) + NEXT(IDLE); } break; case KEY_UP: - unregister_code(code); - NEXT(IDLE); - break; case MOD_UP: unregister_code(code); break; @@ -451,34 +481,40 @@ static inline void process_key(keyevent_t event) case KEY_DOWN: tmp_mods = keyboard_report->mods; host_set_mods(delayed_fn.mods); - register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code))); + register_code(delayed_fn.code); host_set_mods(waiting_key.mods); register_code(waiting_key.code); host_set_mods(tmp_mods); - register_code(code); + if (kind == FN_DOWN) { + // ignore Fn + } else if (kind == FNK_DOWN) { + register_code(code); + } else if (kind == KEY_DOWN) { + register_code(code); + } NEXT(IDLE); break; case MOD_DOWN: register_code(code); break; case FN_UP: - layer_switch_off(code); - NEXT(IDLE); + if (layer_switch_off(code)) + NEXT(IDLE); break; case FNK_UP: if (code == delayed_fn.code) { // alt down, key down, alt up tmp_mods = keyboard_report->mods; host_set_mods(delayed_fn.mods); - register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code))); + register_code(delayed_fn.code); host_set_mods(waiting_key.mods); register_code(waiting_key.code); - unregister_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code))); + unregister_code(delayed_fn.code); host_set_mods(tmp_mods); NEXT(IDLE); } else { - layer_switch_off(code); - NEXT(IDLE); + if (layer_switch_off(code)) + NEXT(IDLE); } break; case KEY_UP: @@ -519,17 +555,11 @@ void keyboard_init(void) void keyboard_task(void) { static matrix_row_t matrix_prev[MATRIX_ROWS]; + static uint8_t led_status = 0; matrix_row_t matrix_row = 0; matrix_row_t matrix_change = 0; matrix_scan(); - if (command_proc()) { - debug("COMMAND\n"); - // TODO: COMMAND state? - clear_keyboard(); - return; - } - for (int r = 0; r < MATRIX_ROWS; r++) { matrix_row = matrix_get_row(r); matrix_change = matrix_row ^ matrix_prev[r]; @@ -570,8 +600,10 @@ void keyboard_task(void) } } +#ifdef MOUSEKEY_ENABLE // mousekey repeat & acceleration mousekey_task(); +#endif // FAIL SAFE: clear all key if no key down if (matrix_change) { @@ -580,11 +612,18 @@ void keyboard_task(void) is_matrix_on |= matrix_get_row(r); } if (!is_matrix_on) { - debug("FAIL SAFE: clear all keys.\n"); + Kdebug("FAIL SAFE: clear all keys(default layer).\n"); clear_keyboard(); + current_layer = default_layer; } } - + + // update LED + if (led_status != host_keyboard_leds()) { + led_status = host_keyboard_leds(); + keyboard_set_leds(led_status); + } + return; }