summaryrefslogtreecommitdiff
path: root/src/input
diff options
context:
space:
mode:
Diffstat (limited to 'src/input')
-rw-r--r--src/input/CMakeLists.txt13
-rw-r--r--src/input/device_factory.cpp58
-rw-r--r--src/input/feedback_haptics.cpp37
-rw-r--r--src/input/include/device_factory.hpp39
-rw-r--r--src/input/include/feedback_device.hpp32
-rw-r--r--src/input/include/feedback_haptics.hpp26
-rw-r--r--src/input/include/input_device.hpp37
-rw-r--r--src/input/include/input_hook.hpp75
-rw-r--r--src/input/include/input_hook_actions.hpp31
-rw-r--r--src/input/include/input_nav_buttons.hpp38
-rw-r--r--src/input/include/input_touch_dpad.hpp40
-rw-r--r--src/input/include/input_touch_wheel.hpp56
-rw-r--r--src/input/include/input_trigger.hpp42
-rw-r--r--src/input/include/input_volume_buttons.hpp37
-rw-r--r--src/input/include/lvgl_input_driver.hpp112
-rw-r--r--src/input/input_hook.cpp97
-rw-r--r--src/input/input_hook_actions.cpp73
-rw-r--r--src/input/input_nav_buttons.cpp35
-rw-r--r--src/input/input_touch_dpad.cpp63
-rw-r--r--src/input/input_touch_wheel.cpp137
-rw-r--r--src/input/input_trigger.cpp88
-rw-r--r--src/input/input_volume_buttons.cpp33
-rw-r--r--src/input/lvgl_input_driver.cpp258
23 files changed, 0 insertions, 1457 deletions
diff --git a/src/input/CMakeLists.txt b/src/input/CMakeLists.txt
deleted file mode 100644
index 4754ba47..00000000
--- a/src/input/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2023 jacqueline <me@jacqueline.id.au>
-#
-# SPDX-License-Identifier: GPL-3.0-only
-
-idf_component_register(
- SRCS "input_touch_wheel.cpp" "input_touch_dpad.cpp" "input_trigger.cpp"
- "input_volume_buttons.cpp" "lvgl_input_driver.cpp" "feedback_haptics.cpp"
- "device_factory.cpp" "input_nav_buttons.cpp" "input_hook.cpp"
- "input_hook_actions.cpp"
- INCLUDE_DIRS "include"
- REQUIRES "drivers" "lvgl" "events" "system_fsm")
-
-target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS})
diff --git a/src/input/device_factory.cpp b/src/input/device_factory.cpp
deleted file mode 100644
index 65f4d785..00000000
--- a/src/input/device_factory.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2023 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#include "device_factory.hpp"
-
-#include <memory>
-
-#include "feedback_haptics.hpp"
-#include "input_device.hpp"
-#include "input_nav_buttons.hpp"
-#include "input_touch_dpad.hpp"
-#include "input_touch_wheel.hpp"
-#include "input_volume_buttons.hpp"
-
-namespace input {
-
-DeviceFactory::DeviceFactory(
- std::shared_ptr<system_fsm::ServiceLocator> services)
- : services_(services) {
- if (services->touchwheel()) {
- wheel_ =
- std::make_shared<TouchWheel>(services->nvs(), **services->touchwheel());
- }
-}
-
-auto DeviceFactory::createInputs(drivers::NvsStorage::InputModes mode)
- -> std::vector<std::shared_ptr<IInputDevice>> {
- std::vector<std::shared_ptr<IInputDevice>> ret;
- switch (mode) {
- case drivers::NvsStorage::InputModes::kButtonsOnly:
- ret.push_back(std::make_shared<NavButtons>(services_->gpios()));
- break;
- case drivers::NvsStorage::InputModes::kDirectionalWheel:
- ret.push_back(std::make_shared<VolumeButtons>(services_->gpios()));
- if (services_->touchwheel()) {
- ret.push_back(std::make_shared<TouchDPad>(**services_->touchwheel()));
- }
- break;
- case drivers::NvsStorage::InputModes::kRotatingWheel:
- default: // Don't break input over a bad enum value.
- ret.push_back(std::make_shared<VolumeButtons>(services_->gpios()));
- if (wheel_) {
- ret.push_back(wheel_);
- }
- break;
- }
- return ret;
-}
-
-auto DeviceFactory::createFeedbacks()
- -> std::vector<std::shared_ptr<IFeedbackDevice>> {
- return {std::make_shared<Haptics>(services_->haptics())};
-}
-
-} // namespace input
diff --git a/src/input/feedback_haptics.cpp b/src/input/feedback_haptics.cpp
deleted file mode 100644
index 5e83d0d6..00000000
--- a/src/input/feedback_haptics.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#include "feedback_haptics.hpp"
-
-#include <cstdint>
-
-#include "lvgl/lvgl.h"
-
-#include "core/lv_event.h"
-#include "esp_log.h"
-
-#include "haptics.hpp"
-
-namespace input {
-
-using Effect = drivers::Haptics::Effect;
-
-Haptics::Haptics(drivers::Haptics& haptics_) : haptics_(haptics_) {}
-
-auto Haptics::feedback(uint8_t event_type) -> void {
- switch (event_type) {
- case LV_EVENT_FOCUSED:
- haptics_.PlayWaveformEffect(Effect::kMediumClick1_100Pct);
- break;
- case LV_EVENT_CLICKED:
- haptics_.PlayWaveformEffect(Effect::kSharpClick_100Pct);
- break;
- default:
- break;
- }
-}
-
-} // namespace input
diff --git a/src/input/include/device_factory.hpp b/src/input/include/device_factory.hpp
deleted file mode 100644
index dd9c7133..00000000
--- a/src/input/include/device_factory.hpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2023 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#pragma once
-
-#include <cstdint>
-#include <memory>
-
-#include "feedback_device.hpp"
-#include "input_device.hpp"
-#include "input_touch_wheel.hpp"
-#include "nvs.hpp"
-#include "service_locator.hpp"
-
-namespace input {
-
-class DeviceFactory {
- public:
- DeviceFactory(std::shared_ptr<system_fsm::ServiceLocator>);
-
- auto createInputs(drivers::NvsStorage::InputModes mode)
- -> std::vector<std::shared_ptr<IInputDevice>>;
-
- auto createFeedbacks() -> std::vector<std::shared_ptr<IFeedbackDevice>>;
-
- auto touch_wheel() -> std::shared_ptr<TouchWheel> { return wheel_; }
-
- private:
- std::shared_ptr<system_fsm::ServiceLocator> services_;
-
- // HACK: the touchwheel is current a special case, since it's the only input
- // device that has some kind of setting/configuration; scroll sensitivity.
- std::shared_ptr<TouchWheel> wheel_;
-};
-
-} // namespace input
diff --git a/src/input/include/feedback_device.hpp b/src/input/include/feedback_device.hpp
deleted file mode 100644
index 4faeeafd..00000000
--- a/src/input/include/feedback_device.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#pragma once
-
-#include <cstdint>
-
-namespace input {
-
-/*
- * Interface for providing non-visual feedback to the user as a result of LVGL
- * events. 'Feedback Devices' are able to observe all events that are generated
- * by LVGL as a result of Input Devices.
- *
- * Implementations of this interface are a mix of hardware features (e.g. a
- * haptic motor buzzing when your selection changes) and firmware features
- * (e.g. playing audio feedback that describes the selected element).
- */
-class IFeedbackDevice {
- public:
- virtual ~IFeedbackDevice() {}
-
- virtual auto feedback(uint8_t event_type) -> void = 0;
-
- // TODO: Add configuration; likely the same shape of interface that
- // IInputDevice uses.
-};
-
-} // namespace input
diff --git a/src/input/include/feedback_haptics.hpp b/src/input/include/feedback_haptics.hpp
deleted file mode 100644
index a307a429..00000000
--- a/src/input/include/feedback_haptics.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#pragma once
-
-#include <cstdint>
-
-#include "feedback_device.hpp"
-#include "haptics.hpp"
-
-namespace input {
-
-class Haptics : public IFeedbackDevice {
- public:
- Haptics(drivers::Haptics& haptics_);
-
- auto feedback(uint8_t event_type) -> void override;
-
- private:
- drivers::Haptics& haptics_;
-};
-
-} // namespace input
diff --git a/src/input/include/input_device.hpp b/src/input/include/input_device.hpp
deleted file mode 100644
index d944c3bf..00000000
--- a/src/input/include/input_device.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#pragma once
-
-#include <functional>
-#include <string>
-#include <vector>
-
-#include "hal/lv_hal_indev.h"
-#include "input_hook.hpp"
-#include "property.hpp"
-
-namespace input {
-
-/*
- * Interface for all device input methods. Each 'Input Device' is polled by
- * LVGL at regular intervals, and can effect the device either via LVGL's input
- * device driver API, or by emitting events for other parts of the system to
- * react to (e.g. issuing a play/pause event, or altering the volume).
- */
-class IInputDevice {
- public:
- virtual ~IInputDevice() {}
-
- virtual auto read(lv_indev_data_t* data) -> void = 0;
-
- virtual auto name() -> std::string = 0;
- virtual auto triggers() -> std::vector<std::reference_wrapper<TriggerHooks>> {
- return {};
- }
-};
-
-} // namespace input
diff --git a/src/input/include/input_hook.hpp b/src/input/include/input_hook.hpp
deleted file mode 100644
index a8705210..00000000
--- a/src/input/include/input_hook.hpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#pragma once
-
-#include <functional>
-#include <optional>
-#include <string>
-
-#include "hal/lv_hal_indev.h"
-#include "lua.hpp"
-
-#include "input_trigger.hpp"
-
-namespace input {
-
-struct HookCallback {
- std::string name;
- std::function<void(lv_indev_data_t*)> fn;
-};
-
-class Hook {
- public:
- Hook(std::string name, std::optional<HookCallback> cb);
-
- auto invoke(lv_indev_data_t*) -> void;
- auto override(std::optional<HookCallback>) -> void;
-
- auto name() const -> const std::string& { return name_; }
- auto callback() -> std::optional<HookCallback>;
-
- // Not copyable or movable.
- Hook(const Hook&) = delete;
- Hook& operator=(const Hook&) = delete;
-
- private:
- std::string name_;
- std::optional<HookCallback> default_;
- std::optional<HookCallback> override_;
-};
-
-class TriggerHooks {
- public:
- TriggerHooks(std::string name, std::optional<HookCallback> cb)
- : TriggerHooks(name, cb, cb, cb, cb) {}
- TriggerHooks(std::string name,
- std::optional<HookCallback> click,
- std::optional<HookCallback> double_click,
- std::optional<HookCallback> long_press,
- std::optional<HookCallback> repeat);
-
- auto update(bool, lv_indev_data_t*) -> void;
- auto override(Trigger::State, std::optional<HookCallback>) -> void;
-
- auto name() const -> const std::string&;
- auto hooks() -> std::vector<std::reference_wrapper<Hook>>;
-
- // Not copyable or movable.
- TriggerHooks(const TriggerHooks&) = delete;
- TriggerHooks& operator=(const TriggerHooks&) = delete;
-
- private:
- std::string name_;
- Trigger trigger_;
-
- Hook click_;
- Hook double_click_;
- Hook long_press_;
- Hook repeat_;
-};
-
-} // namespace input
diff --git a/src/input/include/input_hook_actions.hpp b/src/input/include/input_hook_actions.hpp
deleted file mode 100644
index 105bd10d..00000000
--- a/src/input/include/input_hook_actions.hpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#pragma once
-
-#include "hal/lv_hal_indev.h"
-#include "input_hook.hpp"
-
-namespace input {
-namespace actions {
-
-auto select() -> HookCallback;
-
-auto scrollUp() -> HookCallback;
-auto scrollDown() -> HookCallback;
-
-auto scrollToTop() -> HookCallback;
-auto scrollToBottom() -> HookCallback;
-
-auto goBack() -> HookCallback;
-
-auto volumeUp() -> HookCallback;
-auto volumeDown() -> HookCallback;
-
-auto allActions() -> std::vector<HookCallback>;
-
-} // namespace actions
-} // namespace input
diff --git a/src/input/include/input_nav_buttons.hpp b/src/input/include/input_nav_buttons.hpp
deleted file mode 100644
index 9feeb375..00000000
--- a/src/input/include/input_nav_buttons.hpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#pragma once
-
-#include <cstdint>
-
-#include "gpios.hpp"
-#include "hal/lv_hal_indev.h"
-
-#include "haptics.hpp"
-#include "input_device.hpp"
-#include "input_hook.hpp"
-#include "input_trigger.hpp"
-#include "touchwheel.hpp"
-
-namespace input {
-
-class NavButtons : public IInputDevice {
- public:
- NavButtons(drivers::IGpios&);
-
- auto read(lv_indev_data_t* data) -> void override;
-
- auto name() -> std::string override;
- auto triggers() -> std::vector<std::reference_wrapper<TriggerHooks>> override;
-
- private:
- drivers::IGpios& gpios_;
-
- TriggerHooks up_;
- TriggerHooks down_;
-};
-
-} // namespace input
diff --git a/src/input/include/input_touch_dpad.hpp b/src/input/include/input_touch_dpad.hpp
deleted file mode 100644
index 0c45b2d9..00000000
--- a/src/input/include/input_touch_dpad.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#pragma once
-
-#include <cstdint>
-
-#include "hal/lv_hal_indev.h"
-
-#include "haptics.hpp"
-#include "input_device.hpp"
-#include "input_hook.hpp"
-#include "input_trigger.hpp"
-#include "touchwheel.hpp"
-
-namespace input {
-
-class TouchDPad : public IInputDevice {
- public:
- TouchDPad(drivers::TouchWheel&);
-
- auto read(lv_indev_data_t* data) -> void override;
-
- auto name() -> std::string override;
- auto triggers() -> std::vector<std::reference_wrapper<TriggerHooks>> override;
-
- private:
- drivers::TouchWheel& wheel_;
-
- TriggerHooks centre_;
- TriggerHooks up_;
- TriggerHooks right_;
- TriggerHooks down_;
- TriggerHooks left_;
-};
-
-} // namespace input
diff --git a/src/input/include/input_touch_wheel.hpp b/src/input/include/input_touch_wheel.hpp
deleted file mode 100644
index 764cc68d..00000000
--- a/src/input/include/input_touch_wheel.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#pragma once
-
-#include <sys/_stdint.h>
-#include <cstdint>
-
-#include "hal/lv_hal_indev.h"
-
-#include "haptics.hpp"
-#include "input_device.hpp"
-#include "input_hook.hpp"
-#include "input_trigger.hpp"
-#include "nvs.hpp"
-#include "property.hpp"
-#include "touchwheel.hpp"
-
-namespace input {
-
-class TouchWheel : public IInputDevice {
- public:
- TouchWheel(drivers::NvsStorage&, drivers::TouchWheel&);
-
- auto read(lv_indev_data_t* data) -> void override;
-
- auto name() -> std::string override;
- auto triggers() -> std::vector<std::reference_wrapper<TriggerHooks>> override;
-
- auto sensitivity() -> lua::Property&;
-
- private:
- auto calculateTicks(const drivers::TouchWheelData& data) -> int8_t;
- auto calculateThreshold(uint8_t sensitivity) -> uint8_t;
-
- drivers::NvsStorage& nvs_;
- drivers::TouchWheel& wheel_;
-
- lua::Property sensitivity_;
-
- TriggerHooks centre_;
- TriggerHooks up_;
- TriggerHooks right_;
- TriggerHooks down_;
- TriggerHooks left_;
-
- bool is_scrolling_;
- uint8_t threshold_;
- bool is_first_read_;
- uint8_t last_angle_;
-};
-
-} // namespace input
diff --git a/src/input/include/input_trigger.hpp b/src/input/include/input_trigger.hpp
deleted file mode 100644
index bcafa8ad..00000000
--- a/src/input/include/input_trigger.hpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#pragma once
-
-#include <cstdint>
-#include <optional>
-
-#include "hal/lv_hal_indev.h"
-
-namespace input {
-
-const uint16_t kDoubleClickDelayMs = 500;
-const uint16_t kLongPressDelayMs = LV_INDEV_DEF_LONG_PRESS_TIME;
-const uint16_t kRepeatDelayMs = LV_INDEV_DEF_LONG_PRESS_REP_TIME;
-
-class Trigger {
- public:
- enum class State {
- kNone,
- kClick,
- kDoubleClick,
- kLongPress,
- kRepeatPress,
- };
-
- Trigger();
-
- auto update(bool is_pressed) -> State;
-
- private:
- std::optional<uint64_t> touch_time_ms_;
- bool was_pressed_;
-
- bool was_double_click_;
- uint16_t times_long_pressed_;
-};
-
-} // namespace input
diff --git a/src/input/include/input_volume_buttons.hpp b/src/input/include/input_volume_buttons.hpp
deleted file mode 100644
index e3246df4..00000000
--- a/src/input/include/input_volume_buttons.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#pragma once
-
-#include <cstdint>
-
-#include "gpios.hpp"
-#include "hal/lv_hal_indev.h"
-
-#include "haptics.hpp"
-#include "input_device.hpp"
-#include "input_hook.hpp"
-#include "touchwheel.hpp"
-
-namespace input {
-
-class VolumeButtons : public IInputDevice {
- public:
- VolumeButtons(drivers::IGpios&);
-
- auto read(lv_indev_data_t* data) -> void override;
-
- auto name() -> std::string override;
- auto triggers() -> std::vector<std::reference_wrapper<TriggerHooks>> override;
-
- private:
- drivers::IGpios& gpios_;
-
- TriggerHooks up_;
- TriggerHooks down_;
-};
-
-} // namespace input
diff --git a/src/input/include/lvgl_input_driver.hpp b/src/input/include/lvgl_input_driver.hpp
deleted file mode 100644
index 9adaf143..00000000
--- a/src/input/include/lvgl_input_driver.hpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2023 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#pragma once
-
-#include <cstdint>
-#include <deque>
-#include <memory>
-#include <set>
-
-#include "core/lv_group.h"
-#include "device_factory.hpp"
-#include "feedback_device.hpp"
-#include "gpios.hpp"
-#include "hal/lv_hal_indev.h"
-
-#include "input_device.hpp"
-#include "input_hook.hpp"
-#include "lua_thread.hpp"
-#include "nvs.hpp"
-#include "property.hpp"
-#include "touchwheel.hpp"
-
-namespace input {
-
-/*
- * Implementation of an LVGL input device. This class composes multiple
- * IInputDevice and IFeedbackDevice instances together into a single LVGL
- * device.
- */
-class LvglInputDriver {
- public:
- LvglInputDriver(drivers::NvsStorage& nvs, DeviceFactory&);
-
- auto mode() -> lua::Property& { return mode_; }
-
- auto read(lv_indev_data_t* data) -> void;
- auto feedback(uint8_t) -> void;
-
- auto registration() -> lv_indev_t* { return registration_; }
- auto lock(bool l) -> void { is_locked_ = l; }
-
- auto pushHooks(lua_State* L) -> int;
-
- private:
- drivers::NvsStorage& nvs_;
- DeviceFactory& factory_;
-
- lua::Property mode_;
- lv_indev_drv_t driver_;
- lv_indev_t* registration_;
-
- std::vector<std::shared_ptr<IInputDevice>> inputs_;
- std::vector<std::shared_ptr<IFeedbackDevice>> feedbacks_;
-
- /*
- * Key for identifying which device, trigger, and specific hook are being
- * overriden by Lua.
- */
- struct OverrideSelector {
- std::string device_name;
- std::string trigger_name;
- std::string hook_name;
-
- friend bool operator<(const OverrideSelector& l,
- const OverrideSelector& r) {
- return std::tie(l.device_name, l.trigger_name, l.hook_name) <
- std::tie(r.device_name, r.trigger_name, r.hook_name);
- }
- };
-
- /* Userdata object for tracking the Lua mirror of a TriggerHooks object. */
- class LuaTrigger {
- public:
- LuaTrigger(LvglInputDriver&, IInputDevice&, TriggerHooks&);
-
- static auto get(lua_State*, int idx) -> LuaTrigger&;
- static auto luaGc(lua_State*) -> int;
- static auto luaToString(lua_State*) -> int;
- static auto luaNewIndex(lua_State*) -> int;
-
- static constexpr struct luaL_Reg kFuncs[] = {{"__gc", luaGc},
- {"__tostring", luaToString},
- {"__newindex", luaNewIndex},
- {NULL, NULL}};
-
- private:
- LvglInputDriver* driver_;
-
- std::string device_;
- std::string trigger_;
- std::map<std::string, std::string> hooks_;
- };
-
- /* A hook override implemented as a lua callback */
- struct LuaOverride {
- lua_State* L;
- int ref;
- };
-
- std::map<OverrideSelector, LuaOverride> overrides_;
-
- auto setOverride(lua_State* L, const OverrideSelector&) -> void;
- auto applyOverride(const OverrideSelector&, LuaOverride&) -> void;
-
- bool is_locked_;
-};
-
-} // namespace input
diff --git a/src/input/input_hook.cpp b/src/input/input_hook.cpp
deleted file mode 100644
index bf9f3596..00000000
--- a/src/input/input_hook.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#include "input_hook.hpp"
-
-#include <functional>
-#include <optional>
-#include "hal/lv_hal_indev.h"
-#include "input_trigger.hpp"
-#include "lua.h"
-
-namespace input {
-
-Hook::Hook(std::string name, std::optional<HookCallback> cb)
- : name_(name), default_(cb), override_() {}
-
-auto Hook::invoke(lv_indev_data_t* d) -> void {
- auto cb = callback();
- if (cb) {
- std::invoke(cb->fn, d);
- }
-}
-
-auto Hook::override(std::optional<HookCallback> cb) -> void {
- override_ = cb;
-}
-
-auto Hook::callback() -> std::optional<HookCallback> {
- if (override_) {
- return override_;
- } else if (default_) {
- return default_;
- }
- return {};
-}
-
-TriggerHooks::TriggerHooks(std::string name,
- std::optional<HookCallback> click,
- std::optional<HookCallback> double_click,
- std::optional<HookCallback> long_press,
- std::optional<HookCallback> repeat)
- : name_(name),
- click_("click", click),
- double_click_("double_click", double_click),
- long_press_("long_press", long_press),
- repeat_("repeat", repeat) {}
-
-auto TriggerHooks::update(bool pressed, lv_indev_data_t* d) -> void {
- switch (trigger_.update(pressed)) {
- case Trigger::State::kClick:
- click_.invoke(d);
- break;
- case Trigger::State::kDoubleClick:
- double_click_.invoke(d);
- break;
- case Trigger::State::kLongPress:
- long_press_.invoke(d);
- break;
- case Trigger::State::kRepeatPress:
- repeat_.invoke(d);
- break;
- case Trigger::State::kNone:
- default:
- break;
- }
-}
-
-auto TriggerHooks::override(Trigger::State s, std::optional<HookCallback> cb)
- -> void {
- switch (s) {
- case Trigger::State::kClick:
- click_.override(cb);
- break;
- case Trigger::State::kLongPress:
- long_press_.override(cb);
- break;
- case Trigger::State::kRepeatPress:
- repeat_.override(cb);
- break;
- case Trigger::State::kNone:
- default:
- break;
- }
-}
-
-auto TriggerHooks::name() const -> const std::string& {
- return name_;
-}
-
-auto TriggerHooks::hooks() -> std::vector<std::reference_wrapper<Hook>> {
- return {click_, long_press_, repeat_};
-}
-
-} // namespace input
diff --git a/src/input/input_hook_actions.cpp b/src/input/input_hook_actions.cpp
deleted file mode 100644
index 26075c4c..00000000
--- a/src/input/input_hook_actions.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#include "input_hook_actions.hpp"
-
-#include <cstdint>
-
-#include "hal/lv_hal_indev.h"
-
-#include "event_queue.hpp"
-#include "ui_events.hpp"
-
-namespace input {
-namespace actions {
-
-auto select() -> HookCallback {
- return HookCallback{.name = "select", .fn = [&](lv_indev_data_t* d) {
- d->state = LV_INDEV_STATE_PRESSED;
- }};
-}
-
-auto scrollUp() -> HookCallback {
- return HookCallback{.name = "scroll_up",
- .fn = [&](lv_indev_data_t* d) { d->enc_diff = -1; }};
-}
-
-auto scrollDown() -> HookCallback {
- return HookCallback{.name = "scroll_down",
- .fn = [&](lv_indev_data_t* d) { d->enc_diff = 1; }};
-}
-
-auto scrollToTop() -> HookCallback {
- return HookCallback{.name = "scroll_to_top", .fn = [&](lv_indev_data_t* d) {
- d->enc_diff = INT16_MIN;
- }};
-}
-
-auto scrollToBottom() -> HookCallback {
- return HookCallback{
- .name = "scroll_to_bottom",
- .fn = [&](lv_indev_data_t* d) { d->enc_diff = INT16_MAX; }};
-}
-
-auto goBack() -> HookCallback {
- return HookCallback{.name = "back", .fn = [&](lv_indev_data_t* d) {
- events::Ui().Dispatch(ui::internal::BackPressed{});
- }};
-}
-
-auto volumeUp() -> HookCallback {
- return HookCallback{.name = "volume_up", .fn = [&](lv_indev_data_t* d) {
- events::Audio().Dispatch(audio::StepUpVolume{});
- }};
-}
-
-auto volumeDown() -> HookCallback {
- return HookCallback{.name = "volume_down", .fn = [&](lv_indev_data_t* d) {
- events::Audio().Dispatch(audio::StepDownVolume{});
- }};
-}
-
-auto allActions() -> std::vector<HookCallback> {
- return {
- select(), scrollUp(), scrollDown(), scrollToTop(),
- scrollToBottom(), goBack(), volumeUp(), volumeDown(),
- };
-}
-
-} // namespace actions
-} // namespace input
diff --git a/src/input/input_nav_buttons.cpp b/src/input/input_nav_buttons.cpp
deleted file mode 100644
index 61d80075..00000000
--- a/src/input/input_nav_buttons.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#include "input_nav_buttons.hpp"
-
-#include "event_queue.hpp"
-#include "gpios.hpp"
-#include "hal/lv_hal_indev.h"
-#include "input_hook_actions.hpp"
-
-namespace input {
-
-NavButtons::NavButtons(drivers::IGpios& gpios)
- : gpios_(gpios),
- up_("upper", {}, actions::scrollUp(), actions::select(), {}),
- down_("lower", {}, actions::scrollDown(), actions::select(), {}) {}
-
-auto NavButtons::read(lv_indev_data_t* data) -> void {
- up_.update(!gpios_.Get(drivers::IGpios::Pin::kKeyUp), data);
- down_.update(!gpios_.Get(drivers::IGpios::Pin::kKeyDown), data);
-}
-
-auto NavButtons::name() -> std::string {
- return "buttons";
-}
-
-auto NavButtons::triggers()
- -> std::vector<std::reference_wrapper<TriggerHooks>> {
- return {up_, down_};
-}
-
-} // namespace input
diff --git a/src/input/input_touch_dpad.cpp b/src/input/input_touch_dpad.cpp
deleted file mode 100644
index df17d766..00000000
--- a/src/input/input_touch_dpad.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#include "input_touch_dpad.hpp"
-
-#include <cstdint>
-
-#include "hal/lv_hal_indev.h"
-
-#include "event_queue.hpp"
-#include "haptics.hpp"
-#include "input_device.hpp"
-#include "input_hook_actions.hpp"
-#include "input_touch_dpad.hpp"
-#include "touchwheel.hpp"
-
-namespace input {
-
-TouchDPad::TouchDPad(drivers::TouchWheel& wheel)
- : wheel_(wheel),
- centre_("centre", actions::select(), {}, {}, {}),
- up_("up", actions::scrollUp()),
- right_("right", {}),
- down_("down", actions::scrollDown()),
- left_("left", actions::goBack()) {}
-
-auto TouchDPad::read(lv_indev_data_t* data) -> void {
- wheel_.Update();
- auto wheel_data = wheel_.GetTouchWheelData();
-
- centre_.update(wheel_data.is_button_touched, data);
-
- up_.update(
- wheel_data.is_wheel_touched &&
- drivers::TouchWheel::isAngleWithin(wheel_data.wheel_position, 0, 32),
- data);
- right_.update(
- wheel_data.is_wheel_touched && drivers::TouchWheel::isAngleWithin(
- wheel_data.wheel_position, 192, 32),
- data);
- down_.update(
- wheel_data.is_wheel_touched && drivers::TouchWheel::isAngleWithin(
- wheel_data.wheel_position, 128, 32),
- data);
- left_.update(
- wheel_data.is_wheel_touched &&
- drivers::TouchWheel::isAngleWithin(wheel_data.wheel_position, 64, 32),
- data);
-}
-
-auto TouchDPad::name() -> std::string {
- return "dpad";
-}
-
-auto TouchDPad::triggers()
- -> std::vector<std::reference_wrapper<TriggerHooks>> {
- return {centre_, up_, right_, down_, left_};
-}
-
-} // namespace input
diff --git a/src/input/input_touch_wheel.cpp b/src/input/input_touch_wheel.cpp
deleted file mode 100644
index 41fd73bc..00000000
--- a/src/input/input_touch_wheel.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#include "input_touch_wheel.hpp"
-
-#include <cstdint>
-#include <variant>
-
-#include "hal/lv_hal_indev.h"
-
-#include "event_queue.hpp"
-#include "haptics.hpp"
-#include "input_device.hpp"
-#include "input_hook_actions.hpp"
-#include "input_trigger.hpp"
-#include "nvs.hpp"
-#include "property.hpp"
-#include "touchwheel.hpp"
-#include "ui_events.hpp"
-
-namespace input {
-
-TouchWheel::TouchWheel(drivers::NvsStorage& nvs, drivers::TouchWheel& wheel)
- : nvs_(nvs),
- wheel_(wheel),
- sensitivity_(static_cast<int>(nvs.ScrollSensitivity()),
- [&](const lua::LuaValue& val) {
- if (!std::holds_alternative<int>(val)) {
- return false;
- }
- int int_val = std::get<int>(val);
- if (int_val < 0 || int_val > UINT8_MAX) {
- return false;
- }
- nvs.ScrollSensitivity(int_val);
- threshold_ = calculateThreshold(int_val);
- return true;
- }),
- centre_("centre", actions::select(), {}, {}, {}),
- up_("up", {}, actions::scrollToTop(), {}, {}),
- right_("right", {}),
- down_("down", {}, actions::scrollToBottom(), {}, {}),
- left_("left", {}, actions::goBack(), {}, {}),
- is_scrolling_(false),
- threshold_(calculateThreshold(nvs.ScrollSensitivity())),
- is_first_read_(true),
- last_angle_(0) {}
-
-auto TouchWheel::read(lv_indev_data_t* data) -> void {
- wheel_.Update();
- auto wheel_data = wheel_.GetTouchWheelData();
- int8_t ticks = calculateTicks(wheel_data);
-
- if (!wheel_data.is_wheel_touched) {
- // User has released the wheel.
- is_scrolling_ = false;
- data->enc_diff = 0;
- } else if (ticks != 0) {
- // User is touching the wheel, and has just passed the sensitivity
- // threshold for a scroll tick.
- is_scrolling_ = true;
- data->enc_diff = ticks;
- } else {
- // User is touching the wheel, but hasn't moved.
- data->enc_diff = 0;
- }
-
- centre_.update(wheel_data.is_button_touched && !wheel_data.is_wheel_touched,
- data);
-
- // If the user is touching the wheel but not scrolling, then they may be
- // clicking on one of the wheel's cardinal directions.
- bool pressing = wheel_data.is_wheel_touched && !is_scrolling_;
-
- up_.update(pressing && drivers::TouchWheel::isAngleWithin(
- wheel_data.wheel_position, 0, 32),
- data);
- right_.update(pressing && drivers::TouchWheel::isAngleWithin(
- wheel_data.wheel_position, 192, 32),
- data);
- down_.update(pressing && drivers::TouchWheel::isAngleWithin(
- wheel_data.wheel_position, 128, 32),
- data);
- left_.update(pressing && drivers::TouchWheel::isAngleWithin(
- wheel_data.wheel_position, 64, 32),
- data);
-}
-
-auto TouchWheel::name() -> std::string {
- return "wheel";
-}
-
-auto TouchWheel::triggers()
- -> std::vector<std::reference_wrapper<TriggerHooks>> {
- return {centre_, up_, right_, down_, left_};
-}
-
-auto TouchWheel::sensitivity() -> lua::Property& {
- return sensitivity_;
-}
-
-auto TouchWheel::calculateTicks(const drivers::TouchWheelData& data) -> int8_t {
- if (!data.is_wheel_touched) {
- is_first_read_ = true;
- return 0;
- }
-
- uint8_t new_angle = data.wheel_position;
- if (is_first_read_) {
- is_first_read_ = false;
- last_angle_ = new_angle;
- return 0;
- }
-
- int delta = 128 - last_angle_;
- uint8_t rotated_angle = new_angle + delta;
- if (rotated_angle < 128 - threshold_) {
- last_angle_ = new_angle;
- return 1;
- } else if (rotated_angle > 128 + threshold_) {
- last_angle_ = new_angle;
- return -1;
- } else {
- return 0;
- }
-}
-
-auto TouchWheel::calculateThreshold(uint8_t sensitivity) -> uint8_t {
- int tmax = 35;
- int tmin = 5;
- return (((255. - sensitivity) / 255.) * (tmax - tmin) + tmin);
-}
-
-} // namespace input
diff --git a/src/input/input_trigger.cpp b/src/input/input_trigger.cpp
deleted file mode 100644
index 00d4a32d..00000000
--- a/src/input/input_trigger.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#include "input_trigger.hpp"
-#include <sys/_stdint.h>
-
-#include <cstdint>
-#include "esp_timer.h"
-
-namespace input {
-
-Trigger::Trigger()
- : touch_time_ms_(),
- was_pressed_(false),
- was_double_click_(false),
- times_long_pressed_(0) {}
-
-auto Trigger::update(bool is_pressed) -> State {
- // Bail out early if we're in a steady-state of not pressed.
- if (!is_pressed && !was_pressed_) {
- was_double_click_ = false;
- times_long_pressed_ = 0;
- return State::kNone;
- }
-
- uint64_t now_ms = esp_timer_get_time() / 1000;
-
- // This key wasn't being pressed, but now it is.
- if (is_pressed && !was_pressed_) {
- // Is this a double click?
- if (now_ms - *touch_time_ms_ < kDoubleClickDelayMs) {
- // Don't update touch_time_ms_, since we don't want triple clicks to
- // register as double clicks.
- was_double_click_ = true;
- was_pressed_ = true;
- return State::kDoubleClick;
- }
- // Not a double click; update our accounting info and wait for the next
- // call.
- touch_time_ms_ = now_ms;
- was_double_click_ = false;
- times_long_pressed_ = 0;
- was_pressed_ = true;
- return State::kNone;
- }
-
- // The key was released. If there were no long-press events fired during the
- // press, then this was a standard click.
- if (!is_pressed && was_pressed_) {
- was_pressed_ = false;
- if (!was_double_click_ && times_long_pressed_ == 0) {
- return State::kClick;
- } else {
- return State::kNone;
- }
- }
-
- // Now the more complicated case: the user is continuing to press the button.
- if (times_long_pressed_ == 0) {
- // We haven't fired yet, so we wait for the long-press event.
- if (now_ms - *touch_time_ms_ >= kLongPressDelayMs) {
- times_long_pressed_++;
- return State::kLongPress;
- }
- } else {
- // We've already fired at least once. How long has the user been holding
- // the key for?
- uint64_t time_since_long_press =
- now_ms - (*touch_time_ms_ + kLongPressDelayMs);
-
- // How many times should we have fired?
- // 1 initial fire (for the long-press), plus one additional fire every
- // kRepeatDelayMs since the long-press event.
- uint16_t expected_times_fired =
- 1 + (time_since_long_press / kRepeatDelayMs);
- if (times_long_pressed_ < expected_times_fired) {
- times_long_pressed_++;
- return State::kRepeatPress;
- }
- }
-
- return State::kNone;
-}
-
-} // namespace input
diff --git a/src/input/input_volume_buttons.cpp b/src/input/input_volume_buttons.cpp
deleted file mode 100644
index 37cf90e5..00000000
--- a/src/input/input_volume_buttons.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2024 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#include "input_volume_buttons.hpp"
-#include "event_queue.hpp"
-#include "gpios.hpp"
-#include "input_hook_actions.hpp"
-
-namespace input {
-
-VolumeButtons::VolumeButtons(drivers::IGpios& gpios)
- : gpios_(gpios),
- up_("upper", actions::volumeUp()),
- down_("lower", actions::volumeDown()) {}
-
-auto VolumeButtons::read(lv_indev_data_t* data) -> void {
- up_.update(!gpios_.Get(drivers::IGpios::Pin::kKeyUp), data);
- down_.update(!gpios_.Get(drivers::IGpios::Pin::kKeyDown), data);
-}
-
-auto VolumeButtons::name() -> std::string {
- return "buttons";
-}
-
-auto VolumeButtons::triggers()
- -> std::vector<std::reference_wrapper<TriggerHooks>> {
- return {up_, down_};
-}
-
-} // namespace input
diff --git a/src/input/lvgl_input_driver.cpp b/src/input/lvgl_input_driver.cpp
deleted file mode 100644
index a82b7438..00000000
--- a/src/input/lvgl_input_driver.cpp
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright 2023 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#include "lvgl_input_driver.hpp"
-#include <stdint.h>
-
-#include <cstdint>
-#include <memory>
-#include <variant>
-
-#include "device_factory.hpp"
-#include "feedback_haptics.hpp"
-#include "input_hook.hpp"
-#include "input_touch_wheel.hpp"
-#include "input_trigger.hpp"
-#include "input_volume_buttons.hpp"
-#include "lauxlib.h"
-#include "lua.h"
-#include "lua_thread.hpp"
-#include "lvgl.h"
-#include "nvs.hpp"
-#include "property.hpp"
-
-[[maybe_unused]] static constexpr char kTag[] = "input";
-
-static constexpr char kLuaTriggerMetatableName[] = "input_trigger";
-static constexpr char kLuaOverrideText[] = "lua_callback";
-
-namespace input {
-
-static void read_cb(lv_indev_drv_t* drv, lv_indev_data_t* data) {
- LvglInputDriver* instance =
- reinterpret_cast<LvglInputDriver*>(drv->user_data);
- instance->read(data);
-}
-
-static void feedback_cb(lv_indev_drv_t* drv, uint8_t event) {
- LvglInputDriver* instance =
- reinterpret_cast<LvglInputDriver*>(drv->user_data);
- instance->feedback(event);
-}
-
-auto intToMode(int raw) -> std::optional<drivers::NvsStorage::InputModes> {
- switch (raw) {
- case 0:
- return drivers::NvsStorage::InputModes::kButtonsOnly;
- case 1:
- return drivers::NvsStorage::InputModes::kButtonsWithWheel;
- case 2:
- return drivers::NvsStorage::InputModes::kDirectionalWheel;
- case 3:
- return drivers::NvsStorage::InputModes::kRotatingWheel;
- default:
- return {};
- }
-}
-
-LvglInputDriver::LvglInputDriver(drivers::NvsStorage& nvs,
- DeviceFactory& factory)
- : nvs_(nvs),
- factory_(factory),
- mode_(static_cast<int>(nvs.PrimaryInput()),
- [&](const lua::LuaValue& val) {
- if (!std::holds_alternative<int>(val)) {
- return false;
- }
- auto mode = intToMode(std::get<int>(val));
- if (!mode) {
- return false;
- }
- nvs.PrimaryInput(*mode);
- inputs_ = factory.createInputs(*mode);
- return true;
- }),
- driver_(),
- registration_(nullptr),
- inputs_(factory.createInputs(nvs.PrimaryInput())),
- feedbacks_(factory.createFeedbacks()),
- is_locked_(false) {
- lv_indev_drv_init(&driver_);
- driver_.type = LV_INDEV_TYPE_ENCODER;
- driver_.read_cb = read_cb;
- driver_.feedback_cb = feedback_cb;
- driver_.user_data = this;
- driver_.long_press_time = kLongPressDelayMs;
- driver_.long_press_repeat_time = kRepeatDelayMs;
-
- registration_ = lv_indev_drv_register(&driver_);
-}
-
-auto LvglInputDriver::read(lv_indev_data_t* data) -> void {
- // TODO: we should pass lock state on to the individual devices, since they
- // may wish to either ignore the lock state, or power down until unlock.
- if (is_locked_) {
- return;
- }
- for (auto&& device : inputs_) {
- device->read(data);
- }
-}
-
-auto LvglInputDriver::feedback(uint8_t event) -> void {
- if (is_locked_) {
- return;
- }
- for (auto&& device : feedbacks_) {
- device->feedback(event);
- }
-}
-
-LvglInputDriver::LuaTrigger::LuaTrigger(LvglInputDriver& driver,
- IInputDevice& dev,
- TriggerHooks& trigger)
- : driver_(&driver), device_(dev.name()), trigger_(trigger.name()) {
- for (auto& hook : trigger.hooks()) {
- auto cb = hook.get().callback();
- if (cb) {
- hooks_[hook.get().name()] = hook.get().callback()->name;
- } else {
- hooks_[hook.get().name()] = "";
- }
- }
-}
-
-auto LvglInputDriver::LuaTrigger::get(lua_State* L, int idx) -> LuaTrigger& {
- return **reinterpret_cast<LuaTrigger**>(
- luaL_checkudata(L, idx, kLuaTriggerMetatableName));
-}
-
-auto LvglInputDriver::LuaTrigger::luaGc(lua_State* L) -> int {
- LuaTrigger& trigger = LuaTrigger::get(L, 1);
- delete &trigger;
- return 0;
-}
-
-auto LvglInputDriver::LuaTrigger::luaToString(lua_State* L) -> int {
- LuaTrigger& trigger = LuaTrigger::get(L, 1);
- std::stringstream out;
- out << "{ ";
- for (const auto& hook : trigger.hooks_) {
- if (!hook.second.empty()) {
- out << hook.first << "=" << hook.second << " ";
- }
- }
- out << "}";
- lua_pushlstring(L, out.str().data(), out.str().size());
- return 1;
-}
-
-auto LvglInputDriver::LuaTrigger::luaNewIndex(lua_State* L) -> int {
- LuaTrigger& trigger = LuaTrigger::get(L, 1);
- luaL_checktype(L, 3, LUA_TFUNCTION);
-
- size_t len = 0;
- const char* str = luaL_checklstring(L, 2, &len);
- if (!str) {
- return 0;
- }
- OverrideSelector selector{
- .device_name = trigger.device_,
- .trigger_name = trigger.trigger_,
- .hook_name = std::string{str, len},
- };
- for (const auto& hook : trigger.hooks_) {
- if (hook.first == selector.hook_name) {
- trigger.driver_->setOverride(L, selector);
- trigger.hooks_[hook.first] = kLuaOverrideText;
- return 0;
- }
- }
- return 0;
-}
-
-auto LvglInputDriver::pushHooks(lua_State* L) -> int {
- if (luaL_getmetatable(L, kLuaTriggerMetatableName) == LUA_TNIL) {
- luaL_newmetatable(L, kLuaTriggerMetatableName);
- luaL_setfuncs(L, LuaTrigger::kFuncs, 0);
- lua_pop(L, 1);
- }
- lua_pop(L, 1);
-
- lua_newtable(L);
-
- for (auto& dev : inputs_) {
- lua_pushlstring(L, dev->name().data(), dev->name().size());
- lua_newtable(L);
-
- for (auto& trigger : dev->triggers()) {
- lua_pushlstring(L, trigger.get().name().data(),
- trigger.get().name().size());
- LuaTrigger** lua_obj = reinterpret_cast<LuaTrigger**>(
- lua_newuserdatauv(L, sizeof(LuaTrigger*), 0));
- *lua_obj = new LuaTrigger(*this, *dev, trigger);
- luaL_setmetatable(L, kLuaTriggerMetatableName);
- lua_rawset(L, -3);
- }
-
- lua_rawset(L, -3);
- }
-
- return 1;
-}
-
-auto LvglInputDriver::setOverride(lua_State* L,
- const OverrideSelector& selector) -> void {
- if (overrides_.contains(selector)) {
- LuaOverride& prev = overrides_[selector];
- luaL_unref(prev.L, LUA_REGISTRYINDEX, prev.ref);
- }
-
- int ref = luaL_ref(L, LUA_REGISTRYINDEX);
- LuaOverride override{
- .L = L,
- .ref = ref,
- };
- overrides_[selector] = override;
- applyOverride(selector, override);
-}
-
-auto LvglInputDriver::applyOverride(const OverrideSelector& selector,
- LuaOverride& override) -> void {
- // In general, this algorithm is a very slow approach. We could do better
- // by maintaing maps from [device|trigger|hook]_name to the relevant
- // trigger, but in practice I expect maybe like 5 overrides total ever,
- // spread across 2 devices with 2 or 5 hooks each. So it's not that big a
- // deal. Don't worry about it!!
-
- // Look for a matching device.
- for (auto& device : inputs_) {
- if (device->name() != selector.device_name) {
- continue;
- }
- // Look for a matching trigger
- for (auto& trigger : device->triggers()) {
- if (trigger.get().name() != selector.trigger_name) {
- continue;
- }
- // Look for a matching hook
- for (auto& hook : trigger.get().hooks()) {
- if (hook.get().name() != selector.hook_name) {
- continue;
- }
- // We found the target! Apply the override.
- auto lua_callback = [=](lv_indev_data_t* d) {
- lua_rawgeti(override.L, LUA_REGISTRYINDEX, override.ref);
- lua::CallProtected(override.L, 0, 0);
- };
- hook.get().override(
- HookCallback{.name = kLuaOverrideText, .fn = lua_callback});
- }
- }
- }
-}
-
-} // namespace input