From 258d9bcc9c7e41cf53cef3c915bce2e1cd010cb3 Mon Sep 17 00:00:00 2001 From: Shaun McCance Date: Wed, 10 Mar 2010 23:22:23 -0600 Subject: [src/yelp.c] Basic DBus-enabled libyelp-based Yelp shell Nothing shiny yet. Just managing the application API with DBus and getting basic windows loaded using YelpView. Trying to keep it very simple, and with as little as possible done at startup. --- autogen.sh | 2 +- configure.in | 4 +- src/Makefile.am | 132 ++++++++---------------- src/yelp-application.c | 270 +++++++++++++++++++++++++++++++++++++++++++++++++ src/yelp-application.h | 58 +++++++++++ src/yelp-dbus.xml | 10 ++ src/yelp.c | 49 +++++++++ 7 files changed, 430 insertions(+), 95 deletions(-) create mode 100644 src/yelp-application.c create mode 100644 src/yelp-application.h create mode 100644 src/yelp-dbus.xml create mode 100644 src/yelp.c diff --git a/autogen.sh b/autogen.sh index 13db1cc8..0cc89c3e 100755 --- a/autogen.sh +++ b/autogen.sh @@ -9,7 +9,7 @@ PKG_NAME=Yelp REQUIRED_AUTOMAKE_VERSION=1.9 export REQUIRED_AUTOMAKE_VERSION -if ! test -f $srcdir/src/yelp-main.c; then +if ! test -f $srcdir/src/yelp.c; then echo "**Error**: Directory '$srcdir' does not look like the yelp source directory" exit 1 fi diff --git a/configure.in b/configure.in index cf58ecfd..b119a2ce 100644 --- a/configure.in +++ b/configure.in @@ -50,10 +50,8 @@ AM_GLIB_DEFINE_LOCALEDIR([GNOMELOCALEDIR]) PKG_CHECK_MODULES(YELP, [ - gio-2.0 gio-2.0 gio-unix-2.0 - yelp-xsl gtk+-unix-print-2.0 gtk+-2.0 >= 2.16.0 libxml-2.0 >= 2.6.5 @@ -62,7 +60,9 @@ PKG_CHECK_MODULES(YELP, libstartup-notification-1.0 >= 0.8 dbus-glib-1 rarian >= 0.7.0 + unique-1.0 webkit-1.0 >= 1.1.15 + yelp-xsl ]) AC_SUBST([YELP_CFLAGS]) diff --git a/src/Makefile.am b/src/Makefile.am index 5cc96dec..251e2cb6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,30 +1,33 @@ bin_PROGRAMS = yelp -yelp_SOURCES = \ - yelp-base.c yelp-base.h \ - yelp-bookmarks.c yelp-bookmarks.h \ - yelp-error.c yelp-error.h \ - yelp-html.c yelp-html.h \ - yelp-io-channel.c yelp-io-channel.h \ - yelp-settings.c yelp-settings.h \ - yelp-utils.c yelp-utils.h \ - yelp-window.c yelp-window.h \ - yelp-marshal.c yelp-marshal.h \ - yelp-main.c \ - yelp-page.c yelp-page.h \ - yelp-transform.c yelp-transform.h \ - yelp-document.h yelp-document.c \ - yelp-toc.h yelp-toc.c \ - yelp-docbook.h yelp-docbook.c \ - yelp-db-print.c yelp-db-print.h \ - yelp-mallard.h yelp-mallard.c \ - yelp-man-parser.c yelp-man-parser.h \ - yelp-man.c yelp-man.h \ - yelp-info.c yelp-info.h \ - yelp-info-parser.c yelp-info-parser.h \ - gtkentryaction.c gtkentryaction.h \ - yelp-search.c yelp-search.h \ - yelp-search-parser.c yelp-search-parser.h +yelp_SOURCES = \ + yelp-application.c yelp-application.h \ + yelp.c + +# yelp-base.c yelp-base.h \ +# yelp-bookmarks.c yelp-bookmarks.h \ +# yelp-error.c yelp-error.h \ +# yelp-html.c yelp-html.h \ +# yelp-io-channel.c yelp-io-channel.h \ +# yelp-settings.c yelp-settings.h \ +# yelp-utils.c yelp-utils.h \ +# yelp-window.c yelp-window.h \ +# yelp-marshal.c yelp-marshal.h \ +# yelp-main.c \ +# yelp-page.c yelp-page.h \ +# yelp-transform.c yelp-transform.h \ +# yelp-document.h yelp-document.c \ +# yelp-toc.h yelp-toc.c \ +# yelp-docbook.h yelp-docbook.c \ +# yelp-db-print.c yelp-db-print.h \ +# yelp-mallard.h yelp-mallard.c \ +# yelp-man-parser.c yelp-man-parser.h \ +# yelp-man.c yelp-man.h \ +# yelp-info.c yelp-info.h \ +# yelp-info-parser.c yelp-info-parser.h \ +# gtkentryaction.c gtkentryaction.h \ +# yelp-search.c yelp-search.h \ +# yelp-search-parser.c yelp-search-parser.h YELP_DEFINES = \ @@ -81,76 +84,19 @@ yelp_SOURCES += eggsmclient-osx.c endif endif -check_PROGRAMS = \ - test-document \ - test-man-parser \ - test-page \ - test-transform \ - test-resolver - -test_document_SOURCES = \ - yelp-debug.c yelp-debug.h \ - yelp-docbook.c yelp-docbook.h \ - yelp-document.c yelp-document.h \ - yelp-error.c yelp-error.h \ - yelp-io-channel.c yelp-io-channel.h \ - yelp-mallard.c yelp-mallard.h \ - yelp-man.c yelp-man.h \ - yelp-man-parser.c yelp-man-parser.h \ - yelp-page.c yelp-page.h \ - yelp-toc.c yelp-toc.h \ - yelp-transform.c yelp-transform.h \ - test-document.c -test_document_CFLAGS = $(YELP_CFLAGS) $(AM_CFLAGS) $(YELP_DEFINES) -test_document_LDADD = $(YELP_LIBS) $(Z_LIBS) $(BZ_LIBS) $(LZMADEC_LIBS) -test_document_LDFLAGS = $(AM_LDFLAGS) - -test_man_parser_SOURCES = \ - yelp-debug.c yelp-debug.h \ - yelp-error.c yelp-error.h \ - yelp-io-channel.c yelp-io-channel.h \ - yelp-man-parser.c yelp-man-parser.h \ - test-man-parser.c -test_man_parser_CPPFLAGS = $(YELP_DEFINES) $(AM_CPPFLAGS) -test_man_parser_CFLAGS = $(YELP_CFLAGS) $(AM_CFLAGS) -test_man_parser_LDADD = $(YELP_LIBS) $(Z_LIBS) $(BZ_LIBS) $(LZMADEC_LIBS) -test_man_parser_LDFLAGS = $(AM_LDFLAGS) - -test_page_SOURCES = \ - yelp-debug.c yelp-debug.h \ - yelp-document.c yelp-document.h \ - yelp-error.c yelp-error.h \ - yelp-page.c yelp-page.h \ - test-page.c -test_page_CFLAGS = $(YELP_CFLAGS) $(AM_CFLAGS) $(YELP_DEFINES) -test_page_LDADD = $(YELP_LIBS) -test_page_LDFLAGS = $(AM_LDFLAGS) - -test_transform_SOURCES = \ - yelp-debug.c yelp-debug.h \ - yelp-error.c yelp-error.h \ - yelp-transform.c yelp-transform.h \ - test-transform.c -test_transform_CFLAGS = $(YELP_CFLAGS) $(AM_CFLAGS) $(YELP_DEFINES) -test_transform_LDADD = $(YELP_LIBS) -test_transform_LDFLAGS = $(AM_LDFLAGS) - -test_resolver_SOURCES = \ - yelp-debug.c yelp-debug.h \ - yelp-error.c yelp-error.h \ - yelp-utils.c yelp-utils.h \ - test-resolver.c -test_resolver_CFLAGS = $(YELP_CFLAGS) $(AM_CFLAGS) $(YELP_DEFINES) -test_resolver_LDADD = $(YELP_LIBS) -test_resolver_LDFLAGS = $(AM_LDFLAGS) - -@INTLTOOL_SERVER_RULE@ - -BUILT_SOURCES = yelp-marshal.h stamp-yelp-marshal.h yelp-marshal.c server-bindings.h \ - client-bindings.h +BUILT_SOURCES = \ + yelp-dbus.h \ + yelp-marshal.h \ + stamp-yelp-marshal.h \ + yelp-marshal.c \ + server-bindings.h \ + client-bindings.h noinst_HEADERS = $(BUILT_SOURCES) +yelp-dbus.h: yelp-dbus.xml + dbus-binding-tool --prefix=yelp --mode=glib-server $<> $@ + server-bindings.h: yelp-infos.xml dbus-binding-tool --prefix=server_object --mode=glib-server $< > $@ @@ -179,6 +125,8 @@ MAINTAINERCLEANFILES = $(BUILT_SOURCES) EXTRA_DIST = yelp-marshal.list yelp-infos.xml yelp-print.c yelp-print.h + + install-exec-hook: rm -f $(DESTDIR)$(bindir)/gnome-help && \ $(LN_S) yelp $(DESTDIR)$(bindir)/gnome-help diff --git a/src/yelp-application.c b/src/yelp-application.c new file mode 100644 index 00000000..46ccd720 --- /dev/null +++ b/src/yelp-application.c @@ -0,0 +1,270 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2010 Shaun McCance + * + * 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 of the + * License, 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. + * + * Author: Shaun McCance + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include "yelp-application.h" +#include "yelp-dbus.h" +#include "yelp-view.h" + +typedef struct _YelpApplicationLoad YelpApplicationLoad; +struct _YelpApplicationLoad { + YelpApplication *app; + guint timestamp; +}; + +static void yelp_application_init (YelpApplication *app); +static void yelp_application_class_init (YelpApplicationClass *klass); +static void yelp_application_dispose (GObject *object); +static void yelp_application_finalize (GObject *object); + +static GtkWidget * application_new_window (YelpApplication *app); +static void application_uri_resolved (YelpUri *uri, + YelpApplicationLoad *data); + +G_DEFINE_TYPE (YelpApplication, yelp_application, G_TYPE_OBJECT); +#define GET_PRIV(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_APPLICATION, YelpApplicationPrivate)) + +typedef struct _YelpApplicationPrivate YelpApplicationPrivate; +struct _YelpApplicationPrivate { + DBusGConnection *connection; + + GSList *windows; + + GHashTable *windows_by_document; +}; + +static void +yelp_application_init (YelpApplication *app) +{ + YelpApplicationPrivate *priv = GET_PRIV (app); + + priv->windows_by_document = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + NULL); +} + +static void +yelp_application_class_init (YelpApplicationClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = yelp_application_dispose; + object_class->finalize = yelp_application_finalize; + + dbus_g_object_type_install_info (YELP_TYPE_APPLICATION, + &dbus_glib_yelp_object_info); + + g_type_class_add_private (klass, sizeof (YelpApplicationPrivate)); +} + +static void +yelp_application_dispose (GObject *object) +{ + YelpApplicationPrivate *priv = GET_PRIV (object); + + g_object_unref (priv->connection); + + g_hash_table_destroy (priv->windows_by_document); + + G_OBJECT_CLASS (yelp_application_parent_class)->dispose (object); +} + +static void +yelp_application_finalize (GObject *object) +{ + G_OBJECT_CLASS (yelp_application_parent_class)->finalize (object); +} + + +/******************************************************************************/ + +YelpApplication * +yelp_application_new (void) +{ + YelpApplication *app; + + app = (YelpApplication *) g_object_new (YELP_TYPE_APPLICATION, NULL); + + return app; +} + +gint +yelp_application_run (YelpApplication *app, + GOptionContext *context, + gint argc, + gchar **argv) +{ + GError *error = NULL; + DBusGProxy *proxy; + guint request; + YelpApplicationPrivate *priv = GET_PRIV (app); + gchar *uri; + + priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + if (priv->connection == NULL) { + g_warning ("Unable to connect to dbus: %s", error->message); + g_error_free (error); + return 1; + } + + /* FIXME: canonicalize relative URI */ + if (argc > 1) + uri = argv[1]; + else + uri = "ghelp:user-guide"; + + proxy = dbus_g_proxy_new_for_name (priv->connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + + if (!org_freedesktop_DBus_request_name (proxy, + "org.gnome.Yelp", + 0, &request, + &error)) { + g_warning ("Unable to register service: %s", error->message); + g_error_free (error); + g_object_unref (proxy); + return 1; + } + + g_object_unref (proxy); + + if (request == DBUS_REQUEST_NAME_REPLY_EXISTS || + request == DBUS_REQUEST_NAME_REPLY_IN_QUEUE) { + gchar *newuri; + + newuri = g_strdup (uri); + + proxy = dbus_g_proxy_new_for_name (priv->connection, + "org.gnome.Yelp", + "/org/gnome/Yelp", + "org.gnome.Yelp"); + if (!dbus_g_proxy_call (proxy, "LoadUri", &error, + G_TYPE_STRING, newuri, + G_TYPE_UINT, GDK_CURRENT_TIME, + G_TYPE_INVALID, G_TYPE_INVALID)) { + g_warning ("Unable to notify existing process: %s\n", error->message); + g_error_free (error); + } + + g_free (newuri); + g_object_unref (proxy); + return 1; + } + + dbus_g_connection_register_g_object (priv->connection, + "/org/gnome/Yelp", + G_OBJECT (app)); + + yelp_application_load_uri (app, uri, GDK_CURRENT_TIME, NULL); + + gtk_main (); + + return 0; +} + +gboolean +yelp_application_load_uri (YelpApplication *app, + const gchar *uri, + guint timestamp, + GError **error) +{ + YelpApplicationLoad *data; + YelpUri *yuri; + + data = g_new (YelpApplicationLoad, 1); + data->app = app; + data->timestamp = timestamp; + + yuri = yelp_uri_new (uri); + + g_signal_connect (yuri, "resolved", + G_CALLBACK (application_uri_resolved), + data); + yelp_uri_resolve (yuri); + + return TRUE; +} + +static GtkWidget * +application_new_window (YelpApplication *app) +{ + GtkWidget *window, *scroll, *view; + YelpApplicationPrivate *priv = GET_PRIV (app); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_UTILITY); + gtk_window_set_default_size (GTK_WINDOW (window), 520, 580); + priv->windows = g_slist_prepend (priv->windows, window); + + scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_container_add (GTK_CONTAINER (window), scroll); + + view = yelp_view_new (); + gtk_container_add (GTK_CONTAINER (scroll), view); + + g_object_set_data (G_OBJECT (window), "view", view); + + return window; +} + +static void +application_uri_resolved (YelpUri *uri, + YelpApplicationLoad *data) +{ + GtkWidget *window; + YelpView *view; + gchar *doc_uri; + YelpApplicationPrivate *priv = GET_PRIV (data->app); + + doc_uri = yelp_uri_get_document_uri (uri); + + window = g_hash_table_lookup (priv->windows_by_document, doc_uri); + + if (window == NULL) { + window = application_new_window (data->app); + g_hash_table_insert (priv->windows_by_document, doc_uri, window); + } + else { + g_free (doc_uri); + } + + view = g_object_get_data (G_OBJECT (window), "view"); + yelp_view_load_uri (YELP_VIEW (view), uri); + + gtk_widget_show_all (window); + gtk_window_present_with_time (GTK_WINDOW (window), data->timestamp); + + g_free (data); +} diff --git a/src/yelp-application.h b/src/yelp-application.h new file mode 100644 index 00000000..6e5d141b --- /dev/null +++ b/src/yelp-application.h @@ -0,0 +1,58 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2010 Shaun McCance + * + * 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 of the + * License, 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. + * + * Author: Shaun McCance + */ + +#ifndef __YELP_APPLICATION_H__ +#define __YELP_APPLICATION_H__ + +#include + +#define YELP_TYPE_APPLICATION (yelp_application_get_type ()) +#define YELP_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YELP_TYPE_APPLICATION, YelpApplication)) +#define YELP_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YELP_TYPE_APPLICATION, YelpApplicationClass)) +#define YELP_IS_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YELP_TYPE_APPLICATION)) +#define YELP_IS_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YELP_TYPE_APPLICATION)) + +typedef struct _YelpApplication YelpApplication; +typedef struct _YelpApplicationClass YelpApplicationClass; + +struct _YelpApplication +{ + GObject parent; +}; + +struct _YelpApplicationClass +{ + GObjectClass parent_class; +}; + +GType yelp_application_get_type (void); +YelpApplication* yelp_application_new (void); +gint yelp_application_run (YelpApplication *app, + GOptionContext *context, + gint argc, + gchar **argv); +gboolean yelp_application_load_uri (YelpApplication *app, + const gchar *uri, + guint timestamp, + GError **error); + +#endif /* __YELP_APPLICATION_H__ */ diff --git a/src/yelp-dbus.xml b/src/yelp-dbus.xml new file mode 100644 index 00000000..124bfe7e --- /dev/null +++ b/src/yelp-dbus.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/yelp.c b/src/yelp.c new file mode 100644 index 00000000..ce20a3ac --- /dev/null +++ b/src/yelp.c @@ -0,0 +1,49 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2010 Shaun McCance + * + * 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 of the + * License, 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. + * + * Author: Shaun McCance + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "yelp-application.h" + +int +main (int argc, char **argv) +{ + GOptionContext *context; + YelpApplication *app; + + g_thread_init (NULL); + + g_set_application_name (N_("Help")); + + context = g_option_context_new (NULL); + g_option_context_add_group (context, gtk_get_option_group (TRUE)); + g_option_context_parse (context, &argc, &argv, NULL); + + app = yelp_application_new (); + + return yelp_application_run (app, context, argc, argv); +} -- cgit v1.2.1