This replaces the `Layer.live_composite_keymap_[]` cache with a representation of the keyboard's current state as an array of `Key` objects, one per key on the keyboard. In this new array, an idle key will have the value `Key_Transparent`, and a pressed key will have the value of whatever key it's currently mapped to in the keymap (or whatever value the active set of plugins has assigned to it). A value of `Key_NoKey` will mask that key until it is released. If a plugin returns `ABORT` from its `onKeyswitchEvent()` handler, that means that the keymap cache should not be updated. It's especially important to have this occur after plugins like OneShot and Qukeys, where the key can stay active (or become active) after the physical keyswitch has been released. Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>pull/1024/head
parent
3c2175b062
commit
4a63fe1440
@ -0,0 +1,98 @@
|
||||
/* Kaleidoscope - Firmware for computer input devices
|
||||
* Copyright (C) 2013-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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "kaleidoscope_internal/device.h"
|
||||
#include "kaleidoscope/KeyAddr.h"
|
||||
#include "kaleidoscope/key_defs.h"
|
||||
|
||||
namespace kaleidoscope {
|
||||
|
||||
// A `KeyAddrMap` is a collection of objects, indexed by `KeyAddr`, with one
|
||||
// entry per key on the keyboard.
|
||||
|
||||
template<typename _ContentType, uint8_t _size>
|
||||
class KeyAddrMap {
|
||||
|
||||
private:
|
||||
_ContentType values_[_size]; // NOLINT(runtime/arrays)
|
||||
|
||||
public:
|
||||
typedef KeyAddrMap<_ContentType, _size> ThisType;
|
||||
|
||||
// Return the number of `Key` entries in the array
|
||||
static constexpr uint8_t size() {
|
||||
return _size;
|
||||
}
|
||||
|
||||
// To set the value of an entry:
|
||||
// key_array[key_addr] = Key_X;
|
||||
_ContentType& operator[](KeyAddr key_addr) {
|
||||
return values_[key_addr.toInt()];
|
||||
}
|
||||
|
||||
// To get the value of an entry:
|
||||
// Key key = key_array[key_addr];
|
||||
const _ContentType& operator[](KeyAddr key_addr) const {
|
||||
return values_[key_addr.toInt()];
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// The following code defines an iterator class for a class `KeyMap`, such
|
||||
// that we can write the following code to get each entry in the array:
|
||||
//
|
||||
// typedef KeyAddrMap<Key> KeyMap;
|
||||
//
|
||||
// for (Key key : key_map) {...}
|
||||
//
|
||||
// Or, if we need write access to the entries in the array:
|
||||
//
|
||||
// for (Key &key : key_map) {...}
|
||||
private:
|
||||
class Iterator;
|
||||
friend class ThisType::Iterator;
|
||||
|
||||
public:
|
||||
Iterator begin() {
|
||||
return {*this, KeyAddr(uint8_t(0))};
|
||||
}
|
||||
Iterator end() {
|
||||
return {*this, KeyAddr(_size)};
|
||||
}
|
||||
|
||||
private:
|
||||
class Iterator {
|
||||
public:
|
||||
Iterator(ThisType &map, KeyAddr key_addr)
|
||||
: map_(map), key_addr_(key_addr) {}
|
||||
bool operator!=(const Iterator &other) const {
|
||||
return key_addr_ != other.key_addr_;
|
||||
}
|
||||
_ContentType& operator*() const {
|
||||
return map_[key_addr_];
|
||||
}
|
||||
Iterator& operator++() {
|
||||
++key_addr_;
|
||||
return *this;
|
||||
}
|
||||
private:
|
||||
ThisType &map_;
|
||||
KeyAddr key_addr_;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace kaleidoscope
|
@ -0,0 +1,25 @@
|
||||
/* Kaleidoscope - Firmware for computer input devices
|
||||
* Copyright (C) 2013-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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "kaleidoscope/KeyAddrMap.h"
|
||||
|
||||
namespace kaleidoscope {
|
||||
|
||||
typedef KeyAddrMap<Key, KeyAddr::upper_limit> KeyMap;
|
||||
|
||||
} // namespace kaleidoscope
|
@ -0,0 +1,23 @@
|
||||
/* Kaleidoscope - Firmware for computer input devices
|
||||
* Copyright (C) 2013-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/LiveKeys.h"
|
||||
|
||||
namespace kaleidoscope {
|
||||
|
||||
LiveKeys live_keys;
|
||||
|
||||
} // namespace kaleidoscope
|
@ -0,0 +1,105 @@
|
||||
/* Kaleidoscope - Firmware for computer input devices
|
||||
* Copyright (C) 2013-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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "kaleidoscope/key_defs.h" // for Key, Key_NoKey, Key_Transparent
|
||||
#include "kaleidoscope/KeyAddr.h" // for KeyAddr
|
||||
#include "kaleidoscope/KeyMap.h" // for KeyMap
|
||||
|
||||
namespace kaleidoscope {
|
||||
|
||||
/// A representation of the "live" state of the keys on the keyboard
|
||||
///
|
||||
/// This is structure of `Key` values, indexed by `KeyAddr` values, with one
|
||||
/// entry per key on the keyboard. These entries are meant to represent the
|
||||
/// current state of the keys, with two special values:
|
||||
///
|
||||
/// - `Key_Inactive` indicates that the given key is not active. Usually this
|
||||
/// will correspond to the keyswitch being off (not pressed).
|
||||
///
|
||||
/// - `Key_Masked` indicates that the given key has been masked. When a key
|
||||
/// release event is processed for that key, it will be reset to
|
||||
/// `Key_Inactive`.
|
||||
///
|
||||
/// Any other value indicates that the key is active (i.e. pressed, though
|
||||
/// plugins can set entries to active even when the physical keyswitches are not
|
||||
/// engaged), and the `Key` value is what the that key is "sending" at the
|
||||
/// time. At the end of its processing of a `KeyEvent`, Kaleidoscope will use
|
||||
/// the contents of this array to populate the Keyboard HID reports.
|
||||
|
||||
class LiveKeys {
|
||||
public:
|
||||
// For array-style subscript addressing of entries in a read-only context:
|
||||
const Key& operator[](KeyAddr key_addr) const {
|
||||
if (key_addr.isValid()) {
|
||||
return key_map_[key_addr];
|
||||
}
|
||||
dummy_ = Key_Masked;
|
||||
return dummy_;
|
||||
}
|
||||
|
||||
// For array-style subscript addressing of entries by reference. The client
|
||||
// code can alter values in the array this way.
|
||||
Key& operator[](KeyAddr key_addr) {
|
||||
if (key_addr.isValid()) {
|
||||
return key_map_[key_addr];
|
||||
}
|
||||
dummy_ = Key_Masked;
|
||||
return dummy_;
|
||||
}
|
||||
|
||||
/// Set an entry to "active" with a specified `Key` value.
|
||||
void activate(KeyAddr key_addr, Key key) {
|
||||
if (key_addr.isValid())
|
||||
key_map_[key_addr] = key;
|
||||
}
|
||||
|
||||
/// Deactivate an entry by setting its value to `Key_Inactive`.
|
||||
void clear(KeyAddr key_addr) {
|
||||
if (key_addr.isValid())
|
||||
key_map_[key_addr] = Key_Inactive;
|
||||
}
|
||||
|
||||
/// Mask a key by setting its entry to `Key_Masked`. The key will become
|
||||
/// unmasked by Kaleidoscope on release (but not on a key press event).
|
||||
void mask(KeyAddr key_addr) {
|
||||
if (key_addr.isValid())
|
||||
key_map_[key_addr] = Key_Masked;
|
||||
}
|
||||
|
||||
/// Clear the entire array by setting all values to `Key_Inactive`.
|
||||
void clear() {
|
||||
for (Key &key : key_map_) {
|
||||
key = Key_Inactive;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator for use in range-based for loops:
|
||||
///
|
||||
/// for (Key key : live_keys.all()) {...}
|
||||
KeyMap& all() {
|
||||
return key_map_;
|
||||
}
|
||||
|
||||
private:
|
||||
KeyMap key_map_;
|
||||
mutable Key dummy_{0, 0};
|
||||
};
|
||||
|
||||
extern LiveKeys live_keys;
|
||||
|
||||
} // namespace kaleidoscope
|
Loading…
Reference in new issue