Add basic Window creation to X11WindowDriver
This commit is contained in:
@@ -51,6 +51,7 @@ set(ENGINE_INCLUDES_PUBLIC
|
|||||||
)
|
)
|
||||||
set(ENGINE_LIBS_PRIVATE
|
set(ENGINE_LIBS_PRIVATE
|
||||||
$<$<BOOL:${NOVA_VULKAN}>:Vulkan::Vulkan>
|
$<$<BOOL:${NOVA_VULKAN}>:Vulkan::Vulkan>
|
||||||
|
$<$<BOOL:${NOVA_X11}>:X11>
|
||||||
)
|
)
|
||||||
set(ENGINE_LIBS_PUBLIC
|
set(ENGINE_LIBS_PUBLIC
|
||||||
spdlog::spdlog
|
spdlog::spdlog
|
||||||
|
|||||||
@@ -7,12 +7,29 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <nova/api.h>
|
#include <nova/api.h>
|
||||||
|
#include <nova/render/render_driver.h>
|
||||||
|
#include <nova/types.h>
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
namespace Nova {
|
namespace Nova {
|
||||||
|
using WindowID = uptr;
|
||||||
|
|
||||||
class NOVA_API WindowDriver {
|
class NOVA_API WindowDriver {
|
||||||
public:
|
public:
|
||||||
virtual ~WindowDriver() = default;
|
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;
|
[[nodiscard]] virtual const char* get_surface_extension() const = 0;
|
||||||
};
|
};
|
||||||
} // namespace Nova
|
} // namespace Nova
|
||||||
|
|||||||
@@ -13,14 +13,17 @@ using u8 = uint8_t;
|
|||||||
using u16 = uint16_t;
|
using u16 = uint16_t;
|
||||||
using u32 = uint32_t;
|
using u32 = uint32_t;
|
||||||
using u64 = uint64_t;
|
using u64 = uint64_t;
|
||||||
|
using usize = size_t;
|
||||||
|
using uptr = uintptr_t;
|
||||||
|
using umax = uintmax_t;
|
||||||
|
|
||||||
using i8 = int8_t;
|
using i8 = int8_t;
|
||||||
using i16 = int16_t;
|
using i16 = int16_t;
|
||||||
using i32 = int32_t;
|
using i32 = int32_t;
|
||||||
using i64 = int64_t;
|
using i64 = int64_t;
|
||||||
|
|
||||||
using usize = size_t;
|
|
||||||
using isize = ptrdiff_t;
|
using isize = ptrdiff_t;
|
||||||
|
using iptr = intptr_t;
|
||||||
|
using imax = intmax_t;
|
||||||
|
|
||||||
using f32 = float;
|
using f32 = float;
|
||||||
using f64 = double;
|
using f64 = double;
|
||||||
|
|||||||
@@ -19,10 +19,97 @@ using namespace Nova;
|
|||||||
|
|
||||||
X11WindowDriver::X11WindowDriver() {
|
X11WindowDriver::X11WindowDriver() {
|
||||||
NOVA_AUTO_TRACE();
|
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() {
|
X11WindowDriver::~X11WindowDriver() {
|
||||||
NOVA_AUTO_TRACE();
|
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 {
|
const char* X11WindowDriver::get_surface_extension() const {
|
||||||
|
|||||||
@@ -11,13 +11,36 @@
|
|||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <nova/platform/window_driver.h>
|
#include <nova/platform/window_driver.h>
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace Nova {
|
namespace Nova {
|
||||||
|
struct WindowData {
|
||||||
|
// TODO: Add stuff here
|
||||||
|
};
|
||||||
|
|
||||||
class X11WindowDriver final : public WindowDriver {
|
class X11WindowDriver final : public WindowDriver {
|
||||||
public:
|
public:
|
||||||
X11WindowDriver();
|
X11WindowDriver();
|
||||||
~X11WindowDriver() override;
|
~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;
|
[[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
|
} // namespace Nova
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user