gio/auto/
dbus_connection.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5#[cfg(unix)]
6#[cfg_attr(docsrs, doc(cfg(unix)))]
7use crate::UnixFDList;
8use crate::{
9    ffi, AsyncInitable, AsyncResult, Cancellable, Credentials, DBusAuthObserver, DBusCallFlags,
10    DBusCapabilityFlags, DBusConnectionFlags, DBusMessage, DBusSendMessageFlags, IOStream,
11    Initable,
12};
13use glib::{
14    object::ObjectType as _,
15    prelude::*,
16    signal::{connect_raw, SignalHandlerId},
17    translate::*,
18};
19use std::{boxed::Box as Box_, pin::Pin};
20
21glib::wrapper! {
22    /// The `GDBusConnection` type is used for D-Bus connections to remote
23    /// peers such as a message buses.
24    ///
25    /// It is a low-level API that offers a lot of flexibility. For instance,
26    /// it lets you establish a connection over any transport that can by represented
27    /// as a [`IOStream`][crate::IOStream].
28    ///
29    /// This class is rarely used directly in D-Bus clients. If you are writing
30    /// a D-Bus client, it is often easier to use the `bus_own_name()`,
31    /// `bus_watch_name()` or [`DBusProxy::for_bus()`][crate::DBusProxy::for_bus()] APIs.
32    ///
33    /// As an exception to the usual GLib rule that a particular object must not
34    /// be used by two threads at the same time, `GDBusConnection`s methods may be
35    /// called from any thread. This is so that [`bus_get()`][crate::bus_get()] and
36    /// [`bus_get_sync()`][crate::bus_get_sync()] can safely return the same `GDBusConnection` when
37    /// called from any thread.
38    ///
39    /// Most of the ways to obtain a `GDBusConnection` automatically initialize it
40    /// (i.e. connect to D-Bus): for instance, [`new()`][Self::new()] and
41    /// [`bus_get()`][crate::bus_get()], and the synchronous versions of those methods, give you
42    /// an initialized connection. Language bindings for GIO should use
43    /// [`Initable::new()`][crate::Initable::new()] or [`AsyncInitable::new_async()`][crate::AsyncInitable::new_async()], which also
44    /// initialize the connection.
45    ///
46    /// If you construct an uninitialized `GDBusConnection`, such as via
47    /// [`glib::Object::new()`][crate::glib::Object::new()], you must initialize it via [`InitableExt::init()`][crate::prelude::InitableExt::init()] or
48    /// [`AsyncInitableExt::init_async()`][crate::prelude::AsyncInitableExt::init_async()] before using its methods or properties.
49    /// Calling methods or accessing properties on a `GDBusConnection` that has not
50    /// completed initialization successfully is considered to be invalid, and leads
51    /// to undefined behaviour. In particular, if initialization fails with a
52    /// `GError`, the only valid thing you can do with that `GDBusConnection` is to
53    /// free it with `GObject::Object::unref()`.
54    ///
55    /// ## An example D-Bus server
56    ///
57    /// Here is an example for a D-Bus server:
58    /// [gdbus-example-server.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-server.c)
59    ///
60    /// ## An example for exporting a subtree
61    ///
62    /// Here is an example for exporting a subtree:
63    /// [gdbus-example-subtree.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-subtree.c)
64    ///
65    /// ## An example for file descriptor passing
66    ///
67    /// Here is an example for passing UNIX file descriptors:
68    /// [gdbus-unix-fd-client.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-unix-fd-client.c)
69    ///
70    /// ## An example for exporting a GObject
71    ///
72    /// Here is an example for exporting a #GObject:
73    /// [gdbus-example-export.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-export.c)
74    ///
75    /// ## Properties
76    ///
77    ///
78    /// #### `address`
79    ///  A D-Bus address specifying potential endpoints that can be used
80    /// when establishing the connection.
81    ///
82    /// Writeable | Construct Only
83    ///
84    ///
85    /// #### `authentication-observer`
86    ///  A #GDBusAuthObserver object to assist in the authentication process or [`None`].
87    ///
88    /// Writeable | Construct Only
89    ///
90    ///
91    /// #### `capabilities`
92    ///  Flags from the #GDBusCapabilityFlags enumeration
93    /// representing connection features negotiated with the other peer.
94    ///
95    /// Readable
96    ///
97    ///
98    /// #### `closed`
99    ///  A boolean specifying whether the connection has been closed.
100    ///
101    /// Readable
102    ///
103    ///
104    /// #### `exit-on-close`
105    ///  A boolean specifying whether the process will be terminated (by
106    /// calling `raise(SIGTERM)`) if the connection is closed by the
107    /// remote peer.
108    ///
109    /// Note that #GDBusConnection objects returned by g_bus_get_finish()
110    /// and g_bus_get_sync() will (usually) have this property set to [`true`].
111    ///
112    /// Readable | Writeable
113    ///
114    ///
115    /// #### `flags`
116    ///  Flags from the #GDBusConnectionFlags enumeration.
117    ///
118    /// Readable | Writeable | Construct Only
119    ///
120    ///
121    /// #### `guid`
122    ///  The GUID of the peer performing the role of server when
123    /// authenticating.
124    ///
125    /// If you are constructing a #GDBusConnection and pass
126    /// [`DBusConnectionFlags::AUTHENTICATION_SERVER`][crate::DBusConnectionFlags::AUTHENTICATION_SERVER] in the
127    /// #GDBusConnection:flags property then you **must** also set this
128    /// property to a valid guid.
129    ///
130    /// If you are constructing a #GDBusConnection and pass
131    /// [`DBusConnectionFlags::AUTHENTICATION_CLIENT`][crate::DBusConnectionFlags::AUTHENTICATION_CLIENT] in the
132    /// #GDBusConnection:flags property you will be able to read the GUID
133    /// of the other peer here after the connection has been successfully
134    /// initialized.
135    ///
136    /// Note that the
137    /// [D-Bus specification](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses)
138    /// uses the term ‘UUID’ to refer to this, whereas GLib consistently uses the
139    /// term ‘GUID’ for historical reasons.
140    ///
141    /// Despite its name, the format of #GDBusConnection:guid does not follow
142    /// [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122) or the Microsoft
143    /// GUID format.
144    ///
145    /// Readable | Writeable | Construct Only
146    ///
147    ///
148    /// #### `stream`
149    ///  The underlying #GIOStream used for I/O.
150    ///
151    /// If this is passed on construction and is a #GSocketConnection,
152    /// then the corresponding #GSocket will be put into non-blocking mode.
153    ///
154    /// While the #GDBusConnection is active, it will interact with this
155    /// stream from a worker thread, so it is not safe to interact with
156    /// the stream directly.
157    ///
158    /// Readable | Writeable | Construct Only
159    ///
160    ///
161    /// #### `unique-name`
162    ///  The unique name as assigned by the message bus or [`None`] if the
163    /// connection is not open or not a message bus connection.
164    ///
165    /// Readable
166    ///
167    /// ## Signals
168    ///
169    ///
170    /// #### `closed`
171    ///  Emitted when the connection is closed.
172    ///
173    /// The cause of this event can be
174    ///
175    /// - If g_dbus_connection_close() is called. In this case
176    ///   @remote_peer_vanished is set to [`false`] and @error is [`None`].
177    ///
178    /// - If the remote peer closes the connection. In this case
179    ///   @remote_peer_vanished is set to [`true`] and @error is set.
180    ///
181    /// - If the remote peer sends invalid or malformed data. In this
182    ///   case @remote_peer_vanished is set to [`false`] and @error is set.
183    ///
184    /// Upon receiving this signal, you should give up your reference to
185    /// @connection. You are guaranteed that this signal is emitted only
186    /// once.
187    ///
188    ///
189    ///
190    /// # Implements
191    ///
192    /// [`trait@glib::ObjectExt`], [`AsyncInitableExt`][trait@crate::prelude::AsyncInitableExt], [`InitableExt`][trait@crate::prelude::InitableExt]
193    #[doc(alias = "GDBusConnection")]
194    pub struct DBusConnection(Object<ffi::GDBusConnection>) @implements AsyncInitable, Initable;
195
196    match fn {
197        type_ => || ffi::g_dbus_connection_get_type(),
198    }
199}
200
201impl DBusConnection {
202    /// Synchronously connects and sets up a D-Bus client connection for
203    /// exchanging D-Bus messages with an endpoint specified by @address
204    /// which must be in the
205    /// [D-Bus address format](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses).
206    ///
207    /// This constructor can only be used to initiate client-side
208    /// connections - use g_dbus_connection_new_sync() if you need to act
209    /// as the server. In particular, @flags cannot contain the
210    /// [`DBusConnectionFlags::AUTHENTICATION_SERVER`][crate::DBusConnectionFlags::AUTHENTICATION_SERVER],
211    /// [`DBusConnectionFlags::AUTHENTICATION_ALLOW_ANONYMOUS`][crate::DBusConnectionFlags::AUTHENTICATION_ALLOW_ANONYMOUS] or
212    /// [`DBusConnectionFlags::AUTHENTICATION_REQUIRE_SAME_USER`][crate::DBusConnectionFlags::AUTHENTICATION_REQUIRE_SAME_USER] flags.
213    ///
214    /// This is a synchronous failable constructor. See
215    /// g_dbus_connection_new_for_address() for the asynchronous version.
216    ///
217    /// If @observer is not [`None`] it may be used to control the
218    /// authentication process.
219    /// ## `address`
220    /// a D-Bus address
221    /// ## `flags`
222    /// flags describing how to make the connection
223    /// ## `observer`
224    /// a #GDBusAuthObserver or [`None`]
225    /// ## `cancellable`
226    /// a #GCancellable or [`None`]
227    ///
228    /// # Returns
229    ///
230    /// a #GDBusConnection or [`None`] if @error is set.
231    ///     Free with g_object_unref().
232    #[doc(alias = "g_dbus_connection_new_for_address_sync")]
233    #[doc(alias = "new_for_address_sync")]
234    pub fn for_address_sync(
235        address: &str,
236        flags: DBusConnectionFlags,
237        observer: Option<&DBusAuthObserver>,
238        cancellable: Option<&impl IsA<Cancellable>>,
239    ) -> Result<DBusConnection, glib::Error> {
240        unsafe {
241            let mut error = std::ptr::null_mut();
242            let ret = ffi::g_dbus_connection_new_for_address_sync(
243                address.to_glib_none().0,
244                flags.into_glib(),
245                observer.to_glib_none().0,
246                cancellable.map(|p| p.as_ref()).to_glib_none().0,
247                &mut error,
248            );
249            if error.is_null() {
250                Ok(from_glib_full(ret))
251            } else {
252                Err(from_glib_full(error))
253            }
254        }
255    }
256
257    /// Synchronously sets up a D-Bus connection for exchanging D-Bus messages
258    /// with the end represented by @stream.
259    ///
260    /// If @stream is a #GSocketConnection, then the corresponding #GSocket
261    /// will be put into non-blocking mode.
262    ///
263    /// The D-Bus connection will interact with @stream from a worker thread.
264    /// As a result, the caller should not interact with @stream after this
265    /// method has been called, except by calling g_object_unref() on it.
266    ///
267    /// If @observer is not [`None`] it may be used to control the
268    /// authentication process.
269    ///
270    /// This is a synchronous failable constructor. See
271    /// g_dbus_connection_new() for the asynchronous version.
272    /// ## `stream`
273    /// a #GIOStream
274    /// ## `guid`
275    /// the GUID to use if authenticating as a server or [`None`]
276    /// ## `flags`
277    /// flags describing how to make the connection
278    /// ## `observer`
279    /// a #GDBusAuthObserver or [`None`]
280    /// ## `cancellable`
281    /// a #GCancellable or [`None`]
282    ///
283    /// # Returns
284    ///
285    /// a #GDBusConnection or [`None`] if @error is set.
286    ///     Free with g_object_unref().
287    #[doc(alias = "g_dbus_connection_new_sync")]
288    pub fn new_sync(
289        stream: &impl IsA<IOStream>,
290        guid: Option<&str>,
291        flags: DBusConnectionFlags,
292        observer: Option<&DBusAuthObserver>,
293        cancellable: Option<&impl IsA<Cancellable>>,
294    ) -> Result<DBusConnection, glib::Error> {
295        unsafe {
296            let mut error = std::ptr::null_mut();
297            let ret = ffi::g_dbus_connection_new_sync(
298                stream.as_ref().to_glib_none().0,
299                guid.to_glib_none().0,
300                flags.into_glib(),
301                observer.to_glib_none().0,
302                cancellable.map(|p| p.as_ref()).to_glib_none().0,
303                &mut error,
304            );
305            if error.is_null() {
306                Ok(from_glib_full(ret))
307            } else {
308                Err(from_glib_full(error))
309            }
310        }
311    }
312
313    /// Asynchronously invokes the @method_name method on the
314    /// @interface_name D-Bus interface on the remote object at
315    /// @object_path owned by @bus_name.
316    ///
317    /// If @self is closed then the operation will fail with
318    /// [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed]. If @cancellable is canceled, the operation will
319    /// fail with [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled]. If @parameters contains a value
320    /// not compatible with the D-Bus protocol, the operation fails with
321    /// [`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument].
322    ///
323    /// If @reply_type is non-[`None`] then the reply will be checked for having this type and an
324    /// error will be raised if it does not match.  Said another way, if you give a @reply_type
325    /// then any non-[`None`] return value will be of this type. Unless it’s
326    /// `G_VARIANT_TYPE_UNIT`, the @reply_type will be a tuple containing one or more
327    /// values.
328    ///
329    /// If the @parameters #GVariant is floating, it is consumed. This allows
330    /// convenient 'inline' use of g_variant_new(), e.g.:
331    ///
332    ///
333    /// **⚠️ The following code is in C ⚠️**
334    ///
335    /// ```C
336    ///  g_dbus_connection_call (connection,
337    ///                          "org.freedesktop.StringThings",
338    ///                          "/org/freedesktop/StringThings",
339    ///                          "org.freedesktop.StringThings",
340    ///                          "TwoStrings",
341    ///                          g_variant_new ("(ss)",
342    ///                                         "Thing One",
343    ///                                         "Thing Two"),
344    ///                          NULL,
345    ///                          G_DBUS_CALL_FLAGS_NONE,
346    ///                          -1,
347    ///                          NULL,
348    ///                          (GAsyncReadyCallback) two_strings_done,
349    ///                          NULL);
350    /// ```
351    ///
352    /// This is an asynchronous method. When the operation is finished,
353    /// @callback will be invoked in the thread-default main context
354    /// (see [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()])
355    /// of the thread you are calling this method from. You can then call
356    /// g_dbus_connection_call_finish() to get the result of the operation.
357    /// See g_dbus_connection_call_sync() for the synchronous version of this
358    /// function.
359    ///
360    /// If @callback is [`None`] then the D-Bus method call message will be sent with
361    /// the [`DBusMessageFlags::NO_REPLY_EXPECTED`][crate::DBusMessageFlags::NO_REPLY_EXPECTED] flag set.
362    /// ## `bus_name`
363    /// a unique or well-known bus name or [`None`] if
364    ///     @self is not a message bus connection
365    /// ## `object_path`
366    /// path of remote object
367    /// ## `interface_name`
368    /// D-Bus interface to invoke method on
369    /// ## `method_name`
370    /// the name of the method to invoke
371    /// ## `parameters`
372    /// a #GVariant tuple with parameters for the method
373    ///     or [`None`] if not passing parameters
374    /// ## `reply_type`
375    /// the expected type of the reply (which will be a
376    ///     tuple), or [`None`]
377    /// ## `flags`
378    /// flags from the #GDBusCallFlags enumeration
379    /// ## `timeout_msec`
380    /// the timeout in milliseconds, -1 to use the default
381    ///     timeout or `G_MAXINT` for no timeout
382    /// ## `cancellable`
383    /// a #GCancellable or [`None`]
384    /// ## `callback`
385    /// a #GAsyncReadyCallback to call when the request
386    ///     is satisfied or [`None`] if you don't care about the result of the
387    ///     method invocation
388    #[doc(alias = "g_dbus_connection_call")]
389    pub fn call<P: FnOnce(Result<glib::Variant, glib::Error>) + 'static>(
390        &self,
391        bus_name: Option<&str>,
392        object_path: &str,
393        interface_name: &str,
394        method_name: &str,
395        parameters: Option<&glib::Variant>,
396        reply_type: Option<&glib::VariantTy>,
397        flags: DBusCallFlags,
398        timeout_msec: i32,
399        cancellable: Option<&impl IsA<Cancellable>>,
400        callback: P,
401    ) {
402        let main_context = glib::MainContext::ref_thread_default();
403        let is_main_context_owner = main_context.is_owner();
404        let has_acquired_main_context = (!is_main_context_owner)
405            .then(|| main_context.acquire().ok())
406            .flatten();
407        assert!(
408            is_main_context_owner || has_acquired_main_context.is_some(),
409            "Async operations only allowed if the thread is owning the MainContext"
410        );
411
412        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
413            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
414        unsafe extern "C" fn call_trampoline<
415            P: FnOnce(Result<glib::Variant, glib::Error>) + 'static,
416        >(
417            _source_object: *mut glib::gobject_ffi::GObject,
418            res: *mut crate::ffi::GAsyncResult,
419            user_data: glib::ffi::gpointer,
420        ) {
421            let mut error = std::ptr::null_mut();
422            let ret = ffi::g_dbus_connection_call_finish(_source_object as *mut _, res, &mut error);
423            let result = if error.is_null() {
424                Ok(from_glib_full(ret))
425            } else {
426                Err(from_glib_full(error))
427            };
428            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
429                Box_::from_raw(user_data as *mut _);
430            let callback: P = callback.into_inner();
431            callback(result);
432        }
433        let callback = call_trampoline::<P>;
434        unsafe {
435            ffi::g_dbus_connection_call(
436                self.to_glib_none().0,
437                bus_name.to_glib_none().0,
438                object_path.to_glib_none().0,
439                interface_name.to_glib_none().0,
440                method_name.to_glib_none().0,
441                parameters.to_glib_none().0,
442                reply_type.to_glib_none().0,
443                flags.into_glib(),
444                timeout_msec,
445                cancellable.map(|p| p.as_ref()).to_glib_none().0,
446                Some(callback),
447                Box_::into_raw(user_data) as *mut _,
448            );
449        }
450    }
451
452    pub fn call_future(
453        &self,
454        bus_name: Option<&str>,
455        object_path: &str,
456        interface_name: &str,
457        method_name: &str,
458        parameters: Option<&glib::Variant>,
459        reply_type: Option<&glib::VariantTy>,
460        flags: DBusCallFlags,
461        timeout_msec: i32,
462    ) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::Variant, glib::Error>> + 'static>>
463    {
464        let bus_name = bus_name.map(ToOwned::to_owned);
465        let object_path = String::from(object_path);
466        let interface_name = String::from(interface_name);
467        let method_name = String::from(method_name);
468        let parameters = parameters.map(ToOwned::to_owned);
469        let reply_type = reply_type.map(ToOwned::to_owned);
470        Box_::pin(crate::GioFuture::new(
471            self,
472            move |obj, cancellable, send| {
473                obj.call(
474                    bus_name.as_ref().map(::std::borrow::Borrow::borrow),
475                    &object_path,
476                    &interface_name,
477                    &method_name,
478                    parameters.as_ref().map(::std::borrow::Borrow::borrow),
479                    reply_type.as_ref().map(::std::borrow::Borrow::borrow),
480                    flags,
481                    timeout_msec,
482                    Some(cancellable),
483                    move |res| {
484                        send.resolve(res);
485                    },
486                );
487            },
488        ))
489    }
490
491    /// Synchronously invokes the @method_name method on the
492    /// @interface_name D-Bus interface on the remote object at
493    /// @object_path owned by @bus_name.
494    ///
495    /// If @self is closed then the operation will fail with
496    /// [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed]. If @cancellable is canceled, the
497    /// operation will fail with [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled]. If @parameters
498    /// contains a value not compatible with the D-Bus protocol, the operation
499    /// fails with [`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument].
500    ///
501    /// If @reply_type is non-[`None`] then the reply will be checked for having
502    /// this type and an error will be raised if it does not match.  Said
503    /// another way, if you give a @reply_type then any non-[`None`] return
504    /// value will be of this type.
505    ///
506    /// If the @parameters #GVariant is floating, it is consumed.
507    /// This allows convenient 'inline' use of g_variant_new(), e.g.:
508    ///
509    ///
510    /// **⚠️ The following code is in C ⚠️**
511    ///
512    /// ```C
513    ///  g_dbus_connection_call_sync (connection,
514    ///                               "org.freedesktop.StringThings",
515    ///                               "/org/freedesktop/StringThings",
516    ///                               "org.freedesktop.StringThings",
517    ///                               "TwoStrings",
518    ///                               g_variant_new ("(ss)",
519    ///                                              "Thing One",
520    ///                                              "Thing Two"),
521    ///                               NULL,
522    ///                               G_DBUS_CALL_FLAGS_NONE,
523    ///                               -1,
524    ///                               NULL,
525    ///                               &error);
526    /// ```
527    ///
528    /// The calling thread is blocked until a reply is received. See
529    /// g_dbus_connection_call() for the asynchronous version of
530    /// this method.
531    /// ## `bus_name`
532    /// a unique or well-known bus name or [`None`] if
533    ///     @self is not a message bus connection
534    /// ## `object_path`
535    /// path of remote object
536    /// ## `interface_name`
537    /// D-Bus interface to invoke method on
538    /// ## `method_name`
539    /// the name of the method to invoke
540    /// ## `parameters`
541    /// a #GVariant tuple with parameters for the method
542    ///     or [`None`] if not passing parameters
543    /// ## `reply_type`
544    /// the expected type of the reply, or [`None`]
545    /// ## `flags`
546    /// flags from the #GDBusCallFlags enumeration
547    /// ## `timeout_msec`
548    /// the timeout in milliseconds, -1 to use the default
549    ///     timeout or `G_MAXINT` for no timeout
550    /// ## `cancellable`
551    /// a #GCancellable or [`None`]
552    ///
553    /// # Returns
554    ///
555    /// [`None`] if @error is set. Otherwise a non-floating
556    ///     #GVariant tuple with return values. Free with g_variant_unref().
557    #[doc(alias = "g_dbus_connection_call_sync")]
558    pub fn call_sync(
559        &self,
560        bus_name: Option<&str>,
561        object_path: &str,
562        interface_name: &str,
563        method_name: &str,
564        parameters: Option<&glib::Variant>,
565        reply_type: Option<&glib::VariantTy>,
566        flags: DBusCallFlags,
567        timeout_msec: i32,
568        cancellable: Option<&impl IsA<Cancellable>>,
569    ) -> Result<glib::Variant, glib::Error> {
570        unsafe {
571            let mut error = std::ptr::null_mut();
572            let ret = ffi::g_dbus_connection_call_sync(
573                self.to_glib_none().0,
574                bus_name.to_glib_none().0,
575                object_path.to_glib_none().0,
576                interface_name.to_glib_none().0,
577                method_name.to_glib_none().0,
578                parameters.to_glib_none().0,
579                reply_type.to_glib_none().0,
580                flags.into_glib(),
581                timeout_msec,
582                cancellable.map(|p| p.as_ref()).to_glib_none().0,
583                &mut error,
584            );
585            if error.is_null() {
586                Ok(from_glib_full(ret))
587            } else {
588                Err(from_glib_full(error))
589            }
590        }
591    }
592
593    /// Like g_dbus_connection_call() but also takes a #GUnixFDList object.
594    ///
595    /// The file descriptors normally correspond to `G_VARIANT_TYPE_HANDLE`
596    /// values in the body of the message. For example, if a message contains
597    /// two file descriptors, @fd_list would have length 2, and
598    /// `g_variant_new_handle (0)` and `g_variant_new_handle (1)` would appear
599    /// somewhere in the body of the message (not necessarily in that order!)
600    /// to represent the file descriptors at indexes 0 and 1 respectively.
601    ///
602    /// When designing D-Bus APIs that are intended to be interoperable,
603    /// please note that non-GDBus implementations of D-Bus can usually only
604    /// access file descriptors if they are referenced in this way by a
605    /// value of type `G_VARIANT_TYPE_HANDLE` in the body of the message.
606    ///
607    /// This method is only available on UNIX.
608    /// ## `bus_name`
609    /// a unique or well-known bus name or [`None`] if
610    ///     @self is not a message bus connection
611    /// ## `object_path`
612    /// path of remote object
613    /// ## `interface_name`
614    /// D-Bus interface to invoke method on
615    /// ## `method_name`
616    /// the name of the method to invoke
617    /// ## `parameters`
618    /// a #GVariant tuple with parameters for the method
619    ///     or [`None`] if not passing parameters
620    /// ## `reply_type`
621    /// the expected type of the reply, or [`None`]
622    /// ## `flags`
623    /// flags from the #GDBusCallFlags enumeration
624    /// ## `timeout_msec`
625    /// the timeout in milliseconds, -1 to use the default
626    ///     timeout or `G_MAXINT` for no timeout
627    /// ## `fd_list`
628    /// a #GUnixFDList or [`None`]
629    /// ## `cancellable`
630    /// a #GCancellable or [`None`]
631    /// ## `callback`
632    /// a #GAsyncReadyCallback to call when the request is
633    ///     satisfied or [`None`] if you don't * care about the result of the
634    ///     method invocation
635    #[cfg(unix)]
636    #[cfg_attr(docsrs, doc(cfg(unix)))]
637    #[doc(alias = "g_dbus_connection_call_with_unix_fd_list")]
638    pub fn call_with_unix_fd_list<
639        P: FnOnce(Result<(glib::Variant, Option<UnixFDList>), glib::Error>) + 'static,
640    >(
641        &self,
642        bus_name: Option<&str>,
643        object_path: &str,
644        interface_name: &str,
645        method_name: &str,
646        parameters: Option<&glib::Variant>,
647        reply_type: Option<&glib::VariantTy>,
648        flags: DBusCallFlags,
649        timeout_msec: i32,
650        fd_list: Option<&impl IsA<UnixFDList>>,
651        cancellable: Option<&impl IsA<Cancellable>>,
652        callback: P,
653    ) {
654        let main_context = glib::MainContext::ref_thread_default();
655        let is_main_context_owner = main_context.is_owner();
656        let has_acquired_main_context = (!is_main_context_owner)
657            .then(|| main_context.acquire().ok())
658            .flatten();
659        assert!(
660            is_main_context_owner || has_acquired_main_context.is_some(),
661            "Async operations only allowed if the thread is owning the MainContext"
662        );
663
664        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
665            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
666        unsafe extern "C" fn call_with_unix_fd_list_trampoline<
667            P: FnOnce(Result<(glib::Variant, Option<UnixFDList>), glib::Error>) + 'static,
668        >(
669            _source_object: *mut glib::gobject_ffi::GObject,
670            res: *mut crate::ffi::GAsyncResult,
671            user_data: glib::ffi::gpointer,
672        ) {
673            let mut error = std::ptr::null_mut();
674            let mut out_fd_list = std::ptr::null_mut();
675            let ret = ffi::g_dbus_connection_call_with_unix_fd_list_finish(
676                _source_object as *mut _,
677                &mut out_fd_list,
678                res,
679                &mut error,
680            );
681            let result = if error.is_null() {
682                Ok((from_glib_full(ret), from_glib_full(out_fd_list)))
683            } else {
684                Err(from_glib_full(error))
685            };
686            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
687                Box_::from_raw(user_data as *mut _);
688            let callback: P = callback.into_inner();
689            callback(result);
690        }
691        let callback = call_with_unix_fd_list_trampoline::<P>;
692        unsafe {
693            ffi::g_dbus_connection_call_with_unix_fd_list(
694                self.to_glib_none().0,
695                bus_name.to_glib_none().0,
696                object_path.to_glib_none().0,
697                interface_name.to_glib_none().0,
698                method_name.to_glib_none().0,
699                parameters.to_glib_none().0,
700                reply_type.to_glib_none().0,
701                flags.into_glib(),
702                timeout_msec,
703                fd_list.map(|p| p.as_ref()).to_glib_none().0,
704                cancellable.map(|p| p.as_ref()).to_glib_none().0,
705                Some(callback),
706                Box_::into_raw(user_data) as *mut _,
707            );
708        }
709    }
710
711    #[cfg(unix)]
712    #[cfg_attr(docsrs, doc(cfg(unix)))]
713    pub fn call_with_unix_fd_list_future(
714        &self,
715        bus_name: Option<&str>,
716        object_path: &str,
717        interface_name: &str,
718        method_name: &str,
719        parameters: Option<&glib::Variant>,
720        reply_type: Option<&glib::VariantTy>,
721        flags: DBusCallFlags,
722        timeout_msec: i32,
723        fd_list: Option<&(impl IsA<UnixFDList> + Clone + 'static)>,
724    ) -> Pin<
725        Box_<
726            dyn std::future::Future<
727                    Output = Result<(glib::Variant, Option<UnixFDList>), glib::Error>,
728                > + 'static,
729        >,
730    > {
731        let bus_name = bus_name.map(ToOwned::to_owned);
732        let object_path = String::from(object_path);
733        let interface_name = String::from(interface_name);
734        let method_name = String::from(method_name);
735        let parameters = parameters.map(ToOwned::to_owned);
736        let reply_type = reply_type.map(ToOwned::to_owned);
737        let fd_list = fd_list.map(ToOwned::to_owned);
738        Box_::pin(crate::GioFuture::new(
739            self,
740            move |obj, cancellable, send| {
741                obj.call_with_unix_fd_list(
742                    bus_name.as_ref().map(::std::borrow::Borrow::borrow),
743                    &object_path,
744                    &interface_name,
745                    &method_name,
746                    parameters.as_ref().map(::std::borrow::Borrow::borrow),
747                    reply_type.as_ref().map(::std::borrow::Borrow::borrow),
748                    flags,
749                    timeout_msec,
750                    fd_list.as_ref().map(::std::borrow::Borrow::borrow),
751                    Some(cancellable),
752                    move |res| {
753                        send.resolve(res);
754                    },
755                );
756            },
757        ))
758    }
759
760    /// Like g_dbus_connection_call_sync() but also takes and returns #GUnixFDList objects.
761    /// See g_dbus_connection_call_with_unix_fd_list() and
762    /// g_dbus_connection_call_with_unix_fd_list_finish() for more details.
763    ///
764    /// This method is only available on UNIX.
765    /// ## `bus_name`
766    /// a unique or well-known bus name or [`None`]
767    ///     if @self is not a message bus connection
768    /// ## `object_path`
769    /// path of remote object
770    /// ## `interface_name`
771    /// D-Bus interface to invoke method on
772    /// ## `method_name`
773    /// the name of the method to invoke
774    /// ## `parameters`
775    /// a #GVariant tuple with parameters for
776    ///     the method or [`None`] if not passing parameters
777    /// ## `reply_type`
778    /// the expected type of the reply, or [`None`]
779    /// ## `flags`
780    /// flags from the #GDBusCallFlags enumeration
781    /// ## `timeout_msec`
782    /// the timeout in milliseconds, -1 to use the default
783    ///     timeout or `G_MAXINT` for no timeout
784    /// ## `fd_list`
785    /// a #GUnixFDList or [`None`]
786    /// ## `cancellable`
787    /// a #GCancellable or [`None`]
788    ///
789    /// # Returns
790    ///
791    /// [`None`] if @error is set. Otherwise a non-floating
792    ///     #GVariant tuple with return values. Free with g_variant_unref().
793    ///
794    /// ## `out_fd_list`
795    /// return location for a #GUnixFDList or [`None`]
796    #[cfg(unix)]
797    #[cfg_attr(docsrs, doc(cfg(unix)))]
798    #[doc(alias = "g_dbus_connection_call_with_unix_fd_list_sync")]
799    pub fn call_with_unix_fd_list_sync(
800        &self,
801        bus_name: Option<&str>,
802        object_path: &str,
803        interface_name: &str,
804        method_name: &str,
805        parameters: Option<&glib::Variant>,
806        reply_type: Option<&glib::VariantTy>,
807        flags: DBusCallFlags,
808        timeout_msec: i32,
809        fd_list: Option<&impl IsA<UnixFDList>>,
810        cancellable: Option<&impl IsA<Cancellable>>,
811    ) -> Result<(glib::Variant, Option<UnixFDList>), glib::Error> {
812        unsafe {
813            let mut out_fd_list = std::ptr::null_mut();
814            let mut error = std::ptr::null_mut();
815            let ret = ffi::g_dbus_connection_call_with_unix_fd_list_sync(
816                self.to_glib_none().0,
817                bus_name.to_glib_none().0,
818                object_path.to_glib_none().0,
819                interface_name.to_glib_none().0,
820                method_name.to_glib_none().0,
821                parameters.to_glib_none().0,
822                reply_type.to_glib_none().0,
823                flags.into_glib(),
824                timeout_msec,
825                fd_list.map(|p| p.as_ref()).to_glib_none().0,
826                &mut out_fd_list,
827                cancellable.map(|p| p.as_ref()).to_glib_none().0,
828                &mut error,
829            );
830            if error.is_null() {
831                Ok((from_glib_full(ret), from_glib_full(out_fd_list)))
832            } else {
833                Err(from_glib_full(error))
834            }
835        }
836    }
837
838    /// Closes @self. Note that this never causes the process to
839    /// exit (this might only happen if the other end of a shared message
840    /// bus connection disconnects, see #GDBusConnection:exit-on-close).
841    ///
842    /// Once the connection is closed, operations such as sending a message
843    /// will return with the error [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed]. Closing a connection
844    /// will not automatically flush the connection so queued messages may
845    /// be lost. Use g_dbus_connection_flush() if you need such guarantees.
846    ///
847    /// If @self is already closed, this method fails with
848    /// [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed].
849    ///
850    /// When @self has been closed, the #GDBusConnection::closed
851    /// signal is emitted in the thread-default main context
852    /// (see [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()])
853    /// of the thread that @self was constructed in.
854    ///
855    /// This is an asynchronous method. When the operation is finished,
856    /// @callback will be invoked in the thread-default main context
857    /// (see [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()])
858    /// of the thread you are calling this method from. You can
859    /// then call g_dbus_connection_close_finish() to get the result of the
860    /// operation. See g_dbus_connection_close_sync() for the synchronous
861    /// version.
862    /// ## `cancellable`
863    /// a #GCancellable or [`None`]
864    /// ## `callback`
865    /// a #GAsyncReadyCallback to call when the request is
866    ///     satisfied or [`None`] if you don't care about the result
867    #[doc(alias = "g_dbus_connection_close")]
868    pub fn close<P: FnOnce(Result<(), glib::Error>) + 'static>(
869        &self,
870        cancellable: Option<&impl IsA<Cancellable>>,
871        callback: P,
872    ) {
873        let main_context = glib::MainContext::ref_thread_default();
874        let is_main_context_owner = main_context.is_owner();
875        let has_acquired_main_context = (!is_main_context_owner)
876            .then(|| main_context.acquire().ok())
877            .flatten();
878        assert!(
879            is_main_context_owner || has_acquired_main_context.is_some(),
880            "Async operations only allowed if the thread is owning the MainContext"
881        );
882
883        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
884            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
885        unsafe extern "C" fn close_trampoline<P: FnOnce(Result<(), glib::Error>) + 'static>(
886            _source_object: *mut glib::gobject_ffi::GObject,
887            res: *mut crate::ffi::GAsyncResult,
888            user_data: glib::ffi::gpointer,
889        ) {
890            let mut error = std::ptr::null_mut();
891            let _ = ffi::g_dbus_connection_close_finish(_source_object as *mut _, res, &mut error);
892            let result = if error.is_null() {
893                Ok(())
894            } else {
895                Err(from_glib_full(error))
896            };
897            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
898                Box_::from_raw(user_data as *mut _);
899            let callback: P = callback.into_inner();
900            callback(result);
901        }
902        let callback = close_trampoline::<P>;
903        unsafe {
904            ffi::g_dbus_connection_close(
905                self.to_glib_none().0,
906                cancellable.map(|p| p.as_ref()).to_glib_none().0,
907                Some(callback),
908                Box_::into_raw(user_data) as *mut _,
909            );
910        }
911    }
912
913    pub fn close_future(
914        &self,
915    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
916        Box_::pin(crate::GioFuture::new(
917            self,
918            move |obj, cancellable, send| {
919                obj.close(Some(cancellable), move |res| {
920                    send.resolve(res);
921                });
922            },
923        ))
924    }
925
926    /// Synchronously closes @self. The calling thread is blocked
927    /// until this is done. See g_dbus_connection_close() for the
928    /// asynchronous version of this method and more details about what it
929    /// does.
930    /// ## `cancellable`
931    /// a #GCancellable or [`None`]
932    ///
933    /// # Returns
934    ///
935    /// [`true`] if the operation succeeded, [`false`] if @error is set
936    #[doc(alias = "g_dbus_connection_close_sync")]
937    pub fn close_sync(
938        &self,
939        cancellable: Option<&impl IsA<Cancellable>>,
940    ) -> Result<(), glib::Error> {
941        unsafe {
942            let mut error = std::ptr::null_mut();
943            let is_ok = ffi::g_dbus_connection_close_sync(
944                self.to_glib_none().0,
945                cancellable.map(|p| p.as_ref()).to_glib_none().0,
946                &mut error,
947            );
948            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
949            if error.is_null() {
950                Ok(())
951            } else {
952                Err(from_glib_full(error))
953            }
954        }
955    }
956
957    /// Emits a signal.
958    ///
959    /// If the parameters GVariant is floating, it is consumed.
960    ///
961    /// This can only fail if @parameters is not compatible with the D-Bus protocol
962    /// ([`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument]), or if @self has been closed
963    /// ([`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed]).
964    /// ## `destination_bus_name`
965    /// the unique bus name for the destination
966    ///     for the signal or [`None`] to emit to all listeners
967    /// ## `object_path`
968    /// path of remote object
969    /// ## `interface_name`
970    /// D-Bus interface to emit a signal on
971    /// ## `signal_name`
972    /// the name of the signal to emit
973    /// ## `parameters`
974    /// a #GVariant tuple with parameters for the signal
975    ///              or [`None`] if not passing parameters
976    ///
977    /// # Returns
978    ///
979    /// [`true`] unless @error is set
980    #[doc(alias = "g_dbus_connection_emit_signal")]
981    pub fn emit_signal(
982        &self,
983        destination_bus_name: Option<&str>,
984        object_path: &str,
985        interface_name: &str,
986        signal_name: &str,
987        parameters: Option<&glib::Variant>,
988    ) -> Result<(), glib::Error> {
989        unsafe {
990            let mut error = std::ptr::null_mut();
991            let is_ok = ffi::g_dbus_connection_emit_signal(
992                self.to_glib_none().0,
993                destination_bus_name.to_glib_none().0,
994                object_path.to_glib_none().0,
995                interface_name.to_glib_none().0,
996                signal_name.to_glib_none().0,
997                parameters.to_glib_none().0,
998                &mut error,
999            );
1000            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1001            if error.is_null() {
1002                Ok(())
1003            } else {
1004                Err(from_glib_full(error))
1005            }
1006        }
1007    }
1008
1009    /// Asynchronously flushes @self, that is, writes all queued
1010    /// outgoing messages to the transport and then flushes the transport
1011    /// (using g_output_stream_flush_async()). This is useful in programs
1012    /// that want to emit a D-Bus signal and then exit immediately. Without
1013    /// flushing the connection, there is no guarantee that the message has
1014    /// been sent to the networking buffers in the OS kernel.
1015    ///
1016    /// This is an asynchronous method. When the operation is finished,
1017    /// @callback will be invoked in the thread-default main context
1018    /// (see [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()])
1019    /// of the thread you are calling this method from. You can
1020    /// then call g_dbus_connection_flush_finish() to get the result of the
1021    /// operation. See g_dbus_connection_flush_sync() for the synchronous
1022    /// version.
1023    /// ## `cancellable`
1024    /// a #GCancellable or [`None`]
1025    /// ## `callback`
1026    /// a #GAsyncReadyCallback to call when the
1027    ///     request is satisfied or [`None`] if you don't care about the result
1028    #[doc(alias = "g_dbus_connection_flush")]
1029    pub fn flush<P: FnOnce(Result<(), glib::Error>) + 'static>(
1030        &self,
1031        cancellable: Option<&impl IsA<Cancellable>>,
1032        callback: P,
1033    ) {
1034        let main_context = glib::MainContext::ref_thread_default();
1035        let is_main_context_owner = main_context.is_owner();
1036        let has_acquired_main_context = (!is_main_context_owner)
1037            .then(|| main_context.acquire().ok())
1038            .flatten();
1039        assert!(
1040            is_main_context_owner || has_acquired_main_context.is_some(),
1041            "Async operations only allowed if the thread is owning the MainContext"
1042        );
1043
1044        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
1045            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
1046        unsafe extern "C" fn flush_trampoline<P: FnOnce(Result<(), glib::Error>) + 'static>(
1047            _source_object: *mut glib::gobject_ffi::GObject,
1048            res: *mut crate::ffi::GAsyncResult,
1049            user_data: glib::ffi::gpointer,
1050        ) {
1051            let mut error = std::ptr::null_mut();
1052            let _ = ffi::g_dbus_connection_flush_finish(_source_object as *mut _, res, &mut error);
1053            let result = if error.is_null() {
1054                Ok(())
1055            } else {
1056                Err(from_glib_full(error))
1057            };
1058            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
1059                Box_::from_raw(user_data as *mut _);
1060            let callback: P = callback.into_inner();
1061            callback(result);
1062        }
1063        let callback = flush_trampoline::<P>;
1064        unsafe {
1065            ffi::g_dbus_connection_flush(
1066                self.to_glib_none().0,
1067                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1068                Some(callback),
1069                Box_::into_raw(user_data) as *mut _,
1070            );
1071        }
1072    }
1073
1074    pub fn flush_future(
1075        &self,
1076    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
1077        Box_::pin(crate::GioFuture::new(
1078            self,
1079            move |obj, cancellable, send| {
1080                obj.flush(Some(cancellable), move |res| {
1081                    send.resolve(res);
1082                });
1083            },
1084        ))
1085    }
1086
1087    /// Synchronously flushes @self. The calling thread is blocked
1088    /// until this is done. See g_dbus_connection_flush() for the
1089    /// asynchronous version of this method and more details about what it
1090    /// does.
1091    /// ## `cancellable`
1092    /// a #GCancellable or [`None`]
1093    ///
1094    /// # Returns
1095    ///
1096    /// [`true`] if the operation succeeded, [`false`] if @error is set
1097    #[doc(alias = "g_dbus_connection_flush_sync")]
1098    pub fn flush_sync(
1099        &self,
1100        cancellable: Option<&impl IsA<Cancellable>>,
1101    ) -> Result<(), glib::Error> {
1102        unsafe {
1103            let mut error = std::ptr::null_mut();
1104            let is_ok = ffi::g_dbus_connection_flush_sync(
1105                self.to_glib_none().0,
1106                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1107                &mut error,
1108            );
1109            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1110            if error.is_null() {
1111                Ok(())
1112            } else {
1113                Err(from_glib_full(error))
1114            }
1115        }
1116    }
1117
1118    /// Gets the capabilities negotiated with the remote peer
1119    ///
1120    /// # Returns
1121    ///
1122    /// zero or more flags from the #GDBusCapabilityFlags enumeration
1123    #[doc(alias = "g_dbus_connection_get_capabilities")]
1124    #[doc(alias = "get_capabilities")]
1125    pub fn capabilities(&self) -> DBusCapabilityFlags {
1126        unsafe {
1127            from_glib(ffi::g_dbus_connection_get_capabilities(
1128                self.to_glib_none().0,
1129            ))
1130        }
1131    }
1132
1133    /// Gets whether the process is terminated when @self is
1134    /// closed by the remote peer. See
1135    /// #GDBusConnection:exit-on-close for more details.
1136    ///
1137    /// # Returns
1138    ///
1139    /// whether the process is terminated when @self is
1140    ///     closed by the remote peer
1141    #[doc(alias = "g_dbus_connection_get_exit_on_close")]
1142    #[doc(alias = "get_exit_on_close")]
1143    #[doc(alias = "exit-on-close")]
1144    pub fn exits_on_close(&self) -> bool {
1145        unsafe {
1146            from_glib(ffi::g_dbus_connection_get_exit_on_close(
1147                self.to_glib_none().0,
1148            ))
1149        }
1150    }
1151
1152    /// Gets the flags used to construct this connection
1153    ///
1154    /// # Returns
1155    ///
1156    /// zero or more flags from the #GDBusConnectionFlags enumeration
1157    #[cfg(feature = "v2_60")]
1158    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
1159    #[doc(alias = "g_dbus_connection_get_flags")]
1160    #[doc(alias = "get_flags")]
1161    pub fn flags(&self) -> DBusConnectionFlags {
1162        unsafe { from_glib(ffi::g_dbus_connection_get_flags(self.to_glib_none().0)) }
1163    }
1164
1165    /// The GUID of the peer performing the role of server when
1166    /// authenticating. See #GDBusConnection:guid for more details.
1167    ///
1168    /// # Returns
1169    ///
1170    /// The GUID. Do not free this string, it is owned by
1171    ///     @self.
1172    #[doc(alias = "g_dbus_connection_get_guid")]
1173    #[doc(alias = "get_guid")]
1174    pub fn guid(&self) -> glib::GString {
1175        unsafe { from_glib_none(ffi::g_dbus_connection_get_guid(self.to_glib_none().0)) }
1176    }
1177
1178    /// Retrieves the last serial number assigned to a #GDBusMessage on
1179    /// the current thread. This includes messages sent via both low-level
1180    /// API such as g_dbus_connection_send_message() as well as
1181    /// high-level API such as g_dbus_connection_emit_signal(),
1182    /// g_dbus_connection_call() or g_dbus_proxy_call().
1183    ///
1184    /// # Returns
1185    ///
1186    /// the last used serial or zero when no message has been sent
1187    ///     within the current thread
1188    #[doc(alias = "g_dbus_connection_get_last_serial")]
1189    #[doc(alias = "get_last_serial")]
1190    pub fn last_serial(&self) -> u32 {
1191        unsafe { ffi::g_dbus_connection_get_last_serial(self.to_glib_none().0) }
1192    }
1193
1194    /// Gets the credentials of the authenticated peer. This will always
1195    /// return [`None`] unless @self acted as a server
1196    /// (e.g. [`DBusConnectionFlags::AUTHENTICATION_SERVER`][crate::DBusConnectionFlags::AUTHENTICATION_SERVER] was passed)
1197    /// when set up and the client passed credentials as part of the
1198    /// authentication process.
1199    ///
1200    /// In a message bus setup, the message bus is always the server and
1201    /// each application is a client. So this method will always return
1202    /// [`None`] for message bus clients.
1203    ///
1204    /// # Returns
1205    ///
1206    /// a #GCredentials or [`None`] if not
1207    ///     available. Do not free this object, it is owned by @self.
1208    #[doc(alias = "g_dbus_connection_get_peer_credentials")]
1209    #[doc(alias = "get_peer_credentials")]
1210    pub fn peer_credentials(&self) -> Option<Credentials> {
1211        unsafe {
1212            from_glib_none(ffi::g_dbus_connection_get_peer_credentials(
1213                self.to_glib_none().0,
1214            ))
1215        }
1216    }
1217
1218    /// Gets the underlying stream used for IO.
1219    ///
1220    /// While the #GDBusConnection is active, it will interact with this
1221    /// stream from a worker thread, so it is not safe to interact with
1222    /// the stream directly.
1223    ///
1224    /// # Returns
1225    ///
1226    /// the stream used for IO
1227    #[doc(alias = "g_dbus_connection_get_stream")]
1228    #[doc(alias = "get_stream")]
1229    pub fn stream(&self) -> IOStream {
1230        unsafe { from_glib_none(ffi::g_dbus_connection_get_stream(self.to_glib_none().0)) }
1231    }
1232
1233    /// Gets the unique name of @self as assigned by the message
1234    /// bus. This can also be used to figure out if @self is a
1235    /// message bus connection.
1236    ///
1237    /// # Returns
1238    ///
1239    /// the unique name or [`None`] if @self is not a message
1240    ///     bus connection. Do not free this string, it is owned by
1241    ///     @self.
1242    #[doc(alias = "g_dbus_connection_get_unique_name")]
1243    #[doc(alias = "get_unique_name")]
1244    #[doc(alias = "unique-name")]
1245    pub fn unique_name(&self) -> Option<glib::GString> {
1246        unsafe {
1247            from_glib_none(ffi::g_dbus_connection_get_unique_name(
1248                self.to_glib_none().0,
1249            ))
1250        }
1251    }
1252
1253    /// Gets whether @self is closed.
1254    ///
1255    /// # Returns
1256    ///
1257    /// [`true`] if the connection is closed, [`false`] otherwise
1258    #[doc(alias = "g_dbus_connection_is_closed")]
1259    #[doc(alias = "closed")]
1260    pub fn is_closed(&self) -> bool {
1261        unsafe { from_glib(ffi::g_dbus_connection_is_closed(self.to_glib_none().0)) }
1262    }
1263
1264    /// Asynchronously sends @message to the peer represented by @self.
1265    ///
1266    /// Unless @flags contain the
1267    /// [`DBusSendMessageFlags::PRESERVE_SERIAL`][crate::DBusSendMessageFlags::PRESERVE_SERIAL] flag, the serial number
1268    /// will be assigned by @self and set on @message via
1269    /// g_dbus_message_set_serial(). If @out_serial is not [`None`], then the
1270    /// serial number used will be written to this location prior to
1271    /// submitting the message to the underlying transport. While it has a `volatile`
1272    /// qualifier, this is a historical artifact and the argument passed to it should
1273    /// not be `volatile`.
1274    ///
1275    /// If @self is closed then the operation will fail with
1276    /// [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed]. If @message is not well-formed,
1277    /// the operation fails with [`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument].
1278    ///
1279    /// See this [server][`DBusConnection`][crate::DBusConnection]#an-example-d-bus-server]
1280    /// and [client][`DBusConnection`][crate::DBusConnection]#an-example-for-file-descriptor-passing]
1281    /// for an example of how to use this low-level API to send and receive
1282    /// UNIX file descriptors.
1283    ///
1284    /// Note that @message must be unlocked, unless @flags contain the
1285    /// [`DBusSendMessageFlags::PRESERVE_SERIAL`][crate::DBusSendMessageFlags::PRESERVE_SERIAL] flag.
1286    /// ## `message`
1287    /// a #GDBusMessage
1288    /// ## `flags`
1289    /// flags affecting how the message is sent
1290    ///
1291    /// # Returns
1292    ///
1293    /// [`true`] if the message was well-formed and queued for
1294    ///     transmission, [`false`] if @error is set
1295    ///
1296    /// ## `out_serial`
1297    /// return location for serial number assigned
1298    ///     to @message when sending it or [`None`]
1299    #[doc(alias = "g_dbus_connection_send_message")]
1300    pub fn send_message(
1301        &self,
1302        message: &DBusMessage,
1303        flags: DBusSendMessageFlags,
1304    ) -> Result<u32, glib::Error> {
1305        unsafe {
1306            let mut out_serial = std::mem::MaybeUninit::uninit();
1307            let mut error = std::ptr::null_mut();
1308            let is_ok = ffi::g_dbus_connection_send_message(
1309                self.to_glib_none().0,
1310                message.to_glib_none().0,
1311                flags.into_glib(),
1312                out_serial.as_mut_ptr(),
1313                &mut error,
1314            );
1315            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1316            if error.is_null() {
1317                Ok(out_serial.assume_init())
1318            } else {
1319                Err(from_glib_full(error))
1320            }
1321        }
1322    }
1323
1324    /// Asynchronously sends @message to the peer represented by @self.
1325    ///
1326    /// Unless @flags contain the
1327    /// [`DBusSendMessageFlags::PRESERVE_SERIAL`][crate::DBusSendMessageFlags::PRESERVE_SERIAL] flag, the serial number
1328    /// will be assigned by @self and set on @message via
1329    /// g_dbus_message_set_serial(). If @out_serial is not [`None`], then the
1330    /// serial number used will be written to this location prior to
1331    /// submitting the message to the underlying transport. While it has a `volatile`
1332    /// qualifier, this is a historical artifact and the argument passed to it should
1333    /// not be `volatile`.
1334    ///
1335    /// If @self is closed then the operation will fail with
1336    /// [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed]. If @cancellable is canceled, the operation will
1337    /// fail with [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled]. If @message is not well-formed,
1338    /// the operation fails with [`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument].
1339    ///
1340    /// This is an asynchronous method. When the operation is finished, @callback
1341    /// will be invoked in the thread-default main context
1342    /// (see [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()])
1343    /// of the thread you are calling this method from. You can then call
1344    /// g_dbus_connection_send_message_with_reply_finish() to get the result of the operation.
1345    /// See g_dbus_connection_send_message_with_reply_sync() for the synchronous version.
1346    ///
1347    /// Note that @message must be unlocked, unless @flags contain the
1348    /// [`DBusSendMessageFlags::PRESERVE_SERIAL`][crate::DBusSendMessageFlags::PRESERVE_SERIAL] flag.
1349    ///
1350    /// See this [server][`DBusConnection`][crate::DBusConnection]#an-example-d-bus-server]
1351    /// and [client][`DBusConnection`][crate::DBusConnection]#an-example-for-file-descriptor-passing]
1352    /// for an example of how to use this low-level API to send and receive
1353    /// UNIX file descriptors.
1354    /// ## `message`
1355    /// a #GDBusMessage
1356    /// ## `flags`
1357    /// flags affecting how the message is sent
1358    /// ## `timeout_msec`
1359    /// the timeout in milliseconds, -1 to use the default
1360    ///     timeout or `G_MAXINT` for no timeout
1361    /// ## `cancellable`
1362    /// a #GCancellable or [`None`]
1363    /// ## `callback`
1364    /// a #GAsyncReadyCallback to call when the request
1365    ///     is satisfied or [`None`] if you don't care about the result
1366    ///
1367    /// # Returns
1368    ///
1369    ///
1370    /// ## `out_serial`
1371    /// return location for serial number assigned
1372    ///     to @message when sending it or [`None`]
1373    #[doc(alias = "g_dbus_connection_send_message_with_reply")]
1374    pub fn send_message_with_reply<P: FnOnce(Result<DBusMessage, glib::Error>) + 'static>(
1375        &self,
1376        message: &DBusMessage,
1377        flags: DBusSendMessageFlags,
1378        timeout_msec: i32,
1379        cancellable: Option<&impl IsA<Cancellable>>,
1380        callback: P,
1381    ) -> u32 {
1382        let main_context = glib::MainContext::ref_thread_default();
1383        let is_main_context_owner = main_context.is_owner();
1384        let has_acquired_main_context = (!is_main_context_owner)
1385            .then(|| main_context.acquire().ok())
1386            .flatten();
1387        assert!(
1388            is_main_context_owner || has_acquired_main_context.is_some(),
1389            "Async operations only allowed if the thread is owning the MainContext"
1390        );
1391
1392        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
1393            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
1394        unsafe extern "C" fn send_message_with_reply_trampoline<
1395            P: FnOnce(Result<DBusMessage, glib::Error>) + 'static,
1396        >(
1397            _source_object: *mut glib::gobject_ffi::GObject,
1398            res: *mut crate::ffi::GAsyncResult,
1399            user_data: glib::ffi::gpointer,
1400        ) {
1401            let mut error = std::ptr::null_mut();
1402            let ret = ffi::g_dbus_connection_send_message_with_reply_finish(
1403                _source_object as *mut _,
1404                res,
1405                &mut error,
1406            );
1407            let result = if error.is_null() {
1408                Ok(from_glib_full(ret))
1409            } else {
1410                Err(from_glib_full(error))
1411            };
1412            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
1413                Box_::from_raw(user_data as *mut _);
1414            let callback: P = callback.into_inner();
1415            callback(result);
1416        }
1417        let callback = send_message_with_reply_trampoline::<P>;
1418        unsafe {
1419            let mut out_serial = std::mem::MaybeUninit::uninit();
1420            ffi::g_dbus_connection_send_message_with_reply(
1421                self.to_glib_none().0,
1422                message.to_glib_none().0,
1423                flags.into_glib(),
1424                timeout_msec,
1425                out_serial.as_mut_ptr(),
1426                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1427                Some(callback),
1428                Box_::into_raw(user_data) as *mut _,
1429            );
1430            out_serial.assume_init()
1431        }
1432    }
1433
1434    pub fn send_message_with_reply_future(
1435        &self,
1436        message: &DBusMessage,
1437        flags: DBusSendMessageFlags,
1438        timeout_msec: i32,
1439    ) -> Pin<Box_<dyn std::future::Future<Output = Result<DBusMessage, glib::Error>> + 'static>>
1440    {
1441        let message = message.clone();
1442        Box_::pin(crate::GioFuture::new(
1443            self,
1444            move |obj, cancellable, send| {
1445                obj.send_message_with_reply(
1446                    &message,
1447                    flags,
1448                    timeout_msec,
1449                    Some(cancellable),
1450                    move |res| {
1451                        send.resolve(res);
1452                    },
1453                );
1454            },
1455        ))
1456    }
1457
1458    /// Synchronously sends @message to the peer represented by @self
1459    /// and blocks the calling thread until a reply is received or the
1460    /// timeout is reached. See g_dbus_connection_send_message_with_reply()
1461    /// for the asynchronous version of this method.
1462    ///
1463    /// Unless @flags contain the
1464    /// [`DBusSendMessageFlags::PRESERVE_SERIAL`][crate::DBusSendMessageFlags::PRESERVE_SERIAL] flag, the serial number
1465    /// will be assigned by @self and set on @message via
1466    /// g_dbus_message_set_serial(). If @out_serial is not [`None`], then the
1467    /// serial number used will be written to this location prior to
1468    /// submitting the message to the underlying transport. While it has a `volatile`
1469    /// qualifier, this is a historical artifact and the argument passed to it should
1470    /// not be `volatile`.
1471    ///
1472    /// If @self is closed then the operation will fail with
1473    /// [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed]. If @cancellable is canceled, the operation will
1474    /// fail with [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled]. If @message is not well-formed,
1475    /// the operation fails with [`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument].
1476    ///
1477    /// Note that @error is only set if a local in-process error
1478    /// occurred. That is to say that the returned #GDBusMessage object may
1479    /// be of type [`DBusMessageType::Error`][crate::DBusMessageType::Error]. Use
1480    /// g_dbus_message_to_gerror() to transcode this to a #GError.
1481    ///
1482    /// See this [server][`DBusConnection`][crate::DBusConnection]#an-example-d-bus-server]
1483    /// and [client][`DBusConnection`][crate::DBusConnection]#an-example-for-file-descriptor-passing]
1484    /// for an example of how to use this low-level API to send and receive
1485    /// UNIX file descriptors.
1486    ///
1487    /// Note that @message must be unlocked, unless @flags contain the
1488    /// [`DBusSendMessageFlags::PRESERVE_SERIAL`][crate::DBusSendMessageFlags::PRESERVE_SERIAL] flag.
1489    /// ## `message`
1490    /// a #GDBusMessage
1491    /// ## `flags`
1492    /// flags affecting how the message is sent.
1493    /// ## `timeout_msec`
1494    /// the timeout in milliseconds, -1 to use the default
1495    ///     timeout or `G_MAXINT` for no timeout
1496    /// ## `cancellable`
1497    /// a #GCancellable or [`None`]
1498    ///
1499    /// # Returns
1500    ///
1501    /// a locked #GDBusMessage that is the reply
1502    ///     to @message or [`None`] if @error is set
1503    ///
1504    /// ## `out_serial`
1505    /// return location for serial number
1506    ///     assigned to @message when sending it or [`None`]
1507    #[doc(alias = "g_dbus_connection_send_message_with_reply_sync")]
1508    pub fn send_message_with_reply_sync(
1509        &self,
1510        message: &DBusMessage,
1511        flags: DBusSendMessageFlags,
1512        timeout_msec: i32,
1513        cancellable: Option<&impl IsA<Cancellable>>,
1514    ) -> Result<(DBusMessage, u32), glib::Error> {
1515        unsafe {
1516            let mut out_serial = std::mem::MaybeUninit::uninit();
1517            let mut error = std::ptr::null_mut();
1518            let ret = ffi::g_dbus_connection_send_message_with_reply_sync(
1519                self.to_glib_none().0,
1520                message.to_glib_none().0,
1521                flags.into_glib(),
1522                timeout_msec,
1523                out_serial.as_mut_ptr(),
1524                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1525                &mut error,
1526            );
1527            if error.is_null() {
1528                Ok((from_glib_full(ret), out_serial.assume_init()))
1529            } else {
1530                Err(from_glib_full(error))
1531            }
1532        }
1533    }
1534
1535    /// Sets whether the process should be terminated when @self is
1536    /// closed by the remote peer. See #GDBusConnection:exit-on-close for
1537    /// more details.
1538    ///
1539    /// Note that this function should be used with care. Most modern UNIX
1540    /// desktops tie the notion of a user session with the session bus, and expect
1541    /// all of a user's applications to quit when their bus connection goes away.
1542    /// If you are setting @exit_on_close to [`false`] for the shared session
1543    /// bus connection, you should make sure that your application exits
1544    /// when the user session ends.
1545    /// ## `exit_on_close`
1546    /// whether the process should be terminated
1547    ///     when @self is closed by the remote peer
1548    #[doc(alias = "g_dbus_connection_set_exit_on_close")]
1549    #[doc(alias = "exit-on-close")]
1550    pub fn set_exit_on_close(&self, exit_on_close: bool) {
1551        unsafe {
1552            ffi::g_dbus_connection_set_exit_on_close(
1553                self.to_glib_none().0,
1554                exit_on_close.into_glib(),
1555            );
1556        }
1557    }
1558
1559    /// If @self was created with
1560    /// [`DBusConnectionFlags::DELAY_MESSAGE_PROCESSING`][crate::DBusConnectionFlags::DELAY_MESSAGE_PROCESSING], this method
1561    /// starts processing messages. Does nothing on if @self wasn't
1562    /// created with this flag or if the method has already been called.
1563    #[doc(alias = "g_dbus_connection_start_message_processing")]
1564    pub fn start_message_processing(&self) {
1565        unsafe {
1566            ffi::g_dbus_connection_start_message_processing(self.to_glib_none().0);
1567        }
1568    }
1569
1570    #[cfg(not(feature = "v2_60"))]
1571    #[cfg_attr(docsrs, doc(cfg(not(feature = "v2_60"))))]
1572    pub fn flags(&self) -> DBusConnectionFlags {
1573        ObjectExt::property(self, "flags")
1574    }
1575
1576    /// Asynchronously sets up a D-Bus connection for exchanging D-Bus messages
1577    /// with the end represented by @stream.
1578    ///
1579    /// If @stream is a #GSocketConnection, then the corresponding #GSocket
1580    /// will be put into non-blocking mode.
1581    ///
1582    /// The D-Bus connection will interact with @stream from a worker thread.
1583    /// As a result, the caller should not interact with @stream after this
1584    /// method has been called, except by calling g_object_unref() on it.
1585    ///
1586    /// If @observer is not [`None`] it may be used to control the
1587    /// authentication process.
1588    ///
1589    /// When the operation is finished, @callback will be invoked. You can
1590    /// then call g_dbus_connection_new_finish() to get the result of the
1591    /// operation.
1592    ///
1593    /// This is an asynchronous failable constructor. See
1594    /// g_dbus_connection_new_sync() for the synchronous
1595    /// version.
1596    /// ## `stream`
1597    /// a #GIOStream
1598    /// ## `guid`
1599    /// the GUID to use if authenticating as a server or [`None`]
1600    /// ## `flags`
1601    /// flags describing how to make the connection
1602    /// ## `observer`
1603    /// a #GDBusAuthObserver or [`None`]
1604    /// ## `cancellable`
1605    /// a #GCancellable or [`None`]
1606    /// ## `callback`
1607    /// a #GAsyncReadyCallback to call when the request is satisfied
1608    #[doc(alias = "g_dbus_connection_new")]
1609    pub fn new<P: FnOnce(Result<DBusConnection, glib::Error>) + 'static>(
1610        stream: &impl IsA<IOStream>,
1611        guid: Option<&str>,
1612        flags: DBusConnectionFlags,
1613        observer: Option<&DBusAuthObserver>,
1614        cancellable: Option<&impl IsA<Cancellable>>,
1615        callback: P,
1616    ) {
1617        let main_context = glib::MainContext::ref_thread_default();
1618        let is_main_context_owner = main_context.is_owner();
1619        let has_acquired_main_context = (!is_main_context_owner)
1620            .then(|| main_context.acquire().ok())
1621            .flatten();
1622        assert!(
1623            is_main_context_owner || has_acquired_main_context.is_some(),
1624            "Async operations only allowed if the thread is owning the MainContext"
1625        );
1626
1627        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
1628            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
1629        unsafe extern "C" fn new_trampoline<
1630            P: FnOnce(Result<DBusConnection, glib::Error>) + 'static,
1631        >(
1632            _source_object: *mut glib::gobject_ffi::GObject,
1633            res: *mut crate::ffi::GAsyncResult,
1634            user_data: glib::ffi::gpointer,
1635        ) {
1636            let mut error = std::ptr::null_mut();
1637            let ret = ffi::g_dbus_connection_new_finish(res, &mut error);
1638            let result = if error.is_null() {
1639                Ok(from_glib_full(ret))
1640            } else {
1641                Err(from_glib_full(error))
1642            };
1643            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
1644                Box_::from_raw(user_data as *mut _);
1645            let callback: P = callback.into_inner();
1646            callback(result);
1647        }
1648        let callback = new_trampoline::<P>;
1649        unsafe {
1650            ffi::g_dbus_connection_new(
1651                stream.as_ref().to_glib_none().0,
1652                guid.to_glib_none().0,
1653                flags.into_glib(),
1654                observer.to_glib_none().0,
1655                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1656                Some(callback),
1657                Box_::into_raw(user_data) as *mut _,
1658            );
1659        }
1660    }
1661
1662    pub fn new_future(
1663        stream: &(impl IsA<IOStream> + Clone + 'static),
1664        guid: Option<&str>,
1665        flags: DBusConnectionFlags,
1666        observer: Option<&DBusAuthObserver>,
1667    ) -> Pin<Box_<dyn std::future::Future<Output = Result<DBusConnection, glib::Error>> + 'static>>
1668    {
1669        let stream = stream.clone();
1670        let guid = guid.map(ToOwned::to_owned);
1671        let observer = observer.map(ToOwned::to_owned);
1672        Box_::pin(crate::GioFuture::new(
1673            &(),
1674            move |_obj, cancellable, send| {
1675                Self::new(
1676                    &stream,
1677                    guid.as_ref().map(::std::borrow::Borrow::borrow),
1678                    flags,
1679                    observer.as_ref().map(::std::borrow::Borrow::borrow),
1680                    Some(cancellable),
1681                    move |res| {
1682                        send.resolve(res);
1683                    },
1684                );
1685            },
1686        ))
1687    }
1688
1689    /// Asynchronously connects and sets up a D-Bus client connection for
1690    /// exchanging D-Bus messages with an endpoint specified by @address
1691    /// which must be in the
1692    /// [D-Bus address format](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses).
1693    ///
1694    /// This constructor can only be used to initiate client-side
1695    /// connections - use g_dbus_connection_new() if you need to act as the
1696    /// server. In particular, @flags cannot contain the
1697    /// [`DBusConnectionFlags::AUTHENTICATION_SERVER`][crate::DBusConnectionFlags::AUTHENTICATION_SERVER],
1698    /// [`DBusConnectionFlags::AUTHENTICATION_ALLOW_ANONYMOUS`][crate::DBusConnectionFlags::AUTHENTICATION_ALLOW_ANONYMOUS] or
1699    /// [`DBusConnectionFlags::AUTHENTICATION_REQUIRE_SAME_USER`][crate::DBusConnectionFlags::AUTHENTICATION_REQUIRE_SAME_USER] flags.
1700    ///
1701    /// When the operation is finished, @callback will be invoked. You can
1702    /// then call g_dbus_connection_new_for_address_finish() to get the result of
1703    /// the operation.
1704    ///
1705    /// If @observer is not [`None`] it may be used to control the
1706    /// authentication process.
1707    ///
1708    /// This is an asynchronous failable constructor. See
1709    /// g_dbus_connection_new_for_address_sync() for the synchronous
1710    /// version.
1711    /// ## `address`
1712    /// a D-Bus address
1713    /// ## `flags`
1714    /// flags describing how to make the connection
1715    /// ## `observer`
1716    /// a #GDBusAuthObserver or [`None`]
1717    /// ## `cancellable`
1718    /// a #GCancellable or [`None`]
1719    /// ## `callback`
1720    /// a #GAsyncReadyCallback to call when the request is satisfied
1721    #[doc(alias = "g_dbus_connection_new_for_address")]
1722    #[doc(alias = "new_for_address")]
1723    pub fn for_address<P: FnOnce(Result<DBusConnection, glib::Error>) + 'static>(
1724        address: &str,
1725        flags: DBusConnectionFlags,
1726        observer: Option<&DBusAuthObserver>,
1727        cancellable: Option<&impl IsA<Cancellable>>,
1728        callback: P,
1729    ) {
1730        let main_context = glib::MainContext::ref_thread_default();
1731        let is_main_context_owner = main_context.is_owner();
1732        let has_acquired_main_context = (!is_main_context_owner)
1733            .then(|| main_context.acquire().ok())
1734            .flatten();
1735        assert!(
1736            is_main_context_owner || has_acquired_main_context.is_some(),
1737            "Async operations only allowed if the thread is owning the MainContext"
1738        );
1739
1740        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
1741            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
1742        unsafe extern "C" fn for_address_trampoline<
1743            P: FnOnce(Result<DBusConnection, glib::Error>) + 'static,
1744        >(
1745            _source_object: *mut glib::gobject_ffi::GObject,
1746            res: *mut crate::ffi::GAsyncResult,
1747            user_data: glib::ffi::gpointer,
1748        ) {
1749            let mut error = std::ptr::null_mut();
1750            let ret = ffi::g_dbus_connection_new_for_address_finish(res, &mut error);
1751            let result = if error.is_null() {
1752                Ok(from_glib_full(ret))
1753            } else {
1754                Err(from_glib_full(error))
1755            };
1756            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
1757                Box_::from_raw(user_data as *mut _);
1758            let callback: P = callback.into_inner();
1759            callback(result);
1760        }
1761        let callback = for_address_trampoline::<P>;
1762        unsafe {
1763            ffi::g_dbus_connection_new_for_address(
1764                address.to_glib_none().0,
1765                flags.into_glib(),
1766                observer.to_glib_none().0,
1767                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1768                Some(callback),
1769                Box_::into_raw(user_data) as *mut _,
1770            );
1771        }
1772    }
1773
1774    pub fn for_address_future(
1775        address: &str,
1776        flags: DBusConnectionFlags,
1777        observer: Option<&DBusAuthObserver>,
1778    ) -> Pin<Box_<dyn std::future::Future<Output = Result<DBusConnection, glib::Error>> + 'static>>
1779    {
1780        let address = String::from(address);
1781        let observer = observer.map(ToOwned::to_owned);
1782        Box_::pin(crate::GioFuture::new(
1783            &(),
1784            move |_obj, cancellable, send| {
1785                Self::for_address(
1786                    &address,
1787                    flags,
1788                    observer.as_ref().map(::std::borrow::Borrow::borrow),
1789                    Some(cancellable),
1790                    move |res| {
1791                        send.resolve(res);
1792                    },
1793                );
1794            },
1795        ))
1796    }
1797
1798    /// Emitted when the connection is closed.
1799    ///
1800    /// The cause of this event can be
1801    ///
1802    /// - If g_dbus_connection_close() is called. In this case
1803    ///   @remote_peer_vanished is set to [`false`] and @error is [`None`].
1804    ///
1805    /// - If the remote peer closes the connection. In this case
1806    ///   @remote_peer_vanished is set to [`true`] and @error is set.
1807    ///
1808    /// - If the remote peer sends invalid or malformed data. In this
1809    ///   case @remote_peer_vanished is set to [`false`] and @error is set.
1810    ///
1811    /// Upon receiving this signal, you should give up your reference to
1812    /// @connection. You are guaranteed that this signal is emitted only
1813    /// once.
1814    /// ## `remote_peer_vanished`
1815    /// [`true`] if @connection is closed because the
1816    ///     remote peer closed its end of the connection
1817    /// ## `error`
1818    /// a #GError with more details about the event or [`None`]
1819    #[doc(alias = "closed")]
1820    pub fn connect_closed<F: Fn(&Self, bool, Option<&glib::Error>) + Send + Sync + 'static>(
1821        &self,
1822        f: F,
1823    ) -> SignalHandlerId {
1824        unsafe extern "C" fn closed_trampoline<
1825            F: Fn(&DBusConnection, bool, Option<&glib::Error>) + Send + Sync + 'static,
1826        >(
1827            this: *mut ffi::GDBusConnection,
1828            remote_peer_vanished: glib::ffi::gboolean,
1829            error: *mut glib::ffi::GError,
1830            f: glib::ffi::gpointer,
1831        ) {
1832            let f: &F = &*(f as *const F);
1833            f(
1834                &from_glib_borrow(this),
1835                from_glib(remote_peer_vanished),
1836                Option::<glib::Error>::from_glib_borrow(error)
1837                    .as_ref()
1838                    .as_ref(),
1839            )
1840        }
1841        unsafe {
1842            let f: Box_<F> = Box_::new(f);
1843            connect_raw(
1844                self.as_ptr() as *mut _,
1845                b"closed\0".as_ptr() as *const _,
1846                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1847                    closed_trampoline::<F> as *const (),
1848                )),
1849                Box_::into_raw(f),
1850            )
1851        }
1852    }
1853
1854    #[doc(alias = "capabilities")]
1855    pub fn connect_capabilities_notify<F: Fn(&Self) + Send + Sync + 'static>(
1856        &self,
1857        f: F,
1858    ) -> SignalHandlerId {
1859        unsafe extern "C" fn notify_capabilities_trampoline<
1860            F: Fn(&DBusConnection) + Send + Sync + 'static,
1861        >(
1862            this: *mut ffi::GDBusConnection,
1863            _param_spec: glib::ffi::gpointer,
1864            f: glib::ffi::gpointer,
1865        ) {
1866            let f: &F = &*(f as *const F);
1867            f(&from_glib_borrow(this))
1868        }
1869        unsafe {
1870            let f: Box_<F> = Box_::new(f);
1871            connect_raw(
1872                self.as_ptr() as *mut _,
1873                b"notify::capabilities\0".as_ptr() as *const _,
1874                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1875                    notify_capabilities_trampoline::<F> as *const (),
1876                )),
1877                Box_::into_raw(f),
1878            )
1879        }
1880    }
1881
1882    #[doc(alias = "closed")]
1883    pub fn connect_closed_notify<F: Fn(&Self) + Send + Sync + 'static>(
1884        &self,
1885        f: F,
1886    ) -> SignalHandlerId {
1887        unsafe extern "C" fn notify_closed_trampoline<
1888            F: Fn(&DBusConnection) + Send + Sync + 'static,
1889        >(
1890            this: *mut ffi::GDBusConnection,
1891            _param_spec: glib::ffi::gpointer,
1892            f: glib::ffi::gpointer,
1893        ) {
1894            let f: &F = &*(f as *const F);
1895            f(&from_glib_borrow(this))
1896        }
1897        unsafe {
1898            let f: Box_<F> = Box_::new(f);
1899            connect_raw(
1900                self.as_ptr() as *mut _,
1901                b"notify::closed\0".as_ptr() as *const _,
1902                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1903                    notify_closed_trampoline::<F> as *const (),
1904                )),
1905                Box_::into_raw(f),
1906            )
1907        }
1908    }
1909
1910    #[doc(alias = "exit-on-close")]
1911    pub fn connect_exit_on_close_notify<F: Fn(&Self) + Send + Sync + 'static>(
1912        &self,
1913        f: F,
1914    ) -> SignalHandlerId {
1915        unsafe extern "C" fn notify_exit_on_close_trampoline<
1916            F: Fn(&DBusConnection) + Send + Sync + 'static,
1917        >(
1918            this: *mut ffi::GDBusConnection,
1919            _param_spec: glib::ffi::gpointer,
1920            f: glib::ffi::gpointer,
1921        ) {
1922            let f: &F = &*(f as *const F);
1923            f(&from_glib_borrow(this))
1924        }
1925        unsafe {
1926            let f: Box_<F> = Box_::new(f);
1927            connect_raw(
1928                self.as_ptr() as *mut _,
1929                b"notify::exit-on-close\0".as_ptr() as *const _,
1930                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1931                    notify_exit_on_close_trampoline::<F> as *const (),
1932                )),
1933                Box_::into_raw(f),
1934            )
1935        }
1936    }
1937
1938    #[doc(alias = "unique-name")]
1939    pub fn connect_unique_name_notify<F: Fn(&Self) + Send + Sync + 'static>(
1940        &self,
1941        f: F,
1942    ) -> SignalHandlerId {
1943        unsafe extern "C" fn notify_unique_name_trampoline<
1944            F: Fn(&DBusConnection) + Send + Sync + 'static,
1945        >(
1946            this: *mut ffi::GDBusConnection,
1947            _param_spec: glib::ffi::gpointer,
1948            f: glib::ffi::gpointer,
1949        ) {
1950            let f: &F = &*(f as *const F);
1951            f(&from_glib_borrow(this))
1952        }
1953        unsafe {
1954            let f: Box_<F> = Box_::new(f);
1955            connect_raw(
1956                self.as_ptr() as *mut _,
1957                b"notify::unique-name\0".as_ptr() as *const _,
1958                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1959                    notify_unique_name_trampoline::<F> as *const (),
1960                )),
1961                Box_::into_raw(f),
1962            )
1963        }
1964    }
1965}
1966
1967unsafe impl Send for DBusConnection {}
1968unsafe impl Sync for DBusConnection {}