Fix sefgault using the library
[mmediamanager.git] / src / mm-module.c
blob8cf18e165a67dff5b2b8eb8d717da28c3122119d
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;
46 static gboolean mm_module_load (GTypeModule *gtm);
47 static void mm_module_unload (GTypeModule *gtm);
49 static void
50 mm_module_finalize (GObject *o)
52 MMModule *module = MM_MODULE (o);
54 g_free (module->details->filename);
55 G_OBJECT_CLASS (mm_module_parent_class)->finalize (o);
58 static void
59 mm_module_class_init (MMModuleClass *klass)
61 GTypeModuleClass *type_module_class = G_TYPE_MODULE_CLASS (klass);
63 type_module_class->load = mm_module_load;
64 type_module_class->unload = mm_module_unload;
65 G_OBJECT_CLASS (klass)->finalize = mm_module_finalize;
67 g_type_class_add_private (klass, sizeof (MMModuleDetails));
70 static void
71 mm_module_init (MMModule *module)
73 MMModuleDetails *details = module->details = MM_MODULE_GET_PRIVATE (module);
75 details->filename = NULL;
76 details->library = NULL;
79 static gboolean
80 mm_module_load (GTypeModule *gtm)
82 MMModule *module = MM_MODULE (gtm);
83 MMModuleDetails *details = module->details;
84 gpointer m_initialize, m_shutdown, m_get_types;
86 details->library = g_module_open (details->filename,
87 G_MODULE_BIND_LAZY |
88 G_MODULE_BIND_LOCAL);
89 if (!details->library) {
90 g_warning ("error while loading module %s: %s",
91 details->filename, g_module_error ());
92 return FALSE;
95 if (!g_module_symbol (details->library,
96 "mm_module_initialize",
97 &m_initialize) ||
98 !g_module_symbol (details->library,
99 "mm_module_shutdown",
100 &m_shutdown) ||
101 !g_module_symbol (details->library,
102 "mm_module_get_types",
103 &m_get_types)) {
104 g_warning ("Unable to resolve symbols inside the module %s: %s",
105 details->filename, g_module_error ());
106 g_module_close (details->library);
108 return FALSE;
111 module->initialize = m_initialize;
112 module->shutdown = m_shutdown;
113 module->get_types = m_get_types;
115 module->initialize (gtm);
117 return TRUE;
120 static void
121 mm_module_unload (GTypeModule *gtm)
123 MMModule *module = MM_MODULE (gtm);
125 module->shutdown ();
127 g_module_close (module->details->library);
129 module->initialize = NULL;
130 module->shutdown = NULL;
131 module->get_types = NULL;
134 static GObject *
135 mm_module_create_provider (MMModule *module, GType type)
137 return g_object_new (type, NULL);
140 static void
141 mm_module_add_types (MMModule *module, GType *types)
143 /* types[0] implements MMApplicationProvider
144 * types[1] implements MMCategoryProvider
145 * types[2] implements MMHitCollectionProvider
147 MMModuleDetails *details = module->details;
149 details->app_provider =
150 MM_APPLICATION_PROVIDER (mm_module_create_provider (module, types[0]));
151 details->category_provider =
152 MM_CATEGORY_PROVIDER (mm_module_create_provider (module, types[1]));
153 details->collection_provider =
154 MM_HIT_COLLECTION_PROVIDER (mm_module_create_provider (module, types[2]));
157 static void
158 add_module_objects (MMModule *module)
160 GType *gtypes;
162 module->get_types (&gtypes);
164 mm_module_add_types (module, gtypes);
167 /* public methods */
169 MMModule *
170 mm_module_load_file (const char *path)
172 MMModule *module;
174 module = g_object_new (MM_TYPE_MODULE, NULL);
175 module->details->filename = g_strdup (path);
177 if (g_type_module_use (G_TYPE_MODULE (module))) {
178 add_module_objects (module);
179 g_type_module_unuse (G_TYPE_MODULE (module));
180 return module;
181 } else {
182 g_object_unref (module);
183 return NULL;
187 MMApplicationProvider *
188 mm_module_get_application_provider (MMModule *m)
190 g_return_val_if_fail (m != NULL, NULL);
192 return m->details->app_provider;
195 MMCategoryProvider *
196 mm_module_get_category_provider (MMModule *m)
198 g_return_val_if_fail (m != NULL, NULL);
200 return m->details->category_provider;
203 MMHitCollectionProvider *
204 mm_module_get_hit_collection_provider (MMModule *m)
206 g_return_val_if_fail (m != NULL, NULL);
208 return m->details->collection_provider;