pidgin/pidgin

f7a11b4aef97
propagate from branch 'im.pidgin.pidgin' (head 1ccc3fc7f39ec71e356e5fb2b3794ebc1bc857d8)
to branch 'im.pidgin.cpw.resiak.disconnectreason' (head 786f26a8dc6f51d718fbea247873453e2314aa80)
  • +1 -0
    COPYRIGHT
  • +3 -0
    ChangeLog
  • +3 -2
    finch/finch.h
  • +3 -2
    finch/gntaccount.c
  • +3 -2
    finch/gntaccount.h
  • +3 -2
    finch/gntblist.c
  • +3 -2
    finch/gntblist.h
  • +3 -2
    finch/gntcertmgr.c
  • +3 -2
    finch/gntcertmgr.h
  • +3 -2
    finch/gntconn.c
  • +3 -2
    finch/gntconn.h
  • +3 -2
    finch/gntconv.c
  • +3 -2
    finch/gntconv.h
  • +3 -2
    finch/gntdebug.c
  • +3 -2
    finch/gntdebug.h
  • +3 -2
    finch/gntft.c
  • +3 -2
    finch/gntft.h
  • +3 -2
    finch/gntidle.h
  • +10 -6
    finch/gntnotify.c
  • +3 -2
    finch/gntnotify.h
  • +3 -2
    finch/gntplugin.c
  • +3 -2
    finch/gntplugin.h
  • +3 -2
    finch/gntpounce.c
  • +3 -2
    finch/gntpounce.h
  • +3 -2
    finch/gntprefs.c
  • +3 -2
    finch/gntprefs.h
  • +3 -2
    finch/gntrequest.c
  • +3 -2
    finch/gntrequest.h
  • +3 -2
    finch/gntsound.c
  • +3 -2
    finch/gntsound.h
  • +3 -2
    finch/gntstatus.c
  • +3 -2
    finch/gntstatus.h
  • +26 -2
    finch/libgnt/gntentry.c
  • +3 -2
    libpurple/account.c
  • +3 -2
    libpurple/account.h
  • +3 -2
    libpurple/accountopt.c
  • +3 -2
    libpurple/accountopt.h
  • +3 -2
    libpurple/blist.h
  • +3 -2
    libpurple/buddyicon.c
  • +3 -2
    libpurple/buddyicon.h
  • +3 -2
    libpurple/cipher.h
  • +3 -2
    libpurple/circbuffer.c
  • +4 -3
    libpurple/circbuffer.h
  • +3 -2
    libpurple/cmds.c
  • +3 -2
    libpurple/cmds.h
  • +3 -2
    libpurple/connection.c
  • +3 -2
    libpurple/connection.h
  • +3 -2
    libpurple/conversation.h
  • +3 -2
    libpurple/core.c
  • +3 -2
    libpurple/core.h
  • +3 -2
    libpurple/dbus-bindings.h
  • +3 -2
    libpurple/dbus-server.h
  • +3 -2
    libpurple/debug.c
  • +3 -2
    libpurple/debug.h
  • +3 -2
    libpurple/desktopitem.c
  • +3 -2
    libpurple/desktopitem.h
  • +3 -2
    libpurple/dnsquery.c
  • +3 -2
    libpurple/dnsquery.h
  • +3 -2
    libpurple/dnssrv.c
  • +4 -3
    libpurple/dnssrv.h
  • +3 -2
    libpurple/eventloop.c
  • +3 -2
    libpurple/eventloop.h
  • +3 -2
    libpurple/ft.c
  • +3 -2
    libpurple/ft.h
  • +3 -2
    libpurple/gaim-compat.h
  • +3 -2
    libpurple/idle.h
  • +3 -2
    libpurple/imgstore.c
  • +3 -2
    libpurple/imgstore.h
  • +3 -2
    libpurple/internal.h
  • +3 -2
    libpurple/log.c
  • +3 -2
    libpurple/log.h
  • +3 -2
    libpurple/nat-pmp.c
  • +3 -2
    libpurple/nat-pmp.h
  • +3 -2
    libpurple/network.c
  • +3 -2
    libpurple/network.h
  • +3 -2
    libpurple/notify.c
  • +43 -4
    libpurple/notify.h
  • +3 -2
    libpurple/ntlm.c
  • +3 -2
    libpurple/ntlm.h
  • +3 -2
    libpurple/plugin.h
  • +3 -2
    libpurple/pluginpref.h
  • +10 -0
    libpurple/plugins/debug_example.c
  • +10 -0
    libpurple/plugins/helloworld.c
  • +10 -0
    libpurple/plugins/notify_example.c
  • +3 -2
    libpurple/pounce.c
  • +3 -2
    libpurple/pounce.h
  • +3 -2
    libpurple/prefs.h
  • +3 -2
    libpurple/privacy.h
  • +1 -0
    libpurple/protocols/jabber/jabber.c
  • +3 -0
    libpurple/protocols/jabber/message.c
  • +1 -1
    libpurple/protocols/msn/msn.c
  • +698 -691
    libpurple/protocols/myspace/markup.c
  • +3 -0
    libpurple/protocols/myspace/myspace.h
  • +3 -2
    libpurple/proxy.c
  • +3 -2
    libpurple/proxy.h
  • +3 -2
    libpurple/prpl.h
  • +3 -2
    libpurple/request.c
  • +3 -2
    libpurple/request.h
  • +3 -2
    libpurple/roomlist.c
  • +3 -2
    libpurple/roomlist.h
  • +3 -2
    libpurple/savedstatuses.c
  • +3 -2
    libpurple/savedstatuses.h
  • +3 -2
    libpurple/server.h
  • +3 -2
    libpurple/signals.c
  • +3 -2
    libpurple/signals.h
  • +3 -2
    libpurple/sound.h
  • +3 -2
    libpurple/sslconn.c
  • +3 -2
    libpurple/sslconn.h
  • +3 -2
    libpurple/status.c
  • +3 -2
    libpurple/stringref.c
  • +3 -2
    libpurple/stringref.h
  • +3 -2
    libpurple/stun.c
  • +3 -2
    libpurple/stun.h
  • +3 -2
    libpurple/upnp.c
  • +3 -2
    libpurple/upnp.h
  • +8 -7
    libpurple/util.c
  • +3 -2
    libpurple/util.h
  • +3 -2
    libpurple/value.c
  • +3 -2
    libpurple/value.h
  • +3 -2
    libpurple/version.c
  • +3 -2
    libpurple/whiteboard.h
  • +3 -2
    libpurple/xmlnode.c
  • +3 -2
    libpurple/xmlnode.h
  • +3 -2
    pidgin/gtkaccount.c
  • +3 -2
    pidgin/gtkaccount.h
  • +33 -16
    pidgin/gtkblist.c
  • +3 -2
    pidgin/gtkblist.h
  • +6 -3
    pidgin/gtkcellrendererexpander.c
  • +3 -2
    pidgin/gtkcellrendererprogress.c
  • +3 -2
    pidgin/gtkcertmgr.c
  • +13 -12
    pidgin/gtkconn.c
  • +3 -2
    pidgin/gtkconn.h
  • +10 -12
    pidgin/gtkconv.c
  • +3 -2
    pidgin/gtkconv.h
  • +3 -2
    pidgin/gtkconvwin.h
  • +3 -2
    pidgin/gtkdebug.c
  • +3 -2
    pidgin/gtkdebug.h
  • +3 -2
    pidgin/gtkdialogs.c
  • +3 -2
    pidgin/gtkdialogs.h
  • +3 -2
    pidgin/gtkdnd-hints.c
  • +3 -2
    pidgin/gtkdnd-hints.h
  • +3 -2
    pidgin/gtkeventloop.c
  • +3 -2
    pidgin/gtkeventloop.h
  • +3 -2
    pidgin/gtkft.c
  • +3 -2
    pidgin/gtkft.h
  • +3 -2
    pidgin/gtkgaim-compat.h
  • +3 -2
    pidgin/gtkidle.h
  • +3 -2
    pidgin/gtkimhtml.c
  • +3 -2
    pidgin/gtkimhtml.h
  • +22 -8
    pidgin/gtkimhtmltoolbar.c
  • +3 -2
    pidgin/gtklog.c
  • +3 -2
    pidgin/gtklog.h
  • +7 -0
    pidgin/gtkmain.c
  • +3 -2
    pidgin/gtkmenutray.h
  • +3 -2
    pidgin/gtknickcolors.h
  • +18 -15
    pidgin/gtknotify.c
  • +3 -2
    pidgin/gtknotify.h
  • +3 -2
    pidgin/gtkplugin.c
  • +3 -2
    pidgin/gtkplugin.h
  • +3 -2
    pidgin/gtkpluginpref.c
  • +3 -2
    pidgin/gtkpluginpref.h
  • +3 -2
    pidgin/gtkpounce.c
  • +3 -2
    pidgin/gtkpounce.h
  • +3 -2
    pidgin/gtkprefs.c
  • +3 -2
    pidgin/gtkprefs.h
  • +3 -2
    pidgin/gtkprivacy.c
  • +3 -2
    pidgin/gtkprivacy.h
  • +3 -3
    pidgin/gtkrequest.c
  • +3 -2
    pidgin/gtkrequest.h
  • +3 -2
    pidgin/gtkroomlist.c
  • +3 -2
    pidgin/gtkroomlist.h
  • +3 -2
    pidgin/gtksavedstatuses.c
  • +3 -2
    pidgin/gtksavedstatuses.h
  • +3 -2
    pidgin/gtkscrollbook.c
  • +3 -2
    pidgin/gtkscrollbook.h
  • +8 -3
    pidgin/gtksession.c
  • +3 -2
    pidgin/gtksession.h
  • +3 -2
    pidgin/gtksound.c
  • +3 -2
    pidgin/gtksound.h
  • +3 -2
    pidgin/gtkstatusbox.c
  • +3 -2
    pidgin/gtkstatusbox.h
  • +3 -2
    pidgin/gtkthemes.h
  • +3 -2
    pidgin/gtkutils.c
  • +3 -2
    pidgin/gtkutils.h
  • +3 -2
    pidgin/gtkwhiteboard.h
  • +5 -4
    pidgin/pidgin.h
  • +3 -2
    pidgin/pidginstock.c
  • +3 -2
    pidgin/pidginstock.h
  • +4 -0
    pidgin/plugins/history.c
  • --- a/COPYRIGHT Mon Sep 17 16:54:45 2007 +0000
    +++ b/COPYRIGHT Mon Sep 17 17:51:22 2007 +0000
    @@ -246,6 +246,7 @@
    Kevin Miller
    Paul Miller
    Arkadiusz Miskiewicz
    +David Mohr
    Andrew Molloy
    Michael Monreal
    Benjamin Moody
    --- a/ChangeLog Mon Sep 17 16:54:45 2007 +0000
    +++ b/ChangeLog Mon Sep 17 17:51:22 2007 +0000
    @@ -12,6 +12,9 @@
    is listening to some soothing music.
    * 'Move to' menu in buddy list context menu for moving buddies to
    other groups
    + * Move "Smiley" to the top-level of the toolbar
    + * Save Pidgin's display in the command line for session
    + restoration. (David Mohr)
    Version 2.2.0 (09/13/2007):
    http://developer.pidgin.im/query?status=closed&milestone=2.2.0
    --- a/finch/finch.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/finch.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,7 +1,8 @@
    /**
    * @defgroup finch Finch (GNT User Interface)
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntaccount.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntaccount.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntaccount.c GNT Account API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntaccount.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntaccount.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntaccount.h GNT Account API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntblist.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntblist.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntblist.c GNT BuddyList API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntblist.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntblist.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntblist.h GNT BuddyList API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntcertmgr.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntcertmgr.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntcertmgr.c GNT Certificate Manager API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntcertmgr.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntcertmgr.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntcertmgr.h GNT Certificate Manager API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntconn.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntconn.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntconn.c GNT Connection API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntconn.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntconn.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntconn.h GNT Connection API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntconv.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntconv.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntconv.c GNT Conversation API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntconv.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntconv.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntconv.h GNT Conversation API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntdebug.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntdebug.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntdebug.c GNT Debug API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntdebug.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntdebug.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntdebug.h GNT Debug API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntft.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntft.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntft.c GNT File Transfer UI
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntft.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntft.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntft.h GNT File Transfer UI
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntidle.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntidle.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntidle.h GNT Idle API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntnotify.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntnotify.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntnotify.c GNT Notify API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    @@ -351,14 +352,17 @@
    gnt_box_add_widget(GNT_BOX(window),
    gnt_label_new_with_format(secondary, GNT_TEXT_FLAG_NORMAL));
    - columns = purple_notify_searchresults_get_columns_count(results);
    + columns = g_list_length(results->columns);
    tree = gnt_tree_new_with_columns(columns);
    gnt_tree_set_show_title(GNT_TREE(tree), TRUE);
    gnt_box_add_widget(GNT_BOX(window), tree);
    - for (i = 0; i < columns; i++)
    - gnt_tree_set_column_title(GNT_TREE(tree), i,
    - purple_notify_searchresults_column_get_title(results, i));
    + i = 0;
    + for (iter = results->columns; iter; iter = iter->next)
    + {
    + gnt_tree_set_column_title(GNT_TREE(tree), i, iter->data);
    + i++;
    + }
    box = gnt_hbox_new(TRUE);
    --- a/finch/gntnotify.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntnotify.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntnotify.h GNT Notify API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntplugin.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntplugin.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntplugin.c GNT Plugins API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntplugin.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntplugin.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntplugin.h GNT Plugins API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntpounce.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntpounce.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntpounce.c GNT Buddy Pounce API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntpounce.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntpounce.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntpounce.h GNT Buddy Pounce API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntprefs.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntprefs.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntprefs.c GNT Preferences API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntprefs.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntprefs.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntprefs.h GNT Preferences API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntrequest.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntrequest.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntrequest.c GNT Request API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntrequest.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntrequest.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntrequest.h GNT Request API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntsound.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntsound.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntsound.c GNT Sound API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntsound.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntsound.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntsound.h GNT Sound API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntstatus.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntstatus.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntstatus.c GNT Status API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/gntstatus.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/gntstatus.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gntstatus.h GNT Status API
    * @ingroup finch
    - *
    - * finch
    + */
    +
    +/* finch
    *
    * Finch is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/finch/libgnt/gntentry.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/finch/libgnt/gntentry.c Mon Sep 17 17:51:22 2007 +0000
    @@ -100,6 +100,15 @@
    return changed;
    }
    +static int
    +max_common_prefix(const char *s, const char *t)
    +{
    + const char *f = s;
    + while (*f && *t && *f == *t++)
    + f++;
    + return f - s;
    +}
    +
    static gboolean
    show_suggest_dropdown(GntEntry *entry)
    {
    @@ -110,6 +119,7 @@
    GList *iter;
    const char *text = NULL;
    const char *sgst = NULL;
    + int max = -1;
    if (entry->word)
    {
    @@ -121,14 +131,13 @@
    else
    suggest = g_strdup(entry->start);
    len = strlen(suggest); /* Don't need to use the utf8-function here */
    -
    +
    if (entry->ddown == NULL)
    {
    GntWidget *box = gnt_vbox_new(FALSE);
    entry->ddown = gnt_tree_new();
    gnt_tree_set_compare_func(GNT_TREE(entry->ddown), (GCompareFunc)g_utf8_collate);
    gnt_box_add_widget(GNT_BOX(box), entry->ddown);
    - /* XXX: Connect to the "activate" signal for the dropdown tree */
    GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_TRANSIENT);
    @@ -151,6 +160,10 @@
    gnt_tree_create_row(GNT_TREE(entry->ddown), text),
    NULL, NULL);
    count++;
    + if (max == -1)
    + max = strlen(text) - len;
    + else if (max)
    + max = MIN(max, max_common_prefix(sgst + len, text + len));
    sgst = text;
    }
    }
    @@ -163,6 +176,17 @@
    destroy_suggest(entry);
    return complete_suggest(entry, sgst);
    } else {
    + if (max > 0) {
    + GntWidget *ddown = entry->ddown;
    + char *match = g_strndup(sgst + len, max);
    + entry->ddown = NULL;
    + gnt_entry_key_pressed(GNT_WIDGET(entry), match);
    + g_free(match);
    + if (entry->ddown)
    + gnt_widget_destroy(ddown);
    + else
    + entry->ddown = ddown;
    + }
    gnt_widget_draw(entry->ddown->parent);
    }
    --- a/libpurple/account.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/account.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file account.c Account API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/account.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/account.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file account.h Account API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/accountopt.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/accountopt.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file accountopt.c Account Options API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/accountopt.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/accountopt.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file accountopt.h Account Options API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/blist.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/blist.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file blist.h Buddy List API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/buddyicon.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/buddyicon.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file icon.c Buddy Icon API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/buddyicon.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/buddyicon.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file buddyicon.h Buddy Icon API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/cipher.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/cipher.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file cipher.h Purple Cipher API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/circbuffer.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/circbuffer.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file circbuffer.h Buffer Utility Functions
    * @ingroup core
    - *
    - * Purple is the legal property of its developers, whose names are too numerous
    + */
    +
    +/* Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    * source distribution.
    *
    --- a/libpurple/circbuffer.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/circbuffer.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    -/*
    +/**
    * @file circbuffer.h Buffer Utility Functions
    * @ingroup core
    - *
    - * Purple is the legal property of its developers, whose names are too numerous
    + */
    +
    +/* Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    * source distribution.
    *
    --- a/libpurple/cmds.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/cmds.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file cmds.c Commands API
    * @ingroup core
    - *
    - * Copyright (C) 2003-2004 Timothy Ringenbach <omarvo@hotmail.com
    + */
    +
    +/* Copyright (C) 2003-2004 Timothy Ringenbach <omarvo@hotmail.com
    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License as published by
    --- a/libpurple/cmds.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/cmds.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file cmds.h Commands API
    * @ingroup core
    - *
    - * Copyright (C) 2003 Timothy Ringenbach <omarvo@hotmail.com>
    + */
    +
    +/* Copyright (C) 2003 Timothy Ringenbach <omarvo@hotmail.com>
    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License as published by
    --- a/libpurple/connection.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/connection.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file connection.c Connection API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/connection.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/connection.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file connection.h Connection API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/conversation.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/conversation.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file conversation.h Conversation API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/core.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/core.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file core.c Purple Core API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/core.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/core.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,7 +1,8 @@
    /**
    * @defgroup core libpurple
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/dbus-bindings.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/dbus-bindings.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file dbus-bindings.h Purple DBUS Bindings
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/dbus-server.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/dbus-server.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file dbus-server.h Purple DBUS Server
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/debug.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/debug.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file debug.c Debug API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/debug.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/debug.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file debug.h Debug API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/desktopitem.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/desktopitem.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file purple-desktop-item.c Functions for managing .desktop files
    * @ingroup core
    - *
    - * Purple is the legal property of its developers, whose names are too numerous
    + */
    +
    +/* Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    * source distribution.
    *
    --- a/libpurple/desktopitem.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/desktopitem.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file desktopitem.h Functions for managing .desktop files
    * @ingroup core
    - *
    - * Purple is the legal property of its developers, whose names are too numerous
    + */
    +
    +/* Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    * source distribution.
    *
    --- a/libpurple/dnsquery.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/dnsquery.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file dnsquery.c DNS query API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/dnsquery.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/dnsquery.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file dnsquery.h DNS query API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/dnssrv.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/dnssrv.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,7 +1,8 @@
    /**
    * @file dnssrv.c
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Copyright (C) 2005 Thomas Butter <butter@uni-mannheim.de>
    *
    --- a/libpurple/dnssrv.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/dnssrv.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,10 +1,11 @@
    /**
    * @file dnssrv.h
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Copyright (C) 2005, Thomas Butter <butter@uni-mannheim.de>
    - *i
    + *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License as published by
    * the Free Software Foundation; either version 2 of the License, or
    --- a/libpurple/eventloop.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/eventloop.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file eventloop.c Purple Event Loop API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/eventloop.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/eventloop.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file eventloop.h Purple Event Loop API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/ft.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/ft.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,7 +1,8 @@
    /**
    * @file ft.c File Transfer API
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/ft.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/ft.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file ft.h File Transfer API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/gaim-compat.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/gaim-compat.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gaim-compat.h Gaim Compat macros
    * @ingroup core
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/idle.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/idle.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file idle.h Idle API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/imgstore.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/imgstore.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file imgstore.h IM Image Store API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/imgstore.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/imgstore.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file imgstore.h IM Image Store API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/internal.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/internal.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file internal.h Internal definitions and includes
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/log.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/log.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file log.c Logging API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/log.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/log.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file log.h Logging API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/nat-pmp.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/nat-pmp.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file nat-pmp.c NAT-PMP Implementation
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/nat-pmp.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/nat-pmp.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file nat-pmp.h NAT-PMP Implementation
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/network.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/network.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file network.c Network Implementation
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/network.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/network.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file network.h Network API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/notify.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/notify.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file notify.c Notification API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/notify.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/notify.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file notify.h Notification API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    @@ -292,7 +293,17 @@
    /**
    * Returns a number of the rows in the search results object.
    - *
    + *
    + * @deprecated This function will be removed in Pidgin 3.0.0 unless
    + * there is sufficient demand to keep it. Using this
    + * function encourages looping through the results
    + * inefficiently. Instead of using this function you
    + * should iterate through the results using a loop
    + * similar to this:
    + * for (l = results->rows; l != NULL; l = l->next)
    + * If you really need to get the number of rows you
    + * can use g_list_length(results->rows).
    + *
    * @param results The search results object.
    *
    * @return Number of the result rows.
    @@ -302,6 +313,16 @@
    /**
    * Returns a number of the columns in the search results object.
    *
    + * @deprecated This function will be removed in Pidgin 3.0.0 unless
    + * there is sufficient demand to keep it. Using this
    + * function encourages looping through the columns
    + * inefficiently. Instead of using this function you
    + * should iterate through the columns using a loop
    + * similar to this:
    + * for (l = results->columns; l != NULL; l = l->next)
    + * If you really need to get the number of columns you
    + * can use g_list_length(results->columns).
    + *
    * @param results The search results object.
    *
    * @return Number of the columns.
    @@ -311,6 +332,16 @@
    /**
    * Returns a row of the results from the search results object.
    *
    + * @deprecated This function will be removed in Pidgin 3.0.0 unless
    + * there is sufficient demand to keep it. Using this
    + * function encourages looping through the results
    + * inefficiently. Instead of using this function you
    + * should iterate through the results using a loop
    + * similar to this:
    + * for (l = results->rows; l != NULL; l = l->next)
    + * If you really need to get the data for a particular
    + * row you can use g_list_nth_data(results->rows, row_id).
    + *
    * @param results The search results object.
    * @param row_id Index of the row to be returned.
    *
    @@ -321,7 +352,15 @@
    /**
    * Returns a title of the search results object's column.
    - *
    + *
    + * @deprecated This function will be removed in Pidgin 3.0.0 unless
    + * there is sufficient demand to keep it. Using this
    + * function encourages looping through the columns
    + * inefficiently. Instead of using this function you
    + * should iterate through the name of a particular
    + * column you can use
    + * g_list_nth_data(results->columns, row_id).
    + *
    * @param results The search results object.
    * @param column_id Index of the column.
    *
    --- a/libpurple/ntlm.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/ntlm.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,7 +1,8 @@
    /**
    * @file ntlm.c
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Copyright (C) 2005 Thomas Butter <butter@uni-mannheim.de>
    *
    --- a/libpurple/ntlm.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/ntlm.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,7 +1,8 @@
    /**
    * @file ntlm.h
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Copyright (C) 2005, Thomas Butter <butter@uni-mannheim.de>
    *
    --- a/libpurple/plugin.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/plugin.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file plugin.h Plugin API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/pluginpref.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/pluginpref.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file pluginpref.h Plugin Preferences API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/plugins/debug_example.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/plugins/debug_example.c Mon Sep 17 17:51:22 2007 +0000
    @@ -27,6 +27,16 @@
    /* We're including glib.h again for the gboolean type. */
    #include <glib.h>
    +/* This will prevent compiler errors in some instances and is better explained in the
    + * how-to documents on the wiki */
    +#ifndef G_GNUC_NULL_TERMINATED
    +# if __GNUC__ >= 4
    +# define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__))
    +# else
    +# define G_GNUC_NULL_TERMINATED
    +# endif
    +#endif
    +
    /* This is the required definition of PURPLE_PLUGINS as required for a plugin,
    * but we protect it with an #ifndef because config.h may define it for us
    * already and this would cause an unneeded compiler warning. */
    --- a/libpurple/plugins/helloworld.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/plugins/helloworld.c Mon Sep 17 17:51:22 2007 +0000
    @@ -33,6 +33,16 @@
    #include <glib.h>
    +/* This will prevent compiler errors in some instances and is better explained in the
    + * how-to documents on the wiki */
    +#ifndef G_GNUC_NULL_TERMINATED
    +# if __GNUC__ >= 4
    +# define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__))
    +# else
    +# define G_GNUC_NULL_TERMINATED
    +# endif
    +#endif
    +
    #include <notify.h>
    #include <plugin.h>
    #include <version.h>
    --- a/libpurple/plugins/notify_example.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/plugins/notify_example.c Mon Sep 17 17:51:22 2007 +0000
    @@ -26,6 +26,16 @@
    #include <glib.h>
    +/* This will prevent compiler errors in some instances and is better explained in the
    + * how-to documents on the wiki */
    +#ifndef G_GNUC_NULL_TERMINATED
    +# if __GNUC__ >= 4
    +# define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__))
    +# else
    +# define G_GNUC_NULL_TERMINATED
    +# endif
    +#endif
    +
    /* This is the required definition of PURPLE_PLUGINS as required for a plugin,
    * but we protect it with an #ifndef because config.h may define it for us
    * already and this would cause an unneeded compiler warning. */
    --- a/libpurple/pounce.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/pounce.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file pounce.c Buddy Pounce API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/pounce.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/pounce.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file pounce.h Buddy Pounce API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/prefs.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/prefs.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file prefs.h Prefs API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/privacy.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/privacy.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file privacy.h Privacy API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/protocols/jabber/jabber.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/protocols/jabber/jabber.c Mon Sep 17 17:51:22 2007 +0000
    @@ -141,6 +141,7 @@
    if(jabber_process_starttls(js, packet))
    return;
    } else if(purple_account_get_bool(js->gc->account, "require_tls", FALSE) && !js->gsc) {
    + js->gc->wants_to_die = TRUE;
    purple_connection_error(js->gc, _("You require encryption, but it is not available on this server."));
    return;
    }
    --- a/libpurple/protocols/jabber/message.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/protocols/jabber/message.c Mon Sep 17 17:51:22 2007 +0000
    @@ -41,7 +41,10 @@
    g_free(jm->body);
    g_free(jm->xhtml);
    g_free(jm->password);
    + g_free(jm->error);
    + g_free(jm->thread_id);
    g_list_free(jm->etc);
    + g_list_free(jm->eventitems);
    g_free(jm);
    }
    --- a/libpurple/protocols/msn/msn.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/protocols/msn/msn.c Mon Sep 17 17:51:22 2007 +0000
    @@ -731,7 +731,7 @@
    http_method = purple_account_get_bool(account, "http_method", FALSE);
    if (http_method)
    - host = purple_account_get_string(account, "http_method_server", MSN_SERVER);
    + host = purple_account_get_string(account, "http_method_server", MSN_HTTPCONN_SERVER);
    else
    host = purple_account_get_string(account, "server", MSN_SERVER);
    port = purple_account_get_int(account, "port", MSN_PORT);
    --- a/libpurple/protocols/myspace/markup.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/protocols/myspace/markup.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,691 +1,698 @@
    -/* MySpaceIM Protocol Plugin - markup
    - *
    - * Copyright (C) 2007, Jeff Connelly <jeff2@soc.pidgin.im>
    - *
    - * This program is free software; you can redistribute it and/or modify
    - * it under the terms of the GNU General Public License as published by
    - * the Free Software Foundation; either version 2 of the License, or
    - * (at your option) any later version.
    - *
    - * This program is distributed in the hope that it will be useful,
    - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    - * GNU General Public License for more details.
    - *
    - * You should have received a copy of the GNU General Public License
    - * along with this program; if not, write to the Free Software
    - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
    - */
    -
    -#include "myspace.h"
    -
    -typedef void (*MSIM_XMLNODE_CONVERT)(MsimSession *, xmlnode *, gchar **, gchar **);
    -
    -/* Internal functions */
    -
    -static guint msim_point_to_purple_size(MsimSession *session, guint point);
    -static guint msim_purple_size_to_point(MsimSession *session, guint size);
    -static guint msim_height_to_point(MsimSession *session, guint height);
    -static guint msim_point_to_height(MsimSession *session, guint point);
    -
    -static void msim_markup_tag_to_html(MsimSession *, xmlnode *root, gchar **begin, gchar **end);
    -static void html_tag_to_msim_markup(MsimSession *, xmlnode *root, gchar **begin, gchar **end);
    -static gchar *msim_convert_xml(MsimSession *, const gchar *raw, MSIM_XMLNODE_CONVERT f);
    -static gchar *msim_convert_smileys_to_markup(gchar *before);
    -static double msim_round(double round);
    -
    -
    -/* Globals */
    -
    -/* The names in in emoticon_names (for <i n=whatever>) map to corresponding
    - * entries in emoticon_symbols (for the ASCII representation of the emoticon).
    - *
    - * Multiple emoticon symbols in Pidgin can map to one name. List the
    - * canonical form, as inserted by the "Smile!" dialog, first. For example,
    - * :) comes before :-), because although both are recognized as 'happy',
    - * the first is inserted by the smiley button (first symbol in theme).
    - *
    - * Note that symbols are case-sensitive in Pidgin -- :-X is not :-x. */
    -static struct MSIM_EMOTICON
    -{
    - gchar *name;
    - gchar *symbol;
    -} msim_emoticons[] = {
    - /* Unfortunately, this list duplicates much of the file
    - * pidgin/pidgin/pixmaps/emotes/default/22/default.theme.in, because
    - * that file is part of Pidgin, but we're part of libpurple.
    - */
    - { "bigsmile", ":D" },
    - { "bigsmile", ":-D" },
    - { "devil", "}:)" },
    - { "frazzled", ":Z" },
    - { "geek", "B)" },
    - { "googles", "%)" },
    - { "growl", ":E" },
    - { "laugh", ":))" }, /* Must be before ':)' */
    - { "happy", ":)" },
    - { "happy", ":-)" },
    - { "happi", ":)" },
    - { "heart", ":X" },
    - { "mohawk", "-:" },
    - { "mad", "X(" },
    - { "messed", "X)" },
    - { "nerd", "Q)" },
    - { "oops", ":G" },
    - { "pirate", "P)" },
    - { "scared", ":O" },
    - { "sidefrown", ":{" },
    - { "sinister", ":B" },
    - { "smirk", ":," },
    - { "straight", ":|" },
    - { "tongue", ":P" },
    - { "tongue", ":p" },
    - { "tongy", ":P" },
    - { "upset", "B|" },
    - { "wink", ";-)" },
    - { "wink", ";)" },
    - { "winc", ";)" },
    - { "worried", ":[" },
    - { "kiss", ":x" },
    - { NULL, NULL }
    -};
    -
    -
    -
    -/* Indexes of this array + 1 map HTML font size to scale of normal font size. *
    - * Based on _point_sizes from libpurple/gtkimhtml.c
    - * 1 2 3 4 5 6 7 */
    -static gdouble _font_scale[] = { .85, .95, 1, 1.2, 1.44, 1.728, 2.0736 };
    -
    -#define MAX_FONT_SIZE 7 /* Purple maximum font size */
    -#define POINTS_PER_INCH 72 /* How many pt's in an inch */
    -
    -/* Text formatting bits for <f s=#> */
    -#define MSIM_TEXT_BOLD 1
    -#define MSIM_TEXT_ITALIC 2
    -#define MSIM_TEXT_UNDERLINE 4
    -
    -/* Default baseline size of purple's fonts, in points. What is size 3 in points.
    - * _font_scale specifies scaling factor relative to this point size. Note this
    - * is only the default; it is configurable in account options. */
    -#define MSIM_BASE_FONT_POINT_SIZE 8
    -
    -/* Default display's DPI. 96 is common but it can differ. Also configurable
    - * in account options. */
    -#define MSIM_DEFAULT_DPI 96
    -
    -
    -/* round is part of C99, but sometimes is unavailable before then.
    - * Based on http://forums.belution.com/en/cpp/000/050/13.shtml
    - */
    -double msim_round(double value)
    -{
    - if (value < 0) {
    - return -(floor(-value + 0.5));
    - } else {
    - return floor( value + 0.5);
    - }
    -}
    -
    -
    -/** Convert typographical font point size to HTML font size.
    - * Based on libpurple/gtkimhtml.c */
    -static guint
    -msim_point_to_purple_size(MsimSession *session, guint point)
    -{
    - guint size, this_point, base;
    - gdouble scale;
    -
    - base = purple_account_get_int(session->account, "base_font_size", MSIM_BASE_FONT_POINT_SIZE);
    -
    - for (size = 0;
    - size < sizeof(_font_scale) / sizeof(_font_scale[0]);
    - ++size) {
    - scale = _font_scale[CLAMP(size, 1, MAX_FONT_SIZE) - 1];
    - this_point = (guint)msim_round(scale * base);
    -
    - if (this_point >= point) {
    - purple_debug_info("msim", "msim_point_to_purple_size: %d pt -> size=%d\n",
    - point, size);
    - return size;
    - }
    - }
    -
    - /* No HTML font size was this big; return largest possible. */
    - return this_point;
    -}
    -
    -/** Convert HTML font size to point size. */
    -static guint
    -msim_purple_size_to_point(MsimSession *session, guint size)
    -{
    - gdouble scale;
    - guint point;
    - guint base;
    -
    - scale = _font_scale[CLAMP(size, 1, MAX_FONT_SIZE) - 1];
    -
    - base = purple_account_get_int(session->account, "base_font_size", MSIM_BASE_FONT_POINT_SIZE);
    -
    - point = (guint)msim_round(scale * base);
    -
    - purple_debug_info("msim", "msim_purple_size_to_point: size=%d -> %d pt\n",
    - size, point);
    -
    - return point;
    -}
    -
    -/** Convert a msim markup font pixel height to the more usual point size, for incoming messages. */
    -static guint
    -msim_height_to_point(MsimSession *session, guint height)
    -{
    - guint dpi;
    -
    - dpi = purple_account_get_int(session->account, "port", MSIM_DEFAULT_DPI);
    -
    - return (guint)msim_round((POINTS_PER_INCH * 1. / dpi) * height);
    -
    - /* See also: libpurple/protocols/bonjour/jabber.c
    - * _font_size_ichat_to_purple */
    -}
    -
    -/** Convert point size to msim pixel height font size specification, for outgoing messages. */
    -static guint
    -msim_point_to_height(MsimSession *session, guint point)
    -{
    - guint dpi;
    -
    - dpi = purple_account_get_int(session->account, "port", MSIM_DEFAULT_DPI);
    -
    - return (guint)msim_round((dpi * 1. / POINTS_PER_INCH) * point);
    -}
    -
    -/** Convert the msim markup <f> (font) tag into HTML. */
    -static void
    -msim_markup_f_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
    -{
    - const gchar *face, *height_str, *decor_str;
    - GString *gs_end, *gs_begin;
    - guint decor, height;
    -
    - face = xmlnode_get_attrib(root, "f");
    - height_str = xmlnode_get_attrib(root, "h");
    - decor_str = xmlnode_get_attrib(root, "s");
    -
    - if (height_str) {
    - height = atol(height_str);
    - } else {
    - height = 12;
    - }
    -
    - if (decor_str) {
    - decor = atol(decor_str);
    - } else {
    - decor = 0;
    - }
    -
    - gs_begin = g_string_new("");
    - /* TODO: get font size working */
    - if (height && !face) {
    - g_string_printf(gs_begin, "<font size='%d'>",
    - msim_point_to_purple_size(session, msim_height_to_point(session, height)));
    - } else if (height && face) {
    - g_string_printf(gs_begin, "<font face='%s' size='%d'>", face,
    - msim_point_to_purple_size(session, msim_height_to_point(session, height)));
    - } else {
    - g_string_printf(gs_begin, "<font>");
    - }
    -
    - /* No support for font-size CSS? */
    - /* g_string_printf(gs_begin, "<span style='font-family: %s; font-size: %dpt'>", face,
    - msim_height_to_point(height)); */
    -
    - gs_end = g_string_new("</font>");
    -
    - if (decor & MSIM_TEXT_BOLD) {
    - g_string_append(gs_begin, "<b>");
    - g_string_prepend(gs_end, "</b>");
    - }
    -
    - if (decor & MSIM_TEXT_ITALIC) {
    - g_string_append(gs_begin, "<i>");
    - g_string_append(gs_end, "</i>");
    - }
    -
    - if (decor & MSIM_TEXT_UNDERLINE) {
    - g_string_append(gs_begin, "<u>");
    - g_string_append(gs_end, "</u>");
    - }
    -
    -
    - *begin = gs_begin->str;
    - *end = gs_end->str;
    -}
    -
    -/** Convert a msim markup color to a color suitable for libpurple.
    - *
    - * @param msim Either a color name, or an rgb(x,y,z) code.
    - *
    - * @return A new string, either a color name or #rrggbb code. Must g_free().
    - */
    -static char *
    -msim_color_to_purple(const char *msim)
    -{
    - guint red, green, blue;
    -
    - if (!msim) {
    - return g_strdup("black");
    - }
    -
    - if (sscanf(msim, "rgb(%d,%d,%d)", &red, &green, &blue) != 3) {
    - /* Color name. */
    - return g_strdup(msim);
    - }
    - /* TODO: rgba (alpha). */
    -
    - return g_strdup_printf("#%.2x%.2x%.2x", red, green, blue);
    -}
    -
    -/** Convert the msim markup <a> (anchor) tag into HTML. */
    -static void
    -msim_markup_a_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
    -{
    - const gchar *href;
    -
    - href = xmlnode_get_attrib(root, "h");
    - if (!href) {
    - href = "";
    - }
    -
    - *begin = g_strdup_printf("<a href=\"%s\">%s", href, href);
    - *end = g_strdup("</a>");
    -}
    -
    -/** Convert the msim markup <p> (paragraph) tag into HTML. */
    -static void
    -msim_markup_p_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
    -{
    - /* Just pass through unchanged.
    - *
    - * Note: attributes currently aren't passed, if there are any. */
    - *begin = g_strdup("<p>");
    - *end = g_strdup("</p>");
    -}
    -
    -/** Convert the msim markup <c> tag (text color) into HTML. TODO: Test */
    -static void
    -msim_markup_c_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
    -{
    - const gchar *color;
    - gchar *purple_color;
    -
    - color = xmlnode_get_attrib(root, "v");
    - if (!color) {
    - purple_debug_info("msim", "msim_markup_c_to_html: <c> tag w/o v attr\n");
    - *begin = g_strdup("");
    - *end = g_strdup("");
    - /* TODO: log as unrecognized */
    - return;
    - }
    -
    - purple_color = msim_color_to_purple(color);
    -
    - *begin = g_strdup_printf("<font color='%s'>", purple_color);
    -
    - g_free(purple_color);
    -
    - /* *begin = g_strdup_printf("<span style='color: %s'>", color); */
    - *end = g_strdup("</font>");
    -}
    -
    -/** Convert the msim markup <b> tag (background color) into HTML. TODO: Test */
    -static void
    -msim_markup_b_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
    -{
    - const gchar *color;
    - gchar *purple_color;
    -
    - color = xmlnode_get_attrib(root, "v");
    - if (!color) {
    - *begin = g_strdup("");
    - *end = g_strdup("");
    - purple_debug_info("msim", "msim_markup_b_to_html: <b> w/o v attr\n");
    - /* TODO: log as unrecognized. */
    - return;
    - }
    -
    - purple_color = msim_color_to_purple(color);
    -
    - /* TODO: find out how to set background color. */
    - *begin = g_strdup_printf("<span style='background-color: %s'>",
    - purple_color);
    - g_free(purple_color);
    -
    - *end = g_strdup("</p>");
    -}
    -
    -/** Convert the msim markup <i> tag (emoticon image) into HTML. */
    -static void
    -msim_markup_i_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
    -{
    - const gchar *name;
    - guint i;
    - struct MSIM_EMOTICON *emote;
    -
    - name = xmlnode_get_attrib(root, "n");
    - if (!name) {
    - purple_debug_info("msim", "msim_markup_i_to_html: <i> w/o n\n");
    - *begin = g_strdup("");
    - *end = g_strdup("");
    - /* TODO: log as unrecognized */
    - return;
    - }
    -
    - /* Find and use canonical form of smiley symbol. */
    - for (i = 0; (emote = &msim_emoticons[i]) && emote->name != NULL; ++i) {
    - if (g_str_equal(name, emote->name)) {
    - *begin = g_strdup(emote->symbol);
    - *end = g_strdup("");
    - return;
    - }
    - }
    -
    - /* Couldn't find it, sorry. Try to degrade gracefully. */
    - *begin = g_strdup_printf("**%s**", name);
    - *end = g_strdup("");
    -}
    -
    -/** Convert an individual msim markup tag to HTML. */
    -static void
    -msim_markup_tag_to_html(MsimSession *session, xmlnode *root, gchar **begin,
    - gchar **end)
    -{
    - if (g_str_equal(root->name, "f")) {
    - msim_markup_f_to_html(session, root, begin, end);
    - } else if (g_str_equal(root->name, "a")) {
    - msim_markup_a_to_html(session, root, begin, end);
    - } else if (g_str_equal(root->name, "p")) {
    - msim_markup_p_to_html(session, root, begin, end);
    - } else if (g_str_equal(root->name, "c")) {
    - msim_markup_c_to_html(session, root, begin, end);
    - } else if (g_str_equal(root->name, "b")) {
    - msim_markup_b_to_html(session, root, begin, end);
    - } else if (g_str_equal(root->name, "i")) {
    - msim_markup_i_to_html(session, root, begin, end);
    - } else {
    - purple_debug_info("msim", "msim_markup_tag_to_html: "
    - "unknown tag name=%s, ignoring",
    - (root && root->name) ? root->name : "(NULL)");
    - *begin = g_strdup("");
    - *end = g_strdup("");
    - }
    -}
    -
    -/** Convert an individual HTML tag to msim markup. */
    -static void
    -html_tag_to_msim_markup(MsimSession *session, xmlnode *root, gchar **begin,
    - gchar **end)
    -{
    - /* TODO: Coalesce nested tags into one <f> tag!
    - * Currently, the 's' value will be overwritten when b/i/u is nested
    - * within another one, and only the inner-most formatting will be
    - * applied to the text. */
    - if (!purple_utf8_strcasecmp(root->name, "root")) {
    - *begin = g_strdup("");
    - *end = g_strdup("");
    - } else if (!purple_utf8_strcasecmp(root->name, "b")) {
    - *begin = g_strdup_printf("<f s='%d'>", MSIM_TEXT_BOLD);
    - *end = g_strdup("</f>");
    - } else if (!purple_utf8_strcasecmp(root->name, "i")) {
    - *begin = g_strdup_printf("<f s='%d'>", MSIM_TEXT_ITALIC);
    - *end = g_strdup("</f>");
    - } else if (!purple_utf8_strcasecmp(root->name, "u")) {
    - *begin = g_strdup_printf("<f s='%d'>", MSIM_TEXT_UNDERLINE);
    - *end = g_strdup("</f>");
    - } else if (!purple_utf8_strcasecmp(root->name, "a")) {
    - const gchar *href, *link_text;
    -
    - href = xmlnode_get_attrib(root, "href");
    -
    - if (!href) {
    - href = xmlnode_get_attrib(root, "HREF");
    - }
    -
    - link_text = xmlnode_get_data(root);
    -
    - if (href) {
    - if (g_str_equal(link_text, href)) {
    - /* Purple gives us: <a href="URL">URL</a>
    - * Translate to <a h='URL' />
    - * Displayed as text of URL with link to URL
    - */
    - *begin = g_strdup_printf("<a h='%s' />", href);
    - } else {
    - /* But if we get: <a href="URL">text</a>
    - * Translate to: text: <a h='URL' />
    - *
    - * Because official client only supports self-closed <a>
    - * tags; you can't change the link text.
    - */
    - *begin = g_strdup_printf("%s: <a h='%s' />", link_text, href);
    - }
    - } else {
    - *begin = g_strdup("<a />");
    - }
    -
    - /* Sorry, kid. MySpace doesn't support you within <a> tags. */
    - xmlnode_free(root->child);
    - root->child = NULL;
    -
    - *end = g_strdup("");
    - } else if (!purple_utf8_strcasecmp(root->name, "font")) {
    - const gchar *size;
    - const gchar *face;
    -
    - size = xmlnode_get_attrib(root, "size");
    - face = xmlnode_get_attrib(root, "face");
    -
    - if (face && size) {
    - *begin = g_strdup_printf("<f f='%s' h='%d'>", face,
    - msim_point_to_height(session,
    - msim_purple_size_to_point(session, atoi(size))));
    - } else if (face) {
    - *begin = g_strdup_printf("<f f='%s'>", face);
    - } else if (size) {
    - *begin = g_strdup_printf("<f h='%d'>",
    - msim_point_to_height(session,
    - msim_purple_size_to_point(session, atoi(size))));
    - } else {
    - *begin = g_strdup("<f>");
    - }
    -
    - *end = g_strdup("</f>");
    -
    - /* TODO: color (bg uses <body>), emoticons */
    - } else {
    - *begin = g_strdup_printf("[%s]", root->name);
    - *end = g_strdup_printf("[/%s]", root->name);
    - }
    -}
    -
    -/** Convert an xmlnode of msim markup or HTML to an HTML string or msim markup.
    - *
    - * @param f Function to convert tags.
    - *
    - * @return An HTML string. Caller frees.
    - */
    -static gchar *
    -msim_convert_xmlnode(MsimSession *session, xmlnode *root, MSIM_XMLNODE_CONVERT f)
    -{
    - xmlnode *node;
    - gchar *begin, *inner, *end;
    - GString *final;
    -
    - if (!root || !root->name) {
    - return g_strdup("");
    - }
    -
    - purple_debug_info("msim", "msim_convert_xmlnode: got root=%s\n",
    - root->name);
    -
    - begin = inner = end = NULL;
    -
    - final = g_string_new("");
    -
    - f(session, root, &begin, &end);
    -
    - g_string_append(final, begin);
    -
    - /* Loop over all child nodes. */
    - for (node = root->child; node != NULL; node = node->next) {
    - switch (node->type) {
    - case XMLNODE_TYPE_ATTRIB:
    - /* Attributes handled above. */
    - break;
    -
    - case XMLNODE_TYPE_TAG:
    - /* A tag or tag with attributes. Recursively descend. */
    - inner = msim_convert_xmlnode(session, node, f);
    - g_return_val_if_fail(inner != NULL, NULL);
    -
    - purple_debug_info("msim", " ** node name=%s\n",
    - (node && node->name) ? node->name : "(NULL)");
    - break;
    -
    - case XMLNODE_TYPE_DATA:
    - /* Literal text. */
    - inner = g_new0(char, node->data_sz + 1);
    - strncpy(inner, node->data, node->data_sz);
    - inner[node->data_sz] = 0;
    -
    - purple_debug_info("msim", " ** node data=%s\n",
    - inner ? inner : "(NULL)");
    - break;
    -
    - default:
    - purple_debug_info("msim",
    - "msim_convert_xmlnode: strange node\n");
    - inner = g_strdup("");
    - }
    -
    - if (inner) {
    - g_string_append(final, inner);
    - }
    - }
    -
    - /* TODO: Note that msim counts each piece of text enclosed by <f> as
    - * a paragraph and will display each on its own line. You actually have
    - * to _nest_ <f> tags to intersperse different text in one paragraph!
    - * Comment out this line below to see. */
    - g_string_append(final, end);
    -
    - purple_debug_info("msim", "msim_markup_xmlnode_to_gtkhtml: RETURNING %s\n",
    - (final && final->str) ? final->str : "(NULL)");
    -
    - return final->str;
    -}
    -
    -/** Convert XML to something based on MSIM_XMLNODE_CONVERT. */
    -static gchar *
    -msim_convert_xml(MsimSession *session, const gchar *raw, MSIM_XMLNODE_CONVERT f)
    -{
    - xmlnode *root;
    - gchar *str;
    - gchar *enclosed_raw;
    -
    - g_return_val_if_fail(raw != NULL, NULL);
    -
    - /* Enclose text in one root tag, to try to make it valid XML for parsing. */
    - enclosed_raw = g_strconcat("<root>", raw, "</root>", NULL);
    -
    - root = xmlnode_from_str(enclosed_raw, -1);
    -
    - if (!root) {
    - purple_debug_info("msim", "msim_markup_to_html: couldn't parse "
    - "%s as XML, returning raw: %s\n", enclosed_raw, raw);
    - /* TODO: msim_unrecognized */
    - g_free(enclosed_raw);
    - return g_strdup(raw);
    - }
    -
    - g_free(enclosed_raw);
    -
    - str = msim_convert_xmlnode(session, root, f);
    - g_return_val_if_fail(str != NULL, NULL);
    - purple_debug_info("msim", "msim_markup_to_html: returning %s\n", str);
    -
    - xmlnode_free(root);
    -
    - return str;
    -}
    -
    -/** Convert plaintext smileys to <i> markup tags.
    - *
    - * @param before Original text with ASCII smileys. Will be freed.
    - * @return A new string with <i> tags, if applicable. Must be g_free()'d.
    - */
    -static gchar *
    -msim_convert_smileys_to_markup(gchar *before)
    -{
    - gchar *old, *new, *replacement;
    - guint i;
    - struct MSIM_EMOTICON *emote;
    -
    - old = before;
    - new = NULL;
    -
    - for (i = 0; (emote = &msim_emoticons[i]) && emote->name != NULL; ++i) {
    - gchar *name, *symbol;
    -
    - name = emote->name;
    - symbol = emote->symbol;
    -
    - replacement = g_strdup_printf("<i n=\"%s\"/>", name);
    -
    - purple_debug_info("msim", "msim_convert_smileys_to_markup: %s->%s\n",
    - symbol ? symbol : "(NULL)",
    - replacement ? replacement : "(NULL)");
    - new = purple_strreplace(old, symbol, replacement);
    -
    - g_free(replacement);
    - g_free(old);
    -
    - old = new;
    - }
    -
    - return new;
    -}
    -
    -
    -/** High-level function to convert MySpaceIM markup to Purple (HTML) markup.
    - *
    - * @return Purple markup string, must be g_free()'d. */
    -gchar *
    -msim_markup_to_html(MsimSession *session, const gchar *raw)
    -{
    - return msim_convert_xml(session, raw,
    - (MSIM_XMLNODE_CONVERT)(msim_markup_tag_to_html));
    -}
    -
    -/** High-level function to convert Purple (HTML) to MySpaceIM markup.
    - *
    - * TODO: consider using purple_markup_html_to_xhtml() to make valid XML.
    - *
    - * @return HTML markup string, must be g_free()'d. */
    -gchar *
    -html_to_msim_markup(MsimSession *session, const gchar *raw)
    -{
    - gchar *markup;
    -
    - markup = msim_convert_xml(session, raw,
    - (MSIM_XMLNODE_CONVERT)(html_tag_to_msim_markup));
    -
    - if (purple_account_get_bool(session->account, "emoticons", TRUE)) {
    - /* Frees markup and allocates a new one. */
    - markup = msim_convert_smileys_to_markup(markup);
    - }
    -
    - return markup;
    -}
    -
    -
    +/* MySpaceIM Protocol Plugin - markup
    + *
    + * Copyright (C) 2007, Jeff Connelly <jeff2@soc.pidgin.im>
    + *
    + * This program is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License as published by
    + * the Free Software Foundation; either version 2 of the License, or
    + * (at your option) any later version.
    + *
    + * This program is distributed in the hope that it will be useful,
    + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    + * GNU General Public License for more details.
    + *
    + * You should have received a copy of the GNU General Public License
    + * along with this program; if not, write to the Free Software
    + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
    + */
    +
    +#include "myspace.h"
    +
    +typedef void (*MSIM_XMLNODE_CONVERT)(MsimSession *, xmlnode *, gchar **, gchar **);
    +
    +/* Internal functions */
    +
    +static guint msim_point_to_purple_size(MsimSession *session, guint point);
    +static guint msim_purple_size_to_point(MsimSession *session, guint size);
    +static guint msim_height_to_point(MsimSession *session, guint height);
    +static guint msim_point_to_height(MsimSession *session, guint point);
    +
    +static void msim_markup_tag_to_html(MsimSession *, xmlnode *root, gchar **begin, gchar **end);
    +static void html_tag_to_msim_markup(MsimSession *, xmlnode *root, gchar **begin, gchar **end);
    +static gchar *msim_convert_xml(MsimSession *, const gchar *raw, MSIM_XMLNODE_CONVERT f);
    +static gchar *msim_convert_smileys_to_markup(gchar *before);
    +static double msim_round(double round);
    +
    +
    +/* Globals */
    +
    +/* The names in in emoticon_names (for <i n=whatever>) map to corresponding
    + * entries in emoticon_symbols (for the ASCII representation of the emoticon).
    + *
    + * Multiple emoticon symbols in Pidgin can map to one name. List the
    + * canonical form, as inserted by the "Smile!" dialog, first. For example,
    + * :) comes before :-), because although both are recognized as 'happy',
    + * the first is inserted by the smiley button (first symbol in theme).
    + *
    + * Note that symbols are case-sensitive in Pidgin -- :-X is not :-x. */
    +static struct MSIM_EMOTICON
    +{
    + gchar *name;
    + gchar *symbol;
    +} msim_emoticons[] = {
    + /* Unfortunately, this list duplicates much of the file
    + * pidgin/pidgin/pixmaps/emotes/default/22/default.theme.in, because
    + * that file is part of Pidgin, but we're part of libpurple.
    + */
    + { "bigsmile", ":D" },
    + { "bigsmile", ":-D" },
    + { "devil", "}:)" },
    + { "frazzled", ":Z" },
    + { "geek", "B)" },
    + { "googles", "%)" },
    + { "growl", ":E" },
    + { "laugh", ":))" }, /* Must be before ':)' */
    + { "happy", ":)" },
    + { "happy", ":-)" },
    + { "happi", ":)" },
    + { "heart", ":X" },
    + { "mohawk", "-:" },
    + { "mad", "X(" },
    + { "messed", "X)" },
    + { "nerd", "Q)" },
    + { "oops", ":G" },
    + { "pirate", "P)" },
    + { "scared", ":O" },
    + { "sidefrown", ":{" },
    + { "sinister", ":B" },
    + { "smirk", ":," },
    + { "straight", ":|" },
    + { "tongue", ":P" },
    + { "tongue", ":p" },
    + { "tongy", ":P" },
    + { "upset", "B|" },
    + { "wink", ";-)" },
    + { "wink", ";)" },
    + { "winc", ";)" },
    + { "worried", ":[" },
    + { "kiss", ":x" },
    + { NULL, NULL }
    +};
    +
    +
    +
    +/* Indexes of this array + 1 map HTML font size to scale of normal font size. *
    + * Based on _point_sizes from libpurple/gtkimhtml.c
    + * 1 2 3 4 5 6 7 */
    +static gdouble _font_scale[] = { .85, .95, 1, 1.2, 1.44, 1.728, 2.0736 };
    +
    +#define MAX_FONT_SIZE 7 /* Purple maximum font size */
    +#define POINTS_PER_INCH 72 /* How many pt's in an inch */
    +
    +/* Text formatting bits for <f s=#> */
    +#define MSIM_TEXT_BOLD 1
    +#define MSIM_TEXT_ITALIC 2
    +#define MSIM_TEXT_UNDERLINE 4
    +
    +/* Default baseline size of purple's fonts, in points. What is size 3 in points.
    + * _font_scale specifies scaling factor relative to this point size. Note this
    + * is only the default; it is configurable in account options. */
    +#define MSIM_BASE_FONT_POINT_SIZE 8
    +
    +/* Default display's DPI. 96 is common but it can differ. Also configurable
    + * in account options. */
    +#define MSIM_DEFAULT_DPI 96
    +
    +
    +/* round is part of C99, but sometimes is unavailable before then.
    + * Based on http://forums.belution.com/en/cpp/000/050/13.shtml
    + */
    +double msim_round(double value)
    +{
    + if (value < 0) {
    + return -(floor(-value + 0.5));
    + } else {
    + return floor( value + 0.5);
    + }
    +}
    +
    +
    +/** Convert typographical font point size to HTML font size.
    + * Based on libpurple/gtkimhtml.c */
    +static guint
    +msim_point_to_purple_size(MsimSession *session, guint point)
    +{
    + guint size, this_point, base;
    + gdouble scale;
    +
    + base = purple_account_get_int(session->account, "base_font_size", MSIM_BASE_FONT_POINT_SIZE);
    +
    + for (size = 0;
    + size < sizeof(_font_scale) / sizeof(_font_scale[0]);
    + ++size) {
    + scale = _font_scale[CLAMP(size, 1, MAX_FONT_SIZE) - 1];
    + this_point = (guint)msim_round(scale * base);
    +
    + if (this_point >= point) {
    + purple_debug_info("msim", "msim_point_to_purple_size: %d pt -> size=%d\n",
    + point, size);
    + return size;
    + }
    + }
    +
    + /* No HTML font size was this big; return largest possible. */
    + return this_point;
    +}
    +
    +/** Convert HTML font size to point size. */
    +static guint
    +msim_purple_size_to_point(MsimSession *session, guint size)
    +{
    + gdouble scale;
    + guint point;
    + guint base;
    +
    + scale = _font_scale[CLAMP(size, 1, MAX_FONT_SIZE) - 1];
    +
    + base = purple_account_get_int(session->account, "base_font_size", MSIM_BASE_FONT_POINT_SIZE);
    +
    + point = (guint)msim_round(scale * base);
    +
    + purple_debug_info("msim", "msim_purple_size_to_point: size=%d -> %d pt\n",
    + size, point);
    +
    + return point;
    +}
    +
    +/** Convert a msim markup font pixel height to the more usual point size, for incoming messages. */
    +static guint
    +msim_height_to_point(MsimSession *session, guint height)
    +{
    + guint dpi;
    +
    + dpi = purple_account_get_int(session->account, "port", MSIM_DEFAULT_DPI);
    +
    + return (guint)msim_round((POINTS_PER_INCH * 1. / dpi) * height);
    +
    + /* See also: libpurple/protocols/bonjour/jabber.c
    + * _font_size_ichat_to_purple */
    +}
    +
    +/** Convert point size to msim pixel height font size specification, for outgoing messages. */
    +static guint
    +msim_point_to_height(MsimSession *session, guint point)
    +{
    + guint dpi;
    +
    + dpi = purple_account_get_int(session->account, "port", MSIM_DEFAULT_DPI);
    +
    + return (guint)msim_round((dpi * 1. / POINTS_PER_INCH) * point);
    +}
    +
    +/** Convert the msim markup <f> (font) tag into HTML. */
    +static void
    +msim_markup_f_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
    +{
    + const gchar *face, *height_str, *decor_str;
    + GString *gs_end, *gs_begin;
    + guint decor, height;
    +
    + face = xmlnode_get_attrib(root, "f");
    + height_str = xmlnode_get_attrib(root, "h");
    + decor_str = xmlnode_get_attrib(root, "s");
    +
    + if (height_str) {
    + height = atol(height_str);
    + } else {
    + height = 12;
    + }
    +
    + if (decor_str) {
    + decor = atol(decor_str);
    + } else {
    + decor = 0;
    + }
    +
    + gs_begin = g_string_new("");
    + /* TODO: get font size working */
    + if (height && !face) {
    + g_string_printf(gs_begin, "<font size='%d'>",
    + msim_point_to_purple_size(session, msim_height_to_point(session, height)));
    + } else if (height && face) {
    + g_string_printf(gs_begin, "<font face='%s' size='%d'>", face,
    + msim_point_to_purple_size(session, msim_height_to_point(session, height)));
    + } else {
    + g_string_printf(gs_begin, "<font>");
    + }
    +
    + /* No support for font-size CSS? */
    + /* g_string_printf(gs_begin, "<span style='font-family: %s; font-size: %dpt'>", face,
    + msim_height_to_point(height)); */
    +
    + gs_end = g_string_new("</font>");
    +
    + if (decor & MSIM_TEXT_BOLD) {
    + g_string_append(gs_begin, "<b>");
    + g_string_prepend(gs_end, "</b>");
    + }
    +
    + if (decor & MSIM_TEXT_ITALIC) {
    + g_string_append(gs_begin, "<i>");
    + g_string_append(gs_end, "</i>");
    + }
    +
    + if (decor & MSIM_TEXT_UNDERLINE) {
    + g_string_append(gs_begin, "<u>");
    + g_string_append(gs_end, "</u>");
    + }
    +
    +
    + *begin = gs_begin->str;
    + *end = gs_end->str;
    +}
    +
    +/** Convert a msim markup color to a color suitable for libpurple.
    + *
    + * @param msim Either a color name, or an rgb(x,y,z) code.
    + *
    + * @return A new string, either a color name or #rrggbb code. Must g_free().
    + */
    +static char *
    +msim_color_to_purple(const char *msim)
    +{
    + guint red, green, blue;
    +
    + if (!msim) {
    + return g_strdup("black");
    + }
    +
    + if (sscanf(msim, "rgb(%d,%d,%d)", &red, &green, &blue) != 3) {
    + /* Color name. */
    + return g_strdup(msim);
    + }
    + /* TODO: rgba (alpha). */
    +
    + return g_strdup_printf("#%.2x%.2x%.2x", red, green, blue);
    +}
    +
    +/** Convert the msim markup <a> (anchor) tag into HTML. */
    +static void
    +msim_markup_a_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
    +{
    + const gchar *href;
    +
    + href = xmlnode_get_attrib(root, "h");
    + if (!href) {
    + href = "";
    + }
    +
    + *begin = g_strdup_printf("<a href=\"%s\">%s", href, href);
    + *end = g_strdup("</a>");
    +}
    +
    +/** Convert the msim markup <p> (paragraph) tag into HTML. */
    +static void
    +msim_markup_p_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
    +{
    + /* Just pass through unchanged.
    + *
    + * Note: attributes currently aren't passed, if there are any. */
    + *begin = g_strdup("<p>");
    + *end = g_strdup("</p>");
    +}
    +
    +/** Convert the msim markup <c> tag (text color) into HTML. TODO: Test */
    +static void
    +msim_markup_c_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
    +{
    + const gchar *color;
    + gchar *purple_color;
    +
    + color = xmlnode_get_attrib(root, "v");
    + if (!color) {
    + purple_debug_info("msim", "msim_markup_c_to_html: <c> tag w/o v attr\n");
    + *begin = g_strdup("");
    + *end = g_strdup("");
    + /* TODO: log as unrecognized */
    + return;
    + }
    +
    + purple_color = msim_color_to_purple(color);
    +
    + *begin = g_strdup_printf("<font color='%s'>", purple_color);
    +
    + g_free(purple_color);
    +
    + /* *begin = g_strdup_printf("<span style='color: %s'>", color); */
    + *end = g_strdup("</font>");
    +}
    +
    +/** Convert the msim markup <b> tag (background color) into HTML. TODO: Test */
    +static void
    +msim_markup_b_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
    +{
    + const gchar *color;
    + gchar *purple_color;
    +
    + color = xmlnode_get_attrib(root, "v");
    + if (!color) {
    + *begin = g_strdup("");
    + *end = g_strdup("");
    + purple_debug_info("msim", "msim_markup_b_to_html: <b> w/o v attr\n");
    + /* TODO: log as unrecognized. */
    + return;
    + }
    +
    + purple_color = msim_color_to_purple(color);
    +
    + /* TODO: find out how to set background color. */
    + *begin = g_strdup_printf("<span style='background-color: %s'>",
    + purple_color);
    + g_free(purple_color);
    +
    + *end = g_strdup("</p>");
    +}
    +
    +/** Convert the msim markup <i> tag (emoticon image) into HTML. */
    +static void
    +msim_markup_i_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
    +{
    + const gchar *name;
    + guint i;
    + struct MSIM_EMOTICON *emote;
    +
    + name = xmlnode_get_attrib(root, "n");
    + if (!name) {
    + purple_debug_info("msim", "msim_markup_i_to_html: <i> w/o n\n");
    + *begin = g_strdup("");
    + *end = g_strdup("");
    + /* TODO: log as unrecognized */
    + return;
    + }
    +
    + /* Find and use canonical form of smiley symbol. */
    + for (i = 0; (emote = &msim_emoticons[i]) && emote->name != NULL; ++i) {
    + if (g_str_equal(name, emote->name)) {
    + *begin = g_strdup(emote->symbol);
    + *end = g_strdup("");
    + return;
    + }
    + }
    +
    + /* Couldn't find it, sorry. Try to degrade gracefully. */
    + *begin = g_strdup_printf("**%s**", name);
    + *end = g_strdup("");
    +}
    +
    +/** Convert an individual msim markup tag to HTML. */
    +static void
    +msim_markup_tag_to_html(MsimSession *session, xmlnode *root, gchar **begin,
    + gchar **end)
    +{
    + if (g_str_equal(root->name, "f")) {
    + msim_markup_f_to_html(session, root, begin, end);
    + } else if (g_str_equal(root->name, "a")) {
    + msim_markup_a_to_html(session, root, begin, end);
    + } else if (g_str_equal(root->name, "p")) {
    + msim_markup_p_to_html(session, root, begin, end);
    + } else if (g_str_equal(root->name, "c")) {
    + msim_markup_c_to_html(session, root, begin, end);
    + } else if (g_str_equal(root->name, "b")) {
    + msim_markup_b_to_html(session, root, begin, end);
    + } else if (g_str_equal(root->name, "i")) {
    + msim_markup_i_to_html(session, root, begin, end);
    + } else {
    + purple_debug_info("msim", "msim_markup_tag_to_html: "
    + "unknown tag name=%s, ignoring",
    + (root && root->name) ? root->name : "(NULL)");
    + *begin = g_strdup("");
    + *end = g_strdup("");
    + }
    +}
    +
    +/** Convert an individual HTML tag to msim markup. */
    +static void
    +html_tag_to_msim_markup(MsimSession *session, xmlnode *root, gchar **begin,
    + gchar **end)
    +{
    + if (!purple_utf8_strcasecmp(root->name, "root") ||
    + !purple_utf8_strcasecmp(root->name, "html")) {
    + *begin = g_strdup("");
    + *end = g_strdup("");
    + /* TODO: Coalesce nested tags into one <f> tag!
    + * Currently, the 's' value will be overwritten when b/i/u is nested
    + * within another one, and only the inner-most formatting will be
    + * applied to the text. */
    + } else if (!purple_utf8_strcasecmp(root->name, "b")) {
    + *begin = g_strdup_printf("<f s='%d'>", MSIM_TEXT_BOLD);
    + *end = g_strdup("</f>");
    + } else if (!purple_utf8_strcasecmp(root->name, "i")) {
    + *begin = g_strdup_printf("<f s='%d'>", MSIM_TEXT_ITALIC);
    + *end = g_strdup("</f>");
    + } else if (!purple_utf8_strcasecmp(root->name, "u")) {
    + *begin = g_strdup_printf("<f s='%d'>", MSIM_TEXT_UNDERLINE);
    + *end = g_strdup("</f>");
    + } else if (!purple_utf8_strcasecmp(root->name, "a")) {
    + const gchar *href, *link_text;
    +
    + href = xmlnode_get_attrib(root, "href");
    +
    + if (!href) {
    + href = xmlnode_get_attrib(root, "HREF");
    + }
    +
    + link_text = xmlnode_get_data(root);
    +
    + if (href) {
    + if (g_str_equal(link_text, href)) {
    + /* Purple gives us: <a href="URL">URL</a>
    + * Translate to <a h='URL' />
    + * Displayed as text of URL with link to URL
    + */
    + *begin = g_strdup_printf("<a h='%s' />", href);
    + } else {
    + /* But if we get: <a href="URL">text</a>
    + * Translate to: text: <a h='URL' />
    + *
    + * Because official client only supports self-closed <a>
    + * tags; you can't change the link text.
    + */
    + *begin = g_strdup_printf("%s: <a h='%s' />", link_text, href);
    + }
    + } else {
    + *begin = g_strdup("<a />");
    + }
    +
    + /* Sorry, kid. MySpace doesn't support you within <a> tags. */
    + xmlnode_free(root->child);
    + root->child = NULL;
    +
    + *end = g_strdup("");
    + } else if (!purple_utf8_strcasecmp(root->name, "font")) {
    + const gchar *size;
    + const gchar *face;
    +
    + size = xmlnode_get_attrib(root, "size");
    + face = xmlnode_get_attrib(root, "face");
    +
    + if (face && size) {
    + *begin = g_strdup_printf("<f f='%s' h='%d'>", face,
    + msim_point_to_height(session,
    + msim_purple_size_to_point(session, atoi(size))));
    + } else if (face) {
    + *begin = g_strdup_printf("<f f='%s'>", face);
    + } else if (size) {
    + *begin = g_strdup_printf("<f h='%d'>",
    + msim_point_to_height(session,
    + msim_purple_size_to_point(session, atoi(size))));
    + } else {
    + *begin = g_strdup("<f>");
    + }
    +
    + *end = g_strdup("</f>");
    +
    + /* TODO: color (bg uses <body>), emoticons */
    + } else {
    +
    +#ifdef MSIM_MARKUP_SHOW_UNKNOWN_TAGS
    + *begin = g_strdup_printf("[%s]", root->name);
    + *end = g_strdup_printf("[/%s]", root->name);
    +#else
    + *begin = g_strdup("");
    + *end = g_strdup("");
    +#endif
    + }
    +}
    +
    +/** Convert an xmlnode of msim markup or HTML to an HTML string or msim markup.
    + *
    + * @param f Function to convert tags.
    + *
    + * @return An HTML string. Caller frees.
    + */
    +static gchar *
    +msim_convert_xmlnode(MsimSession *session, xmlnode *root, MSIM_XMLNODE_CONVERT f)
    +{
    + xmlnode *node;
    + gchar *begin, *inner, *end;
    + GString *final;
    +
    + if (!root || !root->name) {
    + return g_strdup("");
    + }
    +
    + purple_debug_info("msim", "msim_convert_xmlnode: got root=%s\n",
    + root->name);
    +
    + begin = inner = end = NULL;
    +
    + final = g_string_new("");
    +
    + f(session, root, &begin, &end);
    +
    + g_string_append(final, begin);
    +
    + /* Loop over all child nodes. */
    + for (node = root->child; node != NULL; node = node->next) {
    + switch (node->type) {
    + case XMLNODE_TYPE_ATTRIB:
    + /* Attributes handled above. */
    + break;
    +
    + case XMLNODE_TYPE_TAG:
    + /* A tag or tag with attributes. Recursively descend. */
    + inner = msim_convert_xmlnode(session, node, f);
    + g_return_val_if_fail(inner != NULL, NULL);
    +
    + purple_debug_info("msim", " ** node name=%s\n",
    + (node && node->name) ? node->name : "(NULL)");
    + break;
    +
    + case XMLNODE_TYPE_DATA:
    + /* Literal text. */
    + inner = g_new0(char, node->data_sz + 1);
    + strncpy(inner, node->data, node->data_sz);
    + inner[node->data_sz] = 0;
    +
    + purple_debug_info("msim", " ** node data=%s\n",
    + inner ? inner : "(NULL)");
    + break;
    +
    + default:
    + purple_debug_info("msim",
    + "msim_convert_xmlnode: strange node\n");
    + inner = g_strdup("");
    + }
    +
    + if (inner) {
    + g_string_append(final, inner);
    + }
    + }
    +
    + /* TODO: Note that msim counts each piece of text enclosed by <f> as
    + * a paragraph and will display each on its own line. You actually have
    + * to _nest_ <f> tags to intersperse different text in one paragraph!
    + * Comment out this line below to see. */
    + g_string_append(final, end);
    +
    + purple_debug_info("msim", "msim_markup_xmlnode_to_gtkhtml: RETURNING %s\n",
    + (final && final->str) ? final->str : "(NULL)");
    +
    + return final->str;
    +}
    +
    +/** Convert XML to something based on MSIM_XMLNODE_CONVERT. */
    +static gchar *
    +msim_convert_xml(MsimSession *session, const gchar *raw, MSIM_XMLNODE_CONVERT f)
    +{
    + xmlnode *root;
    + gchar *str;
    + gchar *enclosed_raw;
    +
    + g_return_val_if_fail(raw != NULL, NULL);
    +
    + /* Enclose text in one root tag, to try to make it valid XML for parsing. */
    + enclosed_raw = g_strconcat("<root>", raw, "</root>", NULL);
    +
    + root = xmlnode_from_str(enclosed_raw, -1);
    +
    + if (!root) {
    + purple_debug_info("msim", "msim_markup_to_html: couldn't parse "
    + "%s as XML, returning raw: %s\n", enclosed_raw, raw);
    + /* TODO: msim_unrecognized */
    + g_free(enclosed_raw);
    + return g_strdup(raw);
    + }
    +
    + g_free(enclosed_raw);
    +
    + str = msim_convert_xmlnode(session, root, f);
    + g_return_val_if_fail(str != NULL, NULL);
    + purple_debug_info("msim", "msim_markup_to_html: returning %s\n", str);
    +
    + xmlnode_free(root);
    +
    + return str;
    +}
    +
    +/** Convert plaintext smileys to <i> markup tags.
    + *
    + * @param before Original text with ASCII smileys. Will be freed.
    + * @return A new string with <i> tags, if applicable. Must be g_free()'d.
    + */
    +static gchar *
    +msim_convert_smileys_to_markup(gchar *before)
    +{
    + gchar *old, *new, *replacement;
    + guint i;
    + struct MSIM_EMOTICON *emote;
    +
    + old = before;
    + new = NULL;
    +
    + for (i = 0; (emote = &msim_emoticons[i]) && emote->name != NULL; ++i) {
    + gchar *name, *symbol;
    +
    + name = emote->name;
    + symbol = emote->symbol;
    +
    + replacement = g_strdup_printf("<i n=\"%s\"/>", name);
    +
    + purple_debug_info("msim", "msim_convert_smileys_to_markup: %s->%s\n",
    + symbol ? symbol : "(NULL)",
    + replacement ? replacement : "(NULL)");
    + new = purple_strreplace(old, symbol, replacement);
    +
    + g_free(replacement);
    + g_free(old);
    +
    + old = new;
    + }
    +
    + return new;
    +}
    +
    +
    +/** High-level function to convert MySpaceIM markup to Purple (HTML) markup.
    + *
    + * @return Purple markup string, must be g_free()'d. */
    +gchar *
    +msim_markup_to_html(MsimSession *session, const gchar *raw)
    +{
    + return msim_convert_xml(session, raw,
    + (MSIM_XMLNODE_CONVERT)(msim_markup_tag_to_html));
    +}
    +
    +/** High-level function to convert Purple (HTML) to MySpaceIM markup.
    + *
    + * TODO: consider using purple_markup_html_to_xhtml() to make valid XML.
    + *
    + * @return HTML markup string, must be g_free()'d. */
    +gchar *
    +html_to_msim_markup(MsimSession *session, const gchar *raw)
    +{
    + gchar *markup;
    +
    + markup = msim_convert_xml(session, raw,
    + (MSIM_XMLNODE_CONVERT)(html_tag_to_msim_markup));
    +
    + if (purple_account_get_bool(session->account, "emoticons", TRUE)) {
    + /* Frees markup and allocates a new one. */
    + markup = msim_convert_smileys_to_markup(markup);
    + }
    +
    + return markup;
    +}
    +
    +
    --- a/libpurple/protocols/myspace/myspace.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/protocols/myspace/myspace.h Mon Sep 17 17:51:22 2007 +0000
    @@ -67,6 +67,9 @@
    /*#define MSIM_DEBUG_LOGIN_CHALLENGE*/
    /*#define MSIM_DEBUG_RXBUF */
    +/* Encode unknown HTML tags in messages in [], instead of ignoring */
    +#define MSIM_MARKUP_SHOW_UNKNOWN_TAGS
    +
    /* Define to cause init_plugin() to run some tests and print
    * the results to the Purple debug log, then exit. Useful to
    * run with 'pidgin -d' to see the output. Don't define if
    --- a/libpurple/proxy.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/proxy.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file proxy.c Proxy API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/proxy.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/proxy.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file proxy.h Proxy API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/prpl.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/prpl.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file prpl.h Protocol Plugin functions
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/request.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/request.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file request.c Request API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/request.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/request.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file request.h Request API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/roomlist.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/roomlist.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file roomlist.c Room List API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/roomlist.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/roomlist.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file roomlist.h Room List API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/savedstatuses.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/savedstatuses.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file savedstatuses.c Saved Status API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/savedstatuses.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/savedstatuses.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file savedstatuses.h Saved Status API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/server.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/server.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file server.h Server API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/signals.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/signals.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file signals.c Signal API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/signals.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/signals.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file signals.h Signal API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/sound.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/sound.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file sound.h Sound API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/sslconn.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/sslconn.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file sslconn.c SSL API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/sslconn.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/sslconn.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file sslconn.h SSL API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/status.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/status.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file status.c Status API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/stringref.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/stringref.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file stringref.c Reference-counted immutable strings
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/stringref.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/stringref.h Mon Sep 17 17:51:22 2007 +0000
    @@ -3,8 +3,9 @@
    /**
    * @file stringref.h Reference-counted immutable strings
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/stun.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/stun.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file stun.c STUN (RFC3489) Implementation
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * STUN implementation inspired by jstun [http://jstun.javawi.de/]
    *
    --- a/libpurple/stun.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/stun.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file stun.h STUN API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/upnp.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/upnp.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file upnp.c UPnP Implementation
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/upnp.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/upnp.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file upnp.h Universal Plug N Play API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/util.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/util.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file util.h Utility Functions
    * @ingroup core
    - *
    - * Purple is the legal property of its developers, whose names are too numerous
    + */
    +
    +/* Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    * source distribution.
    *
    @@ -67,7 +68,7 @@
    };
    static char *custom_user_dir = NULL;
    -static char *home_dir = NULL;
    +static char *user_dir = NULL;
    PurpleMenuAction *
    purple_menu_action_new(const char *label, PurpleCallback callback, gpointer data,
    @@ -2463,10 +2464,10 @@
    {
    if (custom_user_dir != NULL)
    return custom_user_dir;
    - else if (!home_dir)
    - home_dir = g_build_filename(purple_home_dir(), ".purple", NULL);
    -
    - return home_dir;
    + else if (!user_dir)
    + user_dir = g_build_filename(purple_home_dir(), ".purple", NULL);
    +
    + return user_dir;
    }
    void purple_util_set_user_dir(const char *dir)
    --- a/libpurple/util.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/util.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file util.h Utility Functions
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/value.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/value.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file value.c Value wrapper API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/value.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/value.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file value.h Value wrapper API
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/version.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/version.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file version.c Version Functions
    * @ingroup core
    - *
    - * Purple is the legal property of its developers, whose names are too numerous
    + */
    +
    +/* Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    * source distribution.
    *
    --- a/libpurple/whiteboard.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/whiteboard.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,7 +1,8 @@
    /**
    * @file whiteboard.h The PurpleWhiteboard core object
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/xmlnode.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/xmlnode.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,7 +1,8 @@
    /**
    * @file xmlnode.c XML DOM functions
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/libpurple/xmlnode.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/libpurple/xmlnode.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file xmlnode.h XML DOM functions
    * @ingroup core
    - *
    - * purple
    + */
    +
    +/* purple
    *
    * Purple is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkaccount.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkaccount.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkaccount.c GTK+ Account Editor UI
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkaccount.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkaccount.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkaccount.h GTK+ Account Editor UI
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkblist.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkblist.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file gtkblist.c GTK+ BuddyList API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    @@ -87,6 +88,8 @@
    GtkWidget *group_combo;
    GtkWidget *entries_box;
    GtkSizeGroup *sg;
    + GtkWidget *autojoin;
    + GtkWidget *persistent;
    GList *entries;
    @@ -317,8 +320,8 @@
    static void gtk_blist_menu_move_to_cb(GtkWidget *w, PurpleBlistNode *node)
    {
    - PurpleBlistNode *group = g_object_get_data(w, "groupnode");
    - purple_blist_add_contact(node, group, NULL);
    + PurpleGroup *group = g_object_get_data(G_OBJECT(w), "groupnode");
    + purple_blist_add_contact((PurpleContact *)node, group, NULL);
    }
    @@ -471,9 +474,9 @@
    if (node == contact)
    continue;
    - purple_blist_merge_contact(node, contact);
    - }
    -
    + purple_blist_merge_contact((PurpleContact *)node, contact);
    + }
    +
    /* And show the expanded contact, so the people know what's going on */
    pidgin_blist_expand_contact_cb(NULL, contact);
    g_list_free(merges);
    @@ -487,14 +490,13 @@
    GList *merges = NULL;
    int i = 0;
    char *a = g_utf8_casefold(alias, -1);
    - char *msg;
    for (contact = group->child; contact; contact = contact->next) {
    char *node_alias;
    if (contact->type != PURPLE_BLIST_CONTACT_NODE)
    continue;
    -
    - node_alias = g_utf8_casefold(purple_contact_get_alias(contact), -1);
    +
    + node_alias = g_utf8_casefold(purple_contact_get_alias((PurpleContact *)contact), -1);
    if (node_alias && !g_utf8_collate(node_alias, a)) {
    merges = g_list_append(merges, contact);
    i++;
    @@ -506,8 +508,8 @@
    for (buddy = contact->child; buddy; buddy = buddy->next) {
    if (buddy->type != PURPLE_BLIST_BUDDY_NODE)
    continue;
    -
    - node_alias = g_utf8_casefold(purple_buddy_get_alias(buddy), -1);
    +
    + node_alias = g_utf8_casefold(purple_buddy_get_alias((PurpleBuddy *)buddy), -1);
    if (node_alias && !g_utf8_collate(node_alias, a)) {
    merges = g_list_append(merges, buddy);
    i++;
    @@ -517,11 +519,15 @@
    }
    g_free(a);
    - msg = g_strdup_printf(ngettext("You can't merge one contact. That doesn't make any sense. You should never see this message ever", "You currently have %d contacts named %s. Would you like to merge them?", i), i, alias);
    if (i > 1)
    + {
    + char *msg = g_strdup_printf(ngettext("You currently have %d contact named %s. Would you like to merge them?", "You currently have %d contacts named %s. Would you like to merge them?", i), i, alias);
    purple_request_action(NULL, NULL, msg, _("Merging these contacts will cause them to share a single entry on the buddy list and use a single conversation window. "
    "You can separate them again by choosing 'Expand' from the contact's context menu"), 0, NULL, NULL, NULL,
    merges, 2, _("_Merge"), PURPLE_CALLBACK(gtk_blist_do_personize), _("_Cancel"), PURPLE_CALLBACK(g_list_free));
    + g_free(msg);
    + } else
    + g_list_free(merges);
    }
    static void gtk_blist_renderer_edited_cb(GtkCellRendererText *text_rend, char *arg1,
    @@ -1264,14 +1270,14 @@
    gtk_widget_show(menuitem);
    submenu = gtk_menu_new();
    - gtk_menu_item_set_submenu(menuitem, submenu);
    + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
    for (group = purple_blist_get_root(); group; group = group->next) {
    if (group->type != PURPLE_BLIST_GROUP_NODE)
    continue;
    if (group == node->parent)
    continue;
    - menuitem = pidgin_new_item_from_stock(submenu, purple_group_get_name(group), NULL,
    + menuitem = pidgin_new_item_from_stock(submenu, purple_group_get_name((PurpleGroup *)group), NULL,
    G_CALLBACK(gtk_blist_menu_move_to_cb), node, 0, 0, NULL);
    g_object_set_data(G_OBJECT(menuitem), "groupnode", group);
    }
    @@ -1330,7 +1336,7 @@
    pidgin_append_blist_node_extended_menu(menu, (PurpleBlistNode *)buddy);
    if (!contact_expanded)
    - pidgin_append_blist_node_move_to_menu(menu, contact);
    + pidgin_append_blist_node_move_to_menu(menu, (PurpleBlistNode *)contact);
    if (((PurpleBlistNode*)buddy)->parent && ((PurpleBlistNode*)buddy)->parent->child->next &&
    !sub && !contact_expanded) {
    @@ -5897,6 +5903,12 @@
    purple_blist_add_chat(chat, group, NULL);
    }
    + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->autojoin)))
    + purple_blist_node_set_bool((PurpleBlistNode*)chat, "gtk-autojoin", TRUE);
    +
    + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->persistent)))
    + purple_blist_node_set_bool((PurpleBlistNode*)chat, "gtk-persistent", TRUE);
    +
    gtk_widget_destroy(data->window);
    g_free(data->default_chat_name);
    g_list_free(data->entries);
    @@ -6191,6 +6203,11 @@
    gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_BIN(data->group_combo)->child);
    pidgin_set_accessible_label (data->group_combo, label);
    gtk_box_pack_end(GTK_BOX(rowbox), data->group_combo, TRUE, TRUE, 0);
    +
    + data->autojoin = gtk_check_button_new_with_mnemonic(_("Autojoin when account becomes online."));
    + data->persistent = gtk_check_button_new_with_mnemonic(_("Hide chat when the window is closed."));
    + gtk_box_pack_start(GTK_BOX(vbox), data->autojoin, FALSE, FALSE, 0);
    + gtk_box_pack_start(GTK_BOX(vbox), data->persistent, FALSE, FALSE, 0);
    g_signal_connect(G_OBJECT(data->window), "response",
    G_CALLBACK(add_chat_resp_cb), data);
    --- a/pidgin/gtkblist.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkblist.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkblist.h GTK+ Buddy List API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkcellrendererexpander.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkcellrendererexpander.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file gtkcellrendererexpander.c GTK+ Cell Renderer Expander
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    @@ -269,7 +270,9 @@
    cell_area->x + cell->xpad + (width / 2),
    cell_area->y + cell->ypad + (height / 2),
    cell->is_expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED);
    - gtk_paint_hline (widget->style, window, state, NULL, widget, NULL, 0, widget->allocation.width, cell_area->y + cell_area->height);
    + if (cell->is_expanded)
    + gtk_paint_hline (widget->style, window, state, NULL, widget, NULL, 0,
    + widget->allocation.width, cell_area->y + cell_area->height);
    }
    static gboolean pidgin_cell_renderer_expander_activate(GtkCellRenderer *r,
    --- a/pidgin/gtkcellrendererprogress.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkcellrendererprogress.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file gtkcellrendererprogress.c GTK+ Cell Renderer Progress
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkcertmgr.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkcertmgr.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file gtkcertmgr.c GTK+ Certificate Manager API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkconn.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkconn.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file gtkconn.c GTK+ Connection API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    @@ -53,7 +54,7 @@
    * The key is a pointer to the PurpleAccount and the
    * value is a pointer to a PidginAutoRecon.
    */
    -static GHashTable *hash = NULL;
    +static GHashTable *auto_reconns = NULL;
    static void
    pidgin_connection_connect_progress(PurpleConnection *gc,
    @@ -80,7 +81,7 @@
    pidgin_status_box_set_connecting(PIDGIN_STATUS_BOX(gtkblist->statusbox),
    (purple_connections_get_connecting() != NULL));
    - g_hash_table_remove(hash, account);
    + g_hash_table_remove(auto_reconns, account);
    pidgin_blist_update_account_error_state(account, NULL);
    }
    @@ -120,7 +121,7 @@
    purple_debug_info("autorecon", "do_signon called\n");
    g_return_val_if_fail(account != NULL, FALSE);
    - info = g_hash_table_lookup(hash, account);
    + info = g_hash_table_lookup(auto_reconns, account);
    if (info)
    info->timeout = 0;
    @@ -145,13 +146,13 @@
    PidginAutoRecon *info;
    account = purple_connection_get_account(gc);
    - info = g_hash_table_lookup(hash, account);
    + info = g_hash_table_lookup(auto_reconns, account);
    pidgin_blist_update_account_error_state(account, text);
    if (!purple_connection_reason_is_fatal (reason)) {
    if (info == NULL) {
    info = g_new0(PidginAutoRecon, 1);
    - g_hash_table_insert(hash, account, info);
    + g_hash_table_insert(auto_reconns, account, info);
    info->delay = g_random_int_range(INITIAL_RECON_DELAY_MIN, INITIAL_RECON_DELAY_MAX);
    } else {
    info->delay = MIN(2 * info->delay, MAX_RECON_DELAY);
    @@ -162,7 +163,7 @@
    } else {
    char *p, *s, *n=NULL ;
    if (info != NULL)
    - g_hash_table_remove(hash, account);
    + g_hash_table_remove(auto_reconns, account);
    if (purple_account_get_alias(account))
    {
    @@ -206,7 +207,7 @@
    while (list) {
    PurpleAccount *account = (PurpleAccount*)list->data;
    - g_hash_table_remove(hash, account);
    + g_hash_table_remove(auto_reconns, account);
    if (purple_account_is_disconnected(account))
    do_signon(account);
    list = list->next;
    @@ -267,7 +268,7 @@
    static void
    account_removed_cb(PurpleAccount *account, gpointer user_data)
    {
    - g_hash_table_remove(hash, account);
    + g_hash_table_remove(auto_reconns, account);
    pidgin_blist_update_account_error_state(account, NULL);
    }
    @@ -288,7 +289,7 @@
    void
    pidgin_connection_init(void)
    {
    - hash = g_hash_table_new_full(
    + auto_reconns = g_hash_table_new_full(
    g_direct_hash, g_direct_equal,
    NULL, free_auto_recon);
    @@ -302,5 +303,5 @@
    {
    purple_signals_disconnect_by_handle(pidgin_connection_get_handle());
    - g_hash_table_destroy(hash);
    + g_hash_table_destroy(auto_reconns);
    }
    --- a/pidgin/gtkconn.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkconn.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,7 +1,8 @@
    /**
    * @file gtkconn.h GTK+ Connection API
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkconv.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkconv.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkconv.c GTK+ Conversation API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    @@ -219,7 +220,7 @@
    }
    static gboolean
    -close_conv_cb(GtkWidget *w, GdkEventButton *event, PidginConversation *gtkconv)
    +close_conv_cb(GtkWidget *w, GdkEventButton *dontuse, PidginConversation *gtkconv)
    {
    /* We are going to destroy the conversations immediately only if the 'close immediately'
    * preference is selected. Otherwise, close the conversation after a reasonable timeout
    @@ -1912,6 +1913,7 @@
    gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook),
    gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv),
    curconv - 1);
    + return TRUE;
    break;
    case GDK_period:
    @@ -1922,6 +1924,7 @@
    #else
    (curconv + 1) % g_list_length(GTK_NOTEBOOK(win->notebook)->children));
    #endif
    + return TRUE;
    break;
    } /* End of switch */
    @@ -8833,15 +8836,10 @@
    if (win->gtkconvs) {
    while (win->gtkconvs) {
    - GList *nextgtk = win->gtkconvs->next;
    - PidginConversation *gtkconv = win->gtkconvs->data;
    - GList *nextcore = gtkconv->convs->next;
    - PurpleConversation *conv = gtkconv->convs->data;
    - purple_conversation_destroy(conv);
    - if (!nextgtk && !nextcore)
    - /* we'll end up invoking ourselves when we destroy our last child */
    - /* so don't destroy ourselves right now */
    - return;
    + gboolean last = (win->gtkconvs->next == NULL);
    + close_conv_cb(NULL, NULL, win->gtkconvs->data);
    + if (last)
    + break;
    }
    return;
    }
    --- a/pidgin/gtkconv.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkconv.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkconv.h GTK+ Conversation API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkconvwin.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkconvwin.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkconvwin.h GTK+ Conversation Window API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkdebug.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkdebug.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkdebug.c GTK+ Debug API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkdebug.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkdebug.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkdebug.h GTK+ Debug API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkdialogs.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkdialogs.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file gtkdialogs.c GTK+ Dialogs
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkdialogs.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkdialogs.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,7 +1,8 @@
    /**
    * @defgroup pidgin Pidgin (GTK+ User Interface)
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkdnd-hints.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkdnd-hints.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file gtkdnd-hints.c GTK+ Drag-and-Drop arrow hints
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkdnd-hints.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkdnd-hints.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkdnd-hints.h GTK+ Drag-and-Drop arrow hints
    * @ingroup pidgin
    - *
    - * Pidgin is the legal property of its developers, whose names are too numerous
    + */
    +
    +/* Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    * source distribution.
    *
    --- a/pidgin/gtkeventloop.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkeventloop.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtk_eventloop.c Purple Event Loop API (gtk implementation)
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkeventloop.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkeventloop.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkeventloop.h Pidgin GTK+ Event Loop Implementation
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkft.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkft.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkft.c GTK+ File Transfer UI
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkft.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkft.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkft.h GTK+ File Transfer UI
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkgaim-compat.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkgaim-compat.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,7 +1,8 @@
    /**
    * @file gtkgaim-compat.h Gtk Gaim Compat macros
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkidle.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkidle.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkidle.h GTK+ Idle API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkimhtml.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkimhtml.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file gtkimhtml.c GTK+ IMHtml
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkimhtml.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkimhtml.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkimhtml.h GTK+ IM/HTML rendering component
    * @ingroup pidgin
    - *
    - * Pidgin is the legal property of its developers, whose names are too numerous
    + */
    +
    +/* Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    * source distribution.
    *
    --- a/pidgin/gtkimhtmltoolbar.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkimhtmltoolbar.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file gtkimhtmltoolbar.c GTK+ IMHtml Toolbar
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    @@ -1162,6 +1163,7 @@
    GtkWidget *label;
    GtkWidget *insert_button;
    GtkWidget *font_button;
    + GtkWidget *smiley_button;
    GtkWidget *font_menu;
    GtkWidget *insert_menu;
    GtkWidget *menuitem;
    @@ -1263,12 +1265,6 @@
    insert_menu = gtk_menu_new();
    g_object_set_data(G_OBJECT(toolbar), "insert_menu", insert_menu);
    - menuitem = gtk_menu_item_new_with_mnemonic(_("_Smiley"));
    - g_signal_connect_swapped(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_button_clicked), toolbar->smiley);
    - gtk_menu_shell_append(GTK_MENU_SHELL(insert_menu), menuitem);
    - g_signal_connect(G_OBJECT(toolbar->smiley), "notify::sensitive",
    - G_CALLBACK(button_sensitiveness_changed), menuitem);
    -
    menuitem = gtk_menu_item_new_with_mnemonic(_("_Image"));
    g_signal_connect_swapped(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_button_clicked), toolbar->image);
    gtk_menu_shell_append(GTK_MENU_SHELL(insert_menu), menuitem);
    @@ -1290,6 +1286,24 @@
    g_signal_connect(G_OBJECT(insert_button), "activate", G_CALLBACK(pidgin_menu_clicked), insert_menu);
    g_signal_connect(G_OBJECT(insert_menu), "deactivate", G_CALLBACK(pidgin_menu_deactivate), insert_button);
    toolbar->sml = NULL;
    +
    + /* Sep */
    + sep = gtk_vseparator_new();
    + gtk_box_pack_start(GTK_BOX(box), sep, FALSE, FALSE, 0);
    + gtk_widget_show_all(sep);
    +
    + /* Smiley */
    + smiley_button = gtk_button_new();
    + gtk_button_set_relief(GTK_BUTTON(smiley_button), GTK_RELIEF_NONE);
    + bbox = gtk_hbox_new(FALSE, 3);
    + gtk_container_add(GTK_CONTAINER(smiley_button), bbox);
    + image = gtk_image_new_from_stock(PIDGIN_STOCK_TOOLBAR_SMILEY, gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL));
    + gtk_box_pack_start(GTK_BOX(bbox), image, FALSE, FALSE, 0);
    + label = gtk_label_new_with_mnemonic(_("_Smiley"));
    + gtk_box_pack_start(GTK_BOX(bbox), label, FALSE, FALSE, 0);
    + gtk_box_pack_start(GTK_BOX(box), smiley_button, FALSE, FALSE, 0);
    + g_signal_connect_swapped(G_OBJECT(smiley_button), "clicked", G_CALLBACK(gtk_button_clicked), toolbar->smiley);
    + gtk_widget_show_all(smiley_button);
    gtk_box_pack_start(GTK_BOX(hbox), box, FALSE, FALSE, 0);
    g_object_set_data(G_OBJECT(hbox), "lean-view", box);
    --- a/pidgin/gtklog.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtklog.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtklog.c GTK+ Log viewer
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtklog.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtklog.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtklog.h GTK+ Log viewer
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkmain.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkmain.c Mon Sep 17 17:51:22 2007 +0000
    @@ -394,6 +394,9 @@
    " -n, --nologin don't automatically login\n"
    " -l, --login[=NAME] automatically login (optional argument NAME specifies\n"
    " account(s) to use, separated by commas)\n"
    +#ifndef WIN32
    + " --display=DISPLAY X display to use\n"
    +#endif
    " -v, --version display the current version and exit\n"), PIDGIN_NAME, VERSION, name);
    }
    @@ -481,6 +484,7 @@
    {"nologin", no_argument, NULL, 'n'},
    {"session", required_argument, NULL, 's'},
    {"version", no_argument, NULL, 'v'},
    + {"display", required_argument, NULL, 'D'},
    {0, 0, 0, 0}
    };
    @@ -626,6 +630,9 @@
    case 'm': /* do not ensure single instance. */
    opt_si = FALSE;
    break;
    + case 'D': /* --display */
    + /* handled by gtk_init_check below */
    + break;
    case '?': /* show terse help */
    default:
    show_usage(argv[0], TRUE);
    --- a/pidgin/gtkmenutray.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkmenutray.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkmenutray.h GTK+ Tray menu item
    * @ingroup pidgin
    - *
    - * Pidgin is the legal property of its developers, whose names are too numerous
    + */
    +
    +/* Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    * source distribution.
    *
    --- a/pidgin/gtknickcolors.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtknickcolors.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtknickcolors.h GTK+ Conversation API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    * source distribution.
    --- a/pidgin/gtknotify.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtknotify.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtknotify.c GTK+ Notification API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    @@ -660,30 +661,30 @@
    GtkTreeIter iter;
    GdkPixbuf *pixbuf;
    guint col_num;
    - guint i;
    - guint j;
    + GList *row, *column;
    + guint n;
    gtk_list_store_clear(data->model);
    pixbuf = pidgin_create_prpl_icon(purple_connection_get_account(gc), 0.5);
    /* +1 is for the automagically created Status column. */
    - col_num = purple_notify_searchresults_get_columns_count(results) + 1;
    + col_num = g_list_length(results->columns) + 1;
    - for (i = 0; i < purple_notify_searchresults_get_rows_count(results); i++) {
    - GList *row = purple_notify_searchresults_row_get(results, i);
    + for (row = results->rows; row != NULL; row = row->next) {
    gtk_list_store_append(model, &iter);
    gtk_list_store_set(model, &iter, 0, pixbuf, -1);
    - for (j = 1; j < col_num; j++) {
    + n = 1;
    + for (column = row->data; column != NULL; column = column->next) {
    GValue v;
    - char *data = g_list_nth_data(row, j - 1);
    v.g_type = 0;
    g_value_init(&v, G_TYPE_STRING);
    - g_value_set_string(&v, data);
    - gtk_list_store_set_value(model, &iter, j, &v);
    + g_value_set_string(&v, column->data);
    + gtk_list_store_set_value(model, &iter, n, &v);
    + n++;
    }
    }
    @@ -703,6 +704,7 @@
    GtkListStore *model;
    GtkCellRenderer *renderer;
    guint col_num;
    + GList *column;
    guint i;
    GtkWidget *vbox;
    @@ -750,7 +752,7 @@
    g_free(label_text);
    /* +1 is for the automagically created Status column. */
    - col_num = purple_notify_searchresults_get_columns_count(results) + 1;
    + col_num = g_list_length(results->columns) + 1;
    /* Setup the list model */
    col_types = g_new0(GType, col_num);
    @@ -785,12 +787,13 @@
    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview),
    -1, "", renderer, "pixbuf", 0, NULL);
    - for (i = 1; i < col_num; i++) {
    + i = 1;
    + for (column = results->columns; column != NULL; column = column->next) {
    renderer = gtk_cell_renderer_text_new();
    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1,
    - purple_notify_searchresults_column_get_title(results, i-1),
    - renderer, "text", i, NULL);
    + column->data, renderer, "text", i, NULL);
    + i++;
    }
    for (i = 0; i < g_list_length(results->buttons); i++) {
    --- a/pidgin/gtknotify.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtknotify.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtknotify.h GTK+ Notification API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkplugin.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkplugin.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkplugin.c GTK+ Plugins support
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkplugin.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkplugin.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkplugin.h GTK+ Plugin API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkpluginpref.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkpluginpref.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkpluginpref.c GTK+ Plugin preferences
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkpluginpref.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkpluginpref.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkpluginpref.h GTK+ Plugin Preferences
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkpounce.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkpounce.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkpounce.c GTK+ Buddy Pounce API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkpounce.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkpounce.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkpounce.h GTK+ Buddy Pounce API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkprefs.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkprefs.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkprefs.c GTK+ Preferences
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkprefs.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkprefs.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkprefs.h GTK+ Preferences
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkprivacy.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkprivacy.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkprivacy.c GTK+ Privacy UI
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkprivacy.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkprivacy.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkprivacy.h GTK+ Privacy UI
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkrequest.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkrequest.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkrequest.c GTK+ Request API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    @@ -998,7 +999,6 @@
    /* Create the tree view */
    treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
    - gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
    sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
    --- a/pidgin/gtkrequest.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkrequest.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkrequest.h GTK+ Request API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkroomlist.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkroomlist.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkroomlist.c GTK+ Room List UI
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkroomlist.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkroomlist.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkroomlist.h GTK+ Room List UI
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtksavedstatuses.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtksavedstatuses.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtksavedstatus.c GTK+ Saved Status Editor UI
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtksavedstatuses.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtksavedstatuses.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtksavedstatuses.h GTK+ Saved Status Editor UI
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkscrollbook.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkscrollbook.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file gtkscrollbook.c GTK+ Scrolling notebook widget
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkscrollbook.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkscrollbook.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file gtkscrollbook GTK+ Scrolling notebook Widget
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtksession.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtksession.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file gtksession.c X Windows session management API
    * @ingroup pidgin
    - *
    - * Pidgin is the legal property of its developers, whose names are too numerous
    + */
    +
    +/* Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    * source distribution.
    *
    @@ -35,6 +36,7 @@
    #include <gdk/gdkx.h>
    #include <unistd.h>
    #include <fcntl.h>
    +#include <gdk/gdk.h>
    #define ERROR_LENGTH 512
    @@ -140,7 +142,7 @@
    /* my magic utility function */
    static gchar **session_make_command(gchar *client_id, gchar *config_dir) {
    - gint i = 2;
    + gint i = 4;
    gint j = 0;
    gchar **ret;
    @@ -160,6 +162,9 @@
    ret[j++] = g_strdup(config_dir);
    }
    + ret[j++] = g_strdup("--display");
    + ret[j++] = g_strdup((gchar *)gdk_display_get_name(gdk_display_get_default()));
    +
    ret[j++] = NULL;
    return ret;
    --- a/pidgin/gtksession.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtksession.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtksession.h X Windows session management API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtksound.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtksound.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file gtksound.c GTK+ Sound
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtksound.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtksound.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtksound.h GTK+ Sound API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkstatusbox.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkstatusbox.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file gtkstatusbox.c GTK+ Status Selection Widget
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkstatusbox.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkstatusbox.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /*
    * @file gtkstatusbox.c GTK+ Status Selection Widget
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkthemes.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkthemes.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkthemes.h GTK+ Smiley Theme API
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkutils.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkutils.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkutils.c GTK+ utility functions
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkutils.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkutils.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file gtkutils.h GTK+ utility functions
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/gtkwhiteboard.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/gtkwhiteboard.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,7 +1,8 @@
    /**
    * @file gtkwhiteboard.h The PidginWhiteboard frontend object
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/pidgin.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/pidgin.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file pidgin.h UI definitions and includes
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    @@ -26,12 +27,12 @@
    #ifndef _PIDGIN_H_
    #define _PIDGIN_H_
    +#include <gtk/gtk.h>
    +
    #ifdef GDK_WINDOWING_X11
    # include <gdk/gdkx.h>
    #endif
    -#include <gtk/gtk.h>
    -
    #ifdef _WIN32
    # include "gtkwin32dep.h"
    #endif
    --- a/pidgin/pidginstock.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/pidginstock.c Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file pidginstock.c GTK+ Stock resources
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/pidginstock.h Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/pidginstock.h Mon Sep 17 17:51:22 2007 +0000
    @@ -1,8 +1,9 @@
    /**
    * @file pidginstock.h GTK+ Stock resources
    * @ingroup pidgin
    - *
    - * pidgin
    + */
    +
    +/* pidgin
    *
    * Pidgin is the legal property of its developers, whose names are too numerous
    * to list here. Please refer to the COPYRIGHT file distributed with this
    --- a/pidgin/plugins/history.c Mon Sep 17 16:54:45 2007 +0000
    +++ b/pidgin/plugins/history.c Mon Sep 17 17:51:22 2007 +0000
    @@ -45,6 +45,9 @@
    convtype = purple_conversation_get_type(c);
    gtkconv = PIDGIN_CONVERSATION(c);
    + if (gtkconv == NULL)
    + return;
    +
    if (convtype == PURPLE_CONV_TYPE_IM && g_list_length(gtkconv->convs) < 2)
    {
    GSList *buddies;
    @@ -163,6 +166,7 @@
    purple_signal_connect(purple_conversations_get_handle(),
    "conversation-created",
    plugin, PURPLE_CALLBACK(historize), NULL);
    + /* XXX: Do we want to listen to pidgin's "conversation-displayed" signal? */
    purple_prefs_connect_callback(plugin, "/purple/logging/log_ims",
    history_prefs_cb, plugin);