|
|
@ -22,11 +22,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
namespace KaleidoscopePlugins {
|
|
|
|
namespace KaleidoscopePlugins {
|
|
|
|
TypingBreaks::settings_t TypingBreaks::settings = {
|
|
|
|
TypingBreaks::settings_t TypingBreaks::settings = {
|
|
|
|
.idleTimeLimit = 10000, // 10s
|
|
|
|
.idleTimeLimit = 10000, // 10s
|
|
|
|
.lockTimeOut = 2700000, // 45m
|
|
|
|
.lockTimeOut = 2700000, // 45m
|
|
|
|
.lockLength = 300000, // 5m
|
|
|
|
.lockLength = 300000, // 5m
|
|
|
|
.leftHandMaxKeys = 0,
|
|
|
|
.leftHandMaxKeys = 0,
|
|
|
|
.rightHandMaxKeys = 0
|
|
|
|
.rightHandMaxKeys = 0
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t TypingBreaks::sessionStartTime;
|
|
|
|
uint32_t TypingBreaks::sessionStartTime;
|
|
|
@ -36,168 +36,168 @@ uint16_t TypingBreaks::leftHandKeys;
|
|
|
|
uint16_t TypingBreaks::rightHandKeys;
|
|
|
|
uint16_t TypingBreaks::rightHandKeys;
|
|
|
|
uint16_t TypingBreaks::settingsBase;
|
|
|
|
uint16_t TypingBreaks::settingsBase;
|
|
|
|
|
|
|
|
|
|
|
|
TypingBreaks::TypingBreaks (void) {
|
|
|
|
TypingBreaks::TypingBreaks(void) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
TypingBreaks::begin (void) {
|
|
|
|
TypingBreaks::begin(void) {
|
|
|
|
event_handler_hook_use (this->eventHandlerHook);
|
|
|
|
event_handler_hook_use(this->eventHandlerHook);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Key
|
|
|
|
Key
|
|
|
|
TypingBreaks::eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState) {
|
|
|
|
TypingBreaks::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState) {
|
|
|
|
// If we are locked, and didn't time out yet, no key has to be pressed.
|
|
|
|
// If we are locked, and didn't time out yet, no key has to be pressed.
|
|
|
|
if (lockStartTime && (millis () - lockStartTime <= settings.lockLength))
|
|
|
|
if (lockStartTime && (millis() - lockStartTime <= settings.lockLength))
|
|
|
|
return Key_NoKey;
|
|
|
|
return Key_NoKey;
|
|
|
|
|
|
|
|
|
|
|
|
// If we are locked...
|
|
|
|
// If we are locked...
|
|
|
|
if (lockStartTime) {
|
|
|
|
if (lockStartTime) {
|
|
|
|
// ...and the lock has not expired yet
|
|
|
|
// ...and the lock has not expired yet
|
|
|
|
if (millis () - lockStartTime <= settings.lockLength)
|
|
|
|
if (millis() - lockStartTime <= settings.lockLength)
|
|
|
|
return Key_NoKey; // remain locked
|
|
|
|
return Key_NoKey; // remain locked
|
|
|
|
|
|
|
|
|
|
|
|
// ...otherwise clear the lock
|
|
|
|
// ...otherwise clear the lock
|
|
|
|
lockStartTime = 0;
|
|
|
|
lockStartTime = 0;
|
|
|
|
leftHandKeys = rightHandKeys = 0;
|
|
|
|
leftHandKeys = rightHandKeys = 0;
|
|
|
|
sessionStartTime = millis ();
|
|
|
|
sessionStartTime = millis();
|
|
|
|
|
|
|
|
|
|
|
|
TypingBreak (false);
|
|
|
|
TypingBreak(false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Any other case, we are not locked yet! (or we just unlocked)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Are we still in the same session?
|
|
|
|
|
|
|
|
if (lastKeyTime && (millis() - lastKeyTime) >= settings.idleTimeLimit) {
|
|
|
|
|
|
|
|
// No, we are not. Clear timers and start over.
|
|
|
|
|
|
|
|
lockStartTime = 0;
|
|
|
|
|
|
|
|
leftHandKeys = rightHandKeys = 0;
|
|
|
|
|
|
|
|
sessionStartTime = millis();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If we have a limit on the left hand, and we reached it, lock up!
|
|
|
|
|
|
|
|
if (settings.leftHandMaxKeys && leftHandKeys >= settings.leftHandMaxKeys) {
|
|
|
|
|
|
|
|
lockStartTime = millis();
|
|
|
|
|
|
|
|
TypingBreak(true);
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If we have a limit on the right hand, and we reached it, lock up!
|
|
|
|
|
|
|
|
if (settings.rightHandMaxKeys && rightHandKeys >= settings.rightHandMaxKeys) {
|
|
|
|
|
|
|
|
lockStartTime = millis();
|
|
|
|
|
|
|
|
TypingBreak(true);
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (settings.lockTimeOut) {
|
|
|
|
|
|
|
|
// Is the session longer than lockTimeOut?
|
|
|
|
|
|
|
|
if (millis() - sessionStartTime >= settings.lockTimeOut) {
|
|
|
|
|
|
|
|
// Yeah, it is.
|
|
|
|
|
|
|
|
lockStartTime = millis();
|
|
|
|
|
|
|
|
TypingBreak(true);
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Any other case, we are not locked yet! (or we just unlocked)
|
|
|
|
// So it seems we did not need to lock up. In this case, lets increase key
|
|
|
|
|
|
|
|
// counters if need be.
|
|
|
|
|
|
|
|
|
|
|
|
// Are we still in the same session?
|
|
|
|
if (key_toggled_on(keyState)) {
|
|
|
|
if (lastKeyTime && (millis () - lastKeyTime) >= settings.idleTimeLimit) {
|
|
|
|
if (col <= COLS / 2)
|
|
|
|
// No, we are not. Clear timers and start over.
|
|
|
|
leftHandKeys++;
|
|
|
|
lockStartTime = 0;
|
|
|
|
else
|
|
|
|
leftHandKeys = rightHandKeys = 0;
|
|
|
|
rightHandKeys++;
|
|
|
|
sessionStartTime = millis ();
|
|
|
|
lastKeyTime = millis();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If we have a limit on the left hand, and we reached it, lock up!
|
|
|
|
|
|
|
|
if (settings.leftHandMaxKeys && leftHandKeys >= settings.leftHandMaxKeys) {
|
|
|
|
|
|
|
|
lockStartTime = millis ();
|
|
|
|
|
|
|
|
TypingBreak (true);
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If we have a limit on the right hand, and we reached it, lock up!
|
|
|
|
|
|
|
|
if (settings.rightHandMaxKeys && rightHandKeys >= settings.rightHandMaxKeys) {
|
|
|
|
|
|
|
|
lockStartTime = millis ();
|
|
|
|
|
|
|
|
TypingBreak (true);
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (settings.lockTimeOut) {
|
|
|
|
|
|
|
|
// Is the session longer than lockTimeOut?
|
|
|
|
|
|
|
|
if (millis () - sessionStartTime >= settings.lockTimeOut) {
|
|
|
|
|
|
|
|
// Yeah, it is.
|
|
|
|
|
|
|
|
lockStartTime = millis ();
|
|
|
|
|
|
|
|
TypingBreak (true);
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// So it seems we did not need to lock up. In this case, lets increase key
|
|
|
|
|
|
|
|
// counters if need be.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (key_toggled_on (keyState)) {
|
|
|
|
|
|
|
|
if (col <= COLS / 2)
|
|
|
|
|
|
|
|
leftHandKeys++;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
rightHandKeys++;
|
|
|
|
|
|
|
|
lastKeyTime = millis ();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return mappedKey;
|
|
|
|
return mappedKey;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
TypingBreaks::enableEEPROM (void) {
|
|
|
|
TypingBreaks::enableEEPROM(void) {
|
|
|
|
settingsBase = ::EEPROMSettings.requestSlice (sizeof (settings));
|
|
|
|
settingsBase = ::EEPROMSettings.requestSlice(sizeof(settings));
|
|
|
|
|
|
|
|
|
|
|
|
// If idleTime is max, assume that EEPROM is uninitialized, and store the
|
|
|
|
// If idleTime is max, assume that EEPROM is uninitialized, and store the
|
|
|
|
// defaults.
|
|
|
|
// defaults.
|
|
|
|
uint32_t idleTime;
|
|
|
|
uint32_t idleTime;
|
|
|
|
EEPROM.get (settingsBase, idleTime);
|
|
|
|
EEPROM.get(settingsBase, idleTime);
|
|
|
|
if (idleTime == 0xffffffff) {
|
|
|
|
if (idleTime == 0xffffffff) {
|
|
|
|
EEPROM.put (settingsBase, settings);
|
|
|
|
EEPROM.put(settingsBase, settings);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EEPROM.get (settingsBase, settings);
|
|
|
|
EEPROM.get(settingsBase, settings);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
bool
|
|
|
|
TypingBreaks::focusHook (const char *command) {
|
|
|
|
TypingBreaks::focusHook(const char *command) {
|
|
|
|
enum {
|
|
|
|
enum {
|
|
|
|
IDLE_TIME_LIMIT,
|
|
|
|
IDLE_TIME_LIMIT,
|
|
|
|
LOCK_TIMEOUT,
|
|
|
|
LOCK_TIMEOUT,
|
|
|
|
LOCK_LENGTH,
|
|
|
|
LOCK_LENGTH,
|
|
|
|
LEFT_MAX,
|
|
|
|
LEFT_MAX,
|
|
|
|
RIGHT_MAX,
|
|
|
|
RIGHT_MAX,
|
|
|
|
} subCommand;
|
|
|
|
} subCommand;
|
|
|
|
|
|
|
|
|
|
|
|
if (strncmp_P (command, PSTR ("typingbreaks."), 13) != 0)
|
|
|
|
if (strncmp_P(command, PSTR("typingbreaks."), 13) != 0)
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
if (strcmp_P (command + 13, PSTR ("idleTimeLimit")) == 0)
|
|
|
|
if (strcmp_P(command + 13, PSTR("idleTimeLimit")) == 0)
|
|
|
|
subCommand = IDLE_TIME_LIMIT;
|
|
|
|
subCommand = IDLE_TIME_LIMIT;
|
|
|
|
else if (strcmp_P (command + 13, PSTR ("lockTimeOut")) == 0)
|
|
|
|
else if (strcmp_P(command + 13, PSTR("lockTimeOut")) == 0)
|
|
|
|
subCommand = LOCK_TIMEOUT;
|
|
|
|
subCommand = LOCK_TIMEOUT;
|
|
|
|
else if (strcmp_P (command + 13, PSTR ("lockLength")) == 0)
|
|
|
|
else if (strcmp_P(command + 13, PSTR("lockLength")) == 0)
|
|
|
|
subCommand = LOCK_LENGTH;
|
|
|
|
subCommand = LOCK_LENGTH;
|
|
|
|
else if (strcmp_P (command + 13, PSTR ("leftMaxKeys")) == 0)
|
|
|
|
else if (strcmp_P(command + 13, PSTR("leftMaxKeys")) == 0)
|
|
|
|
subCommand = LEFT_MAX;
|
|
|
|
subCommand = LEFT_MAX;
|
|
|
|
else if (strcmp_P (command + 13, PSTR ("rightMaxKeys")) == 0)
|
|
|
|
else if (strcmp_P(command + 13, PSTR("rightMaxKeys")) == 0)
|
|
|
|
subCommand = RIGHT_MAX;
|
|
|
|
subCommand = RIGHT_MAX;
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
switch (subCommand) {
|
|
|
|
switch (subCommand) {
|
|
|
|
case IDLE_TIME_LIMIT:
|
|
|
|
case IDLE_TIME_LIMIT:
|
|
|
|
if (Serial.peek () == '\n') {
|
|
|
|
if (Serial.peek() == '\n') {
|
|
|
|
Serial.println (settings.idleTimeLimit);
|
|
|
|
Serial.println(settings.idleTimeLimit);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
settings.idleTimeLimit = Serial.parseInt ();
|
|
|
|
settings.idleTimeLimit = Serial.parseInt();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case LOCK_TIMEOUT:
|
|
|
|
case LOCK_TIMEOUT:
|
|
|
|
if (Serial.peek () == '\n') {
|
|
|
|
if (Serial.peek() == '\n') {
|
|
|
|
Serial.println (settings.lockTimeOut);
|
|
|
|
Serial.println(settings.lockTimeOut);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
settings.lockTimeOut = Serial.parseInt ();
|
|
|
|
settings.lockTimeOut = Serial.parseInt();
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LOCK_LENGTH:
|
|
|
|
|
|
|
|
if (Serial.peek () == '\n') {
|
|
|
|
|
|
|
|
Serial.println (settings.lockLength);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
settings.lockLength = Serial.parseInt ();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LEFT_MAX:
|
|
|
|
|
|
|
|
if (Serial.peek () == '\n') {
|
|
|
|
|
|
|
|
Serial.println (settings.leftHandMaxKeys);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
settings.leftHandMaxKeys = Serial.parseInt ();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RIGHT_MAX:
|
|
|
|
|
|
|
|
if (Serial.peek () == '\n') {
|
|
|
|
|
|
|
|
Serial.println (settings.rightHandMaxKeys);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
settings.rightHandMaxKeys = Serial.parseInt ();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LOCK_LENGTH:
|
|
|
|
|
|
|
|
if (Serial.peek() == '\n') {
|
|
|
|
|
|
|
|
Serial.println(settings.lockLength);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
settings.lockLength = Serial.parseInt();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LEFT_MAX:
|
|
|
|
|
|
|
|
if (Serial.peek() == '\n') {
|
|
|
|
|
|
|
|
Serial.println(settings.leftHandMaxKeys);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
settings.leftHandMaxKeys = Serial.parseInt();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RIGHT_MAX:
|
|
|
|
|
|
|
|
if (Serial.peek() == '\n') {
|
|
|
|
|
|
|
|
Serial.println(settings.rightHandMaxKeys);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
settings.rightHandMaxKeys = Serial.parseInt();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EEPROM.put (settingsBase, settings);
|
|
|
|
EEPROM.put(settingsBase, settings);
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // namespace KaleidoscopePlugins
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
KaleidoscopePlugins::TypingBreaks TypingBreaks;
|
|
|
|
KaleidoscopePlugins::TypingBreaks TypingBreaks;
|
|
|
|
|
|
|
|
|
|
|
|
__attribute__((weak))
|
|
|
|
__attribute__((weak))
|
|
|
|
void
|
|
|
|
void
|
|
|
|
TypingBreak (bool isLocked) {
|
|
|
|
TypingBreak(bool isLocked) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|