3
* Copyright (C) 2009 Christian Hergert <chris@dronelabs.com>
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Library General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Library General Public License for more details.
15
* You should have received a copy of the GNU Library General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
29
#include "ethos-error.h"
30
#include "ethos-manager.h"
31
#include "ethos-plugin-loader.h"
32
#include "ethos-plugin-info-private.h"
35
* SECTION:ethos-manager
36
* @title: EthosManager
37
* @short_description: plugin management during runtime
39
* The #EthosManager is responsible for managing plugins during runtime. It can be used to
40
* load and unload plugins as well as configure where and how plugins should be loaded.
42
* During runtime, the app_name and plugin_dirs should both be set. The app_name is used
43
* to derive the plugin filenames and how to parse them. The plugin_dirs are used to locate
47
struct _EthosManagerPrivate
52
GList *plugin_loaders;
54
GHashTable *plugin_info_hash;
56
GHashTable *deps_cache;
67
G_DEFINE_TYPE (EthosManager, ethos_manager, G_TYPE_OBJECT);
69
static guint signals[LAST_SIGNAL] = {0,};
74
* Creates a new instance of #EthosManager. There should only be one of these
75
* created per process.
77
* Return value: the newly created #EthosManager instance.
80
ethos_manager_new (void)
82
return g_object_new (ETHOS_TYPE_MANAGER, NULL);
86
* ethos_manager_new_full:
87
* @app_name: The name of the application (Capitalized)
88
* @plugin_dirs: An array of strings containing directories to locate plugins
90
* Creates a new #EthosManager instance and sets the application name and
91
* plugin directories to traverse to locate plugins.
93
* Return value: The newly created #EthosManager instance.
96
ethos_manager_new_full (const gchar *app_name,
99
EthosManager *manager;
101
manager = ethos_manager_new ();
102
ethos_manager_set_app_name (manager, app_name);
103
ethos_manager_set_plugin_dirs (manager, plugin_dirs);
108
static EthosPluginLoader*
109
ethos_manager_create_plugin_loader (EthosManager *manager,
110
const gchar *filename)
112
EthosPluginLoader* (*create_plugin_loader) (void) = NULL;
113
EthosPluginLoader *plugin_loader;
116
module = g_module_open (filename, G_MODULE_BIND_LAZY);
119
g_warning ("%s: %s", filename, g_module_error ());
123
if (!g_module_symbol (module, "ethos_plugin_loader_register",
124
(gpointer*)&create_plugin_loader)) {
125
g_warning ("%s: %s", filename, g_module_error ());
126
if (!g_module_close (module))
127
g_warning ("%s: %s", filename, g_module_error ());
131
if (create_plugin_loader == NULL) {
132
g_warning ("%s: ethos_plugin_loader_register is NULL", filename);
133
if (!g_module_close (module))
134
g_warning ("%s: %s", filename, g_module_error ());
138
plugin_loader = create_plugin_loader ();
140
if (plugin_loader && !ETHOS_IS_PLUGIN_LOADER (plugin_loader)) {
141
g_warning ("%s: ethos_plugin_loader_register returned "
142
"something other than an EthosPluginLoader",
144
if (!g_module_close (module))
145
g_warning ("%s: %s", filename, g_module_error ());
149
ethos_plugin_loader_initialize (plugin_loader, manager);
151
return plugin_loader;
155
* ethos_manager_discover_plugin_loaders:
156
* @manager: An #EthosManager
158
* Discovers the available plugin loaders.
160
* Return value: A #GList containing #EthosPluginLoader instances.
163
ethos_manager_discover_plugin_loaders (EthosManager *manager)
165
EthosManagerPrivate *priv;
167
const gchar *loaders_dir;
168
const gchar *filename;
170
GList *loaders = NULL;
171
EthosPluginLoader *loader;
173
g_return_val_if_fail (ETHOS_IS_MANAGER (manager), NULL);
175
priv = manager->priv;
177
if (g_getenv ("ETHOS_PLUGIN_LOADERS_DIR") != NULL)
178
loaders_dir = g_getenv ("ETHOS_PLUGIN_LOADERS_DIR");
180
loaders_dir = ETHOS_PLUGIN_LOADERS_DIR;
182
if (!g_file_test (loaders_dir, G_FILE_TEST_IS_DIR)) {
183
g_warning ("plugin-loaders directory not found: %s",
188
if (!(dir = g_dir_open (loaders_dir, 0, NULL))) {
189
g_warning ("plugin-loaders directory not accessable: %s",
194
while (NULL != (filename = g_dir_read_name (dir))) {
195
if (g_str_has_suffix (filename, "." G_MODULE_SUFFIX)) {
196
abspath = g_build_filename (loaders_dir, filename, NULL);
197
loader = ethos_manager_create_plugin_loader (manager, abspath);
199
loaders = g_list_prepend (loaders, loader);
210
* ethos_manager_discover_plugins:
211
* @manager: An #EthosManager
213
* Discovers all of the plugins found within the plugin directories.
215
* Return value: A #GList containing #EthosPluginInfo instances that were
216
* created from plugin files in the plugin directories.
219
ethos_manager_discover_plugins (EthosManager *manager)
221
EthosManagerPrivate *priv;
222
EthosPluginInfo *plugin_info;
223
GList *plugins = NULL;
226
const gchar *filename;
234
g_return_val_if_fail (ETHOS_IS_MANAGER (manager), NULL);
236
priv = manager->priv;
238
plugin_dirs = g_strdupv (priv->plugin_dirs);
239
n_dirs = plugin_dirs ? g_strv_length (plugin_dirs) : 0;
240
lower = g_utf8_strdown (priv->app_name, -1);
241
suffix = g_strconcat (".", lower, "-plugin", NULL);
242
group = g_strconcat (priv->app_name, " Plugin", NULL);
244
for (i = 0; i < n_dirs; i++) {
245
if (!(dir = g_dir_open (plugin_dirs [i], 0, NULL))) {
246
g_warning ("Could not access plugin directory: %s",
251
while (NULL != (filename = g_dir_read_name (dir))) {
252
if (!g_str_has_suffix (filename, suffix))
255
abspath = g_build_filename (plugin_dirs [i], filename, NULL);
257
plugin_info = ethos_plugin_info_new ();
258
ethos_plugin_info_set_filename (plugin_info, abspath);
260
/* overwrite the last '.' in the filename and re-use
261
* the same string as the id. */
262
if (g_strrstr (filename, "."))
263
*g_strrstr (filename, ".") = '\0';
265
ethos_plugin_info_set_id (plugin_info, filename);
267
if (ethos_plugin_info_load_from_file (plugin_info, group, abspath, NULL))
268
plugins = g_list_prepend (plugins, g_object_ref (plugin_info));
270
g_object_unref (plugin_info);
277
g_strfreev (plugin_dirs);
286
* ethos_manager_initialize:
287
* @manager: An #EthosManager
289
* Initialize the plugin manager. This will result in the manager looking for
290
* all of the available plugins that it can find in the registered plugin
294
ethos_manager_initialize (EthosManager *manager)
296
EthosManagerPrivate *priv;
299
g_return_if_fail (ETHOS_IS_MANAGER (manager));
301
priv = manager->priv;
303
if (priv->initialized)
306
priv->initialized = TRUE;
307
priv->plugin_loaders = ethos_manager_discover_plugin_loaders (manager);
308
priv->plugin_info = ethos_manager_discover_plugins (manager);
310
for (iter = priv->plugin_info; iter; iter = iter->next) {
311
g_hash_table_insert (priv->plugin_info_hash,
312
g_strdup (ethos_plugin_info_get_id (iter->data)),
313
g_object_ref (iter->data));
316
g_signal_emit (manager, signals [INITIALIZED], 0);
320
* ethos_manager_unload:
321
* @manager: An #EthosManager
323
* Unloads all of the plugins.
326
ethos_manager_unload (EthosManager *manager)
328
g_warning ("%s is not yet implemented", __func__);
332
* ethos_manager_lookup_plugin_loader:
333
* @manager: An #EthosManager
334
* @name: The name of the #EthosPluginLoader
336
* Attempts to find the #EthosPluginLoader matching @name.
338
* Return value: An #EthosPluginLoader or %NULL.
341
ethos_manager_lookup_plugin_loader (EthosManager *manager,
344
EthosManagerPrivate *priv;
346
const gchar *loader_name;
347
gchar *loader_down = NULL,
349
EthosPluginLoader *loader = NULL;
351
g_return_val_if_fail (ETHOS_IS_MANAGER (manager), NULL);
353
priv = manager->priv;
355
for (iter = priv->plugin_loaders; iter; iter = iter->next) {
356
/* To make things a bit more resilient, we will check to see if the developer
357
* accidentally used Loader=C or Loader=Vala and replace that with NULL to
358
* indicate we should use the default shared library loader.
361
loader_name = ethos_plugin_loader_get_name (iter->data);
364
loader_down = g_ascii_strdown (loader_name, -1);
366
name_down = g_ascii_strdown (name, -1);
368
if (g_strcmp0 (name_down, "c") == 0 || g_strcmp0 (name_down, "vala") == 0) {
373
if (g_strcmp0 (name_down, loader_down) == 0)
376
g_free (loader_down);
394
OP_LTE = OP_LT | OP_EQ,
395
OP_GTE = OP_GT | OP_EQ,
413
parse_deps (EthosPluginInfo *plugin_info)
422
depstr = ethos_plugin_info_get_dependencies (plugin_info);
423
if (!depstr || g_strcmp0 (depstr, "") == 0)
426
name = ethos_plugin_info_get_id (plugin_info);
427
scanner = g_scanner_new (NULL);
428
g_scanner_input_text (scanner, depstr, strlen (depstr));
430
scanner->config->scan_float = 0;
432
if (g_scanner_get_next_token (scanner) != G_TOKEN_IDENTIFIER) {
433
g_warning ("%s: Invalid Dependencies", name);
439
dep = g_slice_new0 (Dependency);
440
dep->name = g_strdup (g_scanner_cur_value (scanner).v_string);
442
/* check for first of two possible operator tokens */
443
switch (g_scanner_peek_next_token (scanner)) {
459
g_scanner_get_next_token (scanner);
461
/* check for the second possible operator token */
462
switch (g_scanner_peek_next_token (scanner)) {
478
g_scanner_get_next_token (scanner);
481
int a = 0, b = 0, c = 0;
482
gboolean has_a = FALSE, has_b = FALSE, has_c = FALSE;
484
t = g_scanner_peek_next_token (scanner);
486
if (t != G_TOKEN_INT) {
487
g_warning ("Invalid dependency version string for %s", dep->name);
492
t = g_scanner_get_next_token (scanner);
493
if (t == G_TOKEN_INT) {
495
a = g_scanner_cur_value (scanner).v_int;
499
b = g_scanner_cur_value (scanner).v_int;
503
c = g_scanner_cur_value (scanner).v_int;
507
g_warning ("Invalid version string for %s",
508
ethos_plugin_info_get_id (plugin_info));
511
t = g_scanner_peek_next_token (scanner);
512
} while (t == G_TOKEN_INT || t == '.');
515
dep->version = g_strdup_printf ("%d.%d.%d", a, b, c);
518
deps = g_list_append (deps, dep);
520
while (g_scanner_get_next_token (scanner) == G_TOKEN_IDENTIFIER);
523
g_scanner_destroy (scanner);
529
free_deps (GList *deps)
534
for (iter = deps; iter; iter = iter->next) {
535
g_free (((Dependency*)iter->data)->name);
536
g_slice_free (Dependency, iter->data);
542
* ethos_manager_lookup_plugin_info:
543
* @manager: An #EthosManager
544
* @name: the plugin name
546
* Retrieves the #EthosPluginInfo found for the plugin named @name.
548
* Return value: The #EthosPluginInfo or %NULL.
551
ethos_manager_lookup_plugin_info (EthosManager *manager,
554
EthosManagerPrivate *priv;
557
g_return_val_if_fail (ETHOS_IS_MANAGER (manager), NULL);
559
priv = manager->priv;
561
for (iter = priv->plugin_info; iter; iter = iter->next) {
562
if (g_strcmp0 (name, ethos_plugin_info_get_id (iter->data)) == 0)
570
parse_version (const gchar *str,
575
g_return_val_if_fail (str != NULL, FALSE);
576
g_return_val_if_fail (version != NULL, FALSE);
578
parts = g_strsplit (str, ".", -1);
585
version->major = atoi (parts [0]);
587
version->minor = atoi (parts [1]);
589
version->rev = atoi (parts [2]);
599
version_cmp (Version *a,
604
else if (a->major > b->major
605
|| (a->major == b->major && a->minor > b->minor)
606
|| (a->major == b->major && a->minor == b->minor && a->rev > b->rev))
608
else if (a->major < b->major
609
|| (a->major == b->major && a->minor < b->minor)
610
|| (a->major == b->major && a->minor == b->minor && a->rev < b->rev))
612
else if (a->major == b->major && a->minor == b->minor && a->rev == b->rev)
615
g_assert_not_reached ();
619
* ethos_manager_load_plugin:
620
* @manager: An #EthosManager
621
* @plugin_info: An #EthosPluginInfo
622
* @error: A location for a #GError
624
* Attempts to load a plugin using the #EthosPluginInfo.
626
* Return value: %TRUE if the plugin was loaded. @error is set in case of
630
ethos_manager_load_plugin (EthosManager *manager,
631
EthosPluginInfo *plugin_info,
634
EthosManagerPrivate *priv;
635
EthosPluginLoader *plugin_loader;
637
EthosPluginInfo *dep_info;
644
GError *local_error = NULL;
646
g_return_val_if_fail (ETHOS_IS_MANAGER (manager), FALSE);
647
g_return_val_if_fail (ETHOS_IS_PLUGIN_INFO (plugin_info), FALSE);
649
if (ethos_plugin_info_get_active (plugin_info))
652
priv = manager->priv;
654
loader = ethos_plugin_info_get_loader (plugin_info);
655
plugin_loader = ethos_manager_lookup_plugin_loader (manager, loader);
657
if (!plugin_loader) {
658
g_set_error (error, ETHOS_ERROR, ETHOS_ERROR_PLUGIN,
659
"The plugin loader \"%s\" could not be found",
664
deps = parse_deps (plugin_info);
666
for (iter = deps; iter; iter = iter->next) {
668
if (!parse_version (dep->version, &depver)) {
669
local_error = g_error_new (ETHOS_ERROR,
671
"Invalid request for plugin version %s (%s",
672
dep->name, dep->version);
673
ethos_plugin_info_add_error (plugin_info, local_error);
674
if (error && *error == NULL)
675
*error = local_error;
677
g_error_free (local_error);
681
dep_info = ethos_manager_lookup_plugin_info (manager, dep->name);
683
g_warning ("%s: Could not locate plugin dependency %s",
684
ethos_plugin_info_get_id (plugin_info),
686
local_error = g_error_new (ETHOS_ERROR,
688
"Missing dependency %s",
690
ethos_plugin_info_add_error (plugin_info, local_error);
691
if (error && *error == NULL)
692
*error = local_error;
694
g_error_free (local_error);
698
if (!parse_version (ethos_plugin_info_get_version (dep_info), &ver)) {
699
local_error = g_error_new (ETHOS_ERROR,
701
"Invalid dependency plugin version %s (%s)",
702
ethos_plugin_info_get_id (dep_info),
703
ethos_plugin_info_get_version (dep_info));
704
ethos_plugin_info_add_error (plugin_info, local_error);
705
if (error && *error == NULL)
706
*error = local_error;
708
g_error_free (local_error);
713
/* make sure that the dependency is met */
714
switch (version_cmp (&ver, &depver)) {
716
if ((dep->oper & OP_LT) == 0)
720
if ((dep->oper & OP_EQ) == 0)
724
if ((dep->oper & OP_GT) == 0)
728
g_assert_not_reached ();
731
if (!ethos_manager_load_plugin (manager, dep_info, &local_error))
738
ethos_plugin_info_add_error (dep_info, local_error);
739
ethos_plugin_info_add_error (plugin_info, local_error);
740
if (error && *error == NULL)
741
*error = local_error;
743
g_error_free (local_error);
750
/* cache the dep names for this plugin */
751
for (iter = deps; iter; iter = iter->next) {
753
dep_names = g_list_prepend (dep_names, g_strdup (dep->name));
755
g_hash_table_insert (priv->deps_cache,
756
g_strdup (ethos_plugin_info_get_id (plugin_info)),
761
if (!(plugin = ethos_plugin_loader_load (plugin_loader, plugin_info, error)))
764
if (ETHOS_MANAGER_GET_CLASS (manager)->load_plugin (manager, plugin, error)) {
765
g_hash_table_insert (priv->plugins,
766
g_strdup (ethos_plugin_info_get_id (plugin_info)),
767
g_object_ref (plugin));
768
ethos_plugin_info_set_active (plugin_info, TRUE);
769
g_signal_emit (manager, signals [PLUGIN_LOADED], 0, plugin_info);
770
g_object_unref (plugin);
774
g_object_unref (plugin);
780
* ethos_manager_unload_plugin:
781
* @manager: An #EthosManager
782
* @plugin_info: An #EthosPluginInfo
783
* @error: A location for a #GError or %NULL
785
* Attempts to unload the plugin that was created using @plugin_info.
787
* Return value: %TRUE if the plugin was unloaded. @error is set in case of
791
ethos_manager_unload_plugin (EthosManager *manager,
792
EthosPluginInfo *plugin_info,
795
EthosManagerPrivate *priv;
797
const gchar *plugin_id;
802
g_return_val_if_fail (ETHOS_IS_MANAGER (manager), FALSE);
803
g_return_val_if_fail (ETHOS_IS_PLUGIN_INFO (plugin_info), FALSE);
805
if (!ethos_plugin_info_get_active (plugin_info))
808
priv = manager->priv;
809
plugin_id = ethos_plugin_info_get_id (plugin_info);
811
if (!(plugin = g_hash_table_lookup (priv->plugins, plugin_id)))
814
/* if any other plugin is depending on this plugin, we cannot
815
* unload it right now. deps_cache is a hashtable containing
816
* a linked list of the names of dependencies */
817
g_hash_table_iter_init (&iter, priv->deps_cache);
818
while (g_hash_table_iter_next (&iter, &key, &value)) {
819
for (list = value; list; list = list->next) {
820
if (g_strcmp0 (plugin_id, list->data) == 0) {
824
"Cannot unload the plugin"
825
" because the %s plugin is "
833
if (ETHOS_MANAGER_GET_CLASS (manager)->unload_plugin (manager, plugin, error)) {
834
ethos_plugin_info_set_active (plugin_info, FALSE);
835
g_hash_table_remove (priv->deps_cache, plugin_id);
836
g_hash_table_remove (priv->plugins, plugin_id);
837
g_signal_emit (manager, signals [PLUGIN_UNLOADED], 0, plugin_info);
845
* ethos_manager_get_plugin_loaders:
846
* @manager: An #EthosManager
848
* Retreives a list of #EthosPluginLoader<!-- -->s that were discovered
849
* when the application was initialized.
851
* Return value: A #GList of #EthosPluginLoader<!-- -->s. The list should
852
* be freed using g_list_free().
855
ethos_manager_get_plugin_loaders (EthosManager *manager)
857
EthosManagerPrivate *priv;
859
g_return_val_if_fail (ETHOS_IS_MANAGER (manager), NULL);
861
priv = manager->priv;
863
return g_list_copy (priv->plugin_loaders);
867
* ethos_manager_get_plugin_info:
868
* @manager: An #EthosManager
870
* Retreives the list of #EthosPluginInfo that were discovered.
872
* Return value: A #GList of #EthosPluginInfo which should be freed using
876
ethos_manager_get_plugin_info (EthosManager *manager)
878
g_return_val_if_fail (ETHOS_IS_MANAGER (manager), NULL);
879
return g_list_copy (manager->priv->plugin_info);
883
* ethos_manager_get_plugin_dirs:
884
* @manager: An #EthosManager
886
* Retrieves the list of plugin directories that are traversed when looking to load plugins.
888
* Return value: a %NULL terminated list of strings containing directories that will be
889
* traversed to locate plugins. This reslut should never be modified or freed.
891
G_CONST_RETURN gchar**
892
ethos_manager_get_plugin_dirs (EthosManager *manager)
894
g_return_val_if_fail (ETHOS_IS_MANAGER (manager), NULL);
895
return (G_CONST_RETURN gchar**)manager->priv->plugin_dirs;
899
* ethos_manager_set_plugin_dirs:
900
* @manager: An #EthosManager
901
* @plugin_dirs: A %NULL terminated list of strings of directories
903
* Sets the list of directories to use for locating plugins.
906
ethos_manager_set_plugin_dirs (EthosManager *manager,
909
EthosManagerPrivate *priv;
911
g_return_if_fail (ETHOS_IS_MANAGER (manager));
913
priv = manager->priv;
915
g_strfreev (priv->plugin_dirs);
916
priv->plugin_dirs = g_strdupv (plugin_dirs);
920
* ethos_manager_get_app_name:
921
* @manager: An #EthosManager
923
* Retrieves the app-name that the #EthosManager should use.
925
* Return value: the configured app name used for plugins or %NULL
927
G_CONST_RETURN gchar*
928
ethos_manager_get_app_name (EthosManager *manager)
930
g_return_val_if_fail (ETHOS_IS_MANAGER (manager), NULL);
931
return manager->priv->app_name;
935
* ethos_manager_set_app_name:
936
* @manager: An #EthosManager
937
* @app_name: A single-worded name for the application
939
* Sets the app name used for the application. This should be a single word
940
* to simplify the plugin development process. The app name is used inside
941
* the plugin description files for the group prefix as well as in the name
944
* For example, an application named "Ethos" would have the group
945
* [Ethos Plugin] in the plugin description file which would be named
946
* myplugin.ethos-plugin.
949
ethos_manager_set_app_name (EthosManager *manager,
950
const gchar *app_name)
952
EthosManagerPrivate *priv;
954
g_return_if_fail (ETHOS_IS_MANAGER (manager));
955
g_return_if_fail (app_name != NULL);
957
priv = manager->priv;
959
g_free (priv->app_name);
960
priv->app_name = g_strdup (app_name);
964
* ethos_manager_get_plugin:
965
* @manager: An #EthosManager
966
* @plugin_info: An #EthosPluginInfo
968
* Retrieves the created instance of the plugin defined by @plugin_info. If
969
* no instance of the plugin has been created, then %NULL is returned.
971
* Return value: The #EthosPlugin instance or %NULL
974
ethos_manager_get_plugin (EthosManager *manager,
975
EthosPluginInfo *plugin_info)
977
EthosManagerPrivate *priv;
979
g_return_val_if_fail (ETHOS_IS_MANAGER (manager), NULL);
980
g_return_val_if_fail (ETHOS_IS_PLUGIN_INFO (plugin_info), NULL);
982
priv = manager->priv;
984
return g_hash_table_lookup (priv->plugins,
985
ethos_plugin_info_get_id (plugin_info));
989
ethos_manager_real_load_plugin (EthosManager *manager,
993
ethos_plugin_activate (plugin);
998
ethos_manager_real_unload_plugin (EthosManager *manager,
1002
ethos_plugin_deactivate (plugin);
1007
ethos_manager_real_initialized (EthosManager *manager)
1011
GError *error = NULL;
1013
g_return_if_fail (ETHOS_IS_MANAGER (manager));
1015
list = ethos_manager_get_plugin_info (manager);
1016
for (iter = list; iter; iter = iter->next) {
1017
if (ethos_plugin_info_get_active (iter->data)) {
1020
else if (!ethos_manager_load_plugin (manager, iter->data, &error)) {
1021
g_warning ("%s: %s",
1022
ethos_plugin_info_get_id (iter->data),
1023
error ? error->message : "Error loading");
1026
ethos_plugin_info_add_error (iter->data, error);
1027
g_error_free (error);
1037
ethos_manager_finalize (GObject *object)
1039
EthosManagerPrivate *priv;
1041
priv = ETHOS_MANAGER (object)->priv;
1043
g_free (priv->app_name);
1044
g_strfreev (priv->plugin_dirs);
1045
g_hash_table_destroy (priv->plugin_info_hash);
1047
g_list_foreach (priv->plugin_loaders, (GFunc)g_object_unref, NULL);
1048
g_list_free (priv->plugin_loaders);
1050
g_list_foreach (priv->plugin_info, (GFunc)g_object_unref, NULL);
1051
g_list_free (priv->plugin_info);
1053
G_OBJECT_CLASS (ethos_manager_parent_class)->finalize (object);
1057
ethos_manager_real_plugin_loaded (EthosManager *manager,
1058
EthosPluginInfo *plugin_info)
1063
ethos_manager_real_plugin_unloaded (EthosManager *manager,
1064
EthosPluginInfo *plugin_info)
1069
ethos_manager_class_init (EthosManagerClass *klass)
1071
GObjectClass *object_class;
1073
object_class = G_OBJECT_CLASS (klass);
1074
object_class->finalize = ethos_manager_finalize;
1075
g_type_class_add_private (object_class, sizeof(EthosManagerPrivate));
1077
klass->load_plugin = ethos_manager_real_load_plugin;
1078
klass->unload_plugin = ethos_manager_real_unload_plugin;
1079
klass->initialized = ethos_manager_real_initialized;
1080
klass->plugin_loaded = ethos_manager_real_plugin_loaded;
1081
klass->plugin_unloaded = ethos_manager_real_plugin_unloaded;
1084
* EthosManager::initialized:
1085
* @manager: An #EthosManager
1087
* The initialized signal is emmitted after the manager has completed
1088
* initializing. This is a good place to load the plugins you want
1089
* loaded on startup.
1091
signals [INITIALIZED] =
1092
g_signal_new (g_intern_static_string ("initialized"),
1093
G_TYPE_FROM_CLASS (klass),
1095
G_STRUCT_OFFSET (EthosManagerClass, initialized),
1097
g_cclosure_marshal_VOID__VOID,
1102
* EthosManager::plugin-loaded:
1103
* @manager: An #EthosManager
1104
* @plugin_info: An #EthosPluginInfo
1106
* The plugin-loaded signal is emitted when a plugin has been
1107
* successfully loaded.
1109
signals [PLUGIN_LOADED] =
1110
g_signal_new (g_intern_static_string ("plugin-loaded"),
1111
G_TYPE_FROM_CLASS (klass),
1113
G_STRUCT_OFFSET (EthosManagerClass, plugin_loaded),
1115
g_cclosure_marshal_VOID__OBJECT,
1117
1, ETHOS_TYPE_PLUGIN_INFO);
1120
* EthosManager::plugin-unloaded:
1121
* @manager: An #EthosManager
1122
* @plugin_info: An #EthosPluginInfo
1124
* The plugin-loaded signal is emitted when a plugin has been
1125
* successfully unloaded.
1127
signals [PLUGIN_UNLOADED] =
1128
g_signal_new (g_intern_static_string ("plugin-unloaded"),
1129
G_TYPE_FROM_CLASS (klass),
1131
G_STRUCT_OFFSET (EthosManagerClass, plugin_unloaded),
1133
g_cclosure_marshal_VOID__OBJECT,
1135
1, ETHOS_TYPE_PLUGIN_INFO);
1139
free_dep_list (gpointer data)
1143
for (iter = list; iter; iter = iter->next)
1144
g_free (iter->data);
1149
ethos_manager_init (EthosManager *manager)
1151
manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
1153
EthosManagerPrivate);
1155
/* set the default app name, which is gotten from the executable
1156
* but with an uppercase first letter.
1158
manager->priv->app_name = g_strdup (g_get_prgname ());
1159
if (manager->priv->app_name) {
1160
if (!g_ascii_isupper (manager->priv->app_name [0])) {
1161
manager->priv->app_name [0] =
1162
g_ascii_toupper (manager->priv->app_name [0]);
1166
manager->priv->app_name = g_strdup ("Ethos");
1168
manager->priv->plugin_info_hash =
1169
g_hash_table_new_full (g_str_hash,
1173
manager->priv->plugins =
1174
g_hash_table_new_full (g_str_hash,
1178
manager->priv->deps_cache =
1179
g_hash_table_new_full (g_str_hash,