diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2022-09-16 23:28:09 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2022-09-16 23:28:09 +0200 |
| commit | f4d9880d3c9555b48affad727589ef5c093b1841 (patch) | |
| tree | a5552b5a33000a527748ac1c72ca366476af0936 /source/src/wanda | |
| parent | 64922e213ac731279cf3341253e67509adb2dfc8 (diff) | |
| download | wanda-f4d9880d3c9555b48affad727589ef5c093b1841.tar.xz wanda-f4d9880d3c9555b48affad727589ef5c093b1841.zip | |
source: clean up structure
Diffstat (limited to 'source/src/wanda')
| -rw-r--r-- | source/src/wanda/command.cpp | 47 | ||||
| -rw-r--r-- | source/src/wanda/commander.cpp | 77 | ||||
| -rw-r--r-- | source/src/wanda/control_connection.cpp | 120 | ||||
| -rw-r--r-- | source/src/wanda/control_interface.cpp | 154 | ||||
| -rw-r--r-- | source/src/wanda/environment.cpp | 71 | ||||
| -rw-r--r-- | source/src/wanda/filesystem.cpp | 31 | ||||
| -rw-r--r-- | source/src/wanda/logging.cpp | 21 | ||||
| -rw-r--r-- | source/src/wanda/message.cpp | 75 | ||||
| -rw-r--r-- | source/src/wanda/setting.cpp | 102 | ||||
| -rw-r--r-- | source/src/wanda/wallpaper.cpp | 95 | ||||
| -rw-r--r-- | source/src/wanda/wandac.cpp | 94 | ||||
| -rw-r--r-- | source/src/wanda/wandad.cpp | 146 | ||||
| -rw-r--r-- | source/src/wanda/xdg.cpp | 46 |
13 files changed, 0 insertions, 1079 deletions
diff --git a/source/src/wanda/command.cpp b/source/src/wanda/command.cpp deleted file mode 100644 index 960c52b..0000000 --- a/source/src/wanda/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/src/wanda/commander.cpp b/source/src/wanda/commander.cpp deleted file mode 100644 index 85fc68a..0000000 --- a/source/src/wanda/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/src/wanda/control_connection.cpp b/source/src/wanda/control_connection.cpp deleted file mode 100644 index 40e29f3..0000000 --- a/source/src/wanda/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/src/wanda/control_interface.cpp b/source/src/wanda/control_interface.cpp deleted file mode 100644 index c008920..0000000 --- a/source/src/wanda/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); - } - 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/src/wanda/environment.cpp b/source/src/wanda/environment.cpp deleted file mode 100644 index 533a5f5..0000000 --- a/source/src/wanda/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/src/wanda/filesystem.cpp b/source/src/wanda/filesystem.cpp deleted file mode 100644 index 4da30b1..0000000 --- a/source/src/wanda/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/src/wanda/logging.cpp b/source/src/wanda/logging.cpp deleted file mode 100644 index 8c61953..0000000 --- a/source/src/wanda/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/src/wanda/message.cpp b/source/src/wanda/message.cpp deleted file mode 100644 index 978b7c4..0000000 --- a/source/src/wanda/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/src/wanda/setting.cpp b/source/src/wanda/setting.cpp deleted file mode 100644 index f0cf7a7..0000000 --- a/source/src/wanda/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/src/wanda/wallpaper.cpp b/source/src/wanda/wallpaper.cpp deleted file mode 100644 index 7d4c7d5..0000000 --- a/source/src/wanda/wallpaper.cpp +++ /dev/null @@ -1,95 +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 source_view = ; - - // return fmt::format("#{:02X}{:02X}{:02X}", - // static_cast<uint8_t>(std::sqrt((at_c<0>(pixel64) / image.size()))), - // static_cast<uint8_t>(std::sqrt((at_c<1>(pixel64) / image.size()))), - // static_cast<uint8_t>(std::sqrt((at_c<2>(pixel64) / image.size())))); - } - - 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"); }; - }) || - [&] { get_logger()->error("invalid setting"); }; - } - -} // namespace wanda
\ No newline at end of file diff --git a/source/src/wanda/wandac.cpp b/source/src/wanda/wandac.cpp deleted file mode 100644 index 1873ef4..0000000 --- a/source/src/wanda/wandac.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include <wanda/command.hpp> -#include <wanda/commander.hpp> -#include <wanda/environment.hpp> -#include <wanda/logging.hpp> -#include <wanda/xdg.hpp> - -#include <asio.hpp> -#include <lyra/lyra.hpp> -#include <spdlog/sinks/stdout_color_sinks.h> -#include <spdlog/spdlog.h> - -#include <cstdlib> -#include <filesystem> -#include <iostream> -#include <memory> - -struct cli -{ - std::string command{}; - bool help{}; - - lyra::cli_parser parser{}; - - auto parse(int argc, char const * const * argv, std::ostream & error) - { - parser |= lyra::arg{command, "command"}("The command to send to the deamon").required() | - lyra::help(help); - - auto result = parser.parse({argc, argv}); - - if (!result) - { - error << "Error while processing command line arguments: " - << result.message() - << '\n' - << parser - << '\n'; - return false; - } - - return true; - } -}; - -struct listener : wanda::commander::listener -{ - listener(::cli & cli, asio::io_service & service) - : m_cli{cli} - , m_service{service} - { - } - - void on_connected(wanda::commander & commander) override - { - if (m_cli.command == "change") - { - commander.send(wanda::make_change_command()); - m_service.post([&]{ - commander.stop(); - }); - } - } - -private: - ::cli & m_cli; - asio::io_service & m_service; -}; - -int main(int argc, char const * const * argv) -{ - auto cli = ::cli{}; - if (!cli.parse(argc, argv, std::cerr)) - { - return EXIT_FAILURE; - } - else if (cli.help) - { - std::cout << cli.parser << '\n'; - return EXIT_SUCCESS; - } - - wanda::initialize_logger(std::make_shared<spdlog::sinks::stderr_color_sink_st>()); - - auto interface = wanda::xdg_path_for(wanda::xdg_directory::runtime_dir, wanda::environment{}) / ".wanda_interface"; - auto service = asio::io_service{}; - auto listener = ::listener{cli, service}; - - auto commander = wanda::commander{service, interface, listener}; - - wanda::get_logger()->info("trying to connect to wanda control interface on '{}'", interface.native()); - commander.start(); - - service.run(); -} diff --git a/source/src/wanda/wandad.cpp b/source/src/wanda/wandad.cpp deleted file mode 100644 index 8579a83..0000000 --- a/source/src/wanda/wandad.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#include <wanda/command.hpp> -#include <wanda/control_interface.hpp> -#include <wanda/environment.hpp> -#include <wanda/filesystem.hpp> -#include <wanda/logging.hpp> -#include <wanda/optional.hpp> -#include <wanda/setting.hpp> -#include <wanda/wallpaper.hpp> -#include <wanda/xdg.hpp> - -#include <asio.hpp> -#include <lyra/lyra.hpp> -#include <spdlog/sinks/stdout_color_sinks.h> - -#include <csignal> -#include <cstdlib> -#include <iostream> -#include <set> -#include <string> - -namespace -{ - constexpr auto image_filter = [](auto const & path) { - static auto const extensions = std::set<std::filesystem::path>{ - std::filesystem::path{".jpg"}, - std::filesystem::path{".png"}, - }; - - if (!std::filesystem::is_regular_file(path)) - { - return false; - } - - return extensions.find(path.extension()) != extensions.cend(); - }; - - struct cli - { - std::string wallpaper_directory{}; - bool help{}; - - lyra::cli_parser parser{}; - - auto parse(int argc, char const * const * argv, std::ostream & error) - { - parser |= lyra::arg{wallpaper_directory, "directory"}("The wallpaper source directory").required() | - lyra::help(help); - - auto result = parser.parse({argc, argv}); - - if (!result) - { - error << "Error while processing command line arguments: " - << result.message() - << '\n' - << parser - << '\n'; - return false; - } - - return true; - } - }; - - struct listener : wanda::control_interface::listener - { - listener(std::vector<std::filesystem::path> const & wallpapers) - : m_wallpapers{wallpapers} - { - } - - void on_received(wanda::control_interface & interface, wanda::command command) override - { - switch (command.id) - { - case wanda::command_id::change: { - auto wallpaper = wanda::random_pick(m_wallpapers); - wanda::get_logger()->info("changing wallpaper to '{}'", wallpaper.native()); - wanda::set_wallpaper(wallpaper); - break; - } - default: - wanda::get_logger()->error("received unknown command '{}'", static_cast<int>(command.id)); - } - } - - private: - std::vector<std::filesystem::path> const & m_wallpapers; - }; - -} // namespace - -int main(int argc, char const * const * argv) -{ - using namespace wanda::std_ext; - - auto cli = ::cli{}; - if (!cli.parse(argc, argv, std::cerr)) - { - return EXIT_FAILURE; - } - else if (cli.help) - { - std::cout << cli.parser << '\n'; - return EXIT_SUCCESS; - } - - wanda::initialize_logger(std::make_shared<spdlog::sinks::stdout_color_sink_st>()); - wanda::get_logger()->info("wanda is starting up"); - - with(wanda::scan({cli.wallpaper_directory}, image_filter), [&](auto const & list) { - auto service = asio::io_service{}; - auto socket_path = wanda::xdg_path_for(wanda::xdg_directory::runtime_dir, wanda::environment{}) / ".wanda_interface"; - - wanda::get_logger()->info("starting control interface on '{}'", socket_path.native()); - auto listener = ::listener{list}; - auto interface = wanda::make_interface(service, socket_path, listener); - - if (!interface) - { - wanda::get_logger()->error("failed to start control interface"); - return; - } - - if (interface->start()) - { - return; - } - - auto signals = asio::signal_set{service, SIGINT, SIGTERM}; - signals.async_wait([&](auto const & error, auto const signal) { - if (!error) - { - wanda::get_logger()->info("Received signal {}. terminating...", signal); - interface->shutdown(); - service.stop(); - } - }); - - auto wallpaper = wanda::random_pick(list); - wanda::set_wallpaper(wallpaper); - - service.run(); - }) || - [&] { wanda::get_logger()->error("wallpaper directory does not exist"); }; -} diff --git a/source/src/wanda/xdg.cpp b/source/src/wanda/xdg.cpp deleted file mode 100644 index d49e53f..0000000 --- a/source/src/wanda/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 |
