From 930b846b80fae71573bc6c9047100013e56518c7 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 5 Sep 2024 14:18:32 +0200 Subject: [PATCH] AsyncUserInput: add interface UserInputHandler To remove global variables eventually. --- src/AsyncUserInput.cxx | 35 ++++++++++++++++++++++++++--------- src/AsyncUserInput.hxx | 17 +++++++++++------ src/Instance.cxx | 4 ++-- src/Instance.hxx | 12 ++++++++---- src/Main.cxx | 16 ++++++++-------- src/UserInputHandler.hxx | 20 ++++++++++++++++++++ src/lirc.cxx | 9 ++++++--- src/lirc.hxx | 12 +++++++----- src/ncmpc.hxx | 23 +---------------------- src/screen_find.cxx | 2 +- 10 files changed, 90 insertions(+), 60 deletions(-) create mode 100644 src/UserInputHandler.hxx diff --git a/src/AsyncUserInput.cxx b/src/AsyncUserInput.cxx index 05c6ea43..49214a6c 100644 --- a/src/AsyncUserInput.cxx +++ b/src/AsyncUserInput.cxx @@ -3,12 +3,16 @@ #include "config.h" #include "AsyncUserInput.hxx" +#include "UserInputHandler.hxx" #include "Command.hxx" #include "Bindings.hxx" #include "GlobalBindings.hxx" #include "ncmpc.hxx" #include "ui/Point.hxx" +// TODO remove this kludge +static AsyncUserInput *global_async_user_input; + static constexpr bool ignore_key(int key) noexcept { @@ -41,7 +45,10 @@ AsyncUserInput::OnSocketReady(unsigned) noexcept #endif begin_input_event(); - do_mouse_event({event.x, event.y}, event.bstate); + + if (!handler.OnMouse({event.x, event.y}, event.bstate)) + return; + end_input_event(); return; @@ -54,28 +61,38 @@ AsyncUserInput::OnSocketReady(unsigned) noexcept begin_input_event(); - if (!do_input_event(stdin_event.GetEventLoop(), cmd)) + if (!handler.OnCommand(cmd)) return; end_input_event(); return; } -AsyncUserInput::AsyncUserInput(EventLoop &event_loop, WINDOW &_w) noexcept +AsyncUserInput::AsyncUserInput(EventLoop &event_loop, WINDOW &_w, + UserInputHandler &_handler) noexcept :stdin_event(event_loop, BIND_THIS_METHOD(OnSocketReady), FileDescriptor{STDIN_FILENO}), - w(_w) + w(_w), + handler(_handler) { stdin_event.ScheduleRead(); + + // TODO remove this kludge + global_async_user_input = this; } -void -keyboard_unread(EventLoop &event_loop, int key) noexcept +inline void +AsyncUserInput::InjectKey(int key) noexcept { if (ignore_key(key)) return; - Command cmd = translate_key(key); - if (cmd != Command::NONE) - do_input_event(event_loop, cmd); + if (Command cmd = translate_key(key); cmd != Command::NONE) + handler.OnCommand(cmd); +} + +void +keyboard_unread(int key) noexcept +{ + global_async_user_input->InjectKey(key); } diff --git a/src/AsyncUserInput.hxx b/src/AsyncUserInput.hxx index f03c70df..e1df2d3e 100644 --- a/src/AsyncUserInput.hxx +++ b/src/AsyncUserInput.hxx @@ -1,26 +1,31 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The Music Player Daemon Project -#ifndef ASYNC_USER_INPUT_HXX -#define ASYNC_USER_INPUT_HXX +#pragma once #include "event/PipeEvent.hxx" #include +class UserInputHandler; + class AsyncUserInput { PipeEvent stdin_event; WINDOW &w; + UserInputHandler &handler; + public: - AsyncUserInput(EventLoop &event_loop, WINDOW &_w) noexcept; + AsyncUserInput(EventLoop &event_loop, WINDOW &_w, + UserInputHandler &_handler) noexcept; + + // TODO remove this kludge + void InjectKey(int key) noexcept; private: void OnSocketReady(unsigned flags) noexcept; }; void -keyboard_unread(EventLoop &event_loop, int key) noexcept; - -#endif +keyboard_unread(int key) noexcept; diff --git a/src/Instance.cxx b/src/Instance.cxx index 8c5ea0dc..6d955e4e 100644 --- a/src/Instance.cxx +++ b/src/Instance.cxx @@ -43,9 +43,9 @@ Instance::Instance() #endif screen_manager(event_loop), #ifdef ENABLE_LIRC - lirc_input(event_loop), + lirc_input(event_loop, *this), #endif - user_input(event_loop, *screen_manager.main_window.w) + user_input(event_loop, *screen_manager.main_window.w, *this) { screen_manager.Init(&client); diff --git a/src/Instance.hxx b/src/Instance.hxx index 16846a88..f7e5eb79 100644 --- a/src/Instance.hxx +++ b/src/Instance.hxx @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The Music Player Daemon Project -#ifndef NCMPC_INSTANCE_HXX -#define NCMPC_INSTANCE_HXX +#pragma once #include "config.h" #include "AsyncUserInput.hxx" +#include "UserInputHandler.hxx" #include "mpdclient.hxx" #include "DelayedSeek.hxx" #include "screen.hxx" @@ -20,7 +20,7 @@ /** * A singleton holding global instance variables. */ -class Instance { +class Instance final : UserInputHandler { EventLoop event_loop; struct mpdclient client; @@ -117,6 +117,10 @@ private: #ifndef NCMPC_MINI void OnCheckKeyBindings() noexcept; #endif -}; + // virtual methods from AsyncUserInputHandler + bool OnCommand(Command cmd) noexcept override; +#ifdef HAVE_GETMOUSE + bool OnMouse(Point p, mmask_t bstate) noexcept override; #endif +}; diff --git a/src/Main.cxx b/src/Main.cxx index be4968d3..e45b58f7 100644 --- a/src/Main.cxx +++ b/src/Main.cxx @@ -206,7 +206,7 @@ void end_input_event() noexcept } bool -do_input_event(EventLoop &event_loop, Command cmd) noexcept +Instance::OnCommand(Command cmd) noexcept { if (cmd == Command::QUIT) { event_loop.Break(); @@ -214,8 +214,7 @@ do_input_event(EventLoop &event_loop, Command cmd) noexcept } try { - screen->OnCommand(global_instance->GetClient(), - global_instance->GetSeek(), cmd); + screen_manager.OnCommand(GetClient(), GetSeek(), cmd); } catch (...) { screen_status_error(std::current_exception()); return true; @@ -223,22 +222,23 @@ do_input_event(EventLoop &event_loop, Command cmd) noexcept if (cmd == Command::VOLUME_UP || cmd == Command::VOLUME_DOWN) /* make sure we don't update the volume yet */ - global_instance->DisableUpdateTimer(); + DisableUpdateTimer(); return true; } #ifdef HAVE_GETMOUSE -void -do_mouse_event(Point p, mmask_t bstate) noexcept +bool +Instance::OnMouse(Point p, mmask_t bstate) noexcept { try { - screen->OnMouse(global_instance->GetClient(), - global_instance->GetSeek(), p, bstate); + screen_manager.OnMouse(GetClient(), GetSeek(), p, bstate); } catch (...) { screen_status_error(std::current_exception()); } + + return true; } #endif diff --git a/src/UserInputHandler.hxx b/src/UserInputHandler.hxx new file mode 100644 index 00000000..0aea2643 --- /dev/null +++ b/src/UserInputHandler.hxx @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The Music Player Daemon Project + +#pragma once + +#include "config.h" + +#include + +enum class Command : unsigned; +struct Point; + +class UserInputHandler { +public: + virtual bool OnCommand(Command cmd) noexcept = 0; + +#ifdef HAVE_GETMOUSE + virtual bool OnMouse(Point p, mmask_t bstate) noexcept = 0; +#endif +}; diff --git a/src/lirc.cxx b/src/lirc.cxx index 9ce0a7f1..6665d541 100644 --- a/src/lirc.cxx +++ b/src/lirc.cxx @@ -2,6 +2,7 @@ // Copyright The Music Player Daemon Project #include "lirc.hxx" +#include "UserInputHandler.hxx" #include "ncmpc.hxx" #include "Command.hxx" #include "config.h" @@ -18,7 +19,7 @@ LircInput::OnSocketReady(unsigned) noexcept if (lirc_nextcode(&code) == 0) { while (lirc_code2char(lc, code, &txt) == 0 && txt != nullptr) { const auto cmd = get_key_command_from_name(txt); - if (!do_input_event(GetEventLoop(), cmd)) + if (!handler.OnCommand(cmd)) return; } } @@ -26,8 +27,10 @@ LircInput::OnSocketReady(unsigned) noexcept end_input_event(); } -LircInput::LircInput(EventLoop &_event_loop) noexcept - :event(_event_loop, BIND_THIS_METHOD(OnSocketReady)) +LircInput::LircInput(EventLoop &_event_loop, + UserInputHandler &_handler) noexcept + :handler(_handler), + event(_event_loop, BIND_THIS_METHOD(OnSocketReady)) { int lirc_socket = 0; diff --git a/src/lirc.hxx b/src/lirc.hxx index dd2b5d9e..e3f6002c 100644 --- a/src/lirc.hxx +++ b/src/lirc.hxx @@ -1,18 +1,22 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The Music Player Daemon Project -#ifndef LIRC_H -#define LIRC_H +#pragma once #include "event/SocketEvent.hxx" +class UserInputHandler; + class LircInput final { struct lirc_config *lc = nullptr; + UserInputHandler &handler; + SocketEvent event; public: - explicit LircInput(EventLoop &event_loop) noexcept; + LircInput(EventLoop &event_loop, + UserInputHandler &_handler) noexcept; ~LircInput(); auto &GetEventLoop() const noexcept { @@ -22,5 +26,3 @@ public: private: void OnSocketReady(unsigned flags) noexcept; }; - -#endif diff --git a/src/ncmpc.hxx b/src/ncmpc.hxx index 355d2409..47b04138 100644 --- a/src/ncmpc.hxx +++ b/src/ncmpc.hxx @@ -1,16 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The Music Player Daemon Project -#ifndef NCMPC_H -#define NCMPC_H +#pragma once -#ifdef HAVE_GETMOUSE -#include -#endif - -enum class Command : unsigned; -struct Point; -class EventLoop; class ScreenManager; extern ScreenManager *screen; @@ -19,16 +11,3 @@ begin_input_event() noexcept; void end_input_event() noexcept; - -/** - * @return false if the application shall quit - */ -bool -do_input_event(EventLoop &event_loop, Command cmd) noexcept; - -#ifdef HAVE_GETMOUSE -void -do_mouse_event(Point p, mmask_t bstate) noexcept; -#endif - -#endif /* NCMPC_H */ diff --git a/src/screen_find.cxx b/src/screen_find.cxx index f5178a4e..9b396a5a 100644 --- a/src/screen_find.cxx +++ b/src/screen_find.cxx @@ -113,5 +113,5 @@ screen_jump(ScreenManager &screen, ListWindow &lw, screen.findbuf = search_str; /* ncmpc should get the command */ - keyboard_unread(screen.GetEventLoop(), key); + keyboard_unread(key); }