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