From c745d9b82e3f2047feb97a7a8937f27c6e989fd7 Mon Sep 17 00:00:00 2001 From: XScorpion2 Date: Mon, 29 Apr 2019 22:21:46 -0500 Subject: Simple extended space cadet (#5277) * Simplifying and Extending Space Cadet to work on Ctrl and Alt keys * PR Review feedback * Reverting back to keycodes --- quantum/process_keycode/process_space_cadet.c | 146 ++++++++++++++++++++++++++ quantum/process_keycode/process_space_cadet.h | 21 ++++ 2 files changed, 167 insertions(+) create mode 100644 quantum/process_keycode/process_space_cadet.c create mode 100644 quantum/process_keycode/process_space_cadet.h (limited to 'quantum/process_keycode') diff --git a/quantum/process_keycode/process_space_cadet.c b/quantum/process_keycode/process_space_cadet.c new file mode 100644 index 0000000000..a9c506168d --- /dev/null +++ b/quantum/process_keycode/process_space_cadet.c @@ -0,0 +1,146 @@ +/* Copyright 2019 Jack Humbert + * + * 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 . + */ +#include "process_space_cadet.h" + +#ifndef TAPPING_TERM + #define TAPPING_TERM 200 +#endif + +// ********** OBSOLETE DEFINES, STOP USING! (pls?) ********** +// Shift / paren setup +#ifndef LSPO_KEY + #define LSPO_KEY KC_9 +#endif +#ifndef RSPC_KEY + #define RSPC_KEY KC_0 +#endif + +// Shift / Enter setup +#ifndef SFTENT_KEY + #define SFTENT_KEY KC_ENT +#endif + +#ifdef DISABLE_SPACE_CADET_MODIFIER + #ifndef LSPO_MOD + #define LSPO_MOD KC_TRNS + #endif + #ifndef RSPC_MOD + #define RSPC_MOD KC_TRNS + #endif +#else + #ifndef LSPO_MOD + #define LSPO_MOD KC_LSFT + #endif + #ifndef RSPC_MOD + #define RSPC_MOD KC_RSFT + #endif +#endif +// ********************************************************** + +// Shift / paren setup +#ifndef LSPO_KEYS + #define LSPO_KEYS KC_LSFT, LSPO_MOD, LSPO_KEY +#endif +#ifndef RSPC_KEYS + #define RSPC_KEYS KC_RSFT, RSPC_MOD, RSPC_KEY +#endif + +// Control / paren setup +#ifndef LCPO_KEYS + #define LCPO_KEYS KC_LCTL, KC_LCTL, KC_9 +#endif +#ifndef RCPO_KEYS + #define RCPO_KEYS KC_RCTL, KC_RCTL, KC_0 +#endif + +// Alt / paren setup +#ifndef LAPO_KEYS + #define LAPO_KEYS KC_LALT, KC_LALT, KC_9 +#endif +#ifndef RAPO_KEYS + #define RAPO_KEYS KC_RALT, KC_RALT, KC_0 +#endif + +// Shift / Enter setup +#ifndef SFTENT_KEYS + #define SFTENT_KEYS KC_RSFT, KC_TRNS, SFTENT_KEY +#endif + +static uint8_t sc_last = 0; +static uint16_t sc_timer = 0; + +void perform_space_cadet(keyrecord_t *record, uint8_t normalMod, uint8_t tapMod, uint8_t keycode) { + if (record->event.pressed) { + sc_last = normalMod; + sc_timer = timer_read (); + if (IS_MOD(normalMod)) { + register_mods(MOD_BIT(normalMod)); + } + } + else { + if (IS_MOD(normalMod)) { + unregister_mods(MOD_BIT(normalMod)); + } + + if (sc_last == normalMod && timer_elapsed(sc_timer) < TAPPING_TERM) { + if (IS_MOD(tapMod)) { + register_mods(MOD_BIT(tapMod)); + } + tap_code(keycode); + if (IS_MOD(tapMod)) { + unregister_mods(MOD_BIT(tapMod)); + } + } + } +} + +bool process_space_cadet(uint16_t keycode, keyrecord_t *record) { + switch(keycode) { + case KC_LSPO: { + perform_space_cadet(record, LSPO_KEYS); + return false; + } + case KC_RSPC: { + perform_space_cadet(record, RSPC_KEYS); + return false; + } + case KC_LCPO: { + perform_space_cadet(record, LCPO_KEYS); + return false; + } + case KC_RCPC: { + perform_space_cadet(record, RCPO_KEYS); + return false; + } + case KC_LAPO: { + perform_space_cadet(record, LAPO_KEYS); + return false; + } + case KC_RAPC: { + perform_space_cadet(record, RAPO_KEYS); + return false; + } + case KC_SFTENT: { + perform_space_cadet(record, SFTENT_KEYS); + return false; + } + default: { + sc_last = 0; + break; + } + } + return true; +} diff --git a/quantum/process_keycode/process_space_cadet.h b/quantum/process_keycode/process_space_cadet.h new file mode 100644 index 0000000000..3f08b8002a --- /dev/null +++ b/quantum/process_keycode/process_space_cadet.h @@ -0,0 +1,21 @@ +/* Copyright 2019 Jack Humbert + * + * 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 . + */ +#pragma once + +#include "quantum.h" + +void perform_space_cadet(keyrecord_t *record, uint8_t normalMod, uint8_t tapMod, uint8_t keycode); +bool process_space_cadet(uint16_t keycode, keyrecord_t *record); -- cgit v1.2.3 From bdc8d89e6b8f49528b716d9bd3343a4f9e9327bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20=C4=90or=C4=91evi=C4=87?= Date: Fri, 3 May 2019 18:33:00 +0200 Subject: New keycode macro (XP) for shifted character pairs using UNICODEMAP + bug fixes and improvements (#4803) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Expose unicode_saved_mods * Add UNICODEMAP shift pair functionality and XS keycode * Add XS to keycode reference documentation * Pick pair index based on both Shift and Caps Lock state * Add XS to Unicode feature docs * Clean up process_unicode* headers * Extract unicode_map index calculation into function * Pick pair index as XOR rather than OR of Shift and Caps states * unicode_input_start() has to be called before the unicode_map index is calculated * Replace unicodemap_input_error() with more generic unicode_input_cancel() * Replace register+tap+unregister with tap_code16(LCTL(LSFT(KC_U))) * UNICODE_OSX_KEY → UNICODE_KEY_OSX, UNICODE_WINC_KEY → UNICODE_KEY_WINC * Make keycode range checks more robust * Fix keycode range checks for different input modes * Add UNICODE_KEY_LNX, update docs * QK_UNICODEMAP_SHIFT → QK_UNICODEMAP_PAIR * XS → XP, update docs * Tweak Unicode docs * Use recently added MOD_MASK_SHIFT and IS_HOST_LED_ON helpers * Update Unicode table in docs/keycodes.md * Update Unicode docs per review comments * Replace references to Mac OS X with macOS in Unicode docs * As of v0.9.0, WinCompose supports all possible code points * Expand descriptions in XP docs * Update keycode table and cycling docs * Further expand cycling docs --- quantum/process_keycode/process_unicode.c | 6 ++-- quantum/process_keycode/process_unicode.h | 2 +- quantum/process_keycode/process_unicode_common.c | 38 ++++++++++++++++-------- quantum/process_keycode/process_unicode_common.h | 13 +++++--- quantum/process_keycode/process_unicodemap.c | 36 ++++++++++++++-------- quantum/process_keycode/process_unicodemap.h | 4 +-- 6 files changed, 64 insertions(+), 35 deletions(-) (limited to 'quantum/process_keycode') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index 19beb84520..2c914013ac 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -13,15 +13,15 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + #include "process_unicode.h" #include "action_util.h" #include "eeprom.h" bool process_unicode(uint16_t keycode, keyrecord_t *record) { - if (keycode > QK_UNICODE && record->event.pressed) { - uint16_t unicode = keycode & 0x7FFF; + if (keycode >= QK_UNICODE && keycode <= QK_UNICODE_MAX && record->event.pressed) { unicode_input_start(); - register_hex(unicode); + register_hex(keycode & 0x7FFF); unicode_input_finish(); } return true; diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index 0913e99107..22765ad560 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -13,9 +13,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + #pragma once -#include "quantum.h" #include "process_unicode_common.h" bool process_unicode(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c index d0a9cf2324..21ac2291db 100644 --- a/quantum/process_keycode/process_unicode_common.c +++ b/quantum/process_keycode/process_unicode_common.c @@ -20,6 +20,8 @@ #include unicode_config_t unicode_config; +uint8_t unicode_saved_mods; + #if UNICODE_SELECTED_MODES != -1 static uint8_t selected[] = { UNICODE_SELECTED_MODES }; static uint8_t selected_count = sizeof selected / sizeof *selected; @@ -75,30 +77,24 @@ void persist_unicode_input_mode(void) { eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config.input_mode); } -static uint8_t saved_mods; - __attribute__((weak)) void unicode_input_start(void) { - saved_mods = get_mods(); // Save current mods + unicode_saved_mods = get_mods(); // Save current mods clear_mods(); // Unregister mods to start from a clean state switch (unicode_config.input_mode) { case UC_OSX: - register_code(UNICODE_OSX_KEY); + register_code(UNICODE_KEY_OSX); break; case UC_LNX: - register_code(KC_LCTL); - register_code(KC_LSFT); - tap_code(KC_U); // TODO: Replace with tap_code16(LCTL(LSFT(KC_U))); and test - unregister_code(KC_LSFT); - unregister_code(KC_LCTL); + tap_code16(UNICODE_KEY_LNX); break; case UC_WIN: register_code(KC_LALT); tap_code(KC_PPLS); break; case UC_WINC: - tap_code(UNICODE_WINC_KEY); + tap_code(UNICODE_KEY_WINC); tap_code(KC_U); break; } @@ -110,7 +106,7 @@ __attribute__((weak)) void unicode_input_finish(void) { switch (unicode_config.input_mode) { case UC_OSX: - unregister_code(UNICODE_OSX_KEY); + unregister_code(UNICODE_KEY_OSX); break; case UC_LNX: tap_code(KC_SPC); @@ -123,7 +119,25 @@ void unicode_input_finish(void) { break; } - set_mods(saved_mods); // Reregister previously set mods + set_mods(unicode_saved_mods); // Reregister previously set mods +} + +__attribute__((weak)) +void unicode_input_cancel(void) { + switch (unicode_config.input_mode) { + case UC_OSX: + unregister_code(UNICODE_KEY_OSX); + break; + case UC_LNX: + case UC_WINC: + tap_code(KC_ESC); + break; + case UC_WIN: + unregister_code(KC_LALT); + break; + } + + set_mods(unicode_saved_mods); // Reregister previously set mods } __attribute__((weak)) diff --git a/quantum/process_keycode/process_unicode_common.h b/quantum/process_keycode/process_unicode_common.h index e608ab76be..7340800e56 100644 --- a/quantum/process_keycode/process_unicode_common.h +++ b/quantum/process_keycode/process_unicode_common.h @@ -23,11 +23,14 @@ #endif // Keycodes used for starting Unicode input on different platforms -#ifndef UNICODE_OSX_KEY - #define UNICODE_OSX_KEY KC_LALT +#ifndef UNICODE_KEY_OSX + #define UNICODE_KEY_OSX KC_LALT #endif -#ifndef UNICODE_WINC_KEY - #define UNICODE_WINC_KEY KC_RALT +#ifndef UNICODE_KEY_LNX + #define UNICODE_KEY_LNX LCTL(LSFT(KC_U)) +#endif +#ifndef UNICODE_KEY_WINC + #define UNICODE_KEY_WINC KC_RALT #endif // Comma-delimited, ordered list of input modes selected for use (e.g. in cycle) @@ -63,6 +66,7 @@ typedef union { } unicode_config_t; extern unicode_config_t unicode_config; +extern uint8_t unicode_saved_mods; void unicode_input_mode_init(void); uint8_t get_unicode_input_mode(void); @@ -72,6 +76,7 @@ void persist_unicode_input_mode(void); void unicode_input_start(void); void unicode_input_finish(void); +void unicode_input_cancel(void); void register_hex(uint16_t hex); void send_unicode_hex_string(const char *str); diff --git a/quantum/process_keycode/process_unicodemap.c b/quantum/process_keycode/process_unicodemap.c index 3274027613..b887879860 100644 --- a/quantum/process_keycode/process_unicodemap.c +++ b/quantum/process_keycode/process_unicodemap.c @@ -15,7 +15,6 @@ */ #include "process_unicodemap.h" -#include "process_unicode_common.h" void register_hex32(uint32_t hex) { bool onzerostart = true; @@ -38,28 +37,39 @@ void register_hex32(uint32_t hex) { } __attribute__((weak)) -void unicodemap_input_error() {} +uint16_t unicodemap_index(uint16_t keycode) { + if (keycode >= QK_UNICODEMAP_PAIR) { + // Keycode is a pair: extract index based on Shift / Caps Lock state + uint16_t index = keycode - QK_UNICODEMAP_PAIR; + + bool shift = unicode_saved_mods & MOD_MASK_SHIFT, caps = IS_HOST_LED_ON(USB_LED_CAPS_LOCK); + if (shift ^ caps) { index >>= 7; } + + return index & 0x7F; + } else { + // Keycode is a regular index + return keycode - QK_UNICODEMAP; + } +} bool process_unicodemap(uint16_t keycode, keyrecord_t *record) { - if ((keycode & QK_UNICODEMAP) == QK_UNICODEMAP && record->event.pressed) { - uint16_t index = keycode - QK_UNICODEMAP; - uint32_t code = pgm_read_dword(unicode_map + index); + if (keycode >= QK_UNICODEMAP && keycode <= QK_UNICODEMAP_PAIR_MAX && record->event.pressed) { + unicode_input_start(); + + uint32_t code = pgm_read_dword(unicode_map + unicodemap_index(keycode)); uint8_t input_mode = get_unicode_input_mode(); - if (code > 0xFFFF && code <= 0x10FFFF && input_mode == UC_OSX) { - // Convert to UTF-16 surrogate pair + if (code > 0x10FFFF || (code > 0xFFFF && input_mode == UC_WIN)) { + // Character is out of range supported by the platform + unicode_input_cancel(); + } else if (code > 0xFFFF && input_mode == UC_OSX) { + // Convert to UTF-16 surrogate pair on Mac code -= 0x10000; uint32_t lo = code & 0x3FF, hi = (code & 0xFFC00) >> 10; - - unicode_input_start(); register_hex32(hi + 0xD800); register_hex32(lo + 0xDC00); unicode_input_finish(); - } else if ((code > 0x10FFFF && input_mode == UC_OSX) || (code > 0xFFFFF && input_mode == UC_LNX)) { - // Character is out of range supported by the OS - unicodemap_input_error(); } else { - unicode_input_start(); register_hex32(code); unicode_input_finish(); } diff --git a/quantum/process_keycode/process_unicodemap.h b/quantum/process_keycode/process_unicodemap.h index fe4f979155..51709c5dc8 100644 --- a/quantum/process_keycode/process_unicodemap.h +++ b/quantum/process_keycode/process_unicodemap.h @@ -16,10 +16,10 @@ #pragma once -#include "quantum.h" #include "process_unicode_common.h" extern const uint32_t PROGMEM unicode_map[]; -void unicodemap_input_error(void); +void register_hex32(uint32_t hex); +uint16_t unicodemap_index(uint16_t keycode); bool process_unicodemap(uint16_t keycode, keyrecord_t *record); -- cgit v1.2.3 From e290dc5ad811e9d121e216fba6fe03666772c3a4 Mon Sep 17 00:00:00 2001 From: XScorpion2 Date: Sun, 5 May 2019 18:27:02 -0500 Subject: Space Cadet: Reducing unnecessary reported keypresses (#5781) * Reducing unnecessary reported keypresses and minor docs / variable name changes * Apply suggestions from code review Co-Authored-By: XScorpion2 --- quantum/process_keycode/process_space_cadet.c | 39 +++++++++++++++------------ quantum/process_keycode/process_space_cadet.h | 2 +- 2 files changed, 23 insertions(+), 18 deletions(-) (limited to 'quantum/process_keycode') diff --git a/quantum/process_keycode/process_space_cadet.c b/quantum/process_keycode/process_space_cadet.c index a9c506168d..ac39df8089 100644 --- a/quantum/process_keycode/process_space_cadet.c +++ b/quantum/process_keycode/process_space_cadet.c @@ -62,16 +62,16 @@ #ifndef LCPO_KEYS #define LCPO_KEYS KC_LCTL, KC_LCTL, KC_9 #endif -#ifndef RCPO_KEYS - #define RCPO_KEYS KC_RCTL, KC_RCTL, KC_0 +#ifndef RCPC_KEYS + #define RCPC_KEYS KC_RCTL, KC_RCTL, KC_0 #endif // Alt / paren setup #ifndef LAPO_KEYS #define LAPO_KEYS KC_LALT, KC_LALT, KC_9 #endif -#ifndef RAPO_KEYS - #define RAPO_KEYS KC_RALT, KC_RALT, KC_0 +#ifndef RAPC_KEYS + #define RAPC_KEYS KC_RALT, KC_RALT, KC_0 #endif // Shift / Enter setup @@ -82,27 +82,32 @@ static uint8_t sc_last = 0; static uint16_t sc_timer = 0; -void perform_space_cadet(keyrecord_t *record, uint8_t normalMod, uint8_t tapMod, uint8_t keycode) { +void perform_space_cadet(keyrecord_t *record, uint8_t holdMod, uint8_t tapMod, uint8_t keycode) { if (record->event.pressed) { - sc_last = normalMod; + sc_last = holdMod; sc_timer = timer_read (); - if (IS_MOD(normalMod)) { - register_mods(MOD_BIT(normalMod)); + if (IS_MOD(holdMod)) { + register_mods(MOD_BIT(holdMod)); } } else { - if (IS_MOD(normalMod)) { - unregister_mods(MOD_BIT(normalMod)); - } - - if (sc_last == normalMod && timer_elapsed(sc_timer) < TAPPING_TERM) { - if (IS_MOD(tapMod)) { - register_mods(MOD_BIT(tapMod)); + if (sc_last == holdMod && timer_elapsed(sc_timer) < TAPPING_TERM) { + if (holdMod != tapMod) { + if (IS_MOD(holdMod)) { + unregister_mods(MOD_BIT(holdMod)); + } + if (IS_MOD(tapMod)) { + register_mods(MOD_BIT(tapMod)); + } } tap_code(keycode); if (IS_MOD(tapMod)) { unregister_mods(MOD_BIT(tapMod)); } + } else { + if (IS_MOD(holdMod)) { + unregister_mods(MOD_BIT(holdMod)); + } } } } @@ -122,7 +127,7 @@ bool process_space_cadet(uint16_t keycode, keyrecord_t *record) { return false; } case KC_RCPC: { - perform_space_cadet(record, RCPO_KEYS); + perform_space_cadet(record, RCPC_KEYS); return false; } case KC_LAPO: { @@ -130,7 +135,7 @@ bool process_space_cadet(uint16_t keycode, keyrecord_t *record) { return false; } case KC_RAPC: { - perform_space_cadet(record, RAPO_KEYS); + perform_space_cadet(record, RAPC_KEYS); return false; } case KC_SFTENT: { diff --git a/quantum/process_keycode/process_space_cadet.h b/quantum/process_keycode/process_space_cadet.h index 3f08b8002a..c823143504 100644 --- a/quantum/process_keycode/process_space_cadet.h +++ b/quantum/process_keycode/process_space_cadet.h @@ -17,5 +17,5 @@ #include "quantum.h" -void perform_space_cadet(keyrecord_t *record, uint8_t normalMod, uint8_t tapMod, uint8_t keycode); +void perform_space_cadet(keyrecord_t *record, uint8_t holdMod, uint8_t tapMod, uint8_t keycode); bool process_space_cadet(uint16_t keycode, keyrecord_t *record); -- cgit v1.2.3