You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(106) |
Oct
(334) |
Nov
(246) |
Dec
(145) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(42) |
Feb
(53) |
Mar
(232) |
Apr
(109) |
May
(137) |
Jun
(63) |
Jul
(26) |
Aug
(263) |
Sep
(193) |
Oct
(507) |
Nov
(440) |
Dec
(241) |
2003 |
Jan
(567) |
Feb
(195) |
Mar
(504) |
Apr
(481) |
May
(524) |
Jun
(522) |
Jul
(594) |
Aug
(502) |
Sep
(643) |
Oct
(508) |
Nov
(430) |
Dec
(377) |
2004 |
Jan
(361) |
Feb
(251) |
Mar
(219) |
Apr
(499) |
May
(461) |
Jun
(419) |
Jul
(314) |
Aug
(519) |
Sep
(416) |
Oct
(247) |
Nov
(305) |
Dec
(382) |
2005 |
Jan
(267) |
Feb
(282) |
Mar
(327) |
Apr
(338) |
May
(189) |
Jun
(400) |
Jul
(462) |
Aug
(530) |
Sep
(316) |
Oct
(523) |
Nov
(481) |
Dec
(650) |
2006 |
Jan
(536) |
Feb
(361) |
Mar
(287) |
Apr
(146) |
May
(101) |
Jun
(169) |
Jul
(221) |
Aug
(498) |
Sep
(300) |
Oct
(236) |
Nov
(209) |
Dec
(205) |
2007 |
Jan
(30) |
Feb
(23) |
Mar
(26) |
Apr
(15) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <sa...@us...> - 2006-07-04 01:32:49
|
Revision: 16418 Author: sadrul Date: 2006-07-03 18:32:39 -0700 (Mon, 03 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16418&view=rev Log Message: ----------- Make the conversation windows bigger ... which is better *wink*. Use Panel library to manage the windows. Add a window-list that you can use to quickly switch to a window (press Alt+w to bring it up). Get rid of some unused codes. Modified Paths: -------------- trunk/console/gntaccount.c trunk/console/gntblist.c trunk/console/gntblist.h trunk/console/gntconv.c trunk/console/libgnt/Makefile.am trunk/console/libgnt/gntbox.c trunk/console/libgnt/gntmain.c trunk/console/libgnt/gntwidget.c trunk/console/libgnt/test/Makefile trunk/console/libgnt/test/multiwin.c Modified: trunk/console/gntaccount.c =================================================================== --- trunk/console/gntaccount.c 2006-07-03 21:20:16 UTC (rev 16417) +++ trunk/console/gntaccount.c 2006-07-04 01:32:39 UTC (rev 16418) @@ -38,7 +38,7 @@ gnt_widget_set_name(accounts.window, "accounts"); gnt_box_add_widget(GNT_BOX(accounts.window), - gnt_label_new(_("You can enable/disable accounts from the follwing list."))); + gnt_label_new(_("You can enable/disable accounts from the following list."))); accounts.tree = gnt_tree_new(); GNT_WIDGET_SET_FLAGS(accounts.tree, GNT_WIDGET_NO_BORDER); Modified: trunk/console/gntblist.c =================================================================== --- trunk/console/gntblist.c 2006-07-03 21:20:16 UTC (rev 16417) +++ trunk/console/gntblist.c 2006-07-04 01:32:39 UTC (rev 16418) @@ -355,6 +355,7 @@ gnt_box_add_widget(GNT_BOX(box), gnt_label_new(str->str)); gnt_widget_set_position(box, x, y); + GNT_WIDGET_UNSET_FLAGS(box, GNT_WIDGET_CAN_TAKE_FOCUS); gnt_widget_draw(box); g_free(title); @@ -438,6 +439,10 @@ g_signal_connect(G_OBJECT(ggblist->tree), "selection_changed", G_CALLBACK(selection_changed), ggblist); g_signal_connect(G_OBJECT(ggblist->tree), "key_pressed", G_CALLBACK(key_pressed), ggblist); g_signal_connect(G_OBJECT(ggblist->tree), "activate", G_CALLBACK(selection_activate), ggblist); + g_signal_connect_data(G_OBJECT(ggblist->tree), "gained-focus", G_CALLBACK(draw_tooltip), + ggblist, 0, G_CONNECT_AFTER | G_CONNECT_SWAPPED); + g_signal_connect_data(G_OBJECT(ggblist->tree), "lost-focus", G_CALLBACK(remove_tooltip), + ggblist, 0, G_CONNECT_AFTER | G_CONNECT_SWAPPED); } void gg_blist_uninit() @@ -447,4 +452,23 @@ ggblist = NULL; } +void gg_blist_get_position(int *x, int *y) +{ + gnt_widget_get_position(ggblist->window, x, y); +} +void gg_blist_set_position(int x, int y) +{ + gnt_widget_set_position(ggblist->window, x, y); +} + +void gg_blist_get_size(int *width, int *height) +{ + gnt_widget_get_size(ggblist->window, width, height); +} + +void gg_blist_set_size(int width, int height) +{ + gnt_widget_set_size(ggblist->window, width, height); +} + Modified: trunk/console/gntblist.h =================================================================== --- trunk/console/gntblist.h 2006-07-03 21:20:16 UTC (rev 16417) +++ trunk/console/gntblist.h 2006-07-04 01:32:39 UTC (rev 16418) @@ -5,3 +5,12 @@ void gg_blist_init(); void gg_blist_uninit(); + +void gg_blist_get_position(int *x, int *y); + +void gg_blist_set_position(int x, int y); + +void gg_blist_get_size(int *width, int *height); + +void gg_blist_set_size(int width, int height); + Modified: trunk/console/gntconv.c =================================================================== --- trunk/console/gntconv.c 2006-07-03 21:20:16 UTC (rev 16417) +++ trunk/console/gntconv.c 2006-07-04 01:32:39 UTC (rev 16418) @@ -2,6 +2,7 @@ #include <util.h> #include "gntgaim.h" +#include "gntblist.h" #include "gntconv.h" #include "gnt.h" @@ -91,10 +92,14 @@ GGConv *ggc = g_hash_table_lookup(ggconvs, conv); char *title; GaimConversationType type; + int x, width; if (ggc) return; + gg_blist_get_position(&x, NULL); + gg_blist_get_size(&width, NULL); + ggc = g_new0(GGConv, 1); g_hash_table_insert(ggconvs, conv, ggc); @@ -102,25 +107,28 @@ type = gaim_conversation_get_type(conv); title = g_strdup_printf(_("%s"), gaim_conversation_get_name(conv)); - ggc->window = gnt_box_new(FALSE, TRUE); + ggc->window = gnt_box_new(TRUE, TRUE); gnt_box_set_title(GNT_BOX(ggc->window), title); gnt_box_set_toplevel(GNT_BOX(ggc->window), TRUE); + gnt_box_set_pad(GNT_BOX(ggc->window), 0); gnt_widget_set_name(ggc->window, title); ggc->tv = gnt_text_view_new(); gnt_box_add_widget(GNT_BOX(ggc->window), ggc->tv); gnt_widget_set_name(ggc->tv, "conversation-window-textview"); - gnt_widget_set_size(ggc->tv, getmaxx(stdscr) - 40, getmaxy(stdscr) - 15); + gnt_widget_set_size(ggc->tv, getmaxx(stdscr) - 2 - x - width, getmaxy(stdscr) - 4); ggc->entry = gnt_entry_new(NULL); gnt_box_add_widget(GNT_BOX(ggc->window), ggc->entry); gnt_widget_set_name(ggc->entry, "conversation-window-entry"); - gnt_widget_set_size(ggc->entry, getmaxx(stdscr) - 40, 1); g_signal_connect(G_OBJECT(ggc->entry), "key_pressed", G_CALLBACK(entry_key_pressed), ggc); g_signal_connect(G_OBJECT(ggc->window), "destroy", G_CALLBACK(closing_window), ggc); - gnt_widget_set_position(ggc->window, 32, 0); + /* XXX: I am assuming the buddylist is on the leftmost corner. + * That may not always be correct, since the windows can be moved. + * It might be an option to remember the position of conv. windows. */ + gnt_widget_set_position(ggc->window, x + width, 0); gnt_widget_show(ggc->window); g_free(title); Modified: trunk/console/libgnt/Makefile.am =================================================================== --- trunk/console/libgnt/Makefile.am 2006-07-03 21:20:16 UTC (rev 16417) +++ trunk/console/libgnt/Makefile.am 2006-07-04 01:32:39 UTC (rev 16418) @@ -37,7 +37,7 @@ libgnt_la_LIBADD = \ $(GLIB_LIBS) \ $(STATIC_LINK_LIBS) \ - -lncursesw + -lncursesw -lpanelw AM_CPPFLAGS = \ $(GLIB_CFLAGS) Modified: trunk/console/libgnt/gntbox.c =================================================================== --- trunk/console/libgnt/gntbox.c 2006-07-03 21:20:16 UTC (rev 16417) +++ trunk/console/libgnt/gntbox.c 2006-07-04 01:32:39 UTC (rev 16418) @@ -167,55 +167,6 @@ DEBUG; } -#if 0 -static GntWidget * -find_next_focus(GntBox *box) -{ - GntWidget *w = box->active; - GList *iter; - - if (w == NULL) - { - return find_focusable_widget(box); - } - - while (w && !(iter = g_list_find(box->list, w))) - w = w->parent; - - if (!w) - box->active = NULL; - else if (iter) - { - GntWidget *next = NULL; - - while (!next && (iter = iter->next)) - { - if (GNT_IS_BOX(iter->data)) - next = find_next_focus(iter->data); - else - { - if (GNT_WIDGET_IS_FLAG_SET(iter->data, GNT_WIDGET_CAN_TAKE_FOCUS) && - GNT_WIDGET_IS_FLAG_SET(iter->data, GNT_WIDGET_HAS_FOCUS)) - next = iter->data; - else - next = NULL; - } - } - box->active = next; - } - - if (box->active == NULL && GNT_WIDGET(box)->parent == NULL) - { - box->active = find_focusable_widget(box); - } - - if (box->active) - GNT_WIDGET_SET_FLAGS(box->active, GNT_WIDGET_HAS_FOCUS); - - return box->active; -} -#endif - /* Ensures that the current widget can take focus */ static GntWidget * find_focusable_widget(GntBox *box) @@ -227,62 +178,6 @@ box->active = box->focus->data; return box->active; - -#if 0 - for (iter = box->list; iter; iter = iter->next) - { - w = iter->data; - if (GNT_IS_BOX(w)) - { - w = find_focusable_widget(GNT_BOX(w)); - if (w) - break; - } - else if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_CAN_TAKE_FOCUS)) - break; - } - - if (iter) - box->active = w; - else - box->active = NULL; - - if (box->active) - GNT_WIDGET_SET_FLAGS(box->active, GNT_WIDGET_HAS_FOCUS); - - return box->active; - -#if 0 - if (box->active == NULL && box->list) - box->active = box->list->data; - else - w = box->active; - - total = g_list_length(box->list); - - while (box->active && !GNT_WIDGET_IS_FLAG_SET(box->active, GNT_WIDGET_CAN_TAKE_FOCUS)) - { - box->active = box->active->next; - investigated++; - } - - /* Rotate if necessary */ - if (!box->active && investigated < total) - { - box->active = box->list; - while (investigated < total && !GNT_WIDGET_IS_FLAG_SET(box->active->data, GNT_WIDGET_CAN_TAKE_FOCUS)) - { - box->active = box->active->next; - investigated++; - } - } - - if (box->active) - gnt_widget_set_focus(box->active->data, TRUE); - if (w && w != box->active->data) - gnt_widget_set_focus(w, FALSE); -#endif -#endif } static gboolean @@ -335,66 +230,23 @@ return FALSE; } -#if 0 -static GntWidget *find_focused_widget(GntBox *box) -{ - GList *iter; - - for (iter = box->list; iter; iter = iter->next) - { - GntWidget *w = iter->data; - - if (GNT_IS_BOX(w)) - { - if ((w = find_focused_widget(GNT_BOX(w))) != NULL) - return w; - } - else - { - if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_CAN_TAKE_FOCUS) && - GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_HAS_FOCUS)) - return w; - } - } - return NULL; -} -#endif - -#if 0 static void -gnt_box_set_focus(GntWidget *widget, gboolean set) +gnt_box_lost_focus(GntWidget *widget) { - GntWidget *p = widget; - - while (p->parent) - p = p->parent; - - p = find_focused_widget(GNT_BOX(p)); - if (p) - gnt_widget_set_focus(p, set); + GntWidget *w = GNT_BOX(widget)->active; + if (w) + gnt_widget_set_focus(w, FALSE); gnt_widget_draw(widget); } static void -gnt_box_lost_focus(GntWidget *widget) -{ - gnt_box_set_focus(widget, FALSE); -} - -static void gnt_box_gained_focus(GntWidget *widget) { - GntWidget *p; - - while (widget->parent) - widget = widget->parent; - - p = find_focused_widget(GNT_BOX(widget)); - GNT_BOX(widget)->active = g_list_find(GNT_BOX(widget)->list, p); - if (p) - gnt_widget_draw(p); + GntWidget *w = GNT_BOX(widget)->active; + if (w) + gnt_widget_set_focus(w, TRUE); + gnt_widget_draw(widget); } -#endif static void gnt_box_destroy(GntWidget *w) @@ -432,11 +284,8 @@ parent_class->size_request = gnt_box_size_request; parent_class->set_position = gnt_box_set_position; parent_class->key_pressed = gnt_box_key_pressed; -#if 0 - /* We are going to need this when there are multiple focusble widgets in a box */ parent_class->lost_focus = gnt_box_lost_focus; parent_class->gained_focus = gnt_box_gained_focus; -#endif DEBUG; } @@ -513,9 +362,15 @@ { GntWidget *widget = GNT_WIDGET(box); if (set) + { GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); + GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS); + } else + { GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); + GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS); + } } void gnt_box_sync_children(GntBox *box) Modified: trunk/console/libgnt/gntmain.c =================================================================== --- trunk/console/libgnt/gntmain.c 2006-07-03 21:20:16 UTC (rev 16417) +++ trunk/console/libgnt/gntmain.c 2006-07-04 01:32:39 UTC (rev 16418) @@ -1,3 +1,5 @@ +#include <panel.h> + #include "gnt.h" #include "gntbox.h" #include "gntkeys.h" @@ -2,2 +4,3 @@ #include "gntcolors.h" +#include "gnttree.h" @@ -18,12 +21,17 @@ static int Y_MAX; static GMainLoop *loop; +static struct +{ + GntWidget *window; + GntWidget *tree; +} window_list; typedef struct { GntWidget *me; - GList *below; /* List of widgets below me */ - GList *above; /* List of widgets above me */ + + PANEL *panel; } GntNode; typedef enum @@ -32,6 +40,7 @@ GNT_KP_MODE_RESIZE, GNT_KP_MODE_MOVE, GNT_KP_MODE_MENU, + GNT_KP_MODE_WINDOW_LIST } GntKeyPressMode; static GHashTable *nodes; @@ -91,19 +100,23 @@ GntNode *node = g_hash_table_lookup(nodes, widget); GList *iter; + g_return_if_fail(focus_list->data == widget); + if (!node) return; - for (iter = node->above; iter;) + gnt_widget_set_focus(focus_list->data, TRUE); + gnt_widget_draw(focus_list->data); + + top_panel(node->panel); + + if (window_list.window) { - GntNode *n = iter->data; - iter = iter->next; - n->below = g_list_remove(n->below, node); - n->above = g_list_prepend(n->above, node); - - node->above = g_list_remove(node->above, n); - node->below = g_list_prepend(node->below, n); + GntNode *nd = g_hash_table_lookup(nodes, window_list.window); + top_panel(nd->panel); } + update_panels(); + doupdate(); } static void @@ -178,21 +191,75 @@ if (focus_list) { - gnt_widget_set_focus(focus_list->data, TRUE); bring_on_top(focus_list->data); - gnt_widget_draw(focus_list->data); } if (w && (!focus_list || w != focus_list->data)) + { gnt_widget_set_focus(w, FALSE); -} + } +} +static void +window_list_activate(GntTree *tree, gpointer null) +{ + GntWidget *widget = gnt_tree_get_selection_data(GNT_TREE(tree)); + GntWidget *old; + + if (focus_list) + old = focus_list->data; + + focus_list = g_list_find(g_list_first(focus_list), widget); + bring_on_top(widget); + + if (old && (!focus_list || old != focus_list->data)) + { + gnt_widget_set_focus(old, FALSE); + } +} + +static GntWidget * +show_window_list() +{ + GntWidget *tree, *win; + GList *iter; + int id; + + if (window_list.window) + return window_list.window; + + win = window_list.window = gnt_box_new(FALSE, FALSE); + gnt_box_set_toplevel(GNT_BOX(win), TRUE); + gnt_box_set_title(GNT_BOX(win), "Window List"); + gnt_box_set_pad(GNT_BOX(win), 0); + + tree = window_list.tree = gnt_tree_new(); + + for (iter = g_list_first(focus_list); iter; iter = iter->next) + { + GntBox *box = GNT_BOX(iter->data); + + gnt_tree_add_row_after(GNT_TREE(tree), box, box->title, NULL, NULL); + } + + gnt_box_add_widget(GNT_BOX(win), tree); + + gnt_widget_set_size(tree, getmaxx(stdscr) / 3, getmaxy(stdscr) / 2); + gnt_widget_set_position(win, getmaxx(stdscr) / 3, getmaxy(stdscr) / 4); + + lock_focus_list = 1; + gnt_widget_show(win); + lock_focus_list = 0; + + g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(window_list_activate), NULL); +} + static gboolean io_invoke(GIOChannel *source, GIOCondition cond, gpointer null) { char buffer[256]; + gboolean ret = FALSE; static GntKeyPressMode mode = GNT_KP_MODE_NORMAL; - gboolean ret = FALSE; int rd = read(0, buffer, sizeof(buffer) - 1); if (rd < 0) @@ -251,6 +318,11 @@ { mode = GNT_KP_MODE_MOVE; } + else if (strcmp(buffer + 1, "w") == 0 && focus_list) + { + mode = GNT_KP_MODE_WINDOW_LIST; + show_window_list(); + } } } } @@ -317,7 +389,21 @@ mode = GNT_KP_MODE_NORMAL; } } + else if (mode == GNT_KP_MODE_WINDOW_LIST && window_list.window) + { + gnt_widget_key_pressed(window_list.window, buffer); + if (buffer[0] == '\r' || (buffer[0] == 27 && buffer[1] == 0)) + { + mode = GNT_KP_MODE_NORMAL; + lock_focus_list = 1; + gnt_widget_destroy(window_list.window); + window_list.window = NULL; + window_list.tree = NULL; + lock_focus_list = 0; + } + } + draw_taskbar(); refresh(); @@ -373,36 +459,10 @@ free_node(gpointer data) { GntNode *node = data; - g_list_free(node->below); - g_list_free(node->above); + del_panel(node->panel); g_free(node); } -static void -check_intersection(gpointer key, gpointer value, gpointer data) -{ - GntNode *n = value; - GntNode *nu = data; - - if (value == NULL) - return; - if (n->me == nu->me) - return; - - if (n->me->priv.x + n->me->priv.width < nu->me->priv.x) - return; - if (nu->me->priv.x + nu->me->priv.width < n->me->priv.x) - return; - - if (n->me->priv.y + n->me->priv.height < nu->me->priv.y) - return; - if (nu->me->priv.y + nu->me->priv.height < n->me->priv.y) - return; - - n->above = g_list_prepend(n->above, nu); - nu->below = g_list_prepend(nu->below, n); -} - void gnt_screen_occupy(GntWidget *widget) { GntNode *node; @@ -419,56 +479,41 @@ node = g_new0(GntNode, 1); node->me = widget; - g_hash_table_foreach(nodes, check_intersection, node); g_hash_table_replace(nodes, widget, node); + + if (window_list.window) + { + if ((GNT_IS_BOX(widget) && GNT_BOX(widget)->title) && window_list.window != widget + && GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS)) + gnt_tree_add_row_after(GNT_TREE(window_list.tree), widget, + GNT_BOX(widget)->title, NULL, NULL); + } + + update_panels(); + doupdate(); } void gnt_screen_release(GntWidget *widget) { WINDOW *win; GList *iter; - GntNode *node = g_hash_table_lookup(nodes, widget); + GntNode *node; gnt_screen_remove_widget(widget); + node = g_hash_table_lookup(nodes, widget); if (node == NULL) /* Yay! Nothing to do. */ return; - win = dupwin(widget->window); - werase(win); + g_hash_table_remove(nodes, widget); - /* XXX: This is not going to work. - * It will be necessary to build a topology and go from there. */ - for (iter = node->below; iter; iter = iter->next) + if (window_list.window) { - GntNode *n = iter->data; - GntWidget *w = n->me; - int left, right, top, bottom; - - left = MAX(widget->priv.x, w->priv.x) - w->priv.x; - right = MIN(widget->priv.x + widget->priv.width, w->priv.x + w->priv.width) - w->priv.x; - - top = MAX(widget->priv.y, w->priv.y) - w->priv.y; - bottom = MIN(widget->priv.y + widget->priv.height, w->priv.y + w->priv.height) - w->priv.y; - - copywin(w->window, win, top, left, - w->priv.y - widget->priv.y + top, - w->priv.x - widget->priv.x + left, - w->priv.y - widget->priv.y + bottom - 1, - w->priv.x - widget->priv.x + right - 1, FALSE); - n->above = g_list_remove(n->above, node); + gnt_tree_remove(GNT_TREE(window_list.tree), widget); } - for (iter = node->above; iter; iter = iter->next) - { - GntNode *n = iter->data; - n->below = g_list_remove(n->below, node); - } - - wrefresh(win); - delwin(win); - - g_hash_table_remove(nodes, widget); + update_panels(); + doupdate(); } void gnt_screen_update(GntWidget *widget) @@ -485,34 +530,17 @@ gnt_box_sync_children(GNT_BOX(widget)); node = g_hash_table_lookup(nodes, widget); + if (node && !node->panel) + node->panel = new_panel(node->me->window); - win = dupwin(widget->window); - - if (node && node->above) + if (window_list.window) { - /* XXX: Same here: need to build a topology first. */ - for (iter = node->above; iter; iter = iter->next) - { - GntNode *n = iter->data; - GntWidget *w = n->me; - int left, right, top, bottom; - - left = MAX(widget->priv.x, w->priv.x) - w->priv.x; - right = MIN(widget->priv.x + widget->priv.width, w->priv.x + w->priv.width) - w->priv.x; - - top = MAX(widget->priv.y, w->priv.y) - w->priv.y; - bottom = MIN(widget->priv.y + widget->priv.height, w->priv.y + w->priv.height) - w->priv.y; - - copywin(w->window, win, top, left, - w->priv.y - widget->priv.y + top, - w->priv.x - widget->priv.x + left, - w->priv.y - widget->priv.y + bottom - 1, - w->priv.x - widget->priv.x + right - 1, FALSE); - } + GntNode *nd = g_hash_table_lookup(nodes, window_list.window); + top_panel(nd->panel); } - wrefresh(win); - delwin(win); + update_panels(); + doupdate(); } gboolean gnt_widget_has_focus(GntWidget *widget) @@ -521,6 +549,9 @@ if (!widget) return FALSE; + if (widget == window_list.window) + return TRUE; + w = widget; while (widget->parent) Modified: trunk/console/libgnt/gntwidget.c =================================================================== --- trunk/console/libgnt/gntwidget.c 2006-07-03 21:20:16 UTC (rev 16417) +++ trunk/console/libgnt/gntwidget.c 2006-07-04 01:32:39 UTC (rev 16418) @@ -326,8 +326,11 @@ /* XXX: Need to install properties for these and g_object_notify */ wid->priv.x = x; wid->priv.y = y; + + /* XXX: I am supposed to move_panel ... but that seems to crash */ if (wid->window) mvwin(wid->window, y, x); + g_signal_emit(wid, signals[SIG_POSITION], 0, x, y); } Modified: trunk/console/libgnt/test/Makefile =================================================================== --- trunk/console/libgnt/test/Makefile 2006-07-03 21:20:16 UTC (rev 16417) +++ trunk/console/libgnt/test/Makefile 2006-07-04 01:32:39 UTC (rev 16418) @@ -1,11 +1,10 @@ CC=gcc CFLAGS=`pkg-config --cflags gobject-2.0` -g -I../ -LDFLAGS=`pkg-config --libs gobject-2.0` -lncursesw -pg -lgnt -L../ +LDFLAGS=`pkg-config --libs gobject-2.0` -pg -lgnt -L../ EXAMPLES=focus tv multiwin all: - cd .. && make make examples clean: Modified: trunk/console/libgnt/test/multiwin.c =================================================================== --- trunk/console/libgnt/test/multiwin.c 2006-07-03 21:20:16 UTC (rev 16417) +++ trunk/console/libgnt/test/multiwin.c 2006-07-04 01:32:39 UTC (rev 16418) @@ -1,18 +1,20 @@ +#include "gnt.h" #include "gntbutton.h" -#include "gnt.h" +#include "gntentry.h" #include "gntkeys.h" +#include "gntlabel.h" #include "gnttree.h" #include "gntbox.h" gboolean show(GntWidget *w) { - gnt_widget_draw(w); - - return TRUE; + gnt_widget_destroy(w); + return FALSE; } int main() { + freopen(".error", "w", stderr); gnt_init(); GntWidget *hbox, *tree, *box2; @@ -36,11 +38,11 @@ gnt_box_set_toplevel(GNT_BOX(box2), TRUE); gnt_box_set_title(GNT_BOX(box2), "On top"); - gnt_box_add_widget(GNT_BOX(box2), GNT_WIDGET(gnt_label_new("asdasd"))); + gnt_box_add_widget(GNT_BOX(box2), gnt_label_new("asdasd")); gnt_box_add_widget(GNT_BOX(box2), gnt_entry_new(NULL)); gnt_widget_show(hbox); - gnt_widget_set_position(box2, 5, 5); + gnt_widget_set_position(box2, 35, 15); gnt_widget_show(box2); gnt_tree_add_row_after(GNT_TREE(tree), "a", "a", NULL, NULL); @@ -56,8 +58,9 @@ gnt_tree_add_row_after(GNT_TREE(tree), "5", "5", "d", NULL); gnt_tree_add_row_after(GNT_TREE(tree), "6", "6", "4", NULL); - g_timeout_add(1000, (GSourceFunc)show, hbox); + g_timeout_add(5000, show, box2); + gnt_main(); gnt_quit(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-03 21:20:18
|
Revision: 16417 Author: thekingant Date: 2006-07-03 14:20:16 -0700 (Mon, 03 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16417&view=rev Log Message: ----------- Backport SVN revision #16416 from HEAD to v2_0_0 Original commit message: Stu pointed out two of my classic blunders! (Nineteen penguin points to the first person to figure out what movie I'm alluding to.) The MSN http connect method works now. ViewCVS Links: ------------- http://svn.sourceforge.net/gaim/?rev=16416&view=rev Modified Paths: -------------- branches/v2_0_0/src/protocols/msn/httpconn.c Modified: branches/v2_0_0/src/protocols/msn/httpconn.c =================================================================== --- branches/v2_0_0/src/protocols/msn/httpconn.c 2006-07-03 21:19:56 UTC (rev 16416) +++ branches/v2_0_0/src/protocols/msn/httpconn.c 2006-07-03 21:20:16 UTC (rev 16417) @@ -274,7 +274,7 @@ int len, cur_len; char *result_msg = NULL; size_t result_len = 0; - gboolean error; + gboolean error = FALSE; httpconn = data; servconn = NULL; @@ -506,7 +506,7 @@ char *header; char *auth; - data = httpconn; + httpconn = data; g_return_val_if_fail(httpconn != NULL, FALSE); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-03 21:19:58
|
Revision: 16416 Author: thekingant Date: 2006-07-03 14:19:56 -0700 (Mon, 03 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16416&view=rev Log Message: ----------- Stu pointed out two of my classic blunders! (Nineteen penguin points to the first person to figure out what movie I'm alluding to.) The MSN http connect method works now. Modified Paths: -------------- trunk/src/protocols/msn/httpconn.c Modified: trunk/src/protocols/msn/httpconn.c =================================================================== --- trunk/src/protocols/msn/httpconn.c 2006-07-03 20:39:41 UTC (rev 16415) +++ trunk/src/protocols/msn/httpconn.c 2006-07-03 21:19:56 UTC (rev 16416) @@ -274,7 +274,7 @@ int len, cur_len; char *result_msg = NULL; size_t result_len = 0; - gboolean error; + gboolean error = FALSE; httpconn = data; servconn = NULL; @@ -506,7 +506,7 @@ char *header; char *auth; - data = httpconn; + httpconn = data; g_return_val_if_fail(httpconn != NULL, FALSE); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-03 20:39:44
|
Revision: 16415 Author: thekingant Date: 2006-07-03 13:39:41 -0700 (Mon, 03 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16415&view=rev Log Message: ----------- Backport SVN revision #16414 from HEAD to v2_0_0 Original commit message: First stab at trying to fix the MSN http connect method. It still doesn't work, and I'm not sure why, but it gets a lot farther in the signon process now. For those unfamiliar with the issue, the MSN http connect method stopped working after all the non-blocking I/O changes. The http connect method is apparently used by lots of people behind silly firewalls and stuff, and therefore we really shouldn't release Gaim 2.0.0 without it working, because people will complain. The two main problems were 1. The outgoing message queue was removed in favor of buffering all data to one large buffer. This sounds good in theory... but apparently each message sent to and from the server has a "SessionID" in the HTTP header. Every message we send should use the same SessionID as the last packet we received from the server. So basically you can't put two messages into the outgoing buffer at the same time because you don't have the correct SessionID to use for the second message. You have to wait until you get the reply from the server. 2. There were some strange buffer problems with using the wrong variable when trying to combine the header+body into one buffer before sending the message. I also fixed a small memleak or two, added some comments, and tried to clean up the code a little. ViewCVS Links: ------------- http://svn.sourceforge.net/gaim/?rev=16414&view=rev Modified Paths: -------------- branches/v2_0_0/src/connection.c branches/v2_0_0/src/connection.h branches/v2_0_0/src/protocols/msn/httpconn.c branches/v2_0_0/src/protocols/msn/httpconn.h branches/v2_0_0/src/protocols/msn/msn.c Modified: branches/v2_0_0/src/connection.c =================================================================== --- branches/v2_0_0/src/connection.c 2006-07-03 20:39:04 UTC (rev 16414) +++ branches/v2_0_0/src/connection.c 2006-07-03 20:39:41 UTC (rev 16415) @@ -217,12 +217,9 @@ gaim_account_set_connection(account, NULL); - if (gc->password != NULL) - g_free(gc->password); + g_free(gc->password); + g_free(gc->display_name); - if (gc->display_name != NULL) - g_free(gc->display_name); - if (gc->disconnect_timeout) gaim_timeout_remove(gc->disconnect_timeout); Modified: branches/v2_0_0/src/connection.h =================================================================== --- branches/v2_0_0/src/connection.h 2006-07-03 20:39:04 UTC (rev 16414) +++ branches/v2_0_0/src/connection.h 2006-07-03 20:39:41 UTC (rev 16415) @@ -130,12 +130,12 @@ const char *password); /** + * Disconnects and destroys a GaimConnection. + * * This function should only be called by gaim_account_disconnect() - * in account.c. If you're trying to sign on an account, use that + * in account.c. If you're trying to sign off an account, use that * function instead. * - * Disconnects and destroys a GaimConnection. - * * @param gc The gaim connection to destroy. */ void gaim_connection_destroy(GaimConnection *gc); Modified: branches/v2_0_0/src/protocols/msn/httpconn.c =================================================================== --- branches/v2_0_0/src/protocols/msn/httpconn.c 2006-07-03 20:39:04 UTC (rev 16414) +++ branches/v2_0_0/src/protocols/msn/httpconn.c 2006-07-03 20:39:41 UTC (rev 16415) @@ -25,317 +25,242 @@ #include "debug.h" #include "httpconn.h" -static void read_cb(gpointer data, gint source, GaimInputCondition cond); -gboolean msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf, - size_t size, char **ret_buf, size_t *ret_size, - gboolean *error); - -MsnHttpConn * -msn_httpconn_new(MsnServConn *servconn) +typedef struct { MsnHttpConn *httpconn; + char *body; + size_t body_len; +} MsnHttpQueueData; - g_return_val_if_fail(servconn != NULL, NULL); +static void +msn_httpconn_process_queue(MsnHttpConn *httpconn) +{ + httpconn->waiting_response = FALSE; - httpconn = g_new0(MsnHttpConn, 1); + if (httpconn->queue != NULL) + { + MsnHttpQueueData *queue_data; - gaim_debug_info("msn", "new httpconn (%p)\n", httpconn); + queue_data = (MsnHttpQueueData *)httpconn->queue->data; - /* TODO: Remove this */ - httpconn->session = servconn->session; + httpconn->queue = g_list_remove(httpconn->queue, queue_data); - httpconn->servconn = servconn; + msn_httpconn_write(queue_data->httpconn, + queue_data->body, + queue_data->body_len); - httpconn->tx_buf = gaim_circ_buffer_new(MSN_BUF_LEN); - httpconn->tx_handler = 0; - - return httpconn; + g_free(queue_data->body); + g_free(queue_data); + } } -void -msn_httpconn_destroy(MsnHttpConn *httpconn) +static gboolean +msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf, + size_t size, char **ret_buf, size_t *ret_size, + gboolean *error) { - g_return_if_fail(httpconn != NULL); + const char *s, *c; + char *header, *body; + const char *body_start; + char *tmp; + size_t body_len = 0; + gboolean wasted = FALSE; - gaim_debug_info("msn", "destroy httpconn (%p)\n", httpconn); + g_return_val_if_fail(httpconn != NULL, FALSE); + g_return_val_if_fail(buf != NULL, FALSE); + g_return_val_if_fail(size > 0, FALSE); + g_return_val_if_fail(ret_buf != NULL, FALSE); + g_return_val_if_fail(ret_size != NULL, FALSE); + g_return_val_if_fail(error != NULL, FALSE); - if (httpconn->connected) - msn_httpconn_disconnect(httpconn); +#if 0 + gaim_debug_info("msn", "HTTP: parsing data {%s}\n", buf); +#endif - g_free(httpconn->full_session_id); + /* Healthy defaults. */ + body = NULL; - g_free(httpconn->session_id); + *ret_buf = NULL; + *ret_size = 0; + *error = FALSE; - g_free(httpconn->host); + /* First, some tests to see if we have a full block of stuff. */ + if (((strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) != 0) && + (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) != 0)) && + ((strncmp(buf, "HTTP/1.0 200 OK\r\n", 17) != 0) && + (strncmp(buf, "HTTP/1.0 100 Continue\r\n", 23) != 0))) + { + *error = TRUE; - gaim_circ_buffer_destroy(httpconn->tx_buf); - if (httpconn->tx_handler > 0) - gaim_input_remove(httpconn->tx_handler); - - g_free(httpconn); -} - -static char * -msn_httpconn_proxy_auth(MsnHttpConn *httpconn) -{ - GaimAccount *account; - GaimProxyInfo *gpi; - const char *username, *password; - char *auth = NULL; - - account = httpconn->session->account; - - if (gaim_account_get_proxy_info(account) == NULL) - gpi = gaim_global_proxy_get_info(); - else - gpi = gaim_account_get_proxy_info(account); - - if (gpi == NULL || !(gaim_proxy_info_get_type(gpi) == GAIM_PROXY_HTTP || - gaim_proxy_info_get_type(gpi) == GAIM_PROXY_USE_ENVVAR)) - return NULL; - - username = gaim_proxy_info_get_username(gpi); - password = gaim_proxy_info_get_password(gpi); - - if (username != NULL) { - char *tmp; - auth = g_strdup_printf("%s:%s", username, password ? password : ""); - tmp = gaim_base64_encode((const guchar *)auth, strlen(auth)); - g_free(auth); - auth = g_strdup_printf("Proxy-Authorization: Basic %s\r\n", tmp); - g_free(tmp); + return FALSE; } - return auth; -} + if (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) == 0) + { + if ((s = strstr(buf, "\r\n\r\n")) == NULL) + return FALSE; -static void -httpconn_write_cb(gpointer data, gint source, GaimInputCondition cond) -{ - MsnHttpConn *httpconn = data; - int ret, writelen; + s += 4; - if (httpconn->waiting_response) - return; + if (*s == '\0') + { + *ret_buf = g_strdup(""); + *ret_size = 0; - writelen = gaim_circ_buffer_get_max_read(httpconn->tx_buf); + msn_httpconn_process_queue(httpconn); - if (writelen == 0) { - httpconn->waiting_response = TRUE; - gaim_input_remove(httpconn->tx_handler); - httpconn->tx_handler = 0; - return; - } + return TRUE; + } - ret = write(httpconn->fd, httpconn->tx_buf->outptr, writelen); - - if (ret < 0 && errno == EAGAIN) - return; - else if (ret <= 0) { - msn_servconn_got_error(httpconn->servconn, - MSN_SERVCONN_ERROR_WRITE); - return; + buf = s; + size -= (s - buf); } - gaim_circ_buffer_mark_read(httpconn->tx_buf, ret); + if ((s = strstr(buf, "\r\n\r\n")) == NULL) + /* Need to wait for the full HTTP header to arrive */ + return FALSE; - if (ret == writelen) - httpconn_write_cb(data, source, cond); -} + s += 4; /* Skip \r\n */ + header = g_strndup(buf, s - buf); + body_start = s; + body_len = size - (body_start - buf); -static ssize_t -write_raw(MsnHttpConn *httpconn, const char *data, size_t data_len) -{ - ssize_t res; /* result of the write operation */ - -#ifdef MSN_DEBUG_HTTP - gaim_debug_misc("msn", "Writing HTTP (header): {%s}\n", header); -#endif - - - if (httpconn->tx_handler == 0 && !httpconn->waiting_response) - res = write(httpconn->fd, data, data_len); - else + if ((s = gaim_strcasestr(header, "Content-Length: ")) != NULL) { - res = -1; - errno = EAGAIN; - } + int tmp_len; - if (res <= 0 && errno != EAGAIN) - { - msn_servconn_got_error(httpconn->servconn, - MSN_SERVCONN_ERROR_WRITE); - return -1; - } else if (res < 0 || res < data_len) { - if (res < 0) - res = 0; - if (httpconn->tx_handler == 0 && httpconn->fd) - httpconn->tx_handler = gaim_input_add(httpconn->fd, - GAIM_INPUT_WRITE, httpconn_write_cb, httpconn); - gaim_circ_buffer_append(httpconn->tx_buf, data + res, - data_len - res); - } + s += strlen("Content-Length: "); - return res; -} + if ((c = strchr(s, '\r')) == NULL) + { + g_free(header); -static void -msn_httpconn_poll(MsnHttpConn *httpconn) -{ - char *header; - char *auth; - int r; + return FALSE; + } - g_return_if_fail(httpconn != NULL); + tmp = g_strndup(s, c - s); + tmp_len = atoi(tmp); + g_free(tmp); - if (httpconn->waiting_response || - httpconn->tx_handler > 0) - { - return; - } + if (body_len != tmp_len) + { + /* Need to wait for the full packet to arrive */ - /* It is OK if this is buffered because it will only be buffered if - nothing else is in the buffer */ + g_free(header); - auth = msn_httpconn_proxy_auth(httpconn); +#if 0 + gaim_debug_warning("msn", + "body length (%d) != content length (%d)\n", + body_len, tmp_len); +#endif - header = g_strdup_printf( - "POST http://%s/gateway/gateway.dll?Action=poll&SessionID=%s HTTP/1.1\r\n" - "Accept: */*\r\n" - "Accept-Language: en-us\r\n" - "User-Agent: MSMSGS\r\n" - "Host: %s\r\n" - "Proxy-Connection: Keep-Alive\r\n" - "%s" /* Proxy auth */ - "Connection: Keep-Alive\r\n" - "Pragma: no-cache\r\n" - "Content-Type: application/x-msn-messenger\r\n" - "Content-Length: 0\r\n\r\n", - httpconn->host, - httpconn->full_session_id, - httpconn->host, - auth ? auth : ""); - - g_free(auth); - - r = write_raw(httpconn, header, strlen(header)); - - g_free(header); - - if (r >= 0) - { - httpconn->waiting_response = TRUE; - httpconn->dirty = FALSE; + return FALSE; + } } -} -static gboolean -do_poll(gpointer data) -{ - MsnHttpConn *httpconn; + body = g_malloc0(body_len + 1); + memcpy(body, body_start, body_len); - httpconn = data; - - g_return_val_if_fail(httpconn != NULL, TRUE); - -#if 0 - gaim_debug_info("msn", "polling from %s\n", httpconn->session_id); +#ifdef MSN_DEBUG_HTTP + gaim_debug_misc("msn", "Incoming HTTP buffer (header): {%s\r\n}\n", + header); #endif - if ((httpconn->host == NULL) || (httpconn->full_session_id == NULL)) + /* Now we should be able to process the data. */ + if ((s = gaim_strcasestr(header, "X-MSN-Messenger: ")) != NULL) { - gaim_debug_warning("msn", "Attempted HTTP poll before session is established\n"); - return TRUE; - } + char *full_session_id, *gw_ip, *session_action; + char *t, *session_id; + char **elems, **cur, **tokens; - if (httpconn->dirty) - msn_httpconn_poll(httpconn); + full_session_id = gw_ip = session_action = NULL; - return TRUE; -} + s += strlen("X-MSN-Messenger: "); -static void -connect_cb(gpointer data, gint source, GaimInputCondition cond) -{ - MsnHttpConn *httpconn = data; + if ((c = strchr(s, '\r')) == NULL) + { + msn_session_set_error(httpconn->session, + MSN_ERROR_HTTP_MALFORMED, NULL); + gaim_debug_error("msn", "Malformed X-MSN-Messenger field.\n{%s}", + buf); - httpconn->fd = source; + g_free(body); + return FALSE; + } - if (source > 0) - { - httpconn->inpa = gaim_input_add(httpconn->fd, GAIM_INPUT_READ, - read_cb, data); + tmp = g_strndup(s, c - s); - httpconn->timer = gaim_timeout_add(2000, do_poll, httpconn); + elems = g_strsplit(tmp, "; ", 0); - httpconn->waiting_response = FALSE; - if (httpconn->tx_handler > 0) - gaim_input_remove(httpconn->tx_handler); + for (cur = elems; *cur != NULL; cur++) + { + tokens = g_strsplit(*cur, "=", 2); - httpconn->tx_handler = gaim_input_add(source, - GAIM_INPUT_WRITE, httpconn_write_cb, httpconn); + if (strcmp(tokens[0], "SessionID") == 0) + full_session_id = tokens[1]; + else if (strcmp(tokens[0], "GW-IP") == 0) + gw_ip = tokens[1]; + else if (strcmp(tokens[0], "Session") == 0) + session_action = tokens[1]; + else + g_free(tokens[1]); - httpconn_write_cb(httpconn, source, GAIM_INPUT_WRITE); - } - else - { - gaim_debug_error("msn", "HTTP: Connection error\n"); - msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_CONNECT); - } -} + g_free(tokens[0]); + /* Don't free each of the tokens, only the array. */ + g_free(tokens); + } -gboolean -msn_httpconn_connect(MsnHttpConn *httpconn, const char *host, int port) -{ - int r; + g_strfreev(elems); - g_return_val_if_fail(httpconn != NULL, FALSE); - g_return_val_if_fail(host != NULL, FALSE); - g_return_val_if_fail(port > 0, FALSE); + g_free(tmp); - if (httpconn->connected) - msn_httpconn_disconnect(httpconn); + if ((session_action != NULL) && (strcmp(session_action, "close") == 0)) + wasted = TRUE; - r = gaim_proxy_connect(httpconn->session->account, - "gateway.messenger.hotmail.com", 80, connect_cb, httpconn); + g_free(session_action); - if (r == 0) - { - httpconn->waiting_response = TRUE; - httpconn->connected = TRUE; - } + t = strchr(full_session_id, '.'); + session_id = g_strndup(full_session_id, t - full_session_id); - return httpconn->connected; -} + if (!wasted) + { + g_free(httpconn->full_session_id); + httpconn->full_session_id = full_session_id; -void -msn_httpconn_disconnect(MsnHttpConn *httpconn) -{ - g_return_if_fail(httpconn != NULL); + g_free(httpconn->session_id); + httpconn->session_id = session_id; - if (!httpconn->connected) - return; + g_free(httpconn->host); + httpconn->host = gw_ip; + } + else + { + MsnServConn *servconn; - if (httpconn->timer) - gaim_timeout_remove(httpconn->timer); + /* It's going to die. */ + /* poor thing */ - httpconn->timer = 0; + servconn = httpconn->servconn; - if (httpconn->inpa > 0) - { - gaim_input_remove(httpconn->inpa); - httpconn->inpa = 0; + /* I'll be honest, I don't fully understand all this, but this + * causes crashes, Stu. */ + /* if (servconn != NULL) + servconn->wasted = TRUE; */ + + g_free(full_session_id); + g_free(session_id); + g_free(gw_ip); + } } - close(httpconn->fd); + g_free(header); - g_free(httpconn->rx_buf); - httpconn->rx_buf = NULL; - httpconn->rx_len = 0; + *ret_buf = body; + *ret_size = body_len; - httpconn->connected = FALSE; + msn_httpconn_process_queue(httpconn); - /* msn_servconn_disconnect(httpconn->servconn); */ + return TRUE; } static void @@ -376,7 +301,7 @@ if (!msn_httpconn_parse_data(httpconn, httpconn->rx_buf, httpconn->rx_len, &result_msg, &result_len, &error)) { - /* We must wait for more input, or something went wrong */ + /* Either we must wait for more input, or something went wrong */ if (error) msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_READ); @@ -472,15 +397,169 @@ g_free(old_rx_buf); } +static void +httpconn_write_cb(gpointer data, gint source, GaimInputCondition cond) +{ + MsnHttpConn *httpconn; + int ret, writelen; + + httpconn = data; + writelen = gaim_circ_buffer_get_max_read(httpconn->tx_buf); + + if (writelen == 0) + { + gaim_input_remove(httpconn->tx_handler); + httpconn->tx_handler = 0; + return; + } + + ret = write(httpconn->fd, httpconn->tx_buf->outptr, writelen); + if (ret <= 0) + { + if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) + /* No worries */ + return; + + /* Error! */ + msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_WRITE); + return; + } + + gaim_circ_buffer_mark_read(httpconn->tx_buf, ret); + + /* TODO: I don't think these 2 lines are needed. Remove them? */ + if (ret == writelen) + httpconn_write_cb(data, source, cond); +} + +static gboolean +write_raw(MsnHttpConn *httpconn, const char *data, size_t data_len) +{ + ssize_t res; /* result of the write operation */ + + if (httpconn->tx_handler == 0) + res = write(httpconn->fd, data, data_len); + else + { + res = -1; + errno = EAGAIN; + } + + if ((res <= 0) && ((errno != EAGAIN) && (errno != EWOULDBLOCK))) + { + msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_WRITE); + return FALSE; + } + + if (res < 0 || res < data_len) + { + if (res < 0) + res = 0; + if (httpconn->tx_handler == 0 && httpconn->fd) + httpconn->tx_handler = gaim_input_add(httpconn->fd, + GAIM_INPUT_WRITE, httpconn_write_cb, httpconn); + gaim_circ_buffer_append(httpconn->tx_buf, data + res, + data_len - res); + } + + return TRUE; +} + +static char * +msn_httpconn_proxy_auth(MsnHttpConn *httpconn) +{ + GaimAccount *account; + GaimProxyInfo *gpi; + const char *username, *password; + char *auth = NULL; + + account = httpconn->session->account; + + if (gaim_account_get_proxy_info(account) == NULL) + gpi = gaim_global_proxy_get_info(); + else + gpi = gaim_account_get_proxy_info(account); + + if (gpi == NULL || !(gaim_proxy_info_get_type(gpi) == GAIM_PROXY_HTTP || + gaim_proxy_info_get_type(gpi) == GAIM_PROXY_USE_ENVVAR)) + return NULL; + + username = gaim_proxy_info_get_username(gpi); + password = gaim_proxy_info_get_password(gpi); + + if (username != NULL) { + char *tmp; + auth = g_strdup_printf("%s:%s", username, password ? password : ""); + tmp = gaim_base64_encode((const guchar *)auth, strlen(auth)); + g_free(auth); + auth = g_strdup_printf("Proxy-Authorization: Basic %s\r\n", tmp); + g_free(tmp); + } + + return auth; +} + +static gboolean +msn_httpconn_poll(gpointer data) +{ + MsnHttpConn *httpconn; + char *header; + char *auth; + + data = httpconn; + + g_return_val_if_fail(httpconn != NULL, FALSE); + + if ((httpconn->host == NULL) || (httpconn->full_session_id == NULL)) + { + /* There's no need to poll if the session is not fully established */ + return TRUE; + } + + if (httpconn->waiting_response) + { + /* There's no need to poll if we're already waiting for a response */ + return TRUE; + } + + auth = msn_httpconn_proxy_auth(httpconn); + + header = g_strdup_printf( + "POST http://%s/gateway/gateway.dll?Action=poll&SessionID=%s HTTP/1.1\r\n" + "Accept: */*\r\n" + "Accept-Language: en-us\r\n" + "User-Agent: MSMSGS\r\n" + "Host: %s\r\n" + "Proxy-Connection: Keep-Alive\r\n" + "%s" /* Proxy auth */ + "Connection: Keep-Alive\r\n" + "Pragma: no-cache\r\n" + "Content-Type: application/x-msn-messenger\r\n" + "Content-Length: 0\r\n\r\n", + httpconn->host, + httpconn->full_session_id, + httpconn->host, + auth ? auth : ""); + + g_free(auth); + + if (write_raw(httpconn, header, strlen(header))) + httpconn->waiting_response = TRUE; + + g_free(header); + + return TRUE; +} + ssize_t -msn_httpconn_write(MsnHttpConn *httpconn, const char *body, size_t size) +msn_httpconn_write(MsnHttpConn *httpconn, const char *body, size_t body_len) { char *params; char *data; + int header_len; char *auth; const char *server_types[] = { "NS", "SB" }; const char *server_type; - ssize_t r; /* result of the write operation */ char *host; MsnServConn *servconn; @@ -488,10 +567,23 @@ g_return_val_if_fail(httpconn != NULL, 0); g_return_val_if_fail(body != NULL, 0); - g_return_val_if_fail(size > 0, 0); + g_return_val_if_fail(body_len > 0, 0); servconn = httpconn->servconn; + if (httpconn->waiting_response) + { + MsnHttpQueueData *queue_data = g_new0(MsnHttpQueueData, 1); + + queue_data->httpconn = httpconn; + queue_data->body = g_memdup(body, body_len); + queue_data->body_len = body_len; + + httpconn->queue = g_list_append(httpconn->queue, queue_data); + + return body_len; + } + server_type = server_types[servconn->type]; if (httpconn->virgin) @@ -532,245 +624,158 @@ "Connection: Keep-Alive\r\n" "Pragma: no-cache\r\n" "Content-Type: application/x-msn-messenger\r\n" - "Content-Length: %d\r\n\r\n" - "%s", + "Content-Length: %d\r\n\r\n", host, params, host, auth ? auth : "", - (int) size, - body ? body : ""); + (int) body_len); - g_free(params); g_free(auth); - r = write_raw(httpconn, data, strlen(data)); + header_len = strlen(data); + data = g_realloc(data, header_len + body_len); + memcpy(data + header_len, body, body_len); + if (write_raw(httpconn, data, header_len + body_len)) + httpconn->waiting_response = TRUE; + g_free(data); - if (r >= 0) - { - httpconn->waiting_response = TRUE; - httpconn->dirty = FALSE; - } - - return r; + return body_len; } -gboolean -msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf, - size_t size, char **ret_buf, size_t *ret_size, - gboolean *error) +MsnHttpConn * +msn_httpconn_new(MsnServConn *servconn) { - const char *s, *c; - char *header, *body; - const char *body_start; - char *tmp; - size_t body_len = 0; - gboolean wasted = FALSE; + MsnHttpConn *httpconn; - g_return_val_if_fail(httpconn != NULL, FALSE); - g_return_val_if_fail(buf != NULL, FALSE); - g_return_val_if_fail(size > 0, FALSE); - g_return_val_if_fail(ret_buf != NULL, FALSE); - g_return_val_if_fail(ret_size != NULL, FALSE); - g_return_val_if_fail(error != NULL, FALSE); + g_return_val_if_fail(servconn != NULL, NULL); -#if 0 - gaim_debug_info("msn", "HTTP: parsing data {%s}\n", buf); -#endif + httpconn = g_new0(MsnHttpConn, 1); - httpconn->waiting_response = FALSE; + gaim_debug_info("msn", "new httpconn (%p)\n", httpconn); - /* Healthy defaults. */ - body = NULL; + /* TODO: Remove this */ + httpconn->session = servconn->session; - *ret_buf = NULL; - *ret_size = 0; - *error = FALSE; + httpconn->servconn = servconn; - /* First, some tests to see if we have a full block of stuff. */ - if (((strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) != 0) && - (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) != 0)) && - ((strncmp(buf, "HTTP/1.0 200 OK\r\n", 17) != 0) && - (strncmp(buf, "HTTP/1.0 100 Continue\r\n", 23) != 0))) - { - *error = TRUE; + httpconn->tx_buf = gaim_circ_buffer_new(MSN_BUF_LEN); + httpconn->tx_handler = 0; - return FALSE; - } + return httpconn; +} - if (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) == 0) - { - if ((s = strstr(buf, "\r\n\r\n")) == NULL) - return FALSE; +void +msn_httpconn_destroy(MsnHttpConn *httpconn) +{ + g_return_if_fail(httpconn != NULL); - s += 4; + gaim_debug_info("msn", "destroy httpconn (%p)\n", httpconn); - if (*s == '\0') - { - *ret_buf = g_strdup(""); - *ret_size = 0; + if (httpconn->connected) + msn_httpconn_disconnect(httpconn); - if (httpconn->tx_handler > 0) - httpconn_write_cb(httpconn, httpconn->fd, - GAIM_INPUT_WRITE); - else - httpconn->dirty = TRUE; + g_free(httpconn->full_session_id); - return TRUE; - } + g_free(httpconn->session_id); - buf = s; - size -= (s - buf); - } + g_free(httpconn->host); - if ((s = strstr(buf, "\r\n\r\n")) == NULL) - return FALSE; + gaim_circ_buffer_destroy(httpconn->tx_buf); + if (httpconn->tx_handler > 0) + gaim_input_remove(httpconn->tx_handler); - s += 4; /* Skip \r\n */ - header = g_strndup(buf, s - buf); - body_start = s; - body_len = size - (body_start - buf); + g_free(httpconn); +} - if ((s = gaim_strcasestr(header, "Content-Length: ")) != NULL) +static void +connect_cb(gpointer data, gint source, GaimInputCondition cond) +{ + MsnHttpConn *httpconn = data; + + /* + TODO: Need to do this in case the account is disabled while connecting + if (!g_list_find(gaim_connections_get_all(), gc)) { - int tmp_len; + if (source >= 0) + close(source); + destroy_new_conn_data(new_conn_data); + return; + } + */ - s += strlen("Content-Length: "); + httpconn->fd = source; - if ((c = strchr(s, '\r')) == NULL) - { - g_free(header); + if (source >= 0) + { + httpconn->inpa = gaim_input_add(httpconn->fd, GAIM_INPUT_READ, + read_cb, data); - return FALSE; - } + httpconn->timer = gaim_timeout_add(2000, msn_httpconn_poll, httpconn); - tmp = g_strndup(s, c - s); - tmp_len = atoi(tmp); - g_free(tmp); - - if (body_len != tmp_len) - { - g_free(header); - -#if 0 - gaim_debug_warning("msn", - "body length (%d) != content length (%d)\n", - body_len, tmp_len); -#endif - - return FALSE; - } + msn_httpconn_process_queue(httpconn); } - - body = g_malloc0(body_len + 1); - memcpy(body, body_start, body_len); - -#ifdef MSN_DEBUG_HTTP - gaim_debug_misc("msn", "Incoming HTTP buffer (header): {%s\r\n}\n", - header); -#endif - - /* Now we should be able to process the data. */ - if ((s = gaim_strcasestr(header, "X-MSN-Messenger: ")) != NULL) + else { - char *full_session_id, *gw_ip, *session_action; - char *t, *session_id; - char **elems, **cur, **tokens; + gaim_debug_error("msn", "HTTP: Connection error\n"); + msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_CONNECT); + } +} - full_session_id = gw_ip = session_action = NULL; +gboolean +msn_httpconn_connect(MsnHttpConn *httpconn, const char *host, int port) +{ + int r; - s += strlen("X-MSN-Messenger: "); + g_return_val_if_fail(httpconn != NULL, FALSE); + g_return_val_if_fail(host != NULL, FALSE); + g_return_val_if_fail(port > 0, FALSE); - if ((c = strchr(s, '\r')) == NULL) - { - msn_session_set_error(httpconn->session, - MSN_ERROR_HTTP_MALFORMED, NULL); - gaim_debug_error("msn", "Malformed X-MSN-Messenger field.\n{%s}", - buf); + if (httpconn->connected) + msn_httpconn_disconnect(httpconn); - g_free(body); - return FALSE; - } + r = gaim_proxy_connect(httpconn->session->account, + "gateway.messenger.hotmail.com", 80, connect_cb, httpconn); - tmp = g_strndup(s, c - s); + if (r == 0) + { + httpconn->waiting_response = TRUE; + httpconn->connected = TRUE; + } - elems = g_strsplit(tmp, "; ", 0); + return httpconn->connected; +} - for (cur = elems; *cur != NULL; cur++) - { - tokens = g_strsplit(*cur, "=", 2); +void +msn_httpconn_disconnect(MsnHttpConn *httpconn) +{ + g_return_if_fail(httpconn != NULL); - if (strcmp(tokens[0], "SessionID") == 0) - full_session_id = tokens[1]; - else if (strcmp(tokens[0], "GW-IP") == 0) - gw_ip = tokens[1]; - else if (strcmp(tokens[0], "Session") == 0) - session_action = tokens[1]; + if (!httpconn->connected) + return; - g_free(tokens[0]); - /* Don't free each of the tokens, only the array. */ - g_free(tokens); - } + if (httpconn->timer) + gaim_timeout_remove(httpconn->timer); - g_strfreev(elems); + httpconn->timer = 0; - g_free(tmp); - - if ((session_action != NULL) && (strcmp(session_action, "close") == 0)) - wasted = TRUE; - - g_free(session_action); - - t = strchr(full_session_id, '.'); - session_id = g_strndup(full_session_id, t - full_session_id); - - if (!wasted) - { - g_free(httpconn->full_session_id); - - httpconn->full_session_id = full_session_id; - - g_free(httpconn->session_id); - - httpconn->session_id = session_id; - - g_free(httpconn->host); - - httpconn->host = gw_ip; - } - else - { - MsnServConn *servconn; - - /* It's going to die. */ - /* poor thing */ - - servconn = httpconn->servconn; - - /* I'll be honest, I don't fully understand all this, but this - * causes crashes, Stu. */ - /* if (servconn != NULL) - servconn->wasted = TRUE; */ - - g_free(full_session_id); - g_free(session_id); - g_free(gw_ip); - } + if (httpconn->inpa > 0) + { + gaim_input_remove(httpconn->inpa); + httpconn->inpa = 0; } - g_free(header); + close(httpconn->fd); - *ret_buf = body; - *ret_size = body_len; + g_free(httpconn->rx_buf); + httpconn->rx_buf = NULL; + httpconn->rx_len = 0; - if (httpconn->tx_handler > 0) - httpconn_write_cb(httpconn, httpconn->fd, GAIM_INPUT_WRITE); - else - httpconn->dirty = TRUE; + httpconn->connected = FALSE; - return TRUE; + /* msn_servconn_disconnect(httpconn->servconn); */ } Modified: branches/v2_0_0/src/protocols/msn/httpconn.h =================================================================== --- branches/v2_0_0/src/protocols/msn/httpconn.h 2006-07-03 20:39:04 UTC (rev 16414) +++ branches/v2_0_0/src/protocols/msn/httpconn.h 2006-07-03 20:39:41 UTC (rev 16415) @@ -44,13 +44,13 @@ gboolean waiting_response; /**< The flag that states if we are waiting a response from the server. */ - gboolean dirty; /**< The flag that states if we should poll. */ gboolean connected; /**< The flag that states if the connection is on. */ gboolean virgin; /**< The flag that states if this connection should specify the host (not gateway) to connect to. */ char *host; /**< The HTTP gateway host. */ + GList *queue; /**< The queue of data chunks to write. */ int fd; /**< The connection's file descriptor. */ guint inpa; /**< The connection's input handler. */ @@ -83,11 +83,11 @@ * * @param servconn The server connection. * @param data The data to write. - * @param size The size of the data to write. + * @param data_len The size of the data to write. * * @return The number of bytes written. */ -ssize_t msn_httpconn_write(MsnHttpConn *httpconn, const char *data, size_t size); +ssize_t msn_httpconn_write(MsnHttpConn *httpconn, const char *data, size_t data_len); /** * Connects the HTTP connection object to a host. Modified: branches/v2_0_0/src/protocols/msn/msn.c =================================================================== --- branches/v2_0_0/src/protocols/msn/msn.c 2006-07-03 20:39:04 UTC (rev 16414) +++ branches/v2_0_0/src/protocols/msn/msn.c 2006-07-03 20:39:41 UTC (rev 16415) @@ -731,8 +731,7 @@ return; } - if (gaim_account_get_bool(account, "http_method", FALSE)) - http_method = TRUE; + http_method = gaim_account_get_bool(account, "http_method", FALSE); host = gaim_account_get_string(account, "server", MSN_SERVER); port = gaim_account_get_int(account, "port", MSN_PORT); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-03 20:39:11
|
Revision: 16414 Author: thekingant Date: 2006-07-03 13:39:04 -0700 (Mon, 03 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16414&view=rev Log Message: ----------- First stab at trying to fix the MSN http connect method. It still doesn't work, and I'm not sure why, but it gets a lot farther in the signon process now. For those unfamiliar with the issue, the MSN http connect method stopped working after all the non-blocking I/O changes. The http connect method is apparently used by lots of people behind silly firewalls and stuff, and therefore we really shouldn't release Gaim 2.0.0 without it working, because people will complain. The two main problems were 1. The outgoing message queue was removed in favor of buffering all data to one large buffer. This sounds good in theory... but apparently each message sent to and from the server has a "SessionID" in the HTTP header. Every message we send should use the same SessionID as the last packet we received from the server. So basically you can't put two messages into the outgoing buffer at the same time because you don't have the correct SessionID to use for the second message. You have to wait until you get the reply from the server. 2. There were some strange buffer problems with using the wrong variable when trying to combine the header+body into one buffer before sending the message. I also fixed a small memleak or two, added some comments, and tried to clean up the code a little. Modified Paths: -------------- trunk/src/connection.c trunk/src/connection.h trunk/src/protocols/msn/httpconn.c trunk/src/protocols/msn/httpconn.h trunk/src/protocols/msn/msn.c Modified: trunk/src/connection.c =================================================================== --- trunk/src/connection.c 2006-07-03 18:28:13 UTC (rev 16413) +++ trunk/src/connection.c 2006-07-03 20:39:04 UTC (rev 16414) @@ -217,12 +217,9 @@ gaim_account_set_connection(account, NULL); - if (gc->password != NULL) - g_free(gc->password); + g_free(gc->password); + g_free(gc->display_name); - if (gc->display_name != NULL) - g_free(gc->display_name); - if (gc->disconnect_timeout) gaim_timeout_remove(gc->disconnect_timeout); Modified: trunk/src/connection.h =================================================================== --- trunk/src/connection.h 2006-07-03 18:28:13 UTC (rev 16413) +++ trunk/src/connection.h 2006-07-03 20:39:04 UTC (rev 16414) @@ -130,12 +130,12 @@ const char *password); /** + * Disconnects and destroys a GaimConnection. + * * This function should only be called by gaim_account_disconnect() - * in account.c. If you're trying to sign on an account, use that + * in account.c. If you're trying to sign off an account, use that * function instead. * - * Disconnects and destroys a GaimConnection. - * * @param gc The gaim connection to destroy. */ void gaim_connection_destroy(GaimConnection *gc); Modified: trunk/src/protocols/msn/httpconn.c =================================================================== --- trunk/src/protocols/msn/httpconn.c 2006-07-03 18:28:13 UTC (rev 16413) +++ trunk/src/protocols/msn/httpconn.c 2006-07-03 20:39:04 UTC (rev 16414) @@ -25,317 +25,242 @@ #include "debug.h" #include "httpconn.h" -static void read_cb(gpointer data, gint source, GaimInputCondition cond); -gboolean msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf, - size_t size, char **ret_buf, size_t *ret_size, - gboolean *error); - -MsnHttpConn * -msn_httpconn_new(MsnServConn *servconn) +typedef struct { MsnHttpConn *httpconn; + char *body; + size_t body_len; +} MsnHttpQueueData; - g_return_val_if_fail(servconn != NULL, NULL); +static void +msn_httpconn_process_queue(MsnHttpConn *httpconn) +{ + httpconn->waiting_response = FALSE; - httpconn = g_new0(MsnHttpConn, 1); + if (httpconn->queue != NULL) + { + MsnHttpQueueData *queue_data; - gaim_debug_info("msn", "new httpconn (%p)\n", httpconn); + queue_data = (MsnHttpQueueData *)httpconn->queue->data; - /* TODO: Remove this */ - httpconn->session = servconn->session; + httpconn->queue = g_list_remove(httpconn->queue, queue_data); - httpconn->servconn = servconn; + msn_httpconn_write(queue_data->httpconn, + queue_data->body, + queue_data->body_len); - httpconn->tx_buf = gaim_circ_buffer_new(MSN_BUF_LEN); - httpconn->tx_handler = 0; - - return httpconn; + g_free(queue_data->body); + g_free(queue_data); + } } -void -msn_httpconn_destroy(MsnHttpConn *httpconn) +static gboolean +msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf, + size_t size, char **ret_buf, size_t *ret_size, + gboolean *error) { - g_return_if_fail(httpconn != NULL); + const char *s, *c; + char *header, *body; + const char *body_start; + char *tmp; + size_t body_len = 0; + gboolean wasted = FALSE; - gaim_debug_info("msn", "destroy httpconn (%p)\n", httpconn); + g_return_val_if_fail(httpconn != NULL, FALSE); + g_return_val_if_fail(buf != NULL, FALSE); + g_return_val_if_fail(size > 0, FALSE); + g_return_val_if_fail(ret_buf != NULL, FALSE); + g_return_val_if_fail(ret_size != NULL, FALSE); + g_return_val_if_fail(error != NULL, FALSE); - if (httpconn->connected) - msn_httpconn_disconnect(httpconn); +#if 0 + gaim_debug_info("msn", "HTTP: parsing data {%s}\n", buf); +#endif - g_free(httpconn->full_session_id); + /* Healthy defaults. */ + body = NULL; - g_free(httpconn->session_id); + *ret_buf = NULL; + *ret_size = 0; + *error = FALSE; - g_free(httpconn->host); + /* First, some tests to see if we have a full block of stuff. */ + if (((strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) != 0) && + (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) != 0)) && + ((strncmp(buf, "HTTP/1.0 200 OK\r\n", 17) != 0) && + (strncmp(buf, "HTTP/1.0 100 Continue\r\n", 23) != 0))) + { + *error = TRUE; - gaim_circ_buffer_destroy(httpconn->tx_buf); - if (httpconn->tx_handler > 0) - gaim_input_remove(httpconn->tx_handler); - - g_free(httpconn); -} - -static char * -msn_httpconn_proxy_auth(MsnHttpConn *httpconn) -{ - GaimAccount *account; - GaimProxyInfo *gpi; - const char *username, *password; - char *auth = NULL; - - account = httpconn->session->account; - - if (gaim_account_get_proxy_info(account) == NULL) - gpi = gaim_global_proxy_get_info(); - else - gpi = gaim_account_get_proxy_info(account); - - if (gpi == NULL || !(gaim_proxy_info_get_type(gpi) == GAIM_PROXY_HTTP || - gaim_proxy_info_get_type(gpi) == GAIM_PROXY_USE_ENVVAR)) - return NULL; - - username = gaim_proxy_info_get_username(gpi); - password = gaim_proxy_info_get_password(gpi); - - if (username != NULL) { - char *tmp; - auth = g_strdup_printf("%s:%s", username, password ? password : ""); - tmp = gaim_base64_encode((const guchar *)auth, strlen(auth)); - g_free(auth); - auth = g_strdup_printf("Proxy-Authorization: Basic %s\r\n", tmp); - g_free(tmp); + return FALSE; } - return auth; -} + if (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) == 0) + { + if ((s = strstr(buf, "\r\n\r\n")) == NULL) + return FALSE; -static void -httpconn_write_cb(gpointer data, gint source, GaimInputCondition cond) -{ - MsnHttpConn *httpconn = data; - int ret, writelen; + s += 4; - if (httpconn->waiting_response) - return; + if (*s == '\0') + { + *ret_buf = g_strdup(""); + *ret_size = 0; - writelen = gaim_circ_buffer_get_max_read(httpconn->tx_buf); + msn_httpconn_process_queue(httpconn); - if (writelen == 0) { - httpconn->waiting_response = TRUE; - gaim_input_remove(httpconn->tx_handler); - httpconn->tx_handler = 0; - return; - } + return TRUE; + } - ret = write(httpconn->fd, httpconn->tx_buf->outptr, writelen); - - if (ret < 0 && errno == EAGAIN) - return; - else if (ret <= 0) { - msn_servconn_got_error(httpconn->servconn, - MSN_SERVCONN_ERROR_WRITE); - return; + buf = s; + size -= (s - buf); } - gaim_circ_buffer_mark_read(httpconn->tx_buf, ret); + if ((s = strstr(buf, "\r\n\r\n")) == NULL) + /* Need to wait for the full HTTP header to arrive */ + return FALSE; - if (ret == writelen) - httpconn_write_cb(data, source, cond); -} + s += 4; /* Skip \r\n */ + header = g_strndup(buf, s - buf); + body_start = s; + body_len = size - (body_start - buf); -static ssize_t -write_raw(MsnHttpConn *httpconn, const char *data, size_t data_len) -{ - ssize_t res; /* result of the write operation */ - -#ifdef MSN_DEBUG_HTTP - gaim_debug_misc("msn", "Writing HTTP (header): {%s}\n", header); -#endif - - - if (httpconn->tx_handler == 0 && !httpconn->waiting_response) - res = write(httpconn->fd, data, data_len); - else + if ((s = gaim_strcasestr(header, "Content-Length: ")) != NULL) { - res = -1; - errno = EAGAIN; - } + int tmp_len; - if (res <= 0 && errno != EAGAIN) - { - msn_servconn_got_error(httpconn->servconn, - MSN_SERVCONN_ERROR_WRITE); - return -1; - } else if (res < 0 || res < data_len) { - if (res < 0) - res = 0; - if (httpconn->tx_handler == 0 && httpconn->fd) - httpconn->tx_handler = gaim_input_add(httpconn->fd, - GAIM_INPUT_WRITE, httpconn_write_cb, httpconn); - gaim_circ_buffer_append(httpconn->tx_buf, data + res, - data_len - res); - } + s += strlen("Content-Length: "); - return res; -} + if ((c = strchr(s, '\r')) == NULL) + { + g_free(header); -static void -msn_httpconn_poll(MsnHttpConn *httpconn) -{ - char *header; - char *auth; - int r; + return FALSE; + } - g_return_if_fail(httpconn != NULL); + tmp = g_strndup(s, c - s); + tmp_len = atoi(tmp); + g_free(tmp); - if (httpconn->waiting_response || - httpconn->tx_handler > 0) - { - return; - } + if (body_len != tmp_len) + { + /* Need to wait for the full packet to arrive */ - /* It is OK if this is buffered because it will only be buffered if - nothing else is in the buffer */ + g_free(header); - auth = msn_httpconn_proxy_auth(httpconn); +#if 0 + gaim_debug_warning("msn", + "body length (%d) != content length (%d)\n", + body_len, tmp_len); +#endif - header = g_strdup_printf( - "POST http://%s/gateway/gateway.dll?Action=poll&SessionID=%s HTTP/1.1\r\n" - "Accept: */*\r\n" - "Accept-Language: en-us\r\n" - "User-Agent: MSMSGS\r\n" - "Host: %s\r\n" - "Proxy-Connection: Keep-Alive\r\n" - "%s" /* Proxy auth */ - "Connection: Keep-Alive\r\n" - "Pragma: no-cache\r\n" - "Content-Type: application/x-msn-messenger\r\n" - "Content-Length: 0\r\n\r\n", - httpconn->host, - httpconn->full_session_id, - httpconn->host, - auth ? auth : ""); - - g_free(auth); - - r = write_raw(httpconn, header, strlen(header)); - - g_free(header); - - if (r >= 0) - { - httpconn->waiting_response = TRUE; - httpconn->dirty = FALSE; + return FALSE; + } } -} -static gboolean -do_poll(gpointer data) -{ - MsnHttpConn *httpconn; + body = g_malloc0(body_len + 1); + memcpy(body, body_start, body_len); - httpconn = data; - - g_return_val_if_fail(httpconn != NULL, TRUE); - -#if 0 - gaim_debug_info("msn", "polling from %s\n", httpconn->session_id); +#ifdef MSN_DEBUG_HTTP + gaim_debug_misc("msn", "Incoming HTTP buffer (header): {%s\r\n}\n", + header); #endif - if ((httpconn->host == NULL) || (httpconn->full_session_id == NULL)) + /* Now we should be able to process the data. */ + if ((s = gaim_strcasestr(header, "X-MSN-Messenger: ")) != NULL) { - gaim_debug_warning("msn", "Attempted HTTP poll before session is established\n"); - return TRUE; - } + char *full_session_id, *gw_ip, *session_action; + char *t, *session_id; + char **elems, **cur, **tokens; - if (httpconn->dirty) - msn_httpconn_poll(httpconn); + full_session_id = gw_ip = session_action = NULL; - return TRUE; -} + s += strlen("X-MSN-Messenger: "); -static void -connect_cb(gpointer data, gint source, GaimInputCondition cond) -{ - MsnHttpConn *httpconn = data; + if ((c = strchr(s, '\r')) == NULL) + { + msn_session_set_error(httpconn->session, + MSN_ERROR_HTTP_MALFORMED, NULL); + gaim_debug_error("msn", "Malformed X-MSN-Messenger field.\n{%s}", + buf); - httpconn->fd = source; + g_free(body); + return FALSE; + } - if (source > 0) - { - httpconn->inpa = gaim_input_add(httpconn->fd, GAIM_INPUT_READ, - read_cb, data); + tmp = g_strndup(s, c - s); - httpconn->timer = gaim_timeout_add(2000, do_poll, httpconn); + elems = g_strsplit(tmp, "; ", 0); - httpconn->waiting_response = FALSE; - if (httpconn->tx_handler > 0) - gaim_input_remove(httpconn->tx_handler); + for (cur = elems; *cur != NULL; cur++) + { + tokens = g_strsplit(*cur, "=", 2); - httpconn->tx_handler = gaim_input_add(source, - GAIM_INPUT_WRITE, httpconn_write_cb, httpconn); + if (strcmp(tokens[0], "SessionID") == 0) + full_session_id = tokens[1]; + else if (strcmp(tokens[0], "GW-IP") == 0) + gw_ip = tokens[1]; + else if (strcmp(tokens[0], "Session") == 0) + session_action = tokens[1]; + else + g_free(tokens[1]); - httpconn_write_cb(httpconn, source, GAIM_INPUT_WRITE); - } - else - { - gaim_debug_error("msn", "HTTP: Connection error\n"); - msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_CONNECT); - } -} + g_free(tokens[0]); + /* Don't free each of the tokens, only the array. */ + g_free(tokens); + } -gboolean -msn_httpconn_connect(MsnHttpConn *httpconn, const char *host, int port) -{ - int r; + g_strfreev(elems); - g_return_val_if_fail(httpconn != NULL, FALSE); - g_return_val_if_fail(host != NULL, FALSE); - g_return_val_if_fail(port > 0, FALSE); + g_free(tmp); - if (httpconn->connected) - msn_httpconn_disconnect(httpconn); + if ((session_action != NULL) && (strcmp(session_action, "close") == 0)) + wasted = TRUE; - r = gaim_proxy_connect(httpconn->session->account, - "gateway.messenger.hotmail.com", 80, connect_cb, httpconn); + g_free(session_action); - if (r == 0) - { - httpconn->waiting_response = TRUE; - httpconn->connected = TRUE; - } + t = strchr(full_session_id, '.'); + session_id = g_strndup(full_session_id, t - full_session_id); - return httpconn->connected; -} + if (!wasted) + { + g_free(httpconn->full_session_id); + httpconn->full_session_id = full_session_id; -void -msn_httpconn_disconnect(MsnHttpConn *httpconn) -{ - g_return_if_fail(httpconn != NULL); + g_free(httpconn->session_id); + httpconn->session_id = session_id; - if (!httpconn->connected) - return; + g_free(httpconn->host); + httpconn->host = gw_ip; + } + else + { + MsnServConn *servconn; - if (httpconn->timer) - gaim_timeout_remove(httpconn->timer); + /* It's going to die. */ + /* poor thing */ - httpconn->timer = 0; + servconn = httpconn->servconn; - if (httpconn->inpa > 0) - { - gaim_input_remove(httpconn->inpa); - httpconn->inpa = 0; + /* I'll be honest, I don't fully understand all this, but this + * causes crashes, Stu. */ + /* if (servconn != NULL) + servconn->wasted = TRUE; */ + + g_free(full_session_id); + g_free(session_id); + g_free(gw_ip); + } } - close(httpconn->fd); + g_free(header); - g_free(httpconn->rx_buf); - httpconn->rx_buf = NULL; - httpconn->rx_len = 0; + *ret_buf = body; + *ret_size = body_len; - httpconn->connected = FALSE; + msn_httpconn_process_queue(httpconn); - /* msn_servconn_disconnect(httpconn->servconn); */ + return TRUE; } static void @@ -376,7 +301,7 @@ if (!msn_httpconn_parse_data(httpconn, httpconn->rx_buf, httpconn->rx_len, &result_msg, &result_len, &error)) { - /* We must wait for more input, or something went wrong */ + /* Either we must wait for more input, or something went wrong */ if (error) msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_READ); @@ -472,15 +397,169 @@ g_free(old_rx_buf); } +static void +httpconn_write_cb(gpointer data, gint source, GaimInputCondition cond) +{ + MsnHttpConn *httpconn; + int ret, writelen; + + httpconn = data; + writelen = gaim_circ_buffer_get_max_read(httpconn->tx_buf); + + if (writelen == 0) + { + gaim_input_remove(httpconn->tx_handler); + httpconn->tx_handler = 0; + return; + } + + ret = write(httpconn->fd, httpconn->tx_buf->outptr, writelen); + if (ret <= 0) + { + if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) + /* No worries */ + return; + + /* Error! */ + msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_WRITE); + return; + } + + gaim_circ_buffer_mark_read(httpconn->tx_buf, ret); + + /* TODO: I don't think these 2 lines are needed. Remove them? */ + if (ret == writelen) + httpconn_write_cb(data, source, cond); +} + +static gboolean +write_raw(MsnHttpConn *httpconn, const char *data, size_t data_len) +{ + ssize_t res; /* result of the write operation */ + + if (httpconn->tx_handler == 0) + res = write(httpconn->fd, data, data_len); + else + { + res = -1; + errno = EAGAIN; + } + + if ((res <= 0) && ((errno != EAGAIN) && (errno != EWOULDBLOCK))) + { + msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_WRITE); + return FALSE; + } + + if (res < 0 || res < data_len) + { + if (res < 0) + res = 0; + if (httpconn->tx_handler == 0 && httpconn->fd) + httpconn->tx_handler = gaim_input_add(httpconn->fd, + GAIM_INPUT_WRITE, httpconn_write_cb, httpconn); + gaim_circ_buffer_append(httpconn->tx_buf, data + res, + data_len - res); + } + + return TRUE; +} + +static char * +msn_httpconn_proxy_auth(MsnHttpConn *httpconn) +{ + GaimAccount *account; + GaimProxyInfo *gpi; + const char *username, *password; + char *auth = NULL; + + account = httpconn->session->account; + + if (gaim_account_get_proxy_info(account) == NULL) + gpi = gaim_global_proxy_get_info(); + else + gpi = gaim_account_get_proxy_info(account); + + if (gpi == NULL || !(gaim_proxy_info_get_type(gpi) == GAIM_PROXY_HTTP || + gaim_proxy_info_get_type(gpi) == GAIM_PROXY_USE_ENVVAR)) + return NULL; + + username = gaim_proxy_info_get_username(gpi); + password = gaim_proxy_info_get_password(gpi); + + if (username != NULL) { + char *tmp; + auth = g_strdup_printf("%s:%s", username, password ? password : ""); + tmp = gaim_base64_encode((const guchar *)auth, strlen(auth)); + g_free(auth); + auth = g_strdup_printf("Proxy-Authorization: Basic %s\r\n", tmp); + g_free(tmp); + } + + return auth; +} + +static gboolean +msn_httpconn_poll(gpointer data) +{ + MsnHttpConn *httpconn; + char *header; + char *auth; + + data = httpconn; + + g_return_val_if_fail(httpconn != NULL, FALSE); + + if ((httpconn->host == NULL) || (httpconn->full_session_id == NULL)) + { + /* There's no need to poll if the session is not fully established */ + return TRUE; + } + + if (httpconn->waiting_response) + { + /* There's no need to poll if we're already waiting for a response */ + return TRUE; + } + + auth = msn_httpconn_proxy_auth(httpconn); + + header = g_strdup_printf( + "POST http://%s/gateway/gateway.dll?Action=poll&SessionID=%s HTTP/1.1\r\n" + "Accept: */*\r\n" + "Accept-Language: en-us\r\n" + "User-Agent: MSMSGS\r\n" + "Host: %s\r\n" + "Proxy-Connection: Keep-Alive\r\n" + "%s" /* Proxy auth */ + "Connection: Keep-Alive\r\n" + "Pragma: no-cache\r\n" + "Content-Type: application/x-msn-messenger\r\n" + "Content-Length: 0\r\n\r\n", + httpconn->host, + httpconn->full_session_id, + httpconn->host, + auth ? auth : ""); + + g_free(auth); + + if (write_raw(httpconn, header, strlen(header))) + httpconn->waiting_response = TRUE; + + g_free(header); + + return TRUE; +} + ssize_t -msn_httpconn_write(MsnHttpConn *httpconn, const char *body, size_t size) +msn_httpconn_write(MsnHttpConn *httpconn, const char *body, size_t body_len) { char *params; char *data; + int header_len; char *auth; const char *server_types[] = { "NS", "SB" }; const char *server_type; - ssize_t r; /* result of the write operation */ char *host; MsnServConn *servconn; @@ -488,10 +567,23 @@ g_return_val_if_fail(httpconn != NULL, 0); g_return_val_if_fail(body != NULL, 0); - g_return_val_if_fail(size > 0, 0); + g_return_val_if_fail(body_len > 0, 0); servconn = httpconn->servconn; + if (httpconn->waiting_response) + { + MsnHttpQueueData *queue_data = g_new0(MsnHttpQueueData, 1); + + queue_data->httpconn = httpconn; + queue_data->body = g_memdup(body, body_len); + queue_data->body_len = body_len; + + httpconn->queue = g_list_append(httpconn->queue, queue_data); + + return body_len; + } + server_type = server_types[servconn->type]; if (httpconn->virgin) @@ -532,245 +624,158 @@ "Connection: Keep-Alive\r\n" "Pragma: no-cache\r\n" "Content-Type: application/x-msn-messenger\r\n" - "Content-Length: %d\r\n\r\n" - "%s", + "Content-Length: %d\r\n\r\n", host, params, host, auth ? auth : "", - (int) size, - body ? body : ""); + (int) body_len); - g_free(params); g_free(auth); - r = write_raw(httpconn, data, strlen(data)); + header_len = strlen(data); + data = g_realloc(data, header_len + body_len); + memcpy(data + header_len, body, body_len); + if (write_raw(httpconn, data, header_len + body_len)) + httpconn->waiting_response = TRUE; + g_free(data); - if (r >= 0) - { - httpconn->waiting_response = TRUE; - httpconn->dirty = FALSE; - } - - return r; + return body_len; } -gboolean -msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf, - size_t size, char **ret_buf, size_t *ret_size, - gboolean *error) +MsnHttpConn * +msn_httpconn_new(MsnServConn *servconn) { - const char *s, *c; - char *header, *body; - const char *body_start; - char *tmp; - size_t body_len = 0; - gboolean wasted = FALSE; + MsnHttpConn *httpconn; - g_return_val_if_fail(httpconn != NULL, FALSE); - g_return_val_if_fail(buf != NULL, FALSE); - g_return_val_if_fail(size > 0, FALSE); - g_return_val_if_fail(ret_buf != NULL, FALSE); - g_return_val_if_fail(ret_size != NULL, FALSE); - g_return_val_if_fail(error != NULL, FALSE); + g_return_val_if_fail(servconn != NULL, NULL); -#if 0 - gaim_debug_info("msn", "HTTP: parsing data {%s}\n", buf); -#endif + httpconn = g_new0(MsnHttpConn, 1); - httpconn->waiting_response = FALSE; + gaim_debug_info("msn", "new httpconn (%p)\n", httpconn); - /* Healthy defaults. */ - body = NULL; + /* TODO: Remove this */ + httpconn->session = servconn->session; - *ret_buf = NULL; - *ret_size = 0; - *error = FALSE; + httpconn->servconn = servconn; - /* First, some tests to see if we have a full block of stuff. */ - if (((strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) != 0) && - (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) != 0)) && - ((strncmp(buf, "HTTP/1.0 200 OK\r\n", 17) != 0) && - (strncmp(buf, "HTTP/1.0 100 Continue\r\n", 23) != 0))) - { - *error = TRUE; + httpconn->tx_buf = gaim_circ_buffer_new(MSN_BUF_LEN); + httpconn->tx_handler = 0; - return FALSE; - } + return httpconn; +} - if (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) == 0) - { - if ((s = strstr(buf, "\r\n\r\n")) == NULL) - return FALSE; +void +msn_httpconn_destroy(MsnHttpConn *httpconn) +{ + g_return_if_fail(httpconn != NULL); - s += 4; + gaim_debug_info("msn", "destroy httpconn (%p)\n", httpconn); - if (*s == '\0') - { - *ret_buf = g_strdup(""); - *ret_size = 0; + if (httpconn->connected) + msn_httpconn_disconnect(httpconn); - if (httpconn->tx_handler > 0) - httpconn_write_cb(httpconn, httpconn->fd, - GAIM_INPUT_WRITE); - else - httpconn->dirty = TRUE; + g_free(httpconn->full_session_id); - return TRUE; - } + g_free(httpconn->session_id); - buf = s; - size -= (s - buf); - } + g_free(httpconn->host); - if ((s = strstr(buf, "\r\n\r\n")) == NULL) - return FALSE; + gaim_circ_buffer_destroy(httpconn->tx_buf); + if (httpconn->tx_handler > 0) + gaim_input_remove(httpconn->tx_handler); - s += 4; /* Skip \r\n */ - header = g_strndup(buf, s - buf); - body_start = s; - body_len = size - (body_start - buf); + g_free(httpconn); +} - if ((s = gaim_strcasestr(header, "Content-Length: ")) != NULL) +static void +connect_cb(gpointer data, gint source, GaimInputCondition cond) +{ + MsnHttpConn *httpconn = data; + + /* + TODO: Need to do this in case the account is disabled while connecting + if (!g_list_find(gaim_connections_get_all(), gc)) { - int tmp_len; + if (source >= 0) + close(source); + destroy_new_conn_data(new_conn_data); + return; + } + */ - s += strlen("Content-Length: "); + httpconn->fd = source; - if ((c = strchr(s, '\r')) == NULL) - { - g_free(header); + if (source >= 0) + { + httpconn->inpa = gaim_input_add(httpconn->fd, GAIM_INPUT_READ, + read_cb, data); - return FALSE; - } + httpconn->timer = gaim_timeout_add(2000, msn_httpconn_poll, httpconn); - tmp = g_strndup(s, c - s); - tmp_len = atoi(tmp); - g_free(tmp); - - if (body_len != tmp_len) - { - g_free(header); - -#if 0 - gaim_debug_warning("msn", - "body length (%d) != content length (%d)\n", - body_len, tmp_len); -#endif - - return FALSE; - } + msn_httpconn_process_queue(httpconn); } - - body = g_malloc0(body_len + 1); - memcpy(body, body_start, body_len); - -#ifdef MSN_DEBUG_HTTP - gaim_debug_misc("msn", "Incoming HTTP buffer (header): {%s\r\n}\n", - header); -#endif - - /* Now we should be able to process the data. */ - if ((s = gaim_strcasestr(header, "X-MSN-Messenger: ")) != NULL) + else { - char *full_session_id, *gw_ip, *session_action; - char *t, *session_id; - char **elems, **cur, **tokens; + gaim_debug_error("msn", "HTTP: Connection error\n"); + msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_CONNECT); + } +} - full_session_id = gw_ip = session_action = NULL; +gboolean +msn_httpconn_connect(MsnHttpConn *httpconn, const char *host, int port) +{ + int r; - s += strlen("X-MSN-Messenger: "); + g_return_val_if_fail(httpconn != NULL, FALSE); + g_return_val_if_fail(host != NULL, FALSE); + g_return_val_if_fail(port > 0, FALSE); - if ((c = strchr(s, '\r')) == NULL) - { - msn_session_set_error(httpconn->session, - MSN_ERROR_HTTP_MALFORMED, NULL); - gaim_debug_error("msn", "Malformed X-MSN-Messenger field.\n{%s}", - buf); + if (httpconn->connected) + msn_httpconn_disconnect(httpconn); - g_free(body); - return FALSE; - } + r = gaim_proxy_connect(httpconn->session->account, + "gateway.messenger.hotmail.com", 80, connect_cb, httpconn); - tmp = g_strndup(s, c - s); + if (r == 0) + { + httpconn->waiting_response = TRUE; + httpconn->connected = TRUE; + } - elems = g_strsplit(tmp, "; ", 0); + return httpconn->connected; +} - for (cur = elems; *cur != NULL; cur++) - { - tokens = g_strsplit(*cur, "=", 2); +void +msn_httpconn_disconnect(MsnHttpConn *httpconn) +{ + g_return_if_fail(httpconn != NULL); - if (strcmp(tokens[0], "SessionID") == 0) - full_session_id = tokens[1]; - else if (strcmp(tokens[0], "GW-IP") == 0) - gw_ip = tokens[1]; - else if (strcmp(tokens[0], "Session") == 0) - session_action = tokens[1]; + if (!httpconn->connected) + return; - g_free(tokens[0]); - /* Don't free each of the tokens, only the array. */ - g_free(tokens); - } + if (httpconn->timer) + gaim_timeout_remove(httpconn->timer); - g_strfreev(elems); + httpconn->timer = 0; - g_free(tmp); - - if ((session_action != NULL) && (strcmp(session_action, "close") == 0)) - wasted = TRUE; - - g_free(session_action); - - t = strchr(full_session_id, '.'); - session_id = g_strndup(full_session_id, t - full_session_id); - - if (!wasted) - { - g_free(httpconn->full_session_id); - - httpconn->full_session_id = full_session_id; - - g_free(httpconn->session_id); - - httpconn->session_id = session_id; - - g_free(httpconn->host); - - httpconn->host = gw_ip; - } - else - { - MsnServConn *servconn; - - /* It's going to die. */ - /* poor thing */ - - servconn = httpconn->servconn; - - /* I'll be honest, I don't fully understand all this, but this - * causes crashes, Stu. */ - /* if (servconn != NULL) - servconn->wasted = TRUE; */ - - g_free(full_session_id); - g_free(session_id); - g_free(gw_ip); - } + if (httpconn->inpa > 0) + { + gaim_input_remove(httpconn->inpa); + httpconn->inpa = 0; } - g_free(header); + close(httpconn->fd); - *ret_buf = body; - *ret_size = body_len; + g_free(httpconn->rx_buf); + httpconn->rx_buf = NULL; + httpconn->rx_len = 0; - if (httpconn->tx_handler > 0) - httpconn_write_cb(httpconn, httpconn->fd, GAIM_INPUT_WRITE); - else - httpconn->dirty = TRUE; + httpconn->connected = FALSE; - return TRUE; + /* msn_servconn_disconnect(httpconn->servconn); */ } Modified: trunk/src/protocols/msn/httpconn.h =================================================================== --- trunk/src/protocols/msn/httpconn.h 2006-07-03 18:28:13 UTC (rev 16413) +++ trunk/src/protocols/msn/httpconn.h 2006-07-03 20:39:04 UTC (rev 16414) @@ -44,13 +44,13 @@ gboolean waiting_response; /**< The flag that states if we are waiting a response from the server. */ - gboolean dirty; /**< The flag that states if we should poll. */ gboolean connected; /**< The flag that states if the connection is on. */ gboolean virgin; /**< The flag that states if this connection should specify the host (not gateway) to connect to. */ char *host; /**< The HTTP gateway host. */ + GList *queue; /**< The queue of data chunks to write. */ int fd; /**< The connection's file descriptor. */ guint inpa; /**< The connection's input handler. */ @@ -83,11 +83,11 @@ * * @param servconn The server connection. * @param data The data to write. - * @param size The size of the data to write. + * @param data_len The size of the data to write. * * @return The number of bytes written. */ -ssize_t msn_httpconn_write(MsnHttpConn *httpconn, const char *data, size_t size); +ssize_t msn_httpconn_write(MsnHttpConn *httpconn, const char *data, size_t data_len); /** * Connects the HTTP connection object to a host. Modified: trunk/src/protocols/msn/msn.c =================================================================== --- trunk/src/protocols/msn/msn.c 2006-07-03 18:28:13 UTC (rev 16413) +++ trunk/src/protocols/msn/msn.c 2006-07-03 20:39:04 UTC (rev 16414) @@ -731,8 +731,7 @@ return; } - if (gaim_account_get_bool(account, "http_method", FALSE)) - http_method = TRUE; + http_method = gaim_account_get_bool(account, "http_method", FALSE); host = gaim_account_get_string(account, "server", MSN_SERVER); port = gaim_account_get_int(account, "port", MSN_PORT); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ev...@us...> - 2006-07-03 18:28:18
|
Revision: 16413 Author: evands Date: 2006-07-03 11:28:13 -0700 (Mon, 03 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16413&view=rev Log Message: ----------- As discussed on gaim-devel, use _exit() rather than exit() when exiting the dns resolver forked process. This matches the call used in gaim's own proxy.c and prevents a (fairly ridiculous) crash in the atexit() handler installed by Apple's Address Book framework on OS X. Modified Paths: -------------- trunk/src/protocols/gg/lib/libgadu.c Modified: trunk/src/protocols/gg/lib/libgadu.c =================================================================== --- trunk/src/protocols/gg/lib/libgadu.c 2006-07-03 17:07:03 UTC (rev 16412) +++ trunk/src/protocols/gg/lib/libgadu.c 2006-07-03 18:28:13 UTC (rev 16413) @@ -357,7 +357,7 @@ write(pipes[1], &a, sizeof(a)); - exit(0); + _exit(0); } close(pipes[1]); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aar...@us...> - 2006-07-03 17:07:41
|
Revision: 16412 Author: aaronsheldon Date: 2006-07-03 10:07:03 -0700 (Mon, 03 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16412&view=rev Log Message: ----------- Merges r16370:16411 from trunk. Also includes very hackish-but-working in transition conversation.* and gtkconv.* code. It works much faster, but the code still needs a lot of organizing and cleaning. Modified Paths: -------------- branches/soc-2006-chat-speed/COPYRIGHT branches/soc-2006-chat-speed/console/Makefile branches/soc-2006-chat-speed/console/gntblist.c branches/soc-2006-chat-speed/console/gntblist.h branches/soc-2006-chat-speed/console/gntconv.c branches/soc-2006-chat-speed/console/gntconv.h branches/soc-2006-chat-speed/console/gntgaim.c branches/soc-2006-chat-speed/console/gntui.c branches/soc-2006-chat-speed/console/libgnt/gnt.h branches/soc-2006-chat-speed/console/libgnt/gntbox.c branches/soc-2006-chat-speed/console/libgnt/gntbox.h branches/soc-2006-chat-speed/console/libgnt/gntbutton.c branches/soc-2006-chat-speed/console/libgnt/gntcolors.c branches/soc-2006-chat-speed/console/libgnt/gntcolors.h branches/soc-2006-chat-speed/console/libgnt/gntentry.c branches/soc-2006-chat-speed/console/libgnt/gntkeys.h branches/soc-2006-chat-speed/console/libgnt/gntmain.c branches/soc-2006-chat-speed/console/libgnt/gnttextview.c branches/soc-2006-chat-speed/console/libgnt/gnttextview.h branches/soc-2006-chat-speed/console/libgnt/gnttree.c branches/soc-2006-chat-speed/console/libgnt/gnttree.h branches/soc-2006-chat-speed/console/libgnt/gntwidget.c branches/soc-2006-chat-speed/console/libgnt/gntwidget.h branches/soc-2006-chat-speed/console/libgnt/test/focus.c branches/soc-2006-chat-speed/console/libgnt/test/multiwin.c branches/soc-2006-chat-speed/console/libgnt/test/tv.c branches/soc-2006-chat-speed/doc/C-HOWTO.dox branches/soc-2006-chat-speed/src/blist.h branches/soc-2006-chat-speed/src/conversation.c branches/soc-2006-chat-speed/src/conversation.h branches/soc-2006-chat-speed/src/dnssrv.c branches/soc-2006-chat-speed/src/gtkconv.c branches/soc-2006-chat-speed/src/gtkconv.h branches/soc-2006-chat-speed/src/protocols/bonjour/bonjour.c branches/soc-2006-chat-speed/src/protocols/bonjour/bonjour.h branches/soc-2006-chat-speed/src/protocols/bonjour/buddy.c branches/soc-2006-chat-speed/src/protocols/bonjour/dns_sd.c branches/soc-2006-chat-speed/src/protocols/bonjour/dns_sd.h branches/soc-2006-chat-speed/src/protocols/bonjour/jabber.c branches/soc-2006-chat-speed/src/protocols/bonjour/jabber.h branches/soc-2006-chat-speed/src/protocols/irc/cmds.c branches/soc-2006-chat-speed/src/protocols/jabber/jabber.c branches/soc-2006-chat-speed/src/protocols/jabber/presence.c branches/soc-2006-chat-speed/src/protocols/msn/dialog.c branches/soc-2006-chat-speed/src/protocols/msn/session.c branches/soc-2006-chat-speed/src/protocols/oscar/family_feedbag.c branches/soc-2006-chat-speed/src/protocols/oscar/family_oservice.c branches/soc-2006-chat-speed/src/protocols/oscar/oscar.c branches/soc-2006-chat-speed/src/protocols/oscar/oscar.h branches/soc-2006-chat-speed/src/protocols/qq/Makefile.am branches/soc-2006-chat-speed/src/protocols/silc/silc.c Added Paths: ----------- branches/soc-2006-chat-speed/console/gntaccount.c branches/soc-2006-chat-speed/console/gntaccount.h branches/soc-2006-chat-speed/console/libgnt/AUTHORS branches/soc-2006-chat-speed/console/libgnt/COPYING branches/soc-2006-chat-speed/console/libgnt/ChangeLog branches/soc-2006-chat-speed/console/libgnt/INSTALL branches/soc-2006-chat-speed/console/libgnt/Makefile.am branches/soc-2006-chat-speed/console/libgnt/NEWS branches/soc-2006-chat-speed/console/libgnt/README branches/soc-2006-chat-speed/console/libgnt/autogen.sh branches/soc-2006-chat-speed/console/libgnt/configure.ac branches/soc-2006-chat-speed/console/libgnt/gnt.pc.in Removed Paths: ------------- branches/soc-2006-chat-speed/console/libgnt/Makefile Modified: branches/soc-2006-chat-speed/COPYRIGHT =================================================================== --- branches/soc-2006-chat-speed/COPYRIGHT 2006-07-03 05:37:41 UTC (rev 16411) +++ branches/soc-2006-chat-speed/COPYRIGHT 2006-07-03 17:07:03 UTC (rev 16412) @@ -59,6 +59,7 @@ Eoin Coffey Jason Cohen Todd Cohen +Jono Cole Nathan Conrad Felipe Contreras Alex Converse @@ -302,6 +303,7 @@ Wan Hing Wah Philip Walford Nathan Walp +Jonty Wareing Eric Warmenhoven Adam J. Warrington Andrew Wellington Modified: branches/soc-2006-chat-speed/console/Makefile =================================================================== --- branches/soc-2006-chat-speed/console/Makefile 2006-07-03 05:37:41 UTC (rev 16411) +++ branches/soc-2006-chat-speed/console/Makefile 2006-07-03 17:07:03 UTC (rev 16412) @@ -1,35 +1,37 @@ +VERSION=gntgaim-0.0.0dev CC=gcc -CFLAGS=`pkg-config --cflags gaim gobject-2.0` -g -I./libgnt/ -Wall -LDFLAGS=`pkg-config --libs gaim gobject-2.0 libxml-2.0` -lncursesw -L./libgnt/ -lgnt -pg +CFLAGS=`pkg-config --cflags gaim gobject-2.0 gnt` -g -Wall -DVERSION=\"$(VERSION)\" +LDFLAGS=`pkg-config --libs gaim gobject-2.0 libxml-2.0 gnt` -pg GG_SOURCES = \ + gntaccount.c \ gntblist.c \ gntconv.c \ gntui.c GG_HEADERS = \ + gntaccount.h \ gntblist.h \ gntconv.h \ gntui.h GG_OBJECTS = \ + gntaccount.o \ gntblist.o \ gntconv.o \ gntui.o -all: - cd libgnt && make - make gntgaim +all: gntgaim gntgaim: gntgaim.o $(GG_OBJECTS) $(CC) -o gntgaim gntgaim.o $(GG_OBJECTS) $(LDFLAGS) +gntaccount.o: gntaccount.c $(GG_HEADERS) gntblist.o: gntblist.c $(GG_HEADERS) gntconv.o: gntconv.c $(GG_HEADERS) gntgaim.o: gntgaim.c gntgaim.h $(GG_HEADERS) gntui.o: gntui.c $(GG_HEADERS) clean: - cd libgnt && make clean rm -f *.o rm -f gntgaim Copied: branches/soc-2006-chat-speed/console/gntaccount.c (from rev 16411, trunk/console/gntaccount.c) =================================================================== --- branches/soc-2006-chat-speed/console/gntaccount.c (rev 0) +++ branches/soc-2006-chat-speed/console/gntaccount.c 2006-07-03 17:07:03 UTC (rev 16412) @@ -0,0 +1,180 @@ +#include <gnt.h> +#include <gntbox.h> +#include <gntbutton.h> +#include <gntlabel.h> +#include <gnttree.h> + +#include <connection.h> +#include <notify.h> +#include <request.h> + +#include "gntaccount.h" +#include "gntgaim.h" + +typedef struct +{ + GntWidget *window; + GntWidget *tree; +} GGAccountList; + +static GGAccountList accounts; + +static void +account_toggled(GntWidget *widget, void *key, gpointer null) +{ + GaimAccount *account = key; + + gaim_account_set_enabled(account, GAIM_GNT_UI, gnt_tree_get_choice(GNT_TREE(widget), key)); +} + +void gg_accounts_init() +{ + GList *iter; + GntWidget *box, *button; + + accounts.window = gnt_box_new(TRUE, TRUE); + gnt_box_set_toplevel(GNT_BOX(accounts.window), TRUE); + gnt_box_set_title(GNT_BOX(accounts.window), _("Accounts")); + gnt_widget_set_name(accounts.window, "accounts"); + + gnt_box_add_widget(GNT_BOX(accounts.window), + gnt_label_new(_("You can enable/disable accounts from the follwing list."))); + + accounts.tree = gnt_tree_new(); + GNT_WIDGET_SET_FLAGS(accounts.tree, GNT_WIDGET_NO_BORDER); + + for (iter = gaim_accounts_get_all(); iter; iter = iter->next) + { + GaimAccount *account = iter->data; + char *str = g_strdup_printf("%s (%s)", + gaim_account_get_username(account), gaim_account_get_protocol_id(account)); + + gnt_tree_add_choice(GNT_TREE(accounts.tree), account, + str, NULL, NULL); + gnt_tree_set_choice(GNT_TREE(accounts.tree), account, + gaim_account_get_enabled(account, GAIM_GNT_UI)); + g_free(str); + } + + g_signal_connect(G_OBJECT(accounts.tree), "toggled", G_CALLBACK(account_toggled), NULL); + + gnt_widget_set_size(accounts.tree, 40, 15); + gnt_box_add_widget(GNT_BOX(accounts.window), accounts.tree); + + box = gnt_box_new(FALSE, FALSE); + + button = gnt_button_new(_("Add")); + gnt_box_add_widget(GNT_BOX(box), button); + + button = gnt_button_new(_("Modify")); + gnt_box_add_widget(GNT_BOX(box), button); + + button = gnt_button_new(_("Delete")); + gnt_box_add_widget(GNT_BOX(box), button); + + gnt_box_add_widget(GNT_BOX(accounts.window), box); + + gnt_widget_show(accounts.window); +} + +void gg_accounts_uninit() +{ + gnt_widget_destroy(accounts.window); +} + +#if 0 +/* The following uiops stuff are copied from gtkaccount.c */ +/* Need to do some work on notify- and request-ui before this works */ +typedef struct +{ + GaimAccount *account; + char *username; + char *alias; +} AddUserData; + +static char * +make_info(GaimAccount *account, GaimConnection *gc, const char *remote_user, + const char *id, const char *alias, const char *msg) +{ + if (msg != NULL && *msg == '\0') + msg = NULL; + + return g_strdup_printf(_("%s%s%s%s has made %s his or her buddy%s%s"), + remote_user, + (alias != NULL ? " (" : ""), + (alias != NULL ? alias : ""), + (alias != NULL ? ")" : ""), + (id != NULL + ? id + : (gaim_connection_get_display_name(gc) != NULL + ? gaim_connection_get_display_name(gc) + : gaim_account_get_username(account))), + (msg != NULL ? ": " : "."), + (msg != NULL ? msg : "")); +} + +static void +notify_added(GaimAccount *account, const char *remote_user, + const char *id, const char *alias, + const char *msg) +{ + char *buffer; + GaimConnection *gc; + + gc = gaim_account_get_connection(account); + + buffer = make_info(account, gc, remote_user, id, alias, msg); + + gaim_notify_info(NULL, NULL, buffer, NULL); + + g_free(buffer); +} + +static void +request_add(GaimAccount *account, const char *remote_user, + const char *id, const char *alias, + const char *msg) +{ + char *buffer; + GaimConnection *gc; + AddUserData *data; + + gc = gaim_account_get_connection(account); + + data = g_new0(AddUserData, 1); + data->account = account; + data->username = g_strdup(remote_user); + data->alias = (alias != NULL ? g_strdup(alias) : NULL); + + buffer = make_info(account, gc, remote_user, id, alias, msg); +#if 0 + gaim_request_action(NULL, NULL, _("Add buddy to your list?"), + buffer, GAIM_DEFAULT_ACTION_NONE, data, 2, + _("Add"), G_CALLBACK(add_user_cb), + _("Cancel"), G_CALLBACK(free_add_user_data)); +#endif + g_free(buffer); +} + +static GaimAccountUiOps ui_ops = +{ + .notify_added = notify_added, + .status_changed = NULL, + .request_add = request_add +}; +#else + +static GaimAccountUiOps ui_ops = +{ + .notify_added = NULL, + .status_changed = NULL, + .request_add = NULL +}; + +#endif + +GaimAccountUiOps *gg_accounts_get_ui_ops() +{ + return &ui_ops; +} + Copied: branches/soc-2006-chat-speed/console/gntaccount.h (from rev 16411, trunk/console/gntaccount.h) =================================================================== --- branches/soc-2006-chat-speed/console/gntaccount.h (rev 0) +++ branches/soc-2006-chat-speed/console/gntaccount.h 2006-07-03 17:07:03 UTC (rev 16412) @@ -0,0 +1,7 @@ +#include "account.h" + +GaimAccountUiOps *gg_accounts_get_ui_ops(); + +void gg_accounts_init(); + +void gg_accounts_uninit(); Modified: branches/soc-2006-chat-speed/console/gntblist.c =================================================================== --- branches/soc-2006-chat-speed/console/gntblist.c 2006-07-03 05:37:41 UTC (rev 16411) +++ branches/soc-2006-chat-speed/console/gntblist.c 2006-07-03 17:07:03 UTC (rev 16412) @@ -6,6 +6,7 @@ #include "gntgaim.h" #include "gntbox.h" +#include "gntlabel.h" #include "gnttree.h" #include "gntblist.h" @@ -218,6 +219,7 @@ get_display_name(node), group, NULL); } +#if 0 static void buddy_signed_on(GaimBuddy *buddy, GGBlist *ggblist) { @@ -229,6 +231,7 @@ { node_remove(gaim_get_blist(), (GaimBlistNode*)buddy); } +#endif GaimBlistUiOps *gg_blist_get_ui_ops() { @@ -238,7 +241,21 @@ static void selection_activate(GntWidget *widget, GGBlist *ggblist) { - gnt_widget_set_focus(widget, FALSE); + GntTree *tree = GNT_TREE(ggblist->tree); + GaimBlistNode *node = gnt_tree_get_selection_data(tree); + + if (GAIM_BLIST_NODE_IS_BUDDY(node)) + { + GaimBuddy *buddy = (GaimBuddy *)node; + gaim_conversation_new(GAIM_CONV_TYPE_IM, + gaim_buddy_get_account(buddy), + gaim_buddy_get_name(buddy)); + } + else if (GAIM_BLIST_NODE_IS_CHAT(node)) + { + GaimChat *chat = (GaimChat*)node; + serv_join_chat(chat->account->gc, chat->components); + } } static void @@ -251,12 +268,15 @@ GaimPluginProtocolInfo *prpl_info; GaimAccount *account; GntTree *tree; - GntWidget *widget, *box, *label; + GntWidget *widget, *box; char *title = NULL; widget = ggblist->tree; tree = GNT_TREE(widget); + if (!gnt_widget_has_focus(ggblist->tree)) + return; + if (ggblist->tooltip) { /* XXX: Once we can properly redraw on expose events, this can be removed at the end @@ -332,7 +352,7 @@ GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_NO_SHADOW); gnt_box_set_title(GNT_BOX(box), title); - gnt_box_add_widget(GNT_BOX(box), GNT_WIDGET(gnt_label_new(str->str))); + gnt_box_add_widget(GNT_BOX(box), gnt_label_new(str->str)); gnt_widget_set_position(box, x, y); gnt_widget_draw(box); @@ -365,25 +385,7 @@ return TRUE; } } - else if (text[0] == '\r' && text[1] == '\0') - { - GntTree *tree = GNT_TREE(ggblist->tree); - GaimBlistNode *node = gnt_tree_get_selection_data(tree); - if (GAIM_BLIST_NODE_IS_BUDDY(node)) - { - GaimBuddy *buddy = (GaimBuddy *)node; - gaim_conversation_new(GAIM_CONV_TYPE_IM, - gaim_buddy_get_account(buddy), - gaim_buddy_get_name(buddy)); - } - else if (GAIM_BLIST_NODE_IS_CHAT(node)) - { - GaimChat *chat = (GaimChat*)node; - serv_join_chat(chat->account->gc, chat->components); - } - } - return FALSE; } @@ -409,7 +411,7 @@ ggblist->tree = gnt_tree_new(); GNT_WIDGET_SET_FLAGS(ggblist->tree, GNT_WIDGET_NO_BORDER); - gnt_widget_set_size(ggblist->tree, 25, getmaxy(stdscr) - 2); + gnt_widget_set_size(ggblist->tree, 25, getmaxy(stdscr) - 3); gnt_box_add_widget(GNT_BOX(ggblist->window), ggblist->tree); gnt_widget_show(ggblist->window); @@ -438,3 +440,11 @@ g_signal_connect(G_OBJECT(ggblist->tree), "activate", G_CALLBACK(selection_activate), ggblist); } +void gg_blist_uninit() +{ + gnt_widget_destroy(ggblist->window); + g_free(ggblist); + ggblist = NULL; +} + + Modified: branches/soc-2006-chat-speed/console/gntblist.h =================================================================== --- branches/soc-2006-chat-speed/console/gntblist.h 2006-07-03 05:37:41 UTC (rev 16411) +++ branches/soc-2006-chat-speed/console/gntblist.h 2006-07-03 17:07:03 UTC (rev 16412) @@ -3,3 +3,5 @@ GaimBlistUiOps * gg_blist_get_ui_ops(); void gg_blist_init(); + +void gg_blist_uninit(); Modified: branches/soc-2006-chat-speed/console/gntconv.c =================================================================== --- branches/soc-2006-chat-speed/console/gntconv.c 2006-07-03 05:37:41 UTC (rev 16411) +++ branches/soc-2006-chat-speed/console/gntconv.c 2006-07-03 17:07:03 UTC (rev 16412) @@ -1,3 +1,4 @@ +#include <string.h> #include <util.h> #include "gntgaim.h" @@ -59,6 +60,20 @@ gnt_entry_clear(GNT_ENTRY(ggconv->entry)); return TRUE; } + else if (key[0] == 27) + { + if (strcmp(key+1, GNT_KEY_DOWN) == 0) + gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), 1); + else if (strcmp(key+1, GNT_KEY_UP) == 0) + gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), -1); + else if (strcmp(key+1, GNT_KEY_PGDOWN) == 0) + gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), ggconv->tv->priv.height - 2); + else if (strcmp(key+1, GNT_KEY_PGUP) == 0) + gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), -(ggconv->tv->priv.height - 2)); + else + return FALSE; + return TRUE; + } return FALSE; } @@ -86,11 +101,11 @@ ggc->conv = conv; type = gaim_conversation_get_type(conv); - title = g_strdup_printf(_("Conversation: %s"), gaim_conversation_get_name(conv)); + title = g_strdup_printf(_("%s"), gaim_conversation_get_name(conv)); ggc->window = gnt_box_new(FALSE, TRUE); gnt_box_set_title(GNT_BOX(ggc->window), title); gnt_box_set_toplevel(GNT_BOX(ggc->window), TRUE); - gnt_widget_set_name(ggc->window, "conversation-window"); + gnt_widget_set_name(ggc->window, title); ggc->tv = gnt_text_view_new(); gnt_box_add_widget(GNT_BOX(ggc->window), ggc->tv); @@ -118,38 +133,53 @@ } static void -gg_write_chat(GaimConversation *conv, const char *who, const char *message, +gg_write_common(GaimConversation *conv, const char *who, const char *message, GaimMessageFlags flags, time_t mtime) { GGConv *ggconv = g_hash_table_lookup(ggconvs, conv); - char *name, *strip; + char *strip; + GntTextViewFlags fl = 0; g_return_if_fail(ggconv != NULL); - name = g_strdup_printf("%s: ", who); + if (who && *who && (flags & (GAIM_MESSAGE_SEND | GAIM_MESSAGE_RECV))) + { + char * name = g_strdup_printf("%s: ", who); + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), + name, GNT_TEXT_FLAG_BOLD); + g_free(name); + } + else + fl = GNT_TEXT_FLAG_DIM; + + if (flags & GAIM_MESSAGE_ERROR) + fl |= GNT_TEXT_FLAG_BOLD; + if (flags & GAIM_MESSAGE_NICK) + fl |= GNT_TEXT_FLAG_UNDERLINE; + strip = gaim_markup_strip_html(message); - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), - name, GNT_TEXT_FLAG_BOLD); - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), - strip, (flags & GAIM_MESSAGE_NICK) ? GNT_TEXT_FLAG_UNDERLINE : 0); + strip, fl); gnt_text_view_next_line(GNT_TEXT_VIEW(ggconv->tv)); gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), 0); - g_free(name); g_free(strip); + + if (flags & (GAIM_MESSAGE_RECV | GAIM_MESSAGE_NICK | GAIM_MESSAGE_ERROR)) + gnt_widget_set_urgent(ggconv->tv); } static void +gg_write_chat(GaimConversation *conv, const char *who, const char *message, + GaimMessageFlags flags, time_t mtime) +{ + gg_write_common(conv, who, message, flags, mtime); +} + +static void gg_write_im(GaimConversation *conv, const char *who, const char *message, GaimMessageFlags flags, time_t mtime) { - GGConv *ggconv = g_hash_table_lookup(ggconvs, conv); - char *strip; - char *name; - - g_return_if_fail(ggconv != NULL); - if (flags & GAIM_MESSAGE_SEND) { who = gaim_connection_get_display_name(conv->account->gc); @@ -161,50 +191,22 @@ else if (flags & GAIM_MESSAGE_RECV) who = gaim_conversation_get_name(conv); - name = g_strdup_printf("%s: ", who); - - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), - name, GNT_TEXT_FLAG_BOLD); - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), - (strip = gaim_markup_strip_html(message)), 0); - gnt_text_view_next_line(GNT_TEXT_VIEW(ggconv->tv)); - gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), 0); - - g_free(strip); - g_free(name); + gg_write_common(conv, who, message, flags, mtime); } static void gg_write_conv(GaimConversation *conv, const char *who, const char *alias, const char *message, GaimMessageFlags flags, time_t mtime) { - GGConv *ggconv = g_hash_table_lookup(ggconvs, conv); - char *strip; + const char *name; + if (alias && *alias) + name = alias; + else if (who && *who) + name = who; + else + name = NULL; - g_return_if_fail(ggconv != NULL); - - strip = gaim_markup_strip_html(message); - - if (flags & (GAIM_MESSAGE_SEND | GAIM_MESSAGE_RECV)) - { - char *name; - if (alias && *alias) - name = g_strdup_printf("%s: ", alias); - else if (who && *who) - name = g_strdup_printf("%s: ", who); - else - name = g_strdup(""); - - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), - name, GNT_TEXT_FLAG_BOLD); - g_free(name); - } - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), - strip, 0); - gnt_text_view_next_line(GNT_TEXT_VIEW(ggconv->tv)); - gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), 0); - - g_free(strip); + gg_write_common(conv, name, message, flags, mtime); } static void @@ -260,3 +262,9 @@ ggconvs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_ggconv); } +void gg_conversation_uninit() +{ + g_hash_table_destroy(ggconvs); + ggconvs = NULL; +} + Modified: branches/soc-2006-chat-speed/console/gntconv.h =================================================================== --- branches/soc-2006-chat-speed/console/gntconv.h 2006-07-03 05:37:41 UTC (rev 16411) +++ branches/soc-2006-chat-speed/console/gntconv.h 2006-07-03 17:07:03 UTC (rev 16412) @@ -3,3 +3,5 @@ GaimConversationUiOps *gg_conv_get_ui_ops(); void gg_conversation_init(); + +void gg_conversation_uninit(); Modified: branches/soc-2006-chat-speed/console/gntgaim.c =================================================================== --- branches/soc-2006-chat-speed/console/gntgaim.c 2006-07-03 05:37:41 UTC (rev 16411) +++ branches/soc-2006-chat-speed/console/gntgaim.c 2006-07-03 17:07:03 UTC (rev 16412) @@ -16,7 +16,11 @@ #include "whiteboard.h" #include "gntgaim.h" +#include "gntui.h" +#define _GNU_SOURCE +#include <getopt.h> + /* Anything IO-related is directly copied from gtkgaim's source tree */ static GaimCoreUiOps core_ops = @@ -102,12 +106,6 @@ closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, gaim_gtk_io_invoke, closure, gaim_gtk_io_destroy); -#if 0 - gaim_debug(GAIM_DEBUG_MISC, "gtk_eventloop", - "CLOSURE: adding input watcher %d for fd %d\n", - closure->result, fd); -#endif - g_io_channel_unref(channel); return closure->result; } @@ -128,25 +126,124 @@ /* This is mostly copied from gtkgaim's source tree */ static void -init_libgaim() +show_usage(const char *name, gboolean terse) { + char *text; + + if (terse) { + text = g_strdup_printf(_("Gaim %s. Try `%s -h' for more information.\n"), VERSION, name); + } else { + text = g_strdup_printf(_("Gaim %s\n" + "Usage: %s [OPTION]...\n\n" + " -c, --config=DIR use DIR for config files\n" + " -d, --debug print debugging messages to stdout\n" + " -h, --help display this help and exit\n" + " -n, --nologin don't automatically login\n" + " -v, --version display the current version and exit\n"), VERSION, name); + } + + gaim_print_utf8_to_console(stdout, text); + g_free(text); +} + +static int +init_libgaim(int argc, char **argv) +{ char *path; + int opt; + gboolean opt_help = FALSE; + gboolean opt_nologin = FALSE; + gboolean opt_version = FALSE; + char *opt_config_dir_arg = NULL; + char *opt_session_arg = NULL; + gboolean debug_enabled; + struct option long_options[] = { + {"config", required_argument, NULL, 'c'}, + {"debug", no_argument, NULL, 'd'}, + {"help", no_argument, NULL, 'h'}, + {"nologin", no_argument, NULL, 'n'}, + {"session", required_argument, NULL, 's'}, + {"version", no_argument, NULL, 'v'}, + {0, 0, 0, 0} + }; + + /* scan command-line options */ + opterr = 1; + while ((opt = getopt_long(argc, argv, +#ifndef _WIN32 + "c:dhn::s:v", +#else + "c:dhn::v", +#endif + long_options, NULL)) != -1) { + switch (opt) { + case 'c': /* config dir */ + g_free(opt_config_dir_arg); + opt_config_dir_arg = g_strdup(optarg); + break; + case 'd': /* debug */ + debug_enabled = TRUE; + break; + case 'h': /* help */ + opt_help = TRUE; + break; + case 'n': /* no autologin */ + opt_nologin = TRUE; + break; + case 's': /* use existing session ID */ + g_free(opt_session_arg); + opt_session_arg = g_strdup(optarg); + break; + case 'v': /* version */ + opt_version = TRUE; + break; + case '?': /* show terse help */ + default: + show_usage(argv[0], TRUE); + return 0; + break; + } + } + + /* show help message */ + if (opt_help) { + show_usage(argv[0], FALSE); + return 0; + } + /* show version message */ + if (opt_version) { + printf("Gaim %s\n", VERSION); + return 0; + } + + /* set a user-specified config directory */ + if (opt_config_dir_arg != NULL) { + gaim_util_set_user_dir(opt_config_dir_arg); + } + + /* + * We're done piddling around with command line arguments. + * Fire up this baby. + */ + + /* Because we don't want debug-messages to show up and corrup the display */ gaim_debug_set_enabled(FALSE); gaim_core_set_ui_ops(gnt_core_get_ui_ops()); gaim_eventloop_set_ui_ops(gnt_eventloop_get_ui_ops()); - gaim_util_set_user_dir("/tmp/tmp/"); /* XXX: */ - path = g_build_filename(gaim_user_dir(), "plugins", NULL); gaim_plugins_add_search_path(path); g_free(path); + gaim_plugins_add_search_path("/usr/local/lib/gaim"); /* XXX: */ if (!gaim_core_init(GAIM_GNT_UI)) { - fprintf(stderr, "OOPSSS!!\n"); + fprintf(stderr, + "Initialization of the Gaim core failed. Dumping core.\n" + "Please report this!\n"); abort(); } @@ -159,11 +256,36 @@ gaim_prefs_update_old(); /* load plugins we had when we quit */ - gaim_plugins_load_saved("/gaim/gtk/plugins/loaded"); + gaim_plugins_load_saved("/gaim/gnt/plugins/loaded"); /* TODO: Move pounces loading into gaim_pounces_init() */ gaim_pounces_load(); + if (opt_nologin) + { + /* Set all accounts to "offline" */ + GaimSavedStatus *saved_status; + + /* If we've used this type+message before, lookup the transient status */ + saved_status = gaim_savedstatus_find_transient_by_type_and_message( + GAIM_STATUS_OFFLINE, NULL); + + /* If this type+message is unique then create a new transient saved status */ + if (saved_status == NULL) + saved_status = gaim_savedstatus_new(NULL, GAIM_STATUS_OFFLINE); + + /* Set the status for each account */ + gaim_savedstatus_activate(saved_status); + } + else + { + /* Everything is good to go--sign on already */ + if (!gaim_prefs_get_bool("/core/savedstatus/startup_current_status")) + gaim_savedstatus_activate(gaim_savedstatus_get_startup()); + gaim_accounts_restore_current_statuses(); + } + + return 1; } int main(int argc, char **argv) @@ -172,12 +294,10 @@ freopen(".error", "w", stderr); /* Initialize the libgaim stuff */ - init_libgaim(); + if (!init_libgaim(argc, argv)) + return 0; - /* Enable the accounts and restore the status */ - gaim_accounts_restore_current_statuses(); - - /* Initialize the UI */ + /* Initialize and run the UI */ init_gnt_ui(); gaim_core_quit(); Modified: branches/soc-2006-chat-speed/console/gntui.c =================================================================== --- branches/soc-2006-chat-speed/console/gntui.c 2006-07-03 05:37:41 UTC (rev 16411) +++ branches/soc-2006-chat-speed/console/gntui.c 2006-07-03 17:07:03 UTC (rev 16412) @@ -1,4 +1,6 @@ #include "gntui.h" + +#include "gntaccount.h" #include "gntblist.h" #include "gntconv.h" @@ -6,9 +8,9 @@ { gnt_init(); - wbkgdset(stdscr, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); - werase(stdscr); - wrefresh(stdscr); + /* Accounts */ + gg_accounts_init(); + gaim_accounts_set_ui_ops(gg_accounts_get_ui_ops()); /* Initialize the buddy list */ gg_blist_init(); @@ -19,5 +21,16 @@ gaim_conversations_set_ui_ops(gg_conv_get_ui_ops()); gnt_main(); + + gaim_accounts_set_ui_ops(NULL); + gg_accounts_uninit(); + + gaim_blist_set_ui_ops(NULL); + gg_blist_uninit(); + + gaim_conversations_set_ui_ops(NULL); + gg_conversation_uninit(); + + gnt_quit(); } Copied: branches/soc-2006-chat-speed/console/libgnt/AUTHORS (from rev 16411, trunk/console/libgnt/AUTHORS) =================================================================== Copied: branches/soc-2006-chat-speed/console/libgnt/COPYING (from rev 16411, trunk/console/libgnt/COPYING) =================================================================== --- branches/soc-2006-chat-speed/console/libgnt/COPYING (rev 0) +++ branches/soc-2006-chat-speed/console/libgnt/COPYING 2006-07-03 17:07:03 UTC (rev 16412) @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. Copied: branches/soc-2006-chat-speed/console/libgnt/ChangeLog (from rev 16411, trunk/console/libgnt/ChangeLog) =================================================================== Copied: branches/soc-2006-chat-speed/console/libgnt/INSTALL (from rev 16411, trunk/console/libgnt/INSTALL) =================================================================== --- branches/soc-2006-chat-speed/console/libgnt/INSTALL (rev 0) +++ branches/soc-2006-chat-speed/console/libgnt/INSTALL 2006-07-03 17:07:03 UTC (rev 16412) @@ -0,0 +1,229 @@ +Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software +Foundation, Inc. + + This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the `--target=TYPE' option to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +will cause the specified gcc to be used as the C compiler (unless it is +overridden in the site shell script). + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + Deleted: branches/soc-2006-chat-speed/console/libgnt/Makefile =================================================================== --- branches/soc-2006-chat-speed/console/libgnt/Makefile 2006-07-03 05:37:41 UTC (rev 16411) +++ branches/soc-2006-chat-speed/console/libgnt/Makefile 2006-07-03 17:07:03 UTC (rev 16412) @@ -1,63 +0,0 @@ -CC=gcc -CFLAGS=`pkg-config --cflags gobject-2.0` -g -Wall -LDFLAGS=`pkg-config --libs gobject-2.0` -lncursesw -pg - -HEADERS = \ - gntwidget.h \ - gntbox.h \ - gntbutton.h \ - gntcolors.h \ - gntentry.h \ - gntlabel.h \ - gnttextview.h \ - gnttree.h \ - gntutils.h \ - gnt.h - -SOURCES = \ - gntwidget.c \ - gntbox.c \ - gntbutton.c \ - gntcolors.c \ - gntentry.c \ - gntlabel.c \ - gnttextview.c \ - gnttree.c \ - gntutils.c \ - gntmain.c - -OBJECTS = \ - gntwidget.o \ - gntbox.o \ - gntbutton.o \ - gntcolors.o \ - gntentry.o \ - gntlabel.o \ - gnttextview.o \ - gnttree.o \ - gntutils.o \ - gntmain.o - -all: libgnt - -test2: $(OBJECTS) -key: $(OBJECTS) - -gntwidget.o: gntwidget.c $(HEADERS) -gntbox.o: gntbox.c $(HEADERS) -gntbutton.o: gntbutton.c $(HEADERS) -gntcolors.o: gntcolors.c $(HEADERS) -gntentry.o: gntentry.c $(HEADERS) -gntlabel.o: gntlabel.c $(HEADERS) -gnttextview.o: gnttextview.c $(HEADERS) -gnttree.o: gnttree.c $(HEADERS) -gntutils.o: gntutils.c $(HEADERS) -gntmain.o: gntmain.c $(HEADERS) - -libgnt: $(OBJECTS) - $(CC) --shared -o libgnt.so $(OBJECTS) $(LDFLAGS) - -clean: - rm -f *.o - rm -f libgnt.so - Copied: branches/soc-2006-chat-speed/console/libgnt/Makefile.am (from rev 16411, trunk/console/libgnt/Makefile.am) =================================================================== --- branches/soc-2006-chat-speed/console/libgnt/Makefile.am (rev 0) +++ branches/soc-2006-chat-speed/console/libgnt/Makefile.am 2006-07-03 17:07:03 UTC (rev 16412) @@ -0,0 +1,43 @@ +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = gnt.pc + +lib_LTLIBRARIES = libgnt.la + +libgnt_la_SOURCES = \ + gntwidget.c \ + gntbox.c \ + gntbutton.c \ + gntcolors.c \ + gntentry.c \ + gntlabel.c \ + gnttextview.c \ + gnttree.c \ + gntutils.c \ + gntmain.c + +libgnt_la_headers = \ + gntwidget.h \ + gntbox.h \ + gntbutton.h \ + gntcolors.h \ + gntentry.h \ + gntkeys.h \ + gntlabel.h \ + gnttextview.h \ + gnttree.h \ + gntutils.h \ + gnt.h + +libgnt_laincludedir=$(includedir)/gnt +libgnt_lainclude_HEADERS = \ + $(libgnt_la_headers) + +libgnt_la_DEPENDENCIES = @LIBOBJS@ $(STATIC_LINK_LIBS) $(MS_LIBS) +libgnt_la_LDFLAGS = -export-dynamic +libgnt_la_LIBADD = \ + $(GLIB_LIBS) \ + $(STATIC_LINK_LIBS) \ + -lncursesw + +AM_CPPFLAGS = \ + $(GLIB_CFLAGS) Copied: branches/soc-2006-chat-speed/console/libgnt/NEWS (from rev 16411, trunk/console/libgnt/NEWS) =================================================================== Copied: branches/soc-2006-chat-speed/console/libgnt/README (from rev 16411, trunk/console/libgnt/README) =================================================================== Copied: branches/soc-2006-chat-speed/console/libgnt/autogen.sh (from rev 16411, trunk/console/libgnt/autogen.sh) =================================================================== --- branches/soc-2006-chat-speed/console/libgnt/autogen.sh (rev 0) +++ branches/soc-2006-chat-speed/console/libgnt/autogen.sh 2006-07-03 17:07:03 UTC (rev 16412) @@ -0,0 +1,48 @@ +#!/bin/sh + +(libtoolize --version) < /dev/null > /dev/null 2>&1 || { + echo; + echo "You must have libtool installed to compile LibGNT"; + echo; + exit; +} + +(automake --version) < /dev/null > /dev/null 2>&1 || { + echo; + echo "You must have automake installed to compile LibGNT"; + echo; + exit; +} + +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo; + echo "You must have autoconf installed to compile LibGNT"; + echo; + exit; +} + +echo "Generating configuration files for LibGNT, please wait...." +echo; + +echo "Running libtoolize, please ignore non-fatal messages...." +echo n | libtoolize --copy --force || exit; + +# Add other directories to this list if people continue to experience +# brokennesses ... Obviously the real answer is for them to fix... [truncated message content] |
From: <the...@us...> - 2006-07-03 05:37:45
|
Revision: 16411 Author: thekingant Date: 2006-07-02 22:37:41 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16411&view=rev Log Message: ----------- Fix the IRC crash-on-quit bug that I introduced two weeks ago. My bad. account->disconnecting seems weird to me... it seems like we should get rid of it and add a GAIM_DISCONNECTING state to GaimConnectionState, instead Modified Paths: -------------- trunk/src/protocols/irc/cmds.c Modified: trunk/src/protocols/irc/cmds.c =================================================================== --- trunk/src/protocols/irc/cmds.c 2006-07-03 02:27:41 UTC (rev 16410) +++ trunk/src/protocols/irc/cmds.c 2006-07-03 05:37:41 UTC (rev 16411) @@ -388,7 +388,8 @@ irc->quitting = TRUE; - gaim_account_set_status(irc->account, "offline", TRUE, NULL); + if (!irc->account->disconnecting) + gaim_account_set_status(irc->account, "offline", TRUE, NULL); } return 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sa...@us...> - 2006-07-03 02:27:47
|
Revision: 16410 Author: sadrul Date: 2006-07-02 19:27:41 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16410&view=rev Log Message: ----------- Change some colors for terminals that don't support customizing colors. Make taskbar behave properly when moving a window. Read startup options from command-line (copy-paste from gtkgaim [sic]). I am doing #define _GNU_SOURCE and #include <getopt.h> ... I don't know if that's alright. So now you can specify a location to read config files from. Modified Paths: -------------- trunk/console/Makefile trunk/console/gntgaim.c trunk/console/libgnt/gntcolors.c trunk/console/libgnt/gntmain.c Modified: trunk/console/Makefile =================================================================== --- trunk/console/Makefile 2006-07-03 01:40:12 UTC (rev 16409) +++ trunk/console/Makefile 2006-07-03 02:27:41 UTC (rev 16410) @@ -1,5 +1,6 @@ +VERSION=gntgaim-0.0.0dev CC=gcc -CFLAGS=`pkg-config --cflags gaim gobject-2.0 gnt` -g -Wall +CFLAGS=`pkg-config --cflags gaim gobject-2.0 gnt` -g -Wall -DVERSION=\"$(VERSION)\" LDFLAGS=`pkg-config --libs gaim gobject-2.0 libxml-2.0 gnt` -pg GG_SOURCES = \ Modified: trunk/console/gntgaim.c =================================================================== --- trunk/console/gntgaim.c 2006-07-03 01:40:12 UTC (rev 16409) +++ trunk/console/gntgaim.c 2006-07-03 02:27:41 UTC (rev 16410) @@ -18,6 +18,9 @@ #include "gntgaim.h" #include "gntui.h" +#define _GNU_SOURCE +#include <getopt.h> + /* Anything IO-related is directly copied from gtkgaim's source tree */ static GaimCoreUiOps core_ops = @@ -103,12 +106,6 @@ closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, gaim_gtk_io_invoke, closure, gaim_gtk_io_destroy); -#if 0 - gaim_debug(GAIM_DEBUG_MISC, "gtk_eventloop", - "CLOSURE: adding input watcher %d for fd %d\n", - closure->result, fd); -#endif - g_io_channel_unref(channel); return closure->result; } @@ -129,25 +126,124 @@ /* This is mostly copied from gtkgaim's source tree */ static void -init_libgaim() +show_usage(const char *name, gboolean terse) { + char *text; + + if (terse) { + text = g_strdup_printf(_("Gaim %s. Try `%s -h' for more information.\n"), VERSION, name); + } else { + text = g_strdup_printf(_("Gaim %s\n" + "Usage: %s [OPTION]...\n\n" + " -c, --config=DIR use DIR for config files\n" + " -d, --debug print debugging messages to stdout\n" + " -h, --help display this help and exit\n" + " -n, --nologin don't automatically login\n" + " -v, --version display the current version and exit\n"), VERSION, name); + } + + gaim_print_utf8_to_console(stdout, text); + g_free(text); +} + +static int +init_libgaim(int argc, char **argv) +{ char *path; + int opt; + gboolean opt_help = FALSE; + gboolean opt_nologin = FALSE; + gboolean opt_version = FALSE; + char *opt_config_dir_arg = NULL; + char *opt_session_arg = NULL; + gboolean debug_enabled; + struct option long_options[] = { + {"config", required_argument, NULL, 'c'}, + {"debug", no_argument, NULL, 'd'}, + {"help", no_argument, NULL, 'h'}, + {"nologin", no_argument, NULL, 'n'}, + {"session", required_argument, NULL, 's'}, + {"version", no_argument, NULL, 'v'}, + {0, 0, 0, 0} + }; + + /* scan command-line options */ + opterr = 1; + while ((opt = getopt_long(argc, argv, +#ifndef _WIN32 + "c:dhn::s:v", +#else + "c:dhn::v", +#endif + long_options, NULL)) != -1) { + switch (opt) { + case 'c': /* config dir */ + g_free(opt_config_dir_arg); + opt_config_dir_arg = g_strdup(optarg); + break; + case 'd': /* debug */ + debug_enabled = TRUE; + break; + case 'h': /* help */ + opt_help = TRUE; + break; + case 'n': /* no autologin */ + opt_nologin = TRUE; + break; + case 's': /* use existing session ID */ + g_free(opt_session_arg); + opt_session_arg = g_strdup(optarg); + break; + case 'v': /* version */ + opt_version = TRUE; + break; + case '?': /* show terse help */ + default: + show_usage(argv[0], TRUE); + return 0; + break; + } + } + + /* show help message */ + if (opt_help) { + show_usage(argv[0], FALSE); + return 0; + } + /* show version message */ + if (opt_version) { + printf("Gaim %s\n", VERSION); + return 0; + } + + /* set a user-specified config directory */ + if (opt_config_dir_arg != NULL) { + gaim_util_set_user_dir(opt_config_dir_arg); + } + + /* + * We're done piddling around with command line arguments. + * Fire up this baby. + */ + + /* Because we don't want debug-messages to show up and corrup the display */ gaim_debug_set_enabled(FALSE); gaim_core_set_ui_ops(gnt_core_get_ui_ops()); gaim_eventloop_set_ui_ops(gnt_eventloop_get_ui_ops()); - gaim_util_set_user_dir("/tmp/tmp/"); /* XXX: */ - path = g_build_filename(gaim_user_dir(), "plugins", NULL); gaim_plugins_add_search_path(path); g_free(path); + gaim_plugins_add_search_path("/usr/local/lib/gaim"); /* XXX: */ if (!gaim_core_init(GAIM_GNT_UI)) { - fprintf(stderr, "OOPSSS!!\n"); + fprintf(stderr, + "Initialization of the Gaim core failed. Dumping core.\n" + "Please report this!\n"); abort(); } @@ -160,11 +256,36 @@ gaim_prefs_update_old(); /* load plugins we had when we quit */ - gaim_plugins_load_saved("/gaim/gtk/plugins/loaded"); + gaim_plugins_load_saved("/gaim/gnt/plugins/loaded"); /* TODO: Move pounces loading into gaim_pounces_init() */ gaim_pounces_load(); + if (opt_nologin) + { + /* Set all accounts to "offline" */ + GaimSavedStatus *saved_status; + + /* If we've used this type+message before, lookup the transient status */ + saved_status = gaim_savedstatus_find_transient_by_type_and_message( + GAIM_STATUS_OFFLINE, NULL); + + /* If this type+message is unique then create a new transient saved status */ + if (saved_status == NULL) + saved_status = gaim_savedstatus_new(NULL, GAIM_STATUS_OFFLINE); + + /* Set the status for each account */ + gaim_savedstatus_activate(saved_status); + } + else + { + /* Everything is good to go--sign on already */ + if (!gaim_prefs_get_bool("/core/savedstatus/startup_current_status")) + gaim_savedstatus_activate(gaim_savedstatus_get_startup()); + gaim_accounts_restore_current_statuses(); + } + + return 1; } int main(int argc, char **argv) @@ -173,11 +294,9 @@ freopen(".error", "w", stderr); /* Initialize the libgaim stuff */ - init_libgaim(); + if (!init_libgaim(argc, argv)) + return 0; - /* Enable the accounts and restore the status */ - gaim_accounts_restore_current_statuses(); - /* Initialize and run the UI */ init_gnt_ui(); Modified: trunk/console/libgnt/gntcolors.c =================================================================== --- trunk/console/libgnt/gntcolors.c 2006-07-03 01:40:12 UTC (rev 16409) +++ trunk/console/libgnt/gntcolors.c 2006-07-03 02:27:41 UTC (rev 16410) @@ -29,10 +29,11 @@ else { init_pair(GNT_COLOR_NORMAL, COLOR_BLACK, COLOR_WHITE); - init_pair(GNT_COLOR_HIGHLIGHT, COLOR_YELLOW, COLOR_BLACK); + init_pair(GNT_COLOR_HIGHLIGHT, COLOR_WHITE, COLOR_BLUE); init_pair(GNT_COLOR_SHADOW, COLOR_BLACK, COLOR_BLACK); - init_pair(GNT_COLOR_TITLE, COLOR_WHITE, COLOR_BLACK); - init_pair(GNT_COLOR_TEXT_NORMAL, COLOR_BLACK, COLOR_WHITE); + init_pair(GNT_COLOR_TITLE, COLOR_WHITE, COLOR_BLUE); + init_pair(GNT_COLOR_TITLE_D, COLOR_WHITE, COLOR_BLACK); + init_pair(GNT_COLOR_TEXT_NORMAL, COLOR_WHITE, COLOR_BLUE); init_pair(GNT_COLOR_HIGHLIGHT_D, COLOR_CYAN, COLOR_BLACK); init_pair(GNT_COLOR_DISABLED, COLOR_YELLOW, COLOR_WHITE); } Modified: trunk/console/libgnt/gntmain.c =================================================================== --- trunk/console/libgnt/gntmain.c 2006-07-03 01:40:12 UTC (rev 16409) +++ trunk/console/libgnt/gntmain.c 2006-07-03 02:27:41 UTC (rev 16410) @@ -9,7 +9,9 @@ #include <unistd.h> #include <string.h> +static int lock_focus_list; static GList *focus_list; + static int X_MIN; static int X_MAX; static int Y_MIN; @@ -41,6 +43,9 @@ { GntWidget *w = NULL; + if (lock_focus_list) + return; + if (focus_list) w = focus_list->data; @@ -60,6 +65,9 @@ int pos = g_list_index(g_list_first(focus_list), widget); GList *next; + if (lock_focus_list) + return; + if (pos == -1) return; @@ -297,9 +305,11 @@ if (changed) { + lock_focus_list = 1; gnt_widget_hide(widget); gnt_widget_set_position(widget, x, y); gnt_widget_show(widget); + lock_focus_list = 0; } } else if (*buffer == '\r') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-03 01:40:17
|
Revision: 16409 Author: thekingant Date: 2006-07-02 18:40:12 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16409&view=rev Log Message: ----------- Backport SVN revision #16408 from HEAD to v2_0_0 Original commit message: Get rid of an assertion failure that I hit ViewCVS Links: ------------- http://svn.sourceforge.net/gaim/?rev=16408&view=rev Modified Paths: -------------- branches/v2_0_0/src/protocols/bonjour/bonjour.c branches/v2_0_0/src/protocols/bonjour/jabber.c Modified: branches/v2_0_0/src/protocols/bonjour/bonjour.c =================================================================== --- branches/v2_0_0/src/protocols/bonjour/bonjour.c 2006-07-03 01:39:51 UTC (rev 16408) +++ branches/v2_0_0/src/protocols/bonjour/bonjour.c 2006-07-03 01:40:12 UTC (rev 16409) @@ -556,7 +556,7 @@ #endif /* Try to figure out a good host name to use */ - /* TODO: Avoiding 'localhost,' if possible */ + /* TODO: Avoid 'localhost,' if possible */ if (gethostname(hostname, 255) != 0) { gaim_debug_warning("bonjour", "Error %d when getting host name. Using \"localhost.\"\n", errno); strcpy(hostname, "localhost"); Modified: branches/v2_0_0/src/protocols/bonjour/jabber.c =================================================================== --- branches/v2_0_0/src/protocols/bonjour/jabber.c 2006-07-03 01:39:51 UTC (rev 16408) +++ branches/v2_0_0/src/protocols/bonjour/jabber.c 2006-07-03 01:40:12 UTC (rev 16409) @@ -379,7 +379,8 @@ _jabber_parse_and_write_message_to_ui(message, account->gc, gb); } - xmlnode_free(message_node); + if (message_node != NULL) + xmlnode_free(message_node); } static void This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-03 01:39:55
|
Revision: 16408 Author: thekingant Date: 2006-07-02 18:39:51 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16408&view=rev Log Message: ----------- Get rid of an assertion failure that I hit Modified Paths: -------------- trunk/src/protocols/bonjour/bonjour.c trunk/src/protocols/bonjour/jabber.c Modified: trunk/src/protocols/bonjour/bonjour.c =================================================================== --- trunk/src/protocols/bonjour/bonjour.c 2006-07-03 00:38:12 UTC (rev 16407) +++ trunk/src/protocols/bonjour/bonjour.c 2006-07-03 01:39:51 UTC (rev 16408) @@ -556,7 +556,7 @@ #endif /* Try to figure out a good host name to use */ - /* TODO: Avoiding 'localhost,' if possible */ + /* TODO: Avoid 'localhost,' if possible */ if (gethostname(hostname, 255) != 0) { gaim_debug_warning("bonjour", "Error %d when getting host name. Using \"localhost.\"\n", errno); strcpy(hostname, "localhost"); Modified: trunk/src/protocols/bonjour/jabber.c =================================================================== --- trunk/src/protocols/bonjour/jabber.c 2006-07-03 00:38:12 UTC (rev 16407) +++ trunk/src/protocols/bonjour/jabber.c 2006-07-03 01:39:51 UTC (rev 16408) @@ -379,7 +379,8 @@ _jabber_parse_and_write_message_to_ui(message, account->gc, gb); } - xmlnode_free(message_node); + if (message_node != NULL) + xmlnode_free(message_node); } static void This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-03 00:38:15
|
Revision: 16407 Author: thekingant Date: 2006-07-02 17:38:12 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16407&view=rev Log Message: ----------- Backport SVN revision #16406 from HEAD to v2_0_0 Original commit message: More of sf patch #1490646, from Jonty Wareing & Jono Cole "The screen name + hostname of the sending user is sent in the outgoing jabber message, fixing a sporadic problem with iChat. The port in use has been fixed to the one described in the Bonjour specification and can no longer be changed in the prpl preferences - modifiying this just stops the client from being able to start a chat. The option for a buddy icon has been removed for now as no code actually uses it yet - we plan to change this in the future. This update also introduces automatic local port retry for up to ten attempts if the port is in use (e.g. if multiple instances of gaim are running)." ViewCVS Links: ------------- http://svn.sourceforge.net/gaim/?rev=16406&view=rev Modified Paths: -------------- branches/v2_0_0/src/protocols/bonjour/bonjour.c branches/v2_0_0/src/protocols/bonjour/bonjour.h branches/v2_0_0/src/protocols/bonjour/buddy.c branches/v2_0_0/src/protocols/bonjour/dns_sd.c branches/v2_0_0/src/protocols/bonjour/dns_sd.h branches/v2_0_0/src/protocols/bonjour/jabber.c branches/v2_0_0/src/protocols/bonjour/jabber.h Modified: branches/v2_0_0/src/protocols/bonjour/bonjour.c =================================================================== --- branches/v2_0_0/src/protocols/bonjour/bonjour.c 2006-07-03 00:37:41 UTC (rev 16406) +++ branches/v2_0_0/src/protocols/bonjour/bonjour.c 2006-07-03 00:38:12 UTC (rev 16407) @@ -103,7 +103,7 @@ /* Start waiting for jabber connections (iChat style) */ bd->jabber_data = g_new(BonjourJabber, 1); - bd->jabber_data->port = gaim_account_get_int(account, "port", BONJOUR_DEFAULT_PORT_INT); + bd->jabber_data->port = BONJOUR_DEFAULT_PORT_INT; bd->jabber_data->account = account; if (bonjour_jabber_start(bd->jabber_data) == -1) { @@ -123,7 +123,7 @@ bd->dns_sd_data->version = g_strdup("1"); bd->dns_sd_data->first = g_strdup(gaim_account_get_string(account, "first", default_firstname)); bd->dns_sd_data->last = g_strdup(gaim_account_get_string(account, "last", default_lastname)); - bd->dns_sd_data->port_p2pj = gaim_account_get_int(account, "port", BONJOUR_DEFAULT_PORT_INT); + bd->dns_sd_data->port_p2pj = bd->jabber_data->port; bd->dns_sd_data->phsh = g_strdup(""); bd->dns_sd_data->email = g_strdup(gaim_account_get_string(account, "email", "")); bd->dns_sd_data->vc = g_strdup(""); @@ -356,7 +356,8 @@ OPT_PROTO_NO_PASSWORD, NULL, /* user_splits */ NULL, /* protocol_options */ - {"png", 0, 0, 96, 96, GAIM_ICON_SCALE_DISPLAY}, /* icon_spec */ + /* {"png", 0, 0, 96, 96, GAIM_ICON_SCALE_DISPLAY}, */ /* icon_spec */ + NO_BUDDY_ICONS, /* not yet */ /* icon_spec */ bonjour_list_icon, /* list_icon */ bonjour_list_emblems, /* list_emblems */ bonjour_status_text, /* status_text */ @@ -576,9 +577,6 @@ prpl_info.user_splits = g_list_append(prpl_info.user_splits, split); /* Creating the options for the protocol */ - option = gaim_account_option_int_new(_("Port"), "port", 5298); - prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - option = gaim_account_option_string_new(_("First name"), "first", default_firstname); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); Modified: branches/v2_0_0/src/protocols/bonjour/bonjour.h =================================================================== --- branches/v2_0_0/src/protocols/bonjour/bonjour.h 2006-07-03 00:37:41 UTC (rev 16406) +++ branches/v2_0_0/src/protocols/bonjour/bonjour.h 2006-07-03 00:38:12 UTC (rev 16407) @@ -40,6 +40,8 @@ #define BONJOUR_STATUS_ID_AVAILABLE "available" #define BONJOUR_STATUS_ID_AWAY "away" +#define BONJOUR_DEFAULT_PORT_INT 5298 + typedef struct _BonjourData { BonjourDnsSd *dns_sd_data; Modified: branches/v2_0_0/src/protocols/bonjour/buddy.c =================================================================== --- branches/v2_0_0/src/protocols/bonjour/buddy.c 2006-07-03 00:37:41 UTC (rev 16406) +++ branches/v2_0_0/src/protocols/bonjour/buddy.c 2006-07-03 00:38:12 UTC (rev 16407) @@ -69,10 +69,6 @@ return FALSE; } - if (buddy->port_p2pj == -1) { - return FALSE; - } - if (buddy->status == NULL) { return FALSE; } Modified: branches/v2_0_0/src/protocols/bonjour/dns_sd.c =================================================================== --- branches/v2_0_0/src/protocols/bonjour/dns_sd.c 2006-07-03 00:37:41 UTC (rev 16406) +++ branches/v2_0_0/src/protocols/bonjour/dns_sd.c 2006-07-03 00:38:12 UTC (rev 16407) @@ -21,27 +21,6 @@ #include "buddy.h" #include "debug.h" -/* Private data */ - -typedef struct _dns_sd_packet -{ - gchar *name; - gchar *txtvers; - gchar *version; - gchar *first; - gchar *last; - gint port_p2pj; - gchar *phsh; - gchar *status; - gchar *message; - gchar *email; - gchar *vc; - gchar *jid; - gchar *AIM; -} dns_sd_packet; - -/* End private data */ - /* Private functions */ static sw_result HOWL_API @@ -83,7 +62,6 @@ gchar *txtvers = NULL; gchar *version = NULL; gchar *first = NULL; - gint port_p2pj = -1; gchar *phsh = NULL; gchar *status = NULL; gchar *email = NULL; @@ -119,8 +97,6 @@ version = g_strdup(value); } else if (strcmp(key, "1st") == 0) { first = g_strdup(value); - } else if (strcmp(key, "port.p2pj") == 0) { - port_p2pj = atoi(value); } else if (strcmp(key, "status") == 0) { status = g_strdup(value); } else if (strcmp(key, "email") == 0) { @@ -143,7 +119,7 @@ /* Put the parameters of the text_record in a buddy and add the buddy to */ /* the buddy list */ - buddy = bonjour_buddy_new(name, first, port_p2pj, phsh, + buddy = bonjour_buddy_new(name, first, port, phsh, status, email, last, jid, AIM, vc, ip, msg); if (bonjour_buddy_check(buddy) == FALSE) @@ -200,7 +176,7 @@ gaim_debug_warning("bonjour", "_browser_reply --> Remove domain\n"); break; case SW_DISCOVERY_BROWSE_ADD_SERVICE: - /* A new peer has join the network and uses iChat bonjour */ + /* A new peer has joined the network and uses iChat bonjour */ gaim_debug_info("bonjour", "_browser_reply --> Add service\n"); if (g_ascii_strcasecmp(name, account->username) != 0) { @@ -235,6 +211,7 @@ { sw_text_record dns_data; sw_result publish_result = SW_OKAY; + char portstring[6]; /* Fill the data for the service */ if (sw_text_record_init(&dns_data) != SW_OKAY) @@ -243,16 +220,20 @@ return -1; } + /* Convert the port to a string */ + snprintf(portstring, sizeof(portstring), "%d", data->port_p2pj); + + /* Publish standard records */ sw_text_record_add_key_and_string_value(dns_data, "txtvers", data->txtvers); sw_text_record_add_key_and_string_value(dns_data, "version", data->version); sw_text_record_add_key_and_string_value(dns_data, "1st", data->first); sw_text_record_add_key_and_string_value(dns_data, "last", data->last); - /* sw_text_record_add_key_and_string_value(dns_data, "port.p2pj", itoa(data->port_p2pj)); */ - sw_text_record_add_key_and_string_value(dns_data, "port.p2pj", BONJOUR_DEFAULT_PORT); + sw_text_record_add_key_and_string_value(dns_data, "port.p2pj", portstring); sw_text_record_add_key_and_string_value(dns_data, "phsh", data->phsh); sw_text_record_add_key_and_string_value(dns_data, "status", data->status); sw_text_record_add_key_and_string_value(dns_data, "vc", data->vc); + /* Publish extra records */ if ((data->email != NULL) && (*data->email != '\0')) sw_text_record_add_key_and_string_value(dns_data, "email", data->email); @@ -280,7 +261,7 @@ } if (publish_result != SW_OKAY) { - gaim_debug_error("bonjour", "Unable to publish or change the status of the _presence._tcp service."); + gaim_debug_error("bonjour", "Unable to publish or change the status of the _presence._tcp service.\n"); return -1; } Modified: branches/v2_0_0/src/protocols/bonjour/dns_sd.h =================================================================== --- branches/v2_0_0/src/protocols/bonjour/dns_sd.h 2006-07-03 00:37:41 UTC (rev 16406) +++ branches/v2_0_0/src/protocols/bonjour/dns_sd.h 2006-07-03 00:38:12 UTC (rev 16407) @@ -21,8 +21,6 @@ #include <glib.h> #include "account.h" -#define BONJOUR_DEFAULT_PORT "5298" -#define BONJOUR_DEFAULT_PORT_INT 5298 #define ICHAT_SERVICE "_presence._tcp." /** Modified: branches/v2_0_0/src/protocols/bonjour/jabber.c =================================================================== --- branches/v2_0_0/src/protocols/bonjour/jabber.c 2006-07-03 00:37:41 UTC (rev 16406) +++ branches/v2_0_0/src/protocols/bonjour/jabber.c 2006-07-03 00:38:12 UTC (rev 16407) @@ -450,6 +450,8 @@ { struct sockaddr_in my_addr; int yes = 1; + int i; + gboolean bind_successful; /* Open a listening socket for incoming conversations */ if ((data->socket = socket(PF_INET, SOCK_STREAM, 0)) < 0) @@ -469,19 +471,33 @@ memset(&my_addr, 0, sizeof(struct sockaddr_in)); my_addr.sin_family = PF_INET; - my_addr.sin_port = htons(data->port); - if (bind(data->socket, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) != 0) + /* Attempt to find a free port */ + bind_successful = FALSE; + for (i = 0; i < 10; i++) { + my_addr.sin_port = htons(data->port); + if (bind(data->socket, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) == 0) + { + bind_successful = TRUE; + break; + } + data->port++; + } + + /* On no! We tried 10 ports and could not bind to ANY of them */ + if (!bind_successful) + { gaim_debug_error("bonjour", "Cannot bind socket: %s\n", strerror(errno)); - gaim_connection_error(data->account->gc, _("Cannot bind socket to port")); + gaim_connection_error(data->account->gc, _("Could not bind socket to port")); return -1; } + /* Attempt to listen on the bound socket */ if (listen(data->socket, 10) != 0) { gaim_debug_error("bonjour", "Cannot listen on socket: %s\n", strerror(errno)); - gaim_connection_error(data->account->gc, _("Cannot listen on socket")); + gaim_connection_error(data->account->gc, _("Could not listen on socket")); return -1; } @@ -498,7 +514,7 @@ /* Open a watcher in the socket we have just opened */ data->watcher_id = gaim_input_add(data->socket, GAIM_INPUT_READ, _server_socket_handler, data); - return 0; + return data->port; } int @@ -547,6 +563,7 @@ message_node = xmlnode_new("message"); xmlnode_set_attrib(message_node, "to", ((BonjourBuddy*)(gb->proto_data))->name); + xmlnode_set_attrib(message_node, "from", data->account->username); xmlnode_set_attrib(message_node, "type", "chat"); xmlnode_insert_child(message_node, message_body_node); xmlnode_insert_child(message_node, message_html_node); Modified: branches/v2_0_0/src/protocols/bonjour/jabber.h =================================================================== --- branches/v2_0_0/src/protocols/bonjour/jabber.h 2006-07-03 00:37:41 UTC (rev 16406) +++ branches/v2_0_0/src/protocols/bonjour/jabber.h 2006-07-03 00:38:12 UTC (rev 16407) @@ -49,8 +49,10 @@ } BonjourJabberConversation; /** - * Start listening for jabber connections. Returns 0 if the connection could be - * stablished, -1 if a problem appears. + * Start listening for jabber connections. + * + * @return -1 if there was a problem, else returns the listening + * port number. */ gint bonjour_jabber_start(BonjourJabber *data); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-03 00:37:48
|
Revision: 16406 Author: thekingant Date: 2006-07-02 17:37:41 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16406&view=rev Log Message: ----------- More of sf patch #1490646, from Jonty Wareing & Jono Cole "The screen name + hostname of the sending user is sent in the outgoing jabber message, fixing a sporadic problem with iChat. The port in use has been fixed to the one described in the Bonjour specification and can no longer be changed in the prpl preferences - modifiying this just stops the client from being able to start a chat. The option for a buddy icon has been removed for now as no code actually uses it yet - we plan to change this in the future. This update also introduces automatic local port retry for up to ten attempts if the port is in use (e.g. if multiple instances of gaim are running)." Modified Paths: -------------- trunk/src/protocols/bonjour/bonjour.c trunk/src/protocols/bonjour/bonjour.h trunk/src/protocols/bonjour/buddy.c trunk/src/protocols/bonjour/dns_sd.c trunk/src/protocols/bonjour/dns_sd.h trunk/src/protocols/bonjour/jabber.c trunk/src/protocols/bonjour/jabber.h Modified: trunk/src/protocols/bonjour/bonjour.c =================================================================== --- trunk/src/protocols/bonjour/bonjour.c 2006-07-02 23:56:44 UTC (rev 16405) +++ trunk/src/protocols/bonjour/bonjour.c 2006-07-03 00:37:41 UTC (rev 16406) @@ -103,7 +103,7 @@ /* Start waiting for jabber connections (iChat style) */ bd->jabber_data = g_new(BonjourJabber, 1); - bd->jabber_data->port = gaim_account_get_int(account, "port", BONJOUR_DEFAULT_PORT_INT); + bd->jabber_data->port = BONJOUR_DEFAULT_PORT_INT; bd->jabber_data->account = account; if (bonjour_jabber_start(bd->jabber_data) == -1) { @@ -123,7 +123,7 @@ bd->dns_sd_data->version = g_strdup("1"); bd->dns_sd_data->first = g_strdup(gaim_account_get_string(account, "first", default_firstname)); bd->dns_sd_data->last = g_strdup(gaim_account_get_string(account, "last", default_lastname)); - bd->dns_sd_data->port_p2pj = gaim_account_get_int(account, "port", BONJOUR_DEFAULT_PORT_INT); + bd->dns_sd_data->port_p2pj = bd->jabber_data->port; bd->dns_sd_data->phsh = g_strdup(""); bd->dns_sd_data->email = g_strdup(gaim_account_get_string(account, "email", "")); bd->dns_sd_data->vc = g_strdup(""); @@ -356,7 +356,8 @@ OPT_PROTO_NO_PASSWORD, NULL, /* user_splits */ NULL, /* protocol_options */ - {"png", 0, 0, 96, 96, GAIM_ICON_SCALE_DISPLAY}, /* icon_spec */ + /* {"png", 0, 0, 96, 96, GAIM_ICON_SCALE_DISPLAY}, */ /* icon_spec */ + NO_BUDDY_ICONS, /* not yet */ /* icon_spec */ bonjour_list_icon, /* list_icon */ bonjour_list_emblems, /* list_emblems */ bonjour_status_text, /* status_text */ @@ -576,9 +577,6 @@ prpl_info.user_splits = g_list_append(prpl_info.user_splits, split); /* Creating the options for the protocol */ - option = gaim_account_option_int_new(_("Port"), "port", 5298); - prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - option = gaim_account_option_string_new(_("First name"), "first", default_firstname); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); Modified: trunk/src/protocols/bonjour/bonjour.h =================================================================== --- trunk/src/protocols/bonjour/bonjour.h 2006-07-02 23:56:44 UTC (rev 16405) +++ trunk/src/protocols/bonjour/bonjour.h 2006-07-03 00:37:41 UTC (rev 16406) @@ -40,6 +40,8 @@ #define BONJOUR_STATUS_ID_AVAILABLE "available" #define BONJOUR_STATUS_ID_AWAY "away" +#define BONJOUR_DEFAULT_PORT_INT 5298 + typedef struct _BonjourData { BonjourDnsSd *dns_sd_data; Modified: trunk/src/protocols/bonjour/buddy.c =================================================================== --- trunk/src/protocols/bonjour/buddy.c 2006-07-02 23:56:44 UTC (rev 16405) +++ trunk/src/protocols/bonjour/buddy.c 2006-07-03 00:37:41 UTC (rev 16406) @@ -69,10 +69,6 @@ return FALSE; } - if (buddy->port_p2pj == -1) { - return FALSE; - } - if (buddy->status == NULL) { return FALSE; } Modified: trunk/src/protocols/bonjour/dns_sd.c =================================================================== --- trunk/src/protocols/bonjour/dns_sd.c 2006-07-02 23:56:44 UTC (rev 16405) +++ trunk/src/protocols/bonjour/dns_sd.c 2006-07-03 00:37:41 UTC (rev 16406) @@ -21,27 +21,6 @@ #include "buddy.h" #include "debug.h" -/* Private data */ - -typedef struct _dns_sd_packet -{ - gchar *name; - gchar *txtvers; - gchar *version; - gchar *first; - gchar *last; - gint port_p2pj; - gchar *phsh; - gchar *status; - gchar *message; - gchar *email; - gchar *vc; - gchar *jid; - gchar *AIM; -} dns_sd_packet; - -/* End private data */ - /* Private functions */ static sw_result HOWL_API @@ -83,7 +62,6 @@ gchar *txtvers = NULL; gchar *version = NULL; gchar *first = NULL; - gint port_p2pj = -1; gchar *phsh = NULL; gchar *status = NULL; gchar *email = NULL; @@ -119,8 +97,6 @@ version = g_strdup(value); } else if (strcmp(key, "1st") == 0) { first = g_strdup(value); - } else if (strcmp(key, "port.p2pj") == 0) { - port_p2pj = atoi(value); } else if (strcmp(key, "status") == 0) { status = g_strdup(value); } else if (strcmp(key, "email") == 0) { @@ -143,7 +119,7 @@ /* Put the parameters of the text_record in a buddy and add the buddy to */ /* the buddy list */ - buddy = bonjour_buddy_new(name, first, port_p2pj, phsh, + buddy = bonjour_buddy_new(name, first, port, phsh, status, email, last, jid, AIM, vc, ip, msg); if (bonjour_buddy_check(buddy) == FALSE) @@ -200,7 +176,7 @@ gaim_debug_warning("bonjour", "_browser_reply --> Remove domain\n"); break; case SW_DISCOVERY_BROWSE_ADD_SERVICE: - /* A new peer has join the network and uses iChat bonjour */ + /* A new peer has joined the network and uses iChat bonjour */ gaim_debug_info("bonjour", "_browser_reply --> Add service\n"); if (g_ascii_strcasecmp(name, account->username) != 0) { @@ -235,6 +211,7 @@ { sw_text_record dns_data; sw_result publish_result = SW_OKAY; + char portstring[6]; /* Fill the data for the service */ if (sw_text_record_init(&dns_data) != SW_OKAY) @@ -243,16 +220,20 @@ return -1; } + /* Convert the port to a string */ + snprintf(portstring, sizeof(portstring), "%d", data->port_p2pj); + + /* Publish standard records */ sw_text_record_add_key_and_string_value(dns_data, "txtvers", data->txtvers); sw_text_record_add_key_and_string_value(dns_data, "version", data->version); sw_text_record_add_key_and_string_value(dns_data, "1st", data->first); sw_text_record_add_key_and_string_value(dns_data, "last", data->last); - /* sw_text_record_add_key_and_string_value(dns_data, "port.p2pj", itoa(data->port_p2pj)); */ - sw_text_record_add_key_and_string_value(dns_data, "port.p2pj", BONJOUR_DEFAULT_PORT); + sw_text_record_add_key_and_string_value(dns_data, "port.p2pj", portstring); sw_text_record_add_key_and_string_value(dns_data, "phsh", data->phsh); sw_text_record_add_key_and_string_value(dns_data, "status", data->status); sw_text_record_add_key_and_string_value(dns_data, "vc", data->vc); + /* Publish extra records */ if ((data->email != NULL) && (*data->email != '\0')) sw_text_record_add_key_and_string_value(dns_data, "email", data->email); @@ -280,7 +261,7 @@ } if (publish_result != SW_OKAY) { - gaim_debug_error("bonjour", "Unable to publish or change the status of the _presence._tcp service."); + gaim_debug_error("bonjour", "Unable to publish or change the status of the _presence._tcp service.\n"); return -1; } Modified: trunk/src/protocols/bonjour/dns_sd.h =================================================================== --- trunk/src/protocols/bonjour/dns_sd.h 2006-07-02 23:56:44 UTC (rev 16405) +++ trunk/src/protocols/bonjour/dns_sd.h 2006-07-03 00:37:41 UTC (rev 16406) @@ -21,8 +21,6 @@ #include <glib.h> #include "account.h" -#define BONJOUR_DEFAULT_PORT "5298" -#define BONJOUR_DEFAULT_PORT_INT 5298 #define ICHAT_SERVICE "_presence._tcp." /** Modified: trunk/src/protocols/bonjour/jabber.c =================================================================== --- trunk/src/protocols/bonjour/jabber.c 2006-07-02 23:56:44 UTC (rev 16405) +++ trunk/src/protocols/bonjour/jabber.c 2006-07-03 00:37:41 UTC (rev 16406) @@ -450,6 +450,8 @@ { struct sockaddr_in my_addr; int yes = 1; + int i; + gboolean bind_successful; /* Open a listening socket for incoming conversations */ if ((data->socket = socket(PF_INET, SOCK_STREAM, 0)) < 0) @@ -469,19 +471,33 @@ memset(&my_addr, 0, sizeof(struct sockaddr_in)); my_addr.sin_family = PF_INET; - my_addr.sin_port = htons(data->port); - if (bind(data->socket, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) != 0) + /* Attempt to find a free port */ + bind_successful = FALSE; + for (i = 0; i < 10; i++) { + my_addr.sin_port = htons(data->port); + if (bind(data->socket, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) == 0) + { + bind_successful = TRUE; + break; + } + data->port++; + } + + /* On no! We tried 10 ports and could not bind to ANY of them */ + if (!bind_successful) + { gaim_debug_error("bonjour", "Cannot bind socket: %s\n", strerror(errno)); - gaim_connection_error(data->account->gc, _("Cannot bind socket to port")); + gaim_connection_error(data->account->gc, _("Could not bind socket to port")); return -1; } + /* Attempt to listen on the bound socket */ if (listen(data->socket, 10) != 0) { gaim_debug_error("bonjour", "Cannot listen on socket: %s\n", strerror(errno)); - gaim_connection_error(data->account->gc, _("Cannot listen on socket")); + gaim_connection_error(data->account->gc, _("Could not listen on socket")); return -1; } @@ -498,7 +514,7 @@ /* Open a watcher in the socket we have just opened */ data->watcher_id = gaim_input_add(data->socket, GAIM_INPUT_READ, _server_socket_handler, data); - return 0; + return data->port; } int @@ -547,6 +563,7 @@ message_node = xmlnode_new("message"); xmlnode_set_attrib(message_node, "to", ((BonjourBuddy*)(gb->proto_data))->name); + xmlnode_set_attrib(message_node, "from", data->account->username); xmlnode_set_attrib(message_node, "type", "chat"); xmlnode_insert_child(message_node, message_body_node); xmlnode_insert_child(message_node, message_html_node); Modified: trunk/src/protocols/bonjour/jabber.h =================================================================== --- trunk/src/protocols/bonjour/jabber.h 2006-07-02 23:56:44 UTC (rev 16405) +++ trunk/src/protocols/bonjour/jabber.h 2006-07-03 00:37:41 UTC (rev 16406) @@ -49,8 +49,10 @@ } BonjourJabberConversation; /** - * Start listening for jabber connections. Returns 0 if the connection could be - * stablished, -1 if a problem appears. + * Start listening for jabber connections. + * + * @return -1 if there was a problem, else returns the listening + * port number. */ gint bonjour_jabber_start(BonjourJabber *data); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-02 23:56:48
|
Revision: 16405 Author: thekingant Date: 2006-07-02 16:56:44 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16405&view=rev Log Message: ----------- Backport SVN revision #16404 from HEAD to v2_0_0 Original commit message: Fix a small bug in oscar where the "Send File" option in the conversation menu would be greyed out if the buddy is not in your buddy list. Thanks to foo in #gaim for pointing this out, unbeknowest to him. ViewCVS Links: ------------- http://svn.sourceforge.net/gaim/?rev=16404&view=rev Modified Paths: -------------- branches/v2_0_0/src/protocols/oscar/oscar.c Modified: branches/v2_0_0/src/protocols/oscar/oscar.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/oscar.c 2006-07-02 23:56:08 UTC (rev 16404) +++ branches/v2_0_0/src/protocols/oscar/oscar.c 2006-07-02 23:56:44 UTC (rev 16405) @@ -6161,8 +6161,8 @@ * Don't allowing sending a file to a user that does not support * file transfer, and don't allow sending to ourselves. */ - if ((userinfo != NULL) && - (userinfo->capabilities & OSCAR_CAPABILITY_SENDFILE) && + if (((userinfo == NULL) || + (userinfo->capabilities & OSCAR_CAPABILITY_SENDFILE)) && aim_sncmp(who, gaim_account_get_username(account))) { return TRUE; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-02 23:56:11
|
Revision: 16404 Author: thekingant Date: 2006-07-02 16:56:08 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16404&view=rev Log Message: ----------- Fix a small bug in oscar where the "Send File" option in the conversation menu would be greyed out if the buddy is not in your buddy list. Thanks to foo in #gaim for pointing this out, unbeknowest to him. Modified Paths: -------------- trunk/src/protocols/oscar/oscar.c Modified: trunk/src/protocols/oscar/oscar.c =================================================================== --- trunk/src/protocols/oscar/oscar.c 2006-07-02 22:58:30 UTC (rev 16403) +++ trunk/src/protocols/oscar/oscar.c 2006-07-02 23:56:08 UTC (rev 16404) @@ -6162,8 +6162,8 @@ * Don't allowing sending a file to a user that does not support * file transfer, and don't allow sending to ourselves. */ - if ((userinfo != NULL) && - (userinfo->capabilities & OSCAR_CAPABILITY_SENDFILE) && + if (((userinfo == NULL) || + (userinfo->capabilities & OSCAR_CAPABILITY_SENDFILE)) && aim_sncmp(who, gaim_account_get_username(account))) { return TRUE; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2006-07-02 22:58:35
|
Revision: 16403 Author: roast Date: 2006-07-02 15:58:30 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16403&view=rev Log Message: ----------- receiving a message from self detection fixed. normalizing all names; making no assumptions. Modified Paths: -------------- branches/soc-2006-file-loggers/src/log.c Modified: branches/soc-2006-file-loggers/src/log.c =================================================================== --- branches/soc-2006-file-loggers/src/log.c 2006-07-02 22:13:06 UTC (rev 16402) +++ branches/soc-2006-file-loggers/src/log.c 2006-07-02 22:58:30 UTC (rev 16403) @@ -1059,26 +1059,34 @@ written += fprintf(data->file, "\t<message time=\"%s\" sender=\"%s\" gaim:type=\"whisper\">%s</message>\n", date, from, msg_fixed); } else if (type & GAIM_MESSAGE_AUTO_RESP && (type & GAIM_MESSAGE_SEND || type & GAIM_MESSAGE_RECV)) { - gboolean selfsending = FALSE; - if (!g_ascii_strncasecmp(gaim_account_get_username(log->account), - gaim_account_get_username(log->conv->account), - strlen(gaim_account_get_username(log->account)))) { - selfsending = (type & GAIM_MESSAGE_RECV); + gboolean recv_from_self = FALSE; + if (type & GAIM_MESSAGE_RECV) { + char *from_normed = g_strdup(gaim_normalize(log->account, from)); + if (g_ascii_strncasecmp(from_normed, + gaim_normalize(log->account, gaim_account_get_username(log->account)), + strlen(from)) == 0) { + recv_from_self = TRUE; + g_free(from_normed); + } } written += fprintf(data->file, "\t<message time=\"%s\" sender=\"%s\"%s auto=\"true\">%s</message>\n", - date, from, selfsending ? " gaim:self=\"true\"" : "", msg_fixed); + date, from, recv_from_self ? " gaim:self=\"true\"" : "", msg_fixed); } else if (type & GAIM_MESSAGE_SEND || type & GAIM_MESSAGE_RECV) { - gboolean selfsending = FALSE; - if (!g_ascii_strncasecmp(gaim_account_get_username(log->account), - gaim_account_get_username(log->conv->account), - strlen(gaim_account_get_username(log->account)))) { - selfsending = (type & GAIM_MESSAGE_RECV); + gboolean recv_from_self = FALSE; + if (type & GAIM_MESSAGE_RECV) { + char *from_normed = g_strdup(gaim_normalize(log->account, from)); + if (g_ascii_strncasecmp(from_normed, + gaim_normalize(log->account, gaim_account_get_username(log->account)), + strlen(from)) == 0) { + recv_from_self = TRUE; + g_free(from_normed); + } } written += fprintf(data->file, "\t<message time=\"%s\" sender=\"%s\"%s>%s</message>\n", - date, from, selfsending ? " gaim:self=\"true\"" : "", msg_fixed); + date, from, recv_from_self ? " gaim:self=\"true\"" : "", msg_fixed); } else { gaim_debug_error("log", "Unhandled message type."); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sa...@us...> - 2006-07-02 22:13:22
|
Revision: 16402 Author: sadrul Date: 2006-07-02 15:13:06 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16402&view=rev Log Message: ----------- This commit has 1234 lines of diff :) Windows can now be moved (alt+m, then the arrow keys, then escape/enter). Add a window to enable/disable accounts. But the 'add' etc. buttons don't have any callbacks yet. I am going to need to do some more widgets (checkbox, combobox) before I do anything else. I have also updated the test programs to work with the changes in libgnt. Modified Paths: -------------- trunk/console/Makefile trunk/console/gntblist.c trunk/console/gntblist.h trunk/console/gntconv.c trunk/console/gntconv.h trunk/console/gntgaim.c trunk/console/gntui.c trunk/console/libgnt/gnt.h trunk/console/libgnt/gntbox.c trunk/console/libgnt/gntbox.h trunk/console/libgnt/gntbutton.c trunk/console/libgnt/gntmain.c trunk/console/libgnt/gnttree.c trunk/console/libgnt/gnttree.h trunk/console/libgnt/gntwidget.c trunk/console/libgnt/test/focus.c trunk/console/libgnt/test/multiwin.c trunk/console/libgnt/test/tv.c Added Paths: ----------- trunk/console/gntaccount.c trunk/console/gntaccount.h Modified: trunk/console/Makefile =================================================================== --- trunk/console/Makefile 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/Makefile 2006-07-02 22:13:06 UTC (rev 16402) @@ -3,16 +3,19 @@ LDFLAGS=`pkg-config --libs gaim gobject-2.0 libxml-2.0 gnt` -pg GG_SOURCES = \ + gntaccount.c \ gntblist.c \ gntconv.c \ gntui.c GG_HEADERS = \ + gntaccount.h \ gntblist.h \ gntconv.h \ gntui.h GG_OBJECTS = \ + gntaccount.o \ gntblist.o \ gntconv.o \ gntui.o @@ -21,6 +24,7 @@ gntgaim: gntgaim.o $(GG_OBJECTS) $(CC) -o gntgaim gntgaim.o $(GG_OBJECTS) $(LDFLAGS) +gntaccount.o: gntaccount.c $(GG_HEADERS) gntblist.o: gntblist.c $(GG_HEADERS) gntconv.o: gntconv.c $(GG_HEADERS) gntgaim.o: gntgaim.c gntgaim.h $(GG_HEADERS) Added: trunk/console/gntaccount.c =================================================================== --- trunk/console/gntaccount.c (rev 0) +++ trunk/console/gntaccount.c 2006-07-02 22:13:06 UTC (rev 16402) @@ -0,0 +1,180 @@ +#include <gnt.h> +#include <gntbox.h> +#include <gntbutton.h> +#include <gntlabel.h> +#include <gnttree.h> + +#include <connection.h> +#include <notify.h> +#include <request.h> + +#include "gntaccount.h" +#include "gntgaim.h" + +typedef struct +{ + GntWidget *window; + GntWidget *tree; +} GGAccountList; + +static GGAccountList accounts; + +static void +account_toggled(GntWidget *widget, void *key, gpointer null) +{ + GaimAccount *account = key; + + gaim_account_set_enabled(account, GAIM_GNT_UI, gnt_tree_get_choice(GNT_TREE(widget), key)); +} + +void gg_accounts_init() +{ + GList *iter; + GntWidget *box, *button; + + accounts.window = gnt_box_new(TRUE, TRUE); + gnt_box_set_toplevel(GNT_BOX(accounts.window), TRUE); + gnt_box_set_title(GNT_BOX(accounts.window), _("Accounts")); + gnt_widget_set_name(accounts.window, "accounts"); + + gnt_box_add_widget(GNT_BOX(accounts.window), + gnt_label_new(_("You can enable/disable accounts from the follwing list."))); + + accounts.tree = gnt_tree_new(); + GNT_WIDGET_SET_FLAGS(accounts.tree, GNT_WIDGET_NO_BORDER); + + for (iter = gaim_accounts_get_all(); iter; iter = iter->next) + { + GaimAccount *account = iter->data; + char *str = g_strdup_printf("%s (%s)", + gaim_account_get_username(account), gaim_account_get_protocol_id(account)); + + gnt_tree_add_choice(GNT_TREE(accounts.tree), account, + str, NULL, NULL); + gnt_tree_set_choice(GNT_TREE(accounts.tree), account, + gaim_account_get_enabled(account, GAIM_GNT_UI)); + g_free(str); + } + + g_signal_connect(G_OBJECT(accounts.tree), "toggled", G_CALLBACK(account_toggled), NULL); + + gnt_widget_set_size(accounts.tree, 40, 15); + gnt_box_add_widget(GNT_BOX(accounts.window), accounts.tree); + + box = gnt_box_new(FALSE, FALSE); + + button = gnt_button_new(_("Add")); + gnt_box_add_widget(GNT_BOX(box), button); + + button = gnt_button_new(_("Modify")); + gnt_box_add_widget(GNT_BOX(box), button); + + button = gnt_button_new(_("Delete")); + gnt_box_add_widget(GNT_BOX(box), button); + + gnt_box_add_widget(GNT_BOX(accounts.window), box); + + gnt_widget_show(accounts.window); +} + +void gg_accounts_uninit() +{ + gnt_widget_destroy(accounts.window); +} + +#if 0 +/* The following uiops stuff are copied from gtkaccount.c */ +/* Need to do some work on notify- and request-ui before this works */ +typedef struct +{ + GaimAccount *account; + char *username; + char *alias; +} AddUserData; + +static char * +make_info(GaimAccount *account, GaimConnection *gc, const char *remote_user, + const char *id, const char *alias, const char *msg) +{ + if (msg != NULL && *msg == '\0') + msg = NULL; + + return g_strdup_printf(_("%s%s%s%s has made %s his or her buddy%s%s"), + remote_user, + (alias != NULL ? " (" : ""), + (alias != NULL ? alias : ""), + (alias != NULL ? ")" : ""), + (id != NULL + ? id + : (gaim_connection_get_display_name(gc) != NULL + ? gaim_connection_get_display_name(gc) + : gaim_account_get_username(account))), + (msg != NULL ? ": " : "."), + (msg != NULL ? msg : "")); +} + +static void +notify_added(GaimAccount *account, const char *remote_user, + const char *id, const char *alias, + const char *msg) +{ + char *buffer; + GaimConnection *gc; + + gc = gaim_account_get_connection(account); + + buffer = make_info(account, gc, remote_user, id, alias, msg); + + gaim_notify_info(NULL, NULL, buffer, NULL); + + g_free(buffer); +} + +static void +request_add(GaimAccount *account, const char *remote_user, + const char *id, const char *alias, + const char *msg) +{ + char *buffer; + GaimConnection *gc; + AddUserData *data; + + gc = gaim_account_get_connection(account); + + data = g_new0(AddUserData, 1); + data->account = account; + data->username = g_strdup(remote_user); + data->alias = (alias != NULL ? g_strdup(alias) : NULL); + + buffer = make_info(account, gc, remote_user, id, alias, msg); +#if 0 + gaim_request_action(NULL, NULL, _("Add buddy to your list?"), + buffer, GAIM_DEFAULT_ACTION_NONE, data, 2, + _("Add"), G_CALLBACK(add_user_cb), + _("Cancel"), G_CALLBACK(free_add_user_data)); +#endif + g_free(buffer); +} + +static GaimAccountUiOps ui_ops = +{ + .notify_added = notify_added, + .status_changed = NULL, + .request_add = request_add +}; +#else + +static GaimAccountUiOps ui_ops = +{ + .notify_added = NULL, + .status_changed = NULL, + .request_add = NULL +}; + +#endif + +GaimAccountUiOps *gg_accounts_get_ui_ops() +{ + return &ui_ops; +} + Property changes on: trunk/console/gntaccount.c ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: trunk/console/gntaccount.h =================================================================== --- trunk/console/gntaccount.h (rev 0) +++ trunk/console/gntaccount.h 2006-07-02 22:13:06 UTC (rev 16402) @@ -0,0 +1,7 @@ +#include "account.h" + +GaimAccountUiOps *gg_accounts_get_ui_ops(); + +void gg_accounts_init(); + +void gg_accounts_uninit(); Property changes on: trunk/console/gntaccount.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Modified: trunk/console/gntblist.c =================================================================== --- trunk/console/gntblist.c 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/gntblist.c 2006-07-02 22:13:06 UTC (rev 16402) @@ -440,3 +440,11 @@ g_signal_connect(G_OBJECT(ggblist->tree), "activate", G_CALLBACK(selection_activate), ggblist); } +void gg_blist_uninit() +{ + gnt_widget_destroy(ggblist->window); + g_free(ggblist); + ggblist = NULL; +} + + Modified: trunk/console/gntblist.h =================================================================== --- trunk/console/gntblist.h 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/gntblist.h 2006-07-02 22:13:06 UTC (rev 16402) @@ -3,3 +3,5 @@ GaimBlistUiOps * gg_blist_get_ui_ops(); void gg_blist_init(); + +void gg_blist_uninit(); Modified: trunk/console/gntconv.c =================================================================== --- trunk/console/gntconv.c 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/gntconv.c 2006-07-02 22:13:06 UTC (rev 16402) @@ -165,7 +165,8 @@ g_free(strip); - gnt_widget_set_urgent(ggconv->tv); + if (flags & (GAIM_MESSAGE_RECV | GAIM_MESSAGE_NICK | GAIM_MESSAGE_ERROR)) + gnt_widget_set_urgent(ggconv->tv); } static void @@ -261,3 +262,9 @@ ggconvs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_ggconv); } +void gg_conversation_uninit() +{ + g_hash_table_destroy(ggconvs); + ggconvs = NULL; +} + Modified: trunk/console/gntconv.h =================================================================== --- trunk/console/gntconv.h 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/gntconv.h 2006-07-02 22:13:06 UTC (rev 16402) @@ -3,3 +3,5 @@ GaimConversationUiOps *gg_conv_get_ui_ops(); void gg_conversation_init(); + +void gg_conversation_uninit(); Modified: trunk/console/gntgaim.c =================================================================== --- trunk/console/gntgaim.c 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/gntgaim.c 2006-07-02 22:13:06 UTC (rev 16402) @@ -178,7 +178,7 @@ /* Enable the accounts and restore the status */ gaim_accounts_restore_current_statuses(); - /* Initialize the UI */ + /* Initialize and run the UI */ init_gnt_ui(); gaim_core_quit(); Modified: trunk/console/gntui.c =================================================================== --- trunk/console/gntui.c 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/gntui.c 2006-07-02 22:13:06 UTC (rev 16402) @@ -1,4 +1,6 @@ #include "gntui.h" + +#include "gntaccount.h" #include "gntblist.h" #include "gntconv.h" @@ -6,9 +8,9 @@ { gnt_init(); - wbkgdset(stdscr, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); - werase(stdscr); - wrefresh(stdscr); + /* Accounts */ + gg_accounts_init(); + gaim_accounts_set_ui_ops(gg_accounts_get_ui_ops()); /* Initialize the buddy list */ gg_blist_init(); @@ -19,5 +21,16 @@ gaim_conversations_set_ui_ops(gg_conv_get_ui_ops()); gnt_main(); + + gaim_accounts_set_ui_ops(NULL); + gg_accounts_uninit(); + + gaim_blist_set_ui_ops(NULL); + gg_blist_uninit(); + + gaim_conversations_set_ui_ops(NULL); + gg_conversation_uninit(); + + gnt_quit(); } Modified: trunk/console/libgnt/gnt.h =================================================================== --- trunk/console/libgnt/gnt.h 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/libgnt/gnt.h 2006-07-02 22:13:06 UTC (rev 16402) @@ -18,3 +18,6 @@ gboolean gnt_widget_has_focus(GntWidget *widget); void gnt_widget_set_urgent(GntWidget *widget); + +void gnt_quit(); + Modified: trunk/console/libgnt/gntbox.c =================================================================== --- trunk/console/libgnt/gntbox.c 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/libgnt/gntbox.c 2006-07-02 22:13:06 UTC (rev 16402) @@ -13,10 +13,25 @@ static GntWidget * find_focusable_widget(GntBox *box); static void +add_to_focus(gpointer value, gpointer data) +{ + GntBox *box = GNT_BOX(data); + GntWidget *w = GNT_WIDGET(value); + + if (GNT_IS_BOX(w)) + g_list_foreach(GNT_BOX(w)->list, add_to_focus, box); + else if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_CAN_TAKE_FOCUS)) + box->focus = g_list_append(box->focus, w); +} + +static void gnt_box_draw(GntWidget *widget) { GntBox *box = GNT_BOX(widget); + if (box->focus == NULL && widget->parent == NULL) + g_list_foreach(box->list, add_to_focus, box); + g_list_foreach(box->list, (GFunc)gnt_widget_draw, NULL); gnt_box_sync_children(box); @@ -152,12 +167,18 @@ DEBUG; } +#if 0 static GntWidget * find_next_focus(GntBox *box) { GntWidget *w = box->active; GList *iter; + if (w == NULL) + { + return find_focusable_widget(box); + } + while (w && !(iter = g_list_find(box->list, w))) w = w->parent; @@ -167,12 +188,20 @@ { GntWidget *next = NULL; - do + while (!next && (iter = iter->next)) { - next = find_next_focus(iter->data); - box->active = next; - iter = iter->next; - } while (!next && iter); + if (GNT_IS_BOX(iter->data)) + next = find_next_focus(iter->data); + else + { + if (GNT_WIDGET_IS_FLAG_SET(iter->data, GNT_WIDGET_CAN_TAKE_FOCUS) && + GNT_WIDGET_IS_FLAG_SET(iter->data, GNT_WIDGET_HAS_FOCUS)) + next = iter->data; + else + next = NULL; + } + } + box->active = next; } if (box->active == NULL && GNT_WIDGET(box)->parent == NULL) @@ -185,16 +214,21 @@ return box->active; } +#endif /* Ensures that the current widget can take focus */ static GntWidget * find_focusable_widget(GntBox *box) { - int investigated = 0; - int total; - GntWidget *w = NULL; - GList *iter; + if (box->focus == NULL && GNT_WIDGET(box)->parent == NULL) + g_list_foreach(box->list, add_to_focus, box); + if (box->active == NULL && box->focus) + box->active = box->focus->data; + + return box->active; + +#if 0 for (iter = box->list; iter; iter = iter->next) { w = iter->data; @@ -248,6 +282,7 @@ if (w && w != box->active->data) gnt_widget_set_focus(w, FALSE); #endif +#endif } static gboolean @@ -263,35 +298,44 @@ if (text[0] == 27) { -#if 0 - GList *now = NULL; + GntWidget *now = box->active; if (strcmp(text+1, GNT_KEY_LEFT) == 0) { - now = box->active->prev; - if (now == NULL) - now = g_list_last(box->list); + GList *iter = g_list_find(box->focus, box->active); + if ((!iter || !iter->prev) && box->focus) + { + box->active = box->focus->data; + } + else + { + box->active = iter->prev->data; + } } else if (strcmp(text+1, GNT_KEY_RIGHT) == 0) { - now = box->active->next; - if (now == NULL) - now = box->list; + GList *iter = g_list_find(box->focus, box->active); + if (iter && iter->next) + { + box->active = iter->next->data; + } + else if (box->focus) + { + box->active = box->focus->data; + } } if (now && now != box->active) { - gnt_widget_set_focus(box->active->data, FALSE); - box->active = now; - gnt_widget_set_focus(box->active->data, TRUE); - + gnt_widget_set_focus(now, FALSE); + gnt_widget_set_focus(box->active, TRUE); return TRUE; } -#endif } return FALSE; } +#if 0 static GntWidget *find_focused_widget(GntBox *box) { GList *iter; @@ -314,6 +358,7 @@ } return NULL; } +#endif #if 0 static void @@ -483,6 +528,10 @@ for (iter = box->list; iter; iter = iter->next) { GntWidget *w = GNT_WIDGET(iter->data); + + if (GNT_IS_BOX(w)) + gnt_box_sync_children(GNT_BOX(w)); + copywin(w->window, widget->window, 0, 0, w->priv.y - widget->priv.y, w->priv.x - widget->priv.x, Modified: trunk/console/libgnt/gntbox.h =================================================================== --- trunk/console/libgnt/gntbox.h 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/libgnt/gntbox.h 2006-07-02 22:13:06 UTC (rev 16402) @@ -26,6 +26,7 @@ int pad; /* Number of spaces to use between widgets */ char *title; + GList *focus; /* List of widgets to cycle focus (only valid for parent boxes) */ void (*gnt_reserved1)(void); void (*gnt_reserved2)(void); Modified: trunk/console/libgnt/gntbutton.c =================================================================== --- trunk/console/libgnt/gntbutton.c 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/libgnt/gntbutton.c 2006-07-02 22:13:06 UTC (rev 16402) @@ -16,10 +16,11 @@ GntButton *button = GNT_BUTTON(widget); GntColorType type; - if (GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_HAS_FOCUS) + if (gnt_widget_has_focus(widget)) type = GNT_COLOR_HIGHLIGHT; else type = GNT_COLOR_NORMAL; + wbkgdset(widget->window, '\0' | COLOR_PAIR(type)); mvwprintw(widget->window, 1, 1, button->priv->text); Modified: trunk/console/libgnt/gntmain.c =================================================================== --- trunk/console/libgnt/gntmain.c 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/libgnt/gntmain.c 2006-07-02 22:13:06 UTC (rev 16402) @@ -10,9 +10,13 @@ #include <string.h> static GList *focus_list; -static int max_x; -static int max_y; +static int X_MIN; +static int X_MAX; +static int Y_MIN; +static int Y_MAX; +static GMainLoop *loop; + typedef struct { GntWidget *me; @@ -20,6 +24,14 @@ GList *above; /* List of widgets above me */ } GntNode; +typedef enum +{ + GNT_KP_MODE_NORMAL, + GNT_KP_MODE_RESIZE, + GNT_KP_MODE_MOVE, + GNT_KP_MODE_MENU, +} GntKeyPressMode; + static GHashTable *nodes; static void free_node(gpointer data); @@ -28,9 +40,15 @@ void gnt_screen_take_focus(GntWidget *widget) { GntWidget *w = NULL; + if (focus_list) w = focus_list->data; - focus_list = g_list_prepend(focus_list, widget); + + /* XXX: ew */ + focus_list = g_list_first(focus_list); + focus_list = g_list_append(focus_list, widget); + focus_list = g_list_find(focus_list, widget); + gnt_widget_set_focus(widget, TRUE); if (w) gnt_widget_set_focus(w, FALSE); @@ -39,7 +57,18 @@ void gnt_screen_remove_widget(GntWidget *widget) { + int pos = g_list_index(g_list_first(focus_list), widget); + GList *next; + + if (pos == -1) + return; + + focus_list = g_list_first(focus_list); focus_list = g_list_remove(focus_list, widget); + next = g_list_nth(focus_list, pos - 1); + if (next) + focus_list = next; + if (focus_list) { gnt_widget_set_focus(focus_list->data, TRUE); @@ -82,6 +111,7 @@ taskbar = newwin(1, getmaxx(stdscr), getmaxy(stdscr) - 1, 0); } + wbkgdset(taskbar, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); werase(taskbar); n = g_list_length(g_list_first(focus_list)); @@ -116,10 +146,45 @@ wrefresh(taskbar); } +static void +switch_window(int direction) +{ + GntWidget *w = NULL; + if (focus_list) + w = focus_list->data; + + if (direction == 1) + { + if (focus_list && focus_list->next) + focus_list = focus_list->next; + else + focus_list = g_list_first(focus_list); + } + else if (direction == -1) + { + if (focus_list && focus_list->prev) + focus_list = focus_list->prev; + else + focus_list = g_list_last(focus_list); + } + + if (focus_list) + { + gnt_widget_set_focus(focus_list->data, TRUE); + bring_on_top(focus_list->data); + gnt_widget_draw(focus_list->data); + } + + if (w && (!focus_list || w != focus_list->data)) + gnt_widget_set_focus(w, FALSE); +} + static gboolean io_invoke(GIOChannel *source, GIOCondition cond, gpointer null) { char buffer[256]; + static GntKeyPressMode mode = GNT_KP_MODE_NORMAL; + gboolean ret = FALSE; int rd = read(0, buffer, sizeof(buffer) - 1); if (rd < 0) @@ -137,53 +202,110 @@ buffer[rd] = 0; - if (focus_list) + if (mode == GNT_KP_MODE_NORMAL) { - gboolean ret = FALSE; - ret = gnt_widget_key_pressed(focus_list->data, buffer); - } + if (focus_list) + { + ret = gnt_widget_key_pressed(focus_list->data, buffer); + } - if (buffer[0] == 27) - { - /* Some special key has been pressed */ - if (strcmp(buffer+1, GNT_KEY_POPUP) == 0) - {} - else if (strcmp(buffer + 1, "c") == 0) + if (!ret) { - /* Alt + c was pressed. I am going to use it to close a window. */ - if (focus_list) + if (buffer[0] == 27) { - gnt_widget_destroy(focus_list->data); - gnt_screen_remove_widget(focus_list->data); + /* Some special key has been pressed */ + if (strcmp(buffer+1, GNT_KEY_POPUP) == 0) + {} + else if (strcmp(buffer + 1, "c") == 0) + { + /* Alt + c was pressed. I am going to use it to close a window. */ + if (focus_list) + { + gnt_widget_destroy(focus_list->data); + } + } + else if (strcmp(buffer + 1, "q") == 0) + { + /* I am going to use Alt + q to quit. */ + g_main_loop_quit(loop); + } + else if (strcmp(buffer + 1, "n") == 0) + { + /* Alt + n to go to the next window */ + switch_window(1); + } + else if (strcmp(buffer + 1, "p") == 0) + { + /* Alt + p to go to the previous window */ + switch_window(-1); + } + else if (strcmp(buffer + 1, "m") == 0 && focus_list) + { + mode = GNT_KP_MODE_MOVE; + } } } - else if (strcmp(buffer + 1, "q") == 0) + } + else if (mode == GNT_KP_MODE_MOVE && focus_list) + { + if (buffer[0] == 27) { - /* I am going to use Alt + q to quit. */ - endwin(); - exit(1); - } - else if (strcmp(buffer + 1, "n") == 0) - { - /* Alt + n to go to the next window */ - GntWidget *w = NULL; - if (focus_list) - w = focus_list->data; + gboolean changed = FALSE; + int x, y, w, h; + GntWidget *widget = GNT_WIDGET(focus_list->data); - if (focus_list && focus_list->next) - focus_list = focus_list->next; - else - focus_list = g_list_first(focus_list); - if (focus_list) + gnt_widget_get_position(widget, &x, &y); + gnt_widget_get_size(widget, &w, &h); + + if (strcmp(buffer + 1, GNT_KEY_LEFT) == 0) { - gnt_widget_set_focus(focus_list->data, TRUE); - bring_on_top(focus_list->data); - gnt_widget_draw(focus_list->data); + if (x > X_MIN) + { + x--; + changed = TRUE; + } } + else if (strcmp(buffer + 1, GNT_KEY_RIGHT) == 0) + { + if (x + w < X_MAX) + { + x++; + changed = TRUE; + } + } + else if (strcmp(buffer + 1, GNT_KEY_UP) == 0) + { + if (y > Y_MIN) + { + y--; + changed = TRUE; + } + } + else if (strcmp(buffer + 1, GNT_KEY_DOWN) == 0) + { + if (y + h < Y_MAX) + { + y++; + changed = TRUE; + } + } + else if (buffer[1] == 0) + { + mode = GNT_KP_MODE_NORMAL; + changed = TRUE; + } - if (w && w != focus_list->data) - gnt_widget_set_focus(w, FALSE); + if (changed) + { + gnt_widget_hide(widget); + gnt_widget_set_position(widget, x, y); + gnt_widget_show(widget); + } } + else if (*buffer == '\r') + { + mode = GNT_KP_MODE_NORMAL; + } } draw_taskbar(); @@ -209,8 +331,10 @@ start_color(); gnt_init_colors(); - max_x = getmaxx(stdscr); - max_y = getmaxy(stdscr); + X_MIN = 0; + Y_MIN = 0; + X_MAX = getmaxx(stdscr); + Y_MAX = getmaxy(stdscr) - 1; nodes = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_node); @@ -218,13 +342,17 @@ noecho(); refresh(); mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL); + wbkgdset(stdscr, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); + werase(stdscr); + wrefresh(stdscr); + g_type_init(); } void gnt_main() { - GMainLoop *loop = g_main_new(FALSE); - g_main_run(loop); + loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(loop); } /********************************* @@ -290,6 +418,9 @@ WINDOW *win; GList *iter; GntNode *node = g_hash_table_lookup(nodes, widget); + + gnt_screen_remove_widget(widget); + if (node == NULL) /* Yay! Nothing to do. */ return; @@ -384,15 +515,15 @@ while (widget->parent) { - fprintf(stderr, "%p %p\n", widget, widget->parent); widget = widget->parent; } - fprintf(stderr, "%p %p\n", widget, widget->parent); - if (focus_list && focus_list->data == widget && - (!GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_CAN_TAKE_FOCUS) || - GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_HAS_FOCUS))) - return TRUE; + if (focus_list && focus_list->data == widget) + { + if (GNT_IS_BOX(widget) && + (GNT_BOX(widget)->active == w || widget == w)) + return TRUE; + } return FALSE; } @@ -409,3 +540,8 @@ draw_taskbar(); } +void gnt_quit() +{ + endwin(); +} + Modified: trunk/console/libgnt/gnttree.c =================================================================== --- trunk/console/libgnt/gnttree.c 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/libgnt/gnttree.c 2006-07-02 22:13:06 UTC (rev 16402) @@ -7,6 +7,7 @@ { SIG_SELECTION_CHANGED, SIG_SCROLLED, + SIG_TOGGLED, SIGS, }; @@ -21,6 +22,9 @@ void *data; /* XXX: unused */ gboolean collapsed; + gboolean choice; /* Is this a choice-box? + If choice is true, then child will be NULL */ + gboolean isselected; GntTreeRow *parent; GntTreeRow *child; @@ -188,6 +192,10 @@ else strcpy(format, "- "); } + else if (row->choice) + { + g_snprintf(format, sizeof(format) - 1, "[%c] ", row->isselected ? 'X' : ' '); + } if ((wr = g_snprintf(str, widget->priv.width, "%s%s", format, row->text)) >= widget->priv.width) { @@ -206,7 +214,7 @@ if (gnt_widget_has_focus(widget)) wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_HIGHLIGHT)); else - wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D)); /* XXX: This, somehow, doesn't work */ + wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D)); mvwprintw(widget->window, start, pos, str); wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); } @@ -306,10 +314,19 @@ row->collapsed = !row->collapsed; redraw_tree(tree); } + else if (row && row->choice) + { + row->isselected = !row->isselected; + g_signal_emit(tree, signals[SIG_TOGGLED], 0, row->key); + redraw_tree(tree); + } } if (old != tree->current) + { tree_selection_changed(tree, old, tree->current); + return TRUE; + } return FALSE; } @@ -349,6 +366,14 @@ NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + signals[SIG_TOGGLED] = + g_signal_new("toggled", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); DEBUG; } @@ -616,4 +641,39 @@ } } +GntTreeRow *gnt_tree_add_choice(GntTree *tree, void *key, const char *text, void *parent, void *bigbro) +{ + GntTreeRow *row; + row = g_hash_table_lookup(tree->hash, key); + g_return_val_if_fail(!row || !row->choice, NULL); + + row = gnt_tree_add_row_after(tree, key, text, parent, bigbro); + row->choice = TRUE; + + return row; +} + +void gnt_tree_set_choice(GntTree *tree, void *key, gboolean set) +{ + GntTreeRow *row = g_hash_table_lookup(tree->hash, key); + + if (!row) + return; + g_return_if_fail(row->choice); + + row->isselected = set; + redraw_tree(tree); +} + +gboolean gnt_tree_get_choice(GntTree *tree, void *key) +{ + GntTreeRow *row = g_hash_table_lookup(tree->hash, key); + + if (!row) + return; + g_return_val_if_fail(row->choice, FALSE); + + return row->isselected; +} + Modified: trunk/console/libgnt/gnttree.h =================================================================== --- trunk/console/libgnt/gnttree.h 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/libgnt/gnttree.h 2006-07-02 22:13:06 UTC (rev 16402) @@ -73,6 +73,12 @@ void gnt_tree_change_text(GntTree *tree, gpointer key, const char *text); +GntTreeRow *gnt_tree_add_choice(GntTree *tree, void *key, const char *text, void *parent, void *bigbro); + +void gnt_tree_set_choice(GntTree *tree, void *key, gboolean set); + +gboolean gnt_tree_get_choice(GntTree *tree, void *key); + G_END_DECLS #endif /* GNT_TREE_H */ Modified: trunk/console/libgnt/gntwidget.c =================================================================== --- trunk/console/libgnt/gntwidget.c 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/libgnt/gntwidget.c 2006-07-02 22:13:06 UTC (rev 16402) @@ -239,11 +239,11 @@ gnt_widget_show(GntWidget *widget) { /* Draw the widget and take focus */ - gnt_widget_draw(widget); if (GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_CAN_TAKE_FOCUS) { gnt_widget_take_focus(widget); } + gnt_widget_draw(widget); } void @@ -267,7 +267,7 @@ widget->window = newwin(widget->priv.height, widget->priv.width, widget->priv.y, widget->priv.x); wbkgd(widget->window, COLOR_PAIR(GNT_COLOR_NORMAL)); - + if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER)) box(widget->window, 0, 0); else @@ -316,8 +316,8 @@ gnt_widget_hide(GntWidget *widget) { wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); - werase(widget->window); gnt_screen_release(widget); + GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_MAPPED); } void @@ -326,6 +326,8 @@ /* XXX: Need to install properties for these and g_object_notify */ wid->priv.x = x; wid->priv.y = y; + if (wid->window) + mvwin(wid->window, y, x); g_signal_emit(wid, signals[SIG_POSITION], 0, x, y); } Modified: trunk/console/libgnt/test/focus.c =================================================================== --- trunk/console/libgnt/test/focus.c 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/libgnt/test/focus.c 2006-07-02 22:13:06 UTC (rev 16402) @@ -6,44 +6,79 @@ #include "gntentry.h" #include "gntlabel.h" +static void +toggled(GntWidget *tree, gpointer key, gpointer null) +{ + GntWidget *w = gnt_box_new(FALSE, FALSE); + + gnt_box_set_toplevel(GNT_BOX(w), TRUE); + + gnt_box_add_widget(GNT_BOX(w), + gnt_label_new(gnt_tree_get_choice(GNT_TREE(tree), key) ? "Selected" : "NOT")); + gnt_widget_show(w); +} + int main() { gnt_init(); GntWidget *label = gnt_label_new("So wassup dudes and dudettes!!\nSo this is, like,\nthe third line!! \\o/"); - GntWidget *vbox, *hbox, *tree; + GntWidget *vbox, *hbox, *tree, *box, *button; WINDOW *test; box(stdscr, 0, 0); wrefresh(stdscr); vbox = gnt_box_new(FALSE, FALSE); - hbox = gnt_box_new(FALSE, TRUE); + hbox = gnt_box_new(TRUE, TRUE); gnt_widget_set_name(vbox, "vbox"); gnt_widget_set_name(hbox, "hbox"); gnt_box_add_widget(GNT_BOX(hbox), label); - gnt_box_add_widget(GNT_BOX(hbox), vbox); - gnt_box_add_widget(GNT_BOX(hbox), gnt_entry_new("a")); + GntWidget *entry = gnt_entry_new("a"); + gnt_widget_set_name(entry, "entry"); + gnt_box_add_widget(GNT_BOX(hbox), entry); + box = gnt_box_new(FALSE, FALSE); tree = gnt_tree_new(); - gnt_box_add_widget(GNT_BOX(hbox), tree); + gnt_widget_set_name(tree, "tree"); + gnt_box_add_widget(GNT_BOX(box), tree); + gnt_box_add_widget(GNT_BOX(hbox), box); gnt_tree_add_row_after(GNT_TREE(tree), "a", "a", NULL, NULL); gnt_tree_add_row_after(GNT_TREE(tree), "c", "c", NULL, NULL); gnt_tree_add_row_after(GNT_TREE(tree), "d", "d", NULL, NULL); gnt_tree_add_row_after(GNT_TREE(tree), "e", "e", "a", NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "b", "b", "d", NULL); + gnt_tree_add_choice(GNT_TREE(tree), "b", "b", "d", NULL); GNT_WIDGET_UNSET_FLAGS(hbox, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); gnt_box_set_title(GNT_BOX(hbox), "This is the title …"); + + g_signal_connect(G_OBJECT(tree), "toggled", G_CALLBACK(toggled), NULL); + + button = gnt_button_new("one"); + gnt_widget_set_name(button, "one"); + gnt_box_add_widget(GNT_BOX(vbox), button); + + button = gnt_button_new("two"); + gnt_widget_set_name(button, "two"); + gnt_box_add_widget(GNT_BOX(vbox), button); + + button = gnt_button_new("three"); + gnt_widget_set_name(button, "three"); + gnt_box_add_widget(GNT_BOX(vbox), button); + + gnt_box_add_widget(GNT_BOX(hbox), vbox); + gnt_widget_show(hbox); gnt_main(); + gnt_quit(); + return 0; } Modified: trunk/console/libgnt/test/multiwin.c =================================================================== --- trunk/console/libgnt/test/multiwin.c 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/libgnt/test/multiwin.c 2006-07-02 22:13:06 UTC (rev 16402) @@ -49,7 +49,7 @@ gnt_tree_add_row_after(GNT_TREE(tree), "e", "e", "a", NULL); gnt_tree_add_row_after(GNT_TREE(tree), "b", "b", "d", NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "1", "1", NULL, NULL); + gnt_tree_add_choice(GNT_TREE(tree), "1", "1", NULL, NULL); gnt_tree_add_row_after(GNT_TREE(tree), "2", "2", NULL, NULL); gnt_tree_add_row_after(GNT_TREE(tree), "3", "3", NULL, NULL); gnt_tree_add_row_after(GNT_TREE(tree), "4", "4", "a", NULL); @@ -60,6 +60,8 @@ gnt_main(); + gnt_quit(); + return 0; } Modified: trunk/console/libgnt/test/tv.c =================================================================== --- trunk/console/libgnt/test/tv.c 2006-07-02 21:52:38 UTC (rev 16401) +++ trunk/console/libgnt/test/tv.c 2006-07-02 22:13:06 UTC (rev 16402) @@ -66,6 +66,8 @@ gnt_main(); + gnt_quit(); + return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-02 21:52:42
|
Revision: 16401 Author: thekingant Date: 2006-07-02 14:52:38 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16401&view=rev Log Message: ----------- Backport SVN reivision #16400 from HEAD to v2_0_0 Original commit message: part of sf patch #1490646, from Jonty Wareing & Jono Cole "The user can now specify their AIM and Jabber ID in the preferences" Modified Paths: -------------- branches/v2_0_0/src/protocols/bonjour/bonjour.c branches/v2_0_0/src/protocols/bonjour/dns_sd.c Modified: branches/v2_0_0/src/protocols/bonjour/bonjour.c =================================================================== --- branches/v2_0_0/src/protocols/bonjour/bonjour.c 2006-07-02 21:52:06 UTC (rev 16400) +++ branches/v2_0_0/src/protocols/bonjour/bonjour.c 2006-07-02 21:52:38 UTC (rev 16401) @@ -127,8 +127,8 @@ bd->dns_sd_data->phsh = g_strdup(""); bd->dns_sd_data->email = g_strdup(gaim_account_get_string(account, "email", "")); bd->dns_sd_data->vc = g_strdup(""); - bd->dns_sd_data->jid = g_strdup(""); - bd->dns_sd_data->AIM = g_strdup(""); + bd->dns_sd_data->jid = g_strdup(gaim_account_get_string(account, "jid", "")); + bd->dns_sd_data->AIM = g_strdup(gaim_account_get_string(account, "AIM", "")); status = gaim_account_get_active_status(account); presence = gaim_account_get_presence(account); @@ -588,6 +588,12 @@ option = gaim_account_option_string_new(_("E-mail"), "email", ""); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); + option = gaim_account_option_string_new(_("AIM Account"), "AIM", ""); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); + + option = gaim_account_option_string_new(_("Jabber Account"), "jid", ""); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); + my_protocol = plugin; } Modified: branches/v2_0_0/src/protocols/bonjour/dns_sd.c =================================================================== --- branches/v2_0_0/src/protocols/bonjour/dns_sd.c 2006-07-02 21:52:06 UTC (rev 16400) +++ branches/v2_0_0/src/protocols/bonjour/dns_sd.c 2006-07-02 21:52:38 UTC (rev 16401) @@ -251,12 +251,20 @@ sw_text_record_add_key_and_string_value(dns_data, "port.p2pj", BONJOUR_DEFAULT_PORT); sw_text_record_add_key_and_string_value(dns_data, "phsh", data->phsh); sw_text_record_add_key_and_string_value(dns_data, "status", data->status); - sw_text_record_add_key_and_string_value(dns_data, "msg", data->msg); - sw_text_record_add_key_and_string_value(dns_data, "email", data->email); sw_text_record_add_key_and_string_value(dns_data, "vc", data->vc); - sw_text_record_add_key_and_string_value(dns_data, "jid", data->jid); - sw_text_record_add_key_and_string_value(dns_data, "AIM", data->AIM); + if ((data->email != NULL) && (*data->email != '\0')) + sw_text_record_add_key_and_string_value(dns_data, "email", data->email); + + if ((data->jid != NULL) && (*data->jid != '\0')) + sw_text_record_add_key_and_string_value(dns_data, "jid", data->jid); + + if ((data->AIM != NULL) && (*data->AIM != '\0')) + sw_text_record_add_key_and_string_value(dns_data, "AIM", data->AIM); + + if ((data->msg != NULL) && (*data->msg != '\0')) + sw_text_record_add_key_and_string_value(dns_data, "msg", data->msg); + /* Publish the service */ switch (type) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-02 21:52:15
|
Revision: 16400 Author: thekingant Date: 2006-07-02 14:52:06 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16400&view=rev Log Message: ----------- part of sf patch #1490646, from Jonty Wareing & Jono Cole "The user can now specify their AIM and Jabber ID in the preferences" Modified Paths: -------------- trunk/src/protocols/bonjour/bonjour.c trunk/src/protocols/bonjour/dns_sd.c Modified: trunk/src/protocols/bonjour/bonjour.c =================================================================== --- trunk/src/protocols/bonjour/bonjour.c 2006-07-02 21:12:54 UTC (rev 16399) +++ trunk/src/protocols/bonjour/bonjour.c 2006-07-02 21:52:06 UTC (rev 16400) @@ -127,8 +127,8 @@ bd->dns_sd_data->phsh = g_strdup(""); bd->dns_sd_data->email = g_strdup(gaim_account_get_string(account, "email", "")); bd->dns_sd_data->vc = g_strdup(""); - bd->dns_sd_data->jid = g_strdup(""); - bd->dns_sd_data->AIM = g_strdup(""); + bd->dns_sd_data->jid = g_strdup(gaim_account_get_string(account, "jid", "")); + bd->dns_sd_data->AIM = g_strdup(gaim_account_get_string(account, "AIM", "")); status = gaim_account_get_active_status(account); presence = gaim_account_get_presence(account); @@ -588,6 +588,12 @@ option = gaim_account_option_string_new(_("E-mail"), "email", ""); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); + option = gaim_account_option_string_new(_("AIM Account"), "AIM", ""); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); + + option = gaim_account_option_string_new(_("Jabber Account"), "jid", ""); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); + my_protocol = plugin; } Modified: trunk/src/protocols/bonjour/dns_sd.c =================================================================== --- trunk/src/protocols/bonjour/dns_sd.c 2006-07-02 21:12:54 UTC (rev 16399) +++ trunk/src/protocols/bonjour/dns_sd.c 2006-07-02 21:52:06 UTC (rev 16400) @@ -251,12 +251,20 @@ sw_text_record_add_key_and_string_value(dns_data, "port.p2pj", BONJOUR_DEFAULT_PORT); sw_text_record_add_key_and_string_value(dns_data, "phsh", data->phsh); sw_text_record_add_key_and_string_value(dns_data, "status", data->status); - sw_text_record_add_key_and_string_value(dns_data, "msg", data->msg); - sw_text_record_add_key_and_string_value(dns_data, "email", data->email); sw_text_record_add_key_and_string_value(dns_data, "vc", data->vc); - sw_text_record_add_key_and_string_value(dns_data, "jid", data->jid); - sw_text_record_add_key_and_string_value(dns_data, "AIM", data->AIM); + if ((data->email != NULL) && (*data->email != '\0')) + sw_text_record_add_key_and_string_value(dns_data, "email", data->email); + + if ((data->jid != NULL) && (*data->jid != '\0')) + sw_text_record_add_key_and_string_value(dns_data, "jid", data->jid); + + if ((data->AIM != NULL) && (*data->AIM != '\0')) + sw_text_record_add_key_and_string_value(dns_data, "AIM", data->AIM); + + if ((data->msg != NULL) && (*data->msg != '\0')) + sw_text_record_add_key_and_string_value(dns_data, "msg", data->msg); + /* Publish the service */ switch (type) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2006-07-02 21:13:00
|
Revision: 16399 Author: roast Date: 2006-07-02 14:12:54 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16399&view=rev Log Message: ----------- log creation now calls gaim_escape_filename fewer times; extra strings facilitates Modified Paths: -------------- branches/soc-2006-file-loggers/src/log.c Modified: branches/soc-2006-file-loggers/src/log.c =================================================================== --- branches/soc-2006-file-loggers/src/log.c 2006-07-02 19:34:04 UTC (rev 16398) +++ branches/soc-2006-file-loggers/src/log.c 2006-07-02 21:12:54 UTC (rev 16399) @@ -666,8 +666,8 @@ /* This log is new */ char *dir; struct tm *tm; - char *tz; - const char *date; + char *basename; + char *extname; char *filename; char *path; @@ -677,16 +677,19 @@ gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR); - // roast: tz must be strdup'd. gaim_escape_filename returns a pointer to static data, - // and I need it for escaping remote_user's name for the filename below tm = localtime(&log->time); - tz = g_strdup(gaim_escape_filename(gaim_utf8_strftime("%Z", tm))); - date = gaim_utf8_strftime("%Y-%m-%dT%H%M%S%z", tm); - filename = g_strdup_printf("%s_%s%s%s", - gaim_escape_filename(gaim_normalize(log->account, log->name)), - date, tz, ext ? ext : ""); + { // build basename + char * temp = g_strdup_printf("%s_%s", gaim_normalize(log->account, log->name), + gaim_utf8_strftime("%Y-%m-%dT%H%M%S%z%Z", tm)); + basename = g_strdup(gaim_escape_filename(temp)); + g_free(temp); + } + extname = g_strdup(gaim_escape_filename(ext)); + + filename = g_strdup_printf("%s%s", basename, extname ? extname : ""); + path = g_build_filename(dir, filename, NULL); g_free(filename); @@ -696,9 +699,7 @@ do { g_free(path); - filename = g_strdup_printf("%s_%s%s.%c%s", - gaim_escape_filename(gaim_normalize(log->account, log->name)), - date, tz, suffixchar, ext ? ext : ""); + filename = g_strdup_printf("%s%c%s", basename, suffixchar, extname ? extname : ""); path = g_build_filename(dir, filename, NULL); g_free(filename); @@ -709,9 +710,10 @@ /* we have a collision problem. not logging, and complain. */ gaim_conversation_write(log->conv, NULL, _("Logging of this conversation failed."), GAIM_MESSAGE_ERROR, time(NULL)); - g_free(tz); g_free(dir); g_free(path); + g_free(extname); + g_free(basename); return; } } @@ -727,14 +729,18 @@ if (log->conv != NULL) gaim_conversation_write(log->conv, NULL, _("Logging of this conversation failed."), GAIM_MESSAGE_ERROR, time(NULL)); - g_free(tz); g_free(dir); g_free(path); + g_free(extname); + g_free(basename); return; } data->path = g_strndup(path, strlen(path)); + g_free(dir); g_free(path); + g_free(extname); + g_free(basename); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2006-07-02 19:34:25
|
Revision: 16398 Author: roast Date: 2006-07-02 12:34:04 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16398&view=rev Log Message: ----------- file stream rewinding changed. counting written characters from fprintf doesn't count the \r's on windows. Modified Paths: -------------- branches/soc-2006-file-loggers/src/log.c Modified: branches/soc-2006-file-loggers/src/log.c =================================================================== --- branches/soc-2006-file-loggers/src/log.c 2006-07-02 18:33:13 UTC (rev 16397) +++ branches/soc-2006-file-loggers/src/log.c 2006-07-02 19:34:04 UTC (rev 16398) @@ -1083,14 +1083,19 @@ // append suffix to file and seek back to keep a valid XML document out of the user space buffer { - int tail = 0; + fpos_t tail; const char *date = gaim_utf8_strftime("%Y-%m-%d %H:%M:%S%z", NULL); - tail += fprintf(data->file, "\t<event time=\"%s\" type=\"logEnd\" />\n", date); - tail += fprintf(data->file, "</chat>\n"); + if (fgetpos(data->file, &tail) != 0) { + gaim_debug_error("log", "Could not save logfile stream position. Not writing tail."); + } + else { + fprintf(data->file, "\t<event time=\"%s\" type=\"logEnd\" />\n", date); + fprintf(data->file, "</chat>\n"); - if (fseek(data->file, -1*tail, SEEK_CUR) != 0) { - gaim_debug_error("log", "Could not seek backwards in logfile."); + if (fsetpos(data->file, &tail) != 0) { + gaim_debug_error("log", "Could not return logfile strem position after tail write."); + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2006-07-02 18:33:19
|
Revision: 16397 Author: roast Date: 2006-07-02 11:33:13 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16397&view=rev Log Message: ----------- wingaim port fixes: localtime(NULL) crashes windows; %F/%T are linux specific. Modified Paths: -------------- branches/soc-2006-file-loggers/src/log.c Modified: branches/soc-2006-file-loggers/src/log.c =================================================================== --- branches/soc-2006-file-loggers/src/log.c 2006-07-02 16:02:29 UTC (rev 16396) +++ branches/soc-2006-file-loggers/src/log.c 2006-07-02 18:33:13 UTC (rev 16397) @@ -1003,7 +1003,7 @@ const char *from, time_t time, const char *message) { char *msg_fixed; - char *date = g_strdup(gaim_utf8_strftime("%F %T%z", localtime(&time))); + char *date = g_strdup(gaim_utf8_strftime("%Y-%m-%d %H:%M:%S%z", localtime(&time))); GaimPlugin *plugin = gaim_find_prpl(gaim_account_get_protocol_id(log->account)); GaimLogCommonLoggerData *data = log->logger_data; @@ -1084,7 +1084,7 @@ // append suffix to file and seek back to keep a valid XML document out of the user space buffer { int tail = 0; - const char *date = gaim_utf8_strftime("%F %T%z", localtime(NULL)); + const char *date = gaim_utf8_strftime("%Y-%m-%d %H:%M:%S%z", NULL); tail += fprintf(data->file, "\t<event time=\"%s\" type=\"logEnd\" />\n", date); tail += fprintf(data->file, "</chat>\n"); @@ -1104,7 +1104,7 @@ GaimLogCommonLoggerData *data = log->logger_data; if (data) { if (data->file) { - const char *date = gaim_utf8_strftime("%F %T%z", localtime(NULL)); + const char *date = gaim_utf8_strftime("%Y-%m-%d %H:%M:%S%z", NULL); fprintf(data->file, "\t<event time=\"%s\" type=\"logEnd\" />\n", date); fprintf(data->file, "</chat>\n"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2006-07-02 16:05:50
|
Revision: 16396 Author: roast Date: 2006-07-02 09:02:29 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16396&view=rev Log Message: ----------- merged with svn trunk. 16338:16395. Modified Paths: -------------- branches/soc-2006-file-loggers/COPYRIGHT branches/soc-2006-file-loggers/ChangeLog branches/soc-2006-file-loggers/configure.ac branches/soc-2006-file-loggers/console/Makefile branches/soc-2006-file-loggers/console/gntblist.c branches/soc-2006-file-loggers/console/gntgaim.c branches/soc-2006-file-loggers/console/gntui.c branches/soc-2006-file-loggers/console/libgnt/gnt.h branches/soc-2006-file-loggers/console/libgnt/gntbox.c branches/soc-2006-file-loggers/console/libgnt/gntbox.h branches/soc-2006-file-loggers/console/libgnt/gntbutton.c branches/soc-2006-file-loggers/console/libgnt/gntcolors.c branches/soc-2006-file-loggers/console/libgnt/gntcolors.h branches/soc-2006-file-loggers/console/libgnt/gntentry.c branches/soc-2006-file-loggers/console/libgnt/gntentry.h branches/soc-2006-file-loggers/console/libgnt/gntkeys.h branches/soc-2006-file-loggers/console/libgnt/gntlabel.c branches/soc-2006-file-loggers/console/libgnt/gntmain.c branches/soc-2006-file-loggers/console/libgnt/gnttree.c branches/soc-2006-file-loggers/console/libgnt/gntwidget.c branches/soc-2006-file-loggers/console/libgnt/gntwidget.h branches/soc-2006-file-loggers/doc/C-HOWTO.dox branches/soc-2006-file-loggers/pixmaps/smileys/default/Makefile.am branches/soc-2006-file-loggers/pixmaps/smileys/default/theme branches/soc-2006-file-loggers/pixmaps/status/default/Makefile.am branches/soc-2006-file-loggers/src/blist.c branches/soc-2006-file-loggers/src/blist.h branches/soc-2006-file-loggers/src/buddyicon.c branches/soc-2006-file-loggers/src/dnssrv.c branches/soc-2006-file-loggers/src/gtkblist.c branches/soc-2006-file-loggers/src/protocols/Makefile.am branches/soc-2006-file-loggers/src/protocols/bonjour/jabber.c branches/soc-2006-file-loggers/src/protocols/bonjour/jabber.h branches/soc-2006-file-loggers/src/protocols/irc/cmds.c branches/soc-2006-file-loggers/src/protocols/irc/irc.h branches/soc-2006-file-loggers/src/protocols/irc/msgs.c branches/soc-2006-file-loggers/src/protocols/irc/parse.c branches/soc-2006-file-loggers/src/protocols/jabber/jabber.c branches/soc-2006-file-loggers/src/protocols/jabber/presence.c branches/soc-2006-file-loggers/src/protocols/msn/dialog.c branches/soc-2006-file-loggers/src/protocols/msn/session.c branches/soc-2006-file-loggers/src/protocols/oscar/family_feedbag.c branches/soc-2006-file-loggers/src/protocols/oscar/family_oservice.c branches/soc-2006-file-loggers/src/protocols/oscar/oscar.c branches/soc-2006-file-loggers/src/protocols/oscar/oscar.h branches/soc-2006-file-loggers/src/protocols/silc/silc.c branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo.c Added Paths: ----------- branches/soc-2006-file-loggers/console/gntconv.c branches/soc-2006-file-loggers/console/gntconv.h branches/soc-2006-file-loggers/console/libgnt/AUTHORS branches/soc-2006-file-loggers/console/libgnt/COPYING branches/soc-2006-file-loggers/console/libgnt/ChangeLog branches/soc-2006-file-loggers/console/libgnt/INSTALL branches/soc-2006-file-loggers/console/libgnt/Makefile.am branches/soc-2006-file-loggers/console/libgnt/NEWS branches/soc-2006-file-loggers/console/libgnt/README branches/soc-2006-file-loggers/console/libgnt/autogen.sh branches/soc-2006-file-loggers/console/libgnt/configure.ac branches/soc-2006-file-loggers/console/libgnt/gnt.pc.in branches/soc-2006-file-loggers/console/libgnt/gnttextview.c branches/soc-2006-file-loggers/console/libgnt/gnttextview.h branches/soc-2006-file-loggers/console/libgnt/test/ branches/soc-2006-file-loggers/console/libgnt/test/Makefile branches/soc-2006-file-loggers/console/libgnt/test/focus.c branches/soc-2006-file-loggers/console/libgnt/test/multiwin.c branches/soc-2006-file-loggers/console/libgnt/test/tv.c branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_0.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_1.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_10.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_11.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_12.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_13.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_14.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_15.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_16.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_17.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_18.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_19.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_2.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_20.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_21.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_22.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_23.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_24.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_25.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_26.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_27.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_28.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_29.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_3.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_30.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_31.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_32.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_33.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_34.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_35.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_36.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_37.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_38.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_39.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_4.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_40.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_41.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_42.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_43.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_44.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_45.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_46.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_47.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_48.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_49.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_5.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_50.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_51.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_52.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_53.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_54.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_55.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_56.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_57.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_58.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_59.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_6.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_60.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_61.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_62.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_63.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_64.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_65.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_66.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_67.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_68.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_69.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_7.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_70.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_71.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_72.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_73.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_74.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_75.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_76.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_77.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_78.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_79.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_8.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_80.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_81.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_82.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_83.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_84.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_85.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_86.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_87.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_88.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_89.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_9.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_90.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_91.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_92.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_93.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_94.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_95.gif branches/soc-2006-file-loggers/pixmaps/status/default/qq.png branches/soc-2006-file-loggers/src/protocols/qq/ branches/soc-2006-file-loggers/src/protocols/qq/Makefile.am branches/soc-2006-file-loggers/src/protocols/qq/Makefile.mingw branches/soc-2006-file-loggers/src/protocols/qq/TODO branches/soc-2006-file-loggers/src/protocols/qq/buddy_info.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_info.h branches/soc-2006-file-loggers/src/protocols/qq/buddy_list.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_list.h branches/soc-2006-file-loggers/src/protocols/qq/buddy_opt.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_opt.h branches/soc-2006-file-loggers/src/protocols/qq/buddy_status.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_status.h branches/soc-2006-file-loggers/src/protocols/qq/char_conv.c branches/soc-2006-file-loggers/src/protocols/qq/char_conv.h branches/soc-2006-file-loggers/src/protocols/qq/crypt.c branches/soc-2006-file-loggers/src/protocols/qq/crypt.h branches/soc-2006-file-loggers/src/protocols/qq/file_trans.c branches/soc-2006-file-loggers/src/protocols/qq/file_trans.h branches/soc-2006-file-loggers/src/protocols/qq/group.c branches/soc-2006-file-loggers/src/protocols/qq/group.h branches/soc-2006-file-loggers/src/protocols/qq/group_admindlg.c branches/soc-2006-file-loggers/src/protocols/qq/group_admindlg.h branches/soc-2006-file-loggers/src/protocols/qq/group_conv.c branches/soc-2006-file-loggers/src/protocols/qq/group_conv.h branches/soc-2006-file-loggers/src/protocols/qq/group_find.c branches/soc-2006-file-loggers/src/protocols/qq/group_find.h branches/soc-2006-file-loggers/src/protocols/qq/group_free.c branches/soc-2006-file-loggers/src/protocols/qq/group_free.h branches/soc-2006-file-loggers/src/protocols/qq/group_hash.c branches/soc-2006-file-loggers/src/protocols/qq/group_hash.h branches/soc-2006-file-loggers/src/protocols/qq/group_im.c branches/soc-2006-file-loggers/src/protocols/qq/group_im.h branches/soc-2006-file-loggers/src/protocols/qq/group_info.c branches/soc-2006-file-loggers/src/protocols/qq/group_info.h branches/soc-2006-file-loggers/src/protocols/qq/group_join.c branches/soc-2006-file-loggers/src/protocols/qq/group_join.h branches/soc-2006-file-loggers/src/protocols/qq/group_misc.c branches/soc-2006-file-loggers/src/protocols/qq/group_misc.h branches/soc-2006-file-loggers/src/protocols/qq/group_network.c branches/soc-2006-file-loggers/src/protocols/qq/group_network.h branches/soc-2006-file-loggers/src/protocols/qq/group_opt.c branches/soc-2006-file-loggers/src/protocols/qq/group_opt.h branches/soc-2006-file-loggers/src/protocols/qq/group_search.c branches/soc-2006-file-loggers/src/protocols/qq/group_search.h branches/soc-2006-file-loggers/src/protocols/qq/header_info.c branches/soc-2006-file-loggers/src/protocols/qq/header_info.h branches/soc-2006-file-loggers/src/protocols/qq/im.c branches/soc-2006-file-loggers/src/protocols/qq/im.h branches/soc-2006-file-loggers/src/protocols/qq/infodlg.c branches/soc-2006-file-loggers/src/protocols/qq/infodlg.h branches/soc-2006-file-loggers/src/protocols/qq/ip_location.c branches/soc-2006-file-loggers/src/protocols/qq/ip_location.h branches/soc-2006-file-loggers/src/protocols/qq/keep_alive.c branches/soc-2006-file-loggers/src/protocols/qq/keep_alive.h branches/soc-2006-file-loggers/src/protocols/qq/login_logout.c branches/soc-2006-file-loggers/src/protocols/qq/login_logout.h branches/soc-2006-file-loggers/src/protocols/qq/packet_parse.c branches/soc-2006-file-loggers/src/protocols/qq/packet_parse.h branches/soc-2006-file-loggers/src/protocols/qq/qq.c branches/soc-2006-file-loggers/src/protocols/qq/qq.h branches/soc-2006-file-loggers/src/protocols/qq/qq_proxy.c branches/soc-2006-file-loggers/src/protocols/qq/qq_proxy.h branches/soc-2006-file-loggers/src/protocols/qq/recv_core.c branches/soc-2006-file-loggers/src/protocols/qq/recv_core.h branches/soc-2006-file-loggers/src/protocols/qq/send_core.c branches/soc-2006-file-loggers/src/protocols/qq/send_core.h branches/soc-2006-file-loggers/src/protocols/qq/send_file.c branches/soc-2006-file-loggers/src/protocols/qq/send_file.h branches/soc-2006-file-loggers/src/protocols/qq/sendqueue.c branches/soc-2006-file-loggers/src/protocols/qq/sendqueue.h branches/soc-2006-file-loggers/src/protocols/qq/show.c branches/soc-2006-file-loggers/src/protocols/qq/show.h branches/soc-2006-file-loggers/src/protocols/qq/sys_msg.c branches/soc-2006-file-loggers/src/protocols/qq/sys_msg.h branches/soc-2006-file-loggers/src/protocols/qq/udp_proxy_s5.c branches/soc-2006-file-loggers/src/protocols/qq/udp_proxy_s5.h branches/soc-2006-file-loggers/src/protocols/qq/utils.c branches/soc-2006-file-loggers/src/protocols/qq/utils.h Removed Paths: ------------- branches/soc-2006-file-loggers/console/libgnt/Makefile branches/soc-2006-file-loggers/console/libgnt/test/Makefile branches/soc-2006-file-loggers/console/libgnt/test/focus.c branches/soc-2006-file-loggers/console/libgnt/test/multiwin.c branches/soc-2006-file-loggers/console/libgnt/test/tv.c branches/soc-2006-file-loggers/src/protocols/qq/Makefile.am branches/soc-2006-file-loggers/src/protocols/qq/Makefile.mingw branches/soc-2006-file-loggers/src/protocols/qq/TODO branches/soc-2006-file-loggers/src/protocols/qq/buddy_info.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_info.h branches/soc-2006-file-loggers/src/protocols/qq/buddy_list.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_list.h branches/soc-2006-file-loggers/src/protocols/qq/buddy_opt.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_opt.h branches/soc-2006-file-loggers/src/protocols/qq/buddy_status.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_status.h branches/soc-2006-file-loggers/src/protocols/qq/char_conv.c branches/soc-2006-file-loggers/src/protocols/qq/char_conv.h branches/soc-2006-file-loggers/src/protocols/qq/crypt.c branches/soc-2006-file-loggers/src/protocols/qq/crypt.h branches/soc-2006-file-loggers/src/protocols/qq/file_trans.c branches/soc-2006-file-loggers/src/protocols/qq/file_trans.h branches/soc-2006-file-loggers/src/protocols/qq/group.c branches/soc-2006-file-loggers/src/protocols/qq/group.h branches/soc-2006-file-loggers/src/protocols/qq/group_admindlg.c branches/soc-2006-file-loggers/src/protocols/qq/group_admindlg.h branches/soc-2006-file-loggers/src/protocols/qq/group_conv.c branches/soc-2006-file-loggers/src/protocols/qq/group_conv.h branches/soc-2006-file-loggers/src/protocols/qq/group_find.c branches/soc-2006-file-loggers/src/protocols/qq/group_find.h branches/soc-2006-file-loggers/src/protocols/qq/group_free.c branches/soc-2006-file-loggers/src/protocols/qq/group_free.h branches/soc-2006-file-loggers/src/protocols/qq/group_hash.c branches/soc-2006-file-loggers/src/protocols/qq/group_hash.h branches/soc-2006-file-loggers/src/protocols/qq/group_im.c branches/soc-2006-file-loggers/src/protocols/qq/group_im.h branches/soc-2006-file-loggers/src/protocols/qq/group_info.c branches/soc-2006-file-loggers/src/protocols/qq/group_info.h branches/soc-2006-file-loggers/src/protocols/qq/group_join.c branches/soc-2006-file-loggers/src/protocols/qq/group_join.h branches/soc-2006-file-loggers/src/protocols/qq/group_misc.c branches/soc-2006-file-loggers/src/protocols/qq/group_misc.h branches/soc-2006-file-loggers/src/protocols/qq/group_network.c branches/soc-2006-file-loggers/src/protocols/qq/group_network.h branches/soc-2006-file-loggers/src/protocols/qq/group_opt.c branches/soc-2006-file-loggers/src/protocols/qq/group_opt.h branches/soc-2006-file-loggers/src/protocols/qq/group_search.c branches/soc-2006-file-loggers/src/protocols/qq/group_search.h branches/soc-2006-file-loggers/src/protocols/qq/header_info.c branches/soc-2006-file-loggers/src/protocols/qq/header_info.h branches/soc-2006-file-loggers/src/protocols/qq/im.c branches/soc-2006-file-loggers/src/protocols/qq/im.h branches/soc-2006-file-loggers/src/protocols/qq/infodlg.c branches/soc-2006-file-loggers/src/protocols/qq/infodlg.h branches/soc-2006-file-loggers/src/protocols/qq/ip_location.c branches/soc-2006-file-loggers/src/protocols/qq/ip_location.h branches/soc-2006-file-loggers/src/protocols/qq/keep_alive.c branches/soc-2006-file-loggers/src/protocols/qq/keep_alive.h branches/soc-2006-file-loggers/src/protocols/qq/login_logout.c branches/soc-2006-file-loggers/src/protocols/qq/login_logout.h branches/soc-2006-file-loggers/src/protocols/qq/packet_parse.c branches/soc-2006-file-loggers/src/protocols/qq/packet_parse.h branches/soc-2006-file-loggers/src/protocols/qq/qq.c branches/soc-2006-file-loggers/src/protocols/qq/qq.h branches/soc-2006-file-loggers/src/protocols/qq/qq_proxy.c branches/soc-2006-file-loggers/src/protocols/qq/qq_proxy.h branches/soc-2006-file-loggers/src/protocols/qq/recv_core.c branches/soc-2006-file-loggers/src/protocols/qq/recv_core.h branches/soc-2006-file-loggers/src/protocols/qq/send_core.c branches/soc-2006-file-loggers/src/protocols/qq/send_core.h branches/soc-2006-file-loggers/src/protocols/qq/send_file.c branches/soc-2006-file-loggers/src/protocols/qq/send_file.h branches/soc-2006-file-loggers/src/protocols/qq/sendqueue.c branches/soc-2006-file-loggers/src/protocols/qq/sendqueue.h branches/soc-2006-file-loggers/src/protocols/qq/show.c branches/soc-2006-file-loggers/src/protocols/qq/show.h branches/soc-2006-file-loggers/src/protocols/qq/sys_msg.c branches/soc-2006-file-loggers/src/protocols/qq/sys_msg.h branches/soc-2006-file-loggers/src/protocols/qq/udp_proxy_s5.c branches/soc-2006-file-loggers/src/protocols/qq/udp_proxy_s5.h branches/soc-2006-file-loggers/src/protocols/qq/utils.c branches/soc-2006-file-loggers/src/protocols/qq/utils.h Modified: branches/soc-2006-file-loggers/COPYRIGHT =================================================================== --- branches/soc-2006-file-loggers/COPYRIGHT 2006-07-02 15:49:54 UTC (rev 16395) +++ branches/soc-2006-file-loggers/COPYRIGHT 2006-07-02 16:02:29 UTC (rev 16396) @@ -59,6 +59,7 @@ Eoin Coffey Jason Cohen Todd Cohen +Jono Cole Nathan Conrad Felipe Contreras Alex Converse @@ -302,6 +303,7 @@ Wan Hing Wah Philip Walford Nathan Walp +Jonty Wareing Eric Warmenhoven Adam J. Warrington Andrew Wellington Modified: branches/soc-2006-file-loggers/ChangeLog =================================================================== --- branches/soc-2006-file-loggers/ChangeLog 2006-07-02 15:49:54 UTC (rev 16395) +++ branches/soc-2006-file-loggers/ChangeLog 2006-07-02 16:02:29 UTC (rev 16396) @@ -130,6 +130,7 @@ channel or change your nick * Added /nickserv, /memoserv, /chanserv and /operserv commands (Joao Luís Marques Pinto) + * Added CTCP VERSION via /version (Andrej Krivulčík) Jabber Features: * Support for SRV lookups Modified: branches/soc-2006-file-loggers/configure.ac =================================================================== --- branches/soc-2006-file-loggers/configure.ac 2006-07-02 15:49:54 UTC (rev 16395) +++ branches/soc-2006-file-loggers/configure.ac 2006-07-02 16:02:29 UTC (rev 16396) @@ -401,7 +401,7 @@ fi if test "x$STATIC_PRPLS" = "xall" ; then - STATIC_PRPLS="bonjour gg irc jabber msn novell oscar sametime silc simple yahoo zephyr" + STATIC_PRPLS="bonjour gg irc jabber msn novell oscar qq sametime silc simple yahoo zephyr" fi if test "x$have_meanwhile" != "xyes" ; then STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/sametime//'` @@ -436,6 +436,7 @@ msn) static_msn=yes ;; novell) static_novell=yes ;; oscar) static_oscar=yes ;; + qq) static_qq=yes ;; sametime) static_sametime=yes ;; silc) static_silc=yes ;; simple) static_simple=yes ;; @@ -452,6 +453,7 @@ AM_CONDITIONAL(STATIC_MSN, test "x$static_msn" = "xyes") AM_CONDITIONAL(STATIC_NOVELL, test "x$static_novell" = "xyes") AM_CONDITIONAL(STATIC_OSCAR, test "x$static_oscar" = "xyes") +AM_CONDITIONAL(STATIC_QQ, test "x$static_qq" = "xyes") AM_CONDITIONAL(STATIC_SAMETIME, test "x$static_sametime" = "xyes" -a "x$have_meanwhile" = "xyes") AM_CONDITIONAL(STATIC_SILC, test "x$static_silc" = "xyes" -a "x$silcincludes" = "xyes" -a "x$silcclient" = "xyes") AM_CONDITIONAL(STATIC_SIMPLE, test "x$static_simple" = "xyes") @@ -464,7 +466,7 @@ AC_ARG_WITH(dynamic_prpls, [AC_HELP_STRING([--with-dynamic-prpls], [specify which protocols to build dynamically])], [DYNAMIC_PRPLS=`echo $withval | $sedpath 's/,/ /g'`]) if test "x$DYNAMIC_PRPLS" = "xall" ; then - DYNAMIC_PRPLS="bonjour gg irc jabber msn novell oscar sametime silc simple yahoo zephyr" + DYNAMIC_PRPLS="bonjour gg irc jabber msn novell oscar qq sametime silc simple yahoo zephyr" fi if test "x$have_meanwhile" != "xyes"; then DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/sametime//'` @@ -488,6 +490,7 @@ msn) dynamic_msn=yes ;; novell) dynamic_novell=yes ;; oscar) dynamic_oscar=yes ;; + qq) dynamic_qq=yes ;; sametime) dynamic_sametime=yes ;; silc) dynamic_silc=yes ;; simple) dynamic_simple=yes ;; @@ -504,6 +507,7 @@ AM_CONDITIONAL(DYNAMIC_MSN, test "x$dynamic_msn" = "xyes") AM_CONDITIONAL(DYNAMIC_NOVELL, test "x$dynamic_novell" = "xyes") AM_CONDITIONAL(DYNAMIC_OSCAR, test "x$dynamic_oscar" = "xyes") +AM_CONDITIONAL(DYNAMIC_QQ, test "x$dynamic_qq" = "xyes") AM_CONDITIONAL(DYNAMIC_SAMETIME, test "x$dynamic_sametime" = "xyes" -a "x$have_meanwhile" = "xyes") AM_CONDITIONAL(DYNAMIC_SILC, test "x$dynamic_silc" = "xyes" -a "x$silcincludes" = "xyes" -a "x$silcclient" = "xyes") AM_CONDITIONAL(DYNAMIC_SIMPLE, test "x$dynamic_simple" = "xyes") @@ -1772,6 +1776,7 @@ src/protocols/napster/Makefile src/protocols/novell/Makefile src/protocols/oscar/Makefile + src/protocols/qq/Makefile src/protocols/sametime/Makefile src/protocols/silc/Makefile src/protocols/simple/Makefile Modified: branches/soc-2006-file-loggers/console/Makefile =================================================================== --- branches/soc-2006-file-loggers/console/Makefile 2006-07-02 15:49:54 UTC (rev 16395) +++ branches/soc-2006-file-loggers/console/Makefile 2006-07-02 16:02:29 UTC (rev 16396) @@ -1,30 +1,32 @@ -CFLAGS=`pkg-config --cflags gaim gobject-2.0` -g -I./libgnt/ -LDFLAGS=`pkg-config --libs gaim gobject-2.0 libxml-2.0` -lncursesw -L./libgnt/ -lgnt -pg +CC=gcc +CFLAGS=`pkg-config --cflags gaim gobject-2.0 gnt` -g -Wall +LDFLAGS=`pkg-config --libs gaim gobject-2.0 libxml-2.0 gnt` -pg GG_SOURCES = \ gntblist.c \ + gntconv.c \ gntui.c GG_HEADERS = \ gntblist.h \ + gntconv.h \ gntui.h GG_OBJECTS = \ gntblist.o \ + gntconv.o \ gntui.o -all: - cd libgnt && make - make gntgaim +all: gntgaim gntgaim: gntgaim.o $(GG_OBJECTS) $(CC) -o gntgaim gntgaim.o $(GG_OBJECTS) $(LDFLAGS) gntblist.o: gntblist.c $(GG_HEADERS) +gntconv.o: gntconv.c $(GG_HEADERS) gntgaim.o: gntgaim.c gntgaim.h $(GG_HEADERS) gntui.o: gntui.c $(GG_HEADERS) clean: - cd libgnt && make clean - rm *.o - rm gntgaim + rm -f *.o + rm -f gntgaim Modified: branches/soc-2006-file-loggers/console/gntblist.c =================================================================== --- branches/soc-2006-file-loggers/console/gntblist.c 2006-07-02 15:49:54 UTC (rev 16395) +++ branches/soc-2006-file-loggers/console/gntblist.c 2006-07-02 16:02:29 UTC (rev 16396) @@ -1,11 +1,12 @@ -#include <gaim/account.h> -#include <gaim/blist.h> +#include <account.h> +#include <blist.h> +#include <server.h> #include <signal.h> -#include <gaim/util.h> -#include <gaim/server.h> +#include <util.h> #include "gntgaim.h" #include "gntbox.h" +#include "gntlabel.h" #include "gnttree.h" #include "gntblist.h" @@ -24,6 +25,7 @@ static void add_buddy(GaimBuddy *buddy, GGBlist *ggblist); static void add_group(GaimGroup *group, GGBlist *ggblist); +static void add_chat(GaimChat *chat, GGBlist *ggblist); static void add_node(GaimBlistNode *node, GGBlist *ggblist); static void draw_tooltip(GGBlist *ggblist); @@ -38,6 +40,8 @@ add_buddy((GaimBuddy*)node, ggblist); else if (GAIM_BLIST_NODE_IS_GROUP(node)) add_group((GaimGroup*)node, ggblist); + else if (GAIM_BLIST_NODE_IS_CHAT(node)) + add_chat((GaimChat *)node, ggblist); draw_tooltip(ggblist); } @@ -81,6 +85,10 @@ else node_remove(gaim_get_blist(), node); } + else if (GAIM_BLIST_NODE_IS_CHAT(node)) + { + add_chat((GaimChat *)node, list->ui_data); + } } static void @@ -121,52 +129,82 @@ } static const char * -get_buddy_display_name(GaimBuddy *buddy) +get_display_name(GaimBlistNode *node) { static char text[2096]; - char status[8]; - GaimStatusPrimitive prim; - GaimPresence *presence; - GaimStatus *now; + char status[8] = " "; + const char *name = NULL; - presence = gaim_buddy_get_presence(buddy); - now = gaim_presence_get_active_status(presence); + if (GAIM_BLIST_NODE_IS_BUDDY(node)) + { + GaimBuddy *buddy = (GaimBuddy *)node; + GaimStatusPrimitive prim; + GaimPresence *presence; + GaimStatus *now; - prim = gaim_status_type_get_primitive(gaim_status_get_type(now)); + + presence = gaim_buddy_get_presence(buddy); + now = gaim_presence_get_active_status(presence); - switch(prim) - { + prim = gaim_status_type_get_primitive(gaim_status_get_type(now)); + + switch(prim) + { #if 1 - case GAIM_STATUS_OFFLINE: - strncpy(status, "x", sizeof(status) - 1); - break; - case GAIM_STATUS_AVAILABLE: - strncpy(status, "o", sizeof(status) - 1); - break; - default: - strncpy(status, ".", sizeof(status) - 1); - break; + case GAIM_STATUS_OFFLINE: + strncpy(status, "x", sizeof(status) - 1); + break; + case GAIM_STATUS_AVAILABLE: + strncpy(status, "o", sizeof(status) - 1); + break; + default: + strncpy(status, ".", sizeof(status) - 1); + break; #else - /* XXX: Let's use these some time */ - case GAIM_STATUS_OFFLINE: - strncpy(status, "⊗", sizeof(status) - 1); - break; - case GAIM_STATUS_AVAILABLE: - /* XXX: Detect idleness */ - strncpy(status, "◯", sizeof(status) - 1); - break; - default: - strncpy(status, "⊖", sizeof(status) - 1); - break; + /* XXX: Let's use these some time */ + case GAIM_STATUS_OFFLINE: + strncpy(status, "⊗", sizeof(status) - 1); + break; + case GAIM_STATUS_AVAILABLE: + /* XXX: Detect idleness */ + strncpy(status, "◯", sizeof(status) - 1); + break; + default: + strncpy(status, "⊖", sizeof(status) - 1); + break; #endif + } + name = gaim_buddy_get_alias(buddy); } + else if (GAIM_BLIST_NODE_IS_CHAT(node)) + { + GaimChat *chat = (GaimChat*)node; + name = gaim_chat_get_name(chat); - snprintf(text, sizeof(text) - 1, "%s %s", status, gaim_buddy_get_alias(buddy)); + strncpy(status, "~", sizeof(status) - 1); + } + snprintf(text, sizeof(text) - 1, "%s %s", status, name); + return text; } static void +add_chat(GaimChat *chat, GGBlist *ggblist) +{ + GaimGroup *group; + GaimBlistNode *node = (GaimBlistNode *)chat; + if (node->ui_data) + return; + + group = gaim_chat_get_group(chat); + add_node((GaimBlistNode*)group, ggblist); + + node->ui_data = gnt_tree_add_row_after(GNT_TREE(ggblist->tree), chat, + get_display_name(node), group, NULL); +} + +static void add_buddy(GaimBuddy *buddy, GGBlist *ggblist) { GaimGroup *group; @@ -178,9 +216,10 @@ add_node((GaimBlistNode*)group, ggblist); node->ui_data = gnt_tree_add_row_after(GNT_TREE(ggblist->tree), buddy, - get_buddy_display_name(buddy), group, NULL); + get_display_name(node), group, NULL); } +#if 0 static void buddy_signed_on(GaimBuddy *buddy, GGBlist *ggblist) { @@ -192,6 +231,7 @@ { node_remove(gaim_get_blist(), (GaimBlistNode*)buddy); } +#endif GaimBlistUiOps *gg_blist_get_ui_ops() { @@ -201,7 +241,21 @@ static void selection_activate(GntWidget *widget, GGBlist *ggblist) { - gnt_widget_set_focus(widget, FALSE); + GntTree *tree = GNT_TREE(ggblist->tree); + GaimBlistNode *node = gnt_tree_get_selection_data(tree); + + if (GAIM_BLIST_NODE_IS_BUDDY(node)) + { + GaimBuddy *buddy = (GaimBuddy *)node; + gaim_conversation_new(GAIM_CONV_TYPE_IM, + gaim_buddy_get_account(buddy), + gaim_buddy_get_name(buddy)); + } + else if (GAIM_BLIST_NODE_IS_CHAT(node)) + { + GaimChat *chat = (GaimChat*)node; + serv_join_chat(chat->account->gc, chat->components); + } } static void @@ -214,12 +268,15 @@ GaimPluginProtocolInfo *prpl_info; GaimAccount *account; GntTree *tree; - GntWidget *widget, *box, *label; + GntWidget *widget, *box; char *title = NULL; widget = ggblist->tree; tree = GNT_TREE(widget); + if (!gnt_widget_has_focus(ggblist->tree)) + return; + if (ggblist->tooltip) { /* XXX: Once we can properly redraw on expose events, this can be removed at the end @@ -268,6 +325,15 @@ title = g_strdup(group->name); } + else if (GAIM_BLIST_NODE_IS_CHAT(node)) + { + GaimChat *chat = (GaimChat *)node; + GaimAccount *account = chat->account; + + g_string_append_printf(str, _("Account: %s"), gaim_account_get_username(account)); + + title = g_strdup(gaim_chat_get_name(chat)); + } else { g_string_free(str, TRUE); @@ -286,7 +352,7 @@ GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_NO_SHADOW); gnt_box_set_title(GNT_BOX(box), title); - gnt_box_add_widget(GNT_BOX(box), GNT_WIDGET(gnt_label_new(str->str))); + gnt_box_add_widget(GNT_BOX(box), gnt_label_new(str->str)); gnt_widget_set_position(box, x, y); gnt_widget_draw(box); @@ -319,13 +385,14 @@ return TRUE; } } + return FALSE; } static void buddy_status_changed(GaimBuddy *buddy, GaimStatus *old, GaimStatus *now, GGBlist *ggblist) { - gnt_tree_change_text(GNT_TREE(ggblist->tree), buddy, get_buddy_display_name(buddy)); + gnt_tree_change_text(GNT_TREE(ggblist->tree), buddy, get_display_name((GaimBlistNode*)buddy)); if (ggblist->tnode == (GaimBlistNode*)buddy) draw_tooltip(ggblist); } @@ -344,7 +411,7 @@ ggblist->tree = gnt_tree_new(); GNT_WIDGET_SET_FLAGS(ggblist->tree, GNT_WIDGET_NO_BORDER); - gnt_widget_set_size(ggblist->tree, 25, getmaxy(stdscr) - 2); + gnt_widget_set_size(ggblist->tree, 25, getmaxy(stdscr) - 3); gnt_box_add_widget(GNT_BOX(ggblist->window), ggblist->tree); gnt_widget_show(ggblist->window); Copied: branches/soc-2006-file-loggers/console/gntconv.c (from rev 16395, trunk/console/gntconv.c) =================================================================== --- branches/soc-2006-file-loggers/console/gntconv.c (rev 0) +++ branches/soc-2006-file-loggers/console/gntconv.c 2006-07-02 16:02:29 UTC (rev 16396) @@ -0,0 +1,263 @@ +#include <string.h> +#include <util.h> + +#include "gntgaim.h" +#include "gntconv.h" + +#include "gnt.h" +#include "gntbox.h" +#include "gntentry.h" +#include "gnttextview.h" + +GHashTable *ggconvs; + +typedef struct _GGConv GGConv; +typedef struct _GGConvChat GGConvChat; +typedef struct _GGConvIm GGConvIm; + +struct _GGConv +{ + GaimConversation *conv; + + GntWidget *window; /* the container */ + GntWidget *entry; /* entry */ + GntWidget *tv; /* text-view */ + + union + { + GGConvChat *chat; + GGConvIm *im; + } u; +}; + +struct _GGConvChat +{ + GntWidget *userlist; /* the userlist */ +}; + +struct _GGConvIm +{ + void *nothing_for_now; +}; + +static gboolean +entry_key_pressed(GntWidget *w, const char *key, GGConv *ggconv) +{ + if (key[0] == '\r' && key[1] == 0) + { + const char *text = gnt_entry_get_text(GNT_ENTRY(ggconv->entry)); + switch (gaim_conversation_get_type(ggconv->conv)) + { + case GAIM_CONV_TYPE_IM: + gaim_conv_im_send_with_flags(GAIM_CONV_IM(ggconv->conv), text, GAIM_MESSAGE_SEND); + break; + case GAIM_CONV_TYPE_CHAT: + gaim_conv_chat_send(GAIM_CONV_CHAT(ggconv->conv), text); + break; + default: + g_return_val_if_reached(FALSE); + } + gnt_entry_clear(GNT_ENTRY(ggconv->entry)); + return TRUE; + } + else if (key[0] == 27) + { + if (strcmp(key+1, GNT_KEY_DOWN) == 0) + gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), 1); + else if (strcmp(key+1, GNT_KEY_UP) == 0) + gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), -1); + else if (strcmp(key+1, GNT_KEY_PGDOWN) == 0) + gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), ggconv->tv->priv.height - 2); + else if (strcmp(key+1, GNT_KEY_PGUP) == 0) + gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), -(ggconv->tv->priv.height - 2)); + else + return FALSE; + return TRUE; + } + + return FALSE; +} + +static void +closing_window(GntWidget *window, GGConv *ggconv) +{ + ggconv->window = NULL; + gaim_conversation_destroy(ggconv->conv); +} + +static void +gg_create_conversation(GaimConversation *conv) +{ + GGConv *ggc = g_hash_table_lookup(ggconvs, conv); + char *title; + GaimConversationType type; + + if (ggc) + return; + + ggc = g_new0(GGConv, 1); + g_hash_table_insert(ggconvs, conv, ggc); + + ggc->conv = conv; + + type = gaim_conversation_get_type(conv); + title = g_strdup_printf(_("%s"), gaim_conversation_get_name(conv)); + ggc->window = gnt_box_new(FALSE, TRUE); + gnt_box_set_title(GNT_BOX(ggc->window), title); + gnt_box_set_toplevel(GNT_BOX(ggc->window), TRUE); + gnt_widget_set_name(ggc->window, title); + + ggc->tv = gnt_text_view_new(); + gnt_box_add_widget(GNT_BOX(ggc->window), ggc->tv); + gnt_widget_set_name(ggc->tv, "conversation-window-textview"); + gnt_widget_set_size(ggc->tv, getmaxx(stdscr) - 40, getmaxy(stdscr) - 15); + + ggc->entry = gnt_entry_new(NULL); + gnt_box_add_widget(GNT_BOX(ggc->window), ggc->entry); + gnt_widget_set_name(ggc->entry, "conversation-window-entry"); + gnt_widget_set_size(ggc->entry, getmaxx(stdscr) - 40, 1); + + g_signal_connect(G_OBJECT(ggc->entry), "key_pressed", G_CALLBACK(entry_key_pressed), ggc); + g_signal_connect(G_OBJECT(ggc->window), "destroy", G_CALLBACK(closing_window), ggc); + + gnt_widget_set_position(ggc->window, 32, 0); + gnt_widget_show(ggc->window); + + g_free(title); +} + +static void +gg_destroy_conversation(GaimConversation *conv) +{ + g_hash_table_remove(ggconvs, conv); +} + +static void +gg_write_common(GaimConversation *conv, const char *who, const char *message, + GaimMessageFlags flags, time_t mtime) +{ + GGConv *ggconv = g_hash_table_lookup(ggconvs, conv); + char *strip; + GntTextViewFlags fl = 0; + + g_return_if_fail(ggconv != NULL); + + if (who && *who && (flags & (GAIM_MESSAGE_SEND | GAIM_MESSAGE_RECV))) + { + char * name = g_strdup_printf("%s: ", who); + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), + name, GNT_TEXT_FLAG_BOLD); + g_free(name); + } + else + fl = GNT_TEXT_FLAG_DIM; + + if (flags & GAIM_MESSAGE_ERROR) + fl |= GNT_TEXT_FLAG_BOLD; + if (flags & GAIM_MESSAGE_NICK) + fl |= GNT_TEXT_FLAG_UNDERLINE; + + strip = gaim_markup_strip_html(message); + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), + strip, fl); + gnt_text_view_next_line(GNT_TEXT_VIEW(ggconv->tv)); + gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), 0); + + g_free(strip); + + gnt_widget_set_urgent(ggconv->tv); +} + +static void +gg_write_chat(GaimConversation *conv, const char *who, const char *message, + GaimMessageFlags flags, time_t mtime) +{ + gg_write_common(conv, who, message, flags, mtime); +} + +static void +gg_write_im(GaimConversation *conv, const char *who, const char *message, + GaimMessageFlags flags, time_t mtime) +{ + if (flags & GAIM_MESSAGE_SEND) + { + who = gaim_connection_get_display_name(conv->account->gc); + if (!who) + who = gaim_account_get_alias(conv->account); + if (!who) + who = gaim_account_get_username(conv->account); + } + else if (flags & GAIM_MESSAGE_RECV) + who = gaim_conversation_get_name(conv); + + gg_write_common(conv, who, message, flags, mtime); +} + +static void +gg_write_conv(GaimConversation *conv, const char *who, const char *alias, + const char *message, GaimMessageFlags flags, time_t mtime) +{ + const char *name; + if (alias && *alias) + name = alias; + else if (who && *who) + name = who; + else + name = NULL; + + gg_write_common(conv, name, message, flags, mtime); +} + +static void +gg_chat_add_users(GaimConversation *conv, GList *users, GList *flags, GList *aliases, gboolean new_arrivals) +{} + +static void +gg_chat_rename_user(GaimConversation *conv, const char *old, const char *new_n, const char *new_a) +{} + +static void +gg_chat_remove_user(GaimConversation *conv, GList *list) +{} + +static void +gg_chat_update_user(GaimConversation *conv, const char *user) +{} + +static GaimConversationUiOps conv_ui_ops = +{ + .create_conversation = gg_create_conversation, + .destroy_conversation = gg_destroy_conversation, + .write_chat = gg_write_chat, + .write_im = gg_write_im, + .write_conv = gg_write_conv, + .chat_add_users = gg_chat_add_users, + .chat_rename_user = gg_chat_rename_user, + .chat_remove_users = gg_chat_remove_user, + .chat_update_user = gg_chat_update_user, + .present = NULL, + .has_focus = NULL, + .custom_smiley_add = NULL, + .custom_smiley_write = NULL, + .custom_smiley_close = NULL +}; + +static void +destroy_ggconv(gpointer data) +{ + GGConv *conv = data; + gnt_widget_destroy(conv->window); + g_free(conv); +} + +GaimConversationUiOps *gg_conv_get_ui_ops() +{ + return &conv_ui_ops; +} + + +void gg_conversation_init() +{ + ggconvs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_ggconv); +} + Copied: branches/soc-2006-file-loggers/console/gntconv.h (from rev 16395, trunk/console/gntconv.h) =================================================================== --- branches/soc-2006-file-loggers/console/gntconv.h (rev 0) +++ branches/soc-2006-file-loggers/console/gntconv.h 2006-07-02 16:02:29 UTC (rev 16396) @@ -0,0 +1,5 @@ +#include "conversation.h" + +GaimConversationUiOps *gg_conv_get_ui_ops(); + +void gg_conversation_init(); Modified: branches/soc-2006-file-loggers/console/gntgaim.c =================================================================== --- branches/soc-2006-file-loggers/console/gntgaim.c 2006-07-02 15:49:54 UTC (rev 16395) +++ branches/soc-2006-file-loggers/console/gntgaim.c 2006-07-02 16:02:29 UTC (rev 16396) @@ -16,6 +16,7 @@ #include "whiteboard.h" #include "gntgaim.h" +#include "gntui.h" /* Anything IO-related is directly copied from gtkgaim's source tree */ Modified: branches/soc-2006-file-loggers/console/gntui.c =================================================================== --- branches/soc-2006-file-loggers/console/gntui.c 2006-07-02 15:49:54 UTC (rev 16395) +++ branches/soc-2006-file-loggers/console/gntui.c 2006-07-02 16:02:29 UTC (rev 16396) @@ -1,4 +1,6 @@ #include "gntui.h" +#include "gntblist.h" +#include "gntconv.h" void init_gnt_ui() { @@ -12,6 +14,10 @@ gg_blist_init(); gaim_blist_set_ui_ops(gg_blist_get_ui_ops()); + /* Now the conversations */ + gg_conversation_init(); + gaim_conversations_set_ui_ops(gg_conv_get_ui_ops()); + gnt_main(); } Copied: branches/soc-2006-file-loggers/console/libgnt/AUTHORS (from rev 16395, trunk/console/libgnt/AUTHORS) =================================================================== Copied: branches/soc-2006-file-loggers/console/libgnt/COPYING (from rev 16395, trunk/console/libgnt/COPYING) =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/COPYING (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/COPYING 2006-07-02 16:02:29 UTC (rev 16396) @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show... [truncated message content] |
From: <ro...@us...> - 2006-07-02 15:50:02
|
Revision: 16395 Author: roast Date: 2006-07-02 08:49:54 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16395&view=rev Log Message: ----------- fixing botched 16338 commit. Modified Paths: -------------- branches/soc-2006-file-loggers/console/gntblist.c branches/soc-2006-file-loggers/console/libgnt/test.c branches/soc-2006-file-loggers/src/util.c Modified: branches/soc-2006-file-loggers/console/gntblist.c =================================================================== --- branches/soc-2006-file-loggers/console/gntblist.c 2006-07-02 09:37:25 UTC (rev 16394) +++ branches/soc-2006-file-loggers/console/gntblist.c 2006-07-02 15:49:54 UTC (rev 16395) @@ -149,14 +149,14 @@ #else /* XXX: Let's use these some time */ case GAIM_STATUS_OFFLINE: - strncpy(status, "M-bM-^JM-^W", sizeof(status) - 1); + strncpy(status, "⊗", sizeof(status) - 1); break; case GAIM_STATUS_AVAILABLE: /* XXX: Detect idleness */ - strncpy(status, "M-bM-^WM-/", sizeof(status) - 1); + strncpy(status, "◯", sizeof(status) - 1); break; default: - strncpy(status, "M-bM-^JM-^V", sizeof(status) - 1); + strncpy(status, "⊖", sizeof(status) - 1); break; #endif } Modified: branches/soc-2006-file-loggers/console/libgnt/test.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/test.c 2006-07-02 09:37:25 UTC (rev 16394) +++ branches/soc-2006-file-loggers/console/libgnt/test.c 2006-07-02 15:49:54 UTC (rev 16395) @@ -70,7 +70,7 @@ gnt_init(); GntWidget *widget = gnt_button_new("Button 1"); - GntWidget *widget2 = gnt_button_new("Button 2 has a longish text with a UTF-8 thing M-bM-^@M-&"); + GntWidget *widget2 = gnt_button_new("Button 2 has a longish text with a UTF-8 thing …"); GntWidget *label = gnt_label_new("So wassup dudes and dudettes!!\nSo this is, like,\nthe third line!! \\o/"); GntWidget *vbox, *hbox, *tree; WINDOW *test; @@ -104,7 +104,7 @@ gnt_tree_add_row_after(GNT_TREE(tree), "b", "b", "d", NULL); GNT_WIDGET_UNSET_FLAGS(hbox, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); - gnt_box_set_title(GNT_BOX(hbox), "111111111111111111111111111111111111111111111111111111111111111This is the title M-bM-^@M-&"); + gnt_box_set_title(GNT_BOX(hbox), "111111111111111111111111111111111111111111111111111111111111111This is the title …"); /*gnt_widget_set_take_focus(vbox, TRUE);*/ /*gnt_widget_set_take_focus(hbox, TRUE);*/ Modified: branches/soc-2006-file-loggers/src/util.c =================================================================== --- branches/soc-2006-file-loggers/src/util.c 2006-07-02 09:37:25 UTC (rev 16394) +++ branches/soc-2006-file-loggers/src/util.c 2006-07-02 15:49:54 UTC (rev 16395) @@ -3659,6 +3659,7 @@ "GET %s%s HTTP/%s\r\n" "Connection: close\r\n" "User-Agent: %s\r\n" + "Accept: */*\r\n" "Host: %s\r\n\r\n", (gfud->full ? "" : "/"), (gfud->full ? gfud->url : gfud->website.page), @@ -3668,6 +3669,7 @@ gfud->request = g_strdup_printf( "GET %s%s HTTP/%s\r\n" "Connection: close\r\n" + "Accept: */*\r\n" "Host: %s\r\n\r\n", (gfud->full ? "" : "/"), (gfud->full ? gfud->url : gfud->website.page), This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ev...@us...> - 2006-07-02 09:37:33
|
Revision: 16394 Author: evands Date: 2006-07-02 02:37:25 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16394&view=rev Log Message: ----------- msn_session_sync_users() iterates over the buddy list, following the ->next pointers of the groups, contacts, and buddies. msn_show_sync_issue(), if called, removed the buddy for which it was called, in preparation for the buddy either being added to the server list or confirmed-to-be-removed. This could lead to the buddy pointer being released and ->next therefore being junk. The buddy is now not removed until the user responds to the action dialog presented via msn_show_sync_issue(). I'm unclear why gtkgaim got away with this exercise in memory stomping but Adium/libgaim crashed every time, but it's safer in any case. I also changed some foo->bar to gaim_foo_get_bar(). Modified Paths: -------------- trunk/src/protocols/msn/dialog.c trunk/src/protocols/msn/session.c Modified: trunk/src/protocols/msn/dialog.c =================================================================== --- trunk/src/protocols/msn/dialog.c 2006-07-01 23:21:12 UTC (rev 16393) +++ trunk/src/protocols/msn/dialog.c 2006-07-02 09:37:25 UTC (rev 16394) @@ -34,9 +34,31 @@ } MsnAddRemData; +/* Remove the buddy referenced by the MsnAddRemData before the serverside list is changed. + * If the buddy will be added, he'll be added back; if he will be removed, he won't be. */ static void +msn_complete_sync_issue(MsnAddRemData *data) +{ + GaimBuddy *buddy; + GaimGroup *group = NULL; + + if (data->group != NULL) + group = gaim_find_group(data->group); + + if (group != NULL) + buddy = gaim_find_buddy_in_group(gaim_connection_get_account(data->gc), data->who, group); + else + buddy = gaim_find_buddy(gaim_connection_get_account(data->gc), data->who); + + if (buddy != NULL) + gaim_blist_remove_buddy(buddy); +} + +static void msn_add_cb(MsnAddRemData *data) { + msn_complete_sync_issue(data); + if (g_list_find(gaim_connections_get_all(), data->gc) != NULL) { MsnSession *session = data->gc->proto_data; @@ -55,6 +77,8 @@ static void msn_rem_cb(MsnAddRemData *data) { + msn_complete_sync_issue(data); + if (g_list_find(gaim_connections_get_all(), data->gc) != NULL) { MsnSession *session = data->gc->proto_data; @@ -78,8 +102,6 @@ GaimAccount *account; MsnAddRemData *data; char *msg, *reason; - GaimBuddy *buddy; - GaimGroup *group = NULL; account = session->account; gc = gaim_account_get_connection(account); @@ -114,17 +136,6 @@ _("Yes"), G_CALLBACK(msn_add_cb), _("No"), G_CALLBACK(msn_rem_cb)); - if (group_name != NULL) - group = gaim_find_group(group_name); - - if (group != NULL) - buddy = gaim_find_buddy_in_group(account, passport, group); - else - buddy = gaim_find_buddy(account, passport); - - if (buddy != NULL) - gaim_blist_remove_buddy(buddy); - g_free(reason); g_free(msg); } Modified: trunk/src/protocols/msn/session.c =================================================================== --- trunk/src/protocols/msn/session.c 2006-07-01 23:21:12 UTC (rev 16393) +++ trunk/src/protocols/msn/session.c 2006-07-02 09:37:25 UTC (rev 16394) @@ -231,7 +231,7 @@ * being logged in. This no longer happens, so we manually iterate * over the whole buddy list to identify sync issues. */ - for (gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) { + for (gnode = gaim_blist_get_root(); gnode; gnode = gnode->next) { GaimGroup *group = (GaimGroup *)gnode; const char *group_name = group->name; if(!GAIM_BLIST_NODE_IS_GROUP(gnode)) @@ -244,11 +244,11 @@ if(!GAIM_BLIST_NODE_IS_BUDDY(bnode)) continue; b = (GaimBuddy *)bnode; - if(b->account == gc->account) { + if(gaim_buddy_get_account(b) == gaim_connection_get_account(gc)) { MsnUser *remote_user; gboolean found = FALSE; - remote_user = msn_userlist_find_user(session->userlist, b->name); + remote_user = msn_userlist_find_user(session->userlist, gaim_buddy_get_name(b)); if ((remote_user != NULL) && (remote_user->list_op & MSN_LIST_FL_OP)) { @@ -273,7 +273,7 @@ { /* The user was not on the server list or not in that group * on the server list */ - msn_show_sync_issue(session, b->name, group_name); + msn_show_sync_issue(session, gaim_buddy_get_name(b), group_name); } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |