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