]> git.donarmstrong.com Git - tmk_firmware.git/commitdiff
Fix waiting_keys and periodical update for delaying layer.
authortmk <nobody@nowhere>
Mon, 14 Jan 2013 15:06:52 +0000 (00:06 +0900)
committertmk <nobody@nowhere>
Mon, 14 Jan 2013 15:55:16 +0000 (00:55 +0900)
common/action.c
common/keyboard.c
common/keyboard.h
keyboard/hhkb/keymap.c

index 1a86f16d316406926e3e7dce52bc1589f903dc0f..389fc5df1ba7f7073cf37e23cd4110ac0ad7bbd5 100644 (file)
 #include "debug.h"
 #include "action.h"
 
-#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)
 
 
-/*
- *
- * Event/State|IDLE          PRESSING      DELAYING[f]      WAITING[f,k]         
- * -----------+------------------------------------------------------------------
- * Fn  Down   |(L+)          -*1           WAITING(Sk)      IDLE(Rf,Ps)*7        
- *     Up     |(L-)          IDLE(L-)*8    IDLE(L-)*8       IDLE(L-)*8           
- * Fnk Down   |DELAYING(Sf)* (Rf)          WAITING(Sk)      IDLE(Rf,Ps,Rf)       
- *     Up     |(L-)          IDLE(L-/Uf)*8 IDLE(Rf,Uf/L-)*3 IDLE(Rf,Ps,Uf/L-)*3  
- * Key Down   |PRESSING(Rk)  (Rk)          WAITING(Sk)      IDLE(Rf,Ps,Rk)       
- *     Up     |(Uk)          IDLE(Uk)*4    (Uk)             IDLE(L+,Ps,Pk)/(Uk)*a
- *            |
- * Delay      |-             -             IDLE(L+)         IDLE(L+,Ps)          
- * Magic Key  |COMMAND*5
- *
- * *1: ignore Fn if other key is down.
- * *2: register Fnk if any key is pressing
- * *3: register/unregister delayed Fnk and move to IDLE if code == delayed Fnk, else *8
- * *4: if no keys registered to host
- * *5: unregister all keys
- * *6: only if no keys down
- * *7: ignore Fn because Fnk key and stored key are down.
- * *8: move to IDLE if layer switch(off) occurs, else stay at current state
- * *9: repeat key if pressing Fnk twice quickly(move to PRESSING)
- * *a: layer switch and process waiting key and code if code == wainting key, else unregister key
- *
- * States:
- *      IDLE: No key is down except modifiers
- *      DELAYING: delay layer switch after pressing Fn with alt keycode
- *      WAITING: key is pressed during DELAYING
- *
- * Events:
- *      Fn: Fn key without alternative keycode
- *      Fnk: Fn key with alternative keycode
- *      -: ignore
- *      Delay: layer switch delay term is elapsed
- *
- * Actions:
- *      Rk: register key
- *      Uk: unregister key
- *      Rf: register Fn(alt keycode)
- *      Uf: unregister Fn(alt keycode)
- *      Rs: register stored key
- *      Us: unregister stored key
- *      Sk: Store key(waiting Key)
- *      Sf: Store Fn(delayed Fn)
- *      Ps: Process stored key
- *      Ps: Process key
- *      Is: Interpret stored keys in current layer
- *      L+: Switch to new layer(*unregister* all keys but modifiers)
- *      L-: Switch back to last layer(*unregister* all keys but modifiers)
- *      Ld: Switch back to default layer(*unregister* all keys but modifiers)
- */
-
-
-typedef enum { IDLE, DELAYING, WAITING, PRESSING } kbdstate_t;
-#define NEXT(state)     do { \
-    Kdebug("NEXT: "); Kdebug_P(state_str(kbdstate)); \
-    kbdstate = state; \
-    Kdebug(" -> "); Kdebug_P(state_str(kbdstate)); Kdebug("\n"); \
-} while (0)
-
-
-static kbdstate_t kbdstate = IDLE;
-static uint8_t fn_state_bits = 0;
-
-static const char *state_str(kbdstate_t state)
-{
-    if (state == IDLE)      return PSTR("IDLE");
-    if (state == DELAYING)  return PSTR("DELAYING");
-    if (state == WAITING)   return PSTR("WAITING");
-    if (state == PRESSING)  return PSTR("PRESSING");
-    return PSTR("UNKNOWN");
-}
-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 process(keyevent_t event, action_t action);
 static void register_code(uint8_t code);
 static void unregister_code(uint8_t code);
-static void register_mods(uint8_t mods);
-static void unregister_mods(uint8_t mods);
 static void clear_keyboard(void);
 static void clear_keyboard_but_mods(void);
+static bool sending_anykey(void);
 static void layer_switch(uint8_t new_layer);
 
 
 /* tap */
 #define TAP_TIME    200
-#define LAYER_DELAY 200
 static keyevent_t last_event = {};
 static uint16_t last_event_time = 0;
 static uint8_t tap_count = 0;
@@ -115,31 +32,54 @@ uint8_t default_layer = 0;
 uint8_t current_layer = 0;
 keyrecord_t delaying_layer = {};
 
-keyrecord_t waiting_key = {};
-
-// TODO: ring buffer: waiting_keys[]
-/*
 #define WAITING_KEYS_BUFFER 3
 static keyrecord_t waiting_keys[WAITING_KEYS_BUFFER] = {};
 static uint8_t waiting_keys_head = 0;
-static uint8_t waiting_keys_tail = 0;
-static void waiting_key_queue(keyevent_t event)
+static bool waiting_keys_enqueue(keyevent_t event, action_t action)
 {
+    debug("waiting_keys["); debug_dec(waiting_keys_head); debug("] = ");
+    debug_hex16(action.code); debug("\n");
+    if (waiting_keys_head < WAITING_KEYS_BUFFER) {
+        waiting_keys[waiting_keys_head++] = (keyrecord_t){ .event = event,
+                                                           .action = action,
+                                                           .mods = host_get_mods() };
+    } else {
+        return true;
+    }
 }
-static void waiting_key_dequeue(keyevent_t event)
+static void waiting_keys_clear(void)
 {
+    waiting_keys_head = 0;
 }
-*/
+static bool waiting_keys_has(keypos_t key)
+{
+    for (uint8_t i = 0; i < waiting_keys_head; i++) {
+        if KEYEQ(key, waiting_keys[i].event.key) return true;
+    }
+    return false;
+}
+static void waiting_keys_process_in_current_layer(void)
+{
+    // TODO: in case of including layer key in waiting keys
+    uint8_t tmp_mods = host_get_mods();
+    for (uint8_t i = 0; i < waiting_keys_head; i++) {
+        /* revive status of mods */
+        host_set_mods(waiting_keys[i].mods);
+        process(waiting_keys[i].event, keymap_get_action(current_layer,
+                                                         waiting_keys[i].event.key.row,
+                                                         waiting_keys[i].event.key.col));
+        debug("waiting_keys_process_in_current_layer["); debug_dec(i); debug("]\n");
+    }
+    host_set_mods(tmp_mods);
+    waiting_keys_clear();
+}
+
 
 static void process(keyevent_t event, action_t action)
 {
     //action_t action = keymap_get_action(current_layer, event.key.row, event.key.col);
-
     debug("action: "); debug_hex16(action.code); debug("\n");
-    debug("kind.id: "); debug_hex(action.kind.id); debug("\n");
-    debug("kind.param: "); debug_hex16(action.kind.param); debug("\n");
-    debug("key.code: "); debug_hex(action.key.code); debug("\n");
-    debug("key.mods: "); debug_hex(action.key.mods); debug("\n");
+
 
     switch (action.kind.id) {
         /* Key and Mods */
@@ -244,12 +184,12 @@ static void process(keyevent_t event, action_t action)
                     break;
                 default:
                     // with tap key
-                    debug("tap: "); debug_hex(tap_count); debug("\n");
                     if (event.pressed) {
                         if (tap_count == 0) {
                             if (host_has_anykey()) {
                                 register_code(action.layer.code);
                             } else {
+                                debug("Delay switching layer("); debug_hex8(action.layer.opt); debug(")\n");
                                 delaying_layer = (keyrecord_t){
                                     .event = event,
                                     .action = action,
@@ -257,12 +197,13 @@ static void process(keyevent_t event, action_t action)
                                 };
                             }
                         } else if (tap_count > 0) {
+                            debug("tap: "); debug_hex(tap_count); debug("\n");
                             register_code(action.layer.code);
                         }
                     } else {
                         // tap key
                         if (KEYEQ(event.key, delaying_layer.event.key) &&
-                                timer_elapsed(delaying_layer.event.time) < TAP_TIME) {
+                                timer_elapsed(delaying_layer.event.time) <= TAP_TIME) {
                             uint8_t tmp_mods = host_get_mods();
                             host_set_mods(delaying_layer.mods);
                             register_code(delaying_layer.action.layer.code);
@@ -321,7 +262,6 @@ static void process(keyevent_t event, action_t action)
                     break;
                 default:
                     // with tap key
-                    debug("tap: "); debug_hex(tap_count); debug("\n");
                     if (event.pressed) {
                         if (tap_count == 0) {
                             if (host_has_anykey()) {
@@ -334,6 +274,7 @@ static void process(keyevent_t event, action_t action)
                                 };
                             }
                         } else if (tap_count > 0) {
+                            debug("tap: "); debug_hex(tap_count); debug("\n");
                             register_code(action.layer.code);
                         }
                     } else {
@@ -409,18 +350,16 @@ static void process(keyevent_t event, action_t action)
 
 void action_exec(keyevent_t event)
 {
-    /* count tap when key is up */
-    if (KEYEQ(event.key, last_event.key) && timer_elapsed(last_event_time) < TAP_TIME) {
-        if (!event.pressed) tap_count++;
-    } else {
-        tap_count = 0;
-    }
+/*
+    debug("key["); debug_hex8(event.key.row); debug(":"); debug_hex8(event.key.col);
+    if (event.pressed) debug("]down\n"); else debug("]up\n");
+*/
 
     /* When delaying layer switch */
     if (delaying_layer.action.code) {
-        /* Layer switch when delay time elapses or waiting key is released */
-        if ((timer_elapsed(delaying_layer.event.time) > LAYER_DELAY) ||
-            (!event.pressed && KEYEQ(event.key, waiting_key.event.key))) {
+        /* Layer switch when tap time elapses or waiting key is released */
+        if ((timer_elapsed(delaying_layer.event.time) > TAP_TIME) ||
+            (!event.pressed && waiting_keys_has(event.key))) {
             /* layer switch */
             switch (delaying_layer.action.kind.id) {
                 case ACT_LAYER_PRESSED:
@@ -433,15 +372,7 @@ void action_exec(keyevent_t event)
             delaying_layer = (keyrecord_t){};
 
             /* Process waiting keys in new layer */
-            if (waiting_key.event.time) {
-                uint8_t tmp_mods = host_get_mods();
-                host_set_mods(waiting_key.mods);
-                process(waiting_key.event, keymap_get_action(current_layer,
-                                                             waiting_key.event.key.row,
-                                                             waiting_key.event.key.col));
-                host_set_mods(tmp_mods);
-                waiting_key = (keyrecord_t){};
-            }
+            waiting_keys_process_in_current_layer();
         }
         /* when delaying layer key is released within delay term */
         else if (!event.pressed && KEYEQ(event.key, delaying_layer.event.key)) {
@@ -450,28 +381,32 @@ void action_exec(keyevent_t event)
             host_set_mods(delaying_layer.mods);
             register_code(delaying_layer.action.layer.code);
             delaying_layer = (keyrecord_t){};
+            host_set_mods(tmp_mods);
 
             /* process waiting keys */
-            if (waiting_key.event.time) {
-                host_set_mods(waiting_key.mods);
-                process(waiting_key.event, waiting_key.action);
-                waiting_key = (keyrecord_t){};
-            }
-            host_set_mods(tmp_mods);
+            waiting_keys_process_in_current_layer();
         }
     }
 
+    // not real event. event just to update delaying layer.
+    if (IS_NOEVENT(event)) {
+        return;
+    }
+
+    /* count tap when key is up */
+    if (KEYEQ(event.key, last_event.key) && timer_elapsed(last_event.time) <= TAP_TIME) {
+        if (!event.pressed) tap_count++;
+    } else {
+        tap_count = 0;
+    }
+
     action_t action = keymap_get_action(current_layer, event.key.row, event.key.col);
 
+    // TODO: all key events(pressed, released) should be recorded?
     /* postpone key-down events while delaying layer */
     if (delaying_layer.action.code) {
         if (event.pressed) {
-            // TODO: waiting_keys[]
-            waiting_key = (keyrecord_t){
-                .event = event,
-                .action = action,
-                .mods = host_get_mods()
-            };
+            waiting_keys_enqueue(event, action);
         } else {
             process(event, action);
         }
@@ -481,7 +416,6 @@ void action_exec(keyevent_t event)
 
     /* last event */
     last_event = event;
-    last_event_time = timer_read();
 }
 
 
@@ -515,20 +449,6 @@ static void unregister_code(uint8_t code)
     }
 }
 
-static void register_mods(uint8_t mods)
-{
-    if (!mods) return;
-    host_add_mods(mods);
-    host_send_keyboard_report();
-}
-
-static void unregister_mods(uint8_t mods)
-{
-    if (!mods) return;
-    host_del_mods(mods);
-    host_send_keyboard_report();
-}
-
 static void clear_keyboard(void)
 {
     host_clear_mods();
@@ -549,11 +469,17 @@ static void clear_keyboard_but_mods(void)
 #endif
 }
 
+static bool sending_anykey(void)
+{
+    return (host_has_anykey() || host_mouse_in_use() ||
+            host_last_sysytem_report() || host_last_consumer_report());
+}
+
 static void layer_switch(uint8_t new_layer)
 {
     if (current_layer != new_layer) {
-        Kdebug("Layer Switch: "); Kdebug_hex(current_layer);
-        Kdebug(" -> "); Kdebug_hex(new_layer); Kdebug("\n");
+        debug("Layer Switch: "); debug_hex(current_layer);
+        debug(" -> "); debug_hex(new_layer); debug("\n");
 
         current_layer = new_layer;
         clear_keyboard_but_mods(); // To avoid stuck keys
index 4e955e129b6fe9454d781df878ea5212e16ac918..2e32e91e089dff66adce01edf83b3a04d1d0d19b 100644 (file)
@@ -78,7 +78,14 @@ void keyboard_task(void)
             }
         }
     }
-    MATRIX_LOOP_END:
+    // call to update delaying layer when no real event
+    action_exec((keyevent_t) {
+        .key = (keypos_t){ .row = 255, .col = 255 }, // assume this key doesn't exist
+        .pressed = false,
+        .time = 0,
+    });
+
+MATRIX_LOOP_END:
 
 #ifdef MOUSEKEY_ENABLE
     // mousekey repeat & acceleration
index 116653661750473f25cfbaddb3ccf60b0c4eb353..cf85b123364cdd2a98e3cc0061de34406ca9bee1 100644 (file)
@@ -37,7 +37,14 @@ typedef struct {
     uint16_t time;
 } keyevent_t;
 
-#define KEYEQ(keya, keyb)     (keya.row == keyb.row && keya.col == keyb.col)
+#define KEYEQ(keya, keyb)       (keya.row == keyb.row && keya.col == keyb.col)
+#define IS_NOEVENT(event)       (event.time == 0)
+#define NOEVENT                 (keyevent_t) {      \
+    .key = (keypos_t){ .row = 255, .col = 255 },    \
+    .pressed = false,                               \
+    .time = 0,                                      \
+}
+
 
 extern uint8_t current_layer;
 extern uint8_t default_layer;
index 9fe1237aa41f4fa14b3f0a998ce2fe6315c1ed88..38461290b378d02aa58600653dd374dd6f6febbe 100644 (file)
@@ -224,6 +224,5 @@ action_t keymap_get_action(uint8_t layer, uint8_t row, uint8_t col) {
             action.code = ACTION_NO;
             break;
     }
-    debug("action: "); debug_hex16(action.code); debug("\n");
     return action;
 }