midori/midori/main.c

398 lines
14 KiB
C

/*
Copyright (C) 2007-2009 Christian Dywan <christian@twotoasts.de>
Copyright (C) 2008 Dale Whittaker <dayul@users.sf.net>
This library 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 of the License, or (at your option) any later version.
See the file COPYING for the full license text.
*/
#include "midori-frontend.h"
#include "midori-platform.h"
#include "midori-privatedata.h"
#include "midori-searchaction.h"
#include "midori/midori-session.h"
#include <midori/midori-core.h>
#include <config.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <glib/gstdio.h>
#include <glib/gi18n-lib.h>
#include "katze/katze.h"
#include <sqlite3.h>
static void
plain_entry_activate_cb (GtkWidget* entry,
GtkWidget* web_view)
{
gchar* uri = sokoke_magic_uri (gtk_entry_get_text (GTK_ENTRY (entry)), FALSE, TRUE);
webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), uri);
g_free (uri);
}
#ifndef HAVE_WEBKIT2
static void
snapshot_load_finished_cb (GtkWidget* web_view,
WebKitWebFrame* web_frame,
gchar* filename)
{
GdkPixbuf* pixbuf = gtk_offscreen_window_get_pixbuf (GTK_OFFSCREEN_WINDOW (
gtk_widget_get_parent (web_view)));
gdk_pixbuf_save (pixbuf, filename, "png", NULL, "compression", "7", NULL);
g_object_unref (pixbuf);
g_print (_("Snapshot saved to: %s\n"), filename);
gtk_main_quit ();
}
#endif
int
main (int argc,
char** argv)
{
gchar* webapp;
gchar* config;
gboolean private;
gboolean portable;
gboolean plain;
gboolean diagnostic_dialog = FALSE;
gboolean debug = FALSE;
gboolean run;
gchar* snapshot;
gchar** execute;
gboolean help_execute;
gboolean version;
gchar** uris;
gchar* block_uris;
gint inactivity_reset;
GOptionEntry entries[] =
{
{ "app", 'a', 0, G_OPTION_ARG_STRING, &webapp,
N_("Run ADDRESS as a web application"), N_("ADDRESS") },
{ "config", 'c', 0, G_OPTION_ARG_FILENAME, &config,
N_("Use FOLDER as configuration folder"), N_("FOLDER") },
{ "private", 'p', 0, G_OPTION_ARG_NONE, &private,
N_("Private browsing, no changes are saved"), NULL },
#ifdef G_OS_WIN32
{ "portable", 'P', 0, G_OPTION_ARG_NONE, &portable,
N_("Portable mode, all runtime files are stored in one place"), NULL },
#endif
{ "plain", '\0', 0, G_OPTION_ARG_NONE, &plain,
N_("Plain GTK+ window with WebKit, akin to GtkLauncher"), NULL },
{ "diagnostic-dialog", 'd', 0, G_OPTION_ARG_NONE, &diagnostic_dialog,
N_("Show a diagnostic dialog"), NULL },
{ "debug", 'g', 0, G_OPTION_ARG_NONE, &debug,
N_("Run within gdb and save a backtrace on crash"), NULL },
{ "run", 'r', 0, G_OPTION_ARG_NONE, &run,
N_("Run the specified filename as javascript"), NULL },
{ "snapshot", 's', 0, G_OPTION_ARG_STRING, &snapshot,
N_("Take a snapshot of the specified URI"), NULL },
{ "execute", 'e', 0, G_OPTION_ARG_STRING_ARRAY, &execute,
N_("Execute the specified command"), NULL },
{ "help-execute", 0, 0, G_OPTION_ARG_NONE, &help_execute,
N_("List available commands to execute with -e/ --execute"), NULL },
{ "version", 'V', 0, G_OPTION_ARG_NONE, &version,
N_("Display program version"), NULL },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &uris,
N_("Addresses"), NULL },
{ "block-uris", 'b', 0, G_OPTION_ARG_STRING, &block_uris,
N_("Block URIs according to regular expression PATTERN"), _("PATTERN") },
#ifdef HAVE_X11_EXTENSIONS_SCRNSAVER_H
{ "inactivity-reset", 'i', 0, G_OPTION_ARG_INT, &inactivity_reset,
/* i18n: CLI: Close tabs, clear private data, open starting page */
N_("Reset Midori after SECONDS seconds of inactivity"), N_("SECONDS") },
#endif
{ NULL }
};
/* Parse cli options */
webapp = NULL;
config = NULL;
private = FALSE;
portable = FALSE;
plain = FALSE;
run = FALSE;
snapshot = NULL;
execute = NULL;
help_execute = FALSE;
version = FALSE;
uris = NULL;
block_uris = NULL;
inactivity_reset = 0;
midori_app_setup (&argc, &argv, entries);
if (debug)
{
gchar* gdb = g_find_program_in_path ("gdb");
if (gdb == NULL)
midori_error (_("Error: \"gdb\" can't be found\n"));
sokoke_spawn_gdb (gdb, TRUE);
g_free (gdb);
return 0;
}
g_set_application_name (_("Midori"));
/* Versioned prgname to override menuproxy blacklist */
g_set_prgname (PACKAGE_NAME "4");
if (version)
{
GString* versions = g_string_new ("");
g_string_append_c (versions, '\n');
midori_view_list_versions (versions, FALSE);
/* FIXME Plugins may clutter output and hang
midori_view_list_plugins (NULL, versions, FALSE); */
g_print ("%s\n", versions->str);
g_string_free (versions, TRUE);
g_print (
"Copyright (c) 2007-2013 Christian Dywan\n\n"
"%s\n"
"\t%s\n\n"
"%s\n"
"\thttp://www.midori-browser.org\n",
_("Please report comments, suggestions and bugs to:"),
PACKAGE_BUGREPORT,
_("Check for new versions at:")
);
return 0;
}
if (help_execute)
{
MidoriBrowser* browser = midori_browser_new ();
GtkActionGroup* action_group = midori_browser_get_action_group (browser);
GList* actions = gtk_action_group_list_actions (action_group);
GList* temp = actions;
GObjectClass* class = G_OBJECT_GET_CLASS (midori_browser_get_settings (browser));
guint i, n_properties;
GParamSpec** pspecs = g_object_class_list_properties (class, &n_properties);
guint length = 1;
gchar* space;
for (; temp; temp = g_list_next (temp))
length = MAX (length, 1 + strlen (gtk_action_get_name (temp->data)));
for (i = 0; i < n_properties; i++)
length = MAX (length, 1 + strlen (g_param_spec_get_name (pspecs[i])));
space = g_strnfill (length, ' ');
for (; actions; actions = g_list_next (actions))
{
GtkAction* action = actions->data;
const gchar* name = gtk_action_get_name (action);
gchar* padding = g_strndup (space, strlen (space) - strlen (name));
gchar* label = katze_object_get_string (action, "label");
gchar* stripped = katze_strip_mnemonics (label);
gchar* tooltip = katze_object_get_string (action, "tooltip");
g_print ("%s%s%s%s%s\n", name, padding, stripped,
tooltip ? ": " : "", tooltip ? tooltip : "");
g_free (tooltip);
g_free (padding);
g_free (label);
g_free (stripped);
}
g_list_free (actions);
g_print ("\n");
for (i = 0; i < n_properties; i++)
{
GParamSpec* pspec = pspecs[i];
if (!(pspec->flags & G_PARAM_WRITABLE))
continue;
const gchar* property = g_param_spec_get_name (pspec);
gchar* padding = g_strndup (space, strlen (space) - strlen (property));
GType type = G_PARAM_SPEC_TYPE (pspec);
const gchar* tname;
GString* tname_string = NULL;
if (type == G_TYPE_PARAM_STRING)
tname = "string";
else if (type == G_TYPE_PARAM_BOOLEAN)
tname = "true/ false";
else if (type == G_TYPE_PARAM_ENUM)
{
GEnumClass* enum_class = G_ENUM_CLASS (g_type_class_peek (pspec->value_type));
guint j = 0;
tname_string = g_string_new ("");
for (j = 0; j < enum_class->n_values; j++)
{
g_string_append (tname_string, enum_class->values[j].value_name);
g_string_append (tname_string, j == 2 ? "\n " : " ");
}
tname = tname_string->str;
}
else
tname = "number";
g_print ("%s%s%s\n", property, padding, tname);
if (tname_string != NULL)
g_string_free (tname_string, TRUE);
g_free (padding);
}
g_free (pspecs);
g_free (space);
gtk_widget_destroy (GTK_WIDGET (browser));
return 0;
}
if (snapshot)
{
GError* error = NULL;
gchar* filename;
GtkWidget* web_view;
gchar* uri;
GtkWidget* offscreen;
GdkScreen* screen;
gint fd = g_file_open_tmp ("snapshot-XXXXXX.png", &filename, &error);
close (fd);
if (error)
{
g_error ("%s", error->message);
return 1;
}
if (g_unlink (filename) == -1)
{
g_error ("%s", g_strerror (errno));
return 1;
}
web_view = webkit_web_view_new ();
offscreen = gtk_offscreen_window_new ();
gtk_container_add (GTK_CONTAINER (offscreen), web_view);
if ((screen = gdk_screen_get_default ()))
gtk_widget_set_size_request (web_view,
gdk_screen_get_width (screen), gdk_screen_get_height (screen));
else
gtk_widget_set_size_request (web_view, 800, 600);
gtk_widget_show_all (offscreen);
#ifndef HAVE_WEBKIT2
g_signal_connect (web_view, "load-finished",
G_CALLBACK (snapshot_load_finished_cb), filename);
#endif
uri = sokoke_magic_uri (snapshot, FALSE, TRUE);
webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), uri);
g_free (uri);
gtk_main ();
g_free (filename);
return 0;
}
if (plain)
{
GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
GtkWidget* entry = gtk_entry_new ();
#ifndef HAVE_WEBKIT2
GtkWidget* scrolled = gtk_scrolled_window_new (NULL, NULL);
#endif
GtkWidget* web_view = webkit_web_view_new ();
katze_window_set_sensible_default_size (GTK_WINDOW (window));
gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
#ifndef HAVE_WEBKIT2
gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (scrolled), web_view);
#else
gtk_box_pack_start (GTK_BOX (vbox), web_view, TRUE, TRUE, 0);
#endif
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_entry_set_text (GTK_ENTRY (entry), uris && *uris ? *uris : "http://www.example.com");
plain_entry_activate_cb (entry, web_view);
g_signal_connect (entry, "activate",
G_CALLBACK (plain_entry_activate_cb), web_view);
g_signal_connect (window, "delete-event",
G_CALLBACK (gtk_main_quit), window);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
midori_private_data_register_built_ins ();
if (run)
{
gchar* script = NULL;
GError* error = NULL;
if (g_file_get_contents (uris ? *uris : NULL, &script, NULL, &error))
{
midori_paths_init (MIDORI_RUNTIME_MODE_PRIVATE, config);
MidoriBrowser* browser = midori_browser_new ();
MidoriWebSettings* settings = midori_browser_get_settings (browser);
#ifndef HAVE_WEBKIT2
g_object_set_data (G_OBJECT (webkit_get_default_session ()), "pass-through-console", (void*)1);
#endif
midori_load_soup_session (settings);
gchar* msg = NULL;
GtkWidget* view = midori_view_new_with_item (NULL, settings);
g_object_set (settings, "open-new-pages-in", MIDORI_NEW_PAGE_WINDOW, NULL);
midori_browser_add_tab (browser, view);
gtk_widget_show_all (GTK_WIDGET (browser));
gtk_widget_hide (GTK_WIDGET (browser));
midori_view_execute_script (MIDORI_VIEW (view), script, &msg);
if (msg != NULL)
{
g_error ("%s\n", msg);
g_free (msg);
}
gtk_main ();
}
else if (error != NULL)
{
g_error ("%s\n", error->message);
g_error_free (error);
}
else
g_error ("%s\n", _("An unknown error occured"));
g_free (script);
return 0;
}
if (private)
{
MidoriBrowser* browser = midori_private_app_new (config, webapp,
uris, execute, inactivity_reset, block_uris);
g_signal_connect (browser, "destroy", G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (browser, "quit", G_CALLBACK (gtk_main_quit), NULL);
gtk_main ();
return 0;
}
if (webapp)
{
MidoriBrowser* browser = midori_web_app_new (webapp,
uris, execute, inactivity_reset, block_uris);
g_signal_connect (browser, "destroy", G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (browser, "quit", G_CALLBACK (gtk_main_quit), NULL);
gtk_main ();
return 0;
}
MidoriApp* app = midori_normal_app_new (config,
portable ? "portable" : "normal", diagnostic_dialog,
uris, execute, inactivity_reset, block_uris);
if (app == NULL)
return 0;
if (app == (void*)0xdeadbeef)
return 1;
g_signal_connect (app, "quit", G_CALLBACK (gtk_main_quit), NULL);
gtk_main ();
midori_normal_app_on_quit (app);
g_object_unref (app);
return 0;
}