diff src/protocols/yahoo/yahoo_doodle.c @ 11475:7fab28c991f3

[gaim-migrate @ 13717] merging gaim-doodle/whiteboard/whatever you like to call it. Needs some cleanups and doxygen comments, but has basic functionality committer: Tailor Script <tailor@pidgin.im>
author Gary Kramlich <grim@reaperworld.com>
date Fri, 09 Sep 2005 04:40:21 +0000
parents
children 4aa1de1f5545
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/yahoo/yahoo_doodle.c	Fri Sep 09 04:40:21 2005 +0000
@@ -0,0 +1,728 @@
+/*
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+// INCLUDES ============================================================================================
+
+#include "internal.h"
+
+#include "account.h"
+#include "accountopt.h"
+#include "blist.h"
+#include "cipher.h"
+#include "cmds.h"
+#include "debug.h"
+#include "notify.h"
+#include "privacy.h"
+#include "prpl.h"
+#include "proxy.h"
+#include "request.h"
+#include "server.h"
+#include "util.h"
+#include "version.h"
+
+#include "yahoo.h"
+#include "yahoo_packet.h"
+#include "yahoo_friend.h"
+#include "yahoochat.h"
+#include "ycht.h"
+#include "yahoo_auth.h"
+#include "yahoo_filexfer.h"
+#include "yahoo_picture.h"
+
+#include "whiteboard.h"
+#include "yahoo_doodle.h"
+
+// GLOBALS =============================================================================================
+
+const int DefaultColorRGB24[]	=
+{
+	DOODLE_COLOR_RED,
+	DOODLE_COLOR_ORANGE,
+	DOODLE_COLOR_YELLOW,
+	DOODLE_COLOR_GREEN,
+	DOODLE_COLOR_CYAN,
+	DOODLE_COLOR_BLUE,
+	DOODLE_COLOR_VIOLET,
+	DOODLE_COLOR_PURPLE,
+	DOODLE_COLOR_TAN,
+	DOODLE_COLOR_BROWN,
+	DOODLE_COLOR_BLACK,
+	DOODLE_COLOR_GREY,
+	DOODLE_COLOR_WHITE
+};
+
+// FUNCTIONS ============================================================================================
+
+GaimCmdRet yahoo_doodle_gaim_cmd_start( GaimConversation *conv, const char *cmd, char **args, char **error, void *data )
+{
+	if( *args && args[0] )
+		return( GAIM_CMD_RET_FAILED );
+	
+	GaimAccount		*account	= gaim_conversation_get_account( conv );
+	GaimConnection		*gc		= gaim_account_get_connection( account );
+	char			*to		= ( char* )( gaim_conversation_get_name( conv ) );
+	GaimWhiteboard		*wb		= gaim_whiteboard_get_session( account, to );
+	
+	// NOTE Functionalize this code?
+	
+	if( wb == NULL )
+	{
+		// Insert this 'session' in the list.  At this point, it's only a requested session.	
+		wb = gaim_whiteboard_create( account, to, DOODLE_STATE_REQUESTING );
+	}
+	//else
+	//	; // NOTE Perhaps some careful handling of remote assumed established sessions
+	
+	yahoo_doodle_command_send_request( gc, to );
+	yahoo_doodle_command_send_ready( gc, to );
+	
+	// Write a local message to this conversation showing that
+	// a request for a Doodle session has been made
+	gaim_conv_im_write( GAIM_CONV_IM( conv ), "", _("Sent Doodle request."),
+			    GAIM_MESSAGE_NICK | GAIM_MESSAGE_RECV, time( NULL ) );
+	
+	return( GAIM_CMD_RET_OK );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_process( GaimConnection *gc, char *me, char *from, char *command, char *message )
+{
+//	g_print( "-----------------------------------------------\n" );
+//	g_print( "%s : %s : %s -> %s\n", from, imv, command, message );
+	
+	// Now check to see what sort of Doodle message it is
+	int cmd = atoi( command );
+
+	switch( cmd )
+	{
+		case DOODLE_CMD_REQUEST:
+		{
+			yahoo_doodle_command_got_request( gc, from );
+		} break;
+		
+		case DOODLE_CMD_READY:
+		{
+			yahoo_doodle_command_got_ready( gc, from );
+		} break;
+		
+		case DOODLE_CMD_CLEAR:
+		{
+			yahoo_doodle_command_got_clear( gc, from );
+		} break;
+		
+		case DOODLE_CMD_DRAW:
+		{
+			yahoo_doodle_command_got_draw( gc, from, message );
+		} break;
+		
+		case DOODLE_CMD_EXTRA:
+		{
+			yahoo_doodle_command_got_extra( gc, from, message );
+		} break;
+		
+		case DOODLE_CMD_CONFIRM:
+		{
+			yahoo_doodle_command_got_confirm( gc, from );
+		} break;
+	}
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_got_request( GaimConnection *gc, char *from )
+{	
+	g_print( "-----------------------------------------------\n" );
+	g_print( "Got REQUEST (%s)\n", from );
+	
+	GaimAccount	*account	= gaim_connection_get_account( gc );
+	
+	// Only handle this if local client requested Doodle session (else local client would have sent one)
+	GaimWhiteboard	*wb		= gaim_whiteboard_get_session( account, from );
+	
+	// If a session with the remote user doesn't exist
+	if( wb == NULL )
+	{
+		// Ask user if he/she wishes to accept the request for a doodle session
+		// TODO Ask local user to start Doodle session with remote user
+		// NOTE This if/else statement won't work right--must use dialog results
+		
+		/*	char dialog_message[64];
+		g_sprintf( dialog_message, "%s is requesting to start a Doodle session with you.", from );
+			
+		gaim_notify_message( NULL, GAIM_NOTIFY_MSG_INFO, "Doodle",
+		dialog_message, NULL, NULL, NULL );
+		*/
+		
+		wb = gaim_whiteboard_create( account, from, DOODLE_STATE_REQUESTED );
+		
+		yahoo_doodle_command_send_request( gc, from );
+	}
+	
+	// TODO Might be required to clear the canvas of an existing doodle session at this point
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_got_ready( GaimConnection *gc, char *from )
+{
+	g_print( "-----------------------------------------------\n" );
+	g_print( "Got READY (%s)\n", from );
+	
+	GaimAccount	*account	= gaim_connection_get_account( gc );
+	
+	// Only handle this if local client requested Doodle session (else local client would have sent one)
+	GaimWhiteboard	*wb		= gaim_whiteboard_get_session( account, from );
+							
+	if( wb == NULL )
+		return;
+	
+	if( wb->state == DOODLE_STATE_REQUESTING )
+	{
+		gaim_whiteboard_start( wb );
+		
+		wb->state = DOODLE_STATE_ESTABLISHED;
+		
+		yahoo_doodle_command_send_confirm( gc, from );
+	}
+	
+	if( wb->state == DOODLE_STATE_ESTABLISHED )
+	{
+		// Ask whether to save picture too
+		
+		gaim_whiteboard_clear( wb );
+	}
+	
+	// NOTE Not sure about this... I am trying to handle if the remote user already
+	// thinks we're in a session with them (when their chat message contains the doodle;11 imv key)
+	if( wb->state == DOODLE_STATE_REQUESTED )
+	{
+		g_print( "Hmmmm\n" );
+		
+		//gaim_whiteboard_start( wb );
+		yahoo_doodle_command_send_request( gc, from );
+	}
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_got_draw( GaimConnection *gc, char *from, char *message )
+{
+	g_print( "-----------------------------------------------\n" );
+	g_print( "Got DRAW (%s)\n", from );
+	
+	g_print( "Draw Message:  %s\n", message );
+	
+	GaimAccount	*account	= gaim_connection_get_account( gc );
+	
+	// Only handle this if local client requested Doodle session (else local client would have sent one)
+	GaimWhiteboard	*wb		= gaim_whiteboard_get_session( account, from );
+	
+	if( wb == NULL )
+		return;
+	
+	// TODO Functionalize
+	// Convert drawing packet message to an integer list
+	
+	int	*token		= NULL;
+	int	length		= strlen( message );
+	char	*token_end;
+	
+	GList	*d_list		= NULL;	// a local list of drawing info
+	
+	// Check to see if the message begans and ends with quotes
+	if( ( message[0] != '\"' ) || ( message[length - 1] != '\"' ) )
+		return;
+	
+	// Truncate the quotations off of our message (why the hell did they add them anyways!?)
+	message[length - 1]	= ',';
+	message			= message + 1;
+	
+	// Traverse and extract all integers divided by commas
+	while( ( token_end = strchr( message, ',' ) ) )
+	{
+		token_end[0]	= 0;
+		
+		token		= g_new0( int, 1 );
+		
+		*token		= atoi( message );
+		
+		d_list		= g_list_append( d_list, ( gpointer )( token ) );
+		
+		message		= token_end + 1;
+	}
+	
+	yahoo_doodle_draw_stroke( wb, d_list );
+	
+	//goodle_doodle_session_set_canvas_as_icon( ds );
+	
+	// Remove that shit
+	int	*n = NULL;
+	GList	*l = d_list;
+	while( l )
+	{
+		n = l->data;
+		
+		g_free( n );
+		
+		l = l->next;
+	}
+	
+	g_list_free( d_list );
+	d_list = NULL;
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_got_clear( GaimConnection *gc, char *from )
+{
+	g_print( "-----------------------------------------------\n" );
+	g_print( "Got CLEAR (%s)\n", from );
+	
+	GaimAccount	*account	= gaim_connection_get_account( gc );
+	
+	// Only handle this if local client requested Doodle session (else local client would have sent one)
+	GaimWhiteboard	*wb		= gaim_whiteboard_get_session( account, from );
+	
+	if( wb == NULL )
+		return;
+	
+	if( wb->state == DOODLE_STATE_ESTABLISHED )
+	{
+		// TODO Ask user whether to save the image before clearing it
+		
+		gaim_whiteboard_clear( wb );
+	}
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_got_extra( GaimConnection *gc, char *from, char *message )
+{
+	g_print( "-----------------------------------------------\n" );
+	g_print( "Got EXTRA (%s)\n", from );
+	
+	// I do not like these 'extra' features, so I'll only handle them in one way,
+	// which is returning them with the command/packet to turn them off
+	
+	yahoo_doodle_command_send_extra( gc, from, DOODLE_EXTRA_NONE );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_got_confirm( GaimConnection *gc, char *from )
+{	
+	g_print( "-----------------------------------------------\n" );
+	g_print( "Got CONFIRM (%s)\n", from );
+	
+	// Get the doodle session
+	GaimAccount	*account	= gaim_connection_get_account( gc );
+	
+	// Only handle this if local client requested Doodle session (else local client would have sent one)
+	GaimWhiteboard	*wb		= gaim_whiteboard_get_session( account, from );
+	
+	if( wb == NULL )
+		return;
+	
+	// TODO Combine the following IF's?
+	
+	// Check if we requested a doodle session
+	if( wb->state == DOODLE_STATE_REQUESTING )
+	{	
+		wb->state = DOODLE_STATE_ESTABLISHED;
+		
+		gaim_whiteboard_start( wb );
+		
+		yahoo_doodle_command_send_confirm( gc, from );
+	}
+	
+	// Check if we accepted a request for a doodle session
+	if( wb->state == DOODLE_STATE_REQUESTED )
+	{	
+		wb->state = DOODLE_STATE_ESTABLISHED;
+		
+		gaim_whiteboard_start( wb );
+	}
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_got_shutdown( GaimConnection *gc, char *from )
+{
+	g_print( "-----------------------------------------------\n" );
+	g_print( "Got SHUTDOWN (%s)\n", from );
+	
+	GaimAccount	*account	= gaim_connection_get_account( gc );
+	
+	// Only handle this if local client requested Doodle session (else local client would have sent one)
+	GaimWhiteboard	*wb		= gaim_whiteboard_get_session( account, from );
+	
+	// TODO Ask if user wants to save picture before the session is closed
+	
+	// If this session doesn't exist, don't try and kill it
+	if( wb == NULL )
+		return;
+	else
+	{
+		gaim_whiteboard_destroy( wb );
+		
+		//yahoo_doodle_command_send_shutdown( gc, from );
+	}
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_send_request( GaimConnection *gc, char *to )
+{
+	g_print( "-----------------------------------------------\n" );
+	g_print( "Sent REQUEST (%s)\n", to );
+	
+	struct yahoo_data	*yd;
+	struct yahoo_packet	*pkt;
+	
+	yd = gc->proto_data;
+
+	// Make and send an acknowledge (ready) Doodle packet
+	pkt = yahoo_packet_new( YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, 0 );
+	yahoo_packet_hash_str( pkt, 49,		"IMVIRONMENT" );
+	yahoo_packet_hash_str( pkt, 1,		gaim_account_get_username( gc->account ) );
+	yahoo_packet_hash_str( pkt, 14,		"1" );
+	yahoo_packet_hash_str( pkt, 13,		"1" );
+	yahoo_packet_hash_str( pkt, 5,		to );
+	yahoo_packet_hash_str( pkt, 63,		"doodle;11" );
+	yahoo_packet_hash_str( pkt, 64,		"1" );
+	yahoo_packet_hash_str( pkt, 1002,	"1" );
+	
+	yahoo_packet_send_and_free( pkt, yd );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_send_ready( GaimConnection *gc, char *to )
+{
+	g_print( "-----------------------------------------------\n" );
+	g_print( "Sent READY (%s)\n", to );
+	
+	struct yahoo_data	*yd;
+	struct yahoo_packet	*pkt;
+
+	yd = gc->proto_data;
+	
+	// Make and send a request to start a Doodle session
+	pkt = yahoo_packet_new( YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, 0 );
+	yahoo_packet_hash_str( pkt, 49,		"IMVIRONMENT" );
+	yahoo_packet_hash_str( pkt, 1,		gaim_account_get_username( gc->account ) );
+	yahoo_packet_hash_str( pkt, 14,		"" );
+	yahoo_packet_hash_str( pkt, 13,		"0" );
+	yahoo_packet_hash_str( pkt, 5,		to );
+	yahoo_packet_hash_str( pkt, 63,		"doodle;11" );
+	yahoo_packet_hash_str( pkt, 64,		"0" );
+	yahoo_packet_hash_str( pkt, 1002,	"1" );
+	
+	yahoo_packet_send_and_free( pkt, yd );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_send_draw( GaimConnection *gc, char *to, char *message )
+{
+	g_print( "-----------------------------------------------\n" );
+	g_print( "Sent DRAW (%s)\n", to );
+	
+	struct yahoo_data	*yd;
+	struct yahoo_packet	*pkt;
+
+	yd = gc->proto_data;
+	
+	// Make and send a drawing packet
+	pkt = yahoo_packet_new( YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, 0 );
+	yahoo_packet_hash_str( pkt, 49,		"IMVIRONMENT" );
+	yahoo_packet_hash_str( pkt, 1,		gaim_account_get_username( gc->account ) );
+	yahoo_packet_hash_str( pkt, 14,		message );
+	yahoo_packet_hash_str( pkt, 13,		"3" );
+	yahoo_packet_hash_str( pkt, 5,		to );
+	yahoo_packet_hash_str( pkt, 63,		"doodle;11" );
+	yahoo_packet_hash_str( pkt, 64,		"1" );
+	yahoo_packet_hash_str( pkt, 1002,	"1" );
+	
+	yahoo_packet_send_and_free( pkt, yd );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_send_clear( GaimConnection *gc, char *to )
+{
+	g_print( "-----------------------------------------------\n" );
+	g_print( "Sent CLEAR (%s)\n", to );
+	
+	struct yahoo_data	*yd;
+	struct yahoo_packet	*pkt;
+
+	yd = gc->proto_data;
+	
+	// Make and send a request to clear packet
+	pkt = yahoo_packet_new( YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, 0 );
+	yahoo_packet_hash_str( pkt, 49,		"IMVIRONMENT" );
+	yahoo_packet_hash_str( pkt, 1,		gaim_account_get_username( gc->account ) );
+	yahoo_packet_hash_str( pkt, 14,		" " );
+	yahoo_packet_hash_str( pkt, 13,		"2" );
+	yahoo_packet_hash_str( pkt, 5,		to );
+	yahoo_packet_hash_str( pkt, 63,		"doodle;11" );
+	yahoo_packet_hash_str( pkt, 64,		"1" );
+	yahoo_packet_hash_str( pkt, 1002,	"1" );
+	
+	yahoo_packet_send_and_free( pkt, yd );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_send_extra( GaimConnection *gc, char *to, char *message )
+{
+	g_print( "-----------------------------------------------\n" );
+	g_print( "Sent EXTRA (%s)\n", to );
+	
+	struct yahoo_data	*yd;
+	struct yahoo_packet	*pkt;
+
+	yd = gc->proto_data;
+		
+	// Send out a request to use a specified 'extra' feature (message)
+	pkt = yahoo_packet_new( YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, 0 );
+	yahoo_packet_hash_str( pkt, 49,		"IMVIRONMENT" );
+	yahoo_packet_hash_str( pkt, 1,		gaim_account_get_username( gc->account ) );
+	yahoo_packet_hash_str( pkt, 14,		message );
+	yahoo_packet_hash_str( pkt, 13,		"4" );
+	yahoo_packet_hash_str( pkt, 5,		to );
+	yahoo_packet_hash_str( pkt, 63,		"doodle;11" );
+	yahoo_packet_hash_str( pkt, 64,		"1" );
+	yahoo_packet_hash_str( pkt, 1002,	"1" );
+	
+	yahoo_packet_send_and_free( pkt, yd );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_send_confirm( GaimConnection *gc, char *to )
+{
+	g_print( "-----------------------------------------------\n" );
+	g_print( "Sent CONFIRM (%s)\n", to );
+	
+	struct yahoo_data	*yd;
+	struct yahoo_packet	*pkt;
+
+	yd = gc->proto_data;
+	
+	// Send ready packet (that local client accepted and is ready)
+	pkt = yahoo_packet_new( YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, 0 );
+	yahoo_packet_hash_str( pkt, 49,		"IMVIRONMENT" );
+	yahoo_packet_hash_str( pkt, 1,		( char* )( gaim_account_get_username( gc->account ) ) );
+	yahoo_packet_hash_str( pkt, 14,		"1" );
+	yahoo_packet_hash_str( pkt, 13,		"5" );
+	yahoo_packet_hash_str( pkt, 5,		to );
+	yahoo_packet_hash_str( pkt, 63,		"doodle;11" );
+	yahoo_packet_hash_str( pkt, 64,		"1" );
+	yahoo_packet_hash_str( pkt, 1002,	"1" );
+	
+	yahoo_packet_send_and_free( pkt, yd );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_send_shutdown( GaimConnection *gc, char *to )
+{
+	g_print( "-----------------------------------------------\n" );
+	g_print( "Sent SHUTDOWN (%s)\n", to );
+	
+	struct yahoo_data	*yd;
+	struct yahoo_packet	*pkt;
+
+	yd = gc->proto_data;
+	
+	// Declare that you are ending the Doodle session
+	pkt = yahoo_packet_new( YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, 0 );
+	yahoo_packet_hash_str( pkt, 49,		"IMVIRONMENT" );
+	yahoo_packet_hash_str( pkt, 1,		gaim_account_get_username( gc->account ) );
+	yahoo_packet_hash_str( pkt, 14,		"" );
+	yahoo_packet_hash_str( pkt, 13,		"0" );
+	yahoo_packet_hash_str( pkt, 5,		to );
+	yahoo_packet_hash_str( pkt, 63,		";0" );
+	yahoo_packet_hash_str( pkt, 64,		"0" );
+	yahoo_packet_hash_str( pkt, 1002,	"1" );
+	
+	yahoo_packet_send_and_free( pkt, yd );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_start( GaimWhiteboard *wb )
+{
+	//g_print( "yahoo_doodle_start()\n" );
+	
+	doodle_session *ds	= g_new0( doodle_session, 1 );
+
+	// Set default brush size and color
+	ds->brush_size		= DOODLE_BRUSH_MEDIUM;
+	ds->brush_color		= 0;	// black
+	
+	wb->proto_data		= ds;
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_end( GaimWhiteboard *wb )
+{
+	//g_print( "yahoo_doodle_end()\n" );
+	
+	GaimConnection *gc = gaim_account_get_connection( wb->account );
+	
+	yahoo_doodle_command_send_shutdown( gc, wb->who );
+	
+	doodle_session *ds = wb->proto_data;
+	if( ds )
+		g_free( ds );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_get_dimensions( GaimWhiteboard *wb, int *width, int *height )
+{
+	// Standard Doodle canvases are of one size:  368x256
+	*width	= DOODLE_CANVAS_WIDTH;
+	*height	= DOODLE_CANVAS_HEIGHT;
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_send_draw_list( GaimWhiteboard *wb, GList *draw_list )
+{
+	//g_print( "yahoo_doodle_send_draw_list()\n" );
+	
+	doodle_session	*ds		= wb->proto_data;
+	char 		*message	= yahoo_doodle_build_draw_string( ds, draw_list );
+	
+	if( message )
+		yahoo_doodle_command_send_draw( wb->account->gc, wb->who, message );
+
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_clear( GaimWhiteboard *wb )
+{
+	yahoo_doodle_command_send_clear( wb->account->gc, wb->who );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_draw_stroke( GaimWhiteboard *wb, GList *draw_list )
+{
+	// Traverse through the list and draw the points and lines
+	
+	//g_print( "Drawing: color=%d, size=%d, (%d,%d)\n", brush_color, brush_size, x, y );
+	
+	GList	*l = draw_list;
+	
+	int	*n = NULL;
+	
+	int	brush_color;
+	int	brush_size;
+	int	x;
+	int	y;
+	
+	int	dx, dy;
+	
+	n = l->data; brush_color = *n; l = l->next;
+	n = l->data; brush_size	 = *n; l = l->next;
+	n = l->data; x		 = *n; l = l->next;
+	n = l->data; y		 = *n; l = l->next;
+	
+	int count = 0;
+	
+	// Pray this works and pray that the list has an even number of elements
+	while( l )
+	{
+		count++;
+		
+		n = l->data; dx	= *n; l = l->next;
+		n = l->data; dy	= *n; l = l->next;
+		
+		gaim_whiteboard_draw_line( wb,
+					   x, y,
+					   x + dx, y + dy,
+					   brush_color, brush_size );
+		
+		x = x + dx;
+		y = y + dy;
+	}
+	
+	//g_print( "Counted %d deltas\n", count );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+char *yahoo_doodle_build_draw_string( doodle_session *ds, GList *draw_list )
+{
+	//g_print( "yahoo_doodle_build_draw_string()\n" );
+	
+	if( draw_list == NULL )
+		return( NULL );	
+	
+	GList		*l = draw_list;
+	
+	int		*n = NULL;
+	
+	static char	message[1024];		// Hope that 1024 is enough
+	char		token_string[16];	// Token string extracted from draw list
+	
+	strcpy( message, "\"" );
+	
+	sprintf( token_string, "%d,%d,", ds->brush_color, ds->brush_size );
+	strcat( message, token_string );
+	
+	// Pray this works and pray that the list has an even number of elements
+	while( l )
+	{
+		n = l->data;
+		
+		sprintf( token_string, "%d,", *n );
+		
+		// This check prevents overflow
+		if( ( strlen( message ) + strlen( token_string ) ) < 1024 )
+			strcat( message, token_string );
+		else
+			break;
+		
+		l = l->next;
+	}
+	
+	message[strlen( message ) - 1]	= '\"';
+	//message[strlen( message )]	= 0;
+	//message[511]			= 0;
+	
+	//g_print( "Draw Message:  %s\n", message );
+	
+	return( message );
+}
+
+// ------------------------------------------------------------------------------------------------------
+