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