Initial commit after changes to support multiple keys

pull/389/head
Ben Gemperline 7 years ago
parent a74169961c
commit c3348eb096

@ -14,84 +14,202 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Modified by Ben Gemperline to support additional keys.
*/ */
#include <Kaleidoscope-SpaceCadet.h> #include <Kaleidoscope-SpaceCadet.h>
#include <kaleidoscope/hid.h> #include <kaleidoscope/hid.h>
#include <stdint.h>
#include "SpaceCadet.h"
namespace kaleidoscope { namespace kaleidoscope {
uint8_t SpaceCadetShift::paren_needed_; //Default constructor
uint32_t SpaceCadetShift::start_time_; ModifierKeyMap::ModifierKeyMap(){
uint16_t SpaceCadetShift::time_out = 1000; }
Key SpaceCadetShift::opening_paren = Key_9, SpaceCadetShift::closing_paren = Key_0;
SpaceCadetShift::SpaceCadetShift() { //Constructor with input and output, and assume default timeout
} ModifierKeyMap::ModifierKeyMap(Key input_, Key output_){
input = input_;
output = output_;
}
void SpaceCadetShift::begin() { //Constructor with all three set
Kaleidoscope.useEventHandlerHook(eventHandlerHook); 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) { //Space Cadet
// If nothing happened, bail out fast. uint8_t SpaceCadet::map_size = 0;
if (!keyIsPressed(key_state) && !keyWasPressed(key_state)) { ModifierKeyMap * SpaceCadet::map;
return mapped_key; uint16_t SpaceCadet::time_out = 1000;
}
SpaceCadet::SpaceCadet() {
// If a key has been just toggled on... //By default, we make one with left shift sending left paren, and right shift sending right paren
if (keyToggledOn(key_state)) { static ModifierKeyMap internalMap[] = {
if (mapped_key.raw == Key_LeftShift.raw) { // if it is LShift, remember it {Key_LeftShift,Key_LeftParen,250}
bitWrite(paren_needed_, 0, 1); ,{Key_RightShift,Key_RightParen,250}
start_time_ = millis(); /*,{Key_LeftGui,Key_LeftCurlyBracket,250}
} else if (mapped_key.raw == Key_RightShift.raw) { // if it is RShift, remember it ,{Key_RightAlt,Key_RightCurlyBracket,250}
bitWrite(paren_needed_, 1, 1); ,{Key_LeftControl,Key_LeftBracket,250}
start_time_ = millis(); ,{Key_RightControl,Key_RightBracket,250}*/
} else { // if it is something else, we do not need a paren at the end. };
paren_needed_ = 0;
start_time_ = 0; 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. SpaceCadet::SpaceCadet(ModifierKeyMap * map_, uint8_t map_size_) {
return mapped_key; //Call the initializer
} setMap(map_, map_size_);
}
// 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. void SpaceCadet::setMap(ModifierKeyMap * map_, uint8_t map_size_){
if (!paren_needed_) //Set the map
return mapped_key; map = map_;
//set the map size to be the length of the array
// if we timed out, that means we need to keep pressing shift, but won't map_size = map_size_;
// need the parens in the end. }
if ((millis() - start_time_) >= time_out) {
paren_needed_ = 0; void SpaceCadet::begin() {
return mapped_key; Kaleidoscope.useEventHandlerHook(eventHandlerHook);
} }
// if we have a state, but the key in question is not either of the shifts, Key SpaceCadet::eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state) {
// return. This can happen when another key is released, and that should not //char buffer[50];
// interrupt us.
if (mapped_key.raw != Key_LeftShift.raw && //Serial.print("In eventHandlerHook");
mapped_key.raw != Key_RightShift.raw) // If nothing happened, bail out fast.
return mapped_key; if (!keyIsPressed(key_state) && !keyWasPressed(key_state)) {
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)) { // If a key has been just toggled on...
Key paren = opening_paren; if (keyToggledOn(key_state)) {
if (bitRead(paren_needed_, 1))
paren = closing_paren; /*
sprintf(buffer, "Pressed Key: %u\n", mapped_key.raw );
handleKeyswitchEvent(mapped_key, row, col, IS_PRESSED | INJECTED); Serial.print(buffer);
handleKeyswitchEvent(paren, row, col, IS_PRESSED | INJECTED); */
hid::sendKeyboardReport();
if(map_size > 0) {
paren_needed_ = 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) {
return mapped_key; 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;

@ -21,22 +21,47 @@
#include <Kaleidoscope.h> #include <Kaleidoscope.h>
namespace kaleidoscope { 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 { //Declaration for the method (implementing KaleidoscopePlugin)
public: class SpaceCadet : public KaleidoscopePlugin {
SpaceCadetShift(void); public:
//Empty constructor
SpaceCadet(void);
void begin(void) final; //Constructor with mapping
SpaceCadet(ModifierKeyMap * map, uint8_t map_size);
static uint16_t time_out; //Methods
static Key opening_paren, closing_paren; void setMap(ModifierKeyMap * map, uint8_t map_size);
void begin(void) final;
private: static uint16_t time_out;
static uint8_t paren_needed_;
static uint32_t start_time_;
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;

Loading…
Cancel
Save