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