changeset 20890:086b6e3e5015

merge of 'b7ee9ed3d96546482462baf63c4127858553c275' and 'fa0e512d79dfe479bc36c2436089b51854ef3eb5'
author Richard Laager <rlaager@wiktel.com>
date Fri, 12 Oct 2007 03:49:39 +0000
parents 63ce5e7f453d (current diff) c7b20abc3885 (diff)
children 59c9c04879af ce9579a6bcdd e967fd47baa5
files ChangeLog.API
diffstat 32 files changed, 424 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog.API	Wed Oct 10 04:04:07 2007 +0000
+++ b/ChangeLog.API	Fri Oct 12 03:49:39 2007 +0000
@@ -96,9 +96,6 @@
 		* purple_timeout_add_seconds
 		    Callers should prefer this to purple_timeout_add for timers
 		    longer than 1 second away.  Be aware of the rounding, though.
-		* purple_timeout_add_seconds
-		    Callers should prefer this to purple_timeout_add for timers
-		    longer than 1 second away.  Be aware of the rounding, though.
 		* purple_xfer_get_remote_user
 		* purple_pounces_get_all_for_ui
 		* purple_prefs_get_children_names
--- a/configure.ac	Wed Oct 10 04:04:07 2007 +0000
+++ b/configure.ac	Fri Oct 12 03:49:39 2007 +0000
@@ -142,13 +142,21 @@
 dnl If we don't have msgfmt, then po/ is going to fail -- ensure that
 dnl AM_GLIB_GNU_GETTEXT found it.
 
-if test x$MSGFMT = xno
+if test x$MSGFMT = xno -o x$MSGFMT$GMSGFMT = x
 then
 	AC_ERROR([
 
 The msgfmt command is required to build libpurple.  If it is installed
 on your system, ensure that it is in your path.  If it is not, install
 GNU gettext to continue.
+
+If you have msgfmt installed, but for some reason this error message
+is still displayed, you have encountered what appears to be a bug in
+third-party configure macros.  Try setting the MSGFMT environment
+variable to the absolute path to your msgfmt binary and trying
+configure again, like this:
+
+MSGFMT=/path/to/msgfmt ./configure ...
 ])
 fi
 
--- a/doc/conversation-signals.dox	Wed Oct 10 04:04:07 2007 +0000
+++ b/doc/conversation-signals.dox	Fri Oct 12 03:49:39 2007 +0000
@@ -429,6 +429,7 @@
    conversation.
   @param conv   The conversation.
   @param list   A pointer to the list of actions.
+  @since 2.1.0
  @endsignaldef
 */
 // vim: syntax=c.doxygen tw=75 et
--- a/doc/gtkconv-signals.dox	Wed Oct 10 04:04:07 2007 +0000
+++ b/doc/gtkconv-signals.dox	Fri Oct 12 03:49:39 2007 +0000
@@ -127,6 +127,7 @@
   @signaldesc
    Emitted immediately before an existing conversation is hidden.
   @param gtkconv  The PidginConversation
+  @since 2.2.0
  @endsignaldef
 
  @signaldef conversation-displayed
@@ -136,6 +137,7 @@
   @signaldesc
    Emitted right after the Pidgin UI is attached to a new or a hidden conversation.
   @param gtkconv  The PidginConversation
+  @since 2.2.0
  @endsignaldef
 
 */
--- a/doc/notify-signals.dox	Wed Oct 10 04:04:07 2007 +0000
+++ b/doc/notify-signals.dox	Fri Oct 12 03:49:39 2007 +0000
@@ -35,6 +35,7 @@
   @param from      Who the email is from.
   @param to        Who the email is to.
   @param url       A url to view the email.
+  @since 2.1.0
  @endsignaldef
 
  @signaldef displaying-emails-notification
@@ -52,6 +53,7 @@
   @param tos        Who the emails are to.
   @param urls       The urls to view the emails.
   @param count      Number of emails being notified of.
+  @since 2.1.0
  @endsignaldef
 
 */
--- a/finch/gntaccount.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/finch/gntaccount.h	Fri Oct 12 03:49:39 2007 +0000
@@ -59,6 +59,8 @@
  * Show the edit dialog for an account.
  *
  * @param account  The account to edit, or @c NULL to create a new account.
+ *
+ * @since 2.2.0
  */
 void finch_account_dialog_show(PurpleAccount *account);
 
--- a/finch/gntblist.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/finch/gntblist.h	Fri Oct 12 03:49:39 2007 +0000
@@ -98,6 +98,8 @@
  * @param name   The user to get information about.
  *
  * @return  Returns the ui-handle for the userinfo notification.
+ *
+ * @since 2.1.0
  */
 gpointer finch_retrieve_user_info(PurpleConnection *conn, const char *name);
 
--- a/finch/gntsound.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/finch/gntsound.h	Fri Oct 12 03:49:39 2007 +0000
@@ -37,6 +37,8 @@
  * Get the name of the active sound profile.
  *
  * @return The name of the profile
+ *
+ * @since 2.1.0
  */
 const char *finch_sound_get_active_profile(void);
 
@@ -44,6 +46,8 @@
  * Set the active profile.  If the profile doesn't exist, nothing is changed.
  * 
  * @param name  The name of the profile
+ *
+ * @since 2.1.0
  */
 void finch_sound_set_active_profile(const char *name);
 
@@ -52,6 +56,8 @@
  *
  * @return A list of strings denoting sound profile names.
  *         Caller must free the list (but not the data).
+ *
+ * @since 2.1.0
  */
 GList *finch_sound_get_profiles(void);
 
@@ -60,6 +66,8 @@
  *
  * @return Returns FALSE if preference is set to 'No sound', or if volume is
  *         set to zero.
+ *
+ * @since 2.2.0
  */
 gboolean finch_sound_is_enabled(void);
 
@@ -67,11 +75,15 @@
  * Gets GNT sound UI ops.
  *
  * @return The UI operations structure.
+ *
+ * @since 2.1.0
  */
 PurpleSoundUiOps *finch_sound_get_ui_ops(void);
 
 /**
  * Show the sound settings dialog.
+ *
+ * @since 2.1.0
  */
 void finch_sounds_show_all(void);
 
--- a/finch/libgnt/gnt.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/finch/libgnt/gnt.h	Fri Oct 12 03:49:39 2007 +0000
@@ -62,6 +62,14 @@
  */
 gboolean gnt_ascii_only(void);
 
+/**
+ * Present a window. If the event was triggered because of user interaction,
+ * the window is moved to the foreground. Otherwise, the Urgent hint is set.
+ *
+ * @param window   The window the present.
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
+ */
 void gnt_window_present(GntWidget *window);
 /**
  * 
--- a/finch/libgnt/gntslider.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/finch/libgnt/gntslider.h	Fri Oct 12 03:49:39 2007 +0000
@@ -75,6 +75,8 @@
 
 /**
  * @return The GType for GntSlider
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 GType gnt_slider_get_gtype(void);
 
@@ -89,6 +91,8 @@
  * @param min    The minimum value for the slider
  *
  * @return  The newly created slider
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 GntWidget * gnt_slider_new(gboolean orient, int max, int min);
 
@@ -98,6 +102,8 @@
  * @param slider  The slider
  * @param max     The maximum value
  * @param min     The minimum value
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 void gnt_slider_set_range(GntSlider *slider, int max, int min);
 
@@ -106,6 +112,8 @@
  * 
  * @param slider  The slider
  * @param step    The amount for each step
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 void gnt_slider_set_step(GntSlider *slider, int step);
 
@@ -114,6 +122,8 @@
  * 
  * @param slider  The slider
  * @param step    The amount for a small step (for the slider)
+ *
+ * @since 2.2.0
  */
 void gnt_slider_set_small_step(GntSlider *slider, int step);
 
@@ -122,6 +132,8 @@
  * 
  * @param slider  The slider
  * @param step    The amount for a large step (for the slider)
+ *
+ * @since 2.2.0
  */
 void gnt_slider_set_large_step(GntSlider *slider, int step);
 
@@ -133,6 +145,8 @@
  *                 forward, negative to change backward
  *
  * @return   The value of the slider after the change
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 int gnt_slider_advance_step(GntSlider *slider, int steps);
 
@@ -141,6 +155,8 @@
  *
  * @param slider  The slider
  * @param value   The current value
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 void gnt_slider_set_value(GntSlider *slider, int value);
 
@@ -149,6 +165,8 @@
  *
  * @param slider The slider
  *
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 int gnt_slider_get_value(GntSlider *slider);
 
@@ -157,6 +175,8 @@
  *
  * @param slider   The slider
  * @param label    The label to update
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 void gnt_slider_reflect_label(GntSlider *slider, GntLabel *label);
 
--- a/finch/libgnt/gntstyle.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/finch/libgnt/gntstyle.h	Fri Oct 12 03:49:39 2007 +0000
@@ -53,6 +53,8 @@
  * @param key     The key
  *
  * @return  The value of the setting as a string, or @c NULL
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 char *gnt_style_get_from_name(const char *group, const char *key);
 
@@ -62,6 +64,8 @@
  *
  * @param value   The value of the boolean setting as a string
  * @return    The boolean value
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 gboolean gnt_style_parse_bool(const char *value);
 
--- a/finch/libgnt/gnttextview.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/finch/libgnt/gnttextview.h	Fri Oct 12 03:49:39 2007 +0000
@@ -204,6 +204,8 @@
  *
  * @param view  The textview widget
  * @param flag  The flag to set
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 void gnt_text_view_set_flag(GntTextView *view, GntTextViewFlag flag);
 
--- a/finch/libgnt/gnttree.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/finch/libgnt/gnttree.h	Fri Oct 12 03:49:39 2007 +0000
@@ -383,6 +383,8 @@
  *
  * @see gnt_tree_set_column_titles
  * @see gnt_tree_set_show_title
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 void gnt_tree_set_column_title(GntTree *tree, int index, const char *title);
 
@@ -486,6 +488,8 @@
  *
  * @see gnt_tree_set_col_width
  * @see gnt_tree_set_column_width_ratio
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 void gnt_tree_set_column_resizable(GntTree *tree, int col, gboolean res);
 
@@ -505,6 +509,8 @@
  * @param tree  The tree
  * @param col   The index of the column
  * @param right @c TRUE if the text in the column should be right aligned
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 void gnt_tree_set_column_is_right_aligned(GntTree *tree, int col, gboolean right);
 
@@ -519,6 +525,8 @@
  *
  * @see gnt_tree_set_col_width
  * @see gnt_tree_set_column_resizable
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 void gnt_tree_set_column_width_ratio(GntTree *tree, int cols[]);
 
@@ -527,6 +535,8 @@
  *
  * @param tree   The tree
  * @param col    The index of the column
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 void gnt_tree_set_search_column(GntTree *tree, int col);
 
@@ -535,6 +545,8 @@
  *
  * @param tree   The tree
  * @return  @c TRUE if the user is searching, @c FALSE otherwise.
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 gboolean gnt_tree_is_searching(GntTree *tree);
 
@@ -547,6 +559,8 @@
  *              string and the content of row in the search column.
  *              If the function returns @c TRUE, the row is dislayed,
  *              otherwise it's not.
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 void gnt_tree_set_search_function(GntTree *tree,
 		gboolean (*func)(GntTree *tree, gpointer key, const char *search, const char *current));
--- a/finch/libgnt/gntutils.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/finch/libgnt/gntutils.h	Fri Oct 12 03:49:39 2007 +0000
@@ -139,6 +139,8 @@
  * @param string   The XHTML string
  * @param tv       The GntTextView
  * @return  @c TRUE if the string was added to the textview properly, @c FALSE otherwise.
+ *
+ * @since 2.2.0
  */
 gboolean gnt_util_parse_xhtml_to_textview(const char *string, GntTextView *tv);
 
@@ -148,6 +150,8 @@
  * @param widget  The widget
  * @param key     The key to trigger the button
  * @param button  The button to trigger
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
  */
 void gnt_util_set_trigger_widget(GntWidget *wid, const char *text, GntWidget *button);
 
--- a/finch/libgnt/gntws.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/finch/libgnt/gntws.h	Fri Oct 12 03:49:39 2007 +0000
@@ -69,18 +69,112 @@
 
 G_BEGIN_DECLS
 
+/**
+ * @return The GType for GntWS.
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
+ */
 GType gnt_ws_get_gtype(void);
 
+/**
+ * Create a new workspace with the specified name.
+ *
+ * @param name  The desired name of the workspace, or @c NULL.
+ *
+ * @return The newly created workspace.
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
+ */
 GntWS *gnt_ws_new(const char *name);
+
+/**
+ * Set the name of a workspace.
+ *
+ * @param ws    The workspace to rename.
+ * @param name  The new name of the workspace.
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
+ */
 void gnt_ws_set_name(GntWS *ws, const gchar *name);
+
+/**
+ * Add a widget to a workspace.
+ *
+ * @param ws     The workspace.
+ * @param widget The widget to add.
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
+ */
 void gnt_ws_add_widget(GntWS *ws, GntWidget *widget);
+
+/**
+ * Remove a widget from a workspace.
+ *
+ * @param ws      The workspace
+ * @param widget  The widget to remove from the workspace.
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
+ */
 void gnt_ws_remove_widget(GntWS *ws, GntWidget *widget);
+
+/**
+ * Hide a widget in a workspace.
+ *
+ * @param widget  The widget to hide.
+ * @param nodes   A hashtable containing information about the widgets.
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
+ */
 void gnt_ws_widget_hide(GntWidget *widget, GHashTable *nodes);
+
+/**
+ * Show a widget in a workspace.
+ *
+ * @param widget   The widget to show.
+ * @param nodes   A hashtable containing information about the widgets.
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
+ */
 void gnt_ws_widget_show(GntWidget *widget, GHashTable *nodes);
+
+/**
+ * Draw the taskbar in a workspace.
+ *
+ * @param ws         The workspace.
+ * @param reposition Whether the workspace should reposition the taskbar.
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
+ */
 void gnt_ws_draw_taskbar(GntWS *ws, gboolean reposition);
+
+/**
+ * Hide a workspace.
+ *
+ * @param ws      The workspace to hide.
+ * @param table   A hashtable containing information about the widgets.
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
+ */
 void gnt_ws_hide(GntWS *ws, GHashTable *table);
+
+/**
+ * Show a workspace.
+ *
+ * @param ws      The workspace to hide.
+ * @param table   A hashtable containing information about the widgets.
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
+ */
 void gnt_ws_show(GntWS *ws, GHashTable *table);
 
+/**
+ * Get the name of a workspace.
+ *
+ * @param ws   The workspace.
+ * @return  The name of the workspace (can be @c NULL).
+ *
+ * @since 2.0.0 (gnt), 2.1.0 (pidgin)
+ */
 const char * gnt_ws_get_name(GntWS *ws);
 
 #endif
--- a/finch/libgnt/test/Makefile	Wed Oct 10 04:04:07 2007 +0000
+++ b/finch/libgnt/test/Makefile	Fri Oct 12 03:49:39 2007 +0000
@@ -1,5 +1,5 @@
 CC=gcc
-CFLAGS=`pkg-config --cflags gobject-2.0 gmodule-2.0` -g -I../ -DSTANDALONE
+CFLAGS=`pkg-config --cflags gobject-2.0 gmodule-2.0` -g -I../ -DSTANDALONE -I/usr/inclue/ncursesw/
 LDFLAGS=`pkg-config --libs gobject-2.0 gmodule-2.0 gnt` -pg
 
 EXAMPLES=combo focus tv multiwin keys menu parse
--- a/libpurple/certificate.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/libpurple/certificate.h	Fri Oct 12 03:49:39 2007 +0000
@@ -2,6 +2,7 @@
  * @file certificate.h Public-Key Certificate API
  * @ingroup core
  * @see @ref certificate-signals
+ * @since 2.2.0
  */
 
 /*
--- a/libpurple/conversation.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/libpurple/conversation.h	Fri Oct 12 03:49:39 2007 +0000
@@ -285,6 +285,8 @@
 
 /**
  * Description of a conversation message
+ *
+ * @since 2.2.0
  */
 struct _PurpleConvMessage
 {
@@ -670,6 +672,8 @@
  * @return  A GList of PurpleConvMessage's. The must not modify the list or the data within.
  *          The list contains the newest message at the beginning, and the oldest message at
  *          the end.
+ *
+ * @since 2.2.0
  */
 GList *purple_conversation_get_message_history(PurpleConversation *conv);
 
@@ -677,6 +681,8 @@
  * Clear the message history of a conversation.
  *
  * @param conv  The conversation
+ *
+ * @since 2.2.0
  */
 void purple_conversation_clear_message_history(PurpleConversation *conv);
 
@@ -686,6 +692,8 @@
  * @param msg   A PurpleConvMessage
  *
  * @return   The name of the sender of the message
+ *
+ * @since 2.2.0
  */
 const char *purple_conversation_message_get_sender(PurpleConvMessage *msg);
 
@@ -695,6 +703,8 @@
  * @param msg   A PurpleConvMessage
  *
  * @return   The name of the sender of the message
+ *
+ * @since 2.2.0
  */
 const char *purple_conversation_message_get_message(PurpleConvMessage *msg);
 
@@ -704,6 +714,8 @@
  * @param msg   A PurpleConvMessage
  *
  * @return   The name of the sender of the message
+ *
+ * @since 2.2.0
  */
 PurpleMessageFlags purple_conversation_message_get_flags(PurpleConvMessage *msg);
 
@@ -713,6 +725,8 @@
  * @param msg   A PurpleConvMessage
  *
  * @return   The name of the sender of the message
+ *
+ * @since 2.2.0
  */
 time_t purple_conversation_message_get_timestamp(PurpleConvMessage *msg);
 
@@ -1318,6 +1332,8 @@
  * @return  A list of PurpleMenuAction items, harvested by the
  *          chat-extended-menu signal. The list and the menuaction
  *          items should be freed by the caller.
+ *
+ * @since 2.1.0
  */
 GList * purple_conversation_get_extended_menu(PurpleConversation *conv);
 
@@ -1331,6 +1347,8 @@
  *                message, if not @c NULL. It must be freed by the caller with g_free().
  *
  * @return  @c TRUE if the command was executed successfully, @c FALSE otherwise.
+ *
+ * @since 2.1.0
  */
 gboolean purple_conversation_do_command(PurpleConversation *conv, const gchar *cmdline, const gchar *markup, gchar **error);
 
--- a/libpurple/eventloop.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/libpurple/eventloop.h	Fri Oct 12 03:49:39 2007 +0000
@@ -138,6 +138,8 @@
  * @param data		data to pass to @a function.
  * @return A handle to the timer which can be passed to 
  *         purple_timeout_remove to remove the timer.
+ *
+ * @since 2.1.0
  */
 guint purple_timeout_add_seconds(guint interval, GSourceFunc function, gpointer data);
 
--- a/libpurple/ft.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/libpurple/ft.h	Fri Oct 12 03:49:39 2007 +0000
@@ -242,6 +242,8 @@
  * @param xfer The file transfer.
  *
  * @return The name of the remote user.
+ *
+ * @since 2.1.0
  */
 const char *purple_xfer_get_remote_user(const PurpleXfer *xfer);
 
--- a/libpurple/pluginpref.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/libpurple/pluginpref.h	Fri Oct 12 03:49:39 2007 +0000
@@ -35,16 +35,16 @@
  */
 typedef enum
 {
-	PURPLE_STRING_FORMAT_TYPE_NONE      = 0,
-	PURPLE_STRING_FORMAT_TYPE_MULTILINE = 1 << 0,
-	PURPLE_STRING_FORMAT_TYPE_HTML      = 1 << 1
+	PURPLE_STRING_FORMAT_TYPE_NONE      = 0,          /**< The string is plain text. */
+	PURPLE_STRING_FORMAT_TYPE_MULTILINE = 1 << 0,     /**< The string can have newlines. */
+	PURPLE_STRING_FORMAT_TYPE_HTML      = 1 << 1      /**< The string can be in HTML. */
 } PurpleStringFormatType;
 
 typedef enum {
 	PURPLE_PLUGIN_PREF_NONE,
 	PURPLE_PLUGIN_PREF_CHOICE,
-	PURPLE_PLUGIN_PREF_INFO,   /**< no-value label */
-	PURPLE_PLUGIN_PREF_STRING_FORMAT
+	PURPLE_PLUGIN_PREF_INFO,              /**< no-value label */
+	PURPLE_PLUGIN_PREF_STRING_FORMAT      /**< The preference has a string value. */
 } PurplePluginPrefType;
 
 #include <glib.h>
--- a/libpurple/prefs.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/libpurple/prefs.h	Fri Oct 12 03:49:39 2007 +0000
@@ -291,6 +291,8 @@
  * @return A list of newly allocated strings denoting the names of the children.
  *         Returns @c NULL if there are no children or if pref doesn't exist.
  *         The caller must free all the strings and the list.
+ *
+ * @since 2.1.0
  */
 GList *purple_prefs_get_children_names(const char *name);
 
--- a/libpurple/protocols/bonjour/Makefile.mingw	Wed Oct 10 04:04:07 2007 +0000
+++ b/libpurple/protocols/bonjour/Makefile.mingw	Fri Oct 12 03:49:39 2007 +0000
@@ -36,7 +36,7 @@
 			-I$(PIDGIN_TREE_TOP)
 
 LIB_PATHS +=		-L$(GTK_TOP)/lib \
-			-L$(BONJOUR_TOP)/lib \
+			-L$(BONJOUR_TOP)/lib/win32 \
 			-L$(LIBXML2_TOP)/lib \
 			-L$(PURPLE_TOP)
 
--- a/libpurple/protocols/qq/buddy_info.c	Wed Oct 10 04:04:07 2007 +0000
+++ b/libpurple/protocols/qq/buddy_info.c	Fri Oct 12 03:49:39 2007 +0000
@@ -306,12 +306,10 @@
 	g_free(mid);
 }
 
-static gchar *parse_field(GList **list, gboolean choice)
+static gchar *parse_field(PurpleRequestField *field, gboolean choice)
 {
 	gchar *value;
-	PurpleRequestField *field;
 
-	field = (PurpleRequestField *) (*list)->data;
 	if (choice) {
 		value = g_strdup_printf("%d", purple_request_field_choice_get_value(field));
 	} else {
@@ -321,7 +319,6 @@
 		else
 			value = utf8_to_qq(value, QQ_CHARSET_DEFAULT);
 	}
-	*list = g_list_remove_link(*list, *list);
 
 	return value;
 }
@@ -331,7 +328,7 @@
 {
 	PurpleConnection *gc;
 	qq_data *qd;
-	GList *list,  *groups;
+	GList *groups;
 	contact_info *info;
 
 	gc = mid->gc;
@@ -341,34 +338,76 @@
 	info = mid->info;
 
 	groups = purple_request_fields_get_groups(fields);
-	list = purple_request_field_group_get_fields(groups->data);
-	info->uid = parse_field(&list, FALSE);
-	info->nick = parse_field(&list, FALSE);
-	info->name = parse_field(&list, FALSE);
-	info->age = parse_field(&list, FALSE);
-	info->gender = parse_field(&list, TRUE);
-	info->country = parse_field(&list, FALSE);
-	info->province = parse_field(&list, FALSE);
-	info->city = parse_field(&list, FALSE);
-	groups = g_list_remove_link(groups, groups);
-	list = purple_request_field_group_get_fields(groups->data);
-	info->horoscope = parse_field(&list, TRUE);
-	info->occupation = parse_field(&list, FALSE);
-	info->zodiac = parse_field(&list, TRUE);
-	info->blood = parse_field(&list, TRUE);
-	info->college = parse_field(&list, FALSE);
-	info->email = parse_field(&list, FALSE);
-	info->address = parse_field(&list, FALSE);
-	info->zipcode = parse_field(&list, FALSE);
-	info->hp_num = parse_field(&list, FALSE);
-	info->tel = parse_field(&list, FALSE);
-	info->homepage = parse_field(&list, FALSE);
-	groups = g_list_remove_link(groups, groups);
-	list = purple_request_field_group_get_fields(groups->data);
-	info->intro = parse_field(&list, FALSE);
+	while (groups != NULL) {
+		PurpleRequestFieldGroup *group = groups->data;
+		const char *g_name = purple_request_field_group_get_title(group);
+		GList *fields = purple_request_field_group_get_fields(group);
+
+		if (g_name == NULL)
+			continue;
+
+		while (fields != NULL) {
+			PurpleRequestField *field = fields->data;
+			const char *f_id = purple_request_field_get_id(field);
+
+			if (!strcmp(QQ_PRIMARY_INFORMATION, g_name)) {
+
+				if (!strcmp(f_id, "uid"))
+					info->uid = parse_field(field, FALSE);
+				else if (!strcmp(f_id, "nick"))
+					info->nick = parse_field(field, FALSE);
+				else if (!strcmp(f_id, "name"))
+					info->name = parse_field(field, FALSE);
+				else if (!strcmp(f_id, "age"))
+					info->age = parse_field(field, FALSE);
+				else if (!strcmp(f_id, "gender"))
+					info->gender = parse_field(field, TRUE);
+				else if (!strcmp(f_id, "country"))
+					info->country = parse_field(field, FALSE);
+				else if (!strcmp(f_id, "province"))
+					info->province = parse_field(field, FALSE);
+				else if (!strcmp(f_id, "city"))
+					info->city = parse_field(field, FALSE);
+
+			} else if (!strcmp(QQ_ADDITIONAL_INFORMATION, g_name)) {
 
-	g_list_free(groups);
+				if (!strcmp(f_id, "horoscope"))
+					info->horoscope = parse_field(field, TRUE);
+				else if (!strcmp(f_id, "occupation"))
+					info->occupation = parse_field(field, FALSE);
+				else if (!strcmp(f_id, "zodiac"))
+					info->zodiac = parse_field(field, TRUE);
+				else if (!strcmp(f_id, "blood"))
+					info->blood = parse_field(field, TRUE);
+				else if (!strcmp(f_id, "college"))
+					info->college = parse_field(field, FALSE);
+				else if (!strcmp(f_id, "email"))
+					info->email = parse_field(field, FALSE);
+				else if (!strcmp(f_id, "address"))
+					info->address = parse_field(field, FALSE);
+				else if (!strcmp(f_id, "zipcode"))
+					info->zipcode = parse_field(field, FALSE);
+				else if (!strcmp(f_id, "hp_num"))
+					info->hp_num = parse_field(field, FALSE);
+				else if (!strcmp(f_id, "tel"))
+					info->tel = parse_field(field, FALSE);
+				else if (!strcmp(f_id, "homepage"))
+					info->homepage = parse_field(field, FALSE);
 
+			} else if (!strcmp(QQ_INTRO, g_name)) {
+
+				if (!strcmp(f_id, "intro"))
+					info->intro = parse_field(field, FALSE);
+
+			}
+
+			fields = fields->next;
+		}
+
+		groups = groups->next;
+	}
+
+	/* This casting looks like a horrible idea to me -DAA */
 	qq_send_packet_modify_info(gc, (gchar **) info);
 
 	g_strfreev((gchar **) mid->info);
@@ -438,6 +477,7 @@
 		add_string_field_to_group(group, "country", QQ_COUNTRY, info->country);
 		add_string_field_to_group(group, "province", QQ_PROVINCE, info->province);
 		add_string_field_to_group(group, "city", QQ_CITY, info->city);
+
 		group = setup_field_group(fields, QQ_ADDITIONAL_INFORMATION);
 		add_choice_field_to_group(group, "horoscope", QQ_HOROSCOPE, info->horoscope, horoscope_names, QQ_HOROSCOPE_SIZE);
 		add_string_field_to_group(group, "occupation", QQ_OCCUPATION, info->occupation);
--- a/libpurple/sslconn.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/libpurple/sslconn.h	Fri Oct 12 03:49:39 2007 +0000
@@ -204,17 +204,19 @@
  									   void *data);
 
 /**
-  * Makes a SSL connection using an already open file descriptor.
-  *
-  * @param account    The account making the connection.
-  * @param fd         The file descriptor.
-  * @param func       The SSL input handler function.
-  * @param error_func The SSL error handler function.
-  * @param host       The hostname of the other peer (to verify the CN)
-  * @param data       User-defined data.
-  *
-  * @return The SSL connection handle.
-  */
+ * Makes a SSL connection using an already open file descriptor.
+ *
+ * @param account    The account making the connection.
+ * @param fd         The file descriptor.
+ * @param func       The SSL input handler function.
+ * @param error_func The SSL error handler function.
+ * @param host       The hostname of the other peer (to verify the CN)
+ * @param data       User-defined data.
+ *
+ * @return The SSL connection handle.
+ *
+ * @since 2.2.0
+ */
 PurpleSslConnection *purple_ssl_connect_with_host_fd(PurpleAccount *account, int fd,
                                            PurpleSslInputFunction func,
                                            PurpleSslErrorFunction error_func,
@@ -268,6 +270,8 @@
  *
  * @return The peer certificate chain, in the order of certificate, issuer,
  *         issuer's issuer, etc. @a NULL if no certificates have been provided,
+ *
+ * @since 2.2.0
  */
 GList * purple_ssl_get_peer_certificates(PurpleSslConnection *gsc);
 
--- a/pidgin/gtkblist.c	Wed Oct 10 04:04:07 2007 +0000
+++ b/pidgin/gtkblist.c	Fri Oct 12 03:49:39 2007 +0000
@@ -5300,7 +5300,7 @@
 static void buddy_node(PurpleBuddy *buddy, GtkTreeIter *iter, PurpleBlistNode *node)
 {
 	PurplePresence *presence;
-	GdkPixbuf *status, *avatar, *emblem;
+	GdkPixbuf *status, *avatar, *emblem, *prpl_icon;
 	char *mark;
 	char *idle = NULL;
 	gboolean expanded = ((struct _pidgin_blist_node *)(node->parent->ui_data))->contact_expanded;
@@ -5310,7 +5310,7 @@
 
 	if (editing_blist)
 		return;
-	
+
 	status = pidgin_blist_get_status_icon((PurpleBlistNode*)buddy,
 						PIDGIN_STATUS_ICON_SMALL);
 
@@ -5357,6 +5357,8 @@
 		}
 	}
 
+	prpl_icon = pidgin_create_prpl_icon(buddy->account, PIDGIN_PRPL_ICON_SMALL);
+
 	gtk_tree_store_set(gtkblist->treemodel, iter,
 			   STATUS_ICON_COLUMN, status,
 			   STATUS_ICON_VISIBLE_COLUMN, TRUE,
@@ -5367,7 +5369,7 @@
 			   BUDDY_ICON_VISIBLE_COLUMN, biglist,
 			   EMBLEM_COLUMN, emblem,
 			   EMBLEM_VISIBLE_COLUMN, (emblem != NULL),
-			   PROTOCOL_ICON_COLUMN, pidgin_create_prpl_icon(buddy->account, PIDGIN_PRPL_ICON_SMALL),
+			   PROTOCOL_ICON_COLUMN, prpl_icon,
 			   PROTOCOL_ICON_VISIBLE_COLUMN, purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"),
 			   BGCOLOR_COLUMN, NULL,
 			   CONTACT_EXPANDER_COLUMN, NULL,
@@ -5383,6 +5385,8 @@
 		g_object_unref(status);
 	if(avatar)
 		g_object_unref(avatar);
+	if(prpl_icon)
+		g_object_unref(prpl_icon);
 }
 
 /* This is a variation on the original gtk_blist_update_contact. Here we
@@ -5503,9 +5507,7 @@
 
 	if(purple_account_is_connected(chat->account)) {
 		GtkTreeIter iter;
-		GdkPixbuf *status;
-		GdkPixbuf *avatar;
-		GdkPixbuf *emblem;
+		GdkPixbuf *status, *avatar, *emblem, *prpl_icon;
 		char *mark;
 		gboolean showicons = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons");
 		PidginBlistNode *ui;
@@ -5536,6 +5538,8 @@
 			mark = bold;
 		}
 
+		prpl_icon = pidgin_create_prpl_icon(chat->account, PIDGIN_PRPL_ICON_SMALL);
+
 		gtk_tree_store_set(gtkblist->treemodel, &iter,
 				STATUS_ICON_COLUMN, status,
 				STATUS_ICON_VISIBLE_COLUMN, TRUE,
@@ -5543,7 +5547,7 @@
 				BUDDY_ICON_VISIBLE_COLUMN,  purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"),
 				EMBLEM_COLUMN, emblem,
 				EMBLEM_VISIBLE_COLUMN, emblem != NULL,
-				PROTOCOL_ICON_COLUMN, pidgin_create_prpl_icon(chat->account, PIDGIN_PRPL_ICON_SMALL),
+				PROTOCOL_ICON_COLUMN, prpl_icon,
 				PROTOCOL_ICON_VISIBLE_COLUMN, purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"),
 				NAME_COLUMN, mark,
 				GROUP_EXPANDER_VISIBLE_COLUMN, FALSE,
@@ -5556,6 +5560,8 @@
 			g_object_unref(status);
 		if(avatar)
 			g_object_unref(avatar);
+		if(prpl_icon)
+			g_object_unref(prpl_icon);
 	} else {
 		pidgin_blist_hide_node(list, node, TRUE);
 	}
--- a/pidgin/gtkblist.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/pidgin/gtkblist.h	Fri Oct 12 03:49:39 2007 +0000
@@ -371,6 +371,8 @@
  * @param selected  Whether this buddy is selected. If TRUE, the markup will not change the color.
  * @param aliased  TRUE to return the appropriate alias of this buddy, FALSE to return its screenname and status information
  * @return The markup for this buddy
+ *
+ * @since 2.1.0
  */
 gchar *pidgin_blist_get_name_markup(PurpleBuddy *buddy, gboolean selected, gboolean aliased);
 
@@ -382,11 +384,15 @@
  *
  * @param node The buddy list node to show a tooltip for
  * @param widget The widget to draw the tooltip on
+ *
+ * @since 2.1.0
  */
 void pidgin_blist_draw_tooltip(PurpleBlistNode *node, GtkWidget *widget);
 
 /**
  * Destroys the current (if any) Buddy List tooltip
+ *
+ * @since 2.1.0
  */
 void pidgin_blist_tooltip_destroy(void);
 
--- a/pidgin/gtkconv.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/pidgin/gtkconv.h	Fri Oct 12 03:49:39 2007 +0000
@@ -253,6 +253,8 @@
  * @param conv  The conversation.
  *
  * @return  Wheter Pidgin UI was successfully attached.
+ *
+ * @since 2.2.0
  */
 gboolean pidgin_conv_attach_to_conversation(PurpleConversation *conv);
 
--- a/pidgin/gtkdocklet.c	Wed Oct 10 04:04:07 2007 +0000
+++ b/pidgin/gtkdocklet.c	Fri Oct 12 03:49:39 2007 +0000
@@ -473,6 +473,87 @@
 	return menuitem;
 }
 
+
+static void
+plugin_act(GtkObject *obj, PurplePluginAction *pam)
+{
+	if (pam && pam->callback)
+		pam->callback(pam);
+}
+
+static void
+build_plugin_actions(GtkWidget *menu, PurplePlugin *plugin,
+		gpointer context)
+{
+	GtkWidget *menuitem;
+	PurplePluginAction *action = NULL;
+	GList *actions, *l;
+
+	actions = PURPLE_PLUGIN_ACTIONS(plugin, context);
+
+	for (l = actions; l != NULL; l = l->next)
+	{
+		if (l->data)
+		{
+			action = (PurplePluginAction *) l->data;
+			action->plugin = plugin;
+			action->context = context;
+
+			menuitem = gtk_menu_item_new_with_label(action->label);
+			gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+
+			g_signal_connect(G_OBJECT(menuitem), "activate",
+					G_CALLBACK(plugin_act), action);
+			g_object_set_data_full(G_OBJECT(menuitem), "plugin_action",
+								   action,
+								   (GDestroyNotify)purple_plugin_action_free);
+			gtk_widget_show(menuitem);
+		}
+		else
+			pidgin_separator(menu);
+	}
+
+	g_list_free(actions);
+}
+
+
+static void
+docklet_plugin_actions(GtkWidget *menu)
+{
+	GtkWidget *menuitem, *submenu;
+	PurplePlugin *plugin = NULL;
+	GList *l;
+	int c = 0;
+
+	g_return_if_fail(menu != NULL);
+
+	/* Add a submenu for each plugin with custom actions */
+	for (l = purple_plugins_get_loaded(); l; l = l->next) {
+		plugin = (PurplePlugin *) l->data;
+
+		if (PURPLE_IS_PROTOCOL_PLUGIN(plugin))
+			continue;
+
+		if (!PURPLE_PLUGIN_HAS_ACTIONS(plugin))
+			continue;
+
+		menuitem = gtk_image_menu_item_new_with_label(_(plugin->info->name));
+		gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+		gtk_widget_show(menuitem);
+
+		submenu = gtk_menu_new();
+		gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
+		gtk_widget_show(submenu);
+
+		build_plugin_actions(submenu, plugin, NULL);
+
+		c++;
+	}
+	if(c>0)
+		pidgin_separator(menu);
+}
+
+
 static void
 docklet_menu() {
 	static GtkWidget *menu = NULL;
@@ -539,6 +620,9 @@
 
 	pidgin_separator(menu);
 
+	/* add plugin actions */
+	docklet_plugin_actions(menu);
+
 	pidgin_new_item_from_stock(menu, _("Quit"), GTK_STOCK_QUIT, G_CALLBACK(purple_core_quit), NULL, 0, 0, NULL);
 
 #ifdef _WIN32
--- a/pidgin/gtkimhtml.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/pidgin/gtkimhtml.h	Fri Oct 12 03:49:39 2007 +0000
@@ -441,6 +441,8 @@
  * @param id       The id to associate with the image.
  *
  * @return A new IM/HTML Scalable object with an image.
+ *
+ * @since 2.1.0
  */
 /*
  * TODO: All this animation code could be combined much better with
@@ -837,6 +839,8 @@
  *
  * @param imhtml  The GTK+ IM/HTML.
  * @param flags   The connection flag which describes the allowed types of formatting.
+ *
+ * @since 2.1.0
  */
 void gtk_imhtml_setup_entry(GtkIMHtml *imhtml, PurpleConnectionFlags flags);
 
--- a/pidgin/gtklog.c	Wed Oct 10 04:04:07 2007 +0000
+++ b/pidgin/gtklog.c	Fri Oct 12 03:49:39 2007 +0000
@@ -680,6 +680,7 @@
 	PidginLogViewer *lv = NULL;
 	const char *name = screenname;
 	char *title;
+	GdkPixbuf *prpl_icon;
 
 	g_return_if_fail(account != NULL);
 	g_return_if_fail(screenname != NULL);
@@ -717,9 +718,14 @@
 		title = g_strdup_printf(_("Conversations with %s"), name);
 	}
 
+	prpl_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_MEDIUM);
+
 	display_log_viewer(ht, purple_log_get_logs(type, screenname, account),
-			title, gtk_image_new_from_pixbuf(pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_MEDIUM)), 
+			title, gtk_image_new_from_pixbuf(prpl_icon),
 			purple_log_get_total_size(type, screenname, account));
+
+	if (prpl_icon)
+		g_object_unref(prpl_icon);
 	g_free(title);
 }
 
--- a/pidgin/gtkutils.h	Wed Oct 10 04:04:07 2007 +0000
+++ b/pidgin/gtkutils.h	Fri Oct 12 03:49:39 2007 +0000
@@ -376,6 +376,8 @@
  *
  * @param conn   The connection to get information from.
  * @param name   The user to get information about.
+ *
+ * @since 2.1.0
  */
 void pidgin_retrieve_user_info(PurpleConnection *conn, const char *name);
 
@@ -385,6 +387,8 @@
  * @param conn   The connection to get information from.
  * @param name   The user to get information about.
  * @param chatid The chat id.
+ *
+ * @since 2.1.0
  */
 void pidgin_retrieve_user_info_in_chat(PurpleConnection *conn, const char *name, int chatid);
 
@@ -423,6 +427,8 @@
  *
  * @param w The widget that we want to label.
  * @param l A GtkLabel that we want to use as the label for the widget.
+ *
+ * @since 2.2.0
  */
 void pidgin_set_accessible_relations(GtkWidget *w, GtkWidget *l);
 
@@ -437,6 +443,8 @@
  *        where the menu shall be drawn. This is an output parameter.
  * @param push_in This is an output parameter?
  * @param data Not used by this particular position function.
+ *
+ * @since 2.1.0
  */
 void pidgin_menu_position_func_helper(GtkMenu *menu, gint *x, gint *y,
 										gboolean *push_in, gpointer data);
@@ -671,6 +679,8 @@
  *
  * @return               A newly created text GtkComboBox containing a GtkEntry
  *                       child.
+ *
+ * @since 2.2.0
  */
 GtkWidget *pidgin_text_combo_box_entry_new(const char *default_item, GList *items);
 
@@ -680,6 +690,8 @@
  * @param widget         The simple text GtkComboBoxEntry equivalent widget
  *
  * @return               The text in the widget's entry. It must not be freed
+ *
+ * @since 2.2.0
  */
 const char *pidgin_text_combo_box_entry_get_text(GtkWidget *widget);
 
@@ -688,6 +700,8 @@
  *
  * @param widget         The simple text GtkComboBoxEntry equivalent widget
  * @param text           The text to set
+ *
+ * @since 2.2.0
  */
 void pidgin_text_combo_box_entry_set_text(GtkWidget *widget, const char *text);