1#![allow(deprecated)]
5
6#[cfg(unix)]
7#[cfg_attr(docsrs, doc(cfg(unix)))]
8use crate::UnixFDList;
9use crate::{
10 ffi, AsyncInitable, AsyncResult, Cancellable, Credentials, DBusAuthObserver, DBusCallFlags,
11 DBusCapabilityFlags, DBusConnectionFlags, DBusMessage, DBusSendMessageFlags, IOStream,
12 Initable,
13};
14use glib::{
15 object::ObjectType as _,
16 prelude::*,
17 signal::{connect_raw, SignalHandlerId},
18 translate::*,
19};
20use std::{boxed::Box as Box_, pin::Pin};
21
22glib::wrapper! {
23 #[doc(alias = "GDBusConnection")]
24 pub struct DBusConnection(Object<ffi::GDBusConnection>) @implements AsyncInitable, Initable;
25
26 match fn {
27 type_ => || ffi::g_dbus_connection_get_type(),
28 }
29}
30
31impl DBusConnection {
32 #[doc(alias = "g_dbus_connection_new_for_address_sync")]
33 #[doc(alias = "new_for_address_sync")]
34 pub fn for_address_sync(
35 address: &str,
36 flags: DBusConnectionFlags,
37 observer: Option<&DBusAuthObserver>,
38 cancellable: Option<&impl IsA<Cancellable>>,
39 ) -> Result<DBusConnection, glib::Error> {
40 unsafe {
41 let mut error = std::ptr::null_mut();
42 let ret = ffi::g_dbus_connection_new_for_address_sync(
43 address.to_glib_none().0,
44 flags.into_glib(),
45 observer.to_glib_none().0,
46 cancellable.map(|p| p.as_ref()).to_glib_none().0,
47 &mut error,
48 );
49 if error.is_null() {
50 Ok(from_glib_full(ret))
51 } else {
52 Err(from_glib_full(error))
53 }
54 }
55 }
56
57 #[doc(alias = "g_dbus_connection_new_sync")]
58 pub fn new_sync(
59 stream: &impl IsA<IOStream>,
60 guid: Option<&str>,
61 flags: DBusConnectionFlags,
62 observer: Option<&DBusAuthObserver>,
63 cancellable: Option<&impl IsA<Cancellable>>,
64 ) -> Result<DBusConnection, glib::Error> {
65 unsafe {
66 let mut error = std::ptr::null_mut();
67 let ret = ffi::g_dbus_connection_new_sync(
68 stream.as_ref().to_glib_none().0,
69 guid.to_glib_none().0,
70 flags.into_glib(),
71 observer.to_glib_none().0,
72 cancellable.map(|p| p.as_ref()).to_glib_none().0,
73 &mut error,
74 );
75 if error.is_null() {
76 Ok(from_glib_full(ret))
77 } else {
78 Err(from_glib_full(error))
79 }
80 }
81 }
82
83 #[doc(alias = "g_dbus_connection_call")]
84 pub fn call<P: FnOnce(Result<glib::Variant, glib::Error>) + 'static>(
85 &self,
86 bus_name: Option<&str>,
87 object_path: &str,
88 interface_name: &str,
89 method_name: &str,
90 parameters: Option<&glib::Variant>,
91 reply_type: Option<&glib::VariantTy>,
92 flags: DBusCallFlags,
93 timeout_msec: i32,
94 cancellable: Option<&impl IsA<Cancellable>>,
95 callback: P,
96 ) {
97 let main_context = glib::MainContext::ref_thread_default();
98 let is_main_context_owner = main_context.is_owner();
99 let has_acquired_main_context = (!is_main_context_owner)
100 .then(|| main_context.acquire().ok())
101 .flatten();
102 assert!(
103 is_main_context_owner || has_acquired_main_context.is_some(),
104 "Async operations only allowed if the thread is owning the MainContext"
105 );
106
107 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
108 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
109 unsafe extern "C" fn call_trampoline<
110 P: FnOnce(Result<glib::Variant, glib::Error>) + 'static,
111 >(
112 _source_object: *mut glib::gobject_ffi::GObject,
113 res: *mut crate::ffi::GAsyncResult,
114 user_data: glib::ffi::gpointer,
115 ) {
116 let mut error = std::ptr::null_mut();
117 let ret = ffi::g_dbus_connection_call_finish(_source_object as *mut _, res, &mut error);
118 let result = if error.is_null() {
119 Ok(from_glib_full(ret))
120 } else {
121 Err(from_glib_full(error))
122 };
123 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
124 Box_::from_raw(user_data as *mut _);
125 let callback: P = callback.into_inner();
126 callback(result);
127 }
128 let callback = call_trampoline::<P>;
129 unsafe {
130 ffi::g_dbus_connection_call(
131 self.to_glib_none().0,
132 bus_name.to_glib_none().0,
133 object_path.to_glib_none().0,
134 interface_name.to_glib_none().0,
135 method_name.to_glib_none().0,
136 parameters.to_glib_none().0,
137 reply_type.to_glib_none().0,
138 flags.into_glib(),
139 timeout_msec,
140 cancellable.map(|p| p.as_ref()).to_glib_none().0,
141 Some(callback),
142 Box_::into_raw(user_data) as *mut _,
143 );
144 }
145 }
146
147 pub fn call_future(
148 &self,
149 bus_name: Option<&str>,
150 object_path: &str,
151 interface_name: &str,
152 method_name: &str,
153 parameters: Option<&glib::Variant>,
154 reply_type: Option<&glib::VariantTy>,
155 flags: DBusCallFlags,
156 timeout_msec: i32,
157 ) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::Variant, glib::Error>> + 'static>>
158 {
159 let bus_name = bus_name.map(ToOwned::to_owned);
160 let object_path = String::from(object_path);
161 let interface_name = String::from(interface_name);
162 let method_name = String::from(method_name);
163 let parameters = parameters.map(ToOwned::to_owned);
164 let reply_type = reply_type.map(ToOwned::to_owned);
165 Box_::pin(crate::GioFuture::new(
166 self,
167 move |obj, cancellable, send| {
168 obj.call(
169 bus_name.as_ref().map(::std::borrow::Borrow::borrow),
170 &object_path,
171 &interface_name,
172 &method_name,
173 parameters.as_ref().map(::std::borrow::Borrow::borrow),
174 reply_type.as_ref().map(::std::borrow::Borrow::borrow),
175 flags,
176 timeout_msec,
177 Some(cancellable),
178 move |res| {
179 send.resolve(res);
180 },
181 );
182 },
183 ))
184 }
185
186 #[doc(alias = "g_dbus_connection_call_sync")]
187 pub fn call_sync(
188 &self,
189 bus_name: Option<&str>,
190 object_path: &str,
191 interface_name: &str,
192 method_name: &str,
193 parameters: Option<&glib::Variant>,
194 reply_type: Option<&glib::VariantTy>,
195 flags: DBusCallFlags,
196 timeout_msec: i32,
197 cancellable: Option<&impl IsA<Cancellable>>,
198 ) -> Result<glib::Variant, glib::Error> {
199 unsafe {
200 let mut error = std::ptr::null_mut();
201 let ret = ffi::g_dbus_connection_call_sync(
202 self.to_glib_none().0,
203 bus_name.to_glib_none().0,
204 object_path.to_glib_none().0,
205 interface_name.to_glib_none().0,
206 method_name.to_glib_none().0,
207 parameters.to_glib_none().0,
208 reply_type.to_glib_none().0,
209 flags.into_glib(),
210 timeout_msec,
211 cancellable.map(|p| p.as_ref()).to_glib_none().0,
212 &mut error,
213 );
214 if error.is_null() {
215 Ok(from_glib_full(ret))
216 } else {
217 Err(from_glib_full(error))
218 }
219 }
220 }
221
222 #[cfg(unix)]
223 #[cfg_attr(docsrs, doc(cfg(unix)))]
224 #[doc(alias = "g_dbus_connection_call_with_unix_fd_list")]
225 pub fn call_with_unix_fd_list<
226 P: FnOnce(Result<(glib::Variant, Option<UnixFDList>), glib::Error>) + 'static,
227 >(
228 &self,
229 bus_name: Option<&str>,
230 object_path: &str,
231 interface_name: &str,
232 method_name: &str,
233 parameters: Option<&glib::Variant>,
234 reply_type: Option<&glib::VariantTy>,
235 flags: DBusCallFlags,
236 timeout_msec: i32,
237 fd_list: Option<&impl IsA<UnixFDList>>,
238 cancellable: Option<&impl IsA<Cancellable>>,
239 callback: P,
240 ) {
241 let main_context = glib::MainContext::ref_thread_default();
242 let is_main_context_owner = main_context.is_owner();
243 let has_acquired_main_context = (!is_main_context_owner)
244 .then(|| main_context.acquire().ok())
245 .flatten();
246 assert!(
247 is_main_context_owner || has_acquired_main_context.is_some(),
248 "Async operations only allowed if the thread is owning the MainContext"
249 );
250
251 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
252 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
253 unsafe extern "C" fn call_with_unix_fd_list_trampoline<
254 P: FnOnce(Result<(glib::Variant, Option<UnixFDList>), glib::Error>) + 'static,
255 >(
256 _source_object: *mut glib::gobject_ffi::GObject,
257 res: *mut crate::ffi::GAsyncResult,
258 user_data: glib::ffi::gpointer,
259 ) {
260 let mut error = std::ptr::null_mut();
261 let mut out_fd_list = std::ptr::null_mut();
262 let ret = ffi::g_dbus_connection_call_with_unix_fd_list_finish(
263 _source_object as *mut _,
264 &mut out_fd_list,
265 res,
266 &mut error,
267 );
268 let result = if error.is_null() {
269 Ok((from_glib_full(ret), from_glib_full(out_fd_list)))
270 } else {
271 Err(from_glib_full(error))
272 };
273 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
274 Box_::from_raw(user_data as *mut _);
275 let callback: P = callback.into_inner();
276 callback(result);
277 }
278 let callback = call_with_unix_fd_list_trampoline::<P>;
279 unsafe {
280 ffi::g_dbus_connection_call_with_unix_fd_list(
281 self.to_glib_none().0,
282 bus_name.to_glib_none().0,
283 object_path.to_glib_none().0,
284 interface_name.to_glib_none().0,
285 method_name.to_glib_none().0,
286 parameters.to_glib_none().0,
287 reply_type.to_glib_none().0,
288 flags.into_glib(),
289 timeout_msec,
290 fd_list.map(|p| p.as_ref()).to_glib_none().0,
291 cancellable.map(|p| p.as_ref()).to_glib_none().0,
292 Some(callback),
293 Box_::into_raw(user_data) as *mut _,
294 );
295 }
296 }
297
298 #[cfg(unix)]
299 #[cfg_attr(docsrs, doc(cfg(unix)))]
300 pub fn call_with_unix_fd_list_future(
301 &self,
302 bus_name: Option<&str>,
303 object_path: &str,
304 interface_name: &str,
305 method_name: &str,
306 parameters: Option<&glib::Variant>,
307 reply_type: Option<&glib::VariantTy>,
308 flags: DBusCallFlags,
309 timeout_msec: i32,
310 fd_list: Option<&(impl IsA<UnixFDList> + Clone + 'static)>,
311 ) -> Pin<
312 Box_<
313 dyn std::future::Future<
314 Output = Result<(glib::Variant, Option<UnixFDList>), glib::Error>,
315 > + 'static,
316 >,
317 > {
318 let bus_name = bus_name.map(ToOwned::to_owned);
319 let object_path = String::from(object_path);
320 let interface_name = String::from(interface_name);
321 let method_name = String::from(method_name);
322 let parameters = parameters.map(ToOwned::to_owned);
323 let reply_type = reply_type.map(ToOwned::to_owned);
324 let fd_list = fd_list.map(ToOwned::to_owned);
325 Box_::pin(crate::GioFuture::new(
326 self,
327 move |obj, cancellable, send| {
328 obj.call_with_unix_fd_list(
329 bus_name.as_ref().map(::std::borrow::Borrow::borrow),
330 &object_path,
331 &interface_name,
332 &method_name,
333 parameters.as_ref().map(::std::borrow::Borrow::borrow),
334 reply_type.as_ref().map(::std::borrow::Borrow::borrow),
335 flags,
336 timeout_msec,
337 fd_list.as_ref().map(::std::borrow::Borrow::borrow),
338 Some(cancellable),
339 move |res| {
340 send.resolve(res);
341 },
342 );
343 },
344 ))
345 }
346
347 #[cfg(unix)]
348 #[cfg_attr(docsrs, doc(cfg(unix)))]
349 #[doc(alias = "g_dbus_connection_call_with_unix_fd_list_sync")]
350 pub fn call_with_unix_fd_list_sync(
351 &self,
352 bus_name: Option<&str>,
353 object_path: &str,
354 interface_name: &str,
355 method_name: &str,
356 parameters: Option<&glib::Variant>,
357 reply_type: Option<&glib::VariantTy>,
358 flags: DBusCallFlags,
359 timeout_msec: i32,
360 fd_list: Option<&impl IsA<UnixFDList>>,
361 cancellable: Option<&impl IsA<Cancellable>>,
362 ) -> Result<(glib::Variant, Option<UnixFDList>), glib::Error> {
363 unsafe {
364 let mut out_fd_list = std::ptr::null_mut();
365 let mut error = std::ptr::null_mut();
366 let ret = ffi::g_dbus_connection_call_with_unix_fd_list_sync(
367 self.to_glib_none().0,
368 bus_name.to_glib_none().0,
369 object_path.to_glib_none().0,
370 interface_name.to_glib_none().0,
371 method_name.to_glib_none().0,
372 parameters.to_glib_none().0,
373 reply_type.to_glib_none().0,
374 flags.into_glib(),
375 timeout_msec,
376 fd_list.map(|p| p.as_ref()).to_glib_none().0,
377 &mut out_fd_list,
378 cancellable.map(|p| p.as_ref()).to_glib_none().0,
379 &mut error,
380 );
381 if error.is_null() {
382 Ok((from_glib_full(ret), from_glib_full(out_fd_list)))
383 } else {
384 Err(from_glib_full(error))
385 }
386 }
387 }
388
389 #[doc(alias = "g_dbus_connection_close")]
390 pub fn close<P: FnOnce(Result<(), glib::Error>) + 'static>(
391 &self,
392 cancellable: Option<&impl IsA<Cancellable>>,
393 callback: P,
394 ) {
395 let main_context = glib::MainContext::ref_thread_default();
396 let is_main_context_owner = main_context.is_owner();
397 let has_acquired_main_context = (!is_main_context_owner)
398 .then(|| main_context.acquire().ok())
399 .flatten();
400 assert!(
401 is_main_context_owner || has_acquired_main_context.is_some(),
402 "Async operations only allowed if the thread is owning the MainContext"
403 );
404
405 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
406 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
407 unsafe extern "C" fn close_trampoline<P: FnOnce(Result<(), glib::Error>) + 'static>(
408 _source_object: *mut glib::gobject_ffi::GObject,
409 res: *mut crate::ffi::GAsyncResult,
410 user_data: glib::ffi::gpointer,
411 ) {
412 let mut error = std::ptr::null_mut();
413 ffi::g_dbus_connection_close_finish(_source_object as *mut _, res, &mut error);
414 let result = if error.is_null() {
415 Ok(())
416 } else {
417 Err(from_glib_full(error))
418 };
419 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
420 Box_::from_raw(user_data as *mut _);
421 let callback: P = callback.into_inner();
422 callback(result);
423 }
424 let callback = close_trampoline::<P>;
425 unsafe {
426 ffi::g_dbus_connection_close(
427 self.to_glib_none().0,
428 cancellable.map(|p| p.as_ref()).to_glib_none().0,
429 Some(callback),
430 Box_::into_raw(user_data) as *mut _,
431 );
432 }
433 }
434
435 pub fn close_future(
436 &self,
437 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
438 Box_::pin(crate::GioFuture::new(
439 self,
440 move |obj, cancellable, send| {
441 obj.close(Some(cancellable), move |res| {
442 send.resolve(res);
443 });
444 },
445 ))
446 }
447
448 #[doc(alias = "g_dbus_connection_close_sync")]
449 pub fn close_sync(
450 &self,
451 cancellable: Option<&impl IsA<Cancellable>>,
452 ) -> Result<(), glib::Error> {
453 unsafe {
454 let mut error = std::ptr::null_mut();
455 let is_ok = ffi::g_dbus_connection_close_sync(
456 self.to_glib_none().0,
457 cancellable.map(|p| p.as_ref()).to_glib_none().0,
458 &mut error,
459 );
460 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
461 if error.is_null() {
462 Ok(())
463 } else {
464 Err(from_glib_full(error))
465 }
466 }
467 }
468
469 #[doc(alias = "g_dbus_connection_emit_signal")]
470 pub fn emit_signal(
471 &self,
472 destination_bus_name: Option<&str>,
473 object_path: &str,
474 interface_name: &str,
475 signal_name: &str,
476 parameters: Option<&glib::Variant>,
477 ) -> Result<(), glib::Error> {
478 unsafe {
479 let mut error = std::ptr::null_mut();
480 let is_ok = ffi::g_dbus_connection_emit_signal(
481 self.to_glib_none().0,
482 destination_bus_name.to_glib_none().0,
483 object_path.to_glib_none().0,
484 interface_name.to_glib_none().0,
485 signal_name.to_glib_none().0,
486 parameters.to_glib_none().0,
487 &mut error,
488 );
489 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
490 if error.is_null() {
491 Ok(())
492 } else {
493 Err(from_glib_full(error))
494 }
495 }
496 }
497
498 #[doc(alias = "g_dbus_connection_flush")]
499 pub fn flush<P: FnOnce(Result<(), glib::Error>) + 'static>(
500 &self,
501 cancellable: Option<&impl IsA<Cancellable>>,
502 callback: P,
503 ) {
504 let main_context = glib::MainContext::ref_thread_default();
505 let is_main_context_owner = main_context.is_owner();
506 let has_acquired_main_context = (!is_main_context_owner)
507 .then(|| main_context.acquire().ok())
508 .flatten();
509 assert!(
510 is_main_context_owner || has_acquired_main_context.is_some(),
511 "Async operations only allowed if the thread is owning the MainContext"
512 );
513
514 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
515 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
516 unsafe extern "C" fn flush_trampoline<P: FnOnce(Result<(), glib::Error>) + 'static>(
517 _source_object: *mut glib::gobject_ffi::GObject,
518 res: *mut crate::ffi::GAsyncResult,
519 user_data: glib::ffi::gpointer,
520 ) {
521 let mut error = std::ptr::null_mut();
522 ffi::g_dbus_connection_flush_finish(_source_object as *mut _, res, &mut error);
523 let result = if error.is_null() {
524 Ok(())
525 } else {
526 Err(from_glib_full(error))
527 };
528 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
529 Box_::from_raw(user_data as *mut _);
530 let callback: P = callback.into_inner();
531 callback(result);
532 }
533 let callback = flush_trampoline::<P>;
534 unsafe {
535 ffi::g_dbus_connection_flush(
536 self.to_glib_none().0,
537 cancellable.map(|p| p.as_ref()).to_glib_none().0,
538 Some(callback),
539 Box_::into_raw(user_data) as *mut _,
540 );
541 }
542 }
543
544 pub fn flush_future(
545 &self,
546 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
547 Box_::pin(crate::GioFuture::new(
548 self,
549 move |obj, cancellable, send| {
550 obj.flush(Some(cancellable), move |res| {
551 send.resolve(res);
552 });
553 },
554 ))
555 }
556
557 #[doc(alias = "g_dbus_connection_flush_sync")]
558 pub fn flush_sync(
559 &self,
560 cancellable: Option<&impl IsA<Cancellable>>,
561 ) -> Result<(), glib::Error> {
562 unsafe {
563 let mut error = std::ptr::null_mut();
564 let is_ok = ffi::g_dbus_connection_flush_sync(
565 self.to_glib_none().0,
566 cancellable.map(|p| p.as_ref()).to_glib_none().0,
567 &mut error,
568 );
569 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
570 if error.is_null() {
571 Ok(())
572 } else {
573 Err(from_glib_full(error))
574 }
575 }
576 }
577
578 #[doc(alias = "g_dbus_connection_get_capabilities")]
579 #[doc(alias = "get_capabilities")]
580 pub fn capabilities(&self) -> DBusCapabilityFlags {
581 unsafe {
582 from_glib(ffi::g_dbus_connection_get_capabilities(
583 self.to_glib_none().0,
584 ))
585 }
586 }
587
588 #[doc(alias = "g_dbus_connection_get_exit_on_close")]
589 #[doc(alias = "get_exit_on_close")]
590 #[doc(alias = "exit-on-close")]
591 pub fn exits_on_close(&self) -> bool {
592 unsafe {
593 from_glib(ffi::g_dbus_connection_get_exit_on_close(
594 self.to_glib_none().0,
595 ))
596 }
597 }
598
599 #[cfg(feature = "v2_60")]
600 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
601 #[doc(alias = "g_dbus_connection_get_flags")]
602 #[doc(alias = "get_flags")]
603 pub fn flags(&self) -> DBusConnectionFlags {
604 unsafe { from_glib(ffi::g_dbus_connection_get_flags(self.to_glib_none().0)) }
605 }
606
607 #[doc(alias = "g_dbus_connection_get_guid")]
608 #[doc(alias = "get_guid")]
609 pub fn guid(&self) -> glib::GString {
610 unsafe { from_glib_none(ffi::g_dbus_connection_get_guid(self.to_glib_none().0)) }
611 }
612
613 #[doc(alias = "g_dbus_connection_get_last_serial")]
614 #[doc(alias = "get_last_serial")]
615 pub fn last_serial(&self) -> u32 {
616 unsafe { ffi::g_dbus_connection_get_last_serial(self.to_glib_none().0) }
617 }
618
619 #[doc(alias = "g_dbus_connection_get_peer_credentials")]
620 #[doc(alias = "get_peer_credentials")]
621 pub fn peer_credentials(&self) -> Option<Credentials> {
622 unsafe {
623 from_glib_none(ffi::g_dbus_connection_get_peer_credentials(
624 self.to_glib_none().0,
625 ))
626 }
627 }
628
629 #[doc(alias = "g_dbus_connection_get_stream")]
630 #[doc(alias = "get_stream")]
631 pub fn stream(&self) -> IOStream {
632 unsafe { from_glib_none(ffi::g_dbus_connection_get_stream(self.to_glib_none().0)) }
633 }
634
635 #[doc(alias = "g_dbus_connection_get_unique_name")]
636 #[doc(alias = "get_unique_name")]
637 #[doc(alias = "unique-name")]
638 pub fn unique_name(&self) -> Option<glib::GString> {
639 unsafe {
640 from_glib_none(ffi::g_dbus_connection_get_unique_name(
641 self.to_glib_none().0,
642 ))
643 }
644 }
645
646 #[doc(alias = "g_dbus_connection_is_closed")]
647 #[doc(alias = "closed")]
648 pub fn is_closed(&self) -> bool {
649 unsafe { from_glib(ffi::g_dbus_connection_is_closed(self.to_glib_none().0)) }
650 }
651
652 #[doc(alias = "g_dbus_connection_send_message")]
653 pub fn send_message(
654 &self,
655 message: &DBusMessage,
656 flags: DBusSendMessageFlags,
657 ) -> Result<u32, glib::Error> {
658 unsafe {
659 let mut out_serial = std::mem::MaybeUninit::uninit();
660 let mut error = std::ptr::null_mut();
661 let is_ok = ffi::g_dbus_connection_send_message(
662 self.to_glib_none().0,
663 message.to_glib_none().0,
664 flags.into_glib(),
665 out_serial.as_mut_ptr(),
666 &mut error,
667 );
668 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
669 if error.is_null() {
670 Ok(out_serial.assume_init())
671 } else {
672 Err(from_glib_full(error))
673 }
674 }
675 }
676
677 #[doc(alias = "g_dbus_connection_send_message_with_reply")]
678 pub fn send_message_with_reply<P: FnOnce(Result<DBusMessage, glib::Error>) + 'static>(
679 &self,
680 message: &DBusMessage,
681 flags: DBusSendMessageFlags,
682 timeout_msec: i32,
683 cancellable: Option<&impl IsA<Cancellable>>,
684 callback: P,
685 ) -> u32 {
686 let main_context = glib::MainContext::ref_thread_default();
687 let is_main_context_owner = main_context.is_owner();
688 let has_acquired_main_context = (!is_main_context_owner)
689 .then(|| main_context.acquire().ok())
690 .flatten();
691 assert!(
692 is_main_context_owner || has_acquired_main_context.is_some(),
693 "Async operations only allowed if the thread is owning the MainContext"
694 );
695
696 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
697 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
698 unsafe extern "C" fn send_message_with_reply_trampoline<
699 P: FnOnce(Result<DBusMessage, glib::Error>) + 'static,
700 >(
701 _source_object: *mut glib::gobject_ffi::GObject,
702 res: *mut crate::ffi::GAsyncResult,
703 user_data: glib::ffi::gpointer,
704 ) {
705 let mut error = std::ptr::null_mut();
706 let ret = ffi::g_dbus_connection_send_message_with_reply_finish(
707 _source_object as *mut _,
708 res,
709 &mut error,
710 );
711 let result = if error.is_null() {
712 Ok(from_glib_full(ret))
713 } else {
714 Err(from_glib_full(error))
715 };
716 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
717 Box_::from_raw(user_data as *mut _);
718 let callback: P = callback.into_inner();
719 callback(result);
720 }
721 let callback = send_message_with_reply_trampoline::<P>;
722 unsafe {
723 let mut out_serial = std::mem::MaybeUninit::uninit();
724 ffi::g_dbus_connection_send_message_with_reply(
725 self.to_glib_none().0,
726 message.to_glib_none().0,
727 flags.into_glib(),
728 timeout_msec,
729 out_serial.as_mut_ptr(),
730 cancellable.map(|p| p.as_ref()).to_glib_none().0,
731 Some(callback),
732 Box_::into_raw(user_data) as *mut _,
733 );
734 out_serial.assume_init()
735 }
736 }
737
738 pub fn send_message_with_reply_future(
739 &self,
740 message: &DBusMessage,
741 flags: DBusSendMessageFlags,
742 timeout_msec: i32,
743 ) -> Pin<Box_<dyn std::future::Future<Output = Result<DBusMessage, glib::Error>> + 'static>>
744 {
745 let message = message.clone();
746 Box_::pin(crate::GioFuture::new(
747 self,
748 move |obj, cancellable, send| {
749 obj.send_message_with_reply(
750 &message,
751 flags,
752 timeout_msec,
753 Some(cancellable),
754 move |res| {
755 send.resolve(res);
756 },
757 );
758 },
759 ))
760 }
761
762 #[doc(alias = "g_dbus_connection_send_message_with_reply_sync")]
763 pub fn send_message_with_reply_sync(
764 &self,
765 message: &DBusMessage,
766 flags: DBusSendMessageFlags,
767 timeout_msec: i32,
768 cancellable: Option<&impl IsA<Cancellable>>,
769 ) -> Result<(DBusMessage, u32), glib::Error> {
770 unsafe {
771 let mut out_serial = std::mem::MaybeUninit::uninit();
772 let mut error = std::ptr::null_mut();
773 let ret = ffi::g_dbus_connection_send_message_with_reply_sync(
774 self.to_glib_none().0,
775 message.to_glib_none().0,
776 flags.into_glib(),
777 timeout_msec,
778 out_serial.as_mut_ptr(),
779 cancellable.map(|p| p.as_ref()).to_glib_none().0,
780 &mut error,
781 );
782 if error.is_null() {
783 Ok((from_glib_full(ret), out_serial.assume_init()))
784 } else {
785 Err(from_glib_full(error))
786 }
787 }
788 }
789
790 #[doc(alias = "g_dbus_connection_set_exit_on_close")]
791 #[doc(alias = "exit-on-close")]
792 pub fn set_exit_on_close(&self, exit_on_close: bool) {
793 unsafe {
794 ffi::g_dbus_connection_set_exit_on_close(
795 self.to_glib_none().0,
796 exit_on_close.into_glib(),
797 );
798 }
799 }
800
801 #[doc(alias = "g_dbus_connection_start_message_processing")]
802 pub fn start_message_processing(&self) {
803 unsafe {
804 ffi::g_dbus_connection_start_message_processing(self.to_glib_none().0);
805 }
806 }
807
808 #[cfg(not(feature = "v2_60"))]
809 #[cfg_attr(docsrs, doc(cfg(not(feature = "v2_60"))))]
810 pub fn flags(&self) -> DBusConnectionFlags {
811 ObjectExt::property(self, "flags")
812 }
813
814 #[doc(alias = "g_dbus_connection_new")]
815 pub fn new<P: FnOnce(Result<DBusConnection, glib::Error>) + 'static>(
816 stream: &impl IsA<IOStream>,
817 guid: Option<&str>,
818 flags: DBusConnectionFlags,
819 observer: Option<&DBusAuthObserver>,
820 cancellable: Option<&impl IsA<Cancellable>>,
821 callback: P,
822 ) {
823 let main_context = glib::MainContext::ref_thread_default();
824 let is_main_context_owner = main_context.is_owner();
825 let has_acquired_main_context = (!is_main_context_owner)
826 .then(|| main_context.acquire().ok())
827 .flatten();
828 assert!(
829 is_main_context_owner || has_acquired_main_context.is_some(),
830 "Async operations only allowed if the thread is owning the MainContext"
831 );
832
833 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
834 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
835 unsafe extern "C" fn new_trampoline<
836 P: FnOnce(Result<DBusConnection, glib::Error>) + 'static,
837 >(
838 _source_object: *mut glib::gobject_ffi::GObject,
839 res: *mut crate::ffi::GAsyncResult,
840 user_data: glib::ffi::gpointer,
841 ) {
842 let mut error = std::ptr::null_mut();
843 let ret = ffi::g_dbus_connection_new_finish(res, &mut error);
844 let result = if error.is_null() {
845 Ok(from_glib_full(ret))
846 } else {
847 Err(from_glib_full(error))
848 };
849 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
850 Box_::from_raw(user_data as *mut _);
851 let callback: P = callback.into_inner();
852 callback(result);
853 }
854 let callback = new_trampoline::<P>;
855 unsafe {
856 ffi::g_dbus_connection_new(
857 stream.as_ref().to_glib_none().0,
858 guid.to_glib_none().0,
859 flags.into_glib(),
860 observer.to_glib_none().0,
861 cancellable.map(|p| p.as_ref()).to_glib_none().0,
862 Some(callback),
863 Box_::into_raw(user_data) as *mut _,
864 );
865 }
866 }
867
868 pub fn new_future(
869 stream: &(impl IsA<IOStream> + Clone + 'static),
870 guid: Option<&str>,
871 flags: DBusConnectionFlags,
872 observer: Option<&DBusAuthObserver>,
873 ) -> Pin<Box_<dyn std::future::Future<Output = Result<DBusConnection, glib::Error>> + 'static>>
874 {
875 let stream = stream.clone();
876 let guid = guid.map(ToOwned::to_owned);
877 let observer = observer.map(ToOwned::to_owned);
878 Box_::pin(crate::GioFuture::new(
879 &(),
880 move |_obj, cancellable, send| {
881 Self::new(
882 &stream,
883 guid.as_ref().map(::std::borrow::Borrow::borrow),
884 flags,
885 observer.as_ref().map(::std::borrow::Borrow::borrow),
886 Some(cancellable),
887 move |res| {
888 send.resolve(res);
889 },
890 );
891 },
892 ))
893 }
894
895 #[doc(alias = "g_dbus_connection_new_for_address")]
896 #[doc(alias = "new_for_address")]
897 pub fn for_address<P: FnOnce(Result<DBusConnection, glib::Error>) + 'static>(
898 address: &str,
899 flags: DBusConnectionFlags,
900 observer: Option<&DBusAuthObserver>,
901 cancellable: Option<&impl IsA<Cancellable>>,
902 callback: P,
903 ) {
904 let main_context = glib::MainContext::ref_thread_default();
905 let is_main_context_owner = main_context.is_owner();
906 let has_acquired_main_context = (!is_main_context_owner)
907 .then(|| main_context.acquire().ok())
908 .flatten();
909 assert!(
910 is_main_context_owner || has_acquired_main_context.is_some(),
911 "Async operations only allowed if the thread is owning the MainContext"
912 );
913
914 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
915 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
916 unsafe extern "C" fn for_address_trampoline<
917 P: FnOnce(Result<DBusConnection, glib::Error>) + 'static,
918 >(
919 _source_object: *mut glib::gobject_ffi::GObject,
920 res: *mut crate::ffi::GAsyncResult,
921 user_data: glib::ffi::gpointer,
922 ) {
923 let mut error = std::ptr::null_mut();
924 let ret = ffi::g_dbus_connection_new_for_address_finish(res, &mut error);
925 let result = if error.is_null() {
926 Ok(from_glib_full(ret))
927 } else {
928 Err(from_glib_full(error))
929 };
930 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
931 Box_::from_raw(user_data as *mut _);
932 let callback: P = callback.into_inner();
933 callback(result);
934 }
935 let callback = for_address_trampoline::<P>;
936 unsafe {
937 ffi::g_dbus_connection_new_for_address(
938 address.to_glib_none().0,
939 flags.into_glib(),
940 observer.to_glib_none().0,
941 cancellable.map(|p| p.as_ref()).to_glib_none().0,
942 Some(callback),
943 Box_::into_raw(user_data) as *mut _,
944 );
945 }
946 }
947
948 pub fn for_address_future(
949 address: &str,
950 flags: DBusConnectionFlags,
951 observer: Option<&DBusAuthObserver>,
952 ) -> Pin<Box_<dyn std::future::Future<Output = Result<DBusConnection, glib::Error>> + 'static>>
953 {
954 let address = String::from(address);
955 let observer = observer.map(ToOwned::to_owned);
956 Box_::pin(crate::GioFuture::new(
957 &(),
958 move |_obj, cancellable, send| {
959 Self::for_address(
960 &address,
961 flags,
962 observer.as_ref().map(::std::borrow::Borrow::borrow),
963 Some(cancellable),
964 move |res| {
965 send.resolve(res);
966 },
967 );
968 },
969 ))
970 }
971
972 #[doc(alias = "closed")]
973 pub fn connect_closed<F: Fn(&Self, bool, Option<&glib::Error>) + Send + Sync + 'static>(
974 &self,
975 f: F,
976 ) -> SignalHandlerId {
977 unsafe extern "C" fn closed_trampoline<
978 F: Fn(&DBusConnection, bool, Option<&glib::Error>) + Send + Sync + 'static,
979 >(
980 this: *mut ffi::GDBusConnection,
981 remote_peer_vanished: glib::ffi::gboolean,
982 error: *mut glib::ffi::GError,
983 f: glib::ffi::gpointer,
984 ) {
985 let f: &F = &*(f as *const F);
986 f(
987 &from_glib_borrow(this),
988 from_glib(remote_peer_vanished),
989 Option::<glib::Error>::from_glib_borrow(error)
990 .as_ref()
991 .as_ref(),
992 )
993 }
994 unsafe {
995 let f: Box_<F> = Box_::new(f);
996 connect_raw(
997 self.as_ptr() as *mut _,
998 c"closed".as_ptr() as *const _,
999 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1000 closed_trampoline::<F> as *const (),
1001 )),
1002 Box_::into_raw(f),
1003 )
1004 }
1005 }
1006
1007 #[doc(alias = "capabilities")]
1008 pub fn connect_capabilities_notify<F: Fn(&Self) + Send + Sync + 'static>(
1009 &self,
1010 f: F,
1011 ) -> SignalHandlerId {
1012 unsafe extern "C" fn notify_capabilities_trampoline<
1013 F: Fn(&DBusConnection) + Send + Sync + 'static,
1014 >(
1015 this: *mut ffi::GDBusConnection,
1016 _param_spec: glib::ffi::gpointer,
1017 f: glib::ffi::gpointer,
1018 ) {
1019 let f: &F = &*(f as *const F);
1020 f(&from_glib_borrow(this))
1021 }
1022 unsafe {
1023 let f: Box_<F> = Box_::new(f);
1024 connect_raw(
1025 self.as_ptr() as *mut _,
1026 c"notify::capabilities".as_ptr() as *const _,
1027 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1028 notify_capabilities_trampoline::<F> as *const (),
1029 )),
1030 Box_::into_raw(f),
1031 )
1032 }
1033 }
1034
1035 #[doc(alias = "closed")]
1036 pub fn connect_closed_notify<F: Fn(&Self) + Send + Sync + 'static>(
1037 &self,
1038 f: F,
1039 ) -> SignalHandlerId {
1040 unsafe extern "C" fn notify_closed_trampoline<
1041 F: Fn(&DBusConnection) + Send + Sync + 'static,
1042 >(
1043 this: *mut ffi::GDBusConnection,
1044 _param_spec: glib::ffi::gpointer,
1045 f: glib::ffi::gpointer,
1046 ) {
1047 let f: &F = &*(f as *const F);
1048 f(&from_glib_borrow(this))
1049 }
1050 unsafe {
1051 let f: Box_<F> = Box_::new(f);
1052 connect_raw(
1053 self.as_ptr() as *mut _,
1054 c"notify::closed".as_ptr() as *const _,
1055 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1056 notify_closed_trampoline::<F> as *const (),
1057 )),
1058 Box_::into_raw(f),
1059 )
1060 }
1061 }
1062
1063 #[doc(alias = "exit-on-close")]
1064 pub fn connect_exit_on_close_notify<F: Fn(&Self) + Send + Sync + 'static>(
1065 &self,
1066 f: F,
1067 ) -> SignalHandlerId {
1068 unsafe extern "C" fn notify_exit_on_close_trampoline<
1069 F: Fn(&DBusConnection) + Send + Sync + 'static,
1070 >(
1071 this: *mut ffi::GDBusConnection,
1072 _param_spec: glib::ffi::gpointer,
1073 f: glib::ffi::gpointer,
1074 ) {
1075 let f: &F = &*(f as *const F);
1076 f(&from_glib_borrow(this))
1077 }
1078 unsafe {
1079 let f: Box_<F> = Box_::new(f);
1080 connect_raw(
1081 self.as_ptr() as *mut _,
1082 c"notify::exit-on-close".as_ptr() as *const _,
1083 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1084 notify_exit_on_close_trampoline::<F> as *const (),
1085 )),
1086 Box_::into_raw(f),
1087 )
1088 }
1089 }
1090
1091 #[doc(alias = "unique-name")]
1092 pub fn connect_unique_name_notify<F: Fn(&Self) + Send + Sync + 'static>(
1093 &self,
1094 f: F,
1095 ) -> SignalHandlerId {
1096 unsafe extern "C" fn notify_unique_name_trampoline<
1097 F: Fn(&DBusConnection) + Send + Sync + 'static,
1098 >(
1099 this: *mut ffi::GDBusConnection,
1100 _param_spec: glib::ffi::gpointer,
1101 f: glib::ffi::gpointer,
1102 ) {
1103 let f: &F = &*(f as *const F);
1104 f(&from_glib_borrow(this))
1105 }
1106 unsafe {
1107 let f: Box_<F> = Box_::new(f);
1108 connect_raw(
1109 self.as_ptr() as *mut _,
1110 c"notify::unique-name".as_ptr() as *const _,
1111 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1112 notify_unique_name_trampoline::<F> as *const (),
1113 )),
1114 Box_::into_raw(f),
1115 )
1116 }
1117 }
1118}
1119
1120unsafe impl Send for DBusConnection {}
1121unsafe impl Sync for DBusConnection {}