## GDBusConnection

GDBusConnection — D-Bus Connections

## Synopsis

    #include <gio/gio.h>

    enum                GBusType;
    void                g_bus_get                           (GBusType bus_type,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    GDBusConnection *   g_bus_get_finish                    (GAsyncResult *res,
                                                             GError **error);
    GDBusConnection *   g_bus_get_sync                      (GBusType bus_type,
                                                             GCancellable *cancellable,
                                                             GError **error);
                        GDBusConnection;
    enum                GDBusConnectionFlags;
    void                g_dbus_connection_new               (GIOStream *stream,
                                                             const gchar *guid,
                                                             GDBusConnectionFlags flags,
                                                             GDBusAuthObserver *observer,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    GDBusConnection *   g_dbus_connection_new_finish        (GAsyncResult *res,
                                                             GError **error);
    GDBusConnection *   g_dbus_connection_new_sync          (GIOStream *stream,
                                                             const gchar *guid,
                                                             GDBusConnectionFlags flags,
                                                             GDBusAuthObserver *observer,
                                                             GCancellable *cancellable,
                                                             GError **error);
    void                g_dbus_connection_new_for_address   (const gchar *address,
                                                             GDBusConnectionFlags flags,
                                                             GDBusAuthObserver *observer,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    GDBusConnection *   g_dbus_connection_new_for_address_finish
                                                            (GAsyncResult *res,
                                                             GError **error);
    GDBusConnection *   g_dbus_connection_new_for_address_sync
                                                            (const gchar *address,
                                                             GDBusConnectionFlags flags,
                                                             GDBusAuthObserver *observer,
                                                             GCancellable *cancellable,
                                                             GError **error);
    void                g_dbus_connection_start_message_processing
                                                            (GDBusConnection *connection);
    void                g_dbus_connection_close             (GDBusConnection *connection,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            g_dbus_connection_close_finish      (GDBusConnection *connection,
                                                             GAsyncResult *res,
                                                             GError **error);
    gboolean            g_dbus_connection_close_sync        (GDBusConnection *connection,
                                                             GCancellable *cancellable,
                                                             GError **error);
    gboolean            g_dbus_connection_is_closed         (GDBusConnection *connection);
    void                g_dbus_connection_flush             (GDBusConnection *connection,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    gboolean            g_dbus_connection_flush_finish      (GDBusConnection *connection,
                                                             GAsyncResult *res,
                                                             GError **error);
    gboolean            g_dbus_connection_flush_sync        (GDBusConnection *connection,
                                                             GCancellable *cancellable,
                                                             GError **error);
    gboolean            g_dbus_connection_get_exit_on_close (GDBusConnection *connection);
    void                g_dbus_connection_set_exit_on_close (GDBusConnection *connection,
                                                             gboolean exit_on_close);
    GIOStream *         g_dbus_connection_get_stream        (GDBusConnection *connection);
    const gchar *       g_dbus_connection_get_guid          (GDBusConnection *connection);
    const gchar *       g_dbus_connection_get_unique_name   (GDBusConnection *connection);
    enum                GDBusCapabilityFlags;
    GDBusCapabilityFlags  g_dbus_connection_get_capabilities
                                                            (GDBusConnection *connection);
    GCredentials *      g_dbus_connection_get_peer_credentials
                                                            (GDBusConnection *connection);
    enum                GDBusCallFlags;
    void                g_dbus_connection_call              (GDBusConnection *connection,
                                                             const gchar *bus_name,
                                                             const gchar *object_path,
                                                             const gchar *interface_name,
                                                             const gchar *method_name,
                                                             GVariant *parameters,
                                                             const GVariantType *reply_type,
                                                             GDBusCallFlags flags,
                                                             gint timeout_msec,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    GVariant *          g_dbus_connection_call_finish       (GDBusConnection *connection,
                                                             GAsyncResult *res,
                                                             GError **error);
    GVariant *          g_dbus_connection_call_sync         (GDBusConnection *connection,
                                                             const gchar *bus_name,
                                                             const gchar *object_path,
                                                             const gchar *interface_name,
                                                             const gchar *method_name,
                                                             GVariant *parameters,
                                                             const GVariantType *reply_type,
                                                             GDBusCallFlags flags,
                                                             gint timeout_msec,
                                                             GCancellable *cancellable,
                                                             GError **error);
    gboolean            g_dbus_connection_emit_signal       (GDBusConnection *connection,
                                                             const gchar *destination_bus_name,
                                                             const gchar *object_path,
                                                             const gchar *interface_name,
                                                             const gchar *signal_name,
                                                             GVariant *parameters,
                                                             GError **error);
    enum                GDBusSignalFlags;
    void                (*GDBusSignalCallback)              (GDBusConnection *connection,
                                                             const gchar *sender_name,
                                                             const gchar *object_path,
                                                             const gchar *interface_name,
                                                             const gchar *signal_name,
                                                             GVariant *parameters,
                                                             gpointer user_data);
    guint               g_dbus_connection_signal_subscribe  (GDBusConnection *connection,
                                                             const gchar *sender,
                                                             const gchar *interface_name,
                                                             const gchar *member,
                                                             const gchar *object_path,
                                                             const gchar *arg0,
                                                             GDBusSignalFlags flags,
                                                             GDBusSignalCallback callback,
                                                             gpointer user_data,
                                                             GDestroyNotify user_data_free_func);
    void                g_dbus_connection_signal_unsubscribe
                                                            (GDBusConnection *connection,
                                                             guint subscription_id);
    enum                GDBusSendMessageFlags;
    gboolean            g_dbus_connection_send_message      (GDBusConnection *connection,
                                                             GDBusMessage *message,
                                                             GDBusSendMessageFlags flags,
                                                             volatile guint32 *out_serial,
                                                             GError **error);
    void                g_dbus_connection_send_message_with_reply
                                                            (GDBusConnection *connection,
                                                             GDBusMessage *message,
                                                             GDBusSendMessageFlags flags,
                                                             gint timeout_msec,
                                                             volatile guint32 *out_serial,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
    GDBusMessage *      g_dbus_connection_send_message_with_reply_finish
                                                            (GDBusConnection *connection,
                                                             GAsyncResult *res,
                                                             GError **error);
    GDBusMessage *      g_dbus_connection_send_message_with_reply_sync
                                                            (GDBusConnection *connection,
                                                             GDBusMessage *message,
                                                             GDBusSendMessageFlags flags,
                                                             gint timeout_msec,
                                                             volatile guint32 *out_serial,
                                                             GCancellable *cancellable,
                                                             GError **error);
    GDBusMessage *      (*GDBusMessageFilterFunction)       (GDBusConnection *connection,
                                                             GDBusMessage *message,
                                                             gboolean incoming,
                                                             gpointer user_data);
    guint               g_dbus_connection_add_filter        (GDBusConnection *connection,
                                                             GDBusMessageFilterFunction filter_function,
                                                             gpointer user_data,
                                                             GDestroyNotify user_data_free_func);
    void                g_dbus_connection_remove_filter     (GDBusConnection *connection,
                                                             guint filter_id);
                        GDBusInterfaceVTable;
    void                (*GDBusInterfaceMethodCallFunc)     (GDBusConnection *connection,
                                                             const gchar *sender,
                                                             const gchar *object_path,
                                                             const gchar *interface_name,
                                                             const gchar *method_name,
                                                             GVariant *parameters,
                                                             GDBusMethodInvocation *invocation,
                                                             gpointer user_data);
    GVariant *          (*GDBusInterfaceGetPropertyFunc)    (GDBusConnection *connection,
                                                             const gchar *sender,
                                                             const gchar *object_path,
                                                             const gchar *interface_name,
                                                             const gchar *property_name,
                                                             GError **error,
                                                             gpointer user_data);
    gboolean            (*GDBusInterfaceSetPropertyFunc)    (GDBusConnection *connection,
                                                             const gchar *sender,
                                                             const gchar *object_path,
                                                             const gchar *interface_name,
                                                             const gchar *property_name,
                                                             GVariant *value,
                                                             GError **error,
                                                             gpointer user_data);
    guint               g_dbus_connection_register_object   (GDBusConnection *connection,
                                                             const gchar *object_path,
                                                             GDBusInterfaceInfo *interface_info,
                                                             const GDBusInterfaceVTable *vtable,
                                                             gpointer user_data,
                                                             GDestroyNotify user_data_free_func,
                                                             GError **error);
    gboolean            g_dbus_connection_unregister_object (GDBusConnection *connection,
                                                             guint registration_id);
                        GDBusSubtreeVTable;
    gchar **            (*GDBusSubtreeEnumerateFunc)        (GDBusConnection *connection,
                                                             const gchar *sender,
                                                             const gchar *object_path,
                                                             gpointer user_data);
    GDBusInterfaceInfo ** (*GDBusSubtreeIntrospectFunc)     (GDBusConnection *connection,
                                                             const gchar *sender,
                                                             const gchar *object_path,
                                                             const gchar *node,
                                                             gpointer user_data);
    const GDBusInterfaceVTable * (*GDBusSubtreeDispatchFunc)
                                                            (GDBusConnection *connection,
                                                             const gchar *sender,
                                                             const gchar *object_path,
                                                             const gchar *interface_name,
                                                             const gchar *node,
                                                             gpointer *out_user_data,
                                                             gpointer user_data);
    enum                GDBusSubtreeFlags;
    guint               g_dbus_connection_register_subtree  (GDBusConnection *connection,
                                                             const gchar *object_path,
                                                             const GDBusSubtreeVTable *vtable,
                                                             GDBusSubtreeFlags flags,
                                                             gpointer user_data,
                                                             GDestroyNotify user_data_free_func,
                                                             GError **error);
    gboolean            g_dbus_connection_unregister_subtree
                                                            (GDBusConnection *connection,
                                                             guint registration_id);

## Object Hierarchy

      GEnum
       +----GBusType

      GObject
       +----GDBusConnection

      GFlags
       +----GDBusConnectionFlags

      GFlags
       +----GDBusCapabilityFlags

## Implemented Interfaces

GDBusConnection implements GInitable and GAsyncInitable.

## Properties

      "address"                  gchar*                : Write / Construct Only
      "authentication-observer"  GDBusAuthObserver*    : Write / Construct Only
      "capabilities"             GDBusCapabilityFlags  : Read
      "closed"                   gboolean              : Read
      "exit-on-close"            gboolean              : Read / Write
      "flags"                    GDBusConnectionFlags  : Write / Construct Only
      "guid"                     gchar*                : Read / Write / Construct Only
      "stream"                   GIOStream*            : Read / Write / Construct Only
      "unique-name"              gchar*                : Read

## Signals

      "closed"                                         : Run Last

## Description

The GDBusConnection type is used for D-Bus connections to remote peers such as a message buses. It is a low-level API that offers a lot of flexibility. For instance, it lets you establish a connection over any transport that can by represented as an GIOStream.

This class is rarely used directly in D-Bus clients. If you are writing an D-Bus client, it is often easier to use the `g_bus_own_name()`, `g_bus_watch_name()` or `g_dbus_proxy_new_for_bus()` APIs.

Example 2. D-Bus server example

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392

    #include <gio/gio.h>
    #include <stdlib.h>

    #ifdef G_OS_UNIX
    #include <gio/gunixfdlist.h>
    /* For STDOUT_FILENO */
    #include <unistd.h>
    #endif

    /* ---------------------------------------------------------------------------------------------------- */

    static GDBusNodeInfo *introspection_data = NULL;

    /* Introspection data for the service we are exporting */
    static const gchar introspection_xml[] =
      "<node>"
      "  <interface name='org.gtk.GDBus.TestInterface'>"
      "    <annotation name='org.gtk.GDBus.Annotation' value='OnInterface'/>"
      "    <annotation name='org.gtk.GDBus.Annotation' value='AlsoOnInterface'/>"
      "    <method name='HelloWorld'>"
      "      <annotation name='org.gtk.GDBus.Annotation' value='OnMethod'/>"
      "      <arg type='s' name='greeting' direction='in'/>"
      "      <arg type='s' name='response' direction='out'/>"
      "    </method>"
      "    <method name='EmitSignal'>"
      "      <arg type='d' name='speed_in_mph' direction='in'>"
      "        <annotation name='org.gtk.GDBus.Annotation' value='OnArg'/>"
      "      </arg>"
      "    </method>"
      "    <method name='GimmeStdout'/>"
      "    <signal name='VelocityChanged'>"
      "      <annotation name='org.gtk.GDBus.Annotation' value='Onsignal'/>"
      "      <arg type='d' name='speed_in_mph'/>"
      "      <arg type='s' name='speed_as_string'>"
      "        <annotation name='org.gtk.GDBus.Annotation' value='OnArg_NonFirst'/>"
      "      </arg>"
      "    </signal>"
      "    <property type='s' name='FluxCapicitorName' access='read'>"
      "      <annotation name='org.gtk.GDBus.Annotation' value='OnProperty'>"
      "        <annotation name='org.gtk.GDBus.Annotation' value='OnAnnotation_YesThisIsCrazy'/>"
      "      </annotation>"
      "    </property>"
      "    <property type='s' name='Title' access='readwrite'/>"
      "    <property type='s' name='ReadingAlwaysThrowsError' access='read'/>"
      "    <property type='s' name='WritingAlwaysThrowsError' access='readwrite'/>"
      "    <property type='s' name='OnlyWritable' access='write'/>"
      "    <property type='s' name='Foo' access='read'/>"
      "    <property type='s' name='Bar' access='read'/>"
      "  </interface>"
      "</node>";

    /* ---------------------------------------------------------------------------------------------------- */

    static void
    handle_method_call (GDBusConnection       *connection,
                        const gchar           *sender,
                        const gchar           *object_path,
                        const gchar           *interface_name,
                        const gchar           *method_name,
                        GVariant              *parameters,
                        GDBusMethodInvocation *invocation,
                        gpointer               user_data)
    {
      if (g_strcmp0 (method_name, "HelloWorld") == 0)
        {
          const gchar *greeting;

          g_variant_get (parameters, "(&s)", &greeting);

          if (g_strcmp0 (greeting, "Return Unregistered") == 0)
            {
              g_dbus_method_invocation_return_error (invocation,
                                                     G_IO_ERROR,
                                                     G_IO_ERROR_FAILED_HANDLED,
                                                     "As requested, here's a GError not registered (G_IO_ERROR_FAILED_HANDLED)");
            }
          else if (g_strcmp0 (greeting, "Return Registered") == 0)
            {
              g_dbus_method_invocation_return_error (invocation,
                                                     G_DBUS_ERROR,
                                                     G_DBUS_ERROR_MATCH_RULE_NOT_FOUND,
                                                     "As requested, here's a GError that is registered (G_DBUS_ERROR_MATCH_RULE_NOT_FOUND)");
            }
          else if (g_strcmp0 (greeting, "Return Raw") == 0)
            {
              g_dbus_method_invocation_return_dbus_error (invocation,
                                                          "org.gtk.GDBus.SomeErrorName",
                                                          "As requested, here's a raw D-Bus error");
            }
          else
            {
              gchar *response;
              response = g_strdup_printf ("You greeted me with '%s'. Thanks!", greeting);
              g_dbus_method_invocation_return_value (invocation,
                                                     g_variant_new ("(s)", response));
              g_free (response);
            }
        }
      else if (g_strcmp0 (method_name, "EmitSignal") == 0)
        {
          GError *local_error;
          gdouble speed_in_mph;
          gchar *speed_as_string;

          g_variant_get (parameters, "(d)", &speed_in_mph);
          speed_as_string = g_strdup_printf ("%g mph!", speed_in_mph);

          local_error = NULL;
          g_dbus_connection_emit_signal (connection,
                                         NULL,
                                         object_path,
                                         interface_name,
                                         "VelocityChanged",
                                         g_variant_new ("(ds)",
                                                        speed_in_mph,
                                                        speed_as_string),
                                         &local_error);
          g_assert_no_error (local_error);
          g_free (speed_as_string);

          g_dbus_method_invocation_return_value (invocation, NULL);
        }
      else if (g_strcmp0 (method_name, "GimmeStdout") == 0)
        {
    #ifdef G_OS_UNIX
          if (g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING)
            {
              GDBusMessage *reply;
              GUnixFDList *fd_list;
              GError *error;

              fd_list = g_unix_fd_list_new ();
              error = NULL;
              g_unix_fd_list_append (fd_list, STDOUT_FILENO, &error);
              g_assert_no_error (error);

              reply = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation));
              g_dbus_message_set_unix_fd_list (reply, fd_list);

              error = NULL;
              g_dbus_connection_send_message (connection,
                                              reply,
                                              G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                              NULL, /* out_serial */
                                              &error);
              g_assert_no_error (error);

              g_object_unref (invocation);
              g_object_unref (fd_list);
              g_object_unref (reply);
            }
          else
            {
              g_dbus_method_invocation_return_dbus_error (invocation,
                                                          "org.gtk.GDBus.Failed",
                                                          "Your message bus daemon does not support file descriptor passing (need D-Bus >= 1.3.0)");
            }
    #else
          g_dbus_method_invocation_return_dbus_error (invocation,
                                                      "org.gtk.GDBus.NotOnUnix",
                                                      "Your OS does not support file descriptor passing");
    #endif
        }
    }

    static gchar *_global_title = NULL;

    static gboolean swap_a_and_b = FALSE;

    static GVariant *
    handle_get_property (GDBusConnection  *connection,
                         const gchar      *sender,
                         const gchar      *object_path,
                         const gchar      *interface_name,
                         const gchar      *property_name,
                         GError          **error,
                         gpointer          user_data)
    {
      GVariant *ret;

      ret = NULL;
      if (g_strcmp0 (property_name, "FluxCapicitorName") == 0)
        {
          ret = g_variant_new_string ("DeLorean");
        }
      else if (g_strcmp0 (property_name, "Title") == 0)
        {
          if (_global_title == NULL)
            _global_title = g_strdup ("Back To C!");
          ret = g_variant_new_string (_global_title);
        }
      else if (g_strcmp0 (property_name, "ReadingAlwaysThrowsError") == 0)
        {
          g_set_error (error,
                       G_IO_ERROR,
                       G_IO_ERROR_FAILED,
                       "Hello %s. I thought I said reading this property "
                       "always results in an error. kthxbye",
                       sender);
        }
      else if (g_strcmp0 (property_name, "WritingAlwaysThrowsError") == 0)
        {
          ret = g_variant_new_string ("There's no home like home");
        }
      else if (g_strcmp0 (property_name, "Foo") == 0)
        {
          ret = g_variant_new_string (swap_a_and_b ? "Tock" : "Tick");
        }
      else if (g_strcmp0 (property_name, "Bar") == 0)
        {
          ret = g_variant_new_string (swap_a_and_b ? "Tick" : "Tock");
        }

      return ret;
    }

    static gboolean
    handle_set_property (GDBusConnection  *connection,
                         const gchar      *sender,
                         const gchar      *object_path,
                         const gchar      *interface_name,
                         const gchar      *property_name,
                         GVariant         *value,
                         GError          **error,
                         gpointer          user_data)
    {
      if (g_strcmp0 (property_name, "Title") == 0)
        {
          if (g_strcmp0 (_global_title, g_variant_get_string (value, NULL)) != 0)
            {
              GVariantBuilder *builder;
              GError *local_error;

              g_free (_global_title);
              _global_title = g_variant_dup_string (value, NULL);

              local_error = NULL;
              builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
              g_variant_builder_add (builder,
                                     "{sv}",
                                     "Title",
                                     g_variant_new_string (_global_title));
              g_dbus_connection_emit_signal (connection,
                                             NULL,
                                             object_path,
                                             "org.freedesktop.DBus.Properties",
                                             "PropertiesChanged",
                                             g_variant_new ("(sa{sv}as)",
                                                            interface_name,
                                                            builder,
                                                            NULL),
                                             &local_error);
              g_assert_no_error (local_error);
            }
        }
      else if (g_strcmp0 (property_name, "ReadingAlwaysThrowsError") == 0)
        {
          /* do nothing - they can't read it after all! */
        }
      else if (g_strcmp0 (property_name, "WritingAlwaysThrowsError") == 0)
        {
          g_set_error (error,
                       G_IO_ERROR,
                       G_IO_ERROR_FAILED,
                       "Hello AGAIN %s. I thought I said writing this property "
                       "always results in an error. kthxbye",
                       sender);
        }

      return *error == NULL;
    }

    /* for now */
    static const GDBusInterfaceVTable interface_vtable =
    {
      handle_method_call,
      handle_get_property,
      handle_set_property
    };

    /* ---------------------------------------------------------------------------------------------------- */

    static gboolean
    on_timeout_cb (gpointer user_data)
    {
      GDBusConnection *connection = G_DBUS_CONNECTION (user_data);
      GVariantBuilder *builder;
      GVariantBuilder *invalidated_builder;
      GError *error;

      swap_a_and_b = !swap_a_and_b;

      error = NULL;
      builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
      invalidated_builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
      g_variant_builder_add (builder,
                             "{sv}",
                             "Foo",
                             g_variant_new_string (swap_a_and_b ? "Tock" : "Tick"));
      g_variant_builder_add (builder,
                             "{sv}",
                             "Bar",
                             g_variant_new_string (swap_a_and_b ? "Tick" : "Tock"));
      g_dbus_connection_emit_signal (connection,
                                     NULL,
                                     "/org/gtk/GDBus/TestObject",
                                     "org.freedesktop.DBus.Properties",
                                     "PropertiesChanged",
                                     g_variant_new ("(sa{sv}as)",
                                                    "org.gtk.GDBus.TestInterface",
                                                    builder,
                                                    invalidated_builder),
                                     &error);
      g_assert_no_error (error);

      return TRUE;
    }

    /* ---------------------------------------------------------------------------------------------------- */

    static void
    on_bus_acquired (GDBusConnection *connection,
                     const gchar     *name,
                     gpointer         user_data)
    {
      guint registration_id;

      registration_id = g_dbus_connection_register_object (connection,
                                                           "/org/gtk/GDBus/TestObject",
                                                           introspection_data->interfaces[0],
                                                           &interface_vtable,
                                                           NULL,  /* user_data */
                                                           NULL,  /* user_data_free_func */
                                                           NULL); /* GError** */
      g_assert (registration_id > 0);

      /* swap value of properties Foo and Bar every two seconds */
      g_timeout_add_seconds (2,
                             on_timeout_cb,
                             connection);
    }

    static void
    on_name_acquired (GDBusConnection *connection,
                      const gchar     *name,
                      gpointer         user_data)
    {
    }

    static void
    on_name_lost (GDBusConnection *connection,
                  const gchar     *name,
                  gpointer         user_data)
    {
      exit (1);
    }

    int
    main (int argc, char *argv[])
    {
      guint owner_id;
      GMainLoop *loop;

      g_type_init ();

      /* We are lazy here - we don't want to manually provide
       * the introspection data structures - so we just build
       * them from XML.
       */
      introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
      g_assert (introspection_data != NULL);

      owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
                                 "org.gtk.GDBus.TestServer",
                                 G_BUS_NAME_OWNER_FLAGS_NONE,
                                 on_bus_acquired,
                                 on_name_acquired,
                                 on_name_lost,
                                 NULL,
                                 NULL);

      loop = g_main_loop_new (NULL, FALSE);
      g_main_loop_run (loop);

      g_bus_unown_name (owner_id);

      g_dbus_node_info_unref (introspection_data);

      return 0;
    }

Example 3. D-Bus subtree example

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400

    #include <gio/gio.h>
    #include <stdlib.h>
    #include <string.h>

    /* ---------------------------------------------------------------------------------------------------- */

    static GDBusNodeInfo *introspection_data = NULL;
    static GDBusInterfaceInfo *manager_interface_info = NULL;
    static GDBusInterfaceInfo *block_interface_info = NULL;
    static GDBusInterfaceInfo *partition_interface_info = NULL;

    /* Introspection data for the service we are exporting */
    static const gchar introspection_xml[] =
      "<node>"
      "  <interface name='org.gtk.GDBus.Example.Manager'>"
      "    <method name='Hello'>"
      "      <arg type='s' name='greeting' direction='in'/>"
      "      <arg type='s' name='response' direction='out'/>"
      "    </method>"
      "  </interface>"
      "  <interface name='org.gtk.GDBus.Example.Block'>"
      "    <method name='Hello'>"
      "      <arg type='s' name='greeting' direction='in'/>"
      "      <arg type='s' name='response' direction='out'/>"
      "    </method>"
      "    <property type='i' name='Major' access='read'/>"
      "    <property type='i' name='Minor' access='read'/>"
      "    <property type='s' name='Notes' access='readwrite'/>"
      "  </interface>"
      "  <interface name='org.gtk.GDBus.Example.Partition'>"
      "    <method name='Hello'>"
      "      <arg type='s' name='greeting' direction='in'/>"
      "      <arg type='s' name='response' direction='out'/>"
      "    </method>"
      "    <property type='i' name='PartitionNumber' access='read'/>"
      "    <property type='s' name='Notes' access='readwrite'/>"
      "  </interface>"
      "</node>";

    /* ---------------------------------------------------------------------------------------------------- */

    static void
    manager_method_call (GDBusConnection       *connection,
                         const gchar           *sender,
                         const gchar           *object_path,
                         const gchar           *interface_name,
                         const gchar           *method_name,
                         GVariant              *parameters,
                         GDBusMethodInvocation *invocation,
                         gpointer               user_data)
    {
      const gchar *greeting;
      gchar *response;

      g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.Example.Manager");
      g_assert_cmpstr (method_name, ==, "Hello");

      g_variant_get (parameters, "(&s)", &greeting);

      response = g_strdup_printf ("Method %s.%s with user_data `%s' on object path %s called with arg '%s'",
                                  interface_name,
                                  method_name,
                                  (const gchar *) user_data,
                                  object_path,
                                  greeting);
      g_dbus_method_invocation_return_value (invocation,
                                             g_variant_new ("(s)", response));
      g_free (response);
    }

    const GDBusInterfaceVTable manager_vtable =
    {
      manager_method_call,
      NULL,                 /* get_property */
      NULL                  /* set_property */
    };

    /* ---------------------------------------------------------------------------------------------------- */

    static void
    block_method_call (GDBusConnection       *connection,
                       const gchar           *sender,
                       const gchar           *object_path,
                       const gchar           *interface_name,
                       const gchar           *method_name,
                       GVariant              *parameters,
                       GDBusMethodInvocation *invocation,
                       gpointer               user_data)
    {
      g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.Example.Block");

      if (g_strcmp0 (method_name, "Hello") == 0)
        {
          const gchar *greeting;
          gchar *response;

          g_variant_get (parameters, "(&s)", &greeting);

          response = g_strdup_printf ("Method %s.%s with user_data `%s' on object path %s called with arg '%s'",
                                      interface_name,
                                      method_name,
                                      (const gchar *) user_data,
                                      object_path,
                                      greeting);
          g_dbus_method_invocation_return_value (invocation,
                                                 g_variant_new ("(s)", response));
          g_free (response);
        }
      else if (g_strcmp0 (method_name, "DoStuff") == 0)
        {
          g_dbus_method_invocation_return_dbus_error (invocation,
                                                      "org.gtk.GDBus.TestSubtree.Error.Failed",
                                                      "This method intentionally always fails");
        }
      else
        {
          g_assert_not_reached ();
        }
    }

    static GVariant *
    block_get_property (GDBusConnection  *connection,
                        const gchar      *sender,
                        const gchar      *object_path,
                        const gchar      *interface_name,
                        const gchar      *property_name,
                        GError          **error,
                        gpointer          user_data)
    {
      GVariant *ret;
      const gchar *node;
      gint major;
      gint minor;

      node = strrchr (object_path, '/') + 1;
      if (g_str_has_prefix (node, "sda"))
        major = 8;
      else
        major = 9;
      if (strlen (node) == 4)
        minor = node[3] - '0';
      else
        minor = 0;

      ret = NULL;
      if (g_strcmp0 (property_name, "Major") == 0)
        {
          ret = g_variant_new_int32 (major);
        }
      else if (g_strcmp0 (property_name, "Minor") == 0)
        {
          ret = g_variant_new_int32 (minor);
        }
      else if (g_strcmp0 (property_name, "Notes") == 0)
        {
          g_set_error (error,
                       G_IO_ERROR,
                       G_IO_ERROR_FAILED,
                       "Hello %s. I thought I said reading this property "
                       "always results in an error. kthxbye",
                       sender);
        }
      else
        {
          g_assert_not_reached ();
        }

      return ret;
    }

    static gboolean
    block_set_property (GDBusConnection  *connection,
                        const gchar      *sender,
                        const gchar      *object_path,
                        const gchar      *interface_name,
                        const gchar      *property_name,
                        GVariant         *value,
                        GError          **error,
                        gpointer          user_data)
    {
      /* TODO */
      g_assert_not_reached ();
    }

    const GDBusInterfaceVTable block_vtable =
    {
      block_method_call,
      block_get_property,
      block_set_property,
    };

    /* ---------------------------------------------------------------------------------------------------- */

    static void
    partition_method_call (GDBusConnection       *connection,
                           const gchar           *sender,
                           const gchar           *object_path,
                           const gchar           *interface_name,
                           const gchar           *method_name,
                           GVariant              *parameters,
                           GDBusMethodInvocation *invocation,
                           gpointer               user_data)
    {
      const gchar *greeting;
      gchar *response;

      g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.Example.Partition");
      g_assert_cmpstr (method_name, ==, "Hello");

      g_variant_get (parameters, "(&s)", &greeting);

      response = g_strdup_printf ("Method %s.%s with user_data `%s' on object path %s called with arg '%s'",
                                  interface_name,
                                  method_name,
                                  (const gchar *) user_data,
                                  object_path,
                                  greeting);
      g_dbus_method_invocation_return_value (invocation,
                                             g_variant_new ("(s)", response));
      g_free (response);
    }

    const GDBusInterfaceVTable partition_vtable =
    {
      partition_method_call,
      //partition_get_property,
      //partition_set_property
    };

    /* ---------------------------------------------------------------------------------------------------- */

    static gchar **
    subtree_enumerate (GDBusConnection       *connection,
                       const gchar           *sender,
                       const gchar           *object_path,
                       gpointer               user_data)
    {
      gchar **nodes;
      GPtrArray *p;

      p = g_ptr_array_new ();
      g_ptr_array_add (p, g_strdup ("sda"));
      g_ptr_array_add (p, g_strdup ("sda1"));
      g_ptr_array_add (p, g_strdup ("sda2"));
      g_ptr_array_add (p, g_strdup ("sda3"));
      g_ptr_array_add (p, g_strdup ("sdb"));
      g_ptr_array_add (p, g_strdup ("sdb1"));
      g_ptr_array_add (p, g_strdup ("sdc"));
      g_ptr_array_add (p, g_strdup ("sdc1"));
      g_ptr_array_add (p, NULL);
      nodes = (gchar **) g_ptr_array_free (p, FALSE);

      return nodes;
    }

    static GDBusInterfaceInfo **
    subtree_introspect (GDBusConnection       *connection,
                        const gchar           *sender,
                        const gchar           *object_path,
                        const gchar           *node,
                        gpointer               user_data)
    {
      GPtrArray *p;

      p = g_ptr_array_new ();
      if (node == NULL)
        {
          g_ptr_array_add (p, g_dbus_interface_info_ref (manager_interface_info));
        }
      else
        {
          g_ptr_array_add (p, g_dbus_interface_info_ref (block_interface_info));
          if (strlen (node) == 4)
            g_ptr_array_add (p,
                             g_dbus_interface_info_ref (partition_interface_info));
        }

      g_ptr_array_add (p, NULL);

      return (GDBusInterfaceInfo **) g_ptr_array_free (p, FALSE);
    }

    static const GDBusInterfaceVTable *
    subtree_dispatch (GDBusConnection             *connection,
                      const gchar                 *sender,
                      const gchar                 *object_path,
                      const gchar                 *interface_name,
                      const gchar                 *node,
                      gpointer                    *out_user_data,
                      gpointer                     user_data)
    {
      const GDBusInterfaceVTable *vtable_to_return;
      gpointer user_data_to_return;

      if (g_strcmp0 (interface_name, "org.gtk.GDBus.Example.Manager") == 0)
        {
          user_data_to_return = "The Root";
          vtable_to_return = &manager_vtable;
        }
      else
        {
          if (strlen (node) == 4)
            user_data_to_return = "A partition";
          else
            user_data_to_return = "A block device";

          if (g_strcmp0 (interface_name, "org.gtk.GDBus.Example.Block") == 0)
            vtable_to_return = &block_vtable;
          else if (g_strcmp0 (interface_name, "org.gtk.GDBus.Example.Partition") == 0)
            vtable_to_return = &partition_vtable;
          else
            g_assert_not_reached ();
        }

      *out_user_data = user_data_to_return;

      return vtable_to_return;
    }

    const GDBusSubtreeVTable subtree_vtable =
    {
      subtree_enumerate,
      subtree_introspect,
      subtree_dispatch
    };

    /* ---------------------------------------------------------------------------------------------------- */

    static void
    on_bus_acquired (GDBusConnection *connection,
                     const gchar     *name,
                     gpointer         user_data)
    {
      guint registration_id;

      registration_id = g_dbus_connection_register_subtree (connection,
                                                            "/org/gtk/GDBus/TestSubtree/Devices",
                                                            &subtree_vtable,
                                                            G_DBUS_SUBTREE_FLAGS_NONE,
                                                            NULL,  /* user_data */
                                                            NULL,  /* user_data_free_func */
                                                            NULL); /* GError** */
      g_assert (registration_id > 0);
    }

    static void
    on_name_acquired (GDBusConnection *connection,
                      const gchar     *name,
                      gpointer         user_data)
    {
    }

    static void
    on_name_lost (GDBusConnection *connection,
                  const gchar     *name,
                  gpointer         user_data)
    {
      exit (1);
    }

    int
    main (int argc, char *argv[])
    {
      guint owner_id;
      GMainLoop *loop;

      g_type_init ();

      /* We are lazy here - we don't want to manually provide
       * the introspection data structures - so we just build
       * them from XML.
       */
      introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
      g_assert (introspection_data != NULL);

      manager_interface_info = g_dbus_node_info_lookup_interface (introspection_data, "org.gtk.GDBus.Example.Manager");
      block_interface_info = g_dbus_node_info_lookup_interface (introspection_data, "org.gtk.GDBus.Example.Block");
      partition_interface_info = g_dbus_node_info_lookup_interface (introspection_data, "org.gtk.GDBus.Example.Partition");
      g_assert (manager_interface_info != NULL);
      g_assert (block_interface_info != NULL);
      g_assert (partition_interface_info != NULL);

      owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
                                 "org.gtk.GDBus.TestSubtree",
                                 G_BUS_NAME_OWNER_FLAGS_NONE,
                                 on_bus_acquired,
                                 on_name_acquired,
                                 on_name_lost,
                                 NULL,
                                 NULL);

      loop = g_main_loop_new (NULL, FALSE);
      g_main_loop_run (loop);

      g_bus_unown_name (owner_id);

      g_dbus_node_info_unref (introspection_data);

      return 0;
    }

Example 4. D-Bus UNIX File Descriptor example

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134

    #include <string.h>
    #include <stdlib.h>

    #include <sys/types.h>
    #include <unistd.h>

    #include <time.h>

    #include <gio/gio.h>
    #include <gio/gunixfdlist.h>

    /* see gdbus-example-server.c for the server implementation */
    static gint
    get_server_stdout (GDBusConnection  *connection,
                       const gchar      *name_owner,
                       GError          **error)
    {
      GDBusMessage *method_call_message;
      GDBusMessage *method_reply_message;
      GUnixFDList *fd_list;
      gint fd;

      fd = -1;
      method_call_message = NULL;
      method_reply_message = NULL;

      method_call_message = g_dbus_message_new_method_call (name_owner,
                                                            "/org/gtk/GDBus/TestObject",
                                                            "org.gtk.GDBus.TestInterface",
                                                            "GimmeStdout");
      method_reply_message = g_dbus_connection_send_message_with_reply_sync (connection,
                                                                             method_call_message,
                                                                             G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                                                             -1,
                                                                             NULL, /* out_serial */
                                                                             NULL, /* cancellable */
                                                                             error);
      if (method_reply_message == NULL)
          goto out;

      if (g_dbus_message_get_message_type (method_reply_message) == G_DBUS_MESSAGE_TYPE_ERROR)
        {
          g_dbus_message_to_gerror (method_reply_message, error);
          goto out;
        }

      fd_list = g_dbus_message_get_unix_fd_list (method_reply_message);
      fd = g_unix_fd_list_get (fd_list, 0, error);

     out:
      g_object_unref (method_call_message);
      g_object_unref (method_reply_message);

      return fd;
    }

    static void
    on_name_appeared (GDBusConnection *connection,
                      const gchar     *name,
                      const gchar     *name_owner,
                      gpointer         user_data)
    {
      gint fd;
      GError *error;

      error = NULL;
      fd = get_server_stdout (connection, name_owner, &error);
      if (fd == -1)
        {
          g_printerr ("Error invoking GimmeStdout(): %s\n",
                      error->message);
          g_error_free (error);
          exit (1);
        }
      else
        {
          gchar now_buf[256];
          time_t now;
          gssize len;
          gchar *str;

          now = time (NULL);
          strftime (now_buf,
                    sizeof now_buf,
                    "%c",
                    localtime (&now));

          str = g_strdup_printf ("On %s, gdbus-example-unix-fd-client with pid %d was here!\n",
                                 now_buf,
                                 (gint) getpid ());
          len = strlen (str);
          g_warn_if_fail (write (fd, str, len) == len);
          close (fd);

          g_print ("Wrote the following on server's stdout:\n%s", str);

          g_free (str);
          exit (0);
        }
    }

    static void
    on_name_vanished (GDBusConnection *connection,
                      const gchar     *name,
                      gpointer         user_data)
    {
      g_printerr ("Failed to get name owner for %s\n"
                  "Is ./gdbus-example-server running?\n",
                  name);
      exit (1);
    }

    int
    main (int argc, char *argv[])
    {
      guint watcher_id;
      GMainLoop *loop;

      g_type_init ();

      watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
                                     "org.gtk.GDBus.TestServer",
                                     G_BUS_NAME_WATCHER_FLAGS_NONE,
                                     on_name_appeared,
                                     on_name_vanished,
                                     NULL,
                                     NULL);

      loop = g_main_loop_new (NULL, FALSE);
      g_main_loop_run (loop);

      g_bus_unwatch_name (watcher_id);
      return 0;
    }

Example 5. Exporting a GObject

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335

    #include <gio/gio.h>
    #include <stdlib.h>

    /* ---------------------------------------------------------------------------------------------------- */

    /* The object we want to export */
    typedef struct _MyObjectClass MyObjectClass;
    typedef struct _MyObject MyObject;

    struct _MyObjectClass
    {
      GObjectClass parent_class;
    };

    struct _MyObject
    {
      GObject parent_instance;

      gint count;
      gchar *name;
    };

    enum
    {
      PROP_0,
      PROP_COUNT,
      PROP_NAME
    };

    G_DEFINE_TYPE (MyObject, my_object, G_TYPE_OBJECT);

    static void
    my_object_finalize (GObject *object)
    {
      MyObject *myobj = (MyObject*)object;

      g_free (myobj->name);

      G_OBJECT_CLASS (my_object_parent_class)->finalize (object);
    }

    static void
    my_object_init (MyObject *object)
    {
      object->count = 0;
      object->name = NULL;
    }

    static void
    my_object_get_property (GObject    *object,
                            guint       prop_id,
                            GValue     *value,
                            GParamSpec *pspec)
    {
      MyObject *myobj = (MyObject*)object;

      switch (prop_id)
        {
        case PROP_COUNT:
          g_value_set_int (value, myobj->count);
          break;

        case PROP_NAME:
          g_value_set_string (value, myobj->name);
          break;

        default:
          G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
        }
    }

    static void
    my_object_set_property (GObject      *object,
                            guint         prop_id,
                            const GValue *value,
                            GParamSpec   *pspec)
    {
      MyObject *myobj = (MyObject*)object;

      switch (prop_id)
        {
        case PROP_COUNT:
          myobj->count = g_value_get_int (value);
          break;

        case PROP_NAME:
          g_free (myobj->name);
          myobj->name = g_value_dup_string (value);
          break;

        default:
          G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
        }
    }

    static void
    my_object_class_init (MyObjectClass *class)
    {
      GObjectClass *gobject_class = G_OBJECT_CLASS (class);

      gobject_class->finalize = my_object_finalize;
      gobject_class->set_property = my_object_set_property;
      gobject_class->get_property = my_object_get_property;

      g_object_class_install_property (gobject_class,
                                       PROP_COUNT,
                                       g_param_spec_int ("count",
                                                         "Count",
                                                         "Count",
                                                         0, 99999, 0,
                                                         G_PARAM_READWRITE));

      g_object_class_install_property (gobject_class,
                                       PROP_NAME,
                                       g_param_spec_string ("name",
                                                            "Name",
                                                            "Name",
                                                            NULL,
                                                            G_PARAM_READWRITE));
    }

    /* A method that we want to export */
    void
    my_object_change_count (MyObject *myobj,
                            gint      change)
    {
      myobj->count = 2 * myobj->count + change;

      g_object_notify (G_OBJECT (myobj), "count");
    }

    /* ---------------------------------------------------------------------------------------------------- */

    static GDBusNodeInfo *introspection_data = NULL;

    /* Introspection data for the service we are exporting */
    static const gchar introspection_xml[] =
      "<node>"
      "  <interface name='org.myorg.MyObject'>"
      "    <method name='ChangeCount'>"
      "      <arg type='i' name='change' direction='in'/>"
      "    </method>"
      "    <property type='i' name='Count' access='read'/>"
      "    <property type='s' name='Name' access='readwrite'/>"
      "  </interface>"
      "</node>";

    static void
    handle_method_call (GDBusConnection       *connection,
                        const gchar           *sender,
                        const gchar           *object_path,
                        const gchar           *interface_name,
                        const gchar           *method_name,
                        GVariant              *parameters,
                        GDBusMethodInvocation *invocation,
                        gpointer               user_data)
    {
      MyObject *myobj = user_data;

      if (g_strcmp0 (method_name, "ChangeCount") == 0)
        {
          gint change;
          g_variant_get (parameters, "(i)", &change);

          my_object_change_count (myobj, change);

          g_dbus_method_invocation_return_value (invocation, NULL);
        }
    }

    static GVariant *
    handle_get_property (GDBusConnection  *connection,
                         const gchar      *sender,
                         const gchar      *object_path,
                         const gchar      *interface_name,
                         const gchar      *property_name,
                         GError          **error,
                         gpointer          user_data)
    {
      GVariant *ret;
      MyObject *myobj = user_data;

      ret = NULL;
      if (g_strcmp0 (property_name, "Count") == 0)
        {
          ret = g_variant_new_int32 (myobj->count);
        }
      else if (g_strcmp0 (property_name, "Name") == 0)
        {
          ret = g_variant_new_string (myobj->name ? myobj->name : "");
        }

      return ret;
    }

    static gboolean
    handle_set_property (GDBusConnection  *connection,
                         const gchar      *sender,
                         const gchar      *object_path,
                         const gchar      *interface_name,
                         const gchar      *property_name,
                         GVariant         *value,
                         GError          **error,
                         gpointer          user_data)
    {
      MyObject *myobj = user_data;

      if (g_strcmp0 (property_name, "Count") == 0)
        {
          g_object_set (myobj, "count", g_variant_get_int32 (value), NULL);
        }
      else if (g_strcmp0 (property_name, "Name") == 0)
        {
          g_object_set (myobj, "name", g_variant_get_string (value, NULL), NULL);
        }

      return TRUE;
    }

    /* for now */
    static const GDBusInterfaceVTable interface_vtable =
    {
      handle_method_call,
      handle_get_property,
      handle_set_property
    };

    static void
    send_property_change (GObject         *obj,
                          GParamSpec      *pspec,
                          GDBusConnection *connection)
    {
      GVariantBuilder *builder;
      GVariantBuilder *invalidated_builder;
      MyObject *myobj = (MyObject *)obj;

      builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
      invalidated_builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));

      if (g_strcmp0 (pspec->name, "count") == 0)
        g_variant_builder_add (builder,
                               "{sv}",
                               "Count", g_variant_new_int32 (myobj->count));
      else if (g_strcmp0 (pspec->name, "name") == 0)
        g_variant_builder_add (builder,
                               "{sv}",
                               "Name", g_variant_new_string (myobj->name ? myobj->name : ""));

      g_dbus_connection_emit_signal (connection,
                                     NULL,
                                     "/org/myorg/MyObject",
                                     "org.freedesktop.DBus.Properties",
                                     "PropertiesChanged",
                                     g_variant_new ("(sa{sv}as)",
                                                    "org.myorg.MyObject",
                                                    builder,
                                                    invalidated_builder),
                                     NULL);
    }

    static void
    on_bus_acquired (GDBusConnection *connection,
                     const gchar     *name,
                     gpointer         user_data)
    {
      MyObject *myobj = user_data;
      guint registration_id;

      g_signal_connect (myobj, "notify",
                        G_CALLBACK (send_property_change), connection);
      registration_id = g_dbus_connection_register_object (connection,
                                                           "/org/myorg/MyObject",
                                                           introspection_data->interfaces[0],
                                                           &interface_vtable,
                                                           myobj,
                                                           NULL,  /* user_data_free_func */
                                                           NULL); /* GError** */
      g_assert (registration_id > 0);
    }

    static void
    on_name_acquired (GDBusConnection *connection,
                      const gchar     *name,
                      gpointer         user_data)
    {
    }

    static void
    on_name_lost (GDBusConnection *connection,
                  const gchar     *name,
                  gpointer         user_data)
    {
      exit (1);
    }

    int
    main (int argc, char *argv[])
    {
      guint owner_id;
      GMainLoop *loop;
      MyObject *myobj;

      g_type_init ();

      /* We are lazy here - we don't want to manually provide
       * the introspection data structures - so we just build
       * them from XML.
       */
      introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
      g_assert (introspection_data != NULL);

      myobj = g_object_new (my_object_get_type (), NULL);

      owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
                                 "org.myorg.MyObject",
                                 G_BUS_NAME_OWNER_FLAGS_NONE,
                                 on_bus_acquired,
                                 on_name_acquired,
                                 on_name_lost,
                                 myobj,
                                 NULL);

      loop = g_main_loop_new (NULL, FALSE);
      g_main_loop_run (loop);

      g_bus_unown_name (owner_id);

      g_dbus_node_info_unref (introspection_data);

      g_object_unref (myobj);

      return 0;
    }

## Details

### enum GBusType

    typedef enum
    {
      G_BUS_TYPE_STARTER = -1,
      G_BUS_TYPE_NONE = 0,
      G_BUS_TYPE_SYSTEM  = 1,
      G_BUS_TYPE_SESSION = 2
    } GBusType;

An enumeration for well-known message buses.

`G_BUS_TYPE_STARTER` | An alias for the message bus that activated the process, if any.
`G_BUS_TYPE_NONE` | Not a message bus.
`G_BUS_TYPE_SYSTEM` | The system-wide message bus.
`G_BUS_TYPE_SESSION` | The login session message bus.

Since 2.26

### g_bus_get ()

    void                g_bus_get                           (GBusType bus_type,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Asynchronously connects to the message bus specified by `bus_type`.

When the operation is finished, `callback` will be invoked. You can then call `g_bus_get_finish()` to get the result of the operation.

This is a asynchronous failable function. See `g_bus_get_sync()` for the synchronous version.

`bus_type` : | A GBusType.
`cancellable` : | A GCancellable or `NULL`.
`callback` : | A GAsyncReadyCallback to call when the request is satisfied.
`user_data` : | The data to pass to `callback`.

Since 2.26

### g_bus_get_finish ()

    GDBusConnection *   g_bus_get_finish                    (GAsyncResult *res,
                                                             GError **error);

Finishes an operation started with `g_bus_get()`.

The returned object is a singleton, that is, shared with other callers of `g_bus_get()` and `g_bus_get_sync()` for `bus_type`. In the event that you need a private message bus connection, use `g_dbus_address_get_for_bus()` and `g_dbus_connection_new_for_address()`.

Note that the returned GDBusConnection object will (usually) have the "exit-on-close" property set to `TRUE`.

`res` : | A GAsyncResult obtained from the GAsyncReadyCallback passed to `g_bus_get()`.
`error` : | Return location for error or `NULL`.
Returns : | A GDBusConnection or `NULL` if `error` is set. Free with `g_object_unref()`. [transfer full]

Since 2.26

### g_bus_get_sync ()

    GDBusConnection *   g_bus_get_sync                      (GBusType bus_type,
                                                             GCancellable *cancellable,
                                                             GError **error);

Synchronously connects to the message bus specified by `bus_type`. Note that the returned object may shared with other callers, e.g. if two separate parts of a process calls this function with the same `bus_type`, they will share the same object.

This is a synchronous failable function. See `g_bus_get()` and `g_bus_get_finish()` for the asynchronous version.

The returned object is a singleton, that is, shared with other callers of `g_bus_get()` and `g_bus_get_sync()` for `bus_type`. In the event that you need a private message bus connection, use `g_dbus_address_get_for_bus_sync()` and `g_dbus_connection_new_for_address()`.

Note that the returned GDBusConnection object will (usually) have the "exit-on-close" property set to `TRUE`.

`bus_type` : | A GBusType.
`cancellable` : | A GCancellable or `NULL`.
`error` : | Return location for error or `NULL`.
Returns : | A GDBusConnection or `NULL` if `error` is set. Free with `g_object_unref()`. [transfer full]

Since 2.26

### GDBusConnection

    typedef struct _GDBusConnection GDBusConnection;

The GDBusConnection structure contains only private data and should only be accessed using the provided API.

Since 2.26

### enum GDBusConnectionFlags

    typedef enum {
      G_DBUS_CONNECTION_FLAGS_NONE = 0,
      G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT = (1<<0),
      G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER = (1<<1),
      G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS = (1<<2),
      G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION = (1<<3),
      G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING = (1<<4)
    } GDBusConnectionFlags;

Flags used when creating a new GDBusConnection.

`G_DBUS_CONNECTION_FLAGS_NONE` | No flags set.
`G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT` | Perform authentication against server.
`G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER` | Perform authentication against client.
`G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS` | When authenticating as a server, allow the anonymous authentication method.
`G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION` | Pass this flag if connecting to a peer that is a message bus. This means that the `Hello()` method will be invoked as part of the connection setup.
`G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING` | If set, processing of D-Bus messages is delayed until `g_dbus_connection_start_message_processing()` is called.

Since 2.26

### g_dbus_connection_new ()

    void                g_dbus_connection_new               (GIOStream *stream,
                                                             const gchar *guid,
                                                             GDBusConnectionFlags flags,
                                                             GDBusAuthObserver *observer,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Asynchronously sets up a D-Bus connection for exchanging D-Bus messages with the end represented by `stream`.

If `observer` is not `NULL` it may be used to control the authentication process.

When the operation is finished, `callback` will be invoked. You can then call `g_dbus_connection_new_finish()` to get the result of the operation.

This is a asynchronous failable constructor. See `g_dbus_connection_new_sync()` for the synchronous version.

`stream` : | A GIOStream.
`guid` : | The GUID to use if a authenticating as a server or `NULL`.
`flags` : | Flags describing how to make the connection.
`observer` : | A GDBusAuthObserver or `NULL`.
`cancellable` : | A GCancellable or `NULL`.
`callback` : | A GAsyncReadyCallback to call when the request is satisfied.
`user_data` : | The data to pass to `callback`.

Since 2.26

### g_dbus_connection_new_finish ()

    GDBusConnection *   g_dbus_connection_new_finish        (GAsyncResult *res,
                                                             GError **error);

Finishes an operation started with `g_dbus_connection_new()`.

`res` : | A GAsyncResult obtained from the GAsyncReadyCallback passed to `g_dbus_connection_new()`.
`error` : | Return location for error or `NULL`.
Returns : | A GDBusConnection or `NULL` if `error` is set. Free with `g_object_unref()`.

Since 2.26

### g_dbus_connection_new_sync ()

    GDBusConnection *   g_dbus_connection_new_sync          (GIOStream *stream,
                                                             const gchar *guid,
                                                             GDBusConnectionFlags flags,
                                                             GDBusAuthObserver *observer,
                                                             GCancellable *cancellable,
                                                             GError **error);

Synchronously sets up a D-Bus connection for exchanging D-Bus messages with the end represented by `stream`.

If `observer` is not `NULL` it may be used to control the authentication process.

This is a synchronous failable constructor. See `g_dbus_connection_new()` for the asynchronous version.

`stream` : | A GIOStream.
`guid` : | The GUID to use if a authenticating as a server or `NULL`.
`flags` : | Flags describing how to make the connection.
`observer` : | A GDBusAuthObserver or `NULL`.
`cancellable` : | A GCancellable or `NULL`.
`error` : | Return location for error or `NULL`.
Returns : | A GDBusConnection or `NULL` if `error` is set. Free with `g_object_unref()`.

Since 2.26

### g_dbus_connection_new_for_address ()

    void                g_dbus_connection_new_for_address   (const gchar *address,
                                                             GDBusConnectionFlags flags,
                                                             GDBusAuthObserver *observer,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Asynchronously connects and sets up a D-Bus client connection for exchanging D-Bus messages with an endpoint specified by `address` which must be in the D-Bus address format.

This constructor can only be used to initiate client-side connections - use `g_dbus_connection_new()` if you need to act as the server. In particular, `flags` cannot contain the `G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER` or `G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS` flags.

When the operation is finished, `callback` will be invoked. You can then call `g_dbus_connection_new_finish()` to get the result of the operation.

If `observer` is not `NULL` it may be used to control the authentication process.

This is a asynchronous failable constructor. See `g_dbus_connection_new_for_address_sync()` for the synchronous version.

`address` : | A D-Bus address.
`flags` : | Flags describing how to make the connection.
`observer` : | A GDBusAuthObserver or `NULL`.
`cancellable` : | A GCancellable or `NULL`.
`callback` : | A GAsyncReadyCallback to call when the request is satisfied.
`user_data` : | The data to pass to `callback`.

Since 2.26

### g_dbus_connection_new_for_address_finish ()

    GDBusConnection *   g_dbus_connection_new_for_address_finish
                                                            (GAsyncResult *res,
                                                             GError **error);

Finishes an operation started with `g_dbus_connection_new_for_address()`.

`res` : | A GAsyncResult obtained from the GAsyncReadyCallback passed to `g_dbus_connection_new()`.
`error` : | Return location for error or `NULL`.
Returns : | A GDBusConnection or `NULL` if `error` is set. Free with `g_object_unref()`.

Since 2.26

### g_dbus_connection_new_for_address_sync ()

    GDBusConnection *   g_dbus_connection_new_for_address_sync
                                                            (const gchar *address,
                                                             GDBusConnectionFlags flags,
                                                             GDBusAuthObserver *observer,
                                                             GCancellable *cancellable,
                                                             GError **error);

Synchronously connects and sets up a D-Bus client connection for exchanging D-Bus messages with an endpoint specified by `address` which must be in the D-Bus address format.

This constructor can only be used to initiate client-side connections - use `g_dbus_connection_new_sync()` if you need to act as the server. In particular, `flags` cannot contain the `G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER` or `G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS` flags.

This is a synchronous failable constructor. See `g_dbus_connection_new_for_address()` for the asynchronous version.

If `observer` is not `NULL` it may be used to control the authentication process.

`address` : | A D-Bus address.
`flags` : | Flags describing how to make the connection.
`observer` : | A GDBusAuthObserver or `NULL`.
`cancellable` : | A GCancellable or `NULL`.
`error` : | Return location for error or `NULL`.
Returns : | A GDBusConnection or `NULL` if `error` is set. Free with `g_object_unref()`.

Since 2.26

### g_dbus_connection_start_message_processing ()

    void                g_dbus_connection_start_message_processing
                                                            (GDBusConnection *connection);

If `connection` was created with `G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING`, this method starts processing messages. Does nothing on if `connection` wasn't created with this flag or if the method has already been called.

`connection` : | A GDBusConnection.

Since 2.26

### g_dbus_connection_close ()

    void                g_dbus_connection_close             (GDBusConnection *connection,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Closes `connection`. Note that this never causes the process to exit (this might only happen if the other end of a shared message bus connection disconnects, see "exit-on-close").

Once the connection is closed, operations such as sending a message will return with the error `G_IO_ERROR_CLOSED`. Closing a connection will not automatically flush the connection so queued messages may be lost. Use `g_dbus_connection_flush()` if you need such guarantees.

If `connection` is already closed, this method fails with `G_IO_ERROR_CLOSED`.

When `connection` has been closed, the "closed" signal is emitted in the thread-default main loop of the thread that `connection` was constructed in.

This is an asynchronous method. When the operation is finished, `callback` will be invoked in the thread-default main loop of the thread you are calling this method from. You can then call `g_dbus_connection_close_finish()` to get the result of the operation. See `g_dbus_connection_close_sync()` for the synchronous version.

`connection` : | A GDBusConnection.
`cancellable` : | A GCancellable or `NULL`.
`callback` : | A GAsyncReadyCallback to call when the request is satisfied or `NULL` if you don't care about the result.
`user_data` : | The data to pass to `callback`.

Since 2.26

### g_dbus_connection_close_finish ()

    gboolean            g_dbus_connection_close_finish      (GDBusConnection *connection,
                                                             GAsyncResult *res,
                                                             GError **error);

Finishes an operation started with `g_dbus_connection_close()`.

`connection` : | A GDBusConnection.
`res` : | A GAsyncResult obtained from the GAsyncReadyCallback passed to `g_dbus_connection_close()`.
`error` : | Return location for error or `NULL`.
Returns : | `TRUE` if the operation succeeded, `FALSE` if `error` is set.

Since 2.26

### g_dbus_connection_close_sync ()

    gboolean            g_dbus_connection_close_sync        (GDBusConnection *connection,
                                                             GCancellable *cancellable,
                                                             GError **error);

Synchronously closees `connection`. The calling thread is blocked until this is done. See `g_dbus_connection_close()` for the asynchronous version of this method and more details about what it does.

`connection` : | A GDBusConnection.
`cancellable` : | A GCancellable or `NULL`.
`error` : | Return location for error or `NULL`.
Returns : | `TRUE` if the operation succeeded, `FALSE` if `error` is set.

Since 2.26

### g_dbus_connection_is_closed ()

    gboolean            g_dbus_connection_is_closed         (GDBusConnection *connection);

Gets whether `connection` is closed.

`connection` : | A GDBusConnection.
Returns : | `TRUE` if the connection is closed, `FALSE` otherwise.

Since 2.26

### g_dbus_connection_flush ()

    void                g_dbus_connection_flush             (GDBusConnection *connection,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Asynchronously flushes `connection`, that is, writes all queued outgoing message to the transport and then flushes the transport (using `g_output_stream_flush_async()`). This is useful in programs that wants to emit a D-Bus signal and then exit immediately. Without flushing the connection, there is no guarantee that the message has been sent to the networking buffers in the OS kernel.

This is an asynchronous method. When the operation is finished, `callback` will be invoked in the thread-default main loop of the thread you are calling this method from. You can then call `g_dbus_connection_flush_finish()` to get the result of the operation. See `g_dbus_connection_flush_sync()` for the synchronous version.

`connection` : | A GDBusConnection.
`cancellable` : | A GCancellable or `NULL`.
`callback` : | A GAsyncReadyCallback to call when the request is satisfied or `NULL` if you don't care about the result.
`user_data` : | The data to pass to `callback`.

Since 2.26

### g_dbus_connection_flush_finish ()

    gboolean            g_dbus_connection_flush_finish      (GDBusConnection *connection,
                                                             GAsyncResult *res,
                                                             GError **error);

Finishes an operation started with `g_dbus_connection_flush()`.

`connection` : | A GDBusConnection.
`res` : | A GAsyncResult obtained from the GAsyncReadyCallback passed to `g_dbus_connection_flush()`.
`error` : | Return location for error or `NULL`.
Returns : | `TRUE` if the operation succeeded, `FALSE` if `error` is set.

Since 2.26

### g_dbus_connection_flush_sync ()

    gboolean            g_dbus_connection_flush_sync        (GDBusConnection *connection,
                                                             GCancellable *cancellable,
                                                             GError **error);

Synchronously flushes `connection`. The calling thread is blocked until this is done. See `g_dbus_connection_flush()` for the asynchronous version of this method and more details about what it does.

`connection` : | A GDBusConnection.
`cancellable` : | A GCancellable or `NULL`.
`error` : | Return location for error or `NULL`.
Returns : | `TRUE` if the operation succeeded, `FALSE` if `error` is set.

Since 2.26

### g_dbus_connection_get_exit_on_close ()

    gboolean            g_dbus_connection_get_exit_on_close (GDBusConnection *connection);

Gets whether the process is terminated when `connection` is closed by the remote peer. See "exit-on-close" for more details.

`connection` : | A GDBusConnection.
Returns : | Whether the process is terminated when `connection` is closed by the remote peer.

Since 2.26

### g_dbus_connection_set_exit_on_close ()

    void                g_dbus_connection_set_exit_on_close (GDBusConnection *connection,
                                                             gboolean exit_on_close);

Sets whether the process should be terminated when `connection` is closed by the remote peer. See "exit-on-close" for more details.

Note that this function should be used with care. Most modern UNIX desktops tie the notion of a user session the session bus, and expect all of a users applications to quit when their bus connection goes away. If you are setting `exit_on_close` to `FALSE` for the shared session bus connection, you should make sure that your application exits when the user session ends.

`connection` : | A GDBusConnection.
`exit_on_close` : | Whether the process should be terminated when `connection` is closed by the remote peer.

Since 2.26

### g_dbus_connection_get_stream ()

    GIOStream *         g_dbus_connection_get_stream        (GDBusConnection *connection);

Gets the underlying stream used for IO.

`connection` : | a GDBusConnection
Returns : | the stream used for IO. [transfer none]

Since 2.26

### g_dbus_connection_get_guid ()

    const gchar *       g_dbus_connection_get_guid          (GDBusConnection *connection);

The GUID of the peer performing the role of server when authenticating. See "guid" for more details.

`connection` : | A GDBusConnection.
Returns : | The GUID. Do not free this string, it is owned by `connection`.

Since 2.26

### g_dbus_connection_get_unique_name ()

    const gchar *       g_dbus_connection_get_unique_name   (GDBusConnection *connection);

Gets the unique name of `connection` as assigned by the message bus. This can also be used to figure out if `connection` is a message bus connection.

`connection` : | A GDBusConnection.
Returns : | The unique name or `NULL` if `connection` is not a message bus connection. Do not free this string, it is owned by `connection`.

Since 2.26

### enum GDBusCapabilityFlags

    typedef enum {
      G_DBUS_CAPABILITY_FLAGS_NONE = 0,
      G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING = (1<<0)
    } GDBusCapabilityFlags;

Capabilities negotiated with the remote peer.

`G_DBUS_CAPABILITY_FLAGS_NONE` | No flags set.
`G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING` | The connection supports exchanging UNIX file descriptors with the remote peer.

Since 2.26

### g_dbus_connection_get_capabilities ()

    GDBusCapabilityFlags  g_dbus_connection_get_capabilities
                                                            (GDBusConnection *connection);

Gets the capabilities negotiated with the remote peer

`connection` : | A GDBusConnection.
Returns : | Zero or more flags from the GDBusCapabilityFlags enumeration.

Since 2.26

### g_dbus_connection_get_peer_credentials ()

    GCredentials *      g_dbus_connection_get_peer_credentials
                                                            (GDBusConnection *connection);

Gets the credentials of the authenticated peer. This will always return `NULL` unless `connection` acted as a server (e.g. `G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER` was passed) when set up and the client passed credentials as part of the authentication process.

In a message bus setup, the message bus is always the server and each application is a client. So this method will always return `NULL` for message bus clients.

`connection` : | A GDBusConnection.
Returns : | A GCredentials or `NULL` if not available. Do not free this object, it is owned by `connection`. [transfer none]

Since 2.26

### enum GDBusCallFlags

    typedef enum {
      G_DBUS_CALL_FLAGS_NONE = 0,
      G_DBUS_CALL_FLAGS_NO_AUTO_START = (1<<0)
    } GDBusCallFlags;

Flags used in `g_dbus_connection_call()` and similar APIs.

`G_DBUS_CALL_FLAGS_NONE` | No flags set.
`G_DBUS_CALL_FLAGS_NO_AUTO_START` | The bus must not launch an owner for the destination name in response to this method invocation.

Since 2.26

### g_dbus_connection_call ()

    void                g_dbus_connection_call              (GDBusConnection *connection,
                                                             const gchar *bus_name,
                                                             const gchar *object_path,
                                                             const gchar *interface_name,
                                                             const gchar *method_name,
                                                             GVariant *parameters,
                                                             const GVariantType *reply_type,
                                                             GDBusCallFlags flags,
                                                             gint timeout_msec,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Asynchronously invokes the `method_name` method on the `interface_name` D-Bus interface on the remote object at `object_path` owned by `bus_name`.

If `connection` is closed then the operation will fail with `G_IO_ERROR_CLOSED`. If `cancellable` is canceled, the operation will fail with `G_IO_ERROR_CANCELLED`. If `parameters` contains a value not compatible with the D-Bus protocol, the operation fails with `G_IO_ERROR_INVALID_ARGUMENT`.

If `reply_type` is non-`NULL` then the reply will be checked for having this type and an error will be raised if it does not match. Said another way, if you give a `reply_type` then any non-`NULL` return value will be of this type.

If the `parameters` GVariant is floating, it is consumed. This allows convenient 'inline' use of `g_variant_new()`, e.g.:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    g_dbus_connection_call (connection,
                            "org.freedesktop.StringThings",
                            "/org/freedesktop/StringThings",
                            "org.freedesktop.StringThings",
                            "TwoStrings",
                            g_variant_new ("(ss)",
                                           "Thing One",
                                           "Thing Two"),
                            NULL,
                            G_DBUS_CALL_FLAGS_NONE,
                            -1,
                            NULL,
                            (GAsyncReadyCallback) two_strings_done,
                            NULL);

This is an asynchronous method. When the operation is finished, `callback` will be invoked in the thread-default main loop of the thread you are calling this method from. You can then call `g_dbus_connection_call_finish()` to get the result of the operation. See `g_dbus_connection_call_sync()` for the synchronous version of this function.

`connection` : | A GDBusConnection.
`bus_name` : | A unique or well-known bus name or `NULL` if `connection` is not a message bus connection.
`object_path` : | Path of remote object.
`interface_name` : | D-Bus interface to invoke method on.
`method_name` : | The name of the method to invoke.
`parameters` : | A GVariant tuple with parameters for the method or `NULL` if not passing parameters.
`reply_type` : | The expected type of the reply, or `NULL`.
`flags` : | Flags from the GDBusCallFlags enumeration.
`timeout_msec` : | The timeout in milliseconds, -1 to use the default timeout or `G_MAXINT` for no timeout.
`cancellable` : | A GCancellable or `NULL`.
`callback` : | A GAsyncReadyCallback to call when the request is satisfied or `NULL` if you don't care about the result of the method invocation.
`user_data` : | The data to pass to `callback`.

Since 2.26

### g_dbus_connection_call_finish ()

    GVariant *          g_dbus_connection_call_finish       (GDBusConnection *connection,
                                                             GAsyncResult *res,
                                                             GError **error);

Finishes an operation started with `g_dbus_connection_call()`.

`connection` : | A GDBusConnection.
`res` : | A GAsyncResult obtained from the GAsyncReadyCallback passed to `g_dbus_connection_call()`.
`error` : | Return location for error or `NULL`.
Returns : | `NULL` if `error` is set. Otherwise a GVariant tuple with return values. Free with `g_variant_unref()`.

Since 2.26

### g_dbus_connection_call_sync ()

    GVariant *          g_dbus_connection_call_sync         (GDBusConnection *connection,
                                                             const gchar *bus_name,
                                                             const gchar *object_path,
                                                             const gchar *interface_name,
                                                             const gchar *method_name,
                                                             GVariant *parameters,
                                                             const GVariantType *reply_type,
                                                             GDBusCallFlags flags,
                                                             gint timeout_msec,
                                                             GCancellable *cancellable,
                                                             GError **error);

Synchronously invokes the `method_name` method on the `interface_name` D-Bus interface on the remote object at `object_path` owned by `bus_name`.

If `connection` is closed then the operation will fail with `G_IO_ERROR_CLOSED`. If `cancellable` is canceled, the operation will fail with `G_IO_ERROR_CANCELLED`. If `parameters` contains a value not compatible with the D-Bus protocol, the operation fails with `G_IO_ERROR_INVALID_ARGUMENT`.

If `reply_type` is non-`NULL` then the reply will be checked for having this type and an error will be raised if it does not match. Said another way, if you give a `reply_type` then any non-`NULL` return value will be of this type.

If the `parameters` GVariant is floating, it is consumed. This allows convenient 'inline' use of `g_variant_new()`, e.g.:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    g_dbus_connection_call_sync (connection,
                                 "org.freedesktop.StringThings",
                                 "/org/freedesktop/StringThings",
                                 "org.freedesktop.StringThings",
                                 "TwoStrings",
                                 g_variant_new ("(ss)",
                                                "Thing One",
                                                "Thing Two"),
                                 NULL,
                                 G_DBUS_CALL_FLAGS_NONE,
                                 -1,
                                 NULL,
                                 &error);

The calling thread is blocked until a reply is received. See `g_dbus_connection_call()` for the asynchronous version of this method.

`connection` : | A GDBusConnection.
`bus_name` : | A unique or well-known bus name.
`object_path` : | Path of remote object.
`interface_name` : | D-Bus interface to invoke method on.
`method_name` : | The name of the method to invoke.
`parameters` : | A GVariant tuple with parameters for the method or `NULL` if not passing parameters.
`reply_type` : | The expected type of the reply, or `NULL`.
`flags` : | Flags from the GDBusCallFlags enumeration.
`timeout_msec` : | The timeout in milliseconds, -1 to use the default timeout or `G_MAXINT` for no timeout.
`cancellable` : | A GCancellable or `NULL`.
`error` : | Return location for error or `NULL`.
Returns : | `NULL` if `error` is set. Otherwise a GVariant tuple with return values. Free with `g_variant_unref()`.

Since 2.26

### g_dbus_connection_emit_signal ()

    gboolean            g_dbus_connection_emit_signal       (GDBusConnection *connection,
                                                             const gchar *destination_bus_name,
                                                             const gchar *object_path,
                                                             const gchar *interface_name,
                                                             const gchar *signal_name,
                                                             GVariant *parameters,
                                                             GError **error);

Emits a signal.

If the parameters GVariant is floating, it is consumed.

This can only fail if `parameters` is not compatible with the D-Bus protocol.

`connection` : | A GDBusConnection.
`destination_bus_name` : | The unique bus name for the destination for the signal or `NULL` to emit to all listeners.
`object_path` : | Path of remote object.
`interface_name` : | D-Bus interface to emit a signal on.
`signal_name` : | The name of the signal to emit.
`parameters` : | A GVariant tuple with parameters for the signal or `NULL` if not passing parameters.
`error` : | Return location for error or `NULL`.
Returns : | `TRUE` unless `error` is set.

Since 2.26

### enum GDBusSignalFlags

    typedef enum /*< flags >*/
    {
      G_DBUS_SIGNAL_FLAGS_NONE = 0,
      G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE = (1<<0)
    } GDBusSignalFlags;

Flags used when subscribing to signals via `g_dbus_connection_signal_subscribe()`.

`G_DBUS_SIGNAL_FLAGS_NONE` | No flags set.
`G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE` | Don't actually send the AddMatch D-Bus call for this signal subscription. This gives you more control over which match rules you add (but you must add them manually).

Since 2.26

### GDBusSignalCallback ()

    void                (*GDBusSignalCallback)              (GDBusConnection *connection,
                                                             const gchar *sender_name,
                                                             const gchar *object_path,
                                                             const gchar *interface_name,
                                                             const gchar *signal_name,
                                                             GVariant *parameters,
                                                             gpointer user_data);

Signature for callback function used in `g_dbus_connection_signal_subscribe()`.

`connection` : | A GDBusConnection.
`sender_name` : | The unique bus name of the sender of the signal.
`object_path` : | The object path that the signal was emitted on.
`interface_name` : | The name of the interface.
`signal_name` : | The name of the signal.
`parameters` : | A GVariant tuple with parameters for the signal.
`user_data` : | User data passed when subscribing to the signal.

Since 2.26

### g_dbus_connection_signal_subscribe ()

    guint               g_dbus_connection_signal_subscribe  (GDBusConnection *connection,
                                                             const gchar *sender,
                                                             const gchar *interface_name,
                                                             const gchar *member,
                                                             const gchar *object_path,
                                                             const gchar *arg0,
                                                             GDBusSignalFlags flags,
                                                             GDBusSignalCallback callback,
                                                             gpointer user_data,
                                                             GDestroyNotify user_data_free_func);

Subscribes to signals on `connection` and invokes `callback` with a whenever the signal is received. Note that `callback` will be invoked in the thread-default main loop of the thread you are calling this method from.

If `connection` is not a message bus connection, `sender` must be `NULL`.

If `sender` is a well-known name note that `callback` is invoked with the unique name for the owner of `sender`, not the well-known name as one would expect. This is because the message bus rewrites the name. As such, to avoid certain race conditions, users should be tracking the name owner of the well-known name and use that when processing the received signal.

`connection` : | A GDBusConnection.
`sender` : | Sender name to match on (unique or well-known name) or `NULL` to listen from all senders.
`interface_name` : | D-Bus interface name to match on or `NULL` to match on all interfaces.
`member` : | D-Bus signal name to match on or `NULL` to match on all signals.
`object_path` : | Object path to match on or `NULL` to match on all object paths.
`arg0` : | Contents of first string argument to match on or `NULL` to match on all kinds of arguments.
`flags` : | Flags describing how to subscribe to the signal (currently unused).
`callback` : | Callback to invoke when there is a signal matching the requested data.
`user_data` : | User data to pass to `callback`.
`user_data_free_func` : | Function to free `user_data` with when subscription is removed or `NULL`.
Returns : | A subscription identifier that can be used with `g_dbus_connection_signal_unsubscribe()`.

Since 2.26

### g_dbus_connection_signal_unsubscribe ()

    void                g_dbus_connection_signal_unsubscribe
                                                            (GDBusConnection *connection,
                                                             guint subscription_id);

Unsubscribes from signals.

`connection` : | A GDBusConnection.
`subscription_id` : | A subscription id obtained from `g_dbus_connection_signal_subscribe()`.

Since 2.26

### enum GDBusSendMessageFlags

    typedef enum
    {
      G_DBUS_SEND_MESSAGE_FLAGS_NONE = 0,
      G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL = (1<<0)
    } GDBusSendMessageFlags;

Flags used when sending GDBusMessages on a GDBusConnection.

`G_DBUS_SEND_MESSAGE_FLAGS_NONE` | No flags set.
`G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL` | Do not automatically assign a serial number from the GDBusConnection object when sending a message.

Since 2.26

### g_dbus_connection_send_message ()

    gboolean            g_dbus_connection_send_message      (GDBusConnection *connection,
                                                             GDBusMessage *message,
                                                             GDBusSendMessageFlags flags,
                                                             volatile guint32 *out_serial,
                                                             GError **error);

Asynchronously sends `message` to the peer represented by `connection`.

Unless `flags` contain the `G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL` flag, the serial number will be assigned by `connection` and set on `message` via `g_dbus_message_set_serial()`. If `out_serial` is not `NULL`, then the serial number used will be written to this location prior to submitting the message to the underlying transport.

If `connection` is closed then the operation will fail with `G_IO_ERROR_CLOSED`. If `message` is not well-formed, the operation fails with `G_IO_ERROR_INVALID_ARGUMENT`.

See Example 2, “D-Bus server example” and Example 4, “D-Bus UNIX File Descriptor example” for an example of how to use this low-level API to send and receive UNIX file descriptors.

Note that `message` must be unlocked, unless `flags` contain the `G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL` flag.

`connection` : | A GDBusConnection.
`message` : | A GDBusMessage
`flags` : | Flags affecting how the message is sent.
`out_serial` : | Return location for serial number assigned to `message` when sending it or `NULL`.
`error` : | Return location for error or `NULL`.
Returns : | `TRUE` if the message was well-formed and queued for transmission, `FALSE` if `error` is set.

Since 2.26

### g_dbus_connection_send_message_with_reply ()

    void                g_dbus_connection_send_message_with_reply
                                                            (GDBusConnection *connection,
                                                             GDBusMessage *message,
                                                             GDBusSendMessageFlags flags,
                                                             gint timeout_msec,
                                                             volatile guint32 *out_serial,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);

Asynchronously sends `message` to the peer represented by `connection`.

Unless `flags` contain the `G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL` flag, the serial number will be assigned by `connection` and set on `message` via `g_dbus_message_set_serial()`. If `out_serial` is not `NULL`, then the serial number used will be written to this location prior to submitting the message to the underlying transport.

If `connection` is closed then the operation will fail with `G_IO_ERROR_CLOSED`. If `cancellable` is canceled, the operation will fail with `G_IO_ERROR_CANCELLED`. If `message` is not well-formed, the operation fails with `G_IO_ERROR_INVALID_ARGUMENT`.

This is an asynchronous method. When the operation is finished, `callback` will be invoked in the thread-default main loop of the thread you are calling this method from. You can then call `g_dbus_connection_send_message_with_reply_finish()` to get the result of the operation. See `g_dbus_connection_send_message_with_reply_sync()` for the synchronous version.

Note that `message` must be unlocked, unless `flags` contain the `G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL` flag.

See Example 2, “D-Bus server example” and Example 4, “D-Bus UNIX File Descriptor example” for an example of how to use this low-level API to send and receive UNIX file descriptors.

`connection` : | A GDBusConnection.
`message` : | A GDBusMessage.
`flags` : | Flags affecting how the message is sent.
`timeout_msec` : | The timeout in milliseconds, -1 to use the default timeout or `G_MAXINT` for no timeout.
`out_serial` : | Return location for serial number assigned to `message` when sending it or `NULL`.
`cancellable` : | A GCancellable or `NULL`.
`callback` : | A GAsyncReadyCallback to call when the request is satisfied or `NULL` if you don't care about the result.
`user_data` : | The data to pass to `callback`.

Since 2.26

### g_dbus_connection_send_message_with_reply_finish ()

    GDBusMessage *      g_dbus_connection_send_message_with_reply_finish
                                                            (GDBusConnection *connection,
                                                             GAsyncResult *res,
                                                             GError **error);

Finishes an operation started with `g_dbus_connection_send_message_with_reply()`.

Note that `error` is only set if a local in-process error occured. That is to say that the returned GDBusMessage object may be of type `G_DBUS_MESSAGE_TYPE_ERROR`. Use `g_dbus_message_to_gerror()` to transcode this to a GError.

See Example 2, “D-Bus server example” and Example 4, “D-Bus UNIX File Descriptor example” for an example of how to use this low-level API to send and receive UNIX file descriptors.

`connection` : | a GDBusConnection
`res` : | A GAsyncResult obtained from the GAsyncReadyCallback passed to `g_dbus_connection_send_message_with_reply()`.
`error` : | Return location for error or `NULL`.
Returns : | A locked GDBusMessage or `NULL` if `error` is set. [transfer full]

Since 2.26

### g_dbus_connection_send_message_with_reply_sync ()

    GDBusMessage *      g_dbus_connection_send_message_with_reply_sync
                                                            (GDBusConnection *connection,
                                                             GDBusMessage *message,
                                                             GDBusSendMessageFlags flags,
                                                             gint timeout_msec,
                                                             volatile guint32 *out_serial,
                                                             GCancellable *cancellable,
                                                             GError **error);

Synchronously sends `message` to the peer represented by `connection` and blocks the calling thread until a reply is received or the timeout is reached. See `g_dbus_connection_send_message_with_reply()` for the asynchronous version of this method.

Unless `flags` contain the `G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL` flag, the serial number will be assigned by `connection` and set on `message` via `g_dbus_message_set_serial()`. If `out_serial` is not `NULL`, then the serial number used will be written to this location prior to submitting the message to the underlying transport.

If `connection` is closed then the operation will fail with `G_IO_ERROR_CLOSED`. If `cancellable` is canceled, the operation will fail with `G_IO_ERROR_CANCELLED`. If `message` is not well-formed, the operation fails with `G_IO_ERROR_INVALID_ARGUMENT`.

Note that `error` is only set if a local in-process error occured. That is to say that the returned GDBusMessage object may be of type `G_DBUS_MESSAGE_TYPE_ERROR`. Use `g_dbus_message_to_gerror()` to transcode this to a GError.

See Example 2, “D-Bus server example” and Example 4, “D-Bus UNIX File Descriptor example” for an example of how to use this low-level API to send and receive UNIX file descriptors.

Note that `message` must be unlocked, unless `flags` contain the `G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL` flag.

`connection` : | A GDBusConnection.
`message` : | A GDBusMessage.
`flags` : | Flags affecting how the message is sent.
`timeout_msec` : | The timeout in milliseconds, -1 to use the default timeout or `G_MAXINT` for no timeout.
`out_serial` : | Return location for serial number assigned to `message` when sending it or `NULL`.
`cancellable` : | A GCancellable or `NULL`.
`error` : | Return location for error or `NULL`.
Returns : | A locked GDBusMessage that is the reply to `message` or `NULL` if `error` is set. [transfer full]

Since 2.26

### GDBusMessageFilterFunction ()

    GDBusMessage *      (*GDBusMessageFilterFunction)       (GDBusConnection *connection,
                                                             GDBusMessage *message,
                                                             gboolean incoming,
                                                             gpointer user_data);

Signature for function used in `g_dbus_connection_add_filter()`.

A filter function is passed a GDBusMessage and expected to return a GDBusMessage too. Passive filter functions that don't modify the message can simply return the `message` object:

    1
    2
    3
    4
    5
    6
    7
    8
    9

    static GDBusMessage *
    passive_filter (GDBusConnection *connection
                    GDBusMessage    *message,
                    gboolean         incoming,
                    gpointer         user_data)
    {
      /* inspect @message */
      return message;
    }

Filter functions that wants to drop a message can simply return `NULL`:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    static GDBusMessage *
    drop_filter (GDBusConnection *connection
                 GDBusMessage    *message,
                 gboolean         incoming,
                 gpointer         user_data)
    {
      if (should_drop_message)
        {
          g_object_unref (message);
          message = NULL;
        }
      return message;
    }

Finally, a filter function may modify a message by copying it:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    static GDBusMessage *
    modifying_filter (GDBusConnection *connection
                      GDBusMessage    *message,
                      gboolean         incoming,
                      gpointer         user_data)
    {
      GDBusMessage *copy;
      GError *error;

      error = NULL;
      copy = g_dbus_message_copy (message, &error);
      /* handle @error being is set */
      g_object_unref (message);

      /* modify @copy */

      return copy;
    }

If the returned GDBusMessage is different from `message` and cannot be sent on `connection` (it could use features, such as file descriptors, not compatible with `connection`), then a warning is logged to standard error. Applications can check this ahead of time using `g_dbus_message_to_blob()` passing a GDBusCapabilityFlags value obtained from `connection`.

`connection` : | A GDBusConnection. [transfer none]
`message` : | A locked GDBusMessage that the filter function takes ownership of. [transfer full]
`incoming` : | `TRUE` if it is a message received from the other peer, `FALSE` if it is a message to be sent to the other peer.
`user_data` : | User data passed when adding the filter.
Returns : | A GDBusMessage that will be freed with `g_object_unref()` or `NULL` to drop the message. Passive filter functions can simply return the passed `message` object. [transfer full][allow-none]

Since 2.26

### g_dbus_connection_add_filter ()

    guint               g_dbus_connection_add_filter        (GDBusConnection *connection,
                                                             GDBusMessageFilterFunction filter_function,
                                                             gpointer user_data,
                                                             GDestroyNotify user_data_free_func);

Adds a message filter. Filters are handlers that are run on all incoming and outgoing messages, prior to standard dispatch. Filters are run in the order that they were added. The same handler can be added as a filter more than once, in which case it will be run more than once. Filters added during a filter callback won't be run on the message being processed. Filter functions are allowed to modify and even drop messages - see the GDBusMessageFilterResult enumeration for details.

Note that filters are run in a dedicated message handling thread so they can't block and, generally, can't do anything but signal a worker thread. Also note that filters are rarely needed - use API such as `g_dbus_connection_send_message_with_reply()`, `g_dbus_connection_signal_subscribe()` or `g_dbus_connection_call()` instead.

If a filter consumes an incoming message the message is not dispatched anywhere else - not even the standard dispatch machinery (that API such as `g_dbus_connection_signal_subscribe()` and `g_dbus_connection_send_message_with_reply()` relies on) will see the message. Similary, if a filter consumes an outgoing message, the message will not be sent to the other peer.

`connection` : | A GDBusConnection.
`filter_function` : | A filter function.
`user_data` : | User data to pass to `filter_function`.
`user_data_free_func` : | Function to free `user_data` with when filter is removed or `NULL`.
Returns : | A filter identifier that can be used with `g_dbus_connection_remove_filter()`.

Since 2.26

### g_dbus_connection_remove_filter ()

    void                g_dbus_connection_remove_filter     (GDBusConnection *connection,
                                                             guint filter_id);

Removes a filter.

`connection` : | a GDBusConnection
`filter_id` : | an identifier obtained from `g_dbus_connection_add_filter()`

Since 2.26

### GDBusInterfaceVTable

    typedef struct {
      GDBusInterfaceMethodCallFunc  method_call;
      GDBusInterfaceGetPropertyFunc get_property;
      GDBusInterfaceSetPropertyFunc set_property;
    } GDBusInterfaceVTable;

Virtual table for handling properties and method calls for a D-Bus interface.

If you want to handle getting/setting D-Bus properties asynchronously, simply register an object with the `org.freedesktop.DBus.Properties` D-Bus interface using `g_dbus_connection_register_object()`.

GDBusInterfaceMethodCallFunc `method_call`; | Function for handling incoming method calls.
GDBusInterfaceGetPropertyFunc `get_property`; | Function for getting a property.
GDBusInterfaceSetPropertyFunc `set_property`; | Function for setting a property.

Since 2.26

### GDBusInterfaceMethodCallFunc ()

    void                (*GDBusInterfaceMethodCallFunc)     (GDBusConnection *connection,
                                                             const gchar *sender,
                                                             const gchar *object_path,
                                                             const gchar *interface_name,
                                                             const gchar *method_name,
                                                             GVariant *parameters,
                                                             GDBusMethodInvocation *invocation,
                                                             gpointer user_data);

The type of the `method_call` function in GDBusInterfaceVTable.

`connection` : | A GDBusConnection.
`sender` : | The unique bus name of the remote caller.
`object_path` : | The object path that the method was invoked on.
`interface_name` : | The D-Bus interface name the method was invoked on.
`method_name` : | The name of the method that was invoked.
`parameters` : | A GVariant tuple with parameters.
`invocation` : | A GDBusMethodInvocation object that can be used to return a value or error.
`user_data` : | The `user_data` gpointer passed to `g_dbus_connection_register_object()`.

Since 2.26

### GDBusInterfaceGetPropertyFunc ()

    GVariant *          (*GDBusInterfaceGetPropertyFunc)    (GDBusConnection *connection,
                                                             const gchar *sender,
                                                             const gchar *object_path,
                                                             const gchar *interface_name,
                                                             const gchar *property_name,
                                                             GError **error,
                                                             gpointer user_data);

The type of the `get_property` function in GDBusInterfaceVTable.

`connection` : | A GDBusConnection.
`sender` : | The unique bus name of the remote caller.
`object_path` : | The object path that the method was invoked on.
`interface_name` : | The D-Bus interface name for the property.
`property_name` : | The name of the property to get the value of.
`error` : | Return location for error.
`user_data` : | The `user_data` gpointer passed to `g_dbus_connection_register_object()`.
Returns : | A GVariant with the value for `property_name` or `NULL` if `error` is set. If the returned GVariant is floating, it is consumed - otherwise its reference count is decreased by one.

Since 2.26

### GDBusInterfaceSetPropertyFunc ()

    gboolean            (*GDBusInterfaceSetPropertyFunc)    (GDBusConnection *connection,
                                                             const gchar *sender,
                                                             const gchar *object_path,
                                                             const gchar *interface_name,
                                                             const gchar *property_name,
                                                             GVariant *value,
                                                             GError **error,
                                                             gpointer user_data);

The type of the `set_property` function in GDBusInterfaceVTable.

`connection` : | A GDBusConnection.
`sender` : | The unique bus name of the remote caller.
`object_path` : | The object path that the method was invoked on.
`interface_name` : | The D-Bus interface name for the property.
`property_name` : | The name of the property to get the value of.
`value` : | The value to set the property to.
`error` : | Return location for error.
`user_data` : | The `user_data` gpointer passed to `g_dbus_connection_register_object()`.
Returns : | `TRUE` if the property was set to `value`, `FALSE` if `error` is set.

Since 2.26

### g_dbus_connection_register_object ()

    guint               g_dbus_connection_register_object   (GDBusConnection *connection,
                                                             const gchar *object_path,
                                                             GDBusInterfaceInfo *interface_info,
                                                             const GDBusInterfaceVTable *vtable,
                                                             gpointer user_data,
                                                             GDestroyNotify user_data_free_func,
                                                             GError **error);

Registers callbacks for exported objects at `object_path` with the D-Bus interface that is described in `interface_info`.

Calls to functions in `vtable` (and `user_data_free_func`) will happen in the thread-default main loop of the thread you are calling this method from.

Note that all GVariant values passed to functions in `vtable` will match the signature given in `interface_info` - if a remote caller passes incorrect values, the `org.freedesktop.DBus.Error.InvalidArgs` is returned to the remote caller.

Additionally, if the remote caller attempts to invoke methods or access properties not mentioned in `interface_info` the `org.freedesktop.DBus.Error.UnknownMethod` resp. `org.freedesktop.DBus.Error.InvalidArgs` errors are returned to the caller.

It is considered a programming error if the GDBusInterfaceGetPropertyFunc function in `vtable` returns a GVariant of incorrect type.

If an existing callback is already registered at `object_path` and `interface_name`, then `error` is set to G_IO_ERROR_EXISTS.

GDBus automatically implements the standard D-Bus interfaces org.freedesktop.DBus.Properties, org.freedesktop.DBus.Introspectable and org.freedesktop.Peer, so you don't have to implement those for the objects you export. You can implement org.freedesktop.DBus.Properties yourself, e.g. to handle getting and setting of properties asynchronously.

Note that the reference count on `interface_info` will be incremented by 1 (unless allocated statically, e.g. if the reference count is -1, see `g_dbus_interface_info_ref()`) for as long as the object is exported. Also note that `vtable` will be copied.

A `NULL` `vtable` can be used for marker interfaces.

See Example 2, “D-Bus server example” for an example of how to use this method.

`connection` : | A GDBusConnection
`object_path` : | The object path to register at
`interface_info` : | Introspection data for the interface
`vtable` : | A GDBusInterfaceVTable to call into, or `NULL`
`user_data` : | Data to pass to functions in `vtable`
`user_data_free_func` : | Function to call when the object path is unregistered
`error` : | Return location for error or `NULL`
Returns : | 0 if `error` is set, otherwise a registration id (never 0) that can be used with `g_dbus_connection_unregister_object()` .

Since 2.26

### g_dbus_connection_unregister_object ()

    gboolean            g_dbus_connection_unregister_object (GDBusConnection *connection,
                                                             guint registration_id);

Unregisters an object.

`connection` : | A GDBusConnection.
`registration_id` : | A registration id obtained from `g_dbus_connection_register_object()`.
Returns : | `TRUE` if the object was unregistered, `FALSE` otherwise.

Since 2.26

### GDBusSubtreeVTable

    typedef struct {
      GDBusSubtreeEnumerateFunc  enumerate;
      GDBusSubtreeIntrospectFunc introspect;
      GDBusSubtreeDispatchFunc   dispatch;
    } GDBusSubtreeVTable;

Virtual table for handling subtrees registered with `g_dbus_connection_register_subtree()`.

GDBusSubtreeEnumerateFunc `enumerate`; | Function for enumerating child nodes.
GDBusSubtreeIntrospectFunc `introspect`; | Function for introspecting a child node.
GDBusSubtreeDispatchFunc `dispatch`; | Function for dispatching a remote call on a child node.

Since 2.26

### GDBusSubtreeEnumerateFunc ()

    gchar **            (*GDBusSubtreeEnumerateFunc)        (GDBusConnection *connection,
                                                             const gchar *sender,
                                                             const gchar *object_path,
                                                             gpointer user_data);

The type of the `enumerate` function in GDBusSubtreeVTable.

This function is called when generating introspection data and also when preparing to dispatch incoming messages in the event that the `G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES` flag is not specified (ie: to verify that the object path is valid).

Hierarchies are not supported; the items that you return should not contain the '/' character.

The return value will be freed with `g_strfreev()`.

`connection` : | A GDBusConnection.
`sender` : | The unique bus name of the remote caller.
`object_path` : | The object path that was registered with `g_dbus_connection_register_subtree()`.
`user_data` : | The `user_data` gpointer passed to `g_dbus_connection_register_subtree()`.
Returns : | A newly allocated array of strings for node names that are children of `object_path`.

Since 2.26

### GDBusSubtreeIntrospectFunc ()

    GDBusInterfaceInfo ** (*GDBusSubtreeIntrospectFunc)     (GDBusConnection *connection,
                                                             const gchar *sender,
                                                             const gchar *object_path,
                                                             const gchar *node,
                                                             gpointer user_data);

The type of the `introspect` function in GDBusSubtreeVTable.

Subtrees are flat. `node`, if non-`NULL`, is always exactly one segment of the object path (ie: it never contains a slash).

This function should return `NULL` to indicate that there is no object at this node.

If this function returns non-`NULL`, the return value is expected to be a `NULL`-terminated array of pointers to GDBusInterfaceInfo structures describing the interfaces implemented by `node`. This array will have `g_dbus_interface_info_unref()` called on each item before being freed with `g_free()`.

The difference between returning `NULL` and an array containing zero items is that the standard DBus interfaces will returned to the remote introspector in the empty array case, but not in the `NULL` case.

`connection` : | A GDBusConnection.
`sender` : | The unique bus name of the remote caller.
`object_path` : | The object path that was registered with `g_dbus_connection_register_subtree()`.
`node` : | A node that is a child of `object_path` (relative to `object_path`) or `NULL` for the root of the subtree.
`user_data` : | The `user_data` gpointer passed to `g_dbus_connection_register_subtree()`.
Returns : | A `NULL`-terminated array of pointers to GDBusInterfaceInfo, or `NULL`.

Since 2.26

### GDBusSubtreeDispatchFunc ()

    const GDBusInterfaceVTable * (*GDBusSubtreeDispatchFunc)
                                                            (GDBusConnection *connection,
                                                             const gchar *sender,
                                                             const gchar *object_path,
                                                             const gchar *interface_name,
                                                             const gchar *node,
                                                             gpointer *out_user_data,
                                                             gpointer user_data);

The type of the `dispatch` function in GDBusSubtreeVTable.

Subtrees are flat. `node`, if non-`NULL`, is always exactly one segment of the object path (ie: it never contains a slash).

`connection` : | A GDBusConnection.
`sender` : | The unique bus name of the remote caller.
`object_path` : | The object path that was registered with `g_dbus_connection_register_subtree()`.
`interface_name` : | The D-Bus interface name that the method call or property access is for.
`node` : | A node that is a child of `object_path` (relative to `object_path`) or `NULL` for the root of the subtree.
`out_user_data` : | Return location for user data to pass to functions in the returned GDBusInterfaceVTable (never `NULL`).
`user_data` : | The `user_data` gpointer passed to `g_dbus_connection_register_subtree()`.
Returns : | A GDBusInterfaceVTable or `NULL` if you don't want to handle the methods.

Since 2.26

### enum GDBusSubtreeFlags

    typedef enum
    {
      G_DBUS_SUBTREE_FLAGS_NONE = 0,
      G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES = (1<<0)
    } GDBusSubtreeFlags;

Flags passed to `g_dbus_connection_register_subtree()`.

`G_DBUS_SUBTREE_FLAGS_NONE` | No flags set.
`G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES` | Method calls to objects not in the enumerated range will still be dispatched. This is useful if you want to dynamically spawn objects in the subtree.

Since 2.26

### g_dbus_connection_register_subtree ()

    guint               g_dbus_connection_register_subtree  (GDBusConnection *connection,
                                                             const gchar *object_path,
                                                             const GDBusSubtreeVTable *vtable,
                                                             GDBusSubtreeFlags flags,
                                                             gpointer user_data,
                                                             GDestroyNotify user_data_free_func,
                                                             GError **error);

Registers a whole subtree of “dynamic” objects.

The `enumerate` and `introspection` functions in `vtable` are used to convey, to remote callers, what nodes exist in the subtree rooted by `object_path`.

When handling remote calls into any node in the subtree, first the `enumerate` function is used to check if the node exists. If the node exists or the G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES flag is set the `introspection` function is used to check if the node supports the requested method. If so, the `dispatch` function is used to determine where to dispatch the call. The collected GDBusInterfaceVTable and gpointer will be used to call into the interface vtable for processing the request.

All calls into user-provided code will be invoked in the thread-default main loop of the thread you are calling this method from.

If an existing subtree is already registered at `object_path` or then `error` is set to G_IO_ERROR_EXISTS.

Note that it is valid to register regular objects (using `g_dbus_connection_register_object()`) in a subtree registered with `g_dbus_connection_register_subtree()` - if so, the subtree handler is tried as the last resort. One way to think about a subtree handler is to consider it a “fallback handler” for object paths not registered via `g_dbus_connection_register_object()` or other bindings.

Note that `vtable` will be copied so you cannot change it after registration.

See Example 3, “D-Bus subtree example” for an example of how to use this method.

`connection` : | A GDBusConnection.
`object_path` : | The object path to register the subtree at.
`vtable` : | A GDBusSubtreeVTable to enumerate, introspect and dispatch nodes in the subtree.
`flags` : | Flags used to fine tune the behavior of the subtree.
`user_data` : | Data to pass to functions in `vtable`.
`user_data_free_func` : | Function to call when the subtree is unregistered.
`error` : | Return location for error or `NULL`.
Returns : | 0 if `error` is set, otherwise a subtree registration id (never 0) that can be used with `g_dbus_connection_unregister_subtree()` .

Since 2.26

### g_dbus_connection_unregister_subtree ()

    gboolean            g_dbus_connection_unregister_subtree
                                                            (GDBusConnection *connection,
                                                             guint registration_id);

Unregisters a subtree.

`connection` : | A GDBusConnection.
`registration_id` : | A subtree registration id obtained from `g_dbus_connection_register_subtree()`.
Returns : | `TRUE` if the subtree was unregistered, `FALSE` otherwise.

Since 2.26

## Property Details

### The `"address"` property

      "address"                  gchar*                : Write / Construct Only

A D-Bus address specifying potential endpoints that can be used when establishing the connection.

Default value: NULL

Since 2.26

### The `"authentication-observer"` property

      "authentication-observer"  GDBusAuthObserver*    : Write / Construct Only

A GDBusAuthObserver object to assist in the authentication process or `NULL`.

Since 2.26

### The `"capabilities"` property

      "capabilities"             GDBusCapabilityFlags  : Read

Flags from the GDBusCapabilityFlags enumeration representing connection features negotiated with the other peer.

Since 2.26

### The `"closed"` property

      "closed"                   gboolean              : Read

A boolean specifying whether the connection has been closed.

Default value: FALSE

Since 2.26

### The `"exit-on-close"` property

      "exit-on-close"            gboolean              : Read / Write

A boolean specifying whether the process will be terminated (by calling `raise(SIGTERM)`) if the connection is closed by the remote peer.

Default value: FALSE

Since 2.26

### The `"flags"` property

      "flags"                    GDBusConnectionFlags  : Write / Construct Only

Flags from the GDBusConnectionFlags enumeration.

Since 2.26

### The `"guid"` property

      "guid"                     gchar*                : Read / Write / Construct Only

The GUID of the peer performing the role of server when authenticating.

If you are constructing a GDBusConnection and pass `G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER` in the "flags" property then you MUST also set this property to a valid guid.

If you are constructing a GDBusConnection and pass `G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT` in the "flags" property you will be able to read the GUID of the other peer here after the connection has been successfully initialized.

Default value: NULL

Since 2.26

### The `"stream"` property

      "stream"                   GIOStream*            : Read / Write / Construct Only

The underlying GIOStream used for I/O.

Since 2.26

### The `"unique-name"` property

      "unique-name"              gchar*                : Read

The unique name as assigned by the message bus or `NULL` if the connection is not open or not a message bus connection.

Default value: NULL

Since 2.26

## Signal Details

### The `"closed"` signal

    void                user_function                      (GDBusConnection *connection,
                                                            gboolean         remote_peer_vanished,
                                                            GError          *error,
                                                            gpointer         user_data)                 : Run Last

Emitted when the connection is closed.

The cause of this event can be

- If `g_dbus_connection_close()` is called. In this case `remote_peer_vanished` is set to `FALSE` and `error` is `NULL`.

- If the remote peer closes the connection. In this case `remote_peer_vanished` is set to `TRUE` and `error` is set.

- If the remote peer sends invalid or malformed data. In this case `remote_peer_vanished` is set to `FALSE` and `error` is set.

Upon receiving this signal, you should give up your reference to `connection`. You are guaranteed that this signal is emitted only once.

`connection` : | The GDBusConnection emitting the signal.
`remote_peer_vanished` : | `TRUE` if `connection` is closed because the remote peer closed its end of the connection.
`error` : | A GError with more details about the event or `NULL`.
`user_data` : | user data set when the signal handler was connected.

Since 2.26