process_space_cadet.c (4943B)
1 /* Copyright 2019 Jack Humbert 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 2 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17 #include "process_space_cadet.h" 18 #include "keycodes.h" 19 #include "timer.h" 20 #include "action.h" 21 #include "action_tapping.h" 22 #include "action_util.h" 23 24 // ********** OBSOLETE DEFINES, STOP USING! (pls?) ********** 25 // Shift / paren setup 26 #ifndef LSPO_KEY 27 # define LSPO_KEY KC_9 28 #endif 29 #ifndef RSPC_KEY 30 # define RSPC_KEY KC_0 31 #endif 32 33 // Shift / Enter setup 34 #ifndef SFTENT_KEY 35 # define SFTENT_KEY KC_ENTER 36 #endif 37 38 #ifdef DISABLE_SPACE_CADET_MODIFIER 39 # ifndef LSPO_MOD 40 # define LSPO_MOD KC_TRANSPARENT 41 # endif 42 # ifndef RSPC_MOD 43 # define RSPC_MOD KC_TRANSPARENT 44 # endif 45 #else 46 # ifndef LSPO_MOD 47 # define LSPO_MOD KC_LEFT_SHIFT 48 # endif 49 # ifndef RSPC_MOD 50 # define RSPC_MOD KC_RIGHT_SHIFT 51 # endif 52 #endif 53 // ********************************************************** 54 55 // Shift / paren setup 56 #ifndef LSPO_KEYS 57 # define LSPO_KEYS KC_LEFT_SHIFT, LSPO_MOD, LSPO_KEY 58 #endif 59 #ifndef RSPC_KEYS 60 # define RSPC_KEYS KC_RIGHT_SHIFT, RSPC_MOD, RSPC_KEY 61 #endif 62 63 // Control / paren setup 64 #ifndef LCPO_KEYS 65 # define LCPO_KEYS KC_LEFT_CTRL, KC_LEFT_SHIFT, KC_9 66 #endif 67 #ifndef RCPC_KEYS 68 # define RCPC_KEYS KC_RIGHT_CTRL, KC_RIGHT_SHIFT, KC_0 69 #endif 70 71 // Alt / paren setup 72 #ifndef LAPO_KEYS 73 # define LAPO_KEYS KC_LEFT_ALT, KC_LEFT_SHIFT, KC_9 74 #endif 75 #ifndef RAPC_KEYS 76 # define RAPC_KEYS KC_RIGHT_ALT, KC_RIGHT_SHIFT, KC_0 77 #endif 78 79 // Shift / Enter setup 80 #ifndef SFTENT_KEYS 81 # define SFTENT_KEYS KC_RIGHT_SHIFT, KC_TRANSPARENT, SFTENT_KEY 82 #endif 83 84 static uint8_t sc_last = 0; 85 static uint16_t sc_timer = 0; 86 #ifdef SPACE_CADET_MODIFIER_CARRYOVER 87 static uint8_t sc_mods = 0; 88 #endif 89 90 void perform_space_cadet(keyrecord_t *record, uint16_t sc_keycode, uint8_t holdMod, uint8_t tapMod, uint8_t keycode) { 91 if (record->event.pressed) { 92 sc_last = holdMod; 93 sc_timer = timer_read(); 94 #ifdef SPACE_CADET_MODIFIER_CARRYOVER 95 sc_mods = get_mods(); 96 #endif 97 if (IS_MODIFIER_KEYCODE(holdMod)) { 98 register_mods(MOD_BIT(holdMod)); 99 } 100 } else { 101 if (sc_last == holdMod && timer_elapsed(sc_timer) < GET_TAPPING_TERM(sc_keycode, record)) { 102 if (holdMod != tapMod) { 103 if (IS_MODIFIER_KEYCODE(holdMod)) { 104 unregister_mods(MOD_BIT(holdMod)); 105 } 106 if (IS_MODIFIER_KEYCODE(tapMod)) { 107 register_mods(MOD_BIT(tapMod)); 108 } 109 } 110 #ifdef SPACE_CADET_MODIFIER_CARRYOVER 111 set_weak_mods(sc_mods); 112 #endif 113 tap_code(keycode); 114 #ifdef SPACE_CADET_MODIFIER_CARRYOVER 115 clear_weak_mods(); 116 #endif 117 if (IS_MODIFIER_KEYCODE(tapMod)) { 118 unregister_mods(MOD_BIT(tapMod)); 119 } 120 } else { 121 if (IS_MODIFIER_KEYCODE(holdMod)) { 122 unregister_mods(MOD_BIT(holdMod)); 123 } 124 } 125 } 126 } 127 128 bool process_space_cadet(uint16_t keycode, keyrecord_t *record) { 129 switch (keycode) { 130 case QK_SPACE_CADET_LEFT_SHIFT_PARENTHESIS_OPEN: { 131 perform_space_cadet(record, keycode, LSPO_KEYS); 132 return false; 133 } 134 case QK_SPACE_CADET_RIGHT_SHIFT_PARENTHESIS_CLOSE: { 135 perform_space_cadet(record, keycode, RSPC_KEYS); 136 return false; 137 } 138 case QK_SPACE_CADET_LEFT_CTRL_PARENTHESIS_OPEN: { 139 perform_space_cadet(record, keycode, LCPO_KEYS); 140 return false; 141 } 142 case QK_SPACE_CADET_RIGHT_CTRL_PARENTHESIS_CLOSE: { 143 perform_space_cadet(record, keycode, RCPC_KEYS); 144 return false; 145 } 146 case QK_SPACE_CADET_LEFT_ALT_PARENTHESIS_OPEN: { 147 perform_space_cadet(record, keycode, LAPO_KEYS); 148 return false; 149 } 150 case QK_SPACE_CADET_RIGHT_ALT_PARENTHESIS_CLOSE: { 151 perform_space_cadet(record, keycode, RAPC_KEYS); 152 return false; 153 } 154 case QK_SPACE_CADET_RIGHT_SHIFT_ENTER: { 155 perform_space_cadet(record, keycode, SFTENT_KEYS); 156 return false; 157 } 158 default: { 159 if (record->event.pressed) { 160 reset_space_cadet(); 161 } 162 break; 163 } 164 } 165 return true; 166 } 167 168 void reset_space_cadet() { 169 sc_last = 0; 170 }