changeset 20417:dc042f70bd8c

merge of '04f3de66fbed599e51f30258916fdb8f966ffdcd' and 'b92b51d5aa18a5df8e4de6cfd0c4710845197b51'
author Ka-Hing Cheung <khc@hxbc.us>
date Sat, 19 May 2007 22:48:51 +0000
parents 4c5d68e93ef8 (current diff) 6f3432091d4b (diff)
children 0f6747c5dcc2
files COPYRIGHT
diffstat 15 files changed, 133 insertions(+), 63 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Sat May 19 22:48:25 2007 +0000
+++ b/COPYRIGHT	Sat May 19 22:48:51 2007 +0000
@@ -304,6 +304,7 @@
 David Schmitt
 Mark Schneider
 Evan Schoenberg
+Gabriel Schulof
 Federico Schwindt
 Torrey Searle
 Peter Seebach
@@ -360,6 +361,7 @@
 James Vega
 David Vermeille
 Sid Vicious
+Jorge VillaseƱor (Masca)
 Bjoern Voigt
 Wan Hing Wah
 Philip Walford
--- a/ChangeLog	Sat May 19 22:48:25 2007 +0000
+++ b/ChangeLog	Sat May 19 22:48:51 2007 +0000
@@ -35,6 +35,10 @@
 	* Improved tab completion support
 	* Ctrl+c prompts with a dialog before exiting
 	* Filter string in the debug window
+	* Notify when you leave a chat
+	* Work around an ncurses bug which appears when half of a multi-cell
+	  character is covered by an upper-level window
+	* New plugins are shown in bold text in the plugin dialog
 
 version 2.0.0 (5/3/2007):
 	* The project has new names - libpurple for the core, Pidgin for the
--- a/finch/gntconv.c	Sat May 19 22:48:25 2007 +0000
+++ b/finch/gntconv.c	Sat May 19 22:48:51 2007 +0000
@@ -493,7 +493,8 @@
 		FinchConvChat *fc = ggc->u.chat = g_new0(FinchConvChat, 1);
 		hbox = gnt_hbox_new(FALSE);
 		gnt_box_set_pad(GNT_BOX(hbox), 0);
-		tree = fc->userlist = gnt_tree_new();
+		tree = fc->userlist = gnt_tree_new_with_columns(2);
+		gnt_tree_set_col_width(GNT_TREE(tree), 0, 1);   /* The flag column */
 		gnt_tree_set_compare_func(GNT_TREE(tree), (GCompareFunc)g_utf8_collate);
 		gnt_tree_set_hash_fns(GNT_TREE(tree), g_str_hash, g_str_equal, g_free);
 		GNT_WIDGET_SET_FLAGS(tree, GNT_WIDGET_NO_BORDER);
@@ -675,6 +676,20 @@
 	finch_write_common(conv, name, message, flags, mtime);
 }
 
+static const char *
+chat_flag_text(PurpleConvChatBuddyFlags flags)
+{
+	if (flags & PURPLE_CBFLAGS_FOUNDER)
+		return "~";
+	if (flags & PURPLE_CBFLAGS_OP)
+		return "@";
+	if (flags & PURPLE_CBFLAGS_HALFOP)
+		return "%";
+	if (flags & PURPLE_CBFLAGS_VOICE)
+		return "+";
+	return " ";
+}
+
 static void
 finch_chat_add_users(PurpleConversation *conv, GList *users, gboolean new_arrivals)
 {
@@ -709,7 +724,7 @@
 		gnt_entry_add_suggest(entry, cbuddy->name);
 		gnt_entry_add_suggest(entry, cbuddy->alias);
 		gnt_tree_add_row_after(tree, g_strdup(cbuddy->name),
-				gnt_tree_create_row(tree, cbuddy->alias), NULL, NULL);
+				gnt_tree_create_row(tree, chat_flag_text(cbuddy->flags), cbuddy->alias), NULL, NULL);
 	}
 }
 
@@ -720,12 +735,15 @@
 	FinchConv *ggc = conv->ui_data;
 	GntEntry *entry = GNT_ENTRY(ggc->entry);
 	GntTree *tree = GNT_TREE(ggc->u.chat->userlist);
+	PurpleConvChatBuddy *cb = purple_conv_chat_cb_find(PURPLE_CONV_CHAT(conv), new_n);
+
 	gnt_entry_remove_suggest(entry, old);
+	gnt_tree_remove(tree, (gpointer)old);
+
 	gnt_entry_add_suggest(entry, new_n);
 	gnt_entry_add_suggest(entry, new_a);
-	gnt_tree_remove(tree, (gpointer)old);
 	gnt_tree_add_row_after(tree, g_strdup(new_n),
-			gnt_tree_create_row(tree, new_a), NULL, NULL);
+			gnt_tree_create_row(tree, chat_flag_text(cb->flags), new_a), NULL, NULL);
 }
 
 static void
@@ -744,6 +762,9 @@
 static void
 finch_chat_update_user(PurpleConversation *conv, const char *user)
 {
+	PurpleConvChatBuddy *cb = purple_conv_chat_cb_find(PURPLE_CONV_CHAT(conv), user);
+	FinchConv *ggc = conv->ui_data;
+	gnt_tree_change_text(GNT_TREE(ggc->u.chat->userlist), (gpointer)user, 0, chat_flag_text(cb->flags));
 }
 
 static PurpleConversationUiOps conv_ui_ops = 
--- a/libpurple/Makefile.am	Sat May 19 22:48:25 2007 +0000
+++ b/libpurple/Makefile.am	Sat May 19 22:48:51 2007 +0000
@@ -151,7 +151,7 @@
 dbus_headers  = dbus-bindings.h dbus-purple.h dbus-server.h dbus-useful.h dbus-define-api.h
 
 dbus_exported = dbus-useful.h dbus-define-api.h account.h blist.h buddyicon.h \
-                connection.h conversation.h core.h log.h prefs.h roomlist.h \
+                connection.h conversation.h core.h log.h notify.h prefs.h roomlist.h \
                 savedstatuses.h status.h server.h util.h xmlnode.h
 
 purple_build_coreheaders = $(addprefix $(srcdir)/, $(purple_coreheaders))
--- a/libpurple/conversation.c	Sat May 19 22:48:25 2007 +0000
+++ b/libpurple/conversation.c	Sat May 19 22:48:51 2007 +0000
@@ -970,20 +970,20 @@
 	{
 		im->typing_state = state;
 
-		if (state == PURPLE_TYPING)
-		{
-			purple_signal_emit(purple_conversations_get_handle(),
-							 "buddy-typing", im->conv->account, im->conv->name);
-		}
-		else if (state == PURPLE_TYPED)
+		switch (state)
 		{
-			purple_signal_emit(purple_conversations_get_handle(),
-							 "buddy-typed", im->conv->account, im->conv->name);
-		}
-		else if (state == PURPLE_NOT_TYPING)
-		{
-			purple_signal_emit(purple_conversations_get_handle(),
-							 "buddy-typing-stopped", im->conv->account, im->conv->name);
+			case PURPLE_TYPING:
+				purple_signal_emit(purple_conversations_get_handle(),
+								   "buddy-typing", im->conv->account, im->conv->name);
+				break;
+			case PURPLE_TYPED:
+				purple_signal_emit(purple_conversations_get_handle(),
+								   "buddy-typed", im->conv->account, im->conv->name);
+				break;
+			case PURPLE_NOT_TYPING:
+				purple_signal_emit(purple_conversations_get_handle(),
+								   "buddy-typing-stopped", im->conv->account, im->conv->name);
+				break;
 		}
 	}
 }
--- a/libpurple/dbus-analyze-functions.py	Sat May 19 22:48:25 2007 +0000
+++ b/libpurple/dbus-analyze-functions.py	Sat May 19 22:48:51 2007 +0000
@@ -96,7 +96,7 @@
 
         if len(type) == 1:
             # simple types (int, gboolean, etc.) and enums
-            if (type[0] in simpletypes) or (type[0].startswith("Purple")):
+            if (type[0] in simpletypes) or ((type[0].startswith("Purple") and not type[0].endswith("Callback"))):
                 return self.inputsimple(type, name)
 
         # pointers ... 
@@ -118,7 +118,6 @@
             # unknown pointers are always replaced with NULL
             else:
                 return self.inputpointer(type, name)
-                return
 
         raise myexception
 
--- a/libpurple/idle.c	Sat May 19 22:48:25 2007 +0000
+++ b/libpurple/idle.c	Sat May 19 22:48:51 2007 +0000
@@ -31,7 +31,6 @@
 #include "signals.h"
 
 #define IDLEMARK 600 /* 10 minutes! */
-#define IDLE_CHECK_INTERVAL 5 /* 5 seconds */
 
 typedef enum
 {
@@ -92,6 +91,8 @@
 	purple_presence_set_idle(presence, FALSE, 0);
 }
 
+
+static gint time_until_next_idle_event;
 /*
  * This function should be called when you think your idle state
  * may have changed.  Maybe you're over the 10-minute mark and
@@ -110,14 +111,17 @@
  * 2. Set or unset your auto-away message.
  * 3. Report your current idle time to the IM server.
  */
-static gint
-check_idleness()
+
+static void
+check_idleness(void)
 {
 	time_t time_idle;
 	gboolean auto_away;
 	const gchar *idle_reporting;
 	gboolean report_idle;
 	GList *l;
+	gint away_seconds = 0;
+	static int no_away = 0;
 
 	purple_signal_emit(purple_blist_get_handle(), "update-idle");
 
@@ -153,14 +157,24 @@
 			time_idle = time(NULL) - last_active_time;
 	}
 
-	if (auto_away &&
-		(time_idle > (60 * purple_prefs_get_int("/purple/away/mins_before_away"))))
+	time_until_next_idle_event = IDLEMARK - time_idle; /* reasonable start upperbound */
+
+	if (auto_away || !no_away)
+		away_seconds = 60 * purple_prefs_get_int("/purple/away/mins_before_away");
+
+	if (auto_away && time_idle > away_seconds)
 	{
 		purple_savedstatus_set_idleaway(TRUE);
+		no_away = 0;
+		if (time_idle < away_seconds && (away_seconds - time_idle) < time_until_next_idle_event)
+			time_until_next_idle_event = away_seconds - time_idle;
 	}
-	else if (time_idle < 60 * purple_prefs_get_int("/purple/away/mins_before_away"))
+	else if (!no_away && time_idle < away_seconds)
 	{
 		purple_savedstatus_set_idleaway(FALSE);
+		no_away = 1;
+		if (time_idle < away_seconds && (away_seconds - time_idle) < time_until_next_idle_event)
+			time_until_next_idle_event = away_seconds - time_idle;
 	}
 
 	/* Idle reporting stuff */
@@ -177,8 +191,21 @@
 		while (idled_accts != NULL)
 			set_account_unidle(idled_accts->data);
 	}
+	
+	if (time_until_next_idle_event < 0)
+		time_until_next_idle_event = IDLEMARK;
+}
 
-	return TRUE;
+
+/*
+ * Check idle and set the timer to fire at the next idle-worth event 
+ */
+static gint
+check_idleness_timer()
+{
+	check_idleness();
+	idle_timer = purple_timeout_add(1000 * (time_until_next_idle_event + 1), check_idleness_timer, NULL);
+	return FALSE;
 }
 
 static void
@@ -241,7 +268,7 @@
 purple_idle_init()
 {
 	/* Add the timer to check if we're idle */
-	idle_timer = purple_timeout_add(IDLE_CHECK_INTERVAL * 1000, check_idleness, NULL);
+	idle_timer = purple_timeout_add(1000 * (IDLEMARK + 1), check_idleness_timer, NULL);
 
 	purple_signal_connect(purple_conversations_get_handle(), "sent-im-msg",
 						purple_idle_get_handle(),
--- a/libpurple/notify.c	Sat May 19 22:48:25 2007 +0000
+++ b/libpurple/notify.c	Sat May 19 22:48:51 2007 +0000
@@ -22,6 +22,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+#include "internal.h"
+#include "dbus-maybe.h"
 #include "notify.h"
 
 static PurpleNotifyUiOps *notify_ui_ops = NULL;
@@ -481,6 +483,7 @@
 	PurpleNotifyUserInfoEntry *user_info_entry;
 	
 	user_info_entry = g_new0(PurpleNotifyUserInfoEntry, 1);
+	PURPLE_DBUS_REGISTER_POINTER(user_info_entry, PurpleNotifyUserInfoEntry);
 	user_info_entry->label = g_strdup(label);
 	user_info_entry->value = g_strdup(value);
 	user_info_entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_PAIR;
@@ -495,6 +498,7 @@
 	
 	g_free(user_info_entry->label);
 	g_free(user_info_entry->value);	
+	PURPLE_DBUS_UNREGISTER_POINTER(user_info_entry);
 	g_free(user_info_entry);
 }
 
@@ -504,6 +508,7 @@
 	PurpleNotifyUserInfo *user_info;
 	
 	user_info = g_new0(PurpleNotifyUserInfo, 1);
+	PURPLE_DBUS_REGISTER_POINTER(user_info, PurpleNotifyUserInfo);
 	user_info->user_info_entries = NULL;
 	
 	return user_info;
@@ -521,6 +526,7 @@
 	}
 	
 	g_list_free(user_info->user_info_entries);
+	PURPLE_DBUS_UNREGISTER_POINTER(user_info);
 	g_free(user_info);
 }
 
--- a/libpurple/server.c	Sat May 19 22:48:25 2007 +0000
+++ b/libpurple/server.c	Sat May 19 22:48:51 2007 +0000
@@ -576,15 +576,20 @@
 		purple_conv_im_set_typing_state(im, state);
 		purple_conv_im_update_typing(im);
 	} else {
-		if (state == PURPLE_TYPING)
+		switch (state)
 		{
-			purple_signal_emit(purple_conversations_get_handle(),
-							 "buddy-typing", gc->account, name);
-		}
-		else
-		{
-			purple_signal_emit(purple_conversations_get_handle(),
-							 "buddy-typed", gc->account, name);
+			case PURPLE_TYPING:
+				purple_signal_emit(purple_conversations_get_handle(),
+								   "buddy-typing", gc->account, name);
+				break;
+			case PURPLE_TYPED:
+				purple_signal_emit(purple_conversations_get_handle(),
+								   "buddy-typed", gc->account, name);
+				break;
+			case PURPLE_NOT_TYPING:
+				purple_signal_emit(purple_conversations_get_handle(),
+								   "buddy-typing-stopped", gc->account, name);
+				break;
 		}
 	}
 
--- a/pidgin/gtkconv.c	Sat May 19 22:48:25 2007 +0000
+++ b/pidgin/gtkconv.c	Sat May 19 22:48:51 2007 +0000
@@ -5556,9 +5556,9 @@
 
 	flags = purple_conv_chat_user_get_flags(chat, user);
 
-	cbuddy = purple_conv_chat_cb_new(user, alias, flags);
-
-	add_chat_buddy_common(conv, cbuddy, NULL);
+	cbuddy = purple_conv_chat_cb_find(chat, user);
+	if (cbuddy)
+		add_chat_buddy_common(conv, cbuddy, NULL);
 	g_free(alias);
 }
 
--- a/pidgin/gtkidle.c	Sat May 19 22:48:25 2007 +0000
+++ b/pidgin/gtkidle.c	Sat May 19 22:48:51 2007 +0000
@@ -103,14 +103,21 @@
 
 	/* Query xscreensaver */
 	static XScreenSaverInfo *mit_info = NULL;
+	static int has_extension = -1;
 	int event_base, error_base;
-	if (XScreenSaverQueryExtension(GDK_DISPLAY(), &event_base, &error_base)) {
-		if (mit_info == NULL) {
+
+	if (has_extension == -1)
+		has_extension = XScreenSaverQueryExtension(GDK_DISPLAY(), &event_base, &error_base);
+
+	if (has_extension)
+	{
+		if (mit_info == NULL)
 			mit_info = XScreenSaverAllocInfo();
-		}
+
 		XScreenSaverQueryInfo(GDK_DISPLAY(), GDK_ROOT_WINDOW(), mit_info);
 		return (mit_info->idle) / 1000;
-	} else
+	}
+	else
 		return 0;
 #  endif /* !_WIN32 */
 # endif /* !HAVE_IOKIT */
--- a/pidgin/gtkimhtml.c	Sat May 19 22:48:25 2007 +0000
+++ b/pidgin/gtkimhtml.c	Sat May 19 22:48:51 2007 +0000
@@ -3388,7 +3388,7 @@
 		return FALSE;
 
 	pix = gdk_pixbuf_animation_get_static_image(anim);
-	image = gtk_imhtml_image_new(pix, NULL, 0);
+	image = gtk_imhtml_image_new(pix, smiley->smile, 0);
 	ret = gtk_imhtml_image_clicked(w, event, (GtkIMHtmlImage*)image);
 	g_object_set_data_full(G_OBJECT(w), "image-data", image, (GDestroyNotify)gtk_imhtml_image_free);
 	g_object_unref(G_OBJECT(pix));
--- a/pidgin/gtkmain.c	Sat May 19 22:48:25 2007 +0000
+++ b/pidgin/gtkmain.c	Sat May 19 22:48:51 2007 +0000
@@ -473,9 +473,6 @@
 #else
 	debug_enabled = FALSE;
 #endif
-
-	/* This is the first Glib function call. Make sure to initialize GThread bfeore then */
-	g_thread_init(NULL);
 	
 #ifdef ENABLE_NLS
 	bindtextdomain(PACKAGE, LOCALEDIR);
--- a/pidgin/gtkutils.c	Sat May 19 22:48:25 2007 +0000
+++ b/pidgin/gtkutils.c	Sat May 19 22:48:51 2007 +0000
@@ -510,10 +510,10 @@
 	const char *proto_name;
 	char buf[256];
 	int i, selected_index = -1;
-	char *gtalk_name = NULL;
+	const char *gtalk_name = NULL;
 
 	if (purple_find_prpl("prpl-jabber"))
-		gtalk_name = g_strdup(_("Google Talk"));
+		gtalk_name = _("Google Talk");
 
 	optmenu = gtk_option_menu_new();
 	gtk_widget_show(optmenu);
@@ -548,10 +548,9 @@
 				image = gtk_image_new();
 
 			gtalk_item = pidgin_protocol_option_menu_item(menu, sg, image, gtalk_name, "prpl-fake");
-			g_object_set_data(G_OBJECT(gtalk_item), "real_protocol", plugin->info->id);
+			g_object_set_data(G_OBJECT(gtalk_item), "real_protocol", "prpl-jabber");
 			i++;
 
-			g_free(gtalk_name);
 			gtalk_name = NULL;
 		}
 
@@ -586,12 +585,6 @@
 			g_object_unref(G_OBJECT(pixbuf));
 	}
 
-	/* This is only needed if Pidgin has zero prpls compiled in, but
-	 * I'm doing it because it's proper and might make a difference
-	 * for automated source checkers. */
-	g_free(gtalk_name);
-
-
 	gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), menu);
 
 	if (selected_index != -1)
--- a/pidgin/win32/gtkwin32dep.c	Sat May 19 22:48:25 2007 +0000
+++ b/pidgin/win32/gtkwin32dep.c	Sat May 19 22:48:51 2007 +0000
@@ -251,7 +251,13 @@
 
 static gboolean stop_flashing(GtkWidget *widget, GdkEventFocus *event, gpointer data) {
 	GtkWindow *window = data;
+	gpointer handler_id;
+
 	winpidgin_window_flash(window, FALSE);
+
+	if ((handler_id = g_object_get_data(G_OBJECT(window), "flash_stop_handler_id")))
+		g_signal_handler_disconnect(G_OBJECT(window), (gulong) GPOINTER_TO_UINT(handler_id));
+
 	return FALSE;
 }
 
@@ -275,12 +281,12 @@
 		memset(&info, 0, sizeof(FLASHWINFO));
 		info.cbSize = sizeof(FLASHWINFO);
 		info.hwnd = GDK_WINDOW_HWND(gdkwin);
-		if (flash)
-			info.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG;
-		else
+		if (flash) {
+			info.uCount = 3;
+			info.dwFlags = FLASHW_ALL | FLASHW_TIMER;
+		} else
 			info.dwFlags = FLASHW_STOP;
 		info.dwTimeout = 0;
-		info.dwTimeout = 0;
 
 		MyFlashWindowEx(&info);
 	} else
@@ -314,8 +320,11 @@
 
 	winpidgin_window_flash(window, TRUE);
 	/* Stop flashing when window receives focus */
-	g_signal_connect(G_OBJECT(window), "focus-in-event",
-					 G_CALLBACK(stop_flashing), window);
+	if (g_object_get_data(G_OBJECT(window), "flash_stop_handler_id") == NULL) {
+		gulong handler_id = g_signal_connect(G_OBJECT(window), "focus-in-event",
+						     G_CALLBACK(stop_flashing), window);
+		g_object_set_data(G_OBJECT(window), "flash_stop_handler_id", GUINT_TO_POINTER(handler_id));
+	}
 }
 
 static gboolean