summary refs log tree commit diff
path: root/src/x/connection.rs
blob: 78e721db309a2248d04af60422d87c6ff19dbe5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use crate::x::atoms::Atoms;

use xcb::XidNew;
use xcb::x::{ Atom, InternAtom };


pub struct Connection(xcb::Connection);

impl Connection {
  pub fn connect() -> xcb::ConnResult<(Connection, i32)> {
    let (connection, screen_index)
        = xcb::Connection::connect_with_xlib_display()?;

    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,
    })
  }

  fn get_xlib_display(&self) -> *mut x11::xlib::Display {
    self.connection().0.get_raw_dpy()
  }
}

impl<T: HasConnection> ConnectionExt for T { }