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::{prelude::*, signal::connect_raw, translate::*, SignalHandlerId};
6
7use crate::{ffi, DBusProxy};
8
9mod sealed {
10    pub trait Sealed {}
11    impl<T: super::IsA<super::DBusProxy>> Sealed for T {}
12}
13
14pub trait DBusProxyExtManual: sealed::Sealed + IsA<DBusProxy> + 'static {
15    #[cfg(feature = "v2_72")]
16    #[doc(alias = "g-signal")]
17    fn connect_g_signal<
18        F: Fn(&Self, Option<&str>, &str, &glib::Variant) + Send + Sync + 'static,
19    >(
20        &self,
21        detail: Option<&str>,
22        f: F,
23    ) -> SignalHandlerId {
24        unsafe extern "C" fn g_signal_trampoline<
25            P: IsA<DBusProxy>,
26            F: Fn(&P, Option<&str>, &str, &glib::Variant) + Send + Sync + 'static,
27        >(
28            this: *mut ffi::GDBusProxy,
29            sender_name: *mut libc::c_char,
30            signal_name: *mut libc::c_char,
31            parameters: *mut glib::ffi::GVariant,
32            f: glib::ffi::gpointer,
33        ) {
34            let f: &F = &*(f as *const F);
35            f(
36                DBusProxy::from_glib_borrow(this).unsafe_cast_ref(),
37                Option::<glib::GString>::from_glib_borrow(sender_name)
38                    .as_ref()
39                    .as_deref(),
40                &glib::GString::from_glib_borrow(signal_name),
41                &from_glib_borrow(parameters),
42            )
43        }
44        unsafe {
45            let f: Box_<F> = Box_::new(f);
46            let detailed_signal_name = detail.map(|name| format!("g-signal::{name}\0"));
47            let signal_name: &[u8] = detailed_signal_name
48                .as_ref()
49                .map_or(&b"g-signal\0"[..], |n| n.as_bytes());
50            connect_raw(
51                self.as_ptr() as *mut _,
52                signal_name.as_ptr() as *const _,
53                Some(transmute::<*const (), unsafe extern "C" fn()>(
54                    g_signal_trampoline::<Self, F> as *const (),
55                )),
56                Box_::into_raw(f),
57            )
58        }
59    }
60
61    #[cfg(not(feature = "v2_72"))]
62    #[doc(alias = "g-signal")]
63    fn connect_g_signal<
64        F: Fn(&Self, Option<&str>, &str, &glib::Variant) + Send + Sync + 'static,
65    >(
66        &self,
67        f: F,
68    ) -> SignalHandlerId {
69        unsafe extern "C" fn g_signal_trampoline<
70            P: IsA<DBusProxy>,
71            F: Fn(&P, Option<&str>, &str, &glib::Variant) + Send + Sync + 'static,
72        >(
73            this: *mut ffi::GDBusProxy,
74            sender_name: *mut libc::c_char,
75            signal_name: *mut libc::c_char,
76            parameters: *mut glib::ffi::GVariant,
77            f: glib::ffi::gpointer,
78        ) {
79            let f: &F = &*(f as *const F);
80            f(
81                DBusProxy::from_glib_borrow(this).unsafe_cast_ref(),
82                Option::<glib::GString>::from_glib_borrow(sender_name)
83                    .as_ref()
84                    .as_deref(),
85                &glib::GString::from_glib_borrow(signal_name),
86                &from_glib_borrow(parameters),
87            )
88        }
89        unsafe {
90            let f: Box_<F> = Box_::new(f);
91            connect_raw(
92                self.as_ptr() as *mut _,
93                b"g-signal\0".as_ptr() as *const _,
94                Some(transmute::<*const (), unsafe extern "C" fn()>(
95                    g_signal_trampoline::<Self, F> as *const (),
96                )),
97                Box_::into_raw(f),
98            )
99        }
100    }
101}
102
103impl<O: IsA<DBusProxy>> DBusProxyExtManual for O {}