Added features to readme.
This commit is contained in:
parent
7e380efd7d
commit
fb86dca332
@ -215,7 +215,10 @@ elseif (IS_OS_LINUX)
|
|||||||
|
|
||||||
if (LINUX_WINDOW_SYSTEM STREQUAL "Wayland")
|
if (LINUX_WINDOW_SYSTEM STREQUAL "Wayland")
|
||||||
add_compile_definitions(EHS_WS_WAYLAND)
|
add_compile_definitions(EHS_WS_WAYLAND)
|
||||||
list(APPEND EHS_SOURCES src/io/xdg-shell-protocol.c include/ehs/io/xdg-shell-client-protocol.h src/io/Window_Way.cpp include/ehs/io/Window_Way.h)
|
list(APPEND EHS_SOURCES
|
||||||
|
src/io/xdg-shell-protocol.c include/ehs/io/xdg-shell-client-protocol.h
|
||||||
|
src/io/xdg-decoration.c include/ehs/io/xdg-decoration.h
|
||||||
|
src/io/Window_Way.cpp include/ehs/io/Window_Way.h)
|
||||||
message("Building for Wayland.")
|
message("Building for Wayland.")
|
||||||
elseif (LINUX_WINDOW_SYSTEM STREQUAL "XCB")
|
elseif (LINUX_WINDOW_SYSTEM STREQUAL "XCB")
|
||||||
add_compile_definitions(EHS_WS_XCB)
|
add_compile_definitions(EHS_WS_XCB)
|
||||||
|
@ -1888,11 +1888,7 @@ namespace ehs
|
|||||||
if (aSize != bSize)
|
if (aSize != bSize)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (UInt_64 i = 0; i < aSize; ++i)
|
return Util::Compare(a, b, aSize);
|
||||||
if (a[i] != b[i])
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,19 +4,28 @@
|
|||||||
|
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
#include "xdg-shell-client-protocol.h"
|
#include "xdg-shell-client-protocol.h"
|
||||||
|
#include "xdg-decoration.h"
|
||||||
|
|
||||||
namespace ehs
|
namespace ehs
|
||||||
{
|
{
|
||||||
class Window : public BaseWindow
|
class Window : public BaseWindow
|
||||||
{
|
{
|
||||||
private:
|
protected:
|
||||||
wl_display* display;
|
wl_display *display;
|
||||||
wl_registry *registry;
|
wl_registry *registry;
|
||||||
wl_compositor* compositor;
|
wl_compositor *compositor;
|
||||||
wl_surface* surface;
|
wl_surface *wlSurface;
|
||||||
xdg_wm_base *xdgShell;
|
xdg_wm_base *xdgShell;
|
||||||
xdg_surface *xdgSurface;
|
xdg_surface *xdgSurface;
|
||||||
xdg_toplevel *xdgToplevel;
|
xdg_toplevel *xdgToplevel;
|
||||||
|
wl_shm *shm;
|
||||||
|
wl_buffer *buffer;
|
||||||
|
zxdg_decoration_manager_v1 *decManager;
|
||||||
|
zxdg_toplevel_decoration_v1 *dec;
|
||||||
|
|
||||||
|
static Int_32 CreateShmFile(Size size);
|
||||||
|
|
||||||
|
void CreateBuffer(Vec2_u32 scale);
|
||||||
|
|
||||||
static void SurfaceConfigure(void *data, xdg_surface *xdg_surface, UInt_32 serial);
|
static void SurfaceConfigure(void *data, xdg_surface *xdg_surface, UInt_32 serial);
|
||||||
|
|
||||||
@ -26,11 +35,21 @@ namespace ehs
|
|||||||
|
|
||||||
static void RegistryRemoved(void *data, wl_registry *registry, UInt_32 id);
|
static void RegistryRemoved(void *data, wl_registry *registry, UInt_32 id);
|
||||||
|
|
||||||
|
static void Resolution(void *data, struct xdg_toplevel *xdg_toplevel, Int_32 width, Int_32 height, wl_array *states);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~Window() override;
|
~Window() override;
|
||||||
|
|
||||||
Window();
|
Window();
|
||||||
|
|
||||||
|
Window(Window &&win) noexcept;
|
||||||
|
|
||||||
|
Window(const Window &win);
|
||||||
|
|
||||||
|
Window &operator=(Window &&win) noexcept;
|
||||||
|
|
||||||
|
Window &operator=(const Window &win);
|
||||||
|
|
||||||
void Create_32(const Str_32& title, const Vec2_s32& pos, const Vec2_u32 scale) override;
|
void Create_32(const Str_32& title, const Vec2_s32& pos, const Vec2_u32 scale) override;
|
||||||
|
|
||||||
void Create_16(const Str_16& title, const Vec2_s32& pos, const Vec2_u32 scale) override;
|
void Create_16(const Str_16& title, const Vec2_s32& pos, const Vec2_u32 scale) override;
|
||||||
|
@ -1,7 +1,74 @@
|
|||||||
#include "ehs/io/Window_Way.h"
|
#include "ehs/io/Window_Way.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include "ehs/io/Console.h"
|
||||||
|
#include "ehs/io/xdg-shell-client-protocol.h"
|
||||||
|
|
||||||
namespace ehs
|
namespace ehs
|
||||||
{
|
{
|
||||||
|
Int_32 Window::CreateShmFile(Size size)
|
||||||
|
{
|
||||||
|
const char *path = getenv("XDG_RUNTIME_DIR");
|
||||||
|
if (!path)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT(LogType::ERR, 0, "XDG_RUNTIME_DIR is not set.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_8 tmplPath = Str_8(path) + "/wl_shm_XXXXXX";
|
||||||
|
|
||||||
|
Int_32 fd = mkstemp(tmplPath);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT(LogType::ERR, 1, "Failed to create shared memory file.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlink(tmplPath) < 0)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT(LogType::ERR, 2, "Failed to unlink shared memory file.");
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ftruncate(fd, size) < 0)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT(LogType::ERR, 3, "Failed to set size of shared memory file to " + Str_8::FromNum(size) + ".");
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
EHS_LOG_SUCCESS();
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::CreateBuffer(Vec2_u32 scale)
|
||||||
|
{
|
||||||
|
const Size stride = scale.x * 4;
|
||||||
|
const Size size = stride * scale.y;
|
||||||
|
|
||||||
|
const Int_32 fd = CreateShmFile(size);
|
||||||
|
|
||||||
|
if (mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0) == MAP_FAILED)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT(LogType::ERR, 0, "Failed to map shared memory file.");
|
||||||
|
close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_shm_pool *pool = wl_shm_create_pool(shm, fd, (int32_t)size);
|
||||||
|
|
||||||
|
buffer = wl_shm_pool_create_buffer(pool, 0, (int32_t)scale.x, (int32_t)scale.y, (int32_t)stride,
|
||||||
|
WL_SHM_FORMAT_XRGB8888);
|
||||||
|
|
||||||
|
wl_shm_pool_destroy(pool);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
void Window::SurfaceConfigure(void* data, xdg_surface* xdg_surface, UInt_32 serial)
|
void Window::SurfaceConfigure(void* data, xdg_surface* xdg_surface, UInt_32 serial)
|
||||||
{
|
{
|
||||||
xdg_surface_ack_configure(xdg_surface, serial);
|
xdg_surface_ack_configure(xdg_surface, serial);
|
||||||
@ -16,41 +83,139 @@ namespace ehs
|
|||||||
{
|
{
|
||||||
Serializer<UInt_64>* ser = (Serializer<UInt_64>*)data;
|
Serializer<UInt_64>* ser = (Serializer<UInt_64>*)data;
|
||||||
|
|
||||||
if (Str_8::Cmp(interface, "wl_compositor"))
|
if (Str_8::Cmp(interface, wl_compositor_interface.name))
|
||||||
{
|
{
|
||||||
ser->SetOffset(0);
|
ser->SetOffset(0);
|
||||||
wl_compositor** comp = ser->Read<wl_compositor**>();
|
wl_compositor** comp = ser->Read<wl_compositor**>();
|
||||||
*comp = (wl_compositor*)wl_registry_bind(registry, id, &wl_compositor_interface, 1);
|
*comp = (wl_compositor*)wl_registry_bind(registry, id, &wl_compositor_interface, 1);
|
||||||
}
|
}
|
||||||
|
else if (Str_8::Cmp(interface, xdg_wm_base_interface.name))
|
||||||
if (Str_8::Cmp(interface, "xdg_wm_base"))
|
|
||||||
{
|
{
|
||||||
ser->SetOffset(sizeof(void*));
|
ser->SetOffset(sizeof(void*));
|
||||||
xdg_wm_base** base = ser->Read<xdg_wm_base**>();
|
xdg_wm_base** base = ser->Read<xdg_wm_base**>();
|
||||||
*base = (xdg_wm_base*)wl_registry_bind(registry, id, &xdg_wm_base_interface, 1);
|
*base = (xdg_wm_base*)wl_registry_bind(registry, id, &xdg_wm_base_interface, 1);
|
||||||
}
|
}
|
||||||
|
else if (Str_8::Cmp(interface, wl_shm_interface.name))
|
||||||
|
{
|
||||||
|
ser->SetOffset(sizeof(void*) * 2);
|
||||||
|
wl_shm** shm = ser->Read<wl_shm**>();
|
||||||
|
*shm = (wl_shm*)wl_registry_bind(registry, id, &wl_shm_interface, 1);
|
||||||
|
}
|
||||||
|
else if (Str_8::Cmp(interface, zxdg_decoration_manager_v1_interface.name))
|
||||||
|
{
|
||||||
|
ser->SetOffset(sizeof(void*) * 3);
|
||||||
|
zxdg_decoration_manager_v1** decManager = ser->Read<zxdg_decoration_manager_v1**>();
|
||||||
|
*decManager = (zxdg_decoration_manager_v1*)wl_registry_bind(registry, id, &zxdg_decoration_manager_v1_interface, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::RegistryRemoved(void* data, wl_registry* registry, UInt_32 id)
|
void Window::RegistryRemoved(void* data, wl_registry* registry, UInt_32 id)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::Resolution(void *data, struct xdg_toplevel *xdg_toplevel, Int_32 width, Int_32 height, wl_array *states)
|
||||||
|
{
|
||||||
|
Console::Write_8("Resolution: " + Str_8::FromNum(width) + "x" + Str_8::FromNum(height));
|
||||||
|
}
|
||||||
|
|
||||||
Window::~Window()
|
Window::~Window()
|
||||||
{
|
{
|
||||||
xdg_toplevel_destroy(xdgToplevel);
|
xdg_toplevel_destroy(xdgToplevel);
|
||||||
xdg_surface_destroy(xdgSurface);
|
xdg_surface_destroy(xdgSurface);
|
||||||
xdg_wm_base_destroy(xdgShell);
|
xdg_wm_base_destroy(xdgShell);
|
||||||
wl_surface_destroy(surface);
|
wl_surface_destroy(wlSurface);
|
||||||
wl_compositor_destroy(compositor);
|
wl_compositor_destroy(compositor);
|
||||||
wl_registry_destroy(registry);
|
wl_registry_destroy(registry);
|
||||||
wl_display_disconnect(display);
|
wl_display_disconnect(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::Window()
|
Window::Window()
|
||||||
: display(nullptr), registry(nullptr), compositor(nullptr) , surface(nullptr)
|
: display(nullptr), registry(nullptr), compositor(nullptr), wlSurface(nullptr), xdgShell(nullptr),
|
||||||
|
xdgSurface(nullptr), xdgToplevel(nullptr), shm(nullptr), buffer(nullptr), decManager(nullptr), dec(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window::Window(Window &&win) noexcept
|
||||||
|
: BaseWindow(win), display(win.display), registry(win.registry), compositor(win.compositor),
|
||||||
|
wlSurface(win.wlSurface), xdgShell(win.xdgShell), xdgSurface(win.xdgSurface), xdgToplevel(win.xdgToplevel),
|
||||||
|
shm(win.shm), buffer(win.buffer), decManager(win.decManager), dec(win.dec)
|
||||||
|
{
|
||||||
|
win.display = nullptr;
|
||||||
|
win.registry = nullptr;
|
||||||
|
win.compositor = nullptr;
|
||||||
|
win.wlSurface = nullptr;
|
||||||
|
win.xdgShell = nullptr;
|
||||||
|
win.xdgSurface = nullptr;
|
||||||
|
win.xdgToplevel = nullptr;
|
||||||
|
win.shm = nullptr;
|
||||||
|
win.buffer = nullptr;
|
||||||
|
win.decManager = nullptr;
|
||||||
|
win.dec = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Window::Window(const Window &win)
|
||||||
|
: BaseWindow(win), display(nullptr), registry(nullptr), compositor(nullptr), wlSurface(nullptr),
|
||||||
|
xdgShell(nullptr), xdgSurface(nullptr), xdgToplevel(nullptr), shm(nullptr), buffer(nullptr), decManager(nullptr),
|
||||||
|
dec(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Window & Window::operator=(Window &&win) noexcept
|
||||||
|
{
|
||||||
|
if (this == &win)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
BaseWindow::operator=(win);
|
||||||
|
|
||||||
|
display = win.display;
|
||||||
|
registry = win.registry;
|
||||||
|
compositor = win.compositor;
|
||||||
|
wlSurface = win.wlSurface;
|
||||||
|
xdgShell = win.xdgShell;
|
||||||
|
xdgSurface = win.xdgSurface;
|
||||||
|
xdgToplevel = win.xdgToplevel;
|
||||||
|
shm = win.shm;
|
||||||
|
buffer = win.buffer;
|
||||||
|
decManager = win.decManager;
|
||||||
|
dec = win.dec;
|
||||||
|
|
||||||
|
win.display = nullptr;
|
||||||
|
win.registry = nullptr;
|
||||||
|
win.compositor = nullptr;
|
||||||
|
win.wlSurface = nullptr;
|
||||||
|
win.xdgShell = nullptr;
|
||||||
|
win.xdgSurface = nullptr;
|
||||||
|
win.xdgToplevel = nullptr;
|
||||||
|
win.shm = nullptr;
|
||||||
|
win.buffer = nullptr;
|
||||||
|
win.decManager = nullptr;
|
||||||
|
win.dec = nullptr;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Window & Window::operator=(const Window &win)
|
||||||
|
{
|
||||||
|
if (this == &win)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
BaseWindow::operator=(win);
|
||||||
|
|
||||||
|
display = nullptr;
|
||||||
|
registry = nullptr;
|
||||||
|
compositor = nullptr;
|
||||||
|
wlSurface = nullptr;
|
||||||
|
xdgShell = nullptr;
|
||||||
|
xdgSurface = nullptr;
|
||||||
|
xdgToplevel = nullptr;
|
||||||
|
shm = nullptr;
|
||||||
|
buffer = nullptr;
|
||||||
|
decManager = nullptr;
|
||||||
|
dec = nullptr;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
void Window::Create_32(const Str_32& title, const Vec2_s32& pos, const Vec2_u32 scale)
|
void Window::Create_32(const Str_32& title, const Vec2_s32& pos, const Vec2_u32 scale)
|
||||||
{
|
{
|
||||||
Create_8(UTF::To_8(title), pos, scale);
|
Create_8(UTF::To_8(title), pos, scale);
|
||||||
@ -73,6 +238,8 @@ namespace ehs
|
|||||||
Serializer<UInt_64> data(Endianness::LE);
|
Serializer<UInt_64> data(Endianness::LE);
|
||||||
data.Write(&compositor);
|
data.Write(&compositor);
|
||||||
data.Write(&xdgShell);
|
data.Write(&xdgShell);
|
||||||
|
data.Write(&shm);
|
||||||
|
data.Write(&decManager);
|
||||||
|
|
||||||
static constexpr wl_registry_listener registry_listener = {
|
static constexpr wl_registry_listener registry_listener = {
|
||||||
RegistryHandler,
|
RegistryHandler,
|
||||||
@ -95,22 +262,41 @@ namespace ehs
|
|||||||
|
|
||||||
xdg_wm_base_add_listener(xdgShell, &xdg_shell_listener, nullptr);
|
xdg_wm_base_add_listener(xdgShell, &xdg_shell_listener, nullptr);
|
||||||
|
|
||||||
surface = wl_compositor_create_surface(compositor);
|
wlSurface = wl_compositor_create_surface(compositor);
|
||||||
if (!surface)
|
if (!wlSurface)
|
||||||
{
|
{
|
||||||
EHS_LOG_INT(LogType::ERR, 2, "Can't create surface.");
|
EHS_LOG_INT(LogType::ERR, 2, "Can't create surface.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
xdgSurface = xdg_wm_base_get_xdg_surface(xdgShell, surface);
|
CreateBuffer(scale);
|
||||||
xdgToplevel = xdg_surface_get_toplevel(xdgSurface);
|
|
||||||
|
xdgSurface = xdg_wm_base_get_xdg_surface(xdgShell, wlSurface);
|
||||||
|
|
||||||
static constexpr xdg_surface_listener surfaceListener = {SurfaceConfigure};
|
static constexpr xdg_surface_listener surfaceListener = {SurfaceConfigure};
|
||||||
|
|
||||||
xdg_surface_add_listener(xdgSurface, &surfaceListener, nullptr);
|
xdg_surface_add_listener(xdgSurface, &surfaceListener, nullptr);
|
||||||
|
|
||||||
|
xdgToplevel = xdg_surface_get_toplevel(xdgSurface);
|
||||||
|
|
||||||
|
static constexpr xdg_toplevel_listener topLevelListener = {
|
||||||
|
.configure = Resolution
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg_toplevel_add_listener(xdgToplevel, &topLevelListener, nullptr);
|
||||||
|
|
||||||
xdg_toplevel_set_title(xdgToplevel, title);
|
xdg_toplevel_set_title(xdgToplevel, title);
|
||||||
wl_surface_commit(surface);
|
xdg_toplevel_set_app_id(xdgToplevel, "dsadasfsaAS");
|
||||||
|
|
||||||
|
dec = zxdg_decoration_manager_v1_get_toplevel_decoration(decManager, xdgToplevel);
|
||||||
|
zxdg_toplevel_decoration_v1_set_mode(dec, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
||||||
|
|
||||||
|
wl_surface_attach(wlSurface, buffer, 0, 0);
|
||||||
|
wl_surface_commit(wlSurface);
|
||||||
|
|
||||||
|
wl_display_roundtrip(display);
|
||||||
|
|
||||||
|
OnCreated();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::OnCreated()
|
void Window::OnCreated()
|
||||||
@ -128,8 +314,8 @@ namespace ehs
|
|||||||
xdg_wm_base_destroy(xdgShell);
|
xdg_wm_base_destroy(xdgShell);
|
||||||
xdgShell = nullptr;
|
xdgShell = nullptr;
|
||||||
|
|
||||||
wl_surface_destroy(surface);
|
wl_surface_destroy(wlSurface);
|
||||||
surface = nullptr;
|
wlSurface = nullptr;
|
||||||
|
|
||||||
wl_compositor_destroy(compositor);
|
wl_compositor_destroy(compositor);
|
||||||
compositor = nullptr;
|
compositor = nullptr;
|
||||||
|
Loading…
Reference in New Issue
Block a user