Add basic Window creation to X11WindowDriver
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user