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