[evince/wip/app: 2/19] shell: Use gdbus-codegen for the org.gnome.evince.Window interface



commit c666bae3cb3a9ab0290ed6da5d79685cb80d0584
Author: Christian Persch <chpe gnome org>
Date:   Sun Jun 10 18:07:54 2012 +0200

    shell: Use gdbus-codegen for the org.gnome.evince.Window interface

 shell/Makefile.am                      |    5 +-
 shell/ev-gdbus.c                       |  105 ++++++++++++++++++
 shell/ev-gdbus.h                       |   30 +++++
 shell/ev-gdbus.xml                     |   32 ++++++
 shell/ev-window.c                      |  186 +++++++-------------------------
 shell/ev-window.h                      |    2 +
 shell/org.gnome.evince.Application.xml |   15 ---
 7 files changed, 213 insertions(+), 162 deletions(-)
---
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 98158be..4b5e277 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -163,7 +163,8 @@ EXTRA_DIST = \
 	evince-icon.rc \
 	evince-ui.xml \
 	evince-toolbar.xml \
-	evince.gresource.xml
+	evince.gresource.xml \
+	ev-gdbus.xml
 
 ev-marshal.h: $(srcdir)/ev-marshal.list
 	$(AM_V_GEN)$(GLIB_GENMARSHAL) --prefix=ev_marshal $(srcdir)/ev-marshal.list --header > ev-marshal.h
@@ -175,7 +176,7 @@ 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
+ev-gdbus-generated.c ev-gdbus-generated.h: ev-gdbus.xml Makefile
 	$(AM_V_GEN) $(GDBUS_CODEGEN) \
 			--interface-prefix=org.gnome.evince \
 			--c-namespace=Ev \
diff --git a/shell/ev-gdbus.c b/shell/ev-gdbus.c
index 4528cd8..f3e7063 100644
--- a/shell/ev-gdbus.c
+++ b/shell/ev-gdbus.c
@@ -159,3 +159,108 @@ ev_evince_application_impl_new (void)
   return g_object_new (EV_TYPE_EVINCE_APPLICATION_IMPL, 
                        NULL);
 }
+
+/* ------------------------------------------------------------------------- */
+
+#define EV_EVINCE_WINDOW_IMPL_GET_PRIVATE(impl)(G_TYPE_INSTANCE_GET_PRIVATE ((impl), EV_TYPE_EVINCE_WINDOW_IMPL, EvEvinceWindowImplPrivate))
+
+struct _EvEvinceWindowImplPrivate {
+        EvWindow *window;
+};
+
+enum {
+        PROP_0,
+        PROP_WINDOW
+};
+
+/* helper functions */
+
+/* Class implementation */
+
+static gboolean
+ev_evince_window_impl_sync_view (EvEvinceWindow *object,
+                                 GDBusMethodInvocation *invocation,
+                                 const gchar *source_file,
+                                 GVariant *source_point,
+                                 guint timestamp)
+{
+        EvEvinceWindowImpl *impl = EV_EVINCE_WINDOW_IMPL (object);
+        EvWindow *window = impl->priv->window;
+        EvSourceLink link;
+
+        link.filename = (char *) source_file;
+        g_variant_get (source_point, "(ii)", &link.line, &link.col);
+        ev_window_sync_view (window, &link);
+        gtk_window_present_with_time (GTK_WINDOW (window), timestamp);
+
+        ev_evince_window_complete_sync_view (object, invocation);
+        return TRUE;
+}
+
+static void
+ev_evince_window_impl_iface_init (EvEvinceWindowIface *iface)
+{
+  iface->handle_sync_view = ev_evince_window_impl_sync_view;
+}
+
+G_DEFINE_TYPE_WITH_CODE (EvEvinceWindowImpl, ev_evince_window_impl, EV_TYPE_EVINCE_WINDOW_SKELETON,
+                         G_IMPLEMENT_INTERFACE (EV_TYPE_EVINCE_WINDOW, ev_evince_window_impl_iface_init))
+
+static void
+ev_evince_window_impl_init (EvEvinceWindowImpl *impl)
+{
+        impl->priv = EV_EVINCE_WINDOW_IMPL_GET_PRIVATE (impl);
+}
+
+static void
+ev_evince_window_impl_set_property (GObject *object,
+                                    guint prop_id,
+                                    const GValue *value,
+                                    GParamSpec *pspec)
+{
+        EvEvinceWindowImpl *impl = EV_EVINCE_WINDOW_IMPL (object);
+
+        switch (prop_id) {
+        case PROP_WINDOW:
+                impl->priv->window = g_value_get_object (value);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+
+static void
+ev_evince_window_impl_class_init (EvEvinceWindowImplClass *klass)
+{
+        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+        gobject_class->set_property = ev_evince_window_impl_set_property;
+
+        g_object_class_install_property (gobject_class,
+                                         PROP_WINDOW,
+                                         g_param_spec_object ("ev-window", NULL, NULL,
+                                                              EV_TYPE_WINDOW,
+                                                              G_PARAM_WRITABLE |
+                                                              G_PARAM_CONSTRUCT_ONLY |
+                                                              G_PARAM_STATIC_STRINGS));
+        
+        g_type_class_add_private (klass, sizeof (EvEvinceWindowImplPrivate));
+}
+
+/* public API */
+
+/**
+ * ev_evince_window_impl_new:
+ * @screen: a #EvScreen
+ *
+ * Returns: (transfer full): a new #EvEvinceWindowImpl
+ */
+EvEvinceWindowImpl *
+ev_evince_window_impl_new (EvWindow *window)
+{
+  return g_object_new (EV_TYPE_EVINCE_WINDOW_IMPL,
+                       "ev-window", window,
+                       NULL);
+}
diff --git a/shell/ev-gdbus.h b/shell/ev-gdbus.h
index 5650aa0..7ecb33c 100644
--- a/shell/ev-gdbus.h
+++ b/shell/ev-gdbus.h
@@ -23,6 +23,8 @@
 
 #include "ev-gdbus-generated.h"
 
+#include "ev-window.h"
+
 G_BEGIN_DECLS
 
 #define EV_TYPE_EVINCE_APPLICATION_IMPL         (ev_evince_application_impl_get_type ())
@@ -53,6 +55,34 @@ GType ev_evince_application_impl_get_type (void);
 
 EvEvinceApplicationImpl *ev_evince_application_impl_new (void);
 
+#define EV_TYPE_EVINCE_WINDOW_IMPL         (ev_evince_window_impl_get_type ())
+#define EV_EVINCE_WINDOW_IMPL(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_EVINCE_WINDOW_IMPL, EvEvinceWindowImpl))
+#define EV_EVINCE_WINDOW_IMPL_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_EVINCE_WINDOW_IMPL, EvEvinceWindowImplClass))
+#define EV_IS_EVINCE_WINDOW_IMPL(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_EVINCE_WINDOW_IMPL))
+#define EV_IS_EVINCE_WINDOW_IMPL_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_EVINCE_WINDOW_IMPL))
+#define EV_EVINCE_WINDOW_IMPL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EV_TYPE_EVINCE_WINDOW_IMPL, EvEvinceWindowImplClass))
+
+typedef struct _EvEvinceWindowImpl        EvEvinceWindowImpl;
+typedef struct _EvEvinceWindowImplClass   EvEvinceWindowImplClass;
+typedef struct _EvEvinceWindowImplPrivate EvEvinceWindowImplPrivate;
+
+struct _EvEvinceWindowImpl
+{
+  EvEvinceWindowSkeleton parent_instance;
+
+  /*< private >*/
+  EvEvinceWindowImplPrivate *priv;
+};
+
+struct _EvEvinceWindowImplClass
+{
+  EvEvinceWindowSkeletonClass parent_class;
+};
+
+GType ev_evince_window_impl_get_type (void);
+
+EvEvinceWindowImpl *ev_evince_window_impl_new (EvWindow *window);
+
 G_END_DECLS
 
 #endif /* !EV_EVINCE_APPLICATION_IMPL_H */
diff --git a/shell/ev-gdbus.xml b/shell/ev-gdbus.xml
new file mode 100644
index 0000000..b6b50d1
--- /dev/null
+++ b/shell/ev-gdbus.xml
@@ -0,0 +1,32 @@
+<?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>
+  <interface name='org.gnome.evince.Window'>
+    <annotation name="org.gtk.GDBus.C.Name" value="EvinceWindow" />
+    <method name='SyncView'>
+      <arg type='s' name='source_file' direction='in'/>
+      <arg type='(ii)' name='source_point' direction='in'/>
+      <arg type='u' name='timestamp' direction='in'/>
+    </method>
+    <signal name='SyncSource'>
+      <arg type='s' name='source_file' direction='out'/>
+      <arg type='(ii)' name='source_point' direction='out'/>
+      <arg type='u' name='timestamp' direction='out'/>
+    </signal>
+    <signal name='Closed'/>
+    <signal name='DocumentLoaded'>
+      <arg type='s' name='uri' direction='out'/>
+    </signal>
+  </interface>
+</node>
diff --git a/shell/ev-window.c b/shell/ev-window.c
index c8bd717..914ac1a 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -96,6 +96,7 @@
 #include "ev-bookmark-action.h"
 
 #ifdef ENABLE_DBUS
+#include "ev-gdbus.h"
 #include "ev-media-player-keys.h"
 #endif /* ENABLE_DBUS */
 
@@ -219,7 +220,7 @@ struct _EvWindowPrivate {
 
 #ifdef ENABLE_DBUS
 	/* DBus */
-	guint  dbus_object_id;
+	EvEvinceWindow *impl;
 	gchar *dbus_object_path;
 #endif
 };
@@ -5497,16 +5498,14 @@ ev_window_dispose (GObject *object)
 	}
 
 #ifdef ENABLE_DBUS
-	if (priv->dbus_object_id > 0) {
-		ev_window_emit_closed (window);
-		g_dbus_connection_unregister_object (ev_application_get_dbus_connection (EV_APP),
-						     priv->dbus_object_id);
-		priv->dbus_object_id = 0;
-	}
+	if (priv->impl != NULL) {
+                ev_window_emit_closed (window);
 
-	if (priv->dbus_object_path) {
-		g_free (priv->dbus_object_path);
-		priv->dbus_object_path = NULL;
+                g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (priv->impl));
+                g_object_unref (priv->impl);
+                priv->impl = NULL;
+                g_free (priv->dbus_object_path);
+                priv->dbus_object_path = NULL;
 	}
 #endif /* ENABLE_DBUS */
 
@@ -6990,17 +6989,11 @@ static void
 ev_window_sync_source (EvWindow     *window,
 		       EvSourceLink *link)
 {
-	GDBusConnection *connection;
-	GError          *error = NULL;
 	guint32		 timestamp;
 	gchar		*uri_input;
 	GFile		*input_gfile;
 
-	if (window->priv->dbus_object_id <= 0)
-		return;
-
-	connection = ev_application_get_dbus_connection (EV_APP);
-	if (!connection)
+        if (window->priv->impl == NULL)
 		return;
 
 	timestamp = gtk_get_current_event_time ();
@@ -7026,143 +7019,47 @@ ev_window_sync_source (EvWindow     *window,
 	uri_input = g_file_get_uri (input_gfile);
 	g_object_unref (input_gfile);
 
-	g_dbus_connection_emit_signal (connection,
-				       NULL,
-				       window->priv->dbus_object_path,
-				       EV_WINDOW_DBUS_INTERFACE,
-				       "SyncSource",
-				       g_variant_new ("(s(ii)u)",
-						      uri_input,
-						      link->line,
-						      link->col,
-						      timestamp),
-				       &error);
+        ev_evince_window_emit_sync_source (window->priv->impl,
+                                           uri_input,
+                                           g_variant_new ("(ii)", link->line, link->col),
+                                           timestamp);
 	g_free (uri_input);
-	if (error) {
-		g_printerr ("Failed to emit DBus signal SyncSource: %s\n",
-			    error->message);
-		g_error_free (error);
-	}
 }
 
 static void
 ev_window_emit_closed (EvWindow *window)
 {
-	GDBusConnection *connection;
-	GError          *error = NULL;
-
-	if (window->priv->dbus_object_id <= 0)
+	if (window->priv->impl == NULL)
 		return;
 
-	connection = ev_application_get_dbus_connection (EV_APP);
-	if (!connection)
-		return;
-
-	g_dbus_connection_emit_signal (connection,
-				       NULL,
-				       window->priv->dbus_object_path,
-				       EV_WINDOW_DBUS_INTERFACE,
-				       "Closed",
-				       NULL,
-				       &error);
-	if (error) {
-		g_printerr ("Failed to emit DBus signal Closed: %s\n",
-			    error->message);
-		g_error_free (error);
-
-		return;
-	}
+        ev_evince_window_emit_closed (window->priv->impl);
 
 	/* If this is the last window call g_dbus_connection_flush_sync()
 	 * to make sure the signal is emitted.
 	 */
 	if (ev_application_get_n_windows (EV_APP) == 1)
-		g_dbus_connection_flush_sync (connection, NULL, NULL);
+		g_dbus_connection_flush_sync (ev_application_get_dbus_connection (EV_APP), NULL, NULL);
 }
 
 static void
 ev_window_emit_doc_loaded (EvWindow *window)
 {
-	GDBusConnection *connection;
-	GError          *error = NULL;
-
-	if (window->priv->dbus_object_id <= 0)
-		return;
-
-	connection = ev_application_get_dbus_connection (EV_APP);
-	if (!connection)
-		return;
-
-	g_dbus_connection_emit_signal (connection,
-				       NULL,
-				       window->priv->dbus_object_path,
-				       EV_WINDOW_DBUS_INTERFACE,
-				       "DocumentLoaded",
-				       g_variant_new("(s)", window->priv->uri),
-				       &error);
-	if (error) {
-		g_printerr ("Failed to emit DBus signal DocumentLoaded: %s\n",
-			    error->message);
-		g_error_free (error);
+        if (window->priv->impl == NULL)
+                return;
 
-		return;
-	}
+        ev_evince_window_emit_document_loaded (window->priv->impl, window->priv->uri);
 }
 
-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)
+void
+ev_window_sync_view (EvWindow     *window,
+                     EvSourceLink *link)
 {
-        EvWindow *window = EV_WINDOW (user_data);
-
-        if (g_strcmp0 (method_name, "SyncView") != 0)
-                return;
-
-	if (window->priv->document && ev_document_has_synctex (window->priv->document)) {
-		EvSourceLink link;
-		guint32	     timestamp;
-
-		g_variant_get (parameters, "(&s(ii)u)", &link.filename, &link.line, &link.col, &timestamp);
-		ev_view_highlight_forward_search (EV_VIEW (window->priv->view), &link);
-		gtk_window_present_with_time (GTK_WINDOW (window), timestamp);
-	}
-
-	g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
-}
-
-static const char introspection_xml[] =
-        "<node>"
-          "<interface name='org.gnome.evince.Window'>"
-            "<method name='SyncView'>"
-              "<arg type='s' name='source_file' direction='in'/>"
-              "<arg type='(ii)' name='source_point' direction='in'/>"
-              "<arg type='u' name='timestamp' direction='in'/>"
-            "</method>"
-	    "<signal name='SyncSource'>"
-	      "<arg type='s' name='source_file' direction='out'/>"
-	      "<arg type='(ii)' name='source_point' direction='out'/>"
-	      "<arg type='u' name='timestamp' direction='out'/>"
-	    "</signal>"
-            "<signal name='Closed'/>"
-	    "<signal name='DocumentLoaded'>"
-	      "<arg type='s' name='uri' direction='out'/>"
-	    "</signal>"
-          "</interface>"
-        "</node>";
-
-static const GDBusInterfaceVTable interface_vtable = {
-	method_call_cb,
-	NULL,
-	NULL
-};
+        if (window->priv->document && 
+            ev_document_has_synctex (window->priv->document)) {
+              ev_view_highlight_forward_search (EV_VIEW (window->priv->view), link);
+        }
+}
 
-static GDBusNodeInfo *introspection_data;
 #endif /* ENABLE_DBUS */
 
 static void
@@ -7190,30 +7087,29 @@ ev_window_init (EvWindow *ev_window)
 #ifdef ENABLE_DBUS
 	connection = ev_application_get_dbus_connection (EV_APP);
         if (connection) {
-		if (!introspection_data) {
-			introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, &error);
-			if (error) g_warning ("%s\n", error->message);
-		}
-                g_assert (introspection_data != NULL);
+                EvEvinceWindowImpl *impl;
 
 		ev_window->priv->dbus_object_path = g_strdup_printf (EV_WINDOW_DBUS_OBJECT_PATH, window_id++);
-                ev_window->priv->dbus_object_id =
-                    g_dbus_connection_register_object (connection,
-                                                       ev_window->priv->dbus_object_path,
-                                                       introspection_data->interfaces[0],
-                                                       &interface_vtable,
-                                                       ev_window, NULL,
-                                                       &error);
-                if (ev_window->priv->dbus_object_id == 0) {
+
+                impl = ev_evince_window_impl_new (ev_window);
+
+                if (g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (impl),
+                                                      connection,
+                                                      ev_window->priv->dbus_object_path,
+                                                      &error)) {
+                        ev_window->priv->impl = EV_EVINCE_WINDOW (impl);
+                } else {
                         g_printerr ("Failed to register bus object %s: %s\n",
 				    ev_window->priv->dbus_object_path, error->message);
                         g_error_free (error);
 			g_free (ev_window->priv->dbus_object_path);
 			ev_window->priv->dbus_object_path = NULL;
 			error = NULL;
+
+                        g_object_unref (impl);
+                        ev_window->priv->impl = NULL;
                 }
         }
-
 #endif /* ENABLE_DBUS */
 
 	ev_window->priv->model = ev_document_model_new ();
diff --git a/shell/ev-window.h b/shell/ev-window.h
index 1173390..bb8a3b1 100644
--- a/shell/ev-window.h
+++ b/shell/ev-window.h
@@ -85,6 +85,8 @@ gboolean	ev_window_is_empty	(const EvWindow *ev_window);
 void		ev_window_print_range   (EvWindow       *ev_window,
 					 int             first_page,
 					 int		 last_page);
+void            ev_window_sync_view     (EvWindow       *window,
+                                         EvSourceLink   *link);
 const gchar *	ev_window_get_dbus_object_path (EvWindow *ev_window);
 
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]