]> spindle.queued.net Git - midori/commitdiff
Introduce a C extension interface
authorChristian Dywan <christian@twotoasts.de>
Tue, 18 Nov 2008 01:07:53 +0000 (02:07 +0100)
committerChristian Dywan <christian@twotoasts.de>
Tue, 18 Nov 2008 01:07:53 +0000 (02:07 +0100)
README
extensions/wscript_build [new file with mode: 0644]
katze/wscript_build
midori/main.c
midori/midori-extension.c [new file with mode: 0644]
midori/midori-extension.h [new file with mode: 0644]
midori/midori.h [new file with mode: 0644]
midori/wscript_build
wscript

diff --git a/README b/README
index 63d716d5c4df03572a0eed2c68913b88a75858a2..62995981d6b903f1c1d95dd1c37435f561122722 100644 (file)
--- 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 (file)
index 0000000..4b75ea7
--- /dev/null
@@ -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'
index ca4dddfbdeead1d5b4dfa5aa3991d668f667d524..aad466c1c85f178054b1ead8ada234275490f3d9 100644 (file)
@@ -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')
index 5e0c119c7152b57345094c83c1724ac19d26ac37..a1e5f214c7f82c98ff40072b0e1a18a1271b4b4f 100644 (file)
@@ -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 (file)
index 0000000..b97f8ed
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ 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 <katze/katze.h>
+
+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 (file)
index 0000000..7bf9e2f
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ 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 <glib-object.h>
+
+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 (file)
index 0000000..997e37b
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ 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__ */
index a855e98a1ab2492f9b0cecc94931ffce08650a5f..dd6bac24b86692a3a27e60f35ccf1cef8a0a80ed 100644 (file)
@@ -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 45dcf493cc65288d4394550303389cc67e91adaa..34f31a61c955d6e71b45fb0392f48859214749f6 100644 (file)
--- 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')