gtk/subclass/
socket.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::subclass::prelude::*;
4
5use glib::translate::*;
6use glib::Cast;
7
8use super::container::ContainerImpl;
9
10use crate::Socket;
11
12pub trait SocketImpl: SocketImplExt + ContainerImpl {
13    fn plug_added(&self) {
14        self.parent_plug_added()
15    }
16
17    fn plug_removed(&self) -> glib::Propagation {
18        self.parent_plug_removed()
19    }
20}
21
22mod sealed {
23    pub trait Sealed {}
24    impl<T: super::SocketImpl> Sealed for T {}
25}
26
27pub trait SocketImplExt: ObjectSubclass + sealed::Sealed {
28    fn parent_plug_added(&self) {
29        unsafe {
30            let data = Self::type_data();
31            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkSocketClass;
32            if let Some(f) = (*parent_class).plug_added {
33                f(self.obj().unsafe_cast_ref::<Socket>().to_glib_none().0)
34            }
35        }
36    }
37    fn parent_plug_removed(&self) -> glib::Propagation {
38        unsafe {
39            let data = Self::type_data();
40            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkSocketClass;
41            if let Some(f) = (*parent_class).plug_removed {
42                glib::Propagation::from_glib(f(self
43                    .obj()
44                    .unsafe_cast_ref::<Socket>()
45                    .to_glib_none()
46                    .0))
47            } else {
48                glib::Propagation::Proceed
49            }
50        }
51    }
52}
53
54impl<T: SocketImpl> SocketImplExt for T {}
55
56unsafe impl<T: SocketImpl> IsSubclassable<T> for Socket {
57    fn class_init(class: &mut ::glib::Class<Self>) {
58        Self::parent_class_init::<T>(class);
59
60        if !crate::rt::is_initialized() {
61            panic!("GTK has to be initialized first");
62        }
63
64        let klass = class.as_mut();
65        klass.plug_added = Some(socket_plug_added::<T>);
66        klass.plug_removed = Some(socket_plug_removed::<T>);
67    }
68}
69
70unsafe extern "C" fn socket_plug_added<T: SocketImpl>(ptr: *mut ffi::GtkSocket) {
71    let instance = &*(ptr as *mut T::Instance);
72    let imp = instance.imp();
73
74    imp.plug_added()
75}
76
77unsafe extern "C" fn socket_plug_removed<T: SocketImpl>(
78    ptr: *mut ffi::GtkSocket,
79) -> glib::ffi::gboolean {
80    let instance = &*(ptr as *mut T::Instance);
81    let imp = instance.imp();
82
83    imp.plug_removed().into_glib()
84}