summaryrefslogtreecommitdiff
path: root/src/xcb_resource.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/xcb_resource.hh')
-rw-r--r--src/xcb_resource.hh99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/xcb_resource.hh b/src/xcb_resource.hh
new file mode 100644
index 0000000..b499f2c
--- /dev/null
+++ b/src/xcb_resource.hh
@@ -0,0 +1,99 @@
+#ifndef XCB_RESOURCE_HH
+#define XCB_RESOURCE_HH
+
+#include "xcb_connection.hh"
+
+#include <memory>
+#include <xcb/xproto.h>
+
+namespace xcb {
+
+namespace internal {
+
+struct WndDeleter {
+ void operator()(xcb_connection_t* conn, xcb_window_t wnd) const {
+ xcb_destroy_window(conn, wnd);
+ }
+};
+
+struct GCDeleter {
+ void operator()(xcb_connection_t* conn, xcb_gcontext_t gc) const {
+ xcb_free_gc(conn, gc);
+ }
+};
+
+struct FontDeleter {
+ void operator()(xcb_connection_t* conn, xcb_font_t font) const {
+ xcb_close_font(conn, font);
+ }
+};
+
+} // namespace internal
+
+template <typename T, typename Deleter>
+class xcb_resource {
+ public:
+ explicit xcb_resource(shared_conn conn)
+ : conn_(conn), id_(xcb_generate_id(conn_.get())) {}
+ constexpr xcb_resource() : id_(XCB_NONE) {}
+ xcb_resource(xcb_resource const& res) = delete;
+ xcb_resource(xcb_resource&& res) : conn_(res.conn_), id_(res.release()) {}
+ ~xcb_resource() { reset(); }
+
+ xcb_resource& operator=(xcb_resource const& res) = delete;
+ xcb_resource& operator=(xcb_resource&& res) {
+ reset();
+ conn_ = res.conn_;
+ id_ = res.release();
+ return *this;
+ }
+
+ T id() const { return id_; }
+
+ void reset() {
+ if (id_ == XCB_NONE)
+ return;
+ deleter_(conn_.get(), id_);
+ id_ = XCB_NONE;
+ }
+
+ T release() {
+ auto ret = id_;
+ id_ = XCB_NONE;
+ conn_.reset();
+ return ret;
+ }
+
+ private:
+ shared_conn conn_;
+ T id_;
+ Deleter const deleter_{};
+};
+
+typedef std::unique_ptr<xcb_resource<xcb_window_t, internal::WndDeleter>>
+ unique_wnd;
+typedef std::shared_ptr<xcb_resource<xcb_window_t, internal::WndDeleter>>
+ shared_wnd;
+
+unique_wnd make_unique_wnd(shared_conn conn);
+shared_wnd make_shared_wnd(shared_conn conn);
+
+typedef std::unique_ptr<xcb_resource<xcb_gcontext_t, internal::GCDeleter>>
+ unique_gc;
+typedef std::shared_ptr<xcb_resource<xcb_gcontext_t, internal::GCDeleter>>
+ shared_gc;
+
+unique_gc make_unique_gc(shared_conn conn);
+shared_gc make_shared_gc(shared_conn conn);
+
+typedef std::unique_ptr<xcb_resource<xcb_font_t, internal::FontDeleter>>
+ unique_font;
+typedef std::shared_ptr<xcb_resource<xcb_font_t, internal::FontDeleter>>
+ shared_font;
+
+unique_font make_unique_font(shared_conn conn);
+shared_font make_shared_font(shared_conn conn);
+
+} // namespace xcb
+
+#endif // XCB_RESOURCE_HH