[evince/wip/app: 1/19] shell: Use gdbus-codegen for the org.gnome.evince.Application interface
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince/wip/app: 1/19] shell: Use gdbus-codegen for the org.gnome.evince.Application interface
- Date: Fri, 29 Jun 2012 10:08:03 +0000 (UTC)
commit 8172b502f03e879595d02199493d6f9b7f241325
Author: Christian Persch <chpe gnome org>
Date: Sun Jun 10 16:05:59 2012 +0200
shell: Use gdbus-codegen for the org.gnome.evince.Application interface
configure.ac | 6 +
shell/Makefile.am | 18 ++++
shell/ev-application.c | 161 +++++---------------------------
shell/ev-application.h | 11 ++
shell/ev-gdbus.c | 161 ++++++++++++++++++++++++++++++++
shell/ev-gdbus.h | 58 ++++++++++++
shell/org.gnome.evince.Application.xml | 15 +++
7 files changed, 293 insertions(+), 137 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 1c37a33..ce784be 100644
--- a/configure.ac
+++ b/configure.ac
@@ -208,6 +208,12 @@ if test -z "$XMLLINT"; then
AC_MSG_ERROR([xmllint not found])
fi
+AC_ARG_VAR([GDBUS_CODEGEN],[the gdbus-codegen programme])
+AC_PATH_PROG([GDBUS_CODEGEN],[gdbus-codegen],[])
+if test -z "$GDBUS_CODEGEN"; then
+ AC_MSG_ERROR([gdbus-codegen not found])
+fi
+
# *********
# SM client
# *********
diff --git a/shell/Makefile.am b/shell/Makefile.am
index b730eb3..98158be 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -96,9 +96,15 @@ nodist_evince_SOURCES = \
if ENABLE_DBUS
evince_SOURCES += \
+ ev-gdbus.c \
+ ev-gdbus.h \
ev-media-player-keys.c \
ev-media-player-keys.h \
$(NULL)
+nodist_evince_SOURCES += \
+ ev-gdbus-generated.c \
+ ev-gdbus-generated.h \
+ $(NULL)
endif
evince_LDFLAGS = $(AM_LDFLAGS)
@@ -132,6 +138,10 @@ BUILT_SOURCES = \
ev-resources.c
if ENABLE_DBUS
+BUILT_SOURCES += ev-gdbus-generated.c ev-gdbus-generated.h
+endif
+
+if ENABLE_DBUS
evinced_SOURCES = \
ev-daemon.c \
$(NULL)
@@ -165,6 +175,14 @@ ev-marshal.c: $(srcdir)/ev-marshal.list
ev-resources.c: evince.gresource.xml Makefile $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies --sourcedir $(srcdir) $(srcdir)/evince.gresource.xml)
$(AM_V_GEN) XMLLINT=$(XMLLINT) $(GLIB_COMPILE_RESOURCES) --target $@ --sourcedir $(srcdir) --generate-source --c-name ev $<
+ev-gdbus-generated.c ev-gdbus-generated.h: org.gnome.evince.Application.xml Makefile
+ $(AM_V_GEN) $(GDBUS_CODEGEN) \
+ --interface-prefix=org.gnome.evince \
+ --c-namespace=Ev \
+ --c-generate-object-manager \
+ --generate-c-code ev-gdbus-generated \
+ $<
+
DISTCLEANFILES = $(BUILT_SOURCES)
-include $(top_srcdir)/git.mk
diff --git a/shell/ev-application.c b/shell/ev-application.c
index 34d67f5..8a58b2b 100644
--- a/shell/ev-application.c
+++ b/shell/ev-application.c
@@ -46,6 +46,7 @@
#include "ev-stock-icons.h"
#ifdef ENABLE_DBUS
+#include "ev-gdbus.h"
#include "ev-media-player-keys.h"
#endif /* ENABLE_DBUS */
@@ -57,8 +58,8 @@ struct _EvApplication {
gchar *dot_dir;
#ifdef ENABLE_DBUS
- GDBusConnection *connection;
- guint registration_id;
+ GDBusConnection *connection;
+ EvEvinceApplicationImpl *impl;
EvMediaPlayerKeys *keys;
gboolean doc_registered;
#endif
@@ -94,7 +95,7 @@ static void _ev_application_open_uri_at_dest (EvApplication *application,
EvWindowRunMode mode,
const gchar *search_string,
guint timestamp);
-static void ev_application_open_uri_in_window (EvApplication *application,
+ void ev_application_open_uri_in_window (EvApplication *application,
const char *uri,
EvWindow *ev_window,
GdkScreen *screen,
@@ -195,7 +196,7 @@ ev_application_init_session (EvApplication *application)
*
* Returns: a #GdkDisplay of the display with the passed name.
*/
-static GdkDisplay *
+GdkDisplay *
ev_display_open_if_needed (const gchar *name)
{
GSList *displays;
@@ -321,7 +322,7 @@ ev_spawn (const char *uri,
g_free (cmdline);
}
-static GList *
+GList *
ev_application_get_windows (EvApplication *application)
{
GList *l, *toplevels;
@@ -622,7 +623,7 @@ ev_application_unregister_uri (EvApplication *application,
}
#endif /* ENABLE_DBUS */
-static void
+void
ev_application_open_uri_in_window (EvApplication *application,
const char *uri,
EvWindow *ev_window,
@@ -636,6 +637,9 @@ ev_application_open_uri_in_window (EvApplication *application,
GdkWindow *gdk_window;
#endif
+ if (uri == NULL)
+ uri = application->uri;
+
if (screen) {
ev_stock_icons_set_screen (screen);
gtk_window_set_screen (GTK_WINDOW (ev_window), screen);
@@ -762,118 +766,6 @@ ev_application_open_window (EvApplication *application,
}
}
-#ifdef ENABLE_DBUS
-static void
-method_call_cb (GDBusConnection *connection,
- const gchar *sender,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *method_name,
- GVariant *parameters,
- GDBusMethodInvocation *invocation,
- gpointer user_data)
-{
- EvApplication *application = EV_APPLICATION (user_data);
- GList *windows, *l;
- guint timestamp;
- GVariantIter *iter;
- const gchar *key;
- GVariant *value;
- GdkDisplay *display = NULL;
- int screen_number = 0;
- EvLinkDest *dest = NULL;
- EvWindowRunMode mode = EV_WINDOW_MODE_NORMAL;
- const gchar *search_string = NULL;
- GdkScreen *screen = NULL;
-
- if (g_strcmp0 (method_name, "Reload") == 0) {
- g_variant_get (parameters, "(a{sv}u)", &iter, ×tamp);
-
- while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) {
- if (strcmp (key, "display") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
- display = ev_display_open_if_needed (g_variant_get_string (value, NULL));
- } else if (strcmp (key, "screen") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_INT32) {
- screen_number = g_variant_get_int32 (value);
- } else if (strcmp (key, "mode") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_UINT32) {
- mode = g_variant_get_uint32 (value);
- } else if (strcmp (key, "page-label") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
- dest = ev_link_dest_new_page_label (g_variant_get_string (value, NULL));
- } else if (strcmp (key, "named-dest") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
- dest = ev_link_dest_new_named (g_variant_get_string (value, NULL));
- } else if (strcmp (key, "page-index") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_UINT32) {
- dest = ev_link_dest_new_page (g_variant_get_uint32 (value));
- } else if (strcmp (key, "find-string") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
- search_string = g_variant_get_string (value, NULL);
- }
- }
- g_variant_iter_free (iter);
-
- if (display != NULL &&
- screen_number >= 0 &&
- screen_number < gdk_display_get_n_screens (display))
- screen = gdk_display_get_screen (display, screen_number);
- else
- screen = gdk_screen_get_default ();
-
- windows = ev_application_get_windows (application);
- for (l = windows; l != NULL; l = g_list_next (l)) {
- EvWindow *ev_window = EV_WINDOW (l->data);
-
- ev_application_open_uri_in_window (application, application->uri,
- ev_window,
- screen, dest, mode,
- search_string,
- timestamp);
- }
- g_list_free (windows);
-
- if (dest)
- g_object_unref (dest);
-
- g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
- } else if (g_strcmp0 (method_name, "GetWindowList") == 0) {
- GList *windows = ev_application_get_windows (application);
- GVariantBuilder builder;
- GList *l;
-
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ao)"));
- g_variant_builder_open (&builder, G_VARIANT_TYPE ("ao"));
-
- for (l = windows; l; l = g_list_next (l)) {
- EvWindow *window = (EvWindow *)l->data;
-
- g_variant_builder_add (&builder, "o", ev_window_get_dbus_object_path (window));
- }
-
- g_variant_builder_close (&builder);
- g_list_free (windows);
-
- g_dbus_method_invocation_return_value (invocation, g_variant_builder_end (&builder));
- }
-}
-
-static const char introspection_xml[] =
- "<node>"
- "<interface name='org.gnome.evince.Application'>"
- "<method name='Reload'>"
- "<arg type='a{sv}' name='args' direction='in'/>"
- "<arg type='u' name='timestamp' direction='in'/>"
- "</method>"
- "<method name='GetWindowList'>"
- "<arg type='ao' name='window_list' direction='out'/>"
- "</method>"
- "</interface>"
- "</node>";
-
-static const GDBusInterfaceVTable interface_vtable = {
- method_call_cb,
- NULL,
- NULL
-};
-
-static GDBusNodeInfo *introspection_data;
-#endif /* ENABLE_DBUS */
-
void
ev_application_open_uri_list (EvApplication *application,
GSList *uri_list,
@@ -1047,19 +939,15 @@ ev_application_shutdown (EvApplication *application)
g_object_unref (application->keys);
application->keys = NULL;
}
- if (application->registration_id != 0) {
- g_dbus_connection_unregister_object (application->connection,
- application->registration_id);
- application->registration_id = 0;
+ if (application->impl != NULL) {
+ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (application->impl));
+ g_object_unref (application->impl);
+ application->impl = NULL;
}
if (application->connection != NULL) {
g_object_unref (application->connection);
application->connection = NULL;
}
- if (introspection_data) {
- g_dbus_node_info_ref (introspection_data);
- introspection_data = NULL;
- }
#endif /* ENABLE_DBUS */
g_free (application->dot_dir);
@@ -1095,17 +983,16 @@ ev_application_init (EvApplication *ev_application)
#ifdef ENABLE_DBUS
ev_application->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
if (ev_application->connection != NULL) {
- introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
- g_assert (introspection_data != NULL);
-
- ev_application->registration_id =
- g_dbus_connection_register_object (ev_application->connection,
- APPLICATION_DBUS_OBJECT_PATH,
- introspection_data->interfaces[0],
- &interface_vtable,
- ev_application, NULL,
- &error);
- if (ev_application->registration_id == 0) {
+ EvEvinceApplicationImpl *impl;
+
+ impl = ev_evince_application_impl_new ();
+ if (g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (impl),
+ ev_application->connection,
+ APPLICATION_DBUS_OBJECT_PATH,
+ &error)) {
+ ev_application->impl = impl;
+ } else {
+ g_object_unref (impl);
g_printerr ("Failed to register bus object: %s\n", error->message);
g_error_free (error);
}
diff --git a/shell/ev-application.h b/shell/ev-application.h
index 64b9c8a..f40c44c 100644
--- a/shell/ev-application.h
+++ b/shell/ev-application.h
@@ -61,6 +61,14 @@ void ev_application_open_uri_at_dest (EvApplication *applicati
EvWindowRunMode mode,
const gchar *search_string,
guint32 timestamp);
+void ev_application_open_uri_in_window (EvApplication *application,
+ const char *uri,
+ EvWindow *ev_window,
+ GdkScreen *screen,
+ EvLinkDest *dest,
+ EvWindowRunMode mode,
+ const gchar *search_string,
+ guint32 timestamp);
void ev_application_open_uri_list (EvApplication *application,
GSList *uri_list,
GdkScreen *screen,
@@ -68,6 +76,7 @@ void ev_application_open_uri_list (EvApplication *application,
GDBusConnection *ev_application_get_dbus_connection (EvApplication *application);
gboolean ev_application_has_window (EvApplication *application);
guint ev_application_get_n_windows (EvApplication *application);
+GList *ev_application_get_windows (EvApplication *application);
const gchar * ev_application_get_uri (EvApplication *application);
GObject *ev_application_get_media_keys (EvApplication *application);
@@ -76,6 +85,8 @@ void ev_application_screensaver_disable (EvApplication *application);
const gchar *ev_application_get_dot_dir (EvApplication *application,
gboolean create);
+GdkDisplay *ev_display_open_if_needed (const gchar *name);
+
G_END_DECLS
#endif /* !EV_APPLICATION_H */
diff --git a/shell/ev-gdbus.c b/shell/ev-gdbus.c
new file mode 100644
index 0000000..4528cd8
--- /dev/null
+++ b/shell/ev-gdbus.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright  2012 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "ev-gdbus.h"
+#include "ev-application.h"
+
+#include <string.h>
+#include <gio/gio.h>
+
+/* ------------------------------------------------------------------------- */
+
+#define EV_EVINCE_APPLICATION_IMPL_GET_PRIVATE(impl)(G_TYPE_INSTANCE_GET_PRIVATE ((impl), EV_TYPE_EVINCE_APPLICATION_IMPL, EvEvinceApplicationImplPrivate))
+
+struct _EvEvinceApplicationImplPrivate {
+};
+
+/* helper functions */
+
+/* Class implementation */
+
+static gboolean
+ev_evince_application_impl_get_window_list (EvEvinceApplication *object,
+ GDBusMethodInvocation *invocation)
+{
+ EvApplication *application = EV_APP;
+ GList *windows, *l;
+ GPtrArray *paths;
+
+ paths = g_ptr_array_new ();
+
+ windows = ev_application_get_windows (application);
+ for (l = windows; l; l = g_list_next (l)) {
+ EvWindow *window = (EvWindow *)l->data;
+
+ g_ptr_array_add (paths, (gpointer) ev_window_get_dbus_object_path (window));
+ }
+ g_list_free (windows);
+
+ g_ptr_array_add (paths, NULL);
+ ev_evince_application_complete_get_window_list (object, invocation,
+ (const char * const *) paths->pdata);
+
+ g_ptr_array_free (paths, TRUE);
+ return TRUE;
+}
+
+static gboolean
+ev_evince_application_impl_reload (EvEvinceApplication *object,
+ GDBusMethodInvocation *invocation,
+ GVariant *args,
+ guint timestamp)
+{
+ EvApplication *application = EV_APP;
+ GList *windows, *l;
+ GVariantIter iter;
+ const gchar *key;
+ GVariant *value;
+ GdkDisplay *display = NULL;
+ int screen_number = 0;
+ EvLinkDest *dest = NULL;
+ EvWindowRunMode mode = EV_WINDOW_MODE_NORMAL;
+ const gchar *search_string = NULL;
+ GdkScreen *screen = NULL;
+
+ g_variant_iter_init (&iter, args);
+
+ while (g_variant_iter_loop (&iter, "{&sv}", &key, &value)) {
+ if (strcmp (key, "display") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
+ display = ev_display_open_if_needed (g_variant_get_string (value, NULL));
+ } else if (strcmp (key, "screen") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_INT32) {
+ screen_number = g_variant_get_int32 (value);
+ } else if (strcmp (key, "mode") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_UINT32) {
+ mode = g_variant_get_uint32 (value);
+ } else if (strcmp (key, "page-label") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
+ dest = ev_link_dest_new_page_label (g_variant_get_string (value, NULL));
+ } else if (strcmp (key, "named-dest") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
+ dest = ev_link_dest_new_named (g_variant_get_string (value, NULL));
+ } else if (strcmp (key, "page-index") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_UINT32) {
+ dest = ev_link_dest_new_page (g_variant_get_uint32 (value));
+ } else if (strcmp (key, "find-string") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
+ search_string = g_variant_get_string (value, NULL);
+ }
+ }
+
+ if (display != NULL &&
+ screen_number >= 0 &&
+ screen_number < gdk_display_get_n_screens (display))
+ screen = gdk_display_get_screen (display, screen_number);
+ else
+ screen = gdk_screen_get_default ();
+
+ windows = ev_application_get_windows (application);
+ for (l = windows; l != NULL; l = g_list_next (l)) {
+ EvWindow *ev_window = EV_WINDOW (l->data);
+
+ ev_application_open_uri_in_window (application, NULL,
+ ev_window,
+ screen, dest, mode,
+ search_string,
+ timestamp);
+ }
+ g_list_free (windows);
+
+ if (dest)
+ g_object_unref (dest);
+
+ ev_evince_application_complete_reload (object, invocation);
+ return TRUE;
+}
+
+static void
+ev_evince_application_impl_iface_init (EvEvinceApplicationIface *iface)
+{
+ iface->handle_get_window_list = ev_evince_application_impl_get_window_list;
+ iface->handle_reload = ev_evince_application_impl_reload;
+}
+
+G_DEFINE_TYPE_WITH_CODE (EvEvinceApplicationImpl, ev_evince_application_impl, EV_TYPE_EVINCE_APPLICATION_SKELETON,
+ G_IMPLEMENT_INTERFACE (EV_TYPE_EVINCE_APPLICATION, ev_evince_application_impl_iface_init))
+
+static void
+ev_evince_application_impl_init (EvEvinceApplicationImpl *impl)
+{
+}
+
+static void
+ev_evince_application_impl_class_init (EvEvinceApplicationImplClass *klass)
+{
+}
+
+/* public API */
+
+/**
+ * ev_evince_application_impl_new:
+ * @screen: a #EvScreen
+ *
+ * Returns: (transfer full): a new #EvEvinceApplicationImpl
+ */
+EvEvinceApplicationImpl *
+ev_evince_application_impl_new (void)
+{
+ return g_object_new (EV_TYPE_EVINCE_APPLICATION_IMPL,
+ NULL);
+}
diff --git a/shell/ev-gdbus.h b/shell/ev-gdbus.h
new file mode 100644
index 0000000..5650aa0
--- /dev/null
+++ b/shell/ev-gdbus.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright  2012 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef EV_EVINCE_APPLICATION_IMPL_H
+#define EV_EVINCE_APPLICATION_IMPL_H
+
+#include <glib-object.h>
+
+#include "ev-gdbus-generated.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_EVINCE_APPLICATION_IMPL (ev_evince_application_impl_get_type ())
+#define EV_EVINCE_APPLICATION_IMPL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_EVINCE_APPLICATION_IMPL, EvEvinceApplicationImpl))
+#define EV_EVINCE_APPLICATION_IMPL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_EVINCE_APPLICATION_IMPL, EvEvinceApplicationImplClass))
+#define EV_IS_EVINCE_APPLICATION_IMPL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_EVINCE_APPLICATION_IMPL))
+#define EV_IS_EVINCE_APPLICATION_IMPL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_EVINCE_APPLICATION_IMPL))
+#define EV_EVINCE_APPLICATION_IMPL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EV_TYPE_EVINCE_APPLICATION_IMPL, EvEvinceApplicationImplClass))
+
+typedef struct _EvEvinceApplicationImpl EvEvinceApplicationImpl;
+typedef struct _EvEvinceApplicationImplClass EvEvinceApplicationImplClass;
+typedef struct _EvEvinceApplicationImplPrivate EvEvinceApplicationImplPrivate;
+
+struct _EvEvinceApplicationImpl
+{
+ EvEvinceApplicationSkeleton parent_instance;
+
+ /*< private >*/
+ EvEvinceApplicationImplPrivate *priv;
+};
+
+struct _EvEvinceApplicationImplClass
+{
+ EvEvinceApplicationSkeletonClass parent_class;
+};
+
+GType ev_evince_application_impl_get_type (void);
+
+EvEvinceApplicationImpl *ev_evince_application_impl_new (void);
+
+G_END_DECLS
+
+#endif /* !EV_EVINCE_APPLICATION_IMPL_H */
diff --git a/shell/org.gnome.evince.Application.xml b/shell/org.gnome.evince.Application.xml
new file mode 100644
index 0000000..e6af0f3
--- /dev/null
+++ b/shell/org.gnome.evince.Application.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Introspection 0.1//EN"
+ "http://www.freedesktop.org/software/dbus/introspection.dtd">
+<node>
+ <interface name='org.gnome.evince.Application'>
+ <annotation name="org.gtk.GDBus.C.Name" value="EvinceApplication" />
+ <method name='Reload'>
+ <arg type='a{sv}' name='args' direction='in'/>
+ <arg type='u' name='timestamp' direction='in'/>
+ </method>
+ <method name='GetWindowList'>
+ <arg type='ao' name='window_list' direction='out'/>
+ </method>
+ </interface>
+</node>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]