From: Christian H. <ch...@us...> - 2003-09-13 09:31:15
|
Update of /cvsroot/gaim/gaim/src In directory sc8-pr-cvs1:/tmp/cvs-serv16015/src Modified Files: plugin.c plugin.h signals.c signals.h Log Message: Added plugin IPC. Its use is shown in plugins/ipc-test-server.c and plugins/ipc-test-client.c. Index: plugin.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/plugin.c,v retrieving revision 1.29 retrieving revision 1.30 diff -u -d -p -r1.29 -r1.30 --- plugin.c 27 Aug 2003 23:03:03 -0000 1.29 +++ plugin.c 13 Sep 2003 09:31:02 -0000 1.30 @@ -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 - * ms...@dw... - * - * Well, I didn't see any work done on it for a while, so I'm going to try - * my hand at it. - Eric war...@ya... - * - * Mike is my roomate. I can assure you that he's lazy :-P - * -- Rob ro...@ma... - * - * Yeah, well now I'm re-writing a good portion of it! The perl stuff was - * a hack. Tsk tsk! -- Christian <ch...@gn...> - */ #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_plugin_unload(GaimPlugin *plugin) } gaim_signals_disconnect_by_handle(plugin); + gaim_plugin_ipc_unregister_all(plugin); /* TODO */ if (unload_cb != NULL) @@ -499,6 +501,201 @@ gaim_plugin_is_loaded(const GaimPlugin * 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) { Index: plugin.h =================================================================== RCS file: /cvsroot/gaim/gaim/src/plugin.h,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -p -r1.12 -r1.13 --- plugin.h 3 Sep 2003 05:21:04 -0000 1.12 +++ plugin.h 13 Sep 2003 09:31:02 -0000 1.13 @@ -24,6 +24,8 @@ #define _GAIM_PLUGIN_H_ #include <gmodule.h> +#include "signals.h" +#include "value.h" typedef struct _GaimPlugin GaimPlugin; /**< GaimPlugin */ typedef struct _GaimPluginInfo GaimPluginInfo; /**< GaimPluginInfo */ @@ -88,8 +90,6 @@ struct _GaimPluginLoaderInfo gboolean (*load)(GaimPlugin *plugin); gboolean (*unload)(GaimPlugin *plugin); void (*destroy)(GaimPlugin *plugin); - - /* XXX GaimSignalBroadcastFunc broadcast; */ }; /** @@ -103,6 +103,7 @@ struct _GaimPlugin char *path; /**< The path to the plugin. */ GaimPluginInfo *info; /**< The plugin information. */ char *error; + void *ipc_data; /**< IPC data. */ void *extra; /**< Plugin-specific data. */ }; @@ -221,6 +222,76 @@ void gaim_plugin_destroy(GaimPlugin *plu * @return TRUE if loaded, or FALSE otherwise. */ gboolean gaim_plugin_is_loaded(const GaimPlugin *plugin); + +/*@}*/ + +/**************************************************************************/ +/** @name Plugin IPC API */ +/**************************************************************************/ +/*@{*/ + +/** + * Registers an IPC command in a plugin. + * + * @param plugin The plugin to register the command with. + * @param command The name of the command. + * @param func The function to execute. + * @param marshal The marshalling function. + * @param ret_value The return value type. + * @param num_values The number of parameters. + * @param ... The parameter types. + * + * @return TRUE if the function was registered successfully, or + * FALSE otherwise. + */ +gboolean gaim_plugin_ipc_register(GaimPlugin *plugin, const char *command, + GaimCallback func, + GaimSignalMarshalFunc marshal, + GaimValue *ret_value, int num_params, ...); + +/** + * Unregisters an IPC command in a plugin. + * + * @param plugin The plugin to unregister the command from. + * @param command The name of the command. + */ +void gaim_plugin_ipc_unregister(GaimPlugin *plugin, const char *command); + +/** + * Unregisters all IPC commands in a plugin. + * + * @param plugin The plugin to unregister the commands from. + */ +void gaim_plugin_ipc_unregister_all(GaimPlugin *plugin); + +/** + * Returns a list of value types used for an IPC command. + * + * @param plugin The plugin. + * @param command The name of the command. + * @param ret_value The returned return value. + * @param num_params The returned number of parameters. + * @param params The returned list of parameters. + * + * @return TRUE if the command was found, or FALSE otherwise. + */ +gboolean gaim_plugin_ipc_get_params(GaimPlugin *plugin, const char *command, + GaimValue **ret_value, int *num_params, + GaimValue ***params); + +/** + * Executes an IPC command. + * + * @param plugin The plugin to execute the command on. + * @param command The name of the command. + * @param ok TRUE if the call was successful, or FALSE otherwise. + * @param ... The parameters to pass. + * + * @return The return value, which will be NULL if the command doesn't + * return a value. + */ +void *gaim_plugin_ipc_call(GaimPlugin *plugin, const char *command, + gboolean *ok, ...); /*@}*/ Index: signals.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/signals.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -p -r1.7 -r1.8 --- signals.c 21 Aug 2003 21:54:36 -0000 1.7 +++ signals.c 13 Sep 2003 09:31:02 -0000 1.8 @@ -536,6 +536,25 @@ gaim_marshal_VOID(GaimCallback cb, va_li } void +gaim_marshal_VOID__INT(GaimCallback cb, va_list args, void *data, + void **return_val) +{ + gint arg1 = va_arg(args, gint); + + ((void (*)(gint, void *))cb)(arg1, data); +} + +void +gaim_marshal_VOID__INT_INT(GaimCallback cb, va_list args, void *data, + void **return_val) +{ + gint arg1 = va_arg(args, gint); + gint arg2 = va_arg(args, gint); + + ((void (*)(gint, gint, void *))cb)(arg1, arg2, data); +} + +void gaim_marshal_VOID__POINTER(GaimCallback cb, va_list args, void *data, void **return_val) { @@ -618,6 +637,33 @@ gaim_marshal_VOID__POINTER_POINTER_POINT ((void (*)(void *, void *, void *, guint, guint, void *))cb)( arg1, arg2, arg3, arg4, arg5, data); +} + +void +gaim_marshal_INT__INT(GaimCallback cb, va_list args, void *data, + void **return_val) +{ + gint ret_val; + gint arg1 = va_arg(args, gint); + + ret_val = ((gint (*)(gint, void *))cb)(arg1, data); + + if (return_val != NULL) + *return_val = GINT_TO_POINTER(ret_val); +} + +void +gaim_marshal_INT__INT_INT(GaimCallback cb, va_list args, void *data, + void **return_val) +{ + gint ret_val; + gint arg1 = va_arg(args, gint); + gint arg2 = va_arg(args, gint); + + ret_val = ((gint (*)(gint, gint, void *))cb)(arg1, arg2, data); + + if (return_val != NULL) + *return_val = GINT_TO_POINTER(ret_val); } void Index: signals.h =================================================================== RCS file: /cvsroot/gaim/gaim/src/signals.h,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -p -r1.7 -r1.8 --- signals.h 3 Sep 2003 05:21:04 -0000 1.7 +++ signals.h 13 Sep 2003 09:31:02 -0000 1.8 @@ -213,6 +213,10 @@ void gaim_signals_uninit(); void gaim_marshal_VOID( GaimCallback cb, va_list args, void *data, void **return_val); +void gaim_marshal_VOID__INT( + GaimCallback cb, va_list args, void *data, void **return_val); +void gaim_marshal_VOID__INT_INT( + GaimCallback cb, va_list args, void *data, void **return_val); void gaim_marshal_VOID__POINTER( GaimCallback cb, va_list args, void *data, void **return_val); void gaim_marshal_VOID__POINTER_POINTER( @@ -226,6 +230,11 @@ void gaim_marshal_VOID__POINTER_POINTER_ void gaim_marshal_VOID__POINTER_POINTER_POINTER_UINT( GaimCallback cb, va_list args, void *data, void **return_val); void gaim_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT( + GaimCallback cb, va_list args, void *data, void **return_val); + +void gaim_marshal_INT__INT( + GaimCallback cb, va_list args, void *data, void **return_val); +void gaim_marshal_INT__INT_INT( GaimCallback cb, va_list args, void *data, void **return_val); void gaim_marshal_BOOLEAN__POINTER( |