changeset 9015:67421e0dc497

[gaim-migrate @ 9791] (05:54:53) siege: that's the first pass on merging the two action sources (05:55:27) siege: using it right now, seems to be working fine. You may want to look it over though... (05:56:04) siege: found a small mem-leak in a GList getting created and not destroyed, this fixes that as well (13:20:40) KingAnt: LSchiere: Well it's probably ok. I haven't even had a chance to look at the commit for the other thing committer: Tailor Script <tailor@pidgin.im>
author Luke Schierer <lschiere@pidgin.im>
date Sat, 22 May 2004 17:33:38 +0000
parents 51b5b3a622ce
children 53c1e635f11d
files plugins/idle.c src/gtkblist.c src/multi.h src/plugin.c src/plugin.h src/protocols/gg/gg.c src/protocols/irc/irc.c src/protocols/jabber/buddy.c src/protocols/jabber/buddy.h src/protocols/jabber/jabber.c src/protocols/msn/msn.c src/protocols/napster/napster.c src/protocols/novell/novell.c src/protocols/oscar/oscar.c src/protocols/silc/silc.c src/protocols/toc/toc.c src/protocols/trepia/trepia.c src/protocols/yahoo/yahoo.c src/protocols/zephyr/zephyr.c src/prpl.h
diffstat 20 files changed, 349 insertions(+), 441 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/idle.c	Sat May 22 17:20:27 2004 +0000
+++ b/plugins/idle.c	Sat May 22 17:33:38 2004 +0000
@@ -7,7 +7,6 @@
 
 #include "connection.h"
 #include "debug.h"
-#include "multi.h"
 #include "plugin.h"
 #include "request.h"
 #include "server.h"
@@ -39,7 +38,7 @@
 
 
 static void
-idle_action(GaimPlugin *plugin)
+idle_action(GaimPluginAction *action)
 {
 	/* Use the super fancy request API */
 
@@ -59,7 +58,7 @@
 	request = gaim_request_fields_new();
 	gaim_request_fields_add_group(request, group);
 
-	gaim_request_fields(plugin,
+	gaim_request_fields(action->plugin,
 			N_("I'dle Mak'er"),
 			_("Set Account Idle Time"),
 			NULL,
@@ -71,16 +70,14 @@
 
 
 static GList *
-actions(GaimPlugin *plugin)
+actions(GaimPlugin *plugin, gpointer context)
 {
 	GList *l = NULL;
-	struct plugin_actions_menu *pam;
+	GaimPluginAction *act = NULL;
 
-	pam = g_new0(struct plugin_actions_menu, 1);
-	pam->label = _("Set Account Idle Time");
-	pam->callback = idle_action;
-	pam->plugin = plugin;
-	l = g_list_append(l, pam);
+	act = gaim_plugin_action_new(_("Set Account Idle Time"),
+			idle_action);
+	l = g_list_append(l, act);
 
 	return l;
 }
--- a/src/gtkblist.c	Sat May 22 17:20:27 2004 +0000
+++ b/src/gtkblist.c	Sat May 22 17:33:38 2004 +0000
@@ -23,6 +23,7 @@
 #include "gtkinternal.h"
 
 #include "account.h"
+#include "connection.h"
 #include "core.h"
 #include "debug.h"
 #include "multi.h"
@@ -4930,117 +4931,108 @@
 
 #endif
 
+
 static void
-proto_act(GtkObject *obj, struct proto_actions_menu *pam)
+plugin_act(GtkObject *obk, GaimPluginAction *pam)
 {
-	if (pam->callback && pam->gc)
-		pam->callback(pam->gc);
+	if (pam->callback) pam->callback(pam);
 }
 
 
+
 static void
-plugin_act(GtkObject *obk, struct plugin_actions_menu *pam)
+build_plugin_actions(GtkWidget *menu, GaimPlugin *plugin, gpointer context)
 {
-	if (pam->callback && pam->plugin)
-		pam->callback(pam->plugin);
+	GtkWidget *menuitem = NULL;
+	GaimPluginAction *action = NULL;
+	GList *l, *ll;
+
+	for (l = ll = GAIM_PLUGIN_ACTIONS(plugin, context); l; l = l->next) {
+		if (l->data) {
+			action = (GaimPluginAction *) l->data;
+			action->plugin = plugin;
+			action->context = context;
+
+			menuitem = gtk_menu_item_new_with_label(action->label);
+			gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+			g_signal_connect(G_OBJECT(menuitem), "activate",
+					G_CALLBACK(plugin_act), action);
+			g_object_set_data(G_OBJECT(menuitem), "plugin_action", action);
+			gtk_widget_show(menuitem);
+		}
+		else
+			gaim_separator(menu);
+	}
+
+	g_list_free(ll);
 }
 
 
 void
 gaim_gtk_blist_update_protocol_actions(void)
 {
-	GtkWidget *menuitem;
-	GtkWidget *submenu;
-	GaimPluginProtocolInfo *prpl_info = NULL;
+	GtkWidget *menuitem, *submenu;
 	GList *l;
-	GList *c;
-	struct proto_actions_menu *pam;
 	GaimConnection *gc = NULL;
+	GaimPlugin *plugin = NULL;
 	int count = 0;
-	char buf[256];
-
-	if (!protomenu)
+
+	if (! protomenu)
 		return;
 
-	for (l = gtk_container_get_children(GTK_CONTAINER(protomenu));
-		 l != NULL;
-		 l = l->next) {
-
+	for (l = gtk_container_get_children(GTK_CONTAINER(protomenu)); l; l = l->next) {
+		GaimPluginAction *action;
+		
 		menuitem = l->data;
-		pam = g_object_get_data(G_OBJECT(menuitem), "proto_actions_menu");
-
-		if (pam)
-			g_free(pam);
+		action = (GaimPluginAction *) g_object_get_data(G_OBJECT(menuitem),
+				"plugin_action");
+		g_free(action);
 
 		gtk_container_remove(GTK_CONTAINER(protomenu), GTK_WIDGET(menuitem));
 	}
 
-	for (c = gaim_connections_get_all(); c != NULL; c = c->next) {
-		gc = c->data;
-
-		prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl);
-
-		if (prpl_info->actions && gc->login_time)
-			count++;
+	for (l = gaim_connections_get_all(); l; l = l->next) {
+		gc = l->data;
+		plugin = gc->prpl;
+
+		/* no need to count past 2, so don't */
+		if (gc->login_time && GAIM_PLUGIN_HAS_ACTIONS(plugin) && count++)
+			break;
 	}
 
-	if (!count) {
-		g_snprintf(buf, sizeof(buf), _("No actions available"));
-		menuitem = gtk_menu_item_new_with_label(buf);
+	
+	if (count == 0) {
+		menuitem = gtk_menu_item_new_with_label(_("No actions available"));
 		gtk_menu_shell_append(GTK_MENU_SHELL(protomenu), menuitem);
+		gtk_widget_set_sensitive(menuitem, FALSE);
 		gtk_widget_show(menuitem);
-		return;
+
 	}
-
+	else
 	if (count == 1) {
-		GList *act;
-
-		for (c = gaim_connections_get_all(); c != NULL; c = c->next) {
-			gc = c->data;
-
-			prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl);
-
-			if (prpl_info->actions && gc->login_time)
-				break;
-		}
-
-		for (act = prpl_info->actions(gc); act != NULL; act = act->next) {
-			if (act->data) {
-				struct proto_actions_menu *pam = act->data;
-				menuitem = gtk_menu_item_new_with_label(pam->label);
-				gtk_menu_shell_append(GTK_MENU_SHELL(protomenu), menuitem);
-				g_signal_connect(G_OBJECT(menuitem), "activate",
-								 G_CALLBACK(proto_act), pam);
-				g_object_set_data(G_OBJECT(menuitem), "proto_actions_menu", pam);
-				gtk_widget_show(menuitem);
-			}
-			else
-				gaim_separator(protomenu);
-		}
+		/* plugin and gc will be set from the counting loop already */
+		build_plugin_actions(protomenu, plugin, gc);
 	}
 	else {
-		for (c = gaim_connections_get_all(); c != NULL; c = c->next) {
+		for (l = gaim_connections_get_all(); l; l = l->next) {
 			GaimAccount *account;
-			GList *act;
 			GdkPixbuf *pixbuf, *scale;
 			GtkWidget *image;
-
-			gc = c->data;
-
-			prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl);
-
-			if (!prpl_info->actions || !gc->login_time)
+			char *buf;
+
+			gc = l->data;
+			plugin = gc->prpl;
+
+			if (gc->login_time == 0	|| !GAIM_PLUGIN_HAS_ACTIONS(plugin))
 				continue;
 
 			account = gaim_connection_get_account(gc);
-
-			g_snprintf(buf, sizeof(buf), "%s (%s)",
-					   gaim_account_get_username(account),
-					   gc->prpl->info->name);
-
+			buf = g_strconcat(gaim_account_get_username(account), " (",
+					plugin->info->name, ")", NULL);
 			menuitem = gtk_image_menu_item_new_with_label(buf);
-
-			pixbuf = create_prpl_icon(gc->account);
+			g_free(buf);
+
+			pixbuf = create_prpl_icon(account);
 			if(pixbuf) {
 				scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16,
 						GDK_INTERP_BILINEAR);
@@ -5048,8 +5040,7 @@
 				g_object_unref(G_OBJECT(pixbuf));
 				g_object_unref(G_OBJECT(scale));
 				gtk_widget_show(image);
-				gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem),
-											  image);
+				gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
 			}
 
 			gtk_menu_shell_append(GTK_MENU_SHELL(protomenu), menuitem);
@@ -5059,99 +5050,64 @@
 			gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
 			gtk_widget_show(submenu);
 
-			for (act = prpl_info->actions(gc); act != NULL; act = act->next) {
-				if (act->data) {
-					struct proto_actions_menu *pam = act->data;
-					menuitem = gtk_menu_item_new_with_label(pam->label);
-					gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-					g_signal_connect(G_OBJECT(menuitem), "activate",
-									 G_CALLBACK(proto_act), pam);
-					g_object_set_data(G_OBJECT(menuitem), "proto_actions_menu",
-									  pam);
-					gtk_widget_show(menuitem);
-				}
-				else
-					gaim_separator(submenu);
-			}
+			build_plugin_actions(submenu, plugin, gc);
 		}
 	}
 }
 
 
-
 void
 gaim_gtk_blist_update_plugin_actions(void)
 {
-	GtkWidget *menuitem;
-	GtkWidget *submenu;
-	GaimPluginInfo *plugin_info = NULL;
+	GtkWidget *menuitem, *submenu;
+	GaimPlugin *plugin = NULL;
 	GList *l;
-	GList *c;
-	struct plugin_actions_menu *pam;
 	int count = 0;
 
-	if (pluginmenu == NULL)
+	if (! pluginmenu)
 		return;
 
-	for (l = gtk_container_get_children(GTK_CONTAINER(pluginmenu));
-		 l != NULL;
-		 l = l->next) {
+	for (l = gtk_container_get_children(GTK_CONTAINER(pluginmenu)); l; l = l->next) {
+		GaimPluginAction *action;
 
 		menuitem = l->data;
-		pam = g_object_get_data(G_OBJECT(menuitem), "plugin_actions_menu");
-		g_free(pam);
+		action = g_object_get_data(G_OBJECT(menuitem), "plugin_action");
+		g_free(action);
 
 		gtk_container_remove(GTK_CONTAINER(pluginmenu), GTK_WIDGET(menuitem));
 	}
 
-	for (c = gaim_plugins_get_loaded(); c != NULL; c = c->next) {
-		plugin_info = ((GaimPlugin *)c->data)->info;
-		if (plugin_info->actions)
-			count++;
+	for (l = gaim_plugins_get_loaded(); l; l = l->next) {
+		plugin = (GaimPlugin *) l->data;
+
+		if( !GAIM_IS_PROTOCOL_PLUGIN(plugin) &&
+				GAIM_PLUGIN_HAS_ACTIONS(plugin) && count++)
+			break;
 	}
 
 	if (count == 0) {
 		menuitem = gtk_menu_item_new_with_label(_("No actions available"));
 		gtk_menu_shell_append(GTK_MENU_SHELL(pluginmenu), menuitem);
+		gtk_widget_set_sensitive(menuitem, FALSE);
 		gtk_widget_show(menuitem);
 
 	}
-	else if (count == 1) {
-		GList *act;
-		GaimPlugin *plugin = NULL;
-
-		for (c = gaim_plugins_get_loaded(); c != NULL; c = c->next) {
-			plugin = (GaimPlugin *) c->data;
-			plugin_info = plugin->info;
-			if (plugin_info->actions != NULL)
-				break;
-		}
-
-		for (act = plugin_info->actions(plugin); act != NULL; act = act->next) {
-			if (act->data) {
-				struct plugin_actions_menu *pam = act->data;
-				menuitem = gtk_menu_item_new_with_label(pam->label);
-				gtk_menu_shell_append(GTK_MENU_SHELL(pluginmenu), menuitem);
-				g_signal_connect(G_OBJECT(menuitem), "activate",
-						G_CALLBACK(plugin_act), pam);
-				g_object_set_data(G_OBJECT(menuitem), "plugin_actions_menu", pam);
-				gtk_widget_show(menuitem);
-			}
-			else
-				gaim_separator(pluginmenu);
-		}
+	else
+	if (count == 1) {
+		/* plugin is already set */
+		build_plugin_actions(pluginmenu, plugin, NULL);
 	}
 	else {
-		for (c = gaim_plugins_get_loaded(); c != NULL; c = c->next) {
-			GList *act;
-			GaimPlugin *plugin;
-
-			plugin = (GaimPlugin *) c->data;
-			plugin_info = plugin->info;
-			if (plugin_info->actions == NULL)
+		for (l = gaim_plugins_get_loaded(); l; l = l->next) {
+			plugin = (GaimPlugin *) l->data;
+
+			if (GAIM_IS_PROTOCOL_PLUGIN(plugin))
 				continue;
 
-			menuitem = gtk_image_menu_item_new_with_label(plugin_info->name);
+			if (! GAIM_PLUGIN_HAS_ACTIONS(plugin))
+				continue;
+
+			menuitem = gtk_image_menu_item_new_with_label(plugin->info->name);
 			gtk_menu_shell_append(GTK_MENU_SHELL(pluginmenu), menuitem);
 			gtk_widget_show(menuitem);
 
@@ -5159,20 +5115,7 @@
 			gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
 			gtk_widget_show(submenu);
 
-			for (act = plugin_info->actions(plugin); act != NULL; act = act->next) {
-				if (act->data) {
-					struct plugin_actions_menu *pam = act->data;
-					menuitem = gtk_menu_item_new_with_label(pam->label);
-					gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-					g_signal_connect(G_OBJECT(menuitem), "activate",
-							G_CALLBACK(plugin_act), pam);
-					g_object_set_data(G_OBJECT(menuitem), "plugin_actions_menu", pam);
-					gtk_widget_show(menuitem);
-				}
-				else {
-					gaim_separator(submenu);
-				}
-			}
+			build_plugin_actions(submenu, plugin, NULL);
 		}
 	}
 }
--- a/src/multi.h	Sat May 22 17:20:27 2004 +0000
+++ b/src/multi.h	Sat May 22 17:33:38 2004 +0000
@@ -25,19 +25,6 @@
 #define _MULTI_H_
 
 #include "account.h"
-#include "plugin.h"
-
-struct proto_actions_menu {
-	char *label;
-	void (*callback)(GaimConnection *);
-	GaimConnection *gc;
-};
-
-struct plugin_actions_menu {
-	char *label;
-	void (*callback)(GaimPlugin *);
-	GaimPlugin *plugin;
-};
 
 struct proto_buddy_menu {
 	char *label;
--- a/src/plugin.c	Sat May 22 17:20:27 2004 +0000
+++ b/src/plugin.c	Sat May 22 17:33:38 2004 +0000
@@ -1154,3 +1154,12 @@
 	return plugins;
 }
 
+
+GaimPluginAction *
+gaim_plugin_action_new(char* label, void (*callback)(GaimPluginAction *))
+{
+	GaimPluginAction *act = g_new0(GaimPluginAction, 1);
+	act->label = label;
+	act->callback = callback;
+}
+
--- a/src/plugin.h	Sat May 22 17:20:27 2004 +0000
+++ b/src/plugin.h	Sat May 22 17:33:38 2004 +0000
@@ -35,6 +35,8 @@
 typedef struct _GaimPluginUiInfo     GaimPluginUiInfo;
 typedef struct _GaimPluginLoaderInfo GaimPluginLoaderInfo;
 
+typedef struct _GaimPluginAction     GaimPluginAction;
+
 typedef int GaimPluginPriority; /**< Plugin priority. */
 
 #include "pluginpref.h"
@@ -89,7 +91,7 @@
 	void *ui_info;
 	void *extra_info;
 	GaimPluginUiInfo *prefs_info;
-	GList *(*actions)(GaimPlugin *plugin);
+	GList *(*actions)(GaimPlugin *plugin, gpointer context);
 };
 
 /**
@@ -138,6 +140,30 @@
 #define GAIM_PLUGIN_UI_INFO(plugin) \
 	((GaimPluginUiInfo*)(plugin)->info->prefs_info)
 
+
+/**
+ * The structure used in the actions member of GaimPluginInfo
+ */
+struct _GaimPluginAction {
+	char *label;
+	void (*callback)(GaimPluginAction *);
+
+	/** set to the owning plugin */
+	GaimPlugin *plugin;
+
+	/** NULL for plugin actions menu, set to the GaimConnection for
+	    account actions menu */
+	gpointer context;
+};
+
+#define GAIM_PLUGIN_HAS_ACTIONS(plugin) \
+	((plugin)->info != NULL && (plugin)->info->actions != NULL)
+
+#define GAIM_PLUGIN_ACTIONS(plugin, context) \
+	(GAIM_PLUGIN_HAS_ACTIONS(plugin)? \
+	(plugin)->info->actions(plugin, context): NULL)
+
+
 /**
  * Handles the initialization of modules.
  */
@@ -158,6 +184,7 @@
 	}
 #endif
 
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -481,6 +508,12 @@
 
 /*@}*/
 
+
+/**
+ * Allocates and returns a new GaimPluginAction.
+ */
+GaimPluginAction *gaim_plugin_action_new(char* label, void (*callback)(GaimPluginAction *));
+
 #ifdef __cplusplus
 }
 #endif
--- a/src/protocols/gg/gg.c	Sat May 22 17:20:27 2004 +0000
+++ b/src/protocols/gg/gg.c	Sat May 22 17:33:38 2004 +0000
@@ -1,6 +1,6 @@
 /*
  * gaim - Gadu-Gadu Protocol Plugin
- * $Id: gg.c 9772 2004-05-21 12:07:26Z lschiere $
+ * $Id: gg.c 9791 2004-05-22 17:33:38Z lschiere $
  *
  * Copyright (C) 2001 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
  *
@@ -924,9 +924,11 @@
 }
 
 static void
-change_pass(GaimConnection *gc)
+change_pass(GaimPluginAction *action)
 {
-	gaim_account_request_change_password(gaim_connection_get_account(gc));
+	GaimConnection *gc = (GaimConnection *) action->context;
+	GaimAccount *account = gaim_connection_get_account(gc);
+	gaim_account_request_change_password(account);
 }
 
 #if 0
@@ -1391,46 +1393,32 @@
 	}
 }
 
-static GList *agg_actions(GaimConnection *gc)
+static GList *agg_actions(GaimPlugin *plugin, gpointer context)
 {
 	GList *m = NULL;
-	struct proto_actions_menu *pam;
+	GaimPluginAction *act = NULL;
 
 #if 0
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Directory Search");
-	pam->callback = show_find_info;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
-
+	act = gaim_plugin_action_new(_("Directory Search"), show_find_info);
+	m = g_list_append(m, act);
 	m = g_list_append(m, NULL);
 #endif
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Change Password");
-	pam->callback = change_pass;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Change Password"), change_pass);
+	m = g_list_append(m, act);
 
 #if 0
-	m = g_list_append(m, NULL);
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Import Buddy List from Server");
-	pam->callback = import_buddies_server;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Import Buddy List from Server"),
+			import_buddies_server);
+	m = g_list_append(m, act);
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Export Buddy List to Server");
-	pam->callback = export_buddies_server;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Export Buddy List to Server"),
+			export_buddies_server);
+	m = g_list_append(m, act);
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Delete Buddy List from Server");
-	pam->callback = delete_buddies_server;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Delete Buddy List from Server"),
+			delete_buddies_server);
+	m = g_list_append(m, act);
 #endif
 
 	return m;
@@ -1542,7 +1530,6 @@
 	NULL,
 	NULL,
 	agg_away_states,
-	agg_actions,
 	agg_buddy_menu,
 	NULL,
 	agg_login,
@@ -1617,7 +1604,7 @@
 	NULL,                                             /**< ui_info        */
 	&prpl_info,                                       /**< extra_info     */
 	NULL,
-	NULL
+	agg_actions
 };
 
 static void
--- a/src/protocols/irc/irc.c	Sat May 22 17:20:27 2004 +0000
+++ b/src/protocols/irc/irc.c	Sat May 22 17:33:38 2004 +0000
@@ -41,7 +41,7 @@
 static const char *irc_blist_icon(GaimAccount *a, GaimBuddy *b);
 static void irc_blist_emblems(GaimBuddy *b, char **se, char **sw, char **nw, char **ne);
 static GList *irc_away_states(GaimConnection *gc);
-static GList *irc_actions(GaimConnection *gc);
+static GList *irc_actions(GaimPlugin *plugin, gpointer context);
 /* static GList *irc_chat_info(GaimConnection *gc); */
 static void irc_login(GaimAccount *account);
 static void irc_login_cb(gpointer data, gint source, GaimInputCondition cond);
@@ -59,8 +59,9 @@
 
 static const char *status_chars = "@+%&";
 
-static void irc_view_motd(GaimConnection *gc)
+static void irc_view_motd(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	struct irc_conn *irc;
 	char *title;
 
@@ -131,16 +132,13 @@
 	return g_list_append(NULL, (gpointer)GAIM_AWAY_CUSTOM);
 }
 
-static GList *irc_actions(GaimConnection *gc)
+static GList *irc_actions(GaimPlugin *plugin, gpointer context)
 {
-	struct proto_actions_menu *pam;
 	GList *list = NULL;
+	GaimPluginAction *act = NULL;
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("View MOTD");
-	pam->callback = irc_view_motd;
-	pam->gc = gc;
-	list = g_list_append(list, pam);
+	act = gaim_plugin_action_new(_("View MOTD"), irc_view_motd);
+	list = g_list_append(list, act);
 
 	return list;
 }
@@ -547,7 +545,6 @@
 	NULL,
 	NULL,
 	irc_away_states,
-	irc_actions,
 	irc_buddy_menu,
 	irc_chat_join_info,
 	irc_login,
@@ -621,7 +618,7 @@
 	NULL,                                             /**< ui_info        */
 	&prpl_info,                                       /**< extra_info     */
 	NULL,
-	NULL
+	irc_actions
 };
 
 static void _init_plugin(GaimPlugin *plugin)
--- a/src/protocols/jabber/buddy.c	Sat May 22 17:20:27 2004 +0000
+++ b/src/protocols/jabber/buddy.c	Sat May 22 17:33:38 2004 +0000
@@ -446,8 +446,9 @@
  * string (if any) into GSLists for the (multi-entry) edit dialog and
  * calls the set_vcard dialog.
  */
-void jabber_setup_set_info(GaimConnection *gc)
+void jabber_setup_set_info(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	GaimRequestFields *fields;
 	GaimRequestFieldGroup *group;
 	GaimRequestField *field;
--- a/src/protocols/jabber/buddy.h	Sat May 22 17:20:27 2004 +0000
+++ b/src/protocols/jabber/buddy.h	Sat May 22 17:33:38 2004 +0000
@@ -69,6 +69,6 @@
 GList *jabber_buddy_menu(GaimConnection *gc, const char *name);
 
 void jabber_set_info(GaimConnection *gc, const char *info);
-void jabber_setup_set_info(GaimConnection *gc);
+void jabber_setup_set_info(GaimPluginAction *action);
 
 #endif /* _GAIM_JABBER_BUDDY_H_ */
--- a/src/protocols/jabber/jabber.c	Sat May 22 17:20:27 2004 +0000
+++ b/src/protocols/jabber/jabber.c	Sat May 22 17:33:38 2004 +0000
@@ -1017,8 +1017,10 @@
 	gaim_account_set_password(js->gc->account, p1);
 }
 
-static void jabber_password_change(GaimConnection *gc)
+static void jabber_password_change(GaimPluginAction *action)
 {
+
+	GaimConnection *gc = (GaimConnection *) action->context;
 	JabberStream *js = gc->proto_data;
 	GaimRequestFields *fields;
 	GaimRequestFieldGroup *group;
@@ -1044,23 +1046,19 @@
 			_("Cancel"), NULL, js);
 }
 
-static GList *jabber_actions(GaimConnection *gc)
+static GList *jabber_actions(GaimPlugin *plugin, gpointer context)
 {
 	GList *m = NULL;
-	struct proto_actions_menu *pam;
+	GaimPluginAction *act;
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Set User Info");
-	pam->callback = jabber_setup_set_info;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Set User Info"),
+			jabber_setup_set_info);
+	m = g_list_append(m, act);
 
 	/* if (js->protocol_options & CHANGE_PASSWORD) { */
-		pam = g_new0(struct proto_actions_menu, 1);
-		pam->label = _("Change Password");
-		pam->callback = jabber_password_change;
-		pam->gc = gc;
-		m = g_list_append(m, pam);
+		act = gaim_plugin_action_new(_("Change Password"),
+				jabber_password_change);
+		m = g_list_append(m, act);
 	/* } */
 
 	return m;
@@ -1299,7 +1297,6 @@
 	jabber_status_text,
 	jabber_tooltip_text,
 	jabber_away_states,
-	jabber_actions,
 	jabber_buddy_menu,
 	jabber_chat_info,
 	jabber_login,
@@ -1374,7 +1371,7 @@
 	NULL,                                             /**< ui_info        */
 	&prpl_info,                                       /**< extra_info     */
 	&prefs_info,                                      /**< prefs_info     */
-	NULL
+	jabber_actions
 };
 
 static void
--- a/src/protocols/msn/msn.c	Sat May 22 17:20:27 2004 +0000
+++ b/src/protocols/msn/msn.c	Sat May 22 17:33:38 2004 +0000
@@ -182,8 +182,9 @@
 /* -- */
 
 static void
-msn_show_set_friendly_name(GaimConnection *gc)
+msn_show_set_friendly_name(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	gaim_request_input(gc, NULL, _("Set your friendly name."),
 					   _("This is the name that other MSN buddies will "
 						 "see you as."),
@@ -193,8 +194,9 @@
 }
 
 static void
-msn_show_set_home_phone(GaimConnection *gc)
+msn_show_set_home_phone(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	MsnSession *session = gc->proto_data;
 
 	gaim_request_input(gc, NULL, _("Set your home phone number."), NULL,
@@ -204,8 +206,9 @@
 }
 
 static void
-msn_show_set_work_phone(GaimConnection *gc)
+msn_show_set_work_phone(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	MsnSession *session = gc->proto_data;
 
 	gaim_request_input(gc, NULL, _("Set your work phone number."), NULL,
@@ -215,8 +218,9 @@
 }
 
 static void
-msn_show_set_mobile_phone(GaimConnection *gc)
+msn_show_set_mobile_phone(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	MsnSession *session = gc->proto_data;
 
 	gaim_request_input(gc, NULL, _("Set your mobile phone number."), NULL,
@@ -226,8 +230,9 @@
 }
 
 static void
-msn_show_set_mobile_pages(GaimConnection *gc)
+msn_show_set_mobile_pages(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	gaim_request_action(gc, NULL, _("Allow MSN Mobile pages?"),
 						_("Do you want to allow or disallow people on "
 						  "your buddy list to send you MSN Mobile pages "
@@ -368,52 +373,38 @@
 }
 
 static GList *
-msn_actions(GaimConnection *gc)
+msn_actions(GaimPlugin *plugin, gpointer context)
 {
 	GList *m = NULL;
-	struct proto_actions_menu *pam;
+	GaimPluginAction *act;
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Set Friendly Name");
-	pam->callback = msn_show_set_friendly_name;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
-
+	act = gaim_plugin_action_new(_("Set Friendly Name"),
+			msn_show_set_friendly_name);
+	m = g_list_append(m, act);
 	m = g_list_append(m, NULL);
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Set Home Phone Number");
-	pam->callback = msn_show_set_home_phone;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Set Home Phone Number"),
+			msn_show_set_home_phone);
+	m = g_list_append(m, act);
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Set Work Phone Number");
-	pam->callback = msn_show_set_work_phone;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Set Work Phone Number"),
+			msn_show_set_work_phone);
+	m = g_list_append(m, act);
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Set Mobile Phone Number");
-	pam->callback = msn_show_set_mobile_phone;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
-
+	act = gaim_plugin_action_new(_("Set Mobile Phone Number"),
+			msn_show_set_mobile_phone);
+	m = g_list_append(m, act);
 	m = g_list_append(m, NULL);
 
 #if 0
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Enable/Disable Mobile Devices");
-	pam->callback = msn_show_set_mobile_support;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Enable/Disable Mobile Devices"),
+			msn_show_set_mobile_support);
+	m = g_list_append(m, act);
 #endif
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Allow/Disallow Mobile Pages");
-	pam->callback = msn_show_set_mobile_pages;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Allow/Disallow Mobile Pages"),
+			msn_show_set_mobile_pages);
+	m = g_list_append(m, act);
 
 	return m;
 }
@@ -1635,7 +1626,6 @@
 	msn_status_text,
 	msn_tooltip_text,
 	msn_away_states,
-	msn_actions,
 	msn_buddy_menu,
 	NULL,
 	msn_login,
@@ -1710,7 +1700,7 @@
 	NULL,                                             /**< ui_info        */
 	&prpl_info,                                       /**< extra_info     */
 	&prefs_info,                                      /**< prefs_info     */
-	NULL
+	msn_actions
 };
 
 static void
--- a/src/protocols/napster/napster.c	Sat May 22 17:20:27 2004 +0000
+++ b/src/protocols/napster/napster.c	Sat May 22 17:33:38 2004 +0000
@@ -572,7 +572,6 @@
 	NULL,
 	NULL,
 	NULL,
-	NULL,
 	nap_buddy_menu,
 	nap_chat_info,
 	nap_login,
--- a/src/protocols/novell/novell.c	Sat May 22 17:20:27 2004 +0000
+++ b/src/protocols/novell/novell.c	Sat May 22 17:33:38 2004 +0000
@@ -3298,7 +3298,6 @@
 	novell_status_text,
 	novell_tooltip_text,
 	novell_away_states,
-	NULL,						/* prpl_actions */
 	novell_buddy_menu,
 	NULL,						/* chat_info */
 	novell_login,
--- a/src/protocols/oscar/oscar.c	Sat May 22 17:20:27 2004 +0000
+++ b/src/protocols/oscar/oscar.c	Sat May 22 17:33:38 2004 +0000
@@ -6737,8 +6737,9 @@
 	}
 }
 
-static void oscar_show_format_screenname(GaimConnection *gc)
+static void oscar_show_format_screenname(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	gaim_request_input(gc, NULL, _("New screen name formatting:"), NULL,
 					   gaim_connection_get_display_name(gc), FALSE, FALSE, NULL,
 					   _("OK"), G_CALLBACK(oscar_format_screenname),
@@ -6746,8 +6747,9 @@
 					   gc);
 }
 
-static void oscar_confirm_account(GaimConnection *gc)
+static void oscar_confirm_account(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	OscarData *od = gc->proto_data;
 	aim_conn_t *conn = aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH);
 
@@ -6759,8 +6761,9 @@
 	}
 }
 
-static void oscar_show_email(GaimConnection *gc)
+static void oscar_show_email(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	OscarData *od = gc->proto_data;
 	aim_conn_t *conn = aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH);
 
@@ -6786,8 +6789,9 @@
 	}
 }
 
-static void oscar_show_change_email(GaimConnection *gc)
+static void oscar_show_change_email(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	gaim_request_input(gc, NULL, _("Change Address To:"), NULL, NULL,
 					   FALSE, FALSE, NULL,
 					   _("OK"), G_CALLBACK(oscar_change_email),
@@ -6795,8 +6799,9 @@
 					   gc);
 }
 
-static void oscar_show_awaitingauth(GaimConnection *gc)
+static void oscar_show_awaitingauth(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	OscarData *od = gc->proto_data;
 	gchar *nombre, *text, *tmp;
 	GaimBlistNode *gnode, *cnode, *bnode;
@@ -6850,8 +6855,9 @@
 	aim_search_address(od->sess, od->conn, email);
 }
 
-static void oscar_show_find_email(GaimConnection *gc)
+static void oscar_show_find_email(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	gaim_request_input(gc, _("Find Buddy by E-mail"),
 					   _("Search for a buddy by e-mail address"),
 					   _("Type the e-mail address of the buddy you are "
@@ -6880,31 +6886,36 @@
 }
 #endif
 
-static void oscar_show_set_info(GaimConnection *gc)
+static void oscar_show_set_info(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	gaim_account_request_change_user_info(gaim_connection_get_account(gc));
 }
 
-static void oscar_show_set_info_icqurl(GaimConnection *gc)
+static void oscar_show_set_info_icqurl(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	gaim_notify_uri(gc, "http://web.icq.com/whitepages/login/1,,,00.html");
 }
 
-static void oscar_change_pass(GaimConnection *gc)
+static void oscar_change_pass(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	gaim_account_request_change_password(gaim_connection_get_account(gc));
 }
 
-static void oscar_show_chpassurl(GaimConnection *gc)
+static void oscar_show_chpassurl(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	OscarData *od = gc->proto_data;
 	gchar *substituted = gaim_strreplace(od->sess->authinfo->chpassurl, "%s", gaim_account_get_username(gaim_connection_get_account(gc)));
 	gaim_notify_uri(gc, substituted);
 	g_free(substituted);
 }
 
-static void oscar_show_imforwardingurl(GaimConnection *gc)
+static void oscar_show_imforwardingurl(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	gaim_notify_uri(gc, "http://mymobile.aol.com/dbreg/register?action=imf&clientID=1");
 }
 
@@ -6941,107 +6952,80 @@
 }
 
 
-static GList *oscar_actions(GaimConnection *gc)
+static GList *oscar_actions(GaimPlugin *plugin, gpointer context)
 {
+	GaimConnection *gc = (GaimConnection *) context;
 	OscarData *od = gc->proto_data;
-	struct proto_actions_menu *pam;
 	GList *m = NULL;
-
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Set User Info...");
-	pam->callback = oscar_show_set_info;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	GaimPluginAction *act;
+
+	act = gaim_plugin_action_new(_("Set User Info..."),
+			oscar_show_set_info);
+	m = g_list_append(m, act);
 
 	if (od->icq) {
-		pam = g_new0(struct proto_actions_menu, 1);
-		pam->label = _("Set User Info (URL)...");
-		pam->callback = oscar_show_set_info_icqurl;
-		pam->gc = gc;
-		m = g_list_append(m, pam);
+		act = gaim_plugin_action_new(_("Set User Info (URL)..."),
+				oscar_show_set_info_icqurl);
+		m = g_list_append(m, act);
 	}
 
 #if 0
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Set Available Message...");
-	pam->callback = oscar_show_setavailmsg;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Set Available Message..."),
+			oscar_show_setavailmsg);
+	m = g_list_append(m, act);
 #endif
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Change Password...");
-	pam->callback = oscar_change_pass;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Change Password..."),
+			oscar_change_pass);
+	m = g_list_append(m, act);
 
 	if (od->sess->authinfo->chpassurl) {
-		pam = g_new0(struct proto_actions_menu, 1);
-		pam->label = _("Change Password (URL)");
-		pam->callback = oscar_show_chpassurl;
-		pam->gc = gc;
-		m = g_list_append(m, pam);
-	}
-
-	if (od->sess->authinfo->chpassurl) {
-		pam = g_new0(struct proto_actions_menu, 1);
-		pam->label = _("Configure IM Forwarding (URL)");
-		pam->callback = oscar_show_imforwardingurl;
-		pam->gc = gc;
-		m = g_list_append(m, pam);
+		act = gaim_plugin_action_new(_("Change Password (URL)"),
+				oscar_show_chpassurl);
+		m = g_list_append(m, act);
+
+		act = gaim_plugin_action_new(_("Configure IM Forwarding (URL)"),
+				oscar_show_imforwardingurl);
+		m = g_list_append(m, act);
 	}
 
 	if (!od->icq) {
 		/* AIM actions */
 		m = g_list_append(m, NULL);
 
-		pam = g_new0(struct proto_actions_menu, 1);
-		pam->label = _("Format Screen Name...");
-		pam->callback = oscar_show_format_screenname;
-		pam->gc = gc;
-		m = g_list_append(m, pam);
-
-		pam = g_new0(struct proto_actions_menu, 1);
-		pam->label = _("Confirm Account");
-		pam->callback = oscar_confirm_account;
-		pam->gc = gc;
-		m = g_list_append(m, pam);
-
-		pam = g_new0(struct proto_actions_menu, 1);
-		pam->label = _("Display Currently Registered Address");
-		pam->callback = oscar_show_email;
-		pam->gc = gc;
-		m = g_list_append(m, pam);
-
-		pam = g_new0(struct proto_actions_menu, 1);
-		pam->label = _("Change Currently Registered Address...");
-		pam->callback = oscar_show_change_email;
-		pam->gc = gc;
-		m = g_list_append(m, pam);
+		act = gaim_plugin_action_new(_("Format Screen Name..."),
+				oscar_show_format_screenname);
+		m = g_list_append(m, act);
+
+		act = gaim_plugin_action_new(_("Confirm Account"),
+				oscar_confirm_account);
+		m = g_list_append(m, act);
+
+		act = gaim_plugin_action_new(_("Display Currently Registered Address"),
+				oscar_show_email);
+		m = g_list_append(m, act);
+
+		act = gaim_plugin_action_new(_("Change Currently Registered Address..."),
+				oscar_show_change_email);
+		m = g_list_append(m, act);
 	}
 
 	m = g_list_append(m, NULL);
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Show Buddies Awaiting Authorization");
-	pam->callback = oscar_show_awaitingauth;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Show Buddies Awaiting Authorization"),
+			oscar_show_awaitingauth);
+	m = g_list_append(m, act);
 
 	m = g_list_append(m, NULL);
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Search for Buddy by Email...");
-	pam->callback = oscar_show_find_email;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Search for Buddy by Email..."),
+			oscar_show_find_email);
+	m = g_list_append(m, act);
 
 #if 0
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Search for Buddy by Information");
-	pam->callback = show_find_info;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Search for Buddy by Information"),
+			show_find_info);
+	m = g_list_append(m, act);
 #endif
 
 	return m;
@@ -7088,7 +7072,6 @@
 	oscar_status_text,
 	oscar_tooltip_text,
 	oscar_away_states,
-	oscar_actions,
 	oscar_buddy_menu,
 	oscar_chat_info,
 	oscar_login,
@@ -7169,7 +7152,7 @@
 	NULL,                                             /**< ui_info        */
 	&prpl_info,                                       /**< extra_info     */
 	NULL,
-	NULL
+	oscar_actions
 };
 
 static void
--- a/src/protocols/silc/silc.c	Sat May 22 17:20:27 2004 +0000
+++ b/src/protocols/silc/silc.c	Sat May 22 17:33:38 2004 +0000
@@ -525,8 +525,9 @@
 }
 
 static void
-silcgaim_attrs(GaimConnection *gc)
+silcgaim_attrs(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	SilcGaim sg = gc->proto_data;
 	SilcClient client = sg->client;
 	SilcClientConnection conn = sg->conn;
@@ -689,8 +690,9 @@
 }
 
 static void
-silcgaim_detach(GaimConnection *gc)
+silcgaim_detach(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	SilcGaim sg;
 
 	if (!gc)
@@ -705,8 +707,9 @@
 }
 
 static void
-silcgaim_view_motd(GaimConnection *gc)
+silcgaim_view_motd(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	SilcGaim sg;
 
 	if (!gc)
@@ -727,30 +730,24 @@
 }
 
 static GList *
-silcgaim_actions(GaimConnection *gc)
+silcgaim_actions(GaimPlugin *plugin, gpointer context)
 {
-	struct proto_actions_menu *pam;
 	GList *list = NULL;
+	GaimPluginAction *act;
 
 	if (!gaim_account_get_bool(gc->account, "reject-attrs", FALSE)) {
-		pam = g_new0(struct proto_actions_menu, 1);
-		pam->label = _("Online Status");
-		pam->callback = silcgaim_attrs;
-		pam->gc = gc;
-		list = g_list_append(list, pam);
+		act = gaim_plugin_action_new(_("Online Status"),
+				silcgaim_attrs);
+		list = g_list_append(list, act);
 	}
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Detach From Server");
-	pam->callback = silcgaim_detach;
-	pam->gc = gc;
-	list = g_list_append(list, pam);
+	act = gaim_plugin_action_new(_("Detach From Server"),
+			silcgaim_detach);
+	list = g_list_append(list, act);
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("View Message of the Day");
-	pam->callback = silcgaim_view_motd;
-	pam->gc = gc;
-	list = g_list_append(list, pam);
+	act = gaim_plugin_action_new(_("View Message of the Day"),
+			silcgaim_view_motd);
+	list = g_list_append(list, act);
 
 	return list;
 }
@@ -951,7 +948,6 @@
 	silcgaim_status_text,
 	silcgaim_tooltip_text,
 	silcgaim_away_states,
-	silcgaim_actions,
 	silcgaim_buddy_menu,
 	silcgaim_chat_info,
 	silcgaim_login,
@@ -1026,7 +1022,7 @@
 	NULL,                                             /**< ui_info        */
 	&prpl_info,                                       /**< extra_info     */
 	&prefs_info,                                      /**< prefs_info     */
-	NULL
+	silcgaim_actions
 };
 
 static void
--- a/src/protocols/toc/toc.c	Sat May 22 17:20:27 2004 +0000
+++ b/src/protocols/toc/toc.c	Sat May 22 17:33:38 2004 +0000
@@ -1519,41 +1519,37 @@
 }
 
 static void
-show_set_info(GaimConnection *gc)
+show_set_info(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	gaim_account_request_change_user_info(gaim_connection_get_account(gc));
 }
 
 static void
-change_pass(GaimConnection *gc)
+change_pass(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	gaim_account_request_change_password(gaim_connection_get_account(gc));
 }
 
-static GList *toc_actions(GaimConnection *gc)
+static GList *toc_actions(GaimPlugin *plugin, gpointer context)
 {
 	GList *m = NULL;
-	struct proto_actions_menu *pam;
+	GaimPluginAction *act;
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Set User Info");
-	pam->callback = show_set_info;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Set User Info"),
+			show_set_info);
+	m = g_list_append(m, act);
 
 #if 0
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Set Dir Info");
-	pam->callback = show_set_dir;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Set Dir Info"),
+			show_set_dir);
+	m = g_list_append(m, act);
 #endif
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Change Password");
-	pam->callback = change_pass;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Change Password"),
+			change_pass);
+	m = g_list_append(m, act);
 
 	return m;
 }
@@ -2107,7 +2103,6 @@
 	NULL,
 	NULL,
 	toc_away_states,
-	toc_actions,
 	toc_buddy_menu,
 	toc_chat_info,
 	toc_login,
@@ -2182,7 +2177,7 @@
 	NULL,                                             /**< ui_info        */
 	&prpl_info,                                       /**< extra_info     */
 	NULL,
-	NULL
+	toc_actions
 };
 
 static void
--- a/src/protocols/trepia/trepia.c	Sat May 22 17:20:27 2004 +0000
+++ b/src/protocols/trepia/trepia.c	Sat May 22 17:33:38 2004 +0000
@@ -430,16 +430,14 @@
 }
 
 static GList *
-trepia_actions(GaimConnection *gc)
+trepia_actions(GaimPlugin *plugin, gpointer context)
 {
 	GList *m = NULL;
-	struct proto_actions_menu *pam;
+	GaimPluginAction *act;
 
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Set Profile");
-	pam->callback = set_profile;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	act = gaim_plugin_action_new(_("Set Profile"),
+			set_profile);
+	m = g_list_append(m, act);
 
 	return m;
 }
@@ -1215,7 +1213,6 @@
 	trepia_status_text,
 	trepia_tooltip_text,
 	NULL,
-	trepia_actions,
 	trepia_buddy_menu,
 	NULL,
 	trepia_login,
@@ -1290,7 +1287,7 @@
 	NULL,                                             /**< ui_info        */
 	&prpl_info,                                       /**< extra_info     */
 	NULL,
-	NULL
+	trepia_actions
 };
 
 static void
--- a/src/protocols/yahoo/yahoo.c	Sat May 22 17:20:27 2004 +0000
+++ b/src/protocols/yahoo/yahoo.c	Sat May 22 17:33:38 2004 +0000
@@ -446,7 +446,10 @@
 	gboolean onlist = 0;
 	char *oname = NULL;
 
-	if (!g_hash_table_lookup_extended(ht, gaim_normalize(account, name), (gpointer *) &oname, (gpointer *) &list))
+	char **oname_p = &oname;
+	GSList **list_p = &list;
+
+	if (!g_hash_table_lookup_extended(ht, gaim_normalize(account, name), (gpointer *) oname_p, (gpointer *) list_p))
 		list = gaim_find_buddies(account, name);
 	else
 		g_hash_table_steal(ht, name);
@@ -2497,37 +2500,35 @@
 	gaim_connection_set_display_name(gc, entry);
 }
 
-static void yahoo_show_act_id(GaimConnection *gc)
+static void yahoo_show_act_id(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	gaim_request_input(gc, NULL, _("Active which ID?"), NULL,
 					   gaim_connection_get_display_name(gc), FALSE, FALSE, NULL,
 					   _("OK"), G_CALLBACK(yahoo_act_id),
 					   _("Cancel"), NULL, gc);
 }
 
-static void yahoo_show_chat_goto(GaimConnection *gc)
+static void yahoo_show_chat_goto(GaimPluginAction *action)
 {
+	GaimConnection *gc = (GaimConnection *) action->context;
 	gaim_request_input(gc, NULL, _("Join who in chat?"), NULL,
 					   "", FALSE, FALSE, NULL,
 					   _("OK"), G_CALLBACK(yahoo_chat_goto),
 					   _("Cancel"), NULL, gc);
 }
 
-static GList *yahoo_actions(GaimConnection *gc) {
+static GList *yahoo_actions(GaimPlugin *plugin, gpointer context) {
 	GList *m = NULL;
-	struct proto_actions_menu *pam;
-
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Activate ID...");
-	pam->callback = yahoo_show_act_id;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
-
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Join user in chat...");
-	pam->callback = yahoo_show_chat_goto;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	GaimPluginAction *act;
+
+	act = gaim_plugin_action_new(_("Activate ID..."),
+			yahoo_show_act_id);
+	m = g_list_append(m, act);
+
+	act = gaim_plugin_action_new(_("Join user in chat..."),
+			yahoo_show_chat_goto);
+	m = g_list_append(m, act);
 
 	return m;
 }
@@ -3222,7 +3223,6 @@
 	yahoo_status_text,
 	yahoo_tooltip_text,
 	yahoo_away_states,
-	yahoo_actions,
 	yahoo_buddy_menu,
 	yahoo_c_info,
 	yahoo_login,
@@ -3302,7 +3302,7 @@
 	NULL,                                             /**< ui_info        */
 	&prpl_info,                                       /**< extra_info     */
 	NULL,
-	NULL
+	yahoo_actions
 };
 
 static void
--- a/src/protocols/zephyr/zephyr.c	Sat May 22 17:20:27 2004 +0000
+++ b/src/protocols/zephyr/zephyr.c	Sat May 22 17:33:38 2004 +0000
@@ -1307,7 +1307,6 @@
 	NULL,
 	NULL,
 	zephyr_away_states,
-	NULL,
 	zephyr_buddy_menu,
 	zephyr_chat_info,
 	zephyr_login,
--- a/src/prpl.h	Sat May 22 17:20:27 2004 +0000
+++ b/src/prpl.h	Sat May 22 17:33:38 2004 +0000
@@ -238,7 +238,6 @@
 	char *(*tooltip_text)(GaimBuddy *buddy);
 
 	GList *(*away_states)(GaimConnection *gc);
-	GList *(*actions)(GaimConnection *gc);
 
 	GList *(*buddy_menu)(GaimConnection *, const char *);
 	GList *(*chat_info)(GaimConnection *);
@@ -328,7 +327,7 @@
 #define GAIM_PLUGIN_PROTOCOL_INFO(plugin) \
 	((GaimPluginProtocolInfo *)(plugin)->info->extra_info)
 
-#define GAIM_PRPL_API_VERSION 3
+#define GAIM_PRPL_API_VERSION 4
 
 #ifdef __cplusplus
 extern "C" {