Revision 95dadaa541776b9f415dd4cbf7a28f092a228206

nwalp at pidgin.im nwalp at pidgin.im
Thu Mar 15 20:03:20 EDT 2007


o     -----------------------------------------------------------------
|\    Revision: 95dadaa541776b9f415dd4cbf7a28f092a228206
| |   Ancestor: 781d0a4beb5fa7b8916127b6e322aa96419230ce
| |   Ancestor: cf9ae5cee9d8608b76627c90ea401cc5347486ca
| |   Author: nwalp at pidgin.im
| |   Date: 2007-03-16T00:02:55
| |   Branch: im.pidgin.pidgin
| |   
| |   Added files:
| |           pidgin/pixmaps/tray/16/Makefile.am
| |           pidgin/pixmaps/tray/16/Makefile.mingw
| |           pidgin/pixmaps/tray/16/tray-away.png
| |           pidgin/pixmaps/tray/16/tray-busy.png
| |           pidgin/pixmaps/tray/16/tray-connecting.png
| |           pidgin/pixmaps/tray/16/tray-extended-away.png
| |           pidgin/pixmaps/tray/16/tray-message.png
| |           pidgin/pixmaps/tray/16/tray-offline.png
| |           pidgin/pixmaps/tray/16/tray-online.png
| |   Added directories:
| |           pidgin/pixmaps/tray/16
| |   Modified files:
| |           configure.ac console/gntconv.c console/libgnt/gntbindable.c
| |           console/libgnt/gntentry.c console/libgnt/gntkeys.c
| |           console/libgnt/gntkeys.h console/libgnt/gntmain.c
| |           console/libgnt/gnttextview.c console/libgnt/gntwidget.c
| |           console/libgnt/gntwm.c console/libgnt/gntwm.h
| |           console/libgnt/test/tv.c console/libgnt/wms/s.c
| |           console/plugins/gntclipboard.c
| |           doc/gaims_funniest_home_convos.txt libpurple/connection.c
| |           libpurple/plugins/ssl/ssl-gnutls.c
| |           libpurple/protocols/jabber/roster.c
| |           libpurple/protocols/jabber/si.c
| |           libpurple/protocols/msn/msn-utils.c
| |           libpurple/protocols/novell/nmuser.c
| |           libpurple/protocols/oscar/oscar.c libpurple/util.c
| |           pidgin/gaimstock.c pidgin/gtkdocklet-x11.c
| |           pidgin/gtkimhtmltoolbar.c pidgin/pixmaps/tray/Makefile.am
| |           pidgin/plugins/musicmessaging/musicmessaging.c
| |           pidgin/win32/gtkdocklet-win32.c
| |   Modified attrs:
| |           pidgin/pixmaps/tray/16/tray-away.png
| |           pidgin/pixmaps/tray/16/tray-busy.png
| |           pidgin/pixmaps/tray/16/tray-connecting.png
| |           pidgin/pixmaps/tray/16/tray-extended-away.png
| |           pidgin/pixmaps/tray/16/tray-message.png
| |           pidgin/pixmaps/tray/16/tray-offline.png
| |           pidgin/pixmaps/tray/16/tray-online.png
| |   
| |   ChangeLog: 
| |   
| |   merge of '781d0a4beb5fa7b8916127b6e322aa96419230ce'
| |        and 'cf9ae5cee9d8608b76627c90ea401cc5347486ca'
| |   
| |   ============================================================
| |   --- pidgin/pixmaps/tray/16/Makefile.am	85840405fe9cec59fb1acb63e91d98c964c0a7f0
| |   +++ pidgin/pixmaps/tray/16/Makefile.am	85840405fe9cec59fb1acb63e91d98c964c0a7f0
| |   @@ -0,0 +1,18 @@
| |   +TRAY_ICONS =	tray-away.png \
| |   +		tray-busy.png \
| |   +		tray-connecting.png \
| |   +		tray-extended-away.png \
| |   +		tray-message.png \
| |   +		tray-offline.png \
| |   +		tray-online.png
| |   +
| |   +EXTRA_DIST = 	tray-away.ico \
| |   +		tray-busy.ico \
| |   +		tray-connecting.ico \
| |   +		tray-extended-away.ico \
| |   +		tray-message.ico \
| |   +		tray-offline.ico \
| |   +		tray-online.ico 
| |   +
| |   +pidgintraypixdir = $(datadir)/pixmaps/pidgin/tray/16
| |   +pidgintraypix_DATA = $(TRAY_ICONS)
| |   ============================================================
| |   --- pidgin/pixmaps/tray/16/Makefile.mingw	2a6c350b12761d0f50a3783008dc7d47803a194c
| |   +++ pidgin/pixmaps/tray/16/Makefile.mingw	2a6c350b12761d0f50a3783008dc7d47803a194c
| |   @@ -0,0 +1,20 @@
| |   +#
| |   +# Makefile.mingw
| |   +#
| |   +# Description: Makefile for win32 (mingw) version of Pidgin pixmaps
| |   +#
| |   +
| |   +GAIM_TOP := ../../../..
| |   +include $(GAIM_TOP)/libpurple/win32/global.mak
| |   +
| |   +datadir = $(GAIM_INSTALL_DIR)
| |   +include ./Makefile.am
| |   +
| |   +.PHONY: install
| |   +
| |   +install:
| |   +	if test '$(pidgintraypix_DATA)'; then \
| |   +	  mkdir -p $(pidgintraypixdir); \
| |   +	  cp $(pidgintraypix_DATA) $(pidgintraypixdir); \
| |   +	fi;
| |   +
| |   ============================================================
| |   # pidgin/pixmaps/tray/16/tray-away.png is binary
| |   ============================================================
| |   # pidgin/pixmaps/tray/16/tray-busy.png is binary
| |   ============================================================
| |   # pidgin/pixmaps/tray/16/tray-connecting.png is binary
| |   ============================================================
| |   # pidgin/pixmaps/tray/16/tray-extended-away.png is binary
| |   ============================================================
| |   # pidgin/pixmaps/tray/16/tray-message.png is binary
| |   ============================================================
| |   # pidgin/pixmaps/tray/16/tray-offline.png is binary
| |   ============================================================
| |   # pidgin/pixmaps/tray/16/tray-online.png is binary
| |   ============================================================
| |   --- configure.ac	fb18cf8f85bd9ed11296db2cc5377e2fe230a33f
| |   +++ configure.ac	9497dadee8b2124f94b99911f554cc6a123bffe3
| |   @@ -1943,6 +1943,7 @@ AC_OUTPUT([Makefile
| |    		   pidgin/pixmaps/toolbar/16/Makefile
| |    		   pidgin/pixmaps/toolbar/16/scalable/Makefile
| |    		   pidgin/pixmaps/tray/Makefile
| |   +		   pidgin/pixmaps/tray/16/Makefile
| |    		   pidgin/pixmaps/tray/22/Makefile
| |    		   pidgin/plugins/Makefile
| |    		   pidgin/plugins/cap/Makefile
| |   ============================================================
| |   --- console/gntconv.c	0c0c2d2f802bb4a31529c0c68ff88d924d2ccd1b
| |   +++ console/gntconv.c	62c5112aea8b1fcdb88487ce5c7227a5bbb93abb
| |   @@ -333,7 +333,6 @@ gg_create_conversation(GaimConversation 
| |    	gnt_entry_set_always_suggest(GNT_ENTRY(ggc->entry), FALSE);
| |    
| |    	g_signal_connect_after(G_OBJECT(ggc->entry), "key_pressed", G_CALLBACK(entry_key_pressed), ggc);
| |   -	g_signal_connect(G_OBJECT(ggc->entry), "text_changed", G_CALLBACK(send_typing_notification), ggc);
| |    	g_signal_connect(G_OBJECT(ggc->window), "destroy", G_CALLBACK(closing_window), ggc);
| |    
| |    	gnt_widget_set_position(ggc->window, gaim_prefs_get_int(PREF_ROOT "/position/x"),
| |   @@ -343,10 +342,13 @@ gg_create_conversation(GaimConversation 
| |    	g_signal_connect(G_OBJECT(ggc->tv), "size_changed", G_CALLBACK(size_changed_cb), NULL);
| |    	g_signal_connect(G_OBJECT(ggc->window), "position_set", G_CALLBACK(save_position_cb), NULL);
| |    
| |   -	gaim_signal_connect(gaim_conversations_get_handle(), "buddy-typing", gg_conv_get_handle(),
| |   -	                GAIM_CALLBACK(update_buddy_typing), NULL);
| |   -	gaim_signal_connect(gaim_conversations_get_handle(), "buddy-typing-stopped", gg_conv_get_handle(),
| |   -	                GAIM_CALLBACK(update_buddy_typing), NULL);
| |   +	if (type == GAIM_CONV_TYPE_IM) {
| |   +		g_signal_connect(G_OBJECT(ggc->entry), "text_changed", G_CALLBACK(send_typing_notification), ggc);
| |   +		gaim_signal_connect(gaim_conversations_get_handle(), "buddy-typing", gg_conv_get_handle(),
| |   +						GAIM_CALLBACK(update_buddy_typing), NULL);
| |   +		gaim_signal_connect(gaim_conversations_get_handle(), "buddy-typing-stopped", gg_conv_get_handle(),
| |   +						GAIM_CALLBACK(update_buddy_typing), NULL);
| |   +	}
| |    
| |    	g_free(title);
| |    }
| |   ============================================================
| |   --- console/libgnt/gntbindable.c	c67dfa77a00ccc5d309030609e8b75c18dd3e468
| |   +++ console/libgnt/gntbindable.c	5aea477bb5e2b0aeb98158764a3be87509d16e56
| |   @@ -155,6 +155,7 @@ register_binding(GntBindableClass *klass
| |    
| |    	if (name == NULL || *name == '\0') {
| |    		g_hash_table_remove(klass->bindings, (char*)trigger);
| |   +		gnt_keys_del_combination(trigger);
| |    		return;
| |    	}
| |    
| |   @@ -171,6 +172,7 @@ register_binding(GntBindableClass *klass
| |    	param->action = action;
| |    	param->list = list;
| |    	g_hash_table_replace(klass->bindings, g_strdup(trigger), param);
| |   +	gnt_keys_add_combination(trigger);
| |    }
| |    
| |    void gnt_bindable_register_binding(GntBindableClass *klass, const char *name,
| |   ============================================================
| |   --- console/libgnt/gntentry.c	948bdbcbb482b47f414240d3e828fe666e213070
| |   +++ console/libgnt/gntentry.c	da215b066fc8231fbb0e5bd36ca86a6689d81ea9
| |   @@ -302,15 +302,15 @@ clipboard_paste(GntBindable *bind, GList
| |    clipboard_paste(GntBindable *bind, GList *n)
| |    {
| |    	GntEntry *entry = GNT_ENTRY(bind);
| |   -	gchar *i;
| |   -	gchar *text = i = gnt_get_clipboard_string();
| |   +	gchar *i, *text, *a, *all;
| |   +	text = i = gnt_get_clipboard_string();
| |    	while (*i != '\0') {
| |    		i = g_utf8_next_char(i);
| |    		if (*i == '\r' || *i == '\n')
| |    			*i = ' ';
| |    	}
| |   -	char *a = g_strndup(entry->start, entry->cursor - entry->start);
| |   -	char *all = g_strconcat(a, text, entry->cursor, NULL);
| |   +	a = g_strndup(entry->start, entry->cursor - entry->start);
| |   +	all = g_strconcat(a, text, entry->cursor, NULL);
| |    	gnt_entry_set_text_internal(entry, all);
| |    	g_free(a);
| |    	g_free(text);
| |   @@ -563,7 +563,7 @@ gnt_entry_key_pressed(GntWidget *widget,
| |    				if (entry->end + len - entry->start >= entry->buffer)
| |    				{
| |    					/* This will cause the buffer to grow */
| |   -					char *tmp = g_strdup_printf("%s%*s", entry->start, len, "");
| |   +					char *tmp = g_strdup(entry->start);
| |    					gnt_entry_set_text_internal(entry, tmp);
| |    					g_free(tmp);
| |    				}
| |   @@ -693,7 +693,7 @@ gnt_entry_class_init(GntEntryClass *klas
| |    				GNT_KEY_CTRL_DOWN, NULL);
| |    	gnt_bindable_class_register_action(bindable, "history-next", history_next,
| |    				GNT_KEY_CTRL_UP, NULL);
| |   -	gnt_bindable_class_register_action(bindable, "clipboard-past", clipboard_paste,
| |   +	gnt_bindable_class_register_action(bindable, "clipboard-paste", clipboard_paste,
| |    				GNT_KEY_CTRL_V, NULL);
| |    
| |    	gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass));
| |   ============================================================
| |   --- console/libgnt/gntkeys.c	250339eba2cef3d9bb3f677eba66438cacc66d28
| |   +++ console/libgnt/gntkeys.c	a7b705a5899d8591003dd89f8d52a20ccc0af5a5
| |   @@ -1,5 +1,6 @@
| |    #include "gntkeys.h"
| |    
| |   +#include <glib.h>
| |    #include <stdlib.h>
| |    #include <string.h>
| |    
| |   @@ -8,7 +9,6 @@ char *gnt_key_cright;
| |    char *gnt_key_cleft;
| |    char *gnt_key_cright;
| |    
| |   -
| |    static const char *term;
| |    
| |    void gnt_init_keys()
| |   @@ -34,7 +34,7 @@ void gnt_keys_refine(char *text)
| |    
| |    void gnt_keys_refine(char *text)
| |    {
| |   -	if (*text == 27 && *(text + 1) == '[' && *(text + 3) == '\0' &&
| |   +	if (*text == 27 && *(text + 1) == '[' &&
| |    			(*(text + 2) >= 'A' && *(text + 2) <= 'D')) {
| |    		/* Apparently this is necessary for urxvt and screen and xterm */
| |    		if (strcmp(term, "screen") == 0 || strcmp(term, "rxvt-unicode") == 0 ||
| |   @@ -48,3 +48,108 @@ void gnt_keys_refine(char *text)
| |    	}
| |    }
| |    
| |   +/**
| |   + * The key-bindings will be saved in a tree. When a keystroke happens, GNT will
| |   + * find the sequence that matches a binding and return the length.
| |   + * A sequence should not be a prefix of another sequence. If it is, then only
| |   + * the shortest one will be processed. If we want to change that, we will need
| |   + * to allow getting the k-th prefix that matches the input, and pay attention
| |   + * to the return value of gnt_wm_process_input in gntmain.c.
| |   + */
| |   +#define SIZE 256
| |   +
| |   +#define IS_END         1 << 0
| |   +struct _node
| |   +{
| |   +	struct _node *next[SIZE];
| |   +	int ref;
| |   +	int flags;
| |   +};
| |   +
| |   +static struct _node root = {.ref = 1, .flags = 0};
| |   +
| |   +static void add_path(struct _node *node, const char *path)
| |   +{
| |   +	struct _node *n = NULL;
| |   +	if (!path || !*path) {
| |   +		node->flags |= IS_END;
| |   +		return;
| |   +	}
| |   +	while (*path && node->next[*path]) {
| |   +		node = node->next[*path];
| |   +		node->ref++;
| |   +		path++;
| |   +	}
| |   +	if (!*path)
| |   +		return;
| |   +	n = g_new0(struct _node, 1);
| |   +	n->ref = 1;
| |   +	node->next[*path++] = n;
| |   +	add_path(n, path);
| |   +}
| |   +
| |   +void gnt_keys_add_combination(const char *path)
| |   +{
| |   +	add_path(&root, path);
| |   +}
| |   +
| |   +static void del_path(struct _node *node, const char *path)
| |   +{
| |   +	struct _node *next = NULL;
| |   +
| |   +	if (!*path)
| |   +		return;
| |   +	next = node->next[*path];
| |   +	if (!next)
| |   +		return;
| |   +	del_path(next, path + 1);
| |   +	next->ref--;
| |   +	if (next->ref == 0) {
| |   +		node->next[*path] = NULL;
| |   +		g_free(next);
| |   +	}
| |   +}
| |   +
| |   +void gnt_keys_del_combination(const char *path)
| |   +{
| |   +	del_path(&root, path);
| |   +}
| |   +
| |   +int gnt_keys_find_combination(const char *path)
| |   +{
| |   +	int depth = 0;
| |   +	struct _node *n = &root;
| |   +
| |   +	while (*path && n->next[*path] && !(n->flags & IS_END)) {
| |   +		if (g_utf8_find_next_char(path, NULL) - path > 1)
| |   +			return 0;
| |   +		n = n->next[*path++];
| |   +		depth++;
| |   +	}
| |   +
| |   +	if (!(n->flags & IS_END))
| |   +		depth = 0;
| |   +	return depth;
| |   +}
| |   +
| |   +static void
| |   +print_path(struct _node *node, int depth)
| |   +{
| |   +	int i;
| |   +	for (i = 0; i < SIZE; i++) {
| |   +		if (node->next[i]) {
| |   +			g_printerr("%*c (%d:%d)\n", depth, i, node->next[i]->ref,
| |   +						node->next[i]->flags);
| |   +			print_path(node->next[i], depth + 1);
| |   +		}
| |   +	}
| |   +}
| |   +
| |   +/* this is purely for debugging purposes. */
| |   +void gnt_keys_print_combinations()
| |   +{
| |   +	g_printerr("--------\n");
| |   +	print_path(&root, 1);
| |   +	g_printerr("--------\n");
| |   +}
| |   +
| |   ============================================================
| |   --- console/libgnt/gntkeys.h	a0d51d2e193ab717ac9bd43974e5ed39b3d02686
| |   +++ console/libgnt/gntkeys.h	94ecd340747dd609c5ecf449bf6e877416639a58
| |   @@ -82,7 +82,11 @@ void gnt_keys_refine(char *text);
| |    void gnt_init_keys();
| |    void gnt_keys_refine(char *text);
| |    
| |   +void gnt_keys_add_combination(const char *path);
| |   +void gnt_keys_del_combination(const char *path);
| |   +int gnt_keys_find_combination(const char *path);
| |    
| |   +
| |    /* A lot of commonly used variable names are defined in <term.h>. 
| |     * #undef them to make life easier for everyone. */
| |    
| |   ============================================================
| |   --- console/libgnt/gntmain.c	b16dfe5d58954e5593a7d5c555075dcbe3455811
| |   +++ console/libgnt/gntmain.c	04fd84cde349738be547682f08b1afe625df2eed
| |   @@ -51,6 +51,20 @@ static GntClipboard *clipboard;
| |    GntWM *wm;
| |    static GntClipboard *clipboard;
| |    
| |   +#define HOLDING_ESCAPE  (escape_stuff.timer != 0)
| |   +
| |   +static struct {
| |   +	int timer;
| |   +} escape_stuff;
| |   +
| |   +static gboolean
| |   +escape_timeout(gpointer data)
| |   +{
| |   +	gnt_wm_process_input(wm, "\033");
| |   +	escape_stuff.timer = 0;
| |   +	return FALSE;
| |   +}
| |   +
| |    /**
| |     * Mouse support:
| |     *  - bring a window on top if you click on its taskbar
| |   @@ -180,7 +194,8 @@ io_invoke(GIOChannel *source, GIOConditi
| |    io_invoke(GIOChannel *source, GIOCondition cond, gpointer null)
| |    {
| |    	char keys[256];
| |   -	int rd = read(STDIN_FILENO, keys, sizeof(keys) - 1);
| |   +	int rd = read(STDIN_FILENO, keys + HOLDING_ESCAPE, sizeof(keys) - 1 - HOLDING_ESCAPE);
| |   +	char *k;
| |    	if (rd < 0)
| |    	{
| |    		int ch = getch(); /* This should return ERR, but let's see what it really returns */
| |   @@ -196,14 +211,39 @@ io_invoke(GIOChannel *source, GIOConditi
| |    		raise(SIGABRT);
| |    	}
| |    
| |   +	rd += HOLDING_ESCAPE;
| |    	keys[rd] = 0;
| |   -	gnt_keys_refine(keys);
| |   -
| |    	if (mouse_enabled && detect_mouse_action(keys))
| |    		return TRUE;
| |   -	
| |   -	gnt_wm_process_input(wm, keys);
| |    
| |   +	if (HOLDING_ESCAPE)
| |   +		keys[0] = '\033';
| |   +	k = keys;
| |   +	while (rd) {
| |   +		char back;
| |   +		int p;
| |   +
| |   +		if (k[0] == '\033' && rd == 1) {
| |   +			if (escape_stuff.timer) {
| |   +				gnt_wm_process_input(wm, "\033\033");
| |   +				g_source_remove(escape_stuff.timer);
| |   +				escape_stuff.timer = 0;
| |   +				break;
| |   +			}
| |   +			escape_stuff.timer = g_timeout_add(250, escape_timeout, NULL);
| |   +			break;
| |   +		}
| |   +
| |   +		gnt_keys_refine(k);
| |   +		p = MAX(1, gnt_keys_find_combination(k));
| |   +		back = k[p];
| |   +		k[p] = '\0';
| |   +		gnt_wm_process_input(wm, k);     /* XXX: */
| |   +		k[p] = back;
| |   +		rd -= p;
| |   +		k += p;
| |   +	}
| |   +
| |    	return TRUE;
| |    }
| |    
| |   @@ -212,6 +252,7 @@ setup_io()
| |    {
| |    	int result;
| |    	channel = g_io_channel_unix_new(STDIN_FILENO);
| |   +	g_io_channel_set_close_on_unref(channel, TRUE);
| |    
| |    #if 0
| |    	g_io_channel_set_encoding(channel, NULL, NULL);
| |   ============================================================
| |   --- console/libgnt/gnttextview.c	b3b66b77893fd432931f5defff14692eca3cd143
| |   +++ console/libgnt/gnttextview.c	c2714a627a272a2c7fa2fb23a2f7d9308482e7d5
| |   @@ -69,13 +69,17 @@ gnt_text_view_draw(GntWidget *widget)
| |    				(select_end <= view->string->str + seg->end && select_start <= view->string->str + seg->start))) {
| |    				char *cur = view->string->str + seg->start;
| |    				while (*cur != '\0') {
| |   +					gchar *last = g_utf8_next_char(cur);
| |   +					gchar *str;
| |    					if (cur >= select_start && cur <= select_end)
| |    						fl |= A_REVERSE;
| |    					else
| |    						fl = seg->flags;
| |   +					str = g_strndup(cur, last - cur);
| |    					wattrset(widget->window, fl);
| |   -					waddch(widget->window, *cur);
| |   -					cur++;
| |   +					waddstr(widget->window, str);
| |   +					g_free(str);
| |   +					cur = g_utf8_next_char(cur);
| |    				}
| |    			} else {
| |    				wattrset(widget->window, fl);
| |   @@ -187,31 +191,43 @@ gnt_text_view_get_p(GntTextView *view, i
| |    static char *
| |    gnt_text_view_get_p(GntTextView *view, int x, int y)
| |    {
| |   -	int i;
| |   +	int i = 0;
| |    	GntWidget *wid = GNT_WIDGET(view);
| |    	GntTextLine *line;
| |    	GList *lines;
| |    	GList *segs;
| |    	GntTextSegment *seg;
| |   +	gchar *pos;
| |    
| |    	y = wid->priv.height - y;
| |    	if (g_list_length(view->list) < y) {
| |    		x = 0;
| |   -		y = g_list_length(view->list);
| |   +		y = g_list_length(view->list) - 1;
| |    	}
| |    
| |    	lines = g_list_nth(view->list, y - 1);
| |   +	if (!lines)
| |   +		return NULL;
| |    	do {
| |    		line = lines->data;
| |    		lines = lines->next;
| |   -	} while (line && !line->segments);
| |   +	} while (line && !line->segments && lines);
| |    
| |   -	if (!line) /* no valid line */
| |   +	if (!line || !line->segments) /* no valid line */
| |    		return NULL;
| |    	segs = line->segments;
| |    	seg = (GntTextSegment *)segs->data;
| |   -	i = 0;
| |   -	return view->string->str + seg->start + MIN(x, line->length);
| |   +	pos = view->string->str + seg->start;
| |   +	x = MIN(x, line->length);
| |   +	while (++i <= x) {
| |   +		gunichar *u;
| |   +		pos = g_utf8_next_char(pos);
| |   +		u = g_utf8_to_ucs4(pos, -1, NULL, NULL, NULL);
| |   +		if (u && g_unichar_iswide_cjk(*u))
| |   +			i++;
| |   +		g_free(u);
| |   +	}
| |   +	return pos;
| |    }
| |    
| |    static GString *
| |   @@ -219,7 +235,7 @@ select_word_text(GntTextView *view, gcha
| |    {
| |    	gchar *start = c;
| |    	gchar *end = c;
| |   -	gchar *t;
| |   +	gchar *t, *endsize;
| |    	while (t = g_utf8_prev_char(start)) {
| |    		if (!g_ascii_isspace(*t)) {
| |    			if (start == view->string->str)
| |   @@ -236,7 +252,8 @@ select_word_text(GntTextView *view, gcha
| |    	}
| |    	select_start = start;
| |    	select_end = end;
| |   -	return g_string_new_len(start, end - start + 1);
| |   +	endsize = g_utf8_next_char(select_end); /* End at the correct byte */
| |   +	return g_string_new_len(start, endsize - start);
| |    }
| |    
| |    static gboolean too_slow(gpointer n)
| |   @@ -276,7 +293,8 @@ gnt_text_view_clicked(GntWidget *widget,
| |    					return;
| |    				}
| |    			} else {
| |   -				clip = g_string_new_len(select_start, select_end - select_start + 1);
| |   +				gchar *endsize = g_utf8_next_char(select_end); /* End at the correct byte */
| |   +				clip = g_string_new_len(select_start, endsize - select_start);
| |    			}
| |    			gnt_widget_draw(widget);
| |    			gnt_set_clipboard_string(clip->str);
| |   ============================================================
| |   --- console/libgnt/gntwidget.c	ad1c371517b2198009db53fe8ec8550e16124bd8
| |   +++ console/libgnt/gntwidget.c	451f5aef1133a55c9d3e4c13cfa35c4f23a911a3
| |   @@ -357,7 +357,7 @@ gnt_widget_draw(GntWidget *widget)
| |    			g_signal_emit(widget, signals[SIG_SIZE_CHANGED], 0, oldw, oldh);
| |    		}
| |    #else
| |   -		widget->window = newpad(150, 350);  /* XXX: */
| |   +		widget->window = newpad(widget->priv.height + 20, widget->priv.width + 20);  /* XXX: */
| |    #endif
| |    		init_widget(widget);
| |    	}
| |   @@ -520,6 +520,10 @@ gnt_widget_set_size(GntWidget *widget, i
| |    
| |    		widget->priv.width = width;
| |    		widget->priv.height = height;
| |   +		if (width >= getmaxx(widget->window) || height >= getmaxy(widget->window)) {
| |   +			delwin(widget->window);
| |   +			widget->window = newpad(height + 20, width + 20);
| |   +		}
| |    
| |    		g_signal_emit(widget, signals[SIG_SIZE_CHANGED], 0, oldw, oldh);
| |    
| |   @@ -581,7 +585,8 @@ update_queue_callback(gpointer data)
| |    
| |    	if (!g_object_get_data(G_OBJECT(widget), "gnt:queue_update"))
| |    		return FALSE;
| |   -	gnt_screen_update(widget);
| |   +	if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED))
| |   +		gnt_screen_update(widget);
| |    	g_object_set_data(G_OBJECT(widget), "gnt:queue_update", NULL);
| |    	return FALSE;
| |    }
| |   ============================================================
| |   --- console/libgnt/gntwm.c	68b25194957957896e4e4c6ef7f15e007bf8488e
| |   +++ console/libgnt/gntwm.c	e136d8a3f24641ab8ac336daec08bee90f906997
| |   @@ -875,6 +875,8 @@ gnt_wm_class_init(GntWMClass *klass)
| |    static void
| |    gnt_wm_class_init(GntWMClass *klass)
| |    {
| |   +	int i;
| |   +
| |    	klass->new_window = gnt_wm_new_window_real;
| |    	klass->decorate_window = NULL;
| |    	klass->close_window = NULL;
| |   @@ -1004,6 +1006,14 @@ gnt_wm_class_init(GntWMClass *klass)
| |    				"\033" GNT_KEY_CTRL_K, NULL);
| |    
| |    	gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass));
| |   +
| |   +	/* Make sure Alt+x are detected properly. */
| |   +	for (i = '0'; i <= '9'; i++) {
| |   +		char str[] = "\033X";
| |   +		str[1] = i;
| |   +		gnt_keys_add_combination(str);
| |   +	}
| |   +
| |    	GNTDEBUG;
| |    }
| |    
| |   @@ -1209,14 +1219,16 @@ time_t gnt_wm_get_idle_time()
| |    	return time(NULL) - last_active_time;
| |    }
| |    
| |   -void gnt_wm_process_input(GntWM *wm, const char *keys)
| |   +gboolean gnt_wm_process_input(GntWM *wm, const char *keys)
| |    {
| |   +	gboolean ret = FALSE;
| |   +
| |    	keys = gnt_bindable_remap_keys(GNT_BINDABLE(wm), keys);
| |    
| |    	idle_update = TRUE;
| |    
| |    	if (gnt_bindable_perform_action_key(GNT_BINDABLE(wm), keys))
| |   -		return;
| |   +		return TRUE;
| |    
| |    	/* Do some manual checking */
| |    	if (wm->ordered && wm->mode != GNT_KP_MODE_NORMAL) {
| |   @@ -1247,7 +1259,7 @@ void gnt_wm_process_input(GntWM *wm, con
| |    			if (ox != x || oy != y) {
| |    				gnt_screen_move_widget(widget, x, y);
| |    				window_reverse(widget, TRUE, wm);
| |   -				return;
| |   +				return TRUE;
| |    			}
| |    		} else if (wm->mode == GNT_KP_MODE_RESIZE) {
| |    			if (strcmp(keys, GNT_KEY_LEFT) == 0) {
| |   @@ -1264,14 +1276,14 @@ void gnt_wm_process_input(GntWM *wm, con
| |    			if (oh != h || ow != w) {
| |    				gnt_screen_resize_widget(widget, w, h);
| |    				window_reverse(widget, TRUE, wm);
| |   -				return;
| |   +				return TRUE;
| |    			}
| |    		}
| |    		if (strcmp(keys, "\r") == 0 || strcmp(keys, "\033") == 0) {
| |    			window_reverse(widget, FALSE, wm);
| |    			wm->mode = GNT_KP_MODE_NORMAL;
| |    		}
| |   -		return;
| |   +		return TRUE;
| |    	}
| |    
| |    	wm->event_stack = TRUE;
| |   @@ -1281,7 +1293,7 @@ void gnt_wm_process_input(GntWM *wm, con
| |    		if (wm->_list.window) {
| |    			gnt_widget_destroy(wm->_list.window);
| |    			wm->event_stack = FALSE;
| |   -			return;
| |   +			return TRUE;
| |    		}
| |    	} else if (keys[0] == '\033' && isdigit(keys[1]) && keys[2] == '\0') {
| |    		/* Alt+x for quick switch */
| |   @@ -1294,16 +1306,17 @@ void gnt_wm_process_input(GntWM *wm, con
| |    		list = g_list_append(list, GINT_TO_POINTER(n - 1));
| |    		switch_window_n(GNT_BINDABLE(wm), list);
| |    		g_list_free(list);
| |   -		return;
| |   +		return TRUE;
| |    	}
| |    
| |    	if (wm->menu)
| |   -		gnt_widget_key_pressed(GNT_WIDGET(wm->menu), keys);
| |   +		ret = gnt_widget_key_pressed(GNT_WIDGET(wm->menu), keys);
| |    	else if (wm->_list.window)
| |   -		gnt_widget_key_pressed(wm->_list.window, keys);
| |   +		ret = gnt_widget_key_pressed(wm->_list.window, keys);
| |    	else if (wm->ordered)
| |   -		gnt_widget_key_pressed(GNT_WIDGET(wm->ordered->data), keys);
| |   +		ret = gnt_widget_key_pressed(GNT_WIDGET(wm->ordered->data), keys);
| |    	wm->event_stack = FALSE;
| |   +	return ret;
| |    }
| |    
| |    static void
| |   @@ -1476,8 +1489,8 @@ gboolean gnt_wm_process_click(GntWM *wm,
| |    
| |    gboolean gnt_wm_process_click(GntWM *wm, GntMouseEvent event, int x, int y, GntWidget *widget)
| |    {
| |   +	gboolean ret = TRUE;
| |    	idle_update = TRUE;
| |   -	gboolean ret = TRUE;
| |    	g_signal_emit(wm, signals[SIG_MOUSE_CLICK], 0, event, x, y, widget, &ret);
| |    	return ret;
| |    }
| |   ============================================================
| |   --- console/libgnt/gntwm.h	35afc169a156b4dc90dafb0cebc36ebf31e0b0ab
| |   +++ console/libgnt/gntwm.h	8fbfeb952f9b58cabd43172e85dd60145ae5b05f
| |   @@ -151,7 +151,7 @@ void gnt_wm_window_close(GntWM *wm, GntW
| |    
| |    void gnt_wm_window_close(GntWM *wm, GntWidget *widget);
| |    
| |   -void gnt_wm_process_input(GntWM *wm, const char *string);
| |   +gboolean gnt_wm_process_input(GntWM *wm, const char *string);
| |    
| |    gboolean gnt_wm_process_click(GntWM *wm, GntMouseEvent event, int x, int y, GntWidget *widget);
| |    
| |   ============================================================
| |   --- console/libgnt/test/tv.c	a48459c9f1599fb61619568505c5fe2c5d6eafa6
| |   +++ console/libgnt/test/tv.c	df77d3d23638996e5d22f096fabe7c21cc878a1c
| |   @@ -83,6 +83,7 @@ int main()
| |    	gnt_entry_set_history_length(GNT_ENTRY(entry), -1);
| |    	g_signal_connect_after(G_OBJECT(entry), "key_pressed", G_CALLBACK(key_pressed), view);
| |    
| |   +	gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "\n", GNT_TEXT_FLAG_NORMAL);
| |    	gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "plugins: ", GNT_TEXT_FLAG_BOLD);
| |    	gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "this is the 1st line\n", GNT_TEXT_FLAG_NORMAL);
| |    
| |   ============================================================
| |   --- console/libgnt/wms/s.c	2cd03d376d2625a7d36fca115f4a900b9ffe8b24
| |   +++ console/libgnt/wms/s.c	4b2ae45e14f3333c6da99240d216465a4972ec93
| |   @@ -182,7 +182,7 @@ toggle_clipboard(GntBindable *bindable, 
| |    	text = gnt_get_clipboard_string();
| |    	clip = gnt_hwindow_new(FALSE);
| |    	GNT_WIDGET_SET_FLAGS(clip, GNT_WIDGET_TRANSIENT);
| |   -	GNT_WIDGET_UNSET_FLAGS(clip, GNT_WIDGET_NO_BORDER);
| |   +	GNT_WIDGET_SET_FLAGS(clip, GNT_WIDGET_NO_BORDER);
| |    	gnt_box_set_pad(GNT_BOX(clip), 0);
| |    	gnt_box_add_widget(GNT_BOX(clip), gnt_label_new(" "));
| |    	gnt_box_add_widget(GNT_BOX(clip), gnt_label_new(text));
| |   ============================================================
| |   --- console/plugins/gntclipboard.c	47e39e9026dcc625f41ac18098659daab13e7b08
| |   +++ console/plugins/gntclipboard.c	5b5780a30ce0f088c25b6b729713bf6fa3b644f1
| |   @@ -30,6 +30,9 @@
| |    #include <X11/Xatom.h>
| |    #endif
| |    
| |   +#include <sys/types.h>
| |   +#include <signal.h>
| |   +
| |    #include <glib.h>
| |    
| |    #include <plugin.h>
| |   @@ -39,11 +42,11 @@
| |    
| |    #include <gntplugin.h>
| |    
| |   -static gboolean stop = FALSE;
| |   +static pid_t child = 0;
| |    
| |    static gulong sig_handle;
| |    
| |   -static gpointer *
| |   +static void
| |    set_clip(gchar *string)
| |    {
| |    #ifdef HAVE_X11
| |   @@ -54,16 +57,16 @@ set_clip(gchar *string)
| |    	Display *dpy = XOpenDisplay(NULL);
| |    
| |    	if (!dpy)
| |   -		return NULL;
| |   +		return;
| |    	ids = getenv("WINDOWID");
| |    	if (ids == NULL)
| |   -		return NULL;
| |   +		return;
| |    	w = atoi(ids);
| |    	XSetSelectionOwner(dpy, XA_PRIMARY, w, CurrentTime);
| |    	XFlush(dpy);
| |    	XSelectInput(dpy, w, StructureNotifyMask);
| |   -	while (!stop) {
| |   -		XNextEvent(dpy, &e);
| |   +	while (TRUE) {
| |   +		XNextEvent(dpy, &e); /* this blocks. */
| |    		req = &e.xselectionrequest;
| |    		if (e.type == SelectionRequest) {
| |    			XChangeProperty(dpy,
| |   @@ -83,33 +86,38 @@ set_clip(gchar *string)
| |    			XSendEvent(dpy, req->requestor, 0, 0, &respond);
| |    			XFlush (dpy);
| |    		} else if (e.type == SelectionClear) {
| |   -			return NULL;
| |   +			return;
| |    		}
| |    	}
| |    #endif
| |   -	return NULL;
| |   +	return;
| |    }
| |    
| |    static void
| |    clipboard_changed(GntWM *wm, gchar *string)
| |    {
| |    #ifdef HAVE_X11
| |   -	static GThread *thread = NULL;
| |   -	if (thread) {
| |   -		stop = TRUE;
| |   -		thread = g_thread_join(thread);
| |   +	if (child) {
| |   +		kill(child, SIGTERM);
| |    	}
| |   -	g_thread_create((GThreadFunc)set_clip, string, TRUE, NULL);
| |   +	if ((child = fork() == 0)) {
| |   +		set_clip(string);
| |   +		_exit(0);
| |   +	}
| |    #endif
| |    }
| |    
| |    static gboolean
| |    plugin_load(GaimPlugin *plugin)
| |    {
| |   -	if (!XOpenDisplay(NULL))
| |   +	if (!XOpenDisplay(NULL)) {
| |    		gaim_debug_warning("gntclipboard", "Couldn't find X display\n");
| |   -	if (!getenv("WINDOWID"))
| |   +		return FALSE;
| |   +	}
| |   +	if (!getenv("WINDOWID")) {
| |    		gaim_debug_warning("gntclipboard", "Couldn't find window\n");
| |   +		return FALSE;
| |   +	}
| |    	sig_handle = g_signal_connect(G_OBJECT(gnt_get_clipboard()), "clipboard_changed", G_CALLBACK(clipboard_changed), NULL);
| |    	return TRUE;
| |    }
| |   @@ -117,6 +125,10 @@ plugin_unload(GaimPlugin *plugin)
| |    static gboolean
| |    plugin_unload(GaimPlugin *plugin)
| |    {
| |   +	if (child) {
| |   +		kill(child, SIGTERM);
| |   +		child = 0;
| |   +	}
| |    	g_signal_handler_disconnect(G_OBJECT(gnt_get_clipboard()), sig_handle);
| |    	return TRUE;
| |    }
| |   @@ -151,7 +163,6 @@ init_plugin(GaimPlugin *plugin)
| |    static void
| |    init_plugin(GaimPlugin *plugin)
| |    {
| |   -	g_thread_init(NULL);
| |    }
| |    
| |    GAIM_INIT_PLUGIN(PLUGIN_STATIC_NAME, init_plugin, info)
| |   ============================================================
| |   --- libpurple/connection.c	be8dc3f9bcde569ab9c715d50f7dbc838d8acdbf
| |   +++ libpurple/connection.c	2780735e26f07cdcd53ed64224722280991e995d
| |   @@ -434,8 +434,12 @@ gaim_connection_error(GaimConnection *gc
| |    	GaimConnectionUiOps *ops;
| |    
| |    	g_return_if_fail(gc   != NULL);
| |   -	g_return_if_fail(text != NULL);
| |    
| |   +	if (text != NULL) {
| |   +		g_critical("gaim_connection_error: check `text != NULL' failed");
| |   +		text = _("Unknown error");
| |   +	}
| |   +
| |    	/* If we've already got one error, we don't need any more */
| |    	if (gc->disconnect_timeout)
| |    		return;
| |   ============================================================
| |   --- libpurple/plugins/ssl/ssl-gnutls.c	74208168c2a7bae9418241039fb37150b6e84e85
| |   +++ libpurple/plugins/ssl/ssl-gnutls.c	a6fc5dc86095e58453cbf8588a18ebc5a4d6125a
| |   @@ -83,7 +83,8 @@ static void ssl_gnutls_handshake_cb(gpoi
| |    	gnutls_data->handshake_handler = 0;
| |    
| |    	if(ret != 0) {
| |   -		gaim_debug_error("gnutls", "Handshake failed. Error %d\n", ret);
| |   +		gaim_debug_error("gnutls", "Handshake failed. Error %s\n",
| |   +			gnutls_strerror(ret));
| |    
| |    		if(gsc->error_cb != NULL)
| |    			gsc->error_cb(gsc, GAIM_SSL_HANDSHAKE_FAILED,
| |   @@ -156,8 +157,16 @@ ssl_gnutls_read(GaimSslConnection *gsc, 
| |    		s = -1;
| |    		errno = EAGAIN;
| |    	} else if(s < 0) {
| |   -		gaim_debug_error("gnutls", "receive failed: %d\n", s);
| |   -		s = 0;
| |   +		gaim_debug_error("gnutls", "receive failed: %s\n",
| |   +				gnutls_strerror(s));
| |   +		s = -1;
| |   +		/*
| |   +		 * TODO: Set errno to something more appropriate.  Or even
| |   +		 *       better: allow ssl plugins to keep track of their
| |   +		 *       own error message, then add a new ssl_ops function
| |   +		 *       that returns the error message.
| |   +		 */
| |   +		errno = EIO;
| |    	}
| |    
| |    	return s;
| |   @@ -177,8 +186,16 @@ ssl_gnutls_write(GaimSslConnection *gsc,
| |    		s = -1;
| |    		errno = EAGAIN;
| |    	} else if(s < 0) {
| |   -		gaim_debug_error("gnutls", "send failed: %d\n", s);
| |   -		s = 0;
| |   +		gaim_debug_error("gnutls", "send failed: %s\n",
| |   +				gnutls_strerror(s));
| |   +		s = -1;
| |   +		/*
| |   +		 * TODO: Set errno to something more appropriate.  Or even
| |   +		 *       better: allow ssl plugins to keep track of their
| |   +		 *       own error message, then add a new ssl_ops function
| |   +		 *       that returns the error message.
| |   +		 */
| |   +		errno = EIO;
| |    	}
| |    
| |    	return s;
| |   ============================================================
| |   --- libpurple/protocols/jabber/roster.c	5a71828362fc4f322825fd8ad4f325854408ee17
| |   +++ libpurple/protocols/jabber/roster.c	553be223e32c9bad69f81eda32fa6b8410962b94
| |   @@ -380,7 +380,7 @@ void jabber_roster_remove_buddy(GaimConn
| |    	GSList *groups = NULL;
| |    
| |    	buddies = g_slist_remove(buddies, buddy);
| |   -	if(g_slist_length(buddies)) {
| |   +	if(buddies != NULL) {
| |    		GaimBuddy *tmpbuddy;
| |    		GaimGroup *tmpgroup;
| |    
| |   ============================================================
| |   --- libpurple/protocols/jabber/si.c	3e841ffef94bb5f5390710d86ada247bab5cc091
| |   +++ libpurple/protocols/jabber/si.c	47d760130efc958d0bb131c2ad406ceeccab26b2
| |   @@ -783,7 +783,7 @@ static void jabber_si_xfer_init(GaimXfer
| |    			return;
| |    
| |    		/* XXX: for now, send to the first resource available */
| |   -		if(g_list_length(jb->resources) >= 1) {
| |   +		if(jb->resources != NULL) {
| |    			char **who_v = g_strsplit(xfer->who, "/", 2);
| |    			char *who;
| |    
| |   ============================================================
| |   --- libpurple/protocols/msn/msn-utils.c	c001fcb8c31329f5516e28c92c284ae1ee267892
| |   +++ libpurple/protocols/msn/msn-utils.c	817c70476a43419c5865bc63cca520c28e80cb7b
| |   @@ -174,6 +174,11 @@ msn_import_html(const char *html, char *
| |    	char fonteffect[4];
| |    	char fontcolor[7];
| |    
| |   +	gboolean has_bold = FALSE;
| |   +	gboolean has_italic = FALSE;
| |   +	gboolean has_underline = FALSE;
| |   +	gboolean has_strikethrough = FALSE;
| |   +
| |    	g_return_if_fail(html       != NULL);
| |    	g_return_if_fail(attributes != NULL);
| |    	g_return_if_fail(message    != NULL);
| |   @@ -197,22 +202,38 @@ msn_import_html(const char *html, char *
| |    			}
| |    			else if (!g_ascii_strncasecmp(c + 1, "i>", 2))
| |    			{
| |   -				strcat(fonteffect, "I");
| |   +				if (!has_italic)
| |   +				{
| |   +					strcat(fonteffect, "I");
| |   +					has_italic = TRUE;
| |   +				}
| |    				c += 3;
| |    			}
| |    			else if (!g_ascii_strncasecmp(c + 1, "b>", 2))
| |    			{
| |   -				strcat(fonteffect, "B");
| |   +				if (!has_bold)
| |   +				{
| |   +					strcat(fonteffect, "B");
| |   +					has_bold = TRUE;
| |   +				}
| |    				c += 3;
| |    			}
| |    			else if (!g_ascii_strncasecmp(c + 1, "u>", 2))
| |    			{
| |   -				strcat(fonteffect, "U");
| |   +				if (!has_underline)
| |   +				{
| |   +					strcat(fonteffect, "U");
| |   +					has_underline = TRUE;
| |   +				}
| |    				c += 3;
| |    			}
| |    			else if (!g_ascii_strncasecmp(c + 1, "s>", 2))
| |    			{
| |   -				strcat(fonteffect, "S");
| |   +				if (!has_strikethrough)
| |   +				{
| |   +					strcat(fonteffect, "S");
| |   +					has_strikethrough = TRUE;
| |   +				}
| |    				c += 3;
| |    			}
| |    			else if (!g_ascii_strncasecmp(c + 1, "a href=\"", 8))
| |   ============================================================
| |   --- libpurple/protocols/novell/nmuser.c	702ebcd067b2391a9dfc48d26474bd2120d84950
| |   +++ libpurple/protocols/novell/nmuser.c	f005ea2bb6b5b7c60f178579384a05ab54580414
| |   @@ -1534,13 +1534,12 @@ _handle_multiple_get_details_joinconf_cb
| |    		}
| |    
| |    		/* Time to callback? */
| |   -		if (g_slist_length(list) == 0) {
| |   +		if (list == NULL) {
| |    			nm_response_cb cb = nm_request_get_callback(request);
| |    
| |    			if (cb) {
| |    				cb(user, 0, conference, conference);
| |    			}
| |   -			g_slist_free(list);
| |    			nm_release_request(request);
| |    		}
| |    	}
| |   ============================================================
| |   --- libpurple/protocols/oscar/oscar.c	c43d9c892937ee98ca0ab48fb12c22df35cf7abe
| |   +++ libpurple/protocols/oscar/oscar.c	1d68435922f317dbde447d781aa434284ec72e9d
| |   @@ -1357,8 +1357,8 @@ gaim_parse_auth_resp(OscarData *od, Flap
| |    			gaim_connection_error(gc, _("Authentication failed"));
| |    			break;
| |    		}
| |   -		gaim_debug_error("oscar", "Login Error Code 0x%04hx\n", info->errorcode);
| |   -		gaim_debug_error("oscar", "Error URL: %s\n", info->errorurl);
| |   +		gaim_debug_info("oscar", "Login Error Code 0x%04hx\n", info->errorcode);
| |   +		gaim_debug_info("oscar", "Error URL: %s\n", info->errorurl);
| |    		od->killme = TRUE;
| |    		return 1;
| |    	}
| |   ============================================================
| |   --- libpurple/util.c	8b56e2be85ee5a053186df0817bb7c78e7501420
| |   +++ libpurple/util.c	42b4016d0ab3c2911c505411eb8a6b022f854e7c
| |   @@ -3217,7 +3217,7 @@ parse_redirect(const char *data, size_t 
| |    		gaim_input_remove(gfud->inpa);
| |    		gfud->inpa = 0;
| |    		close(gfud->fd);
| |   -		gfud->fd = 0;
| |   +		gfud->fd = -1;
| |    
| |    		g_free(gfud->website.user);
| |    		g_free(gfud->website.passwd);
| |   ============================================================
| |   --- pidgin/gaimstock.c	b5d07ae30e7aa5a9f0289da24d787379b963becd
| |   +++ pidgin/gaimstock.c	b03cd954c67bfa9f6e2e0984ede575c3f9d49502
| |   @@ -166,13 +166,13 @@ static struct SizedStockIcon {
| |    	{ PIDGIN_STOCK_TOOLBAR_TYPING, "toolbar", "typing.png", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE },
| |    	{ PIDGIN_STOCK_TOOLBAR_PENDING, "status", "message-pending.png", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE },
| |    	
| |   -	{ PIDGIN_STOCK_TRAY_AVAILABLE, "tray", "tray-online.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE },
| |   -	{ PIDGIN_STOCK_TRAY_AWAY, "tray", "tray-away.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE },
| |   -	{ PIDGIN_STOCK_TRAY_BUSY, "tray", "tray-busy.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE },
| |   -	{ PIDGIN_STOCK_TRAY_XA, "tray", "tray-extended-away.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE },
| |   -	{ PIDGIN_STOCK_TRAY_OFFLINE, "tray", "tray-offline.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE },
| |   -	{ PIDGIN_STOCK_TRAY_CONNECT, "tray", "tray-connecting.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE },
| |   -	{ PIDGIN_STOCK_TRAY_PENDING, "tray", "tray-message.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE }
| |   +	{ PIDGIN_STOCK_TRAY_AVAILABLE, "tray", "tray-online.png", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE },
| |   +	{ PIDGIN_STOCK_TRAY_AWAY, "tray", "tray-away.png", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE },
| |   +	{ PIDGIN_STOCK_TRAY_BUSY, "tray", "tray-busy.png", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE },
| |   +	{ PIDGIN_STOCK_TRAY_XA, "tray", "tray-extended-away.png", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE },
| |   +	{ PIDGIN_STOCK_TRAY_OFFLINE, "tray", "tray-offline.png", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE },
| |   +	{ PIDGIN_STOCK_TRAY_CONNECT, "tray", "tray-connecting.png", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE },
| |   +	{ PIDGIN_STOCK_TRAY_PENDING, "tray", "tray-message.png", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE }
| |    };
| |    
| |    static gchar *
| |   ============================================================
| |   --- pidgin/gtkdocklet-x11.c	0e117782c24bee9aad8f6fa61db30e307b1c5a38
| |   +++ pidgin/gtkdocklet-x11.c	b3b38dd36d790285ba71d22dd7690338f07ca13e
| |   @@ -40,6 +40,8 @@ static int embed_timeout = 0;
| |    static GtkTooltips *tooltips = NULL;
| |    static GdkPixbuf *blank_icon = NULL;
| |    static int embed_timeout = 0;
| |   +static DockletStatus icon_status = 0;
| |   +static int docklet_height = 0;
| |    
| |    /* protos */
| |    static void docklet_x11_create(void);
| |   @@ -115,37 +117,25 @@ docklet_x11_update_icon(DockletStatus ic
| |    			break;
| |    	}
| |    
| |   -	if(icon_name)
| |   -		gtk_image_set_from_stock(GTK_IMAGE(image), icon_name, gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL));
| |   +	if(icon_name) {
| |   +		int icon_size;
| |   +		if (docklet_height < 22)
| |   +			icon_size = gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL);
| |   +		else
| |   +			icon_size = gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL);
| |    
| |   -#if 0
| |   -	GdkPixbuf *p;
| |   -	GdkBitmap *mask = NULL;
| |   -
| |   -	p = gtk_widget_render_icon(GTK_WIDGET(image), icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR, NULL);
| |   -
| |   -	if (p && (gdk_pixbuf_get_colorspace(p) == GDK_COLORSPACE_RGB) && (gdk_pixbuf_get_bits_per_sample(p) == 8)
| |   -	   && (gdk_pixbuf_get_has_alpha(p)) && (gdk_pixbuf_get_n_channels(p) == 4)) {
| |   -		int len = gdk_pixbuf_get_width(p) * gdk_pixbuf_get_height(p);
| |   -		guchar *data = gdk_pixbuf_get_pixels(p);
| |   -		guchar *bitmap = g_malloc((len / 8) + 1);
| |   -		int i;
| |   -
| |   -		for (i = 0; i < len; i++)
| |   -			if (data[i*4 + 3] > 55)
| |   -				bitmap[i/8] |= 1 << i % 8;
| |   -			else
| |   -				bitmap[i/8] &= ~(1 << i % 8);
| |   -
| |   -		mask = gdk_bitmap_create_from_data(GDK_DRAWABLE(GTK_WIDGET(image)->window), bitmap, gdk_pixbuf_get_width(p), gdk_pixbuf_get_height(p));
| |   -		g_free(bitmap);
| |   +		gtk_image_set_from_stock(GTK_IMAGE(image), icon_name, icon_size);
| |    	}
| |   +	icon_status = icon;
| |   +}
| |    
| |   -	if (mask)
| |   -		gdk_window_shape_combine_mask(image->window, mask, 0, 0);
| |   -
| |   -	g_object_unref(G_OBJECT(p));
| |   -#endif
| |   +static void
| |   +docklet_x11_resize_icon(GtkWidget *widget)
| |   +{
| |   +	if (docklet_height == widget->allocation.height)
| |   +		return;
| |   +	docklet_height = widget->allocation.height;
| |   +	docklet_x11_update_icon(icon_status);
| |    }
| |    
| |    static void
| |   @@ -263,8 +253,8 @@ docklet_x11_create()
| |    
| |    	g_signal_connect(G_OBJECT(docklet), "embedded", G_CALLBACK(docklet_x11_embedded_cb), NULL);
| |    	g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(docklet_x11_destroyed_cb), NULL);
| |   +	g_signal_connect(G_OBJECT(docklet), "size-allocate", G_CALLBACK(docklet_x11_resize_icon), NULL);
| |    	g_signal_connect(G_OBJECT(box), "button-release-event", G_CALLBACK(docklet_x11_clicked_cb), NULL);
| |   -
| |    	gtk_container_add(GTK_CONTAINER(box), image);
| |    	gtk_container_add(GTK_CONTAINER(docklet), box);
| |    
| |   ============================================================
| |   --- pidgin/gtkimhtmltoolbar.c	51de283d5c8966ce4a1998dbc6d8e3904f4c3562
| |   +++ pidgin/gtkimhtmltoolbar.c	d84c3eab2623835189bd61dd7b3a1d924bb2c7d1
| |   @@ -672,7 +672,7 @@ insert_smiley_cb(GtkWidget *smiley, GtkI
| |    	gtk_window_set_role(GTK_WINDOW(dialog), "smiley_dialog");
| |    	gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
| |    
| |   -	if (g_slist_length(unique_smileys)) {
| |   +	if (unique_smileys != NULL) {
| |    		struct smiley_button_list *ls, *it, *it_tmp;
| |    		GtkWidget *line;
| |    		int line_width = 0;
| |   ============================================================
| |   --- pidgin/pixmaps/tray/Makefile.am	bd1e2f1d1aabf6908f704ffe36f3085eb312cb86
| |   +++ pidgin/pixmaps/tray/Makefile.am	cb7850722a6df4c8a8bd7b5c28e982b09b39871b
| |   @@ -1,4 +1,4 @@
| |   -SUBDIRS = 22
| |   +SUBDIRS = 16 22
| |    
| |    EXTRA_DIST = \
| |    	Makefile.mingw \
| |   ============================================================
| |   --- pidgin/plugins/musicmessaging/musicmessaging.c	6cae0b1bca6a24b5bb90dd8af1af797721f8a22a
| |   +++ pidgin/plugins/musicmessaging/musicmessaging.c	de324a5a4ab466bc0967dacdc2ba1f8bf8f4272e
| |   @@ -235,16 +235,19 @@ mmconv_from_conv_loc(GaimConversation *c
| |    static int
| |    mmconv_from_conv_loc(GaimConversation *conv)
| |    {
| |   +	GList *l;
| |    	MMConversation *mmconv_current = NULL;
| |    	guint i;
| |    	
| |   -	for (i = 0; i < g_list_length(conversations); i++)
| |   +	i = 0;
| |   +	for (l = conversations; l != NULL; l = l->next)
| |    	{
| |   -		mmconv_current = (MMConversation *)g_list_nth_data(conversations, i);
| |   +		mmconv_current = l->data;
| |    		if (conv == mmconv_current->conv)
| |    		{
| |    			return i;
| |    		}
| |   +		i++;
| |    	}
| |    	return -1;
| |    }
| |   @@ -295,9 +298,9 @@ plugin_unload(GaimPlugin *plugin) {
| |    plugin_unload(GaimPlugin *plugin) {
| |    	MMConversation *mmconv = NULL;
| |    	
| |   -	while (g_list_length(conversations) > 0)
| |   +	while (conversations != NULL)
| |    	{
| |   -		mmconv = g_list_first(conversations)->data;
| |   +		mmconv = conversations->data;
| |    		conv_destroyed(mmconv->conv);
| |    	}
| |    	return TRUE;
| |   ============================================================
| |   --- pidgin/win32/gtkdocklet-win32.c	9b40096c3848d119755151d02d49a8351b8889aa
| |   +++ pidgin/win32/gtkdocklet-win32.c	d53bcc793c8ca47fa2650907040237716e7847ac
| |   @@ -443,7 +443,7 @@ static HICON load_hicon_from_stock(const
| |    static HICON load_hicon_from_stock(const char *stock) {
| |    	HICON hicon = NULL;
| |    	GdkPixbuf *pixbuf = gtk_widget_render_icon(image, stock,
| |   -		gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL), NULL);
| |   +		gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL), NULL);
| |    
| |    	if (pixbuf) {
| |    		hicon = pixbuf_to_hicon(pixbuf);
| |   ============================================================
| |   --- doc/gaims_funniest_home_convos.txt	be47dd74eed7883341313de49c219ee75b7408cf
| |   +++ doc/gaims_funniest_home_convos.txt	b4ebad4a44d1098b442b09a2af09f994b1526312
| |   @@ -439,3 +439,15 @@
| |    (15:58:51) LSchiere: you test things?
| |    (15:59:06) SimGuy: seanegan: by experience, I think we've determined you do
| |    not :)
| |   +
| |   +(07:52:07 PM) clueless21: are you one of the gaim makers?
| |   +(07:52:14 PM) Nathan Walp: yes
| |   +(07:52:24 PM) clueless21:  cool
| |   +(07:52:37 PM) clueless21:  if your busy, i can leave you alone...
| |   +(07:53:03 PM) Nathan Walp: if you have a question I can answer it
| |   +(07:53:34 PM) clueless21:  umm... well i don't exactly know what gaim does and what it's for. i don't know if i should get it
| |   +(07:53:46 PM) Nathan Walp: it is an IM client
| |   +(07:53:57 PM) clueless21:  o. what's it do?
| |   +(07:54:03 PM) clueless21:  what's an im client?
| |   +(07:54:25 PM) Nathan Walp: it lets you chat with other people, like we are chatting now
| |   +(07:54:45 PM) clueless21:  oooooooooo... thanks

To get the patch for this revision, please do this:
mtn log --last 1 --diffs --from 95dadaa541776b9f415dd4cbf7a28f092a228206


More information about the Commits mailing list