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