gaim/gaim

c902dd8c275d
Parents 702c6d109eac
Children b7d392d68507
Conversion from plugin to within prpl actually compiles. Most of old
(usable) code is commented out. Functions for sending and recieving Doodle
packets are active and work. Purposely broken 'doodle_session' code crashes.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Makefile.am Wed Jul 13 22:02:56 2005 -0400
@@ -0,0 +1,268 @@
+EXTRA_DIST = \
+ getopt.c \
+ getopt.h \
+ getopt1.c \
+ Makefile.mingw \
+ win_gaim.c \
+ win32/IdleTracker/Makefile.mingw \
+ win32/IdleTracker/idletrack.c \
+ win32/IdleTracker/idletrack.h \
+ win32/MinimizeToTray.c \
+ win32/MinimizeToTray.h \
+ win32/gaimrc.rc \
+ win32/global.mak \
+ win32/libc_interface.c \
+ win32/libc_interface.h \
+ win32/libc_internal.h \
+ win32/resource.h \
+ win32/stdafx.h \
+ win32/untar.c \
+ win32/untar.h \
+ win32/wgaimerror.h \
+ win32/win32dep.c \
+ win32/win32dep.h \
+ win32/wspell.c \
+ win32/wspell.h \
+ win32/mingw_plus/winuser_extra.h \
+ win32/nsis/gaim-header.bmp \
+ win32/nsis/gaim-intro.bmp \
+ win32/nsis/langmacros.nsh \
+ win32/nsis/translations/albanian.nsh \
+ win32/nsis/translations/bulgarian.nsh \
+ win32/nsis/translations/catalan.nsh \
+ win32/nsis/translations/czech.nsh \
+ win32/nsis/translations/danish.nsh \
+ win32/nsis/translations/dutch.nsh \
+ win32/nsis/translations/english.nsh \
+ win32/nsis/translations/finnish.nsh \
+ win32/nsis/translations/french.nsh \
+ win32/nsis/translations/german.nsh \
+ win32/nsis/translations/hebrew.nsh \
+ win32/nsis/translations/hungarian.nsh \
+ win32/nsis/translations/italian.nsh \
+ win32/nsis/translations/japanese.nsh \
+ win32/nsis/translations/korean.nsh \
+ win32/nsis/translations/norwegian.nsh \
+ win32/nsis/translations/polish.nsh \
+ win32/nsis/translations/portuguese.nsh \
+ win32/nsis/translations/portuguese-br.nsh \
+ win32/nsis/translations/romanian.nsh \
+ win32/nsis/translations/russian.nsh \
+ win32/nsis/translations/serbian-latin.nsh \
+ win32/nsis/translations/simp-chinese.nsh \
+ win32/nsis/translations/slovak.nsh \
+ win32/nsis/translations/slovenian.nsh \
+ win32/nsis/translations/spanish.nsh \
+ win32/nsis/translations/swedish.nsh \
+ win32/nsis/translations/trad-chinese.nsh \
+ win32/nsis/translations/vietnamese.nsh
+
+
+SUBDIRS = protocols
+
+gaim_coresources = \
+ account.c \
+ accountopt.c \
+ blist.c \
+ buddyicon.c \
+ cipher.c \
+ cmds.c \
+ connection.c \
+ conversation.c \
+ core.c \
+ debug.c \
+ desktopitem.c \
+ eventloop.c \
+ ft.c \
+ imgstore.c \
+ log.c \
+ mime.c \
+ network.c \
+ notify.c \
+ plugin.c \
+ pluginpref.c \
+ pounce.c \
+ prefix.c \
+ prefs.c \
+ privacy.c \
+ proxy.c \
+ prpl.c \
+ request.c \
+ roomlist.c \
+ savedstatuses.c \
+ server.c \
+ signals.c \
+ status.c \
+ stringref.c \
+ sound.c \
+ sslconn.c \
+ util.c \
+ value.c \
+ xmlnode.c \
+ whiteboard.c
+
+gaim_coreheaders = \
+ account.h \
+ accountopt.h \
+ blist.h \
+ buddyicon.h \
+ cipher.h \
+ cmds.h \
+ connection.h \
+ conversation.h \
+ core.h \
+ debug.h \
+ desktopitem.h \
+ eventloop.h \
+ ft.h \
+ imgstore.h \
+ log.h \
+ mime.h \
+ network.h \
+ notify.h \
+ plugin.h \
+ pluginpref.h \
+ pounce.h \
+ prefix.h \
+ prefs.h \
+ privacy.h \
+ proxy.h \
+ prpl.h \
+ request.h \
+ roomlist.h \
+ savedstatuses.h \
+ server.h \
+ signals.h \
+ status.h \
+ stringref.h \
+ sound.h \
+ sslconn.h \
+ util.h \
+ value.h \
+ version.h \
+ xmlnode.h \
+ whiteboard.h
+
+bin_PROGRAMS = gaim gaim-remote
+
+gaim_SOURCES = \
+ $(gaim_coresources) \
+ gtkcombobox.c \
+ gtkcelllayout.c \
+ gtkcellview.c \
+ gtkcellviewmenuitem.c \
+ gtkaccount.c \
+ gtkcellrendererprogress.c \
+ gtkblist.c \
+ gtkconn.c \
+ gtkconv.c \
+ gtkdebug.c \
+ gtkdialogs.c \
+ gtkdnd-hints.c \
+ gtkgaim-disclosure.c \
+ gtkeventloop.c \
+ gtkft.c \
+ gtkimhtml.c \
+ gtkimhtmltoolbar.c \
+ gtklog.c \
+ gtkmain.c \
+ gtknotify.c \
+ gtkplugin.c \
+ gtkpluginpref.c \
+ gtkprefs.c \
+ gtkprivacy.c \
+ gtkpounce.c \
+ gtkrequest.c \
+ gtkroomlist.c \
+ gtksavedstatuses.c \
+ gtksound.c \
+ gtksourceiter.c \
+ gtkstatusbox.c \
+ gtkstock.c \
+ gtkthemes.c \
+ gtkutils.c \
+ idle.c \
+ session.c \
+ gtkwhiteboard.c
+
+gaim_headers = \
+ gaim.h \
+ gtkcombobox.h \
+ gtkcelllayout.h \
+ gtkcellview.h \
+ gtkcellviewmenuitem.h \
+ gtkcellview.h \
+ gtkcellviewmenuitem.h \
+ gtkaccount.h \
+ gtkcellrendererprogress.h \
+ gtkblist.h \
+ gtkconn.h \
+ gtkconv.h \
+ gtkdebug.h \
+ gtkdialogs.h \
+ gtkdnd-hints.h \
+ gtkeventloop.h \
+ gtkft.h \
+ gtkgaim.h \
+ gtkgaim-disclosure.h \
+ gtkimhtml.h \
+ gtkimhtmltoolbar.h \
+ gtklog.h \
+ gtknotify.h \
+ gtkplugin.h \
+ gtkpluginpref.h \
+ gtkprefs.h \
+ gtkprivacy.h \
+ gtkpounce.h \
+ gtkrequest.h \
+ gtkroomlist.h \
+ gtksavedstatuses.h \
+ gtksound.h \
+ gtksourceiter.h \
+ gtkstatusbox.h \
+ gtkstock.h \
+ gtkutils.h \
+ internal.h \
+ gtkwhiteboard.h
+
+gaimincludedir=$(includedir)/gaim
+gaiminclude_HEADERS = \
+ $(gaim_coreheaders) \
+ $(gaim_headers)
+
+gaim_DEPENDENCIES = @LIBOBJS@ $(STATIC_LINK_LIBS)
+gaim_LDFLAGS = -export-dynamic
+gaim_LDADD = \
+ @LIBOBJS@ \
+ $(GTK_LIBS) \
+ $(SOUND_LIBS) \
+ $(STATIC_LINK_LIBS) \
+ $(XSS_LIBS) \
+ $(SM_LIBS) \
+ $(INTLLIBS) \
+ $(GTKSPELL_LIBS) \
+ $(STARTUP_NOTIFICATION_LIBS)
+
+gaim_remote_SOURCES = \
+ gaim-remote.c \
+ prefix.c \
+ prefix.h
+
+gaim_remote_DEPENDENCIES = @LIBOBJS@
+gaim_remote_LDADD = \
+ @LIBOBJS@ $(GLIB_LIBS) $(INTLLIBS) \
+ $(top_builddir)/plugins/gaim-remote/libgaim-remote.la
+
+AM_CPPFLAGS = \
+ -DBR_PTHREADS=0 \
+ -DDATADIR=\"$(datadir)\" \
+ -DLIBDIR=\"$(libdir)/gaim/\" \
+ -DLOCALEDIR=\"$(datadir)/locale\" \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -I$(top_srcdir)/plugins \
+ $(AUDIOFILE_CFLAGS) \
+ $(AO_CFLAGS) \
+ $(DEBUG_CFLAGS) \
+ $(GTK_CFLAGS) \
+ $(GTKSPELL_CFLAGS) \
+ $(STARTUP_NOTIFICATION_CFLAGS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gtkwhiteboard.c Wed Jul 13 22:02:56 2005 -0400
@@ -0,0 +1,23 @@
+/*
+ * 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
+ *
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gtkwhiteboard.h Wed Jul 13 22:02:56 2005 -0400
@@ -0,0 +1,24 @@
+/**
+ * @file gtkwhiteboard.h The GtkGaimWhiteboard frontend object
+ *
+ * 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
+ */
+
Binary file src/gtkwhiteboard.o has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/yahoo/Makefile.am Wed Jul 13 22:02:56 2005 -0400
@@ -0,0 +1,51 @@
+EXTRA_DIST = \
+ Makefile.mingw
+
+pkgdir = $(libdir)/gaim
+
+YAHOOSOURCES = \
+ crypt.c \
+ yahoo.h \
+ yahoo_auth.c \
+ yahoo_auth.h \
+ yahoochat.h \
+ yahoo.c \
+ yahoochat.c \
+ util.c \
+ yahoo_filexfer.h \
+ yahoo_filexfer.c \
+ yahoo_friend.h \
+ yahoo_friend.c \
+ yahoo_packet.h \
+ yahoo_packet.c \
+ yahoo_doodle.h \
+ yahoo_doodle.c \
+ yahoo_picture.c \
+ yahoo_picture.h \
+ yahoo_profile.c \
+ ycht.c \
+ ycht.h
+
+AM_CFLAGS = $(st)
+
+libyahoo_la_LDFLAGS = -module -avoid-version $(GLIB_LIBS)
+
+if STATIC_YAHOO
+
+st = -DGAIM_STATIC_PRPL
+noinst_LIBRARIES = libyahoo.a
+libyahoo_a_SOURCES = $(YAHOOSOURCES)
+libyahoo_a_CFLAGS = $(AM_CFLAGS)
+
+else
+
+st =
+pkg_LTLIBRARIES = libyahoo.la
+libyahoo_la_SOURCES = $(YAHOOSOURCES)
+
+endif
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src \
+ $(GLIB_CFLAGS) \
+ $(DEBUG_CFLAGS)
--- a/src/protocols/yahoo/yahoo.c Tue Jul 12 18:30:55 2005 -0400
+++ b/src/protocols/yahoo/yahoo.c Wed Jul 13 22:02:56 2005 -0400
@@ -45,6 +45,7 @@
#include "ycht.h"
#include "yahoo_auth.h"
#include "yahoo_filexfer.h"
+#include "yahoo_doodle.h"
#include "yahoo_picture.h"
extern char *yahoo_crypt(const char *, const char *);
@@ -2017,6 +2018,7 @@
yahoo_process_stealth(gc, pkt);
break;
case YAHOO_SERVICE_P2PFILEXFER:
+ yahoo_process_p2pfilexfer( gc, pkt ); // This case had no break and continued; thus keeping it this way.
case YAHOO_SERVICE_FILETRANSFER:
yahoo_process_filetransfer(gc, pkt);
break;
@@ -2912,6 +2914,19 @@
yahoo_packet_hash_str(pkt, 97, "1");
yahoo_packet_hash_str(pkt, 14, msg2);
+ /*
+ // If this message is to a user who is also Doodling with the local user,
+ // format the chat packet with the IMV information (thanks Yahoo!)
+ doodle_session *ds = goodle_get_doodle_session( dsList,
+ ( char* )( gaim_account_get_username( gc->account ) ),
+ ( char* )( who ) );
+
+ if( ds )
+ yahoo_packet_hash(pkt, 63, "doodle;11");
+ else
+ yahoo_packet_hash(pkt, 63, ";0"); // IMvironment
+ */
+
yahoo_packet_hash_str(pkt, 63, ";0"); /* IMvironment */
yahoo_packet_hash_str(pkt, 64, "0"); /* no idea */
yahoo_packet_hash_str(pkt, 1002, "1"); /* no idea, Yahoo 6 or later only it seems */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/yahoo/yahoo_doodle.c Wed Jul 13 22:02:56 2005 -0400
@@ -0,0 +1,1558 @@
+/*
+ * 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 "yahoo_doodle.h"
+
+
+// GLOBALS =============================================================================================
+gboolean auto_accept = TRUE;
+
+GList *buttonList = NULL;
+
+GList *dsList = NULL;
+
+GList *drawList = NULL;
+
+int LastX; // Tracks last position of the mouse when drawing
+int LastY;
+int MotionCount; // Tracks how many brush motions made
+int BrushState = BRUSH_STATE_UP;
+
+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
+};
+
+//GdkColor DefaultColor[PALETTE_NUM_OF_COLORS];
+
+// FUNCTIONS ============================================================================================
+
+/*
+// This function is called at the start of Gaim (twice?)
+// Anyhow... this is the biggy... I think :P
+void init_plugin( GaimPlugin *plugin )
+{
+ int i;
+
+ for( i = 0; i < PALETTE_NUM_OF_COLORS; i++ )
+ {
+ goodle_rgb24_to_rgb48( DefaultColorRGB24[i], &DefaultColor[i] );
+ }
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+// plugin_load is not required. It is called when the plugin is loaded so that you can
+// initialize any variables and so on. Therefore, called when selected in Preferences->Plugins
+gboolean goodle_load( GaimPlugin *plugin )
+{
+ // Set up signal/functions for when connections are made/ended
+ void *con_handle = gaim_connections_get_handle();
+
+ gaim_signal_connect( con_handle, "signed-on", plugin,
+ GAIM_CALLBACK( goodle_con_signed_on ), NULL );
+
+ gaim_signal_connect( con_handle, "signed-off", plugin,
+ GAIM_CALLBACK( goodle_con_signed_off ), NULL );
+
+ // Set up signal/functions for when the conversation/windows are created
+ void *conv_handle = gaim_conversations_get_handle();
+
+ gaim_signal_connect( conv_handle, "conversation-created", plugin,
+ GAIM_CALLBACK( goodle_conv_created ), NULL );
+
+ gaim_signal_connect( conv_handle, "deleting-conversation", plugin,
+ GAIM_CALLBACK( goodle_conv_destroyed ), NULL );
+
+ // Make all active Yahoo accounts use the Goodle network packet handler
+ goodle_set_goodle_functions( TRUE );
+
+ return( TRUE );
+}
+// ------------------------------------------------------------------------------------------------------
+*/
+/*
+// plugin_destroy is called when plugin is unloaded (unselected)
+gboolean goodle_unload( GaimPlugin *plugin )
+{
+ // Destroy any buttons that haven't been destroyed from closing conversation windows
+ g_list_free( buttonList );
+ buttonList = NULL;
+
+ // Clear the list of Doodle sessions (TODO also make sure the pixmaps and perhaps widgets are destroyed too)
+
+ //struct doodle_session *ds;
+ //GList *l = dsList;
+
+// // Check if a Doodle session exists with this user
+// while( l )
+// {
+// ds = l->data;
+//
+// g_free( ds );
+//
+// //g_print( "%s\n", ds->who );
+//
+// l = l->next;
+ }
+
+ g_list_free( dsList );
+ dsList = NULL;
+
+ // Return full packet handling to the original Yahoo plugin
+ goodle_set_goodle_functions( FALSE );
+
+ return( TRUE );
+}
+// ------------------------------------------------------------------------------------------------------
+
+// plugin_destroy is called when plugin is destroyed (fails/crashes)
+void goodle_destroy( GaimPlugin *plugin )
+{
+ g_list_free( buttonList );
+ buttonList = NULL;
+
+ g_list_free( dsList );
+ dsList = NULL;
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void goodle_con_signed_on( GaimConnection *gc, gpointer data )
+{
+ g_print( "%s -> SIGNED ON\n", gaim_account_get_username( gc->account ) );
+ goodle_set_goodle_functions( TRUE );
+}
+// ------------------------------------------------------------------------------------------------------
+
+void goodle_con_signed_off( GaimConnection *gc, gpointer data )
+{
+ g_print( "%s -> SIGNED OFF\n", gaim_account_get_username( gc->account ) );
+}
+// ------------------------------------------------------------------------------------------------------
+
+
+void goodle_conv_created( GaimConversation *conv, gpointer data )
+{
+ GtkWidget *button;
+ GaimGtkConversation *gtkconv;
+ //GaimConversationType type;
+
+ // Check if this is a valid conversation window in Gaim ?
+ if( ( gtkconv = GAIM_GTK_CONVERSATION( conv ) ) == NULL )
+ return;
+
+ //type = gaim_conversation_get_type( conv );
+
+ // Create this button (via Gaim API)
+ button = gaim_gtkconv_button_new( NULL,
+ "Goodle", "Start a Doodle session with this user",
+ gtkconv->tooltips,
+ goodle_button_press,
+ ( gpointer )( conv ) );
+
+ // Stamp this button with essentially information attributing it to this particular conversation?
+ g_object_set_data( G_OBJECT( button ), "conv", conv );
+
+ // Add this particular button to the global list of buttons
+ buttonList = g_list_append( buttonList, ( gpointer )( button ) );
+
+ // Place the button at the bottom of the Gaim conversation window
+ gtk_box_pack_end( GTK_BOX( gtkconv->bbox ), button, TRUE, TRUE, 0 );
+ gtk_size_group_add_widget( gtkconv->sg, button );
+ gtk_widget_show( button );
+}
+// ------------------------------------------------------------------------------------------------------
+
+void goodle_conv_destroyed( GaimConversation *conv, gpointer data )
+{
+ GaimConversation *stored_conv;
+ GtkWidget *button;
+ GList *l, *l_next;
+
+ // Traverse the list of buttons and destroy the one associated with this conversation window
+ for( l = buttonList; l != NULL; l = l_next )
+ {
+ l_next = l->next;
+
+ button = GTK_WIDGET( l->data );
+ stored_conv = ( GaimConversation* )g_object_get_data( G_OBJECT( button ), "conv" );
+
+ // Does this button's 'stamp' match that of this conversation?
+ if( stored_conv == conv )
+ {
+ gtk_widget_destroy( button );
+
+ buttonList = g_list_remove( buttonList, l->data );
+ break;
+ }
+ }
+}
+// ------------------------------------------------------------------------------------------------------
+
+void goodle_button_press( GtkButton *button, gpointer data )
+{
+ GaimConversation *conv = data;
+ GaimAccount *account = gaim_conversation_get_account( conv );
+ GaimConnection *gc = gaim_account_get_connection( account );
+ char *to = ( char* )( gaim_conversation_get_name( conv ) );
+
+ // Get the doodle session
+ doodle_session *ds = yahoo_doodle_session_get( dsList,
+ ( char* )( gaim_account_get_username( gc->account ) ),
+ 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 ) );
+
+ goodle_send_command_request( gc, to );
+ yahoo_doodle_command_send_ready( gc, to );
+
+ // Insert this 'session' in the list. At this point, it's only a requested session.
+ if( ds == NULL )
+ {
+ ds = g_new0( doodle_session, 1 );
+ strcpy( ds->who, to );
+ ds->gc = gc;
+ ds->state = DOODLE_STATE_REQUESTING;
+ dsList = g_list_append( dsList, ( gpointer )( ds ) );
+ }
+}
+// ------------------------------------------------------------------------------------------------------
+
+// Configuration dialog for plugin (uses GTK)
+GtkWidget *get_config_frame( GaimPlugin *plugin )
+{
+ GtkWidget *vbox, *frame;
+
+ vbox = gtk_vbox_new( FALSE, 6 );
+ gtk_container_set_border_width( GTK_CONTAINER( vbox ), 12 );
+
+ frame = gaim_gtk_make_frame( vbox, "Settings" );
+
+ gaim_gtk_prefs_checkbox( "Automatically accept Doodle requests",
+ "/plugins/gtk/goodle/auto_accept",
+ frame );
+
+ gtk_widget_show_all( vbox );
+
+ return( vbox );
+}
+// ------------------------------------------------------------------------------------------------------
+
+void goodle_set_goodle_functions( gboolean useGoodle )
+{
+ GList *accountList = NULL;
+ GList *l = NULL;
+ GList *l_next = NULL;
+
+ GaimAccount *account;
+ GaimConnection *gc;
+
+ struct yahoo_data *yd;
+
+ // Obtain all the Gaim accounts (no other way to get to the GaimConnections?)
+ accountList = gaim_accounts_get_all();
+
+ // Traverse through the accounts to determine which ones are Yahoo
+ for( l = accountList; l != NULL; l = l_next )
+ {
+ l_next = l->next;
+
+ account = ( GaimAccount* )( l->data );
+
+ // Check if this particular account is Yahoo
+ if( !strcmp( gaim_account_get_protocol_id( account ), "prpl-yahoo" ) )
+ {
+ // See if this Yahoo account is active
+ if( gaim_account_is_connected( account ) )
+ {
+ gc = gaim_account_get_connection( account );
+
+ yd = gc->proto_data;
+
+ GaimPlugin *gp = gaim_find_prpl( "prpl-yahoo" );
+ GaimPluginInfo *gpi = gp->info;
+ GaimPluginProtocolInfo *gppi = gpi->extra_info;
+
+ if( useGoodle )
+ {
+ // Replace the packet handler function with a modified one
+ // to check for packets concerning 'Doodle'
+ gaim_input_remove( gc->inpa );
+ gc->inpa = gaim_input_add( yd->fd, GAIM_INPUT_READ, goodle_pending, gc );
+
+ // Replace the 'send_im' function with a modified one
+ // to check to see if we are chatting with a person we are doodling with
+ gppi->send_im = goodle_send_im;
+ }
+ else
+ {
+ // Replace the modified packet handler function with original
+ gaim_input_remove( gc->inpa );
+ gc->inpa = gaim_input_add( yd->fd, GAIM_INPUT_READ, yahoo_pending, gc );
+
+ // Replace the modified 'send_im' with the original
+ gppi->send_im = yahoo_send_im;
+ }
+ }
+ }
+ }
+
+ // Clear our list of accounts?
+ accountList = NULL;
+}
+
+// ------------------------------------------------------------------------------------------------------
+*/
+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 )
+{
+ char *me = ( char* )( gaim_account_get_username( gc->account ) );
+
+ // Only handle this if local client requested Doodle session (else local client would have sent one)
+ doodle_session *ds = yahoo_doodle_session_get( dsList, me, from );
+
+ g_print( "-----------------------------------------------\n" );
+ g_print( "Got REQUEST (%s)\n", from );
+
+ // If a session with the remote user doesn't exist
+ if( ds == 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 );
+ */
+
+ if( !auto_accept )
+ {};
+
+ ds = g_new0( doodle_session, 1 );
+ strcpy( ds->who, from );
+ ds->gc = gc;
+ ds->state = DOODLE_STATE_REQUESTED;
+ dsList = g_list_append( dsList, ( gpointer )( ds ) );
+
+ 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 )
+{
+ // Only handle this if local client requested Doodle session (else local client would have sent one)
+ doodle_session *ds = yahoo_doodle_session_get( dsList,
+ ( char* )( gaim_account_get_username( gc->account ) ),
+ from );
+
+ g_print( "-----------------------------------------------\n" );
+ g_print( "Got READY (%s)\n", from );
+
+ if( ds == NULL )
+ return;
+
+ if( ds->state == DOODLE_STATE_REQUESTING )
+ {
+ // TODO Check for active pixmap?
+ //goodle_doodle_session_start( ds );
+
+ ds->state = DOODLE_STATE_ESTABLISHED;
+
+ yahoo_doodle_command_send_confirm( gc, from );
+ }
+
+ if( ds->state == DOODLE_STATE_ESTABLISHED )
+ {
+ // TODO Call clear function (requires function to clear canvas (but not send clear command packet)
+ // Ask whether to save picture too
+
+ //goodle_doodle_session_clear_canvas( ds );
+
+ //goodle_doodle_session_set_canvas_as_icon( ds );
+ }
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_got_draw( GaimConnection *gc, char *from, char *message )
+{
+ // Only handle this if local client requested Doodle session (else local client would have sent one)
+ doodle_session *ds = yahoo_doodle_session_get( dsList,
+ ( char* )( gaim_account_get_username( gc->account ) ),
+ from );
+
+ if( ds == NULL )
+ return;
+
+ g_print( "-----------------------------------------------\n" );
+ g_print( "Got DRAW (%s)\n", from );
+
+ g_print( "Draw Message: %s\n", message );
+
+ // 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;
+ }
+
+ //goodle_doodle_draw_stroke( ds, 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 )
+{
+ // Only handle this if local client requested Doodle session (else local client would have sent one)
+ doodle_session *ds = yahoo_doodle_session_get( dsList,
+ ( char* )( gaim_account_get_username( gc->account ) ),
+ from );
+
+ g_print( "-----------------------------------------------\n" );
+ g_print( "Got CLEAR (%s)\n", from );
+
+ if( ds == NULL )
+ return;
+
+ if( ds->state == DOODLE_STATE_ESTABLISHED )
+ {
+ // TODO Ask user whether to save the image before clearing it
+
+ //goodle_doodle_session_clear_canvas( ds );
+
+ //goodle_doodle_session_set_canvas_as_icon( ds );
+ }
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_got_extra( GaimConnection *gc, char *from, char *message )
+{
+ // 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
+
+ g_print( "-----------------------------------------------\n" );
+ g_print( "Got EXTRA (%s)\n", from );
+
+ yahoo_doodle_command_send_extra( gc, from, DOODLE_EXTRA_NONE );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_got_confirm( GaimConnection *gc, char *from )
+{
+ // Get the doodle session
+ doodle_session *ds = yahoo_doodle_session_get( dsList,
+ ( char* )( gaim_account_get_username( gc->account ) ),
+ from );
+
+ g_print( "-----------------------------------------------\n" );
+ g_print( "Got CONFIRM (%s)\n", from );
+
+ if( ds == NULL )
+ return;
+
+ // TODO Combine the following IF's?
+
+ // Check if we requested a doodle session
+ if( ds->state == DOODLE_STATE_REQUESTING )
+ {
+ ds->state = DOODLE_STATE_ESTABLISHED;
+
+ // Check if this session wasn't already started before we start it (again?)
+ //if( ds->pixmap == NULL )
+ // goodle_doodle_session_start( ds );
+
+ yahoo_doodle_command_send_confirm( gc, from );
+ }
+
+ // Check if we accepted a request for a doodle session
+ if( ds->state == DOODLE_STATE_REQUESTED )
+ {
+ ds->state = DOODLE_STATE_ESTABLISHED;
+
+ // Check if this session wasn't already started before we start it (again?)
+ //if( ds->pixmap == NULL )
+ // goodle_doodle_session_start( ds );
+ }
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_got_shutdown( GaimConnection *gc, char *from )
+{
+ // Get the doodle session
+ doodle_session *ds = yahoo_doodle_session_get( dsList,
+ ( char* )( gaim_account_get_username( gc->account ) ),
+ from );
+
+ g_print( "-----------------------------------------------\n" );
+ g_print( "Got SHUTDOWN (%s)\n", 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( ds == NULL )
+ return;
+ else
+ ;//gtk_widget_destroy( ds->window );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+int yahoo_doodle_command_send_request( GaimConnection *gc, char *to )
+{
+ struct yahoo_data *yd;
+ struct yahoo_packet *pkt;
+
+ g_print( "-----------------------------------------------\n" );
+ g_print( "Sent REQUEST (%s)\n", to );
+
+ 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( pkt, 49, "IMVIRONMENT" );
+ yahoo_packet_hash( pkt, 1, gaim_account_get_username( gc->account ) );
+ yahoo_packet_hash( pkt, 14, "1" );
+ yahoo_packet_hash( pkt, 13, "1" );
+ yahoo_packet_hash( pkt, 5, to );
+ yahoo_packet_hash( pkt, 63, "doodle;11" );
+ yahoo_packet_hash( pkt, 64, "1" );
+ yahoo_packet_hash( pkt, 1002, "1" );
+ yahoo_packet_send( yd, pkt );
+
+ yahoo_packet_free( pkt );
+
+ return( 0 );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+int yahoo_doodle_command_send_ready( GaimConnection *gc, char *to )
+{
+ struct yahoo_data *yd;
+ struct yahoo_packet *pkt;
+
+ g_print( "-----------------------------------------------\n" );
+ g_print( "Sent READY (%s)\n", to );
+
+ 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( pkt, 49, "IMVIRONMENT" );
+ yahoo_packet_hash( pkt, 1, gaim_account_get_username( gc->account ) );
+ yahoo_packet_hash( pkt, 14, "" );
+ yahoo_packet_hash( pkt, 13, "0" );
+ yahoo_packet_hash( pkt, 5, to );
+ yahoo_packet_hash( pkt, 63, "doodle;11" );
+ yahoo_packet_hash( pkt, 64, "0" );
+ yahoo_packet_hash( pkt, 1002, "1" );
+ yahoo_packet_send( yd, pkt );
+
+ yahoo_packet_free( pkt );
+
+ return( 0 );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_send_draw( GaimConnection *gc, char *to, char *message )
+{
+ struct yahoo_data *yd;
+ struct yahoo_packet *pkt;
+
+ g_print( "-----------------------------------------------\n" );
+ g_print( "Sent DRAW (%s)\n", to );
+
+ yd = gc->proto_data;
+
+ // Make and send a drawing packet
+ pkt = yahoo_packet_new( YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, 0 );
+ yahoo_packet_hash( pkt, 49, "IMVIRONMENT" );
+ yahoo_packet_hash( pkt, 1, gaim_account_get_username( gc->account ) );
+ yahoo_packet_hash( pkt, 14, message );
+ yahoo_packet_hash( pkt, 13, "3" );
+ yahoo_packet_hash( pkt, 5, to );
+ yahoo_packet_hash( pkt, 63, "doodle;11" );
+ yahoo_packet_hash( pkt, 64, "1" );
+ yahoo_packet_hash( pkt, 1002, "1" );
+ yahoo_packet_send( yd, pkt );
+
+ yahoo_packet_free( pkt );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_send_clear( GaimConnection *gc, char *to )
+{
+ struct yahoo_data *yd;
+ struct yahoo_packet *pkt;
+
+ g_print( "-----------------------------------------------\n" );
+ g_print( "Sent CLEAR (%s)\n", to );
+
+ 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( pkt, 49, "IMVIRONMENT" );
+ yahoo_packet_hash( pkt, 1, gaim_account_get_username( gc->account ) );
+ yahoo_packet_hash( pkt, 14, " " );
+ yahoo_packet_hash( pkt, 13, "2" );
+ yahoo_packet_hash( pkt, 5, to );
+ yahoo_packet_hash( pkt, 63, "doodle;11" );
+ yahoo_packet_hash( pkt, 64, "1" );
+ yahoo_packet_hash( pkt, 1002, "1" );
+ yahoo_packet_send( yd, pkt );
+
+ yahoo_packet_free( pkt );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_send_extra( GaimConnection *gc, char *to, char *message )
+{
+ struct yahoo_data *yd;
+ struct yahoo_packet *pkt;
+
+ g_print( "-----------------------------------------------\n" );
+ g_print( "Sent EXTRA (%s)\n", to );
+
+ 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( pkt, 49, "IMVIRONMENT" );
+ yahoo_packet_hash( pkt, 1, gaim_account_get_username( gc->account ) );
+ yahoo_packet_hash( pkt, 14, message );
+ yahoo_packet_hash( pkt, 13, "4" );
+ yahoo_packet_hash( pkt, 5, to );
+ yahoo_packet_hash( pkt, 63, "doodle;11" );
+ yahoo_packet_hash( pkt, 64, "1" );
+ yahoo_packet_hash( pkt, 1002, "1" );
+ yahoo_packet_send( yd, pkt );
+
+ yahoo_packet_free( pkt );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_send_confirm( GaimConnection *gc, char *to )
+{
+ struct yahoo_data *yd;
+ struct yahoo_packet *pkt;
+
+ g_print( "-----------------------------------------------\n" );
+ g_print( "Sent CONFIRM (%s)\n", to );
+
+ 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( pkt, 49, "IMVIRONMENT" );
+ yahoo_packet_hash( pkt, 1, ( char* )( gaim_account_get_username( gc->account ) ) );
+ yahoo_packet_hash( pkt, 14, "1" );
+ yahoo_packet_hash( pkt, 13, "5" );
+ yahoo_packet_hash( pkt, 5, to );
+ yahoo_packet_hash( pkt, 63, "doodle;11" );
+ yahoo_packet_hash( pkt, 64, "1" );
+ yahoo_packet_hash( pkt, 1002, "1" );
+ yahoo_packet_send( yd, pkt );
+
+ yahoo_packet_free( pkt );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void yahoo_doodle_command_send_shutdown( GaimConnection *gc, char *to )
+{
+ struct yahoo_data *yd;
+ struct yahoo_packet *pkt;
+
+ g_print( "-----------------------------------------------\n" );
+ g_print( "Sent SHUTDOWN (%s)\n", to );
+
+ 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( pkt, 49, "IMVIRONMENT" );
+ yahoo_packet_hash( pkt, 1, gaim_account_get_username( gc->account ) );
+ yahoo_packet_hash( pkt, 14, "" );
+ yahoo_packet_hash( pkt, 13, "0" );
+ yahoo_packet_hash( pkt, 5, to );
+ yahoo_packet_hash( pkt, 63, ";0" );
+ yahoo_packet_hash( pkt, 64, "0" );
+ yahoo_packet_hash( pkt, 1002, "1" );
+ yahoo_packet_send( yd, pkt );
+
+ yahoo_packet_free( pkt );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+// Looks through a specified list of Doodle sessions for one that is between usernames 'me' and 'who'
+// Returns a pointer to a matching doodle_session; if none match, it returns NULL
+doodle_session *yahoo_doodle_session_get( GList *ds_list, char *me, char *who )
+{
+ doodle_session *ds = NULL;
+
+ GList *l = ds_list;
+
+ // Look for a Doodle session between the local user and the remote user
+ while( l )
+ {
+ ds = l->data;
+
+ if( !strcmp( gaim_account_get_username( ds->gc->account ), me ) && !strcmp( ds->who, who ) )
+ return( ds );
+
+ l = l->next;
+ }
+
+ return( NULL );
+}
+
+// ------------------------------------------------------------------------------------------------------
+/*
+void goodle_doodle_session_start( doodle_session *ds )
+{
+ int i;
+
+ GtkWidget *window;
+ GtkWidget *drawing_area;
+
+ GtkWidget *hbox_palette;
+ GtkWidget *vbox_palette_above_canvas_and_controls;
+ GtkWidget *hbox_canvas_and_controls;
+ GtkWidget *vbox_controls;
+
+ // --------------------------
+ // |[][][][palette[][][][][]|
+ // |------------------------|
+ // | canvas | con |
+ // | | trol|
+ // | | s |
+ // | | |
+ // | | |
+ // --------------------------
+
+ GtkWidget *clear_button;
+ GtkWidget *save_button;
+
+ GtkWidget *color_box[PALETTE_NUM_OF_COLORS];
+
+ window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+ ds->window = window;
+ gtk_widget_set_name( window, ds->who );
+ gtk_window_set_title( ( GtkWindow* )( window ), ds->who ); // TODO Try and use alias first
+ gtk_window_set_resizable( ( GtkWindow* )( window ), FALSE );
+
+ g_signal_connect( G_OBJECT( window ), "destroy",
+ G_CALLBACK( goodle_doodle_session_end ), ( gpointer )( ds ) );
+
+ // Create vertical box to place palette above the canvas and controls
+ vbox_palette_above_canvas_and_controls = gtk_vbox_new( FALSE, 0 );
+ gtk_container_add( GTK_CONTAINER( window ), vbox_palette_above_canvas_and_controls );
+ gtk_widget_show( vbox_palette_above_canvas_and_controls );
+
+ // Create horizontal box for the palette and all its entries
+ hbox_palette = gtk_hbox_new( FALSE, 0 );
+ gtk_container_add( GTK_CONTAINER( vbox_palette_above_canvas_and_controls ), hbox_palette );
+ gtk_widget_show( hbox_palette );
+
+ // Create horizontal box to seperate the canvas from the controls
+ hbox_canvas_and_controls = gtk_hbox_new( FALSE, 0 );
+ gtk_container_add( GTK_CONTAINER( vbox_palette_above_canvas_and_controls ), hbox_canvas_and_controls );
+ gtk_widget_show( hbox_canvas_and_controls );
+
+ for( i = 0; i < PALETTE_NUM_OF_COLORS; i++ )
+ {
+ color_box[i] = gtk_label_new( NULL );
+ gtk_widget_set_size_request( color_box[i], DOODLE_CANVAS_WIDTH / PALETTE_NUM_OF_COLORS ,32 );
+ gtk_container_add( GTK_CONTAINER( hbox_palette ), color_box[i] );
+ gtk_widget_show( color_box[i] );
+ }
+
+ // Create the drawing area
+ drawing_area = gtk_drawing_area_new();
+ ds->drawing_area = drawing_area;
+ gtk_widget_set_size_request( GTK_WIDGET( drawing_area ), DOODLE_CANVAS_WIDTH, DOODLE_CANVAS_HEIGHT );
+ gtk_box_pack_start( GTK_BOX( hbox_canvas_and_controls ), drawing_area, TRUE, TRUE, 8 );
+
+ gtk_widget_show( drawing_area );
+
+ // Signals used to handle backing pixmap
+ g_signal_connect( G_OBJECT( drawing_area ), "expose_event",
+ G_CALLBACK( goodle_doodle_session_expose_event ), ( gpointer )( ds ) );
+
+ g_signal_connect( G_OBJECT( drawing_area ), "configure_event",
+ G_CALLBACK( goodle_doodle_session_configure_event ), ( gpointer )( ds ) );
+
+ // Event signals
+ g_signal_connect( G_OBJECT( drawing_area ), "button_press_event",
+ G_CALLBACK( goodle_doodle_session_brush_down ), ( gpointer )( ds ) );
+
+ g_signal_connect( G_OBJECT( drawing_area ), "motion_notify_event",
+ G_CALLBACK( goodle_doodle_session_brush_motion ), ( gpointer )( ds ) );
+
+ g_signal_connect( G_OBJECT( drawing_area ), "button_release_event",
+ G_CALLBACK( goodle_doodle_session_brush_up ), ( gpointer )( ds ) );
+
+ gtk_widget_set_events( drawing_area, GDK_EXPOSURE_MASK |
+ GDK_LEAVE_NOTIFY_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_HINT_MASK );
+
+ // Create vertical box to contain the controls
+ vbox_controls = gtk_vbox_new( FALSE, 0 );
+ gtk_container_add( GTK_CONTAINER( hbox_canvas_and_controls ), vbox_controls );
+ gtk_widget_show( vbox_controls );
+
+ // Add a clear button
+ clear_button = gtk_button_new_with_label( "Clear" );
+ gtk_widget_set_size_request( clear_button, 96 ,32 );
+ gtk_box_pack_start( GTK_BOX( vbox_controls ), clear_button, FALSE, FALSE, 0 );
+ gtk_widget_show( clear_button );
+
+ g_signal_connect( G_OBJECT( clear_button ), "clicked",
+ G_CALLBACK( goodle_doodle_session_button_clear_press ), ( gpointer )( ds ) );
+
+ // Add a save button
+ save_button = gtk_button_new_with_label( "Save" );
+ gtk_widget_set_size_request( save_button, 96 ,32 );
+ gtk_box_pack_start( GTK_BOX( vbox_controls ), save_button, FALSE, FALSE, 8 );
+ gtk_widget_show( save_button );
+
+ // Make all this (window) visible
+ gtk_widget_show( window );
+
+ goodle_doodle_session_set_canvas_as_icon( ds );
+
+ // Set default brush size and color
+ ds->brush_size = DOODLE_BRUSH_MEDIUM;
+ ds->brush_color = 0; // black
+}
+*/
+// ------------------------------------------------------------------------------------------------------
+/*
+void goodle_doodle_session_end( GtkWidget *widget, gpointer data )
+{
+ doodle_session *ds = ( doodle_session* )( data );
+ GaimConnection *gc = ds->gc;
+ GdkPixmap *pixmap = ds->pixmap;
+
+ //g_print( "goodle_doodle_session_end | %s\n", ds->who );
+
+ // TODO Ask if user wants to save picture before the session is closed
+
+ if( ds == NULL ) // Fixes sessions with yourself?
+ return;
+
+ yahoo_doodle_command_send_shutdown( gc, ds->who );
+
+ // Clear pixmap memory before we remove this session from the Doodle session list
+ if( pixmap )
+ g_object_unref( pixmap );
+
+ dsList = g_list_remove( dsList, ds );
+ ds = NULL;
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+gboolean goodle_doodle_session_configure_event( GtkWidget *widget, GdkEventConfigure *event, gpointer data )
+{
+ doodle_session *ds = ( doodle_session* )( data );
+
+ GdkPixmap *pixmap = ds->pixmap;
+
+ //g_print( "goodle_doodle_session_configure_event | %s\n", ds->who );
+
+ if( pixmap )
+ g_object_unref( pixmap );
+
+ pixmap = gdk_pixmap_new( widget->window,
+ widget->allocation.width,
+ widget->allocation.height,
+ -1 );
+
+ ds->pixmap = pixmap;
+
+ gdk_draw_rectangle( pixmap,
+ widget->style->white_gc,
+ TRUE,
+ 0, 0,
+ widget->allocation.width,
+ widget->allocation.height );
+
+ return( TRUE );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+gboolean goodle_doodle_session_expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer data )
+{
+ doodle_session *ds = ( doodle_session* )( data );
+ GdkPixmap *pixmap = ds->pixmap;
+
+ //g_print( "goodle_doodle_session_expose_event | %s\n", ds->who );
+
+ gdk_draw_drawable( widget->window,
+ widget->style->fg_gc[GTK_WIDGET_STATE( widget )],
+ pixmap,
+ event->area.x, event->area.y,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height );
+
+ return( FALSE );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+gboolean goodle_doodle_session_brush_down( GtkWidget *widget, GdkEventButton *event, gpointer data )
+{
+ doodle_session *ds = ( doodle_session* )( data );
+ GdkPixmap *pixmap = ds->pixmap;
+
+ int *brush_color = NULL;
+ int *brush_size = NULL;
+ int *x0 = NULL;
+ int *y0 = NULL;
+
+ if( BrushState != BRUSH_STATE_UP )
+ {
+ // Potential double-click DOWN to DOWN?
+
+ g_print( "***Bad brush state transition %d to DOWN\n", BrushState );
+
+ BrushState = BRUSH_STATE_DOWN;
+
+ //return( FALSE );
+ }
+
+ BrushState = BRUSH_STATE_DOWN;
+
+ //g_print( "BRUSH_DOWN | %s\n", ds->who );
+
+ if( event->button == 1 && pixmap != NULL )
+ {
+ // Check if drawList has contents; if so, clear it
+ if( drawList )
+ goodle_doodle_session_destroy_draw_list( drawList );
+
+ brush_color = g_new0( int, 1 );
+ brush_size = g_new0( int, 1 );
+ x0 = g_new0( int, 1 );
+ y0 = g_new0( int, 1 );
+
+ *brush_color = ds->brush_color;
+ *brush_size = ds->brush_size;
+ *x0 = event->x;
+ *y0 = event->y;
+
+ // Set tracking variables
+ LastX = *x0;
+ LastY = *y0;
+ MotionCount = 0;
+
+ drawList = g_list_append( drawList, ( gpointer )( brush_color ) );
+ drawList = g_list_append( drawList, ( gpointer )( brush_size ) );
+ drawList = g_list_append( drawList, ( gpointer )( x0 ) );
+ drawList = g_list_append( drawList, ( gpointer )( y0 ) );
+
+ goodle_doodle_session_draw_brush_point( widget, ds,
+ event->x, event->y,
+ ds->brush_color, ds->brush_size );
+ }
+
+ return( TRUE );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+gboolean goodle_doodle_session_brush_motion( GtkWidget *widget, GdkEventMotion *event, gpointer data )
+{
+ int x;
+ int y;
+ int *dx;
+ int *dy;
+ GdkModifierType state;
+
+ doodle_session *ds = ( doodle_session* )( data );
+ GdkPixmap *pixmap = ds->pixmap;
+
+ //g_print( "BRUSH_MOTION | %s\n", ds->who );
+
+ if( event->is_hint )
+ gdk_window_get_pointer( event->window, &x, &y, &state );
+ else
+ {
+ x = event->x;
+ y = event->y;
+ state = event->state;
+ }
+
+ if( state & GDK_BUTTON1_MASK && pixmap != NULL )
+ {
+ if( ( BrushState != BRUSH_STATE_DOWN ) && ( BrushState != BRUSH_STATE_MOTION ) )
+ {
+ g_print( "***Bad brush state transition %d to MOTION\n", BrushState );
+
+ BrushState = BRUSH_STATE_MOTION;
+
+ return( FALSE );
+ }
+ BrushState = BRUSH_STATE_MOTION;
+
+ dx = g_new0( int, 1 );
+ dy = g_new0( int, 1 );
+
+ *dx = x - LastX;
+ *dy = y - LastY;
+
+ MotionCount++;
+
+ if( MotionCount == DOODLE_MAX_BRUSH_MOTIONS )
+ {
+ drawList = g_list_append( drawList, ( gpointer )( dx ) );
+ drawList = g_list_append( drawList, ( gpointer )( dy ) );
+
+ char* message = goodle_doodle_session_build_draw_string( drawList );
+
+ yahoo_doodle_command_send_draw( ds->gc, ds->who, message );
+
+ // The brush stroke is finished, clear the list for another one
+ goodle_doodle_session_destroy_draw_list( drawList );
+
+ int *brush_color = g_new0( int, 1 );
+ int *brush_size = g_new0( int, 1 );
+ int *x0 = g_new0( int, 1 );
+ int *y0 = g_new0( int, 1 );
+
+ *brush_color = ds->brush_color;
+ *brush_size = ds->brush_size;
+ *x0 = LastX;
+ *y0 = LastY;
+
+ // Reset motion tracking
+ MotionCount = 0;
+
+ drawList = g_list_append( drawList, ( gpointer )( brush_color ) );
+ drawList = g_list_append( drawList, ( gpointer )( brush_size ) );
+ drawList = g_list_append( drawList, ( gpointer )( x0 ) );
+ drawList = g_list_append( drawList, ( gpointer )( y0 ) );
+ }
+ //else
+ {
+ dx = g_new0( int, 1 );
+ dy = g_new0( int, 1 );
+
+ *dx = x - LastX;
+ *dy = y - LastY;
+
+ drawList = g_list_append( drawList, ( gpointer )( dx ) );
+ drawList = g_list_append( drawList, ( gpointer )( dy ) );
+ }
+
+ goodle_doodle_session_draw_brush_line( ds->drawing_area, ds,
+ LastX, LastY,
+ x, y,
+ ds->brush_color, ds->brush_size );
+
+ // Set tracking variables
+ LastX = x;
+ LastY = y;
+ }
+
+ return( TRUE );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+gboolean goodle_doodle_session_brush_up( GtkWidget *widget, GdkEventButton *event, gpointer data )
+{
+ doodle_session *ds = ( doodle_session* )( data );
+ GdkPixmap *pixmap = ds->pixmap;
+
+ //g_print( "BRUSH_UP | %s\n", ds->who );
+
+ if( ( BrushState != BRUSH_STATE_DOWN ) && ( BrushState != BRUSH_STATE_MOTION ) )
+ {
+ g_print( "***Bad brush state transition %d to UP\n", BrushState );
+
+ BrushState = BRUSH_STATE_UP;
+
+ return( FALSE );
+ }
+ BrushState = BRUSH_STATE_UP;
+
+ if( event->button == 1 && pixmap != NULL )
+ {
+ // If the brush was never moved, express two sets of two deltas
+ // That's a 'point,' but not for Yahoo!
+ //if( ( event->x == LastX ) && ( event->y == LastY ) )
+ if( MotionCount == 0 )
+ {
+ int index;
+
+ for( index = 0; index < 2; index++ )
+ {
+ int *x0 = NULL;
+ int *y0 = NULL;
+
+ x0 = g_new0( int, 1 );
+ y0 = g_new0( int, 1 );
+
+ drawList = g_list_append( drawList, ( gpointer )( x0 ) );
+ drawList = g_list_append( drawList, ( gpointer )( y0 ) );
+ }
+ }
+ //else
+ // MotionCount = 0;
+
+ char* message = goodle_doodle_session_build_draw_string( drawList );
+
+ yahoo_doodle_command_send_draw( ds->gc, ds->who, message );
+ goodle_doodle_session_set_canvas_as_icon( ds );
+
+ // The brush stroke is finished, clear the list for another one
+ goodle_doodle_session_destroy_draw_list( drawList );
+ }
+
+ return( TRUE );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void goodle_doodle_session_draw_brush_point( GtkWidget *widget, doodle_session *ds,
+ int x, int y, int color, int size )
+{
+ GdkPixmap *pixmap = ds->pixmap;
+
+ //g_print( "goodle_doodle_session_draw_brush | %s\n", ds->who );
+
+ GdkRectangle update_rect;
+
+ update_rect.x = x - size / 2;
+ update_rect.y = y - size / 2;
+ update_rect.width = size;
+ update_rect.height = size;
+
+ // Interpret and convert color
+ GdkGC *gfx_con = gdk_gc_new( pixmap );
+ GdkColor col;
+
+ goodle_rgb24_to_rgb48( color, &col );
+
+ gdk_gc_set_rgb_fg_color( gfx_con, &col );
+ //gdk_gc_set_rgb_bg_color( gfx_con, &col );
+
+ if( size < DOODLE_BRUSH_MEDIUM )
+ {
+ // Draw a rectangle/square
+ gdk_draw_rectangle( pixmap,
+ gfx_con, // color element?
+ TRUE,
+ update_rect.x, update_rect.y,
+ update_rect.width, update_rect.height );
+ }
+ else
+ {
+ // Draw a circle
+ gdk_draw_arc( pixmap,
+ gfx_con,
+ TRUE,
+ update_rect.x, update_rect.y,
+ update_rect.width, update_rect.height,
+ 0, FULL_CIRCLE_DEGREES );
+ }
+
+ gtk_widget_queue_draw_area( widget,
+ update_rect.x, update_rect.y,
+ update_rect.width, update_rect.height );
+
+ gdk_gc_unref( gfx_con );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void goodle_doodle_session_draw_brush_line( GtkWidget *widget, doodle_session *ds,
+ int x0, int y0, int x1, int y1, int color, int size )
+{
+ int temp;
+
+ int xstep;
+ int ystep;
+
+ gboolean steep = abs( y1 - y0 ) > abs( x1 - x0 );
+
+ if( steep )
+ {
+ temp = x0; x0 = y0; y0 = temp;
+ temp = x1; x1 = y1; y1 = temp;
+ }
+
+ int dx = abs( x1 - x0 );
+ int dy = abs( y1 - y0 );
+
+ int error = 0;
+ int derror = dy;
+
+ int x = x0;
+ int y = y0;
+
+ if( x0 < x1 )
+ xstep = 1;
+ else
+ xstep = -1;
+
+ if( y0 < y1 )
+ ystep = 1;
+ else
+ ystep = -1;
+
+ if( steep )
+ goodle_doodle_session_draw_brush_point( widget, ds, y, x, color, size );
+ else
+ goodle_doodle_session_draw_brush_point( widget, ds, x, y, color, size );
+
+ while( x != x1 )
+ {
+ x = x + xstep;
+ error = error + derror;
+
+ if( ( error * 2 ) >= dx )
+ {
+ y = y + ystep;
+ error = error - dx;
+ }
+
+ if( steep )
+ goodle_doodle_session_draw_brush_point( widget, ds, y, x, color, size );
+ else
+ goodle_doodle_session_draw_brush_point( widget, ds, x, y, color, size );
+ }
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void goodle_doodle_draw_stroke( doodle_session *ds, GList *d_list )
+{
+ // Traverse through the list and draw the points and lines
+ GList *l = d_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;
+
+ //g_print( "Drawing: color=%d, size=%d, (%d,%d)\n", brush_color, brush_size, x, y );
+
+ // 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;
+
+ goodle_doodle_session_draw_brush_line( ds->drawing_area, ds,
+ x, y,
+ x + dx, y + dy,
+ brush_color, brush_size );
+
+ x = x + dx;
+ y = y + dy;
+ }
+
+ g_print( "Counted %d deltas\n", count );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void goodle_doodle_session_destroy_draw_list( GList *d_list )
+{
+ // Destroy the contents of this list
+ int *n = NULL;
+ GList *l = drawList;
+ while( l )
+ {
+ n = l->data;
+
+ g_free( n );
+
+ l = l->next;
+ }
+
+ g_list_free( drawList );
+ drawList = NULL;
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+char *goodle_doodle_session_build_draw_string( GList *d_list )
+{
+ GList *l = d_list;
+
+ int *n = NULL;
+
+ static char message[1024]; // Hope that 500 is enough
+ char token_string[16]; // Token string extracted from draw list
+
+ strcpy( message, "\"" );
+
+ // 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 );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void goodle_doodle_session_clear_canvas( doodle_session *ds )
+{
+ GdkPixmap *pixmap = ds->pixmap;
+ GtkWidget *drawing_area = ds->drawing_area;
+
+ gdk_draw_rectangle( pixmap,
+ drawing_area->style->white_gc,
+ TRUE,
+ 0, 0,
+ drawing_area->allocation.width, drawing_area->allocation.height );
+
+ gtk_widget_queue_draw_area( drawing_area,
+ 0, 0,
+ drawing_area->allocation.width, drawing_area->allocation.height );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void goodle_doodle_session_button_clear_press( GtkWidget *widget, gpointer data )
+{
+ doodle_session *ds = ( doodle_session* )( data );
+
+ yahoo_doodle_command_send_clear( ds->gc, ds->who );
+
+ goodle_doodle_session_clear_canvas( ds );
+
+ goodle_doodle_session_set_canvas_as_icon( ds );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void goodle_doodle_session_set_canvas_as_icon( doodle_session *ds )
+{
+ GdkPixbuf *pixbuf;
+
+ // Makes an icon from the doodle image
+ pixbuf = gdk_pixbuf_get_from_drawable( NULL,
+ ( GdkDrawable* )( ds->pixmap ),
+ gdk_drawable_get_colormap( ds->pixmap ),
+ 0, 0,
+ 0, 0,
+ DOODLE_CANVAS_WIDTH, DOODLE_CANVAS_HEIGHT );
+
+ gtk_window_set_icon( ( GtkWindow* )( ds->window ), pixbuf );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void goodle_rgb24_to_rgb48( int color_rgb, GdkColor *color )
+{
+ color->red = ( color_rgb >> 8 ) | 0xFF;
+ color->green = ( color_rgb & 0xFF00 ) | 0xFF;
+ color->blue = ( ( color_rgb & 0xFF ) << 8 ) | 0xFF;
+}
+
+// ------------------------------------------------------------------------------------------------------
+*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/yahoo/yahoo_doodle.h Wed Jul 13 22:02:56 2005 -0400
@@ -0,0 +1,162 @@
+/**
+ * @file yahoo_doodle.h The Yahoo! protocol plugin Doodle IMVironment object
+ *
+ * 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
+ */
+
+// DEFINES =============================================================================================
+
+#ifndef YAHOO_DOODLE_H
+#define YAHOO_DOODLE_H
+
+// Doodle communication commands
+#define DOODLE_CMD_REQUEST 0
+#define DOODLE_CMD_READY 1
+#define DOODLE_CMD_CLEAR 2
+#define DOODLE_CMD_DRAW 3
+#define DOODLE_CMD_EXTRA 4
+#define DOODLE_CMD_CONFIRM 5
+
+// Doodle communication command for shutting down (also 0)
+#define DOODLE_CMD_SHUTDOWN DOODLE_CMD_REQUEST
+
+#define DOODLE_EXTRA_NONE "\"1\""
+#define DOODLE_EXTRA_TICTACTOE "\"3\""
+#define DOODLE_EXTRA_DOTS "\"2\""
+
+// Doodle session states
+#define DOODLE_STATE_REQUESTING 0
+#define DOODLE_STATE_REQUESTED 1
+#define DOODLE_STATE_ESTABLISHED 2
+
+// Doodle canvas dimensions
+#define DOODLE_CANVAS_WIDTH 368
+#define DOODLE_CANVAS_HEIGHT 256
+
+// Doodle color codes (most likely RGB)
+#define DOODLE_COLOR_RED 13369344
+#define DOODLE_COLOR_ORANGE 16737792
+#define DOODLE_COLOR_YELLOW 15658496
+#define DOODLE_COLOR_GREEN 52224
+#define DOODLE_COLOR_CYAN 52428
+#define DOODLE_COLOR_BLUE 204
+#define DOODLE_COLOR_VIOLET 5381277
+#define DOODLE_COLOR_PURPLE 13369548
+#define DOODLE_COLOR_TAN 12093547
+#define DOODLE_COLOR_BROWN 5256485
+#define DOODLE_COLOR_BLACK 0
+#define DOODLE_COLOR_GREY 11184810
+#define DOODLE_COLOR_WHITE 16777215
+
+#define PALETTE_NUM_OF_COLORS 12
+
+// Doodle brush sizes (most likely variable)
+#define DOODLE_BRUSH_SMALL 2
+#define DOODLE_BRUSH_MEDIUM 5
+#define DOODLE_BRUSH_LARGE 10
+
+#define DOODLE_MAX_BRUSH_MOTIONS 100
+
+#define FULL_CIRCLE_DEGREES 23040
+
+#define BRUSH_STATE_UP 0
+#define BRUSH_STATE_DOWN 1
+#define BRUSH_STATE_MOTION 2
+
+// DATATYPES ===========================================================================================
+typedef struct _doodle_session
+{
+ int state; // State of Doodle session
+
+ GaimConnection *gc; // Connection associated with this session
+
+ char who[32]; // Name of the remote user
+
+ int brush_size; // Size of drawing brush
+ int brush_color; // Color of drawing brush
+
+ //GtkWidget *window; // Window for the Doodle session
+ //GtkWidget *drawing_area; // Drawing area
+
+ //GdkPixmap *pixmap; // Memory for drawing area
+} doodle_session;
+
+// PROTOTYPES ==========================================================================================
+/*
+void init_plugin( GaimPlugin *plugin );
+gboolean goodle_load( GaimPlugin *plugin );
+gboolean goodle_unload( GaimPlugin *plugin );
+void goodle_destroy( GaimPlugin *plugin ); // void or gboolean?
+GtkWidget *get_config_frame( GaimPlugin *plugin );
+
+void goodle_con_signed_on( GaimConnection *gc, gpointer data );
+void goodle_con_signed_off( GaimConnection *gc, gpointer data );
+void goodle_conv_created( GaimConversation *conv, gpointer data );
+void goodle_conv_destroyed( GaimConversation *conv, gpointer data );
+void goodle_button_press( GtkButton *button, gpointer data );
+
+*/
+void yahoo_doodle_process( GaimConnection *gc, char *me, char *from, char *command, char *message );
+
+void yahoo_doodle_command_got_request( GaimConnection *gc, char *from );
+void yahoo_doodle_command_got_ready( GaimConnection *gc, char *from );
+void yahoo_doodle_command_got_draw( GaimConnection *gc, char *from, char *message );
+void yahoo_doodle_command_got_clear( GaimConnection *gc, char *from );
+void yahoo_doodle_command_got_extra( GaimConnection *gc, char *from, char *message );
+void yahoo_doodle_command_got_confirm( GaimConnection *gc, char *from );
+void yahoo_doodle_command_got_shutdown( GaimConnection *gc, char *from );
+
+int yahoo_doodle_command_send_request( GaimConnection *gc, char *to );
+int yahoo_doodle_command_send_ready( GaimConnection *gc, char *to );
+void yahoo_doodle_command_send_draw( GaimConnection *gc, char *to, char *message );
+void yahoo_doodle_command_send_clear( GaimConnection *gc, char *to );
+void yahoo_doodle_command_send_extra( GaimConnection *gc, char *to, char *message );
+void yahoo_doodle_command_send_confirm( GaimConnection *gc, char *to );
+void yahoo_doodle_command_send_shutdown( GaimConnection *gc, char *to );
+
+doodle_session *yahoo_doodle_session_get( GList *ds_list, char *me, char *who );
+//void goodle_doodle_session_start( doodle_session *ds );
+//void goodle_doodle_session_end( GtkWidget *widget, gpointer data );
+
+/*
+gboolean goodle_doodle_session_configure_event( GtkWidget *widget, GdkEventConfigure *event, gpointer data );
+gboolean goodle_doodle_session_expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer data );
+gboolean goodle_doodle_session_brush_down( GtkWidget *widget, GdkEventButton *event, gpointer data );
+gboolean goodle_doodle_session_brush_motion( GtkWidget *widget, GdkEventMotion *event, gpointer data );
+gboolean goodle_doodle_session_brush_up( GtkWidget *widget, GdkEventButton *event, gpointer data );
+
+void goodle_doodle_session_draw_brush_point( GtkWidget *widget, doodle_session *ds,
+ int x, int y, int color, int size );
+void goodle_doodle_session_draw_brush_line( GtkWidget *widget, doodle_session *ds,
+ int x0, int y0, int x1, int y1, int color, int size );
+void goodle_doodle_draw_stroke( doodle_session *ds, GList *d_list );
+void goodle_doodle_session_destroy_draw_list( GList *d_list );
+char *goodle_doodle_session_build_draw_string( GList *d_list );
+void goodle_doodle_session_clear_canvas( doodle_session *ds );
+
+void goodle_doodle_session_button_clear_press( GtkWidget *widget, gpointer data );
+
+void goodle_doodle_session_set_canvas_as_icon( doodle_session *ds );
+
+void goodle_rgb24_to_rgb48( int color_rgb, GdkColor *color );
+*/
+
+#endif // YAHOO_DOODLE_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/yahoo/yahoo_filexfer.c Wed Jul 13 22:02:56 2005 -0400
@@ -0,0 +1,553 @@
+/*
+ * @file yahoo_filexfer.c Yahoo Filetransfer
+ *
+ * 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
+ */
+
+#include "prpl.h"
+#include "internal.h"
+#include "util.h"
+#include "debug.h"
+#include "notify.h"
+#include "proxy.h"
+#include "ft.h"
+#include "yahoo.h"
+#include "yahoo_packet.h"
+#include "yahoo_filexfer.h"
+#include "yahoo_doodle.h"
+
+
+
+struct yahoo_xfer_data {
+ gchar *host;
+ gchar *path;
+ int port;
+ GaimConnection *gc;
+ long expires;
+ gboolean started;
+ gchar *rxqueue;
+ guint rxlen;
+};
+
+static void yahoo_xfer_data_free(struct yahoo_xfer_data *xd)
+{
+ if (xd->host)
+ g_free(xd->host);
+ if (xd->path)
+ g_free(xd->path);
+ g_free(xd);
+}
+
+static void yahoo_receivefile_connected(gpointer data, gint source, GaimInputCondition condition)
+{
+ GaimXfer *xfer;
+ struct yahoo_xfer_data *xd;
+ gchar *buf;
+
+ gaim_debug(GAIM_DEBUG_INFO, "yahoo",
+ "AAA - in yahoo_receivefile_connected\n");
+ if (!(xfer = data))
+ return;
+ if (!(xd = xfer->data))
+ return;
+ if (source < 0) {
+ gaim_xfer_error(GAIM_XFER_RECEIVE, gaim_xfer_get_account(xfer),
+ xfer->who, _("Unable to connect."));
+ gaim_xfer_cancel_remote(xfer);
+ return;
+ }
+
+ xfer->fd = source;
+ gaim_xfer_start(xfer, source, NULL, 0);
+
+ buf = g_strdup_printf("GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n",
+ xd->path, xd->host);
+ write(xfer->fd, buf, strlen(buf));
+ g_free(buf);
+
+ return;
+}
+
+static void yahoo_sendfile_connected(gpointer data, gint source, GaimInputCondition condition)
+{
+ GaimXfer *xfer;
+ struct yahoo_xfer_data *xd;
+ struct yahoo_packet *pkt;
+ gchar *size, *post, *buf;
+ const char *host;
+ int content_length, port;
+ GaimConnection *gc;
+ GaimAccount *account;
+ struct yahoo_data *yd;
+ char *filename, *encoded_filename;
+
+ gaim_debug(GAIM_DEBUG_INFO, "yahoo",
+ "AAA - in yahoo_sendfile_connected\n");
+ if (!(xfer = data))
+ return;
+ if (!(xd = xfer->data))
+ return;
+
+ gc = xd->gc;
+ account = gaim_connection_get_account(gc);
+ yd = gc->proto_data;
+
+
+
+ if (source < 0) {
+ gaim_xfer_error(GAIM_XFER_RECEIVE, gaim_xfer_get_account(xfer),
+ xfer->who, _("Unable to connect."));
+ gaim_xfer_cancel_remote(xfer);
+ return;
+ }
+
+ xfer->fd = source;
+ gaim_xfer_start(xfer, source, NULL, 0);
+
+
+ pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANSFER, YAHOO_STATUS_AVAILABLE, yd->session_id);
+
+ size = g_strdup_printf("%" G_GSIZE_FORMAT, gaim_xfer_get_size(xfer));
+ filename = g_path_get_basename(gaim_xfer_get_local_filename(xfer));
+ encoded_filename = yahoo_string_encode(gc, filename, NULL);
+
+ yahoo_packet_hash(pkt, "sssss", 0, gaim_connection_get_display_name(gc),
+ 5, xfer->who, 14, "", 27, encoded_filename, 28, size);
+
+ content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt);
+
+ buf = g_strdup_printf("Y=%s; T=%s", yd->cookie_y, yd->cookie_t);
+
+ host = gaim_account_get_string(account, "xfer_host", YAHOO_XFER_HOST);
+ port = gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT);
+ post = g_strdup_printf("POST http://%s:%d/notifyft HTTP/1.0\r\n"
+ "Content-length: %" G_GSIZE_FORMAT "\r\n"
+ "Host: %s:%d\r\n"
+ "Cookie: %s\r\n"
+ "\r\n",
+ host, port, content_length + 4 + gaim_xfer_get_size(xfer), host, port, buf);
+ write(xfer->fd, post, strlen(post));
+
+ yahoo_packet_send_special(pkt, xfer->fd, 8);
+ yahoo_packet_free(pkt);
+
+ write(xfer->fd, "29\xc0\x80", 4);
+
+ g_free(size);
+ g_free(post);
+ g_free(buf);
+ g_free(encoded_filename);
+ g_free(filename);
+}
+
+static void yahoo_xfer_init(GaimXfer *xfer)
+{
+ struct yahoo_xfer_data *xfer_data;
+ GaimConnection *gc;
+ GaimAccount *account;
+ struct yahoo_data *yd;
+
+ xfer_data = xfer->data;
+ gc = xfer_data->gc;
+ yd = gc->proto_data;
+ account = gaim_connection_get_account(gc);
+
+ if (gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) {
+ if (yd->jp) {
+ if (gaim_proxy_connect(account, gaim_account_get_string(account, "xferjp_host", YAHOOJP_XFER_HOST),
+ gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT),
+ yahoo_sendfile_connected, xfer) == -1)
+ {
+ gaim_notify_error(gc, NULL, _("File Transfer Failed"),
+ _("Unable to establish file descriptor."));
+ gaim_xfer_cancel_remote(xfer);
+ }
+ } else {
+ if (gaim_proxy_connect(account, gaim_account_get_string(account, "xfer_host", YAHOO_XFER_HOST),
+ gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT),
+ yahoo_sendfile_connected, xfer) == -1)
+ {
+ gaim_notify_error(gc, NULL, _("File Transfer Failed"),
+ _("Unable to establish file descriptor."));
+ gaim_xfer_cancel_remote(xfer);
+ }
+ }
+ } else {
+ xfer->fd = gaim_proxy_connect(account, xfer_data->host, xfer_data->port,
+ yahoo_receivefile_connected, xfer);
+ if (xfer->fd == -1) {
+ gaim_notify_error(gc, NULL, _("File Transfer Failed"),
+ _("Unable to establish file descriptor."));
+ gaim_xfer_cancel_remote(xfer);
+ }
+ }
+}
+
+static void yahoo_xfer_start(GaimXfer *xfer)
+{
+ /* We don't need to do anything here, do we? */
+}
+
+static void yahoo_xfer_end(GaimXfer *xfer)
+{
+ GaimAccount *account;
+ struct yahoo_xfer_data *xfer_data;
+
+ account = gaim_xfer_get_account(xfer);
+ xfer_data = xfer->data;
+
+
+ if (xfer_data)
+ yahoo_xfer_data_free(xfer_data);
+ xfer->data = NULL;
+
+}
+
+guint calculate_length(const gchar *l, size_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (!g_ascii_isdigit(l[i]))
+ continue;
+ return strtol(l + i, NULL, 10);
+ }
+ return 0;
+}
+
+
+ssize_t yahoo_xfer_read(char **buffer, GaimXfer *xfer)
+{
+ gchar buf[4096];
+ ssize_t len;
+ gchar *start = NULL;
+ gchar *length;
+ gchar *end;
+ int filelen;
+ struct yahoo_xfer_data *xd = xfer->data;
+
+ if (gaim_xfer_get_type(xfer) != GAIM_XFER_RECEIVE) {
+ return 0;
+ }
+
+ len = read(xfer->fd, buf, sizeof(buf));
+
+ if (len <= 0) {
+ if ((gaim_xfer_get_size(xfer) > 0) &&
+ (gaim_xfer_get_bytes_sent(xfer) >= gaim_xfer_get_size(xfer))) {
+ gaim_xfer_set_completed(xfer, TRUE);
+ return 0;
+ } else
+ return -1;
+ }
+
+
+ if (!xd->started) {
+ xd->rxqueue = g_realloc(xd->rxqueue, len + xd->rxlen);
+ memcpy(xd->rxqueue + xd->rxlen, buf, len);
+ xd->rxlen += len;
+
+ length = g_strstr_len(xd->rxqueue, len, "Content-length:");
+ /* some proxies re-write this header, changing the capitalization :(
+ * technically that's allowed since headers are case-insensitive
+ * [RFC 2616, section 4.2] */
+ if (length == NULL)
+ length = g_strstr_len(xd->rxqueue, len, "Content-Length:");
+ if (length) {
+ end = g_strstr_len(length, length - xd->rxqueue, "\r\n");
+ if (!end)
+ return 0;
+ if ((filelen = calculate_length(length, len - (length - xd->rxqueue))))
+ gaim_xfer_set_size(xfer, filelen);
+ }
+ start = g_strstr_len(xd->rxqueue, len, "\r\n\r\n");
+ if (start)
+ start += 4;
+ if (!start || start > (xd->rxqueue + len))
+ return 0;
+ xd->started = TRUE;
+
+ len -= (start - xd->rxqueue);
+
+ *buffer = g_malloc(len);
+ memcpy(*buffer, start, len);
+ g_free(xd->rxqueue);
+ xd->rxqueue = NULL;
+ xd->rxlen = 0;
+ } else {
+ *buffer = g_malloc(len);
+ memcpy(*buffer, buf, len);
+ }
+
+ return len;
+}
+
+ssize_t yahoo_xfer_write(const char *buffer, size_t size, GaimXfer *xfer)
+{
+ ssize_t len;
+ struct yahoo_xfer_data *xd = xfer->data;
+
+ if (!xd)
+ return -1;
+
+ if (gaim_xfer_get_type(xfer) != GAIM_XFER_SEND) {
+ return -1;
+ }
+
+ len = write(xfer->fd, buffer, size);
+
+ if (len == -1) {
+ if (gaim_xfer_get_bytes_sent(xfer) >= gaim_xfer_get_size(xfer))
+ gaim_xfer_set_completed(xfer, TRUE);
+ if ((errno != EAGAIN) && (errno != EINTR))
+ return -1;
+ return 0;
+ }
+
+ if ((gaim_xfer_get_bytes_sent(xfer) + len) >= gaim_xfer_get_size(xfer))
+ gaim_xfer_set_completed(xfer, TRUE);
+
+ return len;
+}
+
+static void yahoo_xfer_cancel_send(GaimXfer *xfer)
+{
+ GaimAccount *account;
+ struct yahoo_xfer_data *xfer_data;
+
+ xfer_data = xfer->data;
+ account = gaim_xfer_get_account(xfer);
+
+ if (xfer_data)
+ yahoo_xfer_data_free(xfer_data);
+ xfer->data = NULL;
+}
+
+static void yahoo_xfer_cancel_recv(GaimXfer *xfer)
+{
+ GaimAccount *account;
+ struct yahoo_xfer_data *xfer_data;
+
+ account = gaim_xfer_get_account(xfer);
+ xfer_data = xfer->data;
+
+ if (xfer_data)
+ yahoo_xfer_data_free(xfer_data);
+ xfer->data = NULL;
+}
+
+void yahoo_process_p2pfilexfer( GaimConnection *gc, struct yahoo_packet *pkt )
+{
+ GSList *l = pkt->hash;
+
+ char *me = NULL;
+ char *from = NULL;
+ char *service = NULL;
+ char *message = NULL;
+ char *command = NULL;
+ char *imv = NULL;
+ char *unknown = NULL;
+
+ // Get all the necessary values from this new packet
+ while( l )
+ {
+ struct yahoo_pair *pair = l->data;
+
+ if( pair->key == 5 ) // Get who the packet is for
+ me = pair->value;
+
+ if( pair->key == 4 ) // Get who the packet is from
+ from = pair->value;
+
+ if( pair->key == 49 ) // Get the type of service
+ service = pair->value;
+
+ if( pair->key == 14 ) // Get the 'message' of the packet
+ message = pair->value;
+
+ if( pair->key == 13 ) // Get the command associated with this packet
+ command = pair->value;
+
+ if( pair->key == 63 ) // IMVironment name and version
+ imv = pair->value;
+
+ if( pair->key == 64 ) // Not sure, but it does vary with initialization of Doodle
+ unknown = pair->value; // So, I'll keep it (for a little while atleast)
+
+ l = l->next;
+ }
+
+ // If this packet is an IMVIRONMENT, handle it accordingly
+ if( !strcmp( service, "IMVIRONMENT" ) )
+ {
+ // Check for a Doodle packet and handle it accordingly
+ if( !strcmp( imv, "doodle;11" ) )
+ yahoo_doodle_process( gc, me, from, command, message );
+
+ // If an IMVIRONMENT packet comes without a specific imviroment name
+ if( !strcmp( imv, "" ) )
+ {
+ // It is unfortunately time to close all IMVironments with remote client
+ yahoo_doodle_command_got_shutdown( gc, from );
+ }
+
+ }
+}
+
+void yahoo_process_filetransfer(GaimConnection *gc, struct yahoo_packet *pkt)
+{
+ char *from = NULL;
+ char *to = NULL;
+ char *msg = NULL;
+ char *url = NULL;
+ long expires = 0;
+ GaimXfer *xfer;
+ struct yahoo_xfer_data *xfer_data;
+
+ char *service = NULL;
+
+ char *filename = NULL;
+ unsigned long filesize = 0L;
+
+ GSList *l;
+
+ for (l = pkt->hash; l; l = l->next) {
+ struct yahoo_pair *pair = l->data;
+
+ if (pair->key == 4)
+ from = pair->value;
+ if (pair->key == 5)
+ to = pair->value;
+ if (pair->key == 14)
+ msg = pair->value;
+ if (pair->key == 20)
+ url = pair->value;
+ if (pair->key == 38)
+ expires = strtol(pair->value, NULL, 10);
+
+ if (pair->key == 27)
+ filename = pair->value;
+ if (pair->key == 28)
+ filesize = atol(pair->value);
+
+ if (pair->key == 49)
+ service = pair->value;
+ }
+
+ if (pkt->service == YAHOO_SERVICE_P2PFILEXFER) {
+ if (service && (strcmp("FILEXFER", service) != 0)) {
+ gaim_debug_misc("yahoo", "unhandled service 0x%02x", pkt->service);
+ return;
+ }
+ }
+
+ if (msg) {
+ char *tmp;
+ tmp = strchr(msg, '\006');
+ if (tmp)
+ *tmp = '\0';
+ }
+
+ if (!url || !from)
+ return;
+
+
+ /* Setup the Yahoo-specific file transfer data */
+ xfer_data = g_new0(struct yahoo_xfer_data, 1);
+ xfer_data->gc = gc;
+ if (!gaim_url_parse(url, &(xfer_data->host), &(xfer_data->port), &(xfer_data->path), NULL, NULL)) {
+ g_free(xfer_data);
+ return;
+ }
+
+ gaim_debug_misc("yahoo_filexfer", "Host is %s, port is %d, path is %s, and the full url was %s.\n",
+ xfer_data->host, xfer_data->port, xfer_data->path, url);
+
+ /* Build the file transfer handle. */
+ xfer = gaim_xfer_new(gc->account, GAIM_XFER_RECEIVE, from);
+ xfer->data = xfer_data;
+
+ /* Set the info about the incoming file. */
+ if (filename) {
+ char *utf8_filename = yahoo_string_decode(gc, filename, TRUE);
+ gaim_xfer_set_filename(xfer, utf8_filename);
+ g_free(utf8_filename);
+ } else {
+ gchar *start, *end;
+ start = g_strrstr(xfer_data->path, "/");
+ if (start)
+ start++;
+ end = g_strrstr(xfer_data->path, "?");
+ if (start && *start && end) {
+ char *utf8_filename;
+ filename = g_strndup(start, end - start);
+ utf8_filename = yahoo_string_decode(gc, filename, TRUE);
+ g_free(filename);
+ gaim_xfer_set_filename(xfer, utf8_filename);
+ g_free(utf8_filename);
+ filename = NULL;
+ }
+ }
+
+ gaim_xfer_set_size(xfer, filesize);
+
+ /* Setup our I/O op functions */
+ gaim_xfer_set_init_fnc(xfer, yahoo_xfer_init);
+ gaim_xfer_set_start_fnc(xfer, yahoo_xfer_start);
+ gaim_xfer_set_end_fnc(xfer, yahoo_xfer_end);
+ gaim_xfer_set_cancel_send_fnc(xfer, yahoo_xfer_cancel_send);
+ gaim_xfer_set_cancel_recv_fnc(xfer, yahoo_xfer_cancel_recv);
+ gaim_xfer_set_read_fnc(xfer, yahoo_xfer_read);
+ gaim_xfer_set_write_fnc(xfer, yahoo_xfer_write);
+
+ /* Now perform the request */
+ gaim_xfer_request(xfer);
+}
+
+void yahoo_send_file(GaimConnection *gc, const char *who, const char *file)
+{
+ GaimXfer *xfer;
+ struct yahoo_xfer_data *xfer_data;
+
+ if (!who)
+ return;
+
+ xfer_data = g_new0(struct yahoo_xfer_data, 1);
+ xfer_data->gc = gc;
+
+
+ /* Build the file transfer handle. */
+ xfer = gaim_xfer_new(gc->account, GAIM_XFER_SEND, who);
+ xfer->data = xfer_data;
+
+ /* Setup our I/O op functions */
+ gaim_xfer_set_init_fnc(xfer, yahoo_xfer_init);
+ gaim_xfer_set_start_fnc(xfer, yahoo_xfer_start);
+ gaim_xfer_set_end_fnc(xfer, yahoo_xfer_end);
+ gaim_xfer_set_cancel_send_fnc(xfer, yahoo_xfer_cancel_send);
+ gaim_xfer_set_cancel_recv_fnc(xfer, yahoo_xfer_cancel_recv);
+ gaim_xfer_set_read_fnc(xfer, yahoo_xfer_read);
+ gaim_xfer_set_write_fnc(xfer, yahoo_xfer_write);
+
+ /* Now perform the request */
+ if (file)
+ gaim_xfer_request_accepted(xfer, file);
+ else
+ gaim_xfer_request(xfer);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/yahoo/yahoo_filexfer.h Wed Jul 13 22:02:56 2005 -0400
@@ -0,0 +1,40 @@
+/*
+ * 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
+ */
+
+/**
+ * Process ymsg events, particular IMViroments like Doodle
+ */
+void yahoo_process_p2pfilexfer( GaimConnection *gc, struct yahoo_packet *pkt );
+
+/**
+ * Process ymsg file receive invites.
+ */
+void yahoo_process_filetransfer(GaimConnection *gc, struct yahoo_packet *pkt);
+
+/**
+ * Send a file.
+ *
+ * @param gc The GaimConnection handle.
+ * @param who Who are we sending it to?
+ * @param file What file? If NULL, user will choose after this call.
+ */
+void yahoo_send_file(GaimConnection *gc, const char *who, const char *file);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/whiteboard.c Wed Jul 13 22:02:56 2005 -0400
@@ -0,0 +1,48 @@
+/*
+ * 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 "whiteboard.h"
+/*
+// DATATYPES ============================================================================================
+
+//static GaimWhiteboardOps *ui_ops = NULL;
+
+// FUNCTIONS ============================================================================================
+
+void gaim_whiteboard_draw_line( GaimWhiteBoard *board, int x1, int y1, int x2, int y2 )
+{
+ if( ui_ops && ui_ops->draw_line )
+ ui_ops->draw_line( board, x1, y1, x2, y2 );
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+void gaim_whiteboard_set_ui_ops( GaimWhiteboardOps *ops )
+{
+ ui_ops = ops;
+}
+
+// ------------------------------------------------------------------------------------------------------
+*/
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/whiteboard.h Wed Jul 13 22:02:56 2005 -0400
@@ -0,0 +1,51 @@
+/**
+ * @file whiteboard.h The GaimWhiteboard core object
+ *
+ * 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
+ */
+
+// DEFINES =============================================================================================
+
+#ifndef _GAIM_WHITEBOARD_H_
+#define _GAIM_WHITEBOARD_H_
+
+// INCLUDES ============================================================================================
+/*
+#include <glib.h>
+
+// DATATYPES ===========================================================================================
+
+typedef struct _GaimWhiteboard
+{
+ int dummy; // remove this when more apporiate stuff is added
+} GaimWhiteboard;
+
+typedef struct _GaimWhiteBoardOps
+{
+ void ( *draw_line )( GaimWhiteboard *board, int x1, int y1, int x2, int y2 );
+} GaimWhiteBoardOps;
+
+// PROTOTYPES ==========================================================================================
+
+void gaim_whiteboard_draw_line( GaimWhiteboard *board, int x1, int y1, int x2, int y2 );
+void gaim_whiteboard_set_ops( GaimWhiteboardOps *ops );
+*/
+#endif // _GAIM_WHITEBOARD_H_
Binary file src/whiteboard.o has changed