diff options
Diffstat (limited to 'src/xcb_resource.hh')
| -rw-r--r-- | src/xcb_resource.hh | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/xcb_resource.hh b/src/xcb_resource.hh new file mode 100644 index 0000000..15619e5 --- /dev/null +++ b/src/xcb_resource.hh @@ -0,0 +1,105 @@ +#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 |
