diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2023-08-17 12:32:50 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2023-08-17 12:32:50 +0200 |
| commit | 375799fa79d1af76f33299acc20a11a167a021f8 (patch) | |
| tree | 8f91b982ec96225c33a2f4871730ababffe5cab0 /source/lib/src | |
| parent | af471b9b780869915d3217b228e24d025892de47 (diff) | |
| download | wanda-375799fa79d1af76f33299acc20a11a167a021f8.tar.xz wanda-375799fa79d1af76f33299acc20a11a167a021f8.zip | |
project: restructure libraries and build env
Diffstat (limited to 'source/lib/src')
| -rw-r--r-- | source/lib/src/command.cpp | 47 | ||||
| -rw-r--r-- | source/lib/src/commander.cpp | 77 | ||||
| -rw-r--r-- | source/lib/src/control_connection.cpp | 120 | ||||
| -rw-r--r-- | source/lib/src/control_interface.cpp | 154 | ||||
| -rw-r--r-- | source/lib/src/environment.cpp | 71 | ||||
| -rw-r--r-- | source/lib/src/filesystem.cpp | 31 | ||||
| -rw-r--r-- | source/lib/src/logging.cpp | 21 | ||||
| -rw-r--r-- | source/lib/src/message.cpp | 75 | ||||
| -rw-r--r-- | source/lib/src/setting.cpp | 102 | ||||
| -rw-r--r-- | source/lib/src/wallpaper.cpp | 91 | ||||
| -rw-r--r-- | source/lib/src/xdg.cpp | 46 |
11 files changed, 0 insertions, 835 deletions
diff --git a/source/lib/src/command.cpp b/source/lib/src/command.cpp deleted file mode 100644 index 83c6b73..0000000 --- a/source/lib/src/command.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "wanda/command.hpp" - -namespace wanda -{ - std::optional<message> command::message() const - { - using namespace std::string_literals; - auto const command = [this] { - switch (id) - { - case command_id::change: - return "CHANGE"s; - default: - return ""s; - } - }(); - - auto argument_string = std::string{}; - for (int index = 0ul; index < arguments.size(); ++index) - { - argument_string += (index) ? "," + arguments[index] : arguments[index]; - } - - if (command.empty()) - { - return std::nullopt; - } - - return wanda::message{"C", command, argument_string}; - } - - std::optional<command> make_command(message message) - { - if (message.command == "CHANGE") - { - return {{command_id::change}}; - } - - return std::nullopt; - } - - command make_change_command() - { - return {command_id::change}; - } - -} // namespace wanda
\ No newline at end of file diff --git a/source/lib/src/commander.cpp b/source/lib/src/commander.cpp deleted file mode 100644 index 5122b62..0000000 --- a/source/lib/src/commander.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "wanda/commander.hpp" -#include "wanda/logging.hpp" -#include "wanda/message.hpp" -#include "wanda/optional.hpp" - -#include <spdlog/fmt/ostr.h> - -namespace wanda -{ - commander::commander(asio::io_service & service, std::filesystem::path socket, listener & listener) - : m_service{service} - , m_endpoint{socket.string()} - , m_socket{service} - , m_listener{listener} - { - } - - void commander::start() - { - m_socket.async_connect(m_endpoint, [&](auto const & error) { - if (error) - { - get_logger()->error("error while connecting to control interface: '{}'", error.message()); - } - else - { - get_logger()->info("establishing connection to wanda deamon"); - m_connection = wanda::make_control_connection(std::move(m_socket)); - m_connection->add(this); - m_connection->start(); - m_connection->send({message_source_controller, message_command_hello, message_argument_hello}); - } - }); - } - - void commander::stop() - { - get_logger()->info("closing control connection"); - m_connection->close(); - } - - void commander::send(command command) - { - using namespace wanda::std_ext; - - if (!m_connection || m_connection->current_state() != control_connection::state::established) - { - get_logger()->error("tried to send command without an established connection"); - m_listener.on_error(*this, "tried to send command without an established connection"); - return; - } - - with(command.message(), [&](auto const & message) { m_connection->send(message); }) || - [&] { get_logger()->error("unknown command"); }; - } - - void commander::on_error(control_connection::pointer connection, std::error_code error) - { - get_logger()->error("control interface communication error: '{}'", error.message()); - } - - void commander::on_received(wanda::control_connection::pointer connection, message message) - { - if (auto state = connection->current_state(); message.command == "HELLO" && state == control_connection::state::fresh) - { - get_logger()->info("connection to wanda deamon successfully established"); - connection->update(control_connection::state::established); - m_listener.on_connected(*this); - } - else - { - get_logger()->error("unexpected message: '{}'", message); - m_listener.on_error(*this, "unexpected message '" + static_cast<std::string>(message) + '\''); - } - } - -} // namespace wanda
\ No newline at end of file diff --git a/source/lib/src/control_connection.cpp b/source/lib/src/control_connection.cpp deleted file mode 100644 index ace13d2..0000000 --- a/source/lib/src/control_connection.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "wanda/control_connection.hpp" - -#include <limits> - -namespace wanda -{ - control_connection::pointer make_control_connection(control_connection::protocol::socket && socket) - { - return std::make_shared<control_connection>(control_connection::key{}, std::move(socket)); - } - - control_connection::control_connection(control_connection::key key, control_connection::protocol::socket socket) - : keyed{key} - , m_socket{std::move(socket)} - { - } - - bool control_connection::add(listener * listener) - { - auto [_, inserted] = m_listeners.insert(listener); - return inserted; - } - - bool control_connection::remove(listener * listener) - { - return m_listeners.erase(listener); - } - - void control_connection::start() - { - if (m_state == state::unknown) - { - m_state = state::fresh; - perform_read(); - } - } - - void control_connection::send(message message) - { - m_output << message << '\n'; - asio::async_write(m_socket, m_out, asio::transfer_exactly(message.size() + 1), [that = shared_from_this(), this](auto const & error, auto const length) { - if (error) - { - // TODO: Handle error - } - else - { - m_out.consume(length); - } - }); - } - - void control_connection::close() - { - if (auto error = std::error_code{}; m_socket.cancel(error)) - { - for (auto & listener : m_listeners) - { - listener->on_error(shared_from_this(), error); - } - } - - if (auto error = std::error_code{}; m_socket.close(error)) - { - for (auto & listener : m_listeners) - { - listener->on_error(shared_from_this(), error); - } - } - - for (auto & listener : m_listeners) - { - listener->on_close(shared_from_this()); - } - m_listeners.clear(); - } - - void control_connection::update(state state) - { - m_state = state; - } - - control_connection::state control_connection::current_state() const - { - return m_state; - } - - void control_connection::perform_read() - { - asio::async_read_until(m_socket, m_in, '\n', [that = shared_from_this(), this](auto const & error, auto const length) { - if (error) - { - for (auto & listener : m_listeners) - { - listener->on_error(shared_from_this(), error); - } - close(); - } - else - { - auto msg = message{}; - m_input >> msg; - if (!m_input) - { - m_input.ignore(std::numeric_limits<std::streamsize>::max()); - m_input.clear(); - } - else - { - for (auto & listener : m_listeners) - { - listener->on_received(shared_from_this(), msg); - } - } - perform_read(); - } - }); - } - -} // namespace wanda
\ No newline at end of file diff --git a/source/lib/src/control_interface.cpp b/source/lib/src/control_interface.cpp deleted file mode 100644 index 68005f9..0000000 --- a/source/lib/src/control_interface.cpp +++ /dev/null @@ -1,154 +0,0 @@ -#include "wanda/control_interface.hpp" -#include "wanda/logging.hpp" -#include "wanda/optional.hpp" - -#include <spdlog/fmt/ostr.h> - -#include <unistd.h> - -#include <algorithm> -#include <iterator> -#include <string> -#include <system_error> -#include <utility> - -namespace wanda -{ - // 'socket_deleter' implementation - - socket_deleter::~socket_deleter() - { - if (std::filesystem::exists(path)) - { - std::filesystem::remove(path); - } - } - - // 'control_interface' implementation - - control_interface::control_interface(control_interface::key key, asio::io_service & service, control_interface::protocol::endpoint endpoint, listener & listener) - : keyed{key} - , m_service{service} - , m_endpoint{std::move(endpoint)} - , m_socket{m_service} - , m_acceptor{m_service} - , m_listener{listener} - { - } - - std::error_code control_interface::start() - { - if (auto error = std::error_code{}; m_acceptor.open(m_endpoint.protocol(), error)) - { - return error; - } - - if (auto error = std::error_code{}; m_acceptor.bind(m_endpoint, error)) - { - return error; - } - - if (auto error = std::error_code{}; m_acceptor.listen(128, error)) - { - return error; - } - else - { - perform_accept(); - return error; - } - } - - std::error_code control_interface::shutdown() - { - for (auto & connection : m_connections) - { - connection->close(); - } - - auto error = std::error_code{}; - return m_acceptor.close(error); - } - - void control_interface::perform_accept() - { - m_acceptor.async_accept(m_socket, [that = shared_from_this(), this](auto const & error) { - if (error && error != asio::error::operation_aborted) - { - get_logger()->error("failed to accept connection because '{}'", error.message()); - } - else - { - get_logger()->info("new incoming controller connection"); - auto [connection, inserted] = m_connections.insert(make_control_connection(std::move(m_socket))); - if (inserted) - { - (*connection)->add(this); - (*connection)->start(); - } - perform_accept(); - } - }); - } - - void control_interface::on_close(control_connection::pointer connection) - { - if (static_cast<char>(connection->current_state()) >= static_cast<char>(control_connection::state::established)) - { - get_logger()->info("controller connection closed"); - } - else - { - get_logger()->info("controller connection aborted before it could be established"); - } - m_connections.erase(connection); - } - - void control_interface::on_received(control_connection::pointer connection, message message) - { - using namespace wanda::std_ext; - - if (m_connections.find(connection) == m_connections.cend()) - { - get_logger()->error("received message from an unknown connection"); - return; - } - - if (message.source != message_source_controller) - { - get_logger()->error("received a deamon message"); - return; - } - - if (auto state = connection->current_state(); message.command == message_command_hello && state == control_connection::state::fresh) - { - get_logger()->info("controller connection established"); - if (message.argument.has_value()) - { - get_logger()->info("remote controller version '{}'", *message.argument); - } - connection->send({message_source_daemon, message_command_hello, message_argument_hello}); - connection->update(control_connection::state::established); - } - else - { - with(make_command(message), [&](auto const & command) { - m_listener.on_received(*this, command); - }) || - [&] { get_logger()->warn("ignoring unknown message '{}'", message); }; - } - } - - control_interface::pointer make_interface(asio::io_service & service, std::filesystem::path socket, control_interface::listener & listener) - { - if (std::filesystem::exists(socket)) - { - get_logger()->error("socket '{}' exists", socket.native()); - return {}; - } - - control_interface::protocol::endpoint endpoint{socket.string()}; - return std::make_shared<control_interface>(control_interface::key{}, service, std::move(endpoint), listener); - } - -} // namespace wanda
\ No newline at end of file diff --git a/source/lib/src/environment.cpp b/source/lib/src/environment.cpp deleted file mode 100644 index 2f1af0a..0000000 --- a/source/lib/src/environment.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "wanda/environment.hpp" - -#include <string> - -namespace wanda -{ - environment::environment(char const * const * env) - { - if (!env) - { - return; - } - - std::string buffer{}; - for (; *env != nullptr; ++env) - { - buffer = *env; - int split_point = buffer.find('='); - if (split_point != std::string::npos) - { - m_cache[buffer.substr(0, split_point)] = buffer.substr(split_point + 1); - } - } - } - - std::string & environment::operator[](std::string const & variable) - { - return m_cache[variable]; - } - - std::string const & environment::operator[](std::string const & variable) const - { - static std::string const empty{}; - if (auto needle = m_cache.find(variable); needle != cend()) - { - return needle->second; - } - return empty; - } - - environment::iterator environment::begin() - { - return m_cache.begin(); - } - - environment::const_iterator environment::begin() const - { - return m_cache.begin(); - } - - environment::const_iterator environment::cbegin() const - { - return m_cache.cbegin(); - } - - environment::iterator environment::end() - { - return m_cache.end(); - } - - environment::const_iterator environment::end() const - { - return m_cache.end(); - } - - environment::const_iterator environment::cend() const - { - return m_cache.cend(); - } - -} // namespace wanda
\ No newline at end of file diff --git a/source/lib/src/filesystem.cpp b/source/lib/src/filesystem.cpp deleted file mode 100644 index 35b6b40..0000000 --- a/source/lib/src/filesystem.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "wanda/filesystem.hpp" - -#include <random> -#include <ranges> - -namespace wanda -{ - std::optional<path_list> scan(std::filesystem::path source, bool(filter)(std::filesystem::path const &)) - { - if (!std::filesystem::is_directory(source)) - { - return std::nullopt; - } - auto entries = std::filesystem::recursive_directory_iterator{source}; - auto result = path_list{}; - for (auto & entry : entries | std::views::filter(filter)) - { - result.push_back(entry.path()); - } - return result; - } - - std::filesystem::path random_pick(path_list const & paths) - { - static auto generator = std::mt19937{std::random_device{}()}; - auto distribution = std::uniform_int_distribution<std::size_t>{0, paths.size() - 1}; - - return paths[distribution(generator)]; - } - -} // namespace wanda
\ No newline at end of file diff --git a/source/lib/src/logging.cpp b/source/lib/src/logging.cpp deleted file mode 100644 index 0aa7e40..0000000 --- a/source/lib/src/logging.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "wanda/logging.hpp" - -namespace wanda -{ - std::function<void(spdlog::sink_ptr)> initializer = [](spdlog::sink_ptr sink) { - spdlog::register_logger(std::make_shared<spdlog::logger>("wanda", sink)); - initializer = [](auto) {}; - }; - - void initialize_logger(spdlog::sink_ptr sink) - { - initializer(sink); - } - - logger_ptr get_logger() - { - initialize_logger(); - return spdlog::get("wanda"); - } - -} // namespace wanda
\ No newline at end of file diff --git a/source/lib/src/message.cpp b/source/lib/src/message.cpp deleted file mode 100644 index 34930bc..0000000 --- a/source/lib/src/message.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "wanda/message.hpp" - -#include <ios> -#include <iterator> -#include <sstream> - -namespace wanda -{ - message::operator std::string() const - { - std::ostringstream buffer{}; - buffer << source - << ':' - << command; - if (argument.has_value()) - { - buffer << ':' << *argument; - } - return buffer.str(); - } - - std::size_t message::size() const - { - return static_cast<std::string>(*this).size(); - } - - template<typename InputIt, typename OutputIt, typename UnaryPredicate> - OutputIt copy_until(InputIt first, InputIt last, OutputIt out, UnaryPredicate predicate) - { - while (first != last && !predicate(*first)) - { - *out++ = *first++; - } - return out; - } - - std::istream & operator>>(std::istream & in, message & message) - { - auto pos = std::istream_iterator<char>{in}; - auto end = std::istream_iterator<char>{}; - auto buffer = std::string{}; - - copy_until(pos, end, std::back_inserter(buffer), [](auto const & c) { return c == ':'; }); - if (in.eof() || buffer.size() != 1) - { - in.setstate(std::ios_base::failbit); - return in; - } - message.source = buffer; - - buffer.clear(); - copy_until(++pos, end, std::back_inserter(buffer), [](auto const & c) { return c == ':'; }); - if (in.eof()) - { - in.setstate(std::ios_base::failbit); - } - message.command = buffer; - - buffer.clear(); - copy(++pos, end, std::back_inserter(buffer)); - if (buffer.size()) - { - message.argument = std::optional{std::move(buffer)}; - } - - in.clear(in.rdstate() ^ std::ios_base::failbit); - return in; - } - - std::ostream & operator<<(std::ostream & out, message const & message) - { - return out << static_cast<std::string>(message); - } - -} // namespace wanda
\ No newline at end of file diff --git a/source/lib/src/setting.cpp b/source/lib/src/setting.cpp deleted file mode 100644 index b3f661e..0000000 --- a/source/lib/src/setting.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "wanda/setting.hpp" - -#include <algorithm> -#include <type_traits> - -namespace wanda -{ - // UDL implementations - - key literals::operator""_key(char const * str, std::size_t len) - { - return key{{str, len}}; - } - - std::optional<setting> literals::operator""_setting(char const * str, std::size_t len) - { - auto source = g_settings_schema_source_get_default(); - if (!source) - { - return std::nullopt; - } - - auto schema = g_settings_schema_source_lookup(source, str, true); - if (!schema) - { - return std::nullopt; - } - - return setting{schema}; - } - - // 'setting' implementation - - setting::setting(GSettingsSchema * schema) - : m_schema{schema, &g_settings_schema_unref} - { - } - - std::optional<setting::entry> setting::operator[](key key) const - { - if (!g_settings_schema_has_key(m_schema.get(), key.get().c_str())) - { - return std::nullopt; - } - - return setting::entry{*this, std::move(key)}; - } - - // 'setting::entry' implementation - - setting::entry::entry(setting const & setting, key key) - : m_settings{g_settings_new(g_settings_schema_get_id(setting.m_schema.get())), &g_object_unref} - , m_key{key.get()} - { - } - - setting::entry::value_type setting::entry::operator*() const - { - auto value = std::unique_ptr<GVariant, decltype(&g_variant_unref)>{g_settings_get_value(m_settings.get(), m_key.get().c_str()), &g_variant_unref}; - auto raw = value.get(); - - if (g_variant_is_of_type(raw, G_VARIANT_TYPE_BOOLEAN)) - { - return static_cast<bool>(g_variant_get_boolean(raw)); - } - else if (g_variant_is_of_type(raw, G_VARIANT_TYPE_INT32)) - { - return static_cast<std::int32_t>(g_variant_get_int32(raw)); - } - else if (g_variant_is_of_type(raw, G_VARIANT_TYPE_INT64)) - { - return static_cast<std::int64_t>(g_variant_get_int64(raw)); - } - else if (g_variant_is_of_type(raw, G_VARIANT_TYPE_UINT32)) - { - return static_cast<std::uint32_t>(g_variant_get_uint32(raw)); - } - else if (g_variant_is_of_type(raw, G_VARIANT_TYPE_UINT64)) - { - return static_cast<std::uint64_t>(g_variant_get_uint64(raw)); - } - else if (g_variant_is_of_type(raw, G_VARIANT_TYPE_DOUBLE)) - { - return static_cast<double>(g_variant_get_double(raw)); - } - else if (g_variant_is_of_type(raw, G_VARIANT_TYPE_STRING)) - { - auto size = gsize{}; - auto string = g_variant_get_string(raw, &size); - return std::string{string, size}; - } - else if (g_variant_is_of_type(raw, G_VARIANT_TYPE_STRING_ARRAY)) - { - auto length = gsize{}; - auto data = g_variant_get_strv(raw, &length); - return std::vector<std::string>{data, data + length}; - } - - return {}; - } - -} // namespace wanda
\ No newline at end of file diff --git a/source/lib/src/wallpaper.cpp b/source/lib/src/wallpaper.cpp deleted file mode 100644 index c9c5cfe..0000000 --- a/source/lib/src/wallpaper.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include "wanda/logging.hpp" -#include "wanda/magic.hpp" -#include "wanda/optional.hpp" -#include "wanda/setting.hpp" -#include "wanda/wallpaper.hpp" - -#include <boost/gil.hpp> -#include <boost/gil/extension/io/jpeg.hpp> -#include <boost/gil/extension/io/png.hpp> -#include <boost/gil/extension/numeric/resample.hpp> -#include <boost/gil/extension/numeric/sampler.hpp> - -#include <fmt/format.h> - -#include <algorithm> -#include <cmath> -#include <memory> - -namespace wanda -{ - namespace - { - auto magic_instance = magic{}; - - auto load_image(std::filesystem::path wallpaper) - { - auto image = boost::gil::rgb8_image_t{}; - - switch (magic_instance.type(wallpaper)) - { - case magic::mime_type::image_jpeg: - boost::gil::read_and_convert_image(wallpaper.native(), image, boost::gil::jpeg_tag{}); - break; - case magic::mime_type::image_png: - boost::gil::read_and_convert_image(wallpaper.native(), image, boost::gil::png_tag{}); - break; - } - - return image; - } - - auto average_colors(boost::gil::rgb8_image_t image) - { - auto accumulator = boost::gil::rgb64f_pixel_t{}; - auto view = const_view(image); - - std::ranges::for_each(view, [&](auto const & source_pixel) { - at_c<0>(accumulator) += std::pow(boost::gil::at_c<0>(source_pixel), 2); - at_c<1>(accumulator) += std::pow(boost::gil::at_c<1>(source_pixel), 2); - at_c<2>(accumulator) += std::pow(boost::gil::at_c<2>(source_pixel), 2); - }); - - at_c<0>(accumulator) = std::sqrt(at_c<0>(accumulator) / view.size()); - at_c<1>(accumulator) = std::sqrt(at_c<1>(accumulator) / view.size()); - at_c<2>(accumulator) = std::sqrt(at_c<2>(accumulator) / view.size()); - - return accumulator; - } - - } // namespace - - void set_wallpaper(std::filesystem::path wallpaper) - { - using namespace wanda::literals; - using namespace wanda::std_ext; - using namespace std::string_literals; - - auto image = load_image(wallpaper); - auto color = average_colors(std::move(image)); - auto hexstring = fmt::format("#{:02X}{:02X}{:02X}", - static_cast<std::uint8_t>(at_c<0>(color)), - static_cast<std::uint8_t>(at_c<1>(color)), - static_cast<std::uint8_t>(at_c<2>(color))); - - with("org.gnome.desktop.background"_setting, [&](auto & setting) { - with(setting["primary-color"_key], [&](auto & value) { - value = hexstring; - }); - with(setting["picture-uri"_key], [&](auto & value) { - value = "file://" + wallpaper.native(); - }) || - [&] { get_logger()->error("invalid settings key"); }; - with(setting["picture-uri-dark"_key], [&](auto & value) { - value = "file://" + wallpaper.native(); - }) || - [&] { get_logger()->error("invalid settings key"); }; - }) || - [&] { get_logger()->error("invalid setting"); }; - } - -} // namespace wanda diff --git a/source/lib/src/xdg.cpp b/source/lib/src/xdg.cpp deleted file mode 100644 index cfd1719..0000000 --- a/source/lib/src/xdg.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "wanda/xdg.hpp" - -#include <unistd.h> - -namespace wanda -{ - std::string xdg_variable(xdg_directory directory) - { - switch (directory) - { - case xdg_directory::data_home: - return "XDG_DATA_HOME"; - case xdg_directory::config_home: - return "XDG_CONFIG_HOME"; - case xdg_directory::cache_home: - return "XDG_CACHE_HOME"; - case xdg_directory::runtime_dir: - return "XDG_RUNTIME_DIR"; - } - return "XDG_INVALID_PATH"; - } - - std::filesystem::path xdg_path_for(xdg_directory directory, environment const & environment) - { - if (auto path = environment[xdg_variable(directory)]; !path.empty()) - { - return path; - } - - auto home = std::filesystem::path{environment["HOME"]}; - switch (directory) - { - case xdg_directory::data_home: - return home / ".local/share"; - case xdg_directory::config_home: - return home / ".config"; - case xdg_directory::cache_home: - return home / ".cache"; - case xdg_directory::runtime_dir: - return std::filesystem::path{"/run/user"} / std::to_string(::getuid()); - } - - return ""; - } - -} // namespace wanda
\ No newline at end of file |
