]> git.friedersdorff.com Git - max/tmk_keyboard.git/blobdiff - common/action.c
Add NO_ACTION_ONESHOT config option
[max/tmk_keyboard.git] / common / action.c
index 7f3e236f0413e3267931be2b9c7ed63b203c5b4c..49bfc54e7ea61b018c4483442c53bd9ae3419fe4 100644 (file)
@@ -23,20 +23,26 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "command.h"
 #include "util.h"
 #include "debug.h"
+#include "led.h"
 #include "layer_switch.h"
+#include "action_oneshot.h"
 #include "action_macro.h"
 #include "action.h"
 
 
 static void process_action(keyrecord_t *record);
+#ifndef NO_ACTION_TAPPING
 static bool process_tapping(keyrecord_t *record);
 static void waiting_buffer_scan_tap(void);
+#endif
 
 static void debug_event(keyevent_t event);
 static void debug_record(keyrecord_t record);
 static void debug_action(action_t action);
+#ifndef NO_ACTION_TAPPING
 static void debug_tapping_key(void);
 static void debug_waiting_buffer(void);
+#endif
 
 
 /*
@@ -52,6 +58,7 @@ static void debug_waiting_buffer(void);
 #define TAPPING_TOGGLE  5
 #endif
 
+#ifndef NO_ACTION_TAPPING
 /* stores a key event of current tap. */
 static keyrecord_t tapping_key = {};
 
@@ -119,45 +126,7 @@ bool waiting_buffer_has_anykey_pressed(void)
     }
     return false;
 }
-
-
-/* Oneshot modifier
- *
- * Problem: Want to capitalize like 'The' but the result tends to be 'THe'.
- * Solution: Oneshot modifier have its effect on only one key coming next.
- *           Tap Shift, then type 't', 'h' and 'e'. Not need to hold Shift key.
- *
- *  Hold:       works as normal modifier.
- *  Tap:        one shot modifier.
- *  2 Tap:      cancel one shot modifier.
- *  5-Tap:      toggles enable/disable oneshot feature.
- */
-static struct {
-    uint8_t mods;
-    uint8_t time;
-    bool    ready;
-    bool    disabled;
-}   oneshot_state;
-
-static void oneshot_start(uint8_t mods, uint16_t time)
-{
-    oneshot_state.mods = mods;
-    oneshot_state.time = time;
-    oneshot_state.ready = true;
-}
-
-static void oneshot_cancel(void)
-{
-    oneshot_state.mods = 0;
-    oneshot_state.time = 0;
-    oneshot_state.ready = false;
-}
-
-static void oneshot_toggle(void)
-{
-    oneshot_state.disabled = !oneshot_state.disabled;
-}
-
+#endif
 
 
 void action_exec(keyevent_t event)
@@ -169,6 +138,7 @@ void action_exec(keyevent_t event)
 
     keyrecord_t record = { .event = event };
 
+#ifndef NO_ACTION_TAPPING
     // pre-process on tapping
     if (process_tapping(&record)) {
         if (!IS_NOEVENT(record.event)) {
@@ -201,6 +171,12 @@ void action_exec(keyevent_t event)
     if (!IS_NOEVENT(event)) {
         debug("\n");
     }
+#else
+    process_action(&record);
+    if (!IS_NOEVENT(record.event)) {
+        debug("processed: "); debug_record(record); debug("\n");
+    }
+#endif
 }
 
 static void process_action(keyrecord_t *record)
@@ -243,12 +219,14 @@ static void process_action(keyrecord_t *record)
                 }
             }
             break;
+#ifndef NO_ACTION_TAPPING
         case ACT_LMODS_TAP:
         case ACT_RMODS_TAP:
             {
                 uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ?  action.key.mods :
                                                                     action.key.mods<<4;
                 switch (action.layer.code) {
+    #ifndef NO_ACTION_ONESHOT
                     case 0x00:
                         // Oneshot modifier
                         if (event.pressed) {
@@ -258,7 +236,7 @@ static void process_action(keyrecord_t *record)
                             }
                             else if (tap_count == 1) {
                                 debug("MODS_TAP: Oneshot: start\n");
-                                oneshot_start(mods, event.time);
+                                oneshot_start(mods);
                             }
                             else if (tap_count == TAPPING_TOGGLE) {
                                 debug("MODS_TAP: Oneshot: toggle\n");
@@ -289,6 +267,7 @@ static void process_action(keyrecord_t *record)
                             }
                         }
                         break;
+    #endif
                     default:
                         if (event.pressed) {
                             if (tap_count > 0) {
@@ -318,10 +297,11 @@ static void process_action(keyrecord_t *record)
                 }
             }
             break;
+#endif
 
+#ifdef EXTRAKEY_ENABLE
         /* other HID usage */
         case ACT_USAGE:
-#ifdef EXTRAKEY_ENABLE
             switch (action.usage.page) {
                 case PAGE_SYSTEM:
                     if (event.pressed) {
@@ -338,12 +318,12 @@ static void process_action(keyrecord_t *record)
                     }
                     break;
             }
-#endif
             break;
+#endif
 
+#ifdef MOUSEKEY_ENABLE
         /* Mouse key */
         case ACT_MOUSEKEY:
-#ifdef MOUSEKEY_ENABLE
             if (event.pressed) {
                 mousekey_on(action.key.code);
                 mousekey_send();
@@ -351,15 +331,17 @@ static void process_action(keyrecord_t *record)
                 mousekey_off(action.key.code);
                 mousekey_send();
             }
-#endif
             break;
+#endif
 
+#ifndef NO_ACTION_KEYMAP
         case ACT_KEYMAP:
             switch (action.layer.code) {
                 /* Keymap clear */
                 case OP_RESET:
                     switch (action.layer.val & 0x03) {
                         case 0:
+                            // NOTE: reserved
                             overlay_clear();
                             keymap_clear();
                             break;
@@ -379,26 +361,21 @@ static void process_action(keyrecord_t *record)
                             overlay_clear();
                             keymap_clear();
                             break;
+                        /* NOTE: 4-7 rserved */
                     }
                     break;
                 /* Keymap Reset default layer */
                 case (OP_RESET | ON_PRESS):
                     if (event.pressed) {
-                        overlay_clear();
-                        keymap_clear();
                         default_layer_set(action.layer.val);
                     }
                     break;
                 case (OP_RESET | ON_RELEASE):
                     if (!event.pressed) {
-                        overlay_clear();
-                        keymap_clear();
                         default_layer_set(action.layer.val);
                     }
                     break;
                 case (OP_RESET | ON_BOTH):
-                    overlay_clear();
-                    keymap_clear();
                     default_layer_set(action.layer.val);
                     break;
 
@@ -519,12 +496,15 @@ static void process_action(keyrecord_t *record)
                     break;
             }
             break;
+#endif
 
+#ifndef NO_ACTION_OVERLAY
         case ACT_OVERLAY:
             switch (action.layer.code) {
                 // Overlay Invert bit4
                 case OP_INV4 | 0:
                     if (action.layer.val == 0) {
+                        // NOTE: reserved for future use
                         overlay_clear();
                     } else {
                         overlay_set(overlay_stat ^ action.layer.val);
@@ -532,6 +512,7 @@ static void process_action(keyrecord_t *record)
                     break;
                 case OP_INV4 | 1:
                     if (action.layer.val == 0) {
+                        // on pressed
                         if (event.pressed) overlay_clear();
                     } else {
                         overlay_set(overlay_stat ^ action.layer.val<<4);
@@ -539,6 +520,7 @@ static void process_action(keyrecord_t *record)
                     break;
                 case OP_INV4 | 2:
                     if (action.layer.val == 0) {
+                        // on released
                         if (!event.pressed) overlay_clear();
                     } else {
                         overlay_set(overlay_stat ^ action.layer.val<<8);
@@ -546,6 +528,7 @@ static void process_action(keyrecord_t *record)
                     break;
                 case OP_INV4 | 3:
                     if (action.layer.val == 0) {
+                        // on both
                         overlay_clear();
                     } else {
                         overlay_set(overlay_stat ^ action.layer.val<<12);
@@ -669,21 +652,27 @@ static void process_action(keyrecord_t *record)
                     break;
             }
             break;
+#endif
 
         /* Extentions */
+#ifndef NO_ACTION_MACRO
         case ACT_MACRO:
             action_macro_play(action_get_macro(record, action.func.id, action.func.opt));
             break;
+#endif
         case ACT_COMMAND:
             break;
+#ifndef NO_ACTION_FUNCTION
         case ACT_FUNCTION:
             action_function(record, action.func.id, action.func.opt);
             break;
+#endif
         default:
             break;
     }
 }
 
+#ifndef NO_ACTION_TAPPING
 /* Tapping
  *
  * Rule: Tap key is typed(pressed and released) within TAPPING_TERM.
@@ -878,6 +867,7 @@ static void waiting_buffer_scan_tap(void)
         }
     }
 }
+#endif
 
 
 
@@ -889,19 +879,35 @@ void register_code(uint8_t code)
     if (code == KC_NO) {
         return;
     }
+#ifdef CAPSLOCK_LOCKING_ENABLE
+    else if (KC_LOCKING_CAPS == code) {
+#ifdef CAPSLOCK_LOCKING_RESYNC_ENABLE
+        // Resync: ignore if caps lock already is on
+        if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) return;
+#endif
+        host_add_key(KC_CAPSLOCK);
+        host_send_keyboard_report();
+        host_del_key(KC_CAPSLOCK);
+        host_send_keyboard_report();
+    }
+#endif
     else if IS_KEY(code) {
         // TODO: should push command_proc out of this block?
         if (command_proc(code)) return;
 
-        if (oneshot_state.mods && oneshot_state.ready && !oneshot_state.disabled) {
+#ifndef NO_ACTION_ONESHOT
+        if (oneshot_state.mods && !oneshot_state.disabled) {
             uint8_t tmp_mods = host_get_mods();
             host_add_mods(oneshot_state.mods);
+
             host_add_key(code);
             host_send_keyboard_report();
 
             host_set_mods(tmp_mods);
-            oneshot_state.ready = false;
-        } else {
+            oneshot_cancel();
+        } else 
+#endif
+        {
             host_add_key(code);
             host_send_keyboard_report();
         }
@@ -914,7 +920,22 @@ void register_code(uint8_t code)
 
 void unregister_code(uint8_t code)
 {
-    if IS_KEY(code) {
+    if (code == KC_NO) {
+        return;
+    }
+#ifdef CAPSLOCK_LOCKING_ENABLE
+    else if (KC_LOCKING_CAPS == code) {
+#ifdef CAPSLOCK_LOCKING_RESYNC_ENABLE
+        // Resync: ignore if caps lock already is off
+        if (!(host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK))) return;
+#endif
+        host_add_key(KC_CAPSLOCK);
+        host_send_keyboard_report();
+        host_del_key(KC_CAPSLOCK);
+        host_send_keyboard_report();
+    }
+#endif
+    else if IS_KEY(code) {
         host_del_key(code);
         host_send_keyboard_report();
     }
@@ -1034,6 +1055,7 @@ static void debug_action(action_t action)
     debug_hex8(action.kind.param & 0xff);
     debug("]");
 }
+#ifndef NO_ACTION_TAPPING
 static void debug_tapping_key(void)
 {
     debug("TAPPING_KEY="); debug_record(tapping_key); debug("\n");
@@ -1046,3 +1068,4 @@ static void debug_waiting_buffer(void)
     }
     debug("}\n");
 }
+#endif