+/**
+ * g_dbus_request_name:
+ * @connection: a #GDBusConnection
+ * @name: well-known bus name (name to request)
+ * @flags: a set of flags from the GBusNameOwnerFlags enumeration
+ * @error: return location for error or %NULL
+ *
+ * Synchronously acquires name on the bus and returns status code.
+ *
+ * The calling thread is blocked until a reply is received.
+ *
+ * Returns: status code or %G_BUS_REQUEST_NAME_FLAGS_ERROR
+ * if @error is set.
+ *
+ * Since: 2.4x
+ */
+GBusRequestNameReplyFlags
+g_dbus_request_name (GDBusConnection *connection,
+ const gchar *name,
+ GBusNameOwnerFlags flags,
+ GError **error)
+{
+ GVariant *result;
+ guint32 request_name_reply;
+
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), G_BUS_RELEASE_NAME_FLAGS_ERROR);
+ g_return_val_if_fail (g_dbus_is_name (name) && !g_dbus_is_unique_name (name), G_BUS_RELEASE_NAME_FLAGS_ERROR);
+ g_return_val_if_fail (error == NULL || *error == NULL, G_BUS_RELEASE_NAME_FLAGS_ERROR);
+
+ if (connection->kdbus_worker)
+ result = _g_kdbus_RequestName (connection->kdbus_worker, name, flags, error);
+ else
+ result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/org/freedesktop/DBus",
+ "org.freedesktop.DBus", "RequestName",
+ g_variant_new ("(su)", name, flags), G_VARIANT_TYPE ("(u)"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
+
+ if (result != NULL)
+ {
+ g_variant_get (result, "(u)", &request_name_reply);
+ g_variant_unref (result);
+ }
+ else
+ request_name_reply = G_BUS_REQUEST_NAME_FLAGS_ERROR;
+
+ return (GBusRequestNameReplyFlags) request_name_reply;
+}
+
+/**
+ * g_dbus_release_name:
+ * @connection: a #GDBusConnection
+ * @name: well-known bus name (name to release)
+ * @error: return location for error or %NULL
+ *
+ * Synchronously releases name on the bus and returns status code.
+ *
+ * The calling thread is blocked until a reply is received.
+ *
+ * Returns: status code or %G_BUS_RELEASE_NAME_FLAGS_ERROR
+ * if @error is set.
+ *
+ * Since: 2.4x
+ */
+GBusReleaseNameReplyFlags
+g_dbus_release_name (GDBusConnection *connection,
+ const gchar *name,
+ GError **error)
+{
+ GVariant *result;
+ guint32 release_name_reply;
+
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), G_BUS_RELEASE_NAME_FLAGS_ERROR);
+ g_return_val_if_fail (g_dbus_is_name (name) && !g_dbus_is_unique_name (name), G_BUS_RELEASE_NAME_FLAGS_ERROR);
+ g_return_val_if_fail (error == NULL || *error == NULL, G_BUS_RELEASE_NAME_FLAGS_ERROR);
+
+ if (connection->kdbus_worker)
+ result = _g_kdbus_ReleaseName (connection->kdbus_worker, name, error);
+ else
+ result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/org/freedesktop/DBus",
+ "org.freedesktop.DBus", "ReleaseName",
+ g_variant_new ("(s)", name), G_VARIANT_TYPE ("(u)"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
+
+ if (result != NULL)
+ {
+ g_variant_get (result, "(u)", &release_name_reply);
+ g_variant_unref (result);
+ }
+ else
+ release_name_reply = G_BUS_RELEASE_NAME_FLAGS_ERROR;
+
+ return (GBusReleaseNameReplyFlags) release_name_reply;
+}
+
+/**
+ * g_dbus_get_bus_id:
+ * @connection: a #GDBusConnection
+ * @error: return location for error or %NULL
+ *
+ * Synchronously returns the unique ID of the bus.
+ *
+ * The calling thread is blocked until a reply is received.
+ *
+ * Returns: the unique ID of the bus or %NULL if @error is set.
+ * Free with g_free().
+ *
+ * Since: 2.4x
+ */
+gchar *
+g_dbus_get_bus_id (GDBusConnection *connection,
+ GError **error)
+{
+ GVariant *result;
+ gchar *bus_id;
+
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ result = NULL;
+ bus_id = NULL;
+
+ if (connection->kdbus_worker)
+ {
+ result = _g_kdbus_GetBusId (connection->kdbus_worker, error);
+ }
+ else
+ {
+ result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
+ "org.freedesktop.DBus", "GetId",
+ NULL, G_VARIANT_TYPE ("(s)"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
+ }
+
+ if (result != NULL)
+ {
+ g_variant_get (result, "(s)", &bus_id);
+ g_variant_unref (result);
+ }
+
+ return bus_id;
+}
+
+typedef enum
+{
+ LIST_NAMES,
+ LIST_ACTIVATABLE_NAMES,
+ LIST_QUEUED_OWNERS
+} GDBusListNameType;
+
+static gchar **
+_g_dbus_get_list_internal (GDBusConnection *connection,
+ const gchar *name,
+ GDBusListNameType list_name_type,
+ GError **error)
+{
+ gchar **strv;
+ GVariant *result;
+ GVariantIter *iter;
+ gchar *str;
+ gsize n, i;
+
+ result = NULL;
+ strv = NULL;
+
+ if (list_name_type == LIST_QUEUED_OWNERS)
+ {
+ if (connection->kdbus_worker)
+ result = _g_kdbus_GetListQueuedOwners (connection->kdbus_worker, name, error);
+ else
+ result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
+ "org.freedesktop.DBus", "ListQueuedOwners",
+ g_variant_new ("(s)", name), G_VARIANT_TYPE ("(as)"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
+ }
+ else
+ {
+ gchar *method_name;
+
+ if (list_name_type == LIST_NAMES)
+ method_name = "ListNames";
+ else
+ method_name = "ListActivatableNames";
+
+ if (connection->kdbus_worker)
+ result = _g_kdbus_GetListNames (connection->kdbus_worker, list_name_type, error);
+ else
+ result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
+ "org.freedesktop.DBus", method_name,
+ NULL, G_VARIANT_TYPE ("(as)"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
+ }
+
+ if (result != NULL)
+ {
+ g_variant_get (result, "(as)", &iter);
+ n = g_variant_iter_n_children (iter);
+ strv = g_new (gchar *, n + 1);
+
+ i = 0;
+ while (g_variant_iter_loop (iter, "s", &str))
+ {
+ strv[i] = g_strdup (str);
+ i++;
+ }
+ strv[i] = NULL;
+
+ g_variant_iter_free (iter);
+ g_variant_unref (result);
+ }
+
+ return strv;
+}
+
+/**
+ * g_dbus_get_list_names:
+ * @connection: a #GDBusConnection
+ * @error: return location for error or %NULL
+ *
+ * Synchronously returns a list of all currently-owned names on the bus.
+ *
+ * The calling thread is blocked until a reply is received.
+ *
+ * Returns: a list of all currently-owned names on the bus or %NULL if
+ * @error is set. Free with g_strfreev().
+ *
+ * Since: 2.4x
+ */
+gchar **
+g_dbus_get_list_names (GDBusConnection *connection,
+ GError **error)
+{
+ gchar **strv;
+
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ strv = _g_dbus_get_list_internal (connection, NULL, LIST_NAMES, error);
+
+ return strv;
+}
+
+/**
+ * g_dbus_get_list_activatable_names:
+ * @connection: a #GDBusConnection
+ * @error: return location for error or %NULL
+ *
+ * Synchronously returns a list of all names that can be activated on the bus.
+ *
+ * The calling thread is blocked until a reply is received.
+ *
+ * Returns: a list of all names that can be activated on the bus or %NULL if
+ * @error is set. Free with g_strfreev().
+ *
+ * Since: 2.4x
+ */
+gchar **
+g_dbus_get_list_activatable_names (GDBusConnection *connection,
+ GError **error)
+{
+ gchar **strv;
+
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ strv = _g_dbus_get_list_internal (connection, NULL, LIST_ACTIVATABLE_NAMES, error);
+
+ return strv;
+}
+
+/**
+ * g_dbus_get_list_queued_names:
+ * @connection: a #GDBusConnection
+ * @name: a unique or well-known bus name
+ * @error: return location for error or %NULL
+ *
+ * Synchronously returns the unique bus names of connections currently queued
+ * for the @name.
+ *
+ * If @name contains a value not compatible with the D-Bus syntax and naming
+ * conventions for bus names, the operation returns %NULL and @error is set.
+ *
+ * The calling thread is blocked until a reply is received.
+ *
+ * Returns: the unique bus names of connections currently queued for the @name
+ * or %NULL if @error is set. Free with g_strfreev().
+ *
+ * Since: 2.4x
+ */
+gchar **
+g_dbus_get_list_queued_owners (GDBusConnection *connection,
+ const gchar *name,
+ GError **error)
+{
+ gchar **strv;
+
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
+ g_return_val_if_fail (name == NULL || g_dbus_is_name (name), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ strv = _g_dbus_get_list_internal (connection, name, LIST_QUEUED_OWNERS, error);
+
+ return strv;
+}
+
+/**
+ * g_dbus_get_name_owner:
+ * @connection: a #GDBusConnection
+ * @name: well-known bus name to get the owner of
+ * @error: return location for error or %NULL
+ *
+ * Synchronously returns the unique connection name of the primary owner of
+ * the name given. If the requested name doesn't have an owner, an @error is
+ * returned.
+ *
+ * If @name contains a value not compatible with the D-Bus syntax and naming
+ * conventions for bus names, the operation returns %NULL and @error is set.
+ *
+ * The calling thread is blocked until a reply is received.
+ *
+ * Returns: the unique connection name of the primary owner of the
+ * name given. If the requested name doesn't have an owner, function
+ * returns %NULL and @error is set. Free with g_free().
+ *
+ * Since: 2.4x
+ */
+gchar *
+g_dbus_get_name_owner (GDBusConnection *connection,
+ const gchar *name,
+ GError **error)
+{
+ GVariant *result;
+ gchar *name_owner;
+
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
+ g_return_val_if_fail (name == NULL || g_dbus_is_name (name), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ name_owner = NULL;
+ result = NULL;
+
+ if (connection->kdbus_worker)
+ result = _g_kdbus_GetNameOwner (connection->kdbus_worker, name, error);
+ else
+ result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
+ "org.freedesktop.DBus", "GetNameOwner",
+ g_variant_new ("(s)", name), G_VARIANT_TYPE ("(s)"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
+ if (result != NULL)
+ {
+ g_variant_get (result, "(s)", &name_owner);
+ g_variant_unref (result);
+ }
+ else
+ name_owner = NULL;
+
+ return name_owner;
+}
+
+/**
+ * g_dbus_get_connection_pid:
+ * @connection: a #GDBusConnection
+ * @name: a unique or well-known bus name of the connection to query
+ * @error: return location for error or %NULL
+ *
+ * Synchronously returns the Unix process ID of the process connected to the
+ * bus. If unable to determine it, an @error is returned.
+ *
+ * If @name contains a value not compatible with the D-Bus syntax and naming
+ * conventions for bus names, the operation returns (guint32) -1 and @error
+ * is set.
+ *
+ * The calling thread is blocked until a reply is received.
+ *
+ * Returns: the Unix process ID of the process connected to the bus or
+ * (guint32) -1 if @error is set.
+ *
+ * Since: 2.4x
+ */
+guint32
+g_dbus_get_connection_pid (GDBusConnection *connection,
+ const gchar *name,
+ GError **error)
+{
+ GVariant *result;
+ guint32 pid;
+
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), -1);
+ g_return_val_if_fail (name == NULL || g_dbus_is_name (name), -1);
+ g_return_val_if_fail (error == NULL || *error == NULL, -1);
+
+ result = NULL;
+ pid = -1;
+
+ if (connection->kdbus_worker)
+ result = _g_kdbus_GetConnectionUnixProcessID (connection->kdbus_worker, name, error);
+ else
+ result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
+ "org.freedesktop.DBus", "GetConnectionUnixProcessID",
+ g_variant_new ("(s)", name), G_VARIANT_TYPE ("(u)"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
+ if (result != NULL)
+ {
+ g_variant_get (result, "(u)", &pid);
+ g_variant_unref (result);
+ }
+
+ return pid;
+}
+
+/**
+ * g_dbus_get_connection_uid:
+ * @connection: a #GDBusConnection
+ * @name: a unique or well-known bus name of the connection to query
+ * @error: return location for error or %NULL
+ *
+ * Synchronously returns the Unix user ID of the process connected to the
+ * bus. If unable to determine it, an @error is returned.
+ *
+ * If @name contains a value not compatible with the D-Bus syntax and naming
+ * conventions for bus names, the operation returns (guint32) -1 and @error
+ * is set.
+ *
+ * The calling thread is blocked until a reply is received.
+ *
+ * Returns: the Unix user ID of the process connected to the bus or
+ * (guint32) -1 if @error is set.
+ *
+ * Since: 2.4x
+ */
+guint32
+g_dbus_get_connection_uid (GDBusConnection *connection,
+ const gchar *name,
+ GError **error)
+{
+ GVariant *result;
+ guint32 uid;
+
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), -1);
+ g_return_val_if_fail (name == NULL || g_dbus_is_name (name), -1);
+ g_return_val_if_fail (error == NULL || *error == NULL, -1);
+
+ result = NULL;
+ uid = -1;
+
+ if (connection->kdbus_worker)
+ result = _g_kdbus_GetConnectionUnixUser (connection->kdbus_worker, name, error);
+ else
+ result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
+ "org.freedesktop.DBus", "GetConnectionUnixUser",
+ g_variant_new ("(s)", name), G_VARIANT_TYPE ("(u)"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
+ if (result != NULL)
+ {
+ g_variant_get (result, "(u)", &uid);
+ g_variant_unref (result);
+ }
+
+ return uid;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * g_dbus_connection_get_last_serial:
+ * @connection: a #GDBusConnection
+ *
+ * Retrieves the last serial number assigned to a #GDBusMessage on
+ * the current thread. This includes messages sent via both low-level
+ * API such as g_dbus_connection_send_message() as well as
+ * high-level API such as g_dbus_connection_emit_signal(),
+ * g_dbus_connection_call() or g_dbus_proxy_call().
+ *
+ * Returns: the last used serial or zero when no message has been sent
+ * within the current thread
+ *
+ * Since: 2.34
+ */
+guint32
+g_dbus_connection_get_last_serial (GDBusConnection *connection)
+{
+ guint32 ret;
+
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), 0);
+
+ CONNECTION_LOCK (connection);
+ ret = GPOINTER_TO_UINT (g_hash_table_lookup (connection->map_thread_to_last_serial,
+ g_thread_self ()));
+ CONNECTION_UNLOCK (connection);
+
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+#include "gkdbus.h"