diff --git a/bin/iwyu.py b/bin/iwyu.py new file mode 100755 index 00000000..db1fea07 --- /dev/null +++ b/bin/iwyu.py @@ -0,0 +1,178 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# Copyright (c) 2022 Michael Richters + +# 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 +# ------------------------------------------------------------------------------ + +"""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() diff --git a/docs/codebase/code-style.md b/docs/codebase/code-style.md index df3063c2..f7562d05 100644 --- a/docs/codebase/code-style.md +++ b/docs/codebase/code-style.md @@ -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 - +> 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 +#include +#include + +#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 +``` -#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" ``` diff --git a/plugins/Kaleidoscope-Cycle/src/kaleidoscope/plugin/Cycle.h b/plugins/Kaleidoscope-Cycle/src/kaleidoscope/plugin/Cycle.h index ee7d013c..30d9c5d0 100644 --- a/plugins/Kaleidoscope-Cycle/src/kaleidoscope/plugin/Cycle.h +++ b/plugins/Kaleidoscope-Cycle/src/kaleidoscope/plugin/Cycle.h @@ -20,7 +20,7 @@ #include "kaleidoscope/Runtime.h" #include -#define Key_Cycle Key(kaleidoscope::ranges::CYCLE) +constexpr Key Key_Cycle = Key(kaleidoscope::ranges::CYCLE); #define cycleThrough(...) ({ \ static const Key __k[] PROGMEM = { __VA_ARGS__ }; \ diff --git a/plugins/Kaleidoscope-DynamicMacros/src/kaleidoscope/plugin/DynamicMacros.h b/plugins/Kaleidoscope-DynamicMacros/src/kaleidoscope/plugin/DynamicMacros.h index 5499dab0..9c2c84c9 100644 --- a/plugins/Kaleidoscope-DynamicMacros/src/kaleidoscope/plugin/DynamicMacros.h +++ b/plugins/Kaleidoscope-DynamicMacros/src/kaleidoscope/plugin/DynamicMacros.h @@ -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(); diff --git a/plugins/Kaleidoscope-DynamicTapDance/src/kaleidoscope/plugin/DynamicTapDance.cpp b/plugins/Kaleidoscope-DynamicTapDance/src/kaleidoscope/plugin/DynamicTapDance.cpp index 27ecd3c9..b0e5d232 100644 --- a/plugins/Kaleidoscope-DynamicTapDance/src/kaleidoscope/plugin/DynamicTapDance.cpp +++ b/plugins/Kaleidoscope-DynamicTapDance/src/kaleidoscope/plugin/DynamicTapDance.cpp @@ -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(); } } diff --git a/plugins/Kaleidoscope-Hardware-Dygma-Raise/src/kaleidoscope/device/dygma/Raise.cpp b/plugins/Kaleidoscope-Hardware-Dygma-Raise/src/kaleidoscope/device/dygma/Raise.cpp index 5e6084c0..939e2991 100644 --- a/plugins/Kaleidoscope-Hardware-Dygma-Raise/src/kaleidoscope/device/dygma/Raise.cpp +++ b/plugins/Kaleidoscope-Hardware-Dygma-Raise/src/kaleidoscope/device/dygma/Raise.cpp @@ -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; diff --git a/plugins/Kaleidoscope-Hardware-Dygma-Raise/src/kaleidoscope/device/dygma/raise/RaiseSide.cpp b/plugins/Kaleidoscope-Hardware-Dygma-Raise/src/kaleidoscope/device/dygma/raise/RaiseSide.cpp index b1a6810b..66242176 100644 --- a/plugins/Kaleidoscope-Hardware-Dygma-Raise/src/kaleidoscope/device/dygma/raise/RaiseSide.cpp +++ b/plugins/Kaleidoscope-Hardware-Dygma-Raise/src/kaleidoscope/device/dygma/raise/RaiseSide.cpp @@ -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)); diff --git a/plugins/Kaleidoscope-Hardware-Dygma-Raise/src/kaleidoscope/device/dygma/raise/RaiseSide.h b/plugins/Kaleidoscope-Hardware-Dygma-Raise/src/kaleidoscope/device/dygma/raise/RaiseSide.h index 66c1d47d..8d63024b 100644 --- a/plugins/Kaleidoscope-Hardware-Dygma-Raise/src/kaleidoscope/device/dygma/raise/RaiseSide.h +++ b/plugins/Kaleidoscope-Hardware-Dygma-Raise/src/kaleidoscope/device/dygma/raise/RaiseSide.h @@ -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(); diff --git a/plugins/Kaleidoscope-Hardware-EZ-ErgoDox/src/kaleidoscope/device/ez/ErgoDox.cpp b/plugins/Kaleidoscope-Hardware-EZ-ErgoDox/src/kaleidoscope/device/ez/ErgoDox.cpp index f9d241c6..901231be 100644 --- a/plugins/Kaleidoscope-Hardware-EZ-ErgoDox/src/kaleidoscope/device/ez/ErgoDox.cpp +++ b/plugins/Kaleidoscope-Hardware-EZ-ErgoDox/src/kaleidoscope/device/ez/ErgoDox.cpp @@ -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)) { diff --git a/plugins/Kaleidoscope-Hardware-GD32-Eval/src/kaleidoscope/device/gd32/eval/KeyScanner.cpp b/plugins/Kaleidoscope-Hardware-GD32-Eval/src/kaleidoscope/device/gd32/eval/KeyScanner.cpp index 8e8699bc..cf3e6f3c 100644 --- a/plugins/Kaleidoscope-Hardware-GD32-Eval/src/kaleidoscope/device/gd32/eval/KeyScanner.cpp +++ b/plugins/Kaleidoscope-Hardware-GD32-Eval/src/kaleidoscope/device/gd32/eval/KeyScanner.cpp @@ -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); diff --git a/plugins/Kaleidoscope-Hardware-Keyboardio-Model01/src/kaleidoscope/device/keyboardio/Model01.cpp b/plugins/Kaleidoscope-Hardware-Keyboardio-Model01/src/kaleidoscope/device/keyboardio/Model01.cpp index 0fb2e820..85f8e566 100644 --- a/plugins/Kaleidoscope-Hardware-Keyboardio-Model01/src/kaleidoscope/device/keyboardio/Model01.cpp +++ b/plugins/Kaleidoscope-Hardware-Keyboardio-Model01/src/kaleidoscope/device/keyboardio/Model01.cpp @@ -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); } diff --git a/plugins/Kaleidoscope-Hardware-Keyboardio-Model01/src/kaleidoscope/device/keyboardio/Model01.h b/plugins/Kaleidoscope-Hardware-Keyboardio-Model01/src/kaleidoscope/device/keyboardio/Model01.h index 14f60631..61d2f65b 100644 --- a/plugins/Kaleidoscope-Hardware-Keyboardio-Model01/src/kaleidoscope/device/keyboardio/Model01.h +++ b/plugins/Kaleidoscope-Hardware-Keyboardio-Model01/src/kaleidoscope/device/keyboardio/Model01.h @@ -60,7 +60,7 @@ class Model01LEDDriver : public kaleidoscope::driver::led::Base -#define Key_Redial Key(kaleidoscope::ranges::REDIAL) +constexpr Key Key_Redial = Key(kaleidoscope::ranges::REDIAL); namespace kaleidoscope { namespace plugin { diff --git a/plugins/Kaleidoscope-SpaceCadet/src/kaleidoscope/plugin/SpaceCadet.h b/plugins/Kaleidoscope-SpaceCadet/src/kaleidoscope/plugin/SpaceCadet.h index 3365d755..0c4d372a 100644 --- a/plugins/Kaleidoscope-SpaceCadet/src/kaleidoscope/plugin/SpaceCadet.h +++ b/plugins/Kaleidoscope-SpaceCadet/src/kaleidoscope/plugin/SpaceCadet.h @@ -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 { diff --git a/plugins/Kaleidoscope-Syster/src/kaleidoscope/plugin/Syster.cpp b/plugins/Kaleidoscope-Syster/src/kaleidoscope/plugin/Syster.cpp index 59d42728..8292de5c 100644 --- a/plugins/Kaleidoscope-Syster/src/kaleidoscope/plugin/Syster.cpp +++ b/plugins/Kaleidoscope-Syster/src/kaleidoscope/plugin/Syster.cpp @@ -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; } diff --git a/plugins/Kaleidoscope-Syster/src/kaleidoscope/plugin/Syster.h b/plugins/Kaleidoscope-Syster/src/kaleidoscope/plugin/Syster.h index ab47c0ea..f8c36898 100644 --- a/plugins/Kaleidoscope-Syster/src/kaleidoscope/plugin/Syster.h +++ b/plugins/Kaleidoscope-Syster/src/kaleidoscope/plugin/Syster.h @@ -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 { diff --git a/plugins/Kaleidoscope-TapDance/src/kaleidoscope/plugin/TapDance.h b/plugins/Kaleidoscope-TapDance/src/kaleidoscope/plugin/TapDance.h index 2c46f98c..fb1fd640 100644 --- a/plugins/Kaleidoscope-TapDance/src/kaleidoscope/plugin/TapDance.h +++ b/plugins/Kaleidoscope-TapDance/src/kaleidoscope/plugin/TapDance.h @@ -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 { diff --git a/plugins/Kaleidoscope-TopsyTurvy/src/kaleidoscope/plugin/TopsyTurvy.h b/plugins/Kaleidoscope-TopsyTurvy/src/kaleidoscope/plugin/TopsyTurvy.h index 9a3ab9ca..2f397dd4 100644 --- a/plugins/Kaleidoscope-TopsyTurvy/src/kaleidoscope/plugin/TopsyTurvy.h +++ b/plugins/Kaleidoscope-TopsyTurvy/src/kaleidoscope/plugin/TopsyTurvy.h @@ -20,11 +20,15 @@ #include "kaleidoscope/Runtime.h" #include -#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) {} diff --git a/plugins/Kaleidoscope-Turbo/src/kaleidoscope/plugin/Turbo.h b/plugins/Kaleidoscope-Turbo/src/kaleidoscope/plugin/Turbo.h index 463b4434..a2b3fab2 100644 --- a/plugins/Kaleidoscope-Turbo/src/kaleidoscope/plugin/Turbo.h +++ b/plugins/Kaleidoscope-Turbo/src/kaleidoscope/plugin/Turbo.h @@ -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 { diff --git a/src/kaleidoscope/KeyAddrBitfield.h b/src/kaleidoscope/KeyAddrBitfield.h index 2a74cf54..ef75baa6 100644 --- a/src/kaleidoscope/KeyAddrBitfield.h +++ b/src/kaleidoscope/KeyAddrBitfield.h @@ -29,7 +29,7 @@ namespace kaleidoscope { // when calling this function (e.g. `bitfieldSize(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 +template constexpr _WidthType bitfieldSize(_WidthType n) { return ((n - 1) / (8 * sizeof(_UnitType))) + 1; } diff --git a/src/kaleidoscope/driver/hid/base/Keyboard.h b/src/kaleidoscope/driver/hid/base/Keyboard.h index c7aac2a8..61bcbdbd 100644 --- a/src/kaleidoscope/driver/hid/base/Keyboard.h +++ b/src/kaleidoscope/driver/hid/base/Keyboard.h @@ -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); } diff --git a/src/kaleidoscope/driver/keyscanner/ATmega.h b/src/kaleidoscope/driver/keyscanner/ATmega.h index 3fa4bb83..b8e05eb3 100644 --- a/src/kaleidoscope/driver/keyscanner/ATmega.h +++ b/src/kaleidoscope/driver/keyscanner/ATmega.h @@ -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); diff --git a/src/kaleidoscope/layers.cpp b/src/kaleidoscope/layers.cpp index b7ff8c55..9a395d48 100644 --- a/src/kaleidoscope/layers.cpp +++ b/src/kaleidoscope/layers.cpp @@ -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; diff --git a/src/kaleidoscope/layers.h b/src/kaleidoscope/layers.h index 9428cc28..9f92d9f2 100644 --- a/src/kaleidoscope/layers.h +++ b/src/kaleidoscope/layers.h @@ -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); diff --git a/src/kaleidoscope/plugin/LEDControl.h b/src/kaleidoscope/plugin/LEDControl.h index a3f04b6e..2b119922 100644 --- a/src/kaleidoscope/plugin/LEDControl.h +++ b/src/kaleidoscope/plugin/LEDControl.h @@ -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 {