From 73fda759c5ee43043dfff4afcf7725a993b85f02 Mon Sep 17 00:00:00 2001 From: admin Date: Wed, 25 Feb 2026 10:08:29 +0100 Subject: [PATCH] feat: input handler work --- Makefile | 7 +++- include/input.h | 33 ++++++++++++++++ include/input/wayland.h | 16 +++++--- include/window.h | 2 + include/window/wayland.h | 2 + src/input.cpp | 25 ++++++++++++ src/input/wayland.cpp | 84 ++++++++++++++++++++++++++++++++-------- src/main.cpp | 11 +++++- src/window.cpp | 15 +++++-- src/window/wayland.cpp | 7 ++++ 10 files changed, 174 insertions(+), 28 deletions(-) create mode 100644 include/input.h create mode 100644 src/input.cpp diff --git a/Makefile b/Makefile index 8db61dd..ca556ab 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ CFLAGS = -Wall -Wextra -I./include/ -g LIBS = $(shell pkg-config --libs wayland-client wayland-egl egl glesv2 wayland-cursor) -build/main: src/main.cpp build/shader.o build/state.o build/renderer.o build/window.o build/window_wayland.o build/input_wayland.o build/xdg-shell-protocol.o - g++ -o build/main $(CFLAGS) src/main.cpp build/shader.o build/state.o build/renderer.o build/window.o build/window_wayland.o build/input_wayland.o build/xdg-shell-protocol.o $(LIBS) +build/main: src/main.cpp build/shader.o build/state.o build/renderer.o build/window.o build/window_wayland.o build/input.o build/input_wayland.o build/xdg-shell-protocol.o + g++ -o build/main $(CFLAGS) src/main.cpp build/shader.o build/state.o build/renderer.o build/window.o build/window_wayland.o build/input.o build/input_wayland.o build/xdg-shell-protocol.o $(LIBS) build/shader.o: src/shader.cpp include/shader.h g++ -o build/shader.o $(CFLAGS) -c src/shader.cpp @@ -21,6 +21,9 @@ build/window.o: src/window.cpp include/window.h build/window_wayland.o: include/window/wayland.h src/window/wayland.cpp g++ -o build/window_wayland.o $(CFLAGS) -c src/window/wayland.cpp +build/input.o: src/input.cpp include/input.h + g++ -o build/input.o $(CFLAGS) -c src/input.cpp + # TODO: dynamic input impl selection depending on platform (wayland/x11) build/input_wayland.o: include/input/wayland.h src/input/wayland.cpp g++ -o build/input_wayland.o $(CFLAGS) -c src/input/wayland.cpp diff --git a/include/input.h b/include/input.h new file mode 100644 index 0000000..9a28a08 --- /dev/null +++ b/include/input.h @@ -0,0 +1,33 @@ +#pragma once +#ifndef H_INPUT_ +#define H_INPUT_ + +#include + +class InputHandlerImpl { +public: + InputHandlerImpl() = default; + virtual ~InputHandlerImpl() = default; + +public: + virtual size_t GetMouseX() = 0; + virtual size_t GetMouseY() = 0; +}; + +class InputHandler { +public: + static InputHandler* GetInstance() { + if (!s_instance) s_instance = new InputHandler; + return s_instance; + } +private: + InputHandler(); +public: + size_t GetMouseX(); + size_t GetMouseY(); +private: + static InputHandler* s_instance; + InputHandlerImpl* m_impl; +}; + +#endif // H_INPUT_ diff --git a/include/input/wayland.h b/include/input/wayland.h index 083c154..c7a3249 100644 --- a/include/input/wayland.h +++ b/include/input/wayland.h @@ -2,11 +2,11 @@ #ifndef H_WAYLAND_INPUT_ #define H_WAYLAND_INPUT_ +#include "input.h" + #include -class WaylandInputHandler { -public: - static WaylandInputHandler* GetInstance(); +class WaylandInputHandler : public InputHandlerImpl { private: static void handle_pointer_enter(void *data, struct wl_pointer *wl_pointer, @@ -58,10 +58,16 @@ private: private: WaylandInputHandler(); ~WaylandInputHandler() = default; -private: - static WaylandInputHandler* s_instance; + + friend class InputHandler; +public: + size_t GetMouseX() override; + size_t GetMouseY() override; private: struct wl_pointer_listener m_pointer_listener; + wl_fixed_t m_surface_x; + wl_fixed_t m_surface_y; }; #endif // H_WAYLAND_INPUT_ + diff --git a/include/window.h b/include/window.h index e5813fa..d2bac63 100644 --- a/include/window.h +++ b/include/window.h @@ -35,6 +35,8 @@ public: Window(size_t width, size_t height); virtual ~Window(); + static void Init(); + Window(const Window &) = delete; Window(Window &&) = delete; diff --git a/include/window/wayland.h b/include/window/wayland.h index 23e2010..36f92c2 100644 --- a/include/window/wayland.h +++ b/include/window/wayland.h @@ -8,6 +8,8 @@ public: WaylandWindowImpl(size_t width, size_t height); ~WaylandWindowImpl() override; + static void Init(); + public: bool Dispatch() override; void OnFrame(IFrameListener fn) override; diff --git a/src/input.cpp b/src/input.cpp new file mode 100644 index 0000000..fd8adda --- /dev/null +++ b/src/input.cpp @@ -0,0 +1,25 @@ +#include "input.h" + +#include +#include "input/wayland.h" + +InputHandler* InputHandler::s_instance = nullptr; + +// TODO: dynamically load input handling implementation depending on platform +#define WAYLAND 1 + +InputHandler::InputHandler() { +#ifdef WAYLAND + m_impl = new WaylandInputHandler(); +#endif + assert(m_impl && "no implementation found for this platform"); +} + +size_t InputHandler::GetMouseX() { + return m_impl->GetMouseX(); +} + +size_t InputHandler::GetMouseY() { + return m_impl->GetMouseY(); +} + diff --git a/src/input/wayland.cpp b/src/input/wayland.cpp index bc9fa4d..a630cff 100644 --- a/src/input/wayland.cpp +++ b/src/input/wayland.cpp @@ -10,10 +10,9 @@ #define UNUSED(x) (void)(x) -WaylandInputHandler *WaylandInputHandler::s_instance = nullptr; - WaylandInputHandler::WaylandInputHandler() { auto pointer = WaylandState::GetInstance()->m_pointer; + assert(pointer && "wayland seat_pointer not initialized"); m_pointer_listener.enter = handle_pointer_enter; m_pointer_listener.leave = handle_pointer_leave; m_pointer_listener.motion = handle_pointer_motion; @@ -28,10 +27,12 @@ WaylandInputHandler::WaylandInputHandler() { wl_pointer_add_listener(pointer, &m_pointer_listener, this); } -WaylandInputHandler *WaylandInputHandler::GetInstance() { - if (!WaylandInputHandler::s_instance) - WaylandInputHandler::s_instance = new WaylandInputHandler(); - return s_instance; +size_t WaylandInputHandler::GetMouseX() { + return wl_fixed_to_double(m_surface_x); +} + +size_t WaylandInputHandler::GetMouseY() { + return wl_fixed_to_double(m_surface_y); } void WaylandInputHandler::handle_pointer_enter( @@ -41,8 +42,9 @@ void WaylandInputHandler::handle_pointer_enter( UNUSED(surface); auto handler = reinterpret_cast(data); // auto state = WaylandState::GetInstance(); - UNUSED(handler); printf("[DEBUG] INPUT.POINTER: pointer enter event:\n\tserial = %d, surface_x = %f, surface_y = %f\n", serial, wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y)); + handler->m_surface_x = surface_x; + handler->m_surface_y = surface_y; // const char* cursor_theme = "XCursor-Pro-Dark"; // auto theme = wl_cursor_theme_load(cursor_theme, 22, state->m_shm); // printf("[DEBUG] CURSOR: theme '%s' loaded: %p\n", cursor_theme, theme); @@ -59,45 +61,95 @@ void WaylandInputHandler::handle_pointer_enter( void WaylandInputHandler::handle_pointer_leave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, - struct wl_surface *surface) {} + struct wl_surface *surface) { + UNUSED(data); + UNUSED(wl_pointer); + UNUSED(serial); + UNUSED(surface); +} void WaylandInputHandler::handle_pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, - wl_fixed_t surface_y) {} + wl_fixed_t surface_y) { + UNUSED(wl_pointer); + UNUSED(time); + auto handler = reinterpret_cast(data); + handler->m_surface_x = surface_x; + handler->m_surface_y = surface_y; +} void WaylandInputHandler::handle_pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, - uint32_t state) {} + uint32_t state) { + UNUSED(data); + UNUSED(wl_pointer); + UNUSED(serial); + UNUSED(button); + UNUSED(state); + UNUSED(time); +} void WaylandInputHandler::handle_pointer_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, - wl_fixed_t value) {} + wl_fixed_t value) { + UNUSED(data); + UNUSED(wl_pointer); + UNUSED(axis); + UNUSED(value); + UNUSED(time); +} void WaylandInputHandler::handle_pointer_frame(void *data, struct wl_pointer *wl_pointer) { printf("[DEBUG] INPUT.POINTER: received pointer frame event\n"); + UNUSED(data); + UNUSED(wl_pointer); } void WaylandInputHandler::handle_pointer_axis_source( - void *data, struct wl_pointer *wl_pointer, uint32_t axis_source) {} + void *data, struct wl_pointer *wl_pointer, uint32_t axis_source) { + UNUSED(data); + UNUSED(wl_pointer); + UNUSED(axis_source); +} void WaylandInputHandler::handle_pointer_axis_stop( - void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis) {} + void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis) { + UNUSED(data); + UNUSED(wl_pointer); + UNUSED(time); + UNUSED(axis); +} void WaylandInputHandler::handle_pointer_axis_discrete( void *data, struct wl_pointer *wl_pointer, uint32_t axis, - int32_t discrete) {} + int32_t discrete) { + UNUSED(data); + UNUSED(wl_pointer); + UNUSED(axis); + UNUSED(discrete); +} void WaylandInputHandler::handle_pointer_axis_value120( void *data, struct wl_pointer *wl_pointer, uint32_t axis, - int32_t value120) {} + int32_t value120) { + UNUSED(data); + UNUSED(value120); + UNUSED(axis); + UNUSED(wl_pointer); +} void WaylandInputHandler::handle_pointer_axis_relative_direction( void *data, struct wl_pointer *wl_pointer, uint32_t axis, - uint32_t direction) {} + uint32_t direction) { + UNUSED(data); + UNUSED(direction); + UNUSED(axis); + UNUSED(wl_pointer); +} diff --git a/src/main.cpp b/src/main.cpp index 41f61ec..a0f0aa9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,6 @@ #include -#include "input/wayland.h" +#include "input.h" #include "window.h" #include "renderer.h" @@ -10,7 +10,13 @@ static Window window(720, 480); void HandleFrame() { printf("[APP]: width = %zu, height = %zu\n", window.GetWidth(), window.GetHeight()); - WaylandInputHandler::GetInstance(); + auto x = InputHandler::GetInstance()->GetMouseX(); + auto y = InputHandler::GetInstance()->GetMouseY(); + printf("[APP]: mouse position: x = %zu, y = %zu\n", x, y); +} + +void HandleMouseMove() { + printf("[APP]: mouse moved"); } int main(int argc, char **argv) { @@ -18,6 +24,7 @@ int main(int argc, char **argv) { UNUSED(argv); Renderer::GetInstance(); + Window::Init(); window.OnFrame(HandleFrame); diff --git a/src/window.cpp b/src/window.cpp index 96ca78a..4d7e11c 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1,6 +1,7 @@ #include #include "window.h" +#include "state/wayland.h" #define WINDOW_WAYLAND 1 @@ -9,11 +10,19 @@ #endif Window::Window(size_t width, size_t height) - : m_last_time(0), m_width(width), m_height(height) { + : m_last_time(0), m_width(width), m_height(height) { #ifdef WINDOW_WAYLAND - m_impl = new WaylandWindowImpl(width, height); + m_impl = new WaylandWindowImpl(width, height); #endif - } +} + +void Window::Init() { +#ifdef WINDOW_WAYLAND + printf("[DEBUG] Window::Init() called\n"); + WaylandState::GetInstance(); + WaylandWindowImpl::Init(); +#endif +} Window::~Window() {} diff --git a/src/window/wayland.cpp b/src/window/wayland.cpp index bfe057c..c8d5b66 100644 --- a/src/window/wayland.cpp +++ b/src/window/wayland.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -100,6 +101,12 @@ WaylandWindowImpl::~WaylandWindowImpl() { m_running = false; } void WaylandWindowImpl::OnFrame(IFrameListener fn) { m_on_frame = fn; } +void WaylandWindowImpl::Init() { + auto display = WaylandState::GetInstance()->m_display; + assert(display && "wayland display is not initialized"); + wl_display_dispatch_pending(display); +} + bool WaylandWindowImpl::Dispatch() { if (!m_running) return false;