Mercurial > pidgin
diff src/plugin.c @ 6822:7dba3e17cb21
[gaim-migrate @ 7366]
Added plugin IPC. Its use is shown in plugins/ipc-test-server.c and
plugins/ipc-test-client.c.
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Sat, 13 Sep 2003 09:31:03 +0000 |
parents | 1b91cb6be4c3 |
children | abd3c684da31 |
line wrap: on
line diff
--- a/src/plugin.c Fri Sep 12 23:32:10 2003 +0000 +++ b/src/plugin.c Sat Sep 13 09:31:03 2003 +0000 @@ -17,23 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - * ---------------- - * The Plug-in plugin - * - * Plugin support is currently being maintained by Mike Saraf - * msaraf@dwc.edu - * - * Well, I didn't see any work done on it for a while, so I'm going to try - * my hand at it. - Eric warmenhoven@yahoo.com - * - * Mike is my roomate. I can assure you that he's lazy :-P - * -- Rob rob@marko.net - * - * Yeah, well now I'm re-writing a good portion of it! The perl stuff was - * a hack. Tsk tsk! -- Christian <chipx86@gnupdate.org> - */ #include "internal.h" #include "accountopt.h" @@ -54,6 +37,24 @@ #endif #endif +typedef struct +{ + GHashTable *commands; + size_t command_count; + +} GaimPluginIpcInfo; + +typedef struct +{ + GaimCallback func; + GaimSignalMarshalFunc marshal; + + int num_params; + GaimValue **params; + GaimValue *ret_value; + +} GaimPluginIpcCommand; + static GList *loaded_plugins = NULL; static GList *plugins = NULL; static GList *plugin_loaders = NULL; @@ -395,6 +396,7 @@ } gaim_signals_disconnect_by_handle(plugin); + gaim_plugin_ipc_unregister_all(plugin); /* TODO */ if (unload_cb != NULL) @@ -499,6 +501,201 @@ return plugin->loaded; } +/************************************************************************** + * Plugin IPC + **************************************************************************/ +static void +destroy_ipc_info(void *data) +{ + GaimPluginIpcCommand *ipc_command = (GaimPluginIpcCommand *)data; + int i; + + for (i = 0; i < ipc_command->num_params; i++) + gaim_value_destroy(ipc_command->params[i]); + + if (ipc_command->ret_value != NULL) + gaim_value_destroy(ipc_command->ret_value); + + g_free(ipc_command); +} + +gboolean +gaim_plugin_ipc_register(GaimPlugin *plugin, const char *command, + GaimCallback func, GaimSignalMarshalFunc marshal, + GaimValue *ret_value, int num_params, ...) +{ + GaimPluginIpcInfo *ipc_info; + GaimPluginIpcCommand *ipc_command; + + g_return_val_if_fail(plugin != NULL, FALSE); + g_return_val_if_fail(command != NULL, FALSE); + g_return_val_if_fail(func != NULL, FALSE); + g_return_val_if_fail(marshal != NULL, FALSE); + + if (plugin->ipc_data == NULL) + { + ipc_info = plugin->ipc_data = g_new0(GaimPluginIpcInfo, 1); + ipc_info->commands = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, destroy_ipc_info); + } + else + ipc_info = (GaimPluginIpcInfo *)plugin->ipc_data; + + ipc_command = g_new0(GaimPluginIpcCommand, 1); + ipc_command->func = func; + ipc_command->marshal = marshal; + ipc_command->num_params = num_params; + ipc_command->ret_value = ret_value; + + if (num_params > 0) + { + va_list args; + int i; + + ipc_command->params = g_new0(GaimValue *, num_params); + + va_start(args, num_params); + + for (i = 0; i < num_params; i++) + ipc_command->params[i] = va_arg(args, GaimValue *); + + va_end(args); + } + + g_hash_table_replace(ipc_info->commands, g_strdup(command), ipc_command); + + ipc_info->command_count++; + + return TRUE; +} + +void +gaim_plugin_ipc_unregister(GaimPlugin *plugin, const char *command) +{ + GaimPluginIpcInfo *ipc_info; + + g_return_if_fail(plugin != NULL); + g_return_if_fail(command != NULL); + + ipc_info = (GaimPluginIpcInfo *)plugin->ipc_data; + + if (ipc_info == NULL || + g_hash_table_lookup(ipc_info->commands, command) == NULL) + { + gaim_debug_error("plugins", + "IPC command '%s' was not registered for plugin %s\n", + command, plugin->info->name); + return; + } + + g_hash_table_remove(ipc_info->commands, command); + + ipc_info->command_count--; + + if (ipc_info->command_count == 0) + { + g_hash_table_destroy(ipc_info->commands); + g_free(ipc_info); + + plugin->ipc_data = NULL; + } +} + +void +gaim_plugin_ipc_unregister_all(GaimPlugin *plugin) +{ + GaimPluginIpcInfo *ipc_info; + + g_return_if_fail(plugin != NULL); + + if (plugin->ipc_data == NULL) + return; /* Silently ignore it. */ + + ipc_info = (GaimPluginIpcInfo *)plugin->ipc_data; + + g_hash_table_destroy(ipc_info->commands); + g_free(ipc_info); + + plugin->ipc_data = NULL; +} + +gboolean +gaim_plugin_ipc_get_params(GaimPlugin *plugin, const char *command, + GaimValue **ret_value, int *num_params, + GaimValue ***params) +{ + GaimPluginIpcInfo *ipc_info; + GaimPluginIpcCommand *ipc_command; + + g_return_val_if_fail(plugin != NULL, FALSE); + g_return_val_if_fail(command != NULL, FALSE); + + ipc_info = (GaimPluginIpcInfo *)plugin->ipc_data; + + if (ipc_info == NULL || + (ipc_command = g_hash_table_lookup(ipc_info->commands, + command)) == NULL) + { + gaim_debug_error("plugins", + "IPC command '%s' was not registered for plugin %s\n", + command, plugin->info->name); + + return FALSE; + } + + if (num_params != NULL) + *num_params = ipc_command->num_params; + + if (params != NULL) + *params = ipc_command->params; + + if (ret_value != NULL) + *ret_value = ipc_command->ret_value; + + return TRUE; +} + +void * +gaim_plugin_ipc_call(GaimPlugin *plugin, const char *command, + gboolean *ok, ...) +{ + GaimPluginIpcInfo *ipc_info; + GaimPluginIpcCommand *ipc_command; + va_list args; + void *ret_value; + + if (ok != NULL) + *ok = FALSE; + + g_return_val_if_fail(plugin != NULL, NULL); + g_return_val_if_fail(command != NULL, NULL); + + ipc_info = (GaimPluginIpcInfo *)plugin->ipc_data; + + if (ipc_info == NULL || + (ipc_command = g_hash_table_lookup(ipc_info->commands, + command)) == NULL) + { + gaim_debug_error("plugins", + "IPC command '%s' was not registered for plugin %s\n", + command, plugin->info->name); + + return NULL; + } + + va_start(args, ok); + ipc_command->marshal(ipc_command->func, args, NULL, &ret_value); + va_end(args); + + if (ok != NULL) + *ok = TRUE; + + return ret_value; +} + +/************************************************************************** + * Plugins subsystem + **************************************************************************/ void gaim_plugins_set_search_paths(size_t count, char **paths) {