Mercurial > pidgin
changeset 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 | 636b5215552e |
children | 2a6f5eb2d561 |
files | ChangeLog plugins/ipc-test-client.c plugins/ipc-test-server.c plugins/raw.c src/plugin.c src/plugin.h src/signals.c src/signals.h |
diffstat | 8 files changed, 549 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Fri Sep 12 23:32:10 2003 +0000 +++ b/ChangeLog Sat Sep 13 09:31:03 2003 +0000 @@ -15,6 +15,7 @@ online accounts as colored. * Fixed the text replacement plugin. * Added SSL support, compatible with GNUTLS and Mozilla NSS. + * Added plugin IPC. * Added support for gettext 0.12.x. * The right-click menu for conversation tabs now shows the tab icon and status, if tab icons are enabled. (Jesse Farmer)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/ipc-test-client.c Sat Sep 13 09:31:03 2003 +0000 @@ -0,0 +1,109 @@ +/* + * IPC test client plugin. + * + * Copyright (C) 2003 Christian Hammond. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ +#include "internal.h" +#include "debug.h" +#include "plugin.h" + +#define IPC_TEST_CLIENT_PLUGIN_ID "core-ipc-test-client" + +static gboolean +plugin_load(GaimPlugin *plugin) +{ + GaimPlugin *server_plugin; + gboolean ok; + int result; + + server_plugin = gaim_plugins_find_with_id("core-ipc-test-server"); + + if (server_plugin == NULL) + { + gaim_debug_error("ipc-test-client", + "Unable to locate plugin core-ipc-test-server, " + "needed for IPC.\n"); + + return TRUE; + } + + result = (int)gaim_plugin_ipc_call(server_plugin, "add", &ok, 36, 6); + + if (!ok) + { + gaim_debug_error("ipc-test-client", + "Unable to call IPC function 'add' in " + "core-ipc-test-server plugin."); + + return TRUE; + } + + gaim_debug_info("ipc-test-client", "36 + 6 = %d\n", result); + + result = (int)gaim_plugin_ipc_call(server_plugin, "sub", &ok, 50, 8); + + if (!ok) + { + gaim_debug_error("ipc-test-client", + "Unable to call IPC function 'sub' in " + "core-ipc-test-server plugin."); + + return TRUE; + } + + gaim_debug_info("ipc-test-client", "50 - 8 = %d\n", result); + + return TRUE; +} + +static GaimPluginInfo info = +{ + 2, /**< api_version */ + GAIM_PLUGIN_STANDARD, /**< type */ + NULL, /**< ui_requirement */ + 0, /**< flags */ + NULL, /**< dependencies */ + GAIM_PRIORITY_DEFAULT, /**< priority */ + + IPC_TEST_CLIENT_PLUGIN_ID, /**< id */ + N_("IPC Test Client"), /**< name */ + VERSION, /**< version */ + /** summary */ + N_("Test plugin IPC support, as a client."), + /** description */ + N_("Test plugin IPC support, as a client. This locates the server " + "plugin and calls the commands registered."), + "Christian Hammond <chipx86@gnupdate.org>", /**< author */ + GAIM_WEBSITE, /**< homepage */ + + plugin_load, /**< load */ + NULL, /**< unload */ + NULL, /**< destroy */ + + NULL, /**< ui_info */ + NULL /**< extra_info */ +}; + +static void +init_plugin(GaimPlugin *plugin) +{ + info.dependencies = g_list_append(info.dependencies, + "core-ipc-test-server"); +} + +GAIM_INIT_PLUGIN(ipctestclient, init_plugin, info)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/ipc-test-server.c Sat Sep 13 09:31:03 2003 +0000 @@ -0,0 +1,94 @@ +/* + * IPC test server plugin. + * + * Copyright (C) 2003 Christian Hammond. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ +#define IPC_TEST_SERVER_PLUGIN_ID "core-ipc-test-server" + +#include "internal.h" +#include "debug.h" +#include "plugin.h" + +static int +add_func(int i1, int i2) +{ + gaim_debug_misc("ipc-test-server", "Got %d, %d, returning %d\n", + i1, i2, i1 + i2); + return i1 + i2; +} + +static int +sub_func(int i1, int i2) +{ + gaim_debug_misc("ipc-test-server", "Got %d, %d, returning %d\n", + i1, i2, i1 - i2); + return i1 - i2; +} + +static gboolean +plugin_load(GaimPlugin *plugin) +{ + gaim_plugin_ipc_register(plugin, "add", GAIM_CALLBACK(add_func), + gaim_marshal_INT__INT_INT, + gaim_value_new(GAIM_TYPE_INT), 2, + gaim_value_new(GAIM_TYPE_INT), + gaim_value_new(GAIM_TYPE_INT)); + + gaim_plugin_ipc_register(plugin, "sub", GAIM_CALLBACK(sub_func), + gaim_marshal_INT__INT_INT, + gaim_value_new(GAIM_TYPE_INT), 2, + gaim_value_new(GAIM_TYPE_INT), + gaim_value_new(GAIM_TYPE_INT)); + + return TRUE; +} + +static GaimPluginInfo info = +{ + 2, /**< api_version */ + GAIM_PLUGIN_STANDARD, /**< type */ + NULL, /**< ui_requirement */ + 0, /**< flags */ + NULL, /**< dependencies */ + GAIM_PRIORITY_DEFAULT, /**< priority */ + + IPC_TEST_SERVER_PLUGIN_ID, /**< id */ + N_("IPC Test Server"), /**< name */ + VERSION, /**< version */ + /** summary */ + N_("Test plugin IPC support, as a server."), + /** description */ + N_("Test plugin IPC support, as a server. This registers the IPC " + "commands."), + "Christian Hammond <chipx86@gnupdate.org>", /**< author */ + GAIM_WEBSITE, /**< homepage */ + + plugin_load, /**< load */ + NULL, /**< unload */ + NULL, /**< destroy */ + + NULL, /**< ui_info */ + NULL /**< extra_info */ +}; + +static void +init_plugin(GaimPlugin *plugin) +{ +} + +GAIM_INIT_PLUGIN(ipctestserver, init_plugin, info)
--- a/plugins/raw.c Fri Sep 12 23:32:10 2003 +0000 +++ b/plugins/raw.c Sat Sep 13 09:31:03 2003 +0000 @@ -41,6 +41,7 @@ txt = gtk_entry_get_text(entry); + gaim_debug_misc("raw", "prpl num = %d\n", gaim_account_get_protocol(account)); switch (gaim_account_get_protocol(account)) { case GAIM_PROTO_TOC: { @@ -76,6 +77,8 @@ break; default: + gaim_debug_error("raw", "Unknown protocol ID %d\n", + gaim_account_get_protocol(account)); break; }
--- 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) {
--- a/src/plugin.h Fri Sep 12 23:32:10 2003 +0000 +++ b/src/plugin.h Sat Sep 13 09:31:03 2003 +0000 @@ -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 @@ gboolean (*load)(GaimPlugin *plugin); gboolean (*unload)(GaimPlugin *plugin); void (*destroy)(GaimPlugin *plugin); - - /* XXX GaimSignalBroadcastFunc broadcast; */ }; /** @@ -103,6 +103,7 @@ char *path; /**< The path to the plugin. */ GaimPluginInfo *info; /**< The plugin information. */ char *error; + void *ipc_data; /**< IPC data. */ void *extra; /**< Plugin-specific data. */ }; @@ -225,6 +226,76 @@ /*@}*/ /**************************************************************************/ +/** @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, ...); + +/*@}*/ + +/**************************************************************************/ /** @name Plugins API */ /**************************************************************************/ /*@{*/
--- a/src/signals.c Fri Sep 12 23:32:10 2003 +0000 +++ b/src/signals.c Sat Sep 13 09:31:03 2003 +0000 @@ -536,6 +536,25 @@ } 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) { @@ -621,6 +640,33 @@ } 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 gaim_marshal_BOOLEAN__POINTER(GaimCallback cb, va_list args, void *data, void **return_val) {
--- a/src/signals.h Fri Sep 12 23:32:10 2003 +0000 +++ b/src/signals.h Sat Sep 13 09:31:03 2003 +0000 @@ -213,6 +213,10 @@ 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( @@ -228,6 +232,11 @@ 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( GaimCallback cb, va_list args, void *data, void **return_val); void gaim_marshal_BOOLEAN__POINTER_POINTER(