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;
}