refactor(connection: Use custom base

This commit is contained in:
Michael Carlberg 2016-12-26 09:40:15 +01:00
parent 3681247dc1
commit 11aabac227
25 changed files with 230 additions and 80 deletions

View File

@ -5,6 +5,7 @@
#include "events/signal_emitter.hpp" #include "events/signal_emitter.hpp"
#include "events/signal_fwd.hpp" #include "events/signal_fwd.hpp"
#include "events/signal_receiver.hpp" #include "events/signal_receiver.hpp"
#include "x11/extensions/fwd.hpp"
#include "x11/fonts.hpp" #include "x11/fonts.hpp"
#include "x11/types.hpp" #include "x11/types.hpp"

View File

@ -1,9 +1,9 @@
#pragma once #pragma once
#include <string> #include <string>
#include <unordered_map>
#include "common.hpp" #include "common.hpp"
#include "x11/color.hpp"
#include "x11/extensions/randr.hpp" #include "x11/extensions/randr.hpp"
POLYBAR_NS POLYBAR_NS

View File

@ -17,10 +17,12 @@ class color {
operator XRenderColor() const; operator XRenderColor() const;
operator string() const; operator string() const;
explicit operator uint32_t();
operator uint32_t() const; operator uint32_t() const;
static color parse(string input, color fallback); static const color& parse(string input, const color& fallback);
static color parse(string input); static const color& parse(string input);
protected: protected:
uint32_t m_value; uint32_t m_value;
@ -28,7 +30,6 @@ class color {
string m_source; string m_source;
}; };
extern std::map<string, class color> g_colorstore;
extern color g_colorempty; extern color g_colorempty;
extern color g_colorblack; extern color g_colorblack;
extern color g_colorwhite; extern color g_colorwhite;

View File

@ -1,32 +1,121 @@
#pragma once #pragma once
#include <X11/X.h> #include <xpp/core.hpp>
#include <X11/Xlib-xcb.h> #include <xpp/event.hpp>
#include <xcb/xcb.h> #include <xpp/generic/factory.hpp>
#include <xpp/proto/x.hpp>
#include "common.hpp" #include "common.hpp"
#include "utils/file.hpp" #include "utils/file.hpp"
#include "x11/extensions/all.hpp" #include "x11/extensions/all.hpp"
#include "x11/registry.hpp" #include "x11/registry.hpp"
#include "x11/types.hpp"
POLYBAR_NS POLYBAR_NS
using xpp_connection = xpp::connection<XPP_EXTENSION_LIST>; namespace detail {
template <typename Connection, typename... Extensions>
class connection : public xpp_connection { class interfaces : public xpp::x::extension::interface<interfaces<Connection, Extensions...>, Connection>,
public Extensions::template interface<interfaces<Connection, Extensions...>, Connection>... {
public: public:
const Connection& connection() const {
return static_cast<const Connection&>(*this);
}
};
template <typename Derived, typename... Extensions>
class connection_base : public xpp::core,
public xpp::generic::error_dispatcher,
public detail::interfaces<connection_base<Derived, Extensions...>, Extensions...>,
private xpp::x::extension,
private xpp::x::extension::error_dispatcher,
private Extensions...,
private Extensions::error_dispatcher... {
public:
template <typename... Args>
explicit connection_base(Args&&... args)
: xpp::core::core(forward<Args>(args)...)
, interfaces<connection_base<Derived, Extensions...>, Extensions...>(*this)
, Extensions(static_cast<xcb_connection_t*>(*this))...
, Extensions::error_dispatcher(static_cast<Extensions&>(*this).get())... {
m_root_window = screen_of_display(default_screen())->root;
}
virtual ~connection_base() {}
const Derived& operator=(const Derived& o) {
return o;
}
virtual operator xcb_connection_t*() const {
return *static_cast<const core&>(*this);
}
void operator()(const shared_ptr<xcb_generic_error_t>& error) const {
check<xpp::x::extension, Extensions...>(error);
}
template <typename Extension>
const Extension& extension() const {
return static_cast<const Extension&>(*this);
}
template <typename WindowType = xcb_window_t>
WindowType root() const {
using make = xpp::generic::factory::make<Derived, xcb_window_t, WindowType>;
return make()(*this, m_root_window);
}
shared_ptr<xcb_generic_event_t> wait_for_event() const {
try {
return core::wait_for_event();
} catch (const shared_ptr<xcb_generic_error_t>& error) {
check<xpp::x::extension, Extensions...>(error);
}
throw; // re-throw any exception caused by wait_for_event
}
shared_ptr<xcb_generic_event_t> wait_for_special_event(xcb_special_event_t* se) const {
try {
return core::wait_for_special_event(se);
} catch (const shared_ptr<xcb_generic_error_t>& error) {
check<xpp::x::extension, Extensions...>(error);
}
throw; // re-throw any exception caused by wait_for_event
}
private:
xcb_window_t m_root_window;
template <typename Extension, typename Next, typename... Rest>
void check(const shared_ptr<xcb_generic_error_t>& error) const {
check<Extension>(error);
check<Next, Rest...>(error);
}
template <typename Extension>
void check(const shared_ptr<xcb_generic_error_t>& error) const {
using error_dispatcher = typename Extension::error_dispatcher;
auto& dispatcher = static_cast<const error_dispatcher&>(*this);
dispatcher(error);
}
};
}
class connection : public detail::connection_base<connection&, XPP_EXTENSION_LIST> {
public:
using base_type = detail::connection_base<connection&, XPP_EXTENSION_LIST>;
using make_type = connection&; using make_type = connection&;
static make_type make(xcb_connection_t* conn = nullptr); static make_type make(xcb_connection_t* conn = nullptr);
explicit connection(xcb_connection_t* conn) : xpp_connection(conn) {} template <typename... Args>
explicit connection(xcb_connection_t* conn, int connection_fd) explicit connection(Args&&... args) : base_type::connection_base(forward<Args>(args)...) {}
: xpp_connection(conn), m_connection_fd(file_util::make_file_descriptor(connection_fd)) {}
connection& operator=(const connection&) { const connection& operator=(const connection& o) {
return *this; return o;
} }
// operator Display*() const;
void preload_atoms(); void preload_atoms();
void query_extensions(); void query_extensions();
@ -52,13 +141,14 @@ class connection : public xpp_connection {
template <typename Event, uint32_t ResponseType> template <typename Event, uint32_t ResponseType>
void wait_for_response(function<bool(const Event*)> check_event) { void wait_for_response(function<bool(const Event*)> check_event) {
int fd = get_file_descriptor();
shared_ptr<xcb_generic_event_t> evt{}; shared_ptr<xcb_generic_event_t> evt{};
while (!connection_has_error()) { while (!connection_has_error()) {
fd_set fds; fd_set fds;
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(*m_connection_fd, &fds); FD_SET(fd, &fds);
if (!select(*m_connection_fd + 1, &fds, nullptr, nullptr, nullptr)) { if (!select(fd + 1, &fds, nullptr, nullptr, nullptr)) {
continue; continue;
} else if ((evt = shared_ptr<xcb_generic_event_t>(xcb_poll_for_event(*this), free)) == nullptr) { } else if ((evt = shared_ptr<xcb_generic_event_t>(xcb_poll_for_event(*this), free)) == nullptr) {
continue; continue;
@ -70,17 +160,11 @@ class connection : public xpp_connection {
} }
} }
/**
* Attach sink to the registry
*/
template <typename Sink> template <typename Sink>
void attach_sink(Sink&& sink, registry::priority prio = 0) { void attach_sink(Sink&& sink, registry::priority prio = 0) {
m_registry.attach(prio, forward<Sink>(sink)); m_registry.attach(prio, forward<Sink>(sink));
} }
/**
* Detach sink from the registry
*/
template <typename Sink> template <typename Sink>
void detach_sink(Sink&& sink, registry::priority prio = 0) { void detach_sink(Sink&& sink, registry::priority prio = 0) {
m_registry.detach(prio, forward<Sink>(sink)); m_registry.detach(prio, forward<Sink>(sink));
@ -89,7 +173,6 @@ class connection : public xpp_connection {
protected: protected:
registry m_registry{*this}; registry m_registry{*this};
xcb_screen_t* m_screen{nullptr}; xcb_screen_t* m_screen{nullptr};
unique_ptr<file_descriptor> m_connection_fd;
}; };
POLYBAR_NS_END POLYBAR_NS_END

View File

@ -0,0 +1,36 @@
#pragma once
#include "config.hpp"
namespace xpp {
#if WITH_XDAMAGE
namespace damage {
class extension;
}
#endif
#if WITH_XRENDER
namespace render {
class extension;
}
#endif
#if WITH_XRANDR
namespace randr {
class extension;
}
#endif
#if WITH_XSYNC
namespace sync {
class extension;
}
#endif
#if WITH_XCOMPOSITE
namespace composite {
class extension;
}
#endif
#if WITH_XKB
namespace xkb {
class extension;
}
#endif
}

View File

@ -8,7 +8,6 @@
#include <xcb/randr.h> #include <xcb/randr.h>
#include <xpp/proto/randr.hpp> #include <xpp/proto/randr.hpp>
#include <xpp/xpp.hpp>
#include "common.hpp" #include "common.hpp"

View File

@ -16,8 +16,8 @@
#endif #endif
#define explicit mask_cxx_explicit_keyword #define explicit mask_cxx_explicit_keyword
#include <xcb/xkb.h> #include <xcb/xkb.h>
#include <xpp/proto/xkb.hpp>
#undef explicit #undef explicit
#include <xpp/proto/xkb.hpp>
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif

View File

@ -1,9 +1,7 @@
#pragma once #pragma once
#include <xcb/xcb.h>
#include "common.hpp" #include "common.hpp"
#include "x11/extensions/all.hpp" #include "x11/extensions/fwd.hpp"
// fwd // fwd
namespace xpp { namespace xpp {
@ -15,13 +13,12 @@ namespace xpp {
POLYBAR_NS POLYBAR_NS
// fwd
class connection; class connection;
using xpp_registry = xpp::event::registry<connection&, XPP_EXTENSION_LIST>; class registry : public xpp::event::registry<connection&, XPP_EXTENSION_LIST> {
class registry : public xpp_registry {
public: public:
using priority = unsigned int;
explicit registry(connection& conn); explicit registry(connection& conn);
}; };

View File

@ -1,9 +1,24 @@
#pragma once #pragma once
#include <xpp/xpp.hpp>
#include "common.hpp" #include "common.hpp"
namespace xpp {
template <typename Connection, template <typename, typename> class...>
class gcontext;
template <typename Connection, template <typename, typename> class...>
class pixmap;
template <typename Connection, template <typename, typename> class...>
class drawable;
template <typename Connection, template <typename, typename> class...>
class colormap;
template <typename Connection, template <typename, typename> class...>
class atom;
template <typename Connection, template <typename, typename> class...>
class font;
template <typename Connection, template <typename, typename> class...>
class cursor;
}
POLYBAR_NS POLYBAR_NS
class connection; class connection;
@ -17,10 +32,4 @@ using atom = xpp::atom<connection&>;
using font = xpp::font<connection&>; using font = xpp::font<connection&>;
using cursor = xpp::cursor<connection&>; using cursor = xpp::cursor<connection&>;
namespace reply_checked = xpp::x::reply::checked;
namespace reply_unchecked = xpp::x::reply::unchecked;
namespace reply {
using get_atom_name = reply_checked::get_atom_name<connection&>;
}
POLYBAR_NS_END POLYBAR_NS_END

View File

@ -2,25 +2,19 @@
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <xcb/xcb_aux.h> #include <xcb/xcb_aux.h>
#include <xpp/window.hpp>
#include "common.hpp" #include "common.hpp"
#include "x11/connection.hpp"
#include "x11/extensions/randr.hpp"
POLYBAR_NS POLYBAR_NS
using connection_t = connection; class connection;
class window : public xpp::window<connection_t&> { class window : public xpp::window<connection&> {
public: public:
using xpp::window<connection_t&>::window; using xpp::window<class connection&>::window;
explicit window(connection_t& conn) : xpp::window<connection_t&>(conn, XCB_NONE) {} window& operator=(const xcb_window_t win);
window& operator=(const xcb_window_t win) {
*this = window{connection(), win};
return *this;
}
window create_checked( window create_checked(
int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t mask = 0, const xcb_params_cw_t* p = nullptr); int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t mask = 0, const xcb_params_cw_t* p = nullptr);

View File

@ -8,6 +8,7 @@
#include "components/renderer.hpp" #include "components/renderer.hpp"
#include "components/screen.hpp" #include "components/screen.hpp"
#include "components/taskqueue.hpp" #include "components/taskqueue.hpp"
#include "components/types.hpp"
#include "events/signal.hpp" #include "events/signal.hpp"
#include "events/signal_emitter.hpp" #include "events/signal_emitter.hpp"
#include "utils/bspwm.hpp" #include "utils/bspwm.hpp"
@ -16,6 +17,7 @@
#include "utils/math.hpp" #include "utils/math.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
#include "x11/atoms.hpp" #include "x11/atoms.hpp"
#include "x11/extensions/all.hpp"
#include "x11/connection.hpp" #include "x11/connection.hpp"
#include "x11/fonts.hpp" #include "x11/fonts.hpp"
#include "x11/tray_manager.hpp" #include "x11/tray_manager.hpp"

View File

@ -5,6 +5,7 @@
#include "drawtypes/label.hpp" #include "drawtypes/label.hpp"
#include "utils/math.hpp" #include "utils/math.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
#include "utils/color.hpp"
POLYBAR_NS POLYBAR_NS

View File

@ -18,6 +18,7 @@
#include "utils/string.hpp" #include "utils/string.hpp"
#include "utils/time.hpp" #include "utils/time.hpp"
#include "x11/connection.hpp" #include "x11/connection.hpp"
#include "x11/extensions/all.hpp"
#include "x11/tray_manager.hpp" #include "x11/tray_manager.hpp"
#include "x11/xutils.hpp" #include "x11/xutils.hpp"

View File

@ -4,6 +4,7 @@
#include "components/types.hpp" #include "components/types.hpp"
#include "events/signal.hpp" #include "events/signal.hpp"
#include "events/signal_emitter.hpp" #include "events/signal_emitter.hpp"
#include "utils/color.hpp"
#include "utils/math.hpp" #include "utils/math.hpp"
#include "utils/memory.hpp" #include "utils/memory.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"

View File

@ -3,7 +3,7 @@
#include "components/types.hpp" #include "components/types.hpp"
#include "errors.hpp" #include "errors.hpp"
#include "events/signal.hpp" #include "events/signal.hpp"
#include "events/signal.hpp" #include "events/signal_receiver.hpp"
#include "events/signal_emitter.hpp" #include "events/signal_emitter.hpp"
#include "x11/connection.hpp" #include "x11/connection.hpp"
#include "x11/draw.hpp" #include "x11/draw.hpp"

View File

@ -2,6 +2,7 @@
#include "drawtypes/label.hpp" #include "drawtypes/label.hpp"
#include "drawtypes/progressbar.hpp" #include "drawtypes/progressbar.hpp"
#include "utils/color.hpp"
#include "utils/factory.hpp" #include "utils/factory.hpp"
#include "utils/math.hpp" #include "utils/math.hpp"

View File

@ -1,5 +1,6 @@
#include <fstream> #include <fstream>
#include <istream> #include <istream>
#include <iomanip>
#include "modules/memory.hpp" #include "modules/memory.hpp"

View File

@ -1,5 +1,5 @@
#include <iomanip> #include <iomanip>
#include <map> #include <unordered_map>
#include <utility> #include <utility>
#include "errors.hpp" #include "errors.hpp"
@ -9,7 +9,8 @@
POLYBAR_NS POLYBAR_NS
std::map<string, color> g_colorstore; std::unordered_map<string, color> g_colorstore;
color g_colorempty{"#00000000"}; color g_colorempty{"#00000000"};
color g_colorblack{"#ff000000"}; color g_colorblack{"#ff000000"};
color g_colorwhite{"#ffffffff"}; color g_colorwhite{"#ffffffff"};
@ -47,32 +48,30 @@ color::operator string() const {
return color_util::hex<uint8_t>(m_color); return color_util::hex<uint8_t>(m_color);
} }
color::operator uint32_t() {
return static_cast<const color&>(*this);
}
color::operator uint32_t() const { color::operator uint32_t() const {
return m_color; return m_color;
} }
color color::parse(string input, color fallback) { const color& color::parse(string input, const color& fallback) {
if (input.empty()) { if (input.empty()) {
throw application_error("Cannot parse empty color"); throw application_error("Cannot parse empty color");
} }
auto it = g_colorstore.find(input); auto it = g_colorstore.find(input);
if (it != g_colorstore.end()) { if (it != g_colorstore.end()) {
return it->second; return it->second;
} } else if ((input = color_util::parse_hex(input)).empty()) {
if ((input = color_util::parse_hex(input)).empty()) {
return fallback; return fallback;
} }
color result{input}; g_colorstore.emplace_hint(it, input, color{input});
g_colorstore.emplace_hint(it, input, result); return g_colorstore.at(input);
return result;
} }
color color::parse(string input) { const color& color::parse(string input) {
return parse(move(input), g_colorempty); return parse(move(input), g_colorempty);
} }

View File

@ -6,6 +6,7 @@
#include "utils/string.hpp" #include "utils/string.hpp"
#include "x11/atoms.hpp" #include "x11/atoms.hpp"
#include "x11/connection.hpp" #include "x11/connection.hpp"
#include "x11/xlib.hpp"
#include "x11/xutils.hpp" #include "x11/xutils.hpp"
POLYBAR_NS POLYBAR_NS
@ -15,10 +16,12 @@ POLYBAR_NS
*/ */
connection::make_type connection::make(xcb_connection_t* conn) { connection::make_type connection::make(xcb_connection_t* conn) {
if (conn == nullptr) { if (conn == nullptr) {
conn = &*xutils::get_connection(); conn = xutils::get_connection();
} }
// return static_cast<connection::make_type>(*factory_util::singleton<std::remove_reference_t<connection::make_type>>(
// conn, file_util::make_file_descriptor(xcb_get_file_descriptor(conn))));
return static_cast<connection::make_type>( return static_cast<connection::make_type>(
*factory_util::singleton<std::remove_reference_t<connection::make_type>>(conn, xcb_get_file_descriptor(conn))); *factory_util::singleton<std::remove_reference_t<connection::make_type>>(conn));
} }
/** /**
@ -181,4 +184,8 @@ void connection::dispatch_event(const shared_ptr<xcb_generic_event_t>& evt) cons
m_registry.dispatch(evt); m_registry.dispatch(evt);
} }
// connection::operator Display*() const {
// return xlib::get_display();
// }
POLYBAR_NS_END POLYBAR_NS_END

4
src/x11/events.cpp Normal file
View File

@ -0,0 +1,4 @@
#include <xpp/event.hpp>
#include <xpp/proto/x.hpp>
#include "x11/events.hpp"

View File

@ -1,6 +1,8 @@
#include "x11/extensions/render.hpp" #include "x11/extensions/render.hpp"
#include "errors.hpp" #include "errors.hpp"
#include "x11/connection.hpp" #include "x11/connection.hpp"
#include "x11/extensions/all.hpp"
POLYBAR_NS POLYBAR_NS

View File

@ -1,6 +1,8 @@
#include "x11/extensions/sync.hpp" #include "x11/extensions/sync.hpp"
#include "errors.hpp" #include "errors.hpp"
#include "x11/connection.hpp" #include "x11/connection.hpp"
#include "x11/extensions/all.hpp"
POLYBAR_NS POLYBAR_NS

View File

@ -1,8 +1,9 @@
#include "x11/connection.hpp" #include "x11/extensions/xkb.hpp"
#include "errors.hpp" #include "errors.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
#include "x11/extensions/xkb.hpp" #include "x11/connection.hpp"
#include "x11/extensions/all.hpp"
POLYBAR_NS POLYBAR_NS
@ -127,7 +128,8 @@ namespace xkb_util {
xcb_xkb_get_names_value_list_unpack(buffer, reply->nTypes, reply->indicators, reply->virtualMods, reply->groupNames, xcb_xkb_get_names_value_list_unpack(buffer, reply->nTypes, reply->indicators, reply->virtualMods, reply->groupNames,
reply->nKeys, reply->nKeyAliases, reply->nRadioGroups, reply->which, &values); reply->nKeys, reply->nKeyAliases, reply->nRadioGroups, reply->which, &values);
vector<reply::get_atom_name> replies; using get_atom_name_reply = xpp::x::reply::checked::get_atom_name<connection&>;
vector<get_atom_name_reply> replies;
for (int i = 0; i < xcb_xkb_get_names_value_list_groups_length(reply, &values); i++) { for (int i = 0; i < xcb_xkb_get_names_value_list_groups_length(reply, &values); i++) {
replies.emplace_back(xpp::x::get_atom_name(conn, values.groups[i])); replies.emplace_back(xpp::x::get_atom_name(conn, values.groups[i]));
} }
@ -141,7 +143,7 @@ namespace xkb_util {
} }
} }
results.emplace_back(keyboard::layout{static_cast<reply::get_atom_name>(reply).name(), sym_names}); results.emplace_back(keyboard::layout{static_cast<get_atom_name_reply>(reply).name(), sym_names});
} }
free(reply); free(reply);
@ -168,13 +170,14 @@ namespace xkb_util {
xcb_xkb_get_names_value_list_unpack(buffer, reply->nTypes, reply->indicators, reply->virtualMods, reply->groupNames, xcb_xkb_get_names_value_list_unpack(buffer, reply->nTypes, reply->indicators, reply->virtualMods, reply->groupNames,
reply->nKeys, reply->nKeyAliases, reply->nRadioGroups, reply->which, &values); reply->nKeys, reply->nKeyAliases, reply->nRadioGroups, reply->which, &values);
map<xcb_atom_t, reply::get_atom_name> entries; using get_atom_name_reply = xpp::x::reply::checked::get_atom_name<connection&>;
map<xcb_atom_t, get_atom_name_reply> entries;
for (int i = 0; i < xcb_xkb_get_names_value_list_indicator_names_length(reply, &values); i++) { for (int i = 0; i < xcb_xkb_get_names_value_list_indicator_names_length(reply, &values); i++) {
entries.emplace(values.indicatorNames[i], xpp::x::get_atom_name(conn, values.indicatorNames[i])); entries.emplace(values.indicatorNames[i], xpp::x::get_atom_name(conn, values.indicatorNames[i]));
} }
for (const auto& entry : entries) { for (const auto& entry : entries) {
auto name = static_cast<reply::get_atom_name>(entry.second).name(); auto name = static_cast<get_atom_name_reply>(entry.second).name();
auto type = keyboard::indicator::type::NONE; auto type = keyboard::indicator::type::NONE;
if (string_util::compare(name, "caps lock")) { if (string_util::compare(name, "caps lock")) {

View File

@ -1,9 +1,11 @@
#include "x11/connection.hpp" #include <xpp/event.hpp>
#include "x11/connection.hpp"
#include "x11/extensions/all.hpp"
#include "x11/registry.hpp" #include "x11/registry.hpp"
POLYBAR_NS POLYBAR_NS
registry::registry(connection& conn) : xpp_registry(conn) {} registry::registry(connection& conn) : xpp::event::registry<connection&, XPP_EXTENSION_LIST>(conn) {}
POLYBAR_NS_END POLYBAR_NS_END

View File

@ -1,15 +1,19 @@
#include <xcb/xcb_icccm.h> #include <xcb/xcb_icccm.h>
#include "utils/math.hpp" #include "components/types.hpp"
#include "x11/atoms.hpp" #include "x11/atoms.hpp"
#include "x11/connection.hpp"
#include "x11/extensions/randr.hpp"
#include "x11/window.hpp" #include "x11/window.hpp"
#include "x11/xutils.hpp" #include "x11/xutils.hpp"
#include "components/types.hpp"
#include "x11/color.hpp"
POLYBAR_NS POLYBAR_NS
window& window::operator=(const xcb_window_t win) {
*this = window{connection(), win};
return *this;
}
/** /**
* Create window and check for errors * Create window and check for errors
*/ */