changeset 2345:a49e8f1afbc4

[gaim-migrate @ 2358] you say potato, i say potato you say tomato, i say tomato potato, potato tomato, tomato let's call the whole thing off. *sigh*. it just doesn't work as well when it's typed. but you wouldn't want to hear me sing it. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Sat, 22 Sep 2001 09:14:27 +0000
parents 19ea44f74a88
children b1c1e3401e10
files ChangeLog plugins/PERL-HOWTO plugins/SIGNALS src/buddy_chat.c src/conversation.c src/gaim.h src/perl.c src/plugins.c src/server.c
diffstat 9 files changed, 245 insertions(+), 286 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Sep 22 07:02:30 2001 +0000
+++ b/ChangeLog	Sat Sep 22 09:14:27 2001 +0000
@@ -1,6 +1,10 @@
 GAIM: The Pimpin' Penguin IM Clone thats good for the soul! 
 
 version 0.45:
+	* Major updates to the perl system (reread PERL-HOWTO and
+	  SIGNALS)
+	* Major updates to event_chat_* events for plugins (reread
+	  SIGNALS)
 
 version 0.44 (09/20/2001):
 	* More sane scaling of buddy icons (intelligently scale to
--- a/plugins/PERL-HOWTO	Sat Sep 22 07:02:30 2001 +0000
+++ b/plugins/PERL-HOWTO	Sat Sep 22 09:14:27 2001 +0000
@@ -19,6 +19,11 @@
 There's a really quick simple perl script in this directory, gaim.pl, that
 should show most of the functions. Most things should be self-explanatory.
 
+There's one thing you need to be aware of in perl scripts for gaim. Gaim
+supports multiple connections, and perl deals with them by using a unique
+identifier for each of them (that's a fancy way of saying that perl scripts
+use the memory address of the connection). 
+
 Everything available in normal perl scripts should be available in gaim's
 perl interface, so I'm not going to bother describing that. The important
 things are the functions provided by gaim's internal GAIM module, which is
@@ -34,27 +39,31 @@
 	This function returns different information based on the integer passed
 	to it.
 	0 - the version of gaim you're running ("0.10.0" for example).
-	1 - the list of currently online screennames
-	2 - given a screenname, the protocol(s) it(/they) use(s) (as ints)
+	1 - the list of connection ids
+	2 - given a connection index, the protocol it uses (as an int)
+	3 - given a connection index, the screenname of the person
+	4 - given a connection index, the index in the users list
+	5 - the list of names of users
+	6 - the list of protocols of the users
 
 GAIM::print(title, message)
 	This displays a nice little dialog window.
 
 
-GAIM::buddy_list(name)
+GAIM::buddy_list(index)
 	This returns the buddy list (no groups, just the names of the buddies)
-	for the specified account
+	for the specified connection.
 
-GAIM::online_list(name)
-	This returns the list of online buddies for the specified account.
+GAIM::online_list(index)
+	This returns the list of online buddies for the specified connection.
 
 
 GAIM::command(command, ...)
 	This sends commands to the server, and each command takes various
 	arguments. The command should be self-explanatory:
-	"signon" - the second arg is the screenname to sign on
-	"signoff" - the optional second arg is who to sign off. if no args are
-		    given, all names are signed off.
+	"signon" - the second arg is the index of the user to sign on
+	"signoff" - the optional second arg is the connection index to sign off.
+		    if no args are given, all connections are signed off.
 	"away" - the second arg is the away message
 	"back" - no args.
 	"idle" - the second arg is how long (in seconds) to set the idle time
@@ -63,9 +72,10 @@
 		 especially evil since it warns the person from every 
 		 connection.  The third argument is 1 if you want to warn
 		 anonymously.  If 0 or ommitted, it will warn normally.
-	"info" - the second arg is what you want to set your profile to.
+	"info" - the second arg is the connection index whose info you want to set,
+	         and the third arg is what you want to set your profile to.
 
-GAIM::user_info(nick)
+GAIM::user_info(index, nick)
 	Returns 8 data items:
 		the screenname of the buddy
 		the alias of the buddy
@@ -96,20 +106,14 @@
 		wflags==1: display message as if sent by <who>
 		wflags==2: display system message
 
-GAIM::print_to_conv(who, what, auto)
-	The question is not what does this do, it's who does this do it as. The
-	answer is "whatever the default is". It uses whichever connection is
-	selected in the conversation window's menu. If the conversation window
-	didn't exist beforehand, then it's the default (first) connection.  If
-	auto is one, it will send as an auto (read: away) message.  If 0 or
-	ommitted, it will send normally.
+GAIM::serv_send_im(index, who, what, auto)
+	Sends what from the connection index to who. :)
 
-GAIM::print_to_chat(room, what)
-	This goes through each connection. If it finds a room matching the name,
-	it'll print the message to that room.
+GAIM::print_to_conv(index, who, what, auto)
+	Convenience function; combination of write_to_conv and serv_send_im.
 
-GAIM::serv_send_im(who, what, auto)
-	Same as print_to_conv, but it does not display the message.
+GAIM::print_to_chat(index, room, what)
+	Room is actually an int. Read SIGNALS to find out why.
 
 GAIM::add_event_handler(event, function)
 	This is the most important of them all. This is basically exactly like
--- a/plugins/SIGNALS	Sat Sep 22 07:02:30 2001 +0000
+++ b/plugins/SIGNALS	Sat Sep 22 09:14:27 2001 +0000
@@ -20,13 +20,13 @@
 	event_chat_recv,
 	event_chat_send,
 	event_warned,
-	event_error,
 	event_quit,
 	event_new_conversation,
 	event_set_info,
 	event_draw_menu,
 	event_im_displayed_sent,
-	event_im_displayed_rcvd
+	event_im_displayed_rcvd,
+	event_chat_send_invite
 };
 
 To add a signal handler, call the fuction gaim_signal_connect with the
@@ -171,22 +171,29 @@
 	an empty string.
 
 event_chat_join:
-	struct gaim_connection *gc, char *room
+	struct gaim_connection *gc, int id, char *room
 
 	'gc' is the connection that joined the room.
+	'id' is the id of the room. See, each room is given an id unique
+	within the connection. The struct conversation*'s in gc->buddy_chats
+	have an 'id' field that's only used if it's is_chat member is TRUE.
+	'id' is the *only* way to detect which chat room you actually mean,
+	because the name of the chat room is not always unique (for example,
+	MSN always uses "MSN Chat" as its name, since group chats in MSN
+	don't actually have names).
 	'room' is the chat room that you have just joined.
 
 event_chat_leave:
-	struct gaim_connection *gc, char *room
+	struct gaim_connection *gc, int
 
 	'gc' is the connection that joined the room.
-	'room' is the chat room that you have just left.
+	'id' is the id of the chat room that you have just left.
 
 event_chat_buddy_join:
-	struct gaim_connection *gc, char *room, char *who
+	struct gaim_connection *gc, int id, char *who
 
 	'gc' is the connection that the chat room is attached to.
-	'room' is the room the person joined.
+	'id' is the id of the room the person joined.
 	'who' is the screenname of the person who joined.
 
 	This is also triggered upon entering the room for every person in the
@@ -196,28 +203,29 @@
 	for though.)
 
 event_chat_buddy_leave:
-	struct gaim_connection *gc, char *room, char *who
+	struct gaim_connection *gc, int id, char *who
 
 	'gc' is the connection that the chat room is attached to.
-	'room' is the room the person left.
+	'id' is the id of the room the person left.
 	'who' is the screenname of the person who left.
 
 event_chat_recv:
-	struct gaim_connection *gc, char *room, char *who, char *text
+	struct gaim_connection *gc, int id, char *who, char *text
 
 	'gc' is the connection that received the message.
-	'room' should be obvious by now.
 	'who' should be too.
 	'text' is the message that got sent.
+	'id' is the id of the room that received the message (see
+	event_chat_join)
 
 	Note that because of the bizarre way chat works, you also receive
 	messages that you send. I didn't design it, AOL did.
 
 event_chat_send:
-	struct gaim_connection *gc, char *room, char **text
+	struct gaim_connection *gc, int id, char **text
 
 	'gc' is the connection that the message is about to be sent on.
-	'room'. Need I say more.
+	'id' is the id of the room to which you're sending the message.
 	'text' is what you're about to say, linkified/HTML-ized, but not
 	TOC-escaped.
 
@@ -234,15 +242,6 @@
 	an anonymous warning, or your warning level has dropped.
 	'level' is your new warning level.
 
-event_error:
-	int error
-
-	'error' is the number of the error as defined by the TOC PROTOCOL
-	document, which can be found in the docs/ directory of the source
-	tree. Note that if the person is using Oscar, this number is often
-	plain wrong, and this event may not always be triggered on error.
-	Experiment to find what is reliable.
-
 event_quit:
 	(none)
 
@@ -302,3 +301,15 @@
 	'who' is who sent the message.
 	'what' is what was sent.
 	'flags' is flags on the message.
+
+event_chat_send_invite:
+	struct gaim_connection *gc, int id, char *who, char *msg
+
+	This is called just before you're about to invite someone. It's
+	useful for if you want to pass someone a key so that they can
+	participate in a group encrypted chat (ahem).
+
+	'gc' is the connection the invite is sent on.
+	'id' is the id of the room you're inviting them to.
+	'who' is who you're inviting.
+	'msg' is the message they'll receive when they're invited.
--- a/src/buddy_chat.c	Sat Sep 22 07:02:30 2001 +0000
+++ b/src/buddy_chat.c	Sat Sep 22 09:14:27 2001 +0000
@@ -633,7 +633,7 @@
 	int pos;
 	GList *ignored;
 
-	plugin_event(event_chat_buddy_join, b->gc, b->name, name, 0);
+	plugin_event(event_chat_buddy_join, b->gc, (void *)b->id, name, 0);
 	b->in_room = g_list_insert_sorted(b->in_room, name, insertname);
 	pos = g_list_index(b->in_room, name);
 
@@ -739,7 +739,7 @@
 
 	char tmp[BUF_LONG];
 
-	plugin_event(event_chat_buddy_leave, b->gc, b->name, buddy, 0);
+	plugin_event(event_chat_buddy_leave, b->gc, (void *)b->id, buddy, 0);
 
 	while (names) {
 		if (!g_strcasecmp((char *)names->data, buddy)) {
--- a/src/conversation.c	Sat Sep 22 07:02:30 2001 +0000
+++ b/src/conversation.c	Sat Sep 22 09:14:27 2001 +0000
@@ -847,7 +847,9 @@
 	{
 		char *buffy = g_strdup(buf);
 		enum gaim_event evnt = c->is_chat ? event_chat_send : event_im_send;
-		int plugin_return = plugin_event(evnt, c->gc, c->name, &buffy, 0);
+		int plugin_return = plugin_event(evnt, c->gc,
+						c->is_chat ? (void *)c->id : c->name,
+						&buffy, 0);
 		if (!buffy) {
 			g_free(buf2);
 			g_free(buf);
--- a/src/gaim.h	Sat Sep 22 07:02:30 2001 +0000
+++ b/src/gaim.h	Sat Sep 22 09:14:27 2001 +0000
@@ -212,6 +212,7 @@
 	event_draw_menu,
 	event_im_displayed_sent,
 	event_im_displayed_rcvd,
+	event_chat_send_invite,
 	/* any others? it's easy to add... */
 };
 
@@ -810,7 +811,6 @@
 extern void gaim_signal_disconnect(GModule *, enum gaim_event, void *);
 extern void gaim_plugin_unload(GModule *);
 #endif
-extern char *event_name(enum gaim_event);
 extern int plugin_event(enum gaim_event, void *, void *, void *, void *);
 extern void remove_all_plugins();
 
--- a/src/perl.c	Sat Sep 22 07:02:30 2001 +0000
+++ b/src/perl.c	Sat Sep 22 09:14:27 2001 +0000
@@ -306,7 +306,7 @@
 	dXSARGS;
 	items = 0;
 
-	switch(atoi(SvPV(ST(0), junk))) {
+	switch(SvIV(ST(0))) {
 	case 0:
 		XST_mPV(0, VERSION);
 		i = 1;
@@ -318,24 +318,55 @@
 
 			while (c) {
 				gc = (struct gaim_connection *)c->data;
-				XST_mPV(i++, gc->username);
+				XST_mIV(i++, (guint)gc);
 				c = c->next;
 			}
 		}
 		break;
 	case 2:
 		{
-			GList *u = aim_users;
-			struct aim_user *a;
-			char *name = g_strdup(normalize(SvPV(ST(1), junk)));
-
-			while (u) {
-				a = (struct aim_user *)u->data;
-				if (!strcasecmp(normalize(a->username), name))
-					XST_mIV(i++, a->protocol);
-				u = u->next;
+			struct gaim_connection *gc = (struct gaim_connection *)SvPV(ST(1), junk);
+			if (g_slist_find(connections, gc))
+				XST_mIV(i++, gc->protocol);
+			else
+				XST_mIV(i++, -1);
+		}
+		break;
+	case 3:
+		{
+			struct gaim_connection *gc = (struct gaim_connection *)SvPV(ST(1), junk);
+			if (g_slist_find(connections, gc))
+				XST_mPV(i++, gc->username);
+			else
+				XST_mPV(i++, "");
+		}
+	case 4:
+		{
+			struct gaim_connection *gc = (struct gaim_connection *)SvPV(ST(1), junk);
+			if (g_slist_find(connections, gc))
+				XST_mIV(i++, g_list_index(aim_users, gc->user));
+			else
+				XST_mIV(i++, -1);
+		}
+		break;
+	case 5:
+		{
+			GList *a = aim_users;
+			while (a) {
+				struct aim_user *u = a->data;
+				XST_mPV(i++, u->username);
+				a = a->next;
 			}
-			g_free(name);
+		}
+		break;
+	case 6:
+		{
+			GList *a = aim_users;
+			while (a) {
+				struct aim_user *u = a->data;
+				XST_mIV(i++, u->protocol);
+				a = a->next;
+			}
 		}
 		break;
 	default:
@@ -362,20 +393,18 @@
 
 XS (XS_GAIM_buddy_list)
 {
-	char *acct;
 	struct gaim_connection *gc;
 	struct buddy *buddy;
 	struct group *g;
 	GSList *list = NULL;
 	GSList *mem;
 	int i = 0;
-	unsigned int junk;
 	dXSARGS;
 	items = 0;
 
-	acct = SvPV(ST(0), junk);
-	gc = find_gaim_conn_by_name(acct);
-	if (gc) list = gc->groups;
+	gc = (struct gaim_connection *)SvIV(ST(0));
+	if (g_slist_find(connections, gc))
+		list = gc->groups;
 
 	while (list) {
 		g = (struct group *)list->data;
@@ -392,20 +421,18 @@
 
 XS (XS_GAIM_online_list)
 {
-	char *acct;
 	struct gaim_connection *gc;
 	struct buddy *b;
 	struct group *g;
 	GSList *list = NULL;
 	GSList *mem;
 	int i = 0;
-	unsigned int junk;
 	dXSARGS;
 	items = 0;
 
-	acct = SvPV(ST(0), junk);
-	gc = find_gaim_conn_by_name(acct);
-	if (gc) list = gc->groups;
+	gc = (struct gaim_connection *)SvIV(ST(0));
+	if (g_slist_find(connections, gc))
+		list = gc->groups;
 
 	while (list) {
 		g = (struct group *)list->data;
@@ -430,22 +457,17 @@
 	command = SvPV(ST(0), junk);
 	if (!command) XSRETURN(0);
 	if        (!strncasecmp(command, "signon", 6)) {
-		char *who = SvPV(ST(1), junk);
-		struct aim_user *u = find_user(who, -1);
-		if (u) serv_login(u);
+		int index = SvIV(ST(1));
+		if (g_list_nth_data(aim_users, index))
+		serv_login(g_list_nth_data(aim_users, index));
 	} else if (!strncasecmp(command, "signoff", 7)) {
-		char *who = SvPV(ST(1), junk);
-		struct gaim_connection *gc = find_gaim_conn_by_name(who);
-		if (gc) signoff(gc);
+		struct gaim_connection *gc = (struct gaim_connection *)SvIV(ST(1));
+		if (g_slist_find(connections, gc)) signoff(gc);
 		else signoff_all(NULL, NULL);
 	} else if (!strncasecmp(command, "info", 4)) {
-	        GSList *c = connections;
-		struct gaim_connection *gc;
-		while (c) {
-		        gc = (struct gaim_connection *)c->data;
-			serv_set_info(gc, SvPV(ST(1), junk));
-			c = c->next;
-		}
+		struct gaim_connection *gc = (struct gaim_connection *)SvIV(ST(1));
+		if (g_slist_find(connections, gc))
+			serv_set_info(gc, SvPV(ST(2), junk));
 	} else if (!strncasecmp(command, "away", 4)) {
 		char *message = SvPV(ST(1), junk);
 		static struct away_message a;
@@ -459,7 +481,7 @@
 
 		while (c) {
 			gc = (struct gaim_connection *)c->data;
-			serv_set_idle(gc, atoi(SvPV(ST(1), junk)));
+			serv_set_idle(gc, SvIV(ST(1)));
 			gc->is_idle = 1;
 			c = c->next;
 		}
@@ -469,7 +491,7 @@
 
 		while (c) {
 			gc = (struct gaim_connection *)c->data;
-			serv_warn(gc, SvPV(ST(1), junk), atoi(SvPV(ST(2), junk)));
+			serv_warn(gc, SvPV(ST(1), junk), SvIV(ST(2)));
 			c = c->next;
 		}
 	}
@@ -479,23 +501,16 @@
 
 XS (XS_GAIM_user_info)
 {
-	GSList *c = connections;
 	struct gaim_connection *gc;
 	unsigned int junk;
 	struct buddy *buddy = NULL;
-	char *nick;
 	dXSARGS;
 	items = 0;
 
-	nick = SvPV(ST(0), junk);
-	if (!nick[0])
-		XSRETURN(0);
-	while (c) {
-		gc = (struct gaim_connection *)c->data;
-		buddy = find_buddy(gc, nick);
-		if (buddy) c = NULL;
-		else c = c->next;
-	}
+	gc = (struct gaim_connection *)SvIV(ST(0));
+	if (g_slist_find(connections, gc))
+		buddy = find_buddy(gc, SvPV(ST(1), junk));
+
 	if (!buddy)
 		XSRETURN(0);
 	XST_mPV(0, buddy->name);
@@ -519,7 +534,7 @@
 	items = 0;
 
 	nick = SvPV(ST(0), junk);
-	send = atoi(SvPV(ST(1), junk));
+	send = SvIV(ST(1));
 	what = SvPV(ST(2), junk);
 	who = SvPV(ST(3), junk);
 	
@@ -537,69 +552,86 @@
 		c = new_conversation(nick);
 		
 	write_to_conv(c, what, wflags, who, time((time_t)NULL));
+	XSRETURN(0);
 }
 
 XS (XS_GAIM_serv_send_im)
 {
-	char *nick, *what, *isauto;
+	struct gaim_connection *gc;
+	char *nick, *what;
+	int isauto;
 	int junk;
 	dXSARGS;
 	items = 0;
 
-	nick = SvPV(ST(0), junk);
-	what = SvPV(ST(1), junk);
-	isauto = SvPV(ST(2), junk);
+	gc = (struct gaim_connection *)SvIV(ST(0));
+	nick = SvPV(ST(1), junk);
+	what = SvPV(ST(2), junk);
+	isauto = SvIV(ST(3));
 
-	if (!connections)
+	if (!g_slist_find(connections, gc)) {
+		XSRETURN(0);
 		return;
-	serv_send_im(connections->data, nick, what, atoi(isauto));
+	}
+	serv_send_im(connections->data, nick, what, isauto);
+	XSRETURN(0);
 }
 
 XS (XS_GAIM_print_to_conv)
 {
-	char *nick, *what, *isauto;
+	struct gaim_connection *gc;
+	char *nick, *what;
+	int isauto;
 	struct conversation *c;
 	unsigned int junk;
 	dXSARGS;
 	items = 0;
 
-	nick = SvPV(ST(0), junk);
-	what = SvPV(ST(1), junk);
-	isauto = SvPV(ST(2), junk);
+	gc = (struct gaim_connection *)SvIV(ST(0));
+	nick = SvPV(ST(1), junk);
+	what = SvPV(ST(2), junk);
+	isauto = SvIV(ST(3));
+	if (!g_slist_find(connections, gc)) {
+		XSRETURN(0);
+		return;
+	}
 	c = find_conversation(nick);
 	if (!c)
 		c = new_conversation(nick);
 	write_to_conv(c, what, WFLAG_SEND, NULL, time((time_t)NULL));
-	serv_send_im(c->gc, nick, what, atoi(isauto) ? IM_FLAG_AWAY : 0);
+	serv_send_im(c->gc, nick, what, isauto ? IM_FLAG_AWAY : 0);
+	XSRETURN(0);
 }
 
 XS (XS_GAIM_print_to_chat)
 {
-	char *nick, *what, *tmp;
-	GSList *c = connections;
 	struct gaim_connection *gc;
+	int id;
+	char *what;
 	struct conversation *b = NULL;
 	GSList *bcs;
 	unsigned int junk;
 	dXSARGS;
 	items = 0;
 
-	nick = SvPV(ST(0), junk);
-	what = SvPV(ST(1), junk);
-	tmp = g_strdup(normalize(nick));
-	while (c) {
-		gc = (struct gaim_connection *)c->data;
-		bcs = gc->buddy_chats;
-		while (bcs) {
-			b = (struct conversation *)bcs->data;
-			if (!strcmp(normalize(b->name), tmp))
-				break;
-			bcs = bcs->next;
-			b = NULL;
-		}
-		serv_chat_send(b->gc, b->id, what);
-		c = c->next;
+	gc = (struct gaim_connection *)SvIV(ST(0));
+	id = SvIV(ST(1));
+	what = SvPV(ST(2), junk);
+
+	if (!g_slist_find(connections, gc)) {
+		XSRETURN(0);
+		return;
 	}
+	bcs = gc->buddy_chats;
+	while (bcs) {
+		b = (struct conversation *)bcs->data;
+		if (b->id == id)
+			break;
+		bcs = bcs->next;
+		b = NULL;
+	}
+	if (b)
+		serv_chat_send(gc, id, what);
 	XSRETURN(0);
 }
 
--- a/src/plugins.c	Sat Sep 22 07:02:30 2001 +0000
+++ b/src/plugins.c	Sat Sep 22 09:14:27 2001 +0000
@@ -645,7 +645,7 @@
 
 #endif /* GAIM_PLUGINS */
 
-char *event_name(enum gaim_event event)
+static char *event_name(enum gaim_event event)
 {
 	static char buf[128];
 	switch (event) {
@@ -733,6 +733,9 @@
 	case event_im_displayed_rcvd:
 		sprintf(buf, "event_im_displayed_rcvd");
 		break;
+	case event_chat_send_invite:
+		sprintf(buf, "event_chat_send_invite");
+		break;
 	default:
 		sprintf(buf, "event_unknown");
 		break;
@@ -744,134 +747,74 @@
 {
 #ifdef USE_PERL
 	char buf[BUF_LONG];
-	char *tmp;
 #endif
 #ifdef GAIM_PLUGINS
 	GList *c = callbacks;
 	struct gaim_callback *g;
 
 	while (c) {
+		void (*zero)(void *);
+		void (*one)(void *, void *);
+		void (*two)(void *, void *, void *);
+		void (*three)(void *, void *, void *, void *);
+		void (*four)(void *, void *, void *, void *, void *);
+
 		g = (struct gaim_callback *)c->data;
 		if (g->event == event && g->function !=NULL) {
 			switch (event) {
 
-				/* struct gaim_connection * */
-			case event_signon:
-			case event_signoff:
-				{
-					void (*function) (struct gaim_connection *, void *) =
-					    g->function;
-					(*function)(arg1, g->data);
-				}
-				break;
-
 				/* no args */
 			case event_blist_update:
 			case event_quit:
-				{
-					void (*function)(void *) = g->function;
-					(*function)(g->data);
-				}
-				break;
-
-				/* struct gaim_connection *, char **, char **, guint32 */
-			case event_im_recv:
-				{
-					void (*function)(struct gaim_connection *, char **, char **,
-							  guint32, void *) = g->function;
-					(*function)(arg1, arg2, arg3, (guint32)arg4, g->data);
-				}
+				zero = g->function;
+				(*zero)(g->data);
 				break;
 
-				/* struct gaim_connection *, char *, char ** */
-			case event_im_send:
-			case event_im_displayed_sent:
-			case event_chat_send:
-				{
-					void (*function)(struct gaim_connection *, char *, char **,
-							  void *) = g->function;
-					(*function)(arg1, arg2, arg3, g->data);
-				}
+				/* one arg */
+			case event_signon:
+			case event_signoff:
+			case event_new_conversation:
+			case event_error:
+				one = g->function;
+				(*one)(arg1, g->data);
 				break;
 
-				/* struct gaim_connection *, char * */
-			case event_chat_join:
-			case event_chat_leave:
+				/* two args */
 			case event_buddy_signon:
 			case event_buddy_signoff:
 			case event_buddy_away:
 			case event_buddy_back:
 			case event_buddy_idle:
 			case event_buddy_unidle:
+			case event_chat_leave:
 			case event_set_info:
-				{
-					void (*function)(struct gaim_connection *, char *, void *) =
-					    g->function;
-					(*function)(arg1, arg2, g->data);
-				}
+			case event_draw_menu:
+				two = g->function;
+				(*two)(arg1, arg2, g->data);
 				break;
 
-				/* char * */
-			case event_new_conversation:
-				{
-					void (*function)(char *, void *) = g->function;
-					(*function)(arg1, g->data);
-				}
-				break;
-
-				/* struct gaim_connection *, char *, char *, char * */
-			case event_chat_invited:
-			case event_chat_recv:
-				{
-					void (*function)(struct gaim_connection *, char *, char *,
-							  char *, void *) = g->function;
-					(*function)(arg1, arg2, arg3, arg4, g->data);
-				}
-				break;
-
-				/* struct gaim_connection *, char *, char * */
+				/* three args */
+			case event_im_send:
+			case event_im_displayed_sent:
+			case event_chat_join:
 			case event_chat_buddy_join:
 			case event_chat_buddy_leave:
+			case event_chat_send:
 			case event_away:
 			case event_back:
-				{
-					void (*function)(struct gaim_connection *, char *, char *,
-							  void *) = g->function;
-					(*function)(arg1, arg2, arg3, g->data);
-				}
-				break;
-
-				/* struct gaim_connection *, char *, char *, guint32 */
-			case event_im_displayed_rcvd:
-				{
-					void (*function)(struct gaim_connection *, char *, char *,
-							  guint32, void *) = g->function;
-					(*function)(arg1, arg2, arg3, (guint32)arg4, g->data);
-				}
+			case event_warned:
+				three = g->function;
+				(*three)(arg1, arg2, arg3, g->data);
 				break;
 
-				/* struct gaim_connection *, char *, int */
-			case event_warned:
-				{
-					void (*function)(struct gaim_connection *, char *, int,
-							void *) = g->function;
-					(*function)(arg1, arg2, (int)arg3, g->data);
-				}
-				break;
-
-				/* int */
-			case event_error:
-				{
-					void (*function)(int, void *) = g->function;
-					(*function)((int)arg1, g->data);
-				}
-				break;
-			/* GtkWidget *, char * */
-			case event_draw_menu:
-				{
-					void(*function)(GtkWidget *, char *) = g->function;
-					(*function)(arg1, arg2);
-				}
+				/* four args */
+			case event_im_recv:
+			case event_chat_recv:
+			case event_im_displayed_rcvd:
+			case event_chat_send_invite:
+			case event_chat_invited:
+				four = g->function;
+				(*four)(arg1, arg2, arg3, arg4, g->data);
 				break;
 
 			default:
@@ -885,83 +828,52 @@
 #ifdef USE_PERL
 	switch (event) {
 	case event_signon:
-		g_snprintf(buf, sizeof buf, "\"%s\"", ((struct gaim_connection *)arg1)->username);
-		break;
 	case event_signoff:
-		g_snprintf(buf, sizeof buf, "\"%s\"", ((struct gaim_connection *)arg1)->username);
-		break;
 	case event_away:
-		g_snprintf(buf, sizeof buf, "\"%s\"", ((struct gaim_connection *)arg1)->username);
-		break;
 	case event_back:
-		g_snprintf(buf, sizeof buf, "\"%s\"", ((struct gaim_connection *)arg1)->username);
+		g_snprintf(buf, sizeof buf, "%p", arg1);
 		break;
 	case event_im_recv:
-		g_snprintf(buf, sizeof buf, "\"%s\" \"%s\" %s",
-			   ((struct gaim_connection *)arg1)->username,
+		g_snprintf(buf, sizeof buf, "%p \"%s\" %s", arg1,
 			   *(char **)arg2 ? *(char **)arg2 : "(null)",
 			   *(char **)arg3 ? *(char **)arg3 : "(null)");
 		break;
 	case event_im_send:
-		g_snprintf(buf, sizeof buf, "\"%s\" \"%s\" %s",
-			   ((struct gaim_connection *)arg1)->username, (char *)arg2,
-			   *(char **)arg3 ? *(char **)arg3 : "(null)");
+		g_snprintf(buf, sizeof buf, "%p \"%s\" %s", arg1,
+			   (char *)arg2, *(char **)arg3 ? *(char **)arg3 : "(null)");
 		break;
 	case event_buddy_signon:
-		g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg2);
-		break;
 	case event_buddy_signoff:
-		g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg2);
-		break;
 	case event_set_info:
-		g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg2);
-		break;
 	case event_buddy_away:
-		g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg2);
-		break;
 	case event_buddy_back:
-		g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg2);
-		break;
 	case event_buddy_idle:
-		g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg2);
-		break;
 	case event_buddy_unidle:
-		g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg2);
-		break;
-	case event_blist_update:
-		buf[0] = 0;
+		g_snprintf(buf, sizeof buf, "%p \"%s\"", arg1, (char *)arg2);
 		break;
 	case event_chat_invited:
-		g_snprintf(buf, sizeof buf, "\"%s\" \"%s\" %s", (char *)arg2, (char *)arg3,
-			   arg4 ? (char *)arg4 : "");
+		g_snprintf(buf, sizeof buf, "%p \"%s\" \"%s\" %s", arg1,
+				(char *)arg2, (char *)arg3, arg4 ? (char *)arg4 : "");
 		break;
 	case event_chat_join:
-		g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg2);
+	case event_chat_buddy_join:
+	case event_chat_buddy_leave:
+		g_snprintf(buf, sizeof buf, "%p %d \"%s\"", arg1, (int)arg2, (char *)arg3);
 		break;
 	case event_chat_leave:
-		g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg2);
-		break;
-	case event_chat_buddy_join:
-		g_snprintf(buf, sizeof buf, "\"%s\" \"%s\"", (char *)arg2, (char *)arg3);
-		break;
-	case event_chat_buddy_leave:
-		g_snprintf(buf, sizeof buf, "\"%s\" \"%s\"", (char *)arg2, (char *)arg3);
+		g_snprintf(buf, sizeof buf, "%p %d", arg1, (int)arg2);
 		break;
 	case event_chat_recv:
-		g_snprintf(buf, sizeof buf, "\"%s\" \"%s\" %s", (char *)arg2, (char *)arg3,
-			   (char *)arg4);
+	case event_chat_send_invite:
+		g_snprintf(buf, sizeof buf, "%p %d \"%s\" %s", arg1,
+				(int)arg2, (char *)arg3, (char *)arg4);
 		break;
 	case event_chat_send:
-		g_snprintf(buf, sizeof buf, "\"%s\" %s", (char *)arg2,
+		g_snprintf(buf, sizeof buf, "%p %d %s", arg1, (int)arg2,
 				*(char **)arg3 ? *(char **)arg3 : "(null)");
 		break;
 	case event_warned:
-		g_snprintf(buf, sizeof buf, "\"%s\" \"%s\" %d",
-			   ((struct gaim_connection *)arg1)->username,
-			   arg2 ? (char *)arg2 : "", (int)arg3);
-		break;
-	case event_error:
-		g_snprintf(buf, sizeof buf, "%d", (int)arg1);
+		g_snprintf(buf, sizeof buf, "%p \"%s\" %d", arg1, arg2 ? (char *)arg2 : "", (int)arg3);
 		break;
 	case event_quit:
 		buf[0] = 0;
@@ -969,25 +881,18 @@
 	case event_new_conversation:
 		g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg1);
 		break;
-	case event_draw_menu:
-		g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg2);
-		break;
 	case event_im_displayed_sent:
-		g_snprintf(buf, sizeof buf, "\"%s\" \"%s\" %s",
-			   ((struct gaim_connection *)arg1)->username, (char *)arg2,
-			   *(char **)arg3 ? *(char **)arg3 : "(null)");
+		g_snprintf(buf, sizeof buf, "%p \"%s\" %s", arg1,
+				(char *)arg2, *(char **)arg3 ? *(char **)arg3 : "(null)");
 		break;
 	case event_im_displayed_rcvd:
-		g_snprintf(buf, sizeof buf, "\"%s\" \"%s\" %s",
-			   ((struct gaim_connection *)arg1)->username, (char *)arg2,
-			   (char *)arg3 ? (char *)arg3 : "(null)");
+		g_snprintf(buf, sizeof buf, "%p \"%s\" %s", arg1,
+				(char *)arg2, (char *)arg3 ? (char *)arg3 : "(null)");
 		break;
 	default:
-		break;
+		return 0;
 	}
-	tmp = event_name(event);
-	debug_printf("%s: %s\n", tmp, buf);
-	return perl_event(tmp, buf);
+	return perl_event(event_name(event), buf);
 #else
 	return 0;
 #endif
--- a/src/server.c	Sat Sep 22 07:02:30 2001 +0000
+++ b/src/server.c	Sat Sep 22 09:14:27 2001 +0000
@@ -302,6 +302,7 @@
 
 void serv_chat_invite(struct gaim_connection *g, int id, char *message, char *name)
 {
+	plugin_event(event_chat_send_invite, g, (void *)id, name, message);
 	if (g->prpl && g->prpl->chat_invite)
 		(*g->prpl->chat_invite)(g, id, message, name);
 }
@@ -836,7 +837,7 @@
 {
 	struct conversation *b;
 
-	plugin_event(event_chat_join, gc, name, 0, 0);
+	plugin_event(event_chat_join, gc, (void *)id, name, 0);
 
 	b = (struct conversation *)g_new0(struct conversation, 1);
 	gc->buddy_chats = g_slist_append(gc->buddy_chats, b);
@@ -894,7 +895,7 @@
 	if (!b)
 		return;
 
-	plugin_event(event_chat_leave, g, b->name, 0, 0);
+	plugin_event(event_chat_leave, g, (void *)b->id, 0, 0);
 
 	debug_printf("Leaving room %s.\n", b->name);
 
@@ -921,7 +922,7 @@
 	if (!b)
 		return;
 
-	if (plugin_event(event_chat_recv, g, b->name, who, message))
+	if (plugin_event(event_chat_recv, g, (void *)b->id, who, message))
 		 return;
 
 	buf = g_malloc(MAX(strlen(message) * 2, 8192));