meow
This commit is contained in:
parent
009556cabf
commit
3d1d344ec1
14 changed files with 383 additions and 196 deletions
|
@ -23,16 +23,22 @@ ContinuationIndentWidth: 2
|
||||||
Cpp11BracedListStyle: false
|
Cpp11BracedListStyle: false
|
||||||
IncludeBlocks: Regroup
|
IncludeBlocks: Regroup
|
||||||
IncludeCategories:
|
IncludeCategories:
|
||||||
# 1. System headers (<iostream>, <vector>, etc.)
|
|
||||||
- Regex: '^<.*>$'
|
- Regex: '^<.*>$'
|
||||||
Priority: 1
|
Priority: 1
|
||||||
# 2. Project headers starting with "src/"
|
- Regex: '^"Config/.*"'
|
||||||
- Regex: '^"src/.*"'
|
|
||||||
Priority: 2
|
Priority: 2
|
||||||
# 3. All other quoted headers (including same-directory like "system_data.h")
|
- Regex: '^"Core/.*"'
|
||||||
# This acts as a fallback for quoted includes not matching the above.
|
|
||||||
- Regex: '^".*"'
|
|
||||||
Priority: 3
|
Priority: 3
|
||||||
|
- Regex: '^"Services/.*"'
|
||||||
|
Priority: 4
|
||||||
|
- Regex: '^"UI/.*"'
|
||||||
|
Priority: 5
|
||||||
|
- Regex: '^"Util/.*"'
|
||||||
|
Priority: 6
|
||||||
|
- Regex: '^"Wrappers/.*"'
|
||||||
|
Priority: 7
|
||||||
|
- Regex: '^".*"$'
|
||||||
|
Priority: 8
|
||||||
IndentExternBlock: Indent
|
IndentExternBlock: Indent
|
||||||
IndentPPDirectives: BeforeHash
|
IndentPPDirectives: BeforeHash
|
||||||
NamespaceIndentation: All
|
NamespaceIndentation: All
|
||||||
|
|
|
@ -1005,9 +1005,7 @@ namespace argparse {
|
||||||
*/
|
*/
|
||||||
template <class F, class... Args>
|
template <class F, class... Args>
|
||||||
fn action(F&& callable, Args&&... bound_args)
|
fn action(F&& callable, Args&&... bound_args)
|
||||||
-> Argument&
|
-> Argument& requires(std::is_invocable_v<F, Args..., const String>) {
|
||||||
requires(std::is_invocable_v<F, Args..., const String>)
|
|
||||||
{
|
|
||||||
using RawReturnType = std::invoke_result_t<F, Args..., const String>;
|
using RawReturnType = std::invoke_result_t<F, Args..., const String>;
|
||||||
|
|
||||||
if constexpr (std::is_void_v<RawReturnType>) {
|
if constexpr (std::is_void_v<RawReturnType>) {
|
||||||
|
@ -1055,7 +1053,7 @@ namespace argparse {
|
||||||
* @details If no default or implicit value is set, configures the argument as a flag
|
* @details If no default or implicit value is set, configures the argument as a flag
|
||||||
*/
|
*/
|
||||||
fn store_into(bool& var)
|
fn store_into(bool& var)
|
||||||
-> Argument& {
|
->Argument& {
|
||||||
if ((!m_default_value.has_value()) && (!m_implicit_value.has_value()))
|
if ((!m_default_value.has_value()) && (!m_implicit_value.has_value()))
|
||||||
flag();
|
flag();
|
||||||
|
|
||||||
|
@ -1077,9 +1075,7 @@ namespace argparse {
|
||||||
* @return Reference to this argument for method chaining
|
* @return Reference to this argument for method chaining
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
fn store_into(T& var) -> Argument&
|
fn store_into(T& var) -> Argument& requires(std::is_integral_v<T>) {
|
||||||
requires(std::is_integral_v<T>)
|
|
||||||
{
|
|
||||||
if (m_default_value.has_value())
|
if (m_default_value.has_value())
|
||||||
var = std::get<T>(m_default_value.value());
|
var = std::get<T>(m_default_value.value());
|
||||||
|
|
||||||
|
@ -1103,9 +1099,7 @@ namespace argparse {
|
||||||
* @return Reference to this argument for method chaining
|
* @return Reference to this argument for method chaining
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
fn store_into(T& var) -> Argument&
|
fn store_into(T& var)->Argument& requires(std::is_floating_point_v<T>) {
|
||||||
requires(std::is_floating_point_v<T>)
|
|
||||||
{
|
|
||||||
if (m_default_value.has_value())
|
if (m_default_value.has_value())
|
||||||
var = std::get<T>(m_default_value.value());
|
var = std::get<T>(m_default_value.value());
|
||||||
|
|
||||||
|
@ -1128,7 +1122,7 @@ namespace argparse {
|
||||||
* @return Reference to this argument for method chaining
|
* @return Reference to this argument for method chaining
|
||||||
*/
|
*/
|
||||||
fn store_into(String& var)
|
fn store_into(String& var)
|
||||||
-> Argument& {
|
->Argument& {
|
||||||
if (m_default_value.has_value())
|
if (m_default_value.has_value())
|
||||||
var = std::get<String>(m_default_value.value());
|
var = std::get<String>(m_default_value.value());
|
||||||
|
|
||||||
|
@ -1291,9 +1285,7 @@ namespace argparse {
|
||||||
* - 'g'/'G': General format
|
* - 'g'/'G': General format
|
||||||
*/
|
*/
|
||||||
template <char Shape, typename T>
|
template <char Shape, typename T>
|
||||||
fn scan() -> Argument&
|
fn scan() -> Argument& requires(std::is_arithmetic_v<T>) {
|
||||||
requires(std::is_arithmetic_v<T>)
|
|
||||||
{
|
|
||||||
static_assert(!(std::is_const_v<T> || std::is_volatile_v<T>), "T should not be cv-qualified");
|
static_assert(!(std::is_const_v<T> || std::is_volatile_v<T>), "T should not be cv-qualified");
|
||||||
|
|
||||||
fn is_one_of = [](char c, auto... x) constexpr {
|
fn is_one_of = [](char c, auto... x) constexpr {
|
||||||
|
@ -1382,7 +1374,7 @@ namespace argparse {
|
||||||
* @return Reference to this argument for method chaining
|
* @return Reference to this argument for method chaining
|
||||||
*/
|
*/
|
||||||
fn nargs(const usize num_args)
|
fn nargs(const usize num_args)
|
||||||
-> Argument& {
|
->Argument& {
|
||||||
m_num_args_range = NArgsRange { num_args, num_args };
|
m_num_args_range = NArgsRange { num_args, num_args };
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -1574,8 +1566,7 @@ namespace argparse {
|
||||||
if (m_implicit_value.has_value())
|
if (m_implicit_value.has_value())
|
||||||
m_values.emplace_back(*m_implicit_value);
|
m_values.emplace_back(*m_implicit_value);
|
||||||
|
|
||||||
for (usize i = 0; i < m_actions.size(); ++i) {
|
for (auto& action : m_actions) {
|
||||||
auto& action = m_actions[i];
|
|
||||||
Result<> action_call_result;
|
Result<> action_call_result;
|
||||||
std::visit([&](auto& f) {
|
std::visit([&](auto& f) {
|
||||||
if constexpr (std::is_same_v<decltype(f({})), Result<ArgValue>>) {
|
if constexpr (std::is_same_v<decltype(f({})), Result<ArgValue>>) {
|
||||||
|
@ -1658,8 +1649,7 @@ namespace argparse {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!dry_run) {
|
if (!dry_run) {
|
||||||
for (usize i = 0; i < m_actions.size(); ++i) {
|
for (auto& action : m_actions) {
|
||||||
auto& action = m_actions[i];
|
|
||||||
Result<> apply_result = std::visit(ActionApply { start, end, *this }, action);
|
Result<> apply_result = std::visit(ActionApply { start, end, *this }, action);
|
||||||
if (!apply_result)
|
if (!apply_result)
|
||||||
return Err(apply_result.error());
|
return Err(apply_result.error());
|
||||||
|
@ -2117,7 +2107,7 @@ namespace argparse {
|
||||||
};
|
};
|
||||||
|
|
||||||
fn consume_digits = [=](StringView sd) -> StringView {
|
fn consume_digits = [=](StringView sd) -> StringView {
|
||||||
const auto it = std::ranges::find_if_not(sd, is_digit);
|
const auto* const it = std::ranges::find_if_not(sd, is_digit);
|
||||||
|
|
||||||
return sd.substr(static_cast<usize>(it - std::begin(sd)));
|
return sd.substr(static_cast<usize>(it - std::begin(sd)));
|
||||||
};
|
};
|
||||||
|
|
|
@ -729,7 +729,8 @@ namespace matchit {
|
||||||
template <typename Unary, typename Pattern>
|
template <typename Unary, typename Pattern>
|
||||||
class App {
|
class App {
|
||||||
public:
|
public:
|
||||||
constexpr App(Unary&& unary, const Pattern& pattern) : mUnary { std::move(unary) }, mPattern { pattern } {}
|
constexpr App(Unary&& unary, const Pattern& pattern)
|
||||||
|
: mUnary { std::move(unary) }, mPattern { pattern } {}
|
||||||
|
|
||||||
[[nodiscard]] constexpr fn unary() const -> const Unary& {
|
[[nodiscard]] constexpr fn unary() const -> const Unary& {
|
||||||
return mUnary;
|
return mUnary;
|
||||||
|
@ -1086,7 +1087,8 @@ namespace matchit {
|
||||||
public:
|
public:
|
||||||
constexpr Id() = default;
|
constexpr Id() = default;
|
||||||
|
|
||||||
constexpr Id(const Id& id) : mBlock(BlockVT { &id.block() }) {}
|
constexpr Id(const Id& id)
|
||||||
|
: mBlock(BlockVT { &id.block() }) {}
|
||||||
|
|
||||||
// non-const to inform users not to mark Id as const.
|
// non-const to inform users not to mark Id as const.
|
||||||
template <typename Pattern>
|
template <typename Pattern>
|
||||||
|
|
|
@ -15,15 +15,17 @@
|
||||||
#include "Util/Env.hpp"
|
#include "Util/Env.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../Services/Weather/MetNoService.hpp"
|
|
||||||
#include "../Services/Weather/OpenMeteoService.hpp"
|
|
||||||
#include "../Services/Weather/OpenWeatherMapService.hpp"
|
|
||||||
#include "Services/Weather.hpp"
|
#include "Services/Weather.hpp"
|
||||||
|
|
||||||
#include "Util/Definitions.hpp"
|
#include "Util/Definitions.hpp"
|
||||||
#include "Util/Error.hpp"
|
#include "Util/Error.hpp"
|
||||||
#include "Util/Logging.hpp"
|
#include "Util/Logging.hpp"
|
||||||
#include "Util/Types.hpp"
|
#include "Util/Types.hpp"
|
||||||
|
|
||||||
|
#include "../Services/Weather/MetNoService.hpp"
|
||||||
|
#include "../Services/Weather/OpenMeteoService.hpp"
|
||||||
|
#include "../Services/Weather/OpenWeatherMapService.hpp"
|
||||||
|
|
||||||
using util::error::DracError;
|
using util::error::DracError;
|
||||||
using util::types::CStr, util::types::String, util::types::Array, util::types::Option, util::types::Result;
|
using util::types::CStr, util::types::String, util::types::Array, util::types::Option, util::types::Result;
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,16 @@
|
||||||
#include <matchit.hpp> // matchit::{match, is, in, _}
|
#include <matchit.hpp> // matchit::{match, is, in, _}
|
||||||
|
|
||||||
#include "Config/Config.hpp"
|
#include "Config/Config.hpp"
|
||||||
#include "OS/OperatingSystem.hpp"
|
|
||||||
#include "Services/PackageCounting.hpp"
|
#include "Services/PackageCounting.hpp"
|
||||||
#include "Services/Weather.hpp"
|
#include "Services/Weather.hpp"
|
||||||
|
|
||||||
#include "Util/Definitions.hpp"
|
#include "Util/Definitions.hpp"
|
||||||
#include "Util/Error.hpp"
|
#include "Util/Error.hpp"
|
||||||
#include "Util/Types.hpp"
|
#include "Util/Types.hpp"
|
||||||
|
|
||||||
|
#include "OS/OperatingSystem.hpp"
|
||||||
|
|
||||||
using util::error::DracError, util::error::DracErrorCode;
|
using util::error::DracError, util::error::DracErrorCode;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <format> // std::{formatter, format_to}
|
#include <format> // std::{formatter, format_to}
|
||||||
|
|
||||||
#include "Services/Weather.hpp"
|
#include "Services/Weather.hpp"
|
||||||
|
|
||||||
#include "Util/Definitions.hpp"
|
#include "Util/Definitions.hpp"
|
||||||
#include "Util/Error.hpp"
|
#include "Util/Error.hpp"
|
||||||
#include "Util/Types.hpp"
|
#include "Util/Types.hpp"
|
||||||
|
|
|
@ -21,12 +21,14 @@
|
||||||
#include <utility> // std::move
|
#include <utility> // std::move
|
||||||
|
|
||||||
#include "Services/PackageCounting.hpp"
|
#include "Services/PackageCounting.hpp"
|
||||||
|
|
||||||
#include "Util/Caching.hpp"
|
#include "Util/Caching.hpp"
|
||||||
#include "Util/Definitions.hpp"
|
#include "Util/Definitions.hpp"
|
||||||
#include "Util/Env.hpp"
|
#include "Util/Env.hpp"
|
||||||
#include "Util/Error.hpp"
|
#include "Util/Error.hpp"
|
||||||
#include "Util/Logging.hpp"
|
#include "Util/Logging.hpp"
|
||||||
#include "Util/Types.hpp"
|
#include "Util/Types.hpp"
|
||||||
|
|
||||||
#include "Wrappers/DBus.hpp"
|
#include "Wrappers/DBus.hpp"
|
||||||
#include "Wrappers/Wayland.hpp"
|
#include "Wrappers/Wayland.hpp"
|
||||||
#include "Wrappers/XCB.hpp"
|
#include "Wrappers/XCB.hpp"
|
||||||
|
@ -40,7 +42,7 @@ using util::types::String, util::types::Result, util::types::Err, util::types::u
|
||||||
namespace {
|
namespace {
|
||||||
#ifdef HAVE_XCB
|
#ifdef HAVE_XCB
|
||||||
fn GetX11WindowManager() -> Result<String> {
|
fn GetX11WindowManager() -> Result<String> {
|
||||||
using namespace xcb;
|
using namespace XCB;
|
||||||
using namespace matchit;
|
using namespace matchit;
|
||||||
using enum ConnError;
|
using enum ConnError;
|
||||||
using util::types::StringView;
|
using util::types::StringView;
|
||||||
|
@ -65,10 +67,10 @@ namespace {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
fn internAtom = [&conn](const StringView name) -> Result<atom_t> {
|
fn internAtom = [&conn](const StringView name) -> Result<Atom> {
|
||||||
using util::types::u16;
|
using util::types::u16;
|
||||||
|
|
||||||
const ReplyGuard<intern_atom_reply_t> reply(InternAtomReply(conn.get(), InternAtom(conn.get(), 0, static_cast<u16>(name.size()), name.data()), nullptr));
|
const ReplyGuard<IntAtomReply> reply(InternAtomReply(conn.get(), InternAtom(conn.get(), 0, static_cast<u16>(name.size()), name.data()), nullptr));
|
||||||
|
|
||||||
if (!reply)
|
if (!reply)
|
||||||
return Err(DracError(DracErrorCode::PlatformSpecific, std::format("Failed to get X11 atom reply for '{}'", name)));
|
return Err(DracError(DracErrorCode::PlatformSpecific, std::format("Failed to get X11 atom reply for '{}'", name)));
|
||||||
|
@ -76,9 +78,9 @@ namespace {
|
||||||
return reply->atom;
|
return reply->atom;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Result<atom_t> supportingWmCheckAtom = internAtom("_NET_SUPPORTING_WM_CHECK");
|
const Result<Atom> supportingWmCheckAtom = internAtom("_NET_SUPPORTING_WM_CHECK");
|
||||||
const Result<atom_t> wmNameAtom = internAtom("_NET_WM_NAME");
|
const Result<Atom> wmNameAtom = internAtom("_NET_WM_NAME");
|
||||||
const Result<atom_t> utf8StringAtom = internAtom("UTF8_STRING");
|
const Result<Atom> utf8StringAtom = internAtom("UTF8_STRING");
|
||||||
|
|
||||||
if (!supportingWmCheckAtom || !wmNameAtom || !utf8StringAtom) {
|
if (!supportingWmCheckAtom || !wmNameAtom || !utf8StringAtom) {
|
||||||
if (!supportingWmCheckAtom)
|
if (!supportingWmCheckAtom)
|
||||||
|
@ -93,7 +95,7 @@ namespace {
|
||||||
return Err(DracError(DracErrorCode::PlatformSpecific, "Failed to get X11 atoms"));
|
return Err(DracError(DracErrorCode::PlatformSpecific, "Failed to get X11 atoms"));
|
||||||
}
|
}
|
||||||
|
|
||||||
const ReplyGuard<get_property_reply_t> wmWindowReply(GetPropertyReply(
|
const ReplyGuard<GetPropReply> wmWindowReply(GetPropertyReply(
|
||||||
conn.get(),
|
conn.get(),
|
||||||
GetProperty(conn.get(), 0, conn.rootScreen()->root, *supportingWmCheckAtom, ATOM_WINDOW, 0, 1),
|
GetProperty(conn.get(), 0, conn.rootScreen()->root, *supportingWmCheckAtom, ATOM_WINDOW, 0, 1),
|
||||||
nullptr
|
nullptr
|
||||||
|
@ -103,9 +105,9 @@ namespace {
|
||||||
GetPropertyValueLength(wmWindowReply.get()) == 0)
|
GetPropertyValueLength(wmWindowReply.get()) == 0)
|
||||||
return Err(DracError(DracErrorCode::NotFound, "Failed to get _NET_SUPPORTING_WM_CHECK property"));
|
return Err(DracError(DracErrorCode::NotFound, "Failed to get _NET_SUPPORTING_WM_CHECK property"));
|
||||||
|
|
||||||
const window_t wmRootWindow = *static_cast<window_t*>(GetPropertyValue(wmWindowReply.get()));
|
const Window wmRootWindow = *static_cast<Window*>(GetPropertyValue(wmWindowReply.get()));
|
||||||
|
|
||||||
const ReplyGuard<get_property_reply_t> wmNameReply(GetPropertyReply(
|
const ReplyGuard<GetPropReply> wmNameReply(GetPropertyReply(
|
||||||
conn.get(), GetProperty(conn.get(), 0, wmRootWindow, *wmNameAtom, *utf8StringAtom, 0, 1024), nullptr
|
conn.get(), GetProperty(conn.get(), 0, wmRootWindow, *wmNameAtom, *utf8StringAtom, 0, 1024), nullptr
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -127,7 +129,7 @@ namespace {
|
||||||
fn GetWaylandCompositor() -> Result<String> {
|
fn GetWaylandCompositor() -> Result<String> {
|
||||||
using util::types::i32, util::types::Array, util::types::isize, util::types::StringView;
|
using util::types::i32, util::types::Array, util::types::isize, util::types::StringView;
|
||||||
|
|
||||||
const wl::DisplayGuard display;
|
const Wayland::DisplayGuard display;
|
||||||
|
|
||||||
if (!display)
|
if (!display)
|
||||||
return Err(DracError(DracErrorCode::NotFound, "Failed to connect to display (is Wayland running?)"));
|
return Err(DracError(DracErrorCode::NotFound, "Failed to connect to display (is Wayland running?)"));
|
||||||
|
@ -226,9 +228,7 @@ namespace os {
|
||||||
value = value.substr(1, value.length() - 2);
|
value = value.substr(1, value.length() - 2);
|
||||||
|
|
||||||
if (value.empty())
|
if (value.empty())
|
||||||
return Err(
|
return Err(DracError(DracErrorCode::ParseError, std::format("PRETTY_NAME value is empty or only quotes in /etc/os-release")));
|
||||||
DracError(DracErrorCode::ParseError, std::format("PRETTY_NAME value is empty or only quotes in /etc/os-release"))
|
|
||||||
);
|
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -257,7 +257,7 @@ namespace os {
|
||||||
|
|
||||||
fn GetNowPlaying() -> Result<MediaInfo> {
|
fn GetNowPlaying() -> Result<MediaInfo> {
|
||||||
#ifdef HAVE_DBUS
|
#ifdef HAVE_DBUS
|
||||||
using namespace dbus;
|
using namespace DBus;
|
||||||
|
|
||||||
Result<Connection> connectionResult = Connection::busGet(DBUS_BUS_SESSION);
|
Result<Connection> connectionResult = Connection::busGet(DBUS_BUS_SESSION);
|
||||||
if (!connectionResult)
|
if (!connectionResult)
|
||||||
|
@ -286,9 +286,7 @@ namespace os {
|
||||||
MessageIter subIter = iter.recurse();
|
MessageIter subIter = iter.recurse();
|
||||||
|
|
||||||
if (!subIter.isValid())
|
if (!subIter.isValid())
|
||||||
return Err(
|
return Err(DracError(DracErrorCode::ParseError, "Invalid DBus ListNames reply format: Could not recurse into array"));
|
||||||
DracError(DracErrorCode::ParseError, "Invalid DBus ListNames reply format: Could not recurse into array")
|
|
||||||
);
|
|
||||||
|
|
||||||
while (subIter.getArgType() != DBUS_TYPE_INVALID) {
|
while (subIter.getArgType() != DBUS_TYPE_INVALID) {
|
||||||
if (Option<String> name = subIter.getString())
|
if (Option<String> name = subIter.getString())
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Services/Weather.hpp"
|
#include "Services/Weather.hpp"
|
||||||
|
|
||||||
#include "Util/Error.hpp"
|
#include "Util/Error.hpp"
|
||||||
|
|
||||||
namespace weather {
|
namespace weather {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#include "UI.hpp"
|
#include "UI.hpp"
|
||||||
|
|
||||||
#include "OS/OperatingSystem.hpp"
|
|
||||||
#include "Util/Types.hpp"
|
#include "Util/Types.hpp"
|
||||||
|
|
||||||
|
#include "OS/OperatingSystem.hpp"
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
using namespace ftxui;
|
using namespace ftxui;
|
||||||
using namespace util::types;
|
using namespace util::types;
|
||||||
|
|
|
@ -3,8 +3,10 @@
|
||||||
#include <ftxui/dom/elements.hpp> // ftxui::Element
|
#include <ftxui/dom/elements.hpp> // ftxui::Element
|
||||||
#include <ftxui/screen/color.hpp> // ftxui::Color
|
#include <ftxui/screen/color.hpp> // ftxui::Color
|
||||||
|
|
||||||
#include "Config/Config.hpp"
|
|
||||||
#include "Core/SystemData.hpp"
|
#include "Core/SystemData.hpp"
|
||||||
|
|
||||||
|
#include "Config/Config.hpp"
|
||||||
|
|
||||||
#include "Util/Types.hpp"
|
#include "Util/Types.hpp"
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
|
@ -14,38 +14,64 @@
|
||||||
#include "Util/Types.hpp"
|
#include "Util/Types.hpp"
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
namespace dbus {
|
namespace DBus {
|
||||||
using util::error::DracError, util::error::DracErrorCode;
|
using util::error::DracError, util::error::DracErrorCode;
|
||||||
using util::types::Option, util::types::Result, util::types::Err, util::types::String, util::types::i32,
|
using util::types::Option, util::types::Result, util::types::Err, util::types::String, util::types::i32,
|
||||||
util::types::u32, util::types::None;
|
util::types::u32, util::types::None;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief RAII wrapper for DBusError. Automatically initializes and frees.
|
* @brief RAII wrapper for DBusError. Automatically initializes and frees the error.
|
||||||
*/
|
*/
|
||||||
class Error {
|
class Error {
|
||||||
DBusError m_err {};
|
DBusError m_err {}; ///< The D-Bus error object
|
||||||
bool m_isInitialized = false;
|
bool m_isInitialized = false; ///< Flag indicating if the error is initialized
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
*
|
||||||
|
* Initializes the D-Bus error object.
|
||||||
|
*/
|
||||||
Error()
|
Error()
|
||||||
: m_isInitialized(true) {
|
: m_isInitialized(true) {
|
||||||
dbus_error_init(&m_err);
|
dbus_error_init(&m_err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor
|
||||||
|
*
|
||||||
|
* Frees the D-Bus error object if it was initialized.
|
||||||
|
*/
|
||||||
~Error() {
|
~Error() {
|
||||||
if (m_isInitialized)
|
if (m_isInitialized)
|
||||||
dbus_error_free(&m_err);
|
dbus_error_free(&m_err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Non-copyable
|
||||||
Error(const Error&) = delete;
|
Error(const Error&) = delete;
|
||||||
fn operator=(const Error&)->Error& = delete;
|
fn operator=(const Error&)->Error& = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move constructor
|
||||||
|
*
|
||||||
|
* Transfers ownership of the D-Bus error object.
|
||||||
|
*
|
||||||
|
* @param other The other Error object to move from
|
||||||
|
*/
|
||||||
Error(Error&& other) noexcept
|
Error(Error&& other) noexcept
|
||||||
: m_err(other.m_err), m_isInitialized(other.m_isInitialized) {
|
: m_err(other.m_err), m_isInitialized(other.m_isInitialized) {
|
||||||
other.m_isInitialized = false;
|
other.m_isInitialized = false;
|
||||||
dbus_error_init(&other.m_err);
|
dbus_error_init(&other.m_err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move assignment operator
|
||||||
|
*
|
||||||
|
* Transfers ownership of the D-Bus error object.
|
||||||
|
*
|
||||||
|
* @param other The other Error object to move from
|
||||||
|
* @return A reference to this object
|
||||||
|
*/
|
||||||
fn operator=(Error&& other) noexcept -> Error& {
|
fn operator=(Error&& other) noexcept -> Error& {
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
if (m_isInitialized)
|
if (m_isInitialized)
|
||||||
|
@ -61,8 +87,8 @@ namespace dbus {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks if the D-Bus error is set.
|
* @brief Checks if the error is set.
|
||||||
* @return True if an error is set, false otherwise.
|
* @return True if the error is set and initialized, false otherwise.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] fn isSet() const -> bool {
|
[[nodiscard]] fn isSet() const -> bool {
|
||||||
return m_isInitialized && dbus_error_is_set(&m_err);
|
return m_isInitialized && dbus_error_is_set(&m_err);
|
||||||
|
@ -91,6 +117,7 @@ namespace dbus {
|
||||||
[[nodiscard]] fn get() -> DBusError* {
|
[[nodiscard]] fn get() -> DBusError* {
|
||||||
return &m_err;
|
return &m_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets a const pointer to the underlying DBusError.
|
* @brief Gets a const pointer to the underlying DBusError.
|
||||||
* @return Const pointer to the DBusError struct.
|
* @return Const pointer to the DBusError struct.
|
||||||
|
@ -100,11 +127,11 @@ namespace dbus {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Converts the D-Bus error to a DraconisError.
|
* @brief Converts the D-Bus error to a DracError.
|
||||||
* @param code The DraconisError code to use if the D-Bus error is set.
|
* @param code The DracErrorCode to use if the D-Bus error is set.
|
||||||
* @return A DraconisError representing the D-Bus error, or an internal error if called when no D-Bus error is set.
|
* @return A DracError representing the D-Bus error, or an internal error if called when no D-Bus error is set.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] fn toDraconisError(const DracErrorCode code = DracErrorCode::PlatformSpecific) const -> DracError {
|
[[nodiscard]] fn toDracError(const DracErrorCode code = DracErrorCode::PlatformSpecific) const -> DracError {
|
||||||
if (isSet())
|
if (isSet())
|
||||||
return { code, std::format("D-Bus Error: {} ({})", message(), name()) };
|
return { code, std::format("D-Bus Error: {} ({})", message(), name()) };
|
||||||
|
|
||||||
|
@ -113,23 +140,36 @@ namespace dbus {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief RAII wrapper for DBusMessageIter. Encapsulates iterator operations.
|
* @brief RAII wrapper for DBusMessageIter. Automatically frees the iterator.
|
||||||
* Note: This wrapper does *not* own the message, only the iterator state.
|
*
|
||||||
* It's designed to be used within the scope where the MessageGuard is valid.
|
* This class provides a convenient way to manage the lifetime of a D-Bus message iterator.
|
||||||
*/
|
*/
|
||||||
class MessageIter {
|
class MessageIter {
|
||||||
DBusMessageIter m_iter {};
|
DBusMessageIter m_iter {}; ///< The D-Bus message iterator
|
||||||
bool m_isValid = false;
|
bool m_isValid = false; ///< Flag indicating if the iterator is valid
|
||||||
|
|
||||||
explicit MessageIter(const DBusMessageIter& iter, const bool isValid)
|
|
||||||
: m_iter(iter), m_isValid(isValid) {}
|
|
||||||
|
|
||||||
|
// Allows the Message class to access private members of this class.
|
||||||
friend class Message;
|
friend class Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the value of a basic-typed argument.
|
* @brief Constructor
|
||||||
* Unsafe: Caller must ensure 'value' points to memory suitable for the actual argument type.
|
*
|
||||||
* @param value Pointer to store the retrieved value.
|
* Initializes the D-Bus message iterator.
|
||||||
|
*
|
||||||
|
* @param iter The D-Bus message iterator to wrap
|
||||||
|
* @param isValid Flag indicating if the iterator is valid
|
||||||
|
*/
|
||||||
|
explicit MessageIter(const DBusMessageIter& iter, const bool isValid)
|
||||||
|
: m_iter(iter), m_isValid(isValid) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor
|
||||||
|
*
|
||||||
|
* Frees the D-Bus message iterator if it was initialized.
|
||||||
|
*
|
||||||
|
* @param value Pointer to the value to be freed
|
||||||
|
*
|
||||||
|
* @note This function is unsafe and should not be called directly.
|
||||||
*/
|
*/
|
||||||
fn getBasic(void* value) -> void {
|
fn getBasic(void* value) -> void {
|
||||||
if (m_isValid)
|
if (m_isValid)
|
||||||
|
@ -137,10 +177,15 @@ namespace dbus {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// Non-copyable
|
||||||
MessageIter(const MessageIter&) = delete;
|
MessageIter(const MessageIter&) = delete;
|
||||||
fn operator=(const MessageIter&)->MessageIter& = delete;
|
fn operator=(const MessageIter&)->MessageIter& = delete;
|
||||||
|
|
||||||
|
// Non-movable
|
||||||
MessageIter(MessageIter&&) = delete;
|
MessageIter(MessageIter&&) = delete;
|
||||||
fn operator=(MessageIter&&)->MessageIter& = delete;
|
fn operator=(MessageIter&&)->MessageIter& = delete;
|
||||||
|
|
||||||
|
// Destructor
|
||||||
~MessageIter() = default;
|
~MessageIter() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -213,23 +258,51 @@ namespace dbus {
|
||||||
* @brief RAII wrapper for DBusMessage. Automatically unrefs.
|
* @brief RAII wrapper for DBusMessage. Automatically unrefs.
|
||||||
*/
|
*/
|
||||||
class Message {
|
class Message {
|
||||||
DBusMessage* m_msg = nullptr;
|
DBusMessage* m_msg = nullptr; ///< The D-Bus message object
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
*
|
||||||
|
* Initializes the D-Bus message object.
|
||||||
|
*
|
||||||
|
* @param msg The D-Bus message object to wrap
|
||||||
|
*/
|
||||||
explicit Message(DBusMessage* msg = nullptr)
|
explicit Message(DBusMessage* msg = nullptr)
|
||||||
: m_msg(msg) {}
|
: m_msg(msg) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor
|
||||||
|
*
|
||||||
|
* Frees the D-Bus message object if it was initialized.
|
||||||
|
*/
|
||||||
~Message() {
|
~Message() {
|
||||||
if (m_msg)
|
if (m_msg)
|
||||||
dbus_message_unref(m_msg);
|
dbus_message_unref(m_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Non-copyable
|
||||||
Message(const Message&) = delete;
|
Message(const Message&) = delete;
|
||||||
fn operator=(const Message&)->Message& = delete;
|
fn operator=(const Message&)->Message& = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move constructor
|
||||||
|
*
|
||||||
|
* Transfers ownership of the D-Bus message object.
|
||||||
|
*
|
||||||
|
* @param other The other Message object to move from
|
||||||
|
*/
|
||||||
Message(Message&& other) noexcept
|
Message(Message&& other) noexcept
|
||||||
: m_msg(std::exchange(other.m_msg, nullptr)) {}
|
: m_msg(std::exchange(other.m_msg, nullptr)) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move assignment operator
|
||||||
|
*
|
||||||
|
* Transfers ownership of the D-Bus message object.
|
||||||
|
*
|
||||||
|
* @param other The other Message object to move from
|
||||||
|
* @return A reference to this object
|
||||||
|
*/
|
||||||
fn operator=(Message&& other) noexcept -> Message& {
|
fn operator=(Message&& other) noexcept -> Message& {
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
if (m_msg)
|
if (m_msg)
|
||||||
|
@ -285,7 +358,7 @@ namespace dbus {
|
||||||
* @param path Object path (e.g., "/org/freedesktop/Notifications"). Must not be null.
|
* @param path Object path (e.g., "/org/freedesktop/Notifications"). Must not be null.
|
||||||
* @param interface Interface name (e.g., "org.freedesktop.Notifications"). Can be null.
|
* @param interface Interface name (e.g., "org.freedesktop.Notifications"). Can be null.
|
||||||
* @param method Method name (e.g., "Notify"). Must not be null.
|
* @param method Method name (e.g., "Notify"). Must not be null.
|
||||||
* @return Result containing a MessageGuard on success, or DraconisError on failure.
|
* @return Result containing a MessageGuard on success, or DracError on failure.
|
||||||
*/
|
*/
|
||||||
static fn newMethodCall(const char* destination, const char* path, const char* interface, const char* method)
|
static fn newMethodCall(const char* destination, const char* path, const char* interface, const char* method)
|
||||||
-> Result<Message> {
|
-> Result<Message> {
|
||||||
|
@ -298,6 +371,13 @@ namespace dbus {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Appends a single argument to the message.
|
||||||
|
* @tparam T Type of the argument to append.
|
||||||
|
* @param iter The D-Bus message iterator.
|
||||||
|
* @param arg The argument to append.
|
||||||
|
* @return True if the argument was appended successfully, false otherwise (e.g., allocation error).
|
||||||
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
fn appendArgInternal(DBusMessageIter& iter, T&& arg) -> bool {
|
fn appendArgInternal(DBusMessageIter& iter, T&& arg) -> bool {
|
||||||
using DecayedT = std::decay_t<T>;
|
using DecayedT = std::decay_t<T>;
|
||||||
|
@ -313,26 +393,56 @@ namespace dbus {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief RAII wrapper for DBusConnection. Automatically unrefs.
|
* @brief RAII wrapper for DBusConnection. Automatically unrefs the connection.
|
||||||
|
*
|
||||||
|
* This class provides a convenient way to manage the lifetime of a D-Bus connection.
|
||||||
*/
|
*/
|
||||||
class Connection {
|
class Connection {
|
||||||
DBusConnection* m_conn = nullptr;
|
DBusConnection* m_conn = nullptr; ///< The D-Bus connection object
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
*
|
||||||
|
* Initializes the D-Bus connection object.
|
||||||
|
*
|
||||||
|
* @param conn The D-Bus connection object to wrap
|
||||||
|
*/
|
||||||
explicit Connection(DBusConnection* conn = nullptr)
|
explicit Connection(DBusConnection* conn = nullptr)
|
||||||
: m_conn(conn) {}
|
: m_conn(conn) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor
|
||||||
|
*
|
||||||
|
* Frees the D-Bus connection object if it was initialized.
|
||||||
|
*/
|
||||||
~Connection() {
|
~Connection() {
|
||||||
if (m_conn)
|
if (m_conn)
|
||||||
dbus_connection_unref(m_conn);
|
dbus_connection_unref(m_conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Non-copyable
|
||||||
Connection(const Connection&) = delete;
|
Connection(const Connection&) = delete;
|
||||||
fn operator=(const Connection&)->Connection& = delete;
|
fn operator=(const Connection&)->Connection& = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move constructor
|
||||||
|
*
|
||||||
|
* Transfers ownership of the D-Bus connection object.
|
||||||
|
*
|
||||||
|
* @param other The other Connection object to move from
|
||||||
|
*/
|
||||||
Connection(Connection&& other) noexcept
|
Connection(Connection&& other) noexcept
|
||||||
: m_conn(std::exchange(other.m_conn, nullptr)) {}
|
: m_conn(std::exchange(other.m_conn, nullptr)) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move assignment operator
|
||||||
|
*
|
||||||
|
* Transfers ownership of the D-Bus connection object.
|
||||||
|
*
|
||||||
|
* @param other The other Connection object to move from
|
||||||
|
* @return A reference to this object
|
||||||
|
*/
|
||||||
fn operator=(Connection&& other) noexcept -> Connection& {
|
fn operator=(Connection&& other) noexcept -> Connection& {
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
if (m_conn)
|
if (m_conn)
|
||||||
|
@ -355,7 +465,7 @@ namespace dbus {
|
||||||
* @brief Sends a message and waits for a reply, blocking execution.
|
* @brief Sends a message and waits for a reply, blocking execution.
|
||||||
* @param message The D-Bus message guard to send.
|
* @param message The D-Bus message guard to send.
|
||||||
* @param timeout_milliseconds Timeout duration in milliseconds.
|
* @param timeout_milliseconds Timeout duration in milliseconds.
|
||||||
* @return Result containing the reply MessageGuard on success, or DraconisError on failure.
|
* @return Result containing the reply MessageGuard on success, or DracError on failure.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] fn sendWithReplyAndBlock(const Message& message, const i32 timeout_milliseconds = 1000) const
|
[[nodiscard]] fn sendWithReplyAndBlock(const Message& message, const i32 timeout_milliseconds = 1000) const
|
||||||
-> Result<Message> {
|
-> Result<Message> {
|
||||||
|
@ -371,16 +481,16 @@ namespace dbus {
|
||||||
if (err.isSet()) {
|
if (err.isSet()) {
|
||||||
if (const char* errName = err.name()) {
|
if (const char* errName = err.name()) {
|
||||||
if (strcmp(errName, DBUS_ERROR_TIMEOUT) == 0 || strcmp(errName, DBUS_ERROR_NO_REPLY) == 0)
|
if (strcmp(errName, DBUS_ERROR_TIMEOUT) == 0 || strcmp(errName, DBUS_ERROR_NO_REPLY) == 0)
|
||||||
return Err(err.toDraconisError(DracErrorCode::Timeout));
|
return Err(err.toDracError(DracErrorCode::Timeout));
|
||||||
|
|
||||||
if (strcmp(errName, DBUS_ERROR_SERVICE_UNKNOWN) == 0)
|
if (strcmp(errName, DBUS_ERROR_SERVICE_UNKNOWN) == 0)
|
||||||
return Err(err.toDraconisError(DracErrorCode::NotFound));
|
return Err(err.toDracError(DracErrorCode::NotFound));
|
||||||
|
|
||||||
if (strcmp(errName, DBUS_ERROR_ACCESS_DENIED) == 0)
|
if (strcmp(errName, DBUS_ERROR_ACCESS_DENIED) == 0)
|
||||||
return Err(err.toDraconisError(DracErrorCode::PermissionDenied));
|
return Err(err.toDracError(DracErrorCode::PermissionDenied));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err(err.toDraconisError(DracErrorCode::PlatformSpecific));
|
return Err(err.toDracError(DracErrorCode::PlatformSpecific));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rawReply)
|
if (!rawReply)
|
||||||
|
@ -396,14 +506,14 @@ namespace dbus {
|
||||||
/**
|
/**
|
||||||
* @brief Connects to a D-Bus bus type (Session or System).
|
* @brief Connects to a D-Bus bus type (Session or System).
|
||||||
* @param bus_type The type of bus (DBUS_BUS_SESSION or DBUS_BUS_SYSTEM).
|
* @param bus_type The type of bus (DBUS_BUS_SESSION or DBUS_BUS_SYSTEM).
|
||||||
* @return Result containing a ConnectionGuard on success, or DraconisError on failure.
|
* @return Result containing a ConnectionGuard on success, or DracError on failure.
|
||||||
*/
|
*/
|
||||||
static fn busGet(const DBusBusType bus_type) -> Result<Connection> {
|
static fn busGet(const DBusBusType bus_type) -> Result<Connection> {
|
||||||
Error err;
|
Error err;
|
||||||
DBusConnection* rawConn = dbus_bus_get(bus_type, err.get());
|
DBusConnection* rawConn = dbus_bus_get(bus_type, err.get());
|
||||||
|
|
||||||
if (err.isSet())
|
if (err.isSet())
|
||||||
return Err(err.toDraconisError(DracErrorCode::ApiUnavailable));
|
return Err(err.toDracError(DracErrorCode::ApiUnavailable));
|
||||||
|
|
||||||
if (!rawConn)
|
if (!rawConn)
|
||||||
return Err(DracError(DracErrorCode::ApiUnavailable, "dbus_bus_get returned null without setting error"));
|
return Err(DracError(DracErrorCode::ApiUnavailable, "dbus_bus_get returned null without setting error"));
|
||||||
|
@ -411,6 +521,6 @@ namespace dbus {
|
||||||
return Connection(rawConn);
|
return Connection(rawConn);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace dbus
|
} // namespace DBus
|
||||||
|
|
||||||
#endif // __linux__ || __FreeBSD__ || __DragonFly__ || __NetBSD__
|
#endif // __linux__ || __FreeBSD__ || __DragonFly__ || __NetBSD__
|
||||||
|
|
|
@ -10,34 +10,66 @@
|
||||||
#include "Util/Types.hpp"
|
#include "Util/Types.hpp"
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
struct wl_display;
|
namespace Wayland {
|
||||||
|
using util::types::i32, util::types::CStr, util::types::None;
|
||||||
|
|
||||||
namespace wl {
|
using Display = wl_display;
|
||||||
using display = wl_display;
|
|
||||||
|
|
||||||
inline fn Connect(const char* name) -> display* {
|
/**
|
||||||
|
* @brief Connect to a Wayland display
|
||||||
|
*
|
||||||
|
* This function establishes a connection to a Wayland display. It takes a
|
||||||
|
* display name as an argument.
|
||||||
|
*
|
||||||
|
* @param name The name of the display to connect to (or nullptr for default)
|
||||||
|
* @return A pointer to the Wayland display object
|
||||||
|
*/
|
||||||
|
inline fn Connect(CStr name) -> Display* {
|
||||||
return wl_display_connect(name);
|
return wl_display_connect(name);
|
||||||
}
|
}
|
||||||
inline fn Disconnect(display* display) -> void {
|
|
||||||
|
/**
|
||||||
|
* @brief Disconnect from a Wayland display
|
||||||
|
*
|
||||||
|
* This function disconnects from a Wayland display.
|
||||||
|
*
|
||||||
|
* @param display The Wayland display object to disconnect from
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
inline fn Disconnect(Display* display) -> void {
|
||||||
wl_display_disconnect(display);
|
wl_display_disconnect(display);
|
||||||
}
|
}
|
||||||
inline fn GetFd(display* display) -> int {
|
|
||||||
|
/**
|
||||||
|
* @brief Get the file descriptor for a Wayland display
|
||||||
|
*
|
||||||
|
* This function retrieves the file descriptor for a Wayland display.
|
||||||
|
*
|
||||||
|
* @param display The Wayland display object
|
||||||
|
* @return The file descriptor for the Wayland display
|
||||||
|
*/
|
||||||
|
inline fn GetFd(Display* display) -> i32 {
|
||||||
return wl_display_get_fd(display);
|
return wl_display_get_fd(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RAII wrapper for Wayland display connections
|
* @brief RAII wrapper for Wayland display connections
|
||||||
* Automatically handles resource acquisition and cleanup
|
*
|
||||||
|
* This class manages the connection to a Wayland display. It automatically
|
||||||
|
* handles resource acquisition and cleanup.
|
||||||
*/
|
*/
|
||||||
class DisplayGuard {
|
class DisplayGuard {
|
||||||
display* m_display;
|
Display* m_display; ///< The Wayland display object
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Opens a Wayland display connection
|
* @brief Constructor
|
||||||
|
*
|
||||||
|
* This constructor sets up a custom logging handler for Wayland and
|
||||||
|
* establishes a connection to the Wayland display.
|
||||||
*/
|
*/
|
||||||
DisplayGuard() {
|
DisplayGuard() {
|
||||||
wl_log_set_handler_client([](const char* fmt, va_list args) -> void {
|
wl_log_set_handler_client([](CStr fmt, va_list args) -> void {
|
||||||
using util::types::i32, util::types::StringView;
|
using util::types::i32, util::types::StringView;
|
||||||
|
|
||||||
va_list argsCopy;
|
va_list argsCopy;
|
||||||
|
@ -71,6 +103,11 @@ namespace wl {
|
||||||
m_display = Connect(nullptr);
|
m_display = Connect(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor
|
||||||
|
*
|
||||||
|
* This destructor disconnects from the Wayland display if it is valid.
|
||||||
|
*/
|
||||||
~DisplayGuard() {
|
~DisplayGuard() {
|
||||||
if (m_display)
|
if (m_display)
|
||||||
Disconnect(m_display);
|
Disconnect(m_display);
|
||||||
|
@ -83,6 +120,15 @@ namespace wl {
|
||||||
// Movable
|
// Movable
|
||||||
DisplayGuard(DisplayGuard&& other) noexcept
|
DisplayGuard(DisplayGuard&& other) noexcept
|
||||||
: m_display(std::exchange(other.m_display, nullptr)) {}
|
: m_display(std::exchange(other.m_display, nullptr)) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move assignment operator
|
||||||
|
*
|
||||||
|
* This operator transfers ownership of the Wayland display connection.
|
||||||
|
*
|
||||||
|
* @param other The other DisplayGuard object to move from
|
||||||
|
* @return A reference to this object
|
||||||
|
*/
|
||||||
fn operator=(DisplayGuard&& other) noexcept -> DisplayGuard& {
|
fn operator=(DisplayGuard&& other) noexcept -> DisplayGuard& {
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
if (m_display)
|
if (m_display)
|
||||||
|
@ -94,17 +140,40 @@ namespace wl {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the display guard is valid
|
||||||
|
*
|
||||||
|
* This function checks if the display guard is valid (i.e., if it holds a
|
||||||
|
* valid Wayland display connection).
|
||||||
|
*
|
||||||
|
* @return True if the display guard is valid, false otherwise
|
||||||
|
*/
|
||||||
[[nodiscard]] explicit operator bool() const {
|
[[nodiscard]] explicit operator bool() const {
|
||||||
return m_display != nullptr;
|
return m_display != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] fn get() const -> display* {
|
/**
|
||||||
|
* @brief Get the Wayland display connection
|
||||||
|
*
|
||||||
|
* This function retrieves the underlying Wayland display connection.
|
||||||
|
*
|
||||||
|
* @return The Wayland display connection
|
||||||
|
*/
|
||||||
|
[[nodiscard]] fn get() const -> Display* {
|
||||||
return m_display;
|
return m_display;
|
||||||
}
|
}
|
||||||
[[nodiscard]] fn fd() const -> util::types::i32 {
|
|
||||||
|
/**
|
||||||
|
* @brief Get the file descriptor for the Wayland display
|
||||||
|
*
|
||||||
|
* This function retrieves the file descriptor for the Wayland display.
|
||||||
|
*
|
||||||
|
* @return The file descriptor for the Wayland display
|
||||||
|
*/
|
||||||
|
[[nodiscard]] fn fd() const -> i32 {
|
||||||
return GetFd(m_display);
|
return GetFd(m_display);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace wl
|
} // namespace Wayland
|
||||||
|
|
||||||
#endif // __linux__ || __FreeBSD__ || __DragonFly__ || __NetBSD__
|
#endif // __linux__ || __FreeBSD__ || __DragonFly__ || __NetBSD__
|
||||||
|
|
|
@ -9,22 +9,22 @@
|
||||||
#include "Util/Types.hpp"
|
#include "Util/Types.hpp"
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
namespace xcb {
|
namespace XCB {
|
||||||
using util::types::u8, util::types::i32, util::types::CStr, util::types::None;
|
using util::types::u8, util::types::u16, util::types::i32, util::types::u32, util::types::CStr, util::types::None;
|
||||||
|
|
||||||
using connection_t = xcb_connection_t;
|
using Connection = xcb_connection_t;
|
||||||
using setup_t = xcb_setup_t;
|
using Setup = xcb_setup_t;
|
||||||
using screen_t = xcb_screen_t;
|
using Screen = xcb_screen_t;
|
||||||
using window_t = xcb_window_t;
|
using Window = xcb_window_t;
|
||||||
using atom_t = xcb_atom_t;
|
using Atom = xcb_atom_t;
|
||||||
|
|
||||||
using generic_error_t = xcb_generic_error_t;
|
using GenericError = xcb_generic_error_t;
|
||||||
using intern_atom_cookie_t = xcb_intern_atom_cookie_t;
|
using IntAtomCookie = xcb_intern_atom_cookie_t;
|
||||||
using intern_atom_reply_t = xcb_intern_atom_reply_t;
|
using IntAtomReply = xcb_intern_atom_reply_t;
|
||||||
using get_property_cookie_t = xcb_get_property_cookie_t;
|
using GetPropCookie = xcb_get_property_cookie_t;
|
||||||
using get_property_reply_t = xcb_get_property_reply_t;
|
using GetPropReply = xcb_get_property_reply_t;
|
||||||
|
|
||||||
constexpr atom_t ATOM_WINDOW = XCB_ATOM_WINDOW; ///< Window atom
|
constexpr Atom ATOM_WINDOW = XCB_ATOM_WINDOW; ///< Window atom
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enum representing different types of connection errors
|
* @brief Enum representing different types of connection errors
|
||||||
|
@ -54,7 +54,7 @@ namespace xcb {
|
||||||
* @param screenp Pointer to an integer that will store the screen number
|
* @param screenp Pointer to an integer that will store the screen number
|
||||||
* @return A pointer to the connection object
|
* @return A pointer to the connection object
|
||||||
*/
|
*/
|
||||||
inline fn Connect(const char* displayname, int* screenp) -> connection_t* {
|
inline fn Connect(CStr displayname, i32* screenp) -> Connection* {
|
||||||
return xcb_connect(displayname, screenp);
|
return xcb_connect(displayname, screenp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ namespace xcb {
|
||||||
*
|
*
|
||||||
* @param conn The connection object to disconnect from
|
* @param conn The connection object to disconnect from
|
||||||
*/
|
*/
|
||||||
inline fn Disconnect(connection_t* conn) -> void {
|
inline fn Disconnect(Connection* conn) -> void {
|
||||||
xcb_disconnect(conn);
|
xcb_disconnect(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ namespace xcb {
|
||||||
* @param conn The connection object to check
|
* @param conn The connection object to check
|
||||||
* @return 1 if the connection has an error, 0 otherwise
|
* @return 1 if the connection has an error, 0 otherwise
|
||||||
*/
|
*/
|
||||||
inline fn ConnectionHasError(connection_t* conn) -> int {
|
inline fn ConnectionHasError(Connection* conn) -> i32 {
|
||||||
return xcb_connection_has_error(conn);
|
return xcb_connection_has_error(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,8 +94,7 @@ namespace xcb {
|
||||||
* @param name The name of the atom
|
* @param name The name of the atom
|
||||||
* @return The cookie for the atom
|
* @return The cookie for the atom
|
||||||
*/
|
*/
|
||||||
inline fn InternAtom(connection_t* conn, const uint8_t only_if_exists, const uint16_t name_len, const char* name)
|
inline fn InternAtom(Connection* conn, const u8 only_if_exists, const u16 name_len, CStr name) -> IntAtomCookie {
|
||||||
-> intern_atom_cookie_t {
|
|
||||||
return xcb_intern_atom(conn, only_if_exists, name_len, name);
|
return xcb_intern_atom(conn, only_if_exists, name_len, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,8 +109,7 @@ namespace xcb {
|
||||||
* @param err The pointer to the generic error
|
* @param err The pointer to the generic error
|
||||||
* @return The reply for the atom
|
* @return The reply for the atom
|
||||||
*/
|
*/
|
||||||
inline fn InternAtomReply(connection_t* conn, const intern_atom_cookie_t cookie, generic_error_t** err)
|
inline fn InternAtomReply(Connection* conn, const IntAtomCookie cookie, GenericError** err) -> IntAtomReply* {
|
||||||
-> intern_atom_reply_t* {
|
|
||||||
return xcb_intern_atom_reply(conn, cookie, err);
|
return xcb_intern_atom_reply(conn, cookie, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,14 +126,14 @@ namespace xcb {
|
||||||
* @param type The type
|
* @param type The type
|
||||||
*/
|
*/
|
||||||
inline fn GetProperty(
|
inline fn GetProperty(
|
||||||
connection_t* conn,
|
Connection* conn,
|
||||||
const uint8_t _delete,
|
const u8 _delete,
|
||||||
const window_t window,
|
const Window window,
|
||||||
const atom_t property,
|
const Atom property,
|
||||||
const atom_t type,
|
const Atom type,
|
||||||
const uint32_t long_offset,
|
const u32 long_offset,
|
||||||
const uint32_t long_length
|
const u32 long_length
|
||||||
) -> get_property_cookie_t {
|
) -> GetPropCookie {
|
||||||
return xcb_get_property(conn, _delete, window, property, type, long_offset, long_length);
|
return xcb_get_property(conn, _delete, window, property, type, long_offset, long_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,8 +148,7 @@ namespace xcb {
|
||||||
* @param err The pointer to the generic error
|
* @param err The pointer to the generic error
|
||||||
* @return The reply for the property
|
* @return The reply for the property
|
||||||
*/
|
*/
|
||||||
inline fn GetPropertyReply(connection_t* conn, const get_property_cookie_t cookie, generic_error_t** err)
|
inline fn GetPropertyReply(Connection* conn, const GetPropCookie cookie, GenericError** err) -> GetPropReply* {
|
||||||
-> get_property_reply_t* {
|
|
||||||
return xcb_get_property_reply(conn, cookie, err);
|
return xcb_get_property_reply(conn, cookie, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +158,7 @@ namespace xcb {
|
||||||
* @param reply The reply for the property
|
* @param reply The reply for the property
|
||||||
* @return The value length for the property
|
* @return The value length for the property
|
||||||
*/
|
*/
|
||||||
inline fn GetPropertyValueLength(const get_property_reply_t* reply) -> int {
|
inline fn GetPropertyValueLength(const GetPropReply* reply) -> i32 {
|
||||||
return xcb_get_property_value_length(reply);
|
return xcb_get_property_value_length(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +168,7 @@ namespace xcb {
|
||||||
* @param reply The reply for the property
|
* @param reply The reply for the property
|
||||||
* @return The value for the property
|
* @return The value for the property
|
||||||
*/
|
*/
|
||||||
inline fn GetPropertyValue(const get_property_reply_t* reply) -> void* {
|
inline fn GetPropertyValue(const GetPropReply* reply) -> void* {
|
||||||
return xcb_get_property_value(reply);
|
return xcb_get_property_value(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,15 +177,16 @@ namespace xcb {
|
||||||
* Automatically handles resource acquisition and cleanup
|
* Automatically handles resource acquisition and cleanup
|
||||||
*/
|
*/
|
||||||
class DisplayGuard {
|
class DisplayGuard {
|
||||||
connection_t* m_connection = nullptr; ///< The connection to the display
|
Connection* m_connection = nullptr; ///< The connection to the display
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Opens an XCB connection
|
* Opens an XCB connection
|
||||||
* @param name Display name (nullptr for default)
|
* @param name Display name (nullptr for default)
|
||||||
*/
|
*/
|
||||||
explicit DisplayGuard(const util::types::CStr name = nullptr)
|
explicit DisplayGuard(const CStr name = nullptr)
|
||||||
: m_connection(Connect(name, nullptr)) {}
|
: m_connection(Connect(name, nullptr)) {}
|
||||||
|
|
||||||
~DisplayGuard() {
|
~DisplayGuard() {
|
||||||
if (m_connection)
|
if (m_connection)
|
||||||
Disconnect(m_connection);
|
Disconnect(m_connection);
|
||||||
|
@ -229,7 +227,7 @@ namespace xcb {
|
||||||
* @brief Get the connection to the display
|
* @brief Get the connection to the display
|
||||||
* @return The connection to the display
|
* @return The connection to the display
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] fn get() const -> connection_t* {
|
[[nodiscard]] fn get() const -> Connection* {
|
||||||
return m_connection;
|
return m_connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +235,7 @@ namespace xcb {
|
||||||
* @brief Get the setup for the display
|
* @brief Get the setup for the display
|
||||||
* @return The setup for the display
|
* @return The setup for the display
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] fn setup() const -> const setup_t* {
|
[[nodiscard]] fn setup() const -> const Setup* {
|
||||||
return m_connection ? xcb_get_setup(m_connection) : nullptr;
|
return m_connection ? xcb_get_setup(m_connection) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,8 +243,9 @@ namespace xcb {
|
||||||
* @brief Get the root screen for the display
|
* @brief Get the root screen for the display
|
||||||
* @return The root screen for the display
|
* @return The root screen for the display
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] fn rootScreen() const -> screen_t* {
|
[[nodiscard]] fn rootScreen() const -> Screen* {
|
||||||
const setup_t* setup = this->setup();
|
const Setup* setup = this->setup();
|
||||||
|
|
||||||
return setup ? xcb_setup_roots_iterator(setup).data : nullptr;
|
return setup ? xcb_setup_roots_iterator(setup).data : nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -335,6 +334,6 @@ namespace xcb {
|
||||||
return *m_reply;
|
return *m_reply;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace xcb
|
} // namespace XCB
|
||||||
|
|
||||||
#endif // __linux__ || __FreeBSD__ || __DragonFly__ || __NetBSD__
|
#endif // __linux__ || __FreeBSD__ || __DragonFly__ || __NetBSD__
|
||||||
|
|
|
@ -10,9 +10,12 @@
|
||||||
#include <iostream> // std::cout
|
#include <iostream> // std::cout
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Config/Config.hpp"
|
|
||||||
#include "Core/SystemData.hpp"
|
#include "Core/SystemData.hpp"
|
||||||
|
|
||||||
|
#include "Config/Config.hpp"
|
||||||
|
|
||||||
#include "UI/UI.hpp"
|
#include "UI/UI.hpp"
|
||||||
|
|
||||||
#include "Util/Definitions.hpp"
|
#include "Util/Definitions.hpp"
|
||||||
#include "Util/Logging.hpp"
|
#include "Util/Logging.hpp"
|
||||||
#include "Util/Types.hpp"
|
#include "Util/Types.hpp"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue