xed/xedit/xedit-plugins-engine.c

862 lines
20 KiB
C
Raw Permalink Normal View History

2011-11-07 13:46:58 -06:00
/*
2016-01-25 08:13:49 -06:00
* xedit-plugins-engine.c
* This file is part of xedit
2011-11-07 13:46:58 -06:00
*
2011-11-07 18:10:16 -06:00
* Copyright (C) 2002-2005 Paolo Maggi
2011-11-07 13:46:58 -06:00
*
* 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 of the License, 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
2012-11-18 19:54:49 -06:00
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
2011-11-07 13:46:58 -06:00
*/
/*
2016-01-25 08:13:49 -06:00
* Modified by the xedit Team, 2002-2005. See the AUTHORS file for a
* list of people on the xedit Team.
2011-11-07 18:10:16 -06:00
* See the ChangeLog files for a list of changes.
2011-11-07 13:46:58 -06:00
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <glib/gi18n.h>
2016-01-25 08:13:49 -06:00
#include "xedit-plugins-engine.h"
#include "xedit-plugin-info-priv.h"
#include "xedit-plugin.h"
#include "xedit-debug.h"
#include "xedit-app.h"
#include "xedit-prefs-manager.h"
#include "xedit-plugin-loader.h"
#include "xedit-object-module.h"
#include "xedit-dirs.h"
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
#define XEDIT_PLUGINS_ENGINE_BASE_KEY "/apps/xedit/plugins"
#define XEDIT_PLUGINS_ENGINE_KEY XEDIT_PLUGINS_ENGINE_BASE_KEY "/active-plugins"
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
#define PLUGIN_EXT ".xedit-plugin"
2011-11-07 13:46:58 -06:00
#define LOADER_EXT G_MODULE_SUFFIX
typedef struct
{
2016-01-25 08:13:49 -06:00
XeditPluginLoader *loader;
XeditObjectModule *module;
2011-11-07 13:46:58 -06:00
} LoaderInfo;
/* Signals */
enum
{
ACTIVATE_PLUGIN,
DEACTIVATE_PLUGIN,
LAST_SIGNAL
};
2014-10-28 09:31:13 -05:00
static guint signals[LAST_SIGNAL] = { 0 };
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
G_DEFINE_TYPE(XeditPluginsEngine, xedit_plugins_engine, G_TYPE_OBJECT)
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
struct _XeditPluginsEnginePrivate
2011-11-07 13:46:58 -06:00
{
GList *plugin_list;
GHashTable *loaders;
gboolean activate_from_prefs;
};
2016-01-25 08:13:49 -06:00
XeditPluginsEngine *default_engine = NULL;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
static void xedit_plugins_engine_activate_plugin_real (XeditPluginsEngine *engine,
XeditPluginInfo *info);
static void xedit_plugins_engine_deactivate_plugin_real (XeditPluginsEngine *engine,
XeditPluginInfo *info);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
typedef gboolean (*LoadDirCallback)(XeditPluginsEngine *engine, const gchar *filename, gpointer userdata);
2011-11-07 13:46:58 -06:00
static gboolean
2016-01-25 08:13:49 -06:00
load_dir_real (XeditPluginsEngine *engine,
2011-11-07 13:46:58 -06:00
const gchar *dir,
const gchar *suffix,
LoadDirCallback callback,
gpointer userdata)
{
GError *error = NULL;
GDir *d;
const gchar *dirent;
gboolean ret = TRUE;
g_return_val_if_fail (dir != NULL, TRUE);
2016-01-25 08:13:49 -06:00
xedit_debug_message (DEBUG_PLUGINS, "DIR: %s", dir);
2011-11-07 13:46:58 -06:00
d = g_dir_open (dir, 0, &error);
if (!d)
{
g_warning ("%s", error->message);
g_error_free (error);
return TRUE;
}
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
while ((dirent = g_dir_read_name (d)))
{
gchar *filename;
if (!g_str_has_suffix (dirent, suffix))
continue;
filename = g_build_filename (dir, dirent, NULL);
ret = callback (engine, filename, userdata);
g_free (filename);
if (!ret)
break;
}
g_dir_close (d);
return ret;
}
static gboolean
2016-01-25 08:13:49 -06:00
load_plugin_info (XeditPluginsEngine *engine,
2011-11-07 13:46:58 -06:00
const gchar *filename,
gpointer userdata)
{
2016-01-25 08:13:49 -06:00
XeditPluginInfo *info;
2011-11-07 18:10:16 -06:00
2016-01-25 08:13:49 -06:00
info = _xedit_plugin_info_new (filename);
2011-11-07 13:46:58 -06:00
if (info == NULL)
return TRUE;
/* If a plugin with this name has already been loaded
* drop this one (user plugins override system plugins) */
2016-01-25 08:13:49 -06:00
if (xedit_plugins_engine_get_plugin_info (engine, xedit_plugin_info_get_module_name (info)) != NULL)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_debug_message (DEBUG_PLUGINS, "Two or more plugins named '%s'. "
2011-11-07 13:46:58 -06:00
"Only the first will be considered.\n",
2016-01-25 08:13:49 -06:00
xedit_plugin_info_get_module_name (info));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
_xedit_plugin_info_unref (info);
2011-11-07 13:46:58 -06:00
return TRUE;
}
engine->priv->plugin_list = g_list_prepend (engine->priv->plugin_list, info);
2016-01-25 08:13:49 -06:00
xedit_debug_message (DEBUG_PLUGINS, "Plugin %s loaded", info->name);
2011-11-07 13:46:58 -06:00
return TRUE;
}
static void
2016-01-25 08:13:49 -06:00
load_all_plugins (XeditPluginsEngine *engine)
2011-11-07 13:46:58 -06:00
{
gchar *plugin_dir;
const gchar *pdirs_env = NULL;
/* load user plugins */
2016-01-25 08:13:49 -06:00
plugin_dir = xedit_dirs_get_user_plugins_dir ();
2011-11-07 13:46:58 -06:00
if (g_file_test (plugin_dir, G_FILE_TEST_IS_DIR))
{
load_dir_real (engine,
plugin_dir,
PLUGIN_EXT,
load_plugin_info,
NULL);
}
g_free (plugin_dir);
/* load system plugins */
2016-01-25 08:13:49 -06:00
pdirs_env = g_getenv ("XEDIT_PLUGINS_PATH");
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_debug_message (DEBUG_PLUGINS, "XEDIT_PLUGINS_PATH=%s", pdirs_env);
2011-11-07 13:46:58 -06:00
if (pdirs_env != NULL)
{
gchar **pdirs;
gint i;
pdirs = g_strsplit (pdirs_env, G_SEARCHPATH_SEPARATOR_S, 0);
for (i = 0; pdirs[i] != NULL; i++)
{
if (!load_dir_real (engine,
pdirs[i],
PLUGIN_EXT,
load_plugin_info,
NULL))
{
break;
}
}
g_strfreev (pdirs);
}
else
{
2016-01-25 08:13:49 -06:00
plugin_dir = xedit_dirs_get_xedit_plugins_dir ();
2011-11-07 13:46:58 -06:00
load_dir_real (engine,
plugin_dir,
PLUGIN_EXT,
load_plugin_info,
NULL);
g_free (plugin_dir);
}
}
static guint
hash_lowercase (gconstpointer data)
{
gchar *lowercase;
guint ret;
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
lowercase = g_ascii_strdown ((const gchar *)data, -1);
ret = g_str_hash (lowercase);
g_free (lowercase);
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
return ret;
}
static gboolean
equal_lowercase (gconstpointer a, gconstpointer b)
{
return g_ascii_strcasecmp ((const gchar *)a, (const gchar *)b) == 0;
}
static void
loader_destroy (LoaderInfo *info)
{
if (!info)
return;
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
if (info->loader)
g_object_unref (info->loader);
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
g_free (info);
}
static void
2016-01-25 08:13:49 -06:00
add_loader (XeditPluginsEngine *engine,
2011-11-07 13:46:58 -06:00
const gchar *loader_id,
2016-01-25 08:13:49 -06:00
XeditObjectModule *module)
2011-11-07 13:46:58 -06:00
{
LoaderInfo *info;
info = g_new (LoaderInfo, 1);
info->loader = NULL;
info->module = module;
g_hash_table_insert (engine->priv->loaders, g_strdup (loader_id), info);
}
static void
2016-01-25 08:13:49 -06:00
xedit_plugins_engine_init (XeditPluginsEngine *engine)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_PLUGINS);
2011-11-07 13:46:58 -06:00
if (!g_module_supported ())
{
2016-01-25 08:13:49 -06:00
g_warning ("xedit is not able to initialize the plugins engine.");
2011-11-07 13:46:58 -06:00
return;
}
engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine,
2016-01-25 08:13:49 -06:00
XEDIT_TYPE_PLUGINS_ENGINE,
XeditPluginsEnginePrivate);
2011-11-07 13:46:58 -06:00
load_all_plugins (engine);
/* make sure that the first reactivation will read active plugins
from the prefs */
engine->priv->activate_from_prefs = TRUE;
/* mapping from loadername -> loader object */
engine->priv->loaders = g_hash_table_new_full (hash_lowercase,
equal_lowercase,
(GDestroyNotify)g_free,
(GDestroyNotify)loader_destroy);
}
static void
loader_garbage_collect (const char *id, LoaderInfo *info)
{
if (info->loader)
2016-01-25 08:13:49 -06:00
xedit_plugin_loader_garbage_collect (info->loader);
2011-11-07 13:46:58 -06:00
}
void
2016-01-25 08:13:49 -06:00
xedit_plugins_engine_garbage_collect (XeditPluginsEngine *engine)
2011-11-07 13:46:58 -06:00
{
g_hash_table_foreach (engine->priv->loaders,
(GHFunc) loader_garbage_collect,
NULL);
}
static void
2016-01-25 08:13:49 -06:00
xedit_plugins_engine_finalize (GObject *object)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditPluginsEngine *engine = XEDIT_PLUGINS_ENGINE (object);
2011-11-07 13:46:58 -06:00
GList *item;
2011-11-07 18:10:16 -06:00
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_PLUGINS);
2011-11-07 13:46:58 -06:00
/* Firs deactivate all plugins */
for (item = engine->priv->plugin_list; item; item = item->next)
{
2016-01-25 08:13:49 -06:00
XeditPluginInfo *info = XEDIT_PLUGIN_INFO (item->data);
2011-11-07 18:10:16 -06:00
2016-01-25 08:13:49 -06:00
if (xedit_plugin_info_is_active (info))
xedit_plugins_engine_deactivate_plugin_real (engine, info);
2011-11-07 13:46:58 -06:00
}
2011-11-07 18:10:16 -06:00
/* unref the loaders */
2011-11-07 13:46:58 -06:00
g_hash_table_destroy (engine->priv->loaders);
/* and finally free the infos */
for (item = engine->priv->plugin_list; item; item = item->next)
{
2016-01-25 08:13:49 -06:00
XeditPluginInfo *info = XEDIT_PLUGIN_INFO (item->data);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
_xedit_plugin_info_unref (info);
2011-11-07 13:46:58 -06:00
}
g_list_free (engine->priv->plugin_list);
2016-01-25 08:13:49 -06:00
G_OBJECT_CLASS (xedit_plugins_engine_parent_class)->finalize (object);
2011-11-07 13:46:58 -06:00
}
static void
2016-01-25 08:13:49 -06:00
xedit_plugins_engine_class_init (XeditPluginsEngineClass *klass)
2011-11-07 13:46:58 -06:00
{
GType the_type = G_TYPE_FROM_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
2016-01-25 08:13:49 -06:00
object_class->finalize = xedit_plugins_engine_finalize;
klass->activate_plugin = xedit_plugins_engine_activate_plugin_real;
klass->deactivate_plugin = xedit_plugins_engine_deactivate_plugin_real;
2011-11-07 13:46:58 -06:00
signals[ACTIVATE_PLUGIN] =
g_signal_new ("activate-plugin",
the_type,
G_SIGNAL_RUN_LAST,
2016-01-25 08:13:49 -06:00
G_STRUCT_OFFSET (XeditPluginsEngineClass, activate_plugin),
2011-11-07 13:46:58 -06:00
NULL, NULL,
g_cclosure_marshal_VOID__BOXED,
G_TYPE_NONE,
1,
2016-01-25 08:13:49 -06:00
XEDIT_TYPE_PLUGIN_INFO | G_SIGNAL_TYPE_STATIC_SCOPE);
2011-11-07 13:46:58 -06:00
signals[DEACTIVATE_PLUGIN] =
g_signal_new ("deactivate-plugin",
the_type,
G_SIGNAL_RUN_LAST,
2016-01-25 08:13:49 -06:00
G_STRUCT_OFFSET (XeditPluginsEngineClass, deactivate_plugin),
2011-11-07 13:46:58 -06:00
NULL, NULL,
g_cclosure_marshal_VOID__BOXED,
G_TYPE_NONE,
1,
2016-01-25 08:13:49 -06:00
XEDIT_TYPE_PLUGIN_INFO | G_SIGNAL_TYPE_STATIC_SCOPE);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_type_class_add_private (klass, sizeof (XeditPluginsEnginePrivate));
2011-11-07 13:46:58 -06:00
}
static gboolean
2016-01-25 08:13:49 -06:00
load_loader (XeditPluginsEngine *engine,
2011-11-07 13:46:58 -06:00
const gchar *filename,
gpointer data)
{
2016-01-25 08:13:49 -06:00
XeditObjectModule *module;
2011-11-07 13:46:58 -06:00
gchar *base;
gchar *path;
const gchar *id;
GType type;
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
/* try to load in the module */
path = g_path_get_dirname (filename);
base = g_path_get_basename (filename);
/* for now they are all resident */
2016-01-25 08:13:49 -06:00
module = xedit_object_module_new (base,
2011-11-07 13:46:58 -06:00
path,
2016-01-25 08:13:49 -06:00
"register_xedit_plugin_loader",
2011-11-07 13:46:58 -06:00
TRUE);
g_free (base);
g_free (path);
/* make sure to load the type definition */
if (!g_type_module_use (G_TYPE_MODULE (module)))
{
g_object_unref (module);
g_warning ("Plugin loader module `%s' could not be loaded", filename);
return TRUE;
}
2011-11-07 18:10:16 -06:00
/* get the exported type and check the name as exported by the
2011-11-07 13:46:58 -06:00
* loader interface */
2016-01-25 08:13:49 -06:00
type = xedit_object_module_get_object_type (module);
id = xedit_plugin_loader_type_get_id (type);
2011-11-07 18:10:16 -06:00
add_loader (engine, id, module);
2011-11-07 13:46:58 -06:00
g_type_module_unuse (G_TYPE_MODULE (module));
return TRUE;
}
static void
ensure_loader (LoaderInfo *info)
{
if (info->loader == NULL && info->module != NULL)
{
/* create a new loader object */
2016-01-25 08:13:49 -06:00
XeditPluginLoader *loader;
loader = (XeditPluginLoader *)xedit_object_module_new_object (info->module, NULL);
2011-11-07 18:10:16 -06:00
2016-01-25 08:13:49 -06:00
if (loader == NULL || !XEDIT_IS_PLUGIN_LOADER (loader))
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
g_warning ("Loader object is not a valid XeditPluginLoader instance");
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
if (loader != NULL && G_IS_OBJECT (loader))
g_object_unref (loader);
}
else
{
info->loader = loader;
}
}
}
2016-01-25 08:13:49 -06:00
static XeditPluginLoader *
get_plugin_loader (XeditPluginsEngine *engine, XeditPluginInfo *info)
2011-11-07 13:46:58 -06:00
{
const gchar *loader_id;
LoaderInfo *loader_info;
loader_id = info->loader;
loader_info = (LoaderInfo *)g_hash_table_lookup (
2011-11-07 18:10:16 -06:00
engine->priv->loaders,
2011-11-07 13:46:58 -06:00
loader_id);
if (loader_info == NULL)
{
gchar *loader_dir;
2016-01-25 08:13:49 -06:00
loader_dir = xedit_dirs_get_xedit_plugin_loaders_dir ();
2011-11-07 13:46:58 -06:00
2011-11-07 18:10:16 -06:00
/* loader could not be found in the hash, try to find it by
2011-11-07 13:46:58 -06:00
scanning */
2011-11-07 18:10:16 -06:00
load_dir_real (engine,
2011-11-07 13:46:58 -06:00
loader_dir,
LOADER_EXT,
(LoadDirCallback)load_loader,
NULL);
g_free (loader_dir);
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
loader_info = (LoaderInfo *)g_hash_table_lookup (
2011-11-07 18:10:16 -06:00
engine->priv->loaders,
2011-11-07 13:46:58 -06:00
loader_id);
}
if (loader_info == NULL)
{
/* cache non-existent so we don't scan again */
add_loader (engine, loader_id, NULL);
return NULL;
}
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
ensure_loader (loader_info);
return loader_info->loader;
}
2016-01-25 08:13:49 -06:00
XeditPluginsEngine *
xedit_plugins_engine_get_default (void)
2011-11-07 13:46:58 -06:00
{
if (default_engine != NULL)
return default_engine;
2016-01-25 08:13:49 -06:00
default_engine = XEDIT_PLUGINS_ENGINE (g_object_new (XEDIT_TYPE_PLUGINS_ENGINE, NULL));
2011-11-07 13:46:58 -06:00
g_object_add_weak_pointer (G_OBJECT (default_engine),
(gpointer) &default_engine);
return default_engine;
}
const GList *
2016-01-25 08:13:49 -06:00
xedit_plugins_engine_get_plugin_list (XeditPluginsEngine *engine)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_PLUGINS);
2011-11-07 13:46:58 -06:00
return engine->priv->plugin_list;
}
static gint
2016-01-25 08:13:49 -06:00
compare_plugin_info_and_name (XeditPluginInfo *info,
2011-11-07 13:46:58 -06:00
const gchar *module_name)
{
2016-01-25 08:13:49 -06:00
return strcmp (xedit_plugin_info_get_module_name (info), module_name);
2011-11-07 13:46:58 -06:00
}
2016-01-25 08:13:49 -06:00
XeditPluginInfo *
xedit_plugins_engine_get_plugin_info (XeditPluginsEngine *engine,
2011-11-07 13:46:58 -06:00
const gchar *name)
{
GList *l = g_list_find_custom (engine->priv->plugin_list,
name,
(GCompareFunc) compare_plugin_info_and_name);
2016-01-25 08:13:49 -06:00
return l == NULL ? NULL : (XeditPluginInfo *) l->data;
2011-11-07 13:46:58 -06:00
}
static void
2016-01-25 08:13:49 -06:00
save_active_plugin_list (XeditPluginsEngine *engine)
2011-11-07 13:46:58 -06:00
{
GSList *active_plugins = NULL;
GList *l;
for (l = engine->priv->plugin_list; l != NULL; l = l->next)
{
2016-01-25 08:13:49 -06:00
XeditPluginInfo *info = (XeditPluginInfo *) l->data;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
if (xedit_plugin_info_is_active (info))
2011-11-07 13:46:58 -06:00
{
active_plugins = g_slist_prepend (active_plugins,
2016-01-25 08:13:49 -06:00
(gpointer)xedit_plugin_info_get_module_name (info));
2011-11-07 13:46:58 -06:00
}
}
2016-01-25 08:13:49 -06:00
xedit_prefs_manager_set_active_plugins (active_plugins);
2011-11-07 13:46:58 -06:00
g_slist_free (active_plugins);
}
static gboolean
2016-01-25 08:13:49 -06:00
load_plugin (XeditPluginsEngine *engine,
XeditPluginInfo *info)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditPluginLoader *loader;
2011-11-07 13:46:58 -06:00
gchar *path;
2016-01-25 08:13:49 -06:00
if (xedit_plugin_info_is_active (info))
2011-11-07 13:46:58 -06:00
return TRUE;
2011-11-07 18:10:16 -06:00
2016-01-25 08:13:49 -06:00
if (!xedit_plugin_info_is_available (info))
2011-11-07 13:46:58 -06:00
return FALSE;
loader = get_plugin_loader (engine, info);
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
if (loader == NULL)
{
g_warning ("Could not find loader `%s' for plugin `%s'", info->loader, info->name);
info->available = FALSE;
return FALSE;
}
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
path = g_path_get_dirname (info->file);
g_return_val_if_fail (path != NULL, FALSE);
2016-01-25 08:13:49 -06:00
info->plugin = xedit_plugin_loader_load (loader, info, path);
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
g_free (path);
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
if (info->plugin == NULL)
{
g_warning ("Error loading plugin '%s'", info->name);
info->available = FALSE;
return FALSE;
}
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
return TRUE;
}
static void
2016-01-25 08:13:49 -06:00
xedit_plugins_engine_activate_plugin_real (XeditPluginsEngine *engine,
XeditPluginInfo *info)
2011-11-07 13:46:58 -06:00
{
const GList *wins;
if (!load_plugin (engine, info))
return;
2016-01-25 08:13:49 -06:00
for (wins = xedit_app_get_windows (xedit_app_get_default ());
2011-11-07 13:46:58 -06:00
wins != NULL;
wins = wins->next)
{
2016-01-25 08:13:49 -06:00
xedit_plugin_activate (info->plugin, XEDIT_WINDOW (wins->data));
2011-11-07 13:46:58 -06:00
}
}
gboolean
2016-01-25 08:13:49 -06:00
xedit_plugins_engine_activate_plugin (XeditPluginsEngine *engine,
XeditPluginInfo *info)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_PLUGINS);
2011-11-07 13:46:58 -06:00
g_return_val_if_fail (info != NULL, FALSE);
2016-01-25 08:13:49 -06:00
if (!xedit_plugin_info_is_available (info))
2011-11-07 13:46:58 -06:00
return FALSE;
2011-11-07 18:10:16 -06:00
2016-01-25 08:13:49 -06:00
if (xedit_plugin_info_is_active (info))
2011-11-07 13:46:58 -06:00
return TRUE;
g_signal_emit (engine, signals[ACTIVATE_PLUGIN], 0, info);
2016-01-25 08:13:49 -06:00
if (xedit_plugin_info_is_active (info))
2011-11-07 13:46:58 -06:00
save_active_plugin_list (engine);
2016-01-25 08:13:49 -06:00
return xedit_plugin_info_is_active (info);
2011-11-07 13:46:58 -06:00
}
static void
2016-01-25 08:13:49 -06:00
call_plugin_deactivate (XeditPlugin *plugin,
XeditWindow *window)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_plugin_deactivate (plugin, window);
2011-11-07 13:46:58 -06:00
/* ensure update of ui manager, because we suspect it does something
with expected static strings in the type module (when unloaded the
strings don't exist anymore, and ui manager updates in an idle
func) */
2016-01-25 08:13:49 -06:00
gtk_ui_manager_ensure_update (xedit_window_get_ui_manager (window));
2011-11-07 13:46:58 -06:00
}
static void
2016-01-25 08:13:49 -06:00
xedit_plugins_engine_deactivate_plugin_real (XeditPluginsEngine *engine,
XeditPluginInfo *info)
2011-11-07 13:46:58 -06:00
{
const GList *wins;
2016-01-25 08:13:49 -06:00
XeditPluginLoader *loader;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
if (!xedit_plugin_info_is_active (info) ||
!xedit_plugin_info_is_available (info))
2011-11-07 13:46:58 -06:00
return;
2016-01-25 08:13:49 -06:00
for (wins = xedit_app_get_windows (xedit_app_get_default ());
2011-11-07 13:46:58 -06:00
wins != NULL;
wins = wins->next)
{
2016-01-25 08:13:49 -06:00
call_plugin_deactivate (info->plugin, XEDIT_WINDOW (wins->data));
2011-11-07 13:46:58 -06:00
}
/* first unref the plugin (the loader still has one) */
g_object_unref (info->plugin);
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
/* find the loader and tell it to gc and unload the plugin */
loader = get_plugin_loader (engine, info);
2011-11-07 18:10:16 -06:00
2016-01-25 08:13:49 -06:00
xedit_plugin_loader_garbage_collect (loader);
xedit_plugin_loader_unload (loader, info);
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
info->plugin = NULL;
}
gboolean
2016-01-25 08:13:49 -06:00
xedit_plugins_engine_deactivate_plugin (XeditPluginsEngine *engine,
XeditPluginInfo *info)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_PLUGINS);
2011-11-07 13:46:58 -06:00
g_return_val_if_fail (info != NULL, FALSE);
2016-01-25 08:13:49 -06:00
if (!xedit_plugin_info_is_active (info))
2011-11-07 13:46:58 -06:00
return TRUE;
g_signal_emit (engine, signals[DEACTIVATE_PLUGIN], 0, info);
2016-01-25 08:13:49 -06:00
if (!xedit_plugin_info_is_active (info))
2011-11-07 13:46:58 -06:00
save_active_plugin_list (engine);
2016-01-25 08:13:49 -06:00
return !xedit_plugin_info_is_active (info);
2011-11-07 13:46:58 -06:00
}
void
2016-01-25 08:13:49 -06:00
xedit_plugins_engine_activate_plugins (XeditPluginsEngine *engine,
XeditWindow *window)
2011-11-07 13:46:58 -06:00
{
GSList *active_plugins = NULL;
GList *pl;
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_PLUGINS);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_PLUGINS_ENGINE (engine));
g_return_if_fail (XEDIT_IS_WINDOW (window));
2011-11-07 13:46:58 -06:00
2013-01-24 14:03:53 -06:00
/* the first time, we get the 'active' plugins from GSettings */
2011-11-07 13:46:58 -06:00
if (engine->priv->activate_from_prefs)
{
2016-01-25 08:13:49 -06:00
active_plugins = xedit_prefs_manager_get_active_plugins ();
2011-11-07 13:46:58 -06:00
}
for (pl = engine->priv->plugin_list; pl; pl = pl->next)
{
2016-01-25 08:13:49 -06:00
XeditPluginInfo *info = (XeditPluginInfo*)pl->data;
2011-11-07 18:10:16 -06:00
if (engine->priv->activate_from_prefs &&
2011-11-07 13:46:58 -06:00
g_slist_find_custom (active_plugins,
2016-01-25 08:13:49 -06:00
xedit_plugin_info_get_module_name (info),
2011-11-07 13:46:58 -06:00
(GCompareFunc)strcmp) == NULL)
continue;
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
/* If plugin is not active, don't try to activate/load it */
2011-11-07 18:10:16 -06:00
if (!engine->priv->activate_from_prefs &&
2016-01-25 08:13:49 -06:00
!xedit_plugin_info_is_active (info))
2011-11-07 13:46:58 -06:00
continue;
if (load_plugin (engine, info))
2016-01-25 08:13:49 -06:00
xedit_plugin_activate (info->plugin,
2011-11-07 13:46:58 -06:00
window);
}
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
if (engine->priv->activate_from_prefs)
{
g_slist_foreach (active_plugins, (GFunc) g_free, NULL);
g_slist_free (active_plugins);
engine->priv->activate_from_prefs = FALSE;
}
2011-11-07 18:10:16 -06:00
2016-01-25 08:13:49 -06:00
xedit_debug_message (DEBUG_PLUGINS, "End");
2011-11-07 13:46:58 -06:00
/* also call update_ui after activation */
2016-01-25 08:13:49 -06:00
xedit_plugins_engine_update_plugins_ui (engine, window);
2011-11-07 13:46:58 -06:00
}
void
2016-01-25 08:13:49 -06:00
xedit_plugins_engine_deactivate_plugins (XeditPluginsEngine *engine,
XeditWindow *window)
2011-11-07 13:46:58 -06:00
{
GList *pl;
2011-11-07 18:10:16 -06:00
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_PLUGINS);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_PLUGINS_ENGINE (engine));
g_return_if_fail (XEDIT_IS_WINDOW (window));
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
for (pl = engine->priv->plugin_list; pl; pl = pl->next)
{
2016-01-25 08:13:49 -06:00
XeditPluginInfo *info = (XeditPluginInfo*)pl->data;
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
/* check if the plugin is actually active */
2016-01-25 08:13:49 -06:00
if (!xedit_plugin_info_is_active (info))
2011-11-07 13:46:58 -06:00
continue;
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
/* call deactivate for the plugin for this window */
2016-01-25 08:13:49 -06:00
xedit_plugin_deactivate (info->plugin, window);
2011-11-07 13:46:58 -06:00
}
2011-11-07 18:10:16 -06:00
2016-01-25 08:13:49 -06:00
xedit_debug_message (DEBUG_PLUGINS, "End");
2011-11-07 13:46:58 -06:00
}
void
2016-01-25 08:13:49 -06:00
xedit_plugins_engine_update_plugins_ui (XeditPluginsEngine *engine,
XeditWindow *window)
2011-11-07 13:46:58 -06:00
{
GList *pl;
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_PLUGINS);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_PLUGINS_ENGINE (engine));
g_return_if_fail (XEDIT_IS_WINDOW (window));
2011-11-07 13:46:58 -06:00
/* call update_ui for all active plugins */
for (pl = engine->priv->plugin_list; pl; pl = pl->next)
{
2016-01-25 08:13:49 -06:00
XeditPluginInfo *info = (XeditPluginInfo*)pl->data;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
if (!xedit_plugin_info_is_active (info))
2011-11-07 13:46:58 -06:00
continue;
2011-11-07 18:10:16 -06:00
2016-01-25 08:13:49 -06:00
xedit_debug_message (DEBUG_PLUGINS, "Updating UI of %s", info->name);
xedit_plugin_update_ui (info->plugin, window);
2011-11-07 13:46:58 -06:00
}
}
2011-11-07 18:10:16 -06:00
void
2016-01-25 08:13:49 -06:00
xedit_plugins_engine_configure_plugin (XeditPluginsEngine *engine,
XeditPluginInfo *info,
2011-11-07 13:46:58 -06:00
GtkWindow *parent)
{
GtkWidget *conf_dlg;
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
GtkWindowGroup *wg;
2011-11-07 18:10:16 -06:00
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_PLUGINS);
2011-11-07 13:46:58 -06:00
g_return_if_fail (info != NULL);
2016-01-25 08:13:49 -06:00
conf_dlg = xedit_plugin_create_configure_dialog (info->plugin);
2011-11-07 13:46:58 -06:00
g_return_if_fail (conf_dlg != NULL);
gtk_window_set_transient_for (GTK_WINDOW (conf_dlg),
parent);
wg = gtk_window_get_group (parent);
if (wg == NULL)
{
wg = gtk_window_group_new ();
gtk_window_group_add_window (wg, parent);
}
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
gtk_window_group_add_window (wg,
GTK_WINDOW (conf_dlg));
2011-11-07 18:10:16 -06:00
gtk_window_set_modal (GTK_WINDOW (conf_dlg), TRUE);
2011-11-07 13:46:58 -06:00
gtk_widget_show (conf_dlg);
}
2011-11-07 18:10:16 -06:00
void
2016-01-25 08:13:49 -06:00
xedit_plugins_engine_active_plugins_changed (XeditPluginsEngine *engine)
2011-11-07 13:46:58 -06:00
{
gboolean to_activate;
GSList *active_plugins;
GList *pl;
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_PLUGINS);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
active_plugins = xedit_prefs_manager_get_active_plugins ();
2011-11-07 13:46:58 -06:00
for (pl = engine->priv->plugin_list; pl; pl = pl->next)
{
2016-01-25 08:13:49 -06:00
XeditPluginInfo *info = (XeditPluginInfo*)pl->data;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
if (!xedit_plugin_info_is_available (info))
2011-11-07 13:46:58 -06:00
continue;
to_activate = (g_slist_find_custom (active_plugins,
2016-01-25 08:13:49 -06:00
xedit_plugin_info_get_module_name (info),
2011-11-07 13:46:58 -06:00
(GCompareFunc)strcmp) != NULL);
2016-01-25 08:13:49 -06:00
if (!xedit_plugin_info_is_active (info) && to_activate)
2011-11-07 13:46:58 -06:00
g_signal_emit (engine, signals[ACTIVATE_PLUGIN], 0, info);
2016-01-25 08:13:49 -06:00
else if (xedit_plugin_info_is_active (info) && !to_activate)
2011-11-07 13:46:58 -06:00
g_signal_emit (engine, signals[DEACTIVATE_PLUGIN], 0, info);
}
g_slist_foreach (active_plugins, (GFunc) g_free, NULL);
g_slist_free (active_plugins);
}
void
2016-01-25 08:13:49 -06:00
xedit_plugins_engine_rescan_plugins (XeditPluginsEngine *engine)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_PLUGINS);
2011-11-07 18:10:16 -06:00
2011-11-07 13:46:58 -06:00
load_all_plugins (engine);
}