Validate args before creating the DBus proxy, just for complete safety.
[mmediamanager.git] / src / mm-module.c
blobaed76cb4e224bc8c492615c339f5a830f2843755
1 /* MManager - a Desktop wide manager for multimedia applications.
3 * Copyright (C) 2008 Cosimo Cecchi <cosimoc@gnome.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
21 #include <glib.h>
22 #include <glib-object.h>
23 #include <gmodule.h>
24 #include "mm-application-provider.h"
25 #include "mm-category-provider.h"
26 #include "mm-hit-collection-provider.h"
27 #include "mm-module.h"
29 #define MM_MODULE_GET_PRIVATE(o) \
30 (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_MODULE, MMModuleDetails))
32 G_DEFINE_TYPE (MMModule, mm_module, G_TYPE_TYPE_MODULE);
34 struct _MMModuleDetails {
35 /* library objects */
36 char *filename;
37 GModule *library;
39 /* providers implemented by the module */
40 MMApplicationProvider *app_provider;
41 MMCategoryProvider *category_provider;
42 MMHitCollectionProvider *collection_provider;
44 /* name */
45 char *name;
49 static gboolean mm_module_load (GTypeModule *gtm);
50 static void mm_module_unload (GTypeModule *gtm);
52 static void
53 mm_module_finalize (GObject *o)
55 MMModule *module = MM_MODULE (o);
57 g_free (module->details->filename);
58 G_OBJECT_CLASS (mm_module_parent_class)->finalize (o);
61 static void
62 mm_module_class_init (MMModuleClass *klass)
64 GTypeModuleClass *type_module_class = G_TYPE_MODULE_CLASS (klass);
66 type_module_class->load = mm_module_load;
67 type_module_class->unload = mm_module_unload;
68 G_OBJECT_CLASS (klass)->finalize = mm_module_finalize;
70 g_type_class_add_private (klass, sizeof (MMModuleDetails));
73 static void
74 mm_module_init (MMModule *module)
76 MMModuleDetails *details = module->details = MM_MODULE_GET_PRIVATE (module);
78 details->filename = NULL;
79 details->library = NULL;
80 details->name = NULL;
83 static gboolean
84 mm_module_load (GTypeModule *gtm)
86 MMModule *module = MM_MODULE (gtm);
87 MMModuleDetails *details = module->details;
88 gpointer m_initialize, m_shutdown, m_get_types, m_get_name;
90 details->library = g_module_open (details->filename,
91 G_MODULE_BIND_LAZY |
92 G_MODULE_BIND_LOCAL);
93 if (!details->library) {
94 g_warning ("error while loading module %s: %s",
95 details->filename, g_module_error ());
96 return FALSE;
99 if (!g_module_symbol (details->library,
100 "mm_module_initialize",
101 &m_initialize) ||
102 !g_module_symbol (details->library,
103 "mm_module_shutdown",
104 &m_shutdown) ||
105 !g_module_symbol (details->library,
106 "mm_module_get_types",
107 &m_get_types) ||
108 !g_module_symbol (details->library,
109 "mm_module_get_name",
110 &m_get_name)) {
111 g_warning ("Unable to resolve symbols inside the module %s: %s",
112 details->filename, g_module_error ());
113 g_module_close (details->library);
115 return FALSE;
118 module->initialize = m_initialize;
119 module->shutdown = m_shutdown;
120 module->get_types = m_get_types;
121 module->get_name = m_get_name;
123 module->initialize (gtm);
125 return TRUE;
128 static void
129 mm_module_unload (GTypeModule *gtm)
131 MMModule *module = MM_MODULE (gtm);
133 module->shutdown ();
135 g_module_close (module->details->library);
137 module->initialize = NULL;
138 module->shutdown = NULL;
139 module->get_types = NULL;
142 static GObject *
143 mm_module_create_provider (MMModule *module, GType type)
145 return g_object_new (type, NULL);
148 static void
149 mm_module_add_types (MMModule *module, GType *types)
151 /* types[0] implements MMApplicationProvider
152 * types[1] implements MMCategoryProvider
153 * types[2] implements MMHitCollectionProvider
155 MMModuleDetails *details = module->details;
157 details->app_provider =
158 MM_APPLICATION_PROVIDER (mm_module_create_provider (module, types[0]));
159 details->category_provider =
160 MM_CATEGORY_PROVIDER (mm_module_create_provider (module, types[1]));
161 details->collection_provider =
162 MM_HIT_COLLECTION_PROVIDER (mm_module_create_provider (module, types[2]));
165 static void
166 add_module_objects (MMModule *module)
168 GType *gtypes;
170 module->get_types (&gtypes);
172 mm_module_add_types (module, gtypes);
175 /* public methods */
177 MMModule *
178 mm_module_load_file (const char *path)
180 MMModule *module;
182 module = g_object_new (MM_TYPE_MODULE, NULL);
183 module->details->filename = g_strdup (path);
185 if (g_type_module_use (G_TYPE_MODULE (module))) {
186 add_module_objects (module);
187 g_type_module_unuse (G_TYPE_MODULE (module));
188 return module;
189 } else {
190 g_object_unref (module);
191 return NULL;
195 MMApplicationProvider *
196 mm_module_get_application_provider (MMModule *m)
198 g_return_val_if_fail (m != NULL, NULL);
200 return m->details->app_provider;
203 MMCategoryProvider *
204 mm_module_get_category_provider (MMModule *m)
206 g_return_val_if_fail (m != NULL, NULL);
208 return m->details->category_provider;
211 MMHitCollectionProvider *
212 mm_module_get_hit_collection_provider (MMModule *m)
214 g_return_val_if_fail (m != NULL, NULL);
216 return m->details->collection_provider;
219 char *
220 mm_module_get_name (MMModule *m)
222 char *name;
224 m->get_name (&name);
226 return name;