Introduce a C extension interface

This commit is contained in:
Christian Dywan 2008-11-18 02:07:53 +01:00
parent 33804965a1
commit 3cd50f419b
9 changed files with 355 additions and 37 deletions

4
README
View file

@ -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.

30
extensions/wscript_build Normal file
View file

@ -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'

View 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')

View 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);

175
midori/midori-extension.c Normal file
View file

@ -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;
}
}

56
midori/midori-extension.h Normal file
View file

@ -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__ */

30
midori/midori.h Normal file
View file

@ -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__ */

View 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'

17
wscript
View file

@ -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')