more stuffs

This commit is contained in:
Mars 2025-04-24 23:17:11 -04:00
parent 801a8d1754
commit 55819ebfe0
Signed by: pupbrained
GPG key ID: 0FF5B8826803F895
10 changed files with 410 additions and 237 deletions

View file

@ -7,35 +7,36 @@
#include "src/util/macros.h"
namespace os::linux {
DisplayGuard::DisplayGuard(const CStr name) : m_Display(XOpenDisplay(name)) {}
XorgDisplayGuard::XorgDisplayGuard(const CStr name) : m_Connection(xcb_connect(name, nullptr)) {}
DisplayGuard::~DisplayGuard() {
if (m_Display)
XCloseDisplay(m_Display);
XorgDisplayGuard::~XorgDisplayGuard() {
if (m_Connection)
xcb_disconnect(m_Connection);
}
DisplayGuard::DisplayGuard(DisplayGuard&& other) noexcept : m_Display(std::exchange(other.m_Display, nullptr)) {}
XorgDisplayGuard::XorgDisplayGuard(XorgDisplayGuard&& other) noexcept
: m_Connection(std::exchange(other.m_Connection, nullptr)) {}
fn DisplayGuard::operator=(DisplayGuard&& other) noexcept -> DisplayGuard& {
fn XorgDisplayGuard::operator=(XorgDisplayGuard&& other) noexcept -> XorgDisplayGuard& {
if (this != &other) {
if (m_Display)
XCloseDisplay(m_Display);
m_Display = std::exchange(other.m_Display, nullptr);
if (m_Connection)
xcb_disconnect(m_Connection);
m_Connection = std::exchange(other.m_Connection, nullptr);
}
return *this;
}
DisplayGuard::operator bool() const { return m_Display != nullptr; }
XorgDisplayGuard::operator bool() const { return m_Connection && !xcb_connection_has_error(m_Connection); }
fn DisplayGuard::get() const -> Display* { return m_Display; }
fn XorgDisplayGuard::get() const -> xcb_connection_t* { return m_Connection; }
fn DisplayGuard::defaultRootWindow() const -> Window {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
return DefaultRootWindow(m_Display);
#pragma clang diagnostic pop
fn XorgDisplayGuard::setup() const -> const xcb_setup_t* {
return m_Connection ? xcb_get_setup(m_Connection) : nullptr;
}
fn XorgDisplayGuard::rootScreen() const -> xcb_screen_t* {
const xcb_setup_t* setup = this->setup();
return setup ? xcb_setup_roots_iterator(setup).data : nullptr;
}
WaylandDisplayGuard::WaylandDisplayGuard() : m_Display(wl_display_connect(nullptr)) {}

View file

@ -2,8 +2,8 @@
#ifdef __linux__
#include <X11/Xlib.h>
#include <wayland-client.h>
#include <xcb/xcb.h>
#include "src/util/macros.h"
@ -12,28 +12,70 @@ namespace os::linux {
* RAII wrapper for X11 Display connections
* Automatically handles resource acquisition and cleanup
*/
class DisplayGuard {
Display* m_Display;
class XorgDisplayGuard {
xcb_connection_t* m_Connection = nullptr;
public:
/**
* Opens an X11 display connection
* Opens an XCB connection
* @param name Display name (nullptr for default)
*/
explicit DisplayGuard(CStr name = nullptr);
~DisplayGuard();
explicit XorgDisplayGuard(CStr name = nullptr);
~XorgDisplayGuard();
// Non-copyable
DisplayGuard(const DisplayGuard&) = delete;
fn operator=(const DisplayGuard&)->DisplayGuard& = delete;
XorgDisplayGuard(const XorgDisplayGuard&) = delete;
fn operator=(const XorgDisplayGuard&)->XorgDisplayGuard& = delete;
// Movable
DisplayGuard(DisplayGuard&& other) noexcept;
fn operator=(DisplayGuard&& other) noexcept -> DisplayGuard&;
XorgDisplayGuard(XorgDisplayGuard&& other) noexcept;
fn operator=(XorgDisplayGuard&& other) noexcept -> XorgDisplayGuard&;
[[nodiscard]] explicit operator bool() const;
[[nodiscard]] fn get() const -> Display*;
[[nodiscard]] fn defaultRootWindow() const -> Window;
[[nodiscard]] fn get() const -> xcb_connection_t*;
[[nodiscard]] fn setup() const -> const xcb_setup_t*;
[[nodiscard]] fn rootScreen() const -> xcb_screen_t*;
};
/**
* RAII wrapper for XCB replies
* Handles automatic cleanup of various XCB reply objects
*/
template <typename T>
class XcbReplyGuard {
T* m_Reply = nullptr;
public:
XcbReplyGuard() = default;
explicit XcbReplyGuard(T* reply) : m_Reply(reply) {}
~XcbReplyGuard() {
if (m_Reply)
free(m_Reply);
}
// Non-copyable
XcbReplyGuard(const XcbReplyGuard&) = delete;
fn operator=(const XcbReplyGuard&)->XcbReplyGuard& = delete;
// Movable
XcbReplyGuard(XcbReplyGuard&& other) noexcept : m_Reply(std::exchange(other.m_Reply, nullptr)) {}
fn operator=(XcbReplyGuard&& other) noexcept -> XcbReplyGuard& {
if (this != &other) {
if (m_Reply)
free(m_Reply);
m_Reply = std::exchange(other.m_Reply, nullptr);
}
return *this;
}
[[nodiscard]] explicit operator bool() const { return m_Reply != nullptr; }
[[nodiscard]] fn get() const -> T* { return m_Reply; }
[[nodiscard]] fn operator->() const->T* { return m_Reply; }
[[nodiscard]] fn operator*() const->T& { return *m_Reply; }
};
/**
@ -59,8 +101,9 @@ namespace os::linux {
fn operator=(WaylandDisplayGuard&& other) noexcept -> WaylandDisplayGuard&;
[[nodiscard]] explicit operator bool() const;
[[nodiscard]] fn get() const -> wl_display*;
[[nodiscard]] fn fd() const -> i32;
[[nodiscard]] fn get() const -> wl_display*;
[[nodiscard]] fn fd() const -> i32;
};
}