|
|
@ -60,218 +60,221 @@ bool OneShot::shouldCancelStickies = false;
|
|
|
|
|
|
|
|
|
|
|
|
// ---- OneShot stuff ----
|
|
|
|
// ---- OneShot stuff ----
|
|
|
|
void
|
|
|
|
void
|
|
|
|
OneShot::injectNormalKey (uint8_t idx, uint8_t keyState) {
|
|
|
|
OneShot::injectNormalKey(uint8_t idx, uint8_t keyState) {
|
|
|
|
Key key;
|
|
|
|
Key key;
|
|
|
|
|
|
|
|
|
|
|
|
if (idx < 8) {
|
|
|
|
if (idx < 8) {
|
|
|
|
key.flags = Key_LeftControl.flags;
|
|
|
|
key.flags = Key_LeftControl.flags;
|
|
|
|
key.keyCode = Key_LeftControl.keyCode + idx;
|
|
|
|
key.keyCode = Key_LeftControl.keyCode + idx;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
key.flags = KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP;
|
|
|
|
key.flags = KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP;
|
|
|
|
key.keyCode = MOMENTARY_OFFSET + idx - 8;
|
|
|
|
key.keyCode = MOMENTARY_OFFSET + idx - 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
handle_keyswitch_event (key, UNKNOWN_KEYSWITCH_LOCATION, keyState | INJECTED);
|
|
|
|
handle_keyswitch_event(key, UNKNOWN_KEYSWITCH_LOCATION, keyState | INJECTED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
OneShot::activateOneShot (uint8_t idx) {
|
|
|
|
OneShot::activateOneShot(uint8_t idx) {
|
|
|
|
injectNormalKey (idx, IS_PRESSED);
|
|
|
|
injectNormalKey(idx, IS_PRESSED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
OneShot::cancelOneShot (uint8_t idx) {
|
|
|
|
OneShot::cancelOneShot(uint8_t idx) {
|
|
|
|
clearOneShot (idx);
|
|
|
|
clearOneShot(idx);
|
|
|
|
injectNormalKey (idx, WAS_PRESSED);
|
|
|
|
injectNormalKey(idx, WAS_PRESSED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
OneShot::mask (byte row, byte col) {
|
|
|
|
OneShot::mask(byte row, byte col) {
|
|
|
|
if (row >= ROWS || col >= COLS)
|
|
|
|
if (row >= ROWS || col >= COLS)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (col >= 8) {
|
|
|
|
if (col >= 8) {
|
|
|
|
col = col - 8;
|
|
|
|
col = col - 8;
|
|
|
|
rightMask |= SCANBIT (row, col);
|
|
|
|
rightMask |= SCANBIT(row, col);
|
|
|
|
} else
|
|
|
|
} else {
|
|
|
|
leftMask |= SCANBIT (row, col);
|
|
|
|
leftMask |= SCANBIT(row, col);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
OneShot::unmask (byte row, byte col) {
|
|
|
|
OneShot::unmask(byte row, byte col) {
|
|
|
|
if (row >= ROWS || col >= COLS)
|
|
|
|
if (row >= ROWS || col >= COLS)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (col >= 8) {
|
|
|
|
if (col >= 8) {
|
|
|
|
col = col - 8;
|
|
|
|
col = col - 8;
|
|
|
|
rightMask &= ~(SCANBIT (row, col));
|
|
|
|
rightMask &= ~(SCANBIT(row, col));
|
|
|
|
} else
|
|
|
|
} else {
|
|
|
|
leftMask &= ~(SCANBIT (row, col));
|
|
|
|
leftMask &= ~(SCANBIT(row, col));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
bool
|
|
|
|
OneShot::isMasked (byte row, byte col) {
|
|
|
|
OneShot::isMasked(byte row, byte col) {
|
|
|
|
if (row >= ROWS || col >= COLS)
|
|
|
|
if (row >= ROWS || col >= COLS)
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
if (col >= 8) {
|
|
|
|
if (col >= 8) {
|
|
|
|
col = col - 8;
|
|
|
|
col = col - 8;
|
|
|
|
return rightMask & SCANBIT (row, col);
|
|
|
|
return rightMask & SCANBIT(row, col);
|
|
|
|
} else
|
|
|
|
} else {
|
|
|
|
return leftMask & SCANBIT (row, col);
|
|
|
|
return leftMask & SCANBIT(row, col);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Key
|
|
|
|
Key
|
|
|
|
OneShot::eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState) {
|
|
|
|
OneShot::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState) {
|
|
|
|
uint8_t idx;
|
|
|
|
uint8_t idx;
|
|
|
|
|
|
|
|
|
|
|
|
if (keyState & INJECTED)
|
|
|
|
if (keyState & INJECTED)
|
|
|
|
return mappedKey;
|
|
|
|
return mappedKey;
|
|
|
|
|
|
|
|
|
|
|
|
if (!State.all) {
|
|
|
|
|
|
|
|
if (!isOS (mappedKey)) {
|
|
|
|
|
|
|
|
if (isMasked (row, col)) {
|
|
|
|
|
|
|
|
if (key_toggled_off (keyState))
|
|
|
|
|
|
|
|
unmask (row, col);
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return mappedKey;
|
|
|
|
if (!State.all) {
|
|
|
|
}
|
|
|
|
if (!isOS(mappedKey)) {
|
|
|
|
|
|
|
|
if (isMasked(row, col)) {
|
|
|
|
|
|
|
|
if (key_toggled_off(keyState))
|
|
|
|
|
|
|
|
unmask(row, col);
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
idx = mappedKey.raw - OS_FIRST;
|
|
|
|
return mappedKey;
|
|
|
|
if (key_toggled_off (keyState)) {
|
|
|
|
}
|
|
|
|
clearPressed (idx);
|
|
|
|
|
|
|
|
} else if (key_toggled_on (keyState)) {
|
|
|
|
|
|
|
|
startTime = millis ();
|
|
|
|
|
|
|
|
setPressed (idx);
|
|
|
|
|
|
|
|
setOneShot (idx);
|
|
|
|
|
|
|
|
saveAsPrevious (mappedKey);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
activateOneShot (idx);
|
|
|
|
idx = mappedKey.raw - OS_FIRST;
|
|
|
|
}
|
|
|
|
if (key_toggled_off(keyState)) {
|
|
|
|
|
|
|
|
clearPressed(idx);
|
|
|
|
|
|
|
|
} else if (key_toggled_on(keyState)) {
|
|
|
|
|
|
|
|
startTime = millis();
|
|
|
|
|
|
|
|
setPressed(idx);
|
|
|
|
|
|
|
|
setOneShot(idx);
|
|
|
|
|
|
|
|
saveAsPrevious(mappedKey);
|
|
|
|
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
activateOneShot(idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!key_is_pressed (keyState) && !key_was_pressed (keyState))
|
|
|
|
return Key_NoKey;
|
|
|
|
return mappedKey;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!key_is_pressed(keyState) && !key_was_pressed(keyState))
|
|
|
|
|
|
|
|
return mappedKey;
|
|
|
|
|
|
|
|
|
|
|
|
if (isOS (mappedKey)) {
|
|
|
|
if (isOS(mappedKey)) {
|
|
|
|
idx = mappedKey.raw - OS_FIRST;
|
|
|
|
idx = mappedKey.raw - OS_FIRST;
|
|
|
|
|
|
|
|
|
|
|
|
if (isSticky (idx)) {
|
|
|
|
if (isSticky(idx)) {
|
|
|
|
if (key_toggled_on (keyState)) { // maybe on _off instead?
|
|
|
|
if (key_toggled_on(keyState)) { // maybe on _off instead?
|
|
|
|
saveAsPrevious (mappedKey);
|
|
|
|
saveAsPrevious(mappedKey);
|
|
|
|
clearSticky (idx);
|
|
|
|
clearSticky(idx);
|
|
|
|
cancelOneShot (idx);
|
|
|
|
cancelOneShot(idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (key_toggled_off (keyState)) {
|
|
|
|
if (key_toggled_off(keyState)) {
|
|
|
|
clearPressed (idx);
|
|
|
|
clearPressed(idx);
|
|
|
|
if ((millis () - startTime) >= holdTimeOut) {
|
|
|
|
if ((millis() - startTime) >= holdTimeOut) {
|
|
|
|
cancelOneShot (idx);
|
|
|
|
cancelOneShot(idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (key_toggled_on (keyState)) {
|
|
|
|
|
|
|
|
setPressed (idx);
|
|
|
|
|
|
|
|
if (isSameAsPrevious (mappedKey)) {
|
|
|
|
|
|
|
|
setSticky (idx);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
saveAsPrevious (mappedKey);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
startTime = millis ();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setOneShot (idx);
|
|
|
|
|
|
|
|
saveAsPrevious (mappedKey);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
activateOneShot (idx);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
if (key_toggled_on(keyState)) {
|
|
|
|
}
|
|
|
|
setPressed(idx);
|
|
|
|
|
|
|
|
if (isSameAsPrevious(mappedKey)) {
|
|
|
|
|
|
|
|
setSticky(idx);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
saveAsPrevious(mappedKey);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
startTime = millis();
|
|
|
|
|
|
|
|
|
|
|
|
// ordinary key here, with some event
|
|
|
|
setOneShot(idx);
|
|
|
|
|
|
|
|
saveAsPrevious(mappedKey);
|
|
|
|
|
|
|
|
|
|
|
|
if (key_is_pressed (keyState)) {
|
|
|
|
activateOneShot(idx);
|
|
|
|
mask (row, col);
|
|
|
|
}
|
|
|
|
saveAsPrevious (mappedKey);
|
|
|
|
}
|
|
|
|
shouldCancel = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return mappedKey;
|
|
|
|
return Key_NoKey;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ordinary key here, with some event
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (key_is_pressed(keyState)) {
|
|
|
|
|
|
|
|
mask(row, col);
|
|
|
|
|
|
|
|
saveAsPrevious(mappedKey);
|
|
|
|
|
|
|
|
shouldCancel = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return mappedKey;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
OneShot::loopHook (bool postClear) {
|
|
|
|
OneShot::loopHook(bool postClear) {
|
|
|
|
if (!State.all)
|
|
|
|
if (!State.all)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (postClear) {
|
|
|
|
if (postClear) {
|
|
|
|
if (hasTimedOut ())
|
|
|
|
if (hasTimedOut())
|
|
|
|
cancel ();
|
|
|
|
cancel();
|
|
|
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < 32; i++) {
|
|
|
|
for (uint8_t i = 0; i < 32; i++) {
|
|
|
|
if (shouldCancel) {
|
|
|
|
if (shouldCancel) {
|
|
|
|
if (isSticky (i)) {
|
|
|
|
if (isSticky(i)) {
|
|
|
|
if (shouldCancelStickies) {
|
|
|
|
if (shouldCancelStickies) {
|
|
|
|
clearSticky (i);
|
|
|
|
clearSticky(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (isOneShot (i) && !isPressed (i)) {
|
|
|
|
} else if (isOneShot(i) && !isPressed(i)) {
|
|
|
|
cancelOneShot (i);
|
|
|
|
cancelOneShot(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (shouldCancel) {
|
|
|
|
if (shouldCancel) {
|
|
|
|
shouldCancel = false;
|
|
|
|
shouldCancel = false;
|
|
|
|
shouldCancelStickies = false;
|
|
|
|
shouldCancelStickies = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
|
|
if (isOneShot (i)) {
|
|
|
|
if (isOneShot(i)) {
|
|
|
|
activateOneShot (i);
|
|
|
|
activateOneShot(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --- glue code ---
|
|
|
|
// --- glue code ---
|
|
|
|
|
|
|
|
|
|
|
|
OneShot::OneShot (void) {
|
|
|
|
OneShot::OneShot(void) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
OneShot::begin (void) {
|
|
|
|
OneShot::begin(void) {
|
|
|
|
event_handler_hook_use (eventHandlerHook);
|
|
|
|
event_handler_hook_use(eventHandlerHook);
|
|
|
|
loop_hook_use (loopHook);
|
|
|
|
loop_hook_use(loopHook);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
bool
|
|
|
|
OneShot::isActive (void) {
|
|
|
|
OneShot::isActive(void) {
|
|
|
|
return (State.all && !hasTimedOut ());
|
|
|
|
return (State.all && !hasTimedOut());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
bool
|
|
|
|
OneShot::isModifierActive (Key key) {
|
|
|
|
OneShot::isModifierActive(Key key) {
|
|
|
|
if (key.raw < Key_LeftControl.raw || key.raw > Key_RightGui.raw)
|
|
|
|
if (key.raw < Key_LeftControl.raw || key.raw > Key_RightGui.raw)
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
return isOneShot (key.keyCode - Key_LeftControl.keyCode);
|
|
|
|
return isOneShot(key.keyCode - Key_LeftControl.keyCode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
OneShot::cancel (bool withStickies) {
|
|
|
|
OneShot::cancel(bool withStickies) {
|
|
|
|
shouldCancel = true;
|
|
|
|
shouldCancel = true;
|
|
|
|
shouldCancelStickies = withStickies;
|
|
|
|
shouldCancelStickies = withStickies;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
OneShot::inject (Key key, uint8_t keyState) {
|
|
|
|
OneShot::inject(Key key, uint8_t keyState) {
|
|
|
|
eventHandlerHook (key, 255, 255, keyState);
|
|
|
|
eventHandlerHook(key, 255, 255, keyState);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|