diff --git a/plugins/Kaleidoscope-DefaultLEDModeConfig/README.md b/plugins/Kaleidoscope-DefaultLEDModeConfig/README.md new file mode 100644 index 00000000..e9302649 --- /dev/null +++ b/plugins/Kaleidoscope-DefaultLEDModeConfig/README.md @@ -0,0 +1,62 @@ +# DefaultLEDModeConfig + +The `DefaultLEDModeConfig` plugin provides a way to set a default LED mode, the +LED mode the device starts up with active, via Focus. + +By default the first LED mode enabled will be the active one, unless set +otherwise in `setup()`. To make this configurable, without having to reorder the +LED modes, this plugin provides the necessary tools to accomplish that. + +## Using the plugin + +The example below shows how to use the plugin, including setting up a LED mode +other than the first to use as a default in case EEPROM is uninitialized. + +```c++ +#include +#include +#include +#include +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, + LEDControl, + LEDOff, + LEDRainbowEffect, + LEDRainbowWaveEffect, + Focus, + DefaultLEDModeConfig); + +void setup() { + Kaleidoscope.setup(); + + DefaultLEDModeConfig.activeLEDModeIfUnconfigured( + &LEDRainbowWaveEffect + ); +} +``` + +## Plugin methods + +The plugin provides a singleton object called `DefaultLEDModeConfig`, with a single method: + +### `.activateLEDModeIfUnconfigured(&LEDModePlugin)` + +> Activates the LED mode pointed to by `&LEDModePlugin` if and only if the +> EEPROM slice of the plugin is unconfigured. This lets us set a default LED +> mode without persisting it into storage, or hard-coding it. + +## Focus commands + +### `led_mode.default` + +> Without arguments, prints the default LED mode's index. +> +> If an argument is given, it must be the index of the LED mode we wish to set +> as the default. + +## Dependencies + +* [Kaleidoscope-EEPROM-Settings](Kaleidoscope-EEPROM-Settings.md) +* [Kaleidoscope-FocusSerial](Kaleidoscope-FocusSerial.md) diff --git a/plugins/Kaleidoscope-DefaultLEDModeConfig/library.properties b/plugins/Kaleidoscope-DefaultLEDModeConfig/library.properties new file mode 100644 index 00000000..8194689e --- /dev/null +++ b/plugins/Kaleidoscope-DefaultLEDModeConfig/library.properties @@ -0,0 +1,7 @@ +name=Kaleidoscope-DefaultLEDModeConfig +version=0.0.0 +sentence=Save & restore the default LED mode +maintainer=Kaleidoscope's Developers +url=https://github.com/keyboardio/Kaleidoscope +author=Keyboardio +paragraph= diff --git a/plugins/Kaleidoscope-DefaultLEDModeConfig/src/Kaleidoscope-DefaultLEDModeConfig.h b/plugins/Kaleidoscope-DefaultLEDModeConfig/src/Kaleidoscope-DefaultLEDModeConfig.h new file mode 100644 index 00000000..805938c7 --- /dev/null +++ b/plugins/Kaleidoscope-DefaultLEDModeConfig/src/Kaleidoscope-DefaultLEDModeConfig.h @@ -0,0 +1,20 @@ +/* -*- mode: c++ -*- + * Kaleidoscope - Firmware for computer input devices + * Copyright (C) 2022 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 . + */ + +#pragma once + +#include "kaleidoscope/plugin/DefaultLEDModeConfig.h" // IWYU pragma: export diff --git a/plugins/Kaleidoscope-DefaultLEDModeConfig/src/kaleidoscope/plugin/DefaultLEDModeConfig.cpp b/plugins/Kaleidoscope-DefaultLEDModeConfig/src/kaleidoscope/plugin/DefaultLEDModeConfig.cpp new file mode 100644 index 00000000..0f13ceca --- /dev/null +++ b/plugins/Kaleidoscope-DefaultLEDModeConfig/src/kaleidoscope/plugin/DefaultLEDModeConfig.cpp @@ -0,0 +1,89 @@ +/* -*- mode: c++ -*- + * Kaleidoscope - Firmware for computer input devices + * Copyright (C) 2022 Keyboard.io, Inc. + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "kaleidoscope/plugin/DefaultLEDModeConfig.h" + +#include // for PSTR, strcmp_P, F, __FlashStringHelper +#include // for EEPROMSettings +#include // for Focus, FocusSerial +#include // for uint8_t, uint16_t + +#include "kaleidoscope/Runtime.h" // for Runtime, Runtime_ +#include "kaleidoscope/device/device.h" // for VirtualProps::Storage, Base<>::Storage +#include "kaleidoscope/event_handler_result.h" // for EventHandlerResult, EventHandlerResult::OK +#include "kaleidoscope/plugin/LEDControl.h" // for LEDControl + +namespace kaleidoscope { +namespace plugin { + +uint16_t DefaultLEDModeConfig::settings_base_; +struct DefaultLEDModeConfig::settings DefaultLEDModeConfig::settings_; + +EventHandlerResult DefaultLEDModeConfig::onSetup() { + settings_base_ = ::EEPROMSettings.requestSlice(sizeof(settings_)); + + Runtime.storage().get(settings_base_, settings_); + + // If our slice is uninitialized, then return early, without touching the + // current mode. + if (Runtime.storage().isSliceUninitialized(settings_base_, sizeof(settings_))) + return EventHandlerResult::OK; + + ::LEDControl.set_mode(settings_.default_mode_index); + + return EventHandlerResult::OK; +} + +EventHandlerResult DefaultLEDModeConfig::onFocusEvent(const char *command) { + const char *cmd = PSTR("led_mode.default"); + + if (::Focus.handleHelp(command, cmd)) + return EventHandlerResult::OK; + + if (strcmp_P(command, cmd) != 0) + return EventHandlerResult::OK; + + if (::Focus.isEOL()) { + ::Focus.send(settings_.default_mode_index); + } else { + uint8_t idx; + ::Focus.read(idx); + settings_.default_mode_index = idx; + + ::LEDControl.set_mode(idx); + Runtime.storage().put(settings_base_, settings_); + Runtime.storage().commit(); + } + + return EventHandlerResult::EVENT_CONSUMED; +} + +EventHandlerResult DefaultLEDModeConfig::onNameQuery() { + return ::Focus.sendName(F("DefaultLEDModeConfig")); +} + +void DefaultLEDModeConfig::activateLEDModeIfUnconfigured(LEDModeInterface *plugin) { + if (!Runtime.storage().isSliceUninitialized(settings_base_, sizeof(settings_))) + return; + + plugin->activate(); +} + +} // namespace plugin +} // namespace kaleidoscope + +kaleidoscope::plugin::DefaultLEDModeConfig DefaultLEDModeConfig; diff --git a/plugins/Kaleidoscope-DefaultLEDModeConfig/src/kaleidoscope/plugin/DefaultLEDModeConfig.h b/plugins/Kaleidoscope-DefaultLEDModeConfig/src/kaleidoscope/plugin/DefaultLEDModeConfig.h new file mode 100644 index 00000000..24de361c --- /dev/null +++ b/plugins/Kaleidoscope-DefaultLEDModeConfig/src/kaleidoscope/plugin/DefaultLEDModeConfig.h @@ -0,0 +1,47 @@ +/* -*- mode: c++ -*- + * Kaleidoscope - Firmware for computer input devices + * Copyright (C) 2022 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 . + */ + +#pragma once + +#include // for uint8_t, uint16_t + +#include "kaleidoscope/event_handler_result.h" // for EventHandlerResult +#include "kaleidoscope/plugin.h" // for Plugin +#include "kaleidoscope/plugin/LEDModeInterface.h" // for LEDModeInterface + +namespace kaleidoscope { +namespace plugin { + +class DefaultLEDModeConfig : public kaleidoscope::Plugin { + public: + EventHandlerResult onSetup(); + EventHandlerResult onNameQuery(); + EventHandlerResult onFocusEvent(const char *command); + + void activateLEDModeIfUnconfigured(LEDModeInterface *plugin); + + private: + static uint16_t settings_base_; + static struct settings { + uint8_t default_mode_index; + } settings_; +}; + +} // namespace plugin +} // namespace kaleidoscope + +extern kaleidoscope::plugin::DefaultLEDModeConfig DefaultLEDModeConfig;