Merge pull request #1139 from keyboardio/jesse/wip/merge-1138

Merge the first bunch of commits from PR 1138
pull/1140/head
Jesse Vincent 3 years ago committed by GitHub
commit 68bbfd2b9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,178 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
# Copyright (c) 2022 Michael Richters <gedankenexperimenter@gmail.com>
# This is free and unencumbered software released into the public domain.
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
# For more information, please refer to <http://unlicense.org/>
# ------------------------------------------------------------------------------
"""This is a script for maintenance of the headers included in Kaleidoscope source
files. It is not currently possible to run this automatically on all
Kaleidoscope source files, because of the peculiarities therein. It uses
llvm/clang to determine which headers should be included in a given file, but
there's no avr-clang, so we're limited to using the virtual hardware device.
It takes any number of source files as its input, examines them and updates the
list of header `#include` directives.
It is safe to run on most Kaleidoscope source files, and a good idea to run it
on new ones (after staging them, so you can easily see what changes have been
made).
"""
# Example invocation:
# $ git ls-files -m | grep '\.\(h\|cpp\)' | bin/iwyu.py
import os
import shutil
import subprocess
import sys
def main():
"""Organize includes in Kaleidoscpe source files."""
iwyu = shutil.which('include-what-you-use')
print(f'IWYU: {iwyu}')
iwyu_flags = [
'-Xiwyu', '--no_fwd_decls', # No forward declarations
'-x', 'c++',
]
fix_includes = shutil.which('fix_includes.py')
print(f'fix_includes: {fix_includes}')
clang = os.getenv('CLANG_COMPILER')
if clang is None:
clang = shutil.which('clang')
print(f'clang: {clang}')
result = subprocess.run([clang, '-print-resource-dir'],
capture_output=True, check=True)
clang_resource_dir = result.stdout.decode('utf-8').rstrip()
system_include_dir = os.path.join(clang_resource_dir, 'include')
kaleidoscope_dir = os.getenv('KALEIDOSCOPE_DIR')
if kaleidoscope_dir is None:
kaleidoscope_dir = os.getcwd()
kaleidoscope_src_dir = os.path.join(kaleidoscope_dir, 'src')
print(f'KALEIDOSCOPE_DIR: {kaleidoscope_dir}')
virtual_hardware_dir = os.path.join(
kaleidoscope_dir, '.arduino', 'user', 'hardware', 'keyboardio', 'virtual'
)
virtual_arduino_core_dir = os.path.join(virtual_hardware_dir, 'cores', 'arduino')
virtual_model01_dir = os.path.join(virtual_hardware_dir, 'variants', 'model01')
virtual_keyboardiohid_dir = os.path.join(virtual_hardware_dir,
'libraries', 'KeyboardioHID', 'src')
clang_flags = [
'-c',
'-g',
'-Wall',
'-Wextra',
'-std=gnu++14', # Not `c++14`, because we're using clang, not gcc
'-ffunction-sections',
'-fdata-sections',
'-fno-threadsafe-statics',
'-MMD',
'-Woverloaded-virtual',
'-Wno-unused-parameter',
'-Wno-unused-variable',
'-Wno-ignored-qualifiers',
'-Wno-type-limits',
'-D' + 'KALEIDOSCOPE_VIRTUAL_BUILD=1',
'-D' + 'KEYBOARDIOHID_BUILD_WITHOUT_HID=1',
'-D' + 'USBCON=dummy',
'-D' + 'ARDUINO_ARCH_AVR=1',
'-D' + 'ARDUINO=10607',
'-D' + 'ARDUINO_AVR_MODEL01',
'-D' + 'ARDUINO_ARCH_VIRTUAL',
'-D' + 'USB_VID=0x1209',
'-D' + 'USB_PID=0x2301',
'-D' + 'USB_MANUFACTURER="Keyboardio"',
'-D' + 'USB_PRODUCT="Model 01"',
'-D' + 'KALEIDOSCOPE_HARDWARE_H="Kaleidoscope-Hardware-Keyboardio-Model01.h"',
'-D' + 'TWI_BUFFER_LENGTH=32',
'-I' + system_include_dir,
'-I' + kaleidoscope_src_dir,
'-I' + virtual_arduino_core_dir,
'-I' + virtual_model01_dir,
'-I' + virtual_keyboardiohid_dir,
]
plugins_dir = os.path.join(kaleidoscope_dir, 'plugins')
for basename in os.listdir(plugins_dir):
plugin_dir = os.path.join(plugins_dir, basename)
if not os.path.isdir(plugin_dir):
continue
clang_flags.append('-I' + os.path.join(plugin_dir, 'src'))
for arg in [iwyu] + iwyu_flags:
print(arg)
for arg in clang_flags:
print(arg)
for source_file in sys.argv[1:]:
iwyu_cmd = [iwyu] + iwyu_flags + clang_flags + [source_file]
print('------------------------------------------------------------')
print(f'File: {source_file}')
# Sometimes, it's useful to force IWYU to make changes, or to have a
# more definitive marker of whether or not it failed due to compilation
# errors (which may differ between IWYU and normal compilation,
# unfortunately). If so, the follwing code can be uncommented. It adds
# a harmless `#include` at the end of the file, which will be removed if
# this script runs successfully.
# with open(source_file, "rb+") as fd:
# fd.seek(-1, 2)
# char = fd.read(1)
# if char != b'\n':
# print('missing newline at end of file')
# fd.write(b'\n')
# if source_file != 'src/kaleidoscope/HIDTables.h':
# fd.write(b'#include "kaleidoscope/HIDTables.h"')
iwyu_proc = subprocess.run(iwyu_cmd, capture_output=True, check=False)
fix_includes_cmd = [
fix_includes,
'--update_comments',
'--nosafe_headers',
# Don't change the order of headers in existing files, because some
# of them have been changed from what IWYU will do. For new files,
# use `--reorder` instead.
'--noreorder',
]
subprocess.run(fix_includes_cmd, input=iwyu_proc.stderr, check=False)
# Optionally, we can write the output of `include-what-you-use` to a
# file for debugging purposes:
# with open(source_file + '.iwyu', 'wb') as fd:
# fd.write(iwyu_proc.stderr)
if __name__ == "__main__":
main()

@ -21,9 +21,11 @@ Our style guide is based on the [Google C++ style guide][goog:c++-guide] which w
- [Header Files](#header-files)
- [Self-contained Headers](#self-contained-headers)
- [Header Guards](#header-guards)
- [Include What You Use](#include-what-you-use)
- [Forward Declarations](#forward-declarations)
- [Inline Functions](#inline-functions)
- [Names and Order of Includes](#names-and-order-of-includes)
- [Organization of Includes](#organization-of-includes)
- [Top-level Arduino Library Headers](#top-level-arduino-library-headers)
- [Scoping](#scoping)
- [Namespaces](#namespaces)
- [Unnamed Namespaces and Static Variables](#unnamed-namespaces-and-static-variables)
@ -258,6 +260,12 @@ There are rare cases where a file designed to be included is not self-contained.
All header files should have `#pragma once` guards at the top to prevent multiple inclusion.
### Include What You Use
If a source or header file refers to a symbol defined elsewhere, the file should directly include a header file which provides a declaration or definition of that symbol.
Do not rely on transitive inclusions. This allows maintainers to remove no-longer-needed `#include` statements from their headers without breaking clients code. This also applies to directly associated headers - `foo.cpp` should include `bar.h` if it uses a symbol defined there, even if `foo.h` (currently) includes `bar.h`.
### Forward Declarations
> Avoid using forward declarations where possible. Just `#include` the headers you need.
@ -311,65 +319,75 @@ Another useful rule of thumb: it's typically not cost effective to inline functi
It is important to know that functions are not always inlined even if they are declared as such; for example, virtual and recursive functions are not normally inlined. Usually recursive functions should not be inline. The main reason for making a virtual function inline is to place its definition in the class, either for convenience or to document its behavior, e.g., for accessors and mutators.
### Names and Order of Includes
### Organization of Includes
<!-- TODO: This section could be simplified, and clarified, I believe. -->
> Use standard order for readability and to avoid hidden dependencies:
> - The header associated with this source file, if any
> - System headers and Arduino library headers (including other Kaleidoscope plugins, but not Kaleidoscope itself)
> - Kaleidoscope headers and headers for the individual plugin (other than the associated header above)
> Use standard order for readability and to avoid hidden dependencies: Related header, Arduino libraries, other libraries' `.h`, your project's `.h`.
These three sections should be separated by single blank lines, and should be sorted alphabetically.
All libraries must have at least one header in their top-level `src/` directory, to be included without any path components. This is the way Arduino finds libraries, and a limitation we must adhere to. These headers should - in general - include any other headers they may need, so that the consumer of the library only has to include one header. The name of this header must be the same as the name of the library.
When including system headers and Arduino library headers (including Kaleidoscope plugins), use angle brackets to indicate that those sources are external.
The recommended naming is to prefix the library name with `Kaleidoscope-`.
For headers inside the current library and for Kaleidoscope core headers, use double quotes and a full pathname (starting below the `src/` directory). This applies to the source file's associated header, as well; don't use a pathname relative to the source file's directory.
If there is more than one header, they should be listed as descendants of the project's source directory without use of UNIX directory shortcuts `.` (the current directory) or `..` (the parent directory), and live in a `Kaleidoscope` subdirectory. For example, if we have a plugin named `Kaleidoscope-Something`, which has an additional header file other than `Kaleidoscope-Something.h`, it should be in `src/Kaleidoscope/Something-Other.h`, and be included as:
For the sake of clarity, the above sections can be further divided to make it clear where each included header file can be found, but this is probably not necessary in most cases, because the path name of a header usually indicates which library it is located in.
For example, the includes in `Kaleidoscope-Something/src/kaleidoscope/Something.cpp` might look like this:
```c++
#include "Kaleidoscope-Something.h"
#include "Kaleidoscope/Something-Other.h"
#include "kaleidoscope/Something.h"
#include <Arduino.h>
#include <Kaleidoscope-Ranges.h>
#include <stdint.h>
#include "kaleidoscope/KeyAddr.h"
#include "kaleidoscope/KeyEvent.h"
#include "kaleidoscope/key_defs.h"
#include "kaleidoscope/plugin/something/utils.h"
```
Having more than one level of subdirectories is not recommended.
**Exception**
In `dir/foo.cpp` or `dir/foo_test.cpp`, whose main purpose is to implement or test the stuff in `dir2/foo2.h`, order your includes as follows:
Sometimes, system-specific code needs conditional includes. Such code can put conditional includes after other includes. Of course, keep your system-specific code small and localized. Example:
1. `dir2/foo2.h`
2. Arduino libraries.
3. Other libraries' `.h` files.
4. Your project's `.h` files.
```c++
#if defined(ARDUINO_AVR_MODEL01)
#include "kaleidoscope/Something-AVR-Model01.h"
#endif
With the preferred ordering, if `dir2/foo2.h` omits any necessary includes, the build of `dir/foo.cpp` or `dir/foo_test.cpp` will break. Thus, this rule ensures that build breakages show up first for the people working on these files, not for innocent people in other packages.
#if defined(ARDUINO_AVR_SHORTCUT)
#include "kaleidoscope/Something-AVR-Shortcut.h"
#endif
```
`dir/foo.cc` and `dir2/foo2.h` are usually in the same directory (e.g. `Kaleidoscope/Something_test.cpp` and `Kaleidoscope/Something.h`), but may sometimes be in different directories too.
### Top-level Arduinio Library Headers
Within each section the includes should be ordered alphabetically.
All libraries must have at least one header in their top-level `src/` directory, to be included without any path components. This is the way Arduino finds libraries, and a limitation we must adhere to. These headers should - in general - include any other headers they may need, so that the consumer of the library only has to include one header. The name of this header must be the same as the name of the library.
You should include all the headers that define the symbols you rely upon, except in the unusual case of [forward declarations](#forward-declarations). If you rely on symbols from `bar.h`, don't count on the fact that you included `foo.h` which (currently) includes `bar.h`: include `bar.h` yourself, unless `foo.h` explicitly demonstrates its intent to provide you the symbols of `bar.h`. However, any includes present in the related header do not need to be included again in the related `cc` (i.e., `foo.cc` can rely on `foo.h`'s includes).
The naming convention for Kaleidoscope plugins is to use the `Kaleidoscope-` prefix: e.g. `Kaleidoscope-Something`, which would have a top-level header named `Kaleidoscope-Something.h` in its `src/` directory.
For example, the includes in `Kaleidoscope-Something/src/Kaleidoscope/Something.cpp` might look like this:
In the case of Kaleidoscope plugin libraries, the number of source and header files tends to be very small (usually just one `*.cpp` file and its associated header, in addition to the library's top-level header). When one plugin depends on another, we therefore only include the top-level header of the dependency. For example, if `Kaleidoscope-OtherThing` depends on `Kaleidoscope-Something`, the file `kaleidoscope/plugin/OtherThing.h` will contain the line:
```c++
#include "Kaleidoscope/Something.h"
#include <Kaleidoscope-Something.h>
```
#include "Arduino.h"
…and `Kaleidoscope-Something.h` will look like this:
#include "Kaleidoscope-LEDControl.h"
#include "Kaleidoscope-Focus.h"
```c++
#include "kaleidoscope/plugin/Something.h"
```
**Exception**
This both makes it clearer where to find the included code, and allows the restructuring of that code without breaking the dependent library (assuming the symbols haven't changed as well).
Sometimes, system-specific code needs conditional includes. Such code can put conditional includes after other includes. Of course, keep your system-specific code small and localized. Example:
If a plugin library has symbols meant to be exported, and more than one header file in which those symbols are defined, all such header files should be included in the top-level header for the library. For example, if `Kaleidoscope-Something` defines types `kaleidoscope::plugin::Something` and `kaleidoscope::plugin::something::Helper`, both of which are meant to be accessible by `Kaleidoscope-OtherThing`, the top-level header `Kaleidoscope-Something.h` should look like this:
```c++
#include "Kaleidoscope.h"
#if defined(ARDUINO_AVR_MODEL01)
#include "Kaleidoscope/Something-AVR-Model01.h"
#endif
#if defined(ARDUINO_AVR_SHORTCUT)
#include "Kaleidoscope/Something-AVR-Shortcut.h"
#endif
#include "kaleidoscope/plugin/Something.h"
#include "kaleidoscope/plugin/something/Helper.h"
```
<!-- TODO: Finish converting the rest... -->

@ -20,7 +20,7 @@
#include "kaleidoscope/Runtime.h"
#include <Kaleidoscope-Ranges.h>
#define Key_Cycle Key(kaleidoscope::ranges::CYCLE)
constexpr Key Key_Cycle = Key(kaleidoscope::ranges::CYCLE);
#define cycleThrough(...) ({ \
static const Key __k[] PROGMEM = { __VA_ARGS__ }; \

@ -22,13 +22,17 @@
#include "kaleidoscope/plugin/Macros/MacroSteps.h"
#define DM(n) Key(kaleidoscope::ranges::DYNAMIC_MACRO_FIRST + n)
#define DM(n) ::kaleidoscope::plugin::DynamicMacrosKey(n)
#define MAX_CONCURRENT_DYNAMIC_MACRO_KEYS 8
namespace kaleidoscope {
namespace plugin {
constexpr Key DynamicMacrosKey(uint8_t n) {
return Key(kaleidoscope::ranges::DYNAMIC_MACRO_FIRST + n);
}
class DynamicMacros : public kaleidoscope::Plugin {
public:
EventHandlerResult onNameQuery();

@ -41,7 +41,7 @@ void DynamicTapDance::updateDynamicTapDanceCache() {
map_[0] = 0;
while (pos < storage_base_ + storage_size_) {
uint16_t raw_key = Kaleidoscope.storage().read(pos);
uint16_t raw_key = Runtime.storage().read(pos);
pos += 2;
Key key(raw_key);
@ -67,7 +67,7 @@ bool DynamicTapDance::dance(uint8_t tap_dance_index, KeyAddr key_addr,
return false;
Key key;
Kaleidoscope.storage().get(storage_base_ + pos, key);
Runtime.storage().get(storage_base_ + pos, key);
switch (tap_dance_action) {
case TapDance::Tap:
@ -103,7 +103,7 @@ EventHandlerResult DynamicTapDance::onFocusEvent(const char *command) {
if (::Focus.isEOL()) {
for (uint16_t i = 0; i < storage_size_; i += 2) {
Key k;
Kaleidoscope.storage().get(storage_base_ + i, k);
Runtime.storage().get(storage_base_ + i, k);
::Focus.send(k);
}
} else {
@ -113,10 +113,10 @@ EventHandlerResult DynamicTapDance::onFocusEvent(const char *command) {
Key k;
::Focus.read(k);
Kaleidoscope.storage().put(storage_base_ + pos, k);
Runtime.storage().put(storage_base_ + pos, k);
pos += 2;
}
Kaleidoscope.storage().commit();
Runtime.storage().commit();
updateDynamicTapDanceCache();
}
}

@ -310,8 +310,8 @@ void RaiseKeyScanner::readMatrix() {
}
void RaiseKeyScanner::actOnMatrixScan() {
for (byte row = 0; row < Props_::matrix_rows; row++) {
for (byte col = 0; col < Props_::left_columns; col++) {
for (uint8_t row = 0; row < Props_::matrix_rows; row++) {
for (uint8_t col = 0; col < Props_::left_columns; col++) {
uint8_t keynum = (row * Props_::left_columns) + col;
uint8_t keyState;

@ -87,7 +87,7 @@ uint8_t RaiseSide::controllerAddress() {
//
// returns the Wire.endTransmission code (0 = success)
// https://www.arduino.cc/en/Reference/WireEndTransmission
byte RaiseSide::setKeyscanInterval(byte delay) {
uint8_t RaiseSide::setKeyscanInterval(uint8_t delay) {
uint8_t data[] = {TWI_CMD_KEYSCAN_INTERVAL, delay};
return twi_.writeTo(data, ELEMENTS(data));
}
@ -106,7 +106,7 @@ int RaiseSide::readSLEDCurrent() {
return readRegister(TWI_CMD_SLED_CURRENT);
}
byte RaiseSide::setSLEDCurrent(byte current) {
uint8_t RaiseSide::setSLEDCurrent(uint8_t current) {
uint8_t data[] = {TWI_CMD_SLED_CURRENT, current};
return twi_.writeTo(data, ELEMENTS(data));
}
@ -131,14 +131,14 @@ int RaiseSide::readLEDSPIFrequency() {
//
// returns the Wire.endTransmission code (0 = success)
// https://www.arduino.cc/en/Reference/WireEndTransmission
byte RaiseSide::setLEDSPIFrequency(byte frequency) {
uint8_t RaiseSide::setLEDSPIFrequency(uint8_t frequency) {
uint8_t data[] = {TWI_CMD_LED_SPI_FREQUENCY, frequency};
return twi_.writeTo(data, ELEMENTS(data));
}
// returns -1 on error, otherwise returns the value of the hall sensor integer
int RaiseSide::readJoint() {
byte return_value = 0;
uint8_t return_value = 0;
uint8_t data[] = {TWI_CMD_JOINED};
uint8_t result = twi_.writeTo(data, ELEMENTS(data));
@ -160,7 +160,7 @@ int RaiseSide::readJoint() {
}
int RaiseSide::readRegister(uint8_t cmd) {
byte return_value = 0;
uint8_t return_value = 0;
uint8_t data[] = {cmd};
uint8_t result = twi_.writeTo(data, ELEMENTS(data));

@ -43,7 +43,7 @@ namespace raise {
typedef union {
cRGB leds[LEDS_PER_HAND];
byte bytes[LED_BANKS][LED_BYTES_PER_BANK];
uint8_t bytes[LED_BANKS][LED_BYTES_PER_BANK];
} LEDData_t;
// return what bank the led is in
@ -56,19 +56,19 @@ typedef union {
class RaiseSide {
public:
explicit RaiseSide(byte ad01) : ad01_(ad01), twi_(i2c_addr_base_ | ad01) {}
explicit RaiseSide(uint8_t ad01) : ad01_(ad01), twi_(i2c_addr_base_ | ad01) {}
int readVersion();
int readSLEDVersion();
int readSLEDCurrent();
byte setSLEDCurrent(byte current);
uint8_t setSLEDCurrent(uint8_t current);
int readJoint();
int readLayout();
byte setKeyscanInterval(byte delay);
uint8_t setKeyscanInterval(uint8_t delay);
int readKeyscanInterval();
byte setLEDSPIFrequency(byte frequency);
uint8_t setLEDSPIFrequency(uint8_t frequency);
int readLEDSPIFrequency();
bool moreKeysWaiting();

@ -112,8 +112,8 @@ void __attribute__((optimize(3))) ErgoDox::readMatrix() {
}
void __attribute__((optimize(3))) ErgoDox::actOnMatrixScan() {
for (byte row = 0; row < matrix_rows; row++) {
for (byte col = 0; col < matrix_columns; col++) {
for (uint8_t row = 0; row < matrix_rows; row++) {
for (uint8_t col = 0; col < matrix_columns; col++) {
uint8_t key_state = (bitRead(previousKeyState_[row], col) << 0) |
(bitRead(keyState_[row], col) << 1);
if (keyToggledOn(key_state) || keyToggledOff(key_state)) {

@ -122,8 +122,8 @@ void KeyScanner::readMatrix() {
}
void KeyScanner::actOnMatrixScan() {
for (byte col = 0; col < Props_::matrix_columns; col++) {
for (byte row = 0; row < Props_::matrix_rows; row++) {
for (uint8_t col = 0; col < Props_::matrix_columns; col++) {
for (uint8_t row = 0; row < Props_::matrix_rows; row++) {
uint8_t keyState = (bitRead(matrix_state_[col].previous, row) << 0) | (bitRead(matrix_state_[col].current, row) << 1);
if (keyState) {
ThisType::handleKeyswitchEvent(Key_NoKey, typename Props_::KeyAddr(row, col), keyState);

@ -124,7 +124,7 @@ void Model01LEDDriver::syncLeds() {
isLEDChanged = false;
}
boolean Model01LEDDriver::ledPowerFault() {
bool Model01LEDDriver::ledPowerFault() {
if (PINB & _BV(4)) {
return true;
} else {
@ -165,9 +165,9 @@ void Model01KeyScanner::readMatrix() {
}
}
void Model01KeyScanner::actOnHalfRow(byte row, byte colState, byte colPrevState, byte startPos) {
void Model01KeyScanner::actOnHalfRow(uint8_t row, uint8_t colState, uint8_t colPrevState, uint8_t startPos) {
if ((colState != colPrevState) || (colState != 0)) {
for (byte col = 0; col < 8; col++) {
for (uint8_t col = 0; col < 8; col++) {
// Build up the key state for row, col
uint8_t keyState = ((bitRead(colPrevState, 0) << 0) |
(bitRead(colState, 0) << 1));
@ -182,7 +182,7 @@ void Model01KeyScanner::actOnHalfRow(byte row, byte colState, byte colPrevState,
}
void Model01KeyScanner::actOnMatrixScan() {
for (byte row = 0; row < 4; row++) {
for (uint8_t row = 0; row < 4; row++) {
actOnHalfRow(row, leftHandState.rows[row], previousLeftHandState.rows[row], 7);
actOnHalfRow(row, rightHandState.rows[row], previousRightHandState.rows[row], 15);
}

@ -60,7 +60,7 @@ class Model01LEDDriver : public kaleidoscope::driver::led::Base<Model01LEDDriver
static uint8_t getBrightness();
static void enableHighPowerLeds();
static boolean ledPowerFault();
static bool ledPowerFault();
private:
static bool isLEDChanged;

@ -40,7 +40,7 @@ namespace keyboardio {
uint8_t twi_uninitialized = 1;
Model01Side::Model01Side(byte setAd01) {
Model01Side::Model01Side(uint8_t setAd01) {
ad01 = setAd01;
addr = SCANNER_I2C_ADDR_BASE | ad01;
if (twi_uninitialized--) {
@ -70,7 +70,7 @@ uint8_t Model01Side::controllerAddress() {
//
// returns the Wire.endTransmission code (0 = success)
// https://www.arduino.cc/en/Reference/WireEndTransmission
byte Model01Side::setKeyscanInterval(byte delay) {
uint8_t Model01Side::setKeyscanInterval(uint8_t delay) {
uint8_t data[] = {TWI_CMD_KEYSCAN_INTERVAL, delay};
uint8_t result = twi_writeTo(addr, data, ELEMENTS(data), 1, 0);
@ -101,7 +101,7 @@ int Model01Side::readLEDSPIFrequency() {
//
// returns the Wire.endTransmission code (0 = success)
// https://www.arduino.cc/en/Reference/WireEndTransmission
byte Model01Side::setLEDSPIFrequency(byte frequency) {
uint8_t Model01Side::setLEDSPIFrequency(uint8_t frequency) {
uint8_t data[] = {TWI_CMD_LED_SPI_FREQUENCY, frequency};
uint8_t result = twi_writeTo(addr, data, ELEMENTS(data), 1, 0);
@ -112,7 +112,7 @@ byte Model01Side::setLEDSPIFrequency(byte frequency) {
int Model01Side::readRegister(uint8_t cmd) {
byte return_value = 0;
uint8_t return_value = 0;
uint8_t data[] = {cmd};
uint8_t result = twi_writeTo(addr, data, ELEMENTS(data), 1, 0);
@ -168,7 +168,7 @@ void Model01Side::sendLEDData() {
auto constexpr gamma8 = kaleidoscope::driver::color::gamma_correction;
void Model01Side::sendLEDBank(byte bank) {
void Model01Side::sendLEDBank(uint8_t bank) {
uint8_t data[LED_BYTES_PER_BANK + 1];
data[0] = TWI_CMD_LED_BASE + bank;
for (uint8_t i = 0 ; i < LED_BYTES_PER_BANK; i++) {
@ -196,7 +196,7 @@ void Model01Side::setAllLEDsTo(cRGB color) {
uint8_t result = twi_writeTo(addr, data, ELEMENTS(data), 1, 0);
}
void Model01Side::setOneLEDTo(byte led, cRGB color) {
void Model01Side::setOneLEDTo(uint8_t led, cRGB color) {
uint8_t data[] = {TWI_CMD_LED_SET_ONE_TO,
led,
pgm_read_byte(&gamma8[color.b]),

@ -48,7 +48,7 @@ namespace keyboardio {
typedef union {
cRGB leds[LEDS_PER_HAND];
byte bytes[LED_BANKS][LED_BYTES_PER_BANK];
uint8_t bytes[LED_BANKS][LED_BYTES_PER_BANK];
} LEDData_t;
typedef union {
@ -62,19 +62,19 @@ typedef union {
// used to configure interrupts, configuration for a particular controller
class Model01Side {
public:
explicit Model01Side(byte setAd01);
explicit Model01Side(uint8_t setAd01);
~Model01Side() {}
int readVersion();
byte setKeyscanInterval(byte delay);
uint8_t setKeyscanInterval(uint8_t delay);
int readKeyscanInterval();
byte setLEDSPIFrequency(byte frequency);
uint8_t setLEDSPIFrequency(uint8_t frequency);
int readLEDSPIFrequency();
void sendLEDData();
void setOneLEDTo(byte led, cRGB color);
void setOneLEDTo(uint8_t led, cRGB color);
void setAllLEDsTo(cRGB color);
keydata_t getKeyData();
bool readKeys();
@ -93,8 +93,8 @@ class Model01Side {
int addr;
int ad01;
keydata_t keyData;
byte nextLEDBank = 0;
void sendLEDBank(byte bank);
uint8_t nextLEDBank = 0;
void sendLEDBank(uint8_t bank);
int readRegister(uint8_t cmd);
};
#else // ifndef KALEIDOSCOPE_VIRTUAL_BUILD

@ -163,9 +163,9 @@ void Model100KeyScanner::readMatrix() {
}
}
void Model100KeyScanner::actOnHalfRow(byte row, byte colState, byte colPrevState, byte startPos) {
void Model100KeyScanner::actOnHalfRow(uint8_t row, uint8_t colState, uint8_t colPrevState, uint8_t startPos) {
if ((colState != colPrevState) || (colState != 0)) {
for (byte col = 0; col < 8; col++) {
for (uint8_t col = 0; col < 8; col++) {
// Build up the key state for row, col
uint8_t keyState = ((bitRead(colPrevState, 0) << 0) |
(bitRead(colState, 0) << 1));
@ -180,7 +180,7 @@ void Model100KeyScanner::actOnHalfRow(byte row, byte colState, byte colPrevState
}
void Model100KeyScanner::actOnMatrixScan() {
for (byte row = 0; row < 4; row++) {
for (uint8_t row = 0; row < 4; row++) {
actOnHalfRow(row, leftHandState.rows[row], previousLeftHandState.rows[row], 7);
actOnHalfRow(row, rightHandState.rows[row], previousRightHandState.rows[row], 15);
}

@ -112,7 +112,7 @@ class Model100KeyScanner : public kaleidoscope::driver::keyscanner::Base<Model10
static driver::keyboardio::keydata_t previousLeftHandState;
static driver::keyboardio::keydata_t previousRightHandState;
static void actOnHalfRow(byte row, byte colState, byte colPrevState, byte startPos);
static void actOnHalfRow(uint8_t row, uint8_t colState, uint8_t colPrevState, uint8_t startPos);
};
#else // ifndef KALEIDOSCOPE_VIRTUAL_BUILD
class Model100KeyScanner;

@ -38,7 +38,7 @@ namespace keyboardio {
uint8_t twi_uninitialized = 1;
Model100Side::Model100Side(byte setAd01) {
Model100Side::Model100Side(uint8_t setAd01) {
ad01 = setAd01;
addr = SCANNER_I2C_ADDR_BASE | ad01;
markDeviceUnavailable();
@ -66,7 +66,7 @@ uint8_t Model100Side::controllerAddress() {
//
// returns the Wire.endTransmission code (0 = success)
// https://www.arduino.cc/en/Reference/WireEndTransmission
byte Model100Side::setKeyscanInterval(byte delay) {
uint8_t Model100Side::setKeyscanInterval(uint8_t delay) {
uint8_t data[] = {TWI_CMD_KEYSCAN_INTERVAL, delay};
uint8_t result = writeData(data, ELEMENTS(data));
return result;
@ -96,7 +96,7 @@ int Model100Side::readLEDSPIFrequency() {
//
// returns the Wire.endTransmission code (0 = success)
// https://www.arduino.cc/en/Reference/WireEndTransmission
byte Model100Side::setLEDSPIFrequency(byte frequency) {
uint8_t Model100Side::setLEDSPIFrequency(uint8_t frequency) {
uint8_t data[] = {TWI_CMD_LED_SPI_FREQUENCY, frequency};
uint8_t result = writeData(data, ELEMENTS(data));
@ -153,7 +153,7 @@ uint8_t Model100Side::writeData(uint8_t *data, uint8_t length) {
}
int Model100Side::readRegister(uint8_t cmd) {
byte return_value = 0;
uint8_t return_value = 0;
uint8_t data[] = {cmd};
uint8_t result = writeData(data, ELEMENTS(data));
@ -220,7 +220,7 @@ void Model100Side::sendLEDData() {
}
void Model100Side::sendLEDBank(byte bank) {
void Model100Side::sendLEDBank(uint8_t bank) {
uint8_t data[LED_BYTES_PER_BANK + 1];
data[0] = TWI_CMD_LED_BASE + bank;
for (uint8_t i = 0 ; i < LED_BYTES_PER_BANK; i++) {
@ -248,7 +248,7 @@ void Model100Side::setAllLEDsTo(cRGB color) {
uint8_t result = writeData(data, ELEMENTS(data));
}
void Model100Side::setOneLEDTo(byte led, cRGB color) {
void Model100Side::setOneLEDTo(uint8_t led, cRGB color) {
uint8_t data[] = {TWI_CMD_LED_SET_ONE_TO,
led,
color.b,

@ -25,12 +25,12 @@ class LEDRainbowEffect : public Plugin,
public:
LEDRainbowEffect(void) {}
void brightness(byte);
byte brightness(void) {
void brightness(uint8_t);
uint8_t brightness(void) {
return rainbow_value;
}
void update_delay(byte);
byte update_delay(void) {
void update_delay(uint8_t);
uint8_t update_delay(void) {
return rainbow_update_delay;
}
@ -57,12 +57,12 @@ class LEDRainbowEffect : public Plugin,
uint8_t rainbow_steps = 1; // number of hues we skip in a 360 range per update
uint8_t rainbow_last_update = 0;
byte rainbow_saturation = 255;
uint8_t rainbow_saturation = 255;
};
private:
uint8_t rainbow_update_delay = 40; // delay between updates (ms)
byte rainbow_value = 50;
uint8_t rainbow_value = 50;
};
@ -70,12 +70,12 @@ class LEDRainbowWaveEffect : public Plugin, public LEDModeInterface {
public:
LEDRainbowWaveEffect(void) {}
void brightness(byte);
byte brightness(void) {
void brightness(uint8_t);
uint8_t brightness(void) {
return rainbow_value;
}
void update_delay(byte);
byte update_delay(void) {
void update_delay(uint8_t);
uint8_t update_delay(void) {
return rainbow_update_delay;
}
@ -102,11 +102,11 @@ class LEDRainbowWaveEffect : public Plugin, public LEDModeInterface {
uint8_t rainbow_wave_steps = 1; // number of hues we skip in a 360 range per update
uint8_t rainbow_last_update = 0;
byte rainbow_saturation = 255;
uint8_t rainbow_saturation = 255;
};
uint8_t rainbow_update_delay = 40; // delay between updates (ms)
byte rainbow_value = 50;
uint8_t rainbow_value = 50;
};
}
}

@ -36,7 +36,7 @@
#define LEADER_MAX_SEQUENCE_LENGTH 4
#define LEAD(n) Key(kaleidoscope::ranges::LEAD_FIRST + n)
#define LEAD(n) kaleidoscope::plugin::LeaderKey(n)
#define LEADER_SEQ(...) { __VA_ARGS__, Key_NoKey }
#define LEADER_DICT(...) { __VA_ARGS__, {{Key_NoKey}, NULL} }
@ -44,6 +44,10 @@
namespace kaleidoscope {
namespace plugin {
constexpr Key LeaderKey(uint8_t n) {
return Key(kaleidoscope::ranges::LEAD_FIRST + n);
}
class Leader : public kaleidoscope::Plugin {
public:
typedef void (*action_t)(uint8_t seq_index);

@ -29,9 +29,9 @@ EventHandlerResult MagicCombo::onNameQuery() {
}
EventHandlerResult MagicCombo::afterEachCycle() {
for (byte i = 0; i < magiccombo::combos_length; i++) {
for (uint8_t i = 0; i < magiccombo::combos_length; i++) {
bool match = true;
byte j;
uint8_t j;
for (j = 0; j < MAX_COMBO_LENGTH; j++) {
int8_t comboKey = pgm_read_byte(&(magiccombo::combos[i].keys[j]));

@ -30,7 +30,7 @@ uint16_t MouseWrapper::next_width;
uint16_t MouseWrapper::next_height;
uint16_t MouseWrapper::section_top;
uint16_t MouseWrapper::section_left;
boolean MouseWrapper::is_warping;
bool MouseWrapper::is_warping;
uint8_t MouseWrapper::accel_step;
uint8_t MouseWrapper::speed_limit = 127;
@ -38,7 +38,7 @@ uint8_t MouseWrapper::speed_limit = 127;
void MouseWrapper::warpJump(uint16_t left, uint16_t top, uint16_t height, uint16_t width) {
uint16_t x_center = left + width / 2;
uint16_t y_center = top + height / 2;
Kaleidoscope.hid().absoluteMouse().moveTo(x_center, y_center, 0);
Runtime.hid().absoluteMouse().moveTo(x_center, y_center, 0);
}
void MouseWrapper::beginWarping() {
@ -131,7 +131,7 @@ void MouseWrapper::move(int8_t x, int8_t y) {
endWarping();
// move by whole pixels, not subpixels
Kaleidoscope.hid().mouse().move(moveX / subpixels_per_pixel, moveY / subpixels_per_pixel);
Runtime.hid().mouse().move(moveX / subpixels_per_pixel, moveY / subpixels_per_pixel);
// save leftover subpixel movements for later
remainderX = moveX - moveX / subpixels_per_pixel * subpixels_per_pixel;
remainderY = moveY - moveY / subpixels_per_pixel * subpixels_per_pixel;

@ -57,7 +57,7 @@ class MouseWrapper {
static uint16_t next_height;
static uint16_t section_top;
static uint16_t section_left;
static boolean is_warping;
static bool is_warping;
static uint8_t acceleration(uint8_t cycles);

@ -24,12 +24,21 @@
// ----------------------------------------------------------------------------
// Keymap macros
#define OSM(kc) Key(kaleidoscope::ranges::OSM_FIRST + (Key_ ## kc).getKeyCode() - Key_LeftControl.getKeyCode())
#define OSL(n) Key(kaleidoscope::ranges::OSL_FIRST + n)
#define OSM(k) ::kaleidoscope::plugin::OneShotModifierKey(Key_ ## k)
#define OSL(n) ::kaleidoscope::plugin::OneShotLayerKey(n)
namespace kaleidoscope {
namespace plugin {
constexpr Key OneShotModifierKey(Key mod_key) {
return Key(kaleidoscope::ranges::OSM_FIRST +
mod_key.getKeyCode() - HID_KEYBOARD_FIRST_MODIFIER);
}
constexpr Key OneShotLayerKey(uint8_t layer) {
return Key(kaleidoscope::ranges::OSL_FIRST + layer);
}
class OneShot : public kaleidoscope::Plugin {
public:
// Constructor

@ -24,21 +24,29 @@
#include "kaleidoscope/KeyEventTracker.h"
// DualUse Key definitions for Qukeys in the keymap
#define MT(mod, key) Key( \
kaleidoscope::ranges::DUM_FIRST + \
(((Key_ ## mod).getKeyCode() - Key_LeftControl.getKeyCode()) << 8) + \
(Key_ ## key).getKeyCode() \
)
#define MT(mod, key) kaleidoscope::plugin::ModTapKey(Key_ ## mod, Key_ ## key)
#define SFT_T(key) MT(LeftShift, key)
#define CTL_T(key) MT(LeftControl, key)
#define ALT_T(key) MT(LeftAlt, key)
#define GUI_T(key) MT(LeftGui, key)
#define LT(layer, key) Key(kaleidoscope::ranges::DUL_FIRST + (layer << 8) + (Key_ ## key).getKeyCode())
#define LT(layer, key) kaleidoscope::plugin::LayerTapKey(layer, Key_ ## key)
namespace kaleidoscope {
namespace plugin {
constexpr Key ModTapKey(Key mod_key, Key tap_key) {
uint8_t mod = mod_key.getKeyCode() - HID_KEYBOARD_FIRST_MODIFIER;
return Key(kaleidoscope::ranges::DUM_FIRST +
(mod << 8) + tap_key.getKeyCode());
}
constexpr Key LayerTapKey(uint8_t layer, Key tap_key) {
return Key(kaleidoscope::ranges::DUL_FIRST +
(layer << 8) + tap_key.getKeyCode());
}
// Data structure for an individual qukey
struct Qukey {
// The layer this qukey is mapped on.

@ -20,7 +20,7 @@
#include "kaleidoscope/Runtime.h"
#include <Kaleidoscope-Ranges.h>
#define Key_Redial Key(kaleidoscope::ranges::REDIAL)
constexpr Key Key_Redial = Key(kaleidoscope::ranges::REDIAL);
namespace kaleidoscope {
namespace plugin {

@ -27,8 +27,8 @@
#define SPACECADET_MAP_END (kaleidoscope::plugin::SpaceCadet::KeyBinding) { Key_NoKey, Key_NoKey, 0 }
#endif
#define Key_SpaceCadetEnable Key(kaleidoscope::ranges::SC_FIRST)
#define Key_SpaceCadetDisable Key(kaleidoscope::ranges::SC_LAST)
constexpr Key Key_SpaceCadetEnable = Key(kaleidoscope::ranges::SC_FIRST);
constexpr Key Key_SpaceCadetDisable = Key(kaleidoscope::ranges::SC_LAST);
namespace kaleidoscope {
namespace plugin {

@ -29,9 +29,6 @@ char Syster::symbol_[SYSTER_MAX_SYMBOL_LENGTH + 1];
uint8_t Syster::symbol_pos_;
bool Syster::is_active_;
// --- helpers ---
#define isSyster(k) (k == kaleidoscope::ranges::SYSTER)
// --- api ---
void Syster::reset(void) {
symbol_pos_ = 0;
@ -53,7 +50,7 @@ EventHandlerResult Syster::onKeyEvent(KeyEvent &event) {
// If Syster isn't actively matching an input sequence, we're only looking
// for the special Syster `Key` value; anything else gets passed through
// immediately.
if (!isSyster(event.key))
if (event.key != Key_Syster)
return EventHandlerResult::OK;
// It's a Syster Key; activate the plugin as soon as it toggles on, so we
@ -72,7 +69,7 @@ EventHandlerResult Syster::onKeyEvent(KeyEvent &event) {
// If a Syster key gets pressed while we're reading an input sequence, ignore
// it. This could be turned into a "reset" where we erase the abandoned input.
if (isSyster(event.key)) {
if (event.key == Key_Syster) {
return EventHandlerResult::EVENT_CONSUMED;
}

@ -22,7 +22,8 @@
#define SYSTER_MAX_SYMBOL_LENGTH 32
#define SYSTER Key(kaleidoscope::ranges::SYSTER)
constexpr Key Key_Syster = Key(kaleidoscope::ranges::SYSTER);
constexpr Key SYSTER = Key_Syster;
namespace kaleidoscope {
namespace plugin {

@ -24,7 +24,7 @@
#include "kaleidoscope/KeyAddrEventQueue.h"
#include "kaleidoscope/KeyEventTracker.h"
#define TD(n) Key(kaleidoscope::ranges::TD_FIRST + n)
#define TD(n) kaleidoscope::plugin::TapDanceKey(n)
#define tapDanceActionKeys(tap_count, tap_dance_action, ...) ({ \
static const Key __k[] PROGMEM = { __VA_ARGS__ }; \
@ -34,6 +34,11 @@
namespace kaleidoscope {
namespace plugin {
constexpr Key TapDanceKey(uint8_t n) {
return Key(kaleidoscope::ranges::TD_FIRST + n);
}
class TapDance : public kaleidoscope::Plugin {
public:
enum ActionType {

@ -20,11 +20,15 @@
#include "kaleidoscope/Runtime.h"
#include <Kaleidoscope-Ranges.h>
#define TOPSY(k) Key(kaleidoscope::ranges::TT_FIRST + (Key_ ## k).getKeyCode())
#define TOPSY(k) ::kaleidoscope::plugin::TopsyTurvyKey(Key_ ## k)
namespace kaleidoscope {
namespace plugin {
constexpr Key TopsyTurvyKey(Key key) {
return Key(kaleidoscope::ranges::TT_FIRST + key.getKeyCode());
}
class TopsyTurvy: public kaleidoscope::Plugin {
public:
TopsyTurvy(void) {}

@ -21,7 +21,7 @@
#pragma once
#define Key_Turbo Key{kaleidoscope::ranges::TURBO}
constexpr Key Key_Turbo = Key(kaleidoscope::ranges::TURBO);
namespace kaleidoscope {
namespace plugin {

@ -29,7 +29,7 @@ namespace kaleidoscope {
// when calling this function (e.g. `bitfieldSize<uint16_t>(n)`). The default `UnitType`
// is `byte` (i.e. `uint8_t`, which is almost always what we want, so most of the time we
// can also drop that template parameter (e.g. `bitfieldSize(n)`).
template <typename _UnitType = byte, typename _WidthType>
template <typename _UnitType = uint8_t, typename _WidthType>
constexpr _WidthType bitfieldSize(_WidthType n) {
return ((n - 1) / (8 * sizeof(_UnitType))) + 1;
}

@ -229,7 +229,7 @@ class Keyboard {
return nkro_keyboard_.isKeyPressed(key.getKeyCode());
}
boolean isModifierKeyActive(Key modifier_key) {
bool isModifierKeyActive(Key modifier_key) {
if (boot_keyboard_.getProtocol() == HID_BOOT_PROTOCOL) {
return boot_keyboard_.isModifierActive(modifier_key.getKeyCode());
}
@ -237,7 +237,7 @@ class Keyboard {
return nkro_keyboard_.isModifierActive(modifier_key.getKeyCode());
}
boolean wasModifierKeyActive(Key modifier_key) {
bool wasModifierKeyActive(Key modifier_key) {
if (boot_keyboard_.getProtocol() == HID_BOOT_PROTOCOL) {
return boot_keyboard_.wasModifierActive(modifier_key.getKeyCode());
}
@ -245,7 +245,7 @@ class Keyboard {
return nkro_keyboard_.wasModifierActive(modifier_key.getKeyCode());
}
boolean isAnyModifierKeyActive() {
bool isAnyModifierKeyActive() {
if (boot_keyboard_.getProtocol() == HID_BOOT_PROTOCOL) {
return boot_keyboard_.isAnyModifierActive();
}
@ -253,7 +253,7 @@ class Keyboard {
return nkro_keyboard_.isAnyModifierActive();
}
boolean wasAnyModifierKeyActive() {
bool wasAnyModifierKeyActive() {
if (boot_keyboard_.getProtocol() == HID_BOOT_PROTOCOL) {
return boot_keyboard_.wasAnyModifierActive();
}
@ -290,7 +290,7 @@ class Keyboard {
// the upcoming USB HID report and passes them through to KeyboardioHID
// immediately
void pressModifiers(byte flags) {
void pressModifiers(uint8_t flags) {
if (flags & SHIFT_HELD) {
pressRawKey(Key_LeftShift);
}
@ -312,7 +312,7 @@ class Keyboard {
// the upcoming USB HID report and passes them through to KeyboardioHID
// immediately
void releaseModifiers(byte flags) {
void releaseModifiers(uint8_t flags) {
if (flags & SHIFT_HELD) {
releaseRawKey(Key_LeftShift);
}

@ -123,8 +123,8 @@ class ATmega: public kaleidoscope::driver::keyscanner::Base<_KeyScannerProps> {
}
void __attribute__((optimize(3))) actOnMatrixScan() {
for (byte row = 0; row < _KeyScannerProps::matrix_rows; row++) {
for (byte col = 0; col < _KeyScannerProps::matrix_columns; col++) {
for (uint8_t row = 0; row < _KeyScannerProps::matrix_rows; row++) {
for (uint8_t col = 0; col < _KeyScannerProps::matrix_columns; col++) {
uint8_t keyState = (bitRead(matrix_state_[row].previous, col) << 0) | (bitRead(matrix_state_[row].current, col) << 1);
if (keyState) {
ThisType::handleKeyswitchEvent(Key_NoKey, typename _KeyScannerProps::KeyAddr(row, col), keyState);

@ -224,7 +224,7 @@ void Layer_::deactivate(uint8_t layer) {
kaleidoscope::Hooks::onLayerChange();
}
boolean Layer_::isActive(uint8_t layer) {
bool Layer_::isActive(uint8_t layer) {
for (int8_t i = 0; i < active_layer_count_; ++i) {
if (active_layers_[i] == layer)
return true;

@ -94,7 +94,7 @@ class Layer_ {
static uint8_t mostRecent() {
return active_layers_[active_layer_count_ - 1];
}
static boolean isActive(uint8_t layer);
static bool isActive(uint8_t layer);
static void handleLayerKeyEvent(const KeyEvent &event);

@ -19,11 +19,11 @@
#include "kaleidoscope/Runtime.h"
#include "kaleidoscope/plugin/LEDMode.h"
#define LED_TOGGLE 0b00000001 // Synthetic, internal
constexpr uint8_t LED_TOGGLE = 0b00000001; // Synthetic, internal
#define Key_LEDEffectNext Key(0, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE)
#define Key_LEDEffectPrevious Key(1, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE)
#define Key_LEDToggle Key(2, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE)
constexpr Key Key_LEDEffectNext = Key(0, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE);
constexpr Key Key_LEDEffectPrevious = Key(1, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE);
constexpr Key Key_LEDToggle = Key(2, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE);
namespace kaleidoscope {
namespace plugin {

Loading…
Cancel
Save