summaryrefslogtreecommitdiff
path: root/libpurple/protocols/yahoo/yahoo_doodle.c
diff options
context:
space:
mode:
Diffstat (limited to 'libpurple/protocols/yahoo/yahoo_doodle.c')
-rw-r--r--libpurple/protocols/yahoo/yahoo_doodle.c605
1 files changed, 605 insertions, 0 deletions
diff --git a/libpurple/protocols/yahoo/yahoo_doodle.c b/libpurple/protocols/yahoo/yahoo_doodle.c
new file mode 100644
index 0000000000..aa2b2343e1
--- /dev/null
+++ b/libpurple/protocols/yahoo/yahoo_doodle.c
@@ -0,0 +1,605 @@
+/*
+ * 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
+ *****************************************************************************/
+#if 0
+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
+};
+#endif
+
+/******************************************************************************
+ * Functions
+ *****************************************************************************/
+GaimCmdRet yahoo_doodle_gaim_cmd_start(GaimConversation *conv, const char *cmd, char **args, char **error, void *data)
+{
+ GaimAccount *account;
+ GaimConnection *gc;
+ const gchar *name;
+
+ if(*args && args[0])
+ return GAIM_CMD_RET_FAILED;
+
+ account = gaim_conversation_get_account(conv);
+ gc = gaim_account_get_connection(account);
+ name = gaim_conversation_get_name(conv);
+ yahoo_doodle_initiate(gc, name);
+
+ /* 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_initiate(GaimConnection *gc, const char *name)
+{
+ GaimAccount *account;
+ char *to = (char*)name;
+ GaimWhiteboard *wb;
+
+ g_return_if_fail(gc);
+ g_return_if_fail(name);
+
+ account = gaim_connection_get_account(gc);
+ wb = gaim_whiteboard_get_session(account, to);
+
+ if(wb == NULL)
+ {
+ /* Insert this 'session' in the list. At this point, it's only a
+ * requested session.
+ */
+ gaim_whiteboard_create(account, to, DOODLE_STATE_REQUESTING);
+ }
+
+ /* NOTE Perhaps some careful handling of remote assumed established
+ * sessions
+ */
+
+ yahoo_doodle_command_send_request(gc, to);
+ yahoo_doodle_command_send_ready(gc, to);
+
+}
+
+void yahoo_doodle_process(GaimConnection *gc, const char *me, const char *from,
+ const char *command, const char *message)
+{
+ if(!command)
+ return;
+
+ /* Now check to see what sort of Doodle message it is */
+ switch(atoi(command))
+ {
+ 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, const char *from)
+{
+ GaimAccount *account;
+ GaimWhiteboard *wb;
+
+ gaim_debug_info("yahoo", "doodle: Got Request (%s)\n", from);
+
+ account = gaim_connection_get_account(gc);
+
+ /* Only handle this if local client requested Doodle session (else local
+ * client would have sent one)
+ */
+ wb = gaim_whiteboard_get_session(account, from);
+
+ /* If a session with the remote user doesn't exist */
+ if(wb == NULL)
+ {
+ /* Ask user if they wish 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);
+ */
+
+ 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, const char *from)
+{
+ GaimAccount *account;
+ GaimWhiteboard *wb;
+
+ gaim_debug_info("yahoo", "doodle: Got Ready (%s)\n", from);
+
+ account = gaim_connection_get_account(gc);
+
+ /* Only handle this if local client requested Doodle session (else local
+ * client would have sent one)
+ */
+ 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)
+ {
+ /* TODO 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)
+ {
+ /* gaim_whiteboard_start(wb); */
+ yahoo_doodle_command_send_request(gc, from);
+ }
+}
+
+void yahoo_doodle_command_got_draw(GaimConnection *gc, const char *from, const char *message)
+{
+ GaimAccount *account;
+ GaimWhiteboard *wb;
+ char **tokens;
+ int i;
+ GList *d_list = NULL; /* a local list of drawing info */
+
+ g_return_if_fail(message != NULL);
+
+ gaim_debug_info("yahoo", "doodle: Got Draw (%s)\n", from);
+ gaim_debug_info("yahoo", "doodle: Draw message: %s\n", message);
+
+ account = gaim_connection_get_account(gc);
+
+ /* Only handle this if local client requested Doodle session (else local
+ * client would have sent one)
+ */
+ wb = gaim_whiteboard_get_session(account, from);
+
+ if(wb == NULL)
+ return;
+
+ /* TODO Functionalize
+ * Convert drawing packet message to an integer list
+ */
+
+ /* Check to see if the message begans and ends with quotes */
+ if((message[0] != '\"') || (message[strlen(message) - 1] != '\"'))
+ return;
+
+ /* Ignore the inital quotation mark. */
+ message += 1;
+
+ tokens = g_strsplit(message, ",", 0);
+
+ /* Traverse and extract all integers divided by commas */
+ for (i = 0; tokens[i] != NULL; i++)
+ {
+ int last = strlen(tokens[i]) - 1;
+ if (tokens[i][last] == '"')
+ tokens[i][last] = '\0';
+
+ d_list = g_list_prepend(d_list, GINT_TO_POINTER(atoi(tokens[i])));
+ }
+ d_list = g_list_reverse(d_list);
+
+ g_strfreev(tokens);
+
+ yahoo_doodle_draw_stroke(wb, d_list);
+
+ /* goodle_doodle_session_set_canvas_as_icon(ds); */
+
+ g_list_free(d_list);
+}
+
+void yahoo_doodle_command_got_clear(GaimConnection *gc, const char *from)
+{
+ GaimAccount *account;
+ GaimWhiteboard *wb;
+
+ gaim_debug_info("yahoo", "doodle: Got Clear (%s)\n", from);
+
+ account = gaim_connection_get_account(gc);
+
+ /* Only handle this if local client requested Doodle session (else local
+ * client would have sent one)
+ */
+ 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, const char *from, const char *message)
+{
+ gaim_debug_info("yahoo", "doodle: 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, const char *from)
+{
+ GaimAccount *account;
+ GaimWhiteboard *wb;
+
+ gaim_debug_info("yahoo", "doodle: Got Confirm (%s)\n", from);
+
+ /* Get the doodle session */
+ account = gaim_connection_get_account(gc);
+
+ /* Only handle this if local client requested Doodle session (else local
+ * client would have sent one)
+ */
+ 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, const char *from)
+{
+ GaimAccount *account;
+ GaimWhiteboard *wb;
+
+ g_return_if_fail(from != NULL);
+
+ gaim_debug_info("yahoo", "doodle: Got Shutdown (%s)\n", from);
+
+ account = gaim_connection_get_account(gc);
+
+ /* Only handle this if local client requested Doodle session (else local
+ * client would have sent one)
+ */
+ 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); */
+ }
+}
+
+static void yahoo_doodle_command_send_generic(const char *type,
+ GaimConnection *gc,
+ const char *to,
+ const char *message,
+ const char *thirteen,
+ const char *sixtythree,
+ const char *sixtyfour)
+{
+ struct yahoo_data *yd;
+ struct yahoo_packet *pkt;
+
+ gaim_debug_info("yahoo", "doodle: Sent %s (%s)\n", type, 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_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, thirteen);
+ yahoo_packet_hash_str(pkt, 5, to);
+ yahoo_packet_hash_str(pkt, 63, sixtythree ? sixtythree : "doodle;11");
+ yahoo_packet_hash_str(pkt, 64, sixtyfour);
+ yahoo_packet_hash_str(pkt, 1002, "1");
+
+ yahoo_packet_send_and_free(pkt, yd);
+}
+
+void yahoo_doodle_command_send_request(GaimConnection *gc, const char *to)
+{
+ yahoo_doodle_command_send_generic("Request", gc, to, "1", "1", NULL, "1");
+}
+
+void yahoo_doodle_command_send_ready(GaimConnection *gc, const char *to)
+{
+ yahoo_doodle_command_send_generic("Ready", gc, to, "", "0", NULL, "0");
+}
+
+void yahoo_doodle_command_send_draw(GaimConnection *gc, const char *to, const char *message)
+{
+ yahoo_doodle_command_send_generic("Draw", gc, to, message, "3", NULL, "1");
+}
+
+void yahoo_doodle_command_send_clear(GaimConnection *gc, const char *to)
+{
+ yahoo_doodle_command_send_generic("Clear", gc, to, " ", "2", NULL, "1");
+}
+
+void yahoo_doodle_command_send_extra(GaimConnection *gc, const char *to, const char *message)
+{
+ yahoo_doodle_command_send_generic("Extra", gc, to, message, "4", NULL, "1");
+}
+
+void yahoo_doodle_command_send_confirm(GaimConnection *gc, const char *to)
+{
+ yahoo_doodle_command_send_generic("Confirm", gc, to, "1", "5", NULL, "1");
+}
+
+void yahoo_doodle_command_send_shutdown(GaimConnection *gc, const char *to)
+{
+ yahoo_doodle_command_send_generic("Shutdown", gc, to, "", "0", ";0", "0");
+}
+
+void yahoo_doodle_start(GaimWhiteboard *wb)
+{
+ doodle_session *ds = g_new0(doodle_session, 1);
+
+ /* gaim_debug_debug("yahoo", "doodle: yahoo_doodle_start()\n"); */
+
+ /* Set default brush size and color */
+ ds->brush_size = DOODLE_BRUSH_SMALL;
+ ds->brush_color = DOODLE_COLOR_RED;
+
+ wb->proto_data = ds;
+}
+
+void yahoo_doodle_end(GaimWhiteboard *wb)
+{
+ GaimConnection *gc = gaim_account_get_connection(wb->account);
+
+ /* g_debug_debug("yahoo", "doodle: yahoo_doodle_end()\n"); */
+
+ yahoo_doodle_command_send_shutdown(gc, wb->who);
+
+ g_free(wb->proto_data);
+}
+
+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;
+}
+
+static char *yahoo_doodle_build_draw_string(doodle_session *ds, GList *draw_list)
+{
+ GString *message;
+
+ g_return_val_if_fail(draw_list != NULL, NULL);
+
+ message = g_string_new("");
+ g_string_printf(message, "\"%d,%d", ds->brush_color, ds->brush_size);
+
+ for(; draw_list != NULL; draw_list = draw_list->next)
+ {
+ g_string_append_printf(message, ",%d", GPOINTER_TO_INT(draw_list->data));
+ }
+ g_string_append_c(message, '"');
+
+ return g_string_free(message, FALSE);
+}
+
+void yahoo_doodle_send_draw_list(GaimWhiteboard *wb, GList *draw_list)
+{
+ doodle_session *ds = wb->proto_data;
+ char *message;
+
+ g_return_if_fail(draw_list != NULL);
+
+ message = yahoo_doodle_build_draw_string(ds, draw_list);
+ yahoo_doodle_command_send_draw(wb->account->gc, wb->who, message);
+ g_free(message);
+}
+
+void yahoo_doodle_clear(GaimWhiteboard *wb)
+{
+ yahoo_doodle_command_send_clear(wb->account->gc, wb->who);
+}
+
+
+/* Traverse through the list and draw the points and lines */
+void yahoo_doodle_draw_stroke(GaimWhiteboard *wb, GList *draw_list)
+{
+ int brush_color;
+ int brush_size;
+ int x;
+ int y;
+
+ g_return_if_fail(draw_list != NULL);
+
+ brush_color = GPOINTER_TO_INT(draw_list->data);
+ draw_list = draw_list->next;
+ g_return_if_fail(draw_list != NULL);
+
+ brush_size = GPOINTER_TO_INT(draw_list->data);
+ draw_list = draw_list->next;
+ g_return_if_fail(draw_list != NULL);
+
+ x = GPOINTER_TO_INT(draw_list->data);
+ draw_list = draw_list->next;
+ g_return_if_fail(draw_list != NULL);
+
+ y = GPOINTER_TO_INT(draw_list->data);
+ draw_list = draw_list->next;
+ g_return_if_fail(draw_list != NULL);
+
+ /*
+ gaim_debug_debug("yahoo", "doodle: Drawing: color=%d, size=%d, (%d,%d)\n", brush_color, brush_size, x, y);
+ */
+
+ while(draw_list != NULL && draw_list->next != NULL)
+ {
+ int dx = GPOINTER_TO_INT(draw_list->data);
+ int dy = GPOINTER_TO_INT(draw_list->next->data);
+
+ gaim_whiteboard_draw_line(wb,
+ x, y,
+ x + dx, y + dy,
+ brush_color, brush_size);
+
+ x += dx;
+ y += dy;
+
+ draw_list = draw_list->next->next;
+ }
+}
+
+void yahoo_doodle_get_brush(GaimWhiteboard *wb, int *size, int *color)
+{
+ doodle_session *ds = (doodle_session *)wb->proto_data;
+ *size = ds->brush_size;
+ *color = ds->brush_color;
+}
+
+void yahoo_doodle_set_brush(GaimWhiteboard *wb, int size, int color)
+{
+ doodle_session *ds = (doodle_session *)wb->proto_data;
+ ds->brush_size = size;
+ ds->brush_color = color;
+
+ /* Notify the core about the changes */
+ gaim_whiteboard_set_brush(wb, size, color);
+}
+