1use 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 {}