1
/* Loader for plugins that use mission-control-plugins
3
* Copyright (C) 2009 Nokia Corporation
4
* Copyright (C) 2009 Collabora Ltd.
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
11
* This library is distributed in the hope that it will be useful, but
12
* WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24
#include <mission-control-plugins/mission-control-plugins.h>
25
#include <mission-control-plugins/debug-internal.h>
27
static gboolean debugging = FALSE;
30
mcp_set_debug (gboolean debug)
36
_mcp_is_debugging (void)
42
_mcp_debug (const gchar *format, ...)
48
va_start (args, format);
49
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format, args);
54
static GList *plugins = NULL;
58
* @object: an object implementing one or more plugin interfaces
60
* As currently implemented, these objects are never unreferenced.
62
* Add an object to the list of plugin objects.
65
mcp_add_object (gpointer object)
67
g_return_if_fail (G_IS_OBJECT (object));
69
plugins = g_list_prepend (plugins, g_object_ref (object));
73
* mcp_plugin_ref_nth_object:
74
* @n: object number, starting from 0
76
* Implemented by each plugin (not implemented in this library!) as a hook
77
* point; it will be called repeatedly with an increasing argument, and must
78
* return a GObject reference each time, until it returns NULL.
80
* As currently implemented, these objects are never unreferenced.
82
* Returns: a new reference to a #GObject, or NULL if @n is at least the number
83
* of objects supported by this plugin
88
* @path: full path to a plugins directory
90
* Read plugins from the given path. Any file with suffix G_MODULE_SUFFIX is
91
* considered as a potential plugin, and loaded; if it contains the symbol
92
* mcp_plugin_ref_nth_object(), it's made resident, then that symbol is called
96
mcp_read_dir (const gchar *path)
99
GDir *dir = g_dir_open (path, 0, &error);
104
DEBUG ("could not load plugins from %s: %s", path, error->message);
105
g_error_free (error);
109
for (entry = g_dir_read_name (dir);
111
entry = g_dir_read_name (dir))
116
if (!g_str_has_prefix (entry, "mcp-"))
118
DEBUG ("%s isn't a plugin (doesn't start with mcp-)", entry);
122
if (!g_str_has_suffix (entry, "." G_MODULE_SUFFIX))
124
DEBUG ("%s is not a loadable module", entry);
128
full_path = g_build_filename (path, entry, NULL);
130
module = g_module_open (full_path, G_MODULE_BIND_LOCAL);
136
if (g_module_symbol (module, MCP_PLUGIN_REF_NTH_OBJECT_SYMBOL,
139
GObject *(* ref_nth) (guint) = symbol;
143
/* In practice, approximately no GModules can safely be unloaded.
144
* For those that can, if there's ever a need for it, we can add
145
* an API for "please don't make me resident". */
146
g_module_make_resident (module);
148
for (object = ref_nth (n);
150
object = ref_nth (++n))
152
mcp_add_object (object);
153
g_object_unref (object);
156
DEBUG ("%u plugin object(s) found in %s", n, entry);
160
DEBUG ("%s does not have symbol %s", entry,
161
MCP_PLUGIN_REF_NTH_OBJECT_SYMBOL);
162
g_module_close (module);
175
* Return a list of objects that might implement plugin interfaces.
177
* Returns: a constant list of plugin objects
180
mcp_list_objects (void)