summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/dconf.c2
-rw-r--r--client/dconf-client.c139
-rw-r--r--client/dconf-client.h21
-rw-r--r--engine/dconf-engine.c45
-rw-r--r--engine/dconf-engine.h10
-rw-r--r--gsettings/dconfsettingsbackend.c36
6 files changed, 195 insertions, 58 deletions
diff --git a/bin/dconf.c b/bin/dconf.c
index 4cdde3e..5702d9b 100644
--- a/bin/dconf.c
+++ b/bin/dconf.c
@@ -233,7 +233,7 @@ main (int argc, char **argv)
g_type_init ();
g_set_prgname (shift (&argc, &argv));
- client = dconf_client_new (NULL, NULL, NULL, NULL);
+ client = dconf_client_new (NULL, FALSE, NULL, NULL, NULL);
if (!do_sync_command (client, argc, argv, &error))
g_error ("%s\n", error->message);
diff --git a/client/dconf-client.c b/client/dconf-client.c
index c6e50c1..97e6ab7 100644
--- a/client/dconf-client.c
+++ b/client/dconf-client.c
@@ -6,7 +6,11 @@ struct _DConfClient
{
GObject parent_instance;
+ GDBusConnection *session_bus;
+ GDBusConnection *system_bus;
+
DConfEngine *engine;
+ gboolean will_write;
DConfWatchFunc watch_func;
gpointer user_data;
@@ -92,18 +96,49 @@ dconf_client_async_op_complete (DConfClientAsyncOp *op,
g_slice_free (DConfClientAsyncOp, op);
}
+static gboolean
+dconf_client_interpret_reply (DConfEngineMessage *dcem,
+ GDBusMessage *reply,
+ gchar **tag,
+ GError **error)
+{
+ gboolean success;
+
+ if (reply == NULL)
+ /* error will already have been set */
+ return FALSE;
+
+
+ success = dconf_engine_interpret_reply (dcem,
+ g_dbus_message_get_sender (reply),
+ g_dbus_message_get_body (reply),
+ tag, error);
+ g_object_unref (reply);
+
+ return success;
+}
+
+
static void
dconf_client_async_op_call_done (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
DConfClientAsyncOp *op = user_data;
- GVariant *reply;
+ GDBusMessage *reply;
- if ((reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object),
- result, &op->error)))
- g_simple_async_result_set_op_res_gpointer (op->simple, reply,
- (GDestroyNotify) g_variant_unref);
+ reply = g_dbus_connection_send_message_with_reply_finish (G_DBUS_CONNECTION (object),
+ result, &op->error);
+
+ if (reply != NULL)
+ {
+ gchar *tag;
+
+ if (dconf_client_interpret_reply (&op->dcem, reply, &tag, &op->error))
+ g_simple_async_result_set_op_res_gpointer (op->simple, tag, g_free);
+
+ g_object_unref (reply);
+ }
dconf_client_async_op_complete (op, FALSE);
}
@@ -141,7 +176,7 @@ static gboolean
dconf_client_async_op_finish (gpointer client,
GAsyncResult *result,
gpointer source_tag,
- guint64 *sequence,
+ gchar **tag,
GError **error)
{
GSimpleAsyncResult *simple;
@@ -154,9 +189,8 @@ dconf_client_async_op_finish (gpointer client,
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
- if (sequence)
- g_variant_get (g_simple_async_result_get_op_res_gpointer (simple),
- "(t)", sequence);
+ if (tag)
+ *tag = g_strdup (g_simple_async_result_get_op_res_gpointer (simple));
return TRUE;
}
@@ -198,6 +232,7 @@ dconf_client_class_init (DConfClientClass *class)
**/
DConfClient *
dconf_client_new (const gchar *context,
+ gboolean will_write,
DConfWatchFunc watch_func,
gpointer user_data,
GDestroyNotify notify)
@@ -205,6 +240,7 @@ dconf_client_new (const gchar *context,
DConfClient *client = g_object_new (DCONF_TYPE_CLIENT, NULL);
client->engine = dconf_engine_new (context);
+ client->will_write = will_write;
client->watch_func = watch_func;
client->user_data = user_data;
client->notify = notify;
@@ -272,10 +308,24 @@ dconf_client_read_no_default (DConfClient *client,
return dconf_engine_read (client->engine, key, DCONF_READ_SET);
}
+static GDBusMessage *
+dconf_client_create_call (DConfEngineMessage *dcem)
+{
+ GDBusMessage *message;
+
+ message = g_dbus_message_new_method_call (dcem->destination,
+ dcem->object_path,
+ dcem->interface,
+ dcem->method);
+ g_dbus_message_set_body (message, dcem->body);
+
+ return message;
+}
+
static gboolean
dconf_client_call_sync (DConfClient *client,
DConfEngineMessage *dcem,
- guint64 *sequence,
+ gchar **tag,
GCancellable *cancellable,
GError **error)
{
@@ -289,22 +339,17 @@ dconf_client_call_sync (DConfClient *client,
if (dcem->body)
{
- GVariant *reply;
+ GDBusMessage *message, *reply;
- reply = g_dbus_connection_call_sync (connection, dcem->destination,
- dcem->object_path, dcem->interface,
- dcem->method, dcem->body,
- dcem->reply_type,
- G_DBUS_CALL_FLAGS_NONE, -1,
- cancellable, error);
+ message = dconf_client_create_call (dcem);
+ reply = g_dbus_connection_send_message_with_reply_sync (connection,
+ message,
+ -1, NULL,
+ cancellable,
+ error);
+ g_object_unref (message);
- if (reply == NULL)
- return FALSE;
-
- if (sequence)
- g_variant_get (reply, "(t)", sequence);
-
- g_variant_unref (reply);
+ return dconf_client_interpret_reply (dcem, reply, tag, error);
}
return TRUE;
@@ -313,6 +358,7 @@ dconf_client_call_sync (DConfClient *client,
/**
* dconf_client_write:
* @client: a #DConfClient
+ * @key: a dconf key
* @value (allow-none): a #GVariant, or %NULL
* @sequence: (out) (allow-none): the sequence number of this write
* @cancellable: a #GCancellable, or %NULL
@@ -323,12 +369,15 @@ dconf_client_call_sync (DConfClient *client,
*
* If @value is %NULL then @key is reset to its default value (which may
* be completely unset), otherwise @value becomes the new value.
+ *
+ * If @sequence is non-%NULL then it is set to the sequence number of
+ * this write. The sequence number is unique to this process.
**/
gboolean
dconf_client_write (DConfClient *client,
const gchar *key,
GVariant *value,
- guint64 *sequence,
+ gchar **tag,
GCancellable *cancellable,
GError **error)
{
@@ -337,9 +386,24 @@ dconf_client_write (DConfClient *client,
if (!dconf_engine_write (client->engine, &dcem, key, value, error))
return FALSE;
- return dconf_client_call_sync (client, &dcem, sequence, cancellable, error);
+ return dconf_client_call_sync (client, &dcem, tag, cancellable, error);
}
+/**
+ * dconf_client_write_async:
+ * @client: a #DConfClient
+ * @key: a dconf key
+ * @value (allow-none): a #GVariant, or %NULL
+ * @cancellable: a #GCancellable, or %NULL
+ * @callback: the function to call when complete
+ * @user_data: the user data for @callback
+ *
+ * Writes a value to the given @key, or reset @key to its default value.
+ *
+ * This is the asynchronous version of dconf_client_write(). You should
+ * call dconf_client_write_finish() from @callback to collect the
+ * result.
+ **/
void
dconf_client_write_async (DConfClient *client,
const gchar *key,
@@ -356,15 +420,23 @@ dconf_client_write_async (DConfClient *client,
dconf_client_async_op_run (op);
}
+/**
+ * dconf_client_write_finish:
+ * @client: a #DConfClient
+ * @sequence: (out) (allow-none): the sequence number of this write
+ * @error: a pointer to a #GError, or %NULL
+ *
+ * Collects the result from a prior call to dconf_client_write_async().
+ **/
gboolean
dconf_client_write_finish (DConfClient *client,
GAsyncResult *result,
- guint64 *sequence,
+ gchar **tag,
GError **error)
{
return dconf_client_async_op_finish (client, result,
dconf_client_write_async,
- sequence, error);
+ tag, error);
}
/**
@@ -414,14 +486,12 @@ dconf_client_is_writable (DConfClient *client,
return dconf_client_call_sync (client, &dcem, NULL, NULL, error);
}
-
-
gboolean
dconf_client_write_many (DConfClient *client,
const gchar *prefix,
const gchar * const *rels,
GVariant **values,
- guint64 *sequence,
+ gchar **tag,
GCancellable *cancellable,
GError **error)
{
@@ -430,7 +500,7 @@ dconf_client_write_many (DConfClient *client,
if (!dconf_engine_write_many (client->engine, &dcem, prefix, rels, values, error))
return FALSE;
- return dconf_client_call_sync (client, &dcem, sequence, cancellable, error);
+ return dconf_client_call_sync (client, &dcem, tag, cancellable, error);
}
void
@@ -454,12 +524,12 @@ dconf_client_write_many_async (DConfClient *client,
gboolean
dconf_client_write_many_finish (DConfClient *client,
GAsyncResult *result,
- guint64 *sequence,
+ gchar **tag,
GError **error)
{
return dconf_client_async_op_finish (client, result,
dconf_client_write_many_async,
- sequence, error);
+ tag, error);
}
#if 0
@@ -485,4 +555,3 @@ gboolean dconf_client_unwatch_finish (DConfCl
gpointer user_data);
#endif
-
diff --git a/client/dconf-client.h b/client/dconf-client.h
index 4f79cc2..989ad3c 100644
--- a/client/dconf-client.h
+++ b/client/dconf-client.h
@@ -13,16 +13,29 @@ typedef GObjectClass DConfClientClass;
typedef struct _DConfClient DConfClient;
typedef void (*DConfWatchFunc) (DConfClient *client,
+ const gchar *tag,
const gchar *path,
const gchar * const *items,
gpointer user_data);
GType dconf_client_get_type (void);
+
DConfClient * dconf_client_new (const gchar *context,
+ gboolean will_write,
DConfWatchFunc watch_func,
gpointer user_data,
GDestroyNotify notify);
+void dconf_client_new_async (const gchar *context,
+ gboolean will_write,
+ DConfWatchFunc watch_func,
+ gpointer watch_func_data,
+ GDestroyNotify notify,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+DConfClient * dconf_client_new_finish (GAsyncResult *result);
+
GVariant * dconf_client_read (DConfClient *client,
const gchar *key);
GVariant * dconf_client_read_default (DConfClient *client,
@@ -41,7 +54,7 @@ gboolean dconf_client_is_writable (DConfCl
gboolean dconf_client_write (DConfClient *client,
const gchar *key,
GVariant *value,
- guint64 *sequence,
+ gchar **sequence,
GCancellable *cancellable,
GError **error);
void dconf_client_write_async (DConfClient *client,
@@ -52,7 +65,7 @@ void dconf_client_write_async (DConfCl
gpointer user_data);
gboolean dconf_client_write_finish (DConfClient *client,
GAsyncResult *result,
- guint64 *sequence,
+ gchar **sequence,
GError **error);
gboolean dconf_client_set_locked (DConfClient *client,
@@ -74,7 +87,7 @@ gboolean dconf_client_write_many (DConfCl
const gchar *prefix,
const gchar * const *keys,
GVariant **values,
- guint64 *sequence,
+ gchar **sequence,
GCancellable *cancellable,
GError **error);
void dconf_client_write_many_async (DConfClient *client,
@@ -86,7 +99,7 @@ void dconf_client_write_many_async (DConfCl
gpointer user_data);
gboolean dconf_client_write_many_finish (DConfClient *client,
GAsyncResult *result,
- guint64 *sequence,
+ gchar **sequence,
GError **error);
gboolean dconf_client_watch (DConfClient *client,
diff --git a/engine/dconf-engine.c b/engine/dconf-engine.c
index 14054c9..1e36126 100644
--- a/engine/dconf-engine.c
+++ b/engine/dconf-engine.c
@@ -221,16 +221,28 @@ dconf_engine_list (DConfEngine *engine,
return list;
}
+static gchar *
+dconf_engine_make_tag (guint bus_type,
+ const gchar *sender,
+ guint64 seqno)
+{
+ return g_strdup_printf ("%c/%s/%"G_GUINT64_FORMAT, bus_type, sender, seqno);
+}
+
gboolean
dconf_engine_decode_notify (DConfEngine *engine,
- guint64 anti_expose,
+ const gchar *anti_expose,
const gchar **path,
const gchar ***rels,
+ guint bus_type,
+ const gchar *sender,
const gchar *iface,
const gchar *method,
GVariant *body)
{
- guint64 ae;
+ gboolean matched;
+ guint64 seqno;
+ gchar *ae;
if (strcmp (iface, "ca.desrt.dconf.Writer") || strcmp (method, "Notify"))
return FALSE;
@@ -238,12 +250,37 @@ dconf_engine_decode_notify (DConfEngine *engine,
if (!g_variant_is_of_type (body, G_VARIANT_TYPE ("(tsas)")))
return FALSE;
- g_variant_get_child (body, 0, "t", &ae);
+ g_variant_get_child (body, 0, "t", &seqno);
+
+ ae = dconf_engine_make_tag (bus_type, sender, seqno);
+ matched = strcmp (ae, anti_expose) == 0;
+ g_free (ae);
- if (ae == anti_expose)
+ if (matched)
return FALSE;
g_variant_get (body, "(t&s^a&s)", NULL, path, rels);
return TRUE;
}
+
+gboolean
+dconf_engine_interpret_reply (DConfEngineMessage *dcem,
+ const gchar *sender,
+ GVariant *body,
+ gchar **tag,
+ GError **error)
+{
+ /* typecheck and so on... */
+
+ if (tag != NULL)
+ {
+ guint64 sequence;
+
+ g_variant_get_child (body, 0, "t", &sequence);
+
+ *tag = dconf_engine_make_tag (dcem->bus_type, sender, sequence);
+ }
+
+ return TRUE;
+}
diff --git a/engine/dconf-engine.h b/engine/dconf-engine.h
index 2cf72c8..af9547c 100644
--- a/engine/dconf-engine.h
+++ b/engine/dconf-engine.h
@@ -61,9 +61,11 @@ void dconf_engine_unwatch (DConfEn
DConfEngineMessage *message,
const gchar *name);
gboolean dconf_engine_decode_notify (DConfEngine *engine,
- guint64 anti_expose,
+ const gchar *anti_expose,
const gchar **prefix,
const gchar ***keys,
+ guint bus_type,
+ const gchar *sender,
const gchar *interface,
const gchar *member,
GVariant *body);
@@ -72,4 +74,10 @@ void dconf_engine_set_locked (DConfEn
const gchar *path,
gboolean locked);
+gboolean dconf_engine_interpret_reply (DConfEngineMessage *message,
+ const gchar *sender,
+ GVariant *body,
+ gchar **tag,
+ GError **error);
+
#endif /* _dconf_engine_h_ */
diff --git a/gsettings/dconfsettingsbackend.c b/gsettings/dconfsettingsbackend.c
index 878409d..f3a549a 100644
--- a/gsettings/dconfsettingsbackend.c
+++ b/gsettings/dconfsettingsbackend.c
@@ -37,9 +37,9 @@ typedef struct
DConfEngine *engine;
GDBusConnection *session_bus;
- guint64 session_anti_expose;
+ gchar *session_anti_expose;
GDBusConnection *system_bus;
- guint64 system_anti_expose;
+ gchar *system_anti_expose;
Outstanding *outstanding;
} DConfSettingsBackend;
@@ -103,9 +103,10 @@ dconf_settings_backend_new_outstanding (DConfSettingsBackend *dcsb,
}
static gboolean
-dconf_settings_backend_remove_outstanding (DConfSettingsBackend *dcsb,
- GDBusMessage *message,
- guint64 *anti_expose)
+dconf_settings_backend_remove_outstanding (DConfSettingsBackend *dcsb,
+ guint bus_type,
+ GDBusMessage *message,
+ gchar **anti_expose)
{
gboolean found = FALSE;
Outstanding **node;
@@ -247,13 +248,15 @@ dconf_settings_backend_scan_outstanding (DConfSettingsBackend *backend,
static void
dconf_settings_backend_incoming_signal (DConfSettingsBackend *dcsb,
+ guint bt,
GDBusMessage *message,
- const guint64 *anti_expose)
+ const gchar *anti_expose)
{
const gchar **rels;
const gchar *path;
- if (dconf_engine_decode_notify (dcsb->engine, *anti_expose, &path, &rels,
+ if (dconf_engine_decode_notify (dcsb->engine, anti_expose, &path, &rels, bt,
+ g_dbus_message_get_sender (message),
g_dbus_message_get_interface (message),
g_dbus_message_get_member (message),
g_dbus_message_get_body (message)))
@@ -279,13 +282,19 @@ dconf_settings_backend_filter (GDBusConnection *connection,
gpointer user_data)
{
DConfSettingsBackend *dcsb = user_data;
- guint64 *ae;
+ guint bus_type;
+ gchar **ae;
if (connection == dcsb->session_bus)
- ae = &dcsb->session_anti_expose;
-
+ {
+ ae = &dcsb->session_anti_expose;
+ bus_type = 'e';
+ }
else if (connection == dcsb->system_bus)
- ae = &dcsb->system_anti_expose;
+ {
+ ae = &dcsb->system_anti_expose;
+ bus_type = 'y';
+ }
else
g_assert_not_reached ();
@@ -293,10 +302,11 @@ dconf_settings_backend_filter (GDBusConnection *connection,
switch (g_dbus_message_get_message_type (message))
{
case G_DBUS_MESSAGE_TYPE_METHOD_RETURN:
- return dconf_settings_backend_remove_outstanding (dcsb, message, ae);
+ return dconf_settings_backend_remove_outstanding (dcsb, bus_type,
+ message, ae);
case G_DBUS_MESSAGE_TYPE_SIGNAL:
- dconf_settings_backend_incoming_signal (dcsb, message, ae);
+ dconf_settings_backend_incoming_signal (dcsb, bus_type, message, *ae);
default:
return FALSE;