polybar/include/x11/connection.hpp

96 lines
2.6 KiB
C++
Raw Normal View History

2016-11-02 19:22:45 +00:00
#pragma once
#include <X11/X.h>
#include <X11/Xlib-xcb.h>
#include <xcb/xcb.h>
#include "common.hpp"
2016-12-21 13:55:19 +00:00
#include "utils/file.hpp"
#include "x11/extensions/all.hpp"
#include "x11/registry.hpp"
2016-11-02 19:22:45 +00:00
#include "x11/types.hpp"
2016-11-19 05:22:44 +00:00
POLYBAR_NS
2016-11-02 19:22:45 +00:00
using xpp_connection = xpp::connection<XPP_EXTENSION_LIST>;
2016-11-02 19:22:45 +00:00
class connection : public xpp_connection {
public:
2016-12-09 08:40:46 +00:00
using make_type = connection&;
2016-12-21 22:22:02 +00:00
static make_type make(xcb_connection_t* conn = nullptr);
2016-12-21 13:55:19 +00:00
2016-12-21 22:22:02 +00:00
explicit connection(xcb_connection_t* conn) : xpp_connection(conn) {}
2016-12-03 15:44:08 +00:00
explicit connection(xcb_connection_t* conn, int connection_fd)
2016-12-21 13:55:19 +00:00
: xpp_connection(conn), m_connection_fd(file_util::make_file_descriptor(connection_fd)) {}
2016-11-02 19:22:45 +00:00
connection& operator=(const connection&) {
return *this;
}
2016-11-02 19:22:45 +00:00
void preload_atoms();
2016-12-21 13:55:19 +00:00
2016-11-02 19:22:45 +00:00
void query_extensions();
string id(xcb_window_t w) const;
2016-12-03 15:44:31 +00:00
xcb_screen_t* screen(bool realloc = false);
2016-11-02 19:22:45 +00:00
void ensure_event_mask(xcb_window_t win, uint32_t event);
2016-12-21 13:55:19 +00:00
void clear_event_mask(xcb_window_t win);
2016-11-25 07:42:31 +00:00
shared_ptr<xcb_client_message_event_t> make_client_message(xcb_atom_t type, xcb_window_t target) const;
2016-11-02 19:22:45 +00:00
2016-11-25 12:55:15 +00:00
void send_client_message(const shared_ptr<xcb_client_message_event_t>& message, xcb_window_t target,
2016-11-02 19:22:45 +00:00
uint32_t event_mask = 0xFFFFFF, bool propagate = false) const;
xcb_visualtype_t* visual_type(xcb_screen_t* screen, int match_depth = 32);
2016-11-02 19:22:45 +00:00
static string error_str(int error_code);
2016-12-21 22:22:02 +00:00
void dispatch_event(const shared_ptr<xcb_generic_event_t>& evt) const;
2016-12-21 13:55:19 +00:00
template <typename Event, uint32_t ResponseType>
2016-12-21 22:22:02 +00:00
void wait_for_response(function<bool(const Event*)> check_event) {
shared_ptr<xcb_generic_event_t> evt{};
2016-12-21 13:55:19 +00:00
while (!connection_has_error()) {
fd_set fds;
FD_ZERO(&fds);
FD_SET(*m_connection_fd, &fds);
if (!select(*m_connection_fd + 1, &fds, nullptr, nullptr, nullptr)) {
continue;
2016-12-21 22:22:02 +00:00
} else if ((evt = shared_ptr<xcb_generic_event_t>(xcb_poll_for_event(*this), free)) == nullptr) {
2016-12-21 13:55:19 +00:00
continue;
} else if (evt->response_type != ResponseType) {
continue;
2016-12-21 22:22:02 +00:00
} else if (check_event(reinterpret_cast<const Event*>(&*evt))) {
2016-12-21 13:55:19 +00:00
break;
}
}
}
2016-11-02 19:22:45 +00:00
/**
2016-12-21 13:55:19 +00:00
* Attach sink to the registry
*/
2016-11-02 19:22:45 +00:00
template <typename Sink>
void attach_sink(Sink&& sink, registry::priority prio = 0) {
m_registry.attach(prio, forward<Sink>(sink));
}
/**
* Detach sink from the registry
*/
template <typename Sink>
void detach_sink(Sink&& sink, registry::priority prio = 0) {
m_registry.detach(prio, forward<Sink>(sink));
}
protected:
registry m_registry{*this};
2016-12-03 15:44:08 +00:00
xcb_screen_t* m_screen{nullptr};
unique_ptr<file_descriptor> m_connection_fd;
2016-11-02 19:22:45 +00:00
};
2016-11-19 05:22:44 +00:00
POLYBAR_NS_END