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