1use crate::{
4 BusType, Cancellable, DBusConnection, DBusObjectManagerClient, DBusObjectManagerClientFlags,
5 DBusObjectProxy, DBusProxy, GioFuture, ffi,
6};
7use glib::object::{Cast as _, IsA};
8use glib::signal::connect_raw;
9use glib::translate::{
10 Borrowed, FromGlibPtrBorrow as _, IntoGlib as _, ToGlibPtr as _, from_glib_borrow,
11 from_glib_full,
12};
13use glib::{SignalHandlerId, StrVRef};
14use std::future::Future;
15use std::pin::Pin;
16
17type DBusProxyTypeFn = Box<
18 dyn Fn(&DBusObjectManagerClient, &str, Option<&str>) -> glib::types::Type
19 + Send
20 + Sync
21 + 'static,
22>;
23
24impl DBusObjectManagerClient {
25 #[doc(alias = "g_dbus_object_manager_client_new_sync")]
26 pub fn new_sync(
27 connection: &DBusConnection,
28 flags: DBusObjectManagerClientFlags,
29 name: Option<&str>,
30 object_path: &str,
31 cancellable: Option<&impl IsA<Cancellable>>,
32 ) -> Result<DBusObjectManagerClient, glib::Error> {
33 Self::new_sync_impl(connection, flags, name, object_path, None, cancellable)
34 }
35
36 #[doc(alias = "g_dbus_object_manager_client_new_sync")]
37 pub fn new_sync_with_fn<
38 F: Fn(&DBusObjectManagerClient, &str, Option<&str>) -> glib::types::Type
39 + Send
40 + Sync
41 + 'static,
42 >(
43 connection: &DBusConnection,
44 flags: DBusObjectManagerClientFlags,
45 name: Option<&str>,
46 object_path: &str,
47 get_proxy_type_func: F,
48 cancellable: Option<&impl IsA<Cancellable>>,
49 ) -> Result<DBusObjectManagerClient, glib::Error> {
50 Self::new_sync_impl(
51 connection,
52 flags,
53 name,
54 object_path,
55 Some(Box::new(get_proxy_type_func)),
56 cancellable,
57 )
58 }
59
60 #[doc(alias = "g_dbus_object_manager_client_new_for_bus_sync")]
61 pub fn for_bus_sync(
62 bus_type: BusType,
63 flags: DBusObjectManagerClientFlags,
64 name: &str,
65 object_path: &str,
66 cancellable: Option<&impl IsA<Cancellable>>,
67 ) -> Result<DBusObjectManagerClient, glib::Error> {
68 Self::for_bus_sync_impl(bus_type, flags, name, object_path, None, cancellable)
69 }
70
71 #[doc(alias = "g_dbus_object_manager_client_new_for_bus_sync")]
72 pub fn for_bus_sync_with_fn<
73 F: Fn(&DBusObjectManagerClient, &str, Option<&str>) -> glib::types::Type
74 + Send
75 + Sync
76 + 'static,
77 >(
78 bus_type: BusType,
79 flags: DBusObjectManagerClientFlags,
80 name: &str,
81 object_path: &str,
82 get_proxy_type_func: F,
83 cancellable: Option<&impl IsA<Cancellable>>,
84 ) -> Result<DBusObjectManagerClient, glib::Error> {
85 Self::for_bus_sync_impl(
86 bus_type,
87 flags,
88 name,
89 object_path,
90 Some(Box::new(get_proxy_type_func)),
91 cancellable,
92 )
93 }
94
95 #[allow(clippy::new_ret_no_self)]
122 #[doc(alias = "g_dbus_object_manager_client_new")]
123 pub fn new<P: FnOnce(Result<DBusObjectManagerClient, glib::Error>) + Send + Sync + 'static>(
124 connection: &DBusConnection,
125 flags: DBusObjectManagerClientFlags,
126 name: &str,
127 object_path: &str,
128 cancellable: Option<&impl IsA<Cancellable>>,
129 callback: P,
130 ) {
131 Self::new_impl(
132 connection,
133 flags,
134 name,
135 object_path,
136 None,
137 cancellable,
138 callback,
139 )
140 }
141
142 #[allow(clippy::new_ret_no_self)]
143 #[doc(alias = "g_dbus_object_manager_client_new")]
144 pub fn new_with_fn<
145 P: FnOnce(Result<DBusObjectManagerClient, glib::Error>) + Send + Sync + 'static,
146 F: Fn(&DBusObjectManagerClient, &str, Option<&str>) -> glib::types::Type
147 + Send
148 + Sync
149 + 'static,
150 >(
151 connection: &DBusConnection,
152 flags: DBusObjectManagerClientFlags,
153 name: &str,
154 object_path: &str,
155 get_proxy_type_func: F,
156 cancellable: Option<&impl IsA<Cancellable>>,
157 callback: P,
158 ) {
159 Self::new_impl(
160 connection,
161 flags,
162 name,
163 object_path,
164 Some(Box::new(get_proxy_type_func)),
165 cancellable,
166 callback,
167 )
168 }
169
170 #[allow(clippy::new_ret_no_self)]
171 fn new_impl<P: FnOnce(Result<DBusObjectManagerClient, glib::Error>) + Send + Sync + 'static>(
172 connection: &DBusConnection,
173 flags: DBusObjectManagerClientFlags,
174 name: &str,
175 object_path: &str,
176 get_proxy_type_func: Option<DBusProxyTypeFn>,
177 cancellable: Option<&impl IsA<Cancellable>>,
178 callback: P,
179 ) {
180 let main_context = glib::MainContext::ref_thread_default();
181 let is_main_context_owner = main_context.is_owner();
182 let has_acquired_main_context = (!is_main_context_owner)
183 .then(|| main_context.acquire().ok())
184 .flatten();
185 assert!(
186 is_main_context_owner || has_acquired_main_context.is_some(),
187 "Async operations only allowed if the thread is owning the MainContext"
188 );
189
190 unsafe extern "C" fn get_proxy_type_func_func(
191 manager: *mut ffi::GDBusObjectManagerClient,
192 object_path: *const std::ffi::c_char,
193 interface_name: *const std::ffi::c_char,
194 data: glib::ffi::gpointer,
195 ) -> glib::ffi::GType {
196 unsafe {
197 let manager = from_glib_borrow(manager);
198 let object_path: Borrowed<glib::GString> = from_glib_borrow(object_path);
199 let interface_name: Borrowed<Option<glib::GString>> =
200 from_glib_borrow(interface_name);
201 let callback = &*(data as *mut Option<DBusProxyTypeFn>);
202 if let Some(ref callback) = *callback {
203 callback(
204 &manager,
205 object_path.as_str(),
206 (*interface_name).as_ref().map(|s| s.as_str()),
207 )
208 } else {
209 panic!("cannot get closure...")
210 }
211 .into_glib()
212 }
213 }
214
215 unsafe extern "C" fn get_proxy_type_destroy_notify_func(data: glib::ffi::gpointer) {
216 unsafe {
217 let _callback = Box::from_raw(data as *mut Option<DBusProxyTypeFn>);
218 }
219 }
220
221 unsafe extern "C" fn new_trampoline<
222 P: FnOnce(Result<DBusObjectManagerClient, glib::Error>) + Send + Sync + 'static,
223 >(
224 _source_object: *mut glib::gobject_ffi::GObject,
225 res: *mut crate::ffi::GAsyncResult,
226 user_data: glib::ffi::gpointer,
227 ) {
228 unsafe {
229 let mut error = std::ptr::null_mut();
230 let ret = ffi::g_dbus_object_manager_client_new_finish(res, &mut error);
231 let result = if error.is_null() {
232 Ok(from_glib_full(ret))
233 } else {
234 Err(from_glib_full(error))
235 };
236 let callback: Box<glib::thread_guard::ThreadGuard<P>> =
237 Box::from_raw(user_data as *mut _);
238 let callback: P = callback.into_inner();
239 callback(result);
240 }
241 }
242
243 let get_proxy_type_user_data = Box::new(get_proxy_type_func);
244 let get_proxy_type_func = if get_proxy_type_user_data.is_some() {
245 Some(get_proxy_type_func_func as _)
246 } else {
247 None
248 };
249 let get_proxy_type_destroy_notify = if get_proxy_type_user_data.is_some() {
250 Some(get_proxy_type_destroy_notify_func as _)
251 } else {
252 None
253 };
254
255 let user_data: Box<glib::thread_guard::ThreadGuard<P>> =
256 Box::new(glib::thread_guard::ThreadGuard::new(callback));
257 let callback = new_trampoline::<P>;
258
259 unsafe {
260 ffi::g_dbus_object_manager_client_new(
261 connection.to_glib_none().0,
262 flags.into_glib(),
263 name.to_glib_none().0,
264 object_path.to_glib_none().0,
265 get_proxy_type_func,
266 Box::into_raw(get_proxy_type_user_data) as *mut _,
267 get_proxy_type_destroy_notify,
268 cancellable.map(|p| p.as_ref()).to_glib_none().0,
269 Some(callback),
270 Box::into_raw(user_data) as *mut _,
271 );
272 }
273 }
274
275 pub fn new_future(
276 connection: &DBusConnection,
277 flags: DBusObjectManagerClientFlags,
278 name: &str,
279 object_path: &str,
280 ) -> Pin<Box<dyn Future<Output = Result<DBusObjectManagerClient, glib::Error>> + 'static>> {
281 Self::new_future_impl(connection, flags, name, object_path, None)
282 }
283
284 pub fn new_future_with_fn<
285 F: Fn(&DBusObjectManagerClient, &str, Option<&str>) -> glib::types::Type
286 + Send
287 + Sync
288 + 'static,
289 >(
290 connection: &DBusConnection,
291 flags: DBusObjectManagerClientFlags,
292 name: &str,
293 object_path: &str,
294 get_proxy_type_func: F,
295 ) -> Pin<Box<dyn Future<Output = Result<DBusObjectManagerClient, glib::Error>> + 'static>> {
296 Self::new_future_impl(
297 connection,
298 flags,
299 name,
300 object_path,
301 Some(Box::new(get_proxy_type_func)),
302 )
303 }
304
305 fn new_future_impl(
306 connection: &DBusConnection,
307 flags: DBusObjectManagerClientFlags,
308 name: &str,
309 object_path: &str,
310 get_proxy_type_func: Option<DBusProxyTypeFn>,
311 ) -> Pin<Box<dyn Future<Output = Result<DBusObjectManagerClient, glib::Error>> + 'static>> {
312 let connection = connection.clone();
313 let name = String::from(name);
314 let object_path = String::from(object_path);
315 Box::pin(GioFuture::new(&(), move |_obj, cancellable, send| {
316 Self::new_impl(
317 &connection,
318 flags,
319 &name,
320 &object_path,
321 get_proxy_type_func,
322 Some(cancellable),
323 move |res| {
324 send.resolve(res);
325 },
326 );
327 }))
328 }
329
330 #[doc(alias = "g_dbus_object_manager_client_new_for_bus")]
358 #[allow(clippy::new_ret_no_self)]
359 pub fn new_for_bus<
360 P: FnOnce(Result<DBusObjectManagerClient, glib::Error>) + Send + Sync + 'static,
361 >(
362 bus_type: BusType,
363 flags: DBusObjectManagerClientFlags,
364 name: &str,
365 object_path: &str,
366 cancellable: Option<&impl IsA<Cancellable>>,
367 callback: P,
368 ) {
369 Self::new_for_bus_impl(
370 bus_type,
371 flags,
372 name,
373 object_path,
374 None,
375 cancellable,
376 callback,
377 );
378 }
379
380 #[doc(alias = "g_dbus_object_manager_client_new_for_bus")]
381 #[allow(clippy::new_ret_no_self)]
382 pub fn new_for_bus_with_fn<
383 P: FnOnce(Result<DBusObjectManagerClient, glib::Error>) + Send + Sync + 'static,
384 F: Fn(&DBusObjectManagerClient, &str, Option<&str>) -> glib::types::Type
385 + Send
386 + Sync
387 + 'static,
388 >(
389 bus_type: BusType,
390 flags: DBusObjectManagerClientFlags,
391 name: &str,
392 object_path: &str,
393 get_proxy_type_func: F,
394 cancellable: Option<&impl IsA<Cancellable>>,
395 callback: P,
396 ) {
397 Self::new_for_bus_impl(
398 bus_type,
399 flags,
400 name,
401 object_path,
402 Some(Box::new(get_proxy_type_func)),
403 cancellable,
404 callback,
405 );
406 }
407
408 #[allow(clippy::new_ret_no_self)]
409 fn new_for_bus_impl<
410 P: FnOnce(Result<DBusObjectManagerClient, glib::Error>) + Send + Sync + 'static,
411 >(
412 bus_type: BusType,
413 flags: DBusObjectManagerClientFlags,
414 name: &str,
415 object_path: &str,
416 get_proxy_type_func: Option<DBusProxyTypeFn>,
417 cancellable: Option<&impl IsA<Cancellable>>,
418 callback: P,
419 ) {
420 let main_context = glib::MainContext::ref_thread_default();
421 let is_main_context_owner = main_context.is_owner();
422 let has_acquired_main_context = (!is_main_context_owner)
423 .then(|| main_context.acquire().ok())
424 .flatten();
425 assert!(
426 is_main_context_owner || has_acquired_main_context.is_some(),
427 "Async operations only allowed if the thread is owning the MainContext"
428 );
429
430 unsafe extern "C" fn get_proxy_type_func_func(
431 manager: *mut ffi::GDBusObjectManagerClient,
432 object_path: *const std::ffi::c_char,
433 interface_name: *const std::ffi::c_char,
434 data: glib::ffi::gpointer,
435 ) -> glib::ffi::GType {
436 unsafe {
437 let manager = from_glib_borrow(manager);
438 let object_path: Borrowed<glib::GString> = from_glib_borrow(object_path);
439 let interface_name: Borrowed<Option<glib::GString>> =
440 from_glib_borrow(interface_name);
441 let callback = &*(data as *mut Option<DBusProxyTypeFn>);
442 if let Some(ref callback) = *callback {
443 callback(
444 &manager,
445 object_path.as_str(),
446 (*interface_name).as_ref().map(|s| s.as_str()),
447 )
448 } else {
449 panic!("cannot get closure...")
450 }
451 .into_glib()
452 }
453 }
454
455 unsafe extern "C" fn get_proxy_type_destroy_notify_func(data: glib::ffi::gpointer) {
456 unsafe {
457 let _callback = Box::from_raw(data as *mut Option<DBusProxyTypeFn>);
458 }
459 }
460
461 unsafe extern "C" fn new_for_bus_trampoline<
462 P: FnOnce(Result<DBusObjectManagerClient, glib::Error>) + Send + Sync + 'static,
463 >(
464 _source_object: *mut glib::gobject_ffi::GObject,
465 res: *mut crate::ffi::GAsyncResult,
466 user_data: glib::ffi::gpointer,
467 ) {
468 unsafe {
469 let mut error = std::ptr::null_mut();
470 let ret = ffi::g_dbus_object_manager_client_new_finish(res, &mut error);
471 let result = if error.is_null() {
472 Ok(from_glib_full(ret))
473 } else {
474 Err(from_glib_full(error))
475 };
476 let callback: Box<glib::thread_guard::ThreadGuard<P>> =
477 Box::from_raw(user_data as *mut _);
478 let callback: P = callback.into_inner();
479 callback(result);
480 }
481 }
482
483 let get_proxy_type_user_data = Box::new(get_proxy_type_func);
484 let get_proxy_type_func = if get_proxy_type_user_data.is_some() {
485 Some(get_proxy_type_func_func as _)
486 } else {
487 None
488 };
489 let get_proxy_type_destroy_notify = if get_proxy_type_user_data.is_some() {
490 Some(get_proxy_type_destroy_notify_func as _)
491 } else {
492 None
493 };
494
495 let user_data: Box<glib::thread_guard::ThreadGuard<P>> =
496 Box::new(glib::thread_guard::ThreadGuard::new(callback));
497 let callback = new_for_bus_trampoline::<P>;
498
499 unsafe {
500 ffi::g_dbus_object_manager_client_new_for_bus(
501 bus_type.into_glib(),
502 flags.into_glib(),
503 name.to_glib_none().0,
504 object_path.to_glib_none().0,
505 get_proxy_type_func,
506 Box::into_raw(get_proxy_type_user_data) as *mut _,
507 get_proxy_type_destroy_notify,
508 cancellable.map(|p| p.as_ref()).to_glib_none().0,
509 Some(callback),
510 Box::into_raw(user_data) as *mut _,
511 );
512 }
513 }
514
515 pub fn new_for_bus_future(
516 bus_type: BusType,
517 flags: DBusObjectManagerClientFlags,
518 name: &str,
519 object_path: &str,
520 ) -> Pin<Box<dyn Future<Output = Result<DBusObjectManagerClient, glib::Error>> + 'static>> {
521 Self::new_for_bus_future_impl(bus_type, flags, name, object_path, None)
522 }
523
524 pub fn new_for_bus_future_with_fn<
525 F: Fn(&DBusObjectManagerClient, &str, Option<&str>) -> glib::types::Type
526 + Send
527 + Sync
528 + 'static,
529 >(
530 bus_type: BusType,
531 flags: DBusObjectManagerClientFlags,
532 name: &str,
533 object_path: &str,
534 get_proxy_type_func: F,
535 ) -> Pin<Box<dyn Future<Output = Result<DBusObjectManagerClient, glib::Error>> + 'static>> {
536 Self::new_for_bus_future_impl(
537 bus_type,
538 flags,
539 name,
540 object_path,
541 Some(Box::new(get_proxy_type_func)),
542 )
543 }
544
545 fn new_for_bus_future_impl(
546 bus_type: BusType,
547 flags: DBusObjectManagerClientFlags,
548 name: &str,
549 object_path: &str,
550 get_proxy_type_func: Option<DBusProxyTypeFn>,
551 ) -> Pin<Box<dyn Future<Output = Result<DBusObjectManagerClient, glib::Error>> + 'static>> {
552 let name = String::from(name);
553 let object_path = String::from(object_path);
554 Box::pin(GioFuture::new(&(), move |_obj, cancellable, send| {
555 Self::new_for_bus_impl(
556 bus_type,
557 flags,
558 &name,
559 &object_path,
560 get_proxy_type_func,
561 Some(cancellable),
562 move |res| {
563 send.resolve(res);
564 },
565 );
566 }))
567 }
568}
569
570pub trait DBusObjectManagerClientExtManual: IsA<DBusObjectManagerClient> + 'static {
571 #[doc(alias = "interface-proxy-properties-changed")]
572 fn connect_interface_proxy_properties_changed<
573 F: Fn(&Self, &DBusObjectProxy, &DBusProxy, &glib::Variant, &StrVRef) + Send + Sync + 'static,
574 >(
575 &self,
576 f: F,
577 ) -> SignalHandlerId {
578 unsafe extern "C" fn interface_proxy_properties_changed_trampoline<
579 P: IsA<DBusObjectManagerClient>,
580 F: Fn(&P, &DBusObjectProxy, &DBusProxy, &glib::Variant, &StrVRef) + Send + Sync + 'static,
581 >(
582 this: *mut ffi::GDBusObjectManagerClient,
583 object_proxy: *mut ffi::GDBusObjectProxy,
584 interface_proxy: *mut ffi::GDBusProxy,
585 changed_properties: *mut glib::ffi::GVariant,
586 invalidated_properties: *const *const std::ffi::c_char,
587 f: glib::ffi::gpointer,
588 ) {
589 unsafe {
590 let f: &F = &*(f as *const F);
591 f(
592 DBusObjectManagerClient::from_glib_borrow(this).unsafe_cast_ref(),
593 &from_glib_borrow(object_proxy),
594 &from_glib_borrow(interface_proxy),
595 &from_glib_borrow(changed_properties),
596 StrVRef::from_glib_borrow(invalidated_properties),
597 )
598 }
599 }
600 unsafe {
601 let f: Box<F> = Box::new(f);
602 connect_raw(
603 self.as_ptr() as *mut _,
604 c"interface-proxy-properties-changed".as_ptr() as *const _,
605 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
606 interface_proxy_properties_changed_trampoline::<Self, F> as *const (),
607 )),
608 Box::into_raw(f),
609 )
610 }
611 }
612}
613
614impl<O: IsA<DBusObjectManagerClient>> DBusObjectManagerClientExtManual for O {}