1
0
Fork 0

Merge branch 'overlays'

This commit is contained in:
tmk 2013-03-05 15:45:15 +09:00
commit 38bbe976e0
51 changed files with 2871 additions and 958 deletions

View file

@ -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;

View file

@ -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 */

View file

@ -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:

View file

@ -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;

View file

@ -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();
}

View file

@ -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)
{
}

View file

@ -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
View 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
View 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

View file

@ -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;
}

View file

@ -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