summary refs log tree commit diff
path: root/src/x/connection.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/x/connection.rs')
-rw-r--r--src/x/connection.rs97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/x/connection.rs b/src/x/connection.rs
new file mode 100644
index 0000000..d9ed9ca
--- /dev/null
+++ b/src/x/connection.rs
@@ -0,0 +1,97 @@
+use crate::x::atoms::Atoms;
+
+use xcb::XidNew;
+use xcb::x::{ Atom, InternAtom };
+
+
+pub struct Connection(xcb::Connection);
+
+impl Connection {
+  pub fn connect(display_name: Option<&str>)
+    -> xcb::ConnResult<(Connection, i32)>
+  {
+    let (connection, screen_index)
+        = xcb::Connection::connect(display_name)?;
+
+    Ok((Connection(connection), screen_index))
+  }
+}
+
+
+pub trait HasConnection {
+  fn connection(&self) -> &Connection;
+}
+
+impl HasConnection for Connection {
+  fn connection(&self) -> &Connection { self }
+}
+
+
+pub trait ConnectionExt: HasConnection {
+  fn get_setup(&self) -> &xcb::x::Setup {
+    self.connection().0.get_setup()
+  }
+
+  fn send_request<R: xcb::Request>(&self, request: &R) -> R::Cookie {
+    self.connection().0.send_request(request)
+  }
+
+  fn wait_for_reply<C: xcb::CookieWithReplyChecked>(&self, cookie: C)
+    -> xcb::Result<C::Reply>
+  {
+    self.connection().0.wait_for_reply(cookie)
+  }
+
+  fn send_request_checked<R: xcb::RequestWithoutReply>(&self, request: &R)
+    -> xcb::VoidCookieChecked
+  {
+    self.connection().0.send_request_checked(request)
+  }
+
+  fn check_request(&self, cookie: xcb::VoidCookieChecked)
+    -> xcb::ProtocolResult<()>
+  {
+    self.connection().0.check_request(cookie)
+  }
+
+  fn wait_for_event(&self) -> xcb::Result<xcb::Event> {
+    self.connection().0.wait_for_event()
+  }
+
+  fn generate_id<T: XidNew>(&self) -> T {
+    let connection = self.connection();
+
+    connection.0.generate_id()
+  }
+
+  fn get_atom(&self, name: &[u8]) -> xcb::Result<Atom> {
+    let connection = self.connection();
+
+    let cookie = connection.send_request(&InternAtom {
+      only_if_exists: true,
+      name: name,
+    });
+
+    Ok(connection.wait_for_reply(cookie)?.atom())
+  }
+
+  fn get_atoms(&self) -> xcb::Result<Atoms> {
+    let wm_protocols = self.get_atom(b"WM_PROTOCOLS")?;
+    let wm_delete_window = self.get_atom(b"WM_DELETE_WINDOW")?;
+
+    let wm_type = self.get_atom(b"_NET_WM_WINDOW_TYPE")?;
+    let wm_type_dock = self.get_atom(b"_NET_WM_WINDOW_TYPE_DOCK")?;
+
+    let wm_strut = self.get_atom(b"_NET_WM_STRUT")?;
+    let wm_strut_partial = self.get_atom(b"_NET_WM_STRUT_PARTIAL")?;
+
+    Ok(Atoms {
+      wm_protocols, wm_delete_window,
+      wm_type, wm_type_dock,
+      wm_strut, wm_strut_partial,
+    })
+  }
+}
+
+impl<T: HasConnection> ConnectionExt for T { }
+