aboutsummaryrefslogtreecommitdiff
path: root/quantum/process_keycode/process_key_lock.c
diff options
context:
space:
mode:
authorFredric Silberberg <fred@silberberg.xyz>2017-08-06 14:14:27 -0700
committerJack Humbert <jack.humb@gmail.com>2017-08-08 10:02:53 -0400
commita3e1d9a8cc8b3d376d52f86aacae6315b15efebf (patch)
tree19784f99eab3fa0b03b96402f7e2b62599d17a0a /quantum/process_keycode/process_key_lock.c
parent02f405708bb3a486224b857feb1f03f883f55ffe (diff)
downloadqmk_firmware-a3e1d9a8cc8b3d376d52f86aacae6315b15efebf.tar.gz
qmk_firmware-a3e1d9a8cc8b3d376d52f86aacae6315b15efebf.zip
Added support for locking One Shot modifiers.
Diffstat (limited to 'quantum/process_keycode/process_key_lock.c')
-rw-r--r--quantum/process_keycode/process_key_lock.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/quantum/process_keycode/process_key_lock.c b/quantum/process_keycode/process_key_lock.c
index e3632b74f..b1ba397a0 100644
--- a/quantum/process_keycode/process_key_lock.c
+++ b/quantum/process_keycode/process_key_lock.c
@@ -50,7 +50,16 @@
50uint64_t key_state[4] = { 0x0, 0x0, 0x0, 0x0 }; 50uint64_t key_state[4] = { 0x0, 0x0, 0x0, 0x0 };
51bool watching = false; 51bool watching = false;
52 52
53bool process_key_lock(uint16_t keycode, keyrecord_t *record) { 53// Translate any OSM keycodes back to their unmasked versions.
54uint16_t inline translate_keycode(uint16_t keycode) {
55 if (keycode > QK_ONE_SHOT_MOD && keycode <= QK_ONE_SHOT_MOD_MAX) {
56 return keycode ^ QK_ONE_SHOT_MOD;
57 } else {
58 return keycode;
59 }
60}
61
62bool process_key_lock(uint16_t *keycode, keyrecord_t *record) {
54 // We start by categorizing the keypress event. In the event of a down 63 // We start by categorizing the keypress event. In the event of a down
55 // event, there are several possibilities: 64 // event, there are several possibilities:
56 // 1. The key is not being locked, and we are not watching for new keys. 65 // 1. The key is not being locked, and we are not watching for new keys.
@@ -76,44 +85,54 @@ bool process_key_lock(uint16_t keycode, keyrecord_t *record) {
76 // 2. The key is being locked. In this case, we will mask the up event 85 // 2. The key is being locked. In this case, we will mask the up event
77 // by returning false, so the OS never sees that the key was released 86 // by returning false, so the OS never sees that the key was released
78 // until the user pressed the key again. 87 // until the user pressed the key again.
88
89 // We translate any OSM keycodes back to their original keycodes, so that if the key being
90 // one-shot modded is a standard keycode, we can handle it. This is the only set of special
91 // keys that we handle
92 uint16_t translated_keycode = translate_keycode(*keycode);
93
79 if (record->event.pressed) { 94 if (record->event.pressed) {
80 // Non-standard keycode, reset and return 95 // Non-standard keycode, reset and return
81 if (!(IS_STANDARD_KEYCODE(keycode) || keycode == KC_LOCK)) { 96 if (!(IS_STANDARD_KEYCODE(translated_keycode) || translated_keycode == KC_LOCK)) {
82 watching = false; 97 watching = false;
83 return true; 98 return true;
84 } 99 }
85 100
86 // If we're already watching, turn off the watch. 101 // If we're already watching, turn off the watch.
87 if (keycode == KC_LOCK) { 102 if (translated_keycode == KC_LOCK) {
88 watching = !watching; 103 watching = !watching;
89 return false; 104 return false;
90 } 105 }
91 106
92 if (IS_STANDARD_KEYCODE(keycode)) { 107 if (IS_STANDARD_KEYCODE(translated_keycode)) {
93 // We check watching first. This is so that in the following scenario, we continue to 108 // We check watching first. This is so that in the following scenario, we continue to
94 // hold the key: KC_LOCK, KC_F, KC_LOCK, KC_F 109 // hold the key: KC_LOCK, KC_F, KC_LOCK, KC_F
95 // If we checked in reverse order, we'd end up holding the key pressed after the second 110 // If we checked in reverse order, we'd end up holding the key pressed after the second
96 // KC_F press is registered, when the user likely meant to hold F 111 // KC_F press is registered, when the user likely meant to hold F
97 if (watching) { 112 if (watching) {
98 watching = false; 113 watching = false;
99 SET_KEY_STATE(keycode); 114 SET_KEY_STATE(translated_keycode);
115 // We need to set the keycode passed in to be the translated keycode, in case we
116 // translated a OSM back to the original keycode.
117 *keycode = translated_keycode;
100 // Let the standard keymap send the keycode down event. The up event will be masked. 118 // Let the standard keymap send the keycode down event. The up event will be masked.
101 return true; 119 return true;
102 } 120 }
103 121
104 if (KEY_STATE(keycode)) { 122 if (KEY_STATE(translated_keycode)) {
105 UNSET_KEY_STATE(keycode); 123 UNSET_KEY_STATE(translated_keycode);
106 // The key is already held, stop this process. The up event will be sent when the user 124 // The key is already held, stop this process. The up event will be sent when the user
107 // releases the key. 125 // releases the key.
108 return false; 126 return false;
109 } 127 }
110 } 128 }
111 129
112 // Either the key isn't a standard key, or we need to send the down event. Continue standard 130 // Either the key isn't a standard key, or we need to send the down event. Continue standard
113 // processing 131 // processing
114 return true; 132 return true;
115 } else { 133 } else {
116 // Stop processing if it's a standard key and we're masking up. 134 // Stop processing if it's a standard key and we're masking up.
117 return !(IS_STANDARD_KEYCODE(keycode) && KEY_STATE(keycode)); 135 return !(IS_STANDARD_KEYCODE(translated_keycode) && KEY_STATE(translated_keycode));
118 } 136 }
119} 137}
138