From b7a81f041906c3c978a314987e486536be0a58cd Mon Sep 17 00:00:00 2001 From: Didier Loiseau Date: Tue, 8 Mar 2016 23:14:15 +0100 Subject: Fix #156: clear weak mods on every key press - new macro_mods bit field for mods applied by macros - weak_mods now only used for ACT_{L,R}MODS (i.e. LSFT, RSFT, LCTL etc.) - clear the _weak_ mods on every key *pressed* such that LSFT etc. can no more interfere with the next key --- tmk_core/common/action_util.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tmk_core/common/action_util.c') diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c index f81877dd9f..a2d6577b24 100644 --- a/tmk_core/common/action_util.c +++ b/tmk_core/common/action_util.c @@ -29,6 +29,7 @@ static inline void del_key_bit(uint8_t code); static uint8_t real_mods = 0; static uint8_t weak_mods = 0; +static uint8_t macro_mods = 0; #ifdef USB_6KRO_ENABLE #define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS) @@ -55,6 +56,7 @@ static int16_t oneshot_time = 0; void send_keyboard_report(void) { keyboard_report->mods = real_mods; keyboard_report->mods |= weak_mods; + keyboard_report->mods |= macro_mods; #ifndef NO_ACTION_ONESHOT if (oneshot_mods) { #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) @@ -118,6 +120,13 @@ void del_weak_mods(uint8_t mods) { weak_mods &= ~mods; } void set_weak_mods(uint8_t mods) { weak_mods = mods; } void clear_weak_mods(void) { weak_mods = 0; } +/* macro modifier */ +uint8_t get_macro_mods(void) { return macro_mods; } +void add_macro_mods(uint8_t mods) { macro_mods |= mods; } +void del_macro_mods(uint8_t mods) { macro_mods &= ~mods; } +void set_macro_mods(uint8_t mods) { macro_mods = mods; } +void clear_macro_mods(void) { macro_mods = 0; } + /* Oneshot modifier */ #ifndef NO_ACTION_ONESHOT void set_oneshot_mods(uint8_t mods) -- cgit v1.2.3 From 74e97eefd7ae76f9ddcb76890a30aa9038804cdb Mon Sep 17 00:00:00 2001 From: Thiago Alves Date: Thu, 5 May 2016 18:41:37 -0700 Subject: Adds oneshot layer and oneshot tap toggling (#308) This commit is mostly a cherry-pick from `ahtn` at https://github.com/tmk/tmk_keyboard/pull/255. These are the changes: * Adds ACTION_LAYER_ONESHOT * Adds ONESHOT_TAP_TOGGLE * Mentions sticky keys in the docs on oneshot. --- tmk_core/common/action.c | 97 +++++++++++++++++++++++++++++++++++++++---- tmk_core/common/action_code.h | 5 ++- tmk_core/common/action_util.c | 70 +++++++++++++++++++++++++++++-- tmk_core/common/action_util.h | 20 +++++++++ tmk_core/doc/keymap.md | 8 +++- 5 files changed, 186 insertions(+), 14 deletions(-) (limited to 'tmk_core/common/action_util.c') diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index f9e6c17dc3..081e90b2db 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c @@ -74,6 +74,7 @@ void process_action_kb(keyrecord_t *record) {} void process_action(keyrecord_t *record) { + bool do_release_oneshot = false; keyevent_t event = record->event; #ifndef NO_ACTION_TAPPING uint8_t tap_count = record->tap.count; @@ -81,6 +82,13 @@ void process_action(keyrecord_t *record) if (IS_NOEVENT(event)) { return; } +#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 + process_action_kb(record); action_t action = store_or_get_action(event.pressed, event.key); @@ -95,6 +103,15 @@ void process_action(keyrecord_t *record) // 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: @@ -139,24 +156,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); } @@ -309,6 +339,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) { @@ -372,6 +440,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_action(record); + layer_off(get_oneshot_layer()); + } +#endif } @@ -560,6 +640,7 @@ 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; diff --git a/tmk_core/common/action_code.h b/tmk_core/common/action_code.h index 2b0b0b077e..ca729aaece 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 . * 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) * * @@ -250,6 +251,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 +268,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)) diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c index a2d6577b24..61ff202bef 100644 --- a/tmk_core/common/action_util.c +++ b/tmk_core/common/action_util.c @@ -18,6 +18,7 @@ along with this program. If not, see . #include "report.h" #include "debug.h" #include "action_util.h" +#include "action_layer.h" #include "timer.h" static inline void add_key_byte(uint8_t code); @@ -47,11 +48,70 @@ report_keyboard_t *keyboard_report = &(report_keyboard_t){}; #ifndef NO_ACTION_ONESHOT static int8_t oneshot_mods = 0; +static int8_t oneshot_locked_mods = 0; +int8_t get_oneshot_locked_mods(void) { return oneshot_locked_mods; } +void set_oneshot_locked_mods(int8_t mods) { oneshot_locked_mods = mods; } +void clear_oneshot_locked_mods(void) { oneshot_locked_mods = 0; } #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) static int16_t oneshot_time = 0; +inline bool has_oneshot_mods_timed_out() { + return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT; +} #endif #endif +/* oneshot layer */ +#ifndef NO_ACTION_ONESHOT +/* oneshot_layer_data bits +* LLLL LSSS +* where: +* L => are layer bits +* S => oneshot state bits +*/ +static int8_t oneshot_layer_data = 0; + +inline uint8_t get_oneshot_layer(void) { return oneshot_layer_data >> 3; } +inline uint8_t get_oneshot_layer_state(void) { return oneshot_layer_data & 0b111; } + +#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) +static int16_t oneshot_layer_time = 0; +inline bool has_oneshot_layer_timed_out() { + return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT && + !(get_oneshot_layer_state() & ONESHOT_TOGGLED); +} +#endif + +/* Oneshot layer */ +void set_oneshot_layer(uint8_t layer, uint8_t state) +{ + oneshot_layer_data = layer << 3 | state; + layer_on(layer); +#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) + oneshot_layer_time = timer_read(); +#endif +} +void reset_oneshot_layer(void) { + oneshot_layer_data = 0; +#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) + oneshot_layer_time = 0; +#endif +} +void clear_oneshot_layer_state(oneshot_fullfillment_t state) +{ + uint8_t start_state = oneshot_layer_data; + oneshot_layer_data &= ~state; + if (!get_oneshot_layer_state() && start_state != oneshot_layer_data) { + layer_off(get_oneshot_layer()); +#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) + oneshot_layer_time = 0; +#endif + } +} +bool is_oneshot_layer_active(void) +{ + return get_oneshot_layer_state(); +} +#endif void send_keyboard_report(void) { keyboard_report->mods = real_mods; @@ -60,7 +120,7 @@ void send_keyboard_report(void) { #ifndef NO_ACTION_ONESHOT if (oneshot_mods) { #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) - if (TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT) { + if (has_oneshot_mods_timed_out()) { dprintf("Oneshot: timeout\n"); clear_oneshot_mods(); } @@ -70,6 +130,7 @@ void send_keyboard_report(void) { clear_oneshot_mods(); } } + #endif host_keyboard_send(keyboard_report); } @@ -143,11 +204,12 @@ void clear_oneshot_mods(void) oneshot_time = 0; #endif } +uint8_t get_oneshot_mods(void) +{ + return oneshot_mods; +} #endif - - - /* * inspect keyboard state */ diff --git a/tmk_core/common/action_util.h b/tmk_core/common/action_util.h index 1a95cec10e..dd0c4c2bfe 100644 --- a/tmk_core/common/action_util.h +++ b/tmk_core/common/action_util.h @@ -56,10 +56,30 @@ void clear_macro_mods(void); /* oneshot modifier */ void set_oneshot_mods(uint8_t mods); +uint8_t get_oneshot_mods(void); void clear_oneshot_mods(void); void oneshot_toggle(void); void oneshot_enable(void); void oneshot_disable(void); +bool has_oneshot_mods_timed_out(void); + +int8_t get_oneshot_locked_mods(void); +void set_oneshot_locked_mods(int8_t mods); +void clear_oneshot_locked_mods(void); + +typedef enum { + ONESHOT_PRESSED = 0b01, + ONESHOT_OTHER_KEY_PRESSED = 0b10, + ONESHOT_START = 0b11, + ONESHOT_TOGGLED = 0b100 +} oneshot_fullfillment_t; +void set_oneshot_layer(uint8_t layer, uint8_t state); +uint8_t get_oneshot_layer(void); +void clear_oneshot_layer_state(oneshot_fullfillment_t state); +void reset_oneshot_layer(void); +bool is_oneshot_layer_active(void); +uint8_t get_oneshot_layer_state(void); +bool has_oneshot_layer_timed_out(void); /* inspect */ uint8_t has_anykey(void); diff --git a/tmk_core/doc/keymap.md b/tmk_core/doc/keymap.md index d4a129b208..4d42fbe5cb 100644 --- a/tmk_core/doc/keymap.md +++ b/tmk_core/doc/keymap.md @@ -528,14 +528,20 @@ This is a feature to assign both toggle layer and momentary switch layer action ### 4.3 Oneshot Modifier -This runs onetime effects which modify only on just one following key. It works as normal modifier key when holding down while oneshot modifier when tapping. +This runs onetime effects which modify only on just one following key. It works as normal modifier key when holding down while oneshot modifier when tapping. The behavior of oneshot modifiers is similar to the [sticky keys](https://en.wikipedia.org/wiki/StickyKeys) functionality found in most operating systems. ACTION_MODS_ONESHOT(MOD_LSFT) +Oneshot layer key: + + ACTION_LAYER_ONESHOT(MY_LAYER) + Say you want to type 'The', you have to push and hold Shift key before type 't' then release it before type 'h' and 'e', otherwise you'll get 'THe' or 'the' unintentionally. With Oneshot Modifier you can tap Shift then type 't', 'h' and 'e' normally, you don't need to holding Shift key properly here. This mean you can release Shift before 't' is pressed down. Oneshot effect is cancel unless following key is pressed down within `ONESHOT_TIMEOUT` of `config.h`. No timeout when it is `0` or not defined. +Most implementations of sticky keys allow you to lock a modifier by double tapping the modifier. The layer then remains locked untill the modifier is tapped again. To enable this behaviour for oneshot modifiers set `ONESHOT_TAP_TOGGLE` to the number taps required. The feature is disabled if `ONESHOT_TAP_TOGGLE<2` or not defined. + ### 4.4 Tap Toggle Mods Similar to layer tap toggle, this works as a momentary modifier when holding, but toggles on with several taps. A single tap will 'unstick' the modifier again. -- cgit v1.2.3 From 558f3ec1eb325caf706efc15e2fab26121aba442 Mon Sep 17 00:00:00 2001 From: IBNobody Date: Tue, 6 Sep 2016 23:19:01 -0500 Subject: Use keyboard config for nkro (#7) * removing nkro references - wip * changed NKRO to be defined by keymap_config --- keyboards/planck/keymaps/pvc/Makefile | 4 +- keyboards/planck/keymaps/pvc/keymap.c | 5 +- quantum/keycode_config.h | 5 ++ quantum/keymap.h | 1 + quantum/quantum.c | 124 +++++++++++++++++++--------------- tmk_core/common/action_util.c | 10 ++- tmk_core/common/bootmagic.c | 4 -- tmk_core/common/command.c | 6 +- tmk_core/common/host.c | 5 -- tmk_core/common/host.h | 4 -- tmk_core/common/keyboard.c | 4 +- tmk_core/common/magic.c | 4 -- tmk_core/protocol/chibios/usb_main.c | 19 +++--- tmk_core/protocol/lufa/lufa.c | 9 ++- tmk_core/protocol/pjrc/usb.c | 18 +++-- tmk_core/protocol/pjrc/usb_keyboard.c | 8 ++- tmk_core/readme.md | 2 +- 17 files changed, 131 insertions(+), 101 deletions(-) (limited to 'tmk_core/common/action_util.c') diff --git a/keyboards/planck/keymaps/pvc/Makefile b/keyboards/planck/keymaps/pvc/Makefile index 0b2f060de4..19c3abc6c6 100644 --- a/keyboards/planck/keymaps/pvc/Makefile +++ b/keyboards/planck/keymaps/pvc/Makefile @@ -1,9 +1,9 @@ # Build Options -# change to "no" to disable the options, or define them in the Makefile in +# change to "no" to disable the options, or define them in the Makefile in # the appropriate keymap folder that will get included automatically # -BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) +BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) MOUSEKEY_ENABLE = yes # Mouse keys(+4700) EXTRAKEY_ENABLE = yes # Audio control and System control(+450) CONSOLE_ENABLE = no # Console for debug(+400) diff --git a/keyboards/planck/keymaps/pvc/keymap.c b/keyboards/planck/keymaps/pvc/keymap.c index 8ff40f377c..23aedfc998 100644 --- a/keyboards/planck/keymaps/pvc/keymap.c +++ b/keyboards/planck/keymaps/pvc/keymap.c @@ -83,6 +83,7 @@ enum keyboard_macros { #define SC_ACLS LALT(KC_F4) #define SC_CCLS LCTL(KC_F4) +#define TG_NKRO MAGIC_TOGGLE_NKRO #define OS_SHFT KC_FN0 #define _______ KC_TRNS @@ -206,7 +207,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [LAYER_ADJUST] = { { XXXXXXX, M_BRTOG, M_BSPDU, M_BSPDD, M_BDFLT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, MU_TOG , AU_TOG }, { XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX }, - { XXXXXXX, M_QWRTY, XXXXXXX, XXXXXXX, M_BACKL, RESET , XXXXXXX, M_MOUSE, XXXXXXX, XXXXXXX, MUV_IN , XXXXXXX }, + { XXXXXXX, M_QWRTY, XXXXXXX, XXXXXXX, M_BACKL, RESET , TG_NKRO, M_MOUSE, XXXXXXX, XXXXXXX, MUV_IN , XXXXXXX }, { XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, M_UPPER, XXXXXXX, XXXXXXX, M_LOWER, XXXXXXX, TMPO_DN, MUV_DE , TMPO_UP } }, @@ -236,7 +237,7 @@ void persistant_default_layer_set(uint16_t default_layer) } const uint16_t PROGMEM fn_actions[] = { - [0] = ACTION_MODS_ONESHOT(MOD_LSFT), + [0] = ACTION_MODS_ONESHOT(MOD_RSFT), }; const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) diff --git a/quantum/keycode_config.h b/quantum/keycode_config.h index 6216eefc90..c15b0d32f8 100644 --- a/quantum/keycode_config.h +++ b/quantum/keycode_config.h @@ -1,6 +1,9 @@ #include "eeconfig.h" #include "keycode.h" +#ifndef KEYCODE_CONFIG_H +#define KEYCODE_CONFIG_H + uint16_t keycode_config(uint16_t keycode); /* NOTE: Not portable. Bit field order depends on implementation */ @@ -19,3 +22,5 @@ typedef union { } keymap_config_t; extern keymap_config_t keymap_config; + +#endif /* KEYCODE_CONFIG_H */ diff --git a/quantum/keymap.h b/quantum/keymap.h index f2d94d75c3..98ddfd0c53 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -111,6 +111,7 @@ enum quantum_keycodes { MAGIC_UNSWAP_BACKSLASH_BACKSPACE, MAGIC_UNHOST_NKRO, MAGIC_UNSWAP_ALT_GUI, + MAGIC_TOGGLE_NKRO, // Leader key #ifndef DISABLE_LEADER diff --git a/quantum/quantum.c b/quantum/quantum.c index fa86b6220f..a16bd5443c 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -27,10 +27,6 @@ static void do_code16 (uint16_t code, void (*f) (uint8_t)) { f(KC_RGUI); } -#ifdef NKRO_ENABLE - extern bool keyboard_nkro; -#endif - void register_code16 (uint16_t code) { do_code16 (code, register_code); register_code (code); @@ -203,7 +199,7 @@ bool process_record_quantum(keyrecord_t *record) { return false; break; #endif - case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_UNSWAP_ALT_GUI: + case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO: if (record->event.pressed) { // MAGIC actions (BOOTMAGIC without the boot) if (!eeconfig_is_enabled()) { @@ -211,57 +207,73 @@ bool process_record_quantum(keyrecord_t *record) { } /* keymap config */ keymap_config.raw = eeconfig_read_keymap(); - if (keycode == MAGIC_SWAP_CONTROL_CAPSLOCK) { - keymap_config.swap_control_capslock = 1; - } else if (keycode == MAGIC_CAPSLOCK_TO_CONTROL) { - keymap_config.capslock_to_control = 1; - } else if (keycode == MAGIC_SWAP_LALT_LGUI) { - keymap_config.swap_lalt_lgui = 1; - } else if (keycode == MAGIC_SWAP_RALT_RGUI) { - keymap_config.swap_ralt_rgui = 1; - } else if (keycode == MAGIC_NO_GUI) { - keymap_config.no_gui = 1; - } else if (keycode == MAGIC_SWAP_GRAVE_ESC) { - keymap_config.swap_grave_esc = 1; - } else if (keycode == MAGIC_SWAP_BACKSLASH_BACKSPACE) { - keymap_config.swap_backslash_backspace = 1; - } else if (keycode == MAGIC_HOST_NKRO) { - keymap_config.nkro = 1; - -#ifdef NKRO_ENABLE - clear_keyboard(); // clear to prevent stuck keys - keyboard_nkro = keymap_config.nkro; -#endif - } else if (keycode == MAGIC_SWAP_ALT_GUI) { - keymap_config.swap_lalt_lgui = 1; - keymap_config.swap_ralt_rgui = 1; - } - /* UNs */ - else if (keycode == MAGIC_UNSWAP_CONTROL_CAPSLOCK) { - keymap_config.swap_control_capslock = 0; - } else if (keycode == MAGIC_UNCAPSLOCK_TO_CONTROL) { - keymap_config.capslock_to_control = 0; - } else if (keycode == MAGIC_UNSWAP_LALT_LGUI) { - keymap_config.swap_lalt_lgui = 0; - } else if (keycode == MAGIC_UNSWAP_RALT_RGUI) { - keymap_config.swap_ralt_rgui = 0; - } else if (keycode == MAGIC_UNNO_GUI) { - keymap_config.no_gui = 0; - } else if (keycode == MAGIC_UNSWAP_GRAVE_ESC) { - keymap_config.swap_grave_esc = 0; - } else if (keycode == MAGIC_UNSWAP_BACKSLASH_BACKSPACE) { - keymap_config.swap_backslash_backspace = 0; - } else if (keycode == MAGIC_UNHOST_NKRO) { - keymap_config.nkro = 0; -#ifdef NKRO_ENABLE - clear_keyboard(); // clear to prevent stuck keys - keyboard_nkro = keymap_config.nkro; -#endif - } else if (keycode == MAGIC_UNSWAP_ALT_GUI) { - keymap_config.swap_lalt_lgui = 0; - keymap_config.swap_ralt_rgui = 0; + switch (keycode) + { + case MAGIC_SWAP_CONTROL_CAPSLOCK: + keymap_config.swap_control_capslock = true; + break; + case MAGIC_CAPSLOCK_TO_CONTROL: + keymap_config.capslock_to_control = true; + break; + case MAGIC_SWAP_LALT_LGUI: + keymap_config.swap_lalt_lgui = true; + break; + case MAGIC_SWAP_RALT_RGUI: + keymap_config.swap_ralt_rgui = true; + break; + case MAGIC_NO_GUI: + keymap_config.no_gui = true; + break; + case MAGIC_SWAP_GRAVE_ESC: + keymap_config.swap_grave_esc = true; + break; + case MAGIC_SWAP_BACKSLASH_BACKSPACE: + keymap_config.swap_backslash_backspace = true; + break; + case MAGIC_HOST_NKRO: + keymap_config.nkro = true; + break; + case MAGIC_SWAP_ALT_GUI: + keymap_config.swap_lalt_lgui = true; + keymap_config.swap_ralt_rgui = true; + break; + case MAGIC_UNSWAP_CONTROL_CAPSLOCK: + keymap_config.swap_control_capslock = false; + break; + case MAGIC_UNCAPSLOCK_TO_CONTROL: + keymap_config.capslock_to_control = false; + break; + case MAGIC_UNSWAP_LALT_LGUI: + keymap_config.swap_lalt_lgui = false; + break; + case MAGIC_UNSWAP_RALT_RGUI: + keymap_config.swap_ralt_rgui = false; + break; + case MAGIC_UNNO_GUI: + keymap_config.no_gui = false; + break; + case MAGIC_UNSWAP_GRAVE_ESC: + keymap_config.swap_grave_esc = false; + break; + case MAGIC_UNSWAP_BACKSLASH_BACKSPACE: + keymap_config.swap_backslash_backspace = false; + break; + case MAGIC_UNHOST_NKRO: + keymap_config.nkro = false; + break; + case MAGIC_UNSWAP_ALT_GUI: + keymap_config.swap_lalt_lgui = false; + keymap_config.swap_ralt_rgui = false; + break; + case MAGIC_TOGGLE_NKRO: + keymap_config.nkro = !keymap_config.nkro; + break; + default: + break; } eeconfig_update_keymap(keymap_config.raw); + clear_keyboard(); // clear to prevent stuck keys + return false; } break; @@ -284,7 +296,7 @@ bool process_record_quantum(keyrecord_t *record) { unregister_mods(MOD_BIT(KC_LSFT)); } return false; - break; + // break; } case KC_RSPC: { @@ -306,7 +318,7 @@ bool process_record_quantum(keyrecord_t *record) { unregister_mods(MOD_BIT(KC_RSFT)); } return false; - break; + // break; } default: { shift_interrupted[0] = true; diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c index 61ff202bef..cb4b252648 100644 --- a/tmk_core/common/action_util.c +++ b/tmk_core/common/action_util.c @@ -20,6 +20,10 @@ along with this program. If not, see . #include "action_util.h" #include "action_layer.h" #include "timer.h" +#include "keycode_config.h" + +extern keymap_config_t keymap_config; + static inline void add_key_byte(uint8_t code); static inline void del_key_byte(uint8_t code); @@ -139,7 +143,7 @@ void send_keyboard_report(void) { void add_key(uint8_t key) { #ifdef NKRO_ENABLE - if (keyboard_protocol && keyboard_nkro) { + if (keyboard_protocol && keymap_config.nkro) { add_key_bit(key); return; } @@ -150,7 +154,7 @@ void add_key(uint8_t key) void del_key(uint8_t key) { #ifdef NKRO_ENABLE - if (keyboard_protocol && keyboard_nkro) { + if (keyboard_protocol && keymap_config.nkro) { del_key_bit(key); return; } @@ -231,7 +235,7 @@ uint8_t has_anymod(void) uint8_t get_first_key(void) { #ifdef NKRO_ENABLE - if (keyboard_protocol && keyboard_nkro) { + if (keyboard_protocol && keymap_config.nkro) { uint8_t i = 0; for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++) ; diff --git a/tmk_core/common/bootmagic.c b/tmk_core/common/bootmagic.c index 6730a2a4aa..2c6bcbae56 100644 --- a/tmk_core/common/bootmagic.c +++ b/tmk_core/common/bootmagic.c @@ -83,10 +83,6 @@ void bootmagic(void) } eeconfig_update_keymap(keymap_config.raw); -#ifdef NKRO_ENABLE - keyboard_nkro = keymap_config.nkro; -#endif - /* default layer */ uint8_t default_layer = 0; if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_0)) { default_layer |= (1<<0); } diff --git a/tmk_core/common/command.c b/tmk_core/common/command.c index 476fc6fe3c..54d6117fd1 100644 --- a/tmk_core/common/command.c +++ b/tmk_core/common/command.c @@ -238,7 +238,7 @@ static void print_status(void) print_val_hex8(keyboard_protocol); print_val_hex8(keyboard_idle); #ifdef NKRO_ENABLE - print_val_hex8(keyboard_nkro); + print_val_hex8(keymap_config.nkro); #endif print_val_hex32(timer_read32()); @@ -435,8 +435,8 @@ static bool command_common(uint8_t code) // NKRO toggle case MAGIC_KC(MAGIC_KEY_NKRO): clear_keyboard(); // clear to prevent stuck keys - keyboard_nkro = !keyboard_nkro; - if (keyboard_nkro) { + keymap_config.nkro = !keymap_config.nkro; + if (keymap_config.nkro) { print("NKRO: on\n"); } else { print("NKRO: off\n"); diff --git a/tmk_core/common/host.c b/tmk_core/common/host.c index 11a05c2ddd..e12b622165 100644 --- a/tmk_core/common/host.c +++ b/tmk_core/common/host.c @@ -22,11 +22,6 @@ along with this program. If not, see . #include "util.h" #include "debug.h" - -#ifdef NKRO_ENABLE -bool keyboard_nkro = true; -#endif - static host_driver_t *driver; static uint16_t last_system_report = 0; static uint16_t last_consumer_report = 0; diff --git a/tmk_core/common/host.h b/tmk_core/common/host.h index 9814b10d2d..aeabba7107 100644 --- a/tmk_core/common/host.h +++ b/tmk_core/common/host.h @@ -28,10 +28,6 @@ along with this program. If not, see . extern "C" { #endif -#ifdef NKRO_ENABLE -extern bool keyboard_nkro; -#endif - extern uint8_t keyboard_idle; extern uint8_t keyboard_protocol; diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index c46a701b3b..371d93f3e5 100644 --- a/tmk_core/common/keyboard.c +++ b/tmk_core/common/keyboard.c @@ -57,6 +57,8 @@ along with this program. If not, see . # include "visualizer/visualizer.h" #endif + + #ifdef MATRIX_HAS_GHOST static bool has_ghost_in_row(uint8_t row) { @@ -106,7 +108,7 @@ void keyboard_init(void) { rgblight_init(); #endif #if defined(NKRO_ENABLE) && defined(FORCE_NKRO) - keyboard_nkro = true; + keymap_config.nkro = 1; #endif } diff --git a/tmk_core/common/magic.c b/tmk_core/common/magic.c index 194e4cc026..49617a3d10 100644 --- a/tmk_core/common/magic.c +++ b/tmk_core/common/magic.c @@ -27,10 +27,6 @@ void magic(void) /* keymap config */ keymap_config.raw = eeconfig_read_keymap(); -#ifdef NKRO_ENABLE - keyboard_nkro = keymap_config.nkro; -#endif - uint8_t default_layer = 0; default_layer = eeconfig_read_default_layer(); default_layer_set((uint32_t)default_layer); diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index e2c9d9bf14..d0c72c46c7 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c @@ -28,6 +28,12 @@ #include "led.h" #endif +#ifdef NKRO_ENABLE + #include "keycode_config.h" + + extern keymap_config_t keymap_config; +#endif + /* --------------------------------------------------------- * Global interface variables and declarations * --------------------------------------------------------- @@ -39,9 +45,6 @@ uint16_t keyboard_led_stats __attribute__((aligned(2))) = 0; volatile uint16_t keyboard_idle_count = 0; static virtual_timer_t keyboard_idle_timer; static void keyboard_idle_timer_cb(void *arg); -#ifdef NKRO_ENABLE -extern bool keyboard_nkro; -#endif /* NKRO_ENABLE */ report_keyboard_t keyboard_report_sent = {{0}}; #ifdef MOUSE_ENABLE @@ -943,8 +946,8 @@ static bool usb_request_hook_cb(USBDriver *usbp) { if((usbp->setup[4] == KBD_INTERFACE) && (usbp->setup[5] == 0)) { /* wIndex */ keyboard_protocol = ((usbp->setup[2]) != 0x00); /* LSB(wValue) */ #ifdef NKRO_ENABLE - keyboard_nkro = !!keyboard_protocol; - if(!keyboard_nkro && keyboard_idle) { + keymap_config.nkro = !!keyboard_protocol; + if(!keymap_config.nkro && keyboard_idle) { #else /* NKRO_ENABLE */ if(keyboard_idle) { #endif /* NKRO_ENABLE */ @@ -962,7 +965,7 @@ static bool usb_request_hook_cb(USBDriver *usbp) { keyboard_idle = usbp->setup[3]; /* MSB(wValue) */ /* arm the timer */ #ifdef NKRO_ENABLE - if(!keyboard_nkro && keyboard_idle) { + if(!keymap_config.nkro && keyboard_idle) { #else /* NKRO_ENABLE */ if(keyboard_idle) { #endif /* NKRO_ENABLE */ @@ -1089,7 +1092,7 @@ static void keyboard_idle_timer_cb(void *arg) { } #ifdef NKRO_ENABLE - if(!keyboard_nkro && keyboard_idle) { + if(!keymap_config.nkro && keyboard_idle) { #else /* NKRO_ENABLE */ if(keyboard_idle) { #endif /* NKRO_ENABLE */ @@ -1122,7 +1125,7 @@ void send_keyboard(report_keyboard_t *report) { osalSysUnlock(); #ifdef NKRO_ENABLE - if(keyboard_nkro) { /* NKRO protocol */ + if(keymap_config.nkro) { /* NKRO protocol */ /* need to wait until the previous packet has made it through */ /* can rewrite this using the synchronous API, then would wait * until *after* the packet has been transmitted. I think diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 9b201374a2..01c0e45b0b 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -52,6 +52,13 @@ #include "descriptor.h" #include "lufa.h" +#ifdef NKRO_ENABLE + #include "keycode_config.h" + + extern keymap_config_t keymap_config; +#endif + + #ifdef AUDIO_ENABLE #include #endif @@ -502,7 +509,7 @@ static void send_keyboard(report_keyboard_t *report) /* Select the Keyboard Report Endpoint */ #ifdef NKRO_ENABLE - if (keyboard_protocol && keyboard_nkro) { + if (keyboard_protocol && keymap_config.nkro) { /* Report protocol - NKRO */ Endpoint_SelectEndpoint(NKRO_IN_EPNUM); diff --git a/tmk_core/protocol/pjrc/usb.c b/tmk_core/protocol/pjrc/usb.c index 1e6ba8719a..09efbe0762 100644 --- a/tmk_core/protocol/pjrc/usb.c +++ b/tmk_core/protocol/pjrc/usb.c @@ -1,17 +1,17 @@ /* USB Keyboard Plus Debug Channel Example for Teensy USB Development Board * http://www.pjrc.com/teensy/usb_keyboard.html * Copyright (c) 2009 PJRC.COM, LLC - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -41,6 +41,12 @@ #include "action.h" #include "action_util.h" +#ifdef NKRO_ENABLE + #include "keycode_config.h" + + extern keymap_config_t keymap_config; +#endif + /************************************************************************** * @@ -694,7 +700,7 @@ ISR(USB_GEN_vect) } /* TODO: should keep IDLE rate on each keyboard interface */ #ifdef NKRO_ENABLE - if (!keyboard_nkro && keyboard_idle && (++div4 & 3) == 0) { + if (!keymap_config.nkro && keyboard_idle && (++div4 & 3) == 0) { #else if (keyboard_idle && (++div4 & 3) == 0) { #endif @@ -881,7 +887,7 @@ ISR(USB_COM_vect) #endif if (bmRequestType == 0x00 && wValue == DEVICE_REMOTE_WAKEUP) { if (bRequest == SET_FEATURE) { - remote_wakeup = true; + remote_wakeup = true; } else { remote_wakeup = false; } @@ -932,7 +938,7 @@ ISR(USB_COM_vect) if (bRequest == HID_SET_PROTOCOL) { keyboard_protocol = wValue; #ifdef NKRO_ENABLE - keyboard_nkro = !!keyboard_protocol; + keymap_config.nkro = !!keyboard_protocol; #endif clear_keyboard(); //usb_wait_in_ready(); diff --git a/tmk_core/protocol/pjrc/usb_keyboard.c b/tmk_core/protocol/pjrc/usb_keyboard.c index 4b87b5d7b5..05f4797340 100644 --- a/tmk_core/protocol/pjrc/usb_keyboard.c +++ b/tmk_core/protocol/pjrc/usb_keyboard.c @@ -30,6 +30,12 @@ #include "util.h" #include "host.h" +#ifdef NKRO_ENABLE + #include "keycode_config.h" + + extern keymap_config_t keymap_config; +#endif + // protocol setting from the host. We use exactly the same report // either way, so this variable only stores the setting since we @@ -56,7 +62,7 @@ int8_t usb_keyboard_send_report(report_keyboard_t *report) int8_t result = 0; #ifdef NKRO_ENABLE - if (keyboard_nkro) + if (keymap_config.nkro) result = send_report(report, KBD2_ENDPOINT, 0, KBD2_SIZE); else #endif diff --git a/tmk_core/readme.md b/tmk_core/readme.md index f460d0ed44..3242328516 100644 --- a/tmk_core/readme.md +++ b/tmk_core/readme.md @@ -23,7 +23,7 @@ These features can be used in your keyboard. * Mouse key - Mouse control with keyboard * System Control Key - Power Down, Sleep, Wake Up and USB Remote Wake up * Media Control Key - Volume Down/Up, Mute, Next/Prev track, Play, Stop and etc -* USB NKRO - 120 keys(+ 8 modifiers) simultaneously +* USB NKRO - 240 keys(+ 8 modifiers) simultaneously * PS/2 mouse support - PS/2 mouse(TrackPoint) as composite device * Keyboard protocols - PS/2, ADB, M0110, Sun and other old keyboard protocols * User Function - Customizable function of key with writing code -- cgit v1.2.3