diff --git a/src/windows/ui_interfaces/wayland/WaylandBuffer.cpp b/src/windows/ui_interfaces/wayland/WaylandBuffer.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/windows/ui_interfaces/wayland/WaylandBuffer.h b/src/windows/ui_interfaces/wayland/WaylandBuffer.h new file mode 100644 index 0000000..e69de29 diff --git a/src/windows/ui_interfaces/wayland/WaylandSurface.cpp b/src/windows/ui_interfaces/wayland/WaylandSurface.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/windows/ui_interfaces/wayland/WaylandSurface.h b/src/windows/ui_interfaces/wayland/WaylandSurface.h new file mode 100644 index 0000000..5b31b7b --- /dev/null +++ b/src/windows/ui_interfaces/wayland/WaylandSurface.h @@ -0,0 +1,115 @@ +#pragma once + +#include "xdg-shell-client-protocol.h" +#include "wayland-client.h" + +#include "Window.h" + +struct wl_surface; +struct xdg_surface; +struct xdg_toplevel; + +class WaylandSurface +{ + + WaylandSurface(mt::Window* window) + : mWindow(window) + { + + } + + + void initialize(wl_compositor* compositor, xdg_wm_base* xdg_wm_base) + { + mSurface = wl_compositor_create_surface(compositor); + mXdgSurface = xdg_wm_base_get_xdg_surface(xdg_wm_base, mSurface); + + auto xdg_surface_configure = [](void *data, struct xdg_surface *xdg_surface, uint32_t serial) + { + auto thisClass = static_cast(data); + thisClass->onConfigure(xdg_surface, serial); + }; + mXdgSurfaceListener.configure = xdg_surface_configure; + + xdg_surface_add_listener(mXdgSurface, &mXdgSurfaceListener, this); + + mXdgTopLevel = xdg_surface_get_toplevel(mXdgSurface); + xdg_toplevel_set_title(mXdgTopLevel, "Example client"); + + wl_surface_commit(mSurface); + } + + void onConfigure(xdg_surface *xdg_surface, uint32_t serial) + { + xdg_surface_ack_configure(xdg_surface, serial); + + auto buffer = draw_frame(); + wl_surface_attach(mSurface, buffer, 0, 0); + //wl_surface_damage(mSurface, 0, 0, UINT32_MAX, UINT32_MAX); + wl_surface_commit(mSurface); + } + + wl_buffer* draw_frame() + { + const auto width = mWindow->GetWidth(); + const auto height = mWindow->GetHeight(); + + const int bitDepth = 4; + + const int stride = width * bitDepth; + //const int numBuffers = 2; // i.e. front/back + const int numBuffers = 1; + const int shm_pool_size = height * stride * numBuffers; + + initializeSharedBuffer(shm_pool_size); + + if (!mSharedMemory->isValid()) + { + std::cout << "Failed to allocate shared memory" << std::endl; + return nullptr; + } + + if (!mPoolData) + { + std::cout << "Failed to mmap pool" << std::endl; + return nullptr; + } + + auto pool = wl_shm_create_pool(mWlSharedMemory, mSharedMemory->getFileDescriptor(), shm_pool_size); + + int index = 0; + // int offset = height * stride * index; // Two buffers, offset to starting point of second + int offset = 0; + + mWorkingBuffer = wl_shm_pool_create_buffer(pool, offset, width, height, stride, WL_SHM_FORMAT_XRGB8888); + + wl_shm_pool_destroy(pool); + close(mSharedMemory->getFileDescriptor()); + + drawCheckerboard(width, height, offset); + + munmap(mPoolData, shm_pool_size); + + auto wl_buffer_release = [](void *data, struct wl_buffer *wl_buffer) + { + wl_buffer_destroy(wl_buffer); + }; + mBufferListener.release = wl_buffer_release; + + wl_buffer_add_listener(mWorkingBuffer, &mBufferListener, nullptr); + + return mWorkingBuffer; + } + +private: + + mt::Window* mWindow{nullptr}; + + wl_surface* mSurface{nullptr}; + xdg_surface* mXdgSurface{nullptr}; + xdg_surface_listener mXdgSurfaceListener{nullptr}; + + xdg_toplevel* mXdgTopLevel{nullptr}; +}; + +using WaylandSurfacePtr = std::unique_ptr; diff --git a/src/windows/ui_interfaces/wayland/WaylandWindowInterface.h b/src/windows/ui_interfaces/wayland/WaylandWindowInterface.h index 4b03501..ab6775e 100644 --- a/src/windows/ui_interfaces/wayland/WaylandWindowInterface.h +++ b/src/windows/ui_interfaces/wayland/WaylandWindowInterface.h @@ -6,8 +6,11 @@ #include "Window.h" #include "SharedMemory.h" +#include "WaylandSurface.h" + #include #include +#include #include #include @@ -118,16 +121,6 @@ public: wl_surface_commit(mSurface); } - void onXdgSurfaceConfigure(void *data, struct xdg_surface *xdg_surface, uint32_t serial) - { - xdg_surface_ack_configure(xdg_surface, serial); - - auto buffer = draw_frame(); - wl_surface_attach(mSurface, buffer, 0, 0); - //wl_surface_damage(mSurface, 0, 0, UINT32_MAX, UINT32_MAX); - wl_surface_commit(mSurface); - } - wl_buffer* draw_frame() { const auto width = mWindow->GetWidth(); @@ -233,12 +226,18 @@ public: void addWindow(mt::Window* window) { - mWindow = window; + auto surface = std::make_unique(window); + mSurfaces.push_back(surface); + } + + void mapWindow(mt::Window* window) + { + } private: - mt::Window* mWindow{nullptr}; + std::vector > mSurfaces; wl_display* mDisplay{nullptr}; wl_compositor* mCompositor{nullptr}; @@ -247,11 +246,7 @@ private: xdg_wm_base* mXdgBase{nullptr}; xdg_wm_base_listener mXdgBaseListener; - wl_surface* mSurface{nullptr}; - xdg_surface* mXdgSurface{nullptr}; - xdg_surface_listener mXdgSurfaceListener{nullptr}; - xdg_toplevel* mXdgTopLevel{nullptr}; wl_shm* mWlSharedMemory{nullptr}; std::unique_ptr mSharedMemory; diff --git a/src/windows/ui_interfaces/wayland/XdgInterface.cpp b/src/windows/ui_interfaces/wayland/XdgInterface.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/windows/ui_interfaces/wayland/XdgInterface.h b/src/windows/ui_interfaces/wayland/XdgInterface.h new file mode 100644 index 0000000..e69de29