Mercurial > pidgin
comparison libpurple/protocols/yahoo/yahoo_doodle.c @ 15373:5fe8042783c1
Rename gtk/ and libgaim/ to pidgin/ and libpurple/
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Sat, 20 Jan 2007 02:32:10 +0000 |
parents | |
children | cf999f8e8a56 |
comparison
equal
deleted
inserted
replaced
15372:f79e0f4df793 | 15373:5fe8042783c1 |
---|---|
1 /* | |
2 * gaim | |
3 * | |
4 * Gaim is the legal property of its developers, whose names are too numerous | |
5 * to list here. Please refer to the COPYRIGHT file distributed with this | |
6 * source distribution. | |
7 * | |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 * | |
22 */ | |
23 | |
24 /****************************************************************************** | |
25 * INCLUDES | |
26 *****************************************************************************/ | |
27 #include "internal.h" | |
28 | |
29 #include "account.h" | |
30 #include "accountopt.h" | |
31 #include "blist.h" | |
32 #include "cipher.h" | |
33 #include "cmds.h" | |
34 #include "debug.h" | |
35 #include "notify.h" | |
36 #include "privacy.h" | |
37 #include "prpl.h" | |
38 #include "proxy.h" | |
39 #include "request.h" | |
40 #include "server.h" | |
41 #include "util.h" | |
42 #include "version.h" | |
43 | |
44 #include "yahoo.h" | |
45 #include "yahoo_packet.h" | |
46 #include "yahoo_friend.h" | |
47 #include "yahoochat.h" | |
48 #include "ycht.h" | |
49 #include "yahoo_auth.h" | |
50 #include "yahoo_filexfer.h" | |
51 #include "yahoo_picture.h" | |
52 | |
53 #include "whiteboard.h" | |
54 #include "yahoo_doodle.h" | |
55 | |
56 /****************************************************************************** | |
57 * Globals | |
58 *****************************************************************************/ | |
59 #if 0 | |
60 const int DefaultColorRGB24[] = | |
61 { | |
62 DOODLE_COLOR_RED, | |
63 DOODLE_COLOR_ORANGE, | |
64 DOODLE_COLOR_YELLOW, | |
65 DOODLE_COLOR_GREEN, | |
66 DOODLE_COLOR_CYAN, | |
67 DOODLE_COLOR_BLUE, | |
68 DOODLE_COLOR_VIOLET, | |
69 DOODLE_COLOR_PURPLE, | |
70 DOODLE_COLOR_TAN, | |
71 DOODLE_COLOR_BROWN, | |
72 DOODLE_COLOR_BLACK, | |
73 DOODLE_COLOR_GREY, | |
74 DOODLE_COLOR_WHITE | |
75 }; | |
76 #endif | |
77 | |
78 /****************************************************************************** | |
79 * Functions | |
80 *****************************************************************************/ | |
81 GaimCmdRet yahoo_doodle_gaim_cmd_start(GaimConversation *conv, const char *cmd, char **args, char **error, void *data) | |
82 { | |
83 GaimAccount *account; | |
84 GaimConnection *gc; | |
85 const gchar *name; | |
86 | |
87 if(*args && args[0]) | |
88 return GAIM_CMD_RET_FAILED; | |
89 | |
90 account = gaim_conversation_get_account(conv); | |
91 gc = gaim_account_get_connection(account); | |
92 name = gaim_conversation_get_name(conv); | |
93 yahoo_doodle_initiate(gc, name); | |
94 | |
95 /* Write a local message to this conversation showing that a request for a | |
96 * Doodle session has been made | |
97 */ | |
98 gaim_conv_im_write(GAIM_CONV_IM(conv), "", _("Sent Doodle request."), | |
99 GAIM_MESSAGE_NICK | GAIM_MESSAGE_RECV, time(NULL)); | |
100 | |
101 return GAIM_CMD_RET_OK; | |
102 } | |
103 | |
104 void yahoo_doodle_initiate(GaimConnection *gc, const char *name) | |
105 { | |
106 GaimAccount *account; | |
107 char *to = (char*)name; | |
108 GaimWhiteboard *wb; | |
109 | |
110 g_return_if_fail(gc); | |
111 g_return_if_fail(name); | |
112 | |
113 account = gaim_connection_get_account(gc); | |
114 wb = gaim_whiteboard_get_session(account, to); | |
115 | |
116 if(wb == NULL) | |
117 { | |
118 /* Insert this 'session' in the list. At this point, it's only a | |
119 * requested session. | |
120 */ | |
121 gaim_whiteboard_create(account, to, DOODLE_STATE_REQUESTING); | |
122 } | |
123 | |
124 /* NOTE Perhaps some careful handling of remote assumed established | |
125 * sessions | |
126 */ | |
127 | |
128 yahoo_doodle_command_send_request(gc, to); | |
129 yahoo_doodle_command_send_ready(gc, to); | |
130 | |
131 } | |
132 | |
133 void yahoo_doodle_process(GaimConnection *gc, const char *me, const char *from, | |
134 const char *command, const char *message) | |
135 { | |
136 if(!command) | |
137 return; | |
138 | |
139 /* Now check to see what sort of Doodle message it is */ | |
140 switch(atoi(command)) | |
141 { | |
142 case DOODLE_CMD_REQUEST: | |
143 yahoo_doodle_command_got_request(gc, from); | |
144 break; | |
145 | |
146 case DOODLE_CMD_READY: | |
147 yahoo_doodle_command_got_ready(gc, from); | |
148 break; | |
149 | |
150 case DOODLE_CMD_CLEAR: | |
151 yahoo_doodle_command_got_clear(gc, from); | |
152 break; | |
153 | |
154 case DOODLE_CMD_DRAW: | |
155 yahoo_doodle_command_got_draw(gc, from, message); | |
156 break; | |
157 | |
158 case DOODLE_CMD_EXTRA: | |
159 yahoo_doodle_command_got_extra(gc, from, message); | |
160 break; | |
161 | |
162 case DOODLE_CMD_CONFIRM: | |
163 yahoo_doodle_command_got_confirm(gc, from); | |
164 break; | |
165 } | |
166 } | |
167 | |
168 void yahoo_doodle_command_got_request(GaimConnection *gc, const char *from) | |
169 { | |
170 GaimAccount *account; | |
171 GaimWhiteboard *wb; | |
172 | |
173 gaim_debug_info("yahoo", "doodle: Got Request (%s)\n", from); | |
174 | |
175 account = gaim_connection_get_account(gc); | |
176 | |
177 /* Only handle this if local client requested Doodle session (else local | |
178 * client would have sent one) | |
179 */ | |
180 wb = gaim_whiteboard_get_session(account, from); | |
181 | |
182 /* If a session with the remote user doesn't exist */ | |
183 if(wb == NULL) | |
184 { | |
185 /* Ask user if they wish to accept the request for a doodle session */ | |
186 /* TODO Ask local user to start Doodle session with remote user */ | |
187 /* NOTE This if/else statement won't work right--must use dialog | |
188 * results | |
189 */ | |
190 | |
191 /* char dialog_message[64]; | |
192 g_sprintf(dialog_message, "%s is requesting to start a Doodle session with you.", from); | |
193 | |
194 gaim_notify_message(NULL, GAIM_NOTIFY_MSG_INFO, "Doodle", | |
195 dialog_message, NULL, NULL, NULL); | |
196 */ | |
197 | |
198 gaim_whiteboard_create(account, from, DOODLE_STATE_REQUESTED); | |
199 | |
200 yahoo_doodle_command_send_request(gc, from); | |
201 } | |
202 | |
203 /* TODO Might be required to clear the canvas of an existing doodle | |
204 * session at this point | |
205 */ | |
206 } | |
207 | |
208 void yahoo_doodle_command_got_ready(GaimConnection *gc, const char *from) | |
209 { | |
210 GaimAccount *account; | |
211 GaimWhiteboard *wb; | |
212 | |
213 gaim_debug_info("yahoo", "doodle: Got Ready (%s)\n", from); | |
214 | |
215 account = gaim_connection_get_account(gc); | |
216 | |
217 /* Only handle this if local client requested Doodle session (else local | |
218 * client would have sent one) | |
219 */ | |
220 wb = gaim_whiteboard_get_session(account, from); | |
221 | |
222 if(wb == NULL) | |
223 return; | |
224 | |
225 if(wb->state == DOODLE_STATE_REQUESTING) | |
226 { | |
227 gaim_whiteboard_start(wb); | |
228 | |
229 wb->state = DOODLE_STATE_ESTABLISHED; | |
230 | |
231 yahoo_doodle_command_send_confirm(gc, from); | |
232 } | |
233 | |
234 if(wb->state == DOODLE_STATE_ESTABLISHED) | |
235 { | |
236 /* TODO Ask whether to save picture too */ | |
237 gaim_whiteboard_clear(wb); | |
238 } | |
239 | |
240 /* NOTE Not sure about this... I am trying to handle if the remote user | |
241 * already thinks we're in a session with them (when their chat message | |
242 * contains the doodle;11 imv key) | |
243 */ | |
244 if(wb->state == DOODLE_STATE_REQUESTED) | |
245 { | |
246 /* gaim_whiteboard_start(wb); */ | |
247 yahoo_doodle_command_send_request(gc, from); | |
248 } | |
249 } | |
250 | |
251 void yahoo_doodle_command_got_draw(GaimConnection *gc, const char *from, const char *message) | |
252 { | |
253 GaimAccount *account; | |
254 GaimWhiteboard *wb; | |
255 char **tokens; | |
256 int i; | |
257 GList *d_list = NULL; /* a local list of drawing info */ | |
258 | |
259 g_return_if_fail(message != NULL); | |
260 | |
261 gaim_debug_info("yahoo", "doodle: Got Draw (%s)\n", from); | |
262 gaim_debug_info("yahoo", "doodle: Draw message: %s\n", message); | |
263 | |
264 account = gaim_connection_get_account(gc); | |
265 | |
266 /* Only handle this if local client requested Doodle session (else local | |
267 * client would have sent one) | |
268 */ | |
269 wb = gaim_whiteboard_get_session(account, from); | |
270 | |
271 if(wb == NULL) | |
272 return; | |
273 | |
274 /* TODO Functionalize | |
275 * Convert drawing packet message to an integer list | |
276 */ | |
277 | |
278 /* Check to see if the message begans and ends with quotes */ | |
279 if((message[0] != '\"') || (message[strlen(message) - 1] != '\"')) | |
280 return; | |
281 | |
282 /* Ignore the inital quotation mark. */ | |
283 message += 1; | |
284 | |
285 tokens = g_strsplit(message, ",", 0); | |
286 | |
287 /* Traverse and extract all integers divided by commas */ | |
288 for (i = 0; tokens[i] != NULL; i++) | |
289 { | |
290 int last = strlen(tokens[i]) - 1; | |
291 if (tokens[i][last] == '"') | |
292 tokens[i][last] = '\0'; | |
293 | |
294 d_list = g_list_prepend(d_list, GINT_TO_POINTER(atoi(tokens[i]))); | |
295 } | |
296 d_list = g_list_reverse(d_list); | |
297 | |
298 g_strfreev(tokens); | |
299 | |
300 yahoo_doodle_draw_stroke(wb, d_list); | |
301 | |
302 /* goodle_doodle_session_set_canvas_as_icon(ds); */ | |
303 | |
304 g_list_free(d_list); | |
305 } | |
306 | |
307 void yahoo_doodle_command_got_clear(GaimConnection *gc, const char *from) | |
308 { | |
309 GaimAccount *account; | |
310 GaimWhiteboard *wb; | |
311 | |
312 gaim_debug_info("yahoo", "doodle: Got Clear (%s)\n", from); | |
313 | |
314 account = gaim_connection_get_account(gc); | |
315 | |
316 /* Only handle this if local client requested Doodle session (else local | |
317 * client would have sent one) | |
318 */ | |
319 wb = gaim_whiteboard_get_session(account, from); | |
320 | |
321 if(wb == NULL) | |
322 return; | |
323 | |
324 if(wb->state == DOODLE_STATE_ESTABLISHED) | |
325 { | |
326 /* TODO Ask user whether to save the image before clearing it */ | |
327 | |
328 gaim_whiteboard_clear(wb); | |
329 } | |
330 } | |
331 | |
332 void | |
333 yahoo_doodle_command_got_extra(GaimConnection *gc, const char *from, const char *message) | |
334 { | |
335 gaim_debug_info("yahoo", "doodle: Got Extra (%s)\n", from); | |
336 | |
337 /* I do not like these 'extra' features, so I'll only handle them in one | |
338 * way, which is returning them with the command/packet to turn them off | |
339 */ | |
340 yahoo_doodle_command_send_extra(gc, from, DOODLE_EXTRA_NONE); | |
341 } | |
342 | |
343 void yahoo_doodle_command_got_confirm(GaimConnection *gc, const char *from) | |
344 { | |
345 GaimAccount *account; | |
346 GaimWhiteboard *wb; | |
347 | |
348 gaim_debug_info("yahoo", "doodle: Got Confirm (%s)\n", from); | |
349 | |
350 /* Get the doodle session */ | |
351 account = gaim_connection_get_account(gc); | |
352 | |
353 /* Only handle this if local client requested Doodle session (else local | |
354 * client would have sent one) | |
355 */ | |
356 wb = gaim_whiteboard_get_session(account, from); | |
357 | |
358 if(wb == NULL) | |
359 return; | |
360 | |
361 /* TODO Combine the following IF's? */ | |
362 | |
363 /* Check if we requested a doodle session */ | |
364 if(wb->state == DOODLE_STATE_REQUESTING) | |
365 { | |
366 wb->state = DOODLE_STATE_ESTABLISHED; | |
367 | |
368 gaim_whiteboard_start(wb); | |
369 | |
370 yahoo_doodle_command_send_confirm(gc, from); | |
371 } | |
372 | |
373 /* Check if we accepted a request for a doodle session */ | |
374 if(wb->state == DOODLE_STATE_REQUESTED) | |
375 { | |
376 wb->state = DOODLE_STATE_ESTABLISHED; | |
377 | |
378 gaim_whiteboard_start(wb); | |
379 } | |
380 } | |
381 | |
382 void yahoo_doodle_command_got_shutdown(GaimConnection *gc, const char *from) | |
383 { | |
384 GaimAccount *account; | |
385 GaimWhiteboard *wb; | |
386 | |
387 g_return_if_fail(from != NULL); | |
388 | |
389 gaim_debug_info("yahoo", "doodle: Got Shutdown (%s)\n", from); | |
390 | |
391 account = gaim_connection_get_account(gc); | |
392 | |
393 /* Only handle this if local client requested Doodle session (else local | |
394 * client would have sent one) | |
395 */ | |
396 wb = gaim_whiteboard_get_session(account, from); | |
397 | |
398 /* TODO Ask if user wants to save picture before the session is closed */ | |
399 | |
400 /* If this session doesn't exist, don't try and kill it */ | |
401 if(wb == NULL) | |
402 return; | |
403 else | |
404 { | |
405 gaim_whiteboard_destroy(wb); | |
406 | |
407 /* yahoo_doodle_command_send_shutdown(gc, from); */ | |
408 } | |
409 } | |
410 | |
411 static void yahoo_doodle_command_send_generic(const char *type, | |
412 GaimConnection *gc, | |
413 const char *to, | |
414 const char *message, | |
415 const char *thirteen, | |
416 const char *sixtythree, | |
417 const char *sixtyfour) | |
418 { | |
419 struct yahoo_data *yd; | |
420 struct yahoo_packet *pkt; | |
421 | |
422 gaim_debug_info("yahoo", "doodle: Sent %s (%s)\n", type, to); | |
423 | |
424 yd = gc->proto_data; | |
425 | |
426 /* Make and send an acknowledge (ready) Doodle packet */ | |
427 pkt = yahoo_packet_new(YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, 0); | |
428 yahoo_packet_hash_str(pkt, 49, "IMVIRONMENT"); | |
429 yahoo_packet_hash_str(pkt, 1, gaim_account_get_username(gc->account)); | |
430 yahoo_packet_hash_str(pkt, 14, message); | |
431 yahoo_packet_hash_str(pkt, 13, thirteen); | |
432 yahoo_packet_hash_str(pkt, 5, to); | |
433 yahoo_packet_hash_str(pkt, 63, sixtythree ? sixtythree : "doodle;11"); | |
434 yahoo_packet_hash_str(pkt, 64, sixtyfour); | |
435 yahoo_packet_hash_str(pkt, 1002, "1"); | |
436 | |
437 yahoo_packet_send_and_free(pkt, yd); | |
438 } | |
439 | |
440 void yahoo_doodle_command_send_request(GaimConnection *gc, const char *to) | |
441 { | |
442 yahoo_doodle_command_send_generic("Request", gc, to, "1", "1", NULL, "1"); | |
443 } | |
444 | |
445 void yahoo_doodle_command_send_ready(GaimConnection *gc, const char *to) | |
446 { | |
447 yahoo_doodle_command_send_generic("Ready", gc, to, "", "0", NULL, "0"); | |
448 } | |
449 | |
450 void yahoo_doodle_command_send_draw(GaimConnection *gc, const char *to, const char *message) | |
451 { | |
452 yahoo_doodle_command_send_generic("Draw", gc, to, message, "3", NULL, "1"); | |
453 } | |
454 | |
455 void yahoo_doodle_command_send_clear(GaimConnection *gc, const char *to) | |
456 { | |
457 yahoo_doodle_command_send_generic("Clear", gc, to, " ", "2", NULL, "1"); | |
458 } | |
459 | |
460 void yahoo_doodle_command_send_extra(GaimConnection *gc, const char *to, const char *message) | |
461 { | |
462 yahoo_doodle_command_send_generic("Extra", gc, to, message, "4", NULL, "1"); | |
463 } | |
464 | |
465 void yahoo_doodle_command_send_confirm(GaimConnection *gc, const char *to) | |
466 { | |
467 yahoo_doodle_command_send_generic("Confirm", gc, to, "1", "5", NULL, "1"); | |
468 } | |
469 | |
470 void yahoo_doodle_command_send_shutdown(GaimConnection *gc, const char *to) | |
471 { | |
472 yahoo_doodle_command_send_generic("Shutdown", gc, to, "", "0", ";0", "0"); | |
473 } | |
474 | |
475 void yahoo_doodle_start(GaimWhiteboard *wb) | |
476 { | |
477 doodle_session *ds = g_new0(doodle_session, 1); | |
478 | |
479 /* gaim_debug_debug("yahoo", "doodle: yahoo_doodle_start()\n"); */ | |
480 | |
481 /* Set default brush size and color */ | |
482 ds->brush_size = DOODLE_BRUSH_SMALL; | |
483 ds->brush_color = DOODLE_COLOR_RED; | |
484 | |
485 wb->proto_data = ds; | |
486 } | |
487 | |
488 void yahoo_doodle_end(GaimWhiteboard *wb) | |
489 { | |
490 GaimConnection *gc = gaim_account_get_connection(wb->account); | |
491 | |
492 /* g_debug_debug("yahoo", "doodle: yahoo_doodle_end()\n"); */ | |
493 | |
494 yahoo_doodle_command_send_shutdown(gc, wb->who); | |
495 | |
496 g_free(wb->proto_data); | |
497 } | |
498 | |
499 void yahoo_doodle_get_dimensions(GaimWhiteboard *wb, int *width, int *height) | |
500 { | |
501 /* standard Doodle canvases are of one size: 368x256 */ | |
502 *width = DOODLE_CANVAS_WIDTH; | |
503 *height = DOODLE_CANVAS_HEIGHT; | |
504 } | |
505 | |
506 static char *yahoo_doodle_build_draw_string(doodle_session *ds, GList *draw_list) | |
507 { | |
508 GString *message; | |
509 | |
510 g_return_val_if_fail(draw_list != NULL, NULL); | |
511 | |
512 message = g_string_new(""); | |
513 g_string_printf(message, "\"%d,%d", ds->brush_color, ds->brush_size); | |
514 | |
515 for(; draw_list != NULL; draw_list = draw_list->next) | |
516 { | |
517 g_string_append_printf(message, ",%d", GPOINTER_TO_INT(draw_list->data)); | |
518 } | |
519 g_string_append_c(message, '"'); | |
520 | |
521 return g_string_free(message, FALSE); | |
522 } | |
523 | |
524 void yahoo_doodle_send_draw_list(GaimWhiteboard *wb, GList *draw_list) | |
525 { | |
526 doodle_session *ds = wb->proto_data; | |
527 char *message; | |
528 | |
529 g_return_if_fail(draw_list != NULL); | |
530 | |
531 message = yahoo_doodle_build_draw_string(ds, draw_list); | |
532 yahoo_doodle_command_send_draw(wb->account->gc, wb->who, message); | |
533 g_free(message); | |
534 } | |
535 | |
536 void yahoo_doodle_clear(GaimWhiteboard *wb) | |
537 { | |
538 yahoo_doodle_command_send_clear(wb->account->gc, wb->who); | |
539 } | |
540 | |
541 | |
542 /* Traverse through the list and draw the points and lines */ | |
543 void yahoo_doodle_draw_stroke(GaimWhiteboard *wb, GList *draw_list) | |
544 { | |
545 int brush_color; | |
546 int brush_size; | |
547 int x; | |
548 int y; | |
549 | |
550 g_return_if_fail(draw_list != NULL); | |
551 | |
552 brush_color = GPOINTER_TO_INT(draw_list->data); | |
553 draw_list = draw_list->next; | |
554 g_return_if_fail(draw_list != NULL); | |
555 | |
556 brush_size = GPOINTER_TO_INT(draw_list->data); | |
557 draw_list = draw_list->next; | |
558 g_return_if_fail(draw_list != NULL); | |
559 | |
560 x = GPOINTER_TO_INT(draw_list->data); | |
561 draw_list = draw_list->next; | |
562 g_return_if_fail(draw_list != NULL); | |
563 | |
564 y = GPOINTER_TO_INT(draw_list->data); | |
565 draw_list = draw_list->next; | |
566 g_return_if_fail(draw_list != NULL); | |
567 | |
568 /* | |
569 gaim_debug_debug("yahoo", "doodle: Drawing: color=%d, size=%d, (%d,%d)\n", brush_color, brush_size, x, y); | |
570 */ | |
571 | |
572 while(draw_list != NULL && draw_list->next != NULL) | |
573 { | |
574 int dx = GPOINTER_TO_INT(draw_list->data); | |
575 int dy = GPOINTER_TO_INT(draw_list->next->data); | |
576 | |
577 gaim_whiteboard_draw_line(wb, | |
578 x, y, | |
579 x + dx, y + dy, | |
580 brush_color, brush_size); | |
581 | |
582 x += dx; | |
583 y += dy; | |
584 | |
585 draw_list = draw_list->next->next; | |
586 } | |
587 } | |
588 | |
589 void yahoo_doodle_get_brush(GaimWhiteboard *wb, int *size, int *color) | |
590 { | |
591 doodle_session *ds = (doodle_session *)wb->proto_data; | |
592 *size = ds->brush_size; | |
593 *color = ds->brush_color; | |
594 } | |
595 | |
596 void yahoo_doodle_set_brush(GaimWhiteboard *wb, int size, int color) | |
597 { | |
598 doodle_session *ds = (doodle_session *)wb->proto_data; | |
599 ds->brush_size = size; | |
600 ds->brush_color = color; | |
601 | |
602 /* Notify the core about the changes */ | |
603 gaim_whiteboard_set_brush(wb, size, color); | |
604 } | |
605 |