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