diff --git a/src/windows/CMakeLists.txt b/src/windows/CMakeLists.txt index 129b998..b05779a 100644 --- a/src/windows/CMakeLists.txt +++ b/src/windows/CMakeLists.txt @@ -36,6 +36,8 @@ if(UNIX) ui_interfaces/wayland/WaylandWindowInterface.cpp ui_interfaces/wayland/WaylandSurface.cpp ui_interfaces/wayland/WaylandBuffer.cpp + ui_interfaces/wayland/WaylandPointerInterface.cpp + ui_interfaces/wayland/WaylandSeatInterface.cpp ${WAYLAND_EXTENSIONS_INCLUDE_DIR}/xdg-shell-protocol.cpp ) set(_HAS_WAYLAND ON) diff --git a/src/windows/ui_interfaces/wayland/WaylandPointerEvent.h b/src/windows/ui_interfaces/wayland/WaylandPointerEvent.h new file mode 100644 index 0000000..bc8dd15 --- /dev/null +++ b/src/windows/ui_interfaces/wayland/WaylandPointerEvent.h @@ -0,0 +1,28 @@ +#pragma once + +#include "wayland-client.h" + +enum pointer_event_mask { + POINTER_EVENT_ENTER = 1 << 0, + POINTER_EVENT_LEAVE = 1 << 1, + POINTER_EVENT_MOTION = 1 << 2, + POINTER_EVENT_BUTTON = 1 << 3, + POINTER_EVENT_AXIS = 1 << 4, + POINTER_EVENT_AXIS_SOURCE = 1 << 5, + POINTER_EVENT_AXIS_STOP = 1 << 6, + POINTER_EVENT_AXIS_DISCRETE = 1 << 7, +}; + +struct WaylandPointerEvent { + uint32_t event_mask; + wl_fixed_t surface_x, surface_y; + uint32_t button, state; + uint32_t time {0}; + uint32_t serial; + struct { + bool valid; + wl_fixed_t value; + int32_t discrete; + } axes[2]; + uint32_t axis_source; +}; \ No newline at end of file diff --git a/src/windows/ui_interfaces/wayland/WaylandPointerInterface.cpp b/src/windows/ui_interfaces/wayland/WaylandPointerInterface.cpp new file mode 100644 index 0000000..8c367c4 --- /dev/null +++ b/src/windows/ui_interfaces/wayland/WaylandPointerInterface.cpp @@ -0,0 +1,129 @@ +#include "WaylandPointerInterface.h" + +#include "FileLogger.h" + +static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) +{ + +} + +static void wl_pointer_axis_source(void *data, struct wl_pointer *wl_pointer, uint32_t axis_source) +{ + +} + +static void wl_pointer_axis_stop(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis) +{ + +} + +static void wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t discrete) +{ + +} + +void WaylandPointerInterface::pointerFrameEvent(void *data, struct wl_pointer *wl_pointer) +{ + auto thisClass = static_cast(data); + thisClass->onPointerFrame(); +} + +void WaylandPointerInterface::pointerEnterEvent(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) +{ + auto thisClass = static_cast(data); + thisClass->onPointerEnter(serial, surface, surface_x, surface_y); +} + +void WaylandPointerInterface::pointerLeaveEvent(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface) +{ + auto thisClass = static_cast(data); + thisClass->onPointerLeave(serial); +} + +void WaylandPointerInterface::pointerMotionEvent(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) +{ + auto thisClass = static_cast(data); + thisClass->onPointerMotion(time, surface_x, surface_y); +} + +void WaylandPointerInterface::pointerButtonEvent(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) +{ + auto thisClass = static_cast(data); + thisClass->onPointerButton(serial, time, button, state); +} + +void WaylandPointerInterface::onPointerFrame() +{ + if (mWorkingPointerEvent.event_mask & POINTER_EVENT_ENTER) + { + const auto locx = wl_fixed_to_double(mWorkingPointerEvent.surface_x); + const auto locy = wl_fixed_to_double(mWorkingPointerEvent.surface_y); + MLOG_INFO("Enter at " << locx << " , " << locy); + } + else if (mWorkingPointerEvent.event_mask & POINTER_EVENT_LEAVE) + { + MLOG_INFO("Leave);") + } + else if (mWorkingPointerEvent.event_mask & POINTER_EVENT_MOTION) + { + + } + else if (mWorkingPointerEvent.event_mask & POINTER_EVENT_BUTTON) + { + const bool released = mWorkingPointerEvent.state == WL_POINTER_BUTTON_STATE_RELEASED; + MLOG_INFO("Mouse button" << released ? "released" : "pressed"); + } + mWorkingPointerEvent = WaylandPointerEvent(); +} + +void WaylandPointerInterface::onPointerButton(uint32_t serial, uint32_t time, uint32_t button, uint32_t state) +{ + mWorkingPointerEvent.event_mask |= POINTER_EVENT_BUTTON; + mWorkingPointerEvent.time = time; + mWorkingPointerEvent.serial = serial; + mWorkingPointerEvent.button = button; + mWorkingPointerEvent.state = state; +} + +void WaylandPointerInterface::onPointerEnter(uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) +{ + mWorkingPointerEvent.event_mask |= POINTER_EVENT_ENTER; + mWorkingPointerEvent.serial = serial; + mWorkingPointerEvent.surface_x = surface_x; + mWorkingPointerEvent.surface_y = surface_y; +} + +void WaylandPointerInterface::onPointerLeave(uint32_t serial) +{ + mWorkingPointerEvent.event_mask |= POINTER_EVENT_LEAVE; + mWorkingPointerEvent.serial = serial; +} + +void WaylandPointerInterface::onPointerMotion(uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) +{ + mWorkingPointerEvent.event_mask |= POINTER_EVENT_MOTION; + mWorkingPointerEvent.time = time; + mWorkingPointerEvent.surface_x = surface_x; + mWorkingPointerEvent.surface_y = surface_y; +} + +WaylandPointerInterface::WaylandPointerInterface(wl_pointer* pointer) + : mPointer(pointer) +{ + mPointerListener.enter = pointerEnterEvent; + mPointerListener.leave = pointerLeaveEvent; + mPointerListener.button = pointerButtonEvent; + mPointerListener.motion = pointerMotionEvent; + mPointerListener.axis = wl_pointer_axis; + mPointerListener.axis_discrete = wl_pointer_axis_discrete; + mPointerListener.axis_source = wl_pointer_axis_source; + mPointerListener.axis_stop = wl_pointer_axis_stop; + mPointerListener.frame = pointerFrameEvent; + + wl_pointer_add_listener(mPointer, &mPointerListener, this); +} + +wl_pointer* WaylandPointerInterface::getPointer() const +{ + return mPointer; +} diff --git a/src/windows/ui_interfaces/wayland/WaylandPointerInterface.h b/src/windows/ui_interfaces/wayland/WaylandPointerInterface.h new file mode 100644 index 0000000..1caa38f --- /dev/null +++ b/src/windows/ui_interfaces/wayland/WaylandPointerInterface.h @@ -0,0 +1,30 @@ +#pragma once + +#include "WaylandPointerEvent.h" + +class WaylandPointerInterface +{ +public: + WaylandPointerInterface(wl_pointer* pointer); + + wl_pointer* getPointer() const; + +private: + + static void pointerEnterEvent(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y); + static void pointerLeaveEvent(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface); + static void pointerMotionEvent(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y); + static void pointerButtonEvent(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state); + static void pointerFrameEvent(void *data, struct wl_pointer *wl_pointer); + + void onPointerButton(uint32_t serial, uint32_t time, uint32_t button, uint32_t state); + void onPointerLeave(uint32_t serial); + void onPointerEnter(uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y); + void onPointerMotion(uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y); + void onPointerFrame(); + + wl_pointer* mPointer{nullptr}; + wl_pointer_listener mPointerListener; + + WaylandPointerEvent mWorkingPointerEvent; +}; diff --git a/src/windows/ui_interfaces/wayland/WaylandSeatInterface.cpp b/src/windows/ui_interfaces/wayland/WaylandSeatInterface.cpp new file mode 100644 index 0000000..35bb09d --- /dev/null +++ b/src/windows/ui_interfaces/wayland/WaylandSeatInterface.cpp @@ -0,0 +1,48 @@ +#include "WaylandSeatInterface.h" + +#include "FileLogger.h" + +void WaylandSeatInterface::seatCapabilitiesEvent(void *data, struct wl_seat *wl_seat, uint32_t capabilities) +{ + auto thisClass = static_cast(data); + thisClass->onSeatCapabilitiesEvent(capabilities); +} + +void WaylandSeatInterface::onSeatCapabilitiesEvent(uint32_t capabilities) +{ + const bool have_pointer = capabilities & WL_SEAT_CAPABILITY_POINTER; + if (have_pointer && mPointerInterface == nullptr) + { + auto pointer = wl_seat_get_pointer(mSeat); + mPointerInterface = std::make_unique(pointer); + } + else if (!have_pointer && mPointerInterface!= nullptr) + { + wl_pointer_release(mPointerInterface->getPointer()); + mPointerInterface.release(); + } +} + +WaylandSeatInterface::WaylandSeatInterface(wl_seat* seat) + : mSeat(seat) +{ + mSeatListener.capabilities = seatCapabilitiesEvent; + mSeatListener.name = seatNameEvent; + + wl_seat_add_listener(mSeat, &mSeatListener, this); +} + +void WaylandSeatInterface::seatNameEvent(void *data, struct wl_seat *wl_seat, const char *name) +{ + MLOG_INFO("seat name: " << name); +} + +void WaylandSeatInterface::setKeyboard(wl_keyboard* keyboard) +{ + +} + +void WaylandSeatInterface::setPointer(wl_pointer* pointer) +{ + +} diff --git a/src/windows/ui_interfaces/wayland/WaylandSeatInterface.h b/src/windows/ui_interfaces/wayland/WaylandSeatInterface.h new file mode 100644 index 0000000..11f4139 --- /dev/null +++ b/src/windows/ui_interfaces/wayland/WaylandSeatInterface.h @@ -0,0 +1,32 @@ +#pragma once + +#include "WaylandPointerInterface.h" + +#include "wayland-client.h" + +#include + +class WaylandSeatInterface +{ +public: + WaylandSeatInterface(wl_seat* seat); + +private: + + static void seatCapabilitiesEvent(void *data, struct wl_seat *wl_seat, uint32_t capabilities); + + static void seatNameEvent(void *data, struct wl_seat *wl_seat, const char *name); + + void onSeatCapabilitiesEvent(uint32_t capabilities); + + void setKeyboard(wl_keyboard* keyboard); + + void setPointer(wl_pointer* pointer); + + wl_seat* mSeat{nullptr}; + wl_seat_listener mSeatListener; + + wl_keyboard* mKeyboard{nullptr}; + + std::unique_ptr mPointerInterface; +}; diff --git a/src/windows/ui_interfaces/wayland/WaylandSurface.cpp b/src/windows/ui_interfaces/wayland/WaylandSurface.cpp index 14b396d..46b47e3 100644 --- a/src/windows/ui_interfaces/wayland/WaylandSurface.cpp +++ b/src/windows/ui_interfaces/wayland/WaylandSurface.cpp @@ -69,7 +69,7 @@ wl_buffer* WaylandSurface::drawFrame() void WaylandSurface::drawCheckerboard(int width, int height, int offset) { uint32_t *pixels = (uint32_t *)&(mBuffer->getPoolData())[offset]; - for (int y = 0; y < height; ++y) + for (int y = 100; y < height; ++y) { for (int x = 0; x < width; ++x) { diff --git a/src/windows/ui_interfaces/wayland/WaylandWindowInterface.cpp b/src/windows/ui_interfaces/wayland/WaylandWindowInterface.cpp index eb82144..c236181 100644 --- a/src/windows/ui_interfaces/wayland/WaylandWindowInterface.cpp +++ b/src/windows/ui_interfaces/wayland/WaylandWindowInterface.cpp @@ -3,11 +3,12 @@ #include "FileLogger.h" #include "WaylandSurface.h" #include "WaylandBuffer.h" +#include "WaylandSeatInterface.h" #include #include -void WaylandWindowInterface::registryHandleGlobalCallback(void *data, struct wl_registry *registry, +void WaylandWindowInterface::registryHandleGlobalEvent(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { auto thisClass = static_cast(data); @@ -28,9 +29,14 @@ void WaylandWindowInterface::registryHandleGlobalCallback(void *data, struct wl_ { thisClass->setXdgBase(static_cast(wl_registry_bind(registry, name, &xdg_wm_base_interface, 1))); } + else if (strcmp(interface, wl_seat_interface.name) == 0) + { + thisClass->setSeat(static_cast(wl_registry_bind(registry, name, &wl_seat_interface, 5))); + + } } -void WaylandWindowInterface::registryHandleGlobalRemoveCallback(void *data, struct wl_registry *registry, uint32_t name) +void WaylandWindowInterface::registryHandleGlobalRemoveEvent(void *data, struct wl_registry *registry, uint32_t name) { } @@ -39,8 +45,8 @@ void WaylandWindowInterface::registryHandleGlobalRemoveCallback(void *data, stru WaylandWindowInterface::WaylandWindowInterface() : mBuffer(std::make_shared()) { - mRegistryListener.global = registryHandleGlobalCallback; - mRegistryListener.global_remove = registryHandleGlobalRemoveCallback; + mRegistryListener.global = registryHandleGlobalEvent; + mRegistryListener.global_remove = registryHandleGlobalRemoveEvent; } WaylandWindowInterface::~WaylandWindowInterface() @@ -69,6 +75,11 @@ void WaylandWindowInterface::connect() wl_display_roundtrip(mDisplay); } +void WaylandWindowInterface::setSeat(wl_seat* seat) +{ + mSeatInterface = std::make_unique(seat); +} + void WaylandWindowInterface::setXdgBase(xdg_wm_base* xdg_base) { mXdgBase = xdg_base; @@ -104,14 +115,12 @@ void WaylandWindowInterface::addWindow(mt::Window* window) void WaylandWindowInterface::mapWindow(mt::Window* window) { - if (mSurfaces.empty()) { return; } mSurfaces[0]->initialize(mCompositor, mXdgBase, mBuffer); - } void WaylandWindowInterface::disconnect() diff --git a/src/windows/ui_interfaces/wayland/WaylandWindowInterface.h b/src/windows/ui_interfaces/wayland/WaylandWindowInterface.h index c476686..5666d60 100644 --- a/src/windows/ui_interfaces/wayland/WaylandWindowInterface.h +++ b/src/windows/ui_interfaces/wayland/WaylandWindowInterface.h @@ -11,12 +11,12 @@ class WaylandSurface; class WaylandBuffer; +class WaylandSeatInterface; class WaylandWindowInterface { public: - WaylandWindowInterface(); ~WaylandWindowInterface(); @@ -32,8 +32,8 @@ public: void mapWindow(mt::Window* window); private: - static void registryHandleGlobalCallback(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version); - static void registryHandleGlobalRemoveCallback(void *data, struct wl_registry *registry, uint32_t name); + static void registryHandleGlobalEvent(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version); + static void registryHandleGlobalRemoveEvent(void *data, struct wl_registry *registry, uint32_t name); void doXdgPong(uint32_t serial); @@ -41,6 +41,8 @@ private: void setSharedMemory(wl_shm* shared_memory); + void setSeat(wl_seat* seat); + void setXdgBase(xdg_wm_base* xdg_base); wl_display* mDisplay{nullptr}; @@ -52,5 +54,5 @@ private: std::vector > mSurfaces; std::shared_ptr mBuffer; - + std::unique_ptr mSeatInterface; };