Skip to content
Permalink
Browse files

shell: Use gdbus-codegen for the org.mate.atril.Application interface

  • Loading branch information...
Christian Persch authored and raveit65 committed Jun 10, 2012
1 parent e4f8fce commit 18a20e89f7f4359baccf1791cc05433e6fed970b
Showing with 149 additions and 119 deletions.
  1. +9 −3 configure.ac
  2. +26 −5 shell/Makefile.am
  3. +98 −111 shell/ev-application.c
  4. +16 −0 shell/ev-gdbus.xml
@@ -144,9 +144,15 @@ AS_IF([test "x$found_zlib" = "xno"], [
AC_SUBST(ZLIB_LIBS)
])

dnl
dnl SM client
dnl
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
# *********

PKG_CHECK_MODULES([SMCLIENT],[gtk+-3.0 gthread-2.0 sm >= 1.0.0])
AC_SUBST([SMCLIENT_CFLAGS])
@@ -44,8 +44,6 @@ atril_SOURCES= \
ev-history.h \
ev-keyring.h \
ev-keyring.c \
ev-marshal.c \
ev-marshal.h \
ev-message-area.c \
ev-message-area.h \
ev-metadata.c \
@@ -90,13 +88,22 @@ atril_SOURCES= \
ev-sidebar-thumbnails.h \
main.c

nodist_atril_SOURCES = \
ev-marshal.c \
ev-marshal.h \
$(NULL)

if ENABLE_DBUS
atril_SOURCES += \
ev-media-player-keys.c \
ev-media-player-keys.h
ev-media-player-keys.h \
$(NULL)
nodist_atril_SOURCES += \
ev-gdbus-generated.c \
ev-gdbus-generated.h \
$(NULL)
endif


atril_LDFLAGS = $(AM_LDFLAGS)

atril_LDADD= \
@@ -112,6 +119,10 @@ atril_LDADD= \

BUILT_SOURCES = ev-marshal.h ev-marshal.c

if ENABLE_DBUS
BUILT_SOURCES += ev-gdbus-generated.c ev-gdbus-generated.h
endif

if ENABLE_DBUS
atrild_SOURCES= \
ev-daemon.c
@@ -131,7 +142,9 @@ atrild_LDADD= \
$(EV_DAEMON_LIBS)
endif

EXTRA_DIST = ev-marshal.list
EXTRA_DIST = \
ev-marshal.list \
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
@@ -140,6 +153,14 @@ ev-marshal.c: $(srcdir)/ev-marshal.list
echo '#include "ev-marshal.h"' > ev-marshal.c
$(AM_V_GEN)$(GLIB_GENMARSHAL) --prefix=ev_marshal $(srcdir)/ev-marshal.list --body >> ev-marshal.c

ev-gdbus-generated.c ev-gdbus-generated.h: ev-gdbus.xml Makefile
$(AM_V_GEN) $(GDBUS_CODEGEN) \
--interface-prefix=org.mate.atril \
--c-namespace=Ev \
--c-generate-object-manager \
--generate-c-code ev-gdbus-generated \
$<

DISTCLEANFILES =

-include $(top_srcdir)/git.mk
@@ -41,6 +41,7 @@
#include "ev-stock-icons.h"

#ifdef ENABLE_DBUS
#include "ev-gdbus-generated.h"
#include "ev-media-player-keys.h"
#endif /* ENABLE_DBUS */

@@ -54,7 +55,7 @@ struct _EvApplication {

#ifdef ENABLE_DBUS
GDBusConnection *connection;
guint registration_id;
EvAtrilApplication *skeleton;
EvMediaPlayerKeys *keys;
gboolean doc_registered;
#endif
@@ -604,6 +605,9 @@ ev_application_open_uri_in_window (EvApplication *application,
{
GdkWindow *gdk_window;

if (uri == NULL)
uri = application->uri;

if (screen) {
ev_stock_icons_set_screen (screen);
gtk_window_set_screen (GTK_WINDOW (ev_window), screen);
@@ -717,110 +721,92 @@ 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)
static gboolean
handle_get_window_list_cb (EvAtrilApplication *object,
GDBusMethodInvocation *invocation,
EvApplication *application)
{
EvApplication *application = EV_APPLICATION (user_data);
GList *windows, *l;
guint timestamp;
GVariantIter *iter;
const gchar *key;
GVariant *value;
GdkDisplay *display = NULL;
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, &timestamp);

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, "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);
GList *windows, *l;
GPtrArray *paths;

if (display != NULL)
screen = gdk_display_get_default_screen (display);
else
screen = gdk_screen_get_default ();
paths = g_ptr_array_new ();

windows = ev_application_get_windows (application);
for (l = windows; l != NULL; l = g_list_next (l)) {
EvWindow *ev_window = EV_WINDOW (l->data);
windows = ev_application_get_windows (application);
for (l = windows; l; l = g_list_next (l)) {
EvWindow *window = (EvWindow *)l->data;

ev_application_open_uri_in_window (application, application->uri,
ev_window,
screen, dest, mode,
search_string,
timestamp);
}
g_list_free (windows);
g_ptr_array_add (paths, (gpointer) ev_window_get_dbus_object_path (window));
}
g_list_free (windows);

if (dest)
g_object_unref (dest);
g_ptr_array_add (paths, NULL);
ev_atril_application_complete_get_window_list (object, invocation,
(const char * const *) paths->pdata);

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_ptr_array_free (paths, TRUE);

g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ao)"));
g_variant_builder_open (&builder, G_VARIANT_TYPE ("ao"));
return TRUE;
}

for (l = windows; l; l = g_list_next (l)) {
EvWindow *window = (EvWindow *)l->data;
static gboolean
handle_reload_cb (EvAtrilApplication *object,
GDBusMethodInvocation *invocation,
GVariant *args,
guint timestamp,
EvApplication *application)
{
GList *windows, *l;
GVariantIter iter;
const gchar *key;
GVariant *value;
GdkDisplay *display = NULL;
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, "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_builder_add (&builder, "o", ev_window_get_dbus_object_path (window));
}
if (display != NULL)
screen = gdk_display_get_default_screen (display);
else
screen = gdk_screen_get_default ();

g_variant_builder_close (&builder);
g_list_free (windows);
windows = ev_application_get_windows (application);
for (l = windows; l != NULL; l = g_list_next (l)) {
EvWindow *ev_window = EV_WINDOW (l->data);

g_dbus_method_invocation_return_value (invocation, g_variant_builder_end (&builder));
}
}
ev_application_open_uri_in_window (application, NULL,
ev_window,
screen, dest, mode,
search_string,
timestamp);
}
g_list_free (windows);

static const char introspection_xml[] =
"<node>"
"<interface name='org.mate.atril.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
};
if (dest)
g_object_unref (dest);

static GDBusNodeInfo *introspection_data;
ev_atril_application_complete_reload (object, invocation);

return TRUE;
}
#endif /* ENABLE_DBUS */

void
@@ -916,19 +902,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->skeleton != NULL) {
g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (application->skeleton));
g_object_unref (application->skeleton);
application->skeleton = 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);
@@ -971,17 +953,22 @@ static void 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) {
EvAtrilApplication *skeleton;

skeleton = ev_atril_application_skeleton_new ();
if (g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton),
ev_application->connection,
APPLICATION_DBUS_OBJECT_PATH,
&error)) {
ev_application->skeleton = skeleton;
g_signal_connect (skeleton, "handle-get-window-list",
G_CALLBACK (handle_get_window_list_cb),
ev_application);
g_signal_connect (skeleton, "handle-reload",
G_CALLBACK (handle_reload_cb),
ev_application);
} else {
g_object_unref (skeleton);
g_printerr ("Failed to register bus object: %s\n", error->message);
g_error_free (error);
}
@@ -0,0 +1,16 @@
<?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.mate.atril.Application'>
<annotation name="org.gtk.GDBus.C.Name" value="AtrilApplication" />
<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>

0 comments on commit 18a20e8

Please sign in to comment.
You can’t perform that action at this time.