Compare commits

...

4 Commits

Author SHA1 Message Date
Gergely Nagy 0cc060e4a4
wip: focus fix
3 years ago
Gergely Nagy ee36ed6929
CharShift: Migrate to a pluggable storage sub-class
3 years ago
Gergely Nagy 7d6ce8bf45
CharShift: WIP CharShiftConfig
3 years ago
Gergely Nagy f916c2c0d4
CharShift: Transition to using a function pointer instead of overridables
3 years ago

@ -32,19 +32,27 @@ namespace plugin {
// =============================================================================
// CharShift class variables
CharShift::KeyPair const * CharShift::progmem_keypairs_{nullptr};
uint8_t CharShift::num_keypairs_{0};
charshift::Storage * CharShift::storage_;
bool CharShift::reverse_shift_state_{false};
static auto progmem_storage_ = charshift::ProgmemStorage();
// =============================================================================
// Event handlers
// -----------------------------------------------------------------------------
EventHandlerResult CharShift::onSetup() {
if (!storage_) {
storage_ = &progmem_storage_;
}
return EventHandlerResult::OK;
}
EventHandlerResult CharShift::onNameQuery() {
return ::Focus.sendName(F("CharShift"));
}
EventHandlerResult CharShift::onFocusEvent(const char *command) {
return storage_->onFocusEvent(command);
}
// -----------------------------------------------------------------------------
EventHandlerResult CharShift::onKeyEvent(KeyEvent &event) {
@ -117,32 +125,12 @@ bool CharShift::isCharShiftKey(Key key) {
CharShift::KeyPair CharShift::decodeCharShiftKey(Key key) {
uint8_t i = key.getRaw() - ranges::CS_FIRST;
if (i < numKeyPairs()) {
return readKeyPair(i);
if (i < storage_->numKeyPairs()) {
return storage_->readKeyPair(i);
}
return {Key_NoKey, Key_NoKey};
}
// This should be overridden if the KeyPairs array is stored in EEPROM
__attribute__((weak))
uint8_t CharShift::numKeyPairs() {
return numProgmemKeyPairs();
}
// This should be overridden if the KeyPairs array is stored in EEPROM
__attribute__((weak))
CharShift::KeyPair CharShift::readKeyPair(uint8_t n) {
return readKeyPairFromProgmem(n);
}
uint8_t CharShift::numProgmemKeyPairs() {
return num_keypairs_;
}
CharShift::KeyPair CharShift::readKeyPairFromProgmem(uint8_t n) {
return cloneFromProgmem(progmem_keypairs_[n]);
}
} // namespace plugin
} // namespace kaleidoscope

@ -24,6 +24,10 @@
namespace kaleidoscope {
namespace plugin {
namespace charshift {
class Storage;
}
// =============================================================================
/// Kaleidoscope plugin for independently assigning shifted symbols
///
@ -36,9 +40,11 @@ namespace plugin {
class CharShift : public Plugin {
public:
EventHandlerResult onSetup();
EventHandlerResult onNameQuery();
EventHandlerResult onKeyEvent(KeyEvent &event);
EventHandlerResult beforeReportingState(const KeyEvent &event);
EventHandlerResult onFocusEvent(const char *command);
// ---------------------------------------------------------------------------
/// A structure that stores CharShift key pair values
@ -63,24 +69,15 @@ class CharShift : public Plugin {
KeyPair() = default;
};
/// Configure the KeyPairs array in PROGMEM
///
/// This function configures the PROGMEM array of `KeyPair` objects,
/// automatically setting the internal count variable from the size of the
/// `keypairs` array given, which must be a fixed-sized array, not a pointer.
/// Generally, it will be called via the `KEYPAIRS()` preprocessor macro, not
/// directly by user code.
template <uint8_t _num_keypairs>
static void setProgmemKeyPairs(KeyPair const(&keypairs)[_num_keypairs]) {
progmem_keypairs_ = keypairs;
num_keypairs_ = _num_keypairs;
charshift::Storage &storage() {
return *storage_;
}
void setStorage(charshift::Storage *st) {
storage_ = st;
}
private:
// A pointer to an array of `KeyPair` objects in PROGMEM
static KeyPair const * progmem_keypairs_;
// The size of the PROGMEM array of `KeyPair` objects
static uint8_t num_keypairs_;
static charshift::Storage *storage_;
// If a `shift` key needs to be suppressed in `beforeReportingState()`
static bool reverse_shift_state_;
@ -90,25 +87,64 @@ class CharShift : public Plugin {
/// Look up the `KeyPair` specified by the given keymap entry
static KeyPair decodeCharShiftKey(Key key);
};
/// Get the total number of KeyPairs defined
///
/// This function can be overridden in order to store the `KeyPair` array in
/// EEPROM instead of PROGMEM.
static uint8_t numKeyPairs();
namespace charshift {
class Storage {
public:
Storage() {}
static uint8_t numKeyPairs() {
return num_keypairs_;
}
static CharShift::KeyPair readKeyPair(uint8_t n) {
return CharShift::KeyPair(Key_NoKey, Key_NoKey);
}
EventHandlerResult onFocusEvent(const char *command) {
return EventHandlerResult::OK;
}
protected:
static uint8_t num_keypairs_;
};
class ProgmemStorage: public Storage {
public:
static CharShift::KeyPair readKeyPair(uint8_t n);
/// Get the `KeyPair` at the specified index from the defined `KeyPair` array
/// Configure the KeyPairs array in PROGMEM
///
/// This function can be overridden in order to store the `KeyPair` array in
/// EEPROM instead of PROGMEM.
static KeyPair readKeyPair(uint8_t n);
// Default for `keypairsCount()`: size of the PROGMEM array
static uint8_t numProgmemKeyPairs();
// Default for `readKeypair(i)`: fetch the value from PROGMEM
static KeyPair readKeyPairFromProgmem(uint8_t n);
/// This function configures the PROGMEM array of `KeyPair` objects,
/// automatically setting the internal count variable from the size of the
/// `keypairs` array given, which must be a fixed-sized array, not a pointer.
/// Generally, it will be called via the `KEYPAIRS()` preprocessor macro, not
/// directly by user code.
template <uint8_t _num_keypairs>
static void setKeyPairs(CharShift::KeyPair const(&keypairs)[_num_keypairs]) {
keypairs_ = keypairs;
num_keypairs_ = _num_keypairs;
}
private:
// A pointer to an array of `KeyPair` objects in PROGMEM
static CharShift::KeyPair const *keypairs_;
};
class EEPROMStorage: public Storage {
public:
void setup(uint8_t num_pairs);
static CharShift::KeyPair readKeyPair(uint8_t n);
EventHandlerResult onFocusEvent(const char *command);
private:
static uint16_t storage_base_;
};
}
} // namespace plugin
} // namespace kaleidoscope
@ -124,7 +160,7 @@ extern kaleidoscope::plugin::CharShift CharShift;
static kaleidoscope::plugin::CharShift::KeyPair const kp_table[] PROGMEM = { \
keypairs \
}; \
CharShift.setProgmemKeyPairs(kp_table); \
CharShift.storage().setKeyPairs(kp_table); \
}
/// Define an `KeyPair` entry in a keymap

@ -0,0 +1,107 @@
/* -*- 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 <http://www.gnu.org/licenses/>.
*/
#include "kaleidoscope/plugin/CharShift.h"
#include <Kaleidoscope-Ranges.h>
#include <Kaleidoscope-FocusSerial.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include "kaleidoscope/KeyAddr.h"
#include "kaleidoscope/key_defs.h"
#include "kaleidoscope/KeyEvent.h"
#include "kaleidoscope/keyswitch_state.h"
#include "kaleidoscope/progmem_helpers.h"
#include "kaleidoscope/Runtime.h"
namespace kaleidoscope {
namespace plugin {
namespace charshift {
// =============================================================================
// Storage class variables
uint8_t Storage::num_keypairs_;
CharShift::KeyPair const * ProgmemStorage::keypairs_{nullptr};
uint16_t EEPROMStorage::storage_base_;
// =============================================================================
// Progmem Storage
CharShift::KeyPair ProgmemStorage::readKeyPair(uint8_t n) {
return cloneFromProgmem(keypairs_[n]);
}
// =============================================================================
// EEPROM Storage
EventHandlerResult EEPROMStorage::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 < num_keypairs_ * 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;
}
void EEPROMStorage::setup(uint8_t num_keypairs) {
num_keypairs_ = num_keypairs;
storage_base_ = ::EEPROMSettings.requestSlice(num_keypairs * 4);
}
CharShift::KeyPair EEPROMStorage::readKeyPair(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));
}
}
} // namespace plugin
} // namespace kaleidoscope
Loading…
Cancel
Save