diff --git a/plugins/Kaleidoscope-CharShift/src/kaleidoscope/plugin/CharShift.h b/plugins/Kaleidoscope-CharShift/src/kaleidoscope/plugin/CharShift.h
index 293f88fd..2a34da25 100644
--- a/plugins/Kaleidoscope-CharShift/src/kaleidoscope/plugin/CharShift.h
+++ b/plugins/Kaleidoscope-CharShift/src/kaleidoscope/plugin/CharShift.h
@@ -86,6 +86,8 @@ class CharShift : public Plugin {
readKeyPair_ = f;
}
+ friend class CharShiftConfig;
+
private:
// A pointer to an array of `KeyPair` objects in PROGMEM
static KeyPair const * progmem_keypairs_;
@@ -110,10 +112,34 @@ class CharShift : public Plugin {
static KeyPair readKeyPairFromProgmem(uint8_t n);
};
+class CharShiftConfig: public Plugin {
+ public:
+ CharShiftConfig() {}
+
+ EventHandlerResult onNameQuery();
+ EventHandlerResult onFocusEvent(const char *command);
+
+ static void setup(uint8_t dynamic_offset, uint8_t max_pairs);
+
+ private:
+ static uint8_t max_pairs_;
+ static uint16_t storage_base_;
+ static uint8_t dynamic_offset_;
+
+ static uint8_t numEEPROMPairs() {
+ return max_pairs_;
+ }
+ static CharShift::KeyPair readKeyPairFromEEPROM(uint8_t n);
+
+ static uint8_t numPairs();
+ static CharShift::KeyPair readKeyPair(uint8_t n);
+};
+
} // namespace plugin
} // namespace kaleidoscope
extern kaleidoscope::plugin::CharShift CharShift;
+extern kaleidoscope::plugin::CharShiftConfig CharShiftConfig;
/// Define an array of `KeyPair` objects in PROGMEM
///
diff --git a/plugins/Kaleidoscope-CharShift/src/kaleidoscope/plugin/CharShiftConfig.cpp b/plugins/Kaleidoscope-CharShift/src/kaleidoscope/plugin/CharShiftConfig.cpp
new file mode 100644
index 00000000..7fc849ea
--- /dev/null
+++ b/plugins/Kaleidoscope-CharShift/src/kaleidoscope/plugin/CharShiftConfig.cpp
@@ -0,0 +1,110 @@
+/* -*- mode: c++ -*-
+ * Kaleidoscope-CharShift -- Independently assign shifted and unshifted symbols
+ * Copyright (C) 2021 Keyboard.io, Inc
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ */
+
+#include "kaleidoscope/plugin/CharShift.h"
+
+#include
+#include
+
+#include "kaleidoscope/Runtime.h"
+
+namespace kaleidoscope {
+namespace plugin {
+
+// =============================================================================
+// CharShiftConfig class variables
+
+uint8_t CharShiftConfig::max_pairs_;
+uint8_t CharShiftConfig::dynamic_offset_;
+uint16_t CharShiftConfig::storage_base_;
+
+// =============================================================================
+// Event handlers
+
+EventHandlerResult CharShiftConfig::onNameQuery() {
+ return ::Focus.sendName(F("CharShiftConfig"));
+}
+
+EventHandlerResult CharShiftConfig::onFocusEvent(const char *command) {
+ if (::Focus.handleHelp(command, PSTR("charshift.map")))
+ return EventHandlerResult::OK;
+
+ if (strcmp_P(command, PSTR("charshift.map")) != 0)
+ return EventHandlerResult::OK;
+
+ if (::Focus.isEOL()) {
+ // We dump key by key, rather than pairs, because the end result is the
+ // same, and dumping one by one is less code.
+ for (uint16_t i = 0; i < max_pairs_ * 2; i += 2) {
+ Key k;
+
+ Runtime.storage().get(storage_base_ + i, k);
+ ::Focus.send(k);
+ }
+ } else {
+ uint16_t pos = 0;
+
+ // We read one key at a time, rather than a keypair, to better handle
+ // partials and failure, and to make the code simpler.
+ while (!::Focus.isEOL()) {
+ Key k;
+
+ ::Focus.read(k);
+ Runtime.storage().put(storage_base_ + pos, k);
+ pos += 2;
+ }
+ Runtime.storage().commit();
+ }
+
+ return EventHandlerResult::EVENT_CONSUMED;
+}
+
+// =============================================================================
+// Support functions
+
+void CharShiftConfig::setup(uint8_t dynamic_offset, uint8_t max_pairs) {
+ dynamic_offset_ = dynamic_offset;
+ max_pairs_ = max_pairs;
+
+ storage_base_ = ::EEPROMSettings.requestSlice(max_pairs * 4);
+ ::CharShift.setNumKeyPairsFunction(numPairs);
+ ::CharShift.setReadKeyPairFunction(readKeyPair);
+}
+
+CharShift::KeyPair CharShiftConfig::readKeyPairFromEEPROM(uint8_t n) {
+ uint16_t pos = storage_base_ + n * 4; // 4: Size of a keypair.
+ uint16_t raw_lower = Runtime.storage().read(pos);
+ uint16_t raw_upper = Runtime.storage().read(pos + 2);
+
+ return CharShift::KeyPair(Key(raw_lower), Key(raw_upper));
+}
+
+uint8_t CharShiftConfig::numPairs() {
+ return CharShift::numProgmemKeyPairs() + numEEPROMPairs();
+}
+
+CharShift::KeyPair CharShiftConfig::readKeyPair(uint8_t n) {
+ if (n < dynamic_offset_) {
+ return CharShift::readKeyPairFromProgmem(n);
+ }
+ return readKeyPairFromEEPROM(n - dynamic_offset_);
+}
+
+} // namespace plugin
+} // namespace kaleidoscope
+
+kaleidoscope::plugin::CharShiftConfig CharShiftConfig;