From 11aabac2278d1afbf8c81291a59281741c5448ed Mon Sep 17 00:00:00 2001 From: Michael Carlberg Date: Mon, 26 Dec 2016 09:40:15 +0100 Subject: [PATCH] refactor(connection: Use custom base --- include/components/renderer.hpp | 1 + include/components/types.hpp | 2 +- include/x11/color.hpp | 7 +- include/x11/connection.hpp | 123 ++++++++++++++++++++++++++----- include/x11/extensions/fwd.hpp | 36 +++++++++ include/x11/extensions/randr.hpp | 1 - include/x11/extensions/xkb.hpp | 2 +- include/x11/registry.hpp | 11 +-- include/x11/types.hpp | 25 +++++-- include/x11/window.hpp | 16 ++-- src/components/bar.cpp | 2 + src/components/builder.cpp | 1 + src/components/controller.cpp | 1 + src/components/parser.cpp | 1 + src/components/renderer.cpp | 2 +- src/drawtypes/progressbar.cpp | 1 + src/modules/memory.cpp | 1 + src/x11/color.cpp | 25 +++---- src/x11/connection.cpp | 11 ++- src/x11/events.cpp | 4 + src/x11/extensions/render.cpp | 2 + src/x11/extensions/sync.cpp | 2 + src/x11/extensions/xkb.cpp | 15 ++-- src/x11/registry.cpp | 6 +- src/x11/window.cpp | 12 ++- 25 files changed, 230 insertions(+), 80 deletions(-) create mode 100644 include/x11/extensions/fwd.hpp create mode 100644 src/x11/events.cpp diff --git a/include/components/renderer.hpp b/include/components/renderer.hpp index 647f022b..97c6f253 100644 --- a/include/components/renderer.hpp +++ b/include/components/renderer.hpp @@ -5,6 +5,7 @@ #include "events/signal_emitter.hpp" #include "events/signal_fwd.hpp" #include "events/signal_receiver.hpp" +#include "x11/extensions/fwd.hpp" #include "x11/fonts.hpp" #include "x11/types.hpp" diff --git a/include/components/types.hpp b/include/components/types.hpp index affafa4d..b6ab18f1 100644 --- a/include/components/types.hpp +++ b/include/components/types.hpp @@ -1,9 +1,9 @@ #pragma once #include +#include #include "common.hpp" -#include "x11/color.hpp" #include "x11/extensions/randr.hpp" POLYBAR_NS diff --git a/include/x11/color.hpp b/include/x11/color.hpp index 76aa4eaa..ed1c3f6a 100644 --- a/include/x11/color.hpp +++ b/include/x11/color.hpp @@ -17,10 +17,12 @@ class color { operator XRenderColor() const; operator string() const; + + explicit operator uint32_t(); operator uint32_t() const; - static color parse(string input, color fallback); - static color parse(string input); + static const color& parse(string input, const color& fallback); + static const color& parse(string input); protected: uint32_t m_value; @@ -28,7 +30,6 @@ class color { string m_source; }; -extern std::map g_colorstore; extern color g_colorempty; extern color g_colorblack; extern color g_colorwhite; diff --git a/include/x11/connection.hpp b/include/x11/connection.hpp index f9a9a54c..1e1d3197 100644 --- a/include/x11/connection.hpp +++ b/include/x11/connection.hpp @@ -1,32 +1,121 @@ #pragma once -#include -#include -#include +#include +#include +#include +#include #include "common.hpp" #include "utils/file.hpp" #include "x11/extensions/all.hpp" #include "x11/registry.hpp" -#include "x11/types.hpp" POLYBAR_NS -using xpp_connection = xpp::connection; +namespace detail { + template + class interfaces : public xpp::x::extension::interface, Connection>, + public Extensions::template interface, Connection>... { + public: + const Connection& connection() const { + return static_cast(*this); + } + }; -class connection : public xpp_connection { + template + class connection_base : public xpp::core, + public xpp::generic::error_dispatcher, + public detail::interfaces, Extensions...>, + private xpp::x::extension, + private xpp::x::extension::error_dispatcher, + private Extensions..., + private Extensions::error_dispatcher... { + public: + template + explicit connection_base(Args&&... args) + : xpp::core::core(forward(args)...) + , interfaces, Extensions...>(*this) + , Extensions(static_cast(*this))... + , Extensions::error_dispatcher(static_cast(*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(*this); + } + + void operator()(const shared_ptr& error) const { + check(error); + } + + template + const Extension& extension() const { + return static_cast(*this); + } + + template + WindowType root() const { + using make = xpp::generic::factory::make; + return make()(*this, m_root_window); + } + + shared_ptr wait_for_event() const { + try { + return core::wait_for_event(); + } catch (const shared_ptr& error) { + check(error); + } + throw; // re-throw any exception caused by wait_for_event + } + + shared_ptr wait_for_special_event(xcb_special_event_t* se) const { + try { + return core::wait_for_special_event(se); + } catch (const shared_ptr& error) { + check(error); + } + throw; // re-throw any exception caused by wait_for_event + } + + private: + xcb_window_t m_root_window; + + template + void check(const shared_ptr& error) const { + check(error); + check(error); + } + + template + void check(const shared_ptr& error) const { + using error_dispatcher = typename Extension::error_dispatcher; + auto& dispatcher = static_cast(*this); + dispatcher(error); + } + }; +} + +class connection : public detail::connection_base { public: + using base_type = detail::connection_base; using make_type = connection&; static make_type make(xcb_connection_t* conn = nullptr); - explicit connection(xcb_connection_t* conn) : xpp_connection(conn) {} - explicit connection(xcb_connection_t* conn, int connection_fd) - : xpp_connection(conn), m_connection_fd(file_util::make_file_descriptor(connection_fd)) {} + template + explicit connection(Args&&... args) : base_type::connection_base(forward(args)...) {} - connection& operator=(const connection&) { - return *this; + const connection& operator=(const connection& o) { + return o; } + // operator Display*() const; + void preload_atoms(); void query_extensions(); @@ -52,13 +141,14 @@ class connection : public xpp_connection { template void wait_for_response(function check_event) { + int fd = get_file_descriptor(); shared_ptr evt{}; while (!connection_has_error()) { fd_set 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; } else if ((evt = shared_ptr(xcb_poll_for_event(*this), free)) == nullptr) { continue; @@ -70,17 +160,11 @@ class connection : public xpp_connection { } } - /** - * Attach sink to the registry - */ template void attach_sink(Sink&& sink, registry::priority prio = 0) { m_registry.attach(prio, forward(sink)); } - /** - * Detach sink from the registry - */ template void detach_sink(Sink&& sink, registry::priority prio = 0) { m_registry.detach(prio, forward(sink)); @@ -89,7 +173,6 @@ class connection : public xpp_connection { protected: registry m_registry{*this}; xcb_screen_t* m_screen{nullptr}; - unique_ptr m_connection_fd; }; POLYBAR_NS_END diff --git a/include/x11/extensions/fwd.hpp b/include/x11/extensions/fwd.hpp new file mode 100644 index 00000000..93be9778 --- /dev/null +++ b/include/x11/extensions/fwd.hpp @@ -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 +} diff --git a/include/x11/extensions/randr.hpp b/include/x11/extensions/randr.hpp index 51e10b4a..f8aeb091 100644 --- a/include/x11/extensions/randr.hpp +++ b/include/x11/extensions/randr.hpp @@ -8,7 +8,6 @@ #include #include -#include #include "common.hpp" diff --git a/include/x11/extensions/xkb.hpp b/include/x11/extensions/xkb.hpp index e8b866ee..3b2c3651 100644 --- a/include/x11/extensions/xkb.hpp +++ b/include/x11/extensions/xkb.hpp @@ -16,8 +16,8 @@ #endif #define explicit mask_cxx_explicit_keyword #include -#include #undef explicit +#include #if defined(__clang__) #pragma clang diagnostic pop #endif diff --git a/include/x11/registry.hpp b/include/x11/registry.hpp index 6a707d2f..1a262771 100644 --- a/include/x11/registry.hpp +++ b/include/x11/registry.hpp @@ -1,9 +1,7 @@ #pragma once -#include - #include "common.hpp" -#include "x11/extensions/all.hpp" +#include "x11/extensions/fwd.hpp" // fwd namespace xpp { @@ -15,13 +13,12 @@ namespace xpp { POLYBAR_NS -// fwd class connection; -using xpp_registry = xpp::event::registry; - -class registry : public xpp_registry { +class registry : public xpp::event::registry { public: + using priority = unsigned int; + explicit registry(connection& conn); }; diff --git a/include/x11/types.hpp b/include/x11/types.hpp index d4575628..284cf84d 100644 --- a/include/x11/types.hpp +++ b/include/x11/types.hpp @@ -1,9 +1,24 @@ #pragma once -#include - #include "common.hpp" +namespace xpp { + template class...> + class gcontext; + template class...> + class pixmap; + template class...> + class drawable; + template class...> + class colormap; + template class...> + class atom; + template class...> + class font; + template class...> + class cursor; +} + POLYBAR_NS class connection; @@ -17,10 +32,4 @@ using atom = xpp::atom; using font = xpp::font; using cursor = xpp::cursor; -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; -} - POLYBAR_NS_END diff --git a/include/x11/window.hpp b/include/x11/window.hpp index a5e0eafa..87ba2149 100644 --- a/include/x11/window.hpp +++ b/include/x11/window.hpp @@ -2,25 +2,19 @@ #include #include +#include #include "common.hpp" -#include "x11/connection.hpp" -#include "x11/extensions/randr.hpp" POLYBAR_NS -using connection_t = connection; +class connection; -class window : public xpp::window { +class window : public xpp::window { public: - using xpp::window::window; + using xpp::window::window; - explicit window(connection_t& conn) : xpp::window(conn, XCB_NONE) {} - - window& operator=(const xcb_window_t win) { - *this = window{connection(), win}; - return *this; - } + window& operator=(const xcb_window_t win); 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); diff --git a/src/components/bar.cpp b/src/components/bar.cpp index 1d4ee4cd..051d304c 100644 --- a/src/components/bar.cpp +++ b/src/components/bar.cpp @@ -8,6 +8,7 @@ #include "components/renderer.hpp" #include "components/screen.hpp" #include "components/taskqueue.hpp" +#include "components/types.hpp" #include "events/signal.hpp" #include "events/signal_emitter.hpp" #include "utils/bspwm.hpp" @@ -16,6 +17,7 @@ #include "utils/math.hpp" #include "utils/string.hpp" #include "x11/atoms.hpp" +#include "x11/extensions/all.hpp" #include "x11/connection.hpp" #include "x11/fonts.hpp" #include "x11/tray_manager.hpp" diff --git a/src/components/builder.cpp b/src/components/builder.cpp index 4c0acd57..c50491f1 100644 --- a/src/components/builder.cpp +++ b/src/components/builder.cpp @@ -5,6 +5,7 @@ #include "drawtypes/label.hpp" #include "utils/math.hpp" #include "utils/string.hpp" +#include "utils/color.hpp" POLYBAR_NS diff --git a/src/components/controller.cpp b/src/components/controller.cpp index 53115f30..f89ff589 100644 --- a/src/components/controller.cpp +++ b/src/components/controller.cpp @@ -18,6 +18,7 @@ #include "utils/string.hpp" #include "utils/time.hpp" #include "x11/connection.hpp" +#include "x11/extensions/all.hpp" #include "x11/tray_manager.hpp" #include "x11/xutils.hpp" diff --git a/src/components/parser.cpp b/src/components/parser.cpp index 5e0255b6..562140e8 100644 --- a/src/components/parser.cpp +++ b/src/components/parser.cpp @@ -4,6 +4,7 @@ #include "components/types.hpp" #include "events/signal.hpp" #include "events/signal_emitter.hpp" +#include "utils/color.hpp" #include "utils/math.hpp" #include "utils/memory.hpp" #include "utils/string.hpp" diff --git a/src/components/renderer.cpp b/src/components/renderer.cpp index 627af684..d24874a6 100644 --- a/src/components/renderer.cpp +++ b/src/components/renderer.cpp @@ -3,7 +3,7 @@ #include "components/types.hpp" #include "errors.hpp" #include "events/signal.hpp" -#include "events/signal.hpp" +#include "events/signal_receiver.hpp" #include "events/signal_emitter.hpp" #include "x11/connection.hpp" #include "x11/draw.hpp" diff --git a/src/drawtypes/progressbar.cpp b/src/drawtypes/progressbar.cpp index a1cfc68d..55d379dc 100644 --- a/src/drawtypes/progressbar.cpp +++ b/src/drawtypes/progressbar.cpp @@ -2,6 +2,7 @@ #include "drawtypes/label.hpp" #include "drawtypes/progressbar.hpp" +#include "utils/color.hpp" #include "utils/factory.hpp" #include "utils/math.hpp" diff --git a/src/modules/memory.cpp b/src/modules/memory.cpp index 30143195..9d93ad45 100644 --- a/src/modules/memory.cpp +++ b/src/modules/memory.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "modules/memory.hpp" diff --git a/src/x11/color.cpp b/src/x11/color.cpp index c4fd5e0b..a9550ac9 100644 --- a/src/x11/color.cpp +++ b/src/x11/color.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include "errors.hpp" @@ -9,7 +9,8 @@ POLYBAR_NS -std::map g_colorstore; +std::unordered_map g_colorstore; + color g_colorempty{"#00000000"}; color g_colorblack{"#ff000000"}; color g_colorwhite{"#ffffffff"}; @@ -47,32 +48,30 @@ color::operator string() const { return color_util::hex(m_color); } +color::operator uint32_t() { + return static_cast(*this); +} + color::operator uint32_t() const { return m_color; } -color color::parse(string input, color fallback) { +const color& color::parse(string input, const color& fallback) { if (input.empty()) { throw application_error("Cannot parse empty color"); } - auto it = g_colorstore.find(input); - if (it != g_colorstore.end()) { return it->second; - } - - if ((input = color_util::parse_hex(input)).empty()) { + } else if ((input = color_util::parse_hex(input)).empty()) { return fallback; } - color result{input}; - g_colorstore.emplace_hint(it, input, result); - - return result; + g_colorstore.emplace_hint(it, input, color{input}); + return g_colorstore.at(input); } -color color::parse(string input) { +const color& color::parse(string input) { return parse(move(input), g_colorempty); } diff --git a/src/x11/connection.cpp b/src/x11/connection.cpp index fae4ec7c..aae3e943 100644 --- a/src/x11/connection.cpp +++ b/src/x11/connection.cpp @@ -6,6 +6,7 @@ #include "utils/string.hpp" #include "x11/atoms.hpp" #include "x11/connection.hpp" +#include "x11/xlib.hpp" #include "x11/xutils.hpp" POLYBAR_NS @@ -15,10 +16,12 @@ POLYBAR_NS */ connection::make_type connection::make(xcb_connection_t* conn) { if (conn == nullptr) { - conn = &*xutils::get_connection(); + conn = xutils::get_connection(); } + // return static_cast(*factory_util::singleton>( + // conn, file_util::make_file_descriptor(xcb_get_file_descriptor(conn)))); return static_cast( - *factory_util::singleton>(conn, xcb_get_file_descriptor(conn))); + *factory_util::singleton>(conn)); } /** @@ -181,4 +184,8 @@ void connection::dispatch_event(const shared_ptr& evt) cons m_registry.dispatch(evt); } +// connection::operator Display*() const { +// return xlib::get_display(); +// } + POLYBAR_NS_END diff --git a/src/x11/events.cpp b/src/x11/events.cpp new file mode 100644 index 00000000..2954805f --- /dev/null +++ b/src/x11/events.cpp @@ -0,0 +1,4 @@ +#include +#include + +#include "x11/events.hpp" diff --git a/src/x11/extensions/render.cpp b/src/x11/extensions/render.cpp index 730b3250..6d552ddf 100644 --- a/src/x11/extensions/render.cpp +++ b/src/x11/extensions/render.cpp @@ -1,6 +1,8 @@ #include "x11/extensions/render.hpp" + #include "errors.hpp" #include "x11/connection.hpp" +#include "x11/extensions/all.hpp" POLYBAR_NS diff --git a/src/x11/extensions/sync.cpp b/src/x11/extensions/sync.cpp index ad8116d1..1b2fde8d 100644 --- a/src/x11/extensions/sync.cpp +++ b/src/x11/extensions/sync.cpp @@ -1,6 +1,8 @@ #include "x11/extensions/sync.hpp" + #include "errors.hpp" #include "x11/connection.hpp" +#include "x11/extensions/all.hpp" POLYBAR_NS diff --git a/src/x11/extensions/xkb.cpp b/src/x11/extensions/xkb.cpp index f06d6638..a6006667 100644 --- a/src/x11/extensions/xkb.cpp +++ b/src/x11/extensions/xkb.cpp @@ -1,8 +1,9 @@ -#include "x11/connection.hpp" +#include "x11/extensions/xkb.hpp" #include "errors.hpp" #include "utils/string.hpp" -#include "x11/extensions/xkb.hpp" +#include "x11/connection.hpp" +#include "x11/extensions/all.hpp" 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, reply->nKeys, reply->nKeyAliases, reply->nRadioGroups, reply->which, &values); - vector replies; + using get_atom_name_reply = xpp::x::reply::checked::get_atom_name; + vector replies; 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])); } @@ -141,7 +143,7 @@ namespace xkb_util { } } - results.emplace_back(keyboard::layout{static_cast(reply).name(), sym_names}); + results.emplace_back(keyboard::layout{static_cast(reply).name(), sym_names}); } 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, reply->nKeys, reply->nKeyAliases, reply->nRadioGroups, reply->which, &values); - map entries; + using get_atom_name_reply = xpp::x::reply::checked::get_atom_name; + map entries; 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])); } for (const auto& entry : entries) { - auto name = static_cast(entry.second).name(); + auto name = static_cast(entry.second).name(); auto type = keyboard::indicator::type::NONE; if (string_util::compare(name, "caps lock")) { diff --git a/src/x11/registry.cpp b/src/x11/registry.cpp index 30390ca8..ff703f90 100644 --- a/src/x11/registry.cpp +++ b/src/x11/registry.cpp @@ -1,9 +1,11 @@ -#include "x11/connection.hpp" +#include +#include "x11/connection.hpp" +#include "x11/extensions/all.hpp" #include "x11/registry.hpp" POLYBAR_NS -registry::registry(connection& conn) : xpp_registry(conn) {} +registry::registry(connection& conn) : xpp::event::registry(conn) {} POLYBAR_NS_END diff --git a/src/x11/window.cpp b/src/x11/window.cpp index 79ca9ced..04bdd1a3 100644 --- a/src/x11/window.cpp +++ b/src/x11/window.cpp @@ -1,15 +1,19 @@ #include -#include "utils/math.hpp" +#include "components/types.hpp" #include "x11/atoms.hpp" +#include "x11/connection.hpp" +#include "x11/extensions/randr.hpp" #include "x11/window.hpp" #include "x11/xutils.hpp" -#include "components/types.hpp" -#include "x11/color.hpp" - POLYBAR_NS +window& window::operator=(const xcb_window_t win) { + *this = window{connection(), win}; + return *this; +} + /** * Create window and check for errors */