From b4f442dfeaf4d434ae0d8459dc5199cd8fefc1c7 Mon Sep 17 00:00:00 2001
From: Wojciech Siewierski <wojciech.siewierski@onet.pl>
Date: Sun, 27 Mar 2016 23:50:07 +0200
Subject: Cut the memory consumption of PREVENT_STUCK_MODIFIERS in half

---
 tmk_core/common/action_layer.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

(limited to 'tmk_core/common/action_layer.c')

diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c
index c535615f44..76164adb5d 100644
--- a/tmk_core/common/action_layer.c
+++ b/tmk_core/common/action_layer.c
@@ -111,8 +111,7 @@ void layer_debug(void)
 #endif
 
 
-
-action_t layer_switch_get_action(keypos_t key)
+int8_t layer_switch_get_layer(keypos_t key)
 {
     action_t action;
     action.code = ACTION_TRANSPARENT;
@@ -124,15 +123,18 @@ action_t layer_switch_get_action(keypos_t key)
         if (layers & (1UL<<i)) {
             action = action_for_key(i, key);
             if (action.code != ACTION_TRANSPARENT) {
-                return action;
+                return i;
             }
         }
     }
     /* fall back to layer 0 */
-    action = action_for_key(0, key);
-    return action;
+    return 0;
 #else
-    action = action_for_key(biton32(default_layer_state), key);
-    return action;
+    return biton32(default_layer_state);
 #endif
 }
+
+action_t layer_switch_get_action(keypos_t key)
+{
+    return action_for_key(layer_switch_get_layer(key), key);
+}
-- 
cgit v1.2.3


From 567f256c5d4598adb4dcd63fa4e4a7b4df553b12 Mon Sep 17 00:00:00 2001
From: Wojciech Siewierski <wojciech.siewierski@onet.pl>
Date: Tue, 5 Apr 2016 10:54:47 +0200
Subject: Refactor the source layer cache encoding

---
 tmk_core/common/action_layer.c | 63 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

(limited to 'tmk_core/common/action_layer.c')

diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c
index 76164adb5d..fc721a7323 100644
--- a/tmk_core/common/action_layer.c
+++ b/tmk_core/common/action_layer.c
@@ -110,6 +110,69 @@ void layer_debug(void)
 }
 #endif
 
+#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+uint8_t source_layers_cache[MAX_LAYER_BITS][(MATRIX_ROWS * MATRIX_COLS + 7) / 8] = {0};
+
+void update_source_layers_cache(keypos_t key, uint8_t layer)
+{
+    const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
+    const uint8_t storage_row = key_number / 8;
+    const uint8_t storage_bit = key_number % 8;
+
+    for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
+        source_layers_cache[bit_number][storage_row] ^=
+            (-((layer & (1U << bit_number)) != 0)
+             ^ source_layers_cache[bit_number][storage_row])
+            & (1U << storage_bit);
+    }
+}
+
+uint8_t read_source_layers_cache(keypos_t key)
+{
+    const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
+    const uint8_t storage_row = key_number / 8;
+    const uint8_t storage_bit = key_number % 8;
+    uint8_t layer = 0;
+
+    for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
+        layer |=
+            ((source_layers_cache[bit_number][storage_row]
+              & (1U << storage_bit)) != 0)
+            << bit_number;
+    }
+
+    return layer;
+}
+#endif
+
+/*
+ * Make sure the action triggered when the key is released is the same
+ * one as the one triggered on press. It's important for the mod keys
+ * when the layer is switched after the down event but before the up
+ * event as they may get stuck otherwise.
+ */
+action_t store_or_get_action(bool pressed, keypos_t key)
+{
+#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+    if (disable_action_cache) {
+        return layer_switch_get_action(key);
+    }
+
+    uint8_t layer;
+
+    if (pressed) {
+        layer = layer_switch_get_layer(key);
+        update_source_layers_cache(key, layer);
+    }
+    else {
+        layer = read_source_layers_cache(key);
+    }
+    return action_for_key(layer, key);
+#else
+    return layer_switch_get_action(key);
+#endif
+}
+
 
 int8_t layer_switch_get_layer(keypos_t key)
 {
-- 
cgit v1.2.3