diff --git a/src/Kaleidoscope/SpaceCadet.cpp b/src/Kaleidoscope/SpaceCadet.cpp
index 7ee88dd1..e5bc8556 100644
--- a/src/Kaleidoscope/SpaceCadet.cpp
+++ b/src/Kaleidoscope/SpaceCadet.cpp
@@ -14,84 +14,202 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
+ *
+ * Modified by Ben Gemperline to support additional keys.
*/
#include
#include
+#include
+#include "SpaceCadet.h"
namespace kaleidoscope {
-uint8_t SpaceCadetShift::paren_needed_;
-uint32_t SpaceCadetShift::start_time_;
-uint16_t SpaceCadetShift::time_out = 1000;
-Key SpaceCadetShift::opening_paren = Key_9, SpaceCadetShift::closing_paren = Key_0;
+ //Default constructor
+ ModifierKeyMap::ModifierKeyMap(){
+ }
-SpaceCadetShift::SpaceCadetShift() {
-}
+ //Constructor with input and output, and assume default timeout
+ ModifierKeyMap::ModifierKeyMap(Key input_, Key output_){
+ input = input_;
+ output = output_;
+ }
-void SpaceCadetShift::begin() {
- Kaleidoscope.useEventHandlerHook(eventHandlerHook);
-}
+ //Constructor with all three set
+ ModifierKeyMap::ModifierKeyMap(Key input_, Key output_, uint16_t timeout_) {
+ input = input_;
+ output = output_;
+ timeout = timeout_;
+ }
-Key SpaceCadetShift::eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state) {
- // If nothing happened, bail out fast.
- if (!keyIsPressed(key_state) && !keyWasPressed(key_state)) {
- return mapped_key;
- }
-
- // If a key has been just toggled on...
- if (keyToggledOn(key_state)) {
- if (mapped_key.raw == Key_LeftShift.raw) { // if it is LShift, remember it
- bitWrite(paren_needed_, 0, 1);
- start_time_ = millis();
- } else if (mapped_key.raw == Key_RightShift.raw) { // if it is RShift, remember it
- bitWrite(paren_needed_, 1, 1);
- start_time_ = millis();
- } else { // if it is something else, we do not need a paren at the end.
- paren_needed_ = 0;
- start_time_ = 0;
+ //Space Cadet
+ uint8_t SpaceCadet::map_size = 0;
+ ModifierKeyMap * SpaceCadet::map;
+ uint16_t SpaceCadet::time_out = 1000;
+
+ SpaceCadet::SpaceCadet() {
+ //By default, we make one with left shift sending left paren, and right shift sending right paren
+ static ModifierKeyMap internalMap[] = {
+ {Key_LeftShift,Key_LeftParen,250}
+ ,{Key_RightShift,Key_RightParen,250}
+ /*,{Key_LeftGui,Key_LeftCurlyBracket,250}
+ ,{Key_RightAlt,Key_RightCurlyBracket,250}
+ ,{Key_LeftControl,Key_LeftBracket,250}
+ ,{Key_RightControl,Key_RightBracket,250}*/
+ };
+
+ map = internalMap;
+ map_size = sizeof(internalMap)/sizeof(internalMap[0]);
+ //setMap(internalMap, sizeof(internalMap));
}
- // this is all we need to do on keypress, let the next handler do its thing too.
- return mapped_key;
- }
-
- // if the state is empty, that means that either the shifts weren't pressed,
- // or we used another key in the interim. in both cases, nothing special to do.
- if (!paren_needed_)
- return mapped_key;
-
- // if we timed out, that means we need to keep pressing shift, but won't
- // need the parens in the end.
- if ((millis() - start_time_) >= time_out) {
- paren_needed_ = 0;
- return mapped_key;
- }
-
- // if we have a state, but the key in question is not either of the shifts,
- // return. This can happen when another key is released, and that should not
- // interrupt us.
- if (mapped_key.raw != Key_LeftShift.raw &&
- mapped_key.raw != Key_RightShift.raw)
- return mapped_key;
-
- // if a key toggled off (and that must be one of the shifts at this point),
- // send the parens too (if we were interrupted, we bailed out earlier).
- if (keyToggledOff(key_state)) {
- Key paren = opening_paren;
- if (bitRead(paren_needed_, 1))
- paren = closing_paren;
-
- handleKeyswitchEvent(mapped_key, row, col, IS_PRESSED | INJECTED);
- handleKeyswitchEvent(paren, row, col, IS_PRESSED | INJECTED);
- hid::sendKeyboardReport();
-
- paren_needed_ = 0;
- }
-
- return mapped_key;
-}
+ SpaceCadet::SpaceCadet(ModifierKeyMap * map_, uint8_t map_size_) {
+ //Call the initializer
+ setMap(map_, map_size_);
+ }
+
+ void SpaceCadet::setMap(ModifierKeyMap * map_, uint8_t map_size_){
+ //Set the map
+ map = map_;
+ //set the map size to be the length of the array
+ map_size = map_size_;
+ }
+
+ void SpaceCadet::begin() {
+ Kaleidoscope.useEventHandlerHook(eventHandlerHook);
+ }
+
+ Key SpaceCadet::eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state) {
+ //char buffer[50];
+
+ //Serial.print("In eventHandlerHook");
+ // If nothing happened, bail out fast.
+ if (!keyIsPressed(key_state) && !keyWasPressed(key_state)) {
+ return mapped_key;
+ }
+
+ // If a key has been just toggled on...
+ if (keyToggledOn(key_state)) {
+
+ /*
+ sprintf(buffer, "Pressed Key: %u\n", mapped_key.raw );
+ Serial.print(buffer);
+ */
+
+ if(map_size > 0) {
+ //This will only set one key, and if it isn't in our map it clears everything for the non-pressed key
+ for (uint8_t i = 0; i < map_size; ++i) {
+ if(mapped_key.raw == map[i].input.raw) {
+ map[i].flagged = true;
+ map[i].start_time = millis();
+ //There was a valid keypress
+ /*sprintf(buffer, "Valid Key: %u\n", mapped_key.raw);
+ Serial.print(buffer);*/
+
+ } else {
+ map[i].flagged = false;
+ map[i].start_time = 0;
+ }
+
+ /*
+ sprintf(buffer, "Key: %u\n", map[i].input.raw);
+ Serial.print(buffer);
+ if(map[i].flagged){
+ Serial.print("Flagged\n");
+ } else {
+ Serial.print("Not Flagged\n");
+ }
+ sprintf(buffer, "Start Time: %u\n", map[i].start_time);
+ Serial.print(buffer);
+ */
+ }
+ }
+
+ // this is all we need to do on keypress, let the next handler do its thing too.
+ return mapped_key;
+ }
+
+ // if the state is empty, that means that either the shifts weren't pressed,
+ // or we used another key in the interim. in both cases, nothing special to do.
+ bool valid_key = false;
+ bool pressed_key_was_valid = false;
+ uint8_t index = 0;
+ if(map_size > 0) {
+ //Look to see if any are flagged
+ for (uint8_t i = 0; i < map_size; ++i) {
+
+ if (map[i].flagged) {
+ valid_key = true;
+ index = i;
+ }
+ if (map[i].input.raw == mapped_key.raw) {
+ pressed_key_was_valid = true;
+ }
+ }
+ }
+ if (!valid_key) {
+ return mapped_key;
+ }
+
+ //use the map index to find the local timeout for this key
+ uint16_t current_timeout = map[index].timeout;
+ //If that isn't set, use the global timeout setting.
+ if(current_timeout == 0){
+ current_timeout = time_out;
+ }
+
+
+
+ if ((millis() - map[index].start_time) >= current_timeout) {
+ // if we timed out, that means we need to keep pressing shift, but won't
+ // need the parens in the end.
+ map[index].flagged = false;
+ map[index].start_time = 0;
+ return mapped_key;
+ }
+
+ /*
+ sprintf(buffer, "Check Index: %u\n", index );
+ Serial.print(buffer);
+
+ sprintf(buffer, "Current Timeout: %u\n", current_timeout );
+ Serial.print(buffer);
+
+ sprintf(buffer, "Start Time: %u\n", map[index].start_time );
+ Serial.print(buffer);
+
+ Serial.print("Made it past timeout check\n");
+ */
+
+ // if we have a state, but the key in question is not either of the shifts,
+ // return. This can happen when another key is released, and that should not
+ // interrupt us.
+
+ if (!pressed_key_was_valid) {
+ return mapped_key;
+ }
+
+ //Serial.print("Made it validity check\n");
+
+
+ // if a key toggled off (and that must be one of the shifts at this point),
+ // send the parens too (if we were interrupted, we bailed out earlier).
+ if (keyToggledOff(key_state)) {
+ Key pressed_key = map[index].input;
+ Key alternate_key = map[index].output;
+
+ //Don't necessarily need to send the original key
+ //handleKeyswitchEvent(pressed_key, row, col, WAS_PRESSED | INJECTED);
+ handleKeyswitchEvent(alternate_key, row, col, IS_PRESSED | INJECTED);
+ hid::sendKeyboardReport();
+
+ map[index].flagged = false;
+ map[index].start_time = 0;
+ }
+
+ return mapped_key;
+ }
}
-kaleidoscope::SpaceCadetShift SpaceCadetShift;
+kaleidoscope::SpaceCadet SpaceCadet;
diff --git a/src/Kaleidoscope/SpaceCadet.h b/src/Kaleidoscope/SpaceCadet.h
index 626ef573..62af27c2 100644
--- a/src/Kaleidoscope/SpaceCadet.h
+++ b/src/Kaleidoscope/SpaceCadet.h
@@ -21,22 +21,47 @@
#include
namespace kaleidoscope {
+ //Declarations for the modifier key mapping
+ class ModifierKeyMap {
+ public:
+ //Empty constructor; set the vars separately
+ ModifierKeyMap(void);
+ //Constructor with input and output
+ ModifierKeyMap(Key input_, Key output_);
+ //Constructor with all three set
+ ModifierKeyMap(Key input_, Key output_, uint16_t timeout_);
+ //The key that is pressed
+ Key input;
+ //the key that is sent
+ Key output;
+ //The timeout (default to global timeout)
+ uint16_t timeout = 0;
+ //The flag (set to 0)
+ bool flagged = false;
+ //the start time for this key press
+ uint32_t start_time = 0;
+ };
-class SpaceCadetShift : public KaleidoscopePlugin {
- public:
- SpaceCadetShift(void);
+ //Declaration for the method (implementing KaleidoscopePlugin)
+ class SpaceCadet : public KaleidoscopePlugin {
+ public:
+ //Empty constructor
+ SpaceCadet(void);
- void begin(void) final;
+ //Constructor with mapping
+ SpaceCadet(ModifierKeyMap * map, uint8_t map_size);
- static uint16_t time_out;
- static Key opening_paren, closing_paren;
+ //Methods
+ void setMap(ModifierKeyMap * map, uint8_t map_size);
+ void begin(void) final;
- private:
- static uint8_t paren_needed_;
- static uint32_t start_time_;
+ static uint16_t time_out;
- static Key eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state);
-};
+ private:
+ static uint8_t map_size;
+ static ModifierKeyMap * map;
+ static Key eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state);
+ };
};
-extern kaleidoscope::SpaceCadetShift SpaceCadetShift;
+extern kaleidoscope::SpaceCadet SpaceCadet;