Fix compilation.
This commit is contained in:
parent
5d06b170ef
commit
92e7a78710
8 changed files with 343 additions and 298 deletions
|
@ -14,6 +14,8 @@ list(APPEND platform_INCLUDES
|
||||||
ui_interfaces/x11/GlxInterface.cpp
|
ui_interfaces/x11/GlxInterface.cpp
|
||||||
|
|
||||||
ui_interfaces/wayland/WaylandWindowInterface.cpp
|
ui_interfaces/wayland/WaylandWindowInterface.cpp
|
||||||
|
ui_interfaces/wayland/WaylandSurface.cpp
|
||||||
|
ui_interfaces/wayland/WaylandBuffer.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND platform_LIBS
|
list(APPEND platform_LIBS
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
#include "WaylandBuffer.h"
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void WaylandBuffer::setSharedMemory(wl_shm* shared_memory)
|
||||||
|
{
|
||||||
|
mWlSharedMemory = shared_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaylandBuffer::initializeSharedBuffer(int size)
|
||||||
|
{
|
||||||
|
mSharedMemory = std::make_unique<SharedMemory>();
|
||||||
|
mSharedMemory->allocate("/wl_shm-XXXXXX", size);
|
||||||
|
|
||||||
|
if (!mSharedMemory->isValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mPoolData = static_cast<uint8_t*>(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, mSharedMemory->getFileDescriptor(), 0));
|
||||||
|
if (mPoolData == MAP_FAILED)
|
||||||
|
{
|
||||||
|
close(mSharedMemory->getFileDescriptor());
|
||||||
|
mPoolData = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaylandBuffer::setUpPool(int size, int width, int height, int stride)
|
||||||
|
{
|
||||||
|
if (!mSharedMemory->isValid())
|
||||||
|
{
|
||||||
|
std::cout << "Failed to allocate shared memory" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mPoolData)
|
||||||
|
{
|
||||||
|
std::cout << "Failed to mmap pool" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pool = wl_shm_create_pool(mWlSharedMemory, mSharedMemory->getFileDescriptor(), 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaylandBuffer::tearDownPool(int size)
|
||||||
|
{
|
||||||
|
munmap(mPoolData, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* WaylandBuffer::getPoolData()
|
||||||
|
{
|
||||||
|
return mPoolData;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_buffer* WaylandBuffer::getWorkingBuffer()
|
||||||
|
{
|
||||||
|
return mWorkingBuffer;
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "wayland-client.h"
|
||||||
|
|
||||||
|
#include "SharedMemory.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class WaylandBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
WaylandBuffer() = default;
|
||||||
|
|
||||||
|
void setSharedMemory(wl_shm* shared_memory);
|
||||||
|
|
||||||
|
void initializeSharedBuffer(int size);
|
||||||
|
|
||||||
|
uint8_t* getPoolData();
|
||||||
|
wl_buffer* getWorkingBuffer();
|
||||||
|
|
||||||
|
void setUpPool(int size, int width, int height, int stride);
|
||||||
|
|
||||||
|
void tearDownPool(int size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
wl_shm* mWlSharedMemory{nullptr};
|
||||||
|
|
||||||
|
std::unique_ptr<SharedMemory> mSharedMemory;
|
||||||
|
uint8_t* mPoolData{nullptr};
|
||||||
|
wl_shm_pool* mPool{nullptr};
|
||||||
|
|
||||||
|
wl_buffer* mWorkingBuffer{nullptr};
|
||||||
|
wl_buffer_listener mBufferListener;
|
||||||
|
};
|
|
@ -0,0 +1,91 @@
|
||||||
|
#include "WaylandSurface.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
WaylandSurface::WaylandSurface(mt::Window* window)
|
||||||
|
: mWindow(window)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WaylandSurface::~WaylandSurface()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaylandSurface::initialize(wl_compositor* compositor, xdg_wm_base* xdg_wm_base, std::shared_ptr<WaylandBuffer> buffer)
|
||||||
|
{
|
||||||
|
mBuffer = buffer;
|
||||||
|
|
||||||
|
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<WaylandSurface*>(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 WaylandSurface::onConfigure(xdg_surface *xdg_surface, uint32_t serial)
|
||||||
|
{
|
||||||
|
xdg_surface_ack_configure(xdg_surface, serial);
|
||||||
|
|
||||||
|
auto buffer = drawFrame();
|
||||||
|
wl_surface_attach(mSurface, buffer, 0, 0);
|
||||||
|
//wl_surface_damage(mSurface, 0, 0, UINT32_MAX, UINT32_MAX);
|
||||||
|
wl_surface_commit(mSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_buffer* WaylandSurface::drawFrame()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
mBuffer->initializeSharedBuffer(shm_pool_size);
|
||||||
|
mBuffer->setUpPool(shm_pool_size, width, height, stride);
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
drawCheckerboard(width, height, offset);
|
||||||
|
|
||||||
|
mBuffer->tearDownPool(shm_pool_size);
|
||||||
|
|
||||||
|
return mBuffer->getWorkingBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 x = 0; x < width; ++x)
|
||||||
|
{
|
||||||
|
if ((x + y / 8 * 8) % 16 < 8)
|
||||||
|
{
|
||||||
|
pixels[y * width + x] = 0xFF666666;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pixels[y * width + x] = 0xFFEEEEEE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include "wayland-client.h"
|
#include "wayland-client.h"
|
||||||
|
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
#include "SharedMemory.h"
|
||||||
|
#include <WaylandBuffer.h>
|
||||||
|
|
||||||
struct wl_surface;
|
struct wl_surface;
|
||||||
struct xdg_surface;
|
struct xdg_surface;
|
||||||
|
@ -12,94 +14,19 @@ struct xdg_toplevel;
|
||||||
class WaylandSurface
|
class WaylandSurface
|
||||||
{
|
{
|
||||||
|
|
||||||
WaylandSurface(mt::Window* window)
|
public:
|
||||||
: mWindow(window)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
WaylandSurface(mt::Window* window);
|
||||||
|
|
||||||
|
~WaylandSurface();
|
||||||
|
|
||||||
void initialize(wl_compositor* compositor, xdg_wm_base* xdg_wm_base)
|
void initialize(wl_compositor* compositor, xdg_wm_base* xdg_wm_base, std::shared_ptr<WaylandBuffer> buffer);
|
||||||
{
|
|
||||||
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)
|
void onConfigure(xdg_surface *xdg_surface, uint32_t serial);
|
||||||
{
|
|
||||||
auto thisClass = static_cast<WaylandSurface*>(data);
|
|
||||||
thisClass->onConfigure(xdg_surface, serial);
|
|
||||||
};
|
|
||||||
mXdgSurfaceListener.configure = xdg_surface_configure;
|
|
||||||
|
|
||||||
xdg_surface_add_listener(mXdgSurface, &mXdgSurfaceListener, this);
|
wl_buffer* drawFrame();
|
||||||
|
|
||||||
mXdgTopLevel = xdg_surface_get_toplevel(mXdgSurface);
|
void drawCheckerboard(int width, int height, int offset);
|
||||||
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:
|
private:
|
||||||
|
|
||||||
|
@ -110,6 +37,8 @@ private:
|
||||||
xdg_surface_listener mXdgSurfaceListener{nullptr};
|
xdg_surface_listener mXdgSurfaceListener{nullptr};
|
||||||
|
|
||||||
xdg_toplevel* mXdgTopLevel{nullptr};
|
xdg_toplevel* mXdgTopLevel{nullptr};
|
||||||
|
|
||||||
|
std::shared_ptr<WaylandBuffer> mBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
using WaylandSurfacePtr = std::unique_ptr<WaylandSurface>;
|
using WaylandSurfacePtr = std::unique_ptr<WaylandSurface>;
|
||||||
|
|
|
@ -1 +1,114 @@
|
||||||
#include "WaylandWindowInterface.h"
|
#include "WaylandWindowInterface.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
WaylandWindowInterface::WaylandWindowInterface()
|
||||||
|
: mBuffer(std::make_shared<WaylandBuffer>())
|
||||||
|
{
|
||||||
|
auto registry_handle_global_func = [](void *data, struct wl_registry *registry,
|
||||||
|
uint32_t name, const char *interface, uint32_t version)
|
||||||
|
{
|
||||||
|
auto thisClass = static_cast<WaylandWindowInterface*>(data);
|
||||||
|
|
||||||
|
printf("interface: '%s', version: %d, name: %d\n", interface, version, name);
|
||||||
|
|
||||||
|
if (strcmp(interface, wl_compositor_interface.name) == 0)
|
||||||
|
{
|
||||||
|
thisClass->setCompositor(static_cast<wl_compositor*>(wl_registry_bind(registry, name, &wl_compositor_interface, 4)));
|
||||||
|
}
|
||||||
|
else if (strcmp(interface, wl_shm_interface.name) == 0)
|
||||||
|
{
|
||||||
|
thisClass->setSharedMemory(static_cast<wl_shm*>(wl_registry_bind(registry, name, &wl_shm_interface, 1)));
|
||||||
|
}
|
||||||
|
else if (strcmp(interface, xdg_wm_base_interface.name) == 0)
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
uint32_t name)
|
||||||
|
{
|
||||||
|
// This space deliberately left blank;
|
||||||
|
};
|
||||||
|
|
||||||
|
mRegistryListener.global = registry_handle_global_func;
|
||||||
|
mRegistryListener.global_remove = registry_handle_global_remove_func;
|
||||||
|
}
|
||||||
|
|
||||||
|
WaylandWindowInterface::~WaylandWindowInterface()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaylandWindowInterface::setXdgBase(xdg_wm_base* xdg_base)
|
||||||
|
{
|
||||||
|
mXdgBase = xdg_base;
|
||||||
|
auto xdg_ping_handler = [](void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial)
|
||||||
|
{
|
||||||
|
auto thisClass = static_cast<WaylandWindowInterface*>(data);
|
||||||
|
thisClass->doXdgPong(serial);
|
||||||
|
};
|
||||||
|
mXdgBaseListener.ping = xdg_ping_handler;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
mCompositor = compositor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaylandWindowInterface::setSharedMemory(wl_shm* shared_memory)
|
||||||
|
{
|
||||||
|
mBuffer->setSharedMemory(shared_memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaylandWindowInterface::connect()
|
||||||
|
{
|
||||||
|
mDisplay = wl_display_connect(nullptr);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
auto surface = std::make_unique<WaylandSurface>(window);
|
||||||
|
mSurfaces.push_back(std::move(surface));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaylandWindowInterface::mapWindow(mt::Window* window)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaylandWindowInterface::disconnect()
|
||||||
|
{
|
||||||
|
if (mDisplay)
|
||||||
|
{
|
||||||
|
wl_display_disconnect(mDisplay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaylandWindowInterface::run()
|
||||||
|
{
|
||||||
|
while (wl_display_dispatch(mDisplay) != -1) {
|
||||||
|
/* This space deliberately left blank */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,14 +7,10 @@
|
||||||
#include "SharedMemory.h"
|
#include "SharedMemory.h"
|
||||||
|
|
||||||
#include "WaylandSurface.h"
|
#include "WaylandSurface.h"
|
||||||
|
#include "WaylandBuffer.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstring>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class WaylandWindowInterface
|
class WaylandWindowInterface
|
||||||
|
@ -22,218 +18,27 @@ class WaylandWindowInterface
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
WaylandWindowInterface()
|
WaylandWindowInterface();
|
||||||
{
|
|
||||||
auto registry_handle_global = [](void *data, struct wl_registry *registry,
|
|
||||||
uint32_t name, const char *interface, uint32_t version)
|
|
||||||
{
|
|
||||||
auto thisClass = static_cast<WaylandWindowInterface*>(data);
|
|
||||||
|
|
||||||
printf("interface: '%s', version: %d, name: %d\n", interface, version, name);
|
~WaylandWindowInterface();
|
||||||
|
|
||||||
if (strcmp(interface, wl_compositor_interface.name) == 0)
|
void setXdgBase(xdg_wm_base* xdg_base);
|
||||||
{
|
|
||||||
thisClass->setCompositor(static_cast<wl_compositor*>(wl_registry_bind(registry, name, &wl_compositor_interface, 4)));
|
|
||||||
}
|
|
||||||
else if (strcmp(interface, wl_shm_interface.name) == 0)
|
|
||||||
{
|
|
||||||
thisClass->setSharedMemory(static_cast<wl_shm*>(wl_registry_bind(registry, name, &wl_shm_interface, 1)));
|
|
||||||
}
|
|
||||||
else if (strcmp(interface, xdg_wm_base_interface.name) == 0)
|
|
||||||
{
|
|
||||||
thisClass->setXdgBase(static_cast<xdg_wm_base*>(wl_registry_bind(registry, name, &xdg_wm_base_interface, 1)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto registry_handle_global_remove = [](void *data, struct wl_registry *registry,
|
void doXdgPong(uint32_t serial);
|
||||||
uint32_t name)
|
|
||||||
{
|
|
||||||
// This space deliberately left blank;
|
|
||||||
};
|
|
||||||
|
|
||||||
mRegistryListener.global = registry_handle_global;
|
void setCompositor(wl_compositor* compositor);
|
||||||
mRegistryListener.global_remove = registry_handle_global_remove;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setXdgBase(xdg_wm_base* xdg_base)
|
void setSharedMemory(wl_shm* shared_memory);
|
||||||
{
|
|
||||||
mXdgBase = xdg_base;
|
|
||||||
auto xdg_ping_handler = [](void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial)
|
|
||||||
{
|
|
||||||
auto thisClass = static_cast<WaylandWindowInterface*>(data);
|
|
||||||
thisClass->doXdgPong(serial);
|
|
||||||
};
|
|
||||||
mXdgBaseListener.ping = xdg_ping_handler;
|
|
||||||
xdg_wm_base_add_listener(mXdgBase, &mXdgBaseListener, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void doXdgPong(uint32_t serial)
|
void connect();
|
||||||
{
|
|
||||||
xdg_wm_base_pong(mXdgBase, serial);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setCompositor(wl_compositor* compositor)
|
void disconnect();
|
||||||
{
|
|
||||||
mCompositor = compositor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSharedMemory(wl_shm* shared_memory)
|
void run();
|
||||||
{
|
|
||||||
mWlSharedMemory = shared_memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
void connect()
|
void addWindow(mt::Window* window);
|
||||||
{
|
|
||||||
mDisplay = wl_display_connect(nullptr);
|
|
||||||
|
|
||||||
if (!mDisplay)
|
void mapWindow(mt::Window* window);
|
||||||
{
|
|
||||||
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 createSurface()
|
|
||||||
{
|
|
||||||
mSurface = wl_compositor_create_surface(mCompositor);
|
|
||||||
mXdgSurface = xdg_wm_base_get_xdg_surface(mXdgBase, mSurface);
|
|
||||||
|
|
||||||
auto xdg_surface_configure = [](void *data, struct xdg_surface *xdg_surface, uint32_t serial)
|
|
||||||
{
|
|
||||||
auto thisClass = static_cast<WaylandWindowInterface*>(data);
|
|
||||||
thisClass->onXdgSurfaceConfigure(data, 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawCheckerboard(int width, int height, int offset)
|
|
||||||
{
|
|
||||||
uint32_t *pixels = (uint32_t *)&mPoolData[offset];
|
|
||||||
for (int y = 0; y < height; ++y)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < width; ++x)
|
|
||||||
{
|
|
||||||
if ((x + y / 8 * 8) % 16 < 8)
|
|
||||||
{
|
|
||||||
pixels[y * width + x] = 0xFF666666;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pixels[y * width + x] = 0xFFEEEEEE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void disconnect()
|
|
||||||
{
|
|
||||||
if (mDisplay)
|
|
||||||
{
|
|
||||||
wl_display_disconnect(mDisplay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void run()
|
|
||||||
{
|
|
||||||
while (wl_display_dispatch(mDisplay) != -1) {
|
|
||||||
/* This space deliberately left blank */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void initializeSharedBuffer(int size)
|
|
||||||
{
|
|
||||||
mSharedMemory = std::make_unique<SharedMemory>();
|
|
||||||
mSharedMemory->allocate("/wl_shm-XXXXXX", size);
|
|
||||||
|
|
||||||
if (!mSharedMemory->isValid())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mPoolData = static_cast<uint8_t*>(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, mSharedMemory->getFileDescriptor(), 0));
|
|
||||||
if (mPoolData == MAP_FAILED)
|
|
||||||
{
|
|
||||||
close(mSharedMemory->getFileDescriptor());
|
|
||||||
mPoolData = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void addWindow(mt::Window* window)
|
|
||||||
{
|
|
||||||
auto surface = std::make_unique<WaylandSurface>(window);
|
|
||||||
mSurfaces.push_back(surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mapWindow(mt::Window* window)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -246,13 +51,6 @@ private:
|
||||||
xdg_wm_base* mXdgBase{nullptr};
|
xdg_wm_base* mXdgBase{nullptr};
|
||||||
xdg_wm_base_listener mXdgBaseListener;
|
xdg_wm_base_listener mXdgBaseListener;
|
||||||
|
|
||||||
|
std::shared_ptr<WaylandBuffer> mBuffer;
|
||||||
|
|
||||||
|
|
||||||
wl_shm* mWlSharedMemory{nullptr};
|
|
||||||
std::unique_ptr<SharedMemory> mSharedMemory;
|
|
||||||
uint8_t* mPoolData{nullptr};
|
|
||||||
wl_shm_pool* mPool{nullptr};
|
|
||||||
|
|
||||||
wl_buffer* mWorkingBuffer{nullptr};
|
|
||||||
wl_buffer_listener mBufferListener;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,7 +14,7 @@ int main()
|
||||||
|
|
||||||
window_interface.addWindow(window.get());
|
window_interface.addWindow(window.get());
|
||||||
|
|
||||||
window_interface.createSurface();
|
window_interface.mapWindow(window.get());
|
||||||
|
|
||||||
window_interface.run();
|
window_interface.run();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue