EHS/src/io/Window_Way.cpp

418 lines
9.4 KiB
C++
Raw Normal View History

2024-02-14 00:11:47 -08:00
#include "ehs/io/Window_Way.h"
2024-02-05 22:25:30 -08:00
2024-07-03 19:49:18 -07:00
#include <unistd.h>
#include <sys/mman.h>
#include "ehs/io/Console.h"
#include "ehs/io/xdg-shell-client-protocol.h"
2024-02-05 22:25:30 -08:00
namespace ehs
{
2024-07-03 19:49:18 -07:00
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);
}
2024-02-05 22:25:30 -08:00
void Window::SurfaceConfigure(void* data, xdg_surface* xdg_surface, UInt_32 serial)
{
xdg_surface_ack_configure(xdg_surface, serial);
}
void Window::ShellPing(void* data, xdg_wm_base* shell, UInt_32 serial)
{
xdg_wm_base_pong(shell, serial);
}
void Window::RegistryHandler(void* data, wl_registry* registry, UInt_32 id, const char* interface, UInt_32 version)
{
Serializer<UInt_64>* ser = (Serializer<UInt_64>*)data;
2024-07-03 19:49:18 -07:00
if (Str_8::Cmp(interface, wl_compositor_interface.name))
2024-02-05 22:25:30 -08:00
{
ser->SetOffset(0);
wl_compositor** comp = ser->Read<wl_compositor**>();
*comp = (wl_compositor*)wl_registry_bind(registry, id, &wl_compositor_interface, 1);
}
2024-07-03 19:49:18 -07:00
else if (Str_8::Cmp(interface, xdg_wm_base_interface.name))
2024-02-05 22:25:30 -08:00
{
ser->SetOffset(sizeof(void*));
xdg_wm_base** base = ser->Read<xdg_wm_base**>();
*base = (xdg_wm_base*)wl_registry_bind(registry, id, &xdg_wm_base_interface, 1);
}
2024-07-03 19:49:18 -07:00
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);
}
2024-02-05 22:25:30 -08:00
}
void Window::RegistryRemoved(void* data, wl_registry* registry, UInt_32 id)
{
}
2024-07-03 19:49:18 -07:00
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));
}
2024-02-05 22:25:30 -08:00
Window::~Window()
{
zxdg_toplevel_decoration_v1_destroy(dec);
zxdg_decoration_manager_v1_destroy(decManager);
wl_buffer_destroy(buffer);
wl_shm_destroy(shm);
2024-02-05 22:25:30 -08:00
xdg_toplevel_destroy(xdgToplevel);
xdg_surface_destroy(xdgSurface);
xdg_wm_base_destroy(xdgShell);
2024-07-03 19:49:18 -07:00
wl_surface_destroy(wlSurface);
2024-02-05 22:25:30 -08:00
wl_compositor_destroy(compositor);
wl_registry_destroy(registry);
wl_display_disconnect(display);
}
Window::Window()
2024-07-03 19:49:18 -07:00
: 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)
2024-02-05 22:25:30 -08:00
{
}
2024-07-03 19:49:18 -07:00
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;
}
2024-02-05 22:25:30 -08:00
void Window::Create_32(const Str_32& title, const Vec2_s32& pos, const Vec2_u32 scale)
{
Create_8(UTF::To_8(title), pos, scale);
}
void Window::Create_16(const Str_16& title, const Vec2_s32& pos, const Vec2_u32 scale)
{
Create_8(UTF::To_8(title), pos, scale);
}
void Window::Create_8(const Str_8& title, const Vec2_s32& pos, const Vec2_u32 scale)
{
display = wl_display_connect(nullptr);
if (!display)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to connect to display server.");
2024-02-05 22:25:30 -08:00
return;
}
Serializer<UInt_64> data(Endianness::LE);
data.Write(&compositor);
data.Write(&xdgShell);
2024-07-03 19:49:18 -07:00
data.Write(&shm);
data.Write(&decManager);
2024-02-05 22:25:30 -08:00
static constexpr wl_registry_listener registry_listener = {
RegistryHandler,
RegistryRemoved
};
registry = wl_display_get_registry(display);
wl_registry_add_listener(registry, &registry_listener, &data);
wl_display_dispatch(display);
wl_display_roundtrip(display);
if (!compositor || !xdgShell)
{
EHS_LOG_INT(LogType::ERR, 1, "Can't find required interfaces.");
2024-02-05 22:25:30 -08:00
return;
}
static constexpr xdg_wm_base_listener xdg_shell_listener = {ShellPing};
xdg_wm_base_add_listener(xdgShell, &xdg_shell_listener, nullptr);
2024-07-03 19:49:18 -07:00
wlSurface = wl_compositor_create_surface(compositor);
if (!wlSurface)
2024-02-05 22:25:30 -08:00
{
EHS_LOG_INT(LogType::ERR, 2, "Can't create surface.");
2024-02-05 22:25:30 -08:00
return;
}
2024-07-03 19:49:18 -07:00
CreateBuffer(scale);
xdgSurface = xdg_wm_base_get_xdg_surface(xdgShell, wlSurface);
2024-02-05 22:25:30 -08:00
static constexpr xdg_surface_listener surfaceListener = {SurfaceConfigure};
xdg_surface_add_listener(xdgSurface, &surfaceListener, nullptr);
2024-07-03 19:49:18 -07:00
xdgToplevel = xdg_surface_get_toplevel(xdgSurface);
static constexpr xdg_toplevel_listener topLevelListener = {
.configure = Resolution
};
xdg_toplevel_add_listener(xdgToplevel, &topLevelListener, nullptr);
2024-02-05 22:25:30 -08:00
xdg_toplevel_set_title(xdgToplevel, title);
2024-07-03 19:49:18 -07:00
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_display_roundtrip(display);
2024-07-03 19:49:18 -07:00
wl_surface_commit(wlSurface);
wl_display_roundtrip(display);
OnCreated();
2024-02-05 22:25:30 -08:00
}
void Window::OnCreated()
{
}
void Window::Close()
{
xdg_toplevel_destroy(xdgToplevel);
xdgToplevel = nullptr;
xdg_surface_destroy(xdgSurface);
xdgSurface = nullptr;
xdg_wm_base_destroy(xdgShell);
xdgShell = nullptr;
2024-07-03 19:49:18 -07:00
wl_surface_destroy(wlSurface);
wlSurface = nullptr;
2024-02-05 22:25:30 -08:00
wl_compositor_destroy(compositor);
compositor = nullptr;
wl_registry_destroy(registry);
registry = nullptr;
wl_display_disconnect(display);
display = nullptr;
}
void Window::Show()
{
}
void Window::Hide()
{
}
bool Window::Poll()
{
wl_display_dispatch(display);
return true;
}
void Window::ShowCursor(bool toggle)
{
}
void Window::ConstrainCursor(const bool constrain)
{
}
void Window::SetTitle_32(const Str_32& newTitle)
{
}
Str_32 Window::GetTitle_32() const
{
return {};
}
void Window::SetTitle_16(const Str_16& newTitle)
{
}
Str_16 Window::GetTitle_16() const
{
return {};
}
void Window::SetTitle_8(const Str_8& newTitle)
{
}
Str_8 Window::GetTitle_8() const
{
return {};
}
void Window::SetPos(const Vec2_s32& newPos)
{
}
Vec2_s32 Window::GetPos() const
{
return {};
}
void Window::SetScale(const Vec2_u32& newScale)
{
}
Vec2_u32 Window::GetScale() const
{
return {};
}
Serializer<UInt_64> Window::GetClipboard()
{
return {};
}
void Window::SetClipboard(Serializer<UInt_64> data)
{
}
void Window::SetCursorImg(const CursorImg img)
{
}
}