[dconf] fill in missing parts of dconf API
- From: Ryan Lortie <ryanl src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [dconf] fill in missing parts of dconf API
- Date: Fri, 18 Sep 2009 02:17:37 +0000 (UTC)
commit 5aec98254ce866ac0d8101e0e00a1e19838cb5f0
Author: Ryan Lortie <desrt desrt ca>
Date: Thu Sep 17 22:10:42 2009 -0400
fill in missing parts of dconf API
update GSettings backend accordingly
dconf/dconf-core.c | 137 ++++++++++++++++++++----
dconf/dconf-dbus.c | 298 +++++++++++++++++++++++++++++++++-------------------
dconf/dconf-dbus.h | 26 ++++-
dconf/dconf.h | 32 +++++-
gio/dconfstorage.c | 6 +-
5 files changed, 360 insertions(+), 139 deletions(-)
---
diff --git a/dconf/dconf-core.c b/dconf/dconf-core.c
index fea59a5..30cb9c9 100644
--- a/dconf/dconf-core.c
+++ b/dconf/dconf-core.c
@@ -403,7 +403,7 @@ dconf_unwatch (const gchar *match,
}
/**
- * dconf_merge_tree:
+ * dconf_merge:
* @prefix: the common part of the path to write to
* @tree: a list of the values to store
* @event_id: a pointer for the event ID return (or %NULL)
@@ -449,9 +449,28 @@ dconf_unwatch (const gchar *match,
* notification corresponding to this modification and is unique for the
* life of the program. It has no particular format.
**/
+gboolean
+dconf_merge (const gchar *prefix,
+ GTree *tree,
+ gchar **event_id,
+ GError **error)
+{
+ DConfMount *mount;
+
+ g_assert (prefix != NULL);
+ g_assert (tree != NULL);
+
+ g_assert (g_str_has_suffix (prefix, "/") || g_tree_nnodes (tree) == 1);
+ g_assert (g_str_has_prefix (prefix, "/"));
+
+ mount = dconf_demux_path (&prefix, TRUE, NULL);
+ g_assert (mount);
+
+ return dconf_dbus_merge (mount->dbs[0]->bus, prefix, tree, event_id, error);
+}
/**
- * dconf_merge_tree_async:
+ * dconf_merge_async:
* @prefix: the common part of the path to write to
* @values: a list of the values to store
* @callback: the completion callback
@@ -459,16 +478,16 @@ dconf_unwatch (const gchar *match,
*
* Atomically set the value of several keys.
*
- * This is the asynchronous variant of dconf_merge_tree(). When the
- * merge is complete, @callback will be called with a #DConfAsyncResult
- * and @user_data. You should pass the #DConfAsyncResult to
+ * This is the asynchronous variant of dconf_merge(). When the merge is
+ * complete, @callback will be called with a #DConfAsyncResult and
+ * @user_data. You should pass the #DConfAsyncResult to
* dconf_merge_finish() to collect the result.
**/
void
-dconf_merge_tree_async (const gchar *prefix,
- GTree *tree,
- DConfAsyncReadyCallback callback,
- gpointer user_data)
+dconf_merge_async (const gchar *prefix,
+ GTree *tree,
+ DConfAsyncReadyCallback callback,
+ gpointer user_data)
{
DConfMount *mount;
@@ -481,31 +500,29 @@ dconf_merge_tree_async (const gchar *prefix,
mount = dconf_demux_path (&prefix, TRUE, NULL);
g_assert (mount);
- dconf_dbus_merge_tree_async (mount->dbs[0]->bus, prefix, tree,
- (DConfDBusAsyncReadyCallback) callback,
- user_data);
+ dconf_dbus_merge_async (mount->dbs[0]->bus, prefix, tree,
+ (DConfDBusAsyncReadyCallback) callback,
+ user_data);
}
/**
- * dconf_merge_tree:
+ * dconf_merge_finish:
* @result: the #DConfAsyncResult given to your callback
* @event_id: a pointer for the event ID return (or %NULL)
* @error: a pointer to a %NULL #GError pointer (or %NULL)
* @returns: %TRUE on success
*
- * Collects the results from a call to dconf_merge_tree_async() or
- * dconf_merge_array_async().
+ * Collects the results from a call to dconf_merge_async().
*
- * This is the shared second half of the asyncronous variants of
- * dconf_merge_array() and dconf_merge_tree().
+ * This is the second half of the asyncronous variant of dconf_merge().
**/
gboolean
dconf_merge_finish (DConfAsyncResult *result,
gchar **event_id,
GError **error)
{
- return dconf_dbus_merge_finish ((DConfDBusAsyncResult *) result,
- event_id, error);
+ return dconf_dbus_async_finish ((DConfDBusAsyncResult *) result,
+ "u", event_id, error);
}
gboolean
@@ -525,6 +542,34 @@ dconf_set (const gchar *key,
return dconf_dbus_set (mount->dbs[0]->bus, key, value, event_id, error);
}
+void
+dconf_set_async (const gchar *key,
+ GVariant *value,
+ DConfAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ DConfMount *mount;
+
+ g_assert (dconf_is_key (key));
+ g_assert (value != NULL);
+
+ mount = dconf_demux_path (&key, TRUE, NULL);
+ g_assert (mount);
+
+ dconf_dbus_set_async (mount->dbs[0]->bus, key, value,
+ (DConfDBusAsyncReadyCallback) callback,
+ user_data);
+}
+
+gboolean
+dconf_set_finish (DConfAsyncResult *result,
+ gchar **event_id,
+ GError **error)
+{
+ return dconf_dbus_async_finish ((DConfDBusAsyncResult *) result,
+ "u", event_id, error);
+}
+
gboolean
dconf_reset (const gchar *key,
gchar **event_id,
@@ -537,7 +582,33 @@ dconf_reset (const gchar *key,
if ((mount = dconf_demux_path (&key, TRUE, error)) == NULL)
return FALSE;
- return dconf_dbus_unset (mount->dbs[0]->bus, key, event_id, error);
+ return dconf_dbus_reset (mount->dbs[0]->bus, key, event_id, error);
+}
+
+void
+dconf_reset_async (const gchar *key,
+ DConfAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ DConfMount *mount;
+
+ g_assert (dconf_is_key (key));
+
+ mount = dconf_demux_path (&key, TRUE, NULL);
+ g_assert (mount);
+
+ dconf_dbus_reset_async (mount->dbs[0]->bus, key,
+ (DConfDBusAsyncReadyCallback) callback,
+ user_data);
+}
+
+gboolean
+dconf_reset_finish (DConfAsyncResult *result,
+ gchar **event_id,
+ GError **error)
+{
+ return dconf_dbus_async_finish ((DConfDBusAsyncResult *) result,
+ "u", event_id, error);
}
gboolean
@@ -552,7 +623,31 @@ dconf_set_locked (const gchar *key,
if ((mount = dconf_demux_path (&key, TRUE, error)) == NULL)
return FALSE;
- return dconf_dbus_set_locked (mount->dbs[0]->bus, key, locked, error);
+ return dconf_dbus_set_locked (mount->dbs[0]->bus, key, !!locked, error);
}
+void
+dconf_set_locked_async (const gchar *key,
+ gboolean locked,
+ DConfAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ DConfMount *mount;
+ g_assert (dconf_is_key (key));
+
+ mount = dconf_demux_path (&key, TRUE, NULL);
+ g_assert (mount);
+
+ dconf_dbus_set_locked_async (mount->dbs[0]->bus, key, !!locked,
+ (DConfDBusAsyncReadyCallback) callback,
+ user_data);
+}
+
+gboolean
+dconf_set_locked_finish (DConfAsyncResult *result,
+ GError **error)
+{
+ return dconf_dbus_async_finish ((DConfDBusAsyncResult *) result,
+ "", NULL, error);
+}
diff --git a/dconf/dconf-dbus.c b/dconf/dconf-dbus.c
index 1ce3a00..f6fd548 100644
--- a/dconf/dconf-dbus.c
+++ b/dconf/dconf-dbus.c
@@ -522,23 +522,94 @@ dconf_dbus_blocking_call (DConfDBus *bus,
return TRUE;
}
-gboolean
-dconf_dbus_set (DConfDBus *bus,
- const gchar *key,
- GVariant *value,
- gchar **event_id,
- GError **error)
+typedef struct
+{
+ DConfDBus *bus;
+ DConfDBusAsyncReadyCallback callback;
+ gpointer user_data;
+} DConfDBusClosure;
+
+struct OPAQUE_TYPE__DConfDBusAsyncResult
+{
+ DConfDBus *bus;
+ DBusPendingCall *pending;
+};
+
+static DConfDBusClosure *
+dconf_dbus_closure_new (DConfDBus *bus,
+ DConfDBusAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ DConfDBusClosure *closure;
+
+ closure = g_slice_new (DConfDBusClosure);
+ closure->bus = bus;
+ closure->callback = callback;
+ closure->user_data = user_data;
+
+ return closure;
+}
+
+static void
+dconf_dbus_closure_fire (DConfDBusClosure *closure,
+ DBusPendingCall *pending)
+{
+ DConfDBusAsyncResult result = { closure->bus, pending };
+
+ closure->callback (&result, closure->user_data);
+ g_slice_free (DConfDBusClosure, closure);
+}
+
+static void
+dconf_dbus_async_ready (DBusPendingCall *pending,
+ gpointer user_data)
+{
+ DConfDBusClosure *closure = user_data;
+
+ dconf_dbus_closure_fire (closure, pending);
+}
+
+static void
+dconf_dbus_async_call (DConfDBus *bus,
+ DBusMessage *message,
+ DConfDBusAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ DBusPendingCall *pending;
+
+ dbus_connection_send_with_reply (bus->connection, message, &pending, -1);
+ dbus_pending_call_set_notify (pending, dconf_dbus_async_ready,
+ dconf_dbus_closure_new (bus, callback,
+ user_data),
+ NULL);
+ dbus_message_unref (message);
+}
+
+
+static DBusMessage *
+dconf_dbus_new_call (DConfDBus *bus,
+ const gchar *method)
+{
+ DBusMessage *message;
+ gchar *bus_name;
+
+ bus_name = g_strdup_printf ("ca.desrt.dconf.writer.%s", bus->name + 1);
+ message = dbus_message_new_method_call (bus_name, bus->name,
+ "ca.desrt.dconf.writer", method);
+ g_free (bus_name);
+
+ return message;
+}
+
+static DBusMessage *
+dconf_dbus_new_set_call (DConfDBus *bus,
+ const gchar *key,
+ GVariant *value)
{
DBusMessageIter iter, variant;
DBusMessage *message;
- {
- gchar *bus_name = g_strdup_printf ("ca.desrt.dconf.writer.%s",
- bus->name + 1);
- message = dbus_message_new_method_call (bus_name, bus->name,
- "ca.desrt.dconf.writer", "Set");
- g_free (bus_name);
- }
+ message = dconf_dbus_new_call (bus, "Set");
dbus_message_iter_init_append (message, &iter);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
@@ -548,112 +619,108 @@ dconf_dbus_set (DConfDBus *bus,
dconf_dbus_from_gv (&variant, value);
dbus_message_iter_close_container (&iter, &variant);
- return dconf_dbus_blocking_call (bus, message, "u", event_id, error);
+ return message;
}
+/* == set == */
gboolean
-dconf_dbus_unset (DConfDBus *bus,
- const gchar *key,
- gchar **event_id,
- GError **error)
+dconf_dbus_set (DConfDBus *bus,
+ const gchar *key,
+ GVariant *value,
+ gchar **event_id,
+ GError **error)
{
- DBusMessageIter iter;
- DBusMessage *message;
- DBusMessage *reply;
-
- {
- gchar *bus_name = g_strdup_printf ("ca.desrt.dconf.writer.%s",
- bus->name + 1);
- message = dbus_message_new_method_call (bus_name, bus->name,
- "ca.desrt.dconf.writer", "Unset");
- g_free (bus_name);
- }
-
- dbus_message_iter_init_append (message, &iter);
- dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
-
- reply = dbus_connection_send_with_reply_and_block (bus->connection,
- message,
- -1, NULL);
-
+ DBusMessage *message = dconf_dbus_new_set_call (bus, key, value);
return dconf_dbus_blocking_call (bus, message, "u", event_id, error);
}
-gboolean
-dconf_dbus_set_locked (DConfDBus *bus,
- const gchar *key,
- gboolean locked,
- GError **error)
+void
+dconf_dbus_set_async (DConfDBus *bus,
+ const gchar *key,
+ GVariant *value,
+ DConfDBusAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ DBusMessage *message = dconf_dbus_new_set_call (bus, key, value);
+ dconf_dbus_async_call (bus, message, callback, user_data);
+}
+
+/* == reset == */
+static DBusMessage *
+dconf_dbus_new_reset_call (DConfDBus *bus,
+ const gchar *key)
{
DBusMessageIter iter;
DBusMessage *message;
- dbus_bool_t val;
-
- {
- gchar *bus_name = g_strdup_printf ("ca.desrt.dconf.writer.%s",
- bus->name + 1);
- message = dbus_message_new_method_call (bus_name, bus->name,
- "ca.desrt.dconf.writer",
- "SetLocked");
- g_free (bus_name);
- }
- val = !!locked;
+ message = dconf_dbus_new_call (bus, "Reset");
dbus_message_iter_init_append (message, &iter);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
- dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &val);
- return dconf_dbus_blocking_call (bus, message, "", NULL, error);
+ return message;
}
-typedef struct
+gboolean
+dconf_dbus_reset (DConfDBus *bus,
+ const gchar *key,
+ gchar **event_id,
+ GError **error)
{
- DConfDBus *bus;
- DConfDBusAsyncReadyCallback callback;
- gpointer user_data;
-} DConfDBusClosure;
+ DBusMessage *message = dconf_dbus_new_reset_call (bus, key);
+ return dconf_dbus_blocking_call (bus, message, "u", event_id, error);
+}
-static DConfDBusClosure *
-dconf_dbus_closure_new (DConfDBus *bus,
+void
+dconf_dbus_reset_async (DConfDBus *bus,
+ const gchar *key,
DConfDBusAsyncReadyCallback callback,
gpointer user_data)
{
- DConfDBusClosure *closure;
-
- closure = g_slice_new (DConfDBusClosure);
- closure->bus = bus;
- closure->callback = callback;
- closure->user_data = user_data;
-
- return closure;
+ DBusMessage *message = dconf_dbus_new_reset_call (bus, key);
+ dconf_dbus_async_call (bus, message, callback, user_data);
}
-struct OPAQUE_TYPE__DConfDBusAsyncResult
+/* == set_locked == */
+static DBusMessage *
+dconf_dbus_new_set_locked_call (DConfDBus *bus,
+ const gchar *key,
+ dbus_bool_t locked)
{
- DConfDBus *bus;
- DBusPendingCall *pending;
-};
+ DBusMessageIter iter;
+ DBusMessage *message;
-static void
-dconf_dbus_closure_fire (DConfDBusClosure *closure,
- DBusPendingCall *pending)
-{
- DConfDBusAsyncResult result = { closure->bus, pending };
+ message = dconf_dbus_new_call (bus, "SetLocked");
- closure->callback (&result, closure->user_data);
- g_slice_free (DConfDBusClosure, closure);
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &locked);
+
+ return message;
}
-static void
-dconf_dbus_merge_ready (DBusPendingCall *pending,
- gpointer user_data)
+gboolean
+dconf_dbus_set_locked (DConfDBus *bus,
+ const gchar *key,
+ gboolean locked,
+ GError **error)
{
- DConfDBusClosure *closure = user_data;
+ DBusMessage *message = dconf_dbus_new_set_locked_call (bus, key, locked);
+ return dconf_dbus_blocking_call (bus, message, "", NULL, error);
+}
- dconf_dbus_closure_fire (closure, pending);
+void
+dconf_dbus_set_locked_async (DConfDBus *bus,
+ const gchar *key,
+ gboolean locked,
+ DConfDBusAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ DBusMessage *message = dconf_dbus_new_set_locked_call (bus, key, locked);
+ dconf_dbus_async_call (bus, message, callback, user_data);
}
+/* == merge == */
static gboolean
dconf_dbus_append_to_iter (gpointer key,
gpointer value,
@@ -677,40 +744,51 @@ dconf_dbus_append_to_iter (gpointer key,
return FALSE;
}
-void
-dconf_dbus_merge_tree_async (DConfDBus *bus,
- const gchar *prefix,
- GTree *values,
- DConfDBusAsyncReadyCallback callback,
- gpointer user_data)
+static DBusMessage *
+dconf_dbus_new_merge_call (DConfDBus *bus,
+ const gchar *prefix,
+ GTree *tree)
{
DBusMessageIter iter, array;
- DBusPendingCall *pending;
DBusMessage *message;
- {
- gchar *bus_name = g_strdup_printf ("ca.desrt.dconf.writer.%s",
- bus->name + 1);
- message = dbus_message_new_method_call (bus_name, bus->name,
- "ca.desrt.dconf.writer", "Merge");
- g_free (bus_name);
- }
+ message = dconf_dbus_new_call (bus, "Merge");
dbus_message_iter_init_append (message, &iter);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &prefix);
dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "(sv)", &array);
- g_tree_foreach (values, dconf_dbus_append_to_iter, &array);
+ g_tree_foreach (tree, dconf_dbus_append_to_iter, &array);
dbus_message_iter_close_container (&iter, &array);
- dbus_connection_send_with_reply (bus->connection, message, &pending, -1);
- dbus_pending_call_set_notify (pending, dconf_dbus_merge_ready,
- dconf_dbus_closure_new (bus, callback,
- user_data),
- NULL);
+ return message;
+}
+
+
+gboolean
+dconf_dbus_merge (DConfDBus *bus,
+ const gchar *prefix,
+ GTree *tree,
+ gchar **event_id,
+ GError **error)
+{
+ DBusMessage *message = dconf_dbus_new_merge_call (bus, prefix, tree);
+ return dconf_dbus_blocking_call (bus, message, "u", event_id, error);
+}
+
+void
+dconf_dbus_merge_async (DConfDBus *bus,
+ const gchar *prefix,
+ GTree *tree,
+ DConfDBusAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ DBusMessage *message = dconf_dbus_new_merge_call (bus, prefix, tree);
+ dconf_dbus_async_call (bus, message, callback, user_data);
}
gboolean
-dconf_dbus_merge_finish (DConfDBusAsyncResult *result,
+dconf_dbus_async_finish (DConfDBusAsyncResult *result,
+ const gchar *signature,
gchar **event_id,
GError **error)
{
@@ -732,13 +810,13 @@ dconf_dbus_merge_finish (DConfDBusAsyncResult *result,
if (have_message)
g_set_error (error, 0, 0, "%s: %s", code, message);
else
- g_set_error (error, 0, 0, "dbus error: %s", code);
+ g_set_error (error, 0, 0, "DBus error: %s", code);
success = FALSE;
}
- else if (!dbus_message_has_signature (reply, "u"))
+ else if (!dbus_message_has_signature (reply, signature))
{
- g_set_error (error, 0, 0, "bad sig");
+ g_set_error (error, 0, 0, "unexpected signature in DBus reply");
success = FALSE;
}
else
diff --git a/dconf/dconf-dbus.h b/dconf/dconf-dbus.h
index c176663..d9351fd 100644
--- a/dconf/dconf-dbus.h
+++ b/dconf/dconf-dbus.h
@@ -33,24 +33,44 @@ gboolean dconf_dbus_set (DConfDB
GVariant *value,
gchar **event_id,
GError **error);
+void dconf_dbus_set_async (DConfDBus *bus,
+ const gchar *path,
+ GVariant *value,
+ DConfDBusAsyncReadyCallback callback,
+ gpointer user_data);
-gboolean dconf_dbus_unset (DConfDBus *bus,
+gboolean dconf_dbus_reset (DConfDBus *bus,
const gchar *path,
gchar **event_id,
GError **error);
+void dconf_dbus_reset_async (DConfDBus *bus,
+ const gchar *path,
+ DConfDBusAsyncReadyCallback callback,
+ gpointer user_data);
gboolean dconf_dbus_set_locked (DConfDBus *bus,
const gchar *path,
gboolean locked,
GError **error);
+void dconf_dbus_set_locked_async (DConfDBus *bus,
+ const gchar *path,
+ gboolean locked,
+ DConfDBusAsyncReadyCallback callback,
+ gpointer user_data);
-void dconf_dbus_merge_tree_async (DConfDBus *bus,
+gboolean dconf_dbus_merge (DConfDBus *bus,
+ const gchar *prefix,
+ GTree *values,
+ gchar **event_id,
+ GError **error);
+void dconf_dbus_merge_async (DConfDBus *bus,
const gchar *prefix,
GTree *values,
DConfDBusAsyncReadyCallback callback,
gpointer user_data);
-gboolean dconf_dbus_merge_finish (DConfDBusAsyncResult *result,
+gboolean dconf_dbus_async_finish (DConfDBusAsyncResult *result,
+ const gchar *signature,
gchar **event_id,
GError **error);
diff --git a/dconf/dconf.h b/dconf/dconf.h
index dd4b33f..b4798c1 100644
--- a/dconf/dconf.h
+++ b/dconf/dconf.h
@@ -35,28 +35,56 @@ gchar ** dconf_list (const g
gboolean dconf_get_writable (const gchar *path);
gboolean dconf_get_locked (const gchar *path);
+
+
gboolean dconf_set (const gchar *key,
GVariant *value,
gchar **event_id,
GError **error);
+void dconf_set_async (const gchar *key,
+ GVariant *value,
+ DConfAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean dconf_set_finish (DConfAsyncResult *result,
+ gchar **event_id,
+ GError **error);
+
gboolean dconf_set_locked (const gchar *key,
gboolean locked,
GError **error);
+void dconf_set_locked_async (const gchar *key,
+ gboolean locked,
+ DConfAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean dconf_set_locked_finish (DConfAsyncResult *result,
+ GError **error);
+
gboolean dconf_reset (const gchar *key,
gchar **event_id,
GError **error);
+void dconf_reset_async (const gchar *key,
+ DConfAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean dconf_reset_finish (DConfAsyncResult *result,
+ gchar **event_id,
+ GError **error);
+
-void dconf_merge_tree_async (const gchar *prefix,
+gboolean dconf_merge (const gchar *prefix,
+ GTree *tree,
+ gchar **event_id,
+ GError **error);
+void dconf_merge_async (const gchar *prefix,
GTree *tree,
DConfAsyncReadyCallback callback,
gpointer user_data);
-
gboolean dconf_merge_finish (DConfAsyncResult *result,
gchar **event_id,
GError **error);
+
void dconf_watch (const gchar *match,
DConfWatchFunc func,
gpointer user_data);
diff --git a/gio/dconfstorage.c b/gio/dconfstorage.c
index 512592b..7464712 100644
--- a/gio/dconfstorage.c
+++ b/gio/dconfstorage.c
@@ -87,9 +87,9 @@ dconf_storage_write (GSettingsBackend *backend,
item->prefix_len = strlen (item->prefix);
path = g_strconcat (storage->base, prefix, NULL);
- dconf_merge_tree_async (path, values,
- dconf_storage_merge_complete,
- storage);
+ dconf_merge_async (path, values,
+ dconf_storage_merge_complete,
+ storage);
g_free (path);
storage->item_list = g_list_insert_before (storage->item_list,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]