gio/
dbus_proxy.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{boxed::Box as Box_, mem::transmute};
4
5use glib::{SignalHandlerId, prelude::*, signal::connect_raw, translate::*};
6
7use crate::{DBusProxy, ffi};
8
9pub trait DBusProxyExtManual: IsA<DBusProxy> + 'static {
10    #[doc(alias = "g-properties-changed")]
11    fn connect_g_properties_changed<
12        F: Fn(&Self, &glib::Variant, &glib::StrVRef) + Send + Sync + 'static,
13    >(
14        &self,
15        f: F,
16    ) -> SignalHandlerId {
17        unsafe extern "C" fn g_properties_changed_trampoline<
18            P: IsA<DBusProxy>,
19            F: Fn(&P, &glib::Variant, &glib::StrVRef) + Send + Sync + 'static,
20        >(
21            this: *mut ffi::GDBusProxy,
22            changed_properties: *mut glib::ffi::GVariant,
23            invalidated_properties: *const *const libc::c_char,
24            f: glib::ffi::gpointer,
25        ) {
26            unsafe {
27                let f: &F = &*(f as *const F);
28                f(
29                    DBusProxy::from_glib_borrow(this).unsafe_cast_ref(),
30                    &from_glib_borrow(changed_properties),
31                    glib::StrVRef::from_glib_borrow(invalidated_properties),
32                )
33            }
34        }
35        unsafe {
36            let f: Box_<F> = Box_::new(f);
37            connect_raw(
38                self.as_ptr() as *mut _,
39                c"g-properties-changed".as_ptr() as *const _,
40                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
41                    g_properties_changed_trampoline::<Self, F> as *const (),
42                )),
43                Box_::into_raw(f),
44            )
45        }
46    }
47
48    #[cfg(feature = "v2_72")]
49    #[doc(alias = "g-signal")]
50    fn connect_g_signal<
51        F: Fn(&Self, Option<&str>, &str, &glib::Variant) + Send + Sync + 'static,
52    >(
53        &self,
54        detail: Option<&str>,
55        f: F,
56    ) -> SignalHandlerId {
57        unsafe extern "C" fn g_signal_trampoline<
58            P: IsA<DBusProxy>,
59            F: Fn(&P, Option<&str>, &str, &glib::Variant) + Send + Sync + 'static,
60        >(
61            this: *mut ffi::GDBusProxy,
62            sender_name: *mut libc::c_char,
63            signal_name: *mut libc::c_char,
64            parameters: *mut glib::ffi::GVariant,
65            f: glib::ffi::gpointer,
66        ) {
67            unsafe {
68                let f: &F = &*(f as *const F);
69                f(
70                    DBusProxy::from_glib_borrow(this).unsafe_cast_ref(),
71                    Option::<glib::GString>::from_glib_borrow(sender_name)
72                        .as_ref()
73                        .as_deref(),
74                    &glib::GString::from_glib_borrow(signal_name),
75                    &from_glib_borrow(parameters),
76                )
77            }
78        }
79        unsafe {
80            let f: Box_<F> = Box_::new(f);
81            let detailed_signal_name = detail.map(|name| format!("g-signal::{name}\0"));
82            let signal_name: &[u8] = detailed_signal_name
83                .as_ref()
84                .map_or(&b"g-signal\0"[..], |n| n.as_bytes());
85            connect_raw(
86                self.as_ptr() as *mut _,
87                signal_name.as_ptr() as *const _,
88                Some(transmute::<*const (), unsafe extern "C" fn()>(
89                    g_signal_trampoline::<Self, F> as *const (),
90                )),
91                Box_::into_raw(f),
92            )
93        }
94    }
95
96    #[cfg(not(feature = "v2_72"))]
97    #[doc(alias = "g-signal")]
98    fn connect_g_signal<
99        F: Fn(&Self, Option<&str>, &str, &glib::Variant) + Send + Sync + 'static,
100    >(
101        &self,
102        f: F,
103    ) -> SignalHandlerId {
104        unsafe extern "C" fn g_signal_trampoline<
105            P: IsA<DBusProxy>,
106            F: Fn(&P, Option<&str>, &str, &glib::Variant) + Send + Sync + 'static,
107        >(
108            this: *mut ffi::GDBusProxy,
109            sender_name: *mut libc::c_char,
110            signal_name: *mut libc::c_char,
111            parameters: *mut glib::ffi::GVariant,
112            f: glib::ffi::gpointer,
113        ) {
114            unsafe {
115                let f: &F = &*(f as *const F);
116                f(
117                    DBusProxy::from_glib_borrow(this).unsafe_cast_ref(),
118                    Option::<glib::GString>::from_glib_borrow(sender_name)
119                        .as_ref()
120                        .as_deref(),
121                    &glib::GString::from_glib_borrow(signal_name),
122                    &from_glib_borrow(parameters),
123                )
124            }
125        }
126        unsafe {
127            let f: Box_<F> = Box_::new(f);
128            connect_raw(
129                self.as_ptr() as *mut _,
130                b"g-signal\0".as_ptr() as *const _,
131                Some(transmute::<*const (), unsafe extern "C" fn()>(
132                    g_signal_trampoline::<Self, F> as *const (),
133                )),
134                Box_::into_raw(f),
135            )
136        }
137    }
138}
139
140impl<O: IsA<DBusProxy>> DBusProxyExtManual for O {}