diff options
author | Rob Taylor <rob.taylor@codethink.co.uk> | 2007-08-01 12:35:06 +0100 |
---|---|---|
committer | Rob Taylor <rob.taylor@codethink.co.uk> | 2007-08-01 12:35:06 +0100 |
commit | a3d42549b71b82e229457cec1ce1cac72e68f3a1 (patch) | |
tree | 795ca18ea1d184fafa0384abf1882f4a0c8f7c31 | |
parent | fed8f45ce82ffaf42e3d20e275c4f490dc8c2b25 (diff) |
change plugin interface to be more efficient
This patch converts the plugin interface to use static dats for interested,
requires, provides, suggests and prevents. It defines a set of macros for
plugin authors to use to make declaring these nice and simple.
It also changes OhmPluginInfo to OhmPluginDesc, cutting down the functions a
plugin author needs to export to initialize, destroy and notify - of course,
all optional.
As the keys are all now const data, this cuts down strcpys dramitically so
memory use and fragmentation should be better. This also fixes a few memory
leaks.
-rw-r--r-- | ohmd/ohm-conf.c | 2 | ||||
-rw-r--r-- | ohmd/ohm-module.c | 217 | ||||
-rw-r--r-- | ohmd/ohm-plugin.c | 222 | ||||
-rw-r--r-- | ohmd/ohm-plugin.h | 134 |
4 files changed, 248 insertions, 327 deletions
diff --git a/ohmd/ohm-conf.c b/ohmd/ohm-conf.c index df982aa..a231c62 100644 --- a/ohmd/ohm-conf.c +++ b/ohmd/ohm-conf.c @@ -262,7 +262,7 @@ ohm_conf_add_key (OhmConf *conf, /* add as the strdup'd value as key is constant */ confkey = ohm_confobj_get_key (confobj); - g_hash_table_insert (conf->priv->keys, (gpointer) confkey, (gpointer) confobj); + g_hash_table_insert (conf->priv->keys, (gpointer) g_strdup(confkey), (gpointer) confobj); return TRUE; } diff --git a/ohmd/ohm-module.c b/ohmd/ohm-module.c index 182a025..c518d47 100644 --- a/ohmd/ohm-module.c +++ b/ohmd/ohm-module.c @@ -53,19 +53,32 @@ struct OhmModulePrivate GSList *plugins; /* list of loaded OhmPlugin's */ GHashTable *interested; OhmConf *conf; - gboolean doing_preload; gboolean do_extra_checks; + gchar **modules_banned; + gchar **modules_suggested; + gchar **modules_required; }; /* used as a hash entry type to provide int-passing services to the plugin */ typedef struct { OhmPlugin *plugin; gint id; -} OhmModuleNofif; +} OhmModuleNotify; G_DEFINE_TYPE (OhmModule, ohm_module, G_TYPE_OBJECT) static void +free_notify_list (GList *list) +{ + GList *l; + + for (l=list; l != NULL; l=l->next) { + g_slice_free (OhmModuleNotify, list->data); + } + g_list_free (list); +} + +static void key_changed_cb (OhmConf *conf, const gchar *key, gint value, @@ -73,7 +86,7 @@ key_changed_cb (OhmConf *conf, { GSList **entry; GSList *l; - OhmModuleNofif *notif; + OhmModuleNotify *notif; const gchar *name; ohm_debug ("key changed! %s : %i", key, value); @@ -89,110 +102,109 @@ key_changed_cb (OhmConf *conf, ohm_debug ("found watched key %s", key); /* go thru the SList and notify each plugin */ for (l=*entry; l != NULL; l=l->next) { - notif = (OhmModuleNofif *) l->data; + notif = (OhmModuleNotify *) l->data; name = ohm_plugin_get_name (notif->plugin); ohm_debug ("notify %s with id:%i", name, notif->id); - ohm_plugin_conf_notify (notif->plugin, notif->id, value); + ohm_plugin_notify (notif->plugin, notif->id, value); } } static void -add_interested_cb (OhmPlugin *plugin, - const gchar *key, - gint id, - OhmModule *module) +add_interesteds (OhmModule *module, OhmPlugin *plugin) { GSList **entry; GSList **l; - OhmModuleNofif *notif; - ohm_debug ("add interested! %s : %i", key, id); + OhmModuleNotify *notif; + const OhmPluginKeyIdMap *interested; + + if (plugin->interested == NULL) + return; - /* if present, add to SList, if not, add to hash as slist object */ - entry = g_hash_table_lookup (module->priv->interested, key); + for (interested = plugin->interested; interested->key_name; interested++) { + ohm_debug ("add interested! %s : %i", interested->key_name, interested->local_key_id); - /* create a new notifier, and copy over the data */ - notif = g_new0 (OhmModuleNofif, 1); /* TODO: use gslice */ - notif->plugin = plugin; - notif->id = id; + /* if present, add to SList, if not, add to hash as slist object */ + entry = g_hash_table_lookup (module->priv->interested, interested->key_name); - if (entry != NULL) { - /* already present, just append to SList */ - ohm_debug ("key already watched by someting else"); - *entry = g_slist_prepend (*entry, (gpointer) notif); - } else { - ohm_debug ("key not already watched by something else"); - /* create the new SList andd add the new notification to it */ - l = g_new0 (GSList *, 1); - *l = NULL; - *l = g_slist_prepend (*l, (gpointer) notif); - /* fixme we need to free this g_strdup at finalize and clear the list */ - g_hash_table_insert (module->priv->interested, (gpointer) g_strdup (key), l); - } -} + /* create a new notifier, and copy over the data */ + notif = g_slice_new (OhmModuleNotify); + notif->plugin = plugin; + notif->id = interested->local_key_id; -static void -add_require_cb (OhmPlugin *plugin, - const gchar *name, - OhmModule *module) -{ - if (module->priv->doing_preload == FALSE) { - g_error ("modules not allowed to call ohm_plugin_require() after load()"); + if (entry != NULL) { + /* already present, just append to SList */ + ohm_debug ("key already watched by someting else"); + *entry = g_slist_prepend (*entry, (gpointer) notif); + } else { + ohm_debug ("key not already watched by something else"); + /* create the new SList andd add the new notification to it */ + l = g_new0 (GSList *, 1); + *l = NULL; + *l = g_slist_prepend (*l, (gpointer) notif); + /*dupping string to cope if module is removed*/ + g_hash_table_insert (module->priv->interested, (gpointer) interested->key_name, l); + } } - ohm_debug ("adding module require %s", name); - module->priv->mod_require = g_slist_prepend (module->priv->mod_require, (gpointer) strdup (name)); } -static void -add_suggest_cb (OhmPlugin *plugin, - const gchar *name, - OhmModule *module) + +static gboolean +add_provides (OhmModule *module, OhmPlugin *plugin) { - if (module->priv->doing_preload == FALSE) { - g_error ("modules not allowed to call ohm_suggest_require() after load()"); + GError *error; + const char **provides = plugin->provides; + gboolean ret=TRUE; + error = NULL; + + if (provides == NULL) + return TRUE; + + for (; *provides; provides++) { + ohm_debug ("%s provides %s", ohm_plugin_get_name(plugin), *provides); + /* provides keys are never public and are always preset at zero */ + ret &= ohm_conf_add_key (module->priv->conf, *provides, 0, FALSE, &error); + if (ret == FALSE) { + ohm_debug ("Cannot provide key %s: %s", *provides, error->message); + g_error_free (error); + } } - ohm_debug ("adding module suggest %s", name); - module->priv->mod_suggest = g_slist_prepend (module->priv->mod_suggest, (gpointer) strdup (name)); + return ret; } static void -add_prevent_cb (OhmPlugin *plugin, - const gchar *name, - OhmModule *module) +add_names (GSList **l, const char **names) { - if (module->priv->doing_preload == FALSE) { - g_error ("modules not allowed to call ohm_plugin_prevent() after load()"); + if (names == NULL) + return; + + for (;*names; names++) { + *l = g_slist_prepend (*l, (gpointer) *names); } - ohm_debug ("adding module prevent %s", name); - module->priv->mod_prevent = g_slist_prepend (module->priv->mod_prevent, (gpointer) strdup (name)); } static gboolean ohm_module_add_plugin (OhmModule *module, const gchar *name) { OhmPlugin *plugin; - gboolean ret; /* setup new plugin */ plugin = ohm_plugin_new (); - g_signal_connect (plugin, "add-interested", - G_CALLBACK (add_interested_cb), module); - g_signal_connect (plugin, "add-require", - G_CALLBACK (add_require_cb), module); - g_signal_connect (plugin, "add-suggest", - G_CALLBACK (add_suggest_cb), module); - g_signal_connect (plugin, "add-prevent", - G_CALLBACK (add_prevent_cb), module); - /* try to preload plugin, this might fail */ - ret = ohm_plugin_preload (plugin, name); - if (ret == TRUE) { - ohm_debug ("adding %s to module list", name); - module->priv->plugins = g_slist_prepend (module->priv->plugins, (gpointer) plugin); - } else { - /* if it does, just unref and warn */ - ohm_debug ("not adding %s to module list as cannot load", name); - g_object_unref (plugin); - } - return ret; + + /* try to load plugin, this might fail */ + if (!ohm_plugin_load (plugin, name)) + return FALSE; + + ohm_debug ("adding %s to module list", name); + module->priv->plugins = g_slist_prepend (module->priv->plugins, (gpointer) plugin); + add_names (&module->priv->mod_require, plugin->requires); + add_names (&module->priv->mod_suggest, plugin->suggests); + add_names (&module->priv->mod_prevent, plugin->prevents); + add_interesteds (module, plugin); + + if (!add_provides (module, plugin)) + return FALSE; + else + return TRUE; } /* adds plugins from require and suggests lists. Failure of require is error, failure of suggests is warning */ @@ -281,7 +293,6 @@ ohm_module_read_defaults (OhmModule *module) GKeyFile *keyfile; gchar *filename; gchar *conf_dir; - gchar **modules; gsize length; guint i; GError *error; @@ -305,7 +316,7 @@ ohm_module_read_defaults (OhmModule *module) error = NULL; ret = g_key_file_load_from_file (keyfile, filename, G_KEY_FILE_NONE, &error); if (ret == FALSE) { - g_error ("cannot load goddammded keyfile %s", filename); + g_error ("cannot load keyfile %s", filename); } g_free (filename); @@ -319,49 +330,43 @@ ohm_module_read_defaults (OhmModule *module) /* read and process ModulesBanned */ error = NULL; - modules = g_key_file_get_string_list (keyfile, "Modules", "ModulesBanned", &length, &error); + module->priv->modules_banned = g_key_file_get_string_list (keyfile, "Modules", "ModulesBanned", &length, &error); if (error != NULL) { ohm_debug ("ModulesBanned read error: %s", error->message); g_error_free (error); } for (i=0; i<length; i++) { - ohm_debug ("ModulesBanned: %s", modules[i]); - module->priv->mod_prevent = g_slist_prepend (module->priv->mod_prevent, (gpointer) strdup(modules[i])); + ohm_debug ("ModulesBanned: %s", module->priv->modules_banned[i]); + module->priv->mod_prevent = g_slist_prepend (module->priv->mod_prevent, (gpointer) module->priv->modules_banned[i]); } - g_strfreev (modules); /* read and process ModulesSuggested */ error = NULL; - modules = g_key_file_get_string_list (keyfile, "Modules", "ModulesSuggested", &length, &error); + module->priv->modules_suggested = g_key_file_get_string_list (keyfile, "Modules", "ModulesSuggested", &length, &error); if (error != NULL) { ohm_debug ("ModulesSuggested read error: %s", error->message); g_error_free (error); } for (i=0; i<length; i++) { - ohm_debug ("ModulesSuggested: %s", modules[i]); - module->priv->mod_suggest = g_slist_prepend (module->priv->mod_suggest, (gpointer) strdup(modules[i])); + ohm_debug ("ModulesSuggested: %s", module->priv->modules_suggested[i]); + module->priv->mod_suggest = g_slist_prepend (module->priv->mod_suggest, (gpointer) module->priv->modules_suggested[i]); } - g_strfreev (modules); /* read and process ModulesRequired */ error = NULL; - modules = g_key_file_get_string_list (keyfile, "Modules", "ModulesRequired", &length, &error); + module->priv->modules_required = g_key_file_get_string_list (keyfile, "Modules", "ModulesRequired", &length, &error); if (error != NULL) { ohm_debug ("ModulesRequired read error: %s", error->message); g_error_free (error); } for (i=0; i<length; i++) { - ohm_debug ("ModulesRequired: %s", modules[i]); - module->priv->mod_require = g_slist_prepend (module->priv->mod_require, (gpointer) strdup(modules[i])); + ohm_debug ("ModulesRequired: %s", module->priv->modules_required[i]); + module->priv->mod_require = g_slist_prepend (module->priv->mod_require, (gpointer) strdup(module->priv->modules_required[i])); } - g_strfreev (modules); g_key_file_free (keyfile); } -/** - * ohm_module_finalize: - **/ static void ohm_module_finalize (GObject *object) { @@ -412,20 +417,13 @@ ohm_module_init (OhmModule *module) gboolean ret; module->priv = OHM_MODULE_GET_PRIVATE (module); - /* clear lists */ - module->priv->mod_require = NULL; - module->priv->mod_suggest = NULL; - module->priv->mod_prevent = NULL; - module->priv->mod_loaded = NULL; - module->priv->interested = g_hash_table_new (g_str_hash, g_str_equal); + module->priv->interested = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)free_notify_list); module->priv->conf = ohm_conf_new (); g_signal_connect (module->priv->conf, "key-changed", G_CALLBACK (key_changed_cb), module); - module->priv->doing_preload = TRUE; - /* read the defaults in from modules.ini */ ohm_module_read_defaults (module); @@ -438,13 +436,16 @@ ohm_module_init (OhmModule *module) ohm_debug ("module add iteration #%i", i++); ohm_module_add_all_plugins (module); if (i > 10) { - g_error ("module add too complex, please file a bug"); + g_error ("Module add too complex, please file a bug"); } } - module->priv->doing_preload = FALSE; + g_strfreev (module->priv->modules_required); + g_strfreev (module->priv->modules_suggested); + g_slist_free (module->priv->mod_prevent); + g_strfreev (module->priv->modules_banned); - /* add defaults for each plugin before the coldplug */ - ohm_debug ("starting plugin coldplug"); + /* add defaults for each plugin before the initialization*/ + ohm_debug ("loading plugin defaults"); for (l=module->priv->plugins; l != NULL; l=l->next) { plugin = (OhmPlugin *) l->data; name = ohm_plugin_get_name (plugin); @@ -459,13 +460,13 @@ ohm_module_init (OhmModule *module) } } - /* coldplug each plugin */ - ohm_debug ("starting plugin coldplug"); + /* initialize each plugin */ + ohm_debug ("starting plugin initialization"); for (l=module->priv->plugins; l != NULL; l=l->next) { plugin = (OhmPlugin *) l->data; name = ohm_plugin_get_name (plugin); - ohm_debug ("coldplug %s", name); - ohm_plugin_coldplug (plugin); + ohm_debug ("initialize %s", name); + ohm_plugin_initialize (plugin); } } diff --git a/ohmd/ohm-plugin.c b/ohmd/ohm-plugin.c index e292264..5279df3 100644 --- a/ohmd/ohm-plugin.c +++ b/ohmd/ohm-plugin.c @@ -1,5 +1,7 @@ /* * Copyright (C) 2007 Richard Hughes <richard@hughsie.com> + * Copyright (C) 2007 Codethink Ltd + * Author: Rob Taylor <rob.taylor@codethink.co.uk> * * Licensed under the GNU Lesser General Public License Version 2 * @@ -50,7 +52,6 @@ struct OhmPluginPrivate { OhmConf *conf; - OhmPluginInfo *info; GModule *handle; gchar *name; /* not assigned unless a plugin uses hal */ @@ -60,64 +61,14 @@ struct OhmPluginPrivate OhmPluginHalCondition hal_condition_cb; }; -enum { - ADD_INTERESTED, - ADD_REQUIRE, - ADD_SUGGEST, - ADD_PREVENT, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0, }; - G_DEFINE_TYPE (OhmPlugin, ohm_plugin, G_TYPE_OBJECT) -/** - * ohm_plugin_get_key: - **/ gboolean -ohm_plugin_require (OhmPlugin *plugin, - const gchar *name) -{ - ohm_debug ("emitting add-require '%s'", name); - g_signal_emit (plugin, signals[ADD_REQUIRE], 0, name); - return TRUE; -} - -/** - * ohm_plugin_add_notify_key: - **/ -gboolean -ohm_plugin_suggest (OhmPlugin *plugin, - const gchar *name) -{ - ohm_debug ("emitting add-suggest '%s'", name); - g_signal_emit (plugin, signals[ADD_SUGGEST], 0, name); - return TRUE; -} - -/** - * ohm_plugin_set_key: - * - **/ -gboolean -ohm_plugin_prevent (OhmPlugin *plugin, - const gchar *name) -{ - ohm_debug ("emitting add-prevent '%s'", name); - g_signal_emit (plugin, signals[ADD_PREVENT], 0, name); - return TRUE; -} - -gboolean -ohm_plugin_preload (OhmPlugin *plugin, const gchar *name) +ohm_plugin_load (OhmPlugin *plugin, const gchar *name) { gchar *path; GModule *handle; gchar *filename; - gboolean ret; - - OhmPluginInfo * (*ohm_init_plugin) (OhmPlugin *); g_return_val_if_fail (name != NULL, FALSE); @@ -138,23 +89,20 @@ ohm_plugin_preload (OhmPlugin *plugin, const gchar *name) } g_free (path); - if (!g_module_symbol (handle, "ohm_init_plugin", (gpointer) &ohm_init_plugin)) { + if (!g_module_symbol (handle, "ohm_plugin_desc", (gpointer) &plugin->desc)) { g_module_close (handle); - g_error ("could not find init function in plugin"); + ohm_debug ("could not find description in plugin %s, not loading", name); + return FALSE; } + g_module_symbol (handle, "ohm_plugin_interested", (gpointer) &plugin->interested); + g_module_symbol (handle, "ohm_plugin_provides", (gpointer) &plugin->provides); + g_module_symbol (handle, "ohm_plugin_requires", (gpointer) &plugin->requires); + g_module_symbol (handle, "ohm_plugin_suggests", (gpointer) &plugin->suggests); + g_module_symbol (handle, "ohm_plugin_prevents", (gpointer) &plugin->prevents); plugin->priv->handle = handle; plugin->priv->name = g_strdup (name); - plugin->priv->info = ohm_init_plugin (plugin); - - /* do the load */ - ret = TRUE; - if (plugin->priv->info->preload != NULL) { - ret = plugin->priv->info->preload (plugin); - /* the plugin preload might fail if we do not have the hardware */ - } - - return ret; + return TRUE; } const gchar * @@ -170,7 +118,7 @@ ohm_plugin_get_version (OhmPlugin *plugin) { g_return_val_if_fail (plugin != NULL, NULL); - return plugin->priv->info->version; + return plugin->desc->version; } const gchar * @@ -178,32 +126,13 @@ ohm_plugin_get_author (OhmPlugin *plugin) { g_return_val_if_fail (plugin != NULL, NULL); - return plugin->priv->info->author; + return plugin->desc->author; } -G_MODULE_EXPORT gboolean -ohm_plugin_conf_provide (OhmPlugin *plugin, - const gchar *name) -{ - GError *error; - gboolean ret; - error = NULL; - - ohm_debug ("%s provides %s", plugin->priv->name, name); - - /* provides keys are never public and are always preset at zero */ - ret = ohm_conf_add_key (plugin->priv->conf, name, 0, FALSE, &error); - if (ret == FALSE) { - ohm_debug ("Cannot provide key: %s", error->message); - g_error_free (error); - } - return ret; -} - -G_MODULE_EXPORT gboolean +gboolean ohm_plugin_conf_get_key (OhmPlugin *plugin, - const gchar *key, - int *value) + const gchar *key, + int *value) { GError *error; gboolean ret; @@ -216,10 +145,10 @@ ohm_plugin_conf_get_key (OhmPlugin *plugin, return ret; } -G_MODULE_EXPORT gboolean +gboolean ohm_plugin_conf_set_key (OhmPlugin *plugin, - const gchar *key, - int value) + const gchar *key, + int value) { GError *error; gboolean ret; @@ -233,30 +162,31 @@ ohm_plugin_conf_set_key (OhmPlugin *plugin, return ret; } -G_MODULE_EXPORT gboolean -ohm_plugin_conf_notify (OhmPlugin *plugin, - int id, - int value) +gboolean +ohm_plugin_notify (OhmPlugin *plugin, + int id, + int value) { - plugin->priv->info->conf_notify (plugin, id, value); + plugin->desc->notify (plugin, id, value); return TRUE; } -G_MODULE_EXPORT gboolean -ohm_plugin_coldplug (OhmPlugin *plugin) +gboolean +ohm_plugin_initialize (OhmPlugin *plugin) { - plugin->priv->info->coldplug (plugin); + if (plugin->desc->initialize) + plugin->desc->initialize (plugin); return TRUE; } /* only use this when required */ -G_MODULE_EXPORT gboolean +gboolean ohm_plugin_hal_init (OhmPlugin *plugin) { DBusConnection *conn; if (plugin->priv->hal_ctx != NULL) { - g_warning ("already initialised HAL from this plugin"); + g_warning ("already initialized HAL from this plugin"); return FALSE; } @@ -347,7 +277,7 @@ hal_condition_cb (LibHalContext *ctx, plugin->priv->hal_condition_cb (plugin, id, name, detail); } -G_MODULE_EXPORT gboolean +gboolean ohm_plugin_hal_use_property_modified (OhmPlugin *plugin, OhmPluginHalPropMod func) { @@ -356,7 +286,7 @@ ohm_plugin_hal_use_property_modified (OhmPlugin *plugin, return TRUE; } -G_MODULE_EXPORT gboolean +gboolean ohm_plugin_hal_use_condition (OhmPlugin *plugin, OhmPluginHalCondition func) { @@ -365,7 +295,7 @@ ohm_plugin_hal_use_condition (OhmPlugin *plugin, return TRUE; } -G_MODULE_EXPORT guint +guint ohm_plugin_hal_add_device_capability (OhmPlugin *plugin, const gchar *capability) { @@ -374,7 +304,7 @@ ohm_plugin_hal_add_device_capability (OhmPlugin *plugin, guint i; if (plugin->priv->hal_ctx == NULL) { - g_warning ("HAL not already initialised from this plugin!"); + g_warning ("HAL not already initialized from this plugin!"); return FALSE; } @@ -397,7 +327,7 @@ ohm_plugin_hal_add_device_capability (OhmPlugin *plugin, return num_devices; } -G_MODULE_EXPORT gboolean +gboolean ohm_plugin_hal_get_bool (OhmPlugin *plugin, guint id, const gchar *key, @@ -405,7 +335,7 @@ ohm_plugin_hal_get_bool (OhmPlugin *plugin, { const gchar *udi; if (plugin->priv->hal_ctx == NULL) { - g_warning ("HAL not already initialised from this plugin!"); + g_warning ("HAL not already initialized from this plugin!"); return FALSE; } @@ -414,7 +344,7 @@ ohm_plugin_hal_get_bool (OhmPlugin *plugin, return TRUE; } -G_MODULE_EXPORT gboolean +gboolean ohm_plugin_hal_get_int (OhmPlugin *plugin, guint id, const gchar *key, @@ -422,7 +352,7 @@ ohm_plugin_hal_get_int (OhmPlugin *plugin, { const gchar *udi; if (plugin->priv->hal_ctx == NULL) { - g_warning ("HAL not already initialised from this plugin!"); + g_warning ("HAL not already initialized from this plugin!"); return FALSE; } udi = ohm_plugin_find_udi_from_id (plugin, id); @@ -431,7 +361,7 @@ ohm_plugin_hal_get_int (OhmPlugin *plugin, } /* have to free */ -G_MODULE_EXPORT gchar * +gchar * ohm_plugin_hal_get_udi (OhmPlugin *plugin, guint id) { const gchar *udi; @@ -442,7 +372,7 @@ ohm_plugin_hal_get_udi (OhmPlugin *plugin, guint id) return g_strdup (udi); } -G_MODULE_EXPORT gboolean +gboolean ohm_plugin_spawn_async (OhmPlugin *plugin, const gchar *commandline) { @@ -459,16 +389,6 @@ ohm_plugin_spawn_async (OhmPlugin *plugin, return ret; } -G_MODULE_EXPORT gboolean -ohm_plugin_conf_interested (OhmPlugin *plugin, - const gchar *key, - gint id) -{ - ohm_debug ("%s provides wants notification of %s on signal %i", plugin->priv->name, key, id); - g_signal_emit (plugin, signals[ADD_INTERESTED], 0, key, id); - return TRUE; -} - static void ohm_plugin_free_hal_table (OhmPlugin *plugin) { @@ -501,18 +421,16 @@ ohm_plugin_finalize (GObject *object) g_object_unref (plugin->priv->conf); - if (plugin->priv->info != NULL) { - if (plugin->priv->info->unload != NULL) { - plugin->priv->info->unload (plugin); - /* free hal stuff, if used */ - if (plugin->priv->hal_ctx != NULL) { - ohm_plugin_free_hal_table (plugin); - libhal_ctx_shutdown (plugin->priv->hal_ctx, NULL); - } + if (plugin->desc != NULL) { + if (plugin->desc->destroy != NULL) { + plugin->desc->destroy (plugin); } - } - if (plugin->priv->handle != NULL) { - g_module_close (plugin->priv->handle); + /* free hal stuff, if used */ + if (plugin->priv->hal_ctx != NULL) { + ohm_plugin_free_hal_table (plugin); + libhal_ctx_shutdown (plugin->priv->hal_ctx, NULL); + } + } if (plugin->priv->name != NULL) { @@ -530,44 +448,8 @@ static void ohm_plugin_class_init (OhmPluginClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = ohm_plugin_finalize; - - signals[ADD_INTERESTED] = - g_signal_new ("add-interested", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (OhmPluginClass, add_interested), - NULL, NULL, - ohm_marshal_VOID__STRING_INT, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT); - - signals[ADD_REQUIRE] = - g_signal_new ("add-require", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (OhmPluginClass, add_require), - NULL, NULL, - ohm_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - signals[ADD_SUGGEST] = - g_signal_new ("add-suggest", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (OhmPluginClass, add_suggest), - NULL, NULL, - ohm_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - signals[ADD_PREVENT] = - g_signal_new ("add-prevent", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (OhmPluginClass, add_prevent), - NULL, NULL, - ohm_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); + object_class->finalize = ohm_plugin_finalize; g_type_class_add_private (klass, sizeof (OhmPluginPrivate)); } @@ -579,7 +461,6 @@ ohm_plugin_init (OhmPlugin *plugin) { plugin->priv = OHM_PLUGIN_GET_PRIVATE (plugin); - plugin->priv->conf = ohm_conf_new (); plugin->priv->hal_udis = g_ptr_array_new (); } @@ -591,5 +472,6 @@ ohm_plugin_new (void) { OhmPlugin *plugin; plugin = g_object_new (OHM_TYPE_PLUGIN, NULL); + plugin->priv->conf = ohm_conf_new (); return OHM_PLUGIN (plugin); } diff --git a/ohmd/ohm-plugin.h b/ohmd/ohm-plugin.h index 2c13250..e9871f4 100644 --- a/ohmd/ohm-plugin.h +++ b/ohmd/ohm-plugin.h @@ -33,61 +33,104 @@ G_BEGIN_DECLS #define OHM_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OHM_TYPE_PLUGIN, OhmPluginClass)) typedef struct OhmPluginPrivate OhmPluginPrivate; +typedef struct OhmPlugin OhmPlugin; +typedef struct OhmPluginDesc OhmPluginDesc; +typedef struct OhmPluginClass OhmPluginClass; +typedef struct OhmPluginKeyIdMap OhmPluginKeyIdMap; -typedef struct +struct OhmPlugin { - GObject parent; + GObject parent; + const OhmPluginDesc *desc; + const OhmPluginKeyIdMap *interested; + const char **provides; + const char **requires; + const char **suggests; + const char **prevents; OhmPluginPrivate *priv; -} OhmPlugin; +}; -typedef struct +struct OhmPluginClass { GObjectClass parent_class; - void (* add_interested) (OhmPlugin *plugin, - const gchar *key, - gint id); - void (* add_require) (OhmPlugin *plugin, - const gchar *name); - void (* add_suggest) (OhmPlugin *plugin, - const gchar *name); - void (* add_prevent) (OhmPlugin *plugin, - const gchar *name); - void (* hal_key_changed) (OhmPlugin *plugin, - const gchar *key); -} OhmPluginClass; - -typedef struct { - gchar *description; - gchar *version; - gchar *author; - gboolean (*preload) (OhmPlugin *plugin); - void (*unload) (OhmPlugin *plugin); - void (*coldplug) (OhmPlugin *plugin); - void (*conf_notify) (OhmPlugin *plugin, gint id, gint value); -} OhmPluginInfo; - -typedef void (*OhmPluginHalPropMod) (OhmPlugin *plugin, +}; + +struct OhmPluginKeyIdMap { + const char *key_name; + gint local_key_id; +}; + +typedef enum { + OHM_LICENSE_LGPL, + OHM_LICENSE_GPL, + OHM_LICENSE_MIT, + OHM_LICENSE_BSD, + OHM_LICENSE_NON_FREE, + OHM_LICENSE_FREE_OTHER +} OhmLicenseType; + +/** + * OhmPluginDesc: + * @description: Plugin description + * @version: Plugin version + * @author: Plugin author + * @license: Plugin license type + * @initialize: method to call on plugin initialization + * @destroy: method to call on plugin destruction + * @notify: method to call to notify of key changes, using the id's described by + * #OHM_PLUGIN_INTERESTED + * @padding: Padding for future expansion + */ +struct OhmPluginDesc { + const char *description; + const char *version; + const char *author; + OhmLicenseType license; + void (*initialize) (OhmPlugin *plugin); + void (*destroy) (OhmPlugin *plugin); + void (*notify) (OhmPlugin *plugin, gint id, gint value); + gpointer padding[8]; +}; + +#define OHM_PLUGIN_DESCRIPTION(description, version, author, license, initialize, destroy, notify) \ + G_MODULE_EXPORT const OhmPluginDesc ohm_plugin_desc = { \ + description, \ + version, \ + author, \ + license,\ + initialize, \ + destroy, \ + notify, \ + {0} \ + } + +#define OHM_PLUGIN_INTERESTED(...) \ + G_MODULE_EXPORT const OhmPluginKeyIdMap ohm_plugin_interested[] = {__VA_ARGS__, {NULL,0}} + +#define OHM_PLUGIN_PROVIDES(...) \ + G_MODULE_EXPORT const gchar *ohm_plugin_provides[] = {__VA_ARGS__,NULL} + +#define OHM_PLUGIN_REQUIRES(...) \ + G_MODULE_EXPORT const gchar *ohm_plugin_requires[] = {__VA_ARGS__,NULL} + +#define OHM_PLUGIN_SUGGESTS(...) \ + G_MODULE_EXPORT const gchar *ohm_plugin_suggests[] = {__VA_ARGS__,NULL} + +#define OHM_PLUGIN_PREVENTS(...) \ + G_MODULE_EXPORT const gchar *ohm_plugin_prevents[] = {__VA_ARGS__,NULL} + +typedef void (*OhmPluginHalPropMod) (OhmPlugin *plugin, guint id, const gchar *key); -typedef void (*OhmPluginHalCondition) (OhmPlugin *plugin, +typedef void (*OhmPluginHalCondition) (OhmPlugin *plugin, guint id, const gchar *name, const gchar *detail); - -#define OHM_INIT_PLUGIN(plugininfo) G_MODULE_EXPORT OhmPluginInfo *ohm_init_plugin (OhmPlugin *plugin) {return &(plugin_info);} - GType ohm_plugin_get_type (void); -OhmPlugin *ohm_plugin_new (void); +OhmPlugin *ohm_plugin_new (void); -gboolean ohm_plugin_preload (OhmPlugin *plugin, - const gchar *name); - -gboolean ohm_plugin_require (OhmPlugin *plugin, - const gchar *name); -gboolean ohm_plugin_suggest (OhmPlugin *plugin, - const gchar *name); -gboolean ohm_plugin_prevent (OhmPlugin *plugin, +gboolean ohm_plugin_load (OhmPlugin *plugin, const gchar *name); const gchar *ohm_plugin_get_name (OhmPlugin *plugin); @@ -99,17 +142,12 @@ gboolean ohm_plugin_spawn_async (OhmPlugin *plugin, const gchar *commandline); /* used by plugin to manager */ -gboolean ohm_plugin_conf_provide (OhmPlugin *plugin, - const gchar *name); gboolean ohm_plugin_conf_get_key (OhmPlugin *plugin, const gchar *key, gint *value); gboolean ohm_plugin_conf_set_key (OhmPlugin *plugin, const gchar *key, gint value); -gboolean ohm_plugin_conf_interested (OhmPlugin *plugin, - const gchar *key, - gint id); /* used by plugin for hal */ gboolean ohm_plugin_hal_init (OhmPlugin *plugin); gboolean ohm_plugin_hal_use_property_modified (OhmPlugin *plugin, @@ -130,10 +168,10 @@ guint ohm_plugin_hal_add_device_capability (OhmPlugin *plugin, const gchar *capability); /* used by manager to plugin */ -gboolean ohm_plugin_conf_notify (OhmPlugin *plugin, +gboolean ohm_plugin_notify (OhmPlugin *plugin, gint id, gint value); -gboolean ohm_plugin_coldplug (OhmPlugin *plugin); +gboolean ohm_plugin_initialize (OhmPlugin *plugin); G_END_DECLS |