[gnome-web-photo/webkit: 1/4] Complete rewrite: it's now using webkit



commit 26435ee035a239bf2c56b5a74fb697b26659ff2e
Author: Vincent Untz <vuntz gnome org>
Date:   Tue Feb 15 08:47:56 2011 +0100

    Complete rewrite: it's now using webkit

 Makefile.am                      |    3 +-
 README                           |    3 +-
 TODO                             |    7 -
 autogen.sh                       |    2 +-
 configure.ac                     |  103 ++---
 data/Makefile.am                 |   16 +-
 data/gnome-web-photo.thumbnailer |    4 +
 data/prefs.js                    |   73 ---
 data/style.css                   |    3 -
 data/thumbnailer.schemas.in      |    4 +-
 m4/libxul.m4                     |  566 ----------------------
 src/Components.cpp               |  191 --------
 src/Components.h                 |   28 --
 src/Embed.cpp                    |  163 -------
 src/Embed.h                      |   65 ---
 src/Listener.cpp                 |  134 ------
 src/Listener.h                   |   55 ---
 src/Makefile.am                  |   54 +--
 src/Prefs.cpp                    |  182 -------
 src/Prefs.h                      |   28 --
 src/Printer.cpp                  |  199 --------
 src/Printer.h                    |   55 ---
 src/Writer.cpp                   |  712 ----------------------------
 src/Writer.h                     |  135 ------
 src/gnome-web-photo.c            |  971 ++++++++++++++++++++++++++++++++++++++
 src/main.cpp                     |  657 --------------------------
 26 files changed, 1026 insertions(+), 3387 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index a7c1432..d559a64 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -36,8 +36,7 @@ MAINTAINERCLEANFILES = \
 
 DISTCHECK_CONFIGURE_FLAGS = \
 	--disable-silent-rules \
-	--disable-schemas-install \
-	--with-gecko=$(GECKO)
+	--disable-schemas-install
 
 ChangeLog:
 	$(AM_V_GEN) if test -f $(top_srcdir)/.git/HEAD; then \
diff --git a/README b/README
index 62d101c..e0bcd19 100644
--- a/README
+++ b/README
@@ -3,6 +3,5 @@ files and thumbnails from HTML files and web pages.
 
 Requirements:
 * gtk+
-* libpng
-* mozilla or firefox trunk build from 2005-07-19 or later
+* webkitgtk
 
diff --git a/TODO b/TODO
index 05a3d77..3ad0669 100644
--- a/TODO
+++ b/TODO
@@ -1,14 +1,7 @@
-Important:
-* Port to gecko 1.9/XULrunner. Maybe look at mozilla's reftest helper (mozilla/layout/tools/reftest/) ?
-
 Improvements:
-* Test on a big endian machine
 * Improve thumbnail creation time
 * Thumbnailing service? I.e. background process (which exits after some time without requests),
   which the frontend tells which files/pages to thumbnail.
-* Find out why it crashes on https:// sites, and on http://slashdot.org/, if I disable the profile
 * Fix the output on framed pages
-* Use <canvas> and drawWindow() instead of the low-level stuff (<canvas> can operate without a document,
-  so we don't need to put it in an embed)
 * Add memory size and CPU time limit (look at totem-video-thumbnailer/indexer)
 * Implement printing to printer, using the gtk 2.10 print APIs
diff --git a/autogen.sh b/autogen.sh
index e0f3d1a..085ac9b 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -6,7 +6,7 @@ test -z "$srcdir" && srcdir=.
 
 PKG_NAME="gnome-web-photo"
 
-(test -f $srcdir/src/main.cpp) || {
+(test -f $srcdir/src/gnome-web-photo.c) || {
     echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
     echo " top-level $PKG_NAME directory"
     exit 1
diff --git a/configure.ac b/configure.ac
index 1cf37ab..ae38e43 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,6 @@
 # Copyright © 2000-2004 Marco Pesenti Gritti
 # Copyright © 2003, 2004, 2005 Christian Persch
+# Copyright © 2011 Vincent Untz
 #
 # 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
@@ -31,9 +32,10 @@ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
 
 IT_PROG_INTLTOOL([0.35.0])
 
-GLIB_REQUIRED=2.6.0
-GTK_REQUIRED=2.6.3
-LIBXML_REQUIRED=2.6.12
+GLIB_REQUIRED=2.14.0
+GTK2_REQUIRED=2.20.0
+GTK3_REQUIRED=2.99.3
+WEBKIT_REQUIRED=1.1.23
 
 AC_ENABLE_SHARED([yes])
 AC_ENABLE_STATIC([no])
@@ -45,97 +47,64 @@ AC_ISC_POSIX
 
 AC_PROG_LN_S
 AC_PROG_CC
-AC_PROG_CXX
 AM_PROG_CC_STDC
 AC_HEADER_STDC
 
 AC_C_BIGENDIAN
 
-# AC_PATH_PROG([GLIB_GENMARSHAL],[glib-genmarshal])
-# AC_PATH_PROG([GLIB_MKENUMS],[glib-mkenums])
-
 GNOME_DEBUG_CHECK
 GNOME_COMPILE_WARNINGS([maximum])
-GNOME_CXX_WARNINGS
 
 MORE_WARN_FLAGS=
 DEPRECATION_FLAGS=
-MOZILLA_WARN_CXXFLAGS="-Wno-ctor-dtor-privacy -Wno-non-virtual-dtor"
 
 if test "x$enable_maintainer_mode" = "xyes"; then
 	AC_DEFINE([MAINTAINER_MODE],[1],[Define to enable 'maintainer-only' behaviour])
 	enable_debug=yes
         DEPRECATION_FLAGS="-DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED -DGCONF_DISABLE_DEPRECATED -DGNOME_VFS_DISABLE_DEPRECATED -DBONOBO_UI_DISABLE_DEPRECATED -DBONOBO_DISABLE_DEPRECATED -DLIBGLADE_DISABLE_DEPRECATED -DPANGO_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGNOME_DISABLE_DEPRECATED"
-	MOZILLA_WARN_CXXFLAGS="-Wall -Wconversion -Wpointer-arith -Wcast-align -Woverloaded-virtual -Wsynth $MOZILLA_WARN_CXXFLAGS"
 fi
 
-PKG_CHECK_MODULES([DEPENDENCY], [\
-		  glib-2.0 >= $GLIB_REQUIRED \
-		  gtk+-2.0 >= $GTK_REQUIRED \
-		  libxml-2.0 >= $LIBXML_REQUIRED \
-		  gconf-2.0 \
-		  libpng])
+AC_MSG_CHECKING([which gtk+ version to compile against])
+AC_ARG_WITH([gtk],
+  [AS_HELP_STRING([--with-gtk=2.0|3.0],[which gtk+ version to compile against (default: 3.0)])],
+  [case "$with_gtk" in
+     2.0|3.0) ;;
+     *) AC_MSG_ERROR([invalid gtk version specified]) ;;
+   esac],
+  [with_gtk=3.0])
+AC_MSG_RESULT([$with_gtk])
+
+case "$with_gtk" in
+  2.0)
+    DEPENDENCY_PC="glib-2.0 >= $GLIB_REQUIRED gtk+-2.0 >= $GTK2_REQUIRED webkit-1.0 >= $WEBKIT_REQUIRED gconf-2.0"
+    ;;
+  3.0)
+    DEPENDENCY_PC="glib-2.0 >= $GLIB_REQUIRED gtk+-3.0 >= $GTK3_REQUIRED webkitgtk-3.0 >= $WEBKIT_REQUIRED"
+    AC_DEFINE([HAVE_GNOME3], 1,
+              [Use GNOME 3 technologies])
+    ;;
+esac
+AM_CONDITIONAL(HAVE_GNOME3, test "$with_gtk" == 3.0)
+
+PKG_CHECK_MODULES([DEPENDENCY], [$DEPENDENCY_PC])
 AC_SUBST([DEPENDENCY_CFLAGS])
 AC_SUBST([DEPENDENCY_LIBS])
 
-# ************
-# JPEG support
-# ************
-
-AC_MSG_CHECKING([whether JPEG support is requested])
-AC_ARG_ENABLE([jpeg],
-	[AS_HELP_STRING([--disable-jpeg],[Disable JPEG support])],
-	[enable_jpeg=$enableval],[enable_jpeg=yes])
-AC_MSG_RESULT([$enable_jpeg])
-
-# libjpeg sucksâ??it doesn't have a .pc file!
-have_jpeg=no
-if test "$enable_jpeg" != "no"; then
-	AC_CHECK_LIB([jpeg],[jpeg_destroy_decompress],[have_jpeg=yes],[have_jpeg=no])
-fi
-if test "$enable_jpeg" != "no" -a "$have_jpeg" = "yes"; then
-	AC_MSG_CHECKING([for jpeglib.h])
-	AC_PREPROC_IFELSE([AC_LANG_SOURCE(
-		[[#include <stdio.h>
-		  #undef PACKAGE
-		  #undef VERSION
-		  #undef HAVE_STDLIB_H
-		  #include <jpeglib.h>]])],
-		[have_jpeg=yes],
-		[have_jpeg=no])
-	AC_MSG_RESULT([$have_jpeg])
-fi
-if test "$enable_jpeg" = "yes" -a "$have_jpeg" = "yes"; then
-	JPEG_LIBS="-ljpeg"
-	AC_SUBST([JPEG_LIBS])
-	AC_DEFINE([ENABLE_JPEG],[1],[Define if JPEG support is enabled])
-elif test "$enable_jpeg" = "yes" -a "$have_jpeg" = "no"; then
-	AC_MSG_ERROR([JPEG support requested but required jpeg library or headers not found])
-else
-	AC_MSG_WARN([JPEG support disabled])
-fi
- 
-AM_CONDITIONAL([ENABLE_JPEG],[test "$enable_jpeg" = "yes" -a "$have_jpeg" = "yes"])
-
 # *****
 # GConf
 # *****
 
-AC_PATH_PROG([GCONFTOOL], [gconftool-2], [no])
+if test "$with_gtk" == 2.0; then
+  AC_PATH_PROG([GCONFTOOL], [gconftool-2], [no])
+
+  if test "x$GCONFTOOL" = xno; then
+    AC_MSG_ERROR([gconftool-2 not found])
+  fi
 
-if test "x$GCONFTOOL" = xno; then
-	AC_MSG_ERROR([gconftool-2 not found])
 fi
 
 AM_GCONF_SOURCE_2
 
-# *********
-# Xulrunner
-# *********
-
-LIBXUL_INIT
-LIBXUL_DEFINES
-
 # ******************
 # Portability checks
 # ******************
@@ -162,18 +131,14 @@ if test "x$enable_maintainer_mode" = "xyes"; then
 	AC_LANG_POP([C])
 fi
 
-SUPPRESSION_CXXFLAGS="-Wconversion -Wpointer-arith -Wcast-align -Woverloaded-virtual -Wsynth -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor"
-
 # *****************
 # Add warning flags
 # *****************
 
 AM_CPPFLAGS="$AM_CPPFLAGS $DEPRECATION_FLAGS"
 AM_CFLAGS="$AM_CFLAGS $WARN_CFLAGS $MORE_WARN_FLAGS"
-AM_CXXFLAGS="$AM_CXXFLAGS $WARN_CXXFLAGS $SUPPRESSION_CXXFLAGS"
 AC_SUBST([AM_CPPFLAGS])
 AC_SUBST([AM_CFLAGS])
-AC_SUBST([AM_CXXFLAGS])
 AC_SUBST([AM_LDFLAGS])
 
 # ********************
diff --git a/data/Makefile.am b/data/Makefile.am
index 3af718d..3665bee 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -1,3 +1,4 @@
+if !HAVE_GNOME3
 @INTLTOOL_SCHEMAS_RULE@
 
 schemadir = $(GCONF_SCHEMA_FILE_DIR)
@@ -12,17 +13,16 @@ if GCONF_SCHEMAS_INSTALL
 	done \
 	fi
 endif
+endif
 
-cssdir = $(pkgdatadir)
-css_DATA = style.css
-
-prefsdir = $(pkgdatadir)
-prefs_DATA = prefs.js
+if HAVE_GNOME3
+thumbnailerdir = $(datadir)/thumbnailers
+thumbnailer_DATA = gnome-web-photo.thumbnailer
+endif
 
 EXTRA_DIST = \
-	$(schema_in_files)	\
-	$(css_DATA)		\
-	$(prefs_DATA)
+	$(schema_in_files) \
+	$(thumbnailer_DATA)
 
 CLEANFILES = $(schema_DATA)
 DISTCLEANFILES = $(schema_DATA)
diff --git a/data/gnome-web-photo.thumbnailer b/data/gnome-web-photo.thumbnailer
new file mode 100644
index 0000000..732c463
--- /dev/null
+++ b/data/gnome-web-photo.thumbnailer
@@ -0,0 +1,4 @@
+[Thumbnailer Entry]
+TryExec=gnome-web-photo
+Exec=gnome-web-photo --mode=thumbnail --timeout=16 --thumbnail-size=%s %u %o
+MimeType=text/html;application/xhtml+xml;
diff --git a/data/thumbnailer.schemas.in b/data/thumbnailer.schemas.in
index 9db40c1..f3a3d65 100644
--- a/data/thumbnailer.schemas.in
+++ b/data/thumbnailer.schemas.in
@@ -16,7 +16,7 @@
       <applyto>/desktop/gnome/thumbnailers/text html/command</applyto>
       <owner>gnome-web-photo</owner>
       <type>string</type>
-      <default>gnome-web-photo --mode=thumbnail --timeout=16 --size=%s %u %o</default>
+      <default>gnome-web-photo --mode=thumbnail --timeout=16 --thumbnail-size=%s %u %o</default>
       <locale name="C">
         <short>The command to thumbnail HTML files</short>
         <long>The command to thumbnail HTML files.</long>
@@ -38,7 +38,7 @@
       <applyto>/desktop/gnome/thumbnailers/application xhtml@xml/command</applyto>
       <owner>gnome-web-photo</owner>
       <type>string</type>
-      <default>gnome-web-photo --mode=thumbnail --timeout=16 --size=%s %u %o</default>
+      <default>gnome-web-photo --mode=thumbnail --timeout=16 --thumbnail-size=%s %u %o</default>
       <locale name="C">
         <short>The command to thumbnail XHTML files</short>
         <long>The command to thumbnail XHTML files.</long>
diff --git a/src/Makefile.am b/src/Makefile.am
index 55e0f10..d310681 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,67 +1,21 @@
 bin_PROGRAMS = gnome-web-photo
 
-gecko_include_subdirs = \
-	.		\
-	content		\
-	docshell	\
-	dom		\
-	embed_base	\
-	gfx		\
-	gtkembedmoz	\
-	layout		\
-	locale		\
-	necko		\
-	pipnss		\
-	pref		\
-	uriloader	\
-	view		\
-	webbrwsr	\
-	widget		\
-	windowwatcher	\
-	xpcom
-
 gnome_web_photo_SOURCES = \
-	Components.cpp	\
-	Components.h	\
-	Embed.cpp	\
-	Embed.h		\
-	Listener.cpp	\
-	Listener.h	\
-	Prefs.cpp	\
-	Prefs.h		\
-	Printer.cpp	\
-	Printer.h	\
-	Writer.cpp	\
-	Writer.h	\
-	main.cpp
+	gnome-web-photo.c
 
 gnome_web_photo_CPPFLAGS = \
 	$(DEPENDENCY_CFLAGS)			\
-	$(addprefix -I$(GECKO_INCLUDE_ROOT)/,$(gecko_include_subdirs))	\
-	-DSHARE_DIR=\"$(pkgdatadir)\"   	\
 	-DLOCALEDIR=\"$(datadir)/locale\"	\
-	-DGECKO_HOME=\"$(GECKO_HOME)\"	\
-	-DGECKO_PREFIX=\"$(GECKO_PREFIX)\"	\
-        -DXPCOM_GLUE_USE_NSPR			\
-        -DXPCOM_GLUE				\
 	$(AM_CPPFLAGS)
 
-gnome_web_photo_CXXFLAGS = \
-	$(DEPENDENCY_CFLAGS) 	\
-	$(LIBXUL_INCLUDES)	\
-	$(LIBXUL_CXXFLAGS)	\
-	-UGTK_DISABLE_DEPRECATED\
-	$(AM_CXXFLAGS)
+gnome_web_photo_CFLAGS = \
+	$(AM_CFLAGS)
 
 gnome_web_photo_LDFLAGS = \
-	-R$(LIBXUL_LIBDIR)	\
 	$(AM_LDFLAGS)
 
 gnome_web_photo_LDADD = \
-	$(DEPENDENCY_LIBS)	\
-	$(JPEG_LIBS)		\
-	$(LIBXUL_LIBS)		\
-	-lxpcomglue
+	$(DEPENDENCY_LIBS)
 
 install-exec-hook: gnome-web-photo
 	cd $(DESTDIR)$(bindir) && \
diff --git a/src/gnome-web-photo.c b/src/gnome-web-photo.c
new file mode 100644
index 0000000..0a9d895
--- /dev/null
+++ b/src/gnome-web-photo.c
@@ -0,0 +1,971 @@
+/*
+ * Copyright (C) 2011 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1, 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ * Authors:
+ *   Vincent Untz <vuntz gnome org>
+ *
+ * A small part of the code is based on the original xulrunner-based
+ * gnome-web-photo (src/main.cpp), which was released under LGPLv2.1+. The
+ * copyright of this code was:
+ *   Copyright (C) 2005 Christian Persch
+ */
+
+/* TODO:
+ * - PHOTO_MODE doesn't work for very tall pages (like pgo, see comment before
+ *   gtk_widget_set_size_request()).
+ * - Correctly define GETTEXT_PACKAGE (via config.h)
+ */
+
+/* Build with either:
+ *    gcc -g -Wall -DHAVE_GNOME3 `pkg-config --cflags --libs gtk+-3.0 webkitgtk-3.0` gnome-web-photo.c -o gnome-web-photo
+ * or:
+ *    gcc -g -Wall `pkg-config --cflags --libs gconf-2.0 gtk+-2.0 webkit-1.0` gnome-web-photo.c -o gnome-web-photo
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#ifdef HAVE_GNOME3
+#include <gio/gio.h>
+#include <cairo/cairo-xlib.h>
+#else
+#include <gconf/gconf-client.h>
+#endif
+
+#ifdef HAVE_GNOME3
+#define GSETTINGS_DESKTOP_INTERFACE  "org.gnome.desktop.interface"
+#define GSETTINGS_VARIABLE_FONT_KEY  "document-font-name"
+#define GSETTINGS_MONOSPACE_FONT_KEY "monospace-font-name"
+#else
+#define GCONF_VARIABLE_FONT_KEY      "/desktop/gnome/interface/document_font_name"
+#define GCONF_MONOSPACE_FONT_KEY     "/desktop/gnome/interface/monospace_font_name"
+#define GCONF_EPHY_MINIMUM_FONT_SIZE "/apps/epiphany/web/minimum_font_size"
+#endif
+
+#define DEFAULT_VARIABLE_FONT     "Sans 10"
+#define DEFAULT_MONOSPACE_FONT    "Monospace 10"
+#define DEFAULT_MINIMUM_SIZE      7
+
+#define MIN_WIDTH       64
+#define MAX_WIDTH       2048
+#define DEFAULT_WIDTH   1024
+
+/* Value to keep in sync with the one from cairo:
+ * MAX_IMAGE_SIZE in cairo-image-surface.c */
+#define MAX_HEIGHT      32767
+
+#define DEFAULT_THUMBNAIL_SIZE  256
+
+typedef enum
+{
+  MODE_PHOTO,
+  MODE_THUMBNAIL,
+  MODE_PRINT,
+  MODE_LAST,
+  MODE_INVALID = MODE_LAST
+} PhotoMode;
+
+static struct {
+  const char *name;
+  PhotoMode   mode;
+} modes[] = {
+  { "photo",     MODE_PHOTO     },
+  { "thumbnail", MODE_THUMBNAIL },
+  { "print",     MODE_PRINT     }
+};
+
+static PhotoMode parsed_mode = MODE_INVALID;
+
+typedef struct {
+  char          *uri;
+  char          *outfile;
+
+  PhotoMode      mode;
+
+  int            width;
+  int            thumbnail_size;
+  gboolean       print_background;
+
+  int            timeout;
+  gboolean       force;
+
+  gboolean       error;
+
+  GtkWidget     *window;
+  WebKitWebView *webview;
+  guint          idle_id;
+  guint          timeout_id;
+} PhotoData;
+
+
+/******************\
+ * Setup Web View *
+\******************/
+
+static gboolean
+_on_new_window (WebKitWebView             *webview,
+                WebKitWebFrame            *frame,
+                WebKitNetworkRequest      *request,
+                WebKitWebNavigationAction *action,
+                WebKitWebPolicyDecision   *decision)
+{
+  webkit_web_policy_decision_ignore (decision);
+  return TRUE;
+}
+
+static gboolean
+_on_print_requested (WebKitWebView  *webview,
+                     WebKitWebFrame *frame)
+{
+  return TRUE;
+}
+
+static gboolean
+_on_console_message (WebKitWebView *webview,
+                     const gchar   *message,
+                     guint          line_number,
+                     const gchar   *source_id)
+{
+  return TRUE;
+}
+
+static gboolean
+_on_script_alert (WebKitWebView  *webview,
+                  WebKitWebFrame *frame,
+                  const gchar    *message)
+{
+  return TRUE;
+}
+
+static gboolean
+_on_script_confirm (WebKitWebView  *webview,
+                    WebKitWebFrame *frame,
+                    const gchar    *message,
+                    gboolean       *confirmed)
+{
+  *confirmed = FALSE;
+  return TRUE;
+}
+
+static gboolean
+_on_script_prompt (WebKitWebView   *webview,
+                   WebKitWebFrame  *frame,
+                   const gchar     *message,
+                   const gchar     *default_txt,
+                   const gchar    **text)
+{
+  *text = NULL;
+  return TRUE;
+}
+
+static gboolean
+_on_geolocation (WebKitWebView                   *webview,
+                 WebKitWebFrame                  *frame,
+                 WebKitGeolocationPolicyDecision *decision)
+{
+  webkit_geolocation_policy_deny (decision);
+  return TRUE;
+}
+
+static void
+_prepare_web_view (WebKitWebView *webview)
+{
+  g_signal_connect (webview, "new-window-policy-decision-requested",
+                    G_CALLBACK (_on_new_window), NULL);
+  g_signal_connect (webview, "print-requested",
+                    G_CALLBACK (_on_print_requested), NULL);
+  g_signal_connect (webview, "console-message",
+                    G_CALLBACK (_on_console_message), NULL);
+  g_signal_connect (webview, "script-alert",
+                    G_CALLBACK (_on_script_alert), NULL);
+  g_signal_connect (webview, "script-confirm",
+                    G_CALLBACK (_on_script_confirm), NULL);
+  g_signal_connect (webview, "script-prompt",
+                    G_CALLBACK (_on_script_prompt), NULL);
+  g_signal_connect (webview, "geolocation-policy-decision-requested",
+                    G_CALLBACK (_on_geolocation), NULL);
+}
+
+
+/******************\
+ * Setup Settings *
+\******************/
+
+static void
+_parse_font (const char  *font_descr,
+             const char  *default_descr,
+             char       **font_name,
+             int         *font_size)
+{
+  PangoFontDescription* pango_descr;
+
+  if (!font_descr)
+    font_descr = default_descr;
+
+  pango_descr = pango_font_description_from_string (font_descr);
+
+  if (!pango_descr && default_descr) {
+    _parse_font (default_descr, NULL, font_name, font_size);
+    return;
+  }
+
+  *font_name = g_strdup (pango_font_description_get_family (pango_descr));
+  *font_size = pango_font_description_get_size (pango_descr);
+
+  if (pango_font_description_get_size_is_absolute (pango_descr) == FALSE)
+    *font_size /= PANGO_SCALE;
+
+  pango_font_description_free (pango_descr);
+}
+
+static void
+_prepare_web_settings (WebKitWebSettings *settings,
+                       gboolean           print_background)
+{
+#ifdef HAVE_GNOME3
+  GSettings *gsettings;
+#else
+  GConfClient *client;
+#endif
+  char *value;
+  char *font_name = NULL;
+  int   font_size = 0;
+
+  /* Various settings */
+
+  g_object_set (G_OBJECT (settings),
+                /* printing settings */
+                "print-backgrounds", print_background,
+                /* don't save anything from this to the global history */
+                "enable-private-browsing", TRUE,
+                /* shouldn't be needed */
+                "enable-html5-database", FALSE,
+                "enable-html5-local-storage", FALSE,
+                /* no automatic popup or other similar behavior */
+                "javascript-can-open-windows-automatically", FALSE,
+                "auto-resize-window", FALSE,
+                /* ensure secure settings */
+                "javascript-can-access-clipboard", FALSE,
+                "enable-universal-access-from-file-uris", FALSE,
+                NULL);
+
+  /* Fetch fonts from user config */
+
+#ifdef HAVE_GNOME3
+  gsettings = g_settings_new (GSETTINGS_DESKTOP_INTERFACE);
+#else
+  client = gconf_client_get_default ();
+#endif
+
+#ifdef HAVE_GNOME3
+  value = g_settings_get_string (gsettings, GSETTINGS_VARIABLE_FONT_KEY);
+#else
+  value = gconf_client_get_string (client, GCONF_VARIABLE_FONT_KEY, NULL);
+#endif
+  _parse_font (value, DEFAULT_VARIABLE_FONT, &font_name, &font_size);
+  g_free (value);
+
+  g_object_set (G_OBJECT (settings),
+                "default-font-family", font_name,
+                "default-font-size", font_size,
+                "sans-serif-font-family", font_name,
+                NULL);
+  g_free (font_name);
+
+#ifdef HAVE_GNOME3
+  value = g_settings_get_string (gsettings, GSETTINGS_MONOSPACE_FONT_KEY);
+#else
+  value = gconf_client_get_string (client, GCONF_MONOSPACE_FONT_KEY, NULL);
+#endif
+  _parse_font (value, DEFAULT_MONOSPACE_FONT, &font_name, &font_size);
+  g_free (value);
+
+  g_object_set (G_OBJECT (settings),
+                "monospace-font-family", font_name,
+                "default-monospace-font-size", font_size,
+                NULL);
+  g_free (font_name);
+
+#ifdef HAVE_GNOME3
+  /* We can't assume the GSettings schemas for epiphany are installed */
+  font_size = DEFAULT_MINIMUM_SIZE;
+#else
+  font_size = gconf_client_get_int (client, GCONF_EPHY_MINIMUM_FONT_SIZE, NULL);
+#endif
+  if (font_size == 0)
+    font_size = DEFAULT_MINIMUM_SIZE;
+
+  g_object_set (G_OBJECT (settings),
+                "minimum-font-size", font_size,
+                NULL);
+
+#ifdef HAVE_GNOME3
+  g_object_unref (gsettings);
+#else
+  g_object_unref (client);
+#endif
+}
+
+
+/*****************\
+ * General Setup *
+\*****************/
+
+static void
+_prepare_webkit (WebKitWebView     *webview,
+                 WebKitWebSettings *settings,
+                 gboolean           print_background)
+{
+  SoupSession* session = webkit_get_default_session();
+
+  /* We don't want auth dialogs */
+  soup_session_remove_feature_by_type (session, WEBKIT_TYPE_SOUP_AUTH_DIALOG);
+
+  _prepare_web_view (webview);
+  _prepare_web_settings (settings, print_background);
+}
+
+
+/******************************************\
+ * GtkOffscreenWindow with limited height *
+\******************************************/
+
+/* This is a GtkOffscreenWindow with a maximum height.
+ * See comment above gtk_widget_set_size_request() call to understand why we
+ * need this. */
+
+typedef struct _PhotoOffscreenWindow      PhotoOffscreenWindow;
+typedef struct _PhotoOffscreenWindowClass PhotoOffscreenWindowClass;
+
+struct _PhotoOffscreenWindow
+{
+  GtkOffscreenWindow parent_object;
+};
+
+struct _PhotoOffscreenWindowClass
+{
+  GtkOffscreenWindowClass parent_class;
+};
+
+GType photo_offscreen_window_get_type (void) G_GNUC_CONST;	
+
+G_DEFINE_TYPE (PhotoOffscreenWindow, photo_offscreen_window, GTK_TYPE_OFFSCREEN_WINDOW)
+
+#ifdef HAVE_GNOME3
+static void
+photo_offscreen_window_get_preferred_height (GtkWidget *widget,
+                                             gint      *minimum,
+                                             gint      *natural)
+{
+  GTK_WIDGET_CLASS (photo_offscreen_window_parent_class)->get_preferred_height (widget, minimum, natural);
+
+  *minimum = MIN (*minimum, MAX_HEIGHT);
+  *natural = MIN (*natural, MAX_HEIGHT);
+}
+#else
+static void
+photo_offscreen_window_size_request (GtkWidget      *widget,
+                                     GtkRequisition *requisition)
+{
+  GTK_WIDGET_CLASS (photo_offscreen_window_parent_class)->size_request (widget, requisition);
+
+  requisition->height = MIN (requisition->height, MAX_HEIGHT);
+}
+#endif
+
+static void
+photo_offscreen_window_class_init (PhotoOffscreenWindowClass *class)
+{
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+#ifdef HAVE_GNOME3
+  widget_class->get_preferred_height = photo_offscreen_window_get_preferred_height;
+#else
+  widget_class->size_request = photo_offscreen_window_size_request;
+#endif
+}
+
+static void
+photo_offscreen_window_init (PhotoOffscreenWindow *window)
+{
+}
+
+static GtkWidget *
+photo_offscreen_window_new (void)
+{
+  return g_object_new (photo_offscreen_window_get_type (), NULL);
+}
+
+/************\
+ *   Core   *
+\************/
+
+static void
+_write_photo (PhotoData *data)
+{
+#ifdef HAVE_GNOME3
+  cairo_surface_t *surface;
+  cairo_status_t   status;
+
+  surface = gtk_offscreen_window_get_surface (GTK_OFFSCREEN_WINDOW (data->window));
+  status = cairo_surface_write_to_png (surface, data->outfile);
+
+  switch (status) {
+    case CAIRO_STATUS_SUCCESS:
+      break;
+    default:
+      data->error = TRUE;
+      /* Translators: first %s is a URI */
+      g_printerr (_("Error while saving '%s': %s\n"),
+                  data->uri, cairo_status_to_string (status));
+      break;
+  }
+#else
+  GdkPixbuf *pixbuf;
+  GError    *error = NULL;
+
+  pixbuf = gtk_offscreen_window_get_pixbuf (GTK_OFFSCREEN_WINDOW (data->window));
+  gdk_pixbuf_save (pixbuf, data->outfile, "png", &error, NULL);
+  g_object_unref (pixbuf);
+
+  if (error) {
+    data->error = TRUE;
+    /* Translators: first %s is a URI */
+    g_printerr (_("Error while saving '%s': %s\n"),
+                data->uri, error->message);
+    g_error_free (error);
+  }
+#endif
+}
+
+static void
+_write_thumbnail (PhotoData *data)
+{
+#ifdef HAVE_GNOME3
+  cairo_surface_t *surface;
+  cairo_surface_t *thumb_surface;
+  cairo_t         *cr;
+  cairo_status_t   status;
+  int width;
+  int height;
+  int thumb_width;
+  int thumb_height;
+
+  surface = gtk_offscreen_window_get_surface (GTK_OFFSCREEN_WINDOW (data->window));
+  width = cairo_xlib_surface_get_width (surface);
+  height = cairo_xlib_surface_get_height (surface);
+
+  /* Too tall? It'll be a square */
+  if (height > width) {
+    height = width;
+  }
+
+  thumb_width = data->thumbnail_size;
+  thumb_height = (data->thumbnail_size * height) / (double) width;
+
+  thumb_surface = cairo_surface_create_similar (surface, CAIRO_CONTENT_COLOR,
+                                                thumb_width, thumb_height);
+
+  cr = cairo_create (thumb_surface);
+  cairo_scale (cr,
+               data->thumbnail_size / (double) width,
+               data->thumbnail_size / (double) width);
+  cairo_set_source_surface (cr, surface, 0, 0);
+  cairo_paint (cr);
+  cairo_destroy (cr);
+
+  status = cairo_surface_write_to_png (thumb_surface, data->outfile);
+
+  cairo_surface_destroy (thumb_surface);
+
+  switch (status) {
+    case CAIRO_STATUS_SUCCESS:
+      break;
+    default:
+      data->error = TRUE;
+      /* Translators: first %s is a URI */
+      g_printerr (_("Error while thumbnailing '%s': %s\n"),
+                  data->uri, cairo_status_to_string (status));
+      break;
+  }
+#else
+  GdkPixbuf *pixbuf;
+  GdkPixbuf *thumb_pixbuf;
+  GError    *error = NULL;
+  int width;
+  int height;
+  int thumb_width;
+  int thumb_height;
+
+  pixbuf = gtk_offscreen_window_get_pixbuf (GTK_OFFSCREEN_WINDOW (data->window));
+  width = gdk_pixbuf_get_width (pixbuf);
+  height = gdk_pixbuf_get_height (pixbuf);
+
+  /* Too tall? It'll be a square */
+  if (height > width) {
+    GdkPixbuf *subpixbuf;
+
+    subpixbuf = gdk_pixbuf_new_subpixbuf (pixbuf, 0, 0, width, width);
+    g_object_unref (pixbuf);
+
+    pixbuf = subpixbuf;
+    height = width;
+  }
+
+  thumb_width = data->thumbnail_size;
+  thumb_height = (data->thumbnail_size * height) / (double) width;
+
+  thumb_pixbuf = gdk_pixbuf_scale_simple (pixbuf,
+                                          thumb_width, thumb_height,
+                                          GDK_INTERP_BILINEAR);
+
+  gdk_pixbuf_save (thumb_pixbuf, data->outfile, "png", &error, NULL);
+
+  g_object_unref (pixbuf);
+  g_object_unref (thumb_pixbuf);
+
+  if (error) {
+    data->error = TRUE;
+    /* Translators: first %s is a URI */
+    g_printerr (_("Error while thumbnailing '%s': %s\n"),
+                data->uri, error->message);
+    g_error_free (error);
+  }
+#endif
+}
+
+static void
+_print_photo (PhotoData *data)
+{
+  GtkPrintOperation *operation;
+  WebKitWebFrame    *main_frame;
+  GError            *error = NULL;
+
+  operation = gtk_print_operation_new ();
+  gtk_print_operation_set_export_filename (operation, data->outfile);
+
+  main_frame = webkit_web_view_get_main_frame (data->webview);
+
+  webkit_web_frame_print_full (main_frame, operation,
+                               GTK_PRINT_OPERATION_ACTION_EXPORT, &error);
+
+  if (error) {
+    data->error = TRUE;
+    /* Translators: first %s is a URI */
+    g_printerr (_("Error while printing '%s': %s\n"),
+                data->uri, error->message);
+    g_error_free (error);
+  }
+
+  g_object_unref (operation);
+}
+
+static void
+_do_action (PhotoData *data)
+{
+  switch (data->mode) {
+    case MODE_PHOTO:
+      _write_photo (data);
+      break;
+    case MODE_THUMBNAIL:
+      _write_thumbnail (data);
+      break;
+    case MODE_PRINT:
+      _print_photo (data);
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+  }
+}
+
+static gboolean
+_on_web_view_load_error (WebKitWebView  *webview,
+                         WebKitWebFrame *frame,
+                         const char     *uri,
+                         GError         *error,
+                         PhotoData      *data)
+{
+  /* Cancelling is explicitly done by us, so we don't do anything here */
+  if (error->domain == WEBKIT_NETWORK_ERROR &&
+      error->code == WEBKIT_NETWORK_ERROR_CANCELLED)
+    return TRUE;
+
+  data->error = TRUE;
+  /* Translators: first %s is a URI */
+  g_printerr (_("Error while loading '%s': %s\n"), uri, error->message);
+
+  gtk_main_quit ();
+
+  return TRUE;
+}
+
+static gboolean
+_web_view_loaded_idle (PhotoData *data)
+{
+  data->idle_id = 0;
+  if (data->timeout_id > 0) {
+    g_source_remove (data->timeout_id);
+    data->timeout_id = 0;
+  }
+
+  _do_action (data);
+
+  gtk_main_quit ();
+
+  return FALSE;
+}
+
+static void
+_on_web_view_load_status (WebKitWebView *webview,
+                          GParamSpec    *pspec,
+                          PhotoData     *data)
+{
+  switch (webkit_web_view_get_load_status (webview)) {
+    case WEBKIT_LOAD_FINISHED:
+      /* For local files, we finish the load so fast that the page is not even
+       * rendered. Going back to the idle loop fixes this. */
+      g_assert (data->idle_id == 0);
+      data->idle_id = g_idle_add ((GSourceFunc) _web_view_loaded_idle, data);
+      break;
+
+    case WEBKIT_LOAD_FAILED:
+      /* Ignore since we'll have the load-error event */
+      break;
+
+    default:
+      break;
+  }
+}
+
+static gboolean
+_on_timeout (PhotoData *data)
+{
+  data->timeout_id = 0;
+  if (data->idle_id > 0) {
+    g_source_remove (data->idle_id);
+    data->idle_id = 0;
+  }
+
+  if (data->force) {
+    switch (webkit_web_view_get_load_status (data->webview)) {
+      case WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT:
+      case WEBKIT_LOAD_FINISHED:
+        /* Translators: first %s is a URI */
+        g_printerr (_("Timed out while loading '%s'. Outputting current view...\n"), data->uri);
+        _do_action (data);
+        break;
+
+      default:
+        data->error = TRUE;
+        /* Translators: first %s is a URI */
+        g_printerr (_("Timed out while loading '%s'. Nothing to output...\n"), data->uri);
+        break;
+    }
+  } else {
+    data->error = TRUE;
+    /* Translators: first %s is a URI */
+    g_printerr (_("Timed out while loading '%s'.\n"), data->uri);
+  }
+
+  /* We have to do it after checking the load status */
+  webkit_web_view_stop_loading (data->webview);
+
+  gtk_main_quit ();
+
+  return FALSE;
+}
+
+static GtkWidget *
+_create_web_window (PhotoData *data)
+{
+  GtkWidget         *window;
+  GtkWidget         *webview;
+  WebKitWebSettings *settings;
+
+  window = photo_offscreen_window_new ();
+  data->window = window;
+
+  /* We don't specify a height: if we did so, we'd be forcing the height of the
+   * output, which is not desirable since the page could be less tall than
+   * that.
+   * But on the other hand, if the page is too tall (eg, planet.gnome.org), we
+   * can't handle it completely and we run out of memory before being able to
+   * use it. This is why we use PhotoOffscreenWindow, which limits the maximum
+   * height of the page.
+   * This means we won't have the whole page "displayed" in the offscreen
+   * window if it's too tall. This is not an issue for MODE_THUMBNAIL (we don't
+   * need the whole page), nor for MODE_PRINT (the print operation is not
+   * related to what is displayed). So it only affects MODE_PHOTO. But it's
+   * better than not getting anything anyway. */
+  gtk_widget_set_size_request (window, data->width, -1);
+
+  webview = webkit_web_view_new ();
+  data->webview = WEBKIT_WEB_VIEW (webview);
+
+  settings = webkit_web_settings_new ();
+
+  _prepare_webkit (data->webview, settings, data->print_background);
+
+  webkit_web_view_set_settings (data->webview, settings);
+
+  gtk_container_add (GTK_CONTAINER(window), webview);
+  gtk_widget_show_all (window);
+
+  g_signal_connect (webview, "load-error",
+                    G_CALLBACK (_on_web_view_load_error), data);
+  g_signal_connect (webview, "notify::load-status",
+                    G_CALLBACK (_on_web_view_load_status), data);
+
+  if (data->timeout > 0)
+    data->timeout_id = g_timeout_add_seconds (data->timeout,
+                                              (GSourceFunc) _on_timeout, data);
+
+  webkit_web_view_open (data->webview, data->uri);
+
+  return window;
+}
+
+
+/************************\
+ * Command-line options *
+\************************/
+
+static gboolean
+_parse_mode (const gchar  *option_name,
+             const gchar  *value,
+             gpointer      data,
+             GError      **error)
+{
+  g_assert (value != NULL);
+
+  guint i;
+  for (i = 0; i <= G_N_ELEMENTS (modes); i++) {
+    if (g_ascii_strcasecmp (value, modes[i].name) == 0) {
+      parsed_mode = modes[i].mode;
+      break;
+    }
+  }
+
+  if (i == MODE_INVALID) {
+    *error = g_error_new (G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                          _("Unknown mode '%s'"), value);
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+static void
+_print_synopsis (void)
+{
+  const char *name = g_get_prgname ();
+  g_assert (name != NULL);
+
+  g_print (_("Usage: %s [--mode=photo|thumbnail|print] [...]\n"), name);
+
+  switch (parsed_mode) {
+    case MODE_PHOTO:
+      g_print (_("Usage: %s [-t TIMEOUT] [--force] [-w WIDTH] [--file] URI|FILE OUTFILE\n"), name);
+      break;
+    case MODE_THUMBNAIL:
+      g_print (_("Usage: %s [-t TIMEOUT] [--force] [-w WIDTH] [-s THUMBNAILSIZE] [--file] URI|FILE OUTFILE\n"), name);
+      break;
+    case MODE_PRINT:
+      g_print (_("Usage: %s [-t TIMEOUT] [--force] [-w WIDTH] [--print-background] [--file] URI|FILE OUTFILE\n"), name);
+      break;
+    default:
+      break;
+  }
+}
+
+int
+main (int    argc,
+      char **argv)
+{
+  GOptionContext  *context;
+  GError          *error = NULL;
+  char           **arguments = NULL;
+  gboolean         is_file = FALSE;
+  GtkWidget       *window;
+
+  PhotoData data = { NULL, NULL,
+                     MODE_INVALID,
+                     /* thumbnail_size set to -1 to be able to check if option
+                      * was passed or not */
+                     DEFAULT_WIDTH, -1, FALSE,
+                     60, FALSE,
+                     FALSE,
+                     NULL, NULL, 0, 0 };
+
+  const GOptionEntry main_options[] =
+  {
+    { "mode", 'm', 0, G_OPTION_ARG_CALLBACK, (void*) _parse_mode,
+      N_("Operation mode [photo|thumbnail|print]"), NULL },
+    { "timeout", 't', 0, G_OPTION_ARG_INT, &data.timeout,
+      N_("Timeout in seconds, or 0 to disable timeout (default: 60)"),
+      /* Translators: T will appear in the help, as in: --timeout=T */
+      N_("T") },
+    { "force", 'f', 0, G_OPTION_ARG_NONE, &data.force,
+      N_("Force output when timeout expires, even if the page is not fully loaded"), NULL },
+    { "width", 'w', 0, G_OPTION_ARG_INT, &data.width,
+      N_("Desired width of the web page (default: 1024)"),
+      /* Translators: W will appear in the help, as in: --width=W */
+      N_("W") },
+    { "thumbnail-size", 's', 0, G_OPTION_ARG_INT, &data.thumbnail_size,
+      N_("Thumbnail size (default: 256)"),
+      /* Translators: S will appear in the help, as in: --thumbnail-size=S */
+      N_("S") },
+    { "print-background", 0, 0, G_OPTION_ARG_NONE, &data.print_background,
+      N_("Print background images and colours (default: false)"), NULL },
+    { "file", 0, 0, G_OPTION_ARG_NONE, &is_file,
+      N_("Argument is a file and not a URI"), NULL },
+    { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &arguments, "", NULL },
+    { NULL }
+  };
+
+#ifdef ENABLE_NLS
+  /* Initialize the i18n stuff */
+  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+  textdomain (GETTEXT_PACKAGE);
+#endif
+
+  /* Now parse the arguments */
+  context = g_option_context_new (NULL);
+  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
+  g_option_context_add_main_entries (context, main_options, GETTEXT_PACKAGE);
+
+  /* This will initialize GTK+ too */
+  g_option_context_add_group (context, gtk_get_option_group (TRUE));
+
+  if (!g_option_context_parse (context, &argc, &argv, &error)) {
+    g_printerr ("%s\n", error->message);
+    g_error_free (error);
+    g_option_context_free (context);
+    _print_synopsis ();
+    return 1;
+  }
+  g_option_context_free (context);
+
+  data.mode = parsed_mode;
+
+  /* Mode not explicitly specified, derive from invocation filename */
+  if (data.mode == MODE_INVALID) {
+    const char *program = g_get_prgname ();
+    g_assert (program != NULL);
+
+    if (g_ascii_strcasecmp (program, "gnome-web-thumbnail") == 0) {
+      data.mode = MODE_THUMBNAIL;
+    } else if (g_ascii_strcasecmp (program, "gnome-web-print") == 0) {
+      data.mode = MODE_PRINT;
+    } else {
+      data.mode = MODE_PHOTO;
+    }
+  }
+
+  /* Renice when thumbnailing, since it is likely that we are called multiple
+   * times in sequence in order to thumbnail a bunch of HTML files. */
+  if (data.mode == MODE_THUMBNAIL) {
+    nice (5);
+  }
+
+  /* Check timeout */
+  if (data.timeout < 0) {
+    g_printerr (_("--timeout cannot be negative!\n"));
+    _print_synopsis ();
+    return 1;
+  }
+
+  /* Check thumbnail size */
+  if (data.mode == MODE_THUMBNAIL) {
+    if (data.thumbnail_size == -1)
+      data.thumbnail_size = DEFAULT_THUMBNAIL_SIZE;
+
+    if (data.thumbnail_size != 32 &&
+        data.thumbnail_size != 64 &&
+        data.thumbnail_size != 96 &&
+        data.thumbnail_size != 128 &&
+        data.thumbnail_size != 256) {
+      g_printerr (_("--size can only be 32, 64, 96, 128 or 256!\n"));
+      return 1;
+    }
+  } else if (data.thumbnail_size != -1) {
+    g_printerr (_("--size is only available in thumbnail mode!\n"));
+    _print_synopsis ();
+    return 1;
+  }
+
+  /* Check width */
+  if (data.width < MIN_WIDTH || data.width > MAX_WIDTH) {
+    g_printerr (_("--width out of bounds; must be between %d and %d!\n"), MIN_WIDTH, MAX_WIDTH);
+    return 1;
+  }
+
+  if (data.mode == MODE_THUMBNAIL && (data.width % 32) != 0) {
+    g_printerr (_("--width must be a multiple of 32 in thumbnail mode!\n"));
+    return 1;
+  }
+
+  /* Check --print-background */
+  if (data.mode != MODE_PRINT && data.print_background) {
+    g_printerr (_("--print-background is only available in print mode!\n"));
+    _print_synopsis ();
+    return 1;
+  }
+
+  /* Check uri/output */
+  if (!arguments || g_strv_length (arguments) < 2) {
+    g_printerr (_("Missing arguments!\n"));
+    _print_synopsis ();
+    return 1;
+  }
+
+  if (g_strv_length (arguments) > 2) {
+    g_printerr (_("Too many arguments!\n"));
+    _print_synopsis ();
+    return 1;
+  }
+
+  /* Replace filename with URI */
+  if (is_file) {
+    GFile *file;
+
+    file = g_file_new_for_commandline_arg (arguments[0]);
+
+    g_free (arguments[0]);
+    arguments[0] = g_file_get_uri (file);
+
+    g_object_unref (file);
+  }
+
+  /* Now let's do the work! */
+  data.uri = arguments[0];
+  data.outfile = arguments[1];
+
+  window = _create_web_window (&data);
+
+  gtk_main ();
+
+  gtk_widget_destroy (window);
+
+  return data.error ? 1 : 0;
+}



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