Some wayland cleanup

This commit is contained in:
James Grogan 2022-11-10 10:48:22 +00:00
parent 7ce29ce8ae
commit 25b1966c0e
10 changed files with 267 additions and 252 deletions

View file

@ -30,6 +30,23 @@ sudo apt-get install libasound2-dev
sudo apt-get install libpng-dev sudo apt-get install libpng-dev
``` ```
#### Window rendering
```bash
sudo apt-get install libwayland-dev wayland-protocols
```
We need to generate suitable xdg shell c code for wayland:
```bash
mkdir $WORK_DIR
cd $WORK_DIR
wayland-scanner private-code < /usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml > xdg-shell-protocol.cpp
wayland-scanner client-header < /usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml > xdg-shell-client-protocol.h
export WAYLAND_EXTENSION_DIR=$WORK_DIR
```
In `xdg-shell-protocol.cpp` - we need access to `xdg_wm_base_interface` so export it also `extern const struct wl_interface xdg_wm_base_interface;` as per similar interface structs.
# Build from Source # Build from Source

View file

@ -23,20 +23,15 @@ if(UNIX)
endif() endif()
find_path(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h) find_path(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h)
if (NOT ${WAYLAND_CLIENT_INCLUDE_DIR-NOTFOUND}) #if (NOT ${WAYLAND_CLIENT_INCLUDE_DIR-NOTFOUND})
list(APPEND WAYLAND_INCLUDE_DIRS ${WAYLAND_CLIENT_INCLUDE_DIR}) list(APPEND WAYLAND_INCLUDE_DIRS ${WAYLAND_CLIENT_INCLUDE_DIR})
find_path(WAYLAND_EXTENSIONS_INCLUDE_DIR NAMES xdg-shell-client-protocol.h find_path(WAYLAND_EXTENSIONS_INCLUDE_DIR NAMES xdg-shell-client-protocol.h HINTS ENV WAYLAND_EXTENSION_DIR)
HINTS ENV WAYLAND_EXTENSION_DIR
) #if(NOT ${WAYLAND_EXTENSIONS_INCLUDE_DIR-NOTFOUND})
if(NOT ${WAYLAND_EXTENSIONS_INCLUDE_DIR-NOTFOUND}) find_library(WAYLAND_CLIENT_LIBRARY NAMES wayland-client libwayland-client)
find_library(
WAYLAND_CLIENT_LIBRARY
NAMES wayland-client libwayland-client
)
list(APPEND WAYLAND_INCLUDE_DIRS ${WAYLAND_EXTENSIONS_INCLUDE_DIR}) list(APPEND WAYLAND_INCLUDE_DIRS ${WAYLAND_EXTENSIONS_INCLUDE_DIR})
list(APPEND platform_INCLUDES list(APPEND platform_INCLUDES
ui_interfaces/wayland/WaylandWindowInterface.cpp ui_interfaces/wayland/WaylandWindowInterface.cpp
ui_interfaces/wayland/WaylandSurface.cpp ui_interfaces/wayland/WaylandSurface.cpp
@ -44,12 +39,12 @@ if(UNIX)
${WAYLAND_EXTENSIONS_INCLUDE_DIR}/xdg-shell-protocol.cpp ${WAYLAND_EXTENSIONS_INCLUDE_DIR}/xdg-shell-protocol.cpp
) )
set(_HAS_WAYLAND ON) set(_HAS_WAYLAND ON)
else() #else()
message(STATUS "Wayland Extensions Header not found - not building Wayland support") #message(STATUS "Wayland Extensions Header not found - not building Wayland support")
endif() #endif()
else() #else()
message(STATUS "Wayland Client Header not found - not building Wayland support") #message(STATUS "Wayland Client Header not found - not building Wayland support")
endif() #endif()
else() else()
list(APPEND platform_INCLUDES list(APPEND platform_INCLUDES
@ -87,6 +82,7 @@ target_include_directories(windows PUBLIC
) )
target_link_libraries(windows PUBLIC ${platform_LIBS} core geometry graphics ui_elements ${WAYLAND_CLIENT_LIBRARY}) target_link_libraries(windows PUBLIC ${platform_LIBS} core geometry graphics ui_elements ${WAYLAND_CLIENT_LIBRARY})
target_compile_options(windows PRIVATE -Wno-attributes) # From xdg shell autogen code
set_property(TARGET windows PROPERTY FOLDER src) set_property(TARGET windows PROPERTY FOLDER src)
set_target_properties( windows PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON ) set_target_properties( windows PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON )

View file

@ -11,10 +11,6 @@
class WindowManager class WindowManager
{ {
private:
std::vector<WindowUPtr> mWindows;
public: public:
WindowManager(); WindowManager();
@ -33,6 +29,8 @@ public:
void OnKeyboardEvent(const KeyboardEvent* event); void OnKeyboardEvent(const KeyboardEvent* event);
private:
std::vector<WindowUPtr> mWindows;
}; };
using WindowManagerUPtr = std::unique_ptr<WindowManager>; using WindowManagerUPtr = std::unique_ptr<WindowManager>;

View file

@ -1,15 +1,10 @@
#include "WaylandBuffer.h" #include "WaylandBuffer.h"
#include "FileLogger.h"
#include <sys/mman.h> #include <sys/mman.h>
#include <unistd.h> #include <unistd.h>
#include <iostream>
void WaylandBuffer::setSharedMemory(wl_shm* shared_memory)
{
mWlSharedMemory = shared_memory;
}
void WaylandBuffer::initializeSharedBuffer(int size) void WaylandBuffer::initializeSharedBuffer(int size)
{ {
mSharedMemory = std::make_unique<SharedMemory>(); mSharedMemory = std::make_unique<SharedMemory>();
@ -19,6 +14,7 @@ void WaylandBuffer::initializeSharedBuffer(int size)
{ {
return; return;
} }
mPoolData = static_cast<uint8_t*>(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, mSharedMemory->getFileDescriptor(), 0)); mPoolData = static_cast<uint8_t*>(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, mSharedMemory->getFileDescriptor(), 0));
if (mPoolData == MAP_FAILED) if (mPoolData == MAP_FAILED)
{ {
@ -27,17 +23,22 @@ void WaylandBuffer::initializeSharedBuffer(int size)
} }
} }
void WaylandBuffer::setSharedMemory(wl_shm* shared_memory)
{
mWlSharedMemory = shared_memory;
}
void WaylandBuffer::setUpPool(int size, int width, int height, int stride) void WaylandBuffer::setUpPool(int size, int width, int height, int stride)
{ {
if (!mSharedMemory->isValid()) if (!mSharedMemory->isValid())
{ {
std::cout << "Failed to allocate shared memory" << std::endl; MLOG_ERROR("Failed to allocate shared memory.");
return; return;
} }
if (!mPoolData) if (!mPoolData)
{ {
std::cout << "Failed to mmap pool" << std::endl; MLOG_ERROR("Failed to allocate shared memory.");
return; return;
} }

View file

@ -11,15 +11,13 @@ class WaylandBuffer
public: public:
WaylandBuffer() = default; WaylandBuffer() = default;
void setSharedMemory(wl_shm* shared_memory);
void initializeSharedBuffer(int size); void initializeSharedBuffer(int size);
uint8_t* getPoolData(); uint8_t* getPoolData();
wl_buffer* getWorkingBuffer(); wl_buffer* getWorkingBuffer();
void setUpPool(int size, int width, int height, int stride); void setUpPool(int size, int width, int height, int stride);
void setSharedMemory(wl_shm* shared_memory);
void tearDownPool(int size); void tearDownPool(int size);

View file

@ -1,9 +1,5 @@
#include "WaylandSurface.h" #include "WaylandSurface.h"
#include <iostream>
#include <sys/mman.h>
#include <unistd.h>
WaylandSurface::WaylandSurface(mt::Window* window) WaylandSurface::WaylandSurface(mt::Window* window)
: mWindow(window) : mWindow(window)
{ {

View file

@ -15,7 +15,6 @@ class WaylandSurface
{ {
public: public:
WaylandSurface(mt::Window* window); WaylandSurface(mt::Window* window);
~WaylandSurface(); ~WaylandSurface();
@ -29,7 +28,6 @@ public:
void drawCheckerboard(int width, int height, int offset); void drawCheckerboard(int width, int height, int offset);
private: private:
mt::Window* mWindow{nullptr}; mt::Window* mWindow{nullptr};
wl_surface* mSurface{nullptr}; wl_surface* mSurface{nullptr};

View file

@ -1,16 +1,20 @@
#include "WaylandWindowInterface.h" #include "WaylandWindowInterface.h"
#include <cstring> #include "FileLogger.h"
#include "WaylandSurface.h"
#include "WaylandBuffer.h"
WaylandWindowInterface::WaylandWindowInterface() #include <cstring>
: mBuffer(std::make_shared<WaylandBuffer>()) #include <sstream>
{
auto registry_handle_global_func = [](void *data, struct wl_registry *registry, void WaylandWindowInterface::registryHandleGlobalCallback(void *data, struct wl_registry *registry,
uint32_t name, const char *interface, uint32_t version) uint32_t name, const char *interface, uint32_t version)
{ {
auto thisClass = static_cast<WaylandWindowInterface*>(data); auto thisClass = static_cast<WaylandWindowInterface*>(data);
printf("interface: '%s', version: %d, name: %d\n", interface, version, name); std::stringstream sstrm;
sstrm << "interface: " << interface << " version " << version << " name " << name;
MLOG_INFO(sstrm.str());
if (strcmp(interface, wl_compositor_interface.name) == 0) if (strcmp(interface, wl_compositor_interface.name) == 0)
{ {
@ -24,16 +28,19 @@ WaylandWindowInterface::WaylandWindowInterface()
{ {
thisClass->setXdgBase(static_cast<xdg_wm_base*>(wl_registry_bind(registry, name, &xdg_wm_base_interface, 1))); thisClass->setXdgBase(static_cast<xdg_wm_base*>(wl_registry_bind(registry, name, &xdg_wm_base_interface, 1)));
} }
}; }
auto registry_handle_global_remove_func = [](void *data, struct wl_registry *registry, void WaylandWindowInterface::registryHandleGlobalRemoveCallback(void *data, struct wl_registry *registry, uint32_t name)
uint32_t name) {
{
// This space deliberately left blank;
};
mRegistryListener.global = registry_handle_global_func; }
mRegistryListener.global_remove = registry_handle_global_remove_func;
WaylandWindowInterface::WaylandWindowInterface()
: mBuffer(std::make_shared<WaylandBuffer>())
{
mRegistryListener.global = registryHandleGlobalCallback;
mRegistryListener.global_remove = registryHandleGlobalRemoveCallback;
} }
WaylandWindowInterface::~WaylandWindowInterface() WaylandWindowInterface::~WaylandWindowInterface()
@ -41,6 +48,27 @@ WaylandWindowInterface::~WaylandWindowInterface()
} }
void WaylandWindowInterface::connect()
{
mDisplay = wl_display_connect(nullptr);
if (!mDisplay)
{
MLOG_ERROR("Display connect error");
return;
}
auto registry = wl_display_get_registry(mDisplay);
if (!registry)
{
MLOG_ERROR("Failed to get registry");
return;
}
wl_registry_add_listener(registry, &mRegistryListener, this);
wl_display_roundtrip(mDisplay);
}
void WaylandWindowInterface::setXdgBase(xdg_wm_base* xdg_base) void WaylandWindowInterface::setXdgBase(xdg_wm_base* xdg_base)
{ {
mXdgBase = xdg_base; mXdgBase = xdg_base;
@ -53,11 +81,6 @@ void WaylandWindowInterface::setXdgBase(xdg_wm_base* xdg_base)
xdg_wm_base_add_listener(mXdgBase, &mXdgBaseListener, this); xdg_wm_base_add_listener(mXdgBase, &mXdgBaseListener, this);
} }
void WaylandWindowInterface::doXdgPong(uint32_t serial)
{
xdg_wm_base_pong(mXdgBase, serial);
}
void WaylandWindowInterface::setCompositor(wl_compositor* compositor) void WaylandWindowInterface::setCompositor(wl_compositor* compositor)
{ {
mCompositor = compositor; mCompositor = compositor;
@ -68,23 +91,9 @@ void WaylandWindowInterface::setSharedMemory(wl_shm* shared_memory)
mBuffer->setSharedMemory(shared_memory); mBuffer->setSharedMemory(shared_memory);
} }
void WaylandWindowInterface::connect() void WaylandWindowInterface::doXdgPong(uint32_t serial)
{ {
mDisplay = wl_display_connect(nullptr); xdg_wm_base_pong(mXdgBase, serial);
if (!mDisplay)
{
std::cout << "Display connect error" << std::endl;
}
auto registry = wl_display_get_registry(mDisplay);
if (!registry)
{
std::cout << "Failed to get registry" << std::endl;
}
wl_registry_add_listener(registry, &mRegistryListener, this);
wl_display_roundtrip(mDisplay);
} }
void WaylandWindowInterface::addWindow(mt::Window* window) void WaylandWindowInterface::addWindow(mt::Window* window)
@ -108,7 +117,8 @@ void WaylandWindowInterface::disconnect()
void WaylandWindowInterface::run() void WaylandWindowInterface::run()
{ {
while (wl_display_dispatch(mDisplay) != -1) { while (wl_display_dispatch(mDisplay) != -1)
{
/* This space deliberately left blank */ /* This space deliberately left blank */
} }
} }

View file

@ -1,18 +1,17 @@
#pragma once #pragma once
#include "wayland-client.h"
#include "xdg-shell-client-protocol.h"
#include "Window.h" #include "Window.h"
#include "SharedMemory.h" #include "SharedMemory.h"
#include "WaylandSurface.h" #include "wayland-client.h"
#include "WaylandBuffer.h" #include "xdg-shell-client-protocol.h"
#include <iostream>
#include <vector> #include <vector>
#include <memory> #include <memory>
class WaylandSurface;
class WaylandBuffer;
class WaylandWindowInterface class WaylandWindowInterface
{ {
@ -22,14 +21,6 @@ public:
~WaylandWindowInterface(); ~WaylandWindowInterface();
void setXdgBase(xdg_wm_base* xdg_base);
void doXdgPong(uint32_t serial);
void setCompositor(wl_compositor* compositor);
void setSharedMemory(wl_shm* shared_memory);
void connect(); void connect();
void disconnect(); void disconnect();
@ -41,8 +32,16 @@ public:
void mapWindow(mt::Window* window); void mapWindow(mt::Window* window);
private: 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);
std::vector<std::unique_ptr<WaylandSurface> > mSurfaces; void doXdgPong(uint32_t serial);
void setCompositor(wl_compositor* compositor);
void setSharedMemory(wl_shm* shared_memory);
void setXdgBase(xdg_wm_base* xdg_base);
wl_display* mDisplay{nullptr}; wl_display* mDisplay{nullptr};
wl_compositor* mCompositor{nullptr}; wl_compositor* mCompositor{nullptr};
@ -51,6 +50,7 @@ private:
xdg_wm_base* mXdgBase{nullptr}; xdg_wm_base* mXdgBase{nullptr};
xdg_wm_base_listener mXdgBaseListener; xdg_wm_base_listener mXdgBaseListener;
std::vector<std::unique_ptr<WaylandSurface> > mSurfaces;
std::shared_ptr<WaylandBuffer> mBuffer; std::shared_ptr<WaylandBuffer> mBuffer;
}; };

View file

@ -1,11 +1,12 @@
#include "WaylandWindowInterface.h" #include "WaylandWindowInterface.h"
#include "Window.h" #include "Window.h"
#include "FileLogger.h"
int main() int main()
{ {
FileLogger::GetInstance().Open();
WaylandWindowInterface window_interface; WaylandWindowInterface window_interface;
window_interface.connect(); window_interface.connect();