Merge branch 'overlays'
This commit is contained in:
commit
38bbe976e0
51 changed files with 2871 additions and 958 deletions
447
common/action.c
447
common/action.c
|
@ -23,15 +23,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "command.h"
|
||||
#include "util.h"
|
||||
#include "debug.h"
|
||||
#include "layer_switch.h"
|
||||
#include "action_macro.h"
|
||||
#include "action.h"
|
||||
|
||||
|
||||
/* default layer indicates base layer */
|
||||
uint8_t default_layer = 0;
|
||||
/* current layer indicates active layer at this time */
|
||||
uint8_t current_layer = 0;
|
||||
|
||||
|
||||
static void process_action(keyrecord_t *record);
|
||||
static bool process_tapping(keyrecord_t *record);
|
||||
static void waiting_buffer_scan_tap(void);
|
||||
|
@ -207,28 +203,18 @@ void action_exec(keyevent_t event)
|
|||
}
|
||||
}
|
||||
|
||||
static action_t get_action(key_t key)
|
||||
{
|
||||
action_t action = action_for_key(current_layer, key);
|
||||
|
||||
/* Transparently use default layer */
|
||||
if (action.code == ACTION_TRANSPARENT) {
|
||||
// TODO: layer stacking
|
||||
action = action_for_key(default_layer, key);
|
||||
debug("TRNASPARENT: "); debug_hex16(action.code); debug("\n");
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
static void process_action(keyrecord_t *record)
|
||||
{
|
||||
keyevent_t event = record->event;
|
||||
uint8_t tap_count = record->tap_count;
|
||||
uint8_t tap_count = record->tap.count;
|
||||
|
||||
if (IS_NOEVENT(event)) { return; }
|
||||
|
||||
action_t action = get_action(event.key);
|
||||
debug("ACTION: "); debug_action(action); debug("\n");
|
||||
action_t action = layer_switch_get_action(event.key);
|
||||
debug("ACTION: "); debug_action(action);
|
||||
debug(" overlays: "); overlay_debug();
|
||||
debug(" keymaps: "); keymap_debug();
|
||||
debug(" default_layer: "); debug_dec(default_layer); debug("\n");
|
||||
|
||||
switch (action.kind.id) {
|
||||
/* Key and Mods */
|
||||
|
@ -287,7 +273,7 @@ static void process_action(keyrecord_t *record)
|
|||
} else {
|
||||
if (tap_count == 0) {
|
||||
debug("MODS_TAP: Oneshot: cancel/del_mods\n");
|
||||
// cancel oneshot by holding.
|
||||
// cancel oneshot on hold
|
||||
oneshot_cancel();
|
||||
del_mods(mods);
|
||||
}
|
||||
|
@ -309,7 +295,7 @@ static void process_action(keyrecord_t *record)
|
|||
if (waiting_buffer_has_anykey_pressed()) {
|
||||
debug("MODS_TAP: Tap: Cancel: add_mods\n");
|
||||
// ad hoc: set 0 to cancel tap
|
||||
record->tap_count = 0;
|
||||
record->tap.count = 0;
|
||||
add_mods(mods);
|
||||
} else {
|
||||
debug("MODS_TAP: Tap: register_code\n");
|
||||
|
@ -368,145 +354,316 @@ static void process_action(keyrecord_t *record)
|
|||
#endif
|
||||
break;
|
||||
|
||||
/* Layer key */
|
||||
case ACT_LAYER:
|
||||
case ACT_KEYMAP:
|
||||
switch (action.layer.code) {
|
||||
case LAYER_MOMENTARY: /* momentary */
|
||||
if (event.pressed) {
|
||||
layer_switch(action.layer.val);
|
||||
}
|
||||
else {
|
||||
// NOTE: This is needed by legacy keymap support
|
||||
layer_switch(default_layer);
|
||||
}
|
||||
break;
|
||||
case LAYER_ON_PRESS:
|
||||
if (event.pressed) {
|
||||
layer_switch(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case LAYER_ON_RELEASE:
|
||||
if (!event.pressed) {
|
||||
layer_switch(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case LAYER_DEFAULT: /* default layer */
|
||||
switch (action.layer.val) {
|
||||
case DEFAULT_ON_BOTH:
|
||||
layer_switch(default_layer);
|
||||
/* Keymap clear */
|
||||
case OP_RESET:
|
||||
switch (action.layer.val & 0x03) {
|
||||
case 0:
|
||||
// NOTE: reserved
|
||||
overlay_clear();
|
||||
keymap_clear();
|
||||
break;
|
||||
case DEFAULT_ON_PRESS:
|
||||
case ON_PRESS:
|
||||
if (event.pressed) {
|
||||
layer_switch(default_layer);
|
||||
overlay_clear();
|
||||
keymap_clear();
|
||||
}
|
||||
break;
|
||||
case DEFAULT_ON_RELEASE:
|
||||
case ON_RELEASE:
|
||||
if (!event.pressed) {
|
||||
layer_switch(default_layer);
|
||||
overlay_clear();
|
||||
keymap_clear();
|
||||
}
|
||||
break;
|
||||
case ON_BOTH:
|
||||
overlay_clear();
|
||||
keymap_clear();
|
||||
break;
|
||||
/* NOTE: 4-7 rserved */
|
||||
}
|
||||
break;
|
||||
case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */
|
||||
/* Keymap Reset default layer */
|
||||
case (OP_RESET | ON_PRESS):
|
||||
if (event.pressed) {
|
||||
default_layer_set(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_RESET | ON_RELEASE):
|
||||
if (!event.pressed) {
|
||||
default_layer_set(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_RESET | ON_BOTH):
|
||||
default_layer_set(action.layer.val);
|
||||
break;
|
||||
|
||||
/* Keymap Bit invert */
|
||||
case OP_INV:
|
||||
/* with tap toggle */
|
||||
if (event.pressed) {
|
||||
if (tap_count < TAPPING_TOGGLE) {
|
||||
layer_switch(action.layer.val);
|
||||
debug("KEYMAP_INV: tap toggle(press).\n");
|
||||
keymap_invert(action.layer.val);
|
||||
}
|
||||
} else {
|
||||
if (tap_count >= TAPPING_TOGGLE) {
|
||||
debug("LAYER_PRESSED: tap toggle.\n");
|
||||
layer_switch(action.layer.val);
|
||||
if (tap_count <= TAPPING_TOGGLE) {
|
||||
debug("KEYMAP_INV: tap toggle(release).\n");
|
||||
keymap_invert(action.layer.val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LAYER_CHANGE_DEFAULT: /* change default layer */
|
||||
case (OP_INV | ON_PRESS):
|
||||
if (event.pressed) {
|
||||
default_layer = action.layer.val;
|
||||
layer_switch(default_layer);
|
||||
keymap_invert(action.layer.val);
|
||||
}
|
||||
break;
|
||||
default: /* switch layer on hold and key on tap*/
|
||||
case (OP_INV | ON_RELEASE):
|
||||
if (!event.pressed) {
|
||||
keymap_invert(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_INV | ON_BOTH):
|
||||
keymap_invert(action.layer.val);
|
||||
break;
|
||||
|
||||
/* Keymap Bit on */
|
||||
case OP_ON:
|
||||
if (event.pressed) {
|
||||
if (tap_count > 0) {
|
||||
debug("LAYER_PRESSED: Tap: register_code\n");
|
||||
keymap_on(action.layer.val);
|
||||
} else {
|
||||
keymap_off(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_ON | ON_PRESS):
|
||||
if (event.pressed) {
|
||||
keymap_on(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_ON | ON_RELEASE):
|
||||
if (!event.pressed) {
|
||||
keymap_on(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_ON | ON_BOTH):
|
||||
keymap_on(action.layer.val);
|
||||
break;
|
||||
|
||||
/* Keymap Bit off */
|
||||
case OP_OFF:
|
||||
if (event.pressed) {
|
||||
keymap_off(action.layer.val);
|
||||
} else {
|
||||
keymap_on(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_OFF | ON_PRESS):
|
||||
if (event.pressed) {
|
||||
keymap_off(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_OFF | ON_RELEASE):
|
||||
if (!event.pressed) {
|
||||
keymap_off(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_OFF | ON_BOTH):
|
||||
keymap_off(action.layer.val);
|
||||
break;
|
||||
|
||||
/* Keymap Bit set */
|
||||
case OP_SET:
|
||||
if (event.pressed) {
|
||||
keymap_set(action.layer.val);
|
||||
} else {
|
||||
keymap_clear();
|
||||
}
|
||||
break;
|
||||
case (OP_SET | ON_PRESS):
|
||||
if (event.pressed) {
|
||||
keymap_set(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_SET | ON_RELEASE):
|
||||
if (!event.pressed) {
|
||||
keymap_set(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_SET | ON_BOTH):
|
||||
keymap_set(action.layer.val);
|
||||
break;
|
||||
|
||||
/* Keymap Bit invert with tap key */
|
||||
default:
|
||||
if (event.pressed) {
|
||||
if (tap_count > 0) {
|
||||
debug("KEYMAP_TAP_KEY: Tap: register_code\n");
|
||||
register_code(action.layer.code);
|
||||
} else {
|
||||
debug("LAYER_PRESSED: No tap: layer_switch\n");
|
||||
layer_switch(action.layer.val);
|
||||
}
|
||||
} else {
|
||||
debug("KEYMAP_TAP_KEY: No tap: On on press\n");
|
||||
keymap_on(action.layer.val);
|
||||
}
|
||||
} else {
|
||||
if (tap_count > 0) {
|
||||
debug("LAYER_PRESSED: Tap: unregister_code\n");
|
||||
debug("KEYMAP_TAP_KEY: Tap: unregister_code\n");
|
||||
unregister_code(action.layer.code);
|
||||
} else {
|
||||
//debug("LAYER_PRESSED: No tap: NO ACTION\n");
|
||||
// NOTE: This is needed by legacy keymap support
|
||||
debug("LAYER_PRESSED: No tap: return to default layer\n");
|
||||
layer_switch(default_layer);
|
||||
debug("KEYMAP_TAP_KEY: No tap: Off on release\n");
|
||||
keymap_off(action.layer.val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ACT_LAYER_BIT:
|
||||
|
||||
case ACT_OVERLAY:
|
||||
switch (action.layer.code) {
|
||||
case LAYER_MOMENTARY: /* momentary */
|
||||
if (event.pressed) {
|
||||
layer_switch(current_layer ^ action.layer.val);
|
||||
// Overlay Invert bit4
|
||||
case OP_INV4 | 0:
|
||||
if (action.layer.val == 0) {
|
||||
// NOTE: reserved for future use
|
||||
overlay_clear();
|
||||
} else {
|
||||
layer_switch(current_layer ^ action.layer.val);
|
||||
overlay_set(overlay_stat ^ action.layer.val);
|
||||
}
|
||||
break;
|
||||
case LAYER_ON_PRESS:
|
||||
if (event.pressed) {
|
||||
layer_switch(current_layer ^ action.layer.val);
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case LAYER_ON_RELEASE:
|
||||
if (!event.pressed) {
|
||||
layer_switch(current_layer ^ action.layer.val);
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */
|
||||
case OP_INV4 | 3:
|
||||
if (action.layer.val == 0) {
|
||||
// on both
|
||||
overlay_clear();
|
||||
} else {
|
||||
overlay_set(overlay_stat ^ action.layer.val<<12);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Overlay Bit invert */
|
||||
case OP_INV:
|
||||
/* with tap toggle */
|
||||
if (event.pressed) {
|
||||
if (tap_count < TAPPING_TOGGLE) {
|
||||
debug("LAYER_BIT: tap toggle(press).\n");
|
||||
layer_switch(current_layer ^ action.layer.val);
|
||||
debug("OVERLAY_INV: tap toggle(press).\n");
|
||||
overlay_invert(action.layer.val);
|
||||
}
|
||||
} else {
|
||||
if (tap_count <= TAPPING_TOGGLE) {
|
||||
debug("LAYER_BIT: tap toggle(release).\n");
|
||||
layer_switch(current_layer ^ action.layer.val);
|
||||
debug("OVERLAY_INV: tap toggle(release).\n");
|
||||
overlay_invert(action.layer.val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xFF:
|
||||
// change default layer
|
||||
case (OP_INV | ON_PRESS):
|
||||
if (event.pressed) {
|
||||
default_layer = current_layer ^ action.layer.val;
|
||||
layer_switch(default_layer);
|
||||
} else {
|
||||
default_layer = current_layer ^ action.layer.val;
|
||||
layer_switch(default_layer);
|
||||
overlay_invert(action.layer.val);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// with tap key
|
||||
case (OP_INV | ON_RELEASE):
|
||||
if (!event.pressed) {
|
||||
overlay_invert(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_INV | ON_BOTH):
|
||||
overlay_invert(action.layer.val);
|
||||
break;
|
||||
|
||||
/* Overlay Bit on */
|
||||
case OP_ON:
|
||||
if (event.pressed) {
|
||||
if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
|
||||
debug("LAYER_BIT: Tap: register_code\n");
|
||||
overlay_on(action.layer.val);
|
||||
} else {
|
||||
overlay_off(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_ON | ON_PRESS):
|
||||
if (event.pressed) {
|
||||
overlay_on(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_ON | ON_RELEASE):
|
||||
if (!event.pressed) {
|
||||
overlay_on(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_ON | ON_BOTH):
|
||||
overlay_on(action.layer.val);
|
||||
break;
|
||||
|
||||
/* Overlay Bit off */
|
||||
case OP_OFF:
|
||||
if (event.pressed) {
|
||||
overlay_off(action.layer.val);
|
||||
} else {
|
||||
overlay_on(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_OFF | ON_PRESS):
|
||||
if (event.pressed) {
|
||||
overlay_off(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_OFF | ON_RELEASE):
|
||||
if (!event.pressed) {
|
||||
overlay_off(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_OFF | ON_BOTH):
|
||||
overlay_off(action.layer.val);
|
||||
break;
|
||||
|
||||
/* Overlay Bit set */
|
||||
case OP_SET:
|
||||
if (event.pressed) {
|
||||
overlay_move(action.layer.val);
|
||||
} else {
|
||||
overlay_clear();
|
||||
}
|
||||
break;
|
||||
case (OP_SET | ON_PRESS):
|
||||
if (event.pressed) {
|
||||
overlay_move(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_SET | ON_RELEASE):
|
||||
if (!event.pressed) {
|
||||
overlay_move(action.layer.val);
|
||||
}
|
||||
break;
|
||||
case (OP_SET | ON_BOTH):
|
||||
overlay_move(action.layer.val);
|
||||
break;
|
||||
|
||||
/* Overlay Bit invert with tap key */
|
||||
default:
|
||||
if (event.pressed) {
|
||||
if (tap_count > 0) {
|
||||
debug("OVERLAY_TAP_KEY: Tap: register_code\n");
|
||||
register_code(action.layer.code);
|
||||
} else {
|
||||
debug("LAYER_BIT: No tap: layer_switch(bit on)\n");
|
||||
layer_switch(current_layer ^ action.layer.val);
|
||||
debug("OVERLAY_TAP_KEY: No tap: On on press\n");
|
||||
overlay_on(action.layer.val);
|
||||
}
|
||||
} else {
|
||||
if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
|
||||
debug("LAYER_BIT: Tap: unregister_code\n");
|
||||
if (tap_count > 0) {
|
||||
debug("OVERLAY_TAP_KEY: Tap: unregister_code\n");
|
||||
unregister_code(action.layer.code);
|
||||
} else {
|
||||
debug("LAYER_BIT: No tap: layer_switch(bit off)\n");
|
||||
layer_switch(current_layer ^ action.layer.val);
|
||||
debug("OVERLAY_TAP_KEY: No tap: Off on release\n");
|
||||
overlay_off(action.layer.val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -515,7 +672,7 @@ static void process_action(keyrecord_t *record)
|
|||
|
||||
/* Extentions */
|
||||
case ACT_MACRO:
|
||||
// TODO
|
||||
action_macro_play(action_get_macro(record, action.func.id, action.func.opt));
|
||||
break;
|
||||
case ACT_COMMAND:
|
||||
break;
|
||||
|
@ -540,16 +697,17 @@ static bool process_tapping(keyrecord_t *keyp)
|
|||
// if tapping
|
||||
if (IS_TAPPING_PRESSED()) {
|
||||
if (WITHIN_TAPPING_TERM(event)) {
|
||||
if (tapping_key.tap_count == 0) {
|
||||
if (tapping_key.tap.count == 0) {
|
||||
if (IS_TAPPING_KEY(event.key) && !event.pressed) {
|
||||
// first tap!
|
||||
debug("Tapping: First tap(0->1).\n");
|
||||
tapping_key.tap_count = 1;
|
||||
tapping_key.tap.count = 1;
|
||||
tapping_key.tap.interrupted = (waiting_buffer_has_anykey_pressed() ? true : false);
|
||||
debug_tapping_key();
|
||||
process_action(&tapping_key);
|
||||
|
||||
// enqueue
|
||||
keyp->tap_count = tapping_key.tap_count;
|
||||
keyp->tap = tapping_key.tap;
|
||||
return false;
|
||||
}
|
||||
#if TAPPING_TERM >= 500
|
||||
|
@ -573,19 +731,19 @@ static bool process_tapping(keyrecord_t *keyp)
|
|||
// tap_count > 0
|
||||
else {
|
||||
if (IS_TAPPING_KEY(event.key) && !event.pressed) {
|
||||
debug("Tapping: Tap release("); debug_dec(tapping_key.tap_count); debug(")\n");
|
||||
keyp->tap_count = tapping_key.tap_count;
|
||||
debug("Tapping: Tap release("); debug_dec(tapping_key.tap.count); debug(")\n");
|
||||
keyp->tap = tapping_key.tap;
|
||||
process_action(keyp);
|
||||
tapping_key = *keyp;
|
||||
debug_tapping_key();
|
||||
return true;
|
||||
}
|
||||
else if (is_tap_key(keyp->event.key) && event.pressed) {
|
||||
if (tapping_key.tap_count > 1) {
|
||||
if (tapping_key.tap.count > 1) {
|
||||
debug("Tapping: Start new tap with releasing last tap(>1).\n");
|
||||
// unregister key
|
||||
process_action(&(keyrecord_t){
|
||||
.tap_count = tapping_key.tap_count,
|
||||
.tap = tapping_key.tap,
|
||||
.event.key = tapping_key.event.key,
|
||||
.event.time = event.time,
|
||||
.event.pressed = false
|
||||
|
@ -609,7 +767,7 @@ static bool process_tapping(keyrecord_t *keyp)
|
|||
}
|
||||
// after TAPPING_TERM
|
||||
else {
|
||||
if (tapping_key.tap_count == 0) {
|
||||
if (tapping_key.tap.count == 0) {
|
||||
debug("Tapping: End. Timeout. Not tap(0): ");
|
||||
debug_event(event); debug("\n");
|
||||
process_action(&tapping_key);
|
||||
|
@ -619,17 +777,17 @@ static bool process_tapping(keyrecord_t *keyp)
|
|||
} else {
|
||||
if (IS_TAPPING_KEY(event.key) && !event.pressed) {
|
||||
debug("Tapping: End. last timeout tap release(>0).");
|
||||
keyp->tap_count = tapping_key.tap_count;
|
||||
keyp->tap = tapping_key.tap;
|
||||
process_action(keyp);
|
||||
tapping_key = (keyrecord_t){};
|
||||
return true;
|
||||
}
|
||||
else if (is_tap_key(keyp->event.key) && event.pressed) {
|
||||
if (tapping_key.tap_count > 1) {
|
||||
if (tapping_key.tap.count > 1) {
|
||||
debug("Tapping: Start new tap with releasing last timeout tap(>1).\n");
|
||||
// unregister key
|
||||
process_action(&(keyrecord_t){
|
||||
.tap_count = tapping_key.tap_count,
|
||||
.tap = tapping_key.tap,
|
||||
.event.key = tapping_key.event.key,
|
||||
.event.time = event.time,
|
||||
.event.pressed = false
|
||||
|
@ -653,10 +811,11 @@ static bool process_tapping(keyrecord_t *keyp)
|
|||
}
|
||||
} else if (IS_TAPPING_RELEASED()) {
|
||||
if (WITHIN_TAPPING_TERM(event)) {
|
||||
if (tapping_key.tap_count > 0 && IS_TAPPING_KEY(event.key) && event.pressed) {
|
||||
if (tapping_key.tap.count > 0 && IS_TAPPING_KEY(event.key) && event.pressed) {
|
||||
// sequential tap.
|
||||
keyp->tap_count = tapping_key.tap_count + 1;
|
||||
debug("Tapping: Tap press("); debug_dec(keyp->tap_count); debug(")\n");
|
||||
keyp->tap = tapping_key.tap;
|
||||
keyp->tap.count += 1;
|
||||
debug("Tapping: Tap press("); debug_dec(keyp->tap.count); debug(")\n");
|
||||
process_action(keyp);
|
||||
tapping_key = *keyp;
|
||||
debug_tapping_key();
|
||||
|
@ -701,16 +860,16 @@ static bool process_tapping(keyrecord_t *keyp)
|
|||
static void waiting_buffer_scan_tap(void)
|
||||
{
|
||||
// tapping already is settled
|
||||
if (tapping_key.tap_count > 0) return;
|
||||
// invalid state: tapping_key released && tap_count == 0
|
||||
if (tapping_key.tap.count > 0) return;
|
||||
// invalid state: tapping_key released && tap.count == 0
|
||||
if (!tapping_key.event.pressed) return;
|
||||
|
||||
for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
|
||||
if (IS_TAPPING_KEY(waiting_buffer[i].event.key) &&
|
||||
!waiting_buffer[i].event.pressed &&
|
||||
WITHIN_TAPPING_TERM(waiting_buffer[i].event)) {
|
||||
tapping_key.tap_count = 1;
|
||||
waiting_buffer[i].tap_count = 1;
|
||||
tapping_key.tap.count = 1;
|
||||
waiting_buffer[i].tap.count = 1;
|
||||
process_action(&tapping_key);
|
||||
|
||||
debug("waiting_buffer_scan_tap: found at ["); debug_dec(i); debug("]\n");
|
||||
|
@ -813,39 +972,24 @@ bool sending_anykey(void)
|
|||
host_last_sysytem_report() || host_last_consumer_report());
|
||||
}
|
||||
|
||||
void layer_switch(uint8_t new_layer)
|
||||
{
|
||||
if (current_layer != new_layer) {
|
||||
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
|
||||
// NOTE: update mods with full scan of matrix? if modifier changes between layers
|
||||
}
|
||||
}
|
||||
|
||||
bool is_tap_key(key_t key)
|
||||
{
|
||||
action_t action = get_action(key);
|
||||
action_t action = layer_switch_get_action(key);
|
||||
|
||||
switch (action.kind.id) {
|
||||
case ACT_LMODS_TAP:
|
||||
case ACT_RMODS_TAP:
|
||||
return true;
|
||||
case ACT_LAYER:
|
||||
case ACT_LAYER_BIT:
|
||||
case ACT_KEYMAP:
|
||||
case ACT_OVERLAY:
|
||||
switch (action.layer.code) {
|
||||
case LAYER_MOMENTARY:
|
||||
case LAYER_ON_PRESS:
|
||||
case LAYER_ON_RELEASE:
|
||||
case LAYER_DEFAULT:
|
||||
return false;
|
||||
case LAYER_TAP_TOGGLE:
|
||||
default: /* tap key */
|
||||
case 0x04 ... 0xEF: /* tap key */
|
||||
case OP_INV:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
case ACT_MACRO:
|
||||
case ACT_FUNCTION:
|
||||
if (action.func.opt & FUNC_TAP) { return true; }
|
||||
return false;
|
||||
|
@ -865,7 +1009,8 @@ static void debug_event(keyevent_t event)
|
|||
}
|
||||
static void debug_record(keyrecord_t record)
|
||||
{
|
||||
debug_event(record.event); debug(":"); debug_dec(record.tap_count);
|
||||
debug_event(record.event); debug(":"); debug_dec(record.tap.count);
|
||||
if (record.tap.interrupted) debug("-");
|
||||
}
|
||||
static void debug_action(action_t action)
|
||||
{
|
||||
|
@ -876,8 +1021,8 @@ static void debug_action(action_t action)
|
|||
case ACT_RMODS_TAP: debug("ACT_RMODS_TAP"); break;
|
||||
case ACT_USAGE: debug("ACT_USAGE"); break;
|
||||
case ACT_MOUSEKEY: debug("ACT_MOUSEKEY"); break;
|
||||
case ACT_LAYER: debug("ACT_LAYER"); break;
|
||||
case ACT_LAYER_BIT: debug("ACT_LAYER_BIT"); break;
|
||||
case ACT_KEYMAP: debug("ACT_KEYMAP"); break;
|
||||
case ACT_OVERLAY: debug("ACT_OVERLAY"); break;
|
||||
case ACT_MACRO: debug("ACT_MACRO"); break;
|
||||
case ACT_COMMAND: debug("ACT_COMMAND"); break;
|
||||
case ACT_FUNCTION: debug("ACT_FUNCTION"); break;
|
||||
|
|
253
common/action.h
253
common/action.h
|
@ -19,12 +19,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include "keyboard.h"
|
||||
#include "keycode.h"
|
||||
#include "action_macro.h"
|
||||
|
||||
|
||||
/* Struct to record event and tap count */
|
||||
typedef union {
|
||||
struct {
|
||||
bool interrupted :1;
|
||||
bool reserved2 :1;
|
||||
bool reserved1 :1;
|
||||
bool reserved0 :1;
|
||||
uint8_t count :4;
|
||||
};
|
||||
} tap_t;
|
||||
|
||||
typedef struct {
|
||||
keyevent_t event;
|
||||
uint8_t tap_count;
|
||||
tap_t tap;
|
||||
} keyrecord_t;
|
||||
|
||||
/* Action struct.
|
||||
|
@ -76,17 +87,15 @@ typedef union {
|
|||
|
||||
|
||||
|
||||
/* layer used currently */
|
||||
extern uint8_t current_layer;
|
||||
/* layer to return or start with */
|
||||
extern uint8_t default_layer;
|
||||
|
||||
/* Execute action per keyevent */
|
||||
void action_exec(keyevent_t event);
|
||||
|
||||
/* action for key */
|
||||
action_t action_for_key(uint8_t layer, key_t key);
|
||||
|
||||
/* macro */
|
||||
const prog_macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt);
|
||||
|
||||
/* user defined special function */
|
||||
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
|
||||
|
||||
|
@ -112,8 +121,8 @@ bool waiting_buffer_has_anykey_pressed(void);
|
|||
* ============
|
||||
* 16bit code: action_kind(4bit) + action_parameter(12bit)
|
||||
*
|
||||
* Keyboard Keys
|
||||
* -------------
|
||||
* Keyboard Keys(00XX)
|
||||
* -------------------
|
||||
* ACT_LMODS(0000):
|
||||
* 0000|0000|000000|00 No action
|
||||
* 0000|0000|000000|01 Transparent
|
||||
|
@ -143,8 +152,8 @@ bool waiting_buffer_has_anykey_pressed(void);
|
|||
* 0011|mods| keycode Right mods + tap Key
|
||||
*
|
||||
*
|
||||
* Other HID Usage
|
||||
* ---------------
|
||||
* Other keys(01XX)
|
||||
* --------------------
|
||||
* This action handles other usages than keyboard.
|
||||
* ACT_USAGE(0100):
|
||||
* 0100|00| usage(10) System control(0x80) - General Desktop page(0x01)
|
||||
|
@ -152,41 +161,45 @@ bool waiting_buffer_has_anykey_pressed(void);
|
|||
* 0100|10| usage(10) (reserved)
|
||||
* 0100|11| usage(10) (reserved)
|
||||
*
|
||||
*
|
||||
* Mouse Keys
|
||||
* ----------
|
||||
* TODO: can be combined with 'Other HID Usage'? to save action kind id.
|
||||
* ACT_MOUSEKEY(0110):
|
||||
* 0101|XXXX| keycode Mouse key
|
||||
*
|
||||
*
|
||||
* Layer Actions
|
||||
* -------------
|
||||
* ACT_LAYER(1000): Set layer
|
||||
* ACT_LAYER_BIT(1001): Bit-op layer
|
||||
*
|
||||
* 1000|LLLL|0000 0000 set L to layer on press and set default on release(momentary)
|
||||
* 1000|LLLL|0000 0001 set L to layer on press
|
||||
* 1000|LLLL|0000 0010 set L to layer on release
|
||||
* 1000|----|0000 0011 set default to layer on both(return to default layer)
|
||||
* 1000|LLLL| keycode set L to layer while hold and send key on tap
|
||||
* 1000|LLLL|1111 0000 set L to layer while hold and toggle on several taps
|
||||
* 1000|LLLL|1111 1111 set L to default and layer(on press)
|
||||
*
|
||||
* 1001|BBBB|0000 0000 (not used)
|
||||
* 1001|BBBB|0000 0001 bit-xor layer with B on press
|
||||
* 1001|BBBB|0000 0010 bit-xor layer with B on release
|
||||
* 1001|BBBB|0000 0011 bit-xor layer with B on both(momentary)
|
||||
* 1001|BBBB| keycode bit-xor layer with B while hold and send key on tap
|
||||
* 1001|BBBB|1111 0000 bit-xor layer with B while hold and toggle on several taps
|
||||
* 1001|BBBB|1111 1111 bit-xor default with B and set layer(on press)
|
||||
* Layer Actions(10XX)
|
||||
* -------------------
|
||||
* ACT_KEYMAP:
|
||||
* 1000|--xx|0000 0000 Clear keyamp and overlay
|
||||
* 1000|LLLL|0000 00xx Reset default layer and clear keymap and overlay
|
||||
* 1000|LLLL| keycode Invert with tap key
|
||||
* 1000|LLLL|1111 0000 Invert with tap toggle
|
||||
* 1000|LLLL|1111 00xx Invert[^= 1<<L]
|
||||
* 1000|LLLL|1111 0100 On/Off
|
||||
* 1000|LLLL|1111 01xx On[|= 1<<L]
|
||||
* 1000|LLLL|1111 1000 Off/On
|
||||
* 1000|LLLL|1111 10xx Off[&= ~(1<<L)]
|
||||
* 1000|LLLL|1111 1100 Set/Clear
|
||||
* 1000|LLLL|1111 11xx Set[= 1<<L]
|
||||
* default layer: 0-15(4bit)
|
||||
* xx: On {00:for special use, 01:press, 10:release, 11:both}
|
||||
*
|
||||
* ACT_OVERLAY:
|
||||
* 1011|0000|0000 0000 Clear overlay
|
||||
* 1011|LLLL|0000 00ss Invert 4-bit chunk [^= L<<(4*ss)]
|
||||
* 1011|LLLL| keycode Invert with tap key
|
||||
* 1011|LLLL|1111 0000 Invert with tap toggle
|
||||
* 1011|LLLL|1111 00xx Invert[^= 1<<L]
|
||||
* 1011|LLLL|1111 0100 On/Off(momentary)
|
||||
* 1011|LLLL|1111 01xx On[|= 1<<L]
|
||||
* 1011|LLLL|1111 1000 Off/On
|
||||
* 1011|LLLL|1111 10xx Off[&= ~(1<<L)]
|
||||
* 1011|LLLL|1111 1100 Set/Clear
|
||||
* 1011|LLLL|1111 11xx Set[= 1<<L]
|
||||
* overlays: 16-layer on/off status(16bit)
|
||||
* xx: On {00:for special use, 01:press, 10:release, 11:both}
|
||||
*
|
||||
*
|
||||
* Extensions(11XX)
|
||||
* ----------------
|
||||
* NOTE: NOT FIXED
|
||||
*
|
||||
* ACT_MACRO(1100):
|
||||
* 1100|opt | id(8) Macro play?
|
||||
* 1100|1111| id(8) Macro record?
|
||||
|
@ -208,8 +221,8 @@ enum action_kind_id {
|
|||
ACT_USAGE = 0b0100,
|
||||
ACT_MOUSEKEY = 0b0101,
|
||||
|
||||
ACT_LAYER = 0b1000,
|
||||
ACT_LAYER_BIT = 0b1001,
|
||||
ACT_KEYMAP = 0b1000,
|
||||
ACT_OVERLAY = 0b1001,
|
||||
|
||||
ACT_MACRO = 0b1100,
|
||||
ACT_COMMAND = 0b1110,
|
||||
|
@ -223,20 +236,20 @@ enum action_kind_id {
|
|||
#define ACTION(kind, param) ((kind)<<12 | (param))
|
||||
#define MODS4(mods) (((mods)>>4 | (mods)) & 0x0F)
|
||||
|
||||
/* Key */
|
||||
/*
|
||||
* Key
|
||||
*/
|
||||
#define ACTION_KEY(key) ACTION(ACT_LMODS, key)
|
||||
/* Mods & key */
|
||||
#define ACTION_LMODS(mods) ACTION(ACT_LMODS, MODS4(mods)<<8 | 0x00)
|
||||
#define ACTION_LMODS_KEY(mods, key) ACTION(ACT_LMODS, MODS4(mods)<<8 | (key))
|
||||
#define ACTION_RMODS(mods) ACTION(ACT_RMODS, MODS4(mods)<<8 | 0x00)
|
||||
#define ACTION_RMODS_KEY(mods, key) ACTION(ACT_RMODS, MODS4(mods)<<8 | (key))
|
||||
/* Mod & key */
|
||||
#define ACTION_LMOD(mod) ACTION(ACT_LMODS, MODS4(MOD_BIT(mod))<<8 | 0x00)
|
||||
#define ACTION_LMOD_KEY(mod, key) ACTION(ACT_LMODS, MODS4(MOD_BIT(mod))<<8 | (key))
|
||||
#define ACTION_RMOD(mod) ACTION(ACT_RMODS, MODS4(MOD_BIT(mod))<<8 | 0x00)
|
||||
#define ACTION_RMOD_KEY(mod, key) ACTION(ACT_RMODS, MODS4(MOD_BIT(mod))<<8 | (key))
|
||||
|
||||
/* Mods + Tap key */
|
||||
/* Tap key */
|
||||
enum mods_codes {
|
||||
MODS_ONESHOT = 0x00,
|
||||
};
|
||||
|
@ -244,80 +257,11 @@ enum mods_codes {
|
|||
#define ACTION_LMODS_ONESHOT(mods) ACTION(ACT_LMODS_TAP, MODS4(mods)<<8 | MODS_ONESHOT)
|
||||
#define ACTION_RMODS_TAP_KEY(mods, key) ACTION(ACT_RMODS_TAP, MODS4(mods)<<8 | (key))
|
||||
#define ACTION_RMODS_ONESHOT(mods) ACTION(ACT_RMODS_TAP, MODS4(mods)<<8 | MODS_ONESHOT)
|
||||
/* Mod + Tap key */
|
||||
#define ACTION_LMOD_TAP_KEY(mod, key) ACTION(ACT_LMODS_TAP, MODS4(MOD_BIT(mod))<<8 | (key))
|
||||
#define ACTION_LMOD_ONESHOT(mod) ACTION(ACT_LMODS_TAP, MODS4(MOD_BIT(mod))<<8 | MODS_ONESHOT)
|
||||
#define ACTION_RMOD_TAP_KEY(mod, key) ACTION(ACT_RMODS_TAP, MODS4(MOD_BIT(mod))<<8 | (key))
|
||||
#define ACTION_RMOD_ONESHOT(mod) ACTION(ACT_RMODS_TAP, MODS4(MOD_BIT(mod))<<8 | MODS_ONESHOT)
|
||||
|
||||
|
||||
/*
|
||||
* Switch layer
|
||||
*/
|
||||
enum layer_codes {
|
||||
LAYER_MOMENTARY = 0,
|
||||
LAYER_ON_PRESS = 1,
|
||||
LAYER_ON_RELEASE = 2,
|
||||
LAYER_DEFAULT =3,
|
||||
LAYER_TAP_TOGGLE = 0xF0,
|
||||
LAYER_CHANGE_DEFAULT = 0xFF
|
||||
};
|
||||
enum layer_vals_default {
|
||||
DEFAULT_ON_PRESS = 1,
|
||||
DEFAULT_ON_RELEASE = 2,
|
||||
DEFAULT_ON_BOTH = 3,
|
||||
};
|
||||
|
||||
/*
|
||||
* return to default layer
|
||||
*/
|
||||
#define ACTION_LAYER_DEFAULT ACTION_LAYER_DEFAULT_R
|
||||
/* set default layer on press */
|
||||
#define ACTION_LAYER_DEFAULT_P ACTION(ACT_LAYER, DEFAULT_ON_PRESS<<8 | LAYER_DEFAULT)
|
||||
/* set default layer on release */
|
||||
#define ACTION_LAYER_DEFAULT_R ACTION(ACT_LAYER, DEFAULT_ON_RELEASE<<8 | LAYER_DEFAULT)
|
||||
/* change default layer and set layer */
|
||||
|
||||
/*
|
||||
* Set layer
|
||||
*/
|
||||
/* set layer on press and none on release */
|
||||
#define ACTION_LAYER_SET(layer) ACTION_LAYER_SET_P(layer)
|
||||
/* set layer on press and set default on release (This is needed by legacy keymap support.) */
|
||||
#define ACTION_LAYER_SET_MOMENTARY(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_MOMENTARY)
|
||||
/* set layer on press and none on release */
|
||||
#define ACTION_LAYER_SET_TOGGLE(layer) ACTION_LAYER_SET_R(layer)
|
||||
/* set layer while hold and send key on tap */
|
||||
#define ACTION_LAYER_SET_TAP_KEY(layer, key) ACTION(ACT_LAYER, (layer)<<8 | (key))
|
||||
/* set layer on press */
|
||||
#define ACTION_LAYER_SET_P(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_ON_PRESS)
|
||||
/* set layer on release */
|
||||
#define ACTION_LAYER_SET_R(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_ON_RELEASE)
|
||||
/* set layer on hold and toggle on several taps */
|
||||
#define ACTION_LAYER_SET_TAP_TOGGLE(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_TAP_TOGGLE)
|
||||
/* set default layer on both press and release */
|
||||
#define ACTION_LAYER_SET_DEFAULT(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_CHANGE_DEFAULT)
|
||||
|
||||
/*
|
||||
* Bit-op layer
|
||||
*/
|
||||
/* bit-xor on both press and release */
|
||||
#define ACTION_LAYER_BIT(bits) ACTION_LAYER_BIT_MOMENTARY(bits)
|
||||
#define ACTION_LAYER_BIT_MOMENTARY(bits) ACTION(ACT_LAYER_BIT, (bits)<<8 | LAYER_MOMENTARY)
|
||||
/* bit-xor on press */
|
||||
#define ACTION_LAYER_BIT_TOGGLE(bits) ACTION_LAYER_BIT_R(bits)
|
||||
/* bit-xor while hold and send key on tap */
|
||||
#define ACTION_LAYER_BIT_TAP_KEY(bits, key) ACTION(ACT_LAYER_BIT, (bits)<<8 | (key))
|
||||
/* bit-xor on press */
|
||||
#define ACTION_LAYER_BIT_P(bits) ACTION(ACT_LAYER_BIT, (bits)<<8 | LAYER_ON_PRESS)
|
||||
/* bit-xor on release */
|
||||
#define ACTION_LAYER_BIT_R(bits) ACTION(ACT_LAYER_BIT, (bits)<<8 | LAYER_ON_RELEASE)
|
||||
/* bit-xor while hold and toggle on several taps */
|
||||
#define ACTION_LAYER_BIT_TAP_TOGGLE(bits) ACTION(ACT_LAYER_BIT, (bits)<<8 | LAYER_TAP_TOGGLE)
|
||||
/* bit-xor default layer and set layer */
|
||||
#define ACTION_LAYER_BIT_DEFAULT(bits) ACTION(ACT_LAYER, (bits)<<8 | LAYER_CHANGE_DEFAULT)
|
||||
|
||||
|
||||
/* HID Usage */
|
||||
enum usage_pages {
|
||||
PAGE_SYSTEM,
|
||||
|
@ -329,17 +273,96 @@ enum usage_pages {
|
|||
/* Mousekey */
|
||||
#define ACTION_MOUSEKEY(key) ACTION(ACT_MOUSEKEY, key)
|
||||
|
||||
|
||||
|
||||
/* Layer Actions:
|
||||
* Invert layer ^= (1<<layer)
|
||||
* On layer |= (1<<layer)
|
||||
* Off layer &= ~(1<<layer)
|
||||
* Set layer = (1<<layer)
|
||||
* Clear layer = 0
|
||||
*/
|
||||
enum layer_params {
|
||||
ON_PRESS = 1,
|
||||
ON_RELEASE = 2,
|
||||
ON_BOTH = 3,
|
||||
|
||||
OP_RESET = 0x00,
|
||||
OP_INV4 = 0x00,
|
||||
OP_INV = 0xF0,
|
||||
OP_ON = 0xF4,
|
||||
OP_OFF = 0xF8,
|
||||
OP_SET = 0xFC,
|
||||
};
|
||||
|
||||
/*
|
||||
* Default Layer
|
||||
*/
|
||||
#define ACTION_DEFAULT_LAYER ACTION(ACT_KEYMAP, ON_RELEASE<<8 | OP_RESET | 0)
|
||||
#define ACTION_DEFAULT_LAYER_SET(layer) ACTION_DEFAULT_LAYER_TO(layer, ON_RELEASE)
|
||||
#define ACTION_DEFAULT_LAYER_TO(layer, on) ACTION(ACT_KEYMAP, (layer)<<8 | OP_RESET | (on))
|
||||
/*
|
||||
* Keymap Layer
|
||||
*/
|
||||
#define ACTION_KEYMAP_MOMENTARY(layer) ACTION_KEYMAP_ON_OFF(layer)
|
||||
#define ACTION_KEYMAP_TOGGLE(layer) ACTION_KEYMAP_INV(layer, ON_RELEASE)
|
||||
/* Keymap Invert */
|
||||
#define ACTION_KEYMAP_INV(layer, on) ACTION(ACT_KEYMAP, (layer)<<8 | OP_INV | (on))
|
||||
#define ACTION_KEYMAP_TAP_TOGGLE(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_INV | 0)
|
||||
/* Keymap On */
|
||||
#define ACTION_KEYMAP_ON(layer, on) ACTION(ACT_KEYMAP, (layer)<<8 | OP_ON | (on))
|
||||
#define ACTION_KEYMAP_ON_OFF(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_ON | 0)
|
||||
/* Keymap Off */
|
||||
#define ACTION_KEYMAP_OFF(layer, on) ACTION(ACT_KEYMAP, (layer)<<8 | OP_OFF | (on))
|
||||
#define ACTION_KEYMAP_OFF_ON(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_OFF | 0)
|
||||
/* Keymap Set */
|
||||
#define ACTION_KEYMAP_SET(layer, on) ACTION(ACT_KEYMAP, (layer)<<8 | OP_SET | (on))
|
||||
#define ACTION_KEYMAP_SET_CLEAR(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_SET | 0)
|
||||
/* Keymap Invert with tap key */
|
||||
#define ACTION_KEYMAP_TAP_KEY(layer, key) ACTION(ACT_KEYMAP, (layer)<<8 | (key))
|
||||
|
||||
/*
|
||||
* Overlay Layer
|
||||
*/
|
||||
#define ACTION_OVERLAY_MOMENTARY(layer) ACTION_OVERLAY_ON_OFF(layer)
|
||||
#define ACTION_OVERLAY_TOGGLE(layer) ACTION_OVERLAY_INV(layer, ON_RELEASE)
|
||||
/* Overlay Clear */
|
||||
#define ACTION_OVERLAY_CLEAR(on) ACTION(ACT_OVERLAY, 0<<8 | OP_INV4 | (on))
|
||||
/* Overlay Invert 4-bit chunk */
|
||||
#define ACTION_OVERLAY_INV4(bits, shift) ACTION(ACT_OVERLAY, (bits)<<8 | OP_INV4 | shift)
|
||||
/* Overlay Invert */
|
||||
#define ACTION_OVERLAY_INV(layer, on) ACTION(ACT_OVERLAY, (layer)<<8 | OP_INV | (on))
|
||||
#define ACTION_OVERLAY_TAP_TOGGLE(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_INV | 0)
|
||||
/* Overlay On */
|
||||
#define ACTION_OVERLAY_ON(layer, on) ACTION(ACT_OVERLAY, (layer)<<8 | OP_ON | (on))
|
||||
#define ACTION_OVERLAY_ON_OFF(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_ON | 0)
|
||||
/* Overlay Off */
|
||||
#define ACTION_OVERLAY_OFF(layer, on) ACTION(ACT_OVERLAY, (layer)<<8 | OP_OFF | (on))
|
||||
#define ACTION_OVERLAY_OFF_ON(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_OFF | 0)
|
||||
/* Overlay Set */
|
||||
#define ACTION_OVERLAY_SET(layer, on) ACTION(ACT_OVERLAY, (layer)<<8 | OP_SET | (on))
|
||||
#define ACTION_OVERLAY_SET_CLEAR(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_SET | 0)
|
||||
/* Overlay Invert with tap key */
|
||||
#define ACTION_OVERLAY_TAP_KEY(layer, key) ACTION(ACT_OVERLAY, (layer)<<8 | (key))
|
||||
|
||||
|
||||
/*
|
||||
* Extensions
|
||||
*/
|
||||
/* Macro */
|
||||
#define ACTION_MACRO(opt, id) ACTION(ACT_FUNCTION, (opt)<<8 | (addr))
|
||||
#define ACTION_MACRO(id) ACTION(ACT_MACRO, (id))
|
||||
#define ACTION_MACRO_TAP(id) ACTION(ACT_MACRO, FUNC_TAP<<8 | (id))
|
||||
#define ACTION_MACRO_OPT(id, opt) ACTION(ACT_MACRO, (opt)<<8 | (id))
|
||||
|
||||
/* Command */
|
||||
#define ACTION_COMMAND(opt, id) ACTION(ACT_COMMAND, (opt)<<8 | (addr))
|
||||
#define ACTION_COMMAND(id, opt) ACTION(ACT_COMMAND, (opt)<<8 | (addr))
|
||||
|
||||
/* Function */
|
||||
enum function_opts {
|
||||
FUNC_TAP = 0x8, /* indciates function is tappable */
|
||||
};
|
||||
#define ACTION_FUNCTION(id, opt) ACTION(ACT_FUNCTION, (opt)<<8 | id)
|
||||
#define ACTION_FUNCTION_TAP(id) ACTION(ACT_FUNCTION, FUNC_TAP<<8 | id)
|
||||
#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))
|
||||
|
||||
#endif /* ACTION_H */
|
||||
|
|
|
@ -41,7 +41,6 @@ void action_macro_play(const prog_macro_t *macro_p)
|
|||
case MODS_DOWN:
|
||||
MACRO_READ();
|
||||
debug("MODS_DOWN("); debug_hex(macro); debug(")\n");
|
||||
debug("MODS_UP("); debug_hex(macro); debug(")\n");
|
||||
add_mods(macro);
|
||||
break;
|
||||
case MODS_UP:
|
||||
|
|
|
@ -20,6 +20,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <avr/pgmspace.h>
|
||||
|
||||
|
||||
#define MACRO_NONE 0
|
||||
#define MACRO(...) ({ static prog_macro_t _m[] PROGMEM = { __VA_ARGS__ }; _m; })
|
||||
|
||||
|
||||
typedef uint8_t macro_t;
|
||||
typedef macro_t prog_macro_t PROGMEM;
|
||||
|
||||
|
|
|
@ -26,7 +26,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "timer.h"
|
||||
#include "keyboard.h"
|
||||
#include "bootloader.h"
|
||||
#include "layer_switch.h"
|
||||
#include "command.h"
|
||||
|
||||
#ifdef MOUSEKEY_ENABLE
|
||||
#include "mousekey.h"
|
||||
#endif
|
||||
|
@ -53,7 +55,7 @@ static void mousekey_console_help(void);
|
|||
#endif
|
||||
|
||||
static uint8_t numkey2num(uint8_t code);
|
||||
static void switch_layer(uint8_t layer);
|
||||
static void switch_default_layer(uint8_t layer);
|
||||
|
||||
|
||||
typedef enum { ONESHOT, CONSOLE, MOUSEKEY } cmdstate_t;
|
||||
|
@ -261,18 +263,16 @@ static bool command_common(uint8_t code)
|
|||
#endif
|
||||
break;
|
||||
#endif
|
||||
case KC_ESC:
|
||||
case KC_GRV:
|
||||
case KC_0:
|
||||
case KC_F10:
|
||||
clear_keyboard();
|
||||
switch_layer(0);
|
||||
switch_default_layer(0);
|
||||
break;
|
||||
case KC_1 ... KC_9:
|
||||
clear_keyboard();
|
||||
switch_layer((code - KC_1) + 1);
|
||||
switch_default_layer((code - KC_1) + 1);
|
||||
break;
|
||||
case KC_F1 ... KC_F9:
|
||||
clear_keyboard();
|
||||
switch_layer((code - KC_F1) + 1);
|
||||
case KC_F1 ... KC_F12:
|
||||
switch_default_layer((code - KC_F1) + 1);
|
||||
break;
|
||||
default:
|
||||
print("?");
|
||||
|
@ -541,11 +541,10 @@ static uint8_t numkey2num(uint8_t code)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void switch_layer(uint8_t layer)
|
||||
static void switch_default_layer(uint8_t layer)
|
||||
{
|
||||
print_val_hex8(current_layer);
|
||||
print_val_hex8(default_layer);
|
||||
current_layer = layer;
|
||||
default_layer = layer;
|
||||
print("switch to "); print_val_hex8(layer);
|
||||
print("switch_default_layer: "); print_dec(default_layer); print(" to "); print_dec(layer); print("\n");
|
||||
default_layer_set(layer);
|
||||
overlay_clear();
|
||||
clear_keyboard();
|
||||
}
|
||||
|
|
|
@ -14,13 +14,71 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <avr/pgmspace.h>
|
||||
#include "keymap.h"
|
||||
#include "report.h"
|
||||
#include "keycode.h"
|
||||
#include "layer_switch.h"
|
||||
#include "action.h"
|
||||
#include "action_macro.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
action_t keymap_keycode_to_action(uint8_t keycode)
|
||||
static action_t keycode_to_action(uint8_t keycode);
|
||||
|
||||
#ifdef USE_KEYMAP_V2
|
||||
/* converts key to action */
|
||||
action_t action_for_key(uint8_t layer, key_t key)
|
||||
{
|
||||
uint8_t keycode = keymap_key_to_keycode(layer, key);
|
||||
switch (keycode) {
|
||||
case KC_FN0 ... KC_FN31:
|
||||
return keymap_fn_to_action(keycode);
|
||||
default:
|
||||
return keycode_to_action(keycode);
|
||||
}
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* legacy keymap support
|
||||
*/
|
||||
/* translation for legacy keymap */
|
||||
action_t action_for_key(uint8_t layer, key_t key)
|
||||
{
|
||||
/* convert from legacy keycode to action */
|
||||
/* layer 16-31 indicate 'overlay' but not supported in legacy keymap */
|
||||
uint8_t keycode = keymap_get_keycode((layer & OVERLAY_MASK), key.row, key.col);
|
||||
action_t action;
|
||||
switch (keycode) {
|
||||
case KC_FN0 ... KC_FN31:
|
||||
{
|
||||
uint8_t layer = keymap_fn_layer(FN_INDEX(keycode));
|
||||
uint8_t key = keymap_fn_keycode(FN_INDEX(keycode));
|
||||
if (key) {
|
||||
action.code = ACTION_KEYMAP_TAP_KEY(layer, key);
|
||||
} else {
|
||||
action.code = ACTION_KEYMAP_MOMENTARY(layer);
|
||||
}
|
||||
}
|
||||
return action;
|
||||
default:
|
||||
return keycode_to_action(keycode);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
__attribute__ ((weak))
|
||||
const prog_macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { return MACRO_NONE; }
|
||||
|
||||
__attribute__ ((weak))
|
||||
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {}
|
||||
|
||||
|
||||
|
||||
|
||||
/* translates keycode to action */
|
||||
static action_t keycode_to_action(uint8_t keycode)
|
||||
{
|
||||
action_t action;
|
||||
switch (keycode) {
|
||||
|
@ -51,34 +109,3 @@ action_t keymap_keycode_to_action(uint8_t keycode)
|
|||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
#ifndef NO_LEGACY_KEYMAP_SUPPORT
|
||||
/* legacy support with weak reference */
|
||||
__attribute__ ((weak))
|
||||
action_t action_for_key(uint8_t layer, key_t key)
|
||||
{
|
||||
/* convert from legacy keycode to action */
|
||||
uint8_t keycode = keymap_get_keycode(layer, key.row, key.col);
|
||||
action_t action;
|
||||
switch (keycode) {
|
||||
case KC_FN0 ... KC_FN31:
|
||||
{
|
||||
uint8_t layer = keymap_fn_layer(FN_INDEX(keycode));
|
||||
uint8_t key = keymap_fn_keycode(FN_INDEX(keycode));
|
||||
if (key) {
|
||||
action.code = ACTION_LAYER_SET_TAP_KEY(layer, key);
|
||||
} else {
|
||||
action.code = ACTION_LAYER_SET_MOMENTARY(layer);
|
||||
}
|
||||
}
|
||||
return action;
|
||||
default:
|
||||
return keymap_keycode_to_action(keycode);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
__attribute__ ((weak))
|
||||
void action_function(keyrecord_t *event, uint8_t id, uint8_t opt)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -23,16 +23,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "action.h"
|
||||
|
||||
|
||||
/* translates key_t to keycode */
|
||||
#ifdef USE_KEYMAP_V2
|
||||
/* translates key to keycode
|
||||
* layer: 0-15 for base layers
|
||||
* 16-31 for overlays
|
||||
*/
|
||||
uint8_t keymap_key_to_keycode(uint8_t layer, key_t key);
|
||||
/* translates keycode to action */
|
||||
action_t keymap_keycode_to_action(uint8_t keycode);
|
||||
/* translates Fn keycode to action */
|
||||
action_t keymap_fn_to_action(uint8_t keycode);
|
||||
|
||||
|
||||
|
||||
#ifndef NO_LEGACY_KEYMAP_SUPPORT
|
||||
#else
|
||||
#warning "You are using LEGACY KEYAMP. Consider using NEW KEYMAP."
|
||||
/*
|
||||
* legacy keymap support
|
||||
*/
|
||||
/* keycode of key */
|
||||
uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col);
|
||||
/* layer to move during press Fn key */
|
||||
|
|
201
common/layer_switch.c
Normal file
201
common/layer_switch.c
Normal file
|
@ -0,0 +1,201 @@
|
|||
#include <stdint.h>
|
||||
#include "keyboard.h"
|
||||
#include "action.h"
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
#include "layer_switch.h"
|
||||
|
||||
|
||||
/*
|
||||
* Default Layer (0-15)
|
||||
*/
|
||||
uint8_t default_layer = 0;
|
||||
|
||||
void default_layer_set(uint8_t layer)
|
||||
{
|
||||
debug("default_layer_set: ");
|
||||
debug_dec(default_layer); debug(" to ");
|
||||
|
||||
default_layer = layer;
|
||||
|
||||
debug_dec(default_layer); debug("\n");
|
||||
|
||||
clear_keyboard_but_mods(); // To avoid stuck keys
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Keymap Layer (0-15)
|
||||
*/
|
||||
uint16_t keymap_stat = 0;
|
||||
|
||||
/* return highest layer whose state is on */
|
||||
uint8_t keymap_get_layer(void)
|
||||
{
|
||||
return biton16(keymap_stat);
|
||||
}
|
||||
|
||||
static void keymap_stat_set(uint16_t stat)
|
||||
{
|
||||
debug("keymap: ");
|
||||
keymap_debug(); debug(" to ");
|
||||
|
||||
keymap_stat = stat;
|
||||
|
||||
keymap_debug(); debug("\n");
|
||||
|
||||
clear_keyboard_but_mods(); // To avoid stuck keys
|
||||
}
|
||||
|
||||
void keymap_clear(void)
|
||||
{
|
||||
keymap_stat_set(0);
|
||||
}
|
||||
|
||||
|
||||
void keymap_set(uint16_t stat)
|
||||
{
|
||||
keymap_stat_set(stat);
|
||||
}
|
||||
|
||||
void keymap_move(uint8_t layer)
|
||||
{
|
||||
keymap_stat_set(1<<layer);
|
||||
}
|
||||
|
||||
void keymap_on(uint8_t layer)
|
||||
{
|
||||
keymap_stat_set(keymap_stat | (1<<layer));
|
||||
}
|
||||
|
||||
void keymap_off(uint8_t layer)
|
||||
{
|
||||
keymap_stat_set(keymap_stat & ~(1<<layer));
|
||||
}
|
||||
|
||||
void keymap_invert(uint8_t layer)
|
||||
{
|
||||
keymap_stat_set(keymap_stat ^ (1<<layer));
|
||||
}
|
||||
|
||||
void keymap_or(uint16_t stat)
|
||||
{
|
||||
keymap_stat_set(keymap_stat | stat);
|
||||
}
|
||||
void keymap_and(uint16_t stat)
|
||||
{
|
||||
keymap_stat_set(keymap_stat & stat);
|
||||
}
|
||||
void keymap_xor(uint16_t stat)
|
||||
{
|
||||
keymap_stat_set(keymap_stat ^ stat);
|
||||
}
|
||||
|
||||
void keymap_debug(void)
|
||||
{
|
||||
debug_hex16(keymap_stat); debug("("); debug_dec(keymap_get_layer()); debug(")");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Overlay Layer (16-31 = 0-15|0x10)
|
||||
*/
|
||||
uint16_t overlay_stat = 0;
|
||||
|
||||
/* return highest layer whose state is on */
|
||||
uint8_t overlay_get_layer(void)
|
||||
{
|
||||
return biton16(overlay_stat);
|
||||
}
|
||||
|
||||
static void overlay_stat_set(uint16_t stat)
|
||||
{
|
||||
debug("overlay: ");
|
||||
overlay_debug(); debug(" to ");
|
||||
|
||||
overlay_stat = stat;
|
||||
|
||||
overlay_debug(); debug("\n");
|
||||
|
||||
clear_keyboard_but_mods(); // To avoid stuck keys
|
||||
}
|
||||
|
||||
void overlay_clear(void)
|
||||
{
|
||||
overlay_stat_set(0);
|
||||
}
|
||||
|
||||
|
||||
void overlay_set(uint16_t stat)
|
||||
{
|
||||
overlay_stat_set(stat);
|
||||
}
|
||||
|
||||
void overlay_move(uint8_t layer)
|
||||
{
|
||||
overlay_stat_set(1<<layer);
|
||||
}
|
||||
|
||||
void overlay_on(uint8_t layer)
|
||||
{
|
||||
overlay_stat_set(overlay_stat | (1<<layer));
|
||||
}
|
||||
|
||||
void overlay_off(uint8_t layer)
|
||||
{
|
||||
overlay_stat_set(overlay_stat & ~(1<<layer));
|
||||
}
|
||||
|
||||
void overlay_invert(uint8_t layer)
|
||||
{
|
||||
overlay_stat_set(overlay_stat ^ (1<<layer));
|
||||
}
|
||||
|
||||
void overlay_or(uint16_t stat)
|
||||
{
|
||||
overlay_stat_set(overlay_stat | stat);
|
||||
}
|
||||
void overlay_and(uint16_t stat)
|
||||
{
|
||||
overlay_stat_set(overlay_stat & stat);
|
||||
}
|
||||
void overlay_xor(uint16_t stat)
|
||||
{
|
||||
overlay_stat_set(overlay_stat ^ stat);
|
||||
}
|
||||
|
||||
void overlay_debug(void)
|
||||
{
|
||||
debug_hex16(overlay_stat); debug("("); debug_dec(overlay_get_layer()); debug(")");
|
||||
}
|
||||
|
||||
action_t layer_switch_get_action(key_t key)
|
||||
{
|
||||
action_t action;
|
||||
action.code = ACTION_TRANSPARENT;
|
||||
|
||||
/* overlay: top layer first */
|
||||
for (int8_t i = 15; i >= 0; i--) {
|
||||
if (overlay_stat & (1<<i)) {
|
||||
action = action_for_key(i | OVERLAY_BIT, key);
|
||||
if (action.code != ACTION_TRANSPARENT) {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* keymap: top layer first */
|
||||
for (int8_t i = 15; i >= 0; i--) {
|
||||
if (keymap_stat & (1<<i)) {
|
||||
action = action_for_key(i, key);
|
||||
if (action.code != ACTION_TRANSPARENT) {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* default layer */
|
||||
action = action_for_key(default_layer, key);
|
||||
return action;
|
||||
}
|
80
common/layer_switch.h
Normal file
80
common/layer_switch.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
Copyright 2013 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef LAYER_SWITCH_H
|
||||
#define LAYER_SWITCH_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "keyboard.h"
|
||||
#include "action.h"
|
||||
|
||||
|
||||
/* overlays are asigned at layer 16-31 */
|
||||
#define OVERLAY_BIT 0x10
|
||||
#define OVERLAY_MASK 0x0F
|
||||
|
||||
|
||||
/*
|
||||
* Default Layer
|
||||
*/
|
||||
/* base layer to fall back */
|
||||
extern uint8_t default_layer;
|
||||
void default_layer_set(uint8_t layer);
|
||||
|
||||
|
||||
/*
|
||||
* Keymap Layer
|
||||
*/
|
||||
extern uint16_t keymap_stat;
|
||||
/* return current active layer */
|
||||
uint8_t keymap_get_layer(void);
|
||||
void keymap_clear(void);
|
||||
void keymap_set(uint16_t stat);
|
||||
void keymap_move(uint8_t layer);
|
||||
void keymap_on(uint8_t layer);
|
||||
void keymap_off(uint8_t layer);
|
||||
void keymap_invert(uint8_t layer);
|
||||
/* bitwise operation */
|
||||
void keymap_or(uint16_t stat);
|
||||
void keymap_and(uint16_t stat);
|
||||
void keymap_xor(uint16_t stat);
|
||||
void keymap_debug(void);
|
||||
|
||||
|
||||
/*
|
||||
* Overlay Layer
|
||||
*/
|
||||
extern uint16_t overlay_stat;
|
||||
/* return current active layer */
|
||||
uint8_t overlay_get_layer(void);
|
||||
void overlay_clear(void);
|
||||
void overlay_set(uint16_t stat);
|
||||
void overlay_move(uint8_t layer);
|
||||
void overlay_on(uint8_t layer);
|
||||
void overlay_off(uint8_t layer);
|
||||
void overlay_invert(uint8_t layer);
|
||||
/* bitwise operation */
|
||||
void overlay_or(uint16_t stat);
|
||||
void overlay_and(uint16_t stat);
|
||||
void overlay_xor(uint16_t stat);
|
||||
void overlay_debug(void);
|
||||
|
||||
|
||||
|
||||
/* return action depending on current layer status */
|
||||
action_t layer_switch_get_action(key_t key);
|
||||
|
||||
#endif
|
|
@ -39,6 +39,7 @@ uint8_t bitpop16(uint16_t bits)
|
|||
}
|
||||
|
||||
// most significant on-bit - return highest location of on-bit
|
||||
// NOTE: return 0 when bit0 is on or all bits are off
|
||||
uint8_t biton(uint8_t bits)
|
||||
{
|
||||
uint8_t n = 0;
|
||||
|
@ -47,3 +48,13 @@ uint8_t biton(uint8_t bits)
|
|||
if (bits >> 1) { bits >>= 1; n += 1;}
|
||||
return n;
|
||||
}
|
||||
|
||||
uint8_t biton16(uint16_t bits)
|
||||
{
|
||||
uint8_t n = 0;
|
||||
if (bits >> 8) { bits >>= 8; n += 8;}
|
||||
if (bits >> 4) { bits >>= 4; n += 4;}
|
||||
if (bits >> 2) { bits >>= 2; n += 2;}
|
||||
if (bits >> 1) { bits >>= 1; n += 1;}
|
||||
return n;
|
||||
}
|
||||
|
|
|
@ -31,5 +31,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
uint8_t bitpop(uint8_t bits);
|
||||
uint8_t bitpop16(uint16_t bits);
|
||||
uint8_t biton(uint8_t bits);
|
||||
uint8_t biton16(uint16_t bits);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue