/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ /* * Copyright © 2009, Robert Carr * * 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 Free Software Foundation; either version 2, 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include #include #include "ephy-seed-extension.h" #include "ephy-extension.h" #include "ephy-window.h" #include "ephy-file-helpers.h" #include "ephy-debug.h" SeedEngine * global_eng = NULL; static void ephy_seed_extension_iface_init (EphyExtensionIface *iface); #define EPHY_SEED_EXTENSION_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_SEED_EXTENSION, EphySeedExtensionPrivate)) struct _EphySeedExtensionPrivate { char *filename; SeedContext ctx; SeedObject obj; }; enum { PROP_0, PROP_FILENAME }; static void ephy_seed_extension_init (EphySeedExtension *extension) { LOG ("EphySeedExtension initialising"); extension->priv = EPHY_SEED_EXTENSION_GET_PRIVATE (extension); } static void call_seed_func (EphyExtension *extension, const char *func_name, EphyWindow *window, EphyEmbed *embed) /* HACK: tab may be NULL */ { EphySeedExtension *seed_ext; EphySeedExtensionPrivate *priv; SeedObject function; SeedException exception = NULL; SeedValue args[2]; seed_ext = EPHY_SEED_EXTENSION (extension); priv = seed_ext->priv; if (priv->obj == NULL || !seed_value_is_object (priv->ctx, priv->obj)) return; function = seed_object_get_property (priv->ctx, priv->obj, func_name); if (!seed_value_is_function (priv->ctx, function)) return; args[0] = seed_value_from_object (priv->ctx, G_OBJECT(window), exception); if (embed != NULL) args[1] = seed_value_from_object (priv->ctx, G_OBJECT(embed), exception); seed_object_call (global_eng->context, function, NULL, embed == NULL ? 1 : 2, args, &exception); if (exception) g_warning ("seed_exception: %s \n", seed_exception_to_string (priv->ctx, exception)); } static void impl_attach_tab (EphyExtension *extension, EphyWindow *window, EphyEmbed *embed) { call_seed_func (extension, "attach_tab", window, embed); } static void impl_detach_tab (EphyExtension *extension, EphyWindow *window, EphyEmbed *embed) { call_seed_func (extension, "detach_tab", window, embed); seed_context_collect (global_eng->context); } static void impl_attach_window (EphyExtension *extension, EphyWindow *window) { call_seed_func (extension, "attach_window", window, NULL); } static void impl_detach_window (EphyExtension *extension, EphyWindow *window) { call_seed_func (extension, "detach_window", window, NULL); seed_context_collect (global_eng->context); } static void ephy_seed_extension_iface_init (EphyExtensionIface *iface) { iface->attach_tab = impl_attach_tab; iface->detach_tab = impl_detach_tab; iface->attach_window = impl_attach_window; iface->detach_window = impl_detach_window; } G_DEFINE_TYPE_WITH_CODE (EphySeedExtension, ephy_seed_extension, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (EPHY_TYPE_EXTENSION, ephy_seed_extension_iface_init)) static gchar * ephy_seed_extension_get_file (const gchar * name) { gchar *dot_path, *system_path, *dirname, *filename; filename = g_strconcat (name, ".js", NULL); dot_path = g_build_filename (ephy_dot_dir(), "extensions", filename, NULL); if (g_file_test (dot_path, G_FILE_TEST_EXISTS)) { g_free(filename); return dot_path; } g_free (dot_path); system_path = g_build_filename (EXTENSIONS_DIR, filename, NULL); g_free (filename); if (g_file_test (system_path, G_FILE_TEST_EXISTS)) { return system_path; } g_free (system_path); dirname = g_path_get_dirname (name); if (g_path_is_absolute (dirname)) { g_free (dirname); return g_strdup (name); } g_free (dirname); return NULL; } static GObject * ephy_seed_extension_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_params) { SeedScript *script = NULL; GObject *object; EphySeedExtension *ext; object = G_OBJECT_CLASS (ephy_seed_extension_parent_class)->constructor (type, n_construct_properties, construct_params); ext = EPHY_SEED_EXTENSION (object); if (ext->priv->filename) script = seed_script_new_from_file (global_eng->context, ext->priv->filename); ext->priv->ctx = seed_context_create (global_eng->group, NULL); ext->priv->obj = seed_evaluate (global_eng->context, script, NULL); seed_value_protect (ext->priv->ctx, ext->priv->obj); if (seed_script_exception (script)) g_warning ("seed_exception: %s", seed_exception_to_string (global_eng->context, seed_script_exception (script))); return object; } static void ephy_seed_extension_finalize (GObject *object) { EphySeedExtension *extension = EPHY_SEED_EXTENSION (object); seed_value_unprotect (extension->priv->ctx, extension->priv->obj); seed_context_unref (extension->priv->ctx); G_OBJECT_CLASS (ephy_seed_extension_parent_class)->finalize (object); } static void ephy_seed_extension_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { /* no readable properties */ g_return_if_reached (); } static void ephy_seed_extension_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { EphySeedExtension *ext = EPHY_SEED_EXTENSION (object); switch (prop_id) { case PROP_FILENAME: ext->priv->filename = ephy_seed_extension_get_file (g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void ephy_seed_extension_class_init (EphySeedExtensionClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = ephy_seed_extension_finalize; object_class->constructor = ephy_seed_extension_constructor; object_class->get_property = ephy_seed_extension_get_property; object_class->set_property = ephy_seed_extension_set_property; g_object_class_install_property (object_class, PROP_FILENAME, g_param_spec_string ("filename", "Filename", "Filename", NULL, G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_CONSTRUCT_ONLY)); g_type_class_add_private (object_class, sizeof (EphySeedExtensionPrivate)); if (global_eng == NULL) { global_eng = seed_init (NULL, NULL); seed_simple_evaluate (global_eng->context, "Gtk = imports.gi.Gtk;" "Epiphany = imports.gi.Epiphany;", NULL); } }