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
|
// See LICENSE file for copyright and license details.
use x11::xlib::{
XEvent,
XKeyEvent,
XButtonEvent,
XMotionEvent,
XCrossingEvent,
XCreateWindowEvent,
XDestroyWindowEvent,
XUnmapEvent,
XMapEvent,
XConfigureEvent,
XPending,
};
use x11::xlib;
use x11::xlib::Display;
use unix_socket::UnixStream;
use unix_socket::UnixListener;
use libc::c_int;
use libc::{
FD_SET,
FD_ZERO,
FD_ISSET,
select,
fd_set,
};
use std::fmt;
use std::ptr;
use std::mem::uninitialized;
use std::cmp::max;
use safe_x11::next_xevent;
pub enum Event {
Key(XKeyEvent, bool),
Button(XButtonEvent, bool),
Drag(XMotionEvent),
Enter(XCrossingEvent),
Leave(XCrossingEvent),
Generic(XEvent),
Create(XCreateWindowEvent),
Destroy(XDestroyWindowEvent),
Unmap(XUnmapEvent),
Map(XMapEvent),
Configure(XConfigureEvent),
Socket(UnixStream),
NoEvent
}
impl fmt::Debug for Event {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = match self {
&Event::Key(ev, pressed) => format!("Key({}, {})", XEvent::from(ev).get_type(), pressed),
&Event::Button(ev, pressed) => format!("Button({}, {})", XEvent::from(ev).get_type(), pressed),
&Event::Drag(ev) => format!("Drag({})", XEvent::from(ev).get_type()),
&Event::Generic(ev) => format!("Generic({})", XEvent::from(ev).get_type()),
&Event::Enter(ev) => format!("Enter({})", XEvent::from(ev).get_type()),
&Event::Leave(ev) => format!("Enter({})", XEvent::from(ev).get_type()),
&Event::Create(ev) => format!("Create({})", XEvent::from(ev).get_type()),
&Event::Destroy(ev) => format!("Destroy({})", XEvent::from(ev).get_type()),
&Event::Unmap(ev) => format!("Unmap({})", XEvent::from(ev).get_type()),
&Event::Map(ev) => format!("Map({})", XEvent::from(ev).get_type()),
&Event::Configure(ev) => format!("Configure({})", XEvent::from(ev).get_type()),
&Event::Socket(_) => format!("Socket()"),
&Event::NoEvent => format!("NoEvent"),
};
write!(f, "{}", s)
}
}
pub unsafe fn select_event(display: *mut Display, x11fd: c_int, socket_fd: c_int,
listener: &UnixListener) -> Event {
// Return right now if there're some XEvent on the queue
if XPending(display) > 0 {
return next_event(display);
}
let mut read_fdset: fd_set = uninitialized();
FD_ZERO(&mut read_fdset);
FD_SET(x11fd, &mut read_fdset);
FD_SET(socket_fd, &mut read_fdset);
select(max(x11fd, socket_fd) + 1,
&mut read_fdset, ptr::null_mut(), ptr::null_mut(),
ptr::null_mut());
if FD_ISSET(x11fd, &mut read_fdset) {
next_event(display)
} else if FD_ISSET(socket_fd, &mut read_fdset) {
let mut listener_iter = listener.incoming();
if let Some(Ok(stream)) = listener_iter.nth(0) {
return Event::Socket(stream)
} else {
Event::NoEvent
}
} else {
Event::NoEvent
}
}
pub fn next_event(display: *mut Display) -> Event {
let ev = next_xevent(display);
match ev.get_type() {
2 => Event::Key(xlib::XKeyEvent::from(ev), true),
3 => Event::Key(xlib::XKeyEvent::from(ev), false),
4 => Event::Button(xlib::XButtonEvent::from(ev), true),
5 => Event::Button(xlib::XButtonEvent::from(ev), false),
6 => Event::Drag(XMotionEvent::from(ev)),
7 => Event::Enter(XCrossingEvent::from(ev)),
8 => Event::Leave(XCrossingEvent::from(ev)),
16 => Event::Create(XCreateWindowEvent::from(ev)),
17 => Event::Destroy(XDestroyWindowEvent::from(ev)),
18 => Event::Unmap(XUnmapEvent::from(ev)),
19 => Event::Map(XMapEvent::from(ev)),
22 => Event::Configure(XConfigureEvent::from(ev)),
e => {
println!("Unknown event {}", e);
Event::NoEvent
},
}
}
|