comparison src/protocols/gg/gg.c @ 11394:54934c165625

[gaim-migrate @ 13625] Implementation of the conferences in the Gadu-Gadu prpl. committer: Tailor Script <tailor@pidgin.im>
author Bartoz Oler <bartosz@pidgin.im>
date Wed, 31 Aug 2005 19:57:20 +0000
parents cf15c1cdcfbd
children d530188f04b8
comparison
equal deleted inserted replaced
11393:1e756e251dc3 11394:54934c165625
1 /**
2 * @file gg.c Gadu-Gadu protocol plugin
3 *
4 * gaim
5 *
6 * Copyright (C) 2005 Bartosz Oler <bartosz@bzimage.us>
7 *
8 * Some parts of the code are adapted or taken for the previous implementation
9 * of this plugin written by Arkadiusz Miskiewicz <misiek@pld.org.pl>
10 *
11 * Thanks to Google's Summer of Code Program.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 */
27
1 28
2 /* 29 /*
3 * NOTES 30 * NOTES
4 * 31 *
5 * I don't like automatic updates of the buddylist stored on the server, so not 32 * I don't like automatic updates of the buddylist stored on the server, so not
23 50
24 static GaimPlugin *my_protocol = NULL; 51 static GaimPlugin *my_protocol = NULL;
25 52
26 typedef struct 53 typedef struct
27 { 54 {
55 char *name;
56 GList *participants;
57
58 } GGPChat;
59
60 typedef struct
61 {
28 char *token_id; 62 char *token_id;
29 63
30 } GGPToken; 64 } GGPToken;
31 65
32 typedef struct { 66 typedef struct {
49 83
50 struct gg_session *session; 84 struct gg_session *session;
51 GGPSearchForm *search_form; 85 GGPSearchForm *search_form;
52 GGPToken *register_token; 86 GGPToken *register_token;
53 GGPToken *chpasswd_token; 87 GGPToken *chpasswd_token;
88 GList *chats;
54 void *searchresults_window; 89 void *searchresults_window;
90
91 char *tmp_buddy;
92 int chats_count;
55 93
56 } GGPInfo; 94 } GGPInfo;
57 95
58 /** 96 /**
59 * Convert enconding of a given string. 97 * Convert enconding of a given string.
157 195
158 return form; 196 return form;
159 } 197 }
160 /* }}} */ 198 /* }}} */
161 199
200 /**
201 * Returns the best name of a buddy from the buddylist.
202 *
203 * @param gc GaimConnection instance.
204 * @param uin UIN of the buddy.
205 *
206 * @return Name of the buddy, or UIN converted to string.
207 */
208 /* static const *char ggp_buddy_get_name(GaimConnection *gc, const uin_t uin) {{{ */
209 static const char *ggp_buddy_get_name(GaimConnection *gc, const uin_t uin)
210 {
211 GaimBuddy *buddy;
212 gchar *str_uin;
213
214 str_uin = g_strdup_printf("%lu", (unsigned long int)uin);
215
216 buddy = gaim_find_buddy(gaim_connection_get_account(gc), str_uin);
217 if (buddy != NULL) {
218 g_free(str_uin);
219 return gaim_buddy_get_alias(buddy);
220 } else {
221 return str_uin;
222 }
223 }
224 /* }}} */
225
226 /* ---------------------------------------------------------------------- */
227 /* ----- CONFERENCES ---------------------------------------------------- */
228 /* ---------------------------------------------------------------------- */
229
230 /**
231 * Finds a CHAT conversation for the current account with the specified name.
232 *
233 * @param gc GaimConnection instance.
234 * @param name Name of the conversation.
235 *
236 * @return GaimConversation or NULL if not found.
237 */
238 /* static GaimConversation *ggp_chat_find_conversation(GaimConnection *gc, const gchar *name) {{{ */
239 static GaimConversation *ggp_chat_find_conversation(GaimConnection *gc, const gchar *name)
240 {
241 g_return_val_if_fail(gc != NULL, NULL);
242 g_return_val_if_fail(name != NULL, NULL);
243
244 return gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, name,
245 gaim_connection_get_account(gc));
246 }
247 /* }}} */
248
249 /**
250 * Adds the specified UIN to the specified conversation.
251 *
252 * @param gc GaimConnection.
253 * @param chat_name Name of the conversation.
254 */
255 /* static void ggp_chat_participants_add_uin(GaimConnection *gc, const gchar *chat_name, const uin_t uin) {{{ */
256 static void ggp_chat_participants_add_uin(GaimConnection *gc, const gchar *chat_name,
257 const uin_t uin)
258 {
259 GaimConversation *conv;
260 GGPInfo *info = gc->proto_data;
261 GGPChat *chat;
262 GList *l;
263 gchar *str_uin;
264
265 str_uin = g_strdup_printf("%lu", (unsigned long int)uin);
266
267 for (l = info->chats; l != NULL; l = l->next) {
268 chat = l->data;
269
270 if (g_utf8_collate(chat->name, chat_name) == 0) {
271 if (g_list_find(chat->participants, str_uin) == NULL) {
272 chat->participants = g_list_append(chat->participants, str_uin);
273 conv = ggp_chat_find_conversation(gc, chat_name);
274
275 gaim_conv_chat_add_user(GAIM_CONV_CHAT(conv),
276 ggp_buddy_get_name(gc, uin), NULL, GAIM_CBFLAGS_NONE, TRUE);
277 }
278 break;
279 }
280 }
281 }
282 /* }}} */
283
284 /**
285 * Add the specified UINs to the specified conversation.
286 *
287 * @param gc GaimConnection.
288 * @param chat_name Name of the conversation.
289 * @param recipients List of the UINs.
290 * @param count Number of the UINs.
291 */
292 /* static void ggp_chat_participants_add(GaimConnection *gc, const gchar *chat_name, const uin_t *recipients, int count) {{{ */
293 static void ggp_chat_participants_add(GaimConnection *gc, const gchar *chat_name,
294 const uin_t *recipients, int count)
295 {
296 GaimConversation *conv;
297 GGPInfo *info = gc->proto_data;
298 GGPChat *chat;
299 GList *l;
300 int i;
301 gchar *uin;
302
303 for (l = info->chats; l != NULL; l = l->next) {
304 chat = l->data;
305
306 if (g_utf8_collate(chat->name, chat_name) == 0) {
307
308 for (i = 0; i < count; i++) {
309 uin = g_strdup_printf("%lu", (unsigned long int)recipients[i]);
310 if (g_list_find(chat->participants, uin) == NULL) {
311 chat->participants = g_list_append(chat->participants, uin);
312 conv = ggp_chat_find_conversation(gc, chat_name);
313
314 gaim_conv_chat_add_user(GAIM_CONV_CHAT(conv),
315 ggp_buddy_get_name(gc, recipients[i]),
316 NULL, GAIM_CBFLAGS_NONE, TRUE);
317 }
318 g_free(uin);
319 }
320 break;
321 }
322 }
323 }
324 /* }}} */
325
326 /**
327 * Finds a conversation in which all the specified recipients participate.
328 *
329 * TODO: This function should be rewritten to better handle situations when
330 * somobody adds more people to the converation.
331 *
332 * @param gc GaimConnection.
333 * @param recipients List of the people in the conversation.
334 * @param count Number of people.
335 *
336 * @return Name of the conversation.
337 */
338 /* static const char *ggp_find_chat_by_recipients(GaimConnection *gc, const uin_t *recipients, int count) {{{ */
339 static const char *ggp_find_chat_by_recipients(GaimConnection *gc,
340 const uin_t *recipients, int count)
341 {
342 GGPInfo *info = gc->proto_data;
343 GGPChat *chat = NULL;
344 GList *l, *m;
345 int i;
346 int maches;
347
348 g_return_val_if_fail(info->chats != NULL, NULL);
349
350 for (l = info->chats; l != NULL; l = l->next) {
351 chat = l->data;
352 maches = 0;
353
354 for (m = chat->participants; m != NULL; m = m->next) {
355 uin_t p = ggp_str_to_uin(m->data);
356
357 for (i = 0; i < count; i++)
358 if (p == recipients[i])
359 maches++;
360 }
361
362 if (maches == count)
363 break;
364
365 chat = NULL;
366 }
367
368 if (chat == NULL)
369 return NULL;
370 else
371 return chat->name;
372 }
373 /* }}} */
374
375 /**
376 * Adds a new conversation to the internal list of conversations.
377 * If name is NULL then it will be automagically generated.
378 *
379 * @param gc GaimConnection.
380 * @param name Name of the conversation.
381 *
382 * @return Name of the conversation.
383 */
384 /* static const char *ggp_chat_add_new(GaimConnection *gc, const char *name) {{{ */
385 static const char *ggp_chat_add_new(GaimConnection *gc, const char *name)
386 {
387 GGPInfo *info = gc->proto_data;
388 GGPChat *chat;
389
390 chat = g_new0(GGPChat, 1);
391
392 if (name == NULL)
393 chat->name = g_strdup_printf("conf#%d", info->chats_count++);
394 else
395 chat->name = g_strdup(name);
396
397 chat->participants = NULL;
398
399 info->chats = g_list_append(info->chats, chat);
400
401 return chat->name;
402 }
403 /* }}} */
404
405 /**
406 * Dispatch a message received from a buddy.
407 *
408 * @param gc GaimConnection.
409 * @param ev Gadu-Gadu event structure.
410 */
411 /* static void ggp_recv_message_handler(GaimConnection *gc, const struct gg_event *ev) {{{ */
412 static void ggp_recv_message_handler(GaimConnection *gc, const struct gg_event *ev)
413 {
414 GGPInfo *info = gc->proto_data;
415 GaimConversation *conv;
416 gchar *from;
417 gchar *msg;
418 gchar *tmp;
419 const char *chat_name;
420 int chat_id;
421
422 from = g_strdup_printf("%lu", (unsigned long int)ev->event.msg.sender);
423
424 msg = charset_convert((const char *)ev->event.msg.message,
425 "CP1250", "UTF-8");
426 gaim_str_strip_cr(msg);
427 tmp = g_markup_escape_text(msg, -1);
428
429 gaim_debug_info("gg", "msg form (%s): %s (class = %d; rcpt_count = %d)\n",
430 from, tmp, ev->event.msg.msgclass, ev->event.msg.recipients_count);
431
432 /*
433 * Chat between only two presons will be treated as a private message.
434 * It's due to some broken clients that send private messages
435 * with msgclass == CHAT
436 */
437 if (ev->event.msg.recipients_count == 0) {
438 serv_got_im(gc, from, tmp, 0, ev->event.msg.time);
439 } else {
440 chat_name = ggp_find_chat_by_recipients(gc,
441 ev->event.msg.recipients,
442 ev->event.msg.recipients_count);
443 if (chat_name == NULL) {
444 chat_name = ggp_chat_add_new(gc, NULL);
445 serv_got_joined_chat(gc, info->chats_count, chat_name);
446 ggp_chat_participants_add_uin(gc, chat_name, ev->event.msg.sender);
447 ggp_chat_participants_add(gc, chat_name, ev->event.msg.recipients,
448 ev->event.msg.recipients_count);
449 }
450 conv = ggp_chat_find_conversation(gc, chat_name);
451 chat_id = gaim_conv_chat_get_id(GAIM_CONV_CHAT(conv));
452 serv_got_chat_in(gc, chat_id, ggp_buddy_get_name(gc, ev->event.msg.sender),
453 0, msg, ev->event.msg.time);
454 }
455 g_free(msg);
456 g_free(tmp);
457 g_free(from);
458 }
459 /* }}} */
460
162 /* ---------------------------------------------------------------------- */ 461 /* ---------------------------------------------------------------------- */
163 /* ----- BUDDYLIST STUFF ------------------------------------------------ */ 462 /* ----- BUDDYLIST STUFF ------------------------------------------------ */
164 /* ---------------------------------------------------------------------- */ 463 /* ---------------------------------------------------------------------- */
165 464
166 /*
167 * Adapted from the previous GG implementation in Gaim
168 * by Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
169 */
170 /* static void ggp_buddylist_send(GaimConnection *gc) {{{ */ 465 /* static void ggp_buddylist_send(GaimConnection *gc) {{{ */
171 static void ggp_buddylist_send(GaimConnection *gc) 466 static void ggp_buddylist_send(GaimConnection *gc)
172 { 467 {
173 GGPInfo *info = gc->proto_data; 468 GGPInfo *info = gc->proto_data;
174 469
284 ggp_buddylist_send(gc); 579 ggp_buddylist_send(gc);
285 580
286 } 581 }
287 /* }}} */ 582 /* }}} */
288 583
289 /* 584 /**
585 * Handle change of the status of the buddy.
586 *
587 * @param gc GaimConnection
588 * @param uin UIN of the buddy.
589 * @param status ID of the status.
590 * @param descr Description.
290 */ 591 */
291 /* static void ggp_generic_status_handler(GaimConnection *gc, uin_t uin, int status, const char *descr) {{{ */ 592 /* static void ggp_generic_status_handler(GaimConnection *gc, uin_t uin, int status, const char *descr) {{{ */
292 static void ggp_generic_status_handler(GaimConnection *gc, uin_t uin, int status, const char *descr) 593 static void ggp_generic_status_handler(GaimConnection *gc, uin_t uin, int status, const char *descr)
293 { 594 {
294 gchar *from; 595 gchar *from;
325 g_free(from); 626 g_free(from);
326 g_free(msg); 627 g_free(msg);
327 } 628 }
328 /* }}} */ 629 /* }}} */
329 630
330 /* 631 /**
632 * Initiate a search in the public directory.
633 *
634 * @param gc GaimConnection.
635 * @param form Filled in GGPSearchForm.
331 */ 636 */
332 /* static void ggp_pubdir_start_search(GaimConnection *gc, GGPSearchForm *form) {{{ */ 637 /* static void ggp_pubdir_start_search(GaimConnection *gc, GGPSearchForm *form) {{{ */
333 static void ggp_pubdir_start_search(GaimConnection *gc, GGPSearchForm *form) 638 static void ggp_pubdir_start_search(GaimConnection *gc, GGPSearchForm *form)
334 { 639 {
335 GGPInfo *info = gc->proto_data; 640 GGPInfo *info = gc->proto_data;
412 717
413 return (tmp == NULL) ? g_strdup("") : tmp; 718 return (tmp == NULL) ? g_strdup("") : tmp;
414 } 719 }
415 /* }}} */ 720 /* }}} */
416 721
722 /*
723 */
724 /* static void ggp_callback_show_next(GaimConnection *gc, GList *row) {{{ */
417 static void ggp_callback_show_next(GaimConnection *gc, GList *row) 725 static void ggp_callback_show_next(GaimConnection *gc, GList *row)
418 { 726 {
419 GGPInfo *info = gc->proto_data; 727 GGPInfo *info = gc->proto_data;
420 728
421 g_free(info->search_form->offset); 729 g_free(info->search_form->offset);
422 info->search_form->offset = g_strdup(info->search_form->last_uin); 730 info->search_form->offset = g_strdup(info->search_form->last_uin);
423 gaim_debug_info("gg", "london calling... offset = %s\n", info->search_form->offset);
424 ggp_pubdir_start_search(gc, info->search_form); 731 ggp_pubdir_start_search(gc, info->search_form);
425 } 732 }
426 733 /* }}} */
734
735 /*
736 */
737 /* static void ggp_callback_add_buddy(GaimConnection *gc, GList *row) {{{ */
427 static void ggp_callback_add_buddy(GaimConnection *gc, GList *row) 738 static void ggp_callback_add_buddy(GaimConnection *gc, GList *row)
428 { 739 {
429 gaim_blist_request_add_buddy(gaim_connection_get_account(gc), 740 gaim_blist_request_add_buddy(gaim_connection_get_account(gc),
430 g_list_nth_data(row, 0), NULL, NULL); 741 g_list_nth_data(row, 0), NULL, NULL);
431 } 742 }
743 /* }}} */
432 744
433 /* 745 /*
434 */ 746 */
435 /* static void ggp_callback_recv(gpointer _gc, gint fd, GaimInputCondition cond) {{{ */ 747 /* static void ggp_callback_recv(gpointer _gc, gint fd, GaimInputCondition cond) {{{ */
436 static void ggp_callback_recv(gpointer _gc, gint fd, GaimInputCondition cond) 748 static void ggp_callback_recv(gpointer _gc, gint fd, GaimInputCondition cond)
449 switch (ev->type) { 761 switch (ev->type) {
450 case GG_EVENT_NONE: 762 case GG_EVENT_NONE:
451 /* Nothing happened. */ 763 /* Nothing happened. */
452 break; 764 break;
453 case GG_EVENT_MSG: 765 case GG_EVENT_MSG:
454 { 766 ggp_recv_message_handler(gc, ev);
455 gchar *from;
456 gchar *msg;
457 gchar *tmp;
458
459 from = g_strdup_printf("%lu", (unsigned long int)ev->event.msg.sender);
460
461 msg = charset_convert((const char *)ev->event.msg.message,
462 "CP1250", "UTF-8");
463 gaim_str_strip_cr(msg);
464 tmp = g_markup_escape_text(msg, -1);
465 gaim_debug_info("gg", "msg form (%s): %s (class = %d)\n", from, tmp, ev->event.msg.msgclass);
466 serv_got_im(gc, from, tmp, 0, ev->event.msg.time);
467 g_free(msg);
468 g_free(tmp);
469 g_free(from);
470 }
471 break; 767 break;
472 case GG_EVENT_ACK: 768 case GG_EVENT_ACK:
473 gaim_debug_info("gg", "message sent to: %ld, delivery status=%d, seq=%d\n", 769 gaim_debug_info("gg", "message sent to: %ld, delivery status=%d, seq=%d\n",
474 ev->event.ack.recipient, ev->event.ack.status, ev->event.ack.seq); 770 ev->event.ack.recipient, ev->event.ack.status, ev->event.ack.seq);
475 break; 771 break;
1197 1493
1198 g_free(msg); 1494 g_free(msg);
1199 } 1495 }
1200 /* }}} */ 1496 /* }}} */
1201 1497
1498 /*
1499 */
1500 /* static void ggp_callback_add_to_chat_ok(GaimConnection *gc, GaimRequestFields *fields) {{{ */
1501 static void ggp_callback_add_to_chat_ok(GaimConnection *gc, GaimRequestFields *fields)
1502 {
1503 GGPInfo *info = gc->proto_data;
1504 GaimRequestField *field;
1505 const GList *sel, *l;
1506
1507 field = gaim_request_fields_get_field(fields, "name");
1508 sel = gaim_request_field_list_get_selected(field);
1509 gaim_debug_info("gg", "selected chat %s for buddy %s\n", sel->data, info->tmp_buddy);
1510
1511 for (l = info->chats; l != NULL; l = l->next) {
1512 GGPChat *chat = l->data;
1513
1514 if (g_utf8_collate(chat->name, sel->data) == 0) {
1515 chat->participants = g_list_append(chat->participants, info->tmp_buddy);
1516 break;
1517 }
1518 }
1519 }
1520 /* }}} */
1521
1522 /*
1523 */
1524 /* static void ggp_bmenu_add_to_chat(GaimBlistNode *node, gpointer ignored) {{{ */
1525 static void ggp_bmenu_add_to_chat(GaimBlistNode *node, gpointer ignored)
1526 {
1527 GaimBuddy *buddy;
1528 GaimConnection *gc;
1529 GGPInfo *info;
1530
1531 GaimRequestFields *fields;
1532 GaimRequestFieldGroup *group;
1533 GaimRequestField *field;
1534
1535 GList *l;
1536 gchar *msg;
1537
1538 buddy = (GaimBuddy *)node;
1539 gc = gaim_account_get_connection(gaim_buddy_get_account(buddy));
1540 info = gc->proto_data;
1541
1542 /* TODO: It tmp_buddy != NULL then stop! */
1543 info->tmp_buddy = g_strdup(gaim_buddy_get_name(buddy));
1544
1545 fields = gaim_request_fields_new();
1546 group = gaim_request_field_group_new(NULL);
1547 gaim_request_fields_add_group(fields, group);
1548
1549 field = gaim_request_field_list_new("name", "Chat name");
1550 for (l = info->chats; l != NULL; l = l->next) {
1551 GGPChat *chat = l->data;
1552 gaim_debug_info("gg", "adding chat %s\n", chat->name);
1553 gaim_request_field_list_add(field, g_strdup(chat->name), g_strdup(chat->name));
1554 }
1555 gaim_request_field_group_add_field(group, field);
1556
1557 msg = g_strdup_printf(_("Select a chat for buddy: %s"), gaim_buddy_get_name(buddy));
1558 gaim_request_fields(gc,
1559 _("Add to chat..."),
1560 _("Add to chat..."),
1561 msg,
1562 fields,
1563 _("Add"), G_CALLBACK(ggp_callback_add_to_chat_ok),
1564 _("Cancel"), NULL, gc);
1565 g_free(msg);
1566 }
1567 /* }}} */
1568
1202 /* ---------------------------------------------------------------------- */ 1569 /* ---------------------------------------------------------------------- */
1203 /* ----- GaimPluginProtocolInfo ----------------------------------------- */ 1570 /* ----- GaimPluginProtocolInfo ----------------------------------------- */
1204 /* ---------------------------------------------------------------------- */ 1571 /* ---------------------------------------------------------------------- */
1205 1572
1206 /* 1573 /*
1210 { 1577 {
1211 return "gadu-gadu"; 1578 return "gadu-gadu";
1212 } 1579 }
1213 /* }}} */ 1580 /* }}} */
1214 1581
1215 /*
1216 */
1217 /* static void ggp_list_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne) {{{ */ 1582 /* static void ggp_list_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne) {{{ */
1218 static void ggp_list_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne) 1583 static void ggp_list_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne)
1219 { 1584 {
1220 GaimPresence *presence = gaim_buddy_get_presence(b); 1585 GaimPresence *presence = gaim_buddy_get_presence(b);
1221 1586
1243 gaim_debug_info("gg", "ggp_list_emblems: unknown status\n"); 1608 gaim_debug_info("gg", "ggp_list_emblems: unknown status\n");
1244 } 1609 }
1245 } 1610 }
1246 /* }}} */ 1611 /* }}} */
1247 1612
1248 /*
1249 */
1250 /* static char *ggp_status_text(GaimBuddy *b) {{{ */ 1613 /* static char *ggp_status_text(GaimBuddy *b) {{{ */
1251 static char *ggp_status_text(GaimBuddy *b) 1614 static char *ggp_status_text(GaimBuddy *b)
1252 { 1615 {
1253 GaimStatus *status; 1616 GaimStatus *status;
1254 const char *msg; 1617 const char *msg;
1273 return text; 1636 return text;
1274 } 1637 }
1275 } 1638 }
1276 /* }}} */ 1639 /* }}} */
1277 1640
1278 /*
1279 */
1280 /* static char *ggp_tooltip_text(GaimBuddy *b) {{{ */ 1641 /* static char *ggp_tooltip_text(GaimBuddy *b) {{{ */
1281 static char *ggp_tooltip_text(GaimBuddy *b) 1642 static char *ggp_tooltip_text(GaimBuddy *b)
1282 { 1643 {
1283 GaimStatus *status; 1644 GaimStatus *status;
1284 char *text; 1645 char *text;
1305 1666
1306 return ret; 1667 return ret;
1307 } 1668 }
1308 /* }}} */ 1669 /* }}} */
1309 1670
1310 /*
1311 */
1312 /* static GList *ggp_status_types(GaimAccount *account) {{{ */ 1671 /* static GList *ggp_status_types(GaimAccount *account) {{{ */
1313 static GList *ggp_status_types(GaimAccount *account) 1672 static GList *ggp_status_types(GaimAccount *account)
1314 { 1673 {
1315 GaimStatusType *type; 1674 GaimStatusType *type;
1316 GList *types = NULL; 1675 GList *types = NULL;
1356 1715
1357 return types; 1716 return types;
1358 } 1717 }
1359 /* }}} */ 1718 /* }}} */
1360 1719
1361 /*
1362 */
1363 /* static GList *ggp_blist_node_menu(GaimBlistNode *node) {{{ */ 1720 /* static GList *ggp_blist_node_menu(GaimBlistNode *node) {{{ */
1364 static GList *ggp_blist_node_menu(GaimBlistNode *node) 1721 static GList *ggp_blist_node_menu(GaimBlistNode *node)
1365 { 1722 {
1723 GaimBlistNodeAction *act;
1366 GList *m = NULL; 1724 GList *m = NULL;
1367 1725
1368 if (!GAIM_BLIST_NODE_IS_BUDDY(node)) 1726 if (!GAIM_BLIST_NODE_IS_BUDDY(node))
1369 return NULL; 1727 return NULL;
1370 1728
1371 /* act = gaim_blist_node_action_new("Change Password", ggp_bmenu_change_passwd, NULL, NULL); */ 1729 act = gaim_blist_node_action_new("Add to chat", ggp_bmenu_add_to_chat, NULL, NULL);
1372 /* m = g_list_append(m, act); */ 1730 m = g_list_append(m, act);
1373 1731
1374 return m; 1732 return m;
1375 } 1733 }
1376 /* }}} */ 1734 /* }}} */
1377 1735
1378 /* 1736 /* static GList *ggp_chat_info(GaimConnection *gc) {{{ */
1379 */ 1737 static GList *ggp_chat_info(GaimConnection *gc)
1738 {
1739 GList *m = NULL;
1740 struct proto_chat_entry *pce;
1741
1742 pce = g_new0(struct proto_chat_entry, 1);
1743 pce->label = _("Chat _name:");
1744 pce->identifier = "name";
1745 pce->required = TRUE;
1746 m = g_list_append(m, pce);
1747
1748 return m;
1749 }
1750 /* }}} */
1751
1380 /* static void ggp_login(GaimAccount *account, GaimStatus *status) {{{ */ 1752 /* static void ggp_login(GaimAccount *account, GaimStatus *status) {{{ */
1381 static void ggp_login(GaimAccount *account, GaimStatus *status) 1753 static void ggp_login(GaimAccount *account, GaimStatus *status)
1382 { 1754 {
1383 GaimConnection *gc = gaim_account_get_connection(account); 1755 GaimConnection *gc = gaim_account_get_connection(account);
1384 struct gg_login_params *glp = g_new0(struct gg_login_params, 1); 1756 struct gg_login_params *glp = g_new0(struct gg_login_params, 1);
1385 GGPInfo *info = g_new0(GGPInfo, 1); 1757 GGPInfo *info = g_new0(GGPInfo, 1);
1386 1758
1759 /* Probably this should be move to some *_new() function. */
1387 info->session = NULL; 1760 info->session = NULL;
1388 info->searchresults_window = NULL; 1761 info->searchresults_window = NULL;
1762 info->chats = NULL;
1763 info->chats_count = 0;
1389 1764
1390 gc->proto_data = info; 1765 gc->proto_data = info;
1391 1766
1392 glp->uin = ggp_get_uin(account); 1767 glp->uin = ggp_get_uin(account);
1393 glp->password = (char *)gaim_account_get_password(account); 1768 glp->password = (char *)gaim_account_get_password(account);
1410 gaim_connection_set_state(gc, GAIM_CONNECTED); 1785 gaim_connection_set_state(gc, GAIM_CONNECTED);
1411 ggp_buddylist_send(gc); 1786 ggp_buddylist_send(gc);
1412 } 1787 }
1413 /* }}} */ 1788 /* }}} */
1414 1789
1415 /*
1416 */
1417 /* static void ggp_close(GaimConnection *gc) {{{ */ 1790 /* static void ggp_close(GaimConnection *gc) {{{ */
1418 static void ggp_close(GaimConnection *gc) 1791 static void ggp_close(GaimConnection *gc)
1419 { 1792 {
1420 GGPInfo *info; 1793 GGPInfo *info;
1421 1794
1439 1812
1440 gaim_debug_info("gg", "Connection closed.\n"); 1813 gaim_debug_info("gg", "Connection closed.\n");
1441 } 1814 }
1442 /* }}} */ 1815 /* }}} */
1443 1816
1444 /*
1445 */
1446 /* static int ggp_send_im(GaimConnection *gc, const char *who, const char *msg, GaimConvImFlags flags) {{{ */ 1817 /* static int ggp_send_im(GaimConnection *gc, const char *who, const char *msg, GaimConvImFlags flags) {{{ */
1447 static int ggp_send_im(GaimConnection *gc, const char *who, const char *msg, GaimConvImFlags flags) 1818 static int ggp_send_im(GaimConnection *gc, const char *who, const char *msg, GaimConvImFlags flags)
1448 { 1819 {
1449 GGPInfo *info = gc->proto_data; 1820 GGPInfo *info = gc->proto_data;
1450 const char *tmp; 1821 char *tmp;
1451 1822
1452 if (strlen(msg) == 0) 1823 if (strlen(msg) == 0)
1453 return 1; 1824 return 1;
1454 1825
1455 tmp = charset_convert(msg, "UTF-8", "CP1250"); 1826 tmp = charset_convert(msg, "UTF-8", "CP1250");
1456 1827
1457 if (tmp != NULL && strlen(tmp) > 0) { 1828 if (tmp != NULL && strlen(tmp) > 0) {
1458 if (gg_send_message(info->session, GG_CLASS_CHAT, ggp_str_to_uin(who), tmp) < 0) { 1829 if (gg_send_message(info->session, GG_CLASS_MSG, ggp_str_to_uin(who), (unsigned char *)tmp) < 0) {
1459 return -1; 1830 return -1;
1460 } 1831 }
1461 } 1832 }
1462 1833
1463 return 1; 1834 return 1;
1464 } 1835 }
1465 /* }}} */ 1836 /* }}} */
1466 1837
1467 /*
1468 */
1469 /* static void ggp_get_info(GaimConnection *gc, const char *name) { {{{ */ 1838 /* static void ggp_get_info(GaimConnection *gc, const char *name) { {{{ */
1470 static void ggp_get_info(GaimConnection *gc, const char *name) 1839 static void ggp_get_info(GaimConnection *gc, const char *name)
1471 { 1840 {
1472 GGPInfo *info = gc->proto_data; 1841 GGPInfo *info = gc->proto_data;
1473 GGPSearchForm *form; 1842 GGPSearchForm *form;
1481 1850
1482 ggp_pubdir_start_search(gc, form); 1851 ggp_pubdir_start_search(gc, form);
1483 } 1852 }
1484 /* }}} */ 1853 /* }}} */
1485 1854
1486 /*
1487 */
1488 /* static void ggp_set_status(GaimAccount *account, GaimStatus *status) {{{ */ 1855 /* static void ggp_set_status(GaimAccount *account, GaimStatus *status) {{{ */
1489 static void ggp_set_status(GaimAccount *account, GaimStatus *status) 1856 static void ggp_set_status(GaimAccount *account, GaimStatus *status)
1490 { 1857 {
1491 GaimStatusPrimitive prim; 1858 GaimStatusPrimitive prim;
1492 GaimConnection *gc; 1859 GaimConnection *gc;
1545 } 1912 }
1546 1913
1547 } 1914 }
1548 /* }}} */ 1915 /* }}} */
1549 1916
1550 /*
1551 */
1552 /* static void ggp_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) {{{ */ 1917 /* static void ggp_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) {{{ */
1553 static void ggp_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) 1918 static void ggp_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group)
1554 { 1919 {
1555 GGPInfo *info = gc->proto_data; 1920 GGPInfo *info = gc->proto_data;
1556 1921
1557 gg_add_notify(info->session, ggp_str_to_uin(buddy->name)); 1922 gg_add_notify(info->session, ggp_str_to_uin(buddy->name));
1558 } 1923 }
1559 /* }}} */ 1924 /* }}} */
1560 1925
1561 /*
1562 */
1563 /* static void ggp_remove_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) {{{ */ 1926 /* static void ggp_remove_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) {{{ */
1564 static void ggp_remove_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) 1927 static void ggp_remove_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group)
1565 { 1928 {
1566 GGPInfo *info = gc->proto_data; 1929 GGPInfo *info = gc->proto_data;
1567 1930
1568 gg_remove_notify(info->session, ggp_str_to_uin(buddy->name)); 1931 gg_remove_notify(info->session, ggp_str_to_uin(buddy->name));
1569 } 1932 }
1570 /* }}} */ 1933 /* }}} */
1571 1934
1572 /* 1935 /* static void ggp_join_chat(GaimConnection *gc, GHashTable *data) {{{ */
1573 */ 1936 static void ggp_join_chat(GaimConnection *gc, GHashTable *data)
1937 {
1938 GGPInfo *info = gc->proto_data;
1939 GGPChat *chat;
1940 char *chat_name;
1941 GList *l;
1942
1943 chat_name = g_hash_table_lookup(data, "name");
1944
1945 if (chat_name == NULL)
1946 return;
1947
1948 gaim_debug_info("gg", "joined %s chat\n", chat_name);
1949
1950 for (l = info->chats; l != NULL; l = l->next) {
1951 chat = l->data;
1952
1953 if (chat != NULL && g_utf8_collate(chat->name, chat_name) == 0) {
1954 gaim_notify_error(gc, _("Chat error"),
1955 _("This chat name is already in use"), NULL);
1956 return;
1957 }
1958 }
1959
1960 ggp_chat_add_new(gc, chat_name);
1961 serv_got_joined_chat(gc, info->chats_count, chat_name);
1962 }
1963 /* }}} */
1964
1965 /* static char *ggp_get_chat_name(GHashTable *data) { {{{ */
1966 static char *ggp_get_chat_name(GHashTable *data) {
1967 return g_strdup(g_hash_table_lookup(data, "name"));
1968 }
1969 /* }}} */
1970
1971 /* static int ggp_chat_send(GaimConnection *gc, int id, const char *message) {{{ */
1972 static int ggp_chat_send(GaimConnection *gc, int id, const char *message)
1973 {
1974 GaimConversation *conv;
1975 GGPInfo *info = gc->proto_data;
1976 GGPChat *chat = NULL;
1977 GList *l;
1978 char *msg;
1979 uin_t *uins;
1980 int count = 0;
1981
1982 if ((conv = gaim_find_chat(gc, id)) == NULL)
1983 return -EINVAL;
1984
1985 for (l = info->chats; l != NULL; l = l->next) {
1986 chat = l->data;
1987
1988 if (g_utf8_collate(chat->name, conv->name) == 0) {
1989 gaim_debug_info("gg", "found conv!\n");
1990 break;
1991 }
1992
1993 chat = NULL;
1994 }
1995
1996 if (chat == NULL) {
1997 gaim_debug_error("gg", "ggp_chat_send: Hm... that's strange. No such chat?\n");
1998 return -EINVAL;
1999 }
2000
2001 uins = g_new0(uin_t, g_list_length(chat->participants));
2002 for (l = chat->participants; l != NULL; l = l->next) {
2003 gchar *name = l->data;
2004 uin_t uin;
2005
2006 if ((uin = ggp_str_to_uin(name)) != 0)
2007 uins[count++] = uin;
2008 }
2009
2010 msg = charset_convert(message, "UTF-8", "CP1250");
2011 gg_send_message_confer(info->session, GG_CLASS_CHAT, count, uins, (unsigned char *)msg);
2012 g_free(msg);
2013 g_free(uins);
2014
2015 serv_got_chat_in(gc, id, gaim_account_get_username(gaim_connection_get_account(gc)),
2016 0, message, time(NULL));
2017
2018 return 0;
2019 }
2020 /* }}} */
2021
1574 /* static void ggp_keepalive(GaimConnection *gc) {{{ */ 2022 /* static void ggp_keepalive(GaimConnection *gc) {{{ */
1575 static void ggp_keepalive(GaimConnection *gc) 2023 static void ggp_keepalive(GaimConnection *gc)
1576 { 2024 {
1577 GGPInfo *info = gc->proto_data; 2025 GGPInfo *info = gc->proto_data;
1578 2026
1584 gaim_connection_error(gc, _("Not connected to the server.")); 2032 gaim_connection_error(gc, _("Not connected to the server."));
1585 } 2033 }
1586 } 2034 }
1587 /* }}} */ 2035 /* }}} */
1588 2036
1589 /*
1590 */
1591 /* static void ggp_register_user(GaimAccount *account) {{{ */ 2037 /* static void ggp_register_user(GaimAccount *account) {{{ */
1592 static void ggp_register_user(GaimAccount *account) 2038 static void ggp_register_user(GaimAccount *account)
1593 { 2039 {
1594 GaimConnection *gc; 2040 GaimConnection *gc;
1595 GaimRequestFields *fields; 2041 GaimRequestFields *fields;
1653 fields, _("OK"), G_CALLBACK(ggp_callback_register_account_ok), 2099 fields, _("OK"), G_CALLBACK(ggp_callback_register_account_ok),
1654 _("Cancel"), NULL, gc); 2100 _("Cancel"), NULL, gc);
1655 } 2101 }
1656 /* }}} */ 2102 /* }}} */
1657 2103
1658 /*
1659 */
1660 /* static GList *ggp_actions(GaimPlugin *plugin, gpointer context) {{{ */ 2104 /* static GList *ggp_actions(GaimPlugin *plugin, gpointer context) {{{ */
1661 static GList *ggp_actions(GaimPlugin *plugin, gpointer context) 2105 static GList *ggp_actions(GaimPlugin *plugin, gpointer context)
1662 { 2106 {
1663 GList *m = NULL; 2107 GList *m = NULL;
1664 GaimPluginAction *act; 2108 GaimPluginAction *act;
1703 ggp_list_emblems, /* list_emblems */ 2147 ggp_list_emblems, /* list_emblems */
1704 ggp_status_text, /* status_text */ 2148 ggp_status_text, /* status_text */
1705 ggp_tooltip_text, /* tooltip_text */ 2149 ggp_tooltip_text, /* tooltip_text */
1706 ggp_status_types, /* status_types */ 2150 ggp_status_types, /* status_types */
1707 ggp_blist_node_menu, /* blist_node_menu */ 2151 ggp_blist_node_menu, /* blist_node_menu */
1708 NULL, /* chat_info */ 2152 ggp_chat_info, /* chat_info */
1709 NULL, /* chat_info_defaults */ 2153 NULL, /* chat_info_defaults */
1710 ggp_login, /* login */ 2154 ggp_login, /* login */
1711 ggp_close, /* close */ 2155 ggp_close, /* close */
1712 ggp_send_im, /* send_im */ 2156 ggp_send_im, /* send_im */
1713 NULL, /* set_info */ 2157 NULL, /* set_info */
1723 NULL, /* add_permit */ 2167 NULL, /* add_permit */
1724 NULL, /* add_deny */ 2168 NULL, /* add_deny */
1725 NULL, /* rem_permit */ 2169 NULL, /* rem_permit */
1726 NULL, /* rem_deny */ 2170 NULL, /* rem_deny */
1727 NULL, /* set_permit_deny */ 2171 NULL, /* set_permit_deny */
1728 NULL, /* join_chat */ 2172 ggp_join_chat, /* join_chat */
1729 NULL, /* reject_chat */ 2173 NULL, /* reject_chat */
1730 NULL, /* get_chat_name */ 2174 ggp_get_chat_name, /* get_chat_name */
1731 NULL, /* chat_invite */ 2175 NULL, /* chat_invite */
1732 NULL, /* chat_leave */ 2176 NULL, /* chat_leave */
1733 NULL, /* chat_whisper */ 2177 NULL, /* chat_whisper */
1734 NULL, /* chat_send */ 2178 ggp_chat_send, /* chat_send */
1735 ggp_keepalive, /* keepalive */ 2179 ggp_keepalive, /* keepalive */
1736 ggp_register_user, /* register_user */ 2180 ggp_register_user, /* register_user */
1737 NULL, /* get_cb_info */ 2181 NULL, /* get_cb_info */
1738 NULL, /* get_cb_away */ 2182 NULL, /* get_cb_away */
1739 NULL, /* alias_buddy */ 2183 NULL, /* alias_buddy */
1801 /* }}} */ 2245 /* }}} */
1802 2246
1803 GAIM_INIT_PLUGIN(gadu-gadu, init_plugin, info); 2247 GAIM_INIT_PLUGIN(gadu-gadu, init_plugin, info);
1804 2248
1805 /* vim: set ts=4 sts=0 sw=4 noet: */ 2249 /* vim: set ts=4 sts=0 sw=4 noet: */
2250