1 use std::{io, rc::Rc};
2 
3 use crate::imp::EventQueueInner;
4 use crate::{AnonymousObject, DispatchData, Display, Main, RawEvent};
5 
6 /// An event queue for protocol messages
7 ///
8 /// Event dispatching in wayland is made on a queue basis, allowing you
9 /// to organize your objects into different queues that can be dispatched
10 /// independently, for example from different threads.
11 ///
12 /// An `EventQueue` is not `Send`, and thus must stay on the thread on which
13 /// it was created. However the `Display` object is `Send + Sync`, allowing
14 /// you to create the queues directly on the threads that host them.
15 ///
16 /// When a queue is dispatched (via the `dispatch(..)` or `dispatch_pending(..)` methods)
17 /// all the incoming messages from the server designated to objects associated with
18 /// the queue are processed sequentially, and the appropriate implementation for each
19 /// is invoked. When all messages have been processed these methods return.
20 ///
21 /// There are two main ways to driving an event queue forward. The first way is the
22 /// simplest and generally sufficient for single-threaded apps that only process events
23 /// from wayland. It consists of using the `EventQueue::dispatch(..)` method, which will
24 /// take care of sending pending requests to the server, block until some events are
25 /// available, read them, and call the associated handlers:
26 ///
27 /// ```no_run
28 /// # extern crate wayland_client;
29 /// # use wayland_client::{Display};
30 /// # let display = Display::connect_to_env().unwrap();
31 /// # let mut event_queue = display.create_event_queue();
32 /// loop {
33 ///     // The dispatch() method returns once it has received some events to dispatch
34 ///     // and have emptied the wayland socket from its pending messages, so it needs
35 ///     // to be called in a loop. If this method returns an error, your connection to
36 ///     // the wayland server is very likely dead. See its documentation for more details.
37 ///     event_queue.dispatch(&mut (), |_,_,_| {
38 ///         /* This closure will be called for every event received by an object not
39 ///            assigned to any Filter. If you plan to assign all your objects to Filter,
40 ///            the simplest thing to do is to assert this is never called. */
41 ///         unreachable!();
42 ///     }).expect("An error occurred during event dispatching!");
43 /// }
44 /// ```
45 ///
46 /// The second way is more appropriate for apps that are either multithreaded (and need to process
47 /// wayland events from different threads conccurently) or need to react to events from different
48 /// sources and can't affort to just block on the wayland socket. It centers around three methods:
49 /// `Display::flush()`, `EventQueue::read_events()` and `EventQueue::dispatch_pending()`:
50 ///
51 /// ```no_run
52 /// # extern crate wayland_client;
53 /// # use wayland_client::Display;
54 /// # let display = Display::connect_to_env().unwrap();
55 /// # let mut event_queue = display.create_event_queue();
56 /// loop {
57 ///     // The first method, called on the Display, is flush(). It writes all pending
58 ///     // requests to the socket. Calling it ensures that the server will indeed
59 ///     // receive your requests (so it can react to them).
60 ///     if let Err(e) = display.flush() {
61 ///         if e.kind() != ::std::io::ErrorKind::WouldBlock {
62 ///             // if you are sending a realy large number of request, it might fill
63 ///             // the internal buffers of the socket, in which case you should just
64 ///             // retry flushing later. Other errors are a problem though.
65 ///             eprintln!("Error while trying to flush the wayland socket: {:?}", e);
66 ///         }
67 ///     }
68 ///
69 ///     // The second method will try to read events from the socket. It is done in two
70 ///     // steps, first the read is prepared, and then it is actually executed. This allows
71 ///     // lower contention when different threads are trying to trigger a read of events
72 ///     // concurently
73 ///     if let Some(guard) = event_queue.prepare_read() {
74 ///         // prepare_read() returns None if there are already events pending in this
75 ///         // event queue, in which case there is no need to try to read from the socket
76 ///         if let Err(e) = guard.read_events() {
77 ///             if e.kind() != ::std::io::ErrorKind::WouldBlock {
78 ///                 // if read_events() returns Err(WouldBlock), this just means that no new
79 ///                 // messages are available to be read
80 ///                 eprintln!("Error while trying to read from the wayland socket: {:?}", e);
81 ///             }
82 ///         }
83 ///     }
84 ///
85 ///     // Then, once events have been read from the socket and stored in the internal
86 ///     // queues, they need to be dispatched to their handler. Note that while flush()
87 ///     // and read_events() are global and will affect the whole connection, this last
88 ///     // method will only affect the event queue it is being called on. This method
89 ///     // cannot error unless there is a bug in the server or a previous read of events
90 ///     // already errored.
91 ///     event_queue.dispatch_pending(&mut (), |_,_,_| {}).expect("Failed to dispatch all messages.");
92 ///
93 ///     // Note that none of these methods are blocking, as such they should not be used
94 ///     // as a loop as-is if there are no other sources of events your program is waiting on.
95 ///
96 ///     // The wayland socket can also be integrated in a poll-like mechanism by using
97 ///     // the file descriptor provided by the `get_connection_fd()` method.
98 /// }
99 /// ```
100 pub struct EventQueue {
101     // EventQueue is *not* Send
102     pub(crate) inner: Rc<EventQueueInner>,
103     display: Display,
104 }
105 
106 impl std::fmt::Debug for EventQueue {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result107     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108         f.write_str("EventQueue { ... }")
109     }
110 }
111 
112 /// A token representing this event queue
113 ///
114 /// This token can be cloned and is meant to allow easier
115 /// interaction with other functions in the library that
116 /// require the specification of an event queue, like
117 /// `Proxy::assign`.
118 #[derive(Clone)]
119 pub struct QueueToken {
120     pub(crate) inner: Rc<EventQueueInner>,
121 }
122 
123 impl std::fmt::Debug for QueueToken {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result124     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
125         f.write_str("QueueToken { ... }")
126     }
127 }
128 
129 impl EventQueue {
new(inner: EventQueueInner, display: Display) -> EventQueue130     pub(crate) fn new(inner: EventQueueInner, display: Display) -> EventQueue {
131         EventQueue { inner: Rc::new(inner), display }
132     }
133     /// Dispatches events from the internal buffer.
134     ///
135     /// Dispatches all events to their appropriate filters.
136     /// If no events were in the internal buffer, will block until
137     /// some events are read and dispatch them.
138     /// This process can insert events in the internal buffers of
139     /// other event queues.
140     ///
141     /// The provided `data` will be mutably accessible from all the callbacks, via the
142     /// [`DispatchData`](struct.DispatchData.html) mechanism. If you don't need global data, you
143     /// can just provide a `&mut ()` there.
144     ///
145     /// If an error is returned, your connection with the wayland compositor is probably lost.
146     /// You may want to check `Display::protocol_error()` to see if it was caused by a protocol error.
dispatch<T: std::any::Any, F>(&mut self, data: &mut T, fallback: F) -> io::Result<u32> where F: FnMut(RawEvent, Main<AnonymousObject>, DispatchData<'_>),147     pub fn dispatch<T: std::any::Any, F>(&mut self, data: &mut T, fallback: F) -> io::Result<u32>
148     where
149         F: FnMut(RawEvent, Main<AnonymousObject>, DispatchData<'_>),
150     {
151         let mut data = DispatchData::wrap(data);
152         self.inner.dispatch(data.reborrow(), fallback)
153     }
154 
155     /// Dispatches pending events from the internal buffer.
156     ///
157     /// Dispatches all events to their appropriate callbacks.
158     /// Never blocks, if no events were pending, simply returns
159     /// `Ok(0)`.
160     ///
161     /// The provided `data` will be mutably accessible from all the callbacks, via the
162     /// [`DispatchData`](struct.DispatchData.html) mechanism. If you don't need global data, you
163     /// can just provide a `&mut ()` there.
164     ///
165     /// If an error is returned, your connection with the wayland compositor is probably lost.
166     /// You may want to check `Display::protocol_error()` to see if it was caused by a protocol error.
dispatch_pending<T: std::any::Any, F>( &mut self, data: &mut T, fallback: F, ) -> io::Result<u32> where F: FnMut(RawEvent, Main<AnonymousObject>, DispatchData<'_>),167     pub fn dispatch_pending<T: std::any::Any, F>(
168         &mut self,
169         data: &mut T,
170         fallback: F,
171     ) -> io::Result<u32>
172     where
173         F: FnMut(RawEvent, Main<AnonymousObject>, DispatchData<'_>),
174     {
175         let mut data = DispatchData::wrap(data);
176         self.inner.dispatch_pending(data.reborrow(), fallback)
177     }
178 
179     /// Synchronous roundtrip
180     ///
181     /// This call will cause a synchronous roundtrip with the wayland server. It will block until all
182     /// pending requests of this queue are sent to the server and it has processed all of them and
183     /// send the appropriate events.
184     ///
185     /// Handlers are called as a consequence.
186     ///
187     /// The provided `data` will be mutably accessible from all the callbacks, via the
188     /// [`DispatchData`](struct.DispatchData.html) mechanism. If you don't need global data, you
189     /// can just provide a `&mut ()` there.
190     ///
191     /// On success returns the number of dispatched events.
192     /// If an error is returned, your connection with the wayland compositor is probably lost.
193     /// You may want to check `Display::protocol_error()` to see if it was caused by a protocol error.
sync_roundtrip<T: std::any::Any, F>( &mut self, data: &mut T, fallback: F, ) -> io::Result<u32> where F: FnMut(RawEvent, Main<AnonymousObject>, DispatchData<'_>),194     pub fn sync_roundtrip<T: std::any::Any, F>(
195         &mut self,
196         data: &mut T,
197         fallback: F,
198     ) -> io::Result<u32>
199     where
200         F: FnMut(RawEvent, Main<AnonymousObject>, DispatchData<'_>),
201     {
202         let mut data = DispatchData::wrap(data);
203         self.inner.sync_roundtrip(data.reborrow(), fallback)
204     }
205 
206     /// Create a new token associated with this event queue
207     ///
208     /// See `QueueToken` documentation for its use.
token(&self) -> QueueToken209     pub fn token(&self) -> QueueToken {
210         QueueToken { inner: self.inner.clone() }
211     }
212 
213     /// Prepare an concurrent read
214     ///
215     /// Will declare your intention to read events from the server socket.
216     ///
217     /// Will return `None` if there are still some events awaiting dispatch on this EventIterator.
218     /// In this case, you need to call `dispatch_pending()` before calling this method again.
219     ///
220     /// The guard can then be used by two means:
221     ///
222     ///  - Calling its `cancel()` method (or letting it go out of scope): the read intention will
223     ///    be cancelled
224     ///  - Calling its `read_events()` method: will block until all existing guards are destroyed
225     ///    by one of these methods, then events will be read and all blocked `read_events()` calls
226     ///    will return.
227     ///
228     /// This call will otherwise not block on the server socket if it is empty, and return
229     /// an io error `WouldBlock` in such cases.
prepare_read(&self) -> Option<ReadEventsGuard>230     pub fn prepare_read(&self) -> Option<ReadEventsGuard> {
231         match self.inner.prepare_read() {
232             Ok(()) => Some(ReadEventsGuard { inner: self.inner.clone(), done: false }),
233             Err(()) => None,
234         }
235     }
236 
237     /// Access the `Display` of the connection
display(&self) -> &Display238     pub fn display(&self) -> &Display {
239         &self.display
240     }
241 }
242 
243 /// A guard over a read intention.
244 ///
245 /// See `EventQueue::prepare_read()` for details about its use.
246 pub struct ReadEventsGuard {
247     inner: Rc<EventQueueInner>,
248     done: bool,
249 }
250 
251 impl std::fmt::Debug for ReadEventsGuard {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result252     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
253         f.write_str("ReadEventsGuard { ... }")
254     }
255 }
256 
257 impl ReadEventsGuard {
258     /// Read events
259     ///
260     /// Reads events from the server socket. If other `ReadEventsGuard` exists, will block
261     /// until they are all consumed or destroyed.
read_events(mut self) -> io::Result<()>262     pub fn read_events(mut self) -> io::Result<()> {
263         self.done = true;
264         self.inner.read_events()
265     }
266 
267     /// Cancel the read
268     ///
269     /// Will cancel the read intention associated with this guard. Never blocks.
270     ///
271     /// Has the same effect as letting the guard go out of scope.
cancel(self)272     pub fn cancel(self) {
273         // just run the destructor
274     }
275 }
276 
277 impl Drop for ReadEventsGuard {
drop(&mut self)278     fn drop(&mut self) {
279         if !self.done {
280             self.inner.cancel_read();
281         }
282     }
283 }
284