diff options
Diffstat (limited to 'keyboards/gboards/engine')
-rw-r--r-- | keyboards/gboards/engine/config.h | 0 | ||||
-rw-r--r-- | keyboards/gboards/engine/engine.c | 458 | ||||
-rw-r--r-- | keyboards/gboards/engine/engine.h | 104 | ||||
-rw-r--r-- | keyboards/gboards/engine/keymap_engine.h | 121 |
4 files changed, 0 insertions, 683 deletions
diff --git a/keyboards/gboards/engine/config.h b/keyboards/gboards/engine/config.h deleted file mode 100644 index e69de29bb2..0000000000 --- a/keyboards/gboards/engine/config.h +++ /dev/null diff --git a/keyboards/gboards/engine/engine.c b/keyboards/gboards/engine/engine.c deleted file mode 100644 index 9094b7905a..0000000000 --- a/keyboards/gboards/engine/engine.c +++ /dev/null @@ -1,458 +0,0 @@ -/* This is a stripped down version of the Georgi engine meant for use with - * Ginni. As such serial-Steno features are disabled, chords are 16bits and - * crap is removed where possible - * - * Do not use this on anything other then Ginny if you want to be sane - */ -#include "engine.h" - -// Chord state -C_SIZE cChord = 0; // Current Chord -int chordIndex = 0; // Keys in previousachord -C_SIZE pressed = 0; // number of held keys -C_SIZE chordState[32]; // Full Chord history -#define QWERBUF 24 // Size of chords to buffer for output - -bool repeatFlag = false; // Should we repeat? -C_SIZE pChord = 0; // Previous Chord -C_SIZE stickyBits = 0; // Or'd with every incoming press -int pChordIndex = 0; // Keys in previousachord -C_SIZE pChordState[32]; // Previous chord sate - -// Key Dicts -extern const struct keyEntry keyDict[]; -extern const struct comboEntry cmbDict[]; -extern const struct funcEntry funDict[]; -extern const struct stringEntry strDict[]; -extern const struct specialEntry spcDict[]; -extern size_t specialLen; -extern size_t stringLen; -extern size_t funcsLen; -extern size_t keyLen; -extern size_t comboLen; - -// Mode state -enum MODE { STENO = 0, QWERTY, COMMAND }; -enum MODE pMode; -enum MODE cMode = QWERTY; - -// Command State -#define MAX_CMD_BUF 20 -uint8_t CMDLEN = 0; -uint8_t CMDBUF[MAX_CMD_BUF]; - -// Key Repeat state -bool inChord = false; -bool repEngaged = false; -uint16_t repTimer = 0; -#define REP_INIT_DELAY 750 -#define REP_DELAY 25 - -// Mousekeys state -bool inMouse = false; -int8_t mousePress; - -// All processing done at chordUp goes through here -void processKeysUp() { - // Check for mousekeys, this is release -#ifdef MOUSEKEY_ENABLE - if (inMouse) { - inMouse = false; - mousekey_off(mousePress); - mousekey_send(); - } -#endif - - // handle command mode - if (cChord == COMMAND_MODE) { -#ifndef NO_DEBUG - uprintf("COMMAND Toggle\n"); -#endif - if (cMode != COMMAND) { // Entering Command Mode - CMDLEN = 0; - pMode = cMode; - cMode = COMMAND; - } else { // Exiting Command Mode - cMode = pMode; - - // Press all and release all - for (int i = 0; i < CMDLEN; i++) { - register_code(CMDBUF[i]); - } - clear_keyboard(); - } - } - - // Process and reset state - processChord(); - cChord = pressed; - inChord = false; - chordIndex = 0; - clear_keyboard(); - repEngaged = false; - for (int i = 0; i < 32; i++) chordState[i] = 0xFFFF; -} - -// Update Chord State -bool process_record_kb(uint16_t keycode, keyrecord_t *record) { - // Everything happens in here when steno keys come in. - // Bail on keyup - - // Update key repeat timers - repTimer = timer_read(); - bool pr = record->event.pressed; - // Switch on the press adding to chord - switch (keycode) { - ENGINE_CONFIG - default: - return true; - } - - // Handle any postprocessing - - // All keys up, send it! - if (inChord && !pr && (pressed & IN_CHORD_MASK) == 0) { - processKeysUp(); - return false; - } - if (pressed == 0 && !pr) { - processKeysUp(); - return false; - } - - cChord |= pressed; - cChord = process_engine_post(cChord, keycode, record); - inChord = (cChord & IN_CHORD_MASK) != 0; - - // Store previous state for fastQWER - if (pr) { - chordState[chordIndex] = cChord; - chordIndex++; - } - -#ifndef NO_DEBUG - uprintf("Chord: %u\n", cChord); -#endif - return false; -} -void matrix_scan_user(void) { - // We abuse this for early sending of key - // Key repeat only on QWER/SYMB layers - if (cMode != QWERTY || !inChord) return; - - // Check timers -#ifndef NO_HOLD - if (!repEngaged && timer_elapsed(repTimer) > REP_INIT_DELAY) { - // Process Key for report - processChord(); - - // Send report to host - send_keyboard_report(); - repEngaged = true; - } -#endif -}; - -// Try and match cChord -C_SIZE mapKeys(C_SIZE chord, bool lookup) { - lookup = lookup || repEngaged; -#ifndef NO_DEBUG - if (!lookup) uprint("SENT!\n"); -#endif - // Single key chords - for (int i = 0; i < keyLen; i++) { - if (keyDict[i].chord == chord) { - if (!lookup) SEND(keyDict[i].key); - return chord; - } - } - - // strings - for (int i = 0; i < stringLen; i++) { - struct stringEntry fromPgm; - memcpy_P(&fromPgm, &strDict[i], sizeof(stringEntry_t)); - if (fromPgm.chord == chord) { - if (!lookup) { - if (get_mods() & (MOD_LSFT | MOD_RSFT)) { - set_mods(get_mods() & ~(MOD_LSFT | MOD_RSFT)); - set_oneshot_mods(MOD_LSFT); - } - send_string_P((PGM_P)(fromPgm.str)); - } - return chord; - } - } - - // combos - for (int i = 0; i < comboLen; i++) { - struct comboEntry fromPgm; - memcpy_P(&fromPgm, &cmbDict[i], sizeof(comboEntry_t)); - if (fromPgm.chord == chord) { -#ifndef NO_DEBUG - uprintf("%d found combo\n", i); -#endif - - if (!lookup) { - uint8_t comboKeys[COMBO_MAX]; - memcpy_P(&comboKeys, fromPgm.keys, sizeof(uint8_t) * COMBO_MAX); - for (int j = 0; j < COMBO_MAX; j++) -#ifndef NO_DEBUG - uprintf("Combo [%u]: %u\n", j, comboKeys[j]); -#endif - - for (int j = 0; (j < COMBO_MAX) && (comboKeys[j] != COMBO_END); j++) { -#ifndef NO_DEBUG - uprintf("Combo [%u]: %u\n", j, comboKeys[j]); -#endif - SEND(comboKeys[j]); - } - } - return chord; - } - } - - // functions - for (int i = 0; i < funcsLen; i++) { - if (funDict[i].chord == chord) { - if (!lookup) funDict[i].act(); - return chord; - } - } - - // Special handling - for (int i = 0; i < specialLen; i++) { - if (spcDict[i].chord == chord) { - if (!lookup) { - uint16_t arg = spcDict[i].arg; - switch (spcDict[i].action) { - case SPEC_STICKY: - SET_STICKY(arg); - break; - case SPEC_REPEAT: - REPEAT(); - break; - case SPEC_CLICK: - CLICK_MOUSE((uint8_t)arg); - break; - case SPEC_SWITCH: - SWITCH_LAYER(arg); - break; - default: - SEND_STRING("Invalid Special in Keymap"); - } - } - return chord; - } - } - - if ((chord & IN_CHORD_MASK) && (chord & IN_CHORD_MASK) != chord && mapKeys((chord & IN_CHORD_MASK), true) == (chord & IN_CHORD_MASK)) { -#ifndef NO_DEBUG - uprintf("Try with ignore mask:%u\n", (chord & IN_CHORD_MASK)); -#endif - mapKeys((chord & ~IN_CHORD_MASK), lookup); - mapKeys((chord & IN_CHORD_MASK), lookup); - return chord; - } -#ifndef NO_DEBUG - uprintf("Reached end\n"); -#endif - return 0; -} -// Traverse the chord history to a given point -// Returns the mask to use -void processChord(void) { - // Save the clean chord state - C_SIZE savedChord = cChord; - - // Apply Stick Bits if needed - if (stickyBits != 0) { - cChord |= stickyBits; - for (int i = 0; i <= chordIndex; i++) chordState[i] |= stickyBits; - } - - // First we test if a whole chord was passsed - // If so we just run it handling repeat logic - if (mapKeys(cChord, true) == cChord) { - mapKeys(cChord, false); - // Repeat logic - if (repeatFlag) { -#ifndef NO_DEBUG - uprintf("repeating?\n"); -#endif - restoreState(); - repeatFlag = false; - processChord(); - } else { - saveState(cChord); - } - return; - } - - C_SIZE next = process_chord_getnext(cChord); - if (next && next != cChord) { -#ifndef NO_DEBUG - uprintf("Trying next candidate: %u\n", next); -#endif - if (mapKeys(next, true) == next) { - mapKeys(next, false); - // Repeat logic - if (repeatFlag) { -#ifndef NO_DEBUG - uprintf("repeating?\n"); -#endif - restoreState(); - repeatFlag = false; - processChord(); - } else { - saveState(cChord); - } - return; - } - } - -#ifndef NO_DEBUG - uprintf("made it past the maw\n"); -#endif - - // Iterate through chord picking out the individual - // and longest chords - C_SIZE bufChords[QWERBUF]; - int bufLen = 0; - C_SIZE mask = 0; - - // We iterate over it multiple times to catch the longest - // chord. Then that gets addded to the mask and re run. - while (savedChord != mask) { - C_SIZE test = 0; - C_SIZE longestChord = 0; - - for (int i = 0; i <= chordIndex; i++) { - cChord = chordState[i] & ~mask; - if (cChord == 0) continue; - - test = mapKeys(cChord, true); - if (test != 0) { - longestChord = test; - } - } - - mask |= longestChord; - bufChords[bufLen] = longestChord; - bufLen++; - - // That's a loop of sorts, halt processing - if (bufLen >= QWERBUF) { -#ifndef NO_DEBUG - uprintf("looped. exiting"); -#endif - return; - } - } - - // Now that the buffer is populated, we run it - for (int i = 0; i < bufLen; i++) { - cChord = bufChords[i]; -#ifndef NO_DEBUG - uprintf("sending: %u\n", cChord); -#endif - mapKeys(cChord, false); - } - - // Save state in case of repeat - if (!repeatFlag) { - saveState(savedChord); - } - - // Restore cChord for held repeat - cChord = savedChord; - return; -} -void saveState(C_SIZE cleanChord) { - pChord = cleanChord; - pChordIndex = chordIndex; - for (int i = 0; i < 32; i++) pChordState[i] = chordState[i]; -} -void restoreState() { - cChord = pChord; - chordIndex = pChordIndex; - for (int i = 0; i < 32; i++) chordState[i] = pChordState[i]; -} - -// Macros for calling from keymap.c -void SEND(uint8_t kc) { - // Send Keycode, Does not work for Quantum Codes - if (cMode == COMMAND && CMDLEN < MAX_CMD_BUF) { -#ifndef NO_DEBUG - uprintf("CMD LEN: %d BUF: %d\n", CMDLEN, MAX_CMD_BUF); -#endif - CMDBUF[CMDLEN] = kc; - CMDLEN++; - } - - if (cMode != COMMAND) register_code(kc); - return; -} -void REPEAT(void) { - if (cMode != QWERTY) return; - - repeatFlag = true; - return; -} -void SET_STICKY(C_SIZE stick) { - stickyBits ^= stick; - return; -} -void CLICK_MOUSE(uint8_t kc) { -#ifdef MOUSEKEY_ENABLE - mousekey_on(kc); - mousekey_send(); - - // Store state for later use - inMouse = true; - mousePress = kc; -#endif -} -void SWITCH_LAYER(int layer) { -#ifndef NO_ACTION_LAYER - if (keymapsCount >= layer) layer_on(layer); -#endif -} -uint8_t bitpop_v(C_SIZE val) { -#if C_SIZE == uint8_t - return bitpop(val); -#elif C_SIZE == uint16_t - return bitpop16(val); -#elif C_SIZE == uint32_t - return bitpop32(val); -#elif C_SIZE == uint64_t - uint8_t n = 0; - if (bits >> 32) { - bits >>= 32; - n += 32; - } - if (bits >> 16) { - bits >>= 16; - n += 16; - } - if (bits >> 8) { - bits >>= 8; - n += 8; - } - if (bits >> 4) { - bits >>= 4; - n += 4; - } - if (bits >> 2) { - bits >>= 2; - n += 2; - } - if (bits >> 1) { - bits >>= 1; - n += 1; - } - return n; -#else -# error unsupported C_SIZE -#endif -} -__attribute__((weak)) C_SIZE process_engine_post(C_SIZE cur_chord, uint16_t keycode, keyrecord_t *record) { return cur_chord; } diff --git a/keyboards/gboards/engine/engine.h b/keyboards/gboards/engine/engine.h deleted file mode 100644 index 5b9d5b0ecb..0000000000 --- a/keyboards/gboards/engine/engine.h +++ /dev/null @@ -1,104 +0,0 @@ -/* 2019, g Heavy Industries - Blessed mother of Christ, please keep this readable - and protect us from segfaults. For thine is the clock, - the slave and the master. Until we return from main. - - Amen. - - This is a stripped down version of the Georgi engine meant for use with - . As such serial-Steno features are disabled, chords are 16bits and - crap is removed where possible -*/ - -#include QMK_KEYBOARD_H -#pragma once -#include "keymap.h" -#include <string.h> -#include <stdint.h> -#include <stdio.h> -#include "config_engine.h" -#include <avr/pgmspace.h> -#include "wait.h" - -// Maximum values for combos -#define COMBO_END 0x00 - -// In memory chord datatypes -enum specialActions { - SPEC_STICKY, - SPEC_REPEAT, - SPEC_CLICK, - SPEC_SWITCH, -}; -struct funcEntry { - C_SIZE chord; - void (*act)(void); -} funcEntry_t; -struct stringEntry { - C_SIZE chord; - PGM_P str; -} stringEntry_t; -struct comboEntry { - C_SIZE chord; - PGM_P keys; -} comboEntry_t; -struct keyEntry { - C_SIZE chord; - uint8_t key; -} keyEntry_t; -struct specialEntry { - C_SIZE chord; - enum specialActions action; - uint16_t arg; -} specialEntry_t; - -// Chord Temps -extern C_SIZE cChord; -extern C_SIZE test; - -// Function defs -void processKeysUp(void); -void processChord(void); -C_SIZE processQwerty(bool lookup); -C_SIZE processFakeSteno(bool lookup); -void saveState(C_SIZE cChord); -void restoreState(void); -uint8_t bitpop_v(C_SIZE val); - -// Macros for use in keymap.c -void SEND(uint8_t kc); -void REPEAT(void); -void SET_STICKY(C_SIZE); -void SWITCH_LAYER(int); -void CLICK_MOUSE(uint8_t); -C_SIZE process_engine_post(C_SIZE cur_chord, uint16_t keycode, keyrecord_t *record); -C_SIZE process_chord_getnext(C_SIZE cur_chord); - -// Keymap helpers -// New Approach, multiple structures -#define P_KEYMAP(chord, keycode) {chord, keycode}, - -#define K_KEYMAP(chord, name, ...) {chord, (PGM_P)&name}, -#define K_ACTION(chord, name, ...) const uint8_t name[] PROGMEM = __VA_ARGS__; - -#define S_KEYMAP(chord, name, string) {chord, (PGM_P)&name}, -#define S_ACTION(chord, name, string) const char name[] PROGMEM = string; - -#define X_KEYMAP(chord, name, func) {chord, name}, -#define X_ACTION(chord, name, func) \ - void name(void) { func } - -#define Z_KEYMAP(chord, act, arg) {chord, act, arg}, - -#define TEST_COLLISION(chord, ...) \ - case chord: \ - break; -#define BLANK(...) - -// Shift to internal representation -// i.e) S(teno)R(ight)F -#define STN(n) ((C_SIZE)1 << n) -#define ENGINE_HOOK(keycode, chord) \ - case keycode: \ - pr ? (pressed |= (chord)) : (pressed &= ~(chord)); \ - break; diff --git a/keyboards/gboards/engine/keymap_engine.h b/keyboards/gboards/engine/keymap_engine.h deleted file mode 100644 index c8a42a052b..0000000000 --- a/keyboards/gboards/engine/keymap_engine.h +++ /dev/null @@ -1,121 +0,0 @@ -/* If for some reason you're still here, maybe due to horror, shock or - * some other godforsaken reason. Meet X Macros. - * - * The we abuse the include system to generate data structures that are - * used by the internal chording engine. The alternative to this is - * using a external generator (Like is done for the ASETNIOP base keymaps) - * With this disgusting bodge, you can just edit your .defs and compile! - */ - -// Clear all X Macros -#define PRES BLANK -#define KEYS BLANK -#define SUBS BLANK -#define EXEC BLANK -#define SPEC BLANK - -// Process single key pushes -#undef PRES -#define PRES P_KEYMAP -const struct keyEntry keyDict[] = { -#include "dicts.def" -}; -#undef PRES -#define PRES BLANK - -// Process Combos -#undef KEYS -#define KEYS K_ACTION -#include "dicts.def" -#undef KEYS -#define KEYS BLANK - -#undef KEYS -#define KEYS K_KEYMAP -const struct comboEntry PROGMEM cmbDict[] = { -#include "dicts.def" -}; -#undef KEYS -#define KEYS BLANK - -// Process String stubs -#undef SUBS -#define SUBS S_ACTION -#include "dicts.def" -#undef SUBS -#define SUBS BLANK - -// Generate dict for strings -#undef SUBS -#define SUBS S_KEYMAP -const struct stringEntry PROGMEM strDict[] = { -#include "dicts.def" -}; -#undef SUBS -#define SUBS BLANK - -// Generate function stubs -#undef EXEC -#define EXEC X_ACTION -#include "dicts.def" -#undef EXEC -#define EXEC BLANK - -// Process the function structure -#undef EXEC -#define EXEC X_KEYMAP -const struct funcEntry funDict[] = { -#include "dicts.def" -}; -#undef EXEC -#define EXEC BLANK - -// Handle Special calls -#undef SPEC -#define SPEC Z_KEYMAP -const struct specialEntry spcDict[] = { -#include "dicts.def" -}; -#undef SPEC -#define SPEC BLANK - -// Test for collisions! -// Switch statement will explode on duplicate -// chords. This will be optimized out -#undef PRES -#undef KEYS -#undef SUBS -#undef EXEC -#undef SPEC -#define PRES TEST_COLLISION -#define KEYS TEST_COLLISION -#define SUBS TEST_COLLISION -#define EXEC TEST_COLLISION -#define SPEC TEST_COLLISION -void testCollisions(void) { - C_SIZE bomb = 0; - switch (bomb) { -#include "dicts.def" - } -} - -// Test for unexpected input -// Should return blank lines for all valid input -#undef PRES -#undef KEYS -#undef SUBS -#undef EXEC -#undef SPEC -#define PRES BLANK -#define KEYS BLANK -#define SUBS BLANK -#define EXEC BLANK -#define SPEC BLANK -#include "dicts.def" - -// Get size data back into the engine -size_t funcsLen = sizeof(funDict) / sizeof(funDict[0]); -size_t stringLen = sizeof(strDict) / sizeof(strDict[0]); -size_t keyLen = sizeof(keyDict) / sizeof(keyDict[0]); -size_t comboLen = sizeof(cmbDict) / sizeof(cmbDict[0]); -size_t specialLen = sizeof(spcDict) / sizeof(spcDict[0]); |