summaryrefslogtreecommitdiffstats
path: root/tmk_core/common
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/common')
-rw-r--r--tmk_core/common/action.c223
-rw-r--r--tmk_core/common/action.h27
-rw-r--r--tmk_core/common/action_code.h35
-rw-r--r--tmk_core/common/action_layer.c81
-rw-r--r--tmk_core/common/action_layer.h12
-rw-r--r--tmk_core/common/action_tapping.c35
-rw-r--r--tmk_core/common/action_util.c80
-rw-r--r--tmk_core/common/action_util.h20
-rw-r--r--tmk_core/common/avr/bootloader.c54
-rw-r--r--tmk_core/common/avr/eeconfig.c45
-rw-r--r--tmk_core/common/avr/sleep_led.c (renamed from tmk_core/common/sleep_led.c)0
-rw-r--r--tmk_core/common/avr/suspend.c16
-rw-r--r--tmk_core/common/avr/xprintf.S1000
-rw-r--r--tmk_core/common/avr/xprintf.h222
-rw-r--r--tmk_core/common/backlight.c15
-rw-r--r--tmk_core/common/backlight.h1
-rw-r--r--tmk_core/common/bootmagic.c19
-rw-r--r--tmk_core/common/chibios/bootloader.c47
-rw-r--r--tmk_core/common/chibios/eeprom.c588
-rw-r--r--tmk_core/common/chibios/printf.c240
-rw-r--r--tmk_core/common/chibios/printf.h111
-rw-r--r--tmk_core/common/chibios/sleep_led.c226
-rw-r--r--tmk_core/common/chibios/suspend.c65
-rw-r--r--tmk_core/common/chibios/timer.c27
-rw-r--r--tmk_core/common/command.c78
-rw-r--r--tmk_core/common/command.h1
-rw-r--r--tmk_core/common/eeconfig.c56
-rw-r--r--tmk_core/common/eeconfig.h15
-rw-r--r--tmk_core/common/eeprom.h22
-rw-r--r--tmk_core/common/host.c7
-rw-r--r--tmk_core/common/host.h6
-rw-r--r--tmk_core/common/keyboard.c58
-rw-r--r--tmk_core/common/keycode.h7
-rw-r--r--tmk_core/common/keymap.c192
-rw-r--r--tmk_core/common/keymap.h71
-rw-r--r--tmk_core/common/led.h3
-rw-r--r--tmk_core/common/magic.c34
-rw-r--r--tmk_core/common/magic.h6
-rw-r--r--tmk_core/common/matrix.h14
-rw-r--r--tmk_core/common/mbed/xprintf.cpp2
-rw-r--r--tmk_core/common/mbed/xprintf.h2
-rw-r--r--tmk_core/common/nodebug.h12
-rw-r--r--tmk_core/common/print.c8
-rw-r--r--tmk_core/common/print.h182
-rw-r--r--tmk_core/common/progmem.h4
-rw-r--r--tmk_core/common/report.h5
-rw-r--r--tmk_core/common/virtser.h10
-rw-r--r--tmk_core/common/wait.h8
48 files changed, 2880 insertions, 1112 deletions
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 9010896343..08ef22eb97 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -41,33 +41,73 @@ void action_exec(keyevent_t event)
dprint("EVENT: "); debug_event(event); dprintln();
}
+#ifdef ONEHAND_ENABLE
+ if (!IS_NOEVENT(event)) {
+ process_hand_swap(&event);
+ }
+#endif
+
keyrecord_t record = { .event = event };
#ifndef NO_ACTION_TAPPING
action_tapping_process(record);
#else
- process_action(&record);
+ process_record(&record);
if (!IS_NOEVENT(record.event)) {
dprint("processed: "); debug_record(record); dprintln();
}
#endif
}
-__attribute__ ((weak))
-void process_action_kb(keyrecord_t *record) {}
+#ifdef ONEHAND_ENABLE
+bool swap_hands = false;
+
+void process_hand_swap(keyevent_t *event) {
+ static swap_state_row_t swap_state[MATRIX_ROWS];
+
+ keypos_t pos = event->key;
+ swap_state_row_t col_bit = (swap_state_row_t)1<<pos.col;
+ bool do_swap = event->pressed ? swap_hands :
+ swap_state[pos.row] & (col_bit);
+
+ if (do_swap) {
+ event->key = hand_swap_config[pos.row][pos.col];
+ swap_state[pos.row] |= col_bit;
+ } else {
+ swap_state[pos.row] &= ~(col_bit);
+ }
+}
+#endif
+
+#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+bool disable_action_cache = false;
-void process_action(keyrecord_t *record)
+void process_record_nocache(keyrecord_t *record)
{
- keyevent_t event = record->event;
-#ifndef NO_ACTION_TAPPING
- uint8_t tap_count = record->tap.count;
+ disable_action_cache = true;
+ process_record(record);
+ disable_action_cache = false;
+}
+#else
+void process_record_nocache(keyrecord_t *record)
+{
+ process_record(record);
+}
#endif
- if (IS_NOEVENT(event)) { return; }
+__attribute__ ((weak))
+bool process_record_quantum(keyrecord_t *record) {
+ return true;
+}
+
+void process_record(keyrecord_t *record)
+{
+ if (IS_NOEVENT(record->event)) { return; }
- process_action_kb(record);
+ if(!process_record_quantum(record))
+ return;
- action_t action = layer_switch_get_action(event.key);
+ action_t action = store_or_get_action(record->event.pressed, record->event.key);
dprint("ACTION: "); debug_action(action);
#ifndef NO_ACTION_LAYER
dprint(" layer_state: "); layer_debug();
@@ -75,10 +115,37 @@ void process_action(keyrecord_t *record)
#endif
dprintln();
+ process_action(record, action);
+}
+
+void process_action(keyrecord_t *record, action_t action)
+{
+ bool do_release_oneshot = false;
+ keyevent_t event = record->event;
+#ifndef NO_ACTION_TAPPING
+ uint8_t tap_count = record->tap.count;
+#endif
+
+#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
+ if (has_oneshot_layer_timed_out()) {
+ dprintf("Oneshot layer: timeout\n");
+ clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
+ }
+#endif
+
if (event.pressed) {
// clear the potential weak mods left by previously pressed keys
clear_weak_mods();
}
+
+#ifndef NO_ACTION_ONESHOT
+ // notice we only clear the one shot layer if the pressed key is not a modifier.
+ if (is_oneshot_layer_active() && event.pressed && !IS_MOD(action.key.code)) {
+ clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
+ do_release_oneshot = !is_oneshot_layer_active();
+ }
+#endif
+
switch (action.kind.id) {
/* Key and Mods */
case ACT_LMODS:
@@ -123,24 +190,37 @@ void process_action(keyrecord_t *record)
// Oneshot modifier
if (event.pressed) {
if (tap_count == 0) {
+ dprint("MODS_TAP: Oneshot: 0\n");
register_mods(mods);
- }
- else if (tap_count == 1) {
+ } else if (tap_count == 1) {
dprint("MODS_TAP: Oneshot: start\n");
set_oneshot_mods(mods);
- }
- else {
+ #if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
+ } else if (tap_count == ONESHOT_TAP_TOGGLE) {
+ dprint("MODS_TAP: Toggling oneshot");
+ clear_oneshot_mods();
+ set_oneshot_locked_mods(mods);
+ register_mods(mods);
+ #endif
+ } else {
register_mods(mods);
}
} else {
if (tap_count == 0) {
clear_oneshot_mods();
unregister_mods(mods);
- }
- else if (tap_count == 1) {
+ } else if (tap_count == 1) {
// Retain Oneshot mods
- }
- else {
+ #if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
+ if (mods & get_mods()) {
+ clear_oneshot_locked_mods();
+ clear_oneshot_mods();
+ unregister_mods(mods);
+ }
+ } else if (tap_count == ONESHOT_TAP_TOGGLE) {
+ // Toggle Oneshot Layer
+ #endif
+ } else {
clear_oneshot_mods();
unregister_mods(mods);
}
@@ -293,6 +373,44 @@ void process_action(keyrecord_t *record)
event.pressed ? layer_move(action.layer_tap.val) :
layer_clear();
break;
+ #ifndef NO_ACTION_ONESHOT
+ case OP_ONESHOT:
+ // Oneshot modifier
+ #if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
+ do_release_oneshot = false;
+ if (event.pressed) {
+ del_mods(get_oneshot_locked_mods());
+ if (get_oneshot_layer_state() == ONESHOT_TOGGLED) {
+ reset_oneshot_layer();
+ layer_off(action.layer_tap.val);
+ break;
+ } else if (tap_count < ONESHOT_TAP_TOGGLE) {
+ layer_on(action.layer_tap.val);
+ set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
+ }
+ } else {
+ add_mods(get_oneshot_locked_mods());
+ if (tap_count >= ONESHOT_TAP_TOGGLE) {
+ reset_oneshot_layer();
+ clear_oneshot_locked_mods();
+ set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED);
+ } else {
+ clear_oneshot_layer_state(ONESHOT_PRESSED);
+ }
+ }
+ #else
+ if (event.pressed) {
+ layer_on(action.layer_tap.val);
+ set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
+ } else {
+ clear_oneshot_layer_state(ONESHOT_PRESSED);
+ if (tap_count > 1) {
+ clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
+ }
+ }
+ #endif
+ break;
+ #endif
default:
/* tap key */
if (event.pressed) {
@@ -348,6 +466,54 @@ void process_action(keyrecord_t *record)
#endif
case ACT_COMMAND:
break;
+#ifdef ONEHAND_ENABLE
+ case ACT_SWAP_HANDS:
+ switch (action.swap.code) {
+ case OP_SH_TOGGLE:
+ if (event.pressed) {
+ swap_hands = !swap_hands;
+ }
+ break;
+ case OP_SH_ON_OFF:
+ swap_hands = event.pressed;
+ break;
+ case OP_SH_OFF_ON:
+ swap_hands = !event.pressed;
+ break;
+ case OP_SH_ON:
+ if (!event.pressed) {
+ swap_hands = true;
+ }
+ break;
+ case OP_SH_OFF:
+ if (!event.pressed) {
+ swap_hands = false;
+ }
+ break;
+ #ifndef NO_ACTION_TAPPING
+ case OP_SH_TAP_TOGGLE:
+ /* tap toggle */
+ if (tap_count > 0) {
+ if (!event.pressed) {
+ swap_hands = !swap_hands;
+ }
+ } else {
+ swap_hands = event.pressed;
+ }
+ break;
+ default:
+ if (tap_count > 0) {
+ if (event.pressed) {
+ register_code(action.swap.code);
+ } else {
+ unregister_code(action.swap.code);
+ }
+ } else {
+ swap_hands = event.pressed;
+ }
+ #endif
+ }
+#endif
#ifndef NO_ACTION_FUNCTION
case ACT_FUNCTION:
action_function(record, action.func.id, action.func.opt);
@@ -356,6 +522,18 @@ void process_action(keyrecord_t *record)
default:
break;
}
+
+#ifndef NO_ACTION_ONESHOT
+ /* Because we switch layers after a oneshot event, we need to release the
+ * key before we leave the layer or no key up event will be generated.
+ */
+ if (do_release_oneshot && !(get_oneshot_layer_state() & ONESHOT_PRESSED ) ) {
+ record->event.pressed = false;
+ layer_on(get_oneshot_layer());
+ process_record(record);
+ layer_off(get_oneshot_layer());
+ }
+#endif
}
@@ -544,6 +722,14 @@ bool is_tap_key(keypos_t key)
switch (action.layer_tap.code) {
case 0x00 ... 0xdf:
case OP_TAP_TOGGLE:
+ case OP_ONESHOT:
+ return true;
+ }
+ return false;
+ case ACT_SWAP_HANDS:
+ switch (action.swap.code) {
+ case 0x00 ... 0xdf:
+ case OP_SH_TAP_TOGGLE:
return true;
}
return false;
@@ -587,6 +773,7 @@ void debug_action(action_t action)
case ACT_MACRO: dprint("ACT_MACRO"); break;
case ACT_COMMAND: dprint("ACT_COMMAND"); break;
case ACT_FUNCTION: dprint("ACT_FUNCTION"); break;
+ case ACT_SWAP_HANDS: dprint("ACT_SWAP_HANDS"); break;
default: dprint("UNKNOWN"); break;
}
dprintf("[%X:%02X]", action.kind.param>>8, action.kind.param&0xff);
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index 9f528af4b9..b9bdfe642c 100644
--- a/tmk_core/common/action.h
+++ b/tmk_core/common/action.h
@@ -59,10 +59,33 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt);
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
/* keyboard-specific key event (pre)processing */
-void process_action_kb(keyrecord_t *record);
+bool process_record_quantum(keyrecord_t *record);
/* Utilities for actions. */
-void process_action(keyrecord_t *record);
+#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+extern bool disable_action_cache;
+#endif
+
+/* Code for handling one-handed key modifiers. */
+#ifdef ONEHAND_ENABLE
+extern bool swap_hands;
+extern const keypos_t hand_swap_config[MATRIX_ROWS][MATRIX_COLS];
+#if (MATRIX_COLS <= 8)
+typedef uint8_t swap_state_row_t;
+#elif (MATRIX_COLS <= 16)
+typedef uint16_t swap_state_row_t;
+#elif (MATRIX_COLS <= 32)
+typedef uint32_t swap_state_row_t;
+#else
+#error "MATRIX_COLS: invalid value"
+#endif
+
+void process_hand_swap(keyevent_t *record);
+#endif
+
+void process_record_nocache(keyrecord_t *record);
+void process_record(keyrecord_t *record);
+void process_action(keyrecord_t *record, action_t action);
void register_code(uint8_t code);
void unregister_code(uint8_t code);
void register_mods(uint8_t mods);
diff --git a/tmk_core/common/action_code.h b/tmk_core/common/action_code.h
index 4fe9c1d581..33da35f35f 100644
--- a/tmk_core/common/action_code.h
+++ b/tmk_core/common/action_code.h
@@ -76,7 +76,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* 101E|LLLL|1111 0001 On/Off (0xF1) [NOT TAP]
* 101E|LLLL|1111 0010 Off/On (0xF2) [NOT TAP]
* 101E|LLLL|1111 0011 Set/Clear (0xF3) [NOT TAP]
- * 101E|LLLL|1111 xxxx Reserved (0xF4-FF)
+ * 101E|LLLL|1111 0100 One Shot Layer (0xF4) [TAP]
+ * 101E|LLLL|1111 xxxx Reserved (0xF5-FF)
* ELLLL: layer 0-31(E: extra bit for layer 16-31)
*
*
@@ -107,6 +108,8 @@ enum action_kind_id {
/* Other Keys */
ACT_USAGE = 0b0100,
ACT_MOUSEKEY = 0b0101,
+ /* One-hand Support */
+ ACT_SWAP_HANDS = 0b0110,
/* Layer Actions */
ACT_LAYER = 0b1000,
ACT_LAYER_TAP = 0b1010, /* Layer 0-15 */
@@ -177,6 +180,11 @@ typedef union {
uint8_t opt :4;
uint8_t kind :4;
} func;
+ struct action_swap {
+ uint8_t code :8;
+ uint8_t opt :4;
+ uint8_t kind :4;
+ } swap;
} action_t;
@@ -250,6 +258,7 @@ enum layer_pram_tap_op {
OP_ON_OFF,
OP_OFF_ON,
OP_SET_CLEAR,
+ OP_ONESHOT,
};
#define ACTION_LAYER_BITOP(op, part, bits, on) (ACT_LAYER<<12 | (op)<<10 | (on)<<8 | (part)<<5 | ((bits)&0x1f))
#define ACTION_LAYER_TAP(layer, key) (ACT_LAYER_TAP<<12 | (layer)<<8 | (key))
@@ -266,6 +275,7 @@ enum layer_pram_tap_op {
#define ACTION_LAYER_ON_OFF(layer) ACTION_LAYER_TAP((layer), OP_ON_OFF)
#define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON)
#define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR)
+#define ACTION_LAYER_ONESHOT(layer) ACTION_LAYER_TAP((layer), OP_ONESHOT)
#define ACTION_LAYER_MODS(layer, mods) ACTION_LAYER_TAP((layer), 0xe0 | ((mods)&0x0f))
/* With Tapping */
#define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key))
@@ -292,6 +302,7 @@ enum backlight_opt {
BACKLIGHT_STEP = 3,
BACKLIGHT_LEVEL = 4,
};
+
/* Macro */
#define ACTION_MACRO(id) ACTION(ACT_MACRO, (id))
#define ACTION_MACRO_TAP(id) ACTION(ACT_MACRO, FUNC_TAP<<8 | (id))
@@ -301,9 +312,9 @@ enum backlight_opt {
#define ACTION_BACKLIGHT_DECREASE() ACTION(ACT_BACKLIGHT, BACKLIGHT_DECREASE << 8)
#define ACTION_BACKLIGHT_TOGGLE() ACTION(ACT_BACKLIGHT, BACKLIGHT_TOGGLE << 8)
#define ACTION_BACKLIGHT_STEP() ACTION(ACT_BACKLIGHT, BACKLIGHT_STEP << 8)
-#define ACTION_BACKLIGHT_LEVEL(level) ACTION(ACT_BACKLIGHT, BACKLIGHT_LEVEL << 8 | level)
+#define ACTION_BACKLIGHT_LEVEL(level) ACTION(ACT_BACKLIGHT, BACKLIGHT_LEVEL << 8 | (level))
/* Command */
-#define ACTION_COMMAND(id, opt) ACTION(ACT_COMMAND, (opt)<<8 | (addr))
+#define ACTION_COMMAND(id, opt) ACTION(ACT_COMMAND, (opt)<<8 | (id))
/* Function */
enum function_opts {
FUNC_TAP = 0x8, /* indciates function is tappable */
@@ -311,5 +322,23 @@ enum function_opts {
#define ACTION_FUNCTION(id) ACTION(ACT_FUNCTION, (id))
#define ACTION_FUNCTION_TAP(id) ACTION(ACT_FUNCTION, FUNC_TAP<<8 | (id))
#define ACTION_FUNCTION_OPT(id, opt) ACTION(ACT_FUNCTION, (opt)<<8 | (id))
+/* OneHand Support */
+enum swap_hands_pram_tap_op {
+ OP_SH_TOGGLE = 0xF0,
+ OP_SH_TAP_TOGGLE,
+ OP_SH_ON_OFF,
+ OP_SH_OFF_ON,
+ OP_SH_OFF,
+ OP_SH_ON,
+};
+
+#define ACTION_SWAP_HANDS() ACTION_SWAP_HANDS_ON_OFF()
+#define ACTION_SWAP_HANDS_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TOGGLE)
+#define ACTION_SWAP_HANDS_TAP_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TAP_TOGGLE)
+#define ACTION_SWAP_HANDS_TAP_KEY(key) ACTION(ACT_SWAP_HANDS, key)
+#define ACTION_SWAP_HANDS_ON_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_ON_OFF)
+#define ACTION_SWAP_HANDS_OFF_ON() ACTION(ACT_SWAP_HANDS, OP_SH_OFF_ON)
+#define ACTION_SWAP_HANDS_ON() ACTION(ACT_SWAP_HANDS, OP_SH_ON)
+#define ACTION_SWAP_HANDS_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_OFF)
#endif /* ACTION_CODE_H */
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c
index c535615f44..a3c7579642 100644
--- a/tmk_core/common/action_layer.c
+++ b/tmk_core/common/action_layer.c
@@ -11,7 +11,7 @@
#endif
-/*
+/*
* Default Layer State
*/
uint32_t default_layer_state = 0;
@@ -52,7 +52,7 @@ void default_layer_xor(uint32_t state)
#ifndef NO_ACTION_LAYER
-/*
+/*
* Keymap Layer State
*/
uint32_t layer_state = 0;
@@ -110,9 +110,71 @@ void layer_debug(void)
}
#endif
+#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS] = {{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;
-action_t layer_switch_get_action(keypos_t key)
+ for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
+ source_layers_cache[storage_row][bit_number] ^=
+ (-((layer & (1U << bit_number)) != 0)
+ ^ source_layers_cache[storage_row][bit_number])
+ & (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[storage_row][bit_number]
+ & (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)
{
action_t action;
action.code = ACTION_TRANSPARENT;
@@ -124,15 +186,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);
+}
diff --git a/tmk_core/common/action_layer.h b/tmk_core/common/action_layer.h
index b6da353cfd..025cf5420f 100644
--- a/tmk_core/common/action_layer.h
+++ b/tmk_core/common/action_layer.h
@@ -68,8 +68,20 @@ void layer_xor(uint32_t state);
#define layer_and(state)
#define layer_xor(state)
#define layer_debug()
+
+#endif
+
+/* pressed actions cache */
+#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+/* The number of bits needed to represent the layer number: log2(32). */
+#define MAX_LAYER_BITS 5
+void update_source_layers_cache(keypos_t key, uint8_t layer);
+uint8_t read_source_layers_cache(keypos_t key);
#endif
+action_t store_or_get_action(bool pressed, keypos_t key);
+/* return the topmost non-transparent layer currently associated with key */
+int8_t layer_switch_get_layer(keypos_t key);
/* return action depending on current layer status */
action_t layer_switch_get_action(keypos_t key);
diff --git a/tmk_core/common/action_tapping.c b/tmk_core/common/action_tapping.c
index 826c233096..e16e11be7f 100644
--- a/tmk_core/common/action_tapping.c
+++ b/tmk_core/common/action_tapping.c
@@ -89,7 +89,7 @@ bool process_tapping(keyrecord_t *keyp)
debug("Tapping: First tap(0->1).\n");
tapping_key.tap.count = 1;
debug_tapping_key();
- process_action(&tapping_key);
+ process_record(&tapping_key);
// copy tapping state
keyp->tap = tapping_key.tap;
@@ -103,7 +103,7 @@ bool process_tapping(keyrecord_t *keyp)
*/
else if (IS_RELEASED(event) && waiting_buffer_typed(event)) {
debug("Tapping: End. No tap. Interfered by typing key\n");
- process_action(&tapping_key);
+ process_record(&tapping_key);
tapping_key = (keyrecord_t){};
debug_tapping_key();
// enqueue
@@ -131,7 +131,7 @@ bool process_tapping(keyrecord_t *keyp)
}
// Release of key should be process immediately.
debug("Tapping: release event of a key pressed before tapping\n");
- process_action(keyp);
+ process_record(keyp);
return true;
}
else {
@@ -139,7 +139,7 @@ bool process_tapping(keyrecord_t *keyp)
if (event.pressed) {
tapping_key.tap.interrupted = true;
}
- // enqueue
+ // enqueue
return false;
}
}
@@ -148,7 +148,7 @@ bool process_tapping(keyrecord_t *keyp)
if (IS_TAPPING_KEY(event.key) && !event.pressed) {
debug("Tapping: Tap release("); debug_dec(tapping_key.tap.count); debug(")\n");
keyp->tap = tapping_key.tap;
- process_action(keyp);
+ process_record(keyp);
tapping_key = *keyp;
debug_tapping_key();
return true;
@@ -157,7 +157,7 @@ bool process_tapping(keyrecord_t *keyp)
if (tapping_key.tap.count > 1) {
debug("Tapping: Start new tap with releasing last tap(>1).\n");
// unregister key
- process_action(&(keyrecord_t){
+ process_record(&(keyrecord_t){
.tap = tapping_key.tap,
.event.key = tapping_key.event.key,
.event.time = event.time,
@@ -175,7 +175,7 @@ bool process_tapping(keyrecord_t *keyp)
if (!IS_NOEVENT(event)) {
debug("Tapping: key event while last tap(>0).\n");
}
- process_action(keyp);
+ process_record(keyp);
return true;
}
}
@@ -185,7 +185,7 @@ bool process_tapping(keyrecord_t *keyp)
if (tapping_key.tap.count == 0) {