aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@gmail.com>2018-11-30 10:48:44 +0100
committerFelix Morgner <felix.morgner@gmail.com>2018-11-30 10:48:44 +0100
commit5b2974cd16b5d2841b72c7d0cc4a34469a8ded5b (patch)
tree27fe6f0b428a1e02f7fe7c677795bdd989e0498c /src
parent543e91dc65d839864b42114b353d0c30db4dcdd1 (diff)
downloadwanda-5b2974cd16b5d2841b72c7d0cc4a34469a8ded5b.tar.xz
wanda-5b2974cd16b5d2841b72c7d0cc4a34469a8ded5b.zip
core: implement basic XDG Base Specification support
Diffstat (limited to 'src')
-rw-r--r--src/environment.cpp73
-rw-r--r--src/environment.hpp39
-rw-r--r--src/wandac.cpp10
-rw-r--r--src/wandad.cpp7
-rw-r--r--src/xdg.cpp47
-rw-r--r--src/xdg.hpp25
6 files changed, 199 insertions, 2 deletions
diff --git a/src/environment.cpp b/src/environment.cpp
new file mode 100644
index 0000000..2051573
--- /dev/null
+++ b/src/environment.cpp
@@ -0,0 +1,73 @@
+#include "environment.hpp"
+
+#include <iostream>
+#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/src/environment.hpp b/src/environment.hpp
new file mode 100644
index 0000000..a6322cb
--- /dev/null
+++ b/src/environment.hpp
@@ -0,0 +1,39 @@
+#ifndef WANDA_ENVIRONMENT_HPP
+#define WANDA_ENVIRONMENT_HPP
+
+#include <unistd.h>
+
+#include <map>
+#include <string>
+
+namespace wanda
+{
+
+struct environment
+{
+ using map_type = std::map<std::string, std::string>;
+ using iterator = map_type::iterator;
+ using const_iterator = map_type::const_iterator;
+ using reference = map_type::reference;
+ using const_reference = map_type::const_reference;
+
+ explicit environment(char const *const *env = ::environ);
+
+ std::string &operator[](std::string const &variable);
+ std::string const &operator[](std::string const &variable) const;
+
+ iterator begin();
+ const_iterator begin() const;
+ const_iterator cbegin() const;
+
+ iterator end();
+ const_iterator end() const;
+ const_iterator cend() const;
+
+ private:
+ map_type m_cache{};
+};
+
+} // namespace wanda
+
+#endif \ No newline at end of file
diff --git a/src/wandac.cpp b/src/wandac.cpp
index 8e068ae..db072ec 100644
--- a/src/wandac.cpp
+++ b/src/wandac.cpp
@@ -1,4 +1,6 @@
#include "control_connection.hpp"
+#include "environment.hpp"
+#include "xdg.hpp"
#include <boost/asio.hpp>
@@ -18,6 +20,7 @@ struct commander : wanda::control_connection::listener, std::enable_shared_from_
void start()
{
+ std::clog << "[commander::start] Starting commander on socket '" << m_endpoint.path() << "'\n";
m_socket.async_connect(m_endpoint, [&](auto const &error) {
if (error)
{
@@ -25,6 +28,7 @@ struct commander : wanda::control_connection::listener, std::enable_shared_from_
}
else
{
+ std::clog << "[commander::start] Control connection established\n";
m_connection = wanda::make_control_connection(std::move(m_socket));
m_connection->start();
send("C:HELLO:1.0.0\n");
@@ -56,8 +60,12 @@ struct commander : wanda::control_connection::listener, std::enable_shared_from_
int main()
{
+ auto environment = wanda::environment{};
+ auto interface = wanda::xdg_path_for(wanda::xdg_directory::runtime_dir, environment) / ".wanda_interface";
auto service = boost::asio::io_service{};
- auto command_processor = commander{service, std::filesystem::path{".wanda_interface"}};
+
+ std::clog << "[wandac::main] Initializing commander for socket '" << interface.native() << "'\n";
+ auto command_processor = commander{service, interface};
command_processor.start();
diff --git a/src/wandad.cpp b/src/wandad.cpp
index 169efd9..04f3394 100644
--- a/src/wandad.cpp
+++ b/src/wandad.cpp
@@ -1,8 +1,10 @@
#include "control_interface.hpp"
+#include "environment.hpp"
#include "filesystem.hpp"
#include "optional.hpp"
#include "setting.hpp"
#include "wallpaper.hpp"
+#include "xdg.hpp"
#include <boost/asio.hpp>
@@ -39,7 +41,10 @@ int main()
wanda::set_wallpaper(wallpaper);
auto service = boost::asio::io_service{};
- auto interface = wanda::make_interface(service, ".wanda_interface");
+ auto socket_path = wanda::xdg_path_for(wanda::xdg_directory::runtime_dir, wanda::environment{}) / ".wanda_interface";
+
+ std::clog << "[wandad::main] Initializing control interface on socket '" << socket_path.native() << "'\n";
+ auto interface = wanda::make_interface(service, socket_path);
auto status = interface->start();
if (status)
diff --git a/src/xdg.cpp b/src/xdg.cpp
new file mode 100644
index 0000000..9293151
--- /dev/null
+++ b/src/xdg.cpp
@@ -0,0 +1,47 @@
+#include "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
diff --git a/src/xdg.hpp b/src/xdg.hpp
new file mode 100644
index 0000000..a5dace0
--- /dev/null
+++ b/src/xdg.hpp
@@ -0,0 +1,25 @@
+#ifndef WANDA_XDG_HPP
+#define WANDA_XDG_HPP
+
+#include "environment.hpp"
+
+#include <cstddef>
+#include <filesystem>
+#include <type_traits>
+
+namespace wanda
+{
+enum struct xdg_directory : std::underlying_type_t<std::byte>
+{
+ data_home,
+ config_home,
+ cache_home,
+ runtime_dir,
+};
+
+std::string xdg_variable(xdg_directory directory);
+
+std::filesystem::path xdg_path_for(xdg_directory directory, environment const &environment);
+} // namespace wanda
+
+#endif \ No newline at end of file