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::fmt; 10 use std::hash; 11 use std::marker::PhantomData; 12 use std::mem; 13 use std::ops; 14 use std::ptr; 15 use translate::*; 16 use types::StaticType; 17 18 use value::ToValue; 19 use BoolError; 20 use Closure; 21 use SignalHandlerId; 22 use Type; 23 use Value; 24 25 use get_thread_id; 26 27 #[doc(hidden)] 28 pub use gobject_sys::GObject; 29 30 #[doc(hidden)] 31 pub use gobject_sys::GObjectClass; 32 33 /// Implemented by types representing `glib::Object` and subclasses of it. 34 pub unsafe trait ObjectType: 35 UnsafeFrom<ObjectRef> 36 + Into<ObjectRef> 37 + StaticType 38 + fmt::Debug 39 + Clone 40 + PartialEq 41 + Eq 42 + PartialOrd 43 + Ord 44 + hash::Hash 45 + for<'a> ToGlibPtr<'a, *mut <Self as ObjectType>::GlibType> 46 + 'static 47 { 48 /// type of the FFI Instance structure. 49 type GlibType: 'static; 50 /// type of the FFI Class structure. 51 type GlibClassType: 'static; 52 /// type of the Rust Class structure. 53 type RustClassType: 'static; 54 as_object_ref(&self) -> &ObjectRef55 fn as_object_ref(&self) -> &ObjectRef; as_ptr(&self) -> *mut Self::GlibType56 fn as_ptr(&self) -> *mut Self::GlibType; 57 } 58 59 /// Unsafe variant of the `From` trait. 60 pub trait UnsafeFrom<T> { unsafe_from(t: T) -> Self61 unsafe fn unsafe_from(t: T) -> Self; 62 } 63 64 /// Declares the "is a" relationship. 65 /// 66 /// `Self` is said to implement `T`. 67 /// 68 /// For instance, since originally `GtkWidget` is a subclass of `GObject` and 69 /// implements the `GtkBuildable` interface, `gtk::Widget` implements 70 /// `IsA<glib::Object>` and `IsA<gtk::Buildable>`. 71 /// 72 /// 73 /// The trait can only be implemented if the appropriate `ToGlibPtr` 74 /// implementations exist. 75 pub unsafe trait IsA<T: ObjectType>: ObjectType + AsRef<T> + 'static {} 76 77 /// Trait for mapping a class struct type to its corresponding instance type. 78 pub unsafe trait IsClassFor: Sized + 'static { 79 /// Corresponding Rust instance type for this class. 80 type Instance: ObjectType; 81 82 /// Get the type id for this class. get_type(&self) -> Type83 fn get_type(&self) -> Type { 84 unsafe { 85 let klass = self as *const _ as *const gobject_sys::GTypeClass; 86 from_glib((*klass).g_type) 87 } 88 } 89 90 /// 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,91 fn upcast_ref<U: IsClassFor>(&self) -> &U 92 where 93 Self::Instance: IsA<U::Instance>, 94 U::Instance: ObjectType, 95 { 96 unsafe { 97 let klass = self as *const _ as *const U; 98 &*klass 99 } 100 } 101 102 /// 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,103 fn upcast_ref_mut<U: IsClassFor>(&mut self) -> &mut U 104 where 105 Self::Instance: IsA<U::Instance>, 106 U::Instance: ObjectType, 107 { 108 unsafe { 109 let klass = self as *mut _ as *mut U; 110 &mut *klass 111 } 112 } 113 114 /// Casts this class to a reference to a child type's class or 115 /// 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,116 fn downcast_ref<U: IsClassFor>(&self) -> Option<&U> 117 where 118 U::Instance: IsA<Self::Instance>, 119 Self::Instance: ObjectType, 120 { 121 if !self.get_type().is_a(&U::Instance::static_type()) { 122 return None; 123 } 124 125 unsafe { 126 let klass = self as *const _ as *const U; 127 Some(&*klass) 128 } 129 } 130 131 /// Casts this class to a mutable reference to a child type's class or 132 /// 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,133 fn downcast_ref_mut<U: IsClassFor>(&mut self) -> Option<&mut U> 134 where 135 U::Instance: IsA<Self::Instance>, 136 Self::Instance: ObjectType, 137 { 138 if !self.get_type().is_a(&U::Instance::static_type()) { 139 return None; 140 } 141 142 unsafe { 143 let klass = self as *mut _ as *mut U; 144 Some(&mut *klass) 145 } 146 } 147 148 /// Gets the class struct corresponding to `type_`. 149 /// 150 /// This will return `None` if `type_` is not a subclass of `Self`. from_type(type_: Type) -> Option<ClassRef<Self>>151 fn from_type(type_: Type) -> Option<ClassRef<Self>> { 152 if !type_.is_a(&Self::Instance::static_type()) { 153 return None; 154 } 155 156 unsafe { 157 let ptr = gobject_sys::g_type_class_ref(type_.to_glib()); 158 if ptr.is_null() { 159 None 160 } else { 161 Some(ClassRef(ptr::NonNull::new_unchecked(ptr as *mut Self))) 162 } 163 } 164 } 165 } 166 167 #[derive(Debug)] 168 pub struct ClassRef<T: IsClassFor>(ptr::NonNull<T>); 169 170 impl<T: IsClassFor> ops::Deref for ClassRef<T> { 171 type Target = T; 172 deref(&self) -> &T173 fn deref(&self) -> &T { 174 unsafe { self.0.as_ref() } 175 } 176 } 177 178 impl<T: IsClassFor> Drop for ClassRef<T> { drop(&mut self)179 fn drop(&mut self) { 180 unsafe { 181 gobject_sys::g_type_class_unref(self.0.as_ptr() as *mut _); 182 } 183 } 184 } 185 186 /// Upcasting and downcasting support. 187 /// 188 /// Provides conversions up and down the class hierarchy tree. 189 pub trait Cast: ObjectType { 190 /// Upcasts an object to a superclass or interface `T`. 191 /// 192 /// *NOTE*: This statically checks at compile-time if casting is possible. It is not always 193 /// known at compile-time, whether a specific object implements an interface or not, in which case 194 /// `upcast` would fail to compile. `dynamic_cast` can be used in these circumstances, which 195 /// is checking the types at runtime. 196 /// 197 /// # Example 198 /// 199 /// ```ignore 200 /// let button = gtk::Button::new(); 201 /// let widget = button.upcast::<gtk::Widget>(); 202 /// ``` 203 #[inline] upcast<T: ObjectType>(self) -> T where Self: IsA<T>,204 fn upcast<T: ObjectType>(self) -> T 205 where 206 Self: IsA<T>, 207 { 208 unsafe { self.unsafe_cast() } 209 } 210 211 /// Upcasts an object to a reference of its superclass or interface `T`. 212 /// 213 /// *NOTE*: This statically checks at compile-time if casting is possible. It is not always 214 /// known at compile-time, whether a specific object implements an interface or not, in which case 215 /// `upcast` would fail to compile. `dynamic_cast` can be used in these circumstances, which 216 /// is checking the types at runtime. 217 /// 218 /// # Example 219 /// 220 /// ```ignore 221 /// let button = gtk::Button::new(); 222 /// let widget = button.upcast_ref::<gtk::Widget>(); 223 /// ``` 224 #[inline] upcast_ref<T: ObjectType>(&self) -> &T where Self: IsA<T>,225 fn upcast_ref<T: ObjectType>(&self) -> &T 226 where 227 Self: IsA<T>, 228 { 229 unsafe { self.unsafe_cast_ref() } 230 } 231 232 /// Tries to downcast to a subclass or interface implementor `T`. 233 /// 234 /// Returns `Ok(T)` if the object is an instance of `T` and `Err(self)` 235 /// otherwise. 236 /// 237 /// *NOTE*: This statically checks at compile-time if casting is possible. It is not always 238 /// known at compile-time, whether a specific object implements an interface or not, in which case 239 /// `upcast` would fail to compile. `dynamic_cast` can be used in these circumstances, which 240 /// is checking the types at runtime. 241 /// 242 /// # Example 243 /// 244 /// ```ignore 245 /// let button = gtk::Button::new(); 246 /// let widget = button.upcast::<gtk::Widget>(); 247 /// assert!(widget.downcast::<gtk::Button>().is_ok()); 248 /// ``` 249 #[inline] downcast<T: ObjectType>(self) -> Result<T, Self> where Self: CanDowncast<T>,250 fn downcast<T: ObjectType>(self) -> Result<T, Self> 251 where 252 Self: CanDowncast<T>, 253 { 254 if self.is::<T>() { 255 Ok(unsafe { self.unsafe_cast() }) 256 } else { 257 Err(self) 258 } 259 } 260 261 /// Tries to downcast to a reference of its subclass or interface implementor `T`. 262 /// 263 /// Returns `Some(T)` if the object is an instance of `T` and `None` 264 /// otherwise. 265 /// 266 /// *NOTE*: This statically checks at compile-time if casting is possible. It is not always 267 /// known at compile-time, whether a specific object implements an interface or not, in which case 268 /// `upcast` would fail to compile. `dynamic_cast` can be used in these circumstances, which 269 /// is checking the types at runtime. 270 /// 271 /// # Example 272 /// 273 /// ```ignore 274 /// let button = gtk::Button::new(); 275 /// let widget = button.upcast::<gtk::Widget>(); 276 /// assert!(widget.downcast_ref::<gtk::Button>().is_some()); 277 /// ``` 278 #[inline] downcast_ref<T: ObjectType>(&self) -> Option<&T> where Self: CanDowncast<T>,279 fn downcast_ref<T: ObjectType>(&self) -> Option<&T> 280 where 281 Self: CanDowncast<T>, 282 { 283 if self.is::<T>() { 284 Some(unsafe { self.unsafe_cast_ref() }) 285 } else { 286 None 287 } 288 } 289 290 /// Tries to cast to an object of type `T`. This handles upcasting, downcasting 291 /// and casting between interface and interface implementors. All checks are performed at 292 /// runtime, while `downcast` and `upcast` will do many checks at compile-time already. 293 /// 294 /// It is not always known at compile-time, whether a specific object implements an interface or 295 /// not, and checking as to be performed at runtime. 296 /// 297 /// Returns `Ok(T)` if the object is an instance of `T` and `Err(self)` 298 /// otherwise. 299 /// 300 /// # Example 301 /// 302 /// ```ignore 303 /// let button = gtk::Button::new(); 304 /// let widget = button.dynamic_cast::<gtk::Widget>(); 305 /// assert!(widget.is_ok()); 306 /// let widget = widget.unwrap(); 307 /// assert!(widget.dynamic_cast::<gtk::Button>().is_ok()); 308 /// ``` 309 #[inline] dynamic_cast<T: ObjectType>(self) -> Result<T, Self>310 fn dynamic_cast<T: ObjectType>(self) -> Result<T, Self> { 311 if !self.is::<T>() { 312 Err(self) 313 } else { 314 Ok(unsafe { self.unsafe_cast() }) 315 } 316 } 317 318 /// Tries to cast to reference to an object of type `T`. This handles upcasting, downcasting 319 /// and casting between interface and interface implementors. All checks are performed at 320 /// runtime, while `downcast` and `upcast` will do many checks at compile-time already. 321 /// 322 /// It is not always known at compile-time, whether a specific object implements an interface or 323 /// not, and checking as to be performed at runtime. 324 /// 325 /// Returns `Some(T)` if the object is an instance of `T` and `None` 326 /// otherwise. 327 /// 328 /// # Example 329 /// 330 /// ```ignore 331 /// let button = gtk::Button::new(); 332 /// let widget = button.dynamic_cast_ref::<gtk::Widget>(); 333 /// assert!(widget.is_some()); 334 /// let widget = widget.unwrap(); 335 /// assert!(widget.dynamic_cast_ref::<gtk::Button>().is_some()); 336 /// ``` 337 #[inline] dynamic_cast_ref<T: ObjectType>(&self) -> Option<&T>338 fn dynamic_cast_ref<T: ObjectType>(&self) -> Option<&T> { 339 if !self.is::<T>() { 340 None 341 } else { 342 // This transmute is safe because all our wrapper types have the 343 // same representation except for the name and the phantom data 344 // type. IsA<> is an unsafe trait that must only be implemented 345 // if this is a valid wrapper type 346 Some(unsafe { self.unsafe_cast_ref() }) 347 } 348 } 349 350 /// Casts to `T` unconditionally. 351 /// 352 /// Panics if compiled with `debug_assertions` and the instance doesn't implement `T`. unsafe_cast<T: ObjectType>(self) -> T353 unsafe fn unsafe_cast<T: ObjectType>(self) -> T { 354 debug_assert!(self.is::<T>()); 355 T::unsafe_from(self.into()) 356 } 357 358 /// Casts to `&T` unconditionally. 359 /// 360 /// Panics if compiled with `debug_assertions` and the instance doesn't implement `T`. unsafe_cast_ref<T: ObjectType>(&self) -> &T361 unsafe fn unsafe_cast_ref<T: ObjectType>(&self) -> &T { 362 debug_assert!(self.is::<T>()); 363 // This transmute is safe because all our wrapper types have the 364 // same representation except for the name and the phantom data 365 // type. IsA<> is an unsafe trait that must only be implemented 366 // if this is a valid wrapper type 367 &*(self as *const Self as *const T) 368 } 369 } 370 371 impl<T: ObjectType> Cast for T {} 372 373 /// Marker trait for the statically known possibility of downcasting from `Self` to `T`. 374 pub trait CanDowncast<T> {} 375 376 impl<Super: IsA<Super>, Sub: IsA<Super>> CanDowncast<Sub> for Super {} 377 378 glib_wrapper! { 379 #[doc(hidden)] 380 #[derive(Debug, Ord, PartialOrd, PartialEq, Eq, Hash)] 381 pub struct ObjectRef(Shared<GObject>); 382 383 match fn { 384 ref => |ptr| gobject_sys::g_object_ref_sink(ptr), 385 unref => |ptr| gobject_sys::g_object_unref(ptr), 386 } 387 } 388 389 /// ObjectType implementations for Object types. See `glib_wrapper!`. 390 #[macro_export] 391 macro_rules! glib_object_wrapper { 392 (@generic_impl [$($attr:meta)*] $name:ident, $ffi_name:path, $ffi_class_name:path, $rust_class_name:path, @get_type $get_type_expr:expr) => { 393 $(#[$attr])* 394 // Always derive Hash/Ord (and below impl Debug, PartialEq, Eq, PartialOrd) for object 395 // types. Due to inheritance and up/downcasting we must implement these by pointer or 396 // otherwise they would potentially give differeny results for the same object depending on 397 // the type we currently know for it 398 #[derive(Clone, Hash, Ord)] 399 pub struct $name($crate::object::ObjectRef, ::std::marker::PhantomData<$ffi_name>); 400 401 #[doc(hidden)] 402 impl Into<$crate::object::ObjectRef> for $name { 403 fn into(self) -> $crate::object::ObjectRef { 404 self.0 405 } 406 } 407 408 #[doc(hidden)] 409 impl $crate::object::UnsafeFrom<$crate::object::ObjectRef> for $name { 410 unsafe fn unsafe_from(t: $crate::object::ObjectRef) -> Self { 411 $name(t, ::std::marker::PhantomData) 412 } 413 } 414 415 #[doc(hidden)] 416 impl $crate::translate::GlibPtrDefault for $name { 417 type GlibType = *mut $ffi_name; 418 } 419 420 #[doc(hidden)] 421 unsafe impl $crate::object::ObjectType for $name { 422 type GlibType = $ffi_name; 423 type GlibClassType = $ffi_class_name; 424 type RustClassType = $rust_class_name; 425 426 fn as_object_ref(&self) -> &$crate::object::ObjectRef { 427 &self.0 428 } 429 430 fn as_ptr(&self) -> *mut Self::GlibType { 431 self.0.to_glib_none().0 as *mut _ 432 } 433 } 434 435 #[doc(hidden)] 436 impl AsRef<$crate::object::ObjectRef> for $name { 437 fn as_ref(&self) -> &$crate::object::ObjectRef { 438 &self.0 439 } 440 } 441 442 #[doc(hidden)] 443 impl AsRef<$name> for $name { 444 fn as_ref(&self) -> &$name { 445 self 446 } 447 } 448 449 #[doc(hidden)] 450 unsafe impl $crate::object::IsA<$name> for $name { } 451 452 #[doc(hidden)] 453 impl<'a> $crate::translate::ToGlibPtr<'a, *const $ffi_name> for $name { 454 type Storage = <$crate::object::ObjectRef as 455 $crate::translate::ToGlibPtr<'a, *mut $crate::object::GObject>>::Storage; 456 457 #[inline] 458 fn to_glib_none(&'a self) -> $crate::translate::Stash<'a, *const $ffi_name, Self> { 459 let stash = $crate::translate::ToGlibPtr::to_glib_none(&self.0); 460 $crate::translate::Stash(stash.0 as *const _, stash.1) 461 } 462 463 #[inline] 464 fn to_glib_full(&self) -> *const $ffi_name { 465 $crate::translate::ToGlibPtr::to_glib_full(&self.0) as *const _ 466 } 467 } 468 469 #[doc(hidden)] 470 impl<'a> $crate::translate::ToGlibPtr<'a, *mut $ffi_name> for $name { 471 type Storage = <$crate::object::ObjectRef as 472 $crate::translate::ToGlibPtr<'a, *mut $crate::object::GObject>>::Storage; 473 474 #[inline] 475 fn to_glib_none(&'a self) -> $crate::translate::Stash<'a, *mut $ffi_name, Self> { 476 let stash = $crate::translate::ToGlibPtr::to_glib_none(&self.0); 477 $crate::translate::Stash(stash.0 as *mut _, stash.1) 478 } 479 480 #[inline] 481 fn to_glib_full(&self) -> *mut $ffi_name { 482 $crate::translate::ToGlibPtr::to_glib_full(&self.0) as *mut _ 483 } 484 } 485 486 #[doc(hidden)] 487 impl<'a> $crate::translate::ToGlibContainerFromSlice<'a, *mut *mut $ffi_name> for $name { 488 type Storage = (Vec<$crate::translate::Stash<'a, *mut $ffi_name, $name>>, Option<Vec<*mut $ffi_name>>); 489 490 fn to_glib_none_from_slice(t: &'a [$name]) -> (*mut *mut $ffi_name, Self::Storage) { 491 let v: Vec<_> = t.iter().map(|s| $crate::translate::ToGlibPtr::to_glib_none(s)).collect(); 492 let mut v_ptr: Vec<_> = v.iter().map(|s| s.0).collect(); 493 v_ptr.push(::std::ptr::null_mut() as *mut $ffi_name); 494 495 (v_ptr.as_ptr() as *mut *mut $ffi_name, (v, Some(v_ptr))) 496 } 497 498 fn to_glib_container_from_slice(t: &'a [$name]) -> (*mut *mut $ffi_name, Self::Storage) { 499 let v: Vec<_> = t.iter().map(|s| $crate::translate::ToGlibPtr::to_glib_none(s)).collect(); 500 501 let v_ptr = unsafe { 502 let v_ptr = $crate::glib_sys::g_malloc0(::std::mem::size_of::<*mut $ffi_name>() * (t.len() + 1)) as *mut *mut $ffi_name; 503 504 for (i, s) in v.iter().enumerate() { 505 ::std::ptr::write(v_ptr.add(i), s.0); 506 } 507 508 v_ptr 509 }; 510 511 (v_ptr, (v, None)) 512 } 513 514 fn to_glib_full_from_slice(t: &[$name]) -> *mut *mut $ffi_name { 515 unsafe { 516 let v_ptr = $crate::glib_sys::g_malloc0(::std::mem::size_of::<*mut $ffi_name>() * (t.len() + 1)) as *mut *mut $ffi_name; 517 518 for (i, s) in t.iter().enumerate() { 519 ::std::ptr::write(v_ptr.add(i), $crate::translate::ToGlibPtr::to_glib_full(s)); 520 } 521 522 v_ptr 523 } 524 } 525 } 526 527 #[doc(hidden)] 528 impl<'a> $crate::translate::ToGlibContainerFromSlice<'a, *const *mut $ffi_name> for $name { 529 type Storage = (Vec<$crate::translate::Stash<'a, *mut $ffi_name, $name>>, Option<Vec<*mut $ffi_name>>); 530 531 fn to_glib_none_from_slice(t: &'a [$name]) -> (*const *mut $ffi_name, Self::Storage) { 532 let (ptr, stash) = $crate::translate::ToGlibContainerFromSlice::<'a, *mut *mut $ffi_name>::to_glib_none_from_slice(t); 533 (ptr as *const *mut $ffi_name, stash) 534 } 535 536 fn to_glib_container_from_slice(_: &'a [$name]) -> (*const *mut $ffi_name, Self::Storage) { 537 // Can't have consumer free a *const pointer 538 unimplemented!() 539 } 540 541 fn to_glib_full_from_slice(_: &[$name]) -> *const *mut $ffi_name { 542 // Can't have consumer free a *const pointer 543 unimplemented!() 544 } 545 } 546 547 #[doc(hidden)] 548 impl $crate::translate::FromGlibPtrNone<*mut $ffi_name> for $name { 549 #[inline] 550 #[allow(clippy::cast_ptr_alignment)] 551 unsafe fn from_glib_none(ptr: *mut $ffi_name) -> Self { 552 debug_assert!($crate::types::instance_of::<Self>(ptr as *const _)); 553 $name($crate::translate::from_glib_none(ptr as *mut _), ::std::marker::PhantomData) 554 } 555 } 556 557 #[doc(hidden)] 558 impl $crate::translate::FromGlibPtrNone<*const $ffi_name> for $name { 559 #[inline] 560 #[allow(clippy::cast_ptr_alignment)] 561 unsafe fn from_glib_none(ptr: *const $ffi_name) -> Self { 562 debug_assert!($crate::types::instance_of::<Self>(ptr as *const _)); 563 $name($crate::translate::from_glib_none(ptr as *mut _), ::std::marker::PhantomData) 564 } 565 } 566 567 #[doc(hidden)] 568 impl $crate::translate::FromGlibPtrFull<*mut $ffi_name> for $name { 569 #[inline] 570 #[allow(clippy::cast_ptr_alignment)] 571 unsafe fn from_glib_full(ptr: *mut $ffi_name) -> Self { 572 debug_assert!($crate::types::instance_of::<Self>(ptr as *const _)); 573 $name($crate::translate::from_glib_full(ptr as *mut _), ::std::marker::PhantomData) 574 } 575 } 576 577 #[doc(hidden)] 578 impl $crate::translate::FromGlibPtrBorrow<*mut $ffi_name> for $name { 579 #[inline] 580 #[allow(clippy::cast_ptr_alignment)] 581 unsafe fn from_glib_borrow(ptr: *mut $ffi_name) -> Self { 582 debug_assert!($crate::types::instance_of::<Self>(ptr as *const _)); 583 $name($crate::translate::from_glib_borrow(ptr as *mut _), 584 ::std::marker::PhantomData) 585 } 586 } 587 588 #[doc(hidden)] 589 impl $crate::translate::FromGlibPtrBorrow<*const $ffi_name> for $name { 590 #[inline] 591 #[allow(clippy::cast_ptr_alignment)] 592 unsafe fn from_glib_borrow(ptr: *const $ffi_name) -> Self { 593 $crate::translate::from_glib_borrow(ptr as *mut $ffi_name) 594 } 595 } 596 597 #[doc(hidden)] 598 impl $crate::translate::FromGlibContainerAsVec<*mut $ffi_name, *mut *mut $ffi_name> for $name { 599 unsafe fn from_glib_none_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self> { 600 if num == 0 || ptr.is_null() { 601 return Vec::new(); 602 } 603 604 let mut res = Vec::with_capacity(num); 605 for i in 0..num { 606 res.push($crate::translate::from_glib_none(::std::ptr::read(ptr.add(i)))); 607 } 608 res 609 } 610 611 unsafe fn from_glib_container_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self> { 612 let res = $crate::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, num); 613 $crate::glib_sys::g_free(ptr as *mut _); 614 res 615 } 616 617 unsafe fn from_glib_full_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self> { 618 if num == 0 || ptr.is_null() { 619 return Vec::new(); 620 } 621 622 let mut res = Vec::with_capacity(num); 623 for i in 0..num { 624 res.push($crate::translate::from_glib_full(::std::ptr::read(ptr.add(i)))); 625 } 626 $crate::glib_sys::g_free(ptr as *mut _); 627 res 628 } 629 } 630 631 #[doc(hidden)] 632 impl $crate::translate::FromGlibPtrArrayContainerAsVec<*mut $ffi_name, *mut *mut $ffi_name> for $name { 633 unsafe fn from_glib_none_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self> { 634 $crate::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, $crate::translate::c_ptr_array_len(ptr)) 635 } 636 637 unsafe fn from_glib_container_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self> { 638 $crate::translate::FromGlibContainerAsVec::from_glib_container_num_as_vec(ptr, $crate::translate::c_ptr_array_len(ptr)) 639 } 640 641 unsafe fn from_glib_full_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self> { 642 $crate::translate::FromGlibContainerAsVec::from_glib_full_num_as_vec(ptr, $crate::translate::c_ptr_array_len(ptr)) 643 } 644 } 645 646 #[doc(hidden)] 647 impl $crate::translate::FromGlibContainerAsVec<*mut $ffi_name, *const *mut $ffi_name> for $name { 648 unsafe fn from_glib_none_num_as_vec(ptr: *const *mut $ffi_name, num: usize) -> Vec<Self> { 649 $crate::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr as *mut *mut _, num) 650 } 651 652 unsafe fn from_glib_container_num_as_vec(_: *const *mut $ffi_name, _: usize) -> Vec<Self> { 653 // Can't free a *const 654 unimplemented!() 655 } 656 657 unsafe fn from_glib_full_num_as_vec(_: *const *mut $ffi_name, _: usize) -> Vec<Self> { 658 // Can't free a *const 659 unimplemented!() 660 } 661 } 662 663 #[doc(hidden)] 664 impl $crate::translate::FromGlibPtrArrayContainerAsVec<*mut $ffi_name, *const *mut $ffi_name> for $name { 665 unsafe fn from_glib_none_as_vec(ptr: *const *mut $ffi_name) -> Vec<Self> { 666 $crate::translate::FromGlibPtrArrayContainerAsVec::from_glib_none_as_vec(ptr as *mut *mut _) 667 } 668 669 unsafe fn from_glib_container_as_vec(_: *const *mut $ffi_name) -> Vec<Self> { 670 // Can't free a *const 671 unimplemented!() 672 } 673 674 unsafe fn from_glib_full_as_vec(_: *const *mut $ffi_name) -> Vec<Self> { 675 // Can't free a *const 676 unimplemented!() 677 } 678 } 679 680 impl $crate::types::StaticType for $name { 681 fn static_type() -> $crate::types::Type { 682 #[allow(unused_unsafe)] 683 unsafe { $crate::translate::from_glib($get_type_expr) } 684 } 685 } 686 687 impl<T: $crate::object::ObjectType> ::std::cmp::PartialEq<T> for $name { 688 #[inline] 689 fn eq(&self, other: &T) -> bool { 690 $crate::translate::ToGlibPtr::to_glib_none(&self.0).0 == $crate::translate::ToGlibPtr::to_glib_none($crate::object::ObjectType::as_object_ref(other)).0 691 } 692 } 693 694 impl ::std::cmp::Eq for $name { } 695 696 impl<T: $crate::object::ObjectType> ::std::cmp::PartialOrd<T> for $name { 697 #[inline] 698 fn partial_cmp(&self, other: &T) -> Option<::std::cmp::Ordering> { 699 $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) 700 } 701 } 702 703 impl ::std::fmt::Debug for $name { 704 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { 705 f.debug_struct(stringify!($name)) 706 .field("inner", &self.0) 707 .field("type", &<$name as $crate::ObjectExt>::get_type(self)) 708 .finish() 709 } 710 } 711 712 #[doc(hidden)] 713 impl<'a> $crate::value::FromValueOptional<'a> for $name { 714 unsafe fn from_value_optional(value: &$crate::Value) -> Option<Self> { 715 let obj = $crate::gobject_sys::g_value_get_object($crate::translate::ToGlibPtr::to_glib_none(value).0); 716 717 // If the object was floating, clear the floating flag. The one and only 718 // reference is still owned by the GValue at this point 719 if !obj.is_null() && $crate::gobject_sys::g_object_is_floating(obj) != $crate::glib_sys::GFALSE { 720 $crate::gobject_sys::g_object_ref_sink(obj); 721 } 722 723 // And get a new reference to the object to pass to the caller 724 Option::<$name>::from_glib_none(obj as *mut $ffi_name).map(|o| $crate::object::Cast::unsafe_cast(o)) 725 } 726 } 727 728 #[doc(hidden)] 729 impl $crate::value::SetValue for $name { 730 #[allow(clippy::cast_ptr_alignment)] 731 unsafe fn set_value(value: &mut $crate::Value, this: &Self) { 732 $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) 733 } 734 } 735 736 #[doc(hidden)] 737 impl $crate::value::SetValueOptional for $name { 738 #[allow(clippy::cast_ptr_alignment)] 739 unsafe fn set_value_optional(value: &mut $crate::Value, this: Option<&Self>) { 740 $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) 741 } 742 } 743 }; 744 745 (@munch_impls $name:ident, ) => { }; 746 747 (@munch_impls $name:ident, $super_name:path) => { 748 unsafe impl $crate::object::IsA<$super_name> for $name { } 749 750 #[doc(hidden)] 751 impl AsRef<$super_name> for $name { 752 fn as_ref(&self) -> &$super_name { 753 $crate::object::Cast::upcast_ref(self) 754 } 755 } 756 }; 757 758 (@munch_impls $name:ident, $super_name:path, $($implements:tt)*) => { 759 glib_object_wrapper!(@munch_impls $name, $super_name); 760 glib_object_wrapper!(@munch_impls $name, $($implements)*); 761 }; 762 763 // If there is no parent class, i.e. only glib::Object 764 (@munch_first_impl $name:ident, $rust_class_name:ident, ) => { 765 glib_object_wrapper!(@munch_impls $name, ); 766 767 impl ::std::ops::Deref for $rust_class_name { 768 type Target = <$crate::object::Object as $crate::object::ObjectType>::RustClassType; 769 770 fn deref(&self) -> &Self::Target { 771 $crate::object::IsClassFor::upcast_ref(self) 772 } 773 } 774 775 impl ::std::ops::DerefMut for $rust_class_name { 776 fn deref_mut(&mut self) -> &mut Self::Target { 777 $crate::object::IsClassFor::upcast_ref_mut(self) 778 } 779 } 780 }; 781 782 // If there is only one parent class 783 (@munch_first_impl $name:ident, $rust_class_name:ident, $super_name:path) => { 784 glib_object_wrapper!(@munch_impls $name, $super_name); 785 786 impl ::std::ops::Deref for $rust_class_name { 787 type Target = <$super_name as $crate::object::ObjectType>::RustClassType; 788 789 fn deref(&self) -> &Self::Target { 790 $crate::object::IsClassFor::upcast_ref(self) 791 } 792 } 793 794 impl ::std::ops::DerefMut for $rust_class_name { 795 fn deref_mut(&mut self) -> &mut Self::Target { 796 $crate::object::IsClassFor::upcast_ref_mut(self) 797 } 798 } 799 }; 800 801 // If there is more than one parent class 802 (@munch_first_impl $name:ident, $rust_class_name:ident, $super_name:path, $($implements:tt)*) => { 803 glib_object_wrapper!(@munch_impls $name, $super_name); 804 805 impl ::std::ops::Deref for $rust_class_name { 806 type Target = <$super_name as $crate::object::ObjectType>::RustClassType; 807 808 fn deref(&self) -> &Self::Target { 809 $crate::object::IsClassFor::upcast_ref(self) 810 } 811 } 812 813 impl ::std::ops::DerefMut for $rust_class_name { 814 fn deref_mut(&mut self) -> &mut Self::Target { 815 $crate::object::IsClassFor::upcast_ref_mut(self) 816 } 817 } 818 819 glib_object_wrapper!(@munch_impls $name, $($implements)*); 820 }; 821 822 (@class_impl $name:ident, $ffi_class_name:path, $rust_class_name:ident) => { 823 #[repr(C)] 824 pub struct $rust_class_name($ffi_class_name); 825 826 unsafe impl $crate::object::IsClassFor for $rust_class_name { 827 type Instance = $name; 828 } 829 830 unsafe impl Send for $rust_class_name { } 831 unsafe impl Sync for $rust_class_name { } 832 }; 833 834 // This case is only for glib::Object itself below. All other cases have glib::Object in its 835 // parent class list 836 (@object [$($attr:meta)*] $name:ident, $ffi_name:path, $ffi_class_name:path, $rust_class_name:ident, @get_type $get_type_expr:expr) => { 837 glib_object_wrapper!(@generic_impl [$($attr)*] $name, $ffi_name, $ffi_class_name, $rust_class_name, 838 @get_type $get_type_expr); 839 glib_object_wrapper!(@class_impl $name, $ffi_class_name, $rust_class_name); 840 }; 841 842 (@object [$($attr:meta)*] $name:ident, $ffi_name:path, $ffi_class_name:path, $rust_class_name:ident, 843 @get_type $get_type_expr:expr, @extends [$($extends:tt)*], @implements [$($implements:tt)*]) => { 844 glib_object_wrapper!(@generic_impl [$($attr)*] $name, $ffi_name, $ffi_class_name, $rust_class_name, 845 @get_type $get_type_expr); 846 glib_object_wrapper!(@munch_first_impl $name, $rust_class_name, $($extends)*); 847 glib_object_wrapper!(@munch_impls $name, $($implements)*); 848 glib_object_wrapper!(@class_impl $name, $ffi_class_name, $rust_class_name); 849 850 #[doc(hidden)] 851 impl AsRef<$crate::object::Object> for $name { 852 fn as_ref(&self) -> &$crate::object::Object { 853 $crate::object::Cast::upcast_ref(self) 854 } 855 } 856 857 #[doc(hidden)] 858 unsafe impl $crate::object::IsA<$crate::object::Object> for $name { } 859 }; 860 861 (@interface [$($attr:meta)*] $name:ident, $ffi_name:path, @get_type $get_type_expr:expr, @requires [$($requires:tt)*]) => { 862 glib_object_wrapper!(@generic_impl [$($attr)*] $name, $ffi_name, $crate::wrapper::Void, $crate::wrapper::Void, 863 @get_type $get_type_expr); 864 glib_object_wrapper!(@munch_impls $name, $($requires)*); 865 866 #[doc(hidden)] 867 impl AsRef<$crate::object::Object> for $name { 868 fn as_ref(&self) -> &$crate::object::Object { 869 $crate::object::Cast::upcast_ref(self) 870 } 871 } 872 873 #[doc(hidden)] 874 unsafe impl $crate::object::IsA<$crate::object::Object> for $name { } 875 }; 876 } 877 878 glib_object_wrapper!(@object 879 [doc = "The base class in the object hierarchy."] 880 Object, GObject, GObjectClass, ObjectClass, @get_type gobject_sys::g_object_get_type() 881 ); 882 883 impl Object { new(type_: Type, properties: &[(&str, &dyn ToValue)]) -> Result<Object, BoolError>884 pub fn new(type_: Type, properties: &[(&str, &dyn ToValue)]) -> Result<Object, BoolError> { 885 use std::ffi::CString; 886 887 if !type_.is_a(&Object::static_type()) { 888 return Err(glib_bool_error!("Can't instantiate non-GObject objects")); 889 } 890 891 let params = properties 892 .iter() 893 .map(|&(name, value)| (CString::new(name).unwrap(), value.to_value())) 894 .collect::<Vec<_>>(); 895 896 let params_c = params 897 .iter() 898 .map(|&(ref name, ref value)| gobject_sys::GParameter { 899 name: name.as_ptr(), 900 value: unsafe { *value.to_glib_none().0 }, 901 }) 902 .collect::<Vec<_>>(); 903 904 unsafe { 905 let ptr = gobject_sys::g_object_newv( 906 type_.to_glib(), 907 params_c.len() as u32, 908 mut_override(params_c.as_ptr()), 909 ); 910 if ptr.is_null() { 911 Err(glib_bool_error!("Can't instantiate object")) 912 } else if type_.is_a(&InitiallyUnowned::static_type()) { 913 Ok(from_glib_none(ptr)) 914 } else { 915 Ok(from_glib_full(ptr)) 916 } 917 } 918 } 919 } 920 921 pub trait ObjectExt: ObjectType { 922 /// Returns `true` if the object is an instance of (can be cast to) `T`. is<T: StaticType>(&self) -> bool923 fn is<T: StaticType>(&self) -> bool; 924 get_type(&self) -> Type925 fn get_type(&self) -> Type; get_object_class(&self) -> &ObjectClass926 fn get_object_class(&self) -> &ObjectClass; 927 set_property<'a, N: Into<&'a str>>( &self, property_name: N, value: &dyn ToValue, ) -> Result<(), BoolError>928 fn set_property<'a, N: Into<&'a str>>( 929 &self, 930 property_name: N, 931 value: &dyn ToValue, 932 ) -> Result<(), BoolError>; get_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Result<Value, BoolError>933 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>934 fn has_property<'a, N: Into<&'a str>>( 935 &self, 936 property_name: N, 937 type_: Option<Type>, 938 ) -> Result<(), BoolError>; get_property_type<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<Type>939 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>940 fn find_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<::ParamSpec>; list_properties(&self) -> Vec<::ParamSpec>941 fn list_properties(&self) -> Vec<::ParamSpec>; 942 block_signal(&self, handler_id: &SignalHandlerId)943 fn block_signal(&self, handler_id: &SignalHandlerId); unblock_signal(&self, handler_id: &SignalHandlerId)944 fn unblock_signal(&self, handler_id: &SignalHandlerId); stop_signal_emission(&self, signal_name: &str)945 fn stop_signal_emission(&self, signal_name: &str); 946 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 + 'static947 fn connect<'a, N, F>( 948 &self, 949 signal_name: N, 950 after: bool, 951 callback: F, 952 ) -> Result<SignalHandlerId, BoolError> 953 where 954 N: Into<&'a str>, 955 F: Fn(&[Value]) -> Option<Value> + Send + Sync + '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>956 unsafe fn connect_unsafe<'a, N, F>( 957 &self, 958 signal_name: N, 959 after: bool, 960 callback: F, 961 ) -> Result<SignalHandlerId, BoolError> 962 where 963 N: Into<&'a str>, 964 F: Fn(&[Value]) -> Option<Value>; emit<'a, N: Into<&'a str>>( &self, signal_name: N, args: &[&dyn ToValue], ) -> Result<Option<Value>, BoolError>965 fn emit<'a, N: Into<&'a str>>( 966 &self, 967 signal_name: N, 968 args: &[&dyn ToValue], 969 ) -> Result<Option<Value>, BoolError>; disconnect(&self, handler_id: SignalHandlerId)970 fn disconnect(&self, handler_id: SignalHandlerId); 971 connect_notify<F: Fn(&Self, &::ParamSpec) + Send + Sync + 'static>( &self, name: Option<&str>, f: F, ) -> SignalHandlerId972 fn connect_notify<F: Fn(&Self, &::ParamSpec) + Send + Sync + 'static>( 973 &self, 974 name: Option<&str>, 975 f: F, 976 ) -> SignalHandlerId; connect_notify_unsafe<F: Fn(&Self, &::ParamSpec)>( &self, name: Option<&str>, f: F, ) -> SignalHandlerId977 unsafe fn connect_notify_unsafe<F: Fn(&Self, &::ParamSpec)>( 978 &self, 979 name: Option<&str>, 980 f: F, 981 ) -> SignalHandlerId; notify<'a, N: Into<&'a str>>(&self, property_name: N)982 fn notify<'a, N: Into<&'a str>>(&self, property_name: N); notify_by_pspec(&self, pspec: &::ParamSpec)983 fn notify_by_pspec(&self, pspec: &::ParamSpec); 984 downgrade(&self) -> WeakRef<Self>985 fn downgrade(&self) -> WeakRef<Self>; 986 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>987 fn bind_property<'a, O: ObjectType, N: Into<&'a str>, M: Into<&'a str>>( 988 &'a self, 989 source_property: N, 990 target: &'a O, 991 target_property: M, 992 ) -> BindingBuilder<'a>; 993 ref_count(&self) -> u32994 fn ref_count(&self) -> u32; 995 } 996 997 impl<T: ObjectType> ObjectExt for T { is<U: StaticType>(&self) -> bool998 fn is<U: StaticType>(&self) -> bool { 999 self.get_type().is_a(&U::static_type()) 1000 } 1001 get_type(&self) -> Type1002 fn get_type(&self) -> Type { 1003 self.get_object_class().get_type() 1004 } 1005 get_object_class(&self) -> &ObjectClass1006 fn get_object_class(&self) -> &ObjectClass { 1007 unsafe { 1008 let obj: *mut gobject_sys::GObject = self.as_object_ref().to_glib_none().0; 1009 let klass = (*obj).g_type_instance.g_class as *const ObjectClass; 1010 &*klass 1011 } 1012 } 1013 set_property<'a, N: Into<&'a str>>( &self, property_name: N, value: &dyn ToValue, ) -> Result<(), BoolError>1014 fn set_property<'a, N: Into<&'a str>>( 1015 &self, 1016 property_name: N, 1017 value: &dyn ToValue, 1018 ) -> Result<(), BoolError> { 1019 let property_name = property_name.into(); 1020 let mut property_value = value.to_value(); 1021 1022 let pspec = match self.find_property(property_name) { 1023 Some(pspec) => pspec, 1024 None => { 1025 return Err(glib_bool_error!("property not found")); 1026 } 1027 }; 1028 1029 if !pspec.get_flags().contains(::ParamFlags::WRITABLE) 1030 || pspec.get_flags().contains(::ParamFlags::CONSTRUCT_ONLY) 1031 { 1032 return Err(glib_bool_error!("property is not writable")); 1033 } 1034 1035 unsafe { 1036 // While GLib actually allows all types that can somehow be transformed 1037 // into the property type, we're more restrictive here to be consistent 1038 // with Rust's type rules. We only allow the exact same type, or if the 1039 // value type is a subtype of the property type 1040 let valid_type: bool = from_glib(gobject_sys::g_type_check_value_holds( 1041 mut_override(property_value.to_glib_none().0), 1042 pspec.get_value_type().to_glib(), 1043 )); 1044 1045 // If it's not directly a valid type but an object type, we check if the 1046 // actual type of the contained object is compatible and if so create 1047 // a properly type Value. This can happen if the type field in the 1048 // Value is set to a more generic type than the contained value 1049 if !valid_type && property_value.type_().is_a(&Object::static_type()) { 1050 if let Some(obj) = property_value.get::<Object>() { 1051 if obj.get_type().is_a(&pspec.get_value_type()) { 1052 property_value.0.g_type = pspec.get_value_type().to_glib(); 1053 } else { 1054 return Err(glib_bool_error!( 1055 "property can't be set from the given object type" 1056 )); 1057 } 1058 } else { 1059 // Otherwise if the value is None then the type is compatible too 1060 property_value.0.g_type = pspec.get_value_type().to_glib(); 1061 } 1062 } else if !valid_type { 1063 return Err(glib_bool_error!( 1064 "property can't be set from the given type" 1065 )); 1066 } 1067 1068 let changed: bool = from_glib(gobject_sys::g_param_value_validate( 1069 pspec.to_glib_none().0, 1070 property_value.to_glib_none_mut().0, 1071 )); 1072 let change_allowed = pspec.get_flags().contains(::ParamFlags::LAX_VALIDATION); 1073 if changed && !change_allowed { 1074 return Err(glib_bool_error!( 1075 "property can't be set from given value, it is invalid or out of range" 1076 )); 1077 } 1078 1079 gobject_sys::g_object_set_property( 1080 self.as_object_ref().to_glib_none().0, 1081 property_name.to_glib_none().0, 1082 property_value.to_glib_none().0, 1083 ); 1084 } 1085 1086 Ok(()) 1087 } 1088 get_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Result<Value, BoolError>1089 fn get_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Result<Value, BoolError> { 1090 let property_name = property_name.into(); 1091 1092 let pspec = match self.find_property(property_name) { 1093 Some(pspec) => pspec, 1094 None => { 1095 return Err(glib_bool_error!("property not found")); 1096 } 1097 }; 1098 1099 if !pspec.get_flags().contains(::ParamFlags::READABLE) { 1100 return Err(glib_bool_error!("property is not readable")); 1101 } 1102 1103 unsafe { 1104 let mut value = Value::from_type(pspec.get_value_type()); 1105 gobject_sys::g_object_get_property( 1106 self.as_object_ref().to_glib_none().0, 1107 property_name.to_glib_none().0, 1108 value.to_glib_none_mut().0, 1109 ); 1110 1111 // This can't really happen unless something goes wrong inside GObject 1112 if value.type_() == ::Type::Invalid { 1113 Err(glib_bool_error!("Failed to get property value")) 1114 } else { 1115 Ok(value) 1116 } 1117 } 1118 } 1119 block_signal(&self, handler_id: &SignalHandlerId)1120 fn block_signal(&self, handler_id: &SignalHandlerId) { 1121 unsafe { 1122 gobject_sys::g_signal_handler_block( 1123 self.as_object_ref().to_glib_none().0, 1124 handler_id.to_glib(), 1125 ); 1126 } 1127 } 1128 unblock_signal(&self, handler_id: &SignalHandlerId)1129 fn unblock_signal(&self, handler_id: &SignalHandlerId) { 1130 unsafe { 1131 gobject_sys::g_signal_handler_unblock( 1132 self.as_object_ref().to_glib_none().0, 1133 handler_id.to_glib(), 1134 ); 1135 } 1136 } 1137 stop_signal_emission(&self, signal_name: &str)1138 fn stop_signal_emission(&self, signal_name: &str) { 1139 unsafe { 1140 gobject_sys::g_signal_stop_emission_by_name( 1141 self.as_object_ref().to_glib_none().0, 1142 signal_name.to_glib_none().0, 1143 ); 1144 } 1145 } 1146 disconnect(&self, handler_id: SignalHandlerId)1147 fn disconnect(&self, handler_id: SignalHandlerId) { 1148 unsafe { 1149 gobject_sys::g_signal_handler_disconnect( 1150 self.as_object_ref().to_glib_none().0, 1151 handler_id.to_glib(), 1152 ); 1153 } 1154 } 1155 connect_notify<F: Fn(&Self, &::ParamSpec) + Send + Sync + 'static>( &self, name: Option<&str>, f: F, ) -> SignalHandlerId1156 fn connect_notify<F: Fn(&Self, &::ParamSpec) + Send + Sync + 'static>( 1157 &self, 1158 name: Option<&str>, 1159 f: F, 1160 ) -> SignalHandlerId { 1161 unsafe { self.connect_notify_unsafe(name, f) } 1162 } 1163 connect_notify_unsafe<F: Fn(&Self, &::ParamSpec)>( &self, name: Option<&str>, f: F, ) -> SignalHandlerId1164 unsafe fn connect_notify_unsafe<F: Fn(&Self, &::ParamSpec)>( 1165 &self, 1166 name: Option<&str>, 1167 f: F, 1168 ) -> SignalHandlerId { 1169 unsafe extern "C" fn notify_trampoline<P, F: Fn(&P, &::ParamSpec)>( 1170 this: *mut gobject_sys::GObject, 1171 param_spec: *mut gobject_sys::GParamSpec, 1172 f: glib_sys::gpointer, 1173 ) where 1174 P: ObjectType, 1175 { 1176 let f: &F = &*(f as *const F); 1177 f( 1178 &Object::from_glib_borrow(this).unsafe_cast(), 1179 &from_glib_borrow(param_spec), 1180 ) 1181 } 1182 1183 let signal_name = if let Some(name) = name { 1184 format!("notify::{}\0", name) 1185 } else { 1186 "notify\0".into() 1187 }; 1188 1189 let f: Box<F> = Box::new(f); 1190 ::signal::connect_raw( 1191 self.as_object_ref().to_glib_none().0, 1192 signal_name.as_ptr() as *const _, 1193 Some(mem::transmute(notify_trampoline::<Self, F> as usize)), 1194 Box::into_raw(f), 1195 ) 1196 } 1197 notify<'a, N: Into<&'a str>>(&self, property_name: N)1198 fn notify<'a, N: Into<&'a str>>(&self, property_name: N) { 1199 let property_name = property_name.into(); 1200 1201 unsafe { 1202 gobject_sys::g_object_notify( 1203 self.as_object_ref().to_glib_none().0, 1204 property_name.to_glib_none().0, 1205 ); 1206 } 1207 } 1208 notify_by_pspec(&self, pspec: &::ParamSpec)1209 fn notify_by_pspec(&self, pspec: &::ParamSpec) { 1210 unsafe { 1211 gobject_sys::g_object_notify_by_pspec( 1212 self.as_object_ref().to_glib_none().0, 1213 pspec.to_glib_none().0, 1214 ); 1215 } 1216 } 1217 has_property<'a, N: Into<&'a str>>( &self, property_name: N, type_: Option<Type>, ) -> Result<(), BoolError>1218 fn has_property<'a, N: Into<&'a str>>( 1219 &self, 1220 property_name: N, 1221 type_: Option<Type>, 1222 ) -> Result<(), BoolError> { 1223 self.get_object_class().has_property(property_name, type_) 1224 } 1225 get_property_type<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<Type>1226 fn get_property_type<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<Type> { 1227 self.get_object_class().get_property_type(property_name) 1228 } 1229 find_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<::ParamSpec>1230 fn find_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<::ParamSpec> { 1231 self.get_object_class().find_property(property_name) 1232 } 1233 list_properties(&self) -> Vec<::ParamSpec>1234 fn list_properties(&self) -> Vec<::ParamSpec> { 1235 self.get_object_class().list_properties() 1236 } 1237 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,1238 fn connect<'a, N, F>( 1239 &self, 1240 signal_name: N, 1241 after: bool, 1242 callback: F, 1243 ) -> Result<SignalHandlerId, BoolError> 1244 where 1245 N: Into<&'a str>, 1246 F: Fn(&[Value]) -> Option<Value> + Send + Sync + 'static, 1247 { 1248 unsafe { self.connect_unsafe(signal_name, after, callback) } 1249 } 1250 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>,1251 unsafe fn connect_unsafe<'a, N, F>( 1252 &self, 1253 signal_name: N, 1254 after: bool, 1255 callback: F, 1256 ) -> Result<SignalHandlerId, BoolError> 1257 where 1258 N: Into<&'a str>, 1259 F: Fn(&[Value]) -> Option<Value>, 1260 { 1261 let signal_name: &str = signal_name.into(); 1262 1263 let type_ = self.get_type(); 1264 1265 let mut signal_id = 0; 1266 let mut signal_detail = 0; 1267 1268 let found: bool = from_glib(gobject_sys::g_signal_parse_name( 1269 signal_name.to_glib_none().0, 1270 type_.to_glib(), 1271 &mut signal_id, 1272 &mut signal_detail, 1273 true.to_glib(), 1274 )); 1275 1276 if !found { 1277 return Err(glib_bool_error!("Signal not found")); 1278 } 1279 1280 let mut details = mem::zeroed(); 1281 gobject_sys::g_signal_query(signal_id, &mut details); 1282 if details.signal_id != signal_id { 1283 return Err(glib_bool_error!("Signal not found")); 1284 } 1285 1286 // This is actually G_SIGNAL_TYPE_STATIC_SCOPE 1287 let return_type: Type = 1288 from_glib(details.return_type & (!gobject_sys::G_TYPE_FLAG_RESERVED_ID_BIT)); 1289 let closure = Closure::new_unsafe(move |values| { 1290 let ret = callback(values); 1291 1292 if return_type == Type::Unit { 1293 if let Some(ret) = ret { 1294 panic!( 1295 "Signal required no return value but got value of type {}", 1296 ret.type_().name() 1297 ); 1298 } 1299 None 1300 } else { 1301 match ret { 1302 Some(mut ret) => { 1303 let valid_type: bool = from_glib(gobject_sys::g_type_check_value_holds( 1304 mut_override(ret.to_glib_none().0), 1305 return_type.to_glib(), 1306 )); 1307 1308 // If it's not directly a valid type but an object type, we check if the 1309 // actual typed of the contained object is compatible and if so create 1310 // a properly typed Value. This can happen if the type field in the 1311 // Value is set to a more generic type than the contained value 1312 if !valid_type && ret.type_().is_a(&Object::static_type()) { 1313 if let Some(obj) = ret.get::<Object>() { 1314 if obj.get_type().is_a(&return_type) { 1315 ret.0.g_type = return_type.to_glib(); 1316 } else { 1317 panic!("Signal required return value of type {} but got {} (actual {})", 1318 return_type.name(), ret.type_().name(), obj.get_type().name()); 1319 } 1320 } else { 1321 // Otherwise if the value is None then the type is compatible too 1322 ret.0.g_type = return_type.to_glib(); 1323 } 1324 } else if !valid_type { 1325 panic!( 1326 "Signal required return value of type {} but got {}", 1327 return_type.name(), 1328 ret.type_().name() 1329 ); 1330 } 1331 Some(ret) 1332 } 1333 None => { 1334 panic!( 1335 "Signal required return value of type {} but got None", 1336 return_type.name() 1337 ); 1338 } 1339 } 1340 } 1341 }); 1342 let handler = gobject_sys::g_signal_connect_closure_by_id( 1343 self.as_object_ref().to_glib_none().0, 1344 signal_id, 1345 signal_detail, 1346 closure.to_glib_none().0, 1347 after.to_glib(), 1348 ); 1349 1350 if handler == 0 { 1351 Err(glib_bool_error!("Failed to connect to signal")) 1352 } else { 1353 Ok(from_glib(handler)) 1354 } 1355 } 1356 emit<'a, N: Into<&'a str>>( &self, signal_name: N, args: &[&dyn ToValue], ) -> Result<Option<Value>, BoolError>1357 fn emit<'a, N: Into<&'a str>>( 1358 &self, 1359 signal_name: N, 1360 args: &[&dyn ToValue], 1361 ) -> Result<Option<Value>, BoolError> { 1362 let signal_name: &str = signal_name.into(); 1363 unsafe { 1364 let type_ = self.get_type(); 1365 1366 let mut signal_id = 0; 1367 let mut signal_detail = 0; 1368 1369 let found: bool = from_glib(gobject_sys::g_signal_parse_name( 1370 signal_name.to_glib_none().0, 1371 type_.to_glib(), 1372 &mut signal_id, 1373 &mut signal_detail, 1374 true.to_glib(), 1375 )); 1376 1377 if !found { 1378 return Err(glib_bool_error!("Signal not found")); 1379 } 1380 1381 let mut details = mem::zeroed(); 1382 gobject_sys::g_signal_query(signal_id, &mut details); 1383 if details.signal_id != signal_id { 1384 return Err(glib_bool_error!("Signal not found")); 1385 } 1386 1387 if details.n_params != args.len() as u32 { 1388 return Err(glib_bool_error!("Incompatible number of arguments")); 1389 } 1390 1391 for (i, item) in args.iter().enumerate() { 1392 let arg_type = 1393 *(details.param_types.add(i)) & (!gobject_sys::G_TYPE_FLAG_RESERVED_ID_BIT); 1394 if arg_type != item.to_value_type().to_glib() { 1395 return Err(glib_bool_error!("Incompatible argument types")); 1396 } 1397 } 1398 1399 let mut v_args: Vec<Value>; 1400 let mut s_args: [Value; 10] = mem::zeroed(); 1401 let self_v = { 1402 let mut v = Value::uninitialized(); 1403 gobject_sys::g_value_init(v.to_glib_none_mut().0, self.get_type().to_glib()); 1404 gobject_sys::g_value_set_object( 1405 v.to_glib_none_mut().0, 1406 self.as_object_ref().to_glib_none().0, 1407 ); 1408 v 1409 }; 1410 let args = if args.len() < 10 { 1411 s_args[0] = self_v; 1412 for (i, arg) in args.iter().enumerate() { 1413 s_args[i + 1] = arg.to_value(); 1414 } 1415 &s_args[0..=args.len()] 1416 } else { 1417 v_args = Vec::with_capacity(args.len() + 1); 1418 v_args.push(self_v); 1419 for arg in args { 1420 v_args.push(arg.to_value()); 1421 } 1422 v_args.as_slice() 1423 }; 1424 1425 let mut return_value = Value::uninitialized(); 1426 if details.return_type != gobject_sys::G_TYPE_NONE { 1427 gobject_sys::g_value_init(return_value.to_glib_none_mut().0, details.return_type); 1428 } 1429 1430 gobject_sys::g_signal_emitv( 1431 mut_override(args.as_ptr()) as *mut gobject_sys::GValue, 1432 signal_id, 1433 signal_detail, 1434 return_value.to_glib_none_mut().0, 1435 ); 1436 1437 if return_value.type_() != Type::Unit && return_value.type_() != Type::Invalid { 1438 Ok(Some(return_value)) 1439 } else { 1440 Ok(None) 1441 } 1442 } 1443 } 1444 downgrade(&self) -> WeakRef<T>1445 fn downgrade(&self) -> WeakRef<T> { 1446 unsafe { 1447 let w = WeakRef(Box::new(mem::uninitialized()), PhantomData); 1448 gobject_sys::g_weak_ref_init( 1449 mut_override(&*w.0), 1450 self.as_object_ref().to_glib_none().0, 1451 ); 1452 w 1453 } 1454 } 1455 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>1456 fn bind_property<'a, O: ObjectType, N: Into<&'a str>, M: Into<&'a str>>( 1457 &'a self, 1458 source_property: N, 1459 target: &'a O, 1460 target_property: M, 1461 ) -> BindingBuilder<'a> { 1462 let source_property = source_property.into(); 1463 let target_property = target_property.into(); 1464 1465 BindingBuilder::new(self, source_property, target, target_property) 1466 } 1467 ref_count(&self) -> u321468 fn ref_count(&self) -> u32 { 1469 let stash = self.as_object_ref().to_glib_none(); 1470 let ptr: *mut gobject_sys::GObject = stash.0; 1471 1472 unsafe { glib_sys::g_atomic_int_get(&(*ptr).ref_count as *const u32 as *const i32) as u32 } 1473 } 1474 } 1475 1476 impl ObjectClass { has_property<'a, N: Into<&'a str>>( &self, property_name: N, type_: Option<Type>, ) -> Result<(), BoolError>1477 pub fn has_property<'a, N: Into<&'a str>>( 1478 &self, 1479 property_name: N, 1480 type_: Option<Type>, 1481 ) -> Result<(), BoolError> { 1482 let property_name = property_name.into(); 1483 let ptype = self.get_property_type(property_name); 1484 1485 match (ptype, type_) { 1486 (None, _) => Err(glib_bool_error!("Invalid property name")), 1487 (Some(_), None) => Ok(()), 1488 (Some(ptype), Some(type_)) => { 1489 if ptype == type_ { 1490 Ok(()) 1491 } else { 1492 Err(glib_bool_error!("Invalid property type")) 1493 } 1494 } 1495 } 1496 } 1497 get_property_type<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<Type>1498 pub fn get_property_type<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<Type> { 1499 self.find_property(property_name) 1500 .map(|pspec| pspec.get_value_type()) 1501 } 1502 find_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<::ParamSpec>1503 pub fn find_property<'a, N: Into<&'a str>>(&self, property_name: N) -> Option<::ParamSpec> { 1504 let property_name = property_name.into(); 1505 unsafe { 1506 let klass = self as *const _ as *const gobject_sys::GObjectClass; 1507 1508 from_glib_none(gobject_sys::g_object_class_find_property( 1509 klass as *mut _, 1510 property_name.to_glib_none().0, 1511 )) 1512 } 1513 } 1514 list_properties(&self) -> Vec<::ParamSpec>1515 pub fn list_properties(&self) -> Vec<::ParamSpec> { 1516 unsafe { 1517 let klass = self as *const _ as *const gobject_sys::GObjectClass; 1518 1519 let mut n_properties = 0; 1520 1521 let props = 1522 gobject_sys::g_object_class_list_properties(klass as *mut _, &mut n_properties); 1523 FromGlibContainer::from_glib_none_num(props, n_properties as usize) 1524 } 1525 } 1526 } 1527 1528 glib_wrapper! { 1529 pub struct InitiallyUnowned(Object<gobject_sys::GInitiallyUnowned, gobject_sys::GInitiallyUnownedClass, InitiallyUnownedClass>); 1530 1531 match fn { 1532 get_type => || gobject_sys::g_initially_unowned_get_type(), 1533 } 1534 } 1535 1536 pub struct WeakRef<T: ObjectType>(Box<gobject_sys::GWeakRef>, PhantomData<*const T>); 1537 1538 impl<T: ObjectType> WeakRef<T> { new() -> WeakRef<T>1539 pub fn new() -> WeakRef<T> { 1540 unsafe { 1541 let w = WeakRef(Box::new(mem::uninitialized()), PhantomData); 1542 gobject_sys::g_weak_ref_init(mut_override(&*w.0), ptr::null_mut()); 1543 w 1544 } 1545 } 1546 upgrade(&self) -> Option<T>1547 pub fn upgrade(&self) -> Option<T> { 1548 unsafe { 1549 let ptr = gobject_sys::g_weak_ref_get(mut_override(&*self.0)); 1550 if ptr.is_null() { 1551 None 1552 } else { 1553 let obj: Object = from_glib_full(ptr); 1554 Some(T::unsafe_from(obj.into())) 1555 } 1556 } 1557 } 1558 } 1559 1560 impl<T: ObjectType> Drop for WeakRef<T> { drop(&mut self)1561 fn drop(&mut self) { 1562 unsafe { 1563 gobject_sys::g_weak_ref_clear(mut_override(&*self.0)); 1564 } 1565 } 1566 } 1567 1568 impl<T: ObjectType> Clone for WeakRef<T> { clone(&self) -> Self1569 fn clone(&self) -> Self { 1570 unsafe { 1571 let c = WeakRef(Box::new(mem::uninitialized()), PhantomData); 1572 1573 let o = gobject_sys::g_weak_ref_get(mut_override(&*self.0)); 1574 gobject_sys::g_weak_ref_init(mut_override(&*c.0), o); 1575 if !o.is_null() { 1576 gobject_sys::g_object_unref(o); 1577 } 1578 1579 c 1580 } 1581 } 1582 } 1583 1584 impl<T: ObjectType> Default for WeakRef<T> { default() -> Self1585 fn default() -> Self { 1586 Self::new() 1587 } 1588 } 1589 1590 unsafe impl<T: ObjectType + Sync + Sync> Sync for WeakRef<T> {} 1591 unsafe impl<T: ObjectType + Send + Sync> Send for WeakRef<T> {} 1592 1593 /// A weak reference to the object it was created for that can be sent to 1594 /// different threads even for object types that don't implement `Send`. 1595 /// 1596 /// Trying to upgrade the weak reference from another thread than the one 1597 /// where it was created on will panic but dropping or cloning can be done 1598 /// safely from any thread. 1599 pub struct SendWeakRef<T: ObjectType>(WeakRef<T>, Option<usize>); 1600 1601 impl<T: ObjectType> SendWeakRef<T> { new() -> SendWeakRef<T>1602 pub fn new() -> SendWeakRef<T> { 1603 SendWeakRef(WeakRef::new(), None) 1604 } 1605 into_weak_ref(self) -> WeakRef<T>1606 pub fn into_weak_ref(self) -> WeakRef<T> { 1607 if self.1.is_some() && self.1 != Some(get_thread_id()) { 1608 panic!("SendWeakRef dereferenced on a different thread"); 1609 } 1610 1611 self.0 1612 } 1613 } 1614 1615 impl<T: ObjectType> ops::Deref for SendWeakRef<T> { 1616 type Target = WeakRef<T>; 1617 deref(&self) -> &WeakRef<T>1618 fn deref(&self) -> &WeakRef<T> { 1619 if self.1.is_some() && self.1 != Some(get_thread_id()) { 1620 panic!("SendWeakRef dereferenced on a different thread"); 1621 } 1622 1623 &self.0 1624 } 1625 } 1626 1627 // Deriving this gives the wrong trait bounds 1628 impl<T: ObjectType> Clone for SendWeakRef<T> { clone(&self) -> Self1629 fn clone(&self) -> Self { 1630 SendWeakRef(self.0.clone(), self.1) 1631 } 1632 } 1633 1634 impl<T: ObjectType> Default for SendWeakRef<T> { default() -> Self1635 fn default() -> Self { 1636 Self::new() 1637 } 1638 } 1639 1640 impl<T: ObjectType> From<WeakRef<T>> for SendWeakRef<T> { from(v: WeakRef<T>) -> SendWeakRef<T>1641 fn from(v: WeakRef<T>) -> SendWeakRef<T> { 1642 SendWeakRef(v, Some(get_thread_id())) 1643 } 1644 } 1645 1646 unsafe impl<T: ObjectType> Sync for SendWeakRef<T> {} 1647 unsafe impl<T: ObjectType> Send for SendWeakRef<T> {} 1648 1649 pub struct BindingBuilder<'a> { 1650 source: &'a ObjectRef, 1651 source_property: &'a str, 1652 target: &'a ObjectRef, 1653 target_property: &'a str, 1654 flags: ::BindingFlags, 1655 transform_to: Option<::Closure>, 1656 transform_from: Option<::Closure>, 1657 } 1658 1659 impl<'a> BindingBuilder<'a> { new<S: ObjectType, T: ObjectType>( source: &'a S, source_property: &'a str, target: &'a T, target_property: &'a str, ) -> Self1660 fn new<S: ObjectType, T: ObjectType>( 1661 source: &'a S, 1662 source_property: &'a str, 1663 target: &'a T, 1664 target_property: &'a str, 1665 ) -> Self { 1666 Self { 1667 source: source.as_object_ref(), 1668 source_property, 1669 target: target.as_object_ref(), 1670 target_property, 1671 flags: ::BindingFlags::DEFAULT, 1672 transform_to: None, 1673 transform_from: None, 1674 } 1675 } 1676 transform_closure<F: Fn(&::Binding, &Value) -> Option<Value> + Send + Sync + 'static>( func: F, ) -> ::Closure1677 fn transform_closure<F: Fn(&::Binding, &Value) -> Option<Value> + Send + Sync + 'static>( 1678 func: F, 1679 ) -> ::Closure { 1680 ::Closure::new(move |values| { 1681 assert_eq!(values.len(), 3); 1682 let binding = values[0].get::<::Binding>().unwrap(); 1683 let from = unsafe { 1684 let ptr = gobject_sys::g_value_get_boxed(mut_override( 1685 &values[1] as *const Value as *const gobject_sys::GValue, 1686 )); 1687 assert!(!ptr.is_null()); 1688 &*(ptr as *const gobject_sys::GValue as *const Value) 1689 }; 1690 1691 match func(&binding, &from) { 1692 None => Some(false.to_value()), 1693 Some(value) => { 1694 unsafe { 1695 gobject_sys::g_value_set_boxed( 1696 mut_override(&values[2] as *const Value as *const gobject_sys::GValue), 1697 &value as *const Value as *const _, 1698 ); 1699 } 1700 1701 Some(true.to_value()) 1702 } 1703 } 1704 }) 1705 } 1706 transform_from<F: Fn(&::Binding, &Value) -> Option<Value> + Send + Sync + 'static>( self, func: F, ) -> Self1707 pub fn transform_from<F: Fn(&::Binding, &Value) -> Option<Value> + Send + Sync + 'static>( 1708 self, 1709 func: F, 1710 ) -> Self { 1711 Self { 1712 transform_from: Some(Self::transform_closure(func)), 1713 ..self 1714 } 1715 } 1716 transform_to<F: Fn(&::Binding, &Value) -> Option<Value> + Send + Sync + 'static>( self, func: F, ) -> Self1717 pub fn transform_to<F: Fn(&::Binding, &Value) -> Option<Value> + Send + Sync + 'static>( 1718 self, 1719 func: F, 1720 ) -> Self { 1721 Self { 1722 transform_to: Some(Self::transform_closure(func)), 1723 ..self 1724 } 1725 } 1726 flags(self, flags: ::BindingFlags) -> Self1727 pub fn flags(self, flags: ::BindingFlags) -> Self { 1728 Self { flags, ..self } 1729 } 1730 build(self) -> Option<::Binding>1731 pub fn build(self) -> Option<::Binding> { 1732 unsafe { 1733 from_glib_none(gobject_sys::g_object_bind_property_with_closures( 1734 self.source.to_glib_none().0, 1735 self.source_property.to_glib_none().0, 1736 self.target.to_glib_none().0, 1737 self.target_property.to_glib_none().0, 1738 self.flags.to_glib(), 1739 self.transform_to.to_glib_none().0, 1740 self.transform_from.to_glib_none().0, 1741 )) 1742 } 1743 } 1744 } 1745