Skip to main content

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