diff --git a/README b/README index 63d716d5..62995981 100644 --- a/README +++ b/README @@ -9,12 +9,12 @@ Midori is a lightweight web browser. * User scripts and user styles support. * Straightforward bookmark management. * Customizable and extensible interface. -* Extensible via Javascript. +* Extensions written in C. * Custom context menu actions. Requirements: GTK+ 2.10, WebkitGtk, libXML2 -Optional: Unique 0.9, libsoup 2.4, sqlite 3.0, xdg-open +Optional: Unique 0.9, libsoup 2.4, sqlite 3.0, docutils, xdg-open For installation instructions read INSTALL. diff --git a/extensions/wscript_build b/extensions/wscript_build new file mode 100644 index 00000000..4b75ea7b --- /dev/null +++ b/extensions/wscript_build @@ -0,0 +1,30 @@ +#! /usr/bin/env python +# WAF build script for midori +# This file is licensed under the terms of the expat license, see the file EXPAT. + +extensions = os.listdir ('extensions') +for extension in extensions: + try: + folder = 'extensions' + os.sep + extension + files = os.listdir (folder) + target = extension + source = '' + for fila in files: + if fila[-2:] == '.c': + source += ' ' + extension + os.sep + fila + includes = '.' + os.sep + '..' + except: + if extension[-2:] != '.c': + continue + target = extension[:-2] + source = extension + includes = '..' + + obj = bld.create_obj ('cc', 'shlib') + obj.target = target + obj.includes = includes + obj.source = source + obj.uselib = 'UNIQUE LIBSOUP GIO GTK SQLITE WEBKIT LIBXML' + obj.uselib_local = 'katze' + obj.inst_var = 'LIBDIR' + obj.inst_dir = 'midori' diff --git a/katze/wscript_build b/katze/wscript_build index ca4dddfb..aad466c1 100644 --- a/katze/wscript_build +++ b/katze/wscript_build @@ -2,12 +2,15 @@ # WAF build script for midori # This file is licensed under the terms of the expat license, see the file EXPAT. +import platform + obj = bld.create_obj ('cc', 'staticlib') obj.name = 'katze' obj.target = 'katze' obj.includes = '.' obj.find_sources_in_dirs ('.') -obj.uselib = 'LIBSOUP GTK LIBXML' +obj.uselib = 'GMODULE LIBSOUP GTK LIBXML' obj.inst_var = 0 -# FIXME: Do not install this static lib +if platform.architecture ()[0] == '64bit': + obj.env.append_value ('CCFLAGS', '-fPIC') diff --git a/midori/main.c b/midori/main.c index 5e0c119c..a1e5f214 100644 --- a/midori/main.c +++ b/midori/main.c @@ -19,6 +19,7 @@ #include "midori-websettings.h" #include "midori-browser.h" #include "midori-stock.h" +#include "midori-extension.h" #include "sokoke.h" #include "gjs.h" @@ -1033,9 +1034,6 @@ midori_browser_weak_notify_cb (MidoriBrowser* browser, G_CALLBACK (midori_browser_session_cb), session, NULL); } -gboolean -midori_view_single_process (gboolean enable); - int main (int argc, char** argv) @@ -1322,6 +1320,45 @@ main (int argc, "history", history, NULL); + /* Load extensions */ + gchar* extension_path; + GDir* extension_dir; + const gchar* filename; + + extension_path = g_build_filename (LIBDIR, PACKAGE_NAME, NULL); + if (g_module_supported ()) + extension_dir = g_dir_open (extension_path, 0, NULL); + else + extension_dir = NULL; + if (extension_dir) + { + while ((filename = g_dir_read_name (extension_dir))) + { + gchar* fullname; + GModule* module; + typedef MidoriExtension* (*extension_main_func)(MidoriApp* app); + extension_main_func extension_main; + + fullname = g_build_filename (extension_path, filename, NULL); + module = g_module_open (fullname, G_MODULE_BIND_LOCAL); + g_free (fullname); + if (!module) + { + g_warning ("%s", g_module_error ()); + continue; + } + ; + if (!g_module_symbol (module, "extension_main", + (gpointer) &extension_main)) + { + g_warning ("%s", g_module_error ()); + continue; + } + extension_main (app); + } + g_dir_close (extension_dir); + } + browser = g_object_new (MIDORI_TYPE_BROWSER, "settings", settings, "bookmarks", bookmarks, @@ -1354,36 +1391,8 @@ main (int argc, g_object_weak_ref (G_OBJECT (session), (GWeakNotify)(midori_browser_weak_notify_cb), browser); - /* Load extensions */ - js_context = gjs_global_context_new (); - /* FIXME: We want to honor system installed addons as well */ - gchar* addon_path = g_build_filename (g_get_user_data_dir (), PACKAGE_NAME, - "extensions", NULL); - GDir* addon_dir = g_dir_open (addon_path, 0, NULL); - if (addon_dir) - { - const gchar* filename; - while ((filename = g_dir_read_name (addon_dir))) - { - if (!g_str_has_prefix (filename, ".midori.js")) - continue; - - gchar* fullname = g_build_filename (addon_path, filename, NULL); - exception = NULL; - gjs_script_from_file (js_context, fullname, &exception); - if (exception) - /* FIXME: Do we want to print this somewhere else? */ - /* FIXME Convert the filename to UTF8 */ - printf ("%s - Exception: %s\n", filename, exception); - g_free (fullname); - } - g_dir_close (addon_dir); - } - gtk_main (); - JSGlobalContextRelease (js_context); - /* Save configuration files */ config_path = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL); diff --git a/midori/midori-extension.c b/midori/midori-extension.c new file mode 100644 index 00000000..b97f8eda --- /dev/null +++ b/midori/midori-extension.c @@ -0,0 +1,175 @@ +/* + Copyright (C) 2008 Christian Dywan + + 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-extension.h" + +#include + +G_DEFINE_TYPE (MidoriExtension, midori_extension, G_TYPE_OBJECT); + +struct _MidoriExtensionPrivate +{ + gchar* name; + gchar* description; + gchar* version; + gchar* authors; +}; + +enum +{ + PROP_0, + + PROP_NAME, + PROP_DESCRIPTION, + PROP_VERSION, + PROP_AUTHORS +}; + +static void +midori_extension_finalize (GObject* object); + +static void +midori_extension_set_property (GObject* object, + guint prop_id, + const GValue* value, + GParamSpec* pspec); + +static void +midori_extension_get_property (GObject* object, + guint prop_id, + GValue* value, + GParamSpec* pspec); + +static void +midori_extension_class_init (MidoriExtensionClass* class) +{ + GObjectClass* gobject_class; + GParamFlags flags; + + gobject_class = G_OBJECT_CLASS (class); + gobject_class->finalize = midori_extension_finalize; + gobject_class->set_property = midori_extension_set_property; + gobject_class->get_property = midori_extension_get_property; + + flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT; + + g_object_class_install_property (gobject_class, + PROP_NAME, + g_param_spec_string ( + "name", + "Name", + "The name of the extension", + NULL, + flags)); + + g_object_class_install_property (gobject_class, + PROP_DESCRIPTION, + g_param_spec_string ( + "description", + "Description", + "The description of the extension", + NULL, + flags)); + + g_object_class_install_property (gobject_class, + PROP_VERSION, + g_param_spec_string ( + "version", + "Version", + "The version of the extension", + NULL, + flags)); + + g_object_class_install_property (gobject_class, + PROP_AUTHORS, + g_param_spec_string ( + "authors", + "Authors", + "The authors of the extension", + NULL, + flags)); + + g_type_class_add_private (class, sizeof (MidoriExtensionPrivate)); +} + +static void +midori_extension_init (MidoriExtension* extension) +{ + extension->priv = G_TYPE_INSTANCE_GET_PRIVATE (extension, + MIDORI_TYPE_EXTENSION, MidoriExtensionPrivate); +} + +static void +midori_extension_finalize (GObject* object) +{ + MidoriExtension* extension = MIDORI_EXTENSION (object); + + katze_assign (extension->priv->name, NULL); + katze_assign (extension->priv->description, NULL); + katze_assign (extension->priv->version, NULL); + katze_assign (extension->priv->authors, NULL); +} + +static void +midori_extension_set_property (GObject* object, + guint prop_id, + const GValue* value, + GParamSpec* pspec) +{ + MidoriExtension* extension = MIDORI_EXTENSION (object); + + switch (prop_id) + { + case PROP_NAME: + katze_assign (extension->priv->name, g_value_dup_string (value)); + break; + case PROP_DESCRIPTION: + katze_assign (extension->priv->description, g_value_dup_string (value)); + break; + case PROP_VERSION: + katze_assign (extension->priv->version, g_value_dup_string (value)); + break; + case PROP_AUTHORS: + katze_assign (extension->priv->authors, g_value_dup_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +midori_extension_get_property (GObject* object, + guint prop_id, + GValue* value, + GParamSpec* pspec) +{ + MidoriExtension* extension = MIDORI_EXTENSION (object); + + switch (prop_id) + { + case PROP_NAME: + g_value_set_string (value, extension->priv->name); + break; + case PROP_DESCRIPTION: + g_value_set_string (value, extension->priv->description); + break; + case PROP_VERSION: + g_value_set_string (value, extension->priv->version); + break; + case PROP_AUTHORS: + g_value_set_string (value, extension->priv->authors); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} diff --git a/midori/midori-extension.h b/midori/midori-extension.h new file mode 100644 index 00000000..7bf9e2f6 --- /dev/null +++ b/midori/midori-extension.h @@ -0,0 +1,56 @@ +/* + Copyright (C) 2008 Christian Dywan + + 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. +*/ + +#ifndef __MIDORI_EXTENSION_H__ +#define __MIDORI_EXTENSION_H__ + +#include + +G_BEGIN_DECLS + +#define MIDORI_TYPE_EXTENSION \ + (midori_extension_get_type ()) +#define MIDORI_EXTENSION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_EXTENSION, MidoriExtension)) +#define MIDORI_EXTENSION_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_EXTENSION, MidoriExtensionClass)) +#define MIDORI_IS_EXTENSION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_EXTENSION)) +#define MIDORI_IS_EXTENSION_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_EXTENSION)) +#define MIDORI_EXTENSION_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_EXTENSION, MidoriExtensionClass)) + +typedef struct _MidoriExtension MidoriExtension; +typedef struct _MidoriExtensionClass MidoriExtensionClass; +typedef struct _MidoriExtensionPrivate MidoriExtensionPrivate; + +struct _MidoriExtension +{ + GObject parent_instance; + + MidoriExtensionPrivate* priv; +}; + +struct _MidoriExtensionClass +{ + GObjectClass parent_class; +}; + +GType +midori_extension_get_type (void); + +/* There is no API for MidoriExtension. Please use the + available properties and signals. */ + +G_END_DECLS + +#endif /* __MIDORI_EXTENSION_H__ */ diff --git a/midori/midori.h b/midori/midori.h new file mode 100644 index 00000000..997e37bd --- /dev/null +++ b/midori/midori.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2008 Christian Dywan + + 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. +*/ + +#ifndef __MIDORI_H__ +#define __MIDORI_H__ + +#include "midori-addons.h" +#include "midori-app.h" +#include "midori-browser.h" +#include "midori-console.h" +#include "midori-extension.h" +#include "midori-locationaction.h" +#include "midori-locationentry.h" +#include "midori-panel.h" +#include "midori-preferences.h" +#include "midori-searchaction.h" +#include "midori-source.h" +#include "midori-stock.h" +#include "midori-view.h" +#include "midori-websettings.h" + +#endif /* __MIDORI_H__ */ diff --git a/midori/wscript_build b/midori/wscript_build index a855e98a..dd6bac24 100644 --- a/midori/wscript_build +++ b/midori/wscript_build @@ -6,5 +6,5 @@ obj = bld.create_obj ('cc', 'program') obj.target = 'midori' obj.includes = '. ..' obj.find_sources_in_dirs ('.') -obj.uselib = 'UNIQUE LIBSOUP GIO GTK SQLITE WEBKIT LIBXML' +obj.uselib = 'UNIQUE LIBSOUP GMODULE GIO GTK SQLITE WEBKIT LIBXML' obj.uselib_local = 'katze' diff --git a/wscript b/wscript index 45dcf493..34f31a61 100644 --- a/wscript +++ b/wscript @@ -51,6 +51,12 @@ def configure (conf): nls = 'no' conf.check_message_custom ('localization', 'support', nls) + if Params.g_options.libdir == '': + libdir = os.path.join (conf.env['PREFIX'], 'lib') + else: + libdir = Params.g_options.libdir + conf.define ('LIBDIR', libdir) + # We support building without intltool # Therefore datadir may not have been defined if not conf.is_defined ('DATADIR'): @@ -100,6 +106,7 @@ def configure (conf): sqlite = 'no' conf.check_message_custom ('history database', 'support', sqlite) + conf.check_pkg ('gmodule-2.0', destvar='GMODULE', vnum='2.8.0', mandatory=False) conf.check_pkg ('gio-2.0', destvar='GIO', vnum='2.16.0', mandatory=False) conf.check_pkg ('gtk+-2.0', destvar='GTK', vnum='2.10.0', mandatory=True) conf.check_pkg ('webkit-1.0', destvar='WEBKIT', vnum='0.1', mandatory=True) @@ -141,7 +148,7 @@ def set_options (opt): opt.tool_options ('compiler_cc') opt.tool_options ('intltool') opt.add_option ('--docdir', type='string', default='', - help='documentation root', dest='docdir') + help='Documentation root', dest='docdir') opt.add_option ('--disable-docs', action='store_true', default=False, help='Disables user documentation', dest='disable_docs') @@ -161,6 +168,11 @@ def set_options (opt): opt.add_option ('--update-po', action='store_true', default=False, help='Update localization files', dest='update_po') + opt.add_option ('--libdir', type='string', default='', + help='Library root', dest='libdir') + opt.add_option ('--disable-extensions', action='store_true', default=False, + help='Disables building of extensions', dest='disable_extensions') + def build (bld): def mkdir (path): if not os.access (path, os.F_OK): @@ -174,6 +186,9 @@ def build (bld): bld.add_subdirs ('katze midori icons') + if not Params.g_options.disable_extensions: + bld.add_subdirs ('extensions') + install_files ('DOCDIR', '/' + APPNAME + '/', \ 'AUTHORS ChangeLog COPYING EXPAT README TRANSLATE')