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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use std::io;
use std::ffi::CStr;
use wayland_sys::client::*;
use event_queue::{create_event_queue, EventQueue};
use generated::client::wl_display::WlDisplay;
use Proxy;
#[derive(Debug)]
pub enum ConnectError {
NoWaylandLib,
NoCompositorListening
}
#[derive(Debug)]
pub enum FatalError {
Io(io::Error),
Protocol {
interface: String,
proxy_id: u32,
error_code: u32
}
}
pub fn default_connect() -> Result<(WlDisplay, EventQueue), ConnectError> {
if !::wayland_sys::client::is_lib_available() { return Err(ConnectError::NoWaylandLib) }
let ptr = unsafe { ffi_dispatch!(WAYLAND_CLIENT_HANDLE, wl_display_connect, ::std::ptr::null()) };
if ptr.is_null() {
Err(ConnectError::NoCompositorListening)
} else {
let display = unsafe { WlDisplay::from_ptr_new(ptr as *mut _) };
let eventiter = unsafe { create_event_queue(display.ptr() as *mut wl_display, None) };
Ok((display, eventiter))
}
}
impl WlDisplay {
pub fn flush(&self) -> io::Result<i32> {
let ret = unsafe { ffi_dispatch!(WAYLAND_CLIENT_HANDLE, wl_display_flush, self.ptr() as *mut _) };
if ret >= 0 { Ok(ret) } else { Err(io::Error::last_os_error()) }
}
pub fn create_event_queue(&self) -> EventQueue {
let evq = unsafe { ffi_dispatch!(WAYLAND_CLIENT_HANDLE, wl_display_create_queue, self.ptr() as *mut _) };
unsafe { create_event_queue(self.ptr() as *mut _, Some(evq)) }
}
pub fn last_error(&self) -> Option<FatalError> {
let err = unsafe { ffi_dispatch!(WAYLAND_CLIENT_HANDLE, wl_display_get_error, self.ptr() as *mut _) };
if err == 0 {
None
} else if err == ::libc::EPROTO {
let mut interface = ::std::ptr::null_mut();
let mut id = 0;
let code = unsafe { ffi_dispatch!(
WAYLAND_CLIENT_HANDLE, wl_display_get_protocol_error,
self.ptr() as *mut _, &mut interface, &mut id
) };
let interface = if interface.is_null() {
"<unkown interface>".to_owned()
} else {
unsafe { CStr::from_ptr((*interface).name) }.to_string_lossy().into_owned()
};
Some(FatalError::Protocol {
interface: interface,
proxy_id: id,
error_code: code
})
} else {
Some(FatalError::Io(io::Error::from_raw_os_error(err)))
}
}
pub fn get_fd(&self) -> ::std::os::unix::io::RawFd {
unsafe { ffi_dispatch!( WAYLAND_CLIENT_HANDLE, wl_display_get_fd, self.ptr() as *mut _) }
}
}
impl Drop for WlDisplay {
fn drop(&mut self) {
unsafe { ffi_dispatch!(WAYLAND_CLIENT_HANDLE, wl_display_disconnect, self.ptr() as *mut _) }
}
}