changeset 15904:15cccdd32321

Changes that give crazychat a better chance of compiling with purple and pidgin
author Mark Doliner <mark@kingant.net>
date Sun, 25 Mar 2007 01:05:56 +0000
parents 402236ee7981
children 6f04fe174f40
files pidgin/plugins/crazychat/Makefile.am pidgin/plugins/crazychat/cc_gaim_plugin.c pidgin/plugins/crazychat/cc_pidgin_plugin.c
diffstat 3 files changed, 491 insertions(+), 491 deletions(-) [+]
line wrap: on
line diff
--- a/pidgin/plugins/crazychat/Makefile.am	Sun Mar 25 01:01:22 2007 +0000
+++ b/pidgin/plugins/crazychat/Makefile.am	Sun Mar 25 01:05:56 2007 +0000
@@ -1,8 +1,8 @@
-plugindir = $(libdir)/gaim
+plugindir = $(libdir)/pidgin
 
 if ENABLE_DEBUG
 DEBUG_CPPFLAGS = -g -pg
-# DEBUG_CPPFLAGS = -D_DEBUG_ -g -pg 
+# DEBUG_CPPFLAGS = -D_DEBUG_ -g -pg
 DEBUG_LFLAGS = -pg
 else
 DEBUG_CPPFLAGS = -O2
@@ -18,7 +18,7 @@
 endif
 
 crazychat_la_LDFLAGS = -module -avoid-version $(GTK_LIBS) $(DEBUG_LFLAGS)
-crazychat_la_SOURCES = cc_gaim_plugin.c cc_gtk_gl.c cc_gtk_gl.h \
+crazychat_la_SOURCES = cc_pidgin_plugin.c cc_gtk_gl.c cc_gtk_gl.h \
 	cc_interface.h crazychat.c crazychat.h util.h\
 	cc_network.c cc_network.h filter.c filter.h\
 	cc_output.c face.c face.h doggy.c doggy.h glm.h glm.c sharky.h sharky.c models.h models.c
@@ -31,9 +31,9 @@
 #$(GTKGLEXT_CFLAGS) \
 #-I$(top_srcdir)/include
 
-AM_CPPFLAGS = -DGAIM_PLUGINS \
-	-I$(top_srcdir)/libgaim \
-	-I$(top_srcdir)/gtk \
+AM_CPPFLAGS = -DPURPLE_PLUGINS \
+	-I$(top_srcdir)/libpurple \
+	-I$(top_srcdir)/pidgin \
 	$(GTK_CFLAGS) \
 	$(GTKGLEXT_CFLAGS) \
 	$(DEBUG_CPPFLAGS) \
--- a/pidgin/plugins/crazychat/cc_gaim_plugin.c	Sun Mar 25 01:01:22 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,485 +0,0 @@
-#include <stdio.h>
-#include <assert.h>
-
-#include "internal.h"
-#include "plugin.h"
-#include "gtkplugin.h"
-#include "gtkblist.h"
-#include "gtkutils.h"
-#include "connection.h"
-#include "conversation.h"
-#include "network.h"
-
-#include <gtk/gtkgl.h>
-#include <GL/gl.h>
-#include <GL/glu.h>
-
-#include "crazychat.h"
-#include "cc_network.h"
-#include "cc_interface.h"
-#include "cc_gtk_gl.h"
-#include "util.h"
-
-/* --- begin type and global variable definitions --- */
-
-static struct crazychat cc_info;
-
-/* --- begin function declarations --- */
-
-/**
- * Called by purple plugin to start CrazyChat
- * @param cc	the crazychat struct
- */
-static void cc_init(struct crazychat *cc);
-
-/**
- * Called by purple plugin to destroy CrazyChat
- * @param cc	the crazychat struct
- */
-static void cc_destroy(struct crazychat *cc);
-
-
-/**
- * Buddy menu drawing callback.  Adds a CrazyChat menuitem.
- * @param menu	the buddy menu widget
- * @param b	the buddy whose menu this is
- */
-static gboolean cc_buddy_menu(GtkWidget *menu, PurpleBuddy *b);
-
-/**
- * Buddy menu callback.  Initiates the CrazyChat session.
- * @param item	the gtk buddy menu item
- * @param b	the buddy whose menu the item was in
- */
-static void cc_menu_cb(GtkMenuItem *item, PurpleBuddy *b);
-
-/**
- * IM callback.  Handles receiving a CrazyChat session request.
- * @param account	the account we received the IM on
- * @param sender	the buddy who we received the message from
- * @param message	the message we received
- * @param flags		IM flags
- * @param data		user data
- */
-static gboolean receive_im_cb(PurpleAccount *account, char **sender,
-		char **message,	int *flags, void *data);
-
-/**
- * Displaying IM callback.  Drops CrazyChat messages from IM window.
- * @param account	the account we are displaying the IM on
- * @param conv		the conversation we are displaying the IM on
- * @param message	the message we are displaying
- * @param data		user data
- */
-static gboolean display_im_cb(PurpleAccount *account, const char *who, char **message,
-			PurpleConnection *conv, PurpleMessageFlags flags, void *data);
-
-/**
- * Callback for CrazyChat plugin configuration frame
- * @param plugin	the plugin data
- * @return	the configuration frame
- */
-static GtkWidget *get_config_frame(PurplePlugin *plugin);
-
-/**
- * TCP port callback.  Changes the port used to listen for new CC sessions
- * @param spin		the spinner button whose value changed
- * @param data		user data
- */
-static void tcp_port_cb(GtkSpinButton *spin, struct crazychat *cc);
-
-/**
- * UDP port callback.  Changes the port used to send/recv CC session frames
- * @param spin		the spinner button whose value changed
- * @param data		user data
- */
-static void udp_port_cb(GtkSpinButton *spin, struct crazychat *cc);
-
-/**
- * Features enabling/disabling callback.  Initializes the input processing
- * or shuts it down.
- * @param data		user data
- */
-static void features_enable_cb(struct crazychat *cc);
-
-/**
- * User signed on callback.  Now we have a buddy list to connect a signal
- * handler to.
- * @param gc		the purple connection we are signed on
- * @param plugin	our plugin struct
- */
-static gboolean cc_signed_on(PurpleConnection *gc, void *plugin);
-
-/**
- * Plugin loading callback.  If a buddy list exists, connect our buddy menu
- * drawing callback to the signal handler, otherwise, connect a signed on
- * signal handler so we know when we get a buddy list.
- * @param plugin	our plugin struct
- */
-static gboolean plugin_load(PurplePlugin *plugin);
-
-/**
- * Plugin unloading callback.  Disconnect all handlers and free data.
- * @param plugin	our plugin struct
- */
-static gboolean plugin_unload(PurplePlugin *plugin);
-
-
-/* --- end function declarations --- */
-
-
-#define CRAZYCHAT_PLUGIN_ID "gtk-crazychat"
-
-static PidginPluginUiInfo ui_info = {
-	get_config_frame				/**< get_config_frame */
-};
-
-static PurplePluginInfo info = {
-	2,						  /**< api_version    */
-	PURPLE_PLUGIN_STANDARD,				  /**< type           */
-	PIDGIN_PLUGIN_TYPE,				  /**< ui_requirement */
-	0,						  /**< flags          */
-	NULL,						  /**< dependencies   */
-	PURPLE_PRIORITY_DEFAULT,				  /**< priority       */
-
-	CRAZYCHAT_PLUGIN_ID,				  /**< id             */
-	N_("Crazychat"),				  /**< name           */
-	VERSION,					  /**< version        */
-							  /**  summary        */
-	N_("Plugin to establish a Crazychat session."),
-							  /**  description    */
-	N_("Uses Purple to obtain buddy ips to connect for a Crazychat session"),
-	"\n"
-	"William Chan <chanman@stanford.edu>\n"
-	"Ian Spiro <ispiro@stanford.edu>\n"
-	"Charlie Stockman<stockman@stanford.edu>\n"
-	"Steve Yelderman<scy@stanford.edu>",		  /**< author         */
-	PURPLE_WEBSITE,					  /**< homepage       */
-
-	plugin_load,					  /**< load           */
-	plugin_unload,					  /**< unload         */
-	NULL,						  /**< destroy        */
-
-	&ui_info,					  /**< ui_info        */
-	&cc_info					  /**< extra_info     */
-};
-
-/* --- end plugin struct definition --- */
-
-static void cc_init(struct crazychat *cc)
-{
-	/* initialize main crazychat thread */
-	
-	assert(cc);
-	memset(cc, 0, sizeof(*cc));
-
-	/* initialize network configuration */
-	cc->tcp_port = DEFAULT_CC_PORT;
-	cc->udp_port = DEFAULT_CC_PORT;
-
-	/* disable input subsystem */
-	//cc->features_state = 0;
-
-	/* initialize input subsystem */
-	cc->features_state = 1;
-	cc->input_data = init_input(cc);
-}
-
-static void cc_destroy(struct crazychat *cc)
-{
-	assert(cc);
-
-	if (cc->features_state) {
-		destroy_input(cc->input_data);
-	}
-	memset(cc, 0, sizeof(*cc));
-}
-
-static gboolean cc_buddy_menu(GtkWidget *menu, PurpleBuddy *b)
-{
-	GtkWidget *menuitem;
-
-	menuitem = gtk_menu_item_new_with_mnemonic("CrazyChat");
-	g_signal_connect(G_OBJECT(menuitem), "activate",
-			G_CALLBACK(cc_menu_cb), b);
-	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
-	return FALSE;
-}
-
-static void cc_menu_cb(GtkMenuItem *item, PurpleBuddy *b)
-{
-	assert(item);
-	assert(b);
-
-	/* send the invite */
-	cc_net_send_invite(&cc_info, b->name, b->account);
-}
-
-static gboolean receive_im_cb(PurpleAccount *account, char **sender,
-		char **message,	int *flags, void *data)
-{
-	struct crazychat *cc;
-
-	cc = (struct crazychat*)data;
-	assert(cc);
-	if (!strncmp(*message, CRAZYCHAT_INVITE_CODE,
-				strlen(CRAZYCHAT_INVITE_CODE))) {
-		Debug(*message);
-		char *split = strchr(*message, '!');
-		assert(split);
-		*split = 0;
-		split++;
-		cc_net_recv_invite(account, cc, *sender,
-				&(*message)[strlen(CRAZYCHAT_INVITE_CODE)],
-				split);
-		return TRUE;
-	} else if (!strncmp(*message, CRAZYCHAT_ACCEPT_CODE,
-				strlen(CRAZYCHAT_ACCEPT_CODE))) {
-		cc_net_recv_accept(account, cc, *sender,
-				&(*message)[strlen(CRAZYCHAT_ACCEPT_CODE)]);
-		return TRUE;
-	} else if (!strncmp(*message, CRAZYCHAT_READY_CODE,
-				strlen(CRAZYCHAT_READY_CODE))) {
-		cc_net_recv_ready(account, cc, *sender);
-		return TRUE;
-	}
-	
-	return FALSE;
-}
-
-static gboolean display_im_cb(PurpleAccount *account, PurpleConversation *conv,
-		char **message, void *data)
-{
-	struct crazychat *cc;
-
-	cc = (struct crazychat*)data;
-	assert(cc);
-	if (!strncmp(*message, CRAZYCHAT_INVITE_CODE,
-				strlen(CRAZYCHAT_INVITE_CODE))) {
-		return TRUE;
-	} else if (!strncmp(*message, CRAZYCHAT_ACCEPT_CODE,
-				strlen(CRAZYCHAT_ACCEPT_CODE))) {
-		return TRUE;
-	} else if (!strncmp(*message, CRAZYCHAT_READY_CODE,
-				strlen(CRAZYCHAT_READY_CODE))) {
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-static GtkWidget *get_config_frame(PurplePlugin *plugin)
-{
-	GtkWidget *ret;
-	GtkWidget *frame;
-	GtkWidget *vbox, *hbox;
-	GtkWidget *drawing_area;
-	GtkWidget *label;
-	GtkAdjustment *adj;
-	GtkWidget *spinner;
-	GtkWidget *button, *button1, *button2;
-	GSList *group;
-	struct draw_info *info;
-	struct crazychat *cc;
-
-	cc = (struct crazychat*)plugin->info->extra_info;
-	assert(cc);
-
-	/* create widgets */
-
-	/* creating the config frame */
-	ret = gtk_vbox_new(FALSE, 18);
-	gtk_container_set_border_width(GTK_CONTAINER(ret), 12);
-
-	/* make the network configuration frame */
-	frame = pidgin_make_frame(ret, _("Network Configuration"));
-	gtk_widget_show(frame);
-
-	/* add boxes for packing purposes */
-	vbox = gtk_vbox_new(FALSE, 0);
-	gtk_box_pack_start(GTK_BOX(frame), vbox, TRUE, TRUE, 0);
-	gtk_widget_show(vbox);
-
-	/* add widgets to row 1 */
-	hbox = gtk_hbox_new(FALSE, 0);
-	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-	gtk_widget_show(hbox);
-	label = gtk_label_new(_("TCP port"));
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 15);
-	gtk_widget_show(label);
-	adj = (GtkAdjustment*)gtk_adjustment_new(DEFAULT_CC_PORT, 1,
-			G_MAXUSHORT, 1, 1000, 0);
-	spinner = gtk_spin_button_new(adj, 1, 0);
-	g_signal_connect(G_OBJECT(spinner), "value_changed",
-			G_CALLBACK(tcp_port_cb), cc);
-	gtk_box_pack_start(GTK_BOX(hbox), spinner, FALSE, FALSE, 0);
-	gtk_widget_show(spinner);
-	label = gtk_label_new(_("UDP port"));
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 15);
-	gtk_widget_show(label);
-	adj = (GtkAdjustment*)gtk_adjustment_new(DEFAULT_CC_PORT, 1,
-			G_MAXUSHORT, 1, 1000, 0);
-	spinner = gtk_spin_button_new(adj, 1, 0);
-	g_signal_connect(G_OBJECT(spinner), "value_changed",
-			G_CALLBACK(udp_port_cb), cc);
-	gtk_box_pack_start(GTK_BOX(hbox), spinner, FALSE, FALSE, 0);
-	gtk_widget_show(spinner);
-
-	/* make the feature configuration frame */
-	frame = pidgin_make_frame(ret, _("Feature Calibration"));
-	gtk_widget_show(frame);
-
-	/* add hbox for packing purposes */
-	hbox = gtk_hbox_new(TRUE, 40);
-	gtk_box_pack_start(GTK_BOX(frame), hbox, TRUE, TRUE, 0);
-	gtk_widget_show(hbox);
-
-	/* add feature calibration options */
-
-	/* add vbox for packing purposes */
-	vbox = gtk_vbox_new(TRUE, 0);
-	gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
-	gtk_widget_show(vbox);
-
-	/* add enabled / disabled */
-	button1 = gtk_radio_button_new_with_label(NULL, _("Enabled"));
-	gtk_box_pack_start(GTK_BOX(vbox), button1, TRUE, TRUE, 0);
-	gtk_widget_show(button1);
-	
-	group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button1));
-	button2 = gtk_radio_button_new_with_label(group, _("Disabled"));
-	gtk_box_pack_start(GTK_BOX(vbox), button2, TRUE, TRUE, 0);
-	gtk_widget_show(button2);
-
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button1),
-			cc->features_state);
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button2),
-			!cc->features_state);
-	g_signal_connect_swapped(G_OBJECT(button1), "toggled",
-			G_CALLBACK(features_enable_cb), cc);
-
-	/* add vbox for packing purposes */
-	vbox = gtk_vbox_new(TRUE, 0);
-	gtk_box_pack_end(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
-	gtk_widget_show(vbox);
-
-	/* add calibrate button */
-	button = gtk_button_new_with_label("Calibrate");
-	gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, FALSE, 0);
-	gtk_widget_show(button);
-	
-	gtk_widget_show(ret);
-	
-	return ret;
-}
-
-static void tcp_port_cb(GtkSpinButton *spin, struct crazychat *cc)
-{
-	assert(spin);
-	assert(cc);
-	cc->tcp_port = gtk_spin_button_get_value_as_int(spin);
-	Debug("New tcp port: %d\n", cc->tcp_port);
-}
-
-static void udp_port_cb(GtkSpinButton *spin, struct crazychat *cc)
-{
-	assert(spin);
-	assert(cc);
-	cc->udp_port = gtk_spin_button_get_value_as_int(spin);
-	Debug("New udp port: %d\n", cc->udp_port);
-}
-
-static void features_enable_cb(struct crazychat *cc)
-{
-	Debug("Changing features state\n");
-	cc->features_state = !cc->features_state;
-	if (cc->features_state) {
-		cc->input_data = init_input(cc);
-	} else {
-		if (cc->input_data) {
-			gtk_widget_destroy(cc->input_data->widget);
-		}
-	}
-}
-
-static gboolean cc_signed_on(PurpleConnection *gc, void *plugin)
-{
-	struct crazychat *extra;
-	void *conv_handle;
-
-	assert(plugin);
-	extra = (struct crazychat*)((PurplePlugin*)plugin)->info->extra_info;
-	purple_signal_disconnect
-	    (purple_connections_get_handle(), "signed-on",
-	     plugin, PURPLE_CALLBACK(cc_signed_on));
-	purple_signal_connect(PIDGIN_BLIST
-			    (purple_get_blist()),
-			    "drawing-menu", plugin,
-			    PURPLE_CALLBACK(cc_buddy_menu), NULL);
-	conv_handle = purple_conversations_get_handle();
-	purple_signal_connect(conv_handle, "received-im-msg", plugin,
-		PURPLE_CALLBACK(receive_im_cb), extra);
-	purple_signal_connect(conv_handle, "displaying-im-msg", plugin,
-		PURPLE_CALLBACK(display_im_cb), extra);
-	return FALSE;
-}
-
-static gboolean plugin_load(PurplePlugin *plugin)
-{
-	PurpleBuddyList *buddy_list;
-	void *conv_handle;
-
-	if (cc_init_gtk_gl())
-		return FALSE;
-
-	cc_init(&cc_info);
-	buddy_list = purple_get_blist();
-	if (buddy_list) {
-		purple_signal_connect(PIDGIN_BLIST
-				    (buddy_list),
-				    "drawing-menu", plugin,
-				    PURPLE_CALLBACK(cc_buddy_menu), NULL);
-		conv_handle = purple_conversations_get_handle();
-		purple_signal_connect(conv_handle, "received-im-msg", plugin,
-			PURPLE_CALLBACK(receive_im_cb), &cc_info);
-		purple_signal_connect(conv_handle, "displaying-im-msg", plugin,
-			PURPLE_CALLBACK(display_im_cb), &cc_info);
-	} else {
-		purple_signal_connect
-		    (purple_connections_get_handle(), "signed-on",
-		     plugin, PURPLE_CALLBACK(cc_signed_on), plugin);
-	}
-
-	Debug("CrazyChat plugin loaded.\n");
-	
-	return TRUE;
-}
-
-static gboolean plugin_unload(PurplePlugin *plugin)
-{
-	void *conv_handle;
-	struct crazychat *extra;
-	assert(plugin);
-	extra = (struct crazychat*) plugin->info->extra_info;
-	cc_destroy(extra);
-	conv_handle = purple_conversations_get_handle();
-	purple_signal_disconnect(PIDGIN_BLIST
-			       (purple_get_blist()),
-			       "drawing-menu", plugin,
-			       PURPLE_CALLBACK(cc_buddy_menu));
-	purple_signal_disconnect(conv_handle, "received-im", plugin,
-			       PURPLE_CALLBACK(receive_im_cb));
-	purple_signal_disconnect(conv_handle, "displaying-im-msg", plugin,
-			       PURPLE_CALLBACK(display_im_cb));
-	Debug("CrazyChat plugin unloaded.\n");
-	return TRUE;
-}
-
-static void init_plugin(PurplePlugin *plugin)
-{
-	gtk_gl_init(NULL, NULL);
-	memset(&cc_info, 0, sizeof(cc_info));
-	Debug("CrazyChat plugin initialized\n");
-}
-
-PURPLE_INIT_PLUGIN(crazychat, init_plugin, info)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/plugins/crazychat/cc_pidgin_plugin.c	Sun Mar 25 01:05:56 2007 +0000
@@ -0,0 +1,485 @@
+#include <stdio.h>
+#include <assert.h>
+
+#include "internal.h"
+#include "plugin.h"
+#include "gtkplugin.h"
+#include "gtkblist.h"
+#include "gtkutils.h"
+#include "connection.h"
+#include "conversation.h"
+#include "network.h"
+
+#include <gtk/gtkgl.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+
+#include "crazychat.h"
+#include "cc_network.h"
+#include "cc_interface.h"
+#include "cc_gtk_gl.h"
+#include "util.h"
+
+/* --- begin type and global variable definitions --- */
+
+static struct crazychat cc_info;
+
+/* --- begin function declarations --- */
+
+/**
+ * Called by purple plugin to start CrazyChat
+ * @param cc	the crazychat struct
+ */
+static void cc_init(struct crazychat *cc);
+
+/**
+ * Called by purple plugin to destroy CrazyChat
+ * @param cc	the crazychat struct
+ */
+static void cc_destroy(struct crazychat *cc);
+
+
+/**
+ * Buddy menu drawing callback.  Adds a CrazyChat menuitem.
+ * @param menu	the buddy menu widget
+ * @param b	the buddy whose menu this is
+ */
+static gboolean cc_buddy_menu(GtkWidget *menu, PurpleBuddy *b);
+
+/**
+ * Buddy menu callback.  Initiates the CrazyChat session.
+ * @param item	the gtk buddy menu item
+ * @param b	the buddy whose menu the item was in
+ */
+static void cc_menu_cb(GtkMenuItem *item, PurpleBuddy *b);
+
+/**
+ * IM callback.  Handles receiving a CrazyChat session request.
+ * @param account	the account we received the IM on
+ * @param sender	the buddy who we received the message from
+ * @param message	the message we received
+ * @param flags		IM flags
+ * @param data		user data
+ */
+static gboolean receive_im_cb(PurpleAccount *account, char **sender,
+		char **message,	int *flags, void *data);
+
+/**
+ * Displaying IM callback.  Drops CrazyChat messages from IM window.
+ * @param account	the account we are displaying the IM on
+ * @param conv		the conversation we are displaying the IM on
+ * @param message	the message we are displaying
+ * @param data		user data
+ */
+static gboolean display_im_cb(PurpleAccount *account, const char *who, char **message,
+			PurpleConnection *conv, PurpleMessageFlags flags, void *data);
+
+/**
+ * Callback for CrazyChat plugin configuration frame
+ * @param plugin	the plugin data
+ * @return	the configuration frame
+ */
+static GtkWidget *get_config_frame(PurplePlugin *plugin);
+
+/**
+ * TCP port callback.  Changes the port used to listen for new CC sessions
+ * @param spin		the spinner button whose value changed
+ * @param data		user data
+ */
+static void tcp_port_cb(GtkSpinButton *spin, struct crazychat *cc);
+
+/**
+ * UDP port callback.  Changes the port used to send/recv CC session frames
+ * @param spin		the spinner button whose value changed
+ * @param data		user data
+ */
+static void udp_port_cb(GtkSpinButton *spin, struct crazychat *cc);
+
+/**
+ * Features enabling/disabling callback.  Initializes the input processing
+ * or shuts it down.
+ * @param data		user data
+ */
+static void features_enable_cb(struct crazychat *cc);
+
+/**
+ * User signed on callback.  Now we have a buddy list to connect a signal
+ * handler to.
+ * @param gc		the purple connection we are signed on
+ * @param plugin	our plugin struct
+ */
+static gboolean cc_signed_on(PurpleConnection *gc, void *plugin);
+
+/**
+ * Plugin loading callback.  If a buddy list exists, connect our buddy menu
+ * drawing callback to the signal handler, otherwise, connect a signed on
+ * signal handler so we know when we get a buddy list.
+ * @param plugin	our plugin struct
+ */
+static gboolean plugin_load(PurplePlugin *plugin);
+
+/**
+ * Plugin unloading callback.  Disconnect all handlers and free data.
+ * @param plugin	our plugin struct
+ */
+static gboolean plugin_unload(PurplePlugin *plugin);
+
+
+/* --- end function declarations --- */
+
+
+#define CRAZYCHAT_PLUGIN_ID "gtk-crazychat"
+
+static PidginPluginUiInfo ui_info = {
+	get_config_frame				/**< get_config_frame */
+};
+
+static PurplePluginInfo info = {
+	2,						  /**< api_version    */
+	PURPLE_PLUGIN_STANDARD,				  /**< type           */
+	PIDGIN_PLUGIN_TYPE,				  /**< ui_requirement */
+	0,						  /**< flags          */
+	NULL,						  /**< dependencies   */
+	PURPLE_PRIORITY_DEFAULT,				  /**< priority       */
+
+	CRAZYCHAT_PLUGIN_ID,				  /**< id             */
+	N_("Crazychat"),				  /**< name           */
+	VERSION,					  /**< version        */
+							  /**  summary        */
+	N_("Plugin to establish a Crazychat session."),
+							  /**  description    */
+	N_("Uses Purple to obtain buddy ips to connect for a Crazychat session"),
+	"\n"
+	"William Chan <chanman@stanford.edu>\n"
+	"Ian Spiro <ispiro@stanford.edu>\n"
+	"Charlie Stockman<stockman@stanford.edu>\n"
+	"Steve Yelderman<scy@stanford.edu>",		  /**< author         */
+	PURPLE_WEBSITE,					  /**< homepage       */
+
+	plugin_load,					  /**< load           */
+	plugin_unload,					  /**< unload         */
+	NULL,						  /**< destroy        */
+
+	&ui_info,					  /**< ui_info        */
+	&cc_info					  /**< extra_info     */
+};
+
+/* --- end plugin struct definition --- */
+
+static void cc_init(struct crazychat *cc)
+{
+	/* initialize main crazychat thread */
+	
+	assert(cc);
+	memset(cc, 0, sizeof(*cc));
+
+	/* initialize network configuration */
+	cc->tcp_port = DEFAULT_CC_PORT;
+	cc->udp_port = DEFAULT_CC_PORT;
+
+	/* disable input subsystem */
+	//cc->features_state = 0;
+
+	/* initialize input subsystem */
+	cc->features_state = 1;
+	cc->input_data = init_input(cc);
+}
+
+static void cc_destroy(struct crazychat *cc)
+{
+	assert(cc);
+
+	if (cc->features_state) {
+		destroy_input(cc->input_data);
+	}
+	memset(cc, 0, sizeof(*cc));
+}
+
+static gboolean cc_buddy_menu(GtkWidget *menu, PurpleBuddy *b)
+{
+	GtkWidget *menuitem;
+
+	menuitem = gtk_menu_item_new_with_mnemonic("CrazyChat");
+	g_signal_connect(G_OBJECT(menuitem), "activate",
+			G_CALLBACK(cc_menu_cb), b);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+	return FALSE;
+}
+
+static void cc_menu_cb(GtkMenuItem *item, PurpleBuddy *b)
+{
+	assert(item);
+	assert(b);
+
+	/* send the invite */
+	cc_net_send_invite(&cc_info, b->name, b->account);
+}
+
+static gboolean receive_im_cb(PurpleAccount *account, char **sender,
+		char **message,	int *flags, void *data)
+{
+	struct crazychat *cc;
+
+	cc = (struct crazychat*)data;
+	assert(cc);
+	if (!strncmp(*message, CRAZYCHAT_INVITE_CODE,
+				strlen(CRAZYCHAT_INVITE_CODE))) {
+		Debug(*message);
+		char *split = strchr(*message, '!');
+		assert(split);
+		*split = 0;
+		split++;
+		cc_net_recv_invite(account, cc, *sender,
+				&(*message)[strlen(CRAZYCHAT_INVITE_CODE)],
+				split);
+		return TRUE;
+	} else if (!strncmp(*message, CRAZYCHAT_ACCEPT_CODE,
+				strlen(CRAZYCHAT_ACCEPT_CODE))) {
+		cc_net_recv_accept(account, cc, *sender,
+				&(*message)[strlen(CRAZYCHAT_ACCEPT_CODE)]);
+		return TRUE;
+	} else if (!strncmp(*message, CRAZYCHAT_READY_CODE,
+				strlen(CRAZYCHAT_READY_CODE))) {
+		cc_net_recv_ready(account, cc, *sender);
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
+static gboolean display_im_cb(PurpleAccount *account, PurpleConversation *conv,
+		char **message, void *data)
+{
+	struct crazychat *cc;
+
+	cc = (struct crazychat*)data;
+	assert(cc);
+	if (!strncmp(*message, CRAZYCHAT_INVITE_CODE,
+				strlen(CRAZYCHAT_INVITE_CODE))) {
+		return TRUE;
+	} else if (!strncmp(*message, CRAZYCHAT_ACCEPT_CODE,
+				strlen(CRAZYCHAT_ACCEPT_CODE))) {
+		return TRUE;
+	} else if (!strncmp(*message, CRAZYCHAT_READY_CODE,
+				strlen(CRAZYCHAT_READY_CODE))) {
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static GtkWidget *get_config_frame(PurplePlugin *plugin)
+{
+	GtkWidget *ret;
+	GtkWidget *frame;
+	GtkWidget *vbox, *hbox;
+	GtkWidget *drawing_area;
+	GtkWidget *label;
+	GtkAdjustment *adj;
+	GtkWidget *spinner;
+	GtkWidget *button, *button1, *button2;
+	GSList *group;
+	struct draw_info *info;
+	struct crazychat *cc;
+
+	cc = (struct crazychat*)plugin->info->extra_info;
+	assert(cc);
+
+	/* create widgets */
+
+	/* creating the config frame */
+	ret = gtk_vbox_new(FALSE, 18);
+	gtk_container_set_border_width(GTK_CONTAINER(ret), 12);
+
+	/* make the network configuration frame */
+	frame = pidgin_make_frame(ret, _("Network Configuration"));
+	gtk_widget_show(frame);
+
+	/* add boxes for packing purposes */
+	vbox = gtk_vbox_new(FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(frame), vbox, TRUE, TRUE, 0);
+	gtk_widget_show(vbox);
+
+	/* add widgets to row 1 */
+	hbox = gtk_hbox_new(FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+	gtk_widget_show(hbox);
+	label = gtk_label_new(_("TCP port"));
+	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 15);
+	gtk_widget_show(label);
+	adj = (GtkAdjustment*)gtk_adjustment_new(DEFAULT_CC_PORT, 1,
+			G_MAXUSHORT, 1, 1000, 0);
+	spinner = gtk_spin_button_new(adj, 1, 0);
+	g_signal_connect(G_OBJECT(spinner), "value_changed",
+			G_CALLBACK(tcp_port_cb), cc);
+	gtk_box_pack_start(GTK_BOX(hbox), spinner, FALSE, FALSE, 0);
+	gtk_widget_show(spinner);
+	label = gtk_label_new(_("UDP port"));
+	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 15);
+	gtk_widget_show(label);
+	adj = (GtkAdjustment*)gtk_adjustment_new(DEFAULT_CC_PORT, 1,
+			G_MAXUSHORT, 1, 1000, 0);
+	spinner = gtk_spin_button_new(adj, 1, 0);
+	g_signal_connect(G_OBJECT(spinner), "value_changed",
+			G_CALLBACK(udp_port_cb), cc);
+	gtk_box_pack_start(GTK_BOX(hbox), spinner, FALSE, FALSE, 0);
+	gtk_widget_show(spinner);
+
+	/* make the feature configuration frame */
+	frame = pidgin_make_frame(ret, _("Feature Calibration"));
+	gtk_widget_show(frame);
+
+	/* add hbox for packing purposes */
+	hbox = gtk_hbox_new(TRUE, 40);
+	gtk_box_pack_start(GTK_BOX(frame), hbox, TRUE, TRUE, 0);
+	gtk_widget_show(hbox);
+
+	/* add feature calibration options */
+
+	/* add vbox for packing purposes */
+	vbox = gtk_vbox_new(TRUE, 0);
+	gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
+	gtk_widget_show(vbox);
+
+	/* add enabled / disabled */
+	button1 = gtk_radio_button_new_with_label(NULL, _("Enabled"));
+	gtk_box_pack_start(GTK_BOX(vbox), button1, TRUE, TRUE, 0);
+	gtk_widget_show(button1);
+	
+	group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button1));
+	button2 = gtk_radio_button_new_with_label(group, _("Disabled"));
+	gtk_box_pack_start(GTK_BOX(vbox), button2, TRUE, TRUE, 0);
+	gtk_widget_show(button2);
+
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button1),
+			cc->features_state);
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button2),
+			!cc->features_state);
+	g_signal_connect_swapped(G_OBJECT(button1), "toggled",
+			G_CALLBACK(features_enable_cb), cc);
+
+	/* add vbox for packing purposes */
+	vbox = gtk_vbox_new(TRUE, 0);
+	gtk_box_pack_end(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
+	gtk_widget_show(vbox);
+
+	/* add calibrate button */
+	button = gtk_button_new_with_label("Calibrate");
+	gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, FALSE, 0);
+	gtk_widget_show(button);
+	
+	gtk_widget_show(ret);
+	
+	return ret;
+}
+
+static void tcp_port_cb(GtkSpinButton *spin, struct crazychat *cc)
+{
+	assert(spin);
+	assert(cc);
+	cc->tcp_port = gtk_spin_button_get_value_as_int(spin);
+	Debug("New tcp port: %d\n", cc->tcp_port);
+}
+
+static void udp_port_cb(GtkSpinButton *spin, struct crazychat *cc)
+{
+	assert(spin);
+	assert(cc);
+	cc->udp_port = gtk_spin_button_get_value_as_int(spin);
+	Debug("New udp port: %d\n", cc->udp_port);
+}
+
+static void features_enable_cb(struct crazychat *cc)
+{
+	Debug("Changing features state\n");
+	cc->features_state = !cc->features_state;
+	if (cc->features_state) {
+		cc->input_data = init_input(cc);
+	} else {
+		if (cc->input_data) {
+			gtk_widget_destroy(cc->input_data->widget);
+		}
+	}
+}
+
+static gboolean cc_signed_on(PurpleConnection *gc, void *plugin)
+{
+	struct crazychat *extra;
+	void *conv_handle;
+
+	assert(plugin);
+	extra = (struct crazychat*)((PurplePlugin*)plugin)->info->extra_info;
+	purple_signal_disconnect
+	    (purple_connections_get_handle(), "signed-on",
+	     plugin, PURPLE_CALLBACK(cc_signed_on));
+	purple_signal_connect(PIDGIN_BLIST
+			    (purple_get_blist()),
+			    "drawing-menu", plugin,
+			    PURPLE_CALLBACK(cc_buddy_menu), NULL);
+	conv_handle = purple_conversations_get_handle();
+	purple_signal_connect(conv_handle, "received-im-msg", plugin,
+		PURPLE_CALLBACK(receive_im_cb), extra);
+	purple_signal_connect(conv_handle, "displaying-im-msg", plugin,
+		PURPLE_CALLBACK(display_im_cb), extra);
+	return FALSE;
+}
+
+static gboolean plugin_load(PurplePlugin *plugin)
+{
+	PurpleBuddyList *buddy_list;
+	void *conv_handle;
+
+	if (cc_init_gtk_gl())
+		return FALSE;
+
+	cc_init(&cc_info);
+	buddy_list = purple_get_blist();
+	if (buddy_list) {
+		purple_signal_connect(PIDGIN_BLIST
+				    (buddy_list),
+				    "drawing-menu", plugin,
+				    PURPLE_CALLBACK(cc_buddy_menu), NULL);
+		conv_handle = purple_conversations_get_handle();
+		purple_signal_connect(conv_handle, "received-im-msg", plugin,
+			PURPLE_CALLBACK(receive_im_cb), &cc_info);
+		purple_signal_connect(conv_handle, "displaying-im-msg", plugin,
+			PURPLE_CALLBACK(display_im_cb), &cc_info);
+	} else {
+		purple_signal_connect
+		    (purple_connections_get_handle(), "signed-on",
+		     plugin, PURPLE_CALLBACK(cc_signed_on), plugin);
+	}
+
+	Debug("CrazyChat plugin loaded.\n");
+	
+	return TRUE;
+}
+
+static gboolean plugin_unload(PurplePlugin *plugin)
+{
+	void *conv_handle;
+	struct crazychat *extra;
+	assert(plugin);
+	extra = (struct crazychat*) plugin->info->extra_info;
+	cc_destroy(extra);
+	conv_handle = purple_conversations_get_handle();
+	purple_signal_disconnect(PIDGIN_BLIST
+			       (purple_get_blist()),
+			       "drawing-menu", plugin,
+			       PURPLE_CALLBACK(cc_buddy_menu));
+	purple_signal_disconnect(conv_handle, "received-im", plugin,
+			       PURPLE_CALLBACK(receive_im_cb));
+	purple_signal_disconnect(conv_handle, "displaying-im-msg", plugin,
+			       PURPLE_CALLBACK(display_im_cb));
+	Debug("CrazyChat plugin unloaded.\n");
+	return TRUE;
+}
+
+static void init_plugin(PurplePlugin *plugin)
+{
+	gtk_gl_init(NULL, NULL);
+	memset(&cc_info, 0, sizeof(cc_info));
+	Debug("CrazyChat plugin initialized\n");
+}
+
+PURPLE_INIT_PLUGIN(crazychat, init_plugin, info)