Add basic Window creation to X11WindowDriver

This commit is contained in:
2025-04-05 07:07:54 +10:00
parent 5e7c94ba8f
commit 286dd0fb0e
5 changed files with 133 additions and 2 deletions

View File

@@ -51,6 +51,7 @@ set(ENGINE_INCLUDES_PUBLIC
)
set(ENGINE_LIBS_PRIVATE
$<$<BOOL:${NOVA_VULKAN}>:Vulkan::Vulkan>
$<$<BOOL:${NOVA_X11}>:X11>
)
set(ENGINE_LIBS_PUBLIC
spdlog::spdlog

View File

@@ -7,12 +7,29 @@
#pragma once
#include <nova/api.h>
#include <nova/render/render_driver.h>
#include <nova/types.h>
#include <string_view>
namespace Nova {
using WindowID = uptr;
class NOVA_API WindowDriver {
public:
virtual ~WindowDriver() = default;
virtual void poll_events() = 0;
virtual WindowID create_window(std::string_view title = "Nova", u32 width = 800, u32 height = 600) = 0;
virtual void destroy_window(WindowID window) = 0;
virtual void set_window_title(WindowID window, std::string_view title) = 0;
virtual void set_window_size(WindowID window, u32 width, u32 height) = 0;
virtual void set_window_position(WindowID window, i32 x, i32 y) = 0;
[[nodiscard]] virtual u32 get_window_count() const = 0;
[[nodiscard]] virtual const char* get_surface_extension() const = 0;
};
} // namespace Nova

View File

@@ -13,14 +13,17 @@ using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using usize = size_t;
using uptr = uintptr_t;
using umax = uintmax_t;
using i8 = int8_t;
using i16 = int16_t;
using i32 = int32_t;
using i64 = int64_t;
using usize = size_t;
using isize = ptrdiff_t;
using iptr = intptr_t;
using imax = intmax_t;
using f32 = float;
using f64 = double;

View File

@@ -19,10 +19,97 @@ using namespace Nova;
X11WindowDriver::X11WindowDriver() {
NOVA_AUTO_TRACE();
m_display = XOpenDisplay(nullptr);
if (!m_display) {
throw std::runtime_error("Failed to connect to X server");
}
m_window_close_atom = XInternAtom(m_display, "WM_DELETE_WINDOW", False);
}
X11WindowDriver::~X11WindowDriver() {
NOVA_AUTO_TRACE();
for (const auto& [id, _] : m_windows) {
XDestroyWindow(m_display, id);
}
if (m_display) {
XCloseDisplay(m_display);
m_display = nullptr;
}
}
void X11WindowDriver::poll_events() {
NOVA_AUTO_TRACE();
XEvent event;
XNextEvent(m_display, &event);
WindowID id = event.xany.window;
NOVA_ASSERT(m_windows.contains(id));
switch (event.type) {
case Expose:
break;
case ClientMessage: {
if (event.xclient.data.l[0] == static_cast<long>(m_window_close_atom)) {
destroy_window(id);
}
break;
}
default:
NOVA_WARN("Unhandled X11 event: {}", event.type);
break;
}
}
WindowID X11WindowDriver::create_window(std::string_view title, u32 width, u32 height) {
NOVA_AUTO_TRACE();
WindowID window = XCreateSimpleWindow(m_display, DefaultRootWindow(m_display), 0, 0, width, height, 0, 0, 0);
WindowData& data = m_windows[window];
(void)data; // TODO: Initialize window data
XSetWMProtocols(m_display, window, &m_window_close_atom, 1);
XSelectInput(m_display, window, ExposureMask);
XStoreName(m_display, window, title.data());
XMapWindow(m_display, window);
XFlush(m_display);
return window;
}
void X11WindowDriver::destroy_window(WindowID id) {
NOVA_AUTO_TRACE();
if (!m_windows.contains(id)) {
return;
}
XDestroyWindow(m_display, id);
m_windows.erase(id);
}
void X11WindowDriver::set_window_title(WindowID id, std::string_view title) {
NOVA_AUTO_TRACE();
NOVA_ASSERT(m_windows.contains(id));
XStoreName(m_display, id, title.data());
}
void X11WindowDriver::set_window_size(WindowID id, u32 width, u32 height) {
NOVA_AUTO_TRACE();
NOVA_ASSERT(m_windows.contains(id));
XResizeWindow(m_display, id, width, height);
}
void X11WindowDriver::set_window_position(WindowID id, i32 x, i32 y) {
NOVA_AUTO_TRACE();
NOVA_ASSERT(m_windows.contains(id));
XMoveWindow(m_display, id, x, y);
}
u32 X11WindowDriver::get_window_count() const {
return m_windows.size();
}
const char* X11WindowDriver::get_surface_extension() const {

View File

@@ -11,13 +11,36 @@
#include <X11/Xlib.h>
#include <nova/platform/window_driver.h>
#include <unordered_map>
namespace Nova {
struct WindowData {
// TODO: Add stuff here
};
class X11WindowDriver final : public WindowDriver {
public:
X11WindowDriver();
~X11WindowDriver() override;
void poll_events() override;
WindowID create_window(std::string_view title, u32 width, u32 height) override;
void destroy_window(WindowID window) override;
void set_window_title(WindowID window, std::string_view title) override;
void set_window_size(WindowID window, u32 width, u32 height) override;
void set_window_position(WindowID window, i32 x, i32 y) override;
[[nodiscard]] u32 get_window_count() const override;
[[nodiscard]] const char* get_surface_extension() const override;
private:
Display* m_display = nullptr;
std::unordered_map<WindowID, WindowData> m_windows;
Atom m_window_close_atom = 0;
};
} // namespace Nova