#include "ehs/io/Window_Way.h" #include #include #include "ehs/io/Console.h" #include "ehs/io/xdg-shell-client-protocol.h" namespace ehs { void Window::SurfaceConfigEvent(void* data, xdg_surface* xdg_surface, UInt_32 serial) { xdg_surface_ack_configure(xdg_surface, serial); Window* win = (Window *)data; wl_surface_commit(win->wlSurface); } 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) { Window *win = (Window *)data; if (Str_8::Cmp(interface, wl_compositor_interface.name)) win->compositor = (wl_compositor*)wl_registry_bind(registry, id, &wl_compositor_interface, 1); else if (Str_8::Cmp(interface, xdg_wm_base_interface.name)) win->xdgShell = (xdg_wm_base*)wl_registry_bind(registry, id, &xdg_wm_base_interface, 1); else if (Str_8::Cmp(interface, zxdg_decoration_manager_v1_interface.name)) win->decManager = (zxdg_decoration_manager_v1*)wl_registry_bind(registry, id, &zxdg_decoration_manager_v1_interface, 1); else if (Str_8::Cmp(interface, wl_seat_interface.name)) win->seat = (wl_seat *)wl_registry_bind(registry, id, &wl_seat_interface, 1); } void Window::RegistryRemoved(void* data, wl_registry* registry, UInt_32 id) { } void Window::ResizeEvent(void *data, struct xdg_toplevel *xdg_toplevel, Int_32 width, Int_32 height, wl_array *states) { if (!width && !height) return; Window *win = (Window *)data; win->scale = {(UInt_32)width, (UInt_32)height}; } void Window::CloseEvent(void *data, xdg_toplevel *xdg_toplevel) { Window *win = (Window *)data; win->Close(); } void Window::SeatCapabilitiesEvent(void *data, wl_seat *seat, UInt_32 capabilities) { Window *win = (Window *)data; if (capabilities & WL_SEAT_CAPABILITY_POINTER) { win->pointer = wl_seat_get_pointer(seat); static const wl_pointer_listener pointer_listener = { .motion = PointerMotionEvent }; wl_pointer_add_listener(win->pointer, &pointer_listener, win); } } void Window::PointerMotionEvent(void *data, wl_pointer *pointer, UInt_32 time, wl_fixed_t sx, wl_fixed_t sy) { EHS_LOG_INT(LogType::INFO, 0, "Pointer Pos: <" + Str_8::FromNum(wl_fixed_to_double(sx)) + ", " + Str_8::FromNum(wl_fixed_to_double(sy)) + ">"); } Window::~Window() { if (!created) return; zxdg_toplevel_decoration_v1_destroy(dec); zxdg_decoration_manager_v1_destroy(decManager); xdg_toplevel_destroy(xdgToplevel); xdg_surface_destroy(xdgSurface); xdg_wm_base_destroy(xdgShell); wl_surface_destroy(wlSurface); wl_compositor_destroy(compositor); wl_registry_destroy(registry); wl_display_disconnect(display); } Window::Window() : display(nullptr), registry(nullptr), compositor(nullptr), wlSurface(nullptr), xdgShell(nullptr), xdgSurface(nullptr), xdgToplevel(nullptr), decManager(nullptr), dec(nullptr), seat(nullptr), pointer(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), decManager(win.decManager), dec(win.dec), seat(win.seat), pointer(win.pointer) { win.display = nullptr; win.registry = nullptr; win.compositor = nullptr; win.wlSurface = nullptr; win.xdgShell = nullptr; win.xdgSurface = nullptr; win.xdgToplevel = nullptr; win.decManager = nullptr; win.dec = nullptr; win.seat = nullptr; win.pointer = nullptr; } Window::Window(const Window &win) : BaseWindow(win), display(nullptr), registry(nullptr), compositor(nullptr), wlSurface(nullptr), xdgShell(nullptr), xdgSurface(nullptr), xdgToplevel(nullptr), decManager(nullptr), dec(nullptr), seat(nullptr), pointer(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; decManager = win.decManager; dec = win.dec; seat = win.seat; pointer = win.pointer; win.display = nullptr; win.registry = nullptr; win.compositor = nullptr; win.wlSurface = nullptr; win.xdgShell = nullptr; win.xdgSurface = nullptr; win.xdgToplevel = nullptr; win.decManager = nullptr; win.dec = nullptr; win.seat = nullptr; win.pointer = 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; decManager = nullptr; dec = nullptr; seat = nullptr; pointer = nullptr; return *this; } 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) { if (created) return; display = wl_display_connect(nullptr); if (!display) { EHS_LOG_INT(LogType::ERR, 0, "Failed to connect to display server."); return; } static constexpr wl_registry_listener registry_listener = { .global = RegistryHandler, .global_remove = RegistryRemoved }; registry = wl_display_get_registry(display); wl_registry_add_listener(registry, ®istry_listener, this); wl_display_dispatch(display); wl_display_roundtrip(display); if (!compositor || !xdgShell) { EHS_LOG_INT(LogType::ERR, 1, "Can't find required interfaces."); return; } static constexpr xdg_wm_base_listener xdg_shell_listener = { .ping = ShellPing }; xdg_wm_base_add_listener(xdgShell, &xdg_shell_listener, nullptr); wlSurface = wl_compositor_create_surface(compositor); if (!wlSurface) { EHS_LOG_INT(LogType::ERR, 2, "Can't create surface."); return; } xdgSurface = xdg_wm_base_get_xdg_surface(xdgShell, wlSurface); static constexpr xdg_surface_listener surfaceListener = { .configure = SurfaceConfigEvent }; xdg_surface_add_listener(xdgSurface, &surfaceListener, this); xdgToplevel = xdg_surface_get_toplevel(xdgSurface); static constexpr xdg_toplevel_listener topLevelListener = { .configure = ResizeEvent, .close = CloseEvent }; xdg_toplevel_add_listener(xdgToplevel, &topLevelListener, this); xdg_toplevel_set_title(xdgToplevel, title); xdg_toplevel_set_app_id(xdgToplevel, title); dec = zxdg_decoration_manager_v1_get_toplevel_decoration(decManager, xdgToplevel); zxdg_toplevel_decoration_v1_set_mode(dec, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); static constexpr wl_seat_listener seat_listener = { .capabilities = SeatCapabilitiesEvent }; wl_seat_add_listener(seat, &seat_listener, this); wl_display_roundtrip(display); wl_surface_commit(wlSurface); wl_display_roundtrip(display); this->scale = scale; created = true; OnCreated(); } void Window::OnCreated() { } void Window::Close() { if (!created) return; zxdg_toplevel_decoration_v1_destroy(dec); dec = nullptr; zxdg_decoration_manager_v1_destroy(decManager); decManager = nullptr; xdg_toplevel_destroy(xdgToplevel); xdgToplevel = nullptr; xdg_surface_destroy(xdgSurface); xdgSurface = nullptr; xdg_wm_base_destroy(xdgShell); xdgShell = nullptr; wl_surface_destroy(wlSurface); wlSurface = nullptr; wl_compositor_destroy(compositor); compositor = nullptr; wl_registry_destroy(registry); registry = nullptr; wl_display_disconnect(display); display = nullptr; created = false; } void Window::Show() { } void Window::Hide() { } bool Window::Poll() { if (wl_display_dispatch_pending(display) == -1) return false; if (!created) return false; 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 scale; } Serializer Window::GetClipboard() { return {}; } void Window::SetClipboard(Serializer data) { } void Window::SetCursorImg(const CursorImg img) { } }