1 //! Client-side rust implementation of a Wayland protocol backend
2 
3 use std::{
4     fmt,
5     os::unix::{
6         io::{AsRawFd, FromRawFd, IntoRawFd, RawFd},
7         net::UnixStream,
8     },
9     sync::{Arc, Condvar, Mutex},
10 };
11 
12 use crate::{
13     core_interfaces::WL_DISPLAY_INTERFACE,
14     protocol::{
15         check_for_signature, same_interface, same_interface_or_anonymous, AllowNull, Argument,
16         ArgumentType, Interface, Message, ObjectInfo, ProtocolError, ANONYMOUS_INTERFACE,
17         INLINE_ARGS,
18     },
19 };
20 use smallvec::SmallVec;
21 
22 use super::{
23     debug::DisplaySlice,
24     map::{Object, ObjectMap, SERVER_ID_LIMIT},
25     socket::{BufferedSocket, Socket},
26     wire::MessageParseError,
27 };
28 
29 pub use crate::types::client::{InvalidId, NoWaylandLib, WaylandError};
30 
31 /// A trait representing your data associated to an object
32 ///
33 /// You will only be given access to it as a `&` reference, so you
34 /// need to handle interior mutability by yourself.
35 ///
36 /// The methods of this trait will be invoked internally every time a
37 /// new object is created to initialize its data.
38 pub trait ObjectData: downcast_rs::DowncastSync {
39     /// Dispatch an event for the associated object
40     ///
41     /// If the event has a NewId argument, the callback must return the object data
42     /// for the newly created object
event( self: Arc<Self>, handle: &mut Handle, msg: Message<ObjectId>, ) -> Option<Arc<dyn ObjectData>>43     fn event(
44         self: Arc<Self>,
45         handle: &mut Handle,
46         msg: Message<ObjectId>,
47     ) -> Option<Arc<dyn ObjectData>>;
48     /// Notification that the object has been destroyed and is no longer active
destroyed(&self, object_id: ObjectId)49     fn destroyed(&self, object_id: ObjectId);
50     /// Helper for forwarding a Debug implementation of your `ObjectData` type
51     ///
52     /// By default will just print `ObjectData { ... }`
debug(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result53     fn debug(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54         f.debug_struct("ObjectData").finish_non_exhaustive()
55     }
56 }
57 
58 #[cfg(not(tarpaulin_include))]
59 impl std::fmt::Debug for dyn ObjectData {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result60     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61         self.debug(f)
62     }
63 }
64 
65 downcast_rs::impl_downcast!(sync ObjectData);
66 
67 #[derive(Debug, Clone)]
68 struct Data {
69     client_destroyed: bool,
70     server_destroyed: bool,
71     user_data: Arc<dyn ObjectData>,
72     serial: u32,
73 }
74 
75 /// An ID representing a Wayland object
76 #[derive(Clone)]
77 pub struct ObjectId {
78     serial: u32,
79     id: u32,
80     interface: &'static Interface,
81 }
82 
83 impl std::cmp::PartialEq for ObjectId {
eq(&self, other: &ObjectId) -> bool84     fn eq(&self, other: &ObjectId) -> bool {
85         self.id == other.id
86             && self.serial == other.serial
87             && same_interface(self.interface, other.interface)
88     }
89 }
90 
91 impl std::cmp::Eq for ObjectId {}
92 
93 #[cfg(not(tarpaulin_include))]
94 impl fmt::Display for ObjectId {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result95     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96         write!(f, "{}@{}", self.interface.name, self.id)
97     }
98 }
99 
100 #[cfg(not(tarpaulin_include))]
101 impl fmt::Debug for ObjectId {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result102     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103         write!(f, "ObjectId({}, {})", self, self.serial)
104     }
105 }
106 
107 impl ObjectId {
108     /// Check if this is the null ID
is_null(&self) -> bool109     pub fn is_null(&self) -> bool {
110         self.id == 0
111     }
112 
113     /// Interface of the represented object
interface(&self) -> &'static Interface114     pub fn interface(&self) -> &'static Interface {
115         self.interface
116     }
117 
118     /// Return the protocol-level numerical ID of this object
119     ///
120     /// Protocol IDs are reused after object destruction, so this should not be used as a
121     /// unique identifier,
protocol_id(&self) -> u32122     pub fn protocol_id(&self) -> u32 {
123         self.id
124     }
125 }
126 
127 /// Main handle of a backend to the Wayland protocol
128 ///
129 /// This type hosts most of the protocol-related functionality of the backend, and is the
130 /// main entry point for manipulating Wayland objects. It can be retrieved both from
131 /// the backend via [`Backend::handle()`](Backend::handle), and is given to you as argument
132 /// in most event callbacks.
133 #[derive(Debug)]
134 pub struct Handle {
135     socket: BufferedSocket,
136     map: ObjectMap<Data>,
137     last_error: Option<WaylandError>,
138     last_serial: u32,
139     pending_placeholder: Option<(&'static Interface, u32)>,
140     debug: bool,
141 }
142 
143 /// A pure rust implementation of a Wayland client backend
144 ///
145 /// This type hosts the plumbing functionalities for interacting with the wayland protocol,
146 /// and most of the protocol-level interactions are made through the [`Handle`] type, accessed
147 /// via the [`handle()`](Backend::handle) method.
148 #[derive(Debug)]
149 pub struct Backend {
150     handle: Handle,
151     prepared_reads: usize,
152     read_condvar: Arc<Condvar>,
153     read_serial: usize,
154 }
155 
156 impl Backend {
157     /// Try to initialize a Wayland backend on the provided unix stream
158     ///
159     /// The provided stream should correspond to an already established unix connection with
160     /// the Wayland server. On this rust backend, this method never fails.
connect(stream: UnixStream) -> Result<Self, NoWaylandLib>161     pub fn connect(stream: UnixStream) -> Result<Self, NoWaylandLib> {
162         let socket = BufferedSocket::new(unsafe { Socket::from_raw_fd(stream.into_raw_fd()) });
163         let mut map = ObjectMap::new();
164         map.insert_at(
165             1,
166             Object {
167                 interface: &WL_DISPLAY_INTERFACE,
168                 version: 1,
169                 data: Data {
170                     client_destroyed: false,
171                     server_destroyed: false,
172                     user_data: Arc::new(DumbObjectData),
173                     serial: 0,
174                 },
175             },
176         )
177         .unwrap();
178 
179         let debug =
180             matches!(std::env::var_os("WAYLAND_DEBUG"), Some(str) if str == "1" || str == "client");
181 
182         Ok(Backend {
183             handle: Handle {
184                 socket,
185                 map,
186                 last_error: None,
187                 last_serial: 0,
188                 pending_placeholder: None,
189                 debug,
190             },
191             prepared_reads: 0,
192             read_condvar: Arc::new(Condvar::new()),
193             read_serial: 0,
194         })
195     }
196 
197     /// Flush all pending outgoing requests to the server
flush(&mut self) -> Result<(), WaylandError>198     pub fn flush(&mut self) -> Result<(), WaylandError> {
199         self.handle.no_last_error()?;
200         if let Err(e) = self.handle.socket.flush() {
201             return Err(self.handle.store_if_not_wouldblock_and_return_error(e));
202         }
203         Ok(())
204     }
205 
206     /// Read events from the wayland socket if available, and invoke the associated callbacks
207     ///
208     /// This function will never block, and returns an I/O `WouldBlock` error if no event is available
209     /// to read.
210     ///
211     /// **Note:** this function should only be used if you know that you are the only thread
212     /// reading events from the wayland socket. If this may not be the case, see [`ReadEventsGuard`]
dispatch_events(&mut self) -> Result<usize, WaylandError>213     pub fn dispatch_events(&mut self) -> Result<usize, WaylandError> {
214         self.handle.no_last_error()?;
215         let mut dispatched = 0;
216         loop {
217             // Attempt to read a message
218             let map = &self.handle.map;
219             let message = match self.handle.socket.read_one_message(|id, opcode| {
220                 map.find(id)
221                     .and_then(|o| o.interface.events.get(opcode as usize))
222                     .map(|desc| desc.signature)
223             }) {
224                 Ok(msg) => msg,
225                 Err(MessageParseError::MissingData) | Err(MessageParseError::MissingFD) => {
226                     // need to read more data
227                     if let Err(e) = self.handle.socket.fill_incoming_buffers() {
228                         if e.kind() != std::io::ErrorKind::WouldBlock {
229                             return Err(self.handle.store_and_return_error(e));
230                         } else if dispatched == 0 {
231                             return Err(e.into());
232                         } else {
233                             break;
234                         }
235                     }
236                     continue;
237                 }
238                 Err(MessageParseError::Malformed) => {
239                     // malformed error, protocol error
240                     let err = WaylandError::Protocol(ProtocolError {
241                         code: 0,
242                         object_id: 0,
243                         object_interface: "".into(),
244                         message: "Malformed Wayland message.".into(),
245                     });
246                     return Err(self.handle.store_and_return_error(err));
247                 }
248             };
249 
250             // We got a message, retrieve its associated object & details
251             // These lookups must succeed otherwise we would not have been able to parse this message
252             let receiver = self.handle.map.find(message.sender_id).unwrap();
253             let message_desc = receiver.interface.events.get(message.opcode as usize).unwrap();
254 
255             // Short-circuit display-associated events
256             if message.sender_id == 1 {
257                 self.handle.handle_display_event(message)?;
258                 continue;
259             }
260 
261             let mut created_id = None;
262 
263             // Convert the arguments and create the new object if applicable
264             let mut args = SmallVec::with_capacity(message.args.len());
265             let mut arg_interfaces = message_desc.arg_interfaces.iter();
266             for arg in message.args.into_iter() {
267                 args.push(match arg {
268                     Argument::Array(a) => Argument::Array(a),
269                     Argument::Int(i) => Argument::Int(i),
270                     Argument::Uint(u) => Argument::Uint(u),
271                     Argument::Str(s) => Argument::Str(s),
272                     Argument::Fixed(f) => Argument::Fixed(f),
273                     Argument::Fd(f) => Argument::Fd(f),
274                     Argument::Object(o) => {
275                         if o != 0 {
276                             // Lookup the object to make the appropriate Id
277                             let obj = match self.handle.map.find(o) {
278                                 Some(o) => o,
279                                 None => {
280                                     let err = WaylandError::Protocol(ProtocolError {
281                                         code: 0,
282                                         object_id: 0,
283                                         object_interface: "".into(),
284                                         message: format!("Unknown object {}.", o),
285                                     });
286                                     return Err(self.handle.store_and_return_error(err));
287                                 }
288                             };
289                             if let Some(next_interface) = arg_interfaces.next() {
290                                 if !same_interface_or_anonymous(next_interface, obj.interface) {
291                                     let err = WaylandError::Protocol(ProtocolError {
292                                         code: 0,
293                                         object_id: 0,
294                                         object_interface: "".into(),
295                                         message: format!(
296                                             "Protocol error: server sent object {} for interface {}, but it has interface {}.",
297                                             o, next_interface.name, obj.interface.name
298                                         ),
299                                     });
300                                     return Err(self.handle.store_and_return_error(err));
301                                 }
302                             }
303                             Argument::Object(ObjectId { id: o, serial: obj.data.serial, interface: obj.interface })
304                         } else {
305                             Argument::Object(ObjectId { id: 0, serial: 0, interface: &ANONYMOUS_INTERFACE })
306                         }
307                     }
308                     Argument::NewId(new_id) => {
309                         // An object should be created
310                         let child_interface = match message_desc.child_interface {
311                             Some(iface) => iface,
312                             None => panic!("Received event {}@{}.{} which creates an object without specifying its interface, this is unsupported.", receiver.interface.name, message.sender_id, message_desc.name),
313                         };
314 
315                         let child_udata = Arc::new(UninitObjectData);
316 
317                         // if this ID belonged to a now destroyed server object, we can replace it
318                         if new_id >= SERVER_ID_LIMIT
319                             && self.handle.map.with(new_id, |obj| obj.data.client_destroyed).unwrap_or(false)
320                         {
321                             self.handle.map.remove(new_id);
322                         }
323 
324                         let child_obj = Object {
325                             interface: child_interface,
326                             version: receiver.version,
327                             data: Data {
328                                 client_destroyed: receiver.data.client_destroyed,
329                                 server_destroyed: false,
330                                 user_data: child_udata,
331                                 serial: self.handle.next_serial(),
332                             }
333                         };
334 
335                         let child_id = ObjectId { id: new_id, serial: child_obj.data.serial, interface: child_obj.interface };
336                         created_id = Some(child_id.clone());
337 
338                         if let Err(()) = self.handle.map.insert_at(new_id, child_obj) {
339                             // abort parsing, this is an unrecoverable error
340                             let err = WaylandError::Protocol(ProtocolError {
341                                 code: 0,
342                                 object_id: 0,
343                                 object_interface: "".into(),
344                                 message: format!(
345                                     "Protocol error: server tried to create \
346                                     an object \"{}\" with invalid id {}.",
347                                     child_interface.name, new_id
348                                 ),
349                             });
350                             return Err(self.handle.store_and_return_error(err));
351                         }
352 
353                         Argument::NewId(child_id)
354                     }
355                 });
356             }
357 
358             if self.handle.debug {
359                 super::debug::print_dispatched_message(
360                     receiver.interface.name,
361                     message.sender_id,
362                     message_desc.name,
363                     &args,
364                 );
365             }
366 
367             // If this event is send to an already destroyed object (by the client), swallow it
368             if receiver.data.client_destroyed {
369                 // but close any associated FD to avoid leaking them
370                 for a in args {
371                     if let Argument::Fd(fd) = a {
372                         let _ = ::nix::unistd::close(fd);
373                     }
374                 }
375                 continue;
376             }
377 
378             // Invoke the user callback
379             let id = ObjectId {
380                 id: message.sender_id,
381                 serial: receiver.data.serial,
382                 interface: receiver.interface,
383             };
384             log::debug!("Dispatching {}.{} ({})", id, receiver.version, DisplaySlice(&args));
385             let ret = receiver
386                 .data
387                 .user_data
388                 .clone()
389                 .event(&mut self.handle, Message { sender_id: id, opcode: message.opcode, args });
390 
391             // If this event is a destructor, destroy the object
392             if message_desc.is_destructor {
393                 self.handle
394                     .map
395                     .with(message.sender_id, |obj| {
396                         obj.data.server_destroyed = true;
397                         obj.data.client_destroyed = true;
398                     })
399                     .unwrap();
400                 receiver.data.user_data.destroyed(ObjectId {
401                     id: message.sender_id,
402                     serial: receiver.data.serial,
403                     interface: receiver.interface,
404                 });
405             }
406 
407             match (created_id, ret) {
408                 (Some(child_id), Some(child_data)) => {
409                     self.handle
410                         .map
411                         .with(child_id.id, |obj| obj.data.user_data = child_data)
412                         .unwrap();
413                 }
414                 (None, None) => {}
415                 (Some(child_id), None) => {
416                     panic!(
417                         "Callback creating object {} did not provide any object data.",
418                         child_id
419                     );
420                 }
421                 (None, Some(_)) => {
422                     panic!("An object data was returned from a callback not creating any object");
423                 }
424             }
425 
426             dispatched += 1;
427         }
428         Ok(dispatched)
429     }
430 
431     /// Access the [`Handle`] associated with this backend
handle(&mut self) -> &mut Handle432     pub fn handle(&mut self) -> &mut Handle {
433         &mut self.handle
434     }
435 }
436 
437 /// Guard for synchronizing event reading across multiple threads
438 ///
439 /// If multiple threads need to read events from the Wayland socket concurrently,
440 /// it is necessary to synchronize their access. Failing to do so may cause some of the
441 /// threads to not be notified of new events, and sleep much longer than appropriate.
442 ///
443 /// To correctly synchronize access, this type should be used. The guard is created using
444 /// the [`try_new()`](ReadEventsGuard::try_new) method. And the event reading is triggered by consuming
445 /// the guard using the [`read()`](ReadEventsGuard::read) method.
446 ///
447 /// If you plan to poll the Wayland socket for readiness, the file descriptor can be retrieved via
448 /// the [`connection_fd`](ReadEventsGuard::connection_fd) method. Note that for the synchronization to
449 /// correctly occur, you must *always* create the `ReadEventsGuard` *before* polling the socket.
450 #[derive(Debug)]
451 pub struct ReadEventsGuard {
452     backend: Arc<Mutex<Backend>>,
453     done: bool,
454 }
455 
456 impl ReadEventsGuard {
457     /// Create a new reading guard
458     ///
459     /// This call will not block, but event callbacks may be invoked in the process
460     /// of preparing the guard.
try_new(backend: Arc<Mutex<Backend>>) -> Result<Self, WaylandError>461     pub fn try_new(backend: Arc<Mutex<Backend>>) -> Result<Self, WaylandError> {
462         backend.lock().unwrap().prepared_reads += 1;
463         Ok(ReadEventsGuard { backend, done: false })
464     }
465 
466     /// Access the Wayland socket FD for polling
connection_fd(&self) -> RawFd467     pub fn connection_fd(&self) -> RawFd {
468         self.backend.lock().unwrap().handle.socket.as_raw_fd()
469     }
470 
471     /// Attempt to read events from the Wayland socket
472     ///
473     /// If multiple threads have a live reading guard, this method will block until all of them
474     /// are either dropped or have their `read()` method invoked, at which point on of the threads
475     /// will read events from the socket and invoke the callbacks for the received events. All
476     /// threads will then resume their execution.
477     ///
478     /// This returns the number of dispatched events, or `0` if an other thread handled the dispatching.
479     /// If no events are available to read from the socket, this returns a `WouldBlock` IO error.
read(mut self) -> Result<usize, WaylandError>480     pub fn read(mut self) -> Result<usize, WaylandError> {
481         let mut backend = self.backend.lock().unwrap();
482         backend.prepared_reads -= 1;
483         self.done = true;
484         if backend.prepared_reads == 0 {
485             // We should be the one reading
486             let ret = backend.dispatch_events();
487             // wake up other threads
488             backend.read_serial = backend.read_serial.wrapping_add(1);
489             backend.read_condvar.notify_all();
490             // forward the return value
491             ret
492         } else {
493             // We should wait for an other thread to read (or cancel)
494             let serial = backend.read_serial;
495             let condvar = backend.read_condvar.clone();
496             backend = condvar.wait_while(backend, |backend| serial == backend.read_serial).unwrap();
497             backend.handle.no_last_error()?;
498             Ok(0)
499         }
500     }
501 }
502 
503 impl Drop for ReadEventsGuard {
drop(&mut self)504     fn drop(&mut self) {
505         if !self.done {
506             let mut backend = self.backend.lock().unwrap();
507             backend.prepared_reads -= 1;
508             if backend.prepared_reads == 0 {
509                 // Cancel the read
510                 backend.read_serial = backend.read_serial.wrapping_add(1);
511                 backend.read_condvar.notify_all();
512             }
513         }
514     }
515 }
516 
517 impl Handle {
518     /// Get the object ID for the `wl_display`
display_id(&self) -> ObjectId519     pub fn display_id(&self) -> ObjectId {
520         ObjectId { serial: 0, id: 1, interface: &WL_DISPLAY_INTERFACE }
521     }
522 
523     /// Get the last error that occurred on this backend
524     ///
525     /// If this returns an error, your Wayland connection is already dead.
last_error(&self) -> Option<WaylandError>526     pub fn last_error(&self) -> Option<WaylandError> {
527         self.last_error.clone()
528     }
529 
530     /// Get the detailed information about a wayland object
531     ///
532     /// Returns an error if the provided object ID is no longer valid.
info(&self, id: ObjectId) -> Result<ObjectInfo, InvalidId>533     pub fn info(&self, id: ObjectId) -> Result<ObjectInfo, InvalidId> {
534         let object = self.get_object(id.clone())?;
535         if object.data.client_destroyed {
536             Err(InvalidId)
537         } else {
538             Ok(ObjectInfo { id: id.id, interface: object.interface, version: object.version })
539         }
540     }
541 
542     /// Create a null object ID
543     ///
544     /// This object ID is always invalid, and can be used as placeholder.
null_id(&mut self) -> ObjectId545     pub fn null_id(&mut self) -> ObjectId {
546         ObjectId { serial: 0, id: 0, interface: &ANONYMOUS_INTERFACE }
547     }
548 
549     /// Create a placeholder ID for object creation
550     ///
551     /// This ID needs to be created beforehand and given as argument to a request creating a
552     /// new object ID. A specification must be specified if the interface and version cannot
553     /// be inferred from the protocol (for example object creation from the `wl_registry`).
554     ///
555     /// If a specification is provided it'll be checked against what can be deduced from the
556     /// protocol specification, and [`send_request`](Handle::send_request) will panic if they
557     /// do not match.
placeholder_id(&mut self, spec: Option<(&'static Interface, u32)>) -> ObjectId558     pub fn placeholder_id(&mut self, spec: Option<(&'static Interface, u32)>) -> ObjectId {
559         self.pending_placeholder = spec;
560         ObjectId {
561             serial: 0,
562             id: 0,
563             interface: spec.map(|(i, _)| i).unwrap_or(&ANONYMOUS_INTERFACE),
564         }
565     }
566 
567     /// Sends a request to the server
568     ///
569     /// Returns an error if the sender ID of the provided message is no longer valid.
570     ///
571     /// **Panic:**
572     ///
573     /// Several checks against the protocol specification are done, and this method will panic if they do
574     /// not pass:
575     ///
576     /// - the message opcode must be valid for the sender interface
577     /// - the argument list must match the prototype for the message associated with this opcode
578     /// - if the method creates a new object, a [`placeholder_id()`](Handle::placeholder_id) must be given
579     ///   in the argument list, either without a specification, or with a specification that matches the
580     ///   interface and version deduced from the protocol rules
581     pub fn send_request(
582         &mut self,
583         Message { sender_id: id, opcode, args }: Message<ObjectId>,
584         data: Option<Arc<dyn ObjectData>>,
585     ) -> Result<ObjectId, InvalidId> {
586         let object = self.get_object(id.clone())?;
587         if object.data.client_destroyed {
588             return Err(InvalidId);
589         }
590 
591         let message_desc = match object.interface.requests.get(opcode as usize) {
592             Some(msg) => msg,
593             None => {
594                 panic!("Unknown opcode {} for object {}@{}.", opcode, object.interface.name, id.id);
595             }
596         };
597 
598         if !check_for_signature(message_desc.signature, &args) {
599             panic!(
600                 "Unexpected signature for request {}@{}.{}: expected {:?}, got {:?}.",
601                 object.interface.name, id.id, message_desc.name, message_desc.signature, args
602             );
603         }
604 
605         // Prepare the child object
606         let child_spec = if message_desc
607             .signature
608             .iter()
609             .any(|arg| matches!(arg, ArgumentType::NewId(_)))
610         {
611             if let Some((iface, version)) = self.pending_placeholder.take() {
612                 if let Some(child_interface) = message_desc.child_interface {
613                     if !same_interface(child_interface, iface) {
614                         panic!(
615                             "Wrong placeholder used when sending request {}@{}.{}: expected interface {} but got {}",
616                             object.interface.name,
617                             id.id,
618                             message_desc.name,
619                             child_interface.name,
620                             iface.name
621                         );
622                     }
623                     if version != object.version {
624                         panic!(
625                             "Wrong placeholder used when sending request {}@{}.{}: expected version {} but got {}",
626                             object.interface.name,
627                             id.id, message_desc.name,
628                             object.version,
629                             version
630                         );
631                     }
632                 }
633                 Some((iface, version))
634             } else if let Some(child_interface) = message_desc.child_interface {
635                 Some((child_interface, object.version))
636             } else {
637                 panic!(
638                     "Wrong placeholder used when sending request {}@{}.{}: target interface must be specified for a generic constructor.",
639                     object.interface.name,
640                     id.id,
641                     message_desc.name
642                 );
643             }
644         } else {
645             None
646         };
647 
648         let child = if let Some((child_interface, child_version)) = child_spec {
649             let child_serial = self.next_serial();
650 
651             let child = Object {
652                 interface: child_interface,
653                 version: child_version,
654                 data: Data {
655                     client_destroyed: false,
656                     server_destroyed: false,
657                     user_data: Arc::new(DumbObjectData),
658                     serial: child_serial,
659                 },
660             };
661 
662             let child_id = self.map.client_insert_new(child);
663 
664             self.map
665                 .with(child_id, |obj| {
666                     obj.data.user_data = data.expect(
667                         "Sending a request creating an object without providing an object data.",
668                     );
669                 })
670                 .unwrap();
671             Some((child_id, child_serial, child_interface))
672         } else {
673             None
674         };
675 
676         // Prepare the message in a debug-compatible way
677         let args = args.into_iter().map(|arg| {
678             if let Argument::NewId(p) = arg {
679                 if !p.id == 0 {
680                     panic!("The newid provided when sending request {}@{}.{} is not a placeholder.", object.interface.name, id.id, message_desc.name);
681                 }
682                 if let Some((child_id, child_serial, child_interface)) = child {
683                     Argument::NewId(ObjectId { id: child_id, serial: child_serial, interface: child_interface})
684                 } else {
685                     unreachable!();
686                 }
687             } else {
688                 arg
689             }
690         }).collect::<SmallVec<[_; INLINE_ARGS]>>();
691 
692         if self.debug {
693             super::debug::print_send_message(
694                 object.interface.name,
695                 id.id,
696                 message_desc.name,
697                 &args,
698             );
699         }
700         log::debug!("Sending {}.{} ({})", id, message_desc.name, DisplaySlice(&args));
701 
702         // Send the message
703 
704         let mut msg_args = SmallVec::with_capacity(args.len());
705         let mut arg_interfaces = message_desc.arg_interfaces.iter();
706         for (i, arg) in args.into_iter().enumerate() {
707             msg_args.push(match arg {
708                 Argument::Array(a) => Argument::Array(a),
709                 Argument::Int(i) => Argument::Int(i),
710                 Argument::Uint(u) => Argument::Uint(u),
711                 Argument::Str(s) => Argument::Str(s),
712                 Argument::Fixed(f) => Argument::Fixed(f),
713                 Argument::NewId(nid) => Argument::NewId(nid.id),
714                 Argument::Fd(f) => Argument::Fd(f),
715                 Argument::Object(o) => {
716                     if o.id != 0 {
717                         let object = self.get_object(o.clone())?;
718                         let next_interface = arg_interfaces.next().unwrap();
719                         if !same_interface_or_anonymous(next_interface, object.interface) {
720                             panic!("Request {}@{}.{} expects an argument of interface {} but {} was provided instead.", object.interface.name, id.id, message_desc.name, next_interface.name, object.interface.name);
721                         }
722                     } else if !matches!(message_desc.signature[i], ArgumentType::Object(AllowNull::Yes)) {
723                         panic!("Request {}@{}.{} expects an non-null object argument.", object.interface.name, id.id, message_desc.name);
724                     }
725                     Argument::Object(o.id)
726                 }
727             });
728         }
729 
730         let msg = Message { sender_id: id.id, opcode, args: msg_args };
731 
732         if let Err(err) = self.socket.write_message(&msg) {
733             self.last_error = Some(WaylandError::Io(err));
734         }
735 
736         // Handle destruction if relevant
737         if message_desc.is_destructor {
738             self.map
739                 .with(id.id, |obj| {
740                     obj.data.client_destroyed = true;
741                 })
742                 .unwrap();
743             object.data.user_data.destroyed(id);
744         }
745         if let Some((child_id, child_serial, child_interface)) = child {
746             Ok(ObjectId { id: child_id, serial: child_serial, interface: child_interface })
747         } else {
748             Ok(self.null_id())
749         }
750     }
751 
752     /// Access the object data associated with a given object ID
753     ///
754     /// Returns an error if the object ID is not longer valid
get_data(&self, id: ObjectId) -> Result<Arc<dyn ObjectData>, InvalidId>755     pub fn get_data(&self, id: ObjectId) -> Result<Arc<dyn ObjectData>, InvalidId> {
756         let object = self.get_object(id)?;
757         Ok(object.data.user_data)
758     }
759 
760     /// Set the object data associated with a given object ID
761     ///
762     /// Returns an error if the object ID is not longer valid
set_data(&mut self, id: ObjectId, data: Arc<dyn ObjectData>) -> Result<(), InvalidId>763     pub fn set_data(&mut self, id: ObjectId, data: Arc<dyn ObjectData>) -> Result<(), InvalidId> {
764         self.map
765             .with(id.id, move |objdata| {
766                 if objdata.data.serial != id.serial {
767                     Err(InvalidId)
768                 } else {
769                     objdata.data.user_data = data;
770                     Ok(())
771                 }
772             })
773             .unwrap_or(Err(InvalidId))
774     }
775 }
776 
777 impl Handle {
next_serial(&mut self) -> u32778     fn next_serial(&mut self) -> u32 {
779         self.last_serial = self.last_serial.wrapping_add(1);
780         self.last_serial
781     }
782 
783     #[inline]
no_last_error(&self) -> Result<(), WaylandError>784     fn no_last_error(&self) -> Result<(), WaylandError> {
785         if let Some(ref err) = self.last_error {
786             Err(err.clone())
787         } else {
788             Ok(())
789         }
790     }
791 
792     #[inline]
store_and_return_error(&mut self, err: impl Into<WaylandError>) -> WaylandError793     fn store_and_return_error(&mut self, err: impl Into<WaylandError>) -> WaylandError {
794         let err = err.into();
795         log::error!("{}", err);
796         self.last_error = Some(err.clone());
797         err
798     }
799 
800     #[inline]
store_if_not_wouldblock_and_return_error(&mut self, e: std::io::Error) -> WaylandError801     fn store_if_not_wouldblock_and_return_error(&mut self, e: std::io::Error) -> WaylandError {
802         if e.kind() != std::io::ErrorKind::WouldBlock {
803             self.store_and_return_error(e)
804         } else {
805             e.into()
806         }
807     }
808 
get_object(&self, id: ObjectId) -> Result<Object<Data>, InvalidId>809     fn get_object(&self, id: ObjectId) -> Result<Object<Data>, InvalidId> {
810         let object = self.map.find(id.id).ok_or(InvalidId)?;
811         if object.data.serial != id.serial {
812             return Err(InvalidId);
813         }
814         Ok(object)
815     }
816 
handle_display_event(&mut self, message: Message<u32>) -> Result<(), WaylandError>817     fn handle_display_event(&mut self, message: Message<u32>) -> Result<(), WaylandError> {
818         match message.opcode {
819             0 => {
820                 // wl_display.error
821                 if let [Argument::Object(obj), Argument::Uint(code), Argument::Str(ref message)] =
822                     message.args[..]
823                 {
824                     let object = self.map.find(obj);
825                     let err = WaylandError::Protocol(ProtocolError {
826                         code,
827                         object_id: obj,
828                         object_interface: object
829                             .map(|obj| obj.interface.name)
830                             .unwrap_or("<unknown>")
831                             .into(),
832                         message: message.to_string_lossy().into(),
833                     });
834                     return Err(self.store_and_return_error(err));
835                 } else {
836                     unreachable!()
837                 }
838             }
839             1 => {
840                 // wl_display.delete_id
841                 if let [Argument::Uint(id)] = message.args[..] {
842                     let client_destroyed = self
843                         .map
844                         .with(id, |obj| {
845                             obj.data.server_destroyed = true;
846                             obj.data.client_destroyed
847                         })
848                         .unwrap_or(false);
849                     if client_destroyed {
850                         self.map.remove(id);
851                     }
852                 } else {
853                     unreachable!()
854                 }
855             }
856             _ => unreachable!(),
857         }
858         Ok(())
859     }
860 }
861 
862 struct DumbObjectData;
863 
864 impl ObjectData for DumbObjectData {
event( self: Arc<Self>, _handle: &mut Handle, _msg: Message<ObjectId>, ) -> Option<Arc<dyn ObjectData>>865     fn event(
866         self: Arc<Self>,
867         _handle: &mut Handle,
868         _msg: Message<ObjectId>,
869     ) -> Option<Arc<dyn ObjectData>> {
870         unreachable!()
871     }
872 
destroyed(&self, _object_id: ObjectId)873     fn destroyed(&self, _object_id: ObjectId) {
874         unreachable!()
875     }
876 }
877 
878 struct UninitObjectData;
879 
880 impl ObjectData for UninitObjectData {
event( self: Arc<Self>, _handle: &mut Handle, msg: Message<ObjectId>, ) -> Option<Arc<dyn ObjectData>>881     fn event(
882         self: Arc<Self>,
883         _handle: &mut Handle,
884         msg: Message<ObjectId>,
885     ) -> Option<Arc<dyn ObjectData>> {
886         panic!("Received a message on an uninitialized object: {:?}", msg);
887     }
888 
destroyed(&self, _object_id: ObjectId)889     fn destroyed(&self, _object_id: ObjectId) {}
890 
debug(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result891     fn debug(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
892         f.debug_struct("UninitObjectData").finish()
893     }
894 }
895