feat(config): Reference values defined in Xresources

Add config tag to reference a value defined in the Xresource db

`parameter = ${xrdb:var_name}`
This commit is contained in:
Michael Carlberg 2016-10-19 09:16:08 +02:00
parent 3eb531b6b5
commit 94ded75756
4 changed files with 91 additions and 5 deletions

View File

@ -88,11 +88,12 @@ find_package(Boost REQUIRED)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
find_package(Freetype REQUIRED Freetype2) find_package(Freetype REQUIRED Freetype2)
find_package(PkgConfig) find_package(PkgConfig)
find_package(X11 REQUIRED COMPONENTS Xft) find_package(X11 REQUIRED COMPONENTS Xft Xutil)
find_package(X11_XCB REQUIRED) find_package(X11_XCB REQUIRED)
pkg_check_modules(FONTCONFIG REQUIRED fontconfig) pkg_check_modules(FONTCONFIG REQUIRED fontconfig)
link_libraries(${X11_X11_LIB})
link_libraries(${X11_Xft_LIB}) link_libraries(${X11_Xft_LIB})
link_libraries(${X11_XCB_LIB}) link_libraries(${X11_XCB_LIB})
link_libraries(${BOOST_LIBRARIES}) link_libraries(${BOOST_LIBRARIES})

View File

@ -6,6 +6,7 @@
#include "common.hpp" #include "common.hpp"
#include "components/logger.hpp" #include "components/logger.hpp"
#include "components/x11/xresources.hpp"
#include "utils/file.hpp" #include "utils/file.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
@ -24,7 +25,8 @@ class config {
/** /**
* Construct config * Construct config
*/ */
explicit config(const logger& logger) : m_logger(logger) {} explicit config(const logger& logger, const xresource_manager& xrm)
: m_logger(logger), m_xrm(xrm) {}
/** /**
* Load configuration and validate bar section * Load configuration and validate bar section
@ -181,13 +183,17 @@ class config {
*/ */
template <typename T = const config&> template <typename T = const config&>
static di::injector<T> configure() { static di::injector<T> configure() {
return di::make_injector(logger::configure()); return di::make_injector(logger::configure(), xresource_manager::configure());
} }
protected: protected:
/** /**
* Find value of a config parameter defined as a reference * Find value of a config parameter defined as a reference
* variable using ${section.param} or ${env:VAR} * variable using ${section.param} or ${env:VAR}
* ${self.key} may be used to reference the current bar section
*
* @deprecated: ${BAR.key} has been replaced with ${self.key}
* but the former is kept to avoid breaking current configs
*/ */
template <typename T> template <typename T>
T dereference_var(string ref_section, string ref_key, string var, const T ref_val) const { T dereference_var(string ref_section, string ref_key, string var, const T ref_val) const {
@ -205,12 +211,25 @@ class config {
return ref_val; return ref_val;
} }
if (path.find("xrdb:") == 0) {
if (std::is_same<string, T>())
return boost::lexical_cast<T>(m_xrm.get_string(path.substr(5)));
else if (std::is_same<float, T>())
return boost::lexical_cast<T>(m_xrm.get_float(path.substr(5)));
else if (std::is_same<int, T>())
return boost::lexical_cast<T>(m_xrm.get_int(path.substr(5)));
}
auto ref_path = build_path(ref_section, ref_key); auto ref_path = build_path(ref_section, ref_key);
if ((n = path.find(".")) == string::npos) if ((n = path.find(".")) == string::npos)
throw value_error("Invalid reference defined at [" + ref_path + "]"); throw value_error("Invalid reference defined at [" + ref_path + "]");
auto section = string_util::replace(path.substr(0, n), "BAR", bar_section()); auto section = path.substr(0, n);
section = string_util::replace(section, "BAR", bar_section());
section = string_util::replace(section, "self", bar_section());
auto key = path.substr(n + 1, path.length() - n - 1); auto key = path.substr(n + 1, path.length() - n - 1);
auto val = m_ptree.get_optional<T>(build_path(section, key)); auto val = m_ptree.get_optional<T>(build_path(section, key));
@ -224,6 +243,7 @@ class config {
private: private:
const logger& m_logger; const logger& m_logger;
const xresource_manager& m_xrm;
ptree m_ptree; ptree m_ptree;
string m_file; string m_file;
string m_current_bar; string m_current_bar;

View File

@ -3,7 +3,6 @@
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include "common.hpp" #include "common.hpp"
#include "components/x11/xutils.hpp"
LEMONBUDDY_NS LEMONBUDDY_NS

View File

@ -0,0 +1,66 @@
#pragma once
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include "common.hpp"
#include "components/x11/xlib.hpp"
LEMONBUDDY_NS
class xresource_manager {
public:
explicit xresource_manager() {
XrmInitialize();
if (xlib::get_display() == nullptr)
return;
if ((m_manager = XResourceManagerString(xlib::get_display())) == nullptr)
return;
if ((m_db = XrmGetStringDatabase(m_manager)) == nullptr)
return;
}
/**
* Configure injection module
*/
template <typename T = const xresource_manager&>
static di::injector<T> configure() {
auto instance = factory::generic_singleton<xresource_manager>();
return di::make_injector(di::bind<>().to(instance));
}
string get_string(string name) const {
return load_value(name, "String", 64);
}
float get_float(string name) const {
return std::strtof(load_value(name, "String", 64).c_str(), 0);
}
int get_int(string name) const {
return std::atoi(load_value(name, "String", 64).c_str());
}
protected:
string load_value(string key, string res_type, size_t n) const {
if (m_manager == nullptr)
return "";
char* type = nullptr;
XrmValue ret;
XrmGetResource(m_db, key.c_str(), res_type.c_str(), &type, &ret);
if (ret.addr != nullptr && !std::strncmp(res_type.c_str(), type, n)) {
return {ret.addr};
}
return "";
}
private:
char* m_manager = nullptr;
XrmDatabase m_db;
};
LEMONBUDDY_NS_END