1 // Copyright 2015-2016, The Gtk-rs Project Developers. 2 // See the COPYRIGHT file at the top-level directory of this distribution. 3 // Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT> 4 5 //! `IMPL` Object wrapper implementation and `Object` binding. 6 7 use glib_sys; 8 use gobject_sys; 9 use std::cmp; 10 use std::fmt; 11 use std::hash; 12 use std::marker::PhantomData; 13 use std::mem; 14 use std::ops; 15 use std::ptr; 16 use translate::*; 17 use types::StaticType; 18 19 use value::ToValue; 20 use BoolError; 21 use Closure; 22 use SignalHandlerId; 23 use Type; 24 use Value; 25 26 use get_thread_id; 27 28 #[doc(hidden)] 29 pub use gobject_sys::GObject; 30 31 #[doc(hidden)] 32 pub use gobject_sys::GObjectClass; 33 34 /// Implemented by types representing `glib::Object` and subclasses of it. 35 pub unsafe trait ObjectType: 36 UnsafeFrom<ObjectRef> 37 + Into<ObjectRef> 38 + StaticType 39 + fmt::Debug 40 + Clone 41 + PartialEq 42 + Eq 43 + PartialOrd 44 + Ord 45 + hash::Hash 46 + for<'a> ToGlibPtr<'a, *mut <Self as ObjectType>::GlibType> 47 + 'static 48 { 49 /// type of the FFI Instance structure. 50 type GlibType: 'static; 51 /// type of the FFI Class structure. 52 type GlibClassType: 'static; 53 /// type of the Rust Class structure. 54 type RustClassType: 'static; 55 as_object_ref(&self) -> &ObjectRef56 fn as_object_ref(&self) -> &ObjectRef; as_ptr(&self) -> *mut Self::GlibType57 fn as_ptr(&self) -> *mut Self::GlibType; 58 } 59 60 /// Unsafe variant of the `From` trait. 61 pub trait UnsafeFrom<T> { unsafe_from(t: T) -> Self62 unsafe fn unsafe_from(t: T) -> Self; 63 } 64 65 /// Declares the "is a" relationship. 66 /// 67 /// `Self` is said to implement `T`. 68 /// 69 /// For instance, since originally `GtkWidget` is a subclass of `GObject` and 70 /// implements the `GtkBuildable` interface, `gtk::Widget` implements 71 /// `IsA<glib::Object>` and `IsA<gtk::Buildable>`. 72 /// 73 /// 74 /// The trait can only be implemented if the appropriate `ToGlibPtr` 75 /// implementations exist. 76 pub unsafe trait IsA<T: ObjectType>: ObjectType + AsRef<T> + 'static {} 77 78 /// Trait for mapping a class struct type to its corresponding instance type. 79 pub unsafe trait IsClassFor: Sized + 'static { 80 /// Corresponding Rust instance type for this class. 81 type Instance: ObjectType; 82 83 /// Get the type id for this class. get_type(&self) -> Type84 fn get_type(&self) -> Type { 85 unsafe { 86 let klass = self as *const _ as *const gobject_sys::GTypeClass; 87 from_glib((*klass).g_type) 88 } 89 } 90 91 /// Casts this class to a reference to a parent type's class. upcast_ref<U: IsClassFor>(&self) -> &U where Self::Instance: IsA<U::Instance>, U::Instance: ObjectType,92 fn upcast_ref<U: IsClassFor>(&self) -> &U 93 where 94 Self::Instance: IsA<U::Instance>, 95 U::Instance: ObjectType, 96 { 97 unsafe { 98 let klass = self as *const _ as *const U; 99 &*klass 100 } 101 } 102 103 /// Casts this class to a mutable reference to a parent type's class. upcast_ref_mut<U: IsClassFor>(&mut self) -> &mut U where Self::Instance: IsA<U::Instance>, U::Instance: ObjectType,104 fn upcast_ref_mut<U: IsClassFor>(&mut self) -> &mut U 105 where 106 Self::Instance: IsA<U::Instance>, 107 U::Instance: ObjectType, 108 { 109 unsafe { 110 let klass = self as *mut _ as *mut U; 111 &mut *klass 112 } 113 } 114 115 /// Casts this class to a reference to a child type's class or 116 /// fails if this class is not implementing the child class. downcast_ref<U: IsClassFor>(&self) -> Option<&U> where U::Instance: IsA<Self::Instance>, Self::Instance: ObjectType,117 fn downcast_ref<U: IsClassFor>(&self) -> Option<&U> 118 where 119 U::Instance: IsA<Self::Instance>, 120 Self::Instance: ObjectType, 121 { 122 if !self.get_type().is_a(&U::Instance::static_type()) { 123 return None; 124 } 125 126 unsafe { 127 let klass = self as *const _ as *const U; 128 Some(&*klass) 129 } 130 } 131 132 /// Casts this class to a mutable reference to a child type's class or 133 /// fails if this class is not implementing the child class. downcast_ref_mut<U: IsClassFor>(&mut self) -> Option<&mut U> where U::Instance: IsA<Self::Instance>, Self::Instance: ObjectType,134 fn downcast_ref_mut<U: IsClassFor>(&mut self) -> Option<&mut U> 135 where 136 U::Instance: IsA<Self::Instance>, 137 Self::Instance: ObjectType, 138 { 139 if !self.get_type().is_a(&U::Instance::static_type()) { 140 return None; 141 } 142 143 unsafe { 144 let klass = self as *mut _ as *mut U; 145 Some(&mut *klass) 146 } 147 } 148 149 /// Gets the class struct corresponding to `type_`. 150 /// 151 /// This will return `None` if `type_` is not a subclass of `Self`. from_type(type_: Type) -> Option<ClassRef<Self>>152 fn from_type(type_: Type) -> Option<ClassRef<Self>> { 153 if !type_.is_a(&Self::Instance::static_type()) { 154 return None; 155 } 156 157 unsafe { 158 let ptr = gobject_sys::g_type_class_ref(type_.to_glib()); 159 if ptr.is_null() { 160 None 161 } else { 162 Some(ClassRef(ptr::NonNull::new_unchecked(ptr as *mut Self))) 163 } 164 } 165 } 166 } 167 168 #[derive(Debug)] 169 pub struct ClassRef<T: IsClassFor>(ptr::NonNull<T>); 170 171 impl<T: IsClassFor> ops::Deref for ClassRef<T> { 172 type Target = T; 173 deref(&self) -> &T174 fn deref(&self) -> &T { 175 unsafe { self.0.as_ref() } 176 } 177 } 178 179 impl<T: IsClassFor> Drop for ClassRef<T> { drop(&mut self)180 fn drop(&mut self) { 181 unsafe { 182 gobject_sys::g_type_class_unref(self.0.as_ptr() as *mut _); 183 } 184 } 185 } 186 187 unsafe impl<T: IsClassFor> Send for ClassRef<T> {} 188 unsafe impl<T: IsClassFor> Sync for ClassRef<T> {} 189 190 /// Upcasting and downcasting support. 191 /// 192 /// Provides conversions up and down the class hierarchy tree. 193 pub trait Cast: ObjectType { 194 /// Upcasts an object to a superclass or interface `T`. 195 /// 196 /// *NOTE*: This statically checks at compile-time if casting is possible. It is not always 197 /// known at compile-time, whether a specific object implements an interface or not, in which case 198 /// `upcast` would fail to compile. `dynamic_cast` can be used in these circumstances, which 199 /// is checking the types at runtime. 200 /// 201 /// # Example 202 /// 203 /// ```ignore 204 /// let button = gtk::Button::new(); 205 /// let widget = button.upcast::<gtk::Widget>(); 206 /// ``` 207 #[inline] upcast<T: ObjectType>(self) -> T where Self: IsA<T>,208 fn upcast<T: ObjectType>(self) -> T 209 where 210 Self: IsA<T>, 211 { 212 unsafe { self.unsafe_cast() } 213 } 214 215 /// Upcasts an object to a reference of its superclass or interface `T`. 216 /// 217 /// *NOTE*: This statically checks at compile-time if casting is possible. It is not always 218 /// known at compile-time, whether a specific object implements an interface or not, in which case 219 /// `upcast` would fail to compile. `dynamic_cast` can be used in these circumstances, which 220 /// is checking the types at runtime. 221 /// 222 /// # Example 223 /// 224 /// ```ignore 225 /// let button = gtk::Button::new(); 226 /// let widget = button.upcast_ref::<gtk::Widget>(); 227 /// ``` 228 #[inline] upcast_ref<T: ObjectType>(&self) -> &T where Self: IsA<T>,229 fn upcast_ref<T: ObjectType>(&self) -> &T 230 where 231 Self: IsA<T>, 232 { 233 unsafe { self.unsafe_cast_ref() } 234 } 235 236 /// Tries to downcast to a subclass or interface implementor `T`. 237 /// 238 /// Returns `Ok(T)` if the object is an instance of `T` and `Err(self)` 239 /// otherwise. 240 /// 241 /// *NOTE*: This statically checks at compile-time if casting is possible. It is not always 242 /// known at compile-time, whether a specific object implements an interface or not, in which case 243 /// `upcast` would fail to compile. `dynamic_cast` can be used in these circumstances, which 244 /// is checking the types at runtime. 245 /// 246 /// # Example 247 /// 248 /// ```ignore 249 /// let button = gtk::Button::new(); 250 /// let widget = button.upcast::<gtk::Widget>(); 251 /// assert!(widget.downcast::<gtk::Button>().is_ok()); 252 /// ``` 253 #[inline] downcast<T: ObjectType>(self) -> Result<T, Self> where Self: CanDowncast<T>,254 fn downcast<T: ObjectType>(self) -> Result<T, Self> 255 where 256 Self: CanDowncast<T>, 257 { 258 if self.is::<T>() { 259 Ok(unsafe { self.unsafe_cast() }) 260 } else { 261 Err(self) 262 } 263 } 264 265 /// Tries to downcast to a reference of its subclass or interface implementor `T`. 266 /// 267 /// Returns `Some(T)` if the object is an instance of `T` and `None` 268 /// otherwise. 269 /// 270 /// *NOTE*: This statically checks at compile-time if casting is possible. It is not always 271 /// known at compile-time, whether a specific object implements an interface or not, in which case 272 /// `upcast` would fail to compile. `dynamic_cast` can be used in these circumstances, which 273 /// is checking the types at runtime. 274 /// 275 /// # Example 276 /// 277 /// ```ignore 278 /// let button = gtk::Button::new(); 279 /// let widget = button.upcast::<gtk::Widget>(); 280 /// assert!(widget.downcast_ref::<gtk::Button>().is_some()); 281 /// ``` 282 #[inline] downcast_ref<T: ObjectType>(&self) -> Option<&T> where Self: CanDowncast<T>,283 fn downcast_ref<T: ObjectType>(&self) -> Option<&T> 284 where 285 Self: CanDowncast<T>, 286 { 287 if self.is::<T>() { 288 Some(unsafe { self.unsafe_cast_ref() }) 289 } else { 290 None 291 } 292 } 293 294 /// Tries to cast to an object of type `T`. This handles upcasting, downcasting 295 /// and casting between interface and interface implementors. All checks are performed at 296 /// runtime, while `downcast` and `upcast` will do many checks at compile-time already. 297 /// 298 /// It is not always known at compile-time, whether a specific object implements an interface or 299 /// not, and checking as to be performed at runtime. 300 /// 301 /// Returns `Ok(T)` if the object is an instance of `T` and `Err(self)` 302 /// otherwise. 303 /// 304 /// # Example 305 /// 306 /// ```ignore 307 /// let button = gtk::Button::new(); 308 /// let widget = button.dynamic_cast::<gtk::Widget>(); 309 /// assert!(widget.is_ok()); 310 /// let widget = widget.unwrap(); 311 /// assert!(widget.dynamic_cast::<gtk::Button>().is_ok()); 312 /// ``` 313 #[inline] dynamic_cast<T: ObjectType>(self) -> Result<T, Self>314 fn dynamic_cast<T: ObjectType>(self) -> Result<T, Self> { 315 if !self.is::<T>() { 316 Err(self) 317 } else { 318 Ok(unsafe { self.unsafe_cast() }) 319 } 320 } 321 322 /// Tries to cast to reference to an object of type `T`. This handles upcasting, downcasting 323 /// and casting between interface and interface implementors. All checks are performed at 324 /// runtime, while `downcast` and `upcast` will do many checks at compile-time already. 325 /// 326 /// It is not always known at compile-time, whether a specific object implements an interface or 327 /// not, and checking as to be performed at runtime. 328 /// 329 /// Returns `Some(T)` if the object is an instance of `T` and `None` 330 /// otherwise. 331 /// 332 /// # Example 333 /// 334 /// ```ignore 335 /// let button = gtk::Button::new(); 336 /// let widget = button.dynamic_cast_ref::<gtk::Widget>(); 337 /// assert!(widget.is_some()); 338 /// let widget = widget.unwrap(); 339 /// assert!(widget.dynamic_cast_ref::<gtk::Button>().is_some()); 340 /// ``` 341 #[inline] dynamic_cast_ref<T: ObjectType>(&self) -> Option<&T>342 fn dynamic_cast_ref<T: ObjectType>(&self) -> Option<&T> { 343 if !self.is::<T>() { 344 None 345 } else { 346 // This transmute is safe because all our wrapper types have the 347 // same representation except for the name and the phantom data 348 // type. IsA<> is an unsafe trait that must only be implemented 349 // if this is a valid wrapper type 350 Some(unsafe { self.unsafe_cast_ref() }) 351 } 352 } 353 354 /// Casts to `T` unconditionally. 355 /// 356 /// Panics if compiled with `debug_assertions` and the instance doesn't implement `T`. unsafe_cast<T: ObjectType>(self) -> T357 unsafe fn unsafe_cast<T: ObjectType>(self) -> T { 358 debug_assert!(self.is::<T>()); 359 T::unsafe_from(self.into()) 360 } 361 362 /// Casts to `&T` unconditionally. 363 /// 364 /// Panics if compiled with `debug_assertions` and the instance doesn't implement `T`. unsafe_cast_ref<T: ObjectType>(&self) -> &T365 unsafe fn unsafe_cast_ref<T: ObjectType>(&self) -> &T { 366 debug_assert!(self.is::<T>()); 367 // This transmute is safe because all our wrapper types have the 368 // same representation except for the name and the phantom data 369 // type. IsA<> is an unsafe trait that must only be implemented 370 // if this is a valid wrapper type 371 &*(self as *const Self as *const T) 372 } 373 } 374 375 impl<T: ObjectType> Cast for T {} 376 377 /// Marker trait for the statically known possibility of downcasting from `Self` to `T`. 378 pub trait CanDowncast<T> {} 379 380 impl<Super: IsA<Super>, Sub: IsA<Super>> CanDowncast<Sub> for Super {} 381 382 // Manual implementation of glib_shared_wrapper! because of special cases 383 pub struct ObjectRef { 384 inner: ptr::NonNull<GObject>, 385 borrowed: bool, 386 } 387 388 impl Clone for ObjectRef { clone(&self) -> Self389 fn clone(&self) -> Self { 390 unsafe { 391 ObjectRef { 392 inner: ptr::NonNull::new_unchecked(gobject_sys::g_object_ref(self.inner.as_ptr())), 393 borrowed: false, 394 } 395 } 396 } 397 } 398 399 impl Drop for ObjectRef { drop(&mut self)400 fn drop(&mut self) { 401 unsafe { 402 if !self.borrowed { 403 gobject_sys::g_object_unref(self.inner.as_ptr()); 404 } 405 } 406 } 407 } 408 409 impl fmt::Debug for ObjectRef { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result410 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 411 let type_ = unsafe { 412 let klass = (*self.inner.as_ptr()).g_type_instance.g_class as *const ObjectClass; 413 (&*klass).get_type() 414 }; 415 416 f.debug_struct("ObjectRef") 417 .field("inner", &self.inner) 418 .field("type", &type_) 419 .field("borrowed", &self.borrowed) 420 .finish() 421 } 422 } 423 424 impl PartialOrd for ObjectRef { partial_cmp(&self, other: &Self) -> Option<cmp::Ordering>425 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { 426 self.inner.partial_cmp(&other.inner) 427 } 428 } 429 430 impl Ord for ObjectRef { cmp(&self, other: &Self) -> cmp::Ordering431 fn cmp(&self, other: &Self) -> cmp::Ordering { 432 self.inner.cmp(&other.inner) 433 } 434 } 435 436 impl PartialEq for ObjectRef { eq(&self, other: &Self) -> bool437 fn eq(&self, other: &Self) -> bool { 438 self.inner == other.inner 439 } 440 } 441 442 impl Eq for ObjectRef {} 443 444 impl hash::Hash for ObjectRef { hash<H>(&self, state: &mut H) where H: hash::Hasher,445 fn hash<H>(&self, state: &mut H) 446 where 447 H: hash::Hasher, 448 { 449 self.inner.hash(state) 450 } 451 } 452 453 #[doc(hidden)] 454 impl GlibPtrDefault for ObjectRef { 455 type GlibType = *mut GObject; 456 } 457 458 #[doc(hidden)] 459 impl<'a> ToGlibPtr<'a, *mut GObject> for ObjectRef { 460 type Storage = &'a ObjectRef; 461 462 #[inline] to_glib_none(&'a self) -> Stash<'a, *mut GObject, Self>463 fn to_glib_none(&'a self) -> Stash<'a, *mut GObject, Self> { 464 Stash(self.inner.as_ptr(), self) 465 } 466 467 #[inline] to_glib_full(&self) -> *mut GObject468 fn to_glib_full(&self) -> *mut GObject { 469 unsafe { gobject_sys::g_object_ref(self.inner.as_ptr()) } 470 } 471 } 472 473 #[doc(hidden)] 474 impl<'a> ToGlibContainerFromSlice<'a, *mut *mut GObject> for ObjectRef { 475 type Storage = ( 476 Vec<Stash<'a, *mut GObject, ObjectRef>>, 477 Option<Vec<*mut GObject>>, 478 ); 479 to_glib_none_from_slice(t: &'a [ObjectRef]) -> (*mut *mut GObject, Self::Storage)480 fn to_glib_none_from_slice(t: &'a [ObjectRef]) -> (*mut *mut GObject, Self::Storage) { 481 let v: Vec<_> = t.iter().map(|s| s.to_glib_none()).collect(); 482 let mut v_ptr: Vec<_> = v.iter().map(|s| s.0).collect(); 483 v_ptr.push(ptr::null_mut() as *mut GObject); 484 485 (v_ptr.as_ptr() as *mut *mut GObject, (v, Some(v_ptr))) 486 } 487 to_glib_container_from_slice(t: &'a [ObjectRef]) -> (*mut *mut GObject, Self::Storage)488 fn to_glib_container_from_slice(t: &'a [ObjectRef]) -> (*mut *mut GObject, Self::Storage) { 489 let v: Vec<_> = t.iter().map(|s| s.to_glib_none()).collect(); 490 491 let v_ptr = unsafe { 492 let v_ptr = glib_sys::g_malloc0(mem::size_of::<*mut GObject>() * (t.len() + 1)) 493 as *mut *mut GObject; 494 495 for (i, s) in v.iter().enumerate() { 496 ptr::write(v_ptr.add(i), s.0); 497 } 498 499 v_ptr 500 }; 501 502 (v_ptr, (v, None)) 503 } 504 to_glib_full_from_slice(t: &[ObjectRef]) -> *mut *mut GObject505 fn to_glib_full_from_slice(t: &[ObjectRef]) -> *mut *mut GObject { 506 unsafe { 507 let v_ptr = glib_sys::g_malloc0(std::mem::size_of::<*mut GObject>() * (t.len() + 1)) 508 as *mut *mut GObject; 509 510 for (i, s) in t.iter().enumerate() { 511 ptr::write(v_ptr.add(i), s.to_glib_full()); 512 } 513 514 v_ptr 515 } 516 } 517 } 518 519 #[doc(hidden)] 520 impl<'a> ToGlibContainerFromSlice<'a, *const *mut GObject> for ObjectRef { 521 type Storage = ( 522 Vec<Stash<'a, *mut GObject, ObjectRef>>, 523 Option<Vec<*mut GObject>>, 524 ); 525 to_glib_none_from_slice(t: &'a [ObjectRef]) -> (*const *mut GObject, Self::Storage)526 fn to_glib_none_from_slice(t: &'a [ObjectRef]) -> (*const *mut GObject, Self::Storage) { 527 let (ptr, stash) = 528 ToGlibContainerFromSlice::<'a, *mut *mut GObject>::to_glib_none_from_slice(t); 529 (ptr as *const *mut GObject, stash) 530 } 531 to_glib_container_from_slice(_: &'a [ObjectRef]) -> (*const *mut GObject, Self::Storage)532 fn to_glib_container_from_slice(_: &'a [ObjectRef]) -> (*const *mut GObject, Self::Storage) { 533 // Can't have consumer free a *const pointer 534 unimplemented!() 535 } 536 to_glib_full_from_slice(_: &[ObjectRef]) -> *const *mut GObject537 fn to_glib_full_from_slice(_: &[ObjectRef]) -> *const *mut GObject { 538 // Can't have consumer free a *const pointer 539 unimplemented!() 540 } 541 } 542 543 #[doc(hidden)] 544 impl FromGlibPtrNone<*mut GObject> for ObjectRef { 545 #[inline] from_glib_none(ptr: *mut GObject) -> Self546 unsafe fn from_glib_none(ptr: *mut GObject) -> Self { 547 assert!(!ptr.is_null()); 548 549 // Attention: This takes ownership of floating references! 550 ObjectRef { 551 inner: ptr::NonNull::new_unchecked(gobject_sys::g_object_ref_sink(ptr)), 552 borrowed: false, 553 } 554 } 555 } 556 557 #[doc(hidden)] 558 impl FromGlibPtrNone<*const GObject> for ObjectRef { 559 #[inline] from_glib_none(ptr: *const GObject) -> Self560 unsafe fn from_glib_none(ptr: *const GObject) -> Self { 561 // Attention: This takes ownership of floating references! 562 from_glib_none(ptr as *mut GObject) 563 } 564 } 565 566 #[doc(hidden)] 567 impl FromGlibPtrFull<*mut GObject> for ObjectRef { 568 #[inline] from_glib_full(ptr: *mut GObject) -> Self569 unsafe fn from_glib_full(ptr: *mut GObject) -> Self { 570 assert!(!ptr.is_null()); 571 572 ObjectRef { 573 inner: ptr::NonNull::new_unchecked(ptr), 574 borrowed: false, 575 } 576 } 577 } 578 579 #[doc(hidden)] 580 impl FromGlibPtrBorrow<*mut GObject> for ObjectRef { 581 #[inline] from_glib_borrow(ptr: *mut GObject) -> Self582 unsafe fn from_glib_borrow(ptr: *mut GObject) -> Self { 583 assert!(!ptr.is_null()); 584 585 ObjectRef { 586 inner: ptr::NonNull::new_unchecked(ptr), 587 borrowed: true, 588 } 589 } 590 } 591 592 #[doc(hidden)] 593 impl FromGlibPtrBorrow<*const GObject> for ObjectRef { 594 #[inline] from_glib_borrow(ptr: *const GObject) -> Self595 unsafe fn from_glib_borrow(ptr: *const GObject) -> Self { 596 from_glib_borrow(ptr as *mut GObject) 597 } 598 } 599 600 #[doc(hidden)] 601 impl FromGlibContainerAsVec<*mut GObject, *mut *mut GObject> for ObjectRef { from_glib_none_num_as_vec(ptr: *mut *mut GObject, num: usize) -> Vec<Self>602 unsafe fn from_glib_none_num_as_vec(ptr: *mut *mut GObject, num: usize) -> Vec<Self> { 603 if num == 0 || ptr.is_null() { 604 return Vec::new(); 605 } 606 607 // Attention: This takes ownership of floating references! 608 let mut res = Vec::with_capacity(num); 609 for i in 0..num { 610 res.push(from_glib_none(ptr::read(ptr.add(i)))); 611 } 612 res 613 } 614 from_glib_container_num_as_vec(ptr: *mut *mut GObject, num: usize) -> Vec<Self>615 unsafe fn from_glib_container_num_as_vec(ptr: *mut *mut GObject, num: usize) -> Vec<Self> { 616 // Attention: This takes ownership of floating references! 617 let res = FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, num); 618 glib_sys::g_free(ptr as *mut _); 619 res 620 } 621 from_glib_full_num_as_vec(ptr: *mut *mut GObject, num: usize) -> Vec<Self>622 unsafe fn from_glib_full_num_as_vec(ptr: *mut *mut GObject, num: usize) -> Vec<Self> { 623 if num == 0 || ptr.is_null() { 624 return Vec::new(); 625 } 626 627 let mut res = Vec::with_capacity(num); 628 for i in 0..num { 629 res.push(from_glib_full(ptr::read(ptr.add(i)))); 630 } 631 glib_sys::g_free(ptr as *mut _); 632 res 633 } 634 } 635 636 #[doc(hidden)] 637 impl FromGlibPtrArrayContainerAsVec<*mut GObject, *mut *mut GObject> for ObjectRef { from_glib_none_as_vec(ptr: *mut *mut GObject) -> Vec<Self>638 unsafe fn from_glib_none_as_vec(ptr: *mut *mut GObject) -> Vec<Self> { 639 // Attention: This takes ownership of floating references! 640 FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, c_ptr_array_len(ptr)) 641 } 642 from_glib_container_as_vec(ptr: *mut *mut GObject) -> Vec<Self>643 unsafe fn from_glib_container_as_vec(ptr: *mut *mut GObject) -> Vec<Self> { 644 // Attention: This takes ownership of floating references! 645 FromGlibContainerAsVec::from_glib_container_num_as_vec(ptr, c_ptr_array_len(ptr)) 646 } 647 from_glib_full_as_vec(ptr: *mut *mut GObject) -> Vec<Self>648 unsafe fn from_glib_full_as_vec(ptr: *mut *mut GObject) -> Vec<Self> { 649 FromGlibContainerAsVec::from_glib_full_num_as_vec(ptr, c_ptr_array_len(ptr)) 650 } 651 } 652 653 #[doc(hidden)] 654 impl FromGlibContainerAsVec<*mut GObject, *const *mut GObject> for ObjectRef { from_glib_none_num_as_vec(ptr: *const *mut GObject, num: usize) -> Vec<Self>655 unsafe fn from_glib_none_num_as_vec(ptr: *const *mut GObject, num: usize) -> Vec<Self> { 656 // Attention: This takes ownership of floating references! 657 FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr as *mut *mut _, num) 658 } 659 from_glib_container_num_as_vec(_: *const *mut GObject, _: usize) -> Vec<Self>660 unsafe fn from_glib_container_num_as_vec(_: *const *mut GObject, _: usize) -> Vec<Self> { 661 // Can't free a *const 662 unimplemented!() 663 } 664 from_glib_full_num_as_vec(_: *const *mut GObject, _: usize) -> Vec<Self>665 unsafe fn from_glib_full_num_as_vec(_: *const *mut GObject, _: usize) -> Vec<Self> { 666 // Can't free a *const 667 unimplemented!() 668 } 669 } 670 671 #[doc(hidden)] 672 impl FromGlibPtrArrayContainerAsVec<*mut GObject, *const *mut GObject> for ObjectRef { from_glib_none_as_vec(ptr: *const *mut GObject) -> Vec<Self>673 unsafe fn from_glib_none_as_vec(ptr: *const *mut GObject) -> Vec<Self> { 674 // Attention: This takes ownership of floating references! 675 FromGlibPtrArrayContainerAsVec::from_glib_none_as_vec(ptr as *mut *mut _) 676 } 677 from_glib_container_as_vec(_: *const *mut GObject) -> Vec<Self>678 unsafe fn from_glib_container_as_vec(_: *const *mut GObject) -> Vec<Self> { 679 // Can't free a *const 680 unimplemented!() 681 } 682 from_glib_full_as_vec(_: *const *mut GObject) -> Vec<Self>683 unsafe fn from_glib_full_as_vec(_: *const *mut GObject) -> Vec<Self> { 684 // Can't free a *const 685 unimplemented!() 686 } 687 } 688 689 #[doc(hidden)] 690 #[macro_export] 691 macro_rules! glib_weak_impl { 692 ($name:ident) => { 693 #[doc(hidden)] 694 impl $crate::clone::Downgrade for $name { 695 type Weak = $crate::object::WeakRef<Self>; 696 697 fn downgrade(&self) -> Self::Weak { 698 <Self as $crate::object::ObjectExt>::downgrade(&self) 699 } 700 } 701 }; 702 } 703 704 /// ObjectType implementations for Object types. See `glib_wrapper!`. 705 #[macro_export] 706 macro_rules! glib_object_wrapper { 707 (@generic_impl [$($attr:meta)*] $name:ident, $ffi_name:path, $ffi_class_name:path, $rust_class_name:path, @get_type $get_type_expr:expr) => { 708 $(#[$attr])* 709 // Always derive Hash/Ord (and below impl Debug, PartialEq, Eq, PartialOrd) for object 710 // types. Due to inheritance and up/downcasting we must implement these by pointer or 711 // otherwise they would potentially give differeny results for the same object depending on 712 // the type we currently know for it 713 #[derive(Clone, Hash, Ord)] 714 pub struct $name($crate::object::ObjectRef, ::std::marker::PhantomData<$ffi_name>); 715 716 #[doc(hidden)] 717 impl Into<$crate::object::ObjectRef> for $name { 718 fn into(self) -> $crate::object::ObjectRef { 719 self.0 720 } 721 } 722 723 #[doc(hidden)] 724 impl $crate::object::UnsafeFrom<$crate::object::ObjectRef> for $name { 725 #[allow(clippy::missing_safety_doc)] 726 unsafe fn unsafe_from(t: $crate::object::ObjectRef) -> Self { 727 $name(t, ::std::marker::PhantomData) 728 } 729 } 730 731 #[doc(hidden)] 732 impl $crate::translate::GlibPtrDefault for $name { 733 type GlibType = *mut $ffi_name; 734 } 735 736 #[doc(hidden)] 737 unsafe impl $crate::object::ObjectType for $name { 738 type GlibType = $ffi_name; 739 type GlibClassType = $ffi_class_name; 740 type RustClassType = $rust_class_name; 741 742 fn as_object_ref(&self) -> &$crate::object::ObjectRef { 743 &self.0 744 } 745 746 fn as_ptr(&self) -> *mut Self::GlibType { 747 self.0.to_glib_none().0 as *mut _ 748 } 749 } 750 751 #[doc(hidden)] 752 impl AsRef<$crate::object::ObjectRef> for $name { 753 fn as_ref(&self) -> &$crate::object::ObjectRef { 754 &self.0 755 } 756 } 757 758 #[doc(hidden)] 759 impl AsRef<$name> for $name { 760 fn as_ref(&self) -> &$name { 761 self 762 } 763 } 764 765 #[doc(hidden)] 766 unsafe impl $crate::object::IsA<$name> for $name { } 767 768 #[doc(hidden)] 769 impl<'a> $crate::translate::ToGlibPtr<'a, *const $ffi_name> for $name { 770 type Storage = <$crate::object::ObjectRef as 771 $crate::translate::ToGlibPtr<'a, *mut $crate::object::GObject>>::Storage; 772 773 #[inline] 774 fn to_glib_none(&'a self) -> $crate::translate::Stash<'a, *const $ffi_name, Self> { 775 let stash = $crate::translate::ToGlibPtr::to_glib_none(&self.0); 776 $crate::translate::Stash(stash.0 as *const _, stash.1) 777 } 778 779 #[inline] 780 fn to_glib_full(&self) -> *const $ffi_name { 781 $crate::translate::ToGlibPtr::to_glib_full(&self.0) as *const _ 782 } 783 } 784 785 #[doc(hidden)] 786 impl<'a> $crate::translate::ToGlibPtr<'a, *mut $ffi_name> for $name { 787 type Storage = <$crate::object::ObjectRef as 788 $crate::translate::ToGlibPtr<'a, *mut $crate::object::GObject>>::Storage; 789 790 #[inline] 791 fn to_glib_none(&'a self) -> $crate::translate::Stash<'a, *mut $ffi_name, Self> { 792 let stash = $crate::translate::ToGlibPtr::to_glib_none(&self.0); 793 $crate::translate::Stash(stash.0 as *mut _, stash.1) 794 } 795 796 #[inline] 797 fn to_glib_full(&self) -> *mut $ffi_name { 798 $crate::translate::ToGlibPtr::to_glib_full(&self.0) as *mut _ 799 } 800 } 801 802 #[doc(hidden)] 803 impl<'a> $crate::translate::ToGlibContainerFromSlice<'a, *mut *mut $ffi_name> for $name { 804 type Storage = (Vec<$crate::translate::Stash<'a, *mut $ffi_name, $name>>, Option<Vec<*mut $ffi_name>>); 805 806 fn to_glib_none_from_slice(t: &'a [$name]) -> (*mut *mut $ffi_name, Self::Storage) { 807 let v: Vec<_> = t.iter().map(|s| $crate::translate::ToGlibPtr::to_glib_none(s)).collect(); 808 let mut v_ptr: Vec<_> = v.iter().map(|s| s.0).collect(); 809 v_ptr.push(::std::ptr::null_mut() as *mut $ffi_name); 810 811 (v_ptr.as_ptr() as *mut *mut $ffi_name, (v, Some(v_ptr))) 812 } 813 814 fn to_glib_container_from_slice(t: &'a [$name]) -> (*mut *mut $ffi_name, Self::Storage) { 815 let v: Vec<_> = t.iter().map(|s| $crate::translate::ToGlibPtr::to_glib_none(s)).collect(); 816 817 let v_ptr = unsafe { 818 let v_ptr = $crate::glib_sys::g_malloc0(::std::mem::size_of::<*mut $ffi_name>() * (t.len() + 1)) as *mut *mut $ffi_name; 819 820 for (i, s) in v.iter().enumerate() { 821 ::std::ptr::write(v_ptr.add(i), s.0); 822 } 823 824 v_ptr 825 }; 826 827 (v_ptr, (v, None)) 828 } 829 830 fn to_glib_full_from_slice(t: &[$name]) -> *mut *mut $ffi_name { 831 unsafe { 832 let v_ptr = $crate::glib_sys::g_malloc0(::std::mem::size_of::<*mut $ffi_name>() * (t.len() + 1)) as *mut *mut $ffi_name; 833 834 for (i, s) in t.iter().enumerate() { 835 ::std::ptr::write(v_ptr.add(i), $crate::translate::ToGlibPtr::to_glib_full(s)); 836 } 837 838 v_ptr 839 } 840 } 841 } 842 843 #[doc(hidden)] 844 impl<'a> $crate::translate::ToGlibContainerFromSlice<'a, *const *mut $ffi_name> for $name { 845 type Storage = (Vec<$crate::translate::Stash<'a, *mut $ffi_name, $name>>, Option<Vec<*mut $ffi_name>>); 846 847 fn to_glib_none_from_slice(t: &'a [$name]) -> (*const *mut $ffi_name, Self::Storage) { 848 let (ptr, stash) = $crate::translate::ToGlibContainerFromSlice::<'a, *mut *mut $ffi_name>::to_glib_none_from_slice(t); 849 (ptr as *const *mut $ffi_name, stash) 850 } 851 852 fn to_glib_container_from_slice(_: &'a [$name]) -> (*const *mut $ffi_name, Self::Storage) { 853 // Can't have consumer free a *const pointer 854 unimplemented!() 855 } 856 857 fn to_glib_full_from_slice(_: &[$name]) -> *const *mut $ffi_name { 858 // Can't have consumer free a *const pointer 859 unimplemented!() 860 } 861 } 862 863 #[doc(hidden)] 864 impl $crate::translate::FromGlibPtrNone<*mut $ffi_name> for $name { 865 #[inline] 866 #[allow(clippy::cast_ptr_alignment)] 867 #[allow(clippy::missing_safety_doc)] 868 unsafe fn from_glib_none(ptr: *mut $ffi_name) -> Self { 869 debug_assert!($crate::types::instance_of::<Self>(ptr as *const _)); 870 $name($crate::translate::from_glib_none(ptr as *mut _), ::std::marker::PhantomData) 871 } 872 } 873 874 #[doc(hidden)] 875 impl $crate::translate::FromGlibPtrNone<*const $ffi_name> for $name { 876 #[inline] 877 #[allow(clippy::cast_ptr_alignment)] 878 #[allow(clippy::missing_safety_doc)] 879 unsafe fn from_glib_none(ptr: *const $ffi_name) -> Self { 880 debug_assert!($crate::types::instance_of::<Self>(ptr as *const _)); 881 $name($crate::translate::from_glib_none(ptr as *mut _), ::std::marker::PhantomData) 882 } 883 } 884 885 #[doc(hidden)] 886 impl $crate::translate::FromGlibPtrFull<*mut $ffi_name> for $name { 887 #[inline] 888 #[allow(clippy::cast_ptr_alignment)] 889 #[allow(clippy::missing_safety_doc)] 890 unsafe fn from_glib_full(ptr: *mut $ffi_name) -> Self { 891 debug_assert!($crate::types::instance_of::<Self>(ptr as *const _)); 892 $name($crate::translate::from_glib_full(ptr as *mut _), ::std::marker::PhantomData) 893 } 894 } 895 896 #[doc(hidden)] 897 impl $crate::translate::FromGlibPtrBorrow<*mut $ffi_name> for $name { 898 #[inline] 899 #[allow(clippy::cast_ptr_alignment)] 900 #[allow(clippy::missing_safety_doc)] 901 unsafe fn from_glib_borrow(ptr: *mut $ffi_name) -> Self { 902 debug_assert!($crate::types::instance_of::<Self>(ptr as *const _)); 903 $name($crate::translate::from_glib_borrow(ptr as *mut _), 904 ::std::marker::PhantomData) 905 } 906 } 907 908 #[doc(hidden)] 909 impl $crate::translate::FromGlibPtrBorrow<*const $ffi_name> for $name { 910 #[inline] 911 #[allow(clippy::cast_ptr_alignment)] 912 #[allow(clippy::missing_safety_doc)] 913 unsafe fn from_glib_borrow(ptr: *const $ffi_name) -> Self { 914 $crate::translate::from_glib_borrow(ptr as *mut $ffi_name) 915 } 916 } 917 918 #[doc(hidden)] 919 impl $crate::translate::FromGlibContainerAsVec<*mut $ffi_name, *mut *mut $ffi_name> for $name { 920 #[allow(clippy::missing_safety_doc)] 921 unsafe fn from_glib_none_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self> { 922 if num == 0 || ptr.is_null() { 923 return Vec::new(); 924 } 925 926 let mut res = Vec::with_capacity(num); 927 for i in 0..num { 928 res.push($crate::translate::from_glib_none(::std::ptr::read(ptr.add(i)))); 929 } 930 res 931 } 932 933 #[allow(clippy::missing_safety_doc)] 934 unsafe fn from_glib_container_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self> { 935 let res = $crate::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, num); 936 $crate::glib_sys::g_free(ptr as *mut _); 937 res 938 } 939 940 #[allow(clippy::missing_safety_doc)] 941 unsafe fn from_glib_full_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self> { 942 if num == 0 || ptr.is_null() { 943 return Vec::new(); 944 } 945 946 let mut res = Vec::with_capacity(num); 947 for i in 0..num { 948 res.push($crate::translate::from_glib_full(::std::ptr::read(ptr.add(i)))); 949 } 950 $crate::glib_sys::g_free(ptr as *mut _); 951 res 952 } 953 } 954 955 #[doc(hidden)] 956 impl $crate::translate::FromGlibPtrArrayContainerAsVec<*mut $ffi_name, *mut *mut $ffi_name> for $name { 957 #[allow(clippy::missing_safety_doc)] 958 unsafe fn from_glib_none_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self> { 959 $crate::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, $crate::translate::c_ptr_array_len(ptr)) 960 } 961 962 #[allow(clippy::missing_safety_doc)] 963 unsafe fn from_glib_container_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self> { 964 $crate::translate::FromGlibContainerAsVec::from_glib_container_num_as_vec(ptr, $crate::translate::c_ptr_array_len(ptr)) 965 } 966 967 #[allow(clippy::missing_safety_doc)] 968 unsafe fn from_glib_full_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self> { 969 $crate::translate::FromGlibContainerAsVec::from_glib_full_num_as_vec(ptr, $crate::translate::c_ptr_array_len(ptr)) 970 } 971 } 972 973 #[doc(hidden)] 974 impl $crate::translate::FromGlibContainerAsVec<*mut $ffi_name, *const *mut $ffi_name> for $name { 975 #[allow(clippy::missing_safety_doc)] 976 unsafe fn from_glib_none_num_as_vec(ptr: *const *mut $ffi_name, num: usize) -> Vec<Self> { 977 $crate::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr as *mut *mut _, num) 978 } 979 980 #[allow(clippy::missing_safety_doc)] 981 unsafe fn from_glib_container_num_as_vec(_: *const *mut $ffi_name, _: usize) -> Vec<Self> { 982 // Can't free a *const 983 unimplemented!() 984 } 985 986 #[allow(clippy::missing_safety_doc)] 987 unsafe fn from_glib_full_num_as_vec(_: *const *mut $ffi_name, _: usize) -> Vec<Self> { 988 // Can't free a *const 989 unimplemented!() 990 } 991 } 992 993 #[doc(hidden)] 994 impl $crate::translate::FromGlibPtrArrayContainerAsVec<*mut $ffi_name, *const *mut $ffi_name> for $name { 995 #[allow(clippy::missing_safety_doc)] 996 unsafe fn from_glib_none_as_vec(ptr: *const *mut $ffi_name) -> Vec<Self> { 997 $crate::translate::FromGlibPtrArrayContainerAsVec::from_glib_none_as_vec(ptr as *mut *mut _) 998 } 999 1000 #[allow(clippy::missing_safety_doc)] 1001 unsafe fn from_glib_container_as_vec(_: *const *mut $ffi_name) -> Vec<Self> { 1002 // Can't free a *const 1003 unimplemented!() 1004 } 1005 1006 #[allow(clippy::missing_safety_doc)] 1007 unsafe fn from_glib_full_as_vec(_: *const *mut $ffi_name) -> Vec<Self> { 1008 // Can't free a *const 1009 unimplemented!() 1010 } 1011 } 1012 1013 impl $crate::types::StaticType for $name { 1014 fn static_type() -> $crate::types::Type { 1015 #[allow(unused_unsafe)] 1016 unsafe { $crate::translate::from_glib($get_type_expr) } 1017 } 1018 } 1019 1020 impl<T: $crate::object::ObjectType> ::std::cmp::PartialEq<T> for $name { 1021 #[inline] 1022 fn eq(&self, other: &T) -> bool { 1023 $crate::translate::ToGlibPtr::to_glib_none(&self.0).0 == $crate::translate::ToGlibPtr::to_glib_none($crate::object::ObjectType::as_object_ref(other)).0 1024 } 1025 } 1026 1027 impl ::std::cmp::Eq for $name { } 1028 1029 impl<T: $crate::object::ObjectType> ::std::cmp::PartialOrd<T> for $name { 1030 #[inline] 1031 fn partial_cmp(&self, other: &T) -> Option<::std::cmp::Ordering> { 1032 $crate::translate::ToGlibPtr::to_glib_none(&self.0).0.partial_cmp(&$crate::translate::ToGlibPtr::to_glib_none($crate::object::ObjectType::as_object_ref(other)).0) 1033 } 1034 } 1035 1036 impl ::std::fmt::Debug for $name { 1037 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { 1038 f.debug_struct(stringify!($name)) 1039 .field("inner", &self.0) 1040 .finish() 1041 } 1042 } 1043 1044 #[doc(hidden)] 1045 impl<'a> $crate::value::FromValueOptional<'a> for $name { 1046 #[allow(clippy::missing_safety_doc)] 1047 unsafe fn from_value_optional(value: &$crate::Value) -> Option<Self> { 1048 let obj = $crate::gobject_sys::g_value_get_object($crate::translate::ToGlibPtr::to_glib_none(value).0); 1049 1050 // Attention: Don't use from_glib_none() here because we don't want to steal any 1051 // floating references that might be owned by someone else. 1052 if !obj.is_null() { 1053 $crate::gobject_sys::g_object_ref(obj); 1054 } 1055 1056 // And take the reference to the object from above to pass it to the caller 1057 Option::<$name>::from_glib_full(obj as *mut $ffi_name).map(|o| $crate::object::Cast::unsafe_cast(o)) 1058 } 1059 } 1060 1061 #[doc(hidden)] 1062 impl $crate::value::SetValue for $name { 1063 #[allow(clippy::cast_ptr_alignment)] 1064 #[allow(clippy::missing_safety_doc)] 1065 unsafe fn set_value(value: &mut $crate::Value, this: &Self) { 1066 $crate::gobject_sys::g_value_set_object($crate::translate::ToGlibPtrMut::to_glib_none_mut(value).0, $crate::translate::ToGlibPtr::<*mut $ffi_name>::to_glib_none(this).0 as *mut $crate::gobject_sys::GObject) 1067 } 1068 } 1069 1070 #[doc(hidden)] 1071 impl $crate::value::SetValueOptional for $name { 1072 #[allow(clippy::cast_ptr_alignment)] 1073 #[allow(clippy::missing_safety_doc)] 1074 unsafe fn set_value_optional(value: &mut $crate::Value, this: Option<&Self>) { 1075 $crate::gobject_sys::g_value_set_object($crate::translate::ToGlibPtrMut::to_glib_none_mut(value).0, $crate::translate::ToGlibPtr::<*mut $ffi_name>::to_glib_none(&this).0 as *mut $crate::gobject_sys::GObject) 1076 } 1077 } 1078 1079 $crate::glib_weak_impl!($name); 1080 }; 1081 1082 (@munch_impls $name:ident, ) => { }; 1083 1084 (@munch_impls $name:ident, $super_name:path) => { 1085 unsafe impl $crate::object::IsA<$super_name> for $name { } 1086 1087 #[doc(hidden)] 1088 impl AsRef<$super_name> for $name { 1089 fn as_ref(&self) -> &$super_name { 1090 $crate::object::Cast::upcast_ref(self) 1091 } 1092 } 1093 }; 1094 1095 (@munch_impls $name:ident, $super_name:path, $($implements:tt)*) => { 1096 glib_object_wrapper!(@munch_impls $name, $super_name); 1097 glib_object_wrapper!(@munch_impls $name, $($implements)*); 1098 }; 1099 1100 // If there is no parent class, i.e. only glib::Object 1101 (@munch_first_impl $name:ident, $rust_class_name:ident, ) => { 1102 glib_object_wrapper!(@munch_impls $name, ); 1103 1104 impl ::std::ops::Deref for $rust_class_name { 1105 type Target = <$crate::object::Object as $crate::object::ObjectType>::RustClassType; 1106 1107 fn deref(&self) -> &Self::Target { 1108 $crate::object::IsClassFor::upcast_ref(self) 1109 } 1110 } 1111 1112 impl ::std::ops::DerefMut for $rust_class_name { 1113 fn deref_mut(&mut self) -> &mut Self::Target { 1114 $crate::object::IsClassFor::upcast_ref_mut(self) 1115 } 1116 } 1117 }; 1118 1119 // If there is only one parent class 1120 (@munch_first_impl $name:ident, $rust_class_name:ident, $super_name:path) => { 1121 glib_object_wrapper!(@munch_impls $name, $super_name); 1122 1123 impl ::std::ops::Deref for $rust_class_name { 1124 type Target = <$super_name as $crate::object::ObjectType>::RustClassType; 1125 1126 fn deref(&self) -> &Self::Target { 1127 $crate::object::IsClassFor::upcast_ref(self) 1128 } 1129 } 1130 1131 impl ::std::ops::DerefMut for $rust_class_name { 1132 fn deref_mut(&mut self) -> &mut Self::Target { 1133 $crate::object::IsClassFor::upcast_ref_mut(self) 1134 } 1135 } 1136 }; 1137 1138 // If there is more than one parent class 1139 (@munch_first_impl $name:ident, $rust_class_name:ident, $super_name:path, $($implements:tt)*) => { 1140 glib_object_wrapper!(@munch_impls $name, $super_name); 1141 1142 impl ::std::ops::Deref for $rust_class_name { 1143 type Target = <$super_name as $crate::object::ObjectType>::RustClassType; 1144 1145 fn deref(&self) -> &Self::Target { 1146 $crate::object::IsClassFor::upcast_ref(self) 1147 } 1148 } 1149 1150 impl ::std::ops::DerefMut for $rust_class_name { 1151 fn deref_mut(&mut self) -> &mut Self::Target { 1152 $crate::object::IsClassFor::upcast_ref_mut(self) 1153 } 1154 } 1155 1156 glib_object_wrapper!(@munch_impls $name, $($implements)*); 1157 }; 1158 1159 (@class_impl $name:ident, $ffi_class_name:path, $rust_class_name:ident) => { 1160 #[repr(C)] 1161 #[derive(Debug)] 1162 pub struct $rust_class_name($ffi_class_name); 1163 1164 unsafe impl $crate::object::IsClassFor for $rust_class_name { 1165 type Instance = $name; 1166 } 1167 1168 unsafe impl Send for $rust_class_name { } 1169 unsafe impl Sync for $rust_class_name { } 1170 }; 1171 1172 // This case is only for glib::Object itself below. All other cases have glib::Object in its 1173 // parent class list 1174 (@object [$($attr:meta)*] $name:ident, $ffi_name:path, $ffi_class_name:path, $rust_class_name:ident, @get_type $get_type_expr:expr) => { 1175 glib_object_wrapper!(@generic_impl [$($attr)*] $name, $ffi_name, $ffi_class_name, $rust_class_name, 1176 @get_type $get_type_expr); 1177 glib_object_wrapper!(@class_impl $name, $ffi_class_name, $rust_class_name); 1178 }; 1179 1180 (@object [$($attr:meta)*] $name:ident, $ffi_name:path, $ffi_class_name:path, $rust_class_name:ident, 1181 @get_type $get_type_expr:expr, @extends [$($extends:tt)*], @implements [$($implements:tt)*]) => { 1182 glib_object_wrapper!(@generic_impl [$($attr)*] $name, $ffi_name, $ffi_class_name, $rust_class_name, 1183 @get_type $get_type_expr); 1184 glib_object_wrapper!(@munch_first_impl $name, $rust_class_name, $($extends)*); 1185 glib_object_wrapper!(@munch_impls $name, $($implements)*); 1186 glib_object_wrapper!(@class_impl $name, $ffi_class_name, $rust_class_name); 1187 1188 #[doc(hidden)] 1189 impl AsRef<$crate::object::Object> for $name { 1190 fn as_ref(&self) -> &$crate::object::Object { 1191 $crate::object::Cast::upcast_ref(self) 1192 } 1193 } 1194 1195 #[doc(hidden)] 1196 unsafe impl $crate::object::IsA<$crate::object::Object> for $name { } 1197 }; 1198 1199 (@interface [$($attr:meta)*] $name:ident, $ffi_name:path, @get_type $get_type_expr:expr, @requires [$($requires:tt)*]) => { 1200 glib_object_wrapper!(@generic_impl [$($attr)*] $name, $ffi_name, $crate::wrapper::Void, $crate::wrapper::Void, 1201 @get_type $get_type_expr); 1202 glib_object_wrapper!(@munch_impls $name, $($requires)*); 1203 1204 #[doc(hidden)] 1205 impl AsRef<$crate::object::Object> for $name { 1206 fn as_ref(&self) -> &$crate::object::Object { 1207 $crate::object::Cast::upcast_ref(self) 1208 } 1209 } 1210 1211 #[doc(hidden)] 1212 unsafe impl $crate::object::IsA<$crate::object::Object> for $name { } 1213 }; 1214 } 1215 1216 glib_object_wrapper!(@object 1217 [doc = "The base class in the object hierarchy."] 1218 Object, GObject, GObjectClass, ObjectClass, @get_type gobject_sys::g_object_get_type() 1219 ); 1220 1221 impl Object { new(type_: Type, properties: &[(&str, &dyn ToValue)]) -> Result<Object, BoolError>1222 pub fn new(type_: Type, properties: &[(&str, &dyn ToValue)]) -> Result<Object, BoolError> { 1223 use std::ffi::CString; 1224 1225 if !type_.is_a(&Object::static_type()) { 1226 return Err(glib_bool_error!("Can't instantiate non-GObject objects")); 1227 } 1228 1229 let params = properties 1230 .iter() 1231 .map(|&(name, value)| (CString::new(name).unwrap(), value.to_value())) 1232 .collect::<Vec<_>>(); 1233 1234 let params_c = params 1235 .iter() 1236 .map(|&(ref name, ref value)| gobject_sys::GParameter { 1237 name: name.as_ptr(), 1238 value: unsafe { *value.to_glib_none().0 }, 1239 }) 1240 .collect::<Vec<_>>(); 1241 1242 unsafe { 1243 let ptr = gobject_sys::g_object_newv( 1244 type_.to_glib(), 1245 params_c.len() as u32, 1246 mut_override(params_c.as_ptr()), 1247 ); 1248 if ptr.is_null() { 1249 Err(glib_bool_error!("Can't instantiate object")) 1250 } else if type_.is_a(&InitiallyUnowned::static_type()) { 1251 // Attention: This takes ownership of the floating reference 1252 Ok(from_glib_none(ptr)) 1253 } else { 1254 Ok(from_glib_full(ptr)) 1255 } 1256 } 1257 } 1258 } 1259 1260 pub trait ObjectExt: ObjectType { 1261 /// Returns `true` if the object is an instance of (can be cast to) `T`. is<T: StaticType>(&self) -> bool1262 fn is<T: StaticType>(&self) -> bool; 1263 get_type(&self) -> Type1264 fn get_type(&self) -> Type; get_object_class(&self) -> &ObjectClass1265 fn get_object_class(&self) -> &ObjectClass; 1266 set_property<'a, N: Into<&'a str>>( &self, property_name: N, value: &dyn ToValue, ) -> Result<(), BoolError>1267 fn set_property<'a, N: Into<&'a str>>( 1268 &self, 1269 property_name: N, 1270 value: &dyn ToValue, 1271 ) -> Result<(), BoolError>; get_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Result<Value, BoolError>1272 fn get_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Result<Value, BoolError>; has_property<'a, N: Into<&'a str>>( &self, property_name: N, type_: Option<Type>, ) -> Result<(), BoolError>1273 fn has_property<'a, N: Into<&'a str>>( 1274 &self, 1275 property_name: N, 1276 type_: Option<Type>, 1277 ) -> Result<(), BoolError>; get_property_type<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<Type>1278 fn get_property_type<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<Type>; find_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<::ParamSpec>1279 fn find_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<::ParamSpec>; list_properties(&self) -> Vec<::ParamSpec>1280 fn list_properties(&self) -> Vec<::ParamSpec>; 1281 block_signal(&self, handler_id: &SignalHandlerId)1282 fn block_signal(&self, handler_id: &SignalHandlerId); unblock_signal(&self, handler_id: &SignalHandlerId)1283 fn unblock_signal(&self, handler_id: &SignalHandlerId); stop_signal_emission(&self, signal_name: &str)1284 fn stop_signal_emission(&self, signal_name: &str); 1285 connect<'a, N, F>( &self, signal_name: N, after: bool, callback: F, ) -> Result<SignalHandlerId, BoolError> where N: Into<&'a str>, F: Fn(&[Value]) -> Option<Value> + Send + Sync + 'static1286 fn connect<'a, N, F>( 1287 &self, 1288 signal_name: N, 1289 after: bool, 1290 callback: F, 1291 ) -> Result<SignalHandlerId, BoolError> 1292 where 1293 N: Into<&'a str>, 1294 F: Fn(&[Value]) -> Option<Value> + Send + Sync + 'static; connect_local<'a, N, F>( &self, signal_name: N, after: bool, callback: F, ) -> Result<SignalHandlerId, BoolError> where N: Into<&'a str>, F: Fn(&[Value]) -> Option<Value> + 'static1295 fn connect_local<'a, N, F>( 1296 &self, 1297 signal_name: N, 1298 after: bool, 1299 callback: F, 1300 ) -> Result<SignalHandlerId, BoolError> 1301 where 1302 N: Into<&'a str>, 1303 F: Fn(&[Value]) -> Option<Value> + 'static; connect_unsafe<'a, N, F>( &self, signal_name: N, after: bool, callback: F, ) -> Result<SignalHandlerId, BoolError> where N: Into<&'a str>, F: Fn(&[Value]) -> Option<Value>1304 unsafe fn connect_unsafe<'a, N, F>( 1305 &self, 1306 signal_name: N, 1307 after: bool, 1308 callback: F, 1309 ) -> Result<SignalHandlerId, BoolError> 1310 where 1311 N: Into<&'a str>, 1312 F: Fn(&[Value]) -> Option<Value>; emit<'a, N: Into<&'a str>>( &self, signal_name: N, args: &[&dyn ToValue], ) -> Result<Option<Value>, BoolError>1313 fn emit<'a, N: Into<&'a str>>( 1314 &self, 1315 signal_name: N, 1316 args: &[&dyn ToValue], 1317 ) -> Result<Option<Value>, BoolError>; disconnect(&self, handler_id: SignalHandlerId)1318 fn disconnect(&self, handler_id: SignalHandlerId); 1319 connect_notify<F: Fn(&Self, &::ParamSpec) + Send + Sync + 'static>( &self, name: Option<&str>, f: F, ) -> SignalHandlerId1320 fn connect_notify<F: Fn(&Self, &::ParamSpec) + Send + Sync + 'static>( 1321 &self, 1322 name: Option<&str>, 1323 f: F, 1324 ) -> SignalHandlerId; connect_notify_unsafe<F: Fn(&Self, &::ParamSpec)>( &self, name: Option<&str>, f: F, ) -> SignalHandlerId1325 unsafe fn connect_notify_unsafe<F: Fn(&Self, &::ParamSpec)>( 1326 &self, 1327 name: Option<&str>, 1328 f: F, 1329 ) -> SignalHandlerId; notify<'a, N: Into<&'a str>>(&self, property_name: N)1330 fn notify<'a, N: Into<&'a str>>(&self, property_name: N); notify_by_pspec(&self, pspec: &::ParamSpec)1331 fn notify_by_pspec(&self, pspec: &::ParamSpec); 1332 downgrade(&self) -> WeakRef<Self>1333 fn downgrade(&self) -> WeakRef<Self>; 1334 bind_property<'a, O: ObjectType, N: Into<&'a str>, M: Into<&'a str>>( &'a self, source_property: N, target: &'a O, target_property: M, ) -> BindingBuilder<'a>1335 fn bind_property<'a, O: ObjectType, N: Into<&'a str>, M: Into<&'a str>>( 1336 &'a self, 1337 source_property: N, 1338 target: &'a O, 1339 target_property: M, 1340 ) -> BindingBuilder<'a>; 1341 ref_count(&self) -> u321342 fn ref_count(&self) -> u32; 1343 } 1344 1345 impl<T: ObjectType> ObjectExt for T { is<U: StaticType>(&self) -> bool1346 fn is<U: StaticType>(&self) -> bool { 1347 self.get_type().is_a(&U::static_type()) 1348 } 1349 get_type(&self) -> Type1350 fn get_type(&self) -> Type { 1351 self.get_object_class().get_type() 1352 } 1353 get_object_class(&self) -> &ObjectClass1354 fn get_object_class(&self) -> &ObjectClass { 1355 unsafe { 1356 let obj: *mut gobject_sys::GObject = self.as_object_ref().to_glib_none().0; 1357 let klass = (*obj).g_type_instance.g_class as *const ObjectClass; 1358 &*klass 1359 } 1360 } 1361 set_property<'a, N: Into<&'a str>>( &self, property_name: N, value: &dyn ToValue, ) -> Result<(), BoolError>1362 fn set_property<'a, N: Into<&'a str>>( 1363 &self, 1364 property_name: N, 1365 value: &dyn ToValue, 1366 ) -> Result<(), BoolError> { 1367 let property_name = property_name.into(); 1368 let mut property_value = value.to_value(); 1369 1370 let pspec = match self.find_property(property_name) { 1371 Some(pspec) => pspec, 1372 None => { 1373 return Err(glib_bool_error!("property not found")); 1374 } 1375 }; 1376 1377 if !pspec.get_flags().contains(::ParamFlags::WRITABLE) 1378 || pspec.get_flags().contains(::ParamFlags::CONSTRUCT_ONLY) 1379 { 1380 return Err(glib_bool_error!("property is not writable")); 1381 } 1382 1383 unsafe { 1384 // While GLib actually allows all types that can somehow be transformed 1385 // into the property type, we're more restrictive here to be consistent 1386 // with Rust's type rules. We only allow the exact same type, or if the 1387 // value type is a subtype of the property type 1388 let valid_type: bool = from_glib(gobject_sys::g_type_check_value_holds( 1389 mut_override(property_value.to_glib_none().0), 1390 pspec.get_value_type().to_glib(), 1391 )); 1392 1393 // If it's not directly a valid type but an object type, we check if the 1394 // actual type of the contained object is compatible and if so create 1395 // a properly type Value. This can happen if the type field in the 1396 // Value is set to a more generic type than the contained value 1397 if !valid_type && property_value.type_().is_a(&Object::static_type()) { 1398 match property_value.get::<Object>() { 1399 Ok(Some(obj)) => { 1400 if obj.get_type().is_a(&pspec.get_value_type()) { 1401 property_value.0.g_type = pspec.get_value_type().to_glib(); 1402 } else { 1403 return Err(glib_bool_error!(format!( 1404 concat!( 1405 "property can't be set from the given object type ", 1406 "(expected: {:?}, got: {:?})", 1407 ), 1408 pspec.get_value_type(), 1409 obj.get_type(), 1410 ))); 1411 } 1412 } 1413 Ok(None) => { 1414 // If the value is None then the type is compatible too 1415 property_value.0.g_type = pspec.get_value_type().to_glib(); 1416 } 1417 Err(_) => unreachable!("property_value type conformity already checked"), 1418 } 1419 } else if !valid_type { 1420 return Err(glib_bool_error!(format!( 1421 "property can't be set from the given type (expected: {:?}, got: {:?})", 1422 pspec.get_value_type(), 1423 property_value.type_(), 1424 ))); 1425 } 1426 1427 let changed: bool = from_glib(gobject_sys::g_param_value_validate( 1428 pspec.to_glib_none().0, 1429 property_value.to_glib_none_mut().0, 1430 )); 1431 let change_allowed = pspec.get_flags().contains(::ParamFlags::LAX_VALIDATION); 1432 if changed && !change_allowed { 1433 return Err(glib_bool_error!( 1434 "property can't be set from given value, it is invalid or out of range" 1435 )); 1436 } 1437 1438 gobject_sys::g_object_set_property( 1439 self.as_object_ref().to_glib_none().0, 1440 property_name.to_glib_none().0, 1441 property_value.to_glib_none().0, 1442 ); 1443 } 1444 1445 Ok(()) 1446 } 1447 get_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Result<Value, BoolError>1448 fn get_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Result<Value, BoolError> { 1449 let property_name = property_name.into(); 1450 1451 let pspec = match self.find_property(property_name) { 1452 Some(pspec) => pspec, 1453 None => { 1454 return Err(glib_bool_error!("property not found")); 1455 } 1456 }; 1457 1458 if !pspec.get_flags().contains(::ParamFlags::READABLE) { 1459 return Err(glib_bool_error!("property is not readable")); 1460 } 1461 1462 unsafe { 1463 let mut value = Value::from_type(pspec.get_value_type()); 1464 gobject_sys::g_object_get_property( 1465 self.as_object_ref().to_glib_none().0, 1466 property_name.to_glib_none().0, 1467 value.to_glib_none_mut().0, 1468 ); 1469 1470 // This can't really happen unless something goes wrong inside GObject 1471 if value.type_() == ::Type::Invalid { 1472 Err(glib_bool_error!("Failed to get property value")) 1473 } else { 1474 Ok(value) 1475 } 1476 } 1477 } 1478 block_signal(&self, handler_id: &SignalHandlerId)1479 fn block_signal(&self, handler_id: &SignalHandlerId) { 1480 unsafe { 1481 gobject_sys::g_signal_handler_block( 1482 self.as_object_ref().to_glib_none().0, 1483 handler_id.to_glib(), 1484 ); 1485 } 1486 } 1487 unblock_signal(&self, handler_id: &SignalHandlerId)1488 fn unblock_signal(&self, handler_id: &SignalHandlerId) { 1489 unsafe { 1490 gobject_sys::g_signal_handler_unblock( 1491 self.as_object_ref().to_glib_none().0, 1492 handler_id.to_glib(), 1493 ); 1494 } 1495 } 1496 stop_signal_emission(&self, signal_name: &str)1497 fn stop_signal_emission(&self, signal_name: &str) { 1498 unsafe { 1499 gobject_sys::g_signal_stop_emission_by_name( 1500 self.as_object_ref().to_glib_none().0, 1501 signal_name.to_glib_none().0, 1502 ); 1503 } 1504 } 1505 disconnect(&self, handler_id: SignalHandlerId)1506 fn disconnect(&self, handler_id: SignalHandlerId) { 1507 unsafe { 1508 gobject_sys::g_signal_handler_disconnect( 1509 self.as_object_ref().to_glib_none().0, 1510 handler_id.to_glib(), 1511 ); 1512 } 1513 } 1514 connect_notify<F: Fn(&Self, &::ParamSpec) + Send + Sync + 'static>( &self, name: Option<&str>, f: F, ) -> SignalHandlerId1515 fn connect_notify<F: Fn(&Self, &::ParamSpec) + Send + Sync + 'static>( 1516 &self, 1517 name: Option<&str>, 1518 f: F, 1519 ) -> SignalHandlerId { 1520 unsafe { self.connect_notify_unsafe(name, f) } 1521 } 1522 connect_notify_unsafe<F: Fn(&Self, &::ParamSpec)>( &self, name: Option<&str>, f: F, ) -> SignalHandlerId1523 unsafe fn connect_notify_unsafe<F: Fn(&Self, &::ParamSpec)>( 1524 &self, 1525 name: Option<&str>, 1526 f: F, 1527 ) -> SignalHandlerId { 1528 unsafe extern "C" fn notify_trampoline<P, F: Fn(&P, &::ParamSpec)>( 1529 this: *mut gobject_sys::GObject, 1530 param_spec: *mut gobject_sys::GParamSpec, 1531 f: glib_sys::gpointer, 1532 ) where 1533 P: ObjectType, 1534 { 1535 let f: &F = &*(f as *const F); 1536 f( 1537 &Object::from_glib_borrow(this).unsafe_cast(), 1538 &from_glib_borrow(param_spec), 1539 ) 1540 } 1541 1542 let signal_name = if let Some(name) = name { 1543 format!("notify::{}\0", name) 1544 } else { 1545 "notify\0".into() 1546 }; 1547 1548 let f: Box<F> = Box::new(f); 1549 ::signal::connect_raw( 1550 self.as_object_ref().to_glib_none().0, 1551 signal_name.as_ptr() as *const _, 1552 Some(mem::transmute(notify_trampoline::<Self, F> as usize)), 1553 Box::into_raw(f), 1554 ) 1555 } 1556 notify<'a, N: Into<&'a str>>(&self, property_name: N)1557 fn notify<'a, N: Into<&'a str>>(&self, property_name: N) { 1558 let property_name = property_name.into(); 1559 1560 unsafe { 1561 gobject_sys::g_object_notify( 1562 self.as_object_ref().to_glib_none().0, 1563 property_name.to_glib_none().0, 1564 ); 1565 } 1566 } 1567 notify_by_pspec(&self, pspec: &::ParamSpec)1568 fn notify_by_pspec(&self, pspec: &::ParamSpec) { 1569 unsafe { 1570 gobject_sys::g_object_notify_by_pspec( 1571 self.as_object_ref().to_glib_none().0, 1572 pspec.to_glib_none().0, 1573 ); 1574 } 1575 } 1576 has_property<'a, N: Into<&'a str>>( &self, property_name: N, type_: Option<Type>, ) -> Result<(), BoolError>1577 fn has_property<'a, N: Into<&'a str>>( 1578 &self, 1579 property_name: N, 1580 type_: Option<Type>, 1581 ) -> Result<(), BoolError> { 1582 self.get_object_class().has_property(property_name, type_) 1583 } 1584 get_property_type<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<Type>1585 fn get_property_type<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<Type> { 1586 self.get_object_class().get_property_type(property_name) 1587 } 1588 find_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<::ParamSpec>1589 fn find_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<::ParamSpec> { 1590 self.get_object_class().find_property(property_name) 1591 } 1592 list_properties(&self) -> Vec<::ParamSpec>1593 fn list_properties(&self) -> Vec<::ParamSpec> { 1594 self.get_object_class().list_properties() 1595 } 1596 connect<'a, N, F>( &self, signal_name: N, after: bool, callback: F, ) -> Result<SignalHandlerId, BoolError> where N: Into<&'a str>, F: Fn(&[Value]) -> Option<Value> + Send + Sync + 'static,1597 fn connect<'a, N, F>( 1598 &self, 1599 signal_name: N, 1600 after: bool, 1601 callback: F, 1602 ) -> Result<SignalHandlerId, BoolError> 1603 where 1604 N: Into<&'a str>, 1605 F: Fn(&[Value]) -> Option<Value> + Send + Sync + 'static, 1606 { 1607 unsafe { self.connect_unsafe(signal_name, after, callback) } 1608 } 1609 connect_local<'a, N, F>( &self, signal_name: N, after: bool, callback: F, ) -> Result<SignalHandlerId, BoolError> where N: Into<&'a str>, F: Fn(&[Value]) -> Option<Value> + 'static,1610 fn connect_local<'a, N, F>( 1611 &self, 1612 signal_name: N, 1613 after: bool, 1614 callback: F, 1615 ) -> Result<SignalHandlerId, BoolError> 1616 where 1617 N: Into<&'a str>, 1618 F: Fn(&[Value]) -> Option<Value> + 'static, 1619 { 1620 let callback = crate::ThreadGuard::new(callback); 1621 1622 unsafe { 1623 self.connect_unsafe(signal_name, after, move |values| { 1624 (callback.get_ref())(values) 1625 }) 1626 } 1627 } 1628 connect_unsafe<'a, N, F>( &self, signal_name: N, after: bool, callback: F, ) -> Result<SignalHandlerId, BoolError> where N: Into<&'a str>, F: Fn(&[Value]) -> Option<Value>,1629 unsafe fn connect_unsafe<'a, N, F>( 1630 &self, 1631 signal_name: N, 1632 after: bool, 1633 callback: F, 1634 ) -> Result<SignalHandlerId, BoolError> 1635 where 1636 N: Into<&'a str>, 1637 F: Fn(&[Value]) -> Option<Value>, 1638 { 1639 let signal_name: &str = signal_name.into(); 1640 1641 let type_ = self.get_type(); 1642 1643 let mut signal_id = 0; 1644 let mut signal_detail = 0; 1645 1646 let found: bool = from_glib(gobject_sys::g_signal_parse_name( 1647 signal_name.to_glib_none().0, 1648 type_.to_glib(), 1649 &mut signal_id, 1650 &mut signal_detail, 1651 true.to_glib(), 1652 )); 1653 1654 if !found { 1655 return Err(glib_bool_error!("Signal not found")); 1656 } 1657 1658 let mut details = mem::MaybeUninit::zeroed(); 1659 gobject_sys::g_signal_query(signal_id, details.as_mut_ptr()); 1660 let details = details.assume_init(); 1661 if details.signal_id != signal_id { 1662 return Err(glib_bool_error!("Signal not found")); 1663 } 1664 1665 // This is actually G_SIGNAL_TYPE_STATIC_SCOPE 1666 let return_type: Type = 1667 from_glib(details.return_type & (!gobject_sys::G_TYPE_FLAG_RESERVED_ID_BIT)); 1668 let closure = Closure::new_unsafe(move |values| { 1669 let ret = callback(values); 1670 1671 if return_type == Type::Unit { 1672 if let Some(ret) = ret { 1673 panic!( 1674 "Signal required no return value but got value of type {}", 1675 ret.type_().name() 1676 ); 1677 } 1678 None 1679 } else { 1680 match ret { 1681 Some(mut ret) => { 1682 let valid_type: bool = from_glib(gobject_sys::g_type_check_value_holds( 1683 mut_override(ret.to_glib_none().0), 1684 return_type.to_glib(), 1685 )); 1686 1687 // If it's not directly a valid type but an object type, we check if the 1688 // actual typed of the contained object is compatible and if so create 1689 // a properly typed Value. This can happen if the type field in the 1690 // Value is set to a more generic type than the contained value 1691 if !valid_type && ret.type_().is_a(&Object::static_type()) { 1692 match ret.get::<Object>() { 1693 Ok(Some(obj)) => { 1694 if obj.get_type().is_a(&return_type) { 1695 ret.0.g_type = return_type.to_glib(); 1696 } else { 1697 panic!("Signal required return value of type {} but got {} (actual {})", 1698 return_type.name(), ret.type_().name(), obj.get_type().name()); 1699 } 1700 } 1701 Ok(None) => { 1702 // If the value is None then the type is compatible too 1703 ret.0.g_type = return_type.to_glib(); 1704 } 1705 Err(_) => unreachable!("ret type conformity already checked"), 1706 } 1707 } else if !valid_type { 1708 panic!( 1709 "Signal required return value of type {} but got {}", 1710 return_type.name(), 1711 ret.type_().name() 1712 ); 1713 } 1714 Some(ret) 1715 } 1716 None => { 1717 panic!( 1718 "Signal required return value of type {} but got None", 1719 return_type.name() 1720 ); 1721 } 1722 } 1723 } 1724 }); 1725 let handler = gobject_sys::g_signal_connect_closure_by_id( 1726 self.as_object_ref().to_glib_none().0, 1727 signal_id, 1728 signal_detail, 1729 closure.to_glib_none().0, 1730 after.to_glib(), 1731 ); 1732 1733 if handler == 0 { 1734 Err(glib_bool_error!("Failed to connect to signal")) 1735 } else { 1736 Ok(from_glib(handler)) 1737 } 1738 } 1739 emit<'a, N: Into<&'a str>>( &self, signal_name: N, args: &[&dyn ToValue], ) -> Result<Option<Value>, BoolError>1740 fn emit<'a, N: Into<&'a str>>( 1741 &self, 1742 signal_name: N, 1743 args: &[&dyn ToValue], 1744 ) -> Result<Option<Value>, BoolError> { 1745 let signal_name: &str = signal_name.into(); 1746 unsafe { 1747 let type_ = self.get_type(); 1748 1749 let mut signal_id = 0; 1750 let mut signal_detail = 0; 1751 1752 let found: bool = from_glib(gobject_sys::g_signal_parse_name( 1753 signal_name.to_glib_none().0, 1754 type_.to_glib(), 1755 &mut signal_id, 1756 &mut signal_detail, 1757 true.to_glib(), 1758 )); 1759 1760 if !found { 1761 return Err(glib_bool_error!("Signal not found")); 1762 } 1763 1764 let mut details = mem::MaybeUninit::zeroed(); 1765 gobject_sys::g_signal_query(signal_id, details.as_mut_ptr()); 1766 let details = details.assume_init(); 1767 if details.signal_id != signal_id { 1768 return Err(glib_bool_error!("Signal not found")); 1769 } 1770 1771 if details.n_params != args.len() as u32 { 1772 return Err(glib_bool_error!("Incompatible number of arguments")); 1773 } 1774 1775 for (i, item) in args.iter().enumerate() { 1776 let arg_type = 1777 *(details.param_types.add(i)) & (!gobject_sys::G_TYPE_FLAG_RESERVED_ID_BIT); 1778 if arg_type != item.to_value_type().to_glib() { 1779 return Err(glib_bool_error!("Incompatible argument types")); 1780 } 1781 } 1782 1783 let mut v_args: Vec<Value>; 1784 let mut s_args: [Value; 10] = mem::zeroed(); 1785 let self_v = { 1786 let mut v = Value::uninitialized(); 1787 gobject_sys::g_value_init(v.to_glib_none_mut().0, self.get_type().to_glib()); 1788 gobject_sys::g_value_set_object( 1789 v.to_glib_none_mut().0, 1790 self.as_object_ref().to_glib_none().0, 1791 ); 1792 v 1793 }; 1794 let args = if args.len() < 10 { 1795 s_args[0] = self_v; 1796 for (i, arg) in args.iter().enumerate() { 1797 s_args[i + 1] = arg.to_value(); 1798 } 1799 &s_args[0..=args.len()] 1800 } else { 1801 v_args = Vec::with_capacity(args.len() + 1); 1802 v_args.push(self_v); 1803 for arg in args { 1804 v_args.push(arg.to_value()); 1805 } 1806 v_args.as_slice() 1807 }; 1808 1809 let mut return_value = Value::uninitialized(); 1810 if details.return_type != gobject_sys::G_TYPE_NONE { 1811 gobject_sys::g_value_init(return_value.to_glib_none_mut().0, details.return_type); 1812 } 1813 1814 gobject_sys::g_signal_emitv( 1815 mut_override(args.as_ptr()) as *mut gobject_sys::GValue, 1816 signal_id, 1817 signal_detail, 1818 return_value.to_glib_none_mut().0, 1819 ); 1820 1821 if return_value.type_() != Type::Unit && return_value.type_() != Type::Invalid { 1822 Ok(Some(return_value)) 1823 } else { 1824 Ok(None) 1825 } 1826 } 1827 } 1828 downgrade(&self) -> WeakRef<T>1829 fn downgrade(&self) -> WeakRef<T> { 1830 unsafe { 1831 let w = WeakRef(Box::new(mem::zeroed()), PhantomData); 1832 gobject_sys::g_weak_ref_init( 1833 mut_override(&*w.0), 1834 self.as_object_ref().to_glib_none().0, 1835 ); 1836 w 1837 } 1838 } 1839 bind_property<'a, O: ObjectType, N: Into<&'a str>, M: Into<&'a str>>( &'a self, source_property: N, target: &'a O, target_property: M, ) -> BindingBuilder<'a>1840 fn bind_property<'a, O: ObjectType, N: Into<&'a str>, M: Into<&'a str>>( 1841 &'a self, 1842 source_property: N, 1843 target: &'a O, 1844 target_property: M, 1845 ) -> BindingBuilder<'a> { 1846 let source_property = source_property.into(); 1847 let target_property = target_property.into(); 1848 1849 BindingBuilder::new(self, source_property, target, target_property) 1850 } 1851 ref_count(&self) -> u321852 fn ref_count(&self) -> u32 { 1853 let stash = self.as_object_ref().to_glib_none(); 1854 let ptr: *mut gobject_sys::GObject = stash.0; 1855 1856 unsafe { glib_sys::g_atomic_int_get(&(*ptr).ref_count as *const u32 as *const i32) as u32 } 1857 } 1858 } 1859 1860 impl ObjectClass { has_property<'a, N: Into<&'a str>>( &self, property_name: N, type_: Option<Type>, ) -> Result<(), BoolError>1861 pub fn has_property<'a, N: Into<&'a str>>( 1862 &self, 1863 property_name: N, 1864 type_: Option<Type>, 1865 ) -> Result<(), BoolError> { 1866 let property_name = property_name.into(); 1867 let ptype = self.get_property_type(property_name); 1868 1869 match (ptype, type_) { 1870 (None, _) => Err(glib_bool_error!("Invalid property name")), 1871 (Some(_), None) => Ok(()), 1872 (Some(ptype), Some(type_)) => { 1873 if ptype == type_ { 1874 Ok(()) 1875 } else { 1876 Err(glib_bool_error!("Invalid property type")) 1877 } 1878 } 1879 } 1880 } 1881 get_property_type<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<Type>1882 pub fn get_property_type<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<Type> { 1883 self.find_property(property_name) 1884 .map(|pspec| pspec.get_value_type()) 1885 } 1886 find_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<::ParamSpec>1887 pub fn find_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<::ParamSpec> { 1888 let property_name = property_name.into(); 1889 unsafe { 1890 let klass = self as *const _ as *const gobject_sys::GObjectClass; 1891 1892 from_glib_none(gobject_sys::g_object_class_find_property( 1893 klass as *mut _, 1894 property_name.to_glib_none().0, 1895 )) 1896 } 1897 } 1898 list_properties(&self) -> Vec<::ParamSpec>1899 pub fn list_properties(&self) -> Vec<::ParamSpec> { 1900 unsafe { 1901 let klass = self as *const _ as *const gobject_sys::GObjectClass; 1902 1903 let mut n_properties = 0; 1904 1905 let props = 1906 gobject_sys::g_object_class_list_properties(klass as *mut _, &mut n_properties); 1907 FromGlibContainer::from_glib_none_num(props, n_properties as usize) 1908 } 1909 } 1910 } 1911 1912 glib_wrapper! { 1913 pub struct InitiallyUnowned(Object<gobject_sys::GInitiallyUnowned, gobject_sys::GInitiallyUnownedClass, InitiallyUnownedClass>); 1914 1915 match fn { 1916 get_type => || gobject_sys::g_initially_unowned_get_type(), 1917 } 1918 } 1919 1920 #[derive(Debug)] 1921 pub struct WeakRef<T: ObjectType>(Box<gobject_sys::GWeakRef>, PhantomData<*const T>); 1922 1923 impl<T: ObjectType> WeakRef<T> { new() -> WeakRef<T>1924 pub fn new() -> WeakRef<T> { 1925 unsafe { 1926 let w = WeakRef(Box::new(mem::zeroed()), PhantomData); 1927 gobject_sys::g_weak_ref_init(mut_override(&*w.0), ptr::null_mut()); 1928 w 1929 } 1930 } 1931 upgrade(&self) -> Option<T>1932 pub fn upgrade(&self) -> Option<T> { 1933 unsafe { 1934 let ptr = gobject_sys::g_weak_ref_get(mut_override(&*self.0)); 1935 if ptr.is_null() { 1936 None 1937 } else { 1938 let obj: Object = from_glib_full(ptr); 1939 Some(T::unsafe_from(obj.into())) 1940 } 1941 } 1942 } 1943 } 1944 1945 impl<T: ObjectType> Drop for WeakRef<T> { drop(&mut self)1946 fn drop(&mut self) { 1947 unsafe { 1948 gobject_sys::g_weak_ref_clear(mut_override(&*self.0)); 1949 } 1950 } 1951 } 1952 1953 impl<T: ObjectType> Clone for WeakRef<T> { clone(&self) -> Self1954 fn clone(&self) -> Self { 1955 unsafe { 1956 let c = WeakRef(Box::new(mem::zeroed()), PhantomData); 1957 1958 let o = gobject_sys::g_weak_ref_get(mut_override(&*self.0)); 1959 gobject_sys::g_weak_ref_init(mut_override(&*c.0), o); 1960 if !o.is_null() { 1961 gobject_sys::g_object_unref(o); 1962 } 1963 1964 c 1965 } 1966 } 1967 } 1968 1969 impl<T: ObjectType> Default for WeakRef<T> { default() -> Self1970 fn default() -> Self { 1971 Self::new() 1972 } 1973 } 1974 1975 unsafe impl<T: ObjectType + Sync + Sync> Sync for WeakRef<T> {} 1976 unsafe impl<T: ObjectType + Send + Sync> Send for WeakRef<T> {} 1977 1978 /// A weak reference to the object it was created for that can be sent to 1979 /// different threads even for object types that don't implement `Send`. 1980 /// 1981 /// Trying to upgrade the weak reference from another thread than the one 1982 /// where it was created on will panic but dropping or cloning can be done 1983 /// safely from any thread. 1984 #[derive(Debug)] 1985 pub struct SendWeakRef<T: ObjectType>(WeakRef<T>, Option<usize>); 1986 1987 impl<T: ObjectType> SendWeakRef<T> { new() -> SendWeakRef<T>1988 pub fn new() -> SendWeakRef<T> { 1989 SendWeakRef(WeakRef::new(), None) 1990 } 1991 into_weak_ref(self) -> WeakRef<T>1992 pub fn into_weak_ref(self) -> WeakRef<T> { 1993 if self.1.is_some() && self.1 != Some(get_thread_id()) { 1994 panic!("SendWeakRef dereferenced on a different thread"); 1995 } 1996 1997 self.0 1998 } 1999 } 2000 2001 impl<T: ObjectType> ops::Deref for SendWeakRef<T> { 2002 type Target = WeakRef<T>; 2003 deref(&self) -> &WeakRef<T>2004 fn deref(&self) -> &WeakRef<T> { 2005 if self.1.is_some() && self.1 != Some(get_thread_id()) { 2006 panic!("SendWeakRef dereferenced on a different thread"); 2007 } 2008 2009 &self.0 2010 } 2011 } 2012 2013 // Deriving this gives the wrong trait bounds 2014 impl<T: ObjectType> Clone for SendWeakRef<T> { clone(&self) -> Self2015 fn clone(&self) -> Self { 2016 SendWeakRef(self.0.clone(), self.1) 2017 } 2018 } 2019 2020 impl<T: ObjectType> Default for SendWeakRef<T> { default() -> Self2021 fn default() -> Self { 2022 Self::new() 2023 } 2024 } 2025 2026 impl<T: ObjectType> From<WeakRef<T>> for SendWeakRef<T> { from(v: WeakRef<T>) -> SendWeakRef<T>2027 fn from(v: WeakRef<T>) -> SendWeakRef<T> { 2028 SendWeakRef(v, Some(get_thread_id())) 2029 } 2030 } 2031 2032 unsafe impl<T: ObjectType> Sync for SendWeakRef<T> {} 2033 unsafe impl<T: ObjectType> Send for SendWeakRef<T> {} 2034 2035 #[derive(Debug)] 2036 pub struct BindingBuilder<'a> { 2037 source: &'a ObjectRef, 2038 source_property: &'a str, 2039 target: &'a ObjectRef, 2040 target_property: &'a str, 2041 flags: ::BindingFlags, 2042 transform_to: Option<::Closure>, 2043 transform_from: Option<::Closure>, 2044 } 2045 2046 impl<'a> BindingBuilder<'a> { new<S: ObjectType, T: ObjectType>( source: &'a S, source_property: &'a str, target: &'a T, target_property: &'a str, ) -> Self2047 fn new<S: ObjectType, T: ObjectType>( 2048 source: &'a S, 2049 source_property: &'a str, 2050 target: &'a T, 2051 target_property: &'a str, 2052 ) -> Self { 2053 Self { 2054 source: source.as_object_ref(), 2055 source_property, 2056 target: target.as_object_ref(), 2057 target_property, 2058 flags: ::BindingFlags::DEFAULT, 2059 transform_to: None, 2060 transform_from: None, 2061 } 2062 } 2063 transform_closure<F: Fn(&::Binding, &Value) -> Option<Value> + Send + Sync + 'static>( func: F, ) -> ::Closure2064 fn transform_closure<F: Fn(&::Binding, &Value) -> Option<Value> + Send + Sync + 'static>( 2065 func: F, 2066 ) -> ::Closure { 2067 ::Closure::new(move |values| { 2068 assert_eq!(values.len(), 3); 2069 let binding = values[0].get::<::Binding>().unwrap_or_else(|_| { 2070 panic!( 2071 "Type mismatch with the first argument in the closure: expected: `Binding`, got: {:?}", 2072 values[0].type_(), 2073 ) 2074 }) 2075 .unwrap_or_else(|| { 2076 panic!("Found `None` for the first argument in the closure, expected `Some`") 2077 }); 2078 let from = unsafe { 2079 let ptr = gobject_sys::g_value_get_boxed(mut_override( 2080 &values[1] as *const Value as *const gobject_sys::GValue, 2081 )); 2082 assert!(!ptr.is_null()); 2083 &*(ptr as *const gobject_sys::GValue as *const Value) 2084 }; 2085 2086 match func(&binding, &from) { 2087 None => Some(false.to_value()), 2088 Some(value) => { 2089 unsafe { 2090 gobject_sys::g_value_set_boxed( 2091 mut_override(&values[2] as *const Value as *const gobject_sys::GValue), 2092 &value as *const Value as *const _, 2093 ); 2094 } 2095 2096 Some(true.to_value()) 2097 } 2098 } 2099 }) 2100 } 2101 transform_from<F: Fn(&::Binding, &Value) -> Option<Value> + Send + Sync + 'static>( self, func: F, ) -> Self2102 pub fn transform_from<F: Fn(&::Binding, &Value) -> Option<Value> + Send + Sync + 'static>( 2103 self, 2104 func: F, 2105 ) -> Self { 2106 Self { 2107 transform_from: Some(Self::transform_closure(func)), 2108 ..self 2109 } 2110 } 2111 transform_to<F: Fn(&::Binding, &Value) -> Option<Value> + Send + Sync + 'static>( self, func: F, ) -> Self2112 pub fn transform_to<F: Fn(&::Binding, &Value) -> Option<Value> + Send + Sync + 'static>( 2113 self, 2114 func: F, 2115 ) -> Self { 2116 Self { 2117 transform_to: Some(Self::transform_closure(func)), 2118 ..self 2119 } 2120 } 2121 flags(self, flags: ::BindingFlags) -> Self2122 pub fn flags(self, flags: ::BindingFlags) -> Self { 2123 Self { flags, ..self } 2124 } 2125 build(self) -> Option<::Binding>2126 pub fn build(self) -> Option<::Binding> { 2127 unsafe { 2128 from_glib_none(gobject_sys::g_object_bind_property_with_closures( 2129 self.source.to_glib_none().0, 2130 self.source_property.to_glib_none().0, 2131 self.target.to_glib_none().0, 2132 self.target_property.to_glib_none().0, 2133 self.flags.to_glib(), 2134 self.transform_to.to_glib_none().0, 2135 self.transform_from.to_glib_none().0, 2136 )) 2137 } 2138 } 2139 } 2140