comparison src/buddy.c @ 1106:5bc8fdacd2cb

[gaim-migrate @ 1116] lots of changes. buddy.c: just in general tried to get things to work better. moving things in the edit list window and signing off should be handled better in the main buddy list window (watch out for flashes). gaim.h: removed toc-specific things and moved them to toc.c and rvous.c as needed. gtkhtml.c: possible fix for AOL 6.0 problems (I wasn't able to reproduce the problem before or after the fix, but i fixed what i think might have been causing the problem). multi.c: moved LOGIN_STEPS from gaim.h here and actually use it now oscar.c: moved an oscar-specific struct definition from gaim.h here and also handle problems better perl.c: fix for stupid problem rvous.c: first pass at attempt to be able to remove toc.c and rvous.c (though this will never happen; gaim will support toc as long as aol does) without cruft. gaim is now only dependent on toc.c and rvous.c for toc_build_config and parse_toc_buddy_list, which gaim needs to save and read its buddy list. toc.c: rewrote the signin process so that the read()'s won't block. it's not actually a non-blocking read; it's just that it won't ever get to the read until there's data to be read (thanks to the gdk_input watcher). this means the cancel button should work after it's connected, but it's still not a non-blocking connect. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Mon, 20 Nov 2000 07:24:18 +0000
parents 7aabbbaae829
children cb338aa38e78
comparison
equal deleted inserted replaced
1105:c964df5b2a84 1106:5bc8fdacd2cb
101 static struct group_show *find_group_show(char *group); 101 static struct group_show *find_group_show(char *group);
102 static struct buddy_show *find_buddy_show(struct group_show *gs, char *name); 102 static struct buddy_show *find_buddy_show(struct group_show *gs, char *name);
103 static int group_number(char *group); 103 static int group_number(char *group);
104 static int buddy_number(char *group, char *buddy); 104 static int buddy_number(char *group, char *buddy);
105 static struct group_show *new_group_show(char *group); 105 static struct group_show *new_group_show(char *group);
106 static struct buddy_show *new_buddy_show(struct group_show *gs, struct buddy *buddy); 106 static struct buddy_show *new_buddy_show(struct group_show *gs, struct buddy *buddy, char **xpm);
107 static struct group_show *find_gs_by_bs(struct buddy_show *b); 107 static struct group_show *find_gs_by_bs(struct buddy_show *b);
108 static void redo_buddy_list();
108 109
109 void destroy_buddy() 110 void destroy_buddy()
110 { 111 {
111 if (blist) 112 if (blist)
112 gtk_widget_destroy(blist); 113 gtk_widget_destroy(blist);
188 struct group *g; 189 struct group *g;
189 struct buddy_show *b; 190 struct buddy_show *b;
190 int total = 0, on = 0; 191 int total = 0, on = 0;
191 char buf[256]; 192 char buf[256];
192 193
193 if (!g_slist_find(shows, gs)) return; 194 if (!g_slist_find(shows, gs)) {
195 debug_printf("update_num_group called for unfound group_show %s\n", gs->name);
196 return;
197 }
194 198
195 while (c) { 199 while (c) {
196 gc = (struct gaim_connection *)c->data; 200 gc = (struct gaim_connection *)c->data;
197 g = find_group(gc, gs->name); 201 g = find_group(gc, gs->name);
198 if (g) { 202 if (g) {
257 } 261 }
258 262
259 #endif 263 #endif
260 264
261 265
262 static void destroy_buddies(struct gaim_connection *gc) {
263 GSList *s = shows;
264 struct group_show *g;
265 GSList *m;
266 struct buddy_show *b;
267 gboolean remove_group;
268
269 while (s) {
270 remove_group = FALSE;
271 g = (struct group_show *)s->data;
272 m = g->members;
273 while (m) {
274 b = (struct buddy_show *)m->data;
275 if ((g_slist_length(b->connlist) == 1) && (b->connlist->data == gc)) {
276 if (b->log_timer > 0)
277 gtk_timeout_remove(b->log_timer);
278 b->log_timer = 0;
279 b->connlist = g_slist_remove(b->connlist, gc);
280 gtk_container_remove(GTK_CONTAINER(g->tree), b->item);
281 m = g->members = g_slist_remove(g->members, b);
282 if ((g->members == NULL) && (display_options & OPT_DISP_NO_MT_GRP)) {
283 shows = g_slist_remove(shows, g);
284 gtk_container_remove(GTK_CONTAINER(buddies), g->item);
285 g_free(g->name);
286 g_free(g);
287 m = NULL;
288 remove_group = TRUE;
289 } else
290 update_num_group(g);
291 g_free(b->name);
292 g_free(b->show);
293 g_free(b);
294 } else if (g_slist_find(b->connlist, gc)) {
295 if (g_slist_find(b->connlist, gc)) {
296 b->connlist = g_slist_remove(b->connlist, gc);
297 update_num_group(g);
298 }
299 m = g_slist_next(m);
300 } else
301 m = g_slist_next(m);
302 }
303 if (remove_group)
304 s = shows;
305 else
306 s = g_slist_next(s);
307 }
308 }
309
310
311 void signoff_all(GtkWidget *w, gpointer d) 266 void signoff_all(GtkWidget *w, gpointer d)
312 { 267 {
313 GSList *c = connections; 268 GSList *c = connections;
314 struct gaim_connection *g = NULL; 269 struct gaim_connection *g = NULL;
315 270
320 } 275 }
321 } 276 }
322 277
323 void signoff(struct gaim_connection *gc) 278 void signoff(struct gaim_connection *gc)
324 { 279 {
325 destroy_buddies(gc);
326 plugin_event(event_signoff, gc, 0, 0, 0); 280 plugin_event(event_signoff, gc, 0, 0, 0);
327 update_keepalive(gc, FALSE); 281 update_keepalive(gc, FALSE);
328 serv_close(gc); 282 serv_close(gc);
283 redo_buddy_list();
329 284
330 if (connections) return; 285 if (connections) return;
331 286
332 { 287 {
333 GSList *s = shows; 288 GSList *s = shows;
649 static void redo_buddy_list() { 604 static void redo_buddy_list() {
650 /* so here we can safely assume that we don't have to add or delete anything, we 605 /* so here we can safely assume that we don't have to add or delete anything, we
651 * just have to go through and reorder everything. remember, nothing is going to 606 * just have to go through and reorder everything. remember, nothing is going to
652 * change connections, so we can assume that we don't have to change any user 607 * change connections, so we can assume that we don't have to change any user
653 * data or anything. this is just a simple reordering. so calm down. */ 608 * data or anything. this is just a simple reordering. so calm down. */
609 /* note: we only have to do this if we want to strongly enforce order; however,
610 * order doesn't particularly matter to the stability of the program. but, it's
611 * kind of nice to have */
612 /* the easy way to implement this is just to go through shows and destroy all the
613 * group_shows, then go through the connections and put everything back. though,
614 * there are slight complications with that; most of them deal with timeouts and
615 * people not seeing the login icon for the full 10 seconds. butt fuck them. */
654 GSList *s = shows; 616 GSList *s = shows;
655 struct group_show *g; 617 struct group_show *gs;
656 GSList *m; 618 GSList *m;
657 struct buddy_show *b; 619 struct buddy_show *bs;
620 GSList *c = connections;
658 struct gaim_connection *gc; 621 struct gaim_connection *gc;
622 GSList *gr;
623 struct group *g;
624 struct buddy *b;
625
626 while (s) {
627 gs = (struct group_show *)s->data;
628 s = g_slist_remove(s, gs);
629 m = gs->members;
630 gtk_container_remove(GTK_CONTAINER(buddies), gs->item);
631 while (m) {
632 bs = (struct buddy_show *)m->data;
633 m = g_slist_remove(m, bs);
634 if (bs->log_timer > 0)
635 gtk_timeout_remove(bs->log_timer);
636 g_free(bs->show);
637 g_free(bs->name);
638 g_free(bs);
639 }
640 g_free(gs->name);
641 g_free(gs);
642 }
643 shows = NULL;
644 while (c) {
645 gc = (struct gaim_connection *)c->data;
646 c = c->next;
647 gr = gc->groups;
648 while (gr) {
649 g = (struct group *)gr->data;
650 gr = gr->next;
651 gs = find_group_show(g->name);
652 if (!gs && !(display_options & OPT_DISP_NO_MT_GRP))
653 gs = new_group_show(g->name);
654 m = g->members;
655 while (m) {
656 b = (struct buddy *)m->data;
657 m = m->next;
658 if (b->present) {
659 if (!gs)
660 gs = new_group_show(g->name);
661 bs = find_buddy_show(gs, b->name);
662 if (!bs) {
663 if (gc->prpl->list_icon)
664 bs = new_buddy_show(gs, b,
665 (*gc->prpl->list_icon)(b->uc));
666 else
667 bs = new_buddy_show(gs, b, (char **)no_icon_xpm);
668 }
669 bs->connlist = g_slist_append(bs->connlist, gc);
670 }
671 }
672 }
673 }
659 } 674 }
660 675
661 static void edit_tree_move (GtkCTree *ctree, GtkCTreeNode *child, GtkCTreeNode *parent, 676 static void edit_tree_move (GtkCTree *ctree, GtkCTreeNode *child, GtkCTreeNode *parent,
662 GtkCTreeNode *sibling, gpointer data) 677 GtkCTreeNode *sibling, gpointer data)
663 { 678 {
1391 1406
1392 1407
1393 static struct group_show *find_group_show(char *group) { 1408 static struct group_show *find_group_show(char *group) {
1394 GSList *m = shows; 1409 GSList *m = shows;
1395 struct group_show *g = NULL; 1410 struct group_show *g = NULL;
1411 char *who = g_strdup(normalize(group));
1396 1412
1397 while (m) { 1413 while (m) {
1398 g = (struct group_show *)m->data; 1414 g = (struct group_show *)m->data;
1399 if (!strcmp(g->name, group)) 1415 if (!strcasecmp(normalize(g->name), who))
1400 break; 1416 break;
1401 g = NULL; 1417 g = NULL;
1402 m = m->next; 1418 m = m->next;
1403 } 1419 }
1420 g_free(who);
1404 1421
1405 return g; 1422 return g;
1406 } 1423 }
1407 1424
1408 static struct buddy_show *find_buddy_show(struct group_show *gs, char *name) { 1425 static struct buddy_show *find_buddy_show(struct group_show *gs, char *name) {
1410 struct buddy_show *b = NULL; 1427 struct buddy_show *b = NULL;
1411 char *who = g_strdup(normalize(name)); 1428 char *who = g_strdup(normalize(name));
1412 1429
1413 while (m) { 1430 while (m) {
1414 b = (struct buddy_show *)m->data; 1431 b = (struct buddy_show *)m->data;
1415 if (!strcmp(normalize(b->name), who)) 1432 if (!strcasecmp(normalize(b->name), who))
1416 break; 1433 break;
1417 b = NULL; 1434 b = NULL;
1418 m = m->next; 1435 m = m->next;
1419 } 1436 }
1420 g_free(who); 1437 g_free(who);
1507 shows = g_slist_insert(shows, g, pos); 1524 shows = g_slist_insert(shows, g, pos);
1508 update_num_groups(g); 1525 update_num_groups(g);
1509 return g; 1526 return g;
1510 } 1527 }
1511 1528
1512 static struct buddy_show *new_buddy_show(struct group_show *gs, struct buddy *buddy) { 1529 static struct buddy_show *new_buddy_show(struct group_show *gs, struct buddy *buddy, char **xpm) {
1513 struct buddy_show *b = g_new0(struct buddy_show, 1); 1530 struct buddy_show *b = g_new0(struct buddy_show, 1);
1514 GtkWidget *box; 1531 GtkWidget *box;
1515 GdkPixmap *pm; 1532 GdkPixmap *pm;
1516 GdkBitmap *bm; 1533 GdkBitmap *bm;
1517 int pos = buddy_number(gs->name, buddy->name); 1534 int pos = buddy_number(gs->name, buddy->name);
1528 1545
1529 box = gtk_hbox_new(FALSE, 1); 1546 box = gtk_hbox_new(FALSE, 1);
1530 gtk_container_add(GTK_CONTAINER(b->item), box); 1547 gtk_container_add(GTK_CONTAINER(b->item), box);
1531 gtk_widget_show(box); 1548 gtk_widget_show(box);
1532 1549
1533 pm = gdk_pixmap_create_from_xpm_d(blist->window, &bm, NULL, (char **)login_icon_xpm); 1550 pm = gdk_pixmap_create_from_xpm_d(blist->window, &bm, NULL, xpm);
1534 b->pix = gtk_pixmap_new(pm, bm); 1551 b->pix = gtk_pixmap_new(pm, bm);
1535 gtk_box_pack_start(GTK_BOX(box), b->pix, FALSE, FALSE, 1); 1552 gtk_box_pack_start(GTK_BOX(box), b->pix, FALSE, FALSE, 1);
1536 gtk_widget_show(b->pix); 1553 gtk_widget_show(b->pix);
1537 gdk_pixmap_unref(pm); 1554 gdk_pixmap_unref(pm);
1538 gdk_bitmap_unref(bm); 1555 gdk_bitmap_unref(bm);
1586 if (blist) 1603 if (blist)
1587 gtk_container_remove(GTK_CONTAINER(buddies), g->item); 1604 gtk_container_remove(GTK_CONTAINER(buddies), g->item);
1588 g_free(g->name); 1605 g_free(g->name);
1589 g_free(g); 1606 g_free(g);
1590 } 1607 }
1608 gtk_timeout_remove(b->log_timer);
1609 b->log_timer = 0;
1591 g_free(b->name); 1610 g_free(b->name);
1592 g_free(b->show); 1611 g_free(b->show);
1593 g_free(b); 1612 g_free(b);
1594 } else { 1613 } else {
1595 /* um.... what do we have to do here? just update the pixmap? */ 1614 /* um.... what do we have to do here? just update the pixmap? */
1607 gtk_widget_show(b->pix); 1626 gtk_widget_show(b->pix);
1608 if (ticker_prefs & OPT_DISP_SHOW_BUDDYTICKER) 1627 if (ticker_prefs & OPT_DISP_SHOW_BUDDYTICKER)
1609 BuddyTickerSetPixmap(b->name, pm, bm); 1628 BuddyTickerSetPixmap(b->name, pm, bm);
1610 gdk_pixmap_unref(pm); 1629 gdk_pixmap_unref(pm);
1611 gdk_bitmap_unref(bm); 1630 gdk_bitmap_unref(bm);
1612 } 1631 gtk_timeout_remove(b->log_timer);
1613 gtk_timeout_remove(b->log_timer); 1632 b->log_timer = 0;
1614 b->log_timer = 0; 1633 }
1615 return 0; 1634 return 0;
1616 } 1635 }
1617 1636
1618 static char *caps_string(gushort caps) 1637 static char *caps_string(gushort caps)
1619 { 1638 {
1751 1770
1752 if (b->present) { 1771 if (b->present) {
1753 if ((gs = find_group_show(g->name)) == NULL) 1772 if ((gs = find_group_show(g->name)) == NULL)
1754 gs = new_group_show(g->name); 1773 gs = new_group_show(g->name);
1755 if ((bs = find_buddy_show(gs, b->name)) == NULL) 1774 if ((bs = find_buddy_show(gs, b->name)) == NULL)
1756 bs = new_buddy_show(gs, b); 1775 bs = new_buddy_show(gs, b, (char **)login_icon_xpm);
1757 if (b->present == 1) { 1776 if (b->present == 1) {
1758 play_sound(BUDDY_ARRIVE); 1777 play_sound(BUDDY_ARRIVE);
1759 pm = gdk_pixmap_create_from_xpm_d(blist->window, &bm, 1778 pm = gdk_pixmap_create_from_xpm_d(blist->window, &bm,
1760 NULL, (char **)login_icon_xpm); 1779 NULL, (char **)login_icon_xpm);
1761 gtk_widget_hide(bs->pix); 1780 gtk_widget_hide(bs->pix);
1766 gtk_timeout_add(10000, (GtkFunction)BuddyTickerLogonTimeout, b->name); 1785 gtk_timeout_add(10000, (GtkFunction)BuddyTickerLogonTimeout, b->name);
1767 } 1786 }
1768 gdk_pixmap_unref(pm); 1787 gdk_pixmap_unref(pm);
1769 gdk_bitmap_unref(bm); 1788 gdk_bitmap_unref(bm);
1770 b->present = 2; 1789 b->present = 2;
1771 if (bs->log_timer > 0)
1772 gtk_timeout_remove(bs->log_timer);
1773 bs->log_timer = 0;
1774 if (!g_slist_find(bs->connlist, gc)) 1790 if (!g_slist_find(bs->connlist, gc))
1775 bs->connlist = g_slist_append(bs->connlist, gc); 1791 bs->connlist = g_slist_append(bs->connlist, gc);
1776 else 1792 else
1777 debug_printf("already got signon for %s from %s\n", b->name, gc->username); 1793 debug_printf("already got signon for %s from %s\n", b->name, gc->username);
1794 if (bs->log_timer > 0)
1795 gtk_timeout_remove(bs->log_timer);
1796 bs->log_timer = gtk_timeout_add(10000, (GtkFunction)log_timeout, bs);
1778 update_num_group(gs); 1797 update_num_group(gs);
1779 bs->log_timer = gtk_timeout_add(10000, (GtkFunction)log_timeout, bs);
1780 if (display_options & OPT_DISP_SHOW_LOGON) { 1798 if (display_options & OPT_DISP_SHOW_LOGON) {
1781 struct conversation *c = find_conversation(b->name); 1799 struct conversation *c = find_conversation(b->name);
1782 if (c) { 1800 if (c) {
1783 char tmp[1024]; 1801 char tmp[1024];
1784 g_snprintf(tmp, sizeof(tmp), _("<HR><B>%s logged in%s%s.</B><BR><HR>"), b->name, 1802 g_snprintf(tmp, sizeof(tmp), _("<HR><B>%s logged in%s%s.</B><BR><HR>"), b->name,
1809 if (!bs) return; 1827 if (!bs) return;
1810 if (!bs->connlist) return; /* we won't do signoff updates for 1828 if (!bs->connlist) return; /* we won't do signoff updates for
1811 buddies that have already signed 1829 buddies that have already signed
1812 off */ 1830 off */
1813 play_sound(BUDDY_LEAVE); 1831 play_sound(BUDDY_LEAVE);
1832
1814 bs->connlist = g_slist_remove(bs->connlist, gc); 1833 bs->connlist = g_slist_remove(bs->connlist, gc);
1815 update_num_group(gs);
1816 if (bs->log_timer > 0) 1834 if (bs->log_timer > 0)
1817 gtk_timeout_remove(bs->log_timer); 1835 gtk_timeout_remove(bs->log_timer);
1818 bs->log_timer = gtk_timeout_add(10000, (GtkFunction)log_timeout, bs); 1836 bs->log_timer = gtk_timeout_add(10000, (GtkFunction)log_timeout, bs);
1837 update_num_group(gs);
1819 pm = gdk_pixmap_create_from_xpm_d(blist->window, &bm, NULL, logout_icon_xpm); 1838 pm = gdk_pixmap_create_from_xpm_d(blist->window, &bm, NULL, logout_icon_xpm);
1820 gtk_widget_hide(bs->pix); 1839 gtk_widget_hide(bs->pix);
1821 gtk_pixmap_set(GTK_PIXMAP(bs->pix), pm, bm); 1840 gtk_pixmap_set(GTK_PIXMAP(bs->pix), pm, bm);
1822 gtk_widget_show(bs->pix); 1841 gtk_widget_show(bs->pix);
1823 if (ticker_prefs & OPT_DISP_SHOW_BUDDYTICKER) { 1842 if (ticker_prefs & OPT_DISP_SHOW_BUDDYTICKER) {