summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Sales de Andrade <quantum.analyst@gmail.com>2012-07-22 19:57:09 -0400
committerElliott Sales de Andrade <quantum.analyst@gmail.com>2012-07-22 19:57:09 -0400
commitc2d77f594c2223750f9f99463405d0af116e7817 (patch)
tree96b1dedca6ea14d136d4f11fb143561ec8ee35dc
parent04d2d08a1f3390a1c07db7136e7f4cc1d5e25f7b (diff)
parentca4fd42d3b6aa5c0943b10088d9002f32ccee7d3 (diff)
downloadpidgin-c2d77f594c2223750f9f99463405d0af116e7817.tar.gz
Merge with release-2.x.y.
-rw-r--r--COPYRIGHT3
-rw-r--r--ChangeLog49
-rw-r--r--ChangeLog.API248
-rw-r--r--Makefile.am2
-rw-r--r--config.h.mingw3
-rw-r--r--configure.ac134
-rw-r--r--doc/account-signals.dox10
-rw-r--r--doc/blist-signals.dox2
-rw-r--r--doc/connection-signals.dox1
-rw-r--r--doc/conversation-signals.dox6
-rw-r--r--doc/gtkconv-signals.dox2
-rw-r--r--doc/notify-signals.dox2
-rw-r--r--finch/Makefile.am2
-rw-r--r--finch/finch.c35
-rw-r--r--finch/gntaccount.h2
-rw-r--r--finch/gntblist.c111
-rw-r--r--finch/gntblist.h7
-rw-r--r--finch/gntconn.c1
-rw-r--r--finch/gntconv.c108
-rw-r--r--finch/gntconv.h3
-rw-r--r--finch/gntft.c27
-rw-r--r--finch/gntmenuutil.c79
-rw-r--r--finch/gntmenuutil.h49
-rw-r--r--finch/gntnotify.c19
-rw-r--r--finch/gntprefs.c8
-rw-r--r--finch/gntrequest.c56
-rw-r--r--finch/gntrequest.h1
-rw-r--r--finch/gntroomlist.c7
-rw-r--r--finch/gntsound.c4
-rw-r--r--finch/gntsound.h12
-rw-r--r--finch/libgnt/gntfilesel.h2
-rw-r--r--finch/libgnt/gntprogressbar.h2
-rw-r--r--finch/libgnt/gnttree.h2
-rw-r--r--finch/libgnt/gntwidget.h6
-rw-r--r--finch/libgnt/gntwm.h2
-rw-r--r--finch/plugins/gntgf.c4
-rw-r--r--finch/plugins/gnttinyurl.c4
-rw-r--r--finch/plugins/grouping.c2
-rw-r--r--finch/plugins/lastlog.c2
-rw-r--r--gaim-uninstalled.pc.in14
-rw-r--r--gaim.pc.in14
-rw-r--r--libpurple/Makefile.am7
-rw-r--r--libpurple/account.c187
-rw-r--r--libpurple/account.h84
-rw-r--r--libpurple/accountopt.c45
-rw-r--r--libpurple/accountopt.h58
-rw-r--r--libpurple/blist.c81
-rw-r--r--libpurple/blist.h113
-rw-r--r--libpurple/buddyicon.c221
-rw-r--r--libpurple/buddyicon.h46
-rw-r--r--libpurple/certificate.c284
-rw-r--r--libpurple/certificate.h86
-rw-r--r--libpurple/cipher.h4
-rw-r--r--libpurple/circbuffer.h10
-rw-r--r--libpurple/cmds.c5
-rw-r--r--libpurple/cmds.h19
-rw-r--r--libpurple/connection.c74
-rw-r--r--libpurple/connection.h164
-rw-r--r--libpurple/conversation.c251
-rw-r--r--libpurple/conversation.h255
-rw-r--r--libpurple/core.c380
-rw-r--r--libpurple/core.h23
-rw-r--r--libpurple/dbus-analyze-functions.py10
-rw-r--r--libpurple/dbus-bindings.h20
-rw-r--r--libpurple/dbus-server.c22
-rw-r--r--libpurple/dbus-server.h2
-rw-r--r--libpurple/dbus-useful.c2
-rw-r--r--libpurple/dbus-useful.h6
-rw-r--r--libpurple/debug.c7
-rw-r--r--libpurple/debug.h16
-rw-r--r--libpurple/dnsquery.c13
-rw-r--r--libpurple/dnsquery.h31
-rw-r--r--libpurple/dnssrv.c42
-rw-r--r--libpurple/dnssrv.h102
-rw-r--r--libpurple/eventloop.h13
-rw-r--r--libpurple/example/nullclient.c2
-rw-r--r--libpurple/ft.c94
-rw-r--r--libpurple/ft.h138
-rw-r--r--libpurple/gaim-compat.h2317
-rw-r--r--libpurple/idle.h8
-rw-r--r--libpurple/imgstore.h11
-rw-r--r--libpurple/internal.h12
-rw-r--r--libpurple/log.c2
-rw-r--r--libpurple/log.h10
-rw-r--r--libpurple/media-gst.h26
-rw-r--r--libpurple/media.h74
-rw-r--r--libpurple/media/backend-fs2.h2
-rw-r--r--libpurple/media/backend-iface.h20
-rw-r--r--libpurple/media/candidate.h34
-rw-r--r--libpurple/media/codec.h28
-rw-r--r--libpurple/media/enum-types.h12
-rw-r--r--libpurple/mediamanager.h38
-rw-r--r--libpurple/mime.h10
-rw-r--r--libpurple/nat-pmp.h20
-rw-r--r--libpurple/network.c44
-rw-r--r--libpurple/network.h108
-rw-r--r--libpurple/notify.c101
-rw-r--r--libpurple/notify.h185
-rw-r--r--libpurple/ntlm.h8
-rw-r--r--libpurple/plugin.c61
-rw-r--r--libpurple/plugin.h78
-rw-r--r--libpurple/pluginpref.h8
-rw-r--r--libpurple/plugins/autoaccept.c16
-rw-r--r--libpurple/plugins/log_reader.c32
-rw-r--r--libpurple/plugins/offlinemsg.c8
-rw-r--r--libpurple/plugins/perl/common/Account.xs12
-rw-r--r--libpurple/plugins/perl/common/BuddyList.xs13
-rw-r--r--libpurple/plugins/perl/common/Certificate.xs6
-rw-r--r--libpurple/plugins/perl/common/Connection.xs9
-rw-r--r--libpurple/plugins/perl/common/Conversation.xs20
-rw-r--r--libpurple/plugins/perl/common/FT.xs2
-rw-r--r--libpurple/plugins/perl/common/Network.xs8
-rw-r--r--libpurple/plugins/perl/common/Notify.xs6
-rw-r--r--libpurple/plugins/perl/common/Request.xs6
-rw-r--r--libpurple/plugins/perl/common/SSLConn.xs7
-rw-r--r--libpurple/plugins/perl/common/Status.xs50
-rw-r--r--libpurple/plugins/perl/common/Util.xs13
-rw-r--r--libpurple/plugins/ssl/Makefile.am24
-rw-r--r--libpurple/plugins/ssl/ssl-gnutls.c84
-rw-r--r--libpurple/plugins/ssl/ssl-nss.c76
-rw-r--r--libpurple/plugins/statenotify.c4
-rw-r--r--libpurple/plugins/tcl/tcl_cmds.c16
-rw-r--r--libpurple/pounce.c31
-rw-r--r--libpurple/pounce.h36
-rw-r--r--libpurple/prefs.c1
-rw-r--r--libpurple/prefs.h12
-rw-r--r--libpurple/privacy.c22
-rw-r--r--libpurple/privacy.h12
-rw-r--r--libpurple/protocols/Makefile.am2
-rw-r--r--libpurple/protocols/bonjour/bonjour.c84
-rw-r--r--libpurple/protocols/bonjour/bonjour_ft.c136
-rw-r--r--libpurple/protocols/bonjour/jabber.c27
-rw-r--r--libpurple/protocols/bonjour/mdns_avahi.c2
-rw-r--r--libpurple/protocols/bonjour/mdns_common.c2
-rw-r--r--libpurple/protocols/bonjour/mdns_types.h2
-rw-r--r--libpurple/protocols/bonjour/mdns_win32.c10
-rw-r--r--libpurple/protocols/gg/Makefile.am2
-rw-r--r--libpurple/protocols/gg/Makefile.mingw3
-rw-r--r--libpurple/protocols/gg/buddylist.c4
-rw-r--r--libpurple/protocols/gg/confer.c8
-rw-r--r--libpurple/protocols/gg/gg-utils.c13
-rw-r--r--libpurple/protocols/gg/gg-utils.h15
-rw-r--r--libpurple/protocols/gg/gg.c578
-rw-r--r--libpurple/protocols/gg/gg.h2
-rw-r--r--libpurple/protocols/gg/lib/common.c18
-rw-r--r--libpurple/protocols/gg/lib/compat.h15
-rw-r--r--libpurple/protocols/gg/lib/dcc.c16
-rw-r--r--libpurple/protocols/gg/lib/dcc7.c14
-rw-r--r--libpurple/protocols/gg/lib/events.c7
-rw-r--r--libpurple/protocols/gg/lib/handlers.c17
-rw-r--r--libpurple/protocols/gg/lib/http.c10
-rw-r--r--libpurple/protocols/gg/lib/libgadu-config.h59
-rw-r--r--libpurple/protocols/gg/lib/libgadu.c21
-rw-r--r--libpurple/protocols/gg/lib/libgadu.h32
-rw-r--r--libpurple/protocols/gg/lib/pubdir.c3
-rw-r--r--libpurple/protocols/gg/lib/pubdir50.c1
-rw-r--r--libpurple/protocols/gg/lib/resolver.c357
-rw-r--r--libpurple/protocols/gg/lib/resolver.h4
-rw-r--r--libpurple/protocols/gg/search.c2
-rw-r--r--libpurple/protocols/gg/win32-resolver.c322
-rw-r--r--libpurple/protocols/gg/win32-resolver.h46
-rw-r--r--libpurple/protocols/irc/cmds.c2
-rw-r--r--libpurple/protocols/irc/dcc_send.c59
-rw-r--r--libpurple/protocols/irc/irc.c94
-rw-r--r--libpurple/protocols/irc/irc.h1
-rw-r--r--libpurple/protocols/irc/msgs.c36
-rw-r--r--libpurple/protocols/irc/parse.c8
-rw-r--r--libpurple/protocols/jabber/Makefile.am10
-rw-r--r--libpurple/protocols/jabber/Makefile.mingw20
-rw-r--r--libpurple/protocols/jabber/adhoccommands.c5
-rw-r--r--libpurple/protocols/jabber/auth.c30
-rw-r--r--libpurple/protocols/jabber/auth_cyrus.c15
-rw-r--r--libpurple/protocols/jabber/auth_plain.c2
-rw-r--r--libpurple/protocols/jabber/bosh.c20
-rw-r--r--libpurple/protocols/jabber/buddy.c75
-rw-r--r--libpurple/protocols/jabber/caps.c20
-rw-r--r--libpurple/protocols/jabber/chat.c25
-rw-r--r--libpurple/protocols/jabber/disco.c12
-rw-r--r--libpurple/protocols/jabber/google/gmail.c2
-rw-r--r--libpurple/protocols/jabber/google/google_presence.c4
-rw-r--r--libpurple/protocols/jabber/google/jingleinfo.c2
-rw-r--r--libpurple/protocols/jabber/google/relay.c2
-rw-r--r--libpurple/protocols/jabber/jabber.c223
-rw-r--r--libpurple/protocols/jabber/jabber.h1
-rw-r--r--libpurple/protocols/jabber/jutil.c9
-rw-r--r--libpurple/protocols/jabber/libfacebook.c326
-rw-r--r--libpurple/protocols/jabber/libgtalk.c334
-rw-r--r--libpurple/protocols/jabber/libxmpp.c8
-rw-r--r--libpurple/protocols/jabber/message.c10
-rw-r--r--libpurple/protocols/jabber/oob.c36
-rw-r--r--libpurple/protocols/jabber/parser.c8
-rw-r--r--libpurple/protocols/jabber/presence.c11
-rw-r--r--libpurple/protocols/jabber/presence.h1
-rw-r--r--libpurple/protocols/jabber/roster.c26
-rw-r--r--libpurple/protocols/jabber/roster.h2
-rw-r--r--libpurple/protocols/jabber/si.c221
-rw-r--r--libpurple/protocols/jabber/useravatar.c2
-rw-r--r--libpurple/protocols/jabber/usermood.c69
-rw-r--r--libpurple/protocols/jabber/usermood.h17
-rw-r--r--libpurple/protocols/jabber/usertune.c6
-rw-r--r--libpurple/protocols/msn/contact.c31
-rw-r--r--libpurple/protocols/msn/error.c2
-rw-r--r--libpurple/protocols/msn/httpconn.c6
-rw-r--r--libpurple/protocols/msn/msg.c25
-rw-r--r--libpurple/protocols/msn/msn.c151
-rw-r--r--libpurple/protocols/msn/nexus.c2
-rw-r--r--libpurple/protocols/msn/notification.c12
-rw-r--r--libpurple/protocols/msn/object.c11
-rw-r--r--libpurple/protocols/msn/object.h5
-rw-r--r--libpurple/protocols/msn/oim.c2
-rw-r--r--libpurple/protocols/msn/sbconn.c2
-rw-r--r--libpurple/protocols/msn/servconn.c6
-rw-r--r--libpurple/protocols/msn/session.c4
-rw-r--r--libpurple/protocols/msn/slp.c14
-rw-r--r--libpurple/protocols/msn/slpcall.c17
-rw-r--r--libpurple/protocols/msn/slplink.c2
-rw-r--r--libpurple/protocols/msn/slpmsg.c2
-rw-r--r--libpurple/protocols/msn/slpmsg.h2
-rw-r--r--libpurple/protocols/msn/switchboard.c7
-rw-r--r--libpurple/protocols/msn/user.c10
-rw-r--r--libpurple/protocols/msn/userlist.c4
-rw-r--r--libpurple/protocols/msn/xfer.c49
-rw-r--r--libpurple/protocols/msn/xfer.h6
-rw-r--r--libpurple/protocols/mxit/actions.c37
-rw-r--r--libpurple/protocols/mxit/cipher.c197
-rw-r--r--libpurple/protocols/mxit/cipher.h4
-rw-r--r--libpurple/protocols/mxit/filexfer.c39
-rw-r--r--libpurple/protocols/mxit/formcmds.c42
-rw-r--r--libpurple/protocols/mxit/http.c2
-rw-r--r--libpurple/protocols/mxit/login.c102
-rw-r--r--libpurple/protocols/mxit/markup.c129
-rw-r--r--libpurple/protocols/mxit/markup.h2
-rw-r--r--libpurple/protocols/mxit/multimx.c18
-rw-r--r--libpurple/protocols/mxit/mxit.c115
-rw-r--r--libpurple/protocols/mxit/mxit.h3
-rw-r--r--libpurple/protocols/mxit/profile.c72
-rw-r--r--libpurple/protocols/mxit/profile.h1
-rw-r--r--libpurple/protocols/mxit/protocol.c117
-rw-r--r--libpurple/protocols/mxit/protocol.h11
-rw-r--r--libpurple/protocols/mxit/roster.c58
-rw-r--r--libpurple/protocols/mxit/roster.h8
-rw-r--r--libpurple/protocols/mxit/splashscreen.c5
-rw-r--r--libpurple/protocols/mxit/voicevideo.c6
-rw-r--r--libpurple/protocols/myspace/myspace.c102
-rw-r--r--libpurple/protocols/myspace/session.h1
-rw-r--r--libpurple/protocols/myspace/user.c49
-rw-r--r--libpurple/protocols/myspace/zap.c6
-rw-r--r--libpurple/protocols/novell/novell.c198
-rw-r--r--libpurple/protocols/null/nullprpl.c188
-rw-r--r--libpurple/protocols/oscar/authorization.c2
-rw-r--r--libpurple/protocols/oscar/clientlogin.c40
-rw-r--r--libpurple/protocols/oscar/family_auth.c31
-rw-r--r--libpurple/protocols/oscar/family_bart.c6
-rw-r--r--libpurple/protocols/oscar/family_feedbag.c371
-rw-r--r--libpurple/protocols/oscar/family_icbm.c15
-rw-r--r--libpurple/protocols/oscar/family_locate.c2
-rw-r--r--libpurple/protocols/oscar/flap_connection.c6
-rw-r--r--libpurple/protocols/oscar/libaim.c9
-rw-r--r--libpurple/protocols/oscar/libicq.c10
-rw-r--r--libpurple/protocols/oscar/odc.c4
-rw-r--r--libpurple/protocols/oscar/oft.c40
-rw-r--r--libpurple/protocols/oscar/oscar.c208
-rw-r--r--libpurple/protocols/oscar/oscar.h37
-rw-r--r--libpurple/protocols/oscar/oscar_data.c12
-rw-r--r--libpurple/protocols/oscar/peer.c10
-rw-r--r--libpurple/protocols/oscar/userinfo.c97
-rw-r--r--libpurple/protocols/oscar/visibility.c4
-rw-r--r--libpurple/protocols/sametime/sametime.c208
-rw-r--r--libpurple/protocols/silc/buddy.c74
-rw-r--r--libpurple/protocols/silc/chat.c43
-rw-r--r--libpurple/protocols/silc/ft.c33
-rw-r--r--libpurple/protocols/silc/ops.c128
-rw-r--r--libpurple/protocols/silc/pk.c2
-rw-r--r--libpurple/protocols/silc/silc.c157
-rw-r--r--libpurple/protocols/silc/silcpurple.h2
-rw-r--r--libpurple/protocols/silc/util.c14
-rw-r--r--libpurple/protocols/silc/wb.c73
-rw-r--r--libpurple/protocols/silc10/Makefile.am36
-rw-r--r--libpurple/protocols/silc10/Makefile.mingw93
-rw-r--r--libpurple/protocols/silc10/README31
-rw-r--r--libpurple/protocols/silc10/TODO8
-rw-r--r--libpurple/protocols/silc10/buddy.c1748
-rw-r--r--libpurple/protocols/silc10/chat.c1456
-rw-r--r--libpurple/protocols/silc10/ft.c412
-rw-r--r--libpurple/protocols/silc10/ops.c2063
-rw-r--r--libpurple/protocols/silc10/pk.c274
-rw-r--r--libpurple/protocols/silc10/silc.c1965
-rw-r--r--libpurple/protocols/silc10/silcpurple.h173
-rw-r--r--libpurple/protocols/silc10/util.c776
-rw-r--r--libpurple/protocols/silc10/wb.c520
-rw-r--r--libpurple/protocols/silc10/wb.h49
-rw-r--r--libpurple/protocols/simple/simple.c97
-rw-r--r--libpurple/protocols/yahoo/libyahoo.c9
-rw-r--r--libpurple/protocols/yahoo/libyahoojp.c7
-rw-r--r--libpurple/protocols/yahoo/libymsg.c281
-rw-r--r--libpurple/protocols/yahoo/libymsg.h3
-rw-r--r--libpurple/protocols/yahoo/util.c9
-rw-r--r--libpurple/protocols/yahoo/yahoo_aliases.c22
-rw-r--r--libpurple/protocols/yahoo/yahoo_doodle.c59
-rw-r--r--libpurple/protocols/yahoo/yahoo_filexfer.c289
-rw-r--r--libpurple/protocols/yahoo/yahoo_friend.c12
-rw-r--r--libpurple/protocols/yahoo/yahoo_packet.c2
-rw-r--r--libpurple/protocols/yahoo/yahoo_picture.c30
-rw-r--r--libpurple/protocols/yahoo/yahoo_profile.c25
-rw-r--r--libpurple/protocols/yahoo/yahoochat.c77
-rw-r--r--libpurple/protocols/yahoo/ycht.c14
-rw-r--r--libpurple/protocols/zephyr/ZRetSubs.c5
-rw-r--r--libpurple/protocols/zephyr/zephyr.c160
-rw-r--r--libpurple/proxy.c30
-rw-r--r--libpurple/proxy.h49
-rw-r--r--libpurple/prpl.c19
-rw-r--r--libpurple/prpl.h146
-rw-r--r--libpurple/purple-3-uninstalled.pc.in (renamed from libpurple/purple-2-uninstalled.pc.in)0
-rw-r--r--libpurple/purple-3.pc.in (renamed from libpurple/purple-2.pc.in)2
-rw-r--r--libpurple/purple-uninstalled.pc.in19
-rw-r--r--libpurple/purple.h.in1
-rw-r--r--libpurple/purple.pc.in16
-rw-r--r--libpurple/request.c202
-rw-r--r--libpurple/request.h274
-rw-r--r--libpurple/roomlist.c84
-rw-r--r--libpurple/roomlist.h117
-rw-r--r--libpurple/savedstatuses.c3
-rw-r--r--libpurple/savedstatuses.h9
-rw-r--r--libpurple/server.c42
-rw-r--r--libpurple/server.h35
-rw-r--r--libpurple/signals.h9
-rw-r--r--libpurple/smiley.h9
-rw-r--r--libpurple/sound-theme-loader.c12
-rw-r--r--libpurple/sound-theme.c6
-rw-r--r--libpurple/sound-theme.h1
-rw-r--r--libpurple/sound.h10
-rw-r--r--libpurple/sslconn.c9
-rw-r--r--libpurple/sslconn.h33
-rw-r--r--libpurple/status.c294
-rw-r--r--libpurple/status.h160
-rw-r--r--libpurple/stringref.h10
-rw-r--r--libpurple/stun.c8
-rw-r--r--libpurple/stun.h10
-rw-r--r--libpurple/tests/test_xmlnode.c98
-rw-r--r--libpurple/theme-loader.c34
-rw-r--r--libpurple/theme-loader.h16
-rw-r--r--libpurple/theme-manager.c64
-rw-r--r--libpurple/theme.c14
-rw-r--r--libpurple/theme.h1
-rw-r--r--libpurple/upnp.c8
-rw-r--r--libpurple/upnp.h8
-rw-r--r--libpurple/util.c507
-rw-r--r--libpurple/util.h239
-rw-r--r--libpurple/value.c38
-rw-r--r--libpurple/value.h45
-rw-r--r--libpurple/version.h.in6
-rw-r--r--libpurple/whiteboard.c86
-rw-r--r--libpurple/whiteboard.h115
-rw-r--r--libpurple/win32/libc_interface.c18
-rw-r--r--libpurple/win32/libc_interface.h2
-rw-r--r--libpurple/win32/libc_internal.h3
-rw-r--r--libpurple/xmlnode.c130
-rw-r--r--libpurple/xmlnode.h94
-rw-r--r--pidgin/Makefile.am29
-rw-r--r--pidgin/Makefile.mingw7
-rw-r--r--pidgin/gtkaccount.c117
-rw-r--r--pidgin/gtkaccount.h4
-rw-r--r--pidgin/gtkblist-theme-loader.c12
-rw-r--r--pidgin/gtkblist-theme.c79
-rw-r--r--pidgin/gtkblist-theme.h33
-rw-r--r--pidgin/gtkblist.c1024
-rw-r--r--pidgin/gtkblist.h40
-rw-r--r--pidgin/gtkcellrendererexpander.c5
-rw-r--r--pidgin/gtkcellrendererexpander.h12
-rw-r--r--pidgin/gtkcertmgr.c24
-rw-r--r--pidgin/gtkcertmgr.h4
-rw-r--r--pidgin/gtkconn.c9
-rw-r--r--pidgin/gtkconn.h4
-rw-r--r--pidgin/gtkconv-theme-loader.c294
-rw-r--r--pidgin/gtkconv-theme-loader.h72
-rw-r--r--pidgin/gtkconv-theme.c751
-rw-r--r--pidgin/gtkconv-theme.h196
-rw-r--r--pidgin/gtkconv.c1869
-rw-r--r--pidgin/gtkconv.h71
-rw-r--r--pidgin/gtkconvwin.h55
-rw-r--r--pidgin/gtkdebug.c701
-rw-r--r--pidgin/gtkdebug.h4
-rw-r--r--pidgin/gtkdialogs.c451
-rw-r--r--pidgin/gtkdialogs.h22
-rw-r--r--pidgin/gtkdnd-hints.c9
-rw-r--r--pidgin/gtkdnd-hints.h4
-rw-r--r--pidgin/gtkdocklet-gtk.c296
-rw-r--r--pidgin/gtkdocklet.c381
-rw-r--r--pidgin/gtkdocklet.h24
-rw-r--r--pidgin/gtkeventloop.h4
-rw-r--r--pidgin/gtkft.c56
-rw-r--r--pidgin/gtkft.h4
-rw-r--r--pidgin/gtkgaim-compat.h412
-rw-r--r--pidgin/gtkicon-theme-loader.c11
-rw-r--r--pidgin/gtkicon-theme.c7
-rw-r--r--pidgin/gtkicon-theme.h1
-rw-r--r--pidgin/gtkidle.c6
-rw-r--r--pidgin/gtkidle.h4
-rw-r--r--pidgin/gtkimhtml.c418
-rw-r--r--pidgin/gtkimhtml.h162
-rw-r--r--pidgin/gtkimhtmltoolbar.c55
-rw-r--r--pidgin/gtkimhtmltoolbar.h16
-rw-r--r--pidgin/gtklog.c46
-rw-r--r--pidgin/gtklog.h5
-rw-r--r--pidgin/gtkmain.c53
-rw-r--r--pidgin/gtkmedia.c14
-rw-r--r--pidgin/gtkmenutray.c20
-rw-r--r--pidgin/gtkmenutray.h2
-rw-r--r--pidgin/gtknotify.c77
-rw-r--r--pidgin/gtknotify.h4
-rw-r--r--pidgin/gtkplugin.h4
-rw-r--r--pidgin/gtkpluginpref.h8
-rw-r--r--pidgin/gtkpounce.c23
-rw-r--r--pidgin/gtkpounce.h4
-rw-r--r--pidgin/gtkprefs.c442
-rw-r--r--pidgin/gtkprefs.h6
-rw-r--r--pidgin/gtkprivacy.c10
-rw-r--r--pidgin/gtkprivacy.h4
-rw-r--r--pidgin/gtkrequest.c134
-rw-r--r--pidgin/gtkrequest.h4
-rw-r--r--pidgin/gtkroomlist.c102
-rw-r--r--pidgin/gtkroomlist.h4
-rw-r--r--pidgin/gtksavedstatuses.c4
-rw-r--r--pidgin/gtksavedstatuses.h4
-rw-r--r--pidgin/gtkscrollbook.c2
-rw-r--r--pidgin/gtksession.h4
-rw-r--r--pidgin/gtksmiley.c10
-rw-r--r--pidgin/gtksmiley.h7
-rw-r--r--pidgin/gtksound.c6
-rw-r--r--pidgin/gtksound.h6
-rw-r--r--pidgin/gtksourceundomanager.h4
-rw-r--r--pidgin/gtkstatusbox.c20
-rw-r--r--pidgin/gtkstatusbox.h4
-rw-r--r--pidgin/gtkthemes.c7
-rw-r--r--pidgin/gtkthemes.h11
-rw-r--r--pidgin/gtkutils.c481
-rw-r--r--pidgin/gtkutils.h148
-rw-r--r--pidgin/gtkwebview.c1131
-rw-r--r--pidgin/gtkwebview.h460
-rw-r--r--pidgin/gtkwebviewtoolbar.c1617
-rw-r--r--pidgin/gtkwebviewtoolbar.h96
-rw-r--r--pidgin/gtkwhiteboard.c32
-rw-r--r--pidgin/gtkwhiteboard.h8
-rw-r--r--pidgin/pidgin-3-uninstalled.pc.in (renamed from pidgin/pidgin-2-uninstalled.pc.in)2
-rw-r--r--pidgin/pidgin-3.pc.in (renamed from pidgin/pidgin-2.pc.in)4
-rw-r--r--pidgin/pidgin-uninstalled.pc.in18
-rw-r--r--pidgin/pidgin.pc.in16
-rw-r--r--pidgin/pidgintooltip.h12
-rw-r--r--pidgin/plugins/Makefile.am19
-rw-r--r--pidgin/plugins/contact_priority.c7
-rw-r--r--pidgin/plugins/gestures/gestures.c58
-rw-r--r--pidgin/plugins/gevolution/gevo-util.c2
-rw-r--r--pidgin/plugins/history.c38
-rw-r--r--pidgin/plugins/markerline.c120
-rw-r--r--pidgin/plugins/musicmessaging/musicmessaging.c11
-rw-r--r--pidgin/plugins/notify.c18
-rw-r--r--pidgin/plugins/perl/common/GtkBlist.xs5
-rw-r--r--pidgin/plugins/perl/common/GtkDialogs.xs4
-rw-r--r--pidgin/plugins/perl/common/GtkIMHtml.xs33
-rw-r--r--pidgin/plugins/relnot.c2
-rw-r--r--pidgin/plugins/themeedit.c2
-rw-r--r--pidgin/plugins/ticker/gtkticker.c31
-rw-r--r--pidgin/plugins/vvconfig.c8
-rw-r--r--pidgin/plugins/webkit.c197
-rw-r--r--pidgin/plugins/xmppconsole.c287
-rw-r--r--pidgin/smileyparser.c169
-rw-r--r--pidgin/smileyparser.h29
-rw-r--r--pidgin/themes/Contents/Info.plist16
-rw-r--r--pidgin/themes/Contents/Resources/Content.html6
-rw-r--r--pidgin/themes/Contents/Resources/Status.html5
-rw-r--r--pidgin/themes/Contents/Resources/Variants/Default.css2
-rw-r--r--pidgin/themes/Contents/Resources/Variants/No-Timestamps.css8
-rw-r--r--pidgin/themes/Contents/Resources/main.css66
-rw-r--r--pidgin/themes/Makefile.am19
-rw-r--r--pidgin/themes/Template.html331
-rw-r--r--pidgin/win32/untar.h2
-rw-r--r--po/POTFILES.in8
-rw-r--r--po/de.po1323
478 files changed, 19608 insertions, 24724 deletions
diff --git a/COPYRIGHT b/COPYRIGHT
index df9c01f087..bdd2b4a4ea 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -24,6 +24,7 @@ Thijs Alkemade
Manuel Amador
Matt Amato
Josef Andrysek
+Flavius Anton
Geoffrey Antos
Daniel Atallah
Paul Aurich
@@ -108,6 +109,7 @@ Patrick Cheung
Ka-Hing Cheung
Sadrul Habib Chowdhury
Brian Chu
+Howard Chu
Arturo Cisneros, Jr.
Vincas Ciziunas
Jonathan Clark
@@ -430,6 +432,7 @@ Etan Reisner
David Reiss
Luoh Ren-Shan
Noa Resare
+Tim Retout
Daniele Ricci
Kristian Rietveld
Pekka Riikonen
diff --git a/ChangeLog b/ChangeLog
index 1d9bee670f..71c93f6da4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,51 @@
Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
-version 2.10.7:
- Alien hatchery:
- * No changes
+version 3.0.0 (??/??/????):
+ Finch:
+ * Support the conversation-extended signal for extending the
+ conversation menu. (Howard Chu) (#14818)
+
+ AIM and ICQ:
+ * Make buddy list management code more efficient. (Oliver) (#4816)
+
+ Bonjour:
+ * Support file transfers up to ~9 EiB.
+
+ Gadu-Gadu:
+ * Possibility to require encryption. Also, using encryption when
+ available is default option now. (Tomasz Wasilczyk)
+ * Show local time for incoming messages. (Tomasz Wasilczyk) (#4579)
+ * Fixed password change dialog and problems with connecting to accounts
+ with non-ASCII passwords. (Tomasz Wasilczyk) (#14652)
+ * Option to show links from strangers. (Tomasz Wasilczyk) (#10591)
+ * Better handling of "invisible" and "chatty" statuses. (Tomasz
+ Wasilczyk) (#13836)
+
+ MSN:
+ * Fix file transfer with older Mac MSN clients.
+ * Support file transfers up to ~9 EiB.
+ * Fix buddies not going offline.
+
+ MXit:
+ * Remove all reference to Hidden Number.
+ * Fix decoding of font-size changes in the markup of received messages.
+ * Ignore new invites to join a GroupChat if you're already joined, or
+ still have a pending invite.
+ * The buddy's name was not centered vertically in the buddy-list if they
+ did not have a status-message or mood set.
+
+ XMPP:
+ * Strip element prefixes from XHTML-IM messages as they're presented
+ to the core (and UIs) as incoming messages (Thijs Alkemade).
+ (#14529)
+ * Support file transfers up to ~9 EiB.
+ * Invalid user moods can no longer be sent to the server.
+
+ Plugins:
+ * The Voice/Video Settings plugin supports using the sndio GStreamer
+ backends. (Brad Smith) (#14414)
+ * The Offline Message Emulation plugin now adds a note that the message
+ was an offline message. (Flavius Anton) (#2497)
MSN:
* Fix a crash when removing a user before its icon is loaded. (Mark
diff --git a/ChangeLog.API b/ChangeLog.API
index 22b24800b8..54b88ab60e 100644
--- a/ChangeLog.API
+++ b/ChangeLog.API
@@ -1,7 +1,251 @@
Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
-version 2.10.7:
- * No changes
+version 3.0.0 (??/??/????):
+ libpurple:
+ Added:
+ * pidgin_create_webview
+ * purple_account_is_disconnecting
+ * purple_account_get_ui_data
+ * purple_account_set_ui_data
+ * purple_account_register_completed
+ * purple_certificate_get_der_data
+ * purple_certificate_get_display_string
+ * purple_conv_chat_cb_get_alias
+ * purple_conv_chat_cb_get_flags
+ * purple_conv_chat_cb_is_buddy
+ * purple_conv_chat_cb_get_ui_data
+ * purple_conv_chat_cb_set_ui_data
+ * purple_connection_get_flags
+ * purple_connection_set_flags
+ * purple_connection_update_last_received
+ * purple_conversation_get_ui_data
+ * purple_conversation_set_ui_data
+ * purple_conversation_message_get_alias
+ * purple_conversation_message_get_conv
+ * purple_contact_get_contact_size
+ * purple_notify_searchresult_column_get_title
+ * purple_notify_searchresult_column_is_visible
+ * purple_notify_searchresult_column_set_visible
+ * purple_notify_user_info_prepend_pair_plaintext
+ * purple_menu_action_get_callback
+ * purple_menu_action_get_children
+ * purple_menu_action_get_data
+ * purple_menu_action_set_label
+ * purple_menu_action_set_data
+ * purple_menu_action_set_callback
+ * purple_menu_action_set_children
+ * purple_request_certificate
+ * purple_request_field_certificate_new
+ * purple_request_field_certificate_get_value
+ * purple_request_field_get_tooltip
+ * purple_request_field_group_get_fields_list
+ * purple_request_field_set_tooltip
+ * purple_request_fields_get_ui_data
+ * purple_request_fields_set_ui_data
+ * purple_roomlist_get_account
+ * purple_roomlist_get_proto_data
+ * purple_roomlist_get_ui_data
+ * purple_roomlist_room_get_expanded_once
+ * purple_roomlist_room_set_expanded_once
+ * purple_roomlist_set_proto_data
+ * purple_roomlist_set_ui_data
+ * purple_whiteboard_get_account
+ * purple_whiteboard_get_draw_list
+ * purple_whiteboard_set_draw_list
+ * purple_whiteboard_get_protocol_data
+ * purple_whiteboard_set_protocol_data
+ * purple_whiteboard_get_state
+ * purple_whiteboard_set_state
+ * purple_whiteboard_get_ui_data
+ * purple_whiteboard_set_ui_data
+ * purple_whiteboard_get_who
+ * purple_xfer_get_fd
+ * purple_xfer_get_protocol_data
+ * purple_xfer_get_ui_data
+ * purple_xfer_get_watcher
+ * purple_xfer_set_fd
+ * purple_xfer_set_local_port
+ * purple_xfer_set_protocol_data
+ * purple_xfer_set_status
+ * purple_xfer_set_ui_data
+ * purple_xfer_set_watcher
+ * Various WebKit-related functions in gtkwebview.h
+ * xmlnode_get_default_namespace
+ * xmlnode_strip_prefixes
+
+ Changed:
+ * purple_account_add_buddy now takes an invite message as the last
+ parameter
+ * purple_account_add_buddies now takes an invite message as the last
+ parameter
+ * purple_certificate_check_signature_chain now returns a list of failing
+ PurpleCertificate*s as the second parameter
+ * purple_connection_error now takes a PurpleConnectionError
+ as the second parameter
+ * purple_conversation_get_gc renamed to
+ purple_conversation_get_connection
+ * purple_dnsquery_a now takes a PurpleAccount as the first parameter
+ * purple_network_listen now takes the protocol family as the second
+ parameter
+ * purple_network_listen now takes a boolean indicating external port
+ mapping as the fourth parameter
+ * purple_network_listen_range now takes a boolean indicating external
+ port mapping as the fifth parameter
+ * purple_network_listen_range now takes the protocol family as the
+ third parameter
+ * purple_notify_user_info_add_pair renamed to
+ purple_notify_user_info_add_pair_html
+ * purple_notify_user_info_get_entries returns a GQueue instead of
+ a GList
+ * purple_notify_user_info_prepend_pair renamed to
+ purple_notify_user_info_prepend_pair_html
+ * purple_srv_resolve now takes a PurpleAccount as the first parameter
+ * purple_str_size_to_units now takes a goffset as the size parameter
+ * purple_txt_resolve now takes a PurpleAccount as the first parameter
+ * purple_util_fetch_url_request now takes a PurpleAccount as
+ the first parameter
+ * purple_util_fetch_url_request now takes a length as the eighth
+ parameter
+ * purple_util_fetch_url_len now takes a length as the fifth parameter
+ * purple_xfer_get_bytes_remaining now returns a goffset
+ * purple_xfer_get_bytes_sent now returns a goffset
+ * purple_xfer_get_size now returns a goffset
+ * purple_xfer_is_canceled renamed to purple_xfer_is_cancelled
+ * purple_xfer_set_bytes_sent now takes a goffset as the bytes_sent
+ parameter
+ * purple_xfer_set_size now takes a goffset as the size parameter
+ * PurpleConnectionUiOps.report_disconnect now passes a
+ PurpleConnectionError as the second parameter
+ * PurpleXfer.bytes_remaining is now a goffset
+ * PurpleXfer.bytes_sent is now a goffset
+ * PurpleXfer.size is now a goffset
+
+ Removed:
+ * _GntFileType
+ * _GntKeyPressMode
+ * _GntMouseEvent
+ * _GntParamFlags
+ * _GntProgressBarOrientation
+ * _GntTreeColumnFlag
+ * _GntWidgetFlags
+ * _PurpleCipherBatchMode
+ * _PurpleCipherCaps
+ * _PurpleCmdFlag
+ * _PurpleCmdPriority
+ * _PurpleCmdRet
+ * _PurpleCmdStatus
+ * _PurplePrefType
+ * _PurplePrivacyType
+ * _PurpleSoundEventID
+ * _XMLNodeType
+ * GtkIMHtml.clipboard_html_string
+ * GtkIMHtml.clipboard_text_string
+ * GtkIMHtmlFontDetail
+ * gtk_imhtml_animation_free
+ * gtk_imhtml_animation_new
+ * gtk_imhtml_image_add_to
+ * gtk_imhtml_image_free
+ * gtk_imhtml_image_new
+ * gtk_imhtml_image_scale
+ * pidgin_blist_update_account_error_state
+ * pidgin_check_if_dir
+ * PIDGIN_DIALOG
+ * pidgin_dialogs_alias_contact
+ * pidgin_set_custom_buddy_icon
+ * pidgin_setup_screenname_autocomplete
+ * PidginBuddyList.connection_errors
+ * PidginConversation.sg
+ * purple_account_add_buddies_with_invite
+ * purple_account_add_buddy_with_invite
+ * purple_blist_update_buddy_icon
+ * purple_buddy_get_local_alias
+ * purple_buddy_icons_has_custom_icon
+ * purple_buddy_icons_find_custom_icon
+ * purple_buddy_icons_set_custom_icon
+ * purple_certificate_check_signature_chain_with_failing. Use
+ purple_certificate_check_signature_chain, instead
+ * purple_certificate_display_x509. Use purple_request_certificate,
+ instead
+ * purple_connection_error_reason
+ * purple_connection_new
+ * purple_connection_new_unregister
+ * purple_connection_destroy
+ * purple_contact_set_alias
+ * purple_conv_chat_set_users
+ * purple_core_migrate
+ * purple_dnsquery_a_account
+ * purple_network_listen_family. Use purple_network_listen, instead.
+ * purple_network_listen_map_external
+ * purple_network_listen_range_family. Use purple_network_listen,
+ instead.
+ * purple_notify_searchresults_column_get_title
+ * purple_notify_searchresults_get_columns_count
+ * purple_notify_searchresults_get_rows_count
+ * purple_notify_searchresults_row_get
+ * purple_plugins_register_load_notify_cb
+ * purple_plugins_register_probe_notify_cb
+ * purple_plugins_register_unload_notify_cb
+ * purple_plugins_unregister_load_notify_cb
+ * purple_plugins_unregister_probe_notify_cb
+ * purple_plugins_unregister_unload_notify_cb
+ * purple_presence_add_status
+ * purple_presence_add_list
+ * purple_proxy_connect_socks5
+ * purple_request_field_list_add
+ * purple_srv_cancel
+ * purple_srv_resolve_account
+ * purple_ssl_connect_fd
+ * purple_status_set_attr_boolean
+ * purple_status_set_attr_int
+ * purple_status_set_attr_string
+ * purple_status_type_add_attr
+ * purple_status_type_add_attrs
+ * purple_status_type_add_attrs_vargs
+ * purple_status_type_get_primary_attr
+ * purple_status_type_set_primary_attr
+ * purple_strlcat
+ * purple_strlcpy
+ * purple_txt_cancel
+ * purple_txt_resolve_account
+ * purple_util_fetch_url_len. Use purple_util_fetch_url, instead.
+ * purple_util_fetch_url_request_len. Use
+ * purple_util_fetch_url_request, instead.
+ * purple_util_fetch_url_request_len_with_account. Use
+ purple_util_fetch_url_request, instead.
+ * PurpleConnectionUiOps.report_disconnect_reason
+ * PurplePluginProtocolInfo.add_buddy_with_invite
+ * PurplePluginProtocolInfo.add_buddies_with_invite
+ * PurplePluginProtocolInfo.get_cb_away
+ * serv_got_attention
+ * serv_send_attention
+ * struct _GtkIMHtmlAnimation
+ * struct _GtkIMHtmlFontDetail
+ * struct _GtkIMHtmlHr
+ * struct _GtkIMHtmlImage
+ * struct _GtkIMHtmlScalable
+ * struct _GtkSmileyTree
+ * struct _PidginChatPane
+ * struct _PidginImPane
+ * struct _PurpleAttentionType
+ * struct _PurpleConversation
+ * struct _PurpleConvChat
+ * struct _PurpleConvChatBuddy
+ * struct _PurpleConvIm
+ * struct _PurpleConvMessage
+ * struct _PurpleMenuAction
+ * struct _PurplePounce
+ * struct _PurpleProxyInfo
+ * struct _PurpleRequestField
+ * struct _PurpleRoomlist
+ * struct _PurpleRoomlistField
+ * struct _PurpleRoomlistRoom
+ * struct _PurpleWhiteboard
+ * struct PurpleAccountOption
+ * struct PurpleAccountUserSplit
+ * struct PurpleNotifySearchColumn
+ * wpurple_g_access
+ * xmlnode_set_attrib_with_namespace
+ * xmlnode_set_attrib_with_prefix
version 2.10.6:
* No changes
diff --git a/Makefile.am b/Makefile.am
index 6a37888bc8..29c38459a3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -11,8 +11,6 @@ EXTRA_DIST = \
config.h.mingw \
doxy2devhelp.xsl \
fix-casts.sh \
- gaim.pc.in \
- gaim-uninstalled.pc.in \
intltool-extract.in \
intltool-merge.in \
intltool-update.in \
diff --git a/config.h.mingw b/config.h.mingw
index 5576d1e899..5458ce3d3b 100644
--- a/config.h.mingw
+++ b/config.h.mingw
@@ -180,9 +180,6 @@
/* Define to 1 if you have the `random' function. */
/* #define HAVE_RANDOM 1 */
-/* Define to 1 if you have the <regex.h> header file. */
-/* #define HAVE_REGEX_H 1 */
-
/* Define to 1 if you have the `setlocale' function. */
#define HAVE_SETLOCALE 1
diff --git a/configure.ac b/configure.ac
index d60bae65c9..86cb1b1558 100644
--- a/configure.ac
+++ b/configure.ac
@@ -43,10 +43,10 @@ AC_PREREQ([2.50])
#
# Make sure to update finch/libgnt/configure.ac with libgnt version changes.
#
-m4_define([purple_lt_current], [10])
-m4_define([purple_major_version], [2])
-m4_define([purple_minor_version], [10])
-m4_define([purple_micro_version], [7])
+m4_define([purple_lt_current], [20])
+m4_define([purple_major_version], [3])
+m4_define([purple_minor_version], [0])
+m4_define([purple_micro_version], [0])
m4_define([purple_version_suffix], [devel])
m4_define([purple_version],
[purple_major_version.purple_minor_version.purple_micro_version])
@@ -123,7 +123,7 @@ AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
dnl Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(arpa/nameser_compat.h fcntl.h sys/time.h unistd.h locale.h signal.h stdint.h regex.h)
+AC_CHECK_HEADERS(arpa/nameser_compat.h fcntl.h sys/time.h unistd.h locale.h signal.h stdint.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
@@ -202,10 +202,10 @@ AC_SYS_LARGEFILE
dnl FreeBSD doesn't have libdl, dlopen is provided by libc
AC_CHECK_FUNC(dlopen, LIBDL="", [AC_CHECK_LIB(dl, dlopen, LIBDL="-ldl")])
-dnl Haiku does not use libm for the math functions, they are part
+dnl Windows and Haiku do not use libm for the math functions, they are part
dnl of the C library
AC_SEARCH_LIBS([ceil], [m], [], [
- AC_MSG_ERROR([unable to find the floor() function])
+ AC_MSG_ERROR([unable to find the ceil() function])
])
AC_MSG_CHECKING(for fileno())
@@ -334,6 +334,9 @@ AM_CONDITIONAL(INSTALL_I18N, test "x$enable_i18n" = "xyes")
dnl #######################################################################
dnl # Check for GLib 2.16 (required)
dnl #######################################################################
+# TODO: gmodule-2.0 is only needed if enable_plugins is 'yes'. It
+# might be nice to change this check so that it's not required
+# if enable_plugins is 'no'.
PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.16.0 gobject-2.0 gmodule-2.0 gthread-2.0], , [
AC_MSG_RESULT(no)
AC_MSG_ERROR([
@@ -404,6 +407,10 @@ AC_ARG_ENABLE(gestures,
[AC_HELP_STRING([--disable-gestures],
[compile without the gestures plugin])],
enable_gestures="$enableval", enable_gestures="yes")
+AC_ARG_ENABLE(gcr,
+ [AC_HELP_STRING([--enable-gcr],
+ [compile with GCR certificate widgets])],
+ enable_gcr="$enableval", enable_gcr="no")
AC_PATH_XTRA
# We can't assume that $x_libraries will be set, because autoconf does not
@@ -437,6 +444,16 @@ running configure.
PKG_CHECK_MODULES(PANGO, [pango >= 1.4.0],
AC_DEFINE(HAVE_PANGO14, 1, [Define if we have Pango 1.4 or newer.]),:)
+ PKG_CHECK_MODULES(WEBKIT, [webkit-1.0 >= 1.1.1], , [
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([
+You must have WebKit 1.1.1 or newer development headers installed to compile
+Pidgin. If you want to build only Finch then specify --disable-gtkui when
+running configure.
+])])
+ AC_SUBST(WEBKIT_CFLAGS)
+ AC_SUBST(WEBKIT_LIBS)
+
dnl #######################################################################
dnl # Check if we should compile with X support
dnl #######################################################################
@@ -607,9 +624,26 @@ Use --disable-cap if you do not need the Contact Availability Prediction plugin.
])
fi])
fi
-
+
+ dnl #######################################################################
+ dnl # Check for GCR for its certificate widgets
+ dnl #######################################################################
+ if test "x$enable_gcr" = "xyes"; then
+ PKG_CHECK_MODULES(GCR, gcr-0, [
+ AC_DEFINE(ENABLE_GCR, 1, [Define to 1 if GCR is found.])], [
+ AC_MSG_RESULT(no)
+ enable_gcr="no"
+ if test "x$force_deps" = "xyes" ; then
+ AC_MSG_ERROR([
+GCR development headers not found.
+Use --disable-gcr if you do not need GCR certificate widgets.
+])
+ fi])
+ fi
+
else # GTK
+ enable_gcr=no
enable_cap=no
enable_gevolution=no
enable_gtkspell=no
@@ -622,6 +656,7 @@ AM_CONDITIONAL(ENABLE_GTK, test "x$enable_gtkui" = "xyes")
AM_CONDITIONAL(BUILD_GEVOLUTION, test "x$enable_gevolution" = "xyes")
AM_CONDITIONAL(ENABLE_CAP, test "x$enable_cap" = "xyes")
AM_CONDITIONAL(ENABLE_GESTURES, test "x$enable_gestures" = "xyes")
+AM_CONDITIONAL(ENABLE_GCR, test "x$enable_gcr" = "xyes")
dnl #######################################################################
@@ -950,25 +985,6 @@ if test "x$silc_manual_check" = "xno"; then
], [
have_silc="no"
])
- if test "x$have_silc" = "xno"; then
- PKG_CHECK_MODULES(SILC, silcclient, [
- have_silc="yes"
- silc10includes="yes"
- silc10client="yes"
- ], [
- have_silc="no"
- ])
- dnl If silcclient.pc wasn't found, check for just silc.pc
- if test "x$have_silc" = "xno"; then
- PKG_CHECK_MODULES(SILC, silc, [
- have_silc="yes"
- silc10includes="yes"
- silc10client="yes"
- ], [
- have_silc="no"
- ])
- fi
- fi
else
if test "$ac_silc_includes" != "no"; then
SILC_CFLAGS="-I$ac_silc_includes"
@@ -986,17 +1002,6 @@ else
if test "x$silcincludes" = "xyes" -a "x$silcclient" = "xyes"; then
have_silc="yes"
- else
- CPPFLAGS_save="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $SILC_CFLAGS"
- AC_CHECK_HEADER(silcincludes.h, [silc10includes=yes])
- CPPFLAGS="$CPPFLAGS_save"
-
- SILC_LIBS="$SILC_LIBS -lsilc -lsilcclient -lpthread $LIBDL"
- AC_CHECK_LIB(silcclient, silc_client_init, [silc10client=yes], , $SILC_LIBS)
- if test "x$silc10includes" = "xyes" -a "x$silc10client" = "xyes"; then
- have_silc="yes"
- fi
fi
fi
AC_SUBST(SILC_LIBS)
@@ -1004,20 +1009,6 @@ AC_SUBST(SILC_CFLAGS)
dnl SILC Toolkit >= 1.0.1 has a new MIME API
if test "x$silcclient" = "xyes"; then
AC_DEFINE(HAVE_SILCMIME_H, 1, [Define if we have silcmime.h])
-elif test "x$silc10client" = "xyes"; then
- CPPFLAGS_save="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $SILC_CFLAGS"
- AC_MSG_CHECKING(for silcmime.h)
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#include <silcincludes.h>
-#include <silcmime.h>
- ]], [[]])], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_SILCMIME_H, 1, [Define if we have silcmime.h])
- ], [
- AC_MSG_RESULT(no)
- ])
- CPPFLAGS="$CPPFLAGS_save"
fi
dnl #######################################################################
@@ -1123,7 +1114,7 @@ if test "x$STATIC_PRPLS" != "x" -a "x$DYNAMIC_PRPLS" = "xall"; then
fi
if test "x$STATIC_PRPLS" = "xall" ; then
- STATIC_PRPLS="bonjour gg irc jabber msn myspace mxit novell oscar sametime silc simple yahoo zephyr"
+ STATIC_PRPLS="bonjour gg irc jabber msn mxit myspace novell oscar sametime silc simple yahoo zephyr"
fi
if test "x$have_meanwhile" != "xyes" ; then
STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/sametime//'`
@@ -1132,10 +1123,7 @@ if test "x$avahiincludes" != "xyes" -o "x$avahilibs" != "xyes"; then
STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/bonjour//'`
fi
if test "x$silcincludes" != "xyes" -o "x$silcclient" != "xyes"; then
- STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/silc/silc10/'`
-fi
-if test "x$silc10includes" != "xyes" -o "x$silc10client" != "xyes"; then
- STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/silc10//'`
+ STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/silc//'`
fi
AC_SUBST(STATIC_PRPLS)
STATIC_LINK_LIBS=
@@ -1159,8 +1147,6 @@ for i in $STATIC_PRPLS ; do
else
if test "x$i" = "xsilc"; then
STATIC_LINK_LIBS="$STATIC_LINK_LIBS \$(top_builddir)/libpurple/protocols/$i/lib${i}purple.la"
- elif test "x$i" = "xsilc10"; then
- STATIC_LINK_LIBS="$STATIC_LINK_LIBS \$(top_builddir)/libpurple/protocols/$i/libsilcpurple.la"
else
STATIC_LINK_LIBS="$STATIC_LINK_LIBS \$(top_builddir)/libpurple/protocols/$i/lib$i.la"
fi
@@ -1173,15 +1159,14 @@ for i in $STATIC_PRPLS ; do
irc) static_irc=yes ;;
jabber) static_jabber=yes ;;
msn) static_msn=yes ;;
- myspace) static_myspace=yes ;;
mxit) static_mxit=yes ;;
+ myspace) static_myspace=yes ;;
novell) static_novell=yes ;;
oscar) static_oscar=yes ;;
aim) static_oscar=yes ;;
icq) static_oscar=yes ;;
sametime) static_sametime=yes ;;
silc) static_silc=yes ;;
- silc10) static_silc=yes ;;
simple) static_simple=yes ;;
yahoo) static_yahoo=yes ;;
zephyr) static_zephyr=yes ;;
@@ -1193,8 +1178,8 @@ AM_CONDITIONAL(STATIC_GG, test "x$static_gg" = "xyes")
AM_CONDITIONAL(STATIC_IRC, test "x$static_irc" = "xyes")
AM_CONDITIONAL(STATIC_JABBER, test "x$static_jabber" = "xyes")
AM_CONDITIONAL(STATIC_MSN, test "x$static_msn" = "xyes")
-AM_CONDITIONAL(STATIC_MYSPACE, test "x$static_myspace" = "xyes")
AM_CONDITIONAL(STATIC_MXIT, test "x$static_mxit" = "xyes")
+AM_CONDITIONAL(STATIC_MYSPACE, test "x$static_myspace" = "xyes")
AM_CONDITIONAL(STATIC_NOVELL, test "x$static_novell" = "xyes")
AM_CONDITIONAL(STATIC_OSCAR, test "x$static_oscar" = "xyes")
AM_CONDITIONAL(STATIC_SAMETIME, test "x$static_sametime" = "xyes" -a "x$have_meanwhile" = "xyes")
@@ -1208,7 +1193,7 @@ AC_DEFINE_UNQUOTED(STATIC_PROTO_INIT, $extern_init static void static_proto_init
AC_ARG_WITH(dynamic_prpls, [AC_HELP_STRING([--with-dynamic-prpls], [specify which protocols to build dynamically])], [DYNAMIC_PRPLS=`echo $withval | $sedpath 's/,/ /g'`])
if test "x$DYNAMIC_PRPLS" = "xall" ; then
- DYNAMIC_PRPLS="bonjour gg irc jabber msn myspace mxit novell oscar sametime silc simple yahoo zephyr"
+ DYNAMIC_PRPLS="bonjour gg irc jabber msn mxit myspace novell oscar sametime silc simple yahoo zephyr"
fi
if test "x$have_meanwhile" != "xyes"; then
DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/sametime//'`
@@ -1217,10 +1202,7 @@ if test "x$avahiincludes" != "xyes" -o "x$avahilibs" != "xyes"; then
DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/bonjour//'`
fi
if test "x$silcincludes" != "xyes" -o "x$silcclient" != "xyes"; then
- DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/silc/silc10/'`
-fi
-if test "x$silc10includes" != "xyes" -o "x$silc10client" != "xyes"; then
- DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/silc10//'`
+ DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/silc//'`
fi
AC_SUBST(DYNAMIC_PRPLS)
for i in $DYNAMIC_PRPLS ; do
@@ -1230,8 +1212,8 @@ for i in $DYNAMIC_PRPLS ; do
irc) dynamic_irc=yes ;;
jabber) dynamic_jabber=yes ;;
msn) dynamic_msn=yes ;;
- myspace) dynamic_myspace=yes ;;
mxit) dynamic_mxit=yes ;;
+ myspace) dynamic_myspace=yes ;;
novell) dynamic_novell=yes ;;
null) dynamic_null=yes ;;
oscar) dynamic_oscar=yes ;;
@@ -1239,7 +1221,6 @@ for i in $DYNAMIC_PRPLS ; do
icq) dynamic_oscar=yes ;;
sametime) dynamic_sametime=yes ;;
silc) dynamic_silc=yes ;;
- silc10) dynamic_silc=yes ;;
simple) dynamic_simple=yes ;;
yahoo) dynamic_yahoo=yes ;;
zephyr) dynamic_zephyr=yes ;;
@@ -2542,10 +2523,8 @@ AC_CONFIG_FILES([Makefile
m4macros/Makefile
pidgin.apspec
pidgin/Makefile
- pidgin/pidgin.pc
- pidgin/pidgin-uninstalled.pc
- pidgin/pidgin-2.pc
- pidgin/pidgin-2-uninstalled.pc
+ pidgin/pidgin-3.pc
+ pidgin/pidgin-3-uninstalled.pc
pidgin/pixmaps/Makefile
pidgin/pixmaps/emotes/default/24/Makefile
pidgin/pixmaps/emotes/none/Makefile
@@ -2559,13 +2538,12 @@ AC_CONFIG_FILES([Makefile
pidgin/plugins/perl/Makefile
pidgin/plugins/perl/common/Makefile.PL
pidgin/plugins/ticker/Makefile
+ pidgin/themes/Makefile
libpurple/ciphers/Makefile
libpurple/example/Makefile
libpurple/gconf/Makefile
- libpurple/purple.pc
- libpurple/purple-uninstalled.pc
- libpurple/purple-2.pc
- libpurple/purple-2-uninstalled.pc
+ libpurple/purple-3.pc
+ libpurple/purple-3-uninstalled.pc
libpurple/plugins/Makefile
libpurple/plugins/mono/Makefile
libpurple/plugins/mono/api/Makefile
@@ -2588,7 +2566,6 @@ AC_CONFIG_FILES([Makefile
libpurple/protocols/oscar/Makefile
libpurple/protocols/sametime/Makefile
libpurple/protocols/silc/Makefile
- libpurple/protocols/silc10/Makefile
libpurple/protocols/simple/Makefile
libpurple/protocols/yahoo/Makefile
libpurple/protocols/zephyr/Makefile
@@ -2645,6 +2622,7 @@ echo Use XScreenSaver Extension.... : $enable_screensaver
echo Use X Session Management...... : $enable_sm
echo Use startup notification...... : $enable_startup_notification
echo Build with GtkSpell support... : $enable_gtkspell
+echo Build with GCR widgets........ : $enable_gcr
echo
echo Build with plugin support..... : $enable_plugins
echo Build with Mono support....... : $enable_mono
diff --git a/doc/account-signals.dox b/doc/account-signals.dox
index 9ef431cced..c4964bcc7b 100644
--- a/doc/account-signals.dox
+++ b/doc/account-signals.dox
@@ -34,7 +34,6 @@ void (*account_created)(PurpleAccount *account);
@signaldesc
Emitted when an account is created by calling purple_account_new.
@param account The account.
- @since 2.6.0
@endsignaldef
@signaldef account-destroying
@@ -44,7 +43,6 @@ void (*account_destroying)(PurpleAccount *account);
@signaldesc
Emitted when an account is about to be destroyed.
@param account The account.
- @since 2.6.0
@endsignaldef
@signaldef account-added
@@ -156,7 +154,6 @@ int (*account_authorization_requested)(PurpleAccount *account, const char *user)
@return Less than zero to deny the request without prompting, greater
than zero if the request should be granted. If zero is returned,
then the user will be prompted with the request.
- @since 2.3.0
@endsignaldef
@signaldef account-authorization-requested-with-message
@@ -173,7 +170,6 @@ int (*account_authorization_requested)(PurpleAccount *account, const char *user,
get informed, PURPLE_ACCOUNT_RESPONSE_ACCEPT if the request should be
granted. If PURPLE_ACCOUNT_RESPONSE_PASS is returned, then the user
will be prompted with the request.
- @since 2.8.0
@endsignaldef
@signaldef account-authorization-denied
@@ -184,7 +180,6 @@ void (*account_authorization_denied)(PurpleAccount *account, const char *user);
Emitted when the authorization request for a buddy is denied.
@param account The account.
@param user The name of the user requesting authorization.
- @since 2.3.0
@endsignaldef
@signaldef account-authorization-granted
@@ -195,7 +190,6 @@ void (*account_authorization_granted)(PurpleAccount *account, const char *user);
Emitted when the authorization request for a buddy is granted.
@param account The account.
@param user The name of the user requesting authorization.
- @since 2.3.0
@endsignaldef
@signaldef account-error-changed
@@ -214,7 +208,6 @@ void (*account_error_changed)(PurpleAccount *account, const PurpleConnectionErro
pointer just after the next time this signal is emitted
for this @a account.
@see purple_account_get_current_error()
- @since 2.3.0
@endsignaldef
@signaldef account-signed-on
@@ -224,7 +217,6 @@ void (*signed_on)(PurpleAccount *account);
@signaldesc
Emitted when an account has signed on.
@param account The account that has signed on.
- @since 2.7.0
@endsignaldef
@signaldef account-signed-off
@@ -234,7 +226,6 @@ void (*signed_off)(PurpleAccount *account);
@signaldesc
Emitted when an account has signed off.
@param account The account that has signed off.
- @since 2.7.0
@endsignaldef
@signaldef account-connection-error
@@ -246,7 +237,6 @@ void (*connection_error)(PurpleAccount *gc, PurpleConnectionError err, const gch
@param account The account on which the error has occurred
@param err The error that occurred
@param desc A description of the error, giving more information.
- @since 2.7.0
@endsignaldef
*/
// vim: syntax=c.doxygen tw=75 et
diff --git a/doc/blist-signals.dox b/doc/blist-signals.dox
index 3617a389db..5c3c68035c 100644
--- a/doc/blist-signals.dox
+++ b/doc/blist-signals.dox
@@ -136,7 +136,6 @@ void (*buddy_caps_changed)(PurpleBuddy *buddy, PurpleMediaCaps newcaps,
@param buddy The buddy
@param newcaps
@param oldcaps
- @since 2.7.0
@endsignaldef
@signaldef ui-caps-changed
@@ -147,7 +146,6 @@ void (*ui_caps_changed)(PurpleMediaCaps newcaps, PurpleMediaCaps oldcaps)
Emitted when updating the media capabilities of the UI.
@param newcaps
@param oldcaps
- @since 2.7.0
@endsignaldef
*/
diff --git a/doc/connection-signals.dox b/doc/connection-signals.dox
index ee0d62fba6..84849876e8 100644
--- a/doc/connection-signals.dox
+++ b/doc/connection-signals.dox
@@ -44,7 +44,6 @@ gboolean (*autojoin)(PurpleConnection *gc);
@return @c TRUE if the signal was handled or @c FALSE otherwise. In
practice, the return value is irrelevant, as it really only
exists so plugins can block the UI's autojoin.
- @since 2.7.0
@endsignaldef
@signaldef signing-off
diff --git a/doc/conversation-signals.dox b/doc/conversation-signals.dox
index 30415a9d1c..b9746990ac 100644
--- a/doc/conversation-signals.dox
+++ b/doc/conversation-signals.dox
@@ -149,7 +149,6 @@ void (*blocked_im_msg)(PurpleAccount *account, const char *sender,
@param message The message that was blocked.
@param flags The IM message flags.
@param when The time the message was sent.
- @since 2.5.0
@endsignaldef
@signaldef writing-chat-msg
@@ -436,7 +435,6 @@ void (*chat_invite_blocked)(PurpleAccount *account, const char *inviter,
@param name The name of the chat invited to.
@param message The invitation message sent.
@param data Hashtable containing data about the invited chat.
- @since 2.5.0
@endsignaldef
@signaldef chat-joined
@@ -477,7 +475,6 @@ void (*conversation_extended_menu)(PurpleConversation *conv, GList **list);
conversation.
@param conv The conversation.
@param list A pointer to the list of actions.
- @since 2.1.0
@endsignaldef
@signaldef cleared-message-history
@@ -487,7 +484,6 @@ void (*cleared_message_history)(PurpleConversation *conv);
@signaldesc
Emitted when the conversation history is cleared.
@param conv The conversation.
- @since 2.8.0
@endsignaldef
@signaldef sent-attention
@@ -501,7 +497,6 @@ void (*got_attention)(PurpleAccount *account, const char *who,
@param who The name of the person receiving the attention
@param conv The conversation
@param type The attention type (an index starting at 0)
- @since 2.7.0
@endsignaldef
@signaldef got-attention
@@ -515,7 +510,6 @@ void (*got_attention)(PurpleAccount *account, const char *who,
@param who The name of the person sending the attention
@param conv The conversation
@param type The attention type (an index starting at 0)
- @since 2.7.0
@endsignaldef
*/
// vim: syntax=c.doxygen tw=75 et
diff --git a/doc/gtkconv-signals.dox b/doc/gtkconv-signals.dox
index b1df1bbd8a..b9427516ef 100644
--- a/doc/gtkconv-signals.dox
+++ b/doc/gtkconv-signals.dox
@@ -129,7 +129,6 @@ void (*conversation_hiding)(PidginConversation *gtkconv);
@signaldesc
Emitted immediately before an existing conversation is hidden.
@param gtkconv The PidginConversation
- @since 2.2.0
@endsignaldef
@signaldef conversation-displayed
@@ -139,7 +138,6 @@ void (*conversation_displayed)(PidginConversation *gtkconv);
@signaldesc
Emitted right after the Pidgin UI is attached to a new or a hidden conversation.
@param gtkconv The PidginConversation
- @since 2.2.0
@endsignaldef
*/
diff --git a/doc/notify-signals.dox b/doc/notify-signals.dox
index 820298c604..2606936083 100644
--- a/doc/notify-signals.dox
+++ b/doc/notify-signals.dox
@@ -35,7 +35,6 @@ void (*displaying_email_notification)(const char *subject,
@param from Who the email is from.
@param to Who the email is to.
@param url A url to view the email.
- @since 2.1.0
@endsignaldef
@signaldef displaying-emails-notification
@@ -53,7 +52,6 @@ void (*displaying_emails_notification)(const char **subjects,
@param tos Who the emails are to.
@param urls The urls to view the emails.
@param count Number of emails being notified of.
- @since 2.1.0
@endsignaldef
*/
diff --git a/finch/Makefile.am b/finch/Makefile.am
index 85502d3015..be23168ad1 100644
--- a/finch/Makefile.am
+++ b/finch/Makefile.am
@@ -27,6 +27,7 @@ finch_SOURCES = \
gntidle.c \
gntlog.c \
gntmedia.c \
+ gntmenuutil.c \
gntnotify.c \
gntplugin.c \
gntpounce.c \
@@ -49,6 +50,7 @@ finch_headers = \
gntidle.h \
gntlog.h \
gntmedia.h \
+ gntmenuutil.h \
gntnotify.h \
gntplugin.h \
gntpounce.h \
diff --git a/finch/finch.c b/finch/finch.c
index 8ae3617569..1af4e87694 100644
--- a/finch/finch.c
+++ b/finch/finch.c
@@ -339,7 +339,17 @@ init_libpurple(int argc, char **argv)
/* set a user-specified config directory */
if (opt_config_dir_arg != NULL) {
- purple_util_set_user_dir(opt_config_dir_arg);
+ if (g_path_is_absolute(opt_config_dir_arg)) {
+ purple_util_set_user_dir(opt_config_dir_arg);
+ } else {
+ /* Make an absolute (if not canonical) path */
+ char *cwd = g_get_current_dir();
+ char *path = g_build_path(G_DIR_SEPARATOR_S, cwd, opt_config_dir_arg, NULL);
+ purple_util_set_user_dir(path);
+ g_free(path);
+ g_free(cwd);
+ }
+
g_free(opt_config_dir_arg);
}
@@ -351,29 +361,6 @@ init_libpurple(int argc, char **argv)
/* We don't want debug-messages to show up and corrupt the display */
purple_debug_set_enabled(debug_enabled);
- /* If we're using a custom configuration directory, we
- * do NOT want to migrate, or weird things will happen. */
- if (opt_config_dir_arg == NULL)
- {
- if (!purple_core_migrate())
- {
- char *old = g_strconcat(purple_home_dir(),
- G_DIR_SEPARATOR_S ".gaim", NULL);
- char *text = g_strdup_printf(_(
- "%s encountered errors migrating your settings "
- "from %s to %s. Please investigate and complete the "
- "migration by hand. Please report this error at http://developer.pidgin.im"), _("Finch"),
- old, purple_user_dir());
-
- g_free(old);
-
- purple_print_utf8_to_console(stderr, text);
- g_free(text);
-
- return 0;
- }
- }
-
purple_core_set_ui_ops(gnt_core_get_ui_ops());
purple_eventloop_set_ui_ops(gnt_eventloop_get_ui_ops());
purple_idle_set_ui_ops(finch_idle_get_ui_ops());
diff --git a/finch/gntaccount.h b/finch/gntaccount.h
index 2cf7d8f9e7..e1fd0378d6 100644
--- a/finch/gntaccount.h
+++ b/finch/gntaccount.h
@@ -59,8 +59,6 @@ void finch_accounts_show_all(void);
* Show the edit dialog for an account.
*
* @param account The account to edit, or @c NULL to create a new account.
- *
- * @since 2.2.0
*/
void finch_account_dialog_show(PurpleAccount *account);
diff --git a/finch/gntblist.c b/finch/gntblist.c
index b2c62c55d8..1f5a9fd66b 100644
--- a/finch/gntblist.c
+++ b/finch/gntblist.c
@@ -50,6 +50,7 @@
#include "gntmenu.h"
#include "gntmenuitem.h"
#include "gntmenuitemcheck.h"
+#include "gntmenuutil.h"
#include "gntpounce.h"
#include "gntstyle.h"
#include "gnttree.h"
@@ -169,7 +170,7 @@ static gboolean default_can_add_node(PurpleBlistNode *node)
if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
PurpleBuddy *buddy = (PurpleBuddy*)node;
- FinchBlistNode *fnode = FINCH_GET_DATA(node);
+ FinchBlistNode *fnode = purple_blist_node_get_ui_data(node);
if (!purple_buddy_get_contact(buddy))
return FALSE; /* When a new buddy is added and show-offline is set */
if (PURPLE_BUDDY_IS_ONLINE(buddy))
@@ -329,11 +330,11 @@ static GList *managers;
static FinchBlistNode *
create_finch_blist_node(PurpleBlistNode *node, gpointer row)
{
- FinchBlistNode *fnode = FINCH_GET_DATA(node);
+ FinchBlistNode *fnode = purple_blist_node_get_ui_data(node);
if (!fnode) {
fnode = g_new0(FinchBlistNode, 1);
fnode->signed_timer = 0;
- FINCH_SET_DATA(node, fnode);
+ purple_blist_node_set_ui_data(node, fnode);
}
fnode->row = row;
return fnode;
@@ -342,13 +343,13 @@ create_finch_blist_node(PurpleBlistNode *node, gpointer row)
static void
reset_blist_node_ui_data(PurpleBlistNode *node)
{
- FinchBlistNode *fnode = FINCH_GET_DATA(node);
+ FinchBlistNode *fnode = purple_blist_node_get_ui_data(node);
if (fnode == NULL)
return;
if (fnode->signed_timer)
purple_timeout_remove(fnode->signed_timer);
g_free(fnode);
- FINCH_SET_DATA(node, NULL);
+ purple_blist_node_set_ui_data(node, NULL);
}
static int
@@ -381,7 +382,7 @@ static GntTextFormatFlags
get_blist_node_flag(PurpleBlistNode *node)
{
GntTextFormatFlags flag = 0;
- FinchBlistNode *fnode = FINCH_GET_DATA(node);
+ FinchBlistNode *fnode = purple_blist_node_get_ui_data(node);
if (ggblist->tagged && g_list_find(ggblist->tagged, node))
flag |= GNT_TEXT_FLAG_BOLD;
@@ -390,7 +391,7 @@ get_blist_node_flag(PurpleBlistNode *node)
flag |= GNT_TEXT_FLAG_BLINK;
else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
node = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node)));
- fnode = FINCH_GET_DATA(node);
+ fnode = purple_blist_node_get_ui_data(node);
if (fnode && fnode->signed_timer)
flag |= GNT_TEXT_FLAG_BLINK;
} else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
@@ -406,7 +407,7 @@ get_blist_node_flag(PurpleBlistNode *node)
node = purple_blist_node_get_sibling_next(node)) {
PurpleBlistNode *pnode;
pnode = purple_contact_get_priority_buddy((PurpleContact*)node);
- fnode = FINCH_GET_DATA(node);
+ fnode = purple_blist_node_get_ui_data(node);
if (fnode && fnode->signed_timer) {
flag |= GNT_TEXT_FLAG_BLINK;
break;
@@ -433,7 +434,7 @@ is_contact_online(PurpleContact *contact)
PurpleBlistNode *node;
for (node = purple_blist_node_get_first_child(((PurpleBlistNode*)contact)); node;
node = purple_blist_node_get_sibling_next(node)) {
- FinchBlistNode *fnode = FINCH_GET_DATA(node);
+ FinchBlistNode *fnode = purple_blist_node_get_ui_data(node);
if (PURPLE_BUDDY_IS_ONLINE((PurpleBuddy*)node) ||
(fnode && fnode->signed_timer))
return TRUE;
@@ -465,7 +466,7 @@ new_node(PurpleBlistNode *node)
static void
add_node(PurpleBlistNode *node, FinchBlist *ggblist)
{
- if (FINCH_GET_DATA(node))
+ if (purple_blist_node_get_ui_data(node))
return;
if (!ggblist->manager->can_add_node(node))
@@ -502,7 +503,7 @@ node_remove(PurpleBuddyList *list, PurpleBlistNode *node)
FinchBlist *ggblist = FINCH_GET_DATA(list);
PurpleBlistNode *parent;
- if (ggblist == NULL || FINCH_GET_DATA(node) == NULL)
+ if (ggblist == NULL || purple_blist_node_get_ui_data(node) == NULL)
return;
if (PURPLE_BLIST_NODE_IS_GROUP(node) && ggblist->new_group) {
@@ -543,7 +544,7 @@ node_update(PurpleBuddyList *list, PurpleBlistNode *node)
if (ggblist->window == NULL)
return;
- if (FINCH_GET_DATA(node)!= NULL) {
+ if (purple_blist_node_get_ui_data(node)!= NULL) {
gnt_tree_change_text(GNT_TREE(ggblist->tree), node,
0, get_display_name(node));
gnt_tree_sort_row(GNT_TREE(ggblist->tree), node);
@@ -560,7 +561,7 @@ node_update(PurpleBuddyList *list, PurpleBlistNode *node)
} else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
add_node(node, FINCH_GET_DATA(list));
} else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
- if (FINCH_GET_DATA(node)== NULL) {
+ if (purple_blist_node_get_ui_data(node)== NULL) {
/* The core seems to expect the UI to add the buddies. */
for (node = purple_blist_node_get_first_child(node); node; node = purple_blist_node_get_sibling_next(node))
add_node(node, FINCH_GET_DATA(list));
@@ -663,7 +664,7 @@ add_buddy_cb(void *data, PurpleRequestFields *allfields)
purple_blist_add_buddy(buddy, NULL, grp, NULL);
}
- purple_account_add_buddy_with_invite(account, buddy, invite);
+ purple_account_add_buddy(account, buddy, invite);
}
static void
@@ -839,7 +840,7 @@ add_group_cb(gpointer null, const char *group)
/* Select the group */
if (ggblist->tree) {
- FinchBlistNode *fnode = FINCH_GET_DATA((PurpleBlistNode*)grp);
+ FinchBlistNode *fnode = purple_blist_node_get_ui_data((PurpleBlistNode*)grp);
if (!fnode)
add_node((PurpleBlistNode*)grp, ggblist);
gnt_tree_set_selected(GNT_TREE(ggblist->tree), grp);
@@ -887,7 +888,7 @@ add_group(PurpleGroup *group, FinchBlist *ggblist)
{
gpointer parent;
PurpleBlistNode *node = (PurpleBlistNode *)group;
- if (FINCH_GET_DATA(node))
+ if (purple_blist_node_get_ui_data(node))
return;
parent = ggblist->manager->find_parent((PurpleBlistNode*)group);
create_finch_blist_node(node, gnt_tree_add_row_after(GNT_TREE(ggblist->tree), group,
@@ -960,7 +961,7 @@ add_chat(PurpleChat *chat, FinchBlist *ggblist)
{
gpointer parent;
PurpleBlistNode *node = (PurpleBlistNode *)chat;
- if (FINCH_GET_DATA(node))
+ if (purple_blist_node_get_ui_data(node))
return;
if (!purple_account_is_connected(purple_chat_get_account(chat)))
return;
@@ -979,7 +980,7 @@ add_contact(PurpleContact *contact, FinchBlist *ggblist)
PurpleBlistNode *node = (PurpleBlistNode*)contact;
const char *name;
- if (FINCH_GET_DATA(node))
+ if (purple_blist_node_get_ui_data(node))
return;
name = get_display_name(node);
@@ -1002,7 +1003,7 @@ add_buddy(PurpleBuddy *buddy, FinchBlist *ggblist)
PurpleBlistNode *node = (PurpleBlistNode *)buddy;
PurpleContact *contact;
- if (FINCH_GET_DATA(node))
+ if (purple_blist_node_get_ui_data(node))
return;
contact = purple_buddy_get_contact(buddy);
@@ -1060,7 +1061,7 @@ selection_activate(GntWidget *widget, FinchBlist *ggblist)
purple_buddy_get_account(buddy),
purple_buddy_get_name(buddy));
} else {
- FinchConv *ggconv = FINCH_GET_DATA(conv);
+ FinchConv *ggconv = FINCH_CONV(conv);
gnt_window_present(ggconv->window);
}
finch_conversation_set_active(conv);
@@ -1072,43 +1073,6 @@ selection_activate(GntWidget *widget, FinchBlist *ggblist)
}
static void
-context_menu_callback(GntMenuItem *item, gpointer data)
-{
- PurpleMenuAction *action = data;
- PurpleBlistNode *node = ggblist->cnode;
- if (action) {
- void (*callback)(PurpleBlistNode *, gpointer);
- callback = (void (*)(PurpleBlistNode *, gpointer))action->callback;
- if (callback)
- callback(node, action->data);
- else
- return;
- }
-}
-
-static void
-gnt_append_menu_action(GntMenu *menu, PurpleMenuAction *action, gpointer parent)
-{
- GList *list;
- GntMenuItem *item;
-
- if (action == NULL)
- return;
-
- item = gnt_menuitem_new(action->label);
- if (action->callback)
- gnt_menuitem_set_callback(GNT_MENU_ITEM(item), context_menu_callback, action);
- gnt_menu_add_item(menu, GNT_MENU_ITEM(item));
-
- if (action->children) {
- GntWidget *sub = gnt_menu_new(GNT_MENU_POPUP);
- gnt_menuitem_set_submenu(item, GNT_MENU(sub));
- for (list = action->children; list; list = list->next)
- gnt_append_menu_action(GNT_MENU(sub), list->data, action);
- }
-}
-
-static void
append_proto_menu(GntMenu *menu, PurpleConnection *gc, PurpleBlistNode *node)
{
GList *list;
@@ -1123,10 +1087,8 @@ append_proto_menu(GntMenu *menu, PurpleConnection *gc, PurpleBlistNode *node)
PurpleMenuAction *act = (PurpleMenuAction *) list->data;
if (!act)
continue;
- act->data = node;
- gnt_append_menu_action(menu, act, NULL);
- g_signal_connect_swapped(G_OBJECT(menu), "destroy",
- G_CALLBACK(purple_menu_action_free), act);
+ purple_menu_action_set_data(act, node);
+ gnt_append_menu_action(menu, act, node);
}
}
@@ -1136,8 +1098,6 @@ add_custom_action(GntMenu *menu, const char *label, PurpleCallback callback,
{
PurpleMenuAction *action = purple_menu_action_new(label, callback, data, NULL);
gnt_append_menu_action(menu, action, NULL);
- g_signal_connect_swapped(G_OBJECT(menu), "destroy",
- G_CALLBACK(purple_menu_action_free), action);
}
static void
@@ -1216,7 +1176,7 @@ static void
autojoin_toggled(GntMenuItem *item, gpointer data)
{
PurpleMenuAction *action = data;
- purple_blist_node_set_bool(action->data, "gnt-autojoin",
+ purple_blist_node_set_bool(purple_menu_action_get_data(action), "gnt-autojoin",
gnt_menuitem_check_get_checked(GNT_MENU_ITEM_CHECK(item)));
}
@@ -1224,7 +1184,8 @@ static void
create_chat_menu(GntMenu *menu, PurpleChat *chat)
{
PurpleMenuAction *action = purple_menu_action_new(_("Auto-join"), NULL, chat, NULL);
- GntMenuItem *check = gnt_menuitem_check_new(action->label);
+ GntMenuItem *check = gnt_menuitem_check_new(
+ purple_menu_action_get_label(action));
gnt_menuitem_check_set_checked(GNT_MENU_ITEM_CHECK(check),
purple_blist_node_get_bool((PurpleBlistNode*)chat, "gnt-autojoin"));
gnt_menu_add_item(menu, check);
@@ -1268,7 +1229,7 @@ gpointer finch_retrieve_user_info(PurpleConnection *conn, const char *name)
{
PurpleNotifyUserInfo *info = purple_notify_user_info_new();
gpointer uihandle;
- purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving..."));
+ purple_notify_user_info_add_pair_plaintext(info, _("Information"), _("Retrieving..."));
uihandle = purple_notify_userinfo(conn, name, info, NULL, NULL);
purple_notify_user_info_destroy(info);
@@ -1375,9 +1336,7 @@ append_extended_menu(GntMenu *menu, PurpleBlistNode *node)
for (iter = purple_blist_node_get_extended_menu(node);
iter; iter = g_list_delete_link(iter, iter))
{
- gnt_append_menu_action(menu, iter->data, NULL);
- g_signal_connect_swapped(G_OBJECT(menu), "destroy",
- G_CALLBACK(purple_menu_action_free), iter->data);
+ gnt_append_menu_action(menu, iter->data, node);
}
}
@@ -1557,7 +1516,7 @@ finch_blist_remove_node_cb(PurpleBlistNode *selected, PurpleBlistNode *node)
if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
PurpleContact *c = (PurpleContact*)node;
name = purple_contact_get_alias(c);
- if (c->totalsize > 1)
+ if (purple_contact_get_contact_size(c, TRUE) > 1)
sec = _("Removing this contact will also remove all the buddies in the contact");
} else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
name = purple_buddy_get_name((PurpleBuddy*)node);
@@ -1783,15 +1742,13 @@ tooltip_for_buddy(PurpleBuddy *buddy, GString *str, gboolean full)
presence = purple_buddy_get_presence(buddy);
if (!full || g_utf8_collate(purple_buddy_get_name(buddy), alias)) {
- char *esc = g_markup_escape_text(alias, -1);
- purple_notify_user_info_add_pair(user_info, _("Nickname"), esc);
- g_free(esc);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Nickname"), alias);
}
tmp = g_strdup_printf("%s (%s)",
purple_account_get_username(account),
purple_account_get_protocol_name(account));
- purple_notify_user_info_add_pair(user_info, _("Account"), tmp);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Account"), tmp);
g_free(tmp);
prpl = purple_find_prpl(purple_account_get_protocol_id(account));
@@ -1806,7 +1763,7 @@ tooltip_for_buddy(PurpleBuddy *buddy, GString *str, gboolean full)
time_t idle = purple_presence_get_idle_time(pre);
if (idle > 0) {
char *st = purple_str_seconds_to_string(time(NULL) - idle);
- purple_notify_user_info_add_pair(user_info, _("Idle"), st);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Idle"), st);
g_free(st);
}
}
@@ -2543,7 +2500,7 @@ static gboolean
buddy_recent_signed_on_off(gpointer data)
{
PurpleBlistNode *node = data;
- FinchBlistNode *fnode = FINCH_GET_DATA(node);
+ FinchBlistNode *fnode = purple_blist_node_get_ui_data(node);
purple_timeout_remove(fnode->signed_timer);
fnode->signed_timer = 0;
@@ -2563,7 +2520,7 @@ static gboolean
buddy_signed_on_off_cb(gpointer data)
{
PurpleBlistNode *node = data;
- FinchBlistNode *fnode = FINCH_GET_DATA(node);
+ FinchBlistNode *fnode = purple_blist_node_get_ui_data(node);
if (!ggblist || !fnode)
return FALSE;
diff --git a/finch/gntblist.h b/finch/gntblist.h
index a8037d597d..5b67691970 100644
--- a/finch/gntblist.h
+++ b/finch/gntblist.h
@@ -115,15 +115,12 @@ void finch_blist_set_size(int width, int height);
* @param name The user to get information about.
*
* @return Returns the ui-handle for the userinfo notification.
- *
- * @since 2.1.0
*/
gpointer finch_retrieve_user_info(PurpleConnection *conn, const char *name);
/**
* Get the tree list of the buddy list.
* @return The GntTree widget.
- * @since 2.4.0
*/
GntTree * finch_blist_get_tree(void);
@@ -131,7 +128,6 @@ GntTree * finch_blist_get_tree(void);
* Add an alternate buddy list manager.
*
* @param manager The alternate buddylist manager.
- * @since 2.4.0
*/
void finch_blist_install_manager(const FinchBlistManager *manager);
@@ -139,7 +135,6 @@ void finch_blist_install_manager(const FinchBlistManager *manager);
* Remove an alternate buddy list manager.
*
* @param manager The buddy list manager to remove.
- * @since 2.4.0
*/
void finch_blist_uninstall_manager(const FinchBlistManager *manager);
@@ -149,7 +144,6 @@ void finch_blist_uninstall_manager(const FinchBlistManager *manager);
* @param id The identifier for the desired buddy list manager.
*
* @return The manager with the requested identifier, if available. @c NULL otherwise.
- * @since 2.4.0
*/
FinchBlistManager * finch_blist_manager_find(const char *id);
@@ -157,7 +151,6 @@ FinchBlistManager * finch_blist_manager_find(const char *id);
* Request the active buddy list manager to add a node.
*
* @param node The node to add
- * @since 2.4.0
*/
void finch_blist_manager_add_node(PurpleBlistNode *node);
diff --git a/finch/gntconn.c b/finch/gntconn.c
index 2c3b8afa43..09d4bf71c1 100644
--- a/finch/gntconn.c
+++ b/finch/gntconn.c
@@ -165,7 +165,6 @@ static PurpleConnectionUiOps ops =
NULL, /* connected */
NULL, /* disconnected */
NULL, /* notice */
- NULL,
NULL, /* network_connected */
NULL, /* network_disconnected */
finch_connection_report_disconnect,
diff --git a/finch/gntconv.c b/finch/gntconv.c
index 04c882857a..368719d123 100644
--- a/finch/gntconv.c
+++ b/finch/gntconv.c
@@ -52,6 +52,7 @@
#include "gntmenu.h"
#include "gntmenuitem.h"
#include "gntmenuitemcheck.h"
+#include "gntmenuutil.h"
#include "gntstyle.h"
#include "gnttextview.h"
#include "gnttree.h"
@@ -123,7 +124,7 @@ send_typing_notification(GntWidget *w, FinchConv *ggconv)
if (send || (purple_conv_im_get_type_again(im) != 0 &&
time(NULL) > purple_conv_im_get_type_again(im))) {
unsigned int timeout;
- timeout = serv_send_typing(purple_conversation_get_gc(conv),
+ timeout = serv_send_typing(purple_conversation_get_connection(conv),
purple_conversation_get_name(conv),
PURPLE_TYPING);
purple_conv_im_set_type_again(im, timeout);
@@ -131,7 +132,7 @@ send_typing_notification(GntWidget *w, FinchConv *ggconv)
} else {
purple_conv_im_stop_send_typed_timeout(im);
- serv_send_typing(purple_conversation_get_gc(conv),
+ serv_send_typing(purple_conversation_get_connection(conv),
purple_conversation_get_name(conv),
PURPLE_NOT_TYPING);
}
@@ -282,7 +283,7 @@ update_buddy_typing(PurpleAccount *account, const char *who, gpointer null)
return;
im = PURPLE_CONV_IM(conv);
- ggc = FINCH_GET_DATA(conv);
+ ggc = FINCH_CONV(conv);
if (purple_conv_im_get_typing_state(im) == PURPLE_TYPING) {
int scroll;
@@ -321,7 +322,7 @@ buddy_signed_on_off(PurpleBuddy *buddy, gpointer null)
PurpleConversation *conv = find_conv_with_contact(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy));
if (conv == NULL)
return;
- generate_send_to_menu(FINCH_GET_DATA(conv));
+ generate_send_to_menu(FINCH_CONV(conv));
}
static void
@@ -333,7 +334,7 @@ account_signed_on_off(PurpleConnection *gc, gpointer null)
PurpleConversation *cc = find_conv_with_contact(
purple_conversation_get_account(conv), purple_conversation_get_name(conv));
if (cc)
- generate_send_to_menu(FINCH_GET_DATA(cc));
+ generate_send_to_menu(FINCH_CONV(cc));
list = list->next;
}
@@ -398,12 +399,36 @@ finch_conv_get_handle(void)
static void
cleared_message_history_cb(PurpleConversation *conv, gpointer data)
{
- FinchConv *ggc = FINCH_GET_DATA(conv);
+ FinchConv *ggc = FINCH_CONV(conv);
if (ggc)
gnt_text_view_clear(GNT_TEXT_VIEW(ggc->tv));
}
static void
+gg_extended_menu(FinchConv *ggc)
+{
+ GntWidget *sub;
+ GList *list;
+
+ sub = gnt_menu_new(GNT_MENU_POPUP);
+ gnt_menuitem_set_submenu(ggc->plugins, GNT_MENU(sub));
+
+ for (list = purple_conversation_get_extended_menu(ggc->active_conv);
+ list; list = g_list_delete_link(list, list))
+ {
+ gnt_append_menu_action(GNT_MENU(sub), list->data, ggc->active_conv);
+ }
+}
+
+static void
+conv_updated(PurpleConversation *conv, PurpleConvUpdateType type)
+{
+ if (type == PURPLE_CONV_UPDATE_FEATURES) {
+ gg_extended_menu(purple_conversation_get_ui_data(conv));
+ }
+}
+
+static void
clear_scrollback_cb(GntMenuItem *item, gpointer ggconv)
{
FinchConv *ggc = ggconv;
@@ -414,7 +439,7 @@ static void
send_file_cb(GntMenuItem *item, gpointer ggconv)
{
FinchConv *ggc = ggconv;
- serv_send_file(purple_conversation_get_gc(ggc->active_conv),
+ serv_send_file(purple_conversation_get_connection(ggc->active_conv),
purple_conversation_get_name(ggc->active_conv), NULL);
}
@@ -431,7 +456,7 @@ static void
get_info_cb(GntMenuItem *item, gpointer ggconv)
{
FinchConv *ggc = ggconv;
- finch_retrieve_user_info(purple_conversation_get_gc(ggc->active_conv),
+ finch_retrieve_user_info(purple_conversation_get_connection(ggc->active_conv),
purple_conversation_get_name(ggc->active_conv));
}
@@ -595,6 +620,12 @@ invite_cb(GntMenuItem *item, gpointer ggconv)
}
static void
+plugin_changed_cb(PurplePlugin *p, gpointer data)
+{
+ gg_extended_menu(data);
+}
+
+static void
gg_create_menu(FinchConv *ggc)
{
GntWidget *menu, *sub;
@@ -665,6 +696,12 @@ gg_create_menu(FinchConv *ggc)
!(ggc->flags & FINCH_CONV_NO_SOUND));
gnt_menu_add_item(GNT_MENU(sub), item);
gnt_menuitem_set_callback(item, toggle_sound_cb, ggc);
+
+ item = gnt_menuitem_new(_("Plugins"));
+ gnt_menu_add_item(GNT_MENU(menu), item);
+ ggc->plugins = item;
+
+ gg_extended_menu(ggc);
}
static void
@@ -683,7 +720,7 @@ create_conv_from_userlist(GntWidget *widget, FinchConv *fc)
name = gnt_tree_get_selection_data(GNT_TREE(widget));
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
if (prpl_info && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_cb_real_name))
realname = prpl_info->get_cb_real_name(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(fc->active_conv)), name);
else
@@ -749,7 +786,7 @@ cmd_removed_cb(const char *cmd, FinchConv *fconv)
static void
finch_create_conversation(PurpleConversation *conv)
{
- FinchConv *ggc = FINCH_GET_DATA(conv);
+ FinchConv *ggc = FINCH_CONV(conv);
char *title;
PurpleConversationType type;
PurpleConversation *cc;
@@ -763,8 +800,8 @@ finch_create_conversation(PurpleConversation *conv)
account = purple_conversation_get_account(conv);
cc = find_conv_with_contact(account, purple_conversation_get_name(conv));
- if (cc && FINCH_GET_DATA(cc))
- ggc = FINCH_GET_DATA(cc);
+ if (cc && FINCH_CONV(cc))
+ ggc = FINCH_CONV(cc);
else
ggc = g_new0(FinchConv, 1);
@@ -776,9 +813,9 @@ finch_create_conversation(PurpleConversation *conv)
ggc->list = g_list_prepend(ggc->list, conv);
ggc->active_conv = conv;
- FINCH_SET_DATA(conv, ggc);
+ purple_conversation_set_ui_data(conv, ggc);
- if (cc && FINCH_GET_DATA(cc) && cc != conv) {
+ if (cc && FINCH_CONV(cc) && cc != conv) {
finch_conversation_set_active(conv);
return;
}
@@ -876,6 +913,11 @@ finch_create_conversation(PurpleConversation *conv)
purple_signal_connect(purple_cmds_get_handle(), "cmd-removed", ggc,
G_CALLBACK(cmd_removed_cb), ggc);
+ purple_signal_connect(purple_plugins_get_handle(), "plugin-load", ggc,
+ PURPLE_CALLBACK(plugin_changed_cb), ggc);
+ purple_signal_connect(purple_plugins_get_handle(), "plugin-unload", ggc,
+ PURPLE_CALLBACK(plugin_changed_cb), ggc);
+
g_free(title);
gnt_box_give_focus_to_child(GNT_BOX(ggc->window), ggc->entry);
g_signal_connect(G_OBJECT(ggc->window), "gained-focus", G_CALLBACK(gained_focus_cb), ggc);
@@ -885,7 +927,7 @@ static void
finch_destroy_conversation(PurpleConversation *conv)
{
/* do stuff here */
- FinchConv *ggc = FINCH_GET_DATA(conv);
+ FinchConv *ggc = FINCH_CONV(conv);
ggc->list = g_list_remove(ggc->list, conv);
if (ggc->list && conv == ggc->active_conv) {
ggc->active_conv = ggc->list->data;
@@ -905,7 +947,7 @@ static void
finch_write_common(PurpleConversation *conv, const char *who, const char *message,
PurpleMessageFlags flags, time_t mtime)
{
- FinchConv *ggconv = FINCH_GET_DATA(conv);
+ FinchConv *ggconv = FINCH_CONV(conv);
char *strip, *newline;
GntTextFormatFlags fl = 0;
int pos;
@@ -1069,7 +1111,7 @@ chat_flag_text(PurpleConvChatBuddyFlags flags)
static void
finch_chat_add_users(PurpleConversation *conv, GList *users, gboolean new_arrivals)
{
- FinchConv *ggc = FINCH_GET_DATA(conv);
+ FinchConv *ggc = FINCH_CONV(conv);
GntEntry *entry = GNT_ENTRY(ggc->entry);
if (!new_arrivals)
@@ -1084,10 +1126,10 @@ finch_chat_add_users(PurpleConversation *conv, GList *users, gboolean new_arriva
for (iter = users; iter; iter = iter->next)
{
PurpleConvChatBuddy *cbuddy = iter->data;
- char *str;
+ const char *str;
- if ((str = cbuddy->alias) == NULL)
- str = cbuddy->name;
+ if ((str = purple_conv_chat_cb_get_alias(cbuddy)) == NULL)
+ str = purple_conv_chat_cb_get_name(cbuddy);
g_string_append_printf(string, "[ %s ]", str);
}
@@ -1100,10 +1142,10 @@ finch_chat_add_users(PurpleConversation *conv, GList *users, gboolean new_arriva
{
PurpleConvChatBuddy *cbuddy = users->data;
GntTree *tree = GNT_TREE(ggc->u.chat->userlist);
- gnt_entry_add_suggest(entry, cbuddy->name);
- gnt_entry_add_suggest(entry, cbuddy->alias);
- gnt_tree_add_row_after(tree, g_strdup(cbuddy->name),
- gnt_tree_create_row(tree, chat_flag_text(cbuddy->flags), cbuddy->alias), NULL, NULL);
+ gnt_entry_add_suggest(entry, purple_conv_chat_cb_get_name(cbuddy));
+ gnt_entry_add_suggest(entry, purple_conv_chat_cb_get_alias(cbuddy));
+ gnt_tree_add_row_after(tree, g_strdup(purple_conv_chat_cb_get_name(cbuddy)),
+ gnt_tree_create_row(tree, chat_flag_text(purple_conv_chat_cb_get_flags(cbuddy)), purple_conv_chat_cb_get_alias(cbuddy)), NULL, NULL);
}
}
@@ -1111,7 +1153,7 @@ static void
finch_chat_rename_user(PurpleConversation *conv, const char *old, const char *new_n, const char *new_a)
{
/* Update the name for string completion */
- FinchConv *ggc = FINCH_GET_DATA(conv);
+ FinchConv *ggc = FINCH_CONV(conv);
GntEntry *entry = GNT_ENTRY(ggc->entry);
GntTree *tree = GNT_TREE(ggc->u.chat->userlist);
PurpleConvChatBuddy *cb = purple_conv_chat_cb_find(PURPLE_CONV_CHAT(conv), new_n);
@@ -1122,14 +1164,14 @@ finch_chat_rename_user(PurpleConversation *conv, const char *old, const char *ne
gnt_entry_add_suggest(entry, new_n);
gnt_entry_add_suggest(entry, new_a);
gnt_tree_add_row_after(tree, g_strdup(new_n),
- gnt_tree_create_row(tree, chat_flag_text(cb->flags), new_a), NULL, NULL);
+ gnt_tree_create_row(tree, chat_flag_text(purple_conv_chat_cb_get_flags(cb)), new_a), NULL, NULL);
}
static void
finch_chat_remove_users(PurpleConversation *conv, GList *list)
{
/* Remove the name from string completion */
- FinchConv *ggc = FINCH_GET_DATA(conv);
+ FinchConv *ggc = FINCH_CONV(conv);
GntEntry *entry = GNT_ENTRY(ggc->entry);
for (; list; list = list->next) {
GntTree *tree = GNT_TREE(ggc->u.chat->userlist);
@@ -1142,8 +1184,8 @@ static void
finch_chat_update_user(PurpleConversation *conv, const char *user)
{
PurpleConvChatBuddy *cb = purple_conv_chat_cb_find(PURPLE_CONV_CHAT(conv), user);
- FinchConv *ggc = FINCH_GET_DATA(conv);
- gnt_tree_change_text(GNT_TREE(ggc->u.chat->userlist), (gpointer)user, 0, chat_flag_text(cb->flags));
+ FinchConv *ggc = FINCH_CONV(conv);
+ gnt_tree_change_text(GNT_TREE(ggc->u.chat->userlist), (gpointer)user, 0, chat_flag_text(purple_conv_chat_cb_get_flags(cb)));
}
static void
@@ -1368,7 +1410,7 @@ cmd_message_color(PurpleConversation *conv, const char *cmd, char **args, char *
static PurpleCmdRet
users_command_cb(PurpleConversation *conv, const char *cmd, char **args, char **error, gpointer data)
{
- FinchConv *fc = FINCH_GET_DATA(conv);
+ FinchConv *fc = FINCH_CONV(conv);
FinchConvChat *ch;
if (!fc)
return PURPLE_CMD_RET_FAILED;
@@ -1475,6 +1517,8 @@ void finch_conversation_init()
PURPLE_CALLBACK(chat_left_cb), NULL);
purple_signal_connect(purple_conversations_get_handle(), "cleared-message-history", finch_conv_get_handle(),
PURPLE_CALLBACK(cleared_message_history_cb), NULL);
+ purple_signal_connect(purple_conversations_get_handle(), "conversation-updated", finch_conv_get_handle(),
+ PURPLE_CALLBACK(conv_updated), NULL);
purple_signal_connect(purple_blist_get_handle(), "buddy-signed-on", finch_conv_get_handle(),
PURPLE_CALLBACK(buddy_signed_on_off), NULL);
purple_signal_connect(purple_blist_get_handle(), "buddy-signed-off", finch_conv_get_handle(),
@@ -1494,7 +1538,7 @@ void finch_conversation_uninit()
void finch_conversation_set_active(PurpleConversation *conv)
{
- FinchConv *ggconv = FINCH_GET_DATA(conv);
+ FinchConv *ggconv = FINCH_CONV(conv);
PurpleAccount *account;
char *title;
@@ -1513,7 +1557,7 @@ void finch_conversation_set_active(PurpleConversation *conv)
void finch_conversation_set_info_widget(PurpleConversation *conv, GntWidget *widget)
{
- FinchConv *fc = FINCH_GET_DATA(conv);
+ FinchConv *fc = FINCH_CONV(conv);
int height, width;
gnt_box_remove_all(GNT_BOX(fc->info));
diff --git a/finch/gntconv.h b/finch/gntconv.h
index b188469bf5..3f512a9a80 100644
--- a/finch/gntconv.h
+++ b/finch/gntconv.h
@@ -33,7 +33,7 @@
#include "conversation.h"
/* Grabs the conv out of a PurpleConverstation */
-#define FINCH_CONV(conv) ((FinchConv *)(conv)->ui_data)
+#define FINCH_CONV(conv) ((FinchConv *)purple_conversation_get_ui_data(conv))
/***************************************************************************
* @name GNT Conversations API
@@ -59,6 +59,7 @@ struct _FinchConv
GntWidget *tv; /* text-view */
GntWidget *menu;
GntWidget *info;
+ GntMenuItem *plugins;
FinchConversationFlag flags;
union
diff --git a/finch/gntft.c b/finch/gntft.c
index 262140a7b6..95c806bbeb 100644
--- a/finch/gntft.c
+++ b/finch/gntft.c
@@ -42,9 +42,6 @@
#include "gntft.h"
#include "prefs.h"
-#define FINCHXFER(xfer) \
- (PurpleGntXferUiData *)FINCH_GET_DATA(xfer)
-
typedef struct
{
gboolean keep_open;
@@ -152,7 +149,7 @@ toggle_clear_finished_cb(GntWidget *w)
while (iter) {
PurpleXfer *xfer = iter->data;
iter = iter->next;
- if (purple_xfer_is_completed(xfer) || purple_xfer_is_canceled(xfer))
+ if (purple_xfer_is_completed(xfer) || purple_xfer_is_cancelled(xfer))
finch_xfer_dialog_remove_xfer(xfer);
}
}
@@ -163,7 +160,7 @@ remove_button_cb(GntButton *button)
{
PurpleXfer *selected_xfer = gnt_tree_get_selection_data(GNT_TREE(xfer_dialog->tree));
if (selected_xfer && (purple_xfer_is_completed(selected_xfer) ||
- purple_xfer_is_canceled(selected_xfer))) {
+ purple_xfer_is_cancelled(selected_xfer))) {
finch_xfer_dialog_remove_xfer(selected_xfer);
}
}
@@ -262,7 +259,7 @@ finch_xfer_dialog_new(void)
for (iter = purple_xfers_get_all(); iter; iter = iter->next) {
PurpleXfer *xfer = (PurpleXfer *)iter->data;
- PurpleGntXferUiData *data = FINCHXFER(xfer);
+ PurpleGntXferUiData *data = purple_xfer_get_ui_data(xfer);
if (data->in_list) {
finch_xfer_dialog_add_xfer(xfer);
finch_xfer_dialog_update_xfer(xfer);
@@ -302,7 +299,7 @@ finch_xfer_dialog_add_xfer(PurpleXfer *xfer)
purple_xfer_ref(xfer);
- data = FINCHXFER(xfer);
+ data = purple_xfer_get_ui_data(xfer);
data->in_list = TRUE;
finch_xfer_dialog_show();
@@ -340,7 +337,7 @@ finch_xfer_dialog_remove_xfer(PurpleXfer *xfer)
g_return_if_fail(xfer_dialog != NULL);
g_return_if_fail(xfer != NULL);
- data = FINCHXFER(xfer);
+ data = purple_xfer_get_ui_data(xfer);
if (data == NULL)
return;
@@ -370,7 +367,7 @@ finch_xfer_dialog_cancel_xfer(PurpleXfer *xfer)
g_return_if_fail(xfer_dialog != NULL);
g_return_if_fail(xfer != NULL);
- data = FINCHXFER(xfer);
+ data = purple_xfer_get_ui_data(xfer);
if (data == NULL)
return;
@@ -385,7 +382,7 @@ finch_xfer_dialog_cancel_xfer(PurpleXfer *xfer)
update_title_progress();
- if (purple_xfer_is_canceled(xfer))
+ if (purple_xfer_is_cancelled(xfer))
status = _("Cancelled");
else
status = _("Failed");
@@ -416,7 +413,7 @@ finch_xfer_dialog_update_xfer(PurpleXfer *xfer)
g_return_if_fail(xfer_dialog != NULL);
g_return_if_fail(xfer != NULL);
- if ((data = FINCHXFER(xfer)) == NULL)
+ if ((data = purple_xfer_get_ui_data(xfer)) == NULL)
return;
if (data->in_list == FALSE || data->notified)
@@ -471,9 +468,9 @@ finch_xfer_new_xfer(PurpleXfer *xfer)
{
PurpleGntXferUiData *data;
- /* This is where we're setting xfer->ui_data for the first time. */
+ /* This is where we're setting xfer's "ui_data" for the first time. */
data = g_new0(PurpleGntXferUiData, 1);
- FINCH_SET_DATA(xfer, data);
+ purple_xfer_set_ui_data(xfer, data);
}
static void
@@ -481,11 +478,11 @@ finch_xfer_destroy(PurpleXfer *xfer)
{
PurpleGntXferUiData *data;
- data = FINCHXFER(xfer);
+ data = purple_xfer_get_ui_data(xfer);
if (data) {
g_free(data->name);
g_free(data);
- FINCH_SET_DATA(xfer, NULL);
+ purple_xfer_set_ui_data(xfer, NULL);
}
}
diff --git a/finch/gntmenuutil.c b/finch/gntmenuutil.c
new file mode 100644
index 0000000000..6be90ff0c7
--- /dev/null
+++ b/finch/gntmenuutil.c
@@ -0,0 +1,79 @@
+/**
+ * @file gntmenuutil.c GNT Menu Utility Functions
+ * @ingroup 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
+ * source distribution.
+ *
+ * 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 <internal.h>
+#include "finch.h"
+
+#include "gnt.h"
+#include "gntmenu.h"
+#include "gntmenuitem.h"
+#include "gntmenuutil.h"
+
+static void
+context_menu_callback(GntMenuItem *item, gpointer data)
+{
+ PurpleMenuAction *action = data;
+ if (action) {
+ void (*callback)(gpointer, gpointer);
+ callback = (void (*)(gpointer, gpointer))
+ purple_menu_action_get_callback(action);
+ if (callback) {
+ gpointer ctx = g_object_get_data(G_OBJECT(item), "menuctx");
+ callback(ctx, purple_menu_action_get_data(action));
+ }
+ }
+}
+
+void
+gnt_append_menu_action(GntMenu *menu, PurpleMenuAction *action, gpointer ctx)
+{
+ GList *list;
+ GntMenuItem *item;
+
+ if (action == NULL)
+ return;
+
+ item = gnt_menuitem_new(purple_menu_action_get_label(action));
+ if (purple_menu_action_get_callback(action)) {
+ gnt_menuitem_set_callback(item, context_menu_callback, action);
+ g_object_set_data(G_OBJECT(item), "menuctx", ctx);
+ }
+ gnt_menu_add_item(menu, item);
+
+ list = purple_menu_action_get_children(action);
+
+ if (list) {
+ GntWidget *sub = gnt_menu_new(GNT_MENU_POPUP);
+ gnt_menuitem_set_submenu(item, GNT_MENU(sub));
+ for (; list; list = g_list_delete_link(list, list))
+ gnt_append_menu_action(GNT_MENU(sub), list->data, action);
+ purple_menu_action_set_children(action, NULL);
+ }
+
+ g_signal_connect_swapped(G_OBJECT(menu), "destroy",
+ G_CALLBACK(purple_menu_action_free), action);
+}
+
diff --git a/finch/gntmenuutil.h b/finch/gntmenuutil.h
new file mode 100644
index 0000000000..e5c38bf70d
--- /dev/null
+++ b/finch/gntmenuutil.h
@@ -0,0 +1,49 @@
+/**
+ * @file gntmenuutil.h GNT Menu Utility Functions
+ * @ingroup 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
+ * source distribution.
+ *
+ * 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
+ */
+#ifndef _GNT_MENUUTIL_H
+#define _GNT_MENUUTIL_H
+
+#include <gnt.h>
+#include <gntmenu.h>
+
+/***************************************************************************
+ * @name GNT Menu Utility Functions
+ ***************************************************************************/
+/*@{*/
+
+/**
+ * Add a PurpleMenuAction to a GntMenu.
+ *
+ * @param menu the GntMenu to add to
+ * @param action the PurpleMenuAction to add
+ * @param ctx the callback context, passed as the first argument to
+ * the PurpleMenuAction's PurpleCallback function.
+ */
+void gnt_append_menu_action(GntMenu *menu, PurpleMenuAction *action, gpointer ctx);
+
+/*@}*/
+
+#endif
diff --git a/finch/gntnotify.c b/finch/gntnotify.c
index 80b9be1d88..103495dc93 100644
--- a/finch/gntnotify.c
+++ b/finch/gntnotify.c
@@ -290,7 +290,7 @@ purple_notify_user_info_get_xhtml(PurpleNotifyUserInfo *user_info)
text = g_string_new("<span>");
- for (l = purple_notify_user_info_get_entries(user_info); l != NULL;
+ for (l = purple_notify_user_info_get_entries(user_info)->head; l != NULL;
l = l->next) {
PurpleNotifyUserInfoEntry *user_info_entry = l->data;
PurpleNotifyUserInfoEntryType type = purple_notify_user_info_entry_get_type(user_info_entry);
@@ -386,6 +386,7 @@ finch_notify_sr_new_rows(PurpleConnection *gc,
{
GntTree *tree = GNT_TREE(data);
GList *o;
+ GntTreeRow *prev = NULL;
/* XXX: Do I need to empty the tree here? */
@@ -393,10 +394,17 @@ finch_notify_sr_new_rows(PurpleConnection *gc,
{
gnt_tree_add_row_after(GNT_TREE(tree), o->data,
gnt_tree_create_row_from_list(GNT_TREE(tree), o->data),
- NULL, NULL);
+ NULL, prev);
+ prev = o->data;
}
}
+static void
+notify_sr_destroy_cb(GntWidget *window, void *data)
+{
+ purple_notify_close(PURPLE_NOTIFY_SEARCHRESULTS, window);
+}
+
static void *
finch_notify_searchresults(PurpleConnection *gc, const char *title,
const char *primary, const char *secondary,
@@ -429,7 +437,10 @@ finch_notify_searchresults(PurpleConnection *gc, const char *title,
for (iter = results->columns; iter; iter = iter->next)
{
PurpleNotifySearchColumn *column = iter->data;
- gnt_tree_set_column_title(GNT_TREE(tree), i, column->title);
+ gnt_tree_set_column_title(GNT_TREE(tree), i, purple_notify_searchresult_column_get_title(column));
+
+ if (!purple_notify_searchresult_column_is_visible(column))
+ gnt_tree_set_column_visible(GNT_TREE(tree), i, FALSE);
i++;
}
@@ -478,6 +489,8 @@ finch_notify_searchresults(PurpleConnection *gc, const char *title,
}
gnt_box_add_widget(GNT_BOX(window), box);
+ g_signal_connect(G_OBJECT(tree), "destroy",
+ G_CALLBACK(notify_sr_destroy_cb), NULL);
finch_notify_sr_new_rows(gc, results, tree);
diff --git a/finch/gntprefs.c b/finch/gntprefs.c
index 02ebf6a98e..f1870976a9 100644
--- a/finch/gntprefs.c
+++ b/finch/gntprefs.c
@@ -62,14 +62,6 @@ void finch_prefs_init()
void finch_prefs_update_old()
{
- const char *str = NULL;
-
- purple_prefs_rename("/gaim/gnt", "/finch");
- purple_prefs_rename("/purple/gnt", "/finch");
-
- if ((str = purple_prefs_get_string("/purple/away/idle_reporting")) &&
- strcmp(str, "gaim") == 0)
- purple_prefs_set_string("/purple/away/idle_reporting", "purple");
}
typedef struct
diff --git a/finch/gntrequest.c b/finch/gntrequest.c
index 37940e01c1..e9bd209b54 100644
--- a/finch/gntrequest.c
+++ b/finch/gntrequest.c
@@ -41,12 +41,6 @@
#include "debug.h"
#include "util.h"
-/* XXX: Until gobjectification ... */
-#undef FINCH_GET_DATA
-#undef FINCH_SET_DATA
-#define FINCH_GET_DATA(obj) purple_request_field_get_ui_data(obj)
-#define FINCH_SET_DATA(obj, data) purple_request_field_set_ui_data(obj, data)
-
typedef struct
{
void *user_data;
@@ -323,26 +317,26 @@ request_fields_cb(GntWidget *button, PurpleRequestFields *fields)
continue;
if (type == PURPLE_REQUEST_FIELD_BOOLEAN)
{
- GntWidget *check = FINCH_GET_DATA(field);
+ GntWidget *check = purple_request_field_get_ui_data(field);
gboolean value = gnt_check_box_get_checked(GNT_CHECK_BOX(check));
purple_request_field_bool_set_value(field, value);
}
else if (type == PURPLE_REQUEST_FIELD_STRING)
{
- GntWidget *entry = FINCH_GET_DATA(field);
+ GntWidget *entry = purple_request_field_get_ui_data(field);
const char *text = gnt_entry_get_text(GNT_ENTRY(entry));
purple_request_field_string_set_value(field, (text && *text) ? text : NULL);
}
else if (type == PURPLE_REQUEST_FIELD_INTEGER)
{
- GntWidget *entry = FINCH_GET_DATA(field);
+ GntWidget *entry = purple_request_field_get_ui_data(field);
const char *text = gnt_entry_get_text(GNT_ENTRY(entry));
int value = (text && *text) ? atoi(text) : 0;
purple_request_field_int_set_value(field, value);
}
else if (type == PURPLE_REQUEST_FIELD_CHOICE)
{
- GntWidget *combo = FINCH_GET_DATA(field);
+ GntWidget *combo = purple_request_field_get_ui_data(field);
int id;
id = GPOINTER_TO_INT(gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo)));
purple_request_field_choice_set_value(field, id);
@@ -352,7 +346,7 @@ request_fields_cb(GntWidget *button, PurpleRequestFields *fields)
GList *list = NULL, *iter;
if (purple_request_field_list_get_multi_select(field))
{
- GntWidget *tree = FINCH_GET_DATA(field);
+ GntWidget *tree = purple_request_field_get_ui_data(field);
iter = purple_request_field_list_get_items(field);
for (; iter; iter = iter->next)
@@ -365,7 +359,7 @@ request_fields_cb(GntWidget *button, PurpleRequestFields *fields)
}
else
{
- GntWidget *combo = FINCH_GET_DATA(field);
+ GntWidget *combo = purple_request_field_get_ui_data(field);
gpointer data = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo));
iter = purple_request_field_list_get_items(field);
@@ -384,7 +378,7 @@ request_fields_cb(GntWidget *button, PurpleRequestFields *fields)
}
else if (type == PURPLE_REQUEST_FIELD_ACCOUNT)
{
- GntWidget *combo = FINCH_GET_DATA(field);
+ GntWidget *combo = purple_request_field_get_ui_data(field);
PurpleAccount *acc = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo));
purple_request_field_account_set_value(field, acc);
}
@@ -577,6 +571,22 @@ create_account_field(PurpleRequestField *field)
return combo;
}
+static GntWidget*
+create_certificate_field(PurpleRequestField *field)
+{
+ GntWidget *w;
+ PurpleCertificate *cert;
+ char *str;
+
+ cert = purple_request_field_certificate_get_value(field);
+ str = purple_certificate_get_display_string(cert);
+ w = gnt_label_new(str);
+
+ g_free(str);
+
+ return w;
+}
+
static void *
finch_request_fields(const char *title, const char *primary,
const char *secondary, PurpleRequestFields *allfields,
@@ -633,36 +643,40 @@ finch_request_fields(const char *title, const char *primary,
if (type == PURPLE_REQUEST_FIELD_BOOLEAN)
{
- FINCH_SET_DATA(field, create_boolean_field(field));
+ purple_request_field_set_ui_data(field, create_boolean_field(field));
}
else if (type == PURPLE_REQUEST_FIELD_STRING)
{
- FINCH_SET_DATA(field, create_string_field(field, &username));
+ purple_request_field_set_ui_data(field, create_string_field(field, &username));
}
else if (type == PURPLE_REQUEST_FIELD_INTEGER)
{
- FINCH_SET_DATA(field, create_integer_field(field));
+ purple_request_field_set_ui_data(field, create_integer_field(field));
}
else if (type == PURPLE_REQUEST_FIELD_CHOICE)
{
- FINCH_SET_DATA(field, create_choice_field(field));
+ purple_request_field_set_ui_data(field, create_choice_field(field));
}
else if (type == PURPLE_REQUEST_FIELD_LIST)
{
- FINCH_SET_DATA(field, create_list_field(field));
+ purple_request_field_set_ui_data(field, create_list_field(field));
}
else if (type == PURPLE_REQUEST_FIELD_ACCOUNT)
{
accountlist = create_account_field(field);
- FINCH_SET_DATA(field, accountlist);
+ purple_request_field_set_ui_data(field, accountlist);
+ }
+ else if (type == PURPLE_REQUEST_FIELD_CERTIFICATE)
+ {
+ purple_request_field_set_ui_data(field, create_certificate_field(field));
}
else
{
- FINCH_SET_DATA(field, gnt_label_new_with_format(_("Not implemented yet."),
+ purple_request_field_set_ui_data(field, gnt_label_new_with_format(_("Not implemented yet."),
GNT_TEXT_FLAG_BOLD));
}
gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID);
- gnt_box_add_widget(GNT_BOX(hbox), GNT_WIDGET(FINCH_GET_DATA(field)));
+ gnt_box_add_widget(GNT_BOX(hbox), GNT_WIDGET(purple_request_field_get_ui_data(field)));
}
if (grlist->next)
gnt_box_add_widget(GNT_BOX(box), gnt_hline_new());
diff --git a/finch/gntrequest.h b/finch/gntrequest.h
index 2e1c33fde5..63c4534486 100644
--- a/finch/gntrequest.h
+++ b/finch/gntrequest.h
@@ -63,7 +63,6 @@ void finch_request_save_in_prefs(gpointer null, PurpleRequestFields *fields);
* @param field The request field.
*
* @return A GntWidget for the request field.
- * @since 2.4.0
*/
GntWidget *finch_request_field_get_widget(PurpleRequestField *field);
/*@}*/
diff --git a/finch/gntroomlist.c b/finch/gntroomlist.c
index 92299d3a5c..e4a17c73fc 100644
--- a/finch/gntroomlist.c
+++ b/finch/gntroomlist.c
@@ -41,6 +41,7 @@
#define PREF_ROOT "/finch/roomlist"
+
/* Yes, just one roomlist at a time. Let's not get greedy. Aight? */
struct _FinchRoomlist
{
@@ -146,9 +147,9 @@ roomlist_activated(GntWidget *widget)
purple_roomlist_room_join(froomlist.roomlist, room);
break;
case PURPLE_ROOMLIST_ROOMTYPE_CATEGORY:
- if (!room->expanded_once) {
+ if (!purple_roomlist_room_get_expanded_once(room)) {
purple_roomlist_expand_category(froomlist.roomlist, room);
- room->expanded_once = TRUE;
+ purple_roomlist_room_set_expanded_once(room, TRUE);
}
break;
}
@@ -343,7 +344,7 @@ fl_show_with_account(PurpleAccount *account)
static void
fl_create(PurpleRoomlist *list)
{
- FINCH_SET_DATA(list, &froomlist);
+ purple_roomlist_set_ui_data(list, &froomlist);
setup_roomlist(NULL);
update_roomlist(list);
}
diff --git a/finch/gntsound.c b/finch/gntsound.c
index 296fee1ef3..3a5deb99d0 100644
--- a/finch/gntsound.c
+++ b/finch/gntsound.c
@@ -150,7 +150,7 @@ chat_nick_matches_name(PurpleConversation *conv, const char *aname)
return ret;
account = purple_conversation_get_account(conv);
- nick = g_strdup(purple_normalize(account, chat->nick));
+ nick = g_strdup(purple_normalize(account, purple_conv_chat_get_nick(chat)));
name = g_strdup(purple_normalize(account, aname));
if (g_utf8_collate(nick, name) == 0)
@@ -268,7 +268,7 @@ chat_msg_received_cb(PurpleAccount *account, char *sender,
if (chat_nick_matches_name(conv, sender))
return;
- if (flags & PURPLE_MESSAGE_NICK || purple_utf8_has_word(message, chat->nick))
+ if (flags & PURPLE_MESSAGE_NICK || purple_utf8_has_word(message, purple_conv_chat_get_nick(chat)))
play_conv_event(conv, PURPLE_SOUND_CHAT_NICK);
else
play_conv_event(conv, event);
diff --git a/finch/gntsound.h b/finch/gntsound.h
index c1edfaac6f..56deb9915e 100644
--- a/finch/gntsound.h
+++ b/finch/gntsound.h
@@ -37,8 +37,6 @@
* Get the name of the active sound profile.
*
* @return The name of the profile
- *
- * @since 2.1.0
*/
const char *finch_sound_get_active_profile(void);
@@ -46,8 +44,6 @@ const char *finch_sound_get_active_profile(void);
* Set the active profile. If the profile doesn't exist, nothing is changed.
*
* @param name The name of the profile
- *
- * @since 2.1.0
*/
void finch_sound_set_active_profile(const char *name);
@@ -56,8 +52,6 @@ void finch_sound_set_active_profile(const char *name);
*
* @return A list of strings denoting sound profile names.
* Caller must free the list (but not the data).
- *
- * @since 2.1.0
*/
GList *finch_sound_get_profiles(void);
@@ -66,8 +60,6 @@ GList *finch_sound_get_profiles(void);
*
* @return Returns FALSE if preference is set to 'No sound', or if volume is
* set to zero.
- *
- * @since 2.2.0
*/
gboolean finch_sound_is_enabled(void);
@@ -75,15 +67,11 @@ gboolean finch_sound_is_enabled(void);
* Gets GNT sound UI ops.
*
* @return The UI operations structure.
- *
- * @since 2.1.0
*/
PurpleSoundUiOps *finch_sound_get_ui_ops(void);
/**
* Show the sound settings dialog.
- *
- * @since 2.1.0
*/
void finch_sounds_show_all(void);
diff --git a/finch/libgnt/gntfilesel.h b/finch/libgnt/gntfilesel.h
index bb6b1d6cf9..c31a8ebe52 100644
--- a/finch/libgnt/gntfilesel.h
+++ b/finch/libgnt/gntfilesel.h
@@ -81,7 +81,7 @@ struct _GntFileSelClass
void (*gnt_reserved4)(void);
};
-typedef enum _GntFileType
+typedef enum
{
GNT_FILE_REGULAR,
GNT_FILE_DIR
diff --git a/finch/libgnt/gntprogressbar.h b/finch/libgnt/gntprogressbar.h
index fbfd788992..dbbf4a36e1 100644
--- a/finch/libgnt/gntprogressbar.h
+++ b/finch/libgnt/gntprogressbar.h
@@ -37,7 +37,7 @@
#define GNT_IS_PROGRESS_BAR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GNT_TYPE_PROGRESS_BAR))
#define GNT_PROGRESS_BAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GNT_TYPE_PROGRESS_BAR, GntProgressBarClass))
-typedef enum _GntProgressBarOrientation
+typedef enum
{
GNT_PROGRESS_LEFT_TO_RIGHT,
GNT_PROGRESS_RIGHT_TO_LEFT,
diff --git a/finch/libgnt/gnttree.h b/finch/libgnt/gnttree.h
index 2be31b2cce..1cb69ce5f2 100644
--- a/finch/libgnt/gnttree.h
+++ b/finch/libgnt/gnttree.h
@@ -47,7 +47,7 @@ typedef struct _GntTreeClass GntTreeClass;
typedef struct _GntTreeRow GntTreeRow;
typedef struct _GntTreeCol GntTreeCol;
-typedef enum _GntTreeColumnFlag {
+typedef enum {
GNT_TREE_COLUMN_INVISIBLE = 1 << 0,
GNT_TREE_COLUMN_FIXED_SIZE = 1 << 1,
GNT_TREE_COLUMN_BINARY_DATA = 1 << 2,
diff --git a/finch/libgnt/gntwidget.h b/finch/libgnt/gntwidget.h
index e25d58f711..cb0f597e32 100644
--- a/finch/libgnt/gntwidget.h
+++ b/finch/libgnt/gntwidget.h
@@ -49,7 +49,7 @@ typedef struct _GntWidget GntWidget;
typedef struct _GntWidgetPriv GntWidgetPriv;
typedef struct _GntWidgetClass GntWidgetClass;
-typedef enum _GntWidgetFlags
+typedef enum
{
GNT_WIDGET_DESTROYING = 1 << 0,
GNT_WIDGET_CAN_TAKE_FOCUS = 1 << 1,
@@ -69,7 +69,7 @@ typedef enum _GntWidgetFlags
} GntWidgetFlags;
/* XXX: This will probably move elsewhere */
-typedef enum _GntMouseEvent
+typedef enum
{
GNT_LEFT_MOUSE_DOWN = 1,
GNT_RIGHT_MOUSE_DOWN,
@@ -80,7 +80,7 @@ typedef enum _GntMouseEvent
} GntMouseEvent;
/* XXX: I'll have to ask grim what he's using this for in guifications. */
-typedef enum _GntParamFlags
+typedef enum
{
GNT_PARAM_SERIALIZABLE = 1 << G_PARAM_USER_SHIFT
} GntParamFlags;
diff --git a/finch/libgnt/gntwm.h b/finch/libgnt/gntwm.h
index 4d8ace2428..be846e6a92 100644
--- a/finch/libgnt/gntwm.h
+++ b/finch/libgnt/gntwm.h
@@ -41,7 +41,7 @@
#define GNT_IS_WM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_WM))
#define GNT_WM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_WM, GntWMClass))
-typedef enum _GntKeyPressMode
+typedef enum
{
GNT_KP_MODE_NORMAL,
GNT_KP_MODE_RESIZE,
diff --git a/finch/plugins/gntgf.c b/finch/plugins/gntgf.c
index 9d7d726d86..925c24834d 100644
--- a/finch/plugins/gntgf.c
+++ b/finch/plugins/gntgf.c
@@ -168,7 +168,7 @@ notify(PurpleConversation *conv, const char *fmt, ...)
beep();
if (conv != NULL) {
- FinchConv *fc = conv->ui_data;
+ FinchConv *fc = FINCH_CONV(conv);
if (gnt_widget_has_focus(fc->window))
return;
}
@@ -256,7 +256,7 @@ received_chat_msg(PurpleAccount *account, const char *sender, const char *msg,
if (flags & PURPLE_MESSAGE_WHISPER)
return;
- nick = PURPLE_CONV_CHAT(conv)->nick;
+ nick = purple_conv_chat_get_nick(PURPLE_CONV_CHAT(conv));
if (g_utf8_collate(sender, nick) == 0)
return;
diff --git a/finch/plugins/gnttinyurl.c b/finch/plugins/gnttinyurl.c
index 4d70de1d03..2718f5fe75 100644
--- a/finch/plugins/gnttinyurl.c
+++ b/finch/plugins/gnttinyurl.c
@@ -319,7 +319,7 @@ process_urls(PurpleConversation *conv, GList *urls)
url = g_strdup_printf("%s%s", purple_prefs_get_string(PREF_URL), purple_url_encode(tmp));
}
g_free(tmp);
- purple_util_fetch_url(url, TRUE, "finch", FALSE, url_fetched, cbdata);
+ purple_util_fetch_url(url, TRUE, "finch", FALSE, -1, url_fetched, cbdata);
i = gnt_text_view_get_lines_below(tv);
str = g_strdup_printf(_("\nFetching TinyURL..."));
gnt_text_view_append_text_with_tag((tv), str, GNT_TEXT_FLAG_DIM, cbdata->tag);
@@ -383,7 +383,7 @@ tinyurl_notify_uri(const char *uri)
/* Store the return value of _fetch_url and destroy that when win is
destroyed, so that the callback for _fetch_url does not try to molest a
non-existent window */
- urlcb = purple_util_fetch_url(fullurl, TRUE, "finch", FALSE, tinyurl_notify_fetch_cb, win);
+ urlcb = purple_util_fetch_url(fullurl, TRUE, "finch", FALSE, -1, tinyurl_notify_fetch_cb, win);
g_free(fullurl);
g_signal_connect_swapped(G_OBJECT(win), "destroy",
G_CALLBACK(purple_util_fetch_url_cancel), urlcb);
diff --git a/finch/plugins/grouping.c b/finch/plugins/grouping.c
index b312c7dc3b..18ebd4cbe0 100644
--- a/finch/plugins/grouping.c
+++ b/finch/plugins/grouping.c
@@ -54,7 +54,7 @@ static gboolean on_offline_can_add_node(PurpleBlistNode *node)
case PURPLE_BLIST_CONTACT_NODE:
{
PurpleContact *contact = (PurpleContact*)node;
- if (contact->currentsize > 0)
+ if (purple_contact_get_contact_size(contact, FALSE) > 0)
return TRUE;
return FALSE;
}
diff --git a/finch/plugins/lastlog.c b/finch/plugins/lastlog.c
index 753935bd48..86cd718e2f 100644
--- a/finch/plugins/lastlog.c
+++ b/finch/plugins/lastlog.c
@@ -60,7 +60,7 @@ window_kpress_cb(GntWidget *wid, const char *key, GntTextView *view)
static PurpleCmdRet
lastlog_cb(PurpleConversation *conv, const char *cmd, char **args, char **error, gpointer null)
{
- FinchConv *ggconv = conv->ui_data;
+ FinchConv *ggconv = FINCH_CONV(conv);
char **strings = g_strsplit(GNT_TEXT_VIEW(ggconv->tv)->string->str, "\n", 0);
GntWidget *win, *tv;
int i, j;
diff --git a/gaim-uninstalled.pc.in b/gaim-uninstalled.pc.in
deleted file mode 100644
index b9d7d0e193..0000000000
--- a/gaim-uninstalled.pc.in
+++ /dev/null
@@ -1,14 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-
-Name: Pidgin (Gaim compatibility)
-Description: Pidgin is a GTK2-based instant messenger application.
-Version: @VERSION@
-Requires: glib-2.0
-Cflags: -I${pc_top_builddir}/${pcfiledir}/libpurple -I${pc_top_builddir}/${pcfiledir}/pidgin
-Libs: ${pc_top_builddir}/${pcfiledir}/libpurple/libpurple.la
diff --git a/gaim.pc.in b/gaim.pc.in
deleted file mode 100644
index bc8f5da073..0000000000
--- a/gaim.pc.in
+++ /dev/null
@@ -1,14 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-
-Name: Pidgin (Gaim compatibility)
-Description: Pidgin is a GTK2-based instant messenger application.
-Version: @VERSION@
-Requires: glib-2.0
-Cflags: -I${includedir}/libpurple
-Libs: -L${libdir} -lpurple
diff --git a/libpurple/Makefile.am b/libpurple/Makefile.am
index 1447d5c052..eebd2df0b7 100644
--- a/libpurple/Makefile.am
+++ b/libpurple/Makefile.am
@@ -9,8 +9,8 @@ EXTRA_DIST = \
purple-send-async \
purple-url-handler \
purple.h.in \
- purple.pc.in \
- purple-uninstalled.pc.in \
+ purple-3.pc.in \
+ purple-3-uninstalled.pc.in \
version.h.in \
Makefile.mingw \
win32/global.mak \
@@ -30,7 +30,7 @@ GCONF_DIR=gconf
endif
pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = purple.pc
+pkgconfig_DATA = purple-3.pc
SUBDIRS = $(GCONF_DIR) plugins protocols ciphers . tests example
@@ -117,7 +117,6 @@ purple_coreheaders = \
desktopitem.h \
eventloop.h \
ft.h \
- gaim-compat.h \
idle.h \
imgstore.h \
log.h \
diff --git a/libpurple/account.c b/libpurple/account.c
index 7d7c32dc82..5948344a36 100644
--- a/libpurple/account.c
+++ b/libpurple/account.c
@@ -41,14 +41,6 @@
#include "util.h"
#include "xmlnode.h"
-typedef struct
-{
- PurpleConnectionErrorInfo *current_error;
-} PurpleAccountPrivate;
-
-#define PURPLE_ACCOUNT_GET_PRIVATE(account) \
- ((PurpleAccountPrivate *) (account->priv))
-
/* TODO: Should use PurpleValue instead of this? What about "ui"? */
typedef struct
{
@@ -361,8 +353,6 @@ current_error_to_xmlnode(PurpleConnectionErrorInfo *err)
static xmlnode *
account_to_xmlnode(PurpleAccount *account)
{
- PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
-
xmlnode *node, *child;
const char *tmp;
PurplePresence *presence;
@@ -419,7 +409,7 @@ account_to_xmlnode(PurpleAccount *account)
xmlnode_insert_child(node, child);
}
- child = current_error_to_xmlnode(priv->current_error);
+ child = current_error_to_xmlnode(account->current_error);
xmlnode_insert_child(node, child);
return node;
@@ -874,7 +864,7 @@ parse_account(xmlnode *node)
return NULL;
}
- ret = purple_account_new(name, _purple_oscar_convert(name, protocol_id)); /* XXX: */
+ ret = purple_account_new(name, protocol_id);
g_free(name);
g_free(protocol_id);
@@ -924,15 +914,6 @@ parse_account(xmlnode *node)
{
purple_buddy_icons_set_account_icon(ret, (guchar *)contents, len);
}
- else
- {
- /* Try to see if the icon got left behind in the old cache. */
- g_free(filename);
- filename = g_build_filename(g_get_home_dir(), ".gaim", "icons", data, NULL);
- if (g_file_get_contents(filename, &contents, &len, NULL)) {
- purple_buddy_icons_set_account_icon(ret, (guchar*)contents, len);
- }
- }
g_free(filename);
g_free(data);
@@ -1005,7 +986,6 @@ PurpleAccount *
purple_account_new(const char *username, const char *protocol_id)
{
PurpleAccount *account = NULL;
- PurpleAccountPrivate *priv = NULL;
PurplePlugin *prpl = NULL;
PurplePluginProtocolInfo *prpl_info = NULL;
PurpleStatusType *status_type;
@@ -1020,8 +1000,6 @@ purple_account_new(const char *username, const char *protocol_id)
account = g_new0(PurpleAccount, 1);
PURPLE_DBUS_REGISTER_POINTER(account, PurpleAccount);
- priv = g_new0(PurpleAccountPrivate, 1);
- account->priv = priv;
purple_account_set_username(account, username);
@@ -1064,7 +1042,6 @@ purple_account_new(const char *username, const char *protocol_id)
void
purple_account_destroy(PurpleAccount *account)
{
- PurpleAccountPrivate *priv = NULL;
GList *l;
g_return_if_fail(account != NULL);
@@ -1095,7 +1072,8 @@ purple_account_destroy(PurpleAccount *account)
purple_account_set_status_types(account, NULL);
- purple_presence_destroy(account->presence);
+ if (account->presence)
+ purple_presence_destroy(account->presence);
if(account->system_log)
purple_log_free(account->system_log);
@@ -1110,13 +1088,11 @@ purple_account_destroy(PurpleAccount *account)
account->permit = g_slist_delete_link(account->permit, account->permit);
}
- priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
- PURPLE_DBUS_UNREGISTER_POINTER(priv->current_error);
- if (priv->current_error) {
- g_free(priv->current_error->description);
- g_free(priv->current_error);
+ PURPLE_DBUS_UNREGISTER_POINTER(account->current_error);
+ if (account->current_error) {
+ g_free(account->current_error->description);
+ g_free(account->current_error);
}
- g_free(priv);
PURPLE_DBUS_UNREGISTER_POINTER(account);
g_free(account);
@@ -1143,6 +1119,15 @@ purple_account_register(PurpleAccount *account)
}
void
+purple_account_register_completed(PurpleAccount *account, gboolean succeeded)
+{
+ g_return_if_fail(account != NULL);
+
+ if (account->registration_cb)
+ (account->registration_cb)(account, succeeded, account->registration_cb_user_data);
+}
+
+void
purple_account_unregister(PurpleAccount *account, PurpleAccountUnregistrationCb cb, void *user_data)
{
g_return_if_fail(account != NULL);
@@ -1289,6 +1274,14 @@ purple_account_disconnect(PurpleAccount *account)
account->disconnecting = FALSE;
}
+gboolean
+purple_account_is_disconnecting(const PurpleAccount *account)
+{
+ g_return_val_if_fail(account != NULL, TRUE);
+
+ return account->disconnecting;
+}
+
void
purple_account_notify_added(PurpleAccount *account, const char *remote_user,
const char *id, const char *alias,
@@ -1615,7 +1608,7 @@ purple_account_request_change_user_info(PurpleAccount *account)
purple_request_input(gc, _("Set User Info"), primary, NULL,
purple_account_get_user_info(account),
TRUE, FALSE, ((gc != NULL) &&
- (gc->flags & PURPLE_CONNECTION_HTML) ? "html" : NULL),
+ (purple_connection_get_flags(gc) & PURPLE_CONNECTION_HTML) ? "html" : NULL),
_("Save"), G_CALLBACK(set_user_info_cb),
_("Cancel"), NULL,
account, NULL, NULL,
@@ -2495,6 +2488,24 @@ purple_account_get_ui_bool(const PurpleAccount *account, const char *ui,
return setting->value.boolean;
}
+gpointer
+purple_account_get_ui_data(const PurpleAccount *account)
+{
+ g_return_val_if_fail(account != NULL, NULL);
+
+ return account->ui_data;
+}
+
+void
+purple_account_set_ui_data(PurpleAccount *account,
+ gpointer ui_data)
+{
+ g_return_if_fail(account != NULL);
+
+ account->ui_data = ui_data;
+}
+
+
PurpleLog *
purple_account_get_log(PurpleAccount *account, gboolean create)
{
@@ -2527,32 +2538,7 @@ purple_account_destroy_log(PurpleAccount *account)
}
void
-purple_account_add_buddy(PurpleAccount *account, PurpleBuddy *buddy)
-{
- PurplePluginProtocolInfo *prpl_info = NULL;
- PurpleConnection *gc;
- PurplePlugin *prpl = NULL;
-
- g_return_if_fail(account != NULL);
- g_return_if_fail(buddy != NULL);
-
- gc = purple_account_get_connection(account);
- if (gc != NULL)
- prpl = purple_connection_get_prpl(gc);
-
- if (prpl != NULL)
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
-
- if (prpl_info != NULL) {
- if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy_with_invite))
- prpl_info->add_buddy_with_invite(gc, buddy, purple_buddy_get_group(buddy), NULL);
- else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy))
- prpl_info->add_buddy(gc, buddy, purple_buddy_get_group(buddy));
- }
-}
-
-void
-purple_account_add_buddy_with_invite(PurpleAccount *account, PurpleBuddy *buddy, const char *message)
+purple_account_add_buddy(PurpleAccount *account, PurpleBuddy *buddy, const char *message)
{
PurplePluginProtocolInfo *prpl_info = NULL;
PurpleConnection *gc;
@@ -2569,15 +2555,13 @@ purple_account_add_buddy_with_invite(PurpleAccount *account, PurpleBuddy *buddy,
prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
if (prpl_info != NULL) {
- if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy_with_invite))
- prpl_info->add_buddy_with_invite(gc, buddy, purple_buddy_get_group(buddy), message);
- else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy))
- prpl_info->add_buddy(gc, buddy, purple_buddy_get_group(buddy));
+ if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy))
+ prpl_info->add_buddy(gc, buddy, purple_buddy_get_group(buddy), message);
}
}
void
-purple_account_add_buddies(PurpleAccount *account, GList *buddies)
+purple_account_add_buddies(PurpleAccount *account, GList *buddies, const char *message)
{
PurplePluginProtocolInfo *prpl_info = NULL;
PurpleConnection *gc = purple_account_get_connection(account);
@@ -2598,73 +2582,13 @@ purple_account_add_buddies(PurpleAccount *account, GList *buddies)
groups = g_list_append(groups, purple_buddy_get_group(buddy));
}
- if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddies_with_invite))
- prpl_info->add_buddies_with_invite(gc, buddies, groups, NULL);
- else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddies))
- prpl_info->add_buddies(gc, buddies, groups);
- else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy_with_invite)) {
- GList *curb = buddies, *curg = groups;
-
- while ((curb != NULL) && (curg != NULL)) {
- prpl_info->add_buddy_with_invite(gc, curb->data, curg->data, NULL);
- curb = curb->next;
- curg = curg->next;
- }
- }
- else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy)) {
- GList *curb = buddies, *curg = groups;
-
- while ((curb != NULL) && (curg != NULL)) {
- prpl_info->add_buddy(gc, curb->data, curg->data);
- curb = curb->next;
- curg = curg->next;
- }
- }
-
- g_list_free(groups);
- }
-}
-
-void
-purple_account_add_buddies_with_invite(PurpleAccount *account, GList *buddies, const char *message)
-{
- PurplePluginProtocolInfo *prpl_info = NULL;
- PurpleConnection *gc = purple_account_get_connection(account);
- PurplePlugin *prpl = NULL;
-
- if (gc != NULL)
- prpl = purple_connection_get_prpl(gc);
-
- if (prpl != NULL)
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
-
- if (prpl_info) {
- GList *cur, *groups = NULL;
-
- /* Make a list of what group each buddy is in */
- for (cur = buddies; cur != NULL; cur = cur->next) {
- PurpleBuddy *buddy = cur->data;
- groups = g_list_append(groups, purple_buddy_get_group(buddy));
- }
-
- if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddies_with_invite))
- prpl_info->add_buddies_with_invite(gc, buddies, groups, message);
- else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy_with_invite)) {
- GList *curb = buddies, *curg = groups;
-
- while ((curb != NULL) && (curg != NULL)) {
- prpl_info->add_buddy_with_invite(gc, curb->data, curg->data, message);
- curb = curb->next;
- curg = curg->next;
- }
- }
- else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddies))
- prpl_info->add_buddies(gc, buddies, groups);
+ if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddies))
+ prpl_info->add_buddies(gc, buddies, groups, message);
else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy)) {
GList *curb = buddies, *curg = groups;
while ((curb != NULL) && (curg != NULL)) {
- prpl_info->add_buddy(gc, curb->data, curg->data);
+ prpl_info->add_buddy(gc, curb->data, curg->data, message);
curb = curb->next;
curg = curg->next;
}
@@ -2804,18 +2728,16 @@ signed_off_cb(PurpleConnection *gc,
static void
set_current_error(PurpleAccount *account, PurpleConnectionErrorInfo *new_err)
{
- PurpleAccountPrivate *priv;
PurpleConnectionErrorInfo *old_err;
g_return_if_fail(account != NULL);
- priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
- old_err = priv->current_error;
+ old_err = account->current_error;
if(new_err == old_err)
return;
- priv->current_error = new_err;
+ account->current_error = new_err;
purple_signal_emit(purple_accounts_get_handle(),
"account-error-changed",
@@ -2857,8 +2779,7 @@ connection_error_cb(PurpleConnection *gc,
const PurpleConnectionErrorInfo *
purple_account_get_current_error(PurpleAccount *account)
{
- PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
- return priv->current_error;
+ return account->current_error;
}
void
diff --git a/libpurple/account.h b/libpurple/account.h
index 80a153b13f..70296b82d9 100644
--- a/libpurple/account.h
+++ b/libpurple/account.h
@@ -168,12 +168,10 @@ struct _PurpleAccount
PurpleAccountRegistrationCb registration_cb;
void *registration_cb_user_data;
- gpointer priv; /**< Pointer to opaque private data. */
+ PurpleConnectionErrorInfo *current_error; /**< Errors */
};
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Account API */
@@ -221,6 +219,15 @@ void purple_account_set_register_callback(PurpleAccount *account, PurpleAccountR
void purple_account_register(PurpleAccount *account);
/**
+ * Registration of the account was completed.
+ * Calls the registration call-back set with purple_account_set_register_callback().
+ *
+ * @param account The account being registered.
+ * @param succeeded Was the account registration successful?
+ */
+void purple_account_register_completed(PurpleAccount *account, gboolean succeeded);
+
+/**
* Unregisters an account (deleting it from the server).
*
* @param account The account to unregister.
@@ -237,6 +244,15 @@ void purple_account_unregister(PurpleAccount *account, PurpleAccountUnregistrati
void purple_account_disconnect(PurpleAccount *account);
/**
+ * Indicates if the account is currently being disconnected.
+ *
+ * @param account The account
+ *
+ * @return TRUE if the account is being disconnected.
+ */
+gboolean purple_account_is_disconnecting(const PurpleAccount *account);
+
+/**
* Notifies the user that the account was added to a remote user's
* buddy list.
*
@@ -433,8 +449,6 @@ void purple_account_set_proxy_info(PurpleAccount *account, PurpleProxyInfo *info
*
* @param account The account.
* @param privacy_type The privacy type.
- *
- * @since 2.7.0
*/
void purple_account_set_privacy_type(PurpleAccount *account, PurplePrivacyType privacy_type);
@@ -491,8 +505,6 @@ void purple_account_set_status_list(PurpleAccount *account,
* is successfully set on the server (or NULL).
* @param failure_cb A callback which will be called if the alias
* is not successfully set on the server (or NULL).
- *
- * @since 2.7.0
*/
void purple_account_set_public_alias(PurpleAccount *account,
const char *alias, PurpleSetPublicAliasSuccessCallback success_cb,
@@ -506,7 +518,6 @@ void purple_account_set_public_alias(PurpleAccount *account,
* @param success_cb A callback which will be called with the alias
* @param failure_cb A callback which will be called if the prpl is
* unable to retrieve the server-side alias.
- * @since 2.7.0
*/
void purple_account_get_public_alias(PurpleAccount *account,
PurpleGetPublicAliasSuccessCallback success_cb,
@@ -542,8 +553,6 @@ void purple_account_clear_settings(PurpleAccount *account);
*
* @param account The account.
* @param setting The setting to remove.
- *
- * @since 2.6.0
*/
void purple_account_remove_setting(PurpleAccount *account, const char *setting);
@@ -610,6 +619,25 @@ void purple_account_set_ui_bool(PurpleAccount *account, const char *ui,
const char *name, gboolean value);
/**
+ * Returns the UI data associated with this account.
+ *
+ * @param account The account.
+ *
+ * @return The UI data associated with this object. This is a
+ * convenience field provided to the UIs--it is not
+ * used by the libuprple core.
+ */
+gpointer purple_account_get_ui_data(const PurpleAccount *account);
+
+/**
+ * Set the UI data associated with this account.
+ *
+ * @param account The account.
+ * @param ui_data A pointer to associate with this object.
+ */
+void purple_account_set_ui_data(PurpleAccount *account, gpointer ui_data);
+
+/**
* Returns whether or not the account is connected.
*
* @param account The account.
@@ -717,8 +745,6 @@ PurpleConnection *purple_account_get_connection(const PurpleAccount *account);
* @param account The account.
*
* @return The name to display.
- *
- * @since 2.7.0
*/
const gchar *purple_account_get_name_for_display(const PurpleAccount *account);
@@ -767,8 +793,6 @@ PurpleProxyInfo *purple_account_get_proxy_info(const PurpleAccount *account);
* @param account The account.
*
* @return The privacy type.
- *
- * @since 2.7.0
*/
PurplePrivacyType purple_account_get_privacy_type(const PurpleAccount *account);
@@ -958,40 +982,18 @@ void purple_account_destroy_log(PurpleAccount *account);
*
* @param account The account.
* @param buddy The buddy to add.
- *
- * @deprecated Use purple_account_add_buddy_with_invite and \c NULL message.
- */
-void purple_account_add_buddy(PurpleAccount *account, PurpleBuddy *buddy);
-/**
- * Adds a buddy to the server-side buddy list for the specified account.
- *
- * @param account The account.
- * @param buddy The buddy to add.
* @param message The invite message. This may be ignored by a prpl.
- *
- * @since 2.8.0
*/
-void purple_account_add_buddy_with_invite(PurpleAccount *account, PurpleBuddy *buddy, const char *message);
+void purple_account_add_buddy(PurpleAccount *account, PurpleBuddy *buddy, const char *message);
/**
* Adds a list of buddies to the server-side buddy list.
*
* @param account The account.
* @param buddies The list of PurpleBlistNodes representing the buddies to add.
- *
- * @deprecated Use purple_account_add_buddies_with_invite and \c NULL message.
- */
-void purple_account_add_buddies(PurpleAccount *account, GList *buddies);
-/**
- * Adds a list of buddies to the server-side buddy list.
- *
- * @param account The account.
- * @param buddies The list of PurpleBlistNodes representing the buddies to add.
* @param message The invite message. This may be ignored by a prpl.
- *
- * @since 2.8.0
*/
-void purple_account_add_buddies_with_invite(PurpleAccount *account, GList *buddies, const char *message);
+void purple_account_add_buddies(PurpleAccount *account, GList *buddies, const char *message);
/**
* Removes a buddy from the server-side buddy list.
@@ -1187,8 +1189,6 @@ void purple_accounts_uninit(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_ACCOUNT_H_ */
diff --git a/libpurple/accountopt.c b/libpurple/accountopt.c
index 726f385f5e..266610c19d 100644
--- a/libpurple/accountopt.c
+++ b/libpurple/accountopt.c
@@ -28,6 +28,51 @@
#include "accountopt.h"
#include "util.h"
+/**
+ * An option for an account.
+ *
+ * This is set by protocol plugins, and appears in the account settings
+ * dialogs.
+ */
+struct _PurpleAccountOption
+{
+ PurplePrefType type; /**< The type of value. */
+
+ char *text; /**< The text that will appear to the user. */
+ char *pref_name; /**< The name of the associated preference. */
+
+ union
+ {
+ gboolean boolean; /**< The default boolean value. */
+ int integer; /**< The default integer value. */
+ char *string; /**< The default string value. */
+ GList *list; /**< The default list value. */
+
+ } default_value;
+
+ gboolean masked; /**< Whether the value entered should be
+ * obscured from view (for passwords and
+ * similar options)
+ */
+};
+
+/**
+ * A username split.
+ *
+ * This is used by some protocols to separate the fields of the username
+ * into more human-readable components.
+ */
+struct _PurpleAccountUserSplit
+{
+ char *text; /**< The text that will appear to the user. */
+ char *default_value; /**< The default value. */
+ char field_sep; /**< The field separator. */
+ gboolean reverse; /**< TRUE if the separator should be found
+ starting a the end of the string, FALSE
+ otherwise */
+};
+
+
PurpleAccountOption *
purple_account_option_new(PurplePrefType type, const char *text,
const char *pref_name)
diff --git a/libpurple/accountopt.h b/libpurple/accountopt.h
index 85aa181149..eed7b4f657 100644
--- a/libpurple/accountopt.h
+++ b/libpurple/accountopt.h
@@ -28,54 +28,16 @@
#include "prefs.h"
-/**
- * An option for an account.
- *
- * This is set by protocol plugins, and appears in the account settings
- * dialogs.
- */
-typedef struct
-{
- PurplePrefType type; /**< The type of value. */
-
- char *text; /**< The text that will appear to the user. */
- char *pref_name; /**< The name of the associated preference. */
-
- union
- {
- gboolean boolean; /**< The default boolean value. */
- int integer; /**< The default integer value. */
- char *string; /**< The default string value. */
- GList *list; /**< The default list value. */
-
- } default_value;
-
- gboolean masked; /**< Whether the value entered should be
- * obscured from view (for passwords and
- * similar options)
- */
-} PurpleAccountOption;
-
-/**
- * A username split.
- *
- * This is used by some protocols to separate the fields of the username
- * into more human-readable components.
- */
-typedef struct
-{
- char *text; /**< The text that will appear to the user. */
- char *default_value; /**< The default value. */
- char field_sep; /**< The field separator. */
- gboolean reverse; /**< TRUE if the separator should be found
- starting a the end of the string, FALSE
- otherwise */
+/**************************************************************************/
+/** Data Structures */
+/**************************************************************************/
-} PurpleAccountUserSplit;
+/** @copydoc _PurpleAccountOption */
+typedef struct _PurpleAccountOption PurpleAccountOption;
+/** @copydoc _PurpleAccountUserSplit */
+typedef struct _PurpleAccountUserSplit PurpleAccountUserSplit;
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Account Option API */
@@ -388,8 +350,6 @@ void purple_account_user_split_set_reverse(PurpleAccountUserSplit *split, gboole
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_ACCOUNTOPT_H_ */
diff --git a/libpurple/blist.c b/libpurple/blist.c
index bd09c6373a..ca64ff5d5c 100644
--- a/libpurple/blist.c
+++ b/libpurple/blist.c
@@ -314,7 +314,7 @@ accountprivacy_to_xmlnode(PurpleAccount *account)
node = xmlnode_new("account");
xmlnode_set_attrib(node, "proto", purple_account_get_protocol_id(account));
xmlnode_set_attrib(node, "name", purple_account_get_username(account));
- g_snprintf(buf, sizeof(buf), "%d", account->perm_deny);
+ g_snprintf(buf, sizeof(buf), "%d", purple_account_get_privacy_type(account));
xmlnode_set_attrib(node, "mode", buf);
for (cur = account->permit; cur; cur = cur->next)
@@ -461,19 +461,16 @@ parse_buddy(PurpleGroup *group, PurpleContact *contact, xmlnode *bnode)
PurpleAccount *account;
PurpleBuddy *buddy;
char *name = NULL, *alias = NULL;
- const char *acct_name, *proto, *protocol;
+ const char *acct_name, *proto;
xmlnode *x;
acct_name = xmlnode_get_attrib(bnode, "account");
- protocol = xmlnode_get_attrib(bnode, "protocol");
- protocol = _purple_oscar_convert(acct_name, protocol); /* XXX: Remove */
proto = xmlnode_get_attrib(bnode, "proto");
- proto = _purple_oscar_convert(acct_name, proto); /* XXX: Remove */
- if (!acct_name || (!proto && !protocol))
+ if (!acct_name || !proto)
return;
- account = purple_accounts_find(acct_name, proto ? proto : protocol);
+ account = purple_accounts_find(acct_name, proto);
if (!account)
return;
@@ -532,19 +529,18 @@ parse_chat(PurpleGroup *group, xmlnode *cnode)
{
PurpleChat *chat;
PurpleAccount *account;
- const char *acct_name, *proto, *protocol;
+ const char *acct_name, *proto;
xmlnode *x;
char *alias = NULL;
GHashTable *components;
acct_name = xmlnode_get_attrib(cnode, "account");
- protocol = xmlnode_get_attrib(cnode, "protocol");
proto = xmlnode_get_attrib(cnode, "proto");
- if (!acct_name || (!proto && !protocol))
+ if (!acct_name || !proto)
return;
- account = purple_accounts_find(acct_name, proto ? proto : protocol);
+ account = purple_accounts_find(acct_name, proto);
if (!account)
return;
@@ -630,23 +626,22 @@ purple_blist_load()
xmlnode *x;
PurpleAccount *account;
int imode;
- const char *acct_name, *proto, *mode, *protocol;
+ const char *acct_name, *proto, *mode;
acct_name = xmlnode_get_attrib(anode, "name");
- protocol = xmlnode_get_attrib(anode, "protocol");
proto = xmlnode_get_attrib(anode, "proto");
mode = xmlnode_get_attrib(anode, "mode");
- if (!acct_name || (!proto && !protocol) || !mode)
+ if (!acct_name || !proto || !mode)
continue;
- account = purple_accounts_find(acct_name, proto ? proto : protocol);
+ account = purple_accounts_find(acct_name, proto);
if (!account)
continue;
imode = atoi(mode);
- account->perm_deny = (imode != 0 ? imode : PURPLE_PRIVACY_ALLOW_ALL);
+ purple_account_set_privacy_type(account, (imode != 0 ? imode : PURPLE_PRIVACY_ALLOW_ALL));
for (x = anode->child; x; x = x->next) {
char *name;
@@ -961,12 +956,6 @@ purple_blist_update_node_icon(PurpleBlistNode *node)
ops->update(purplebuddylist, node);
}
-void
-purple_blist_update_buddy_icon(PurpleBuddy *buddy)
-{
- purple_blist_update_node_icon((PurpleBlistNode *)buddy);
-}
-
/*
* TODO: Maybe remove the call to this from server.c and call it
* from oscar.c and toc.c instead?
@@ -1318,7 +1307,7 @@ void purple_blist_rename_group(PurpleGroup *source, const char *name)
purple_account_remove_buddies(account, buddies, groups);
g_list_free(groups);
- purple_account_add_buddies(account, buddies);
+ purple_account_add_buddies(account, buddies, NULL);
}
g_list_free(buddies);
@@ -1748,11 +1737,6 @@ purple_contact_get_group(const PurpleContact *contact)
return (PurpleGroup *)(((PurpleBlistNode *)contact)->parent);
}
-void purple_contact_set_alias(PurpleContact *contact, const char *alias)
-{
- purple_blist_alias_contact(contact,alias);
-}
-
const char *purple_contact_get_alias(PurpleContact* contact)
{
g_return_val_if_fail(contact != NULL, NULL);
@@ -1790,6 +1774,13 @@ void purple_contact_invalidate_priority_buddy(PurpleContact *contact)
contact->priority_valid = FALSE;
}
+int purple_contact_get_contact_size(PurpleContact *contact, gboolean offline)
+{
+ g_return_val_if_fail(contact != NULL, 0);
+
+ return offline ? contact->totalsize : contact->currentsize;
+}
+
PurpleGroup *purple_group_new(const char *name)
{
PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
@@ -2077,11 +2068,13 @@ void purple_blist_remove_contact(PurpleContact *contact)
{
PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
PurpleBlistNode *node, *gnode;
+ PurpleGroup *group;
g_return_if_fail(contact != NULL);
node = (PurpleBlistNode *)contact;
gnode = node->parent;
+ group = PURPLE_GROUP(gnode);
if (node->child) {
/*
@@ -2106,6 +2099,7 @@ void purple_blist_remove_contact(PurpleContact *contact)
node->prev->next = node->next;
if (node->next)
node->next->prev = node->prev;
+ group->totalsize--;
/* Update the UI */
if (ops && ops->remove)
@@ -2380,26 +2374,6 @@ const char *purple_buddy_get_server_alias(PurpleBuddy *buddy)
return NULL;
}
-const char *purple_buddy_get_local_alias(PurpleBuddy *buddy)
-{
- PurpleContact *c;
-
- g_return_val_if_fail(buddy != NULL, NULL);
-
- /* Search for an alias for the buddy. In order of precedence: */
- /* The buddy alias */
- if (buddy->alias != NULL)
- return buddy->alias;
-
- /* The contact alias */
- c = purple_buddy_get_contact(buddy);
- if ((c != NULL) && (c->alias != NULL))
- return c->alias;
-
- /* The buddy's user name (i.e. no alias) */
- return buddy->name;
-}
-
const char *purple_chat_get_name(PurpleChat *chat)
{
char *ret = NULL;
@@ -2937,6 +2911,17 @@ purple_blist_node_get_type(PurpleBlistNode *node)
return node->type;
}
+gboolean
+purple_blist_node_has_setting(PurpleBlistNode* node, const char *key)
+{
+ g_return_val_if_fail(node != NULL, FALSE);
+ g_return_val_if_fail(node->settings != NULL, FALSE);
+ g_return_val_if_fail(key != NULL, FALSE);
+
+ /* Boxed type, so it won't ever be NULL, so no need for _extended */
+ return (g_hash_table_lookup(node->settings, key) != NULL);
+}
+
void
purple_blist_node_set_bool(PurpleBlistNode* node, const char *key, gboolean data)
{
diff --git a/libpurple/blist.h b/libpurple/blist.h
index a053d081c6..85809421c3 100644
--- a/libpurple/blist.h
+++ b/libpurple/blist.h
@@ -75,9 +75,6 @@ typedef enum
} PurpleBlistNodeFlags;
-/**
- * @since 2.6.0
- */
#define PURPLE_BLIST_NODE(obj) ((PurpleBlistNode *)(obj))
#define PURPLE_BLIST_NODE_HAS_FLAG(b, f) (purple_blist_node_get_flags((PurpleBlistNode*)(b)) & (f))
@@ -86,24 +83,12 @@ typedef enum
#define PURPLE_BLIST_NODE_NAME(n) (purple_blist_node_get_type(n) == PURPLE_BLIST_CHAT_NODE ? purple_chat_get_name((PurpleChat*)n) : \
purple_blist_node_get_type(n) == PURPLE_BLIST_BUDDY_NODE ? purple_buddy_get_name((PurpleBuddy*)n) : NULL)
-/**
- * @since 2.6.0
- */
#define PURPLE_GROUP(obj) ((PurpleGroup *)(obj))
-/**
- * @since 2.6.0
- */
#define PURPLE_CONTACT(obj) ((PurpleContact *)(obj))
-/**
- * @since 2.6.0
- */
#define PURPLE_BUDDY(obj) ((PurpleBuddy *)(obj))
-/**
- * @since 2.6.0
- */
#define PURPLE_CHAT(obj) ((PurpleChat *)(obj))
#include "account.h"
@@ -226,8 +211,6 @@ struct _PurpleBlistUiOps
* previous libpurple versions.
*
* @param node The node which has been modified.
- *
- * @since 2.6.0.
*/
void (*save_node)(PurpleBlistNode *node);
@@ -241,7 +224,6 @@ struct _PurpleBlistUiOps
* previous libpurple versions.
*
* @param node The node which has been modified.
- * @since 2.6.0.
*/
void (*remove_node)(PurpleBlistNode *node);
@@ -256,16 +238,13 @@ struct _PurpleBlistUiOps
*
* @param account The account whose data to save. If NULL, save all data
* for all accounts.
- * @since 2.6.0.
*/
void (*save_account)(PurpleAccount *account);
void (*_purple_reserved1)(void);
};
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Buddy List API */
@@ -311,7 +290,6 @@ PurpleBlistNode *purple_blist_get_root(void);
* freeing the list.
*
* @see purple_find_buddies
- * @since 2.6.0
*/
GSList *purple_blist_get_buddies(void);
@@ -319,8 +297,6 @@ GSList *purple_blist_get_buddies(void);
* Returns the UI data for the list.
*
* @return The UI data for the list.
- *
- * @since 2.6.0
*/
gpointer purple_blist_get_ui_data(void);
@@ -328,8 +304,6 @@ gpointer purple_blist_get_ui_data(void);
* Sets the UI data for the list.
*
* @param ui_data The UI data for the list.
- *
- * @since 2.6.0
*/
void purple_blist_set_ui_data(gpointer ui_data);
@@ -352,7 +326,7 @@ PurpleBlistNode *purple_blist_node_next(PurpleBlistNode *node, gboolean offline)
*
* @param node A node.
* @return The parent node.
- * @since 2.4.0
+ *
* @see purple_blist_node_get_first_child
* @see purple_blist_node_get_sibling_next
* @see purple_blist_node_get_sibling_prev
@@ -365,7 +339,7 @@ PurpleBlistNode *purple_blist_node_get_parent(PurpleBlistNode *node);
*
* @param node A node.
* @return The child node.
- * @since 2.4.0
+ *
* @see purple_blist_node_get_parent
* @see purple_blist_node_get_sibling_next
* @see purple_blist_node_get_sibling_prev
@@ -378,7 +352,7 @@ PurpleBlistNode *purple_blist_node_get_first_child(PurpleBlistNode *node);
*
* @param node A node.
* @return The sibling node.
- * @since 2.4.0
+ *
* @see purple_blist_node_get_parent
* @see purple_blist_node_get_first_child
* @see purple_blist_node_get_sibling_prev
@@ -391,7 +365,7 @@ PurpleBlistNode *purple_blist_node_get_sibling_next(PurpleBlistNode *node);
*
* @param node A node.
* @return The sibling node.
- * @since 2.4.0
+ *
* @see purple_blist_node_get_parent
* @see purple_blist_node_get_first_child
* @see purple_blist_node_get_sibling_next
@@ -404,7 +378,6 @@ PurpleBlistNode *purple_blist_node_get_sibling_prev(PurpleBlistNode *node);
*
* @param node The node.
* @return The UI data.
- * @since 2.6.0
*/
gpointer purple_blist_node_get_ui_data(const PurpleBlistNode *node);
@@ -413,8 +386,6 @@ gpointer purple_blist_node_get_ui_data(const PurpleBlistNode *node);
*
* @param node The node.
* @param ui_data The UI data.
- *
- * @since 2.6.0
*/
void purple_blist_node_set_ui_data(PurpleBlistNode *node, gpointer ui_data);
@@ -454,21 +425,9 @@ void purple_blist_update_buddy_status(PurpleBuddy *buddy, PurpleStatus *old_stat
* Updates a node's custom icon.
*
* @param node The PurpleBlistNode whose custom icon has changed.
- *
- * @since 2.5.0
*/
void purple_blist_update_node_icon(PurpleBlistNode *node);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_BLIST_C_)
-/**
- * Updates a buddy's icon.
- *
- * @param buddy The buddy whose buddy icon has changed
- * @deprecated Use purple_blist_update_node_icon() instead.
- */
-void purple_blist_update_buddy_icon(PurpleBuddy *buddy);
-#endif
-
/**
* Renames a buddy in the buddy list.
*
@@ -623,7 +582,6 @@ PurpleBuddyIcon *purple_buddy_get_icon(const PurpleBuddy *buddy);
* @return The protocol data.
*
* @see purple_buddy_set_protocol_data()
- * @since 2.6.0
*/
gpointer purple_buddy_get_protocol_data(const PurpleBuddy *buddy);
@@ -636,7 +594,6 @@ gpointer purple_buddy_get_protocol_data(const PurpleBuddy *buddy);
* @param data The data.
*
* @see purple_buddy_get_protocol_data()
- * @since 2.6.0
*/
void purple_buddy_set_protocol_data(PurpleBuddy *buddy, gpointer data);
@@ -663,8 +620,6 @@ PurplePresence *purple_buddy_get_presence(const PurpleBuddy *buddy);
*
* @param buddy The buddy.
* @return The media caps.
- *
- * @since 2.7.0
*/
PurpleMediaCaps purple_buddy_get_media_caps(const PurpleBuddy *buddy);
@@ -739,8 +694,6 @@ void purple_contact_destroy(PurpleContact *contact);
*
* @param contact The contact
* @return The group
- *
- * @since 2.7.0
*/
PurpleGroup *purple_contact_get_group(const PurpleContact *contact);
@@ -774,18 +727,6 @@ void purple_blist_merge_contact(PurpleContact *source, PurpleBlistNode *node);
*/
PurpleBuddy *purple_contact_get_priority_buddy(PurpleContact *contact);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_BLIST_C_)
-/**
- * Sets the alias for a contact.
- *
- * @param contact The contact
- * @param alias The alias to set, or NULL to unset
- *
- * @deprecated Use purple_blist_alias_contact() instead.
- */
-void purple_contact_set_alias(PurpleContact *contact, const char *alias);
-#endif
-
/**
* Gets the alias for a contact.
*
@@ -813,6 +754,15 @@ gboolean purple_contact_on_account(PurpleContact *contact, PurpleAccount *accoun
void purple_contact_invalidate_priority_buddy(PurpleContact *contact);
/**
+ * Determines the total size of a contact.
+ *
+ * @param contact The contact
+ * @param offline Count buddies in offline accounts
+ * @return The number of buddies in the contact
+ */
+int purple_contact_get_contact_size(PurpleContact *contact, gboolean offline);
+
+/**
* Removes a buddy from the buddy list and frees the memory allocated to it.
* This doesn't actually try to remove the buddy from the server list.
*
@@ -876,19 +826,6 @@ const char *purple_buddy_get_server_alias(PurpleBuddy *buddy);
*/
const char *purple_buddy_get_contact_alias(PurpleBuddy *buddy);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_BLIST_C_)
-/**
- * Returns the correct alias for this user, ignoring server aliases. Used
- * when a user-recognizable name is required. In order: buddy's alias; buddy's
- * contact alias; buddy's user name.
- *
- * @param buddy The buddy whose alias will be returned.
- * @return The appropriate name or alias.
- * @deprecated Try purple_buddy_get_alias(), if server aliases are okay.
- */
-const char *purple_buddy_get_local_alias(PurpleBuddy *buddy);
-#endif
-
/**
* Returns the correct name to display for a buddy. In order of precedence:
* the buddy's alias; the buddy's server alias; the buddy's contact alias;
@@ -904,8 +841,6 @@ const char *purple_buddy_get_alias(PurpleBuddy *buddy);
*
* @param buddy The buddy
* @return The local alias for the buddy
- *
- * @since 2.6.0
*/
const char *purple_buddy_get_local_buddy_alias(PurpleBuddy *buddy);
@@ -981,8 +916,6 @@ PurpleGroup *purple_chat_get_group(PurpleChat *chat);
* @param chat The chat.
*
* @return The account the chat belongs to.
- *
- * @since 2.4.0
*/
PurpleAccount *purple_chat_get_account(PurpleChat *chat);
@@ -992,8 +925,6 @@ PurpleAccount *purple_chat_get_account(PurpleChat *chat);
* @param chat The chat.
*
* @constreturn The hashtable.
- *
- * @since 2.4.0
*/
GHashTable *purple_chat_get_components(PurpleChat *chat);
@@ -1121,6 +1052,16 @@ void purple_blist_request_add_chat(PurpleAccount *account, PurpleGroup *group,
void purple_blist_request_add_group(void);
/**
+ * Checks whether a named setting exists for a node in the buddy list
+ *
+ * @param node The node to check from which to check settings
+ * @param key The identifier of the data
+ *
+ * @return TRUE if a value exists, or FALSE if there is no setting
+ */
+gboolean purple_blist_node_has_setting(PurpleBlistNode *node, const char *key);
+
+/**
* Associates a boolean with a node in the buddy list
*
* @param node The node to associate the data with
@@ -1211,8 +1152,6 @@ PurpleBlistNodeFlags purple_blist_node_get_flags(PurpleBlistNode *node);
* @param node The node.
*
* @return The type of the node.
- *
- * @since 2.1.0
*/
PurpleBlistNodeType purple_blist_node_get_type(PurpleBlistNode *node);
@@ -1271,8 +1210,6 @@ void purple_blist_uninit(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_BLIST_H_ */
diff --git a/libpurple/buddyicon.c b/libpurple/buddyicon.c
index 6e50a0d403..4738000290 100644
--- a/libpurple/buddyicon.c
+++ b/libpurple/buddyicon.c
@@ -105,9 +105,6 @@ static char *cache_dir = NULL;
/** "Should icons be cached to disk?" */
static gboolean icon_caching = TRUE;
-/* For ~/.gaim to ~/.purple migration. */
-static char *old_icons_dir = NULL;
-
static void delete_buddy_icon_settings(PurpleBlistNode *node, const char *setting_name);
/*
@@ -759,7 +756,7 @@ purple_buddy_icons_set_account_icon(PurpleAccount *account,
else
g_hash_table_remove(pointer_icon_cache, account);
- if (purple_account_is_connected(account))
+ if (!purple_account_is_disconnected(account))
{
PurpleConnection *gc;
PurplePluginProtocolInfo *prpl_info;
@@ -958,31 +955,6 @@ purple_buddy_icons_node_set_custom_icon_from_file(PurpleBlistNode *node,
return purple_buddy_icons_node_set_custom_icon(node, data, len);
}
-gboolean
-purple_buddy_icons_has_custom_icon(PurpleContact *contact)
-{
- return purple_buddy_icons_node_has_custom_icon((PurpleBlistNode*)contact);
-}
-
-PurpleStoredImage *
-purple_buddy_icons_find_custom_icon(PurpleContact *contact)
-{
- return purple_buddy_icons_node_find_custom_icon((PurpleBlistNode*)contact);
-}
-
-PurpleStoredImage *
-purple_buddy_icons_set_custom_icon(PurpleContact *contact, guchar *icon_data,
- size_t icon_len)
-{
- return purple_buddy_icons_node_set_custom_icon((PurpleBlistNode*)contact, icon_data, icon_len);
-}
-
-void
-_purple_buddy_icon_set_old_icons_dir(const char *dirname)
-{
- old_icons_dir = g_strdup(dirname);
-}
-
static void
delete_buddy_icon_settings(PurpleBlistNode *node, const char *setting_name)
{
@@ -995,133 +967,6 @@ delete_buddy_icon_settings(PurpleBlistNode *node, const char *setting_name)
}
}
-static void
-migrate_buddy_icon(PurpleBlistNode *node, const char *setting_name,
- const char *dirname, const char *filename)
-{
- char *path;
-
- if (filename[0] != '/')
- {
- path = g_build_filename(dirname, filename, NULL);
- if (g_file_test(path, G_FILE_TEST_EXISTS))
- {
- g_free(path);
- return;
- }
- g_free(path);
-
- path = g_build_filename(old_icons_dir, filename, NULL);
- }
- else
- path = g_strdup(filename);
-
- if (g_file_test(path, G_FILE_TEST_EXISTS))
- {
- guchar *icon_data;
- size_t icon_len;
- FILE *file;
- char *new_filename;
-
- if (!read_icon_file(path, &icon_data, &icon_len))
- {
- g_free(path);
- delete_buddy_icon_settings(node, setting_name);
- return;
- }
-
- if (icon_data == NULL || icon_len <= 0)
- {
- /* This really applies to the icon_len check.
- * icon_data should never be NULL if
- * read_icon_file() returns TRUE. */
- purple_debug_error("buddyicon", "Empty buddy icon file: %s\n", path);
- delete_buddy_icon_settings(node, setting_name);
- g_free(path);
- return;
- }
-
- g_free(path);
-
- new_filename = purple_util_get_image_filename(icon_data, icon_len);
- if (new_filename == NULL)
- {
- purple_debug_error("buddyicon",
- "New icon filename is NULL. This should never happen! "
- "The old filename was: %s\n", path);
- delete_buddy_icon_settings(node, setting_name);
- g_return_if_reached();
- }
-
- path = g_build_filename(dirname, new_filename, NULL);
- if ((file = g_fopen(path, "wb")) != NULL)
- {
- if (!fwrite(icon_data, icon_len, 1, file))
- {
- purple_debug_error("buddyicon", "Error writing %s: %s\n",
- path, g_strerror(errno));
- }
- else
- purple_debug_info("buddyicon", "Wrote migrated cache file: %s\n", path);
-
- fclose(file);
- }
- else
- {
- purple_debug_error("buddyicon", "Unable to create file %s: %s\n",
- path, g_strerror(errno));
- g_free(new_filename);
- g_free(path);
-
- delete_buddy_icon_settings(node, setting_name);
- return;
- }
- g_free(path);
-
- purple_blist_node_set_string(node,
- setting_name,
- new_filename);
- ref_filename(new_filename);
-
- g_free(new_filename);
-
- if (purple_strequal(setting_name, "buddy_icon"))
- {
- const char *hash;
-
- hash = purple_blist_node_get_string(node, "avatar_hash");
- if (hash != NULL)
- {
- purple_blist_node_set_string(node, "icon_checksum", hash);
- purple_blist_node_remove_setting(node, "avatar_hash");
- }
- else
- {
- PurpleAccount *account = purple_buddy_get_account((PurpleBuddy *)node);
- const char *prpl_id = purple_account_get_protocol_id(account);
-
- if (g_str_equal(prpl_id, "prpl-yahoo") || g_str_equal(prpl_id, "prpl-yahoojp"))
- {
- int checksum = purple_blist_node_get_int(node, "icon_checksum");
- if (checksum != 0)
- {
- char *checksum_str = g_strdup_printf("%i", checksum);
- purple_blist_node_remove_setting(node, "icon_checksum");
- purple_blist_node_set_string(node, "icon_checksum", checksum_str);
- g_free(checksum_str);
- }
- }
- }
- }
- }
- else
- {
- purple_debug_error("buddyicon", "Old icon file doesn't exist: %s\n", path);
- delete_buddy_icon_settings(node, setting_name);
- g_free(path);
- }
-}
-
void
_purple_buddy_icons_account_loaded_cb()
{
@@ -1153,22 +998,6 @@ _purple_buddy_icons_blist_loaded_cb()
PurpleBlistNode *node = purple_blist_get_root();
const char *dirname = purple_buddy_icons_get_cache_dir();
- /* Doing this once here saves having to check it inside a loop. */
- if (old_icons_dir != NULL)
- {
- if (!g_file_test(dirname, G_FILE_TEST_IS_DIR))
- {
- purple_debug_info("buddyicon", "Creating icon cache directory.\n");
-
- if (g_mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0)
- {
- purple_debug_error("buddyicon",
- "Unable to create directory %s: %s\n",
- dirname, g_strerror(errno));
- }
- }
- }
-
while (node != NULL)
{
if (PURPLE_BLIST_NODE_IS_BUDDY(node))
@@ -1178,26 +1007,17 @@ _purple_buddy_icons_blist_loaded_cb()
filename = purple_blist_node_get_string(node, "buddy_icon");
if (filename != NULL)
{
- if (old_icons_dir != NULL)
+ char *path = g_build_filename(dirname, filename, NULL);
+ if (!g_file_test(path, G_FILE_TEST_EXISTS))
{
- migrate_buddy_icon(node,
- "buddy_icon",
- dirname, filename);
+ purple_blist_node_remove_setting(node,
+ "buddy_icon");
+ purple_blist_node_remove_setting(node,
+ "icon_checksum");
}
else
- {
- char *path = g_build_filename(dirname, filename, NULL);
- if (!g_file_test(path, G_FILE_TEST_EXISTS))
- {
- purple_blist_node_remove_setting(node,
- "buddy_icon");
- purple_blist_node_remove_setting(node,
- "icon_checksum");
- }
- else
- ref_filename(filename);
- g_free(path);
- }
+ ref_filename(filename);
+ g_free(path);
}
}
else if (PURPLE_BLIST_NODE_IS_CONTACT(node) ||
@@ -1209,24 +1029,15 @@ _purple_buddy_icons_blist_loaded_cb()
filename = purple_blist_node_get_string(node, "custom_buddy_icon");
if (filename != NULL)
{
- if (old_icons_dir != NULL)
+ char *path = g_build_filename(dirname, filename, NULL);
+ if (!g_file_test(path, G_FILE_TEST_EXISTS))
{
- migrate_buddy_icon(node,
- "custom_buddy_icon",
- dirname, filename);
+ purple_blist_node_remove_setting(node,
+ "custom_buddy_icon");
}
else
- {
- char *path = g_build_filename(dirname, filename, NULL);
- if (!g_file_test(path, G_FILE_TEST_EXISTS))
- {
- purple_blist_node_remove_setting(node,
- "custom_buddy_icon");
- }
- else
- ref_filename(filename);
- g_free(path);
- }
+ ref_filename(filename);
+ g_free(path);
}
}
node = purple_blist_node_next(node, TRUE);
@@ -1298,11 +1109,9 @@ purple_buddy_icons_uninit()
g_hash_table_destroy(icon_data_cache);
g_hash_table_destroy(icon_file_cache);
g_hash_table_destroy(pointer_icon_cache);
- g_free(old_icons_dir);
g_free(cache_dir);
cache_dir = NULL;
- old_icons_dir = NULL;
}
void purple_buddy_icon_get_scale_size(PurpleBuddyIconSpec *spec, int *width, int *height)
diff --git a/libpurple/buddyicon.h b/libpurple/buddyicon.h
index 7fbecbb9a8..873f828304 100644
--- a/libpurple/buddyicon.h
+++ b/libpurple/buddyicon.h
@@ -39,10 +39,7 @@ typedef struct _PurpleBuddyIcon PurpleBuddyIcon;
#include "prpl.h"
#include "util.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Buddy Icon API */
@@ -275,7 +272,6 @@ purple_buddy_icons_get_account_icon_timestamp(PurpleAccount *account);
* @param node The blist node.
*
* @return A boolean indicating if @a node has a custom buddy icon.
- * @since 2.5.0
*/
gboolean
purple_buddy_icons_node_has_custom_icon(PurpleBlistNode *node);
@@ -293,7 +289,6 @@ purple_buddy_icons_node_has_custom_icon(PurpleBlistNode *node);
* @param node The node.
*
* @return The custom buddy icon.
- * @since 2.5.0
*/
PurpleStoredImage *
purple_buddy_icons_node_find_custom_icon(PurpleBlistNode *node);
@@ -311,7 +306,6 @@ purple_buddy_icons_node_find_custom_icon(PurpleBlistNode *node);
*
* @return The icon that was set. The caller does NOT own a reference to this,
* and must call purple_imgstore_ref() if it wants one.
- * @since 2.5.0
*/
PurpleStoredImage *
purple_buddy_icons_node_set_custom_icon(PurpleBlistNode *node,
@@ -329,45 +323,11 @@ purple_buddy_icons_node_set_custom_icon(PurpleBlistNode *node,
*
* @return The icon that was set. The caller does NOT own a reference to this,
* and must call purple_imgstore_ref() if it wants one.
- * @since 2.5.0
*/
PurpleStoredImage *
purple_buddy_icons_node_set_custom_icon_from_file(PurpleBlistNode *node,
const gchar *filename);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_BUDDYICON_C_)
-/**
- * PurpleContact version of purple_buddy_icons_node_has_custom_icon.
- *
- * @copydoc purple_buddy_icons_node_has_custom_icon()
- *
- * @deprecated Use purple_buddy_icons_node_has_custom_icon instead.
- */
-gboolean
-purple_buddy_icons_has_custom_icon(PurpleContact *contact);
-
-/**
- * PurpleContact version of purple_buddy_icons_node_find_custom_icon.
- *
- * @copydoc purple_buddy_icons_node_find_custom_icon()
- *
- * @deprecated Use purple_buddy_icons_node_find_custom_icon instead.
- */
-PurpleStoredImage *
-purple_buddy_icons_find_custom_icon(PurpleContact *contact);
-
-/**
- * PurpleContact version of purple_buddy_icons_node_set_custom_icon.
- *
- * @copydoc purple_buddy_icons_node_set_custom_icon()
- *
- * @deprecated Use purple_buddy_icons_node_set_custom_icon instead.
- */
-PurpleStoredImage *
-purple_buddy_icons_set_custom_icon(PurpleContact *contact,
- guchar *icon_data, size_t icon_len);
-#endif
-
/**
* Sets whether or not buddy icon caching is enabled.
*
@@ -434,8 +394,6 @@ void purple_buddy_icon_get_scale_size(PurpleBuddyIconSpec *spec, int *width, int
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_BUDDYICON_H_ */
diff --git a/libpurple/certificate.c b/libpurple/certificate.c
index 8cc66fb3cd..f714ee3408 100644
--- a/libpurple/certificate.c
+++ b/libpurple/certificate.c
@@ -275,7 +275,7 @@ purple_certificate_signed_by(PurpleCertificate *crt, PurpleCertificate *issuer)
}
gboolean
-purple_certificate_check_signature_chain_with_failing(GList *chain,
+purple_certificate_check_signature_chain(GList *chain,
PurpleCertificate **failing)
{
GList *cur;
@@ -363,12 +363,6 @@ purple_certificate_check_signature_chain_with_failing(GList *chain,
return TRUE;
}
-gboolean
-purple_certificate_check_signature_chain(GList *chain)
-{
- return purple_certificate_check_signature_chain_with_failing(chain, NULL);
-}
-
PurpleCertificate *
purple_certificate_import(PurpleCertificateScheme *scheme, const gchar *filename)
{
@@ -505,6 +499,42 @@ purple_certificate_get_times(PurpleCertificate *crt, time_t *activation, time_t
return (scheme->get_times)(crt, activation, expiration);
}
+GByteArray *
+purple_certificate_get_der_data(PurpleCertificate *crt)
+{
+ PurpleCertificateScheme *scheme;
+ GByteArray *data;
+
+ g_return_val_if_fail(crt, NULL);
+ g_return_val_if_fail(crt->scheme, NULL);
+
+ scheme = crt->scheme;
+
+ g_return_val_if_fail(scheme->get_der_data, NULL);
+
+ data = (scheme->get_der_data)(crt);
+
+ return data;
+}
+
+gchar *
+purple_certificate_get_display_string(PurpleCertificate *crt)
+{
+ PurpleCertificateScheme *scheme;
+ gchar *str;
+
+ g_return_val_if_fail(crt, NULL);
+ g_return_val_if_fail(crt->scheme, NULL);
+
+ scheme = crt->scheme;
+
+ g_return_val_if_fail(scheme->get_display_string, NULL);
+
+ str = (scheme->get_display_string)(crt);
+
+ return str;
+}
+
gchar *
purple_certificate_pool_mkpath(PurpleCertificatePool *pool, const gchar *id)
{
@@ -650,77 +680,62 @@ purple_certificate_pool_destroy_idlist(GList *idlist)
/****************************************************************************/
static void
-x509_singleuse_verify_cb (PurpleCertificateVerificationRequest *vrq, gint id)
+x509_singleuse_verify_accept_cb(PurpleCertificateVerificationRequest *vrq)
{
g_return_if_fail(vrq);
purple_debug_info("certificate/x509_singleuse",
- "VRQ on cert from %s gave %d\n",
- vrq->subject_name, id);
-
- /* Signal what happened back to the caller */
- if (1 == id) {
- /* Accepted! */
- purple_certificate_verify_complete(vrq,
- PURPLE_CERTIFICATE_VALID);
- } else {
- /* Not accepted */
- purple_certificate_verify_complete(vrq,
- PURPLE_CERTIFICATE_INVALID);
+ "VRQ on cert from %s accepted\n",
+ vrq->subject_name);
- }
+ purple_certificate_verify_complete(vrq, PURPLE_CERTIFICATE_VALID);
+}
+
+static void
+x509_singleuse_verify_reject_cb(PurpleCertificateVerificationRequest *vrq)
+{
+ g_return_if_fail(vrq);
+
+ purple_debug_info("certificate/x509_singleuse",
+ "VRQ on cert from %s rejected\n",
+ vrq->subject_name);
+
+ purple_certificate_verify_complete(vrq, PURPLE_CERTIFICATE_INVALID);
}
static void
x509_singleuse_start_verify (PurpleCertificateVerificationRequest *vrq)
{
- gchar *sha_asc;
- GByteArray *sha_bin;
gchar *cn;
const gchar *cn_match;
gchar *primary, *secondary;
- PurpleCertificate *crt = (PurpleCertificate *) vrq->cert_chain->data;
-
- /* Pull out the SHA1 checksum */
- sha_bin = purple_certificate_get_fingerprint_sha1(crt);
- /* Now decode it for display */
- sha_asc = purple_base16_encode_chunked(sha_bin->data,
- sha_bin->len);
+ PurpleCertificate *crt = (PurpleCertificate *)vrq->cert_chain->data;
- /* Get the cert Common Name */
cn = purple_certificate_get_subject_name(crt);
- /* Determine whether the name matches */
if (purple_certificate_check_subject_name(crt, vrq->subject_name)) {
- cn_match = "";
+ cn_match = _("(MATCH)");
} else {
cn_match = _("(DOES NOT MATCH)");
}
- /* Make messages */
primary = g_strdup_printf(_("%s has presented the following certificate for just-this-once use:"), vrq->subject_name);
- secondary = g_strdup_printf(_("Common name: %s %s\nFingerprint (SHA1): %s"), cn, cn_match, sha_asc);
+ secondary = g_strdup_printf(_("Common name: %s %s"), cn, cn_match);
/* Make a semi-pretty display */
- purple_request_accept_cancel(
+ purple_request_certificate(
vrq->cb_data, /* TODO: Find what the handle ought to be */
_("Single-use Certificate Verification"),
primary,
secondary,
- 0, /* Accept by default */
- NULL, /* No account */
- NULL, /* No other user */
- NULL, /* No associated conversation */
- vrq,
- x509_singleuse_verify_cb,
- x509_singleuse_verify_cb );
-
- /* Cleanup */
+ crt,
+ _("Accept"), G_CALLBACK(x509_singleuse_verify_accept_cb),
+ _("Reject"), G_CALLBACK(x509_singleuse_verify_reject_cb),
+ vrq);
+
g_free(cn);
g_free(primary);
g_free(secondary);
- g_free(sha_asc);
- g_byte_array_free(sha_bin, TRUE);
}
static void
@@ -1277,102 +1292,34 @@ static PurpleCertificatePool x509_tls_peers = {
static PurpleCertificateVerifier x509_tls_cached;
-/* The following is several hacks piled together and needs to be fixed.
- * It exists because show_cert (see its comments) needs the original reason
- * given to user_auth in order to rebuild the dialog.
- */
-/* TODO: This will cause a ua_ctx to become memleaked if the request(s) get
- closed by handle or otherwise abnormally. */
-typedef struct {
- PurpleCertificateVerificationRequest *vrq;
- gchar *reason;
-} x509_tls_cached_ua_ctx;
-
-static x509_tls_cached_ua_ctx *
-x509_tls_cached_ua_ctx_new(PurpleCertificateVerificationRequest *vrq,
- const gchar *reason)
-{
- x509_tls_cached_ua_ctx *c;
-
- c = g_new0(x509_tls_cached_ua_ctx, 1);
- c->vrq = vrq;
- c->reason = g_strdup(reason);
-
- return c;
-}
-
-
static void
-x509_tls_cached_ua_ctx_free(x509_tls_cached_ua_ctx *c)
+x509_tls_cached_user_auth_accept_cb(PurpleCertificateVerificationRequest *vrq)
{
- g_return_if_fail(c);
- g_free(c->reason);
- g_free(c);
-}
-
-static void
-x509_tls_cached_user_auth(PurpleCertificateVerificationRequest *vrq,
- const gchar *reason);
-
-static void
-x509_tls_cached_show_cert(x509_tls_cached_ua_ctx *c, gint id)
-{
- PurpleCertificate *disp_crt = c->vrq->cert_chain->data;
-
- /* Since clicking a button closes the request, show it again */
- x509_tls_cached_user_auth(c->vrq, c->reason);
-
- /* Show the certificate AFTER re-opening the dialog so that this
- appears above the other */
- purple_certificate_display_x509(disp_crt);
-
- x509_tls_cached_ua_ctx_free(c);
-}
-
-static void
-x509_tls_cached_user_auth_cb (x509_tls_cached_ua_ctx *c, gint id)
-{
- PurpleCertificateVerificationRequest *vrq;
PurpleCertificatePool *tls_peers;
+ gchar *cache_id;
- g_return_if_fail(c);
- g_return_if_fail(c->vrq);
-
- vrq = c->vrq;
-
- x509_tls_cached_ua_ctx_free(c);
+ g_return_if_fail(vrq);
- tls_peers = purple_certificate_find_pool("x509","tls_peers");
+ tls_peers = purple_certificate_find_pool("x509", "tls_peers");
- if (2 == id) {
- gchar *cache_id = vrq->subject_name;
- purple_debug_info("certificate/x509/tls_cached",
+ cache_id = vrq->subject_name;
+ purple_debug_info("certificate/x509/tls_cached",
"User ACCEPTED cert\nCaching first in chain for future use as %s...\n",
cache_id);
- purple_certificate_pool_store(tls_peers, cache_id,
- vrq->cert_chain->data);
+ purple_certificate_pool_store(tls_peers, cache_id, vrq->cert_chain->data);
- purple_certificate_verify_complete(vrq,
- PURPLE_CERTIFICATE_VALID);
- } else {
- purple_debug_warning("certificate/x509/tls_cached",
- "User REJECTED cert\n");
- purple_certificate_verify_complete(vrq,
- PURPLE_CERTIFICATE_INVALID);
- }
+ purple_certificate_verify_complete(vrq, PURPLE_CERTIFICATE_VALID);
}
static void
-x509_tls_cached_user_auth_accept_cb(x509_tls_cached_ua_ctx *c, gint ignore)
+x509_tls_cached_user_auth_reject_cb(PurpleCertificateVerificationRequest *vrq)
{
- x509_tls_cached_user_auth_cb(c, 2);
-}
+ g_return_if_fail(vrq);
-static void
-x509_tls_cached_user_auth_reject_cb(x509_tls_cached_ua_ctx *c, gint ignore)
-{
- x509_tls_cached_user_auth_cb(c, 1);
+ purple_debug_warning("certificate/x509/tls_cached", "User REJECTED cert\n");
+
+ purple_certificate_verify_complete(vrq, PURPLE_CERTIFICATE_INVALID);
}
/** Validates a certificate by asking the user
@@ -1386,27 +1333,19 @@ x509_tls_cached_user_auth(PurpleCertificateVerificationRequest *vrq,
{
gchar *primary;
- /* Make messages */
primary = g_strdup_printf(_("Accept certificate for %s?"),
vrq->subject_name);
- /* Make a semi-pretty display */
- purple_request_action(
+ purple_request_certificate(
vrq->cb_data, /* TODO: Find what the handle ought to be */
_("SSL Certificate Verification"),
primary,
reason,
- 0, /* Accept by default */
- NULL, /* No account */
- NULL, /* No other user */
- NULL, /* No associated conversation */
- x509_tls_cached_ua_ctx_new(vrq, reason),
- 3, /* Number of actions */
- _("Accept"), x509_tls_cached_user_auth_accept_cb,
- _("Reject"), x509_tls_cached_user_auth_reject_cb,
- _("_View Certificate..."), x509_tls_cached_show_cert);
-
- /* Cleanup */
+ vrq->cert_chain->data,
+ _("Accept"), G_CALLBACK(x509_tls_cached_user_auth_accept_cb),
+ _("Reject"), G_CALLBACK(x509_tls_cached_user_auth_reject_cb),
+ vrq);
+
g_free(primary);
}
@@ -1622,7 +1561,7 @@ x509_tls_cached_unknown_peer(PurpleCertificateVerificationRequest *vrq,
ca = purple_certificate_find_pool(x509_tls_cached.scheme_name, "ca");
/* Next, check that the certificate chain is valid */
- if (!purple_certificate_check_signature_chain_with_failing(chain,
+ if (!purple_certificate_check_signature_chain(chain,
&failing_crt))
{
gboolean chain_validated = FALSE;
@@ -1704,7 +1643,7 @@ x509_tls_cached_unknown_peer(PurpleCertificateVerificationRequest *vrq,
flags |= PURPLE_CERTIFICATE_CA_UNKNOWN;
purple_debug_warning("certificate/x509/tls_cached",
- "No Certificate Authorities with either DN found "
+ "No Certificate Authorities with either DN "
"found. I'll prompt the user, I guess.\n");
x509_tls_cached_check_subject_name(vrq, flags);
@@ -2153,63 +2092,6 @@ purple_certificate_unregister_pool(PurpleCertificatePool *pool)
/* Scheme-specific functions */
/****************************************************************************/
-void
-purple_certificate_display_x509(PurpleCertificate *crt)
-{
- gchar *sha_asc;
- GByteArray *sha_bin;
- gchar *cn;
- time_t activation, expiration;
- gchar *activ_str, *expir_str;
- gchar *secondary;
-
- /* Pull out the SHA1 checksum */
- sha_bin = purple_certificate_get_fingerprint_sha1(crt);
- /* Now decode it for display */
- sha_asc = purple_base16_encode_chunked(sha_bin->data,
- sha_bin->len);
-
- /* Get the cert Common Name */
- /* TODO: Will break on CA certs */
- cn = purple_certificate_get_subject_name(crt);
-
- /* Get the certificate times */
- /* TODO: Check the times against localtime */
- /* TODO: errorcheck? */
- if (!purple_certificate_get_times(crt, &activation, &expiration)) {
- purple_debug_error("certificate",
- "Failed to get certificate times!\n");
- activation = expiration = 0;
- }
- activ_str = g_strdup(ctime(&activation));
- expir_str = g_strdup(ctime(&expiration));
-
- /* Make messages */
- secondary = g_strdup_printf(_("Common name: %s\n\n"
- "Fingerprint (SHA1): %s\n\n"
- "Activation date: %s\n"
- "Expiration date: %s\n"),
- cn ? cn : "(null)",
- sha_asc ? sha_asc : "(null)",
- activ_str ? activ_str : "(null)",
- expir_str ? expir_str : "(null)");
-
- /* Make a semi-pretty display */
- purple_notify_info(
- NULL, /* TODO: Find what the handle ought to be */
- _("Certificate Information"),
- "",
- secondary);
-
- /* Cleanup */
- g_free(cn);
- g_free(secondary);
- g_free(sha_asc);
- g_free(activ_str);
- g_free(expir_str);
- g_byte_array_free(sha_bin, TRUE);
-}
-
void purple_certificate_add_ca_search_path(const char *path)
{
if (g_list_find_custom(x509_ca_paths, path, (GCompareFunc)strcmp))
diff --git a/libpurple/certificate.h b/libpurple/certificate.h
index 66d961770c..96b1da5280 100644
--- a/libpurple/certificate.h
+++ b/libpurple/certificate.h
@@ -2,7 +2,6 @@
* @file certificate.h Public-Key Certificate API
* @ingroup core
* @see @ref certificate-signals
- * @since 2.2.0
*/
/*
@@ -35,11 +34,6 @@
#include <glib.h>
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
typedef enum
{
PURPLE_CERTIFICATE_INVALID = 0,
@@ -258,9 +252,25 @@ struct _PurpleCertificateScheme
*/
GSList * (* import_certificates)(const gchar * filename);
+ /**
+ * Retrieves the certificate data in DER form
+ *
+ * @param crt Certificate instance
+ * @return Binary DER representation of certificate - must be freed using
+ * g_byte_array_free()
+ */
+ GByteArray * (* get_der_data)(PurpleCertificate *crt);
+
+ /**
+ * Retrieves a string representation of the certificate suitable for display
+ *
+ * @param crt Certificate instance
+ * @return User-displayable string representation of certificate - must be
+ * freed using g_free().
+ */
+ gchar * (* get_display_string)(PurpleCertificate *crt);
+
void (*_purple_reserved1)(void);
- void (*_purple_reserved2)(void);
- void (*_purple_reserved3)(void);
};
/** A set of operations used to provide logic for verifying a Certificate's
@@ -350,6 +360,8 @@ struct _PurpleCertificateVerificationRequest
gpointer cb_data;
};
+G_BEGIN_DECLS
+
/*****************************************************************************/
/** @name Certificate Verification Functions */
/*****************************************************************************/
@@ -462,33 +474,12 @@ purple_certificate_signed_by(PurpleCertificate *crt, PurpleCertificate *issuer);
* chain fails to validate, this will be set to the
* certificate whose signature could not be validated.
* @return TRUE if the chain is valid. See description.
- *
- * @since 2.6.0
- * @deprecated This function will become
- * purple_certificate_check_signature_chain in 3.0.0
*/
gboolean
-purple_certificate_check_signature_chain_with_failing(GList *chain,
+purple_certificate_check_signature_chain(GList *chain,
PurpleCertificate **failing);
/**
- * Check that a certificate chain is valid
- *
- * Uses purple_certificate_signed_by() to verify that each PurpleCertificate
- * in the chain carries a valid signature from the next. A single-certificate
- * chain is considered to be valid.
- *
- * @param chain List of PurpleCertificate instances comprising the chain,
- * in the order certificate, issuer, issuer's issuer, etc.
- * @return TRUE if the chain is valid. See description.
- * @todo Specify which certificate in the chain caused a failure
- * @deprecated This function will be removed in 3.0.0 and replaced with
- * purple_certificate_check_signature_chain_with_failing
- */
-gboolean
-purple_certificate_check_signature_chain(GList *chain);
-
-/**
* Imports a PurpleCertificate from a file
*
* @param scheme Scheme to import under
@@ -583,6 +574,28 @@ purple_certificate_check_subject_name(PurpleCertificate *crt, const gchar *name)
gboolean
purple_certificate_get_times(PurpleCertificate *crt, time_t *activation, time_t *expiration);
+/**
+ * Retrieves the certificate data in DER form.
+ *
+ * @param crt Certificate instance
+ *
+ * @return Binary DER representation of the certificate - must be freed using
+ * g_byte_array_free().
+ */
+GByteArray *
+purple_certificate_get_der_data(PurpleCertificate *crt);
+
+/**
+ * Retrieves a string suitable for displaying a certificate to the user.
+ *
+ * @param crt Certificate instance
+ *
+ * @return String representing the certificate that may be displayed to the user
+ * - must be freed using g_free().
+ */
+char *
+purple_certificate_get_display_string(PurpleCertificate *crt);
+
/*@}*/
/*****************************************************************************/
@@ -821,23 +834,12 @@ purple_certificate_unregister_pool(PurpleCertificatePool *pool);
/**
- * Displays a window showing X.509 certificate information
- *
- * @param crt Certificate under an "x509" Scheme
- * @todo Will break on CA certs, as they have no Common Name
- */
-void
-purple_certificate_display_x509(PurpleCertificate *crt);
-
-/**
* Add a search path for certificates.
*
* @param path Path to search for certificates.
*/
void purple_certificate_add_ca_search_path(const char *path);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+G_END_DECLS
#endif /* _PURPLE_CERTIFICATE_H */
diff --git a/libpurple/cipher.h b/libpurple/cipher.h
index b6479c69db..1d19212a94 100644
--- a/libpurple/cipher.h
+++ b/libpurple/cipher.h
@@ -41,7 +41,7 @@ typedef struct _PurpleCipherContext PurpleCipherContext; /**< A context for a Pu
/**
* Modes for batch encrypters
*/
-typedef enum _PurpleCipherBatchMode {
+typedef enum {
PURPLE_CIPHER_BATCH_MODE_ECB,
PURPLE_CIPHER_BATCH_MODE_CBC
} PurpleCipherBatchMode;
@@ -49,7 +49,7 @@ typedef enum _PurpleCipherBatchMode {
/**
* The operation flags for a cipher
*/
-typedef enum _PurpleCipherCaps {
+typedef enum {
PURPLE_CIPHER_CAPS_SET_OPT = 1 << 1, /**< Set option flag */
PURPLE_CIPHER_CAPS_GET_OPT = 1 << 2, /**< Get option flag */
PURPLE_CIPHER_CAPS_INIT = 1 << 3, /**< Init flag */
diff --git a/libpurple/circbuffer.h b/libpurple/circbuffer.h
index 77e7724161..7e9283404c 100644
--- a/libpurple/circbuffer.h
+++ b/libpurple/circbuffer.h
@@ -26,10 +26,6 @@
#include <glib.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct _PurpleCircBuffer {
/** A pointer to the starting address of our chunk of memory. */
@@ -55,6 +51,8 @@ typedef struct _PurpleCircBuffer {
} PurpleCircBuffer;
+G_BEGIN_DECLS
+
/**
* Creates a new circular buffer. This will not allocate any memory for the
* actual buffer until data is appended to it.
@@ -111,8 +109,6 @@ gsize purple_circ_buffer_get_max_read(const PurpleCircBuffer *buf);
*/
gboolean purple_circ_buffer_mark_read(PurpleCircBuffer *buf, gsize len);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _CIRCBUFFER_H */
diff --git a/libpurple/cmds.c b/libpurple/cmds.c
index 6a495acd06..b29e4c4818 100644
--- a/libpurple/cmds.c
+++ b/libpurple/cmds.c
@@ -385,5 +385,10 @@ void purple_cmds_init(void)
void purple_cmds_uninit(void)
{
purple_signals_unregister_by_instance(purple_cmds_get_handle());
+
+ while (cmds) {
+ purple_cmd_free(cmds->data);
+ cmds = g_list_delete_link(cmds, cmds);
+ }
}
diff --git a/libpurple/cmds.h b/libpurple/cmds.h
index 5e189928f7..80549afdf1 100644
--- a/libpurple/cmds.h
+++ b/libpurple/cmds.h
@@ -32,7 +32,7 @@
/*@{*/
/** The possible results of running a command with purple_cmd_do_command(). */
-typedef enum _PurpleCmdStatus {
+typedef enum {
PURPLE_CMD_STATUS_OK,
PURPLE_CMD_STATUS_FAILED,
PURPLE_CMD_STATUS_NOT_FOUND,
@@ -48,7 +48,7 @@ typedef enum _PurpleCmdStatus {
* #PURPLE_CMD_RET_CONTINUE to cause the core to fall through to other
* commands with the same name.
*/
-typedef enum _PurpleCmdRet {
+typedef enum {
PURPLE_CMD_RET_OK, /**< Everything's okay; Don't look for another command to call. */
PURPLE_CMD_RET_FAILED, /**< The command failed, but stop looking.*/
PURPLE_CMD_RET_CONTINUE /**< Continue, looking for other commands with the same name to call. */
@@ -68,7 +68,7 @@ typedef PurpleCmdRet (*PurpleCmdFunc)(PurpleConversation *, const gchar *cmd,
*/
typedef guint PurpleCmdId;
-typedef enum _PurpleCmdPriority {
+typedef enum {
PURPLE_CMD_P_VERY_LOW = -1000,
PURPLE_CMD_P_LOW = 0,
PURPLE_CMD_P_DEFAULT = 1000,
@@ -85,7 +85,7 @@ typedef enum _PurpleCmdPriority {
*
* @see purple_cmd_register
*/
-typedef enum _PurpleCmdFlag {
+typedef enum {
/** Command is usable in IMs. */
PURPLE_CMD_FLAG_IM = 0x01,
/** Command is usable in multi-user chats. */
@@ -99,9 +99,7 @@ typedef enum _PurpleCmdFlag {
/*@}*/
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Commands API */
@@ -225,26 +223,21 @@ GList *purple_cmd_help(PurpleConversation *conv, const gchar *cmd);
/**
* Get the handle for the commands API
* @return The handle
- * @since 2.5.0
*/
gpointer purple_cmds_get_handle(void);
/**
* Initialize the commands subsystem.
- * @since 2.5.0
*/
void purple_cmds_init(void);
/**
* Uninitialize the commands subsystem.
- * @since 2.5.0
*/
void purple_cmds_uninit(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_CMDS_H_ */
diff --git a/libpurple/connection.c b/libpurple/connection.c
index 9e0055fb17..8a67a550e4 100644
--- a/libpurple/connection.c
+++ b/libpurple/connection.c
@@ -92,12 +92,6 @@ update_keepalive(PurpleConnection *gc, gboolean on)
}
void
-purple_connection_new(PurpleAccount *account, gboolean regist, const char *password)
-{
- _purple_connection_new(account, regist, password);
-}
-
-void
_purple_connection_new(PurpleAccount *account, gboolean regist, const char *password)
{
PurpleConnection *gc;
@@ -171,11 +165,6 @@ _purple_connection_new(PurpleAccount *account, gboolean regist, const char *pass
prpl_info->login(account);
}
}
-void
-purple_connection_new_unregister(PurpleAccount *account, const char *password, PurpleAccountUnregistrationCb cb, void *user_data)
-{
- _purple_connection_new_unregister(account, password, cb, user_data);
-}
void
_purple_connection_new_unregister(PurpleAccount *account, const char *password, PurpleAccountUnregistrationCb cb, void *user_data)
@@ -234,12 +223,6 @@ _purple_connection_new_unregister(PurpleAccount *account, const char *password,
}
void
-purple_connection_destroy(PurpleConnection *gc)
-{
- _purple_connection_destroy(gc);
-}
-
-void
_purple_connection_destroy(PurpleConnection *gc)
{
PurpleAccount *account;
@@ -404,6 +387,14 @@ purple_connection_set_state(PurpleConnection *gc, PurpleConnectionState state)
}
void
+purple_connection_set_flags(PurpleConnection *gc, PurpleConnectionFlags flags)
+{
+ g_return_if_fail(gc != NULL);
+
+ gc->flags = flags;
+}
+
+void
purple_connection_set_account(PurpleConnection *gc, PurpleAccount *account)
{
g_return_if_fail(gc != NULL);
@@ -436,6 +427,14 @@ purple_connection_get_state(const PurpleConnection *gc)
return gc->state;
}
+PurpleConnectionFlags
+purple_connection_get_flags(const PurpleConnection *gc)
+{
+ g_return_val_if_fail(gc != NULL, 0);
+
+ return gc->flags;
+}
+
PurpleAccount *
purple_connection_get_account(const PurpleConnection *gc)
{
@@ -457,7 +456,7 @@ purple_connection_get_password(const PurpleConnection *gc)
{
g_return_val_if_fail(gc != NULL, NULL);
- return gc->password ? gc->password : gc->account->password;
+ return gc->password ? gc->password : purple_account_get_password(gc->account);
}
const char *
@@ -528,22 +527,7 @@ purple_connection_disconnect_cb(gpointer data)
}
void
-purple_connection_error(PurpleConnection *gc, const char *text)
-{
- /* prpls that have not been updated to use disconnection reasons will
- * be setting wants_to_die before calling this function, so choose
- * PURPLE_CONNECTION_ERROR_OTHER_ERROR (which is fatal) if it's true,
- * and PURPLE_CONNECTION_ERROR_NETWORK_ERROR (which isn't) if not. See
- * the documentation in connection.h.
- */
- PurpleConnectionError reason = gc->wants_to_die
- ? PURPLE_CONNECTION_ERROR_OTHER_ERROR
- : PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
- purple_connection_error_reason (gc, reason, text);
-}
-
-void
-purple_connection_error_reason (PurpleConnection *gc,
+purple_connection_error (PurpleConnection *gc,
PurpleConnectionError reason,
const char *description)
{
@@ -557,13 +541,13 @@ purple_connection_error_reason (PurpleConnection *gc,
*/
if (reason > PURPLE_CONNECTION_ERROR_OTHER_ERROR) {
purple_debug_error("connection",
- "purple_connection_error_reason: reason %u isn't a "
+ "purple_connection_error: reason %u isn't a "
"valid reason\n", reason);
reason = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
}
if (description == NULL) {
- purple_debug_error("connection", "purple_connection_error_reason called with NULL description\n");
+ purple_debug_error("connection", "purple_connection_error called with NULL description\n");
description = _("Unknown error");
}
@@ -578,13 +562,8 @@ purple_connection_error_reason (PurpleConnection *gc,
ops = purple_connections_get_ui_ops();
- if (ops != NULL)
- {
- if (ops->report_disconnect_reason != NULL)
- ops->report_disconnect_reason (gc, reason, description);
- if (ops->report_disconnect != NULL)
- ops->report_disconnect (gc, description);
- }
+ if (ops && ops->report_disconnect)
+ ops->report_disconnect(gc, reason, description);
purple_signal_emit(purple_connections_get_handle(), "connection-error",
gc, reason, description);
@@ -615,7 +594,7 @@ purple_connection_ssl_error (PurpleConnection *gc,
reason = PURPLE_CONNECTION_ERROR_CERT_OTHER_ERROR;
}
- purple_connection_error_reason (gc, reason,
+ purple_connection_error (gc, reason,
purple_ssl_strerror(ssl_error));
}
@@ -648,6 +627,13 @@ purple_connection_error_is_fatal (PurpleConnectionError reason)
}
}
+void purple_connection_update_last_received(PurpleConnection *gc)
+{
+ g_return_if_fail(gc != NULL);
+
+ gc->last_received = time(NULL);
+}
+
void
purple_connections_disconnect_all(void)
{
diff --git a/libpurple/connection.h b/libpurple/connection.h
index 1eb7c15173..65c88d61b1 100644
--- a/libpurple/connection.h
+++ b/libpurple/connection.h
@@ -59,8 +59,6 @@ typedef enum
/**
* Possible errors that can cause a connection to be closed.
- *
- * @since 2.3.0
*/
typedef enum
{
@@ -128,7 +126,7 @@ typedef enum
/** Some other error occurred which fits into none of the other
* categories.
*/
- /* purple_connection_error_reason() in connection.c uses the fact that
+ /* purple_connection_error() in connection.c uses the fact that
* this is the last member of the enum when sanity-checking; if other
* reasons are added after it, the check must be updated.
*/
@@ -194,16 +192,6 @@ typedef struct
void (*notice)(PurpleConnection *gc, const char *text);
/**
- * Called when an error causes a connection to be disconnected.
- * Called before #disconnected.
- * @param text a localized error message.
- * @see #purple_connection_error
- * @deprecated in favour of
- * #PurpleConnectionUiOps.report_disconnect_reason.
- */
- void (*report_disconnect)(PurpleConnection *gc, const char *text);
-
- /**
* Called when libpurple discovers that the computer's network
* connection is active. On Linux, this uses Network Manager if
* available; on Windows, it uses Win32's network change notification
@@ -219,21 +207,17 @@ typedef struct
/**
* Called when an error causes a connection to be disconnected.
- * Called before #disconnected. This op is intended to replace
- * #report_disconnect. If both are implemented, this will be called
- * first; however, there's no real reason to implement both.
- *
- * @param reason why the connection ended, if known, or
- * #PURPLE_CONNECTION_ERROR_OTHER_ERROR, if not.
- * @param text a localized message describing the disconnection
- * in more detail to the user.
- * @see #purple_connection_error_reason
+ * Called before #disconnected.
*
- * @since 2.3.0
+ * @param reason why the connection ended, if known, or
+ * #PURPLE_CONNECTION_ERROR_OTHER_ERROR, if not.
+ * @param text a localized message describing the disconnection
+ * in more detail to the user.
+ * @see #purple_connection_error
*/
- void (*report_disconnect_reason)(PurpleConnection *gc,
- PurpleConnectionError reason,
- const char *text);
+ void (*report_disconnect)(PurpleConnection *gc,
+ PurpleConnectionError reason,
+ const char *text);
void (*_purple_reserved1)(void);
void (*_purple_reserved2)(void);
@@ -251,7 +235,6 @@ struct _PurpleConnection
PurpleAccount *account; /**< The account being connected to. */
char *password; /**< The password used. */
- int inpa; /**< The input watcher. */
GSList *buddy_chats; /**< A list of active chats
(#PurpleConversation structs of type
@@ -264,7 +247,7 @@ struct _PurpleConnection
/** Wants to Die state. This is set when the user chooses to log out, or
* when the protocol is disconnected and should not be automatically
* reconnected (incorrect password, etc.). prpls should rely on
- * purple_connection_error_reason() to set this for them rather than
+ * purple_connection_error() to set this for them rather than
* setting it themselves.
* @see purple_connection_error_is_fatal
*/
@@ -275,72 +258,13 @@ struct _PurpleConnection
prpl to avoid sending unneeded keepalives */
};
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Connection API */
/**************************************************************************/
/*@{*/
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_CONNECTION_C_)
-/**
- * This function should only be called by purple_account_connect()
- * in account.c. If you're trying to sign on an account, use that
- * function instead.
- *
- * Creates a connection to the specified account and either connects
- * or attempts to register a new account. If you are logging in,
- * the connection uses the current active status for this account.
- * So if you want to sign on as "away," for example, you need to
- * have called purple_account_set_status(account, "away").
- * (And this will call purple_account_connect() automatically).
- *
- * @param account The account the connection should be connecting to.
- * @param regist Whether we are registering a new account or just
- * trying to do a normal signon.
- * @param password The password to use.
- *
- * @deprecated As this is internal, we should make it private in 3.0.0.
- */
-void purple_connection_new(PurpleAccount *account, gboolean regist,
- const char *password);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_CONNECTION_C_)
-/**
- * This function should only be called by purple_account_unregister()
- * in account.c.
- *
- * Tries to unregister the account on the server. If the account is not
- * connected, also creates a new connection.
- *
- * @param account The account to unregister
- * @param password The password to use.
- * @param cb Optional callback to be called when unregistration is complete
- * @param user_data user data to pass to the callback
- *
- * @deprecated As this is internal, we should make it private in 3.0.0.
- */
-void purple_connection_new_unregister(PurpleAccount *account, const char *password, PurpleAccountUnregistrationCb cb, void *user_data);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_CONNECTION_C_)
-/**
- * Disconnects and destroys a PurpleConnection.
- *
- * This function should only be called by purple_account_disconnect()
- * in account.c. If you're trying to sign off an account, use that
- * function instead.
- *
- * @param gc The purple connection to destroy.
- *
- * @deprecated As this is internal, we should make it private in 3.0.0.
- */
-void purple_connection_destroy(PurpleConnection *gc);
-#endif
-
/**
* Sets the connection state. PRPLs should call this and pass in
* the state #PURPLE_CONNECTED when the account is completely
@@ -354,6 +278,14 @@ void purple_connection_destroy(PurpleConnection *gc);
void purple_connection_set_state(PurpleConnection *gc, PurpleConnectionState state);
/**
+ * Sets the connection flags.
+ *
+ * @param gc The connection.
+ * @param flags The flags.
+ */
+void purple_connection_set_flags(PurpleConnection *gc, PurpleConnectionFlags flags);
+
+/**
* Sets the connection's account.
*
* @param gc The connection.
@@ -374,8 +306,6 @@ void purple_connection_set_display_name(PurpleConnection *gc, const char *name);
*
* @param connection The PurpleConnection.
* @param proto_data The protocol data to set for the connection.
- *
- * @since 2.6.0
*/
void purple_connection_set_protocol_data(PurpleConnection *connection, void *proto_data);
@@ -389,6 +319,15 @@ void purple_connection_set_protocol_data(PurpleConnection *connection, void *pro
PurpleConnectionState purple_connection_get_state(const PurpleConnection *gc);
/**
+ * Returns the connection flags.
+ *
+ * @param gc The connection.
+ *
+ * @return The connection flags.
+ */
+PurpleConnectionFlags purple_connection_get_flags(const PurpleConnection *gc);
+
+/**
* Returns TRUE if the account is connected, otherwise returns FALSE.
*
* @return TRUE if the account is connected, otherwise returns FALSE.
@@ -411,8 +350,6 @@ PurpleAccount *purple_connection_get_account(const PurpleConnection *gc);
* @param gc The connection.
*
* @return The protocol plugin.
- *
- * @since 2.4.0
*/
PurplePlugin * purple_connection_get_prpl(const PurpleConnection *gc);
@@ -440,8 +377,6 @@ const char *purple_connection_get_display_name(const PurpleConnection *gc);
* @param connection The PurpleConnection.
*
* @return The protocol data for the connection.
- *
- * @since 2.6.0
*/
void *purple_connection_get_protocol_data(const PurpleConnection *connection);
@@ -465,21 +400,6 @@ void purple_connection_update_progress(PurpleConnection *gc, const char *text,
void purple_connection_notice(PurpleConnection *gc, const char *text);
/**
- * Closes a connection with an error.
- *
- * @param gc The connection.
- * @param reason The error text, which may not be @c NULL.
- * @deprecated in favour of #purple_connection_error_reason. Calling
- * @c purple_connection_error(gc, text) is equivalent to calling
- * @c purple_connection_error_reason(gc, reason, text) where @c reason is
- * #PURPLE_CONNECTION_ERROR_OTHER_ERROR if @c gc->wants_to_die is @c TRUE, and
- * #PURPLE_CONNECTION_ERROR_NETWORK_ERROR if not. (This is to keep
- * auto-reconnection behaviour the same when using old prpls which don't use
- * reasons yet.)
- */
-void purple_connection_error(PurpleConnection *gc, const char *reason);
-
-/**
* Closes a connection with an error and a human-readable description of the
* error. It also sets @c gc->wants_to_die to the value of
* #purple_connection_error_is_fatal(@a reason), mainly for
@@ -488,20 +408,16 @@ void purple_connection_error(PurpleConnection *gc, const char *reason);
* @param gc the connection which is closing.
* @param reason why the connection is closing.
* @param description a non-@c NULL localized description of the error.
- *
- * @since 2.3.0
*/
void
-purple_connection_error_reason (PurpleConnection *gc,
- PurpleConnectionError reason,
- const char *description);
+purple_connection_error(PurpleConnection *gc,
+ PurpleConnectionError reason,
+ const char *description);
/**
* Closes a connection due to an SSL error; this is basically a shortcut to
* turning the #PurpleSslErrorType into a #PurpleConnectionError and a
- * human-readable string and then calling purple_connection_error_reason().
- *
- * @since 2.3.0
+ * human-readable string and then calling purple_connection_error().
*/
void
purple_connection_ssl_error (PurpleConnection *gc,
@@ -524,12 +440,18 @@ purple_connection_ssl_error (PurpleConnection *gc,
*
* @return @c TRUE if the account should not be automatically reconnected, and
* @c FALSE otherwise.
- *
- * @since 2.3.0
*/
gboolean
purple_connection_error_is_fatal (PurpleConnectionError reason);
+/**
+ * Indicate that a packet was received on the connection.
+ * Set by the prpl to avoid sending unneeded keepalives.
+ *
+ * @param gc The connection.
+ */
+void purple_connection_update_last_received(PurpleConnection *gc);
+
/*@}*/
/**************************************************************************/
@@ -619,8 +541,6 @@ void *purple_connections_get_handle(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_CONNECTION_H_ */
diff --git a/libpurple/conversation.c b/libpurple/conversation.c
index 09b637aa55..b6a6058675 100644
--- a/libpurple/conversation.c
+++ b/libpurple/conversation.c
@@ -35,6 +35,131 @@
#define SEND_TYPED_TIMEOUT_SECONDS 5
+/**
+ * Data specific to Chats.
+ */
+struct _PurpleConvChat
+{
+ PurpleConversation *conv; /**< The parent conversation. */
+
+ GList *in_room; /**< The users in the room.
+ * @deprecated Will be removed in 3.0.0
+ */
+ GList *ignored; /**< Ignored users. */
+ char *who; /**< The person who set the topic. */
+ char *topic; /**< The topic. */
+ int id; /**< The chat ID. */
+ char *nick; /**< Your nick in this chat. */
+
+ gboolean left; /**< We left the chat and kept the window open */
+ GHashTable *users; /**< Hash table of the users in the room. */
+};
+
+/**
+ * Data specific to Instant Messages.
+ */
+struct _PurpleConvIm
+{
+ PurpleConversation *conv; /**< The parent conversation. */
+
+ PurpleTypingState typing_state; /**< The current typing state. */
+ guint typing_timeout; /**< The typing timer handle. */
+ time_t type_again; /**< The type again time. */
+ guint send_typed_timeout; /**< The type again timer handle. */
+
+ PurpleBuddyIcon *icon; /**< The buddy icon. */
+};
+
+/**
+ * Data for "Chat Buddies"
+ */
+struct _PurpleConvChatBuddy
+{
+ /** The chat participant's name in the chat. */
+ char *name;
+
+ /** The chat participant's alias, if known; @a NULL otherwise. */
+ char *alias;
+
+ /**
+ * A string by which this buddy will be sorted, or @c NULL if the
+ * buddy should be sorted by its @c name. (This is currently always
+ * @c NULL.
+ */
+ char *alias_key;
+
+ /**
+ * @a TRUE if this chat participant is on the buddy list;
+ * @a FALSE otherwise.
+ */
+ gboolean buddy;
+
+ /**
+ * A bitwise OR of flags for this participant, such as whether they
+ * are a channel operator.
+ */
+ PurpleConvChatBuddyFlags flags;
+
+ /**
+ * A hash table of attributes about the user, such as real name,
+ * user\@host, etc.
+ */
+ GHashTable *attributes;
+
+ /** The UI can put whatever it wants here. */
+ gpointer ui_data;
+};
+
+/**
+ * A core representation of a conversation between two or more people.
+ *
+ * The conversation can be an IM or a chat.
+ */
+struct _PurpleConversation
+{
+ PurpleConversationType type; /**< The type of conversation. */
+
+ PurpleAccount *account; /**< The user using this conversation. */
+
+
+ char *name; /**< The name of the conversation. */
+ char *title; /**< The window title. */
+
+ gboolean logging; /**< The status of logging. */
+
+ GList *logs; /**< This conversation's logs */
+
+ union
+ {
+ PurpleConvIm *im; /**< IM-specific data. */
+ PurpleConvChat *chat; /**< Chat-specific data. */
+ void *misc; /**< Misc. data. */
+
+ } u;
+
+ PurpleConversationUiOps *ui_ops; /**< UI-specific operations. */
+ void *ui_data; /**< UI-specific data. */
+
+ GHashTable *data; /**< Plugin-specific data. */
+
+ PurpleConnectionFlags features; /**< The supported features */
+ GList *message_history; /**< Message history, as a GList of PurpleConvMessage's */
+};
+
+/**
+ * Description of a conversation message
+ */
+struct _PurpleConvMessage
+{
+ char *who;
+ char *what;
+ PurpleMessageFlags flags;
+ time_t when;
+ PurpleConversation *conv;
+ char *alias;
+};
+
+
static GList *conversations = NULL;
static GList *ims = NULL;
static GList *chats = NULL;
@@ -116,7 +241,7 @@ send_typed_cb(gpointer data)
g_return_val_if_fail(conv != NULL, FALSE);
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
name = purple_conversation_get_name(conv);
if (gc != NULL && name != NULL) {
@@ -146,7 +271,7 @@ common_send(PurpleConversation *conv, const char *message, PurpleMessageFlags ms
return;
account = purple_conversation_get_account(conv);
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
g_return_if_fail(account != NULL);
g_return_if_fail(gc != NULL);
@@ -262,7 +387,7 @@ add_message_to_history(PurpleConversation *conv, const char *who, const char *al
if (gc)
me = purple_connection_get_display_name(gc);
if (!me)
- me = conv->account->username;
+ me = purple_account_get_username(conv->account);
who = me;
}
@@ -381,7 +506,7 @@ purple_conversation_new(PurpleConversationType type, PurpleAccount *account,
conv->data = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, NULL);
/* copy features from the connection. */
- conv->features = gc->flags;
+ conv->features = purple_connection_get_flags(gc);
if (type == PURPLE_CONV_TYPE_IM)
{
@@ -416,7 +541,7 @@ purple_conversation_new(PurpleConversationType type, PurpleAccount *account,
chats = g_list_prepend(chats, conv);
- if ((disp = purple_connection_get_display_name(account->gc)))
+ if ((disp = purple_connection_get_display_name(purple_account_get_connection(account))))
purple_conv_chat_set_nick(conv->u.chat, disp);
else
purple_conv_chat_set_nick(conv->u.chat,
@@ -469,7 +594,7 @@ purple_conversation_destroy(PurpleConversation *conv)
purple_request_close_with_handle(conv);
ops = purple_conversation_get_ui_ops(conv);
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
name = purple_conversation_get_name(conv);
if (gc != NULL)
@@ -694,7 +819,7 @@ purple_conversation_get_account(const PurpleConversation *conv)
}
PurpleConnection *
-purple_conversation_get_gc(const PurpleConversation *conv)
+purple_conversation_get_connection(const PurpleConversation *conv)
{
PurpleAccount *account;
@@ -705,7 +830,7 @@ purple_conversation_get_gc(const PurpleConversation *conv)
if (account == NULL)
return NULL;
- return account->gc;
+ return purple_account_get_connection(account);
}
void
@@ -990,7 +1115,7 @@ purple_conversation_write(PurpleConversation *conv, const char *who,
purple_account_get_username(account));
if (purple_account_get_alias(account) != NULL)
- alias = account->alias;
+ alias = purple_account_get_alias(account);
else if (b != NULL && !purple_strequal(purple_buddy_get_name(b), purple_buddy_get_contact_alias(b)))
alias = purple_buddy_get_contact_alias(b);
else if (purple_connection_get_display_name(gc) != NULL)
@@ -1379,16 +1504,6 @@ purple_conv_chat_get_conversation(const PurpleConvChat *chat)
}
GList *
-purple_conv_chat_set_users(PurpleConvChat *chat, GList *users)
-{
- g_return_val_if_fail(chat != NULL, NULL);
-
- chat->in_room = users;
-
- return users;
-}
-
-GList *
purple_conv_chat_get_users(const PurpleConvChat *chat)
{
g_return_val_if_fail(chat != NULL, NULL);
@@ -1544,7 +1659,7 @@ purple_conv_chat_write(PurpleConvChat *chat, const char *who, const char *messag
g_return_if_fail(message != NULL);
conv = purple_conv_chat_get_conversation(chat);
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
account = purple_connection_get_account(gc);
/* Don't display this if the person who wrote it is ignored. */
@@ -1660,7 +1775,7 @@ purple_conv_chat_add_users(PurpleConvChat *chat, GList *users, GList *extra_msgs
conv = purple_conv_chat_get_conversation(chat);
ops = purple_conversation_get_ui_ops(conv);
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
g_return_if_fail(gc != NULL);
prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
g_return_if_fail(prpl_info != NULL);
@@ -1687,7 +1802,7 @@ purple_conv_chat_add_users(PurpleConvChat *chat, GList *users, GList *extra_msgs
}
} else {
PurpleBuddy *buddy;
- if ((buddy = purple_find_buddy(gc->account, user)) != NULL)
+ if ((buddy = purple_find_buddy(purple_connection_get_account(gc), user)) != NULL)
alias = purple_buddy_get_contact_alias(buddy);
}
}
@@ -1761,7 +1876,7 @@ purple_conv_chat_rename_user(PurpleConvChat *chat, const char *old_user,
conv = purple_conv_chat_get_conversation(chat);
ops = purple_conversation_get_ui_ops(conv);
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
g_return_if_fail(gc != NULL);
prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
g_return_if_fail(prpl_info != NULL);
@@ -1780,12 +1895,12 @@ purple_conv_chat_rename_user(PurpleConvChat *chat, const char *old_user,
{
const char *display_name = purple_connection_get_display_name(gc);
if (display_name != NULL)
- alias = display_name;
+ new_alias = display_name;
}
}
} else if (!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
PurpleBuddy *buddy;
- if ((buddy = purple_find_buddy(gc->account, new_user)) != NULL)
+ if ((buddy = purple_find_buddy(purple_connection_get_account(gc), new_user)) != NULL)
new_alias = purple_buddy_get_contact_alias(buddy);
}
@@ -1834,9 +1949,9 @@ purple_conv_chat_rename_user(PurpleConvChat *chat, const char *old_user,
if (!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
PurpleBuddy *buddy;
- if ((buddy = purple_find_buddy(gc->account, old_user)) != NULL)
+ if ((buddy = purple_find_buddy(purple_connection_get_account(gc), old_user)) != NULL)
old_alias = purple_buddy_get_contact_alias(buddy);
- if ((buddy = purple_find_buddy(gc->account, new_user)) != NULL)
+ if ((buddy = purple_find_buddy(purple_connection_get_account(gc), new_user)) != NULL)
new_alias = purple_buddy_get_contact_alias(buddy);
}
@@ -1880,7 +1995,7 @@ purple_conv_chat_remove_users(PurpleConvChat *chat, GList *users, const char *re
conv = purple_conv_chat_get_conversation(chat);
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
g_return_if_fail(gc != NULL);
prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
g_return_if_fail(prpl_info != NULL);
@@ -1911,7 +2026,7 @@ purple_conv_chat_remove_users(PurpleConvChat *chat, GList *users, const char *re
if (!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
PurpleBuddy *buddy;
- if ((buddy = purple_find_buddy(gc->account, user)) != NULL)
+ if ((buddy = purple_find_buddy(purple_connection_get_account(gc), user)) != NULL)
alias = purple_buddy_get_contact_alias(buddy);
}
@@ -2065,7 +2180,7 @@ purple_find_chat(const PurpleConnection *gc, int id)
conv = (PurpleConversation *)l->data;
if (purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)) == id &&
- purple_conversation_get_gc(conv) == gc)
+ purple_conversation_get_connection(conv) == gc)
return conv;
}
@@ -2093,7 +2208,7 @@ invite_user_to_chat(gpointer data, PurpleRequestFields *fields)
user = purple_request_fields_get_string(fields, "screenname");
message = purple_request_fields_get_string(fields, "message");
- serv_chat_invite(purple_conversation_get_gc(conv), chat->id, message, user);
+ serv_chat_invite(purple_conversation_get_connection(conv), chat->id, message, user);
}
void purple_conv_chat_invite_user(PurpleConvChat *chat, const char *user,
@@ -2194,14 +2309,51 @@ purple_conv_chat_cb_destroy(PurpleConvChatBuddy *cb)
g_free(cb);
}
+void purple_conv_chat_cb_set_ui_data(PurpleConvChatBuddy *cb, gpointer ui_data)
+{
+ g_return_if_fail(cb != NULL);
+
+ cb->ui_data = ui_data;
+}
+
+gpointer purple_conv_chat_cb_get_ui_data(const PurpleConvChatBuddy *cb)
+{
+ g_return_val_if_fail(cb != NULL, NULL);
+
+ return cb->ui_data;
+}
+
const char *
-purple_conv_chat_cb_get_name(PurpleConvChatBuddy *cb)
+purple_conv_chat_cb_get_alias(const PurpleConvChatBuddy *cb)
+{
+ g_return_val_if_fail(cb != NULL, NULL);
+
+ return cb->alias;
+}
+
+const char *
+purple_conv_chat_cb_get_name(const PurpleConvChatBuddy *cb)
{
g_return_val_if_fail(cb != NULL, NULL);
return cb->name;
}
+PurpleConvChatBuddyFlags
+purple_conv_chat_cb_get_flags(const PurpleConvChatBuddy *cb)
+{
+ g_return_val_if_fail(cb != NULL, PURPLE_CBFLAGS_NONE);
+
+ return cb->flags;
+}
+
+gboolean purple_conv_chat_cb_is_buddy(const PurpleConvChatBuddy *cb)
+{
+ g_return_val_if_fail(cb != NULL, FALSE);
+
+ return cb->buddy;
+}
+
const char *
purple_conv_chat_cb_get_attribute(PurpleConvChatBuddy *cb, const char *key)
{
@@ -2299,30 +2451,57 @@ GList *purple_conversation_get_message_history(PurpleConversation *conv)
return conv->message_history;
}
-const char *purple_conversation_message_get_sender(PurpleConvMessage *msg)
+const char *purple_conversation_message_get_sender(const PurpleConvMessage *msg)
{
g_return_val_if_fail(msg, NULL);
return msg->who;
}
-const char *purple_conversation_message_get_message(PurpleConvMessage *msg)
+const char *purple_conversation_message_get_message(const PurpleConvMessage *msg)
{
g_return_val_if_fail(msg, NULL);
return msg->what;
}
-PurpleMessageFlags purple_conversation_message_get_flags(PurpleConvMessage *msg)
+PurpleMessageFlags purple_conversation_message_get_flags(const PurpleConvMessage *msg)
{
g_return_val_if_fail(msg, 0);
return msg->flags;
}
-time_t purple_conversation_message_get_timestamp(PurpleConvMessage *msg)
+time_t purple_conversation_message_get_timestamp(const PurpleConvMessage *msg)
{
g_return_val_if_fail(msg, 0);
return msg->when;
}
+const char *purple_conversation_message_get_alias(const PurpleConvMessage *msg)
+{
+ g_return_val_if_fail(msg, NULL);
+ return msg->alias;
+}
+
+PurpleConversation *purple_conversation_message_get_conv(const PurpleConvMessage *msg)
+{
+ g_return_val_if_fail(msg, NULL);
+ return msg->conv;
+}
+
+void purple_conversation_set_ui_data(PurpleConversation *conv, gpointer ui_data)
+{
+ g_return_if_fail(conv != NULL);
+
+ conv->ui_data = ui_data;
+}
+
+gpointer purple_conversation_get_ui_data(const PurpleConversation *conv)
+{
+ g_return_val_if_fail(conv != NULL, NULL);
+
+ return conv->ui_data;
+}
+
+
gboolean
purple_conversation_do_command(PurpleConversation *conv, const gchar *cmdline,
const gchar *markup, gchar **error)
diff --git a/libpurple/conversation.h b/libpurple/conversation.h
index e01dc19145..80262ef809 100644
--- a/libpurple/conversation.h
+++ b/libpurple/conversation.h
@@ -125,7 +125,7 @@ typedef enum
PURPLE_MESSAGE_IMAGES = 0x1000, /**< Message contains images */
PURPLE_MESSAGE_NOTIFY = 0x2000, /**< Message is a notification */
PURPLE_MESSAGE_NO_LINKIFY = 0x4000, /**< Message should not be auto-
- linkified @since 2.1.0 */
+ linkified */
PURPLE_MESSAGE_INVISIBLE = 0x8000 /**< Message should not be displayed */
} PurpleMessageFlags;
@@ -140,7 +140,7 @@ typedef enum
PURPLE_CBFLAGS_OP = 0x0004, /**< Channel Op or Moderator */
PURPLE_CBFLAGS_FOUNDER = 0x0008, /**< Channel Founder */
PURPLE_CBFLAGS_TYPING = 0x0010, /**< Currently typing */
- PURPLE_CBFLAGS_AWAY = 0x0020 /**< Currently away. @since 2.8.0 */
+ PURPLE_CBFLAGS_AWAY = 0x0020 /**< Currently away. */
} PurpleConvChatBuddyFlags;
@@ -249,123 +249,7 @@ struct _PurpleConversationUiOps
void (*_purple_reserved4)(void);
};
-/**
- * Data specific to Instant Messages.
- */
-struct _PurpleConvIm
-{
- PurpleConversation *conv; /**< The parent conversation. */
-
- PurpleTypingState typing_state; /**< The current typing state. */
- guint typing_timeout; /**< The typing timer handle. */
- time_t type_again; /**< The type again time. */
- guint send_typed_timeout; /**< The type again timer handle. */
-
- PurpleBuddyIcon *icon; /**< The buddy icon. */
-};
-
-/**
- * Data specific to Chats.
- */
-struct _PurpleConvChat
-{
- PurpleConversation *conv; /**< The parent conversation. */
-
- GList *in_room; /**< The users in the room.
- * @deprecated Will be removed in 3.0.0
- */
- GList *ignored; /**< Ignored users. */
- char *who; /**< The person who set the topic. */
- char *topic; /**< The topic. */
- int id; /**< The chat ID. */
- char *nick; /**< Your nick in this chat. */
-
- gboolean left; /**< We left the chat and kept the window open */
- GHashTable *users; /**< Hash table of the users in the room.
- * @since 2.9.0
- */
-};
-
-/**
- * Data for "Chat Buddies"
- */
-struct _PurpleConvChatBuddy
-{
- char *name; /**< The chat participant's name in the chat. */
- char *alias; /**< The chat participant's alias, if known;
- * @a NULL otherwise.
- */
- char *alias_key; /**< A string by which this buddy will be sorted,
- * or @c NULL if the buddy should be sorted by
- * its @c name. (This is currently always @c
- * NULL.)
- */
- gboolean buddy; /**< @a TRUE if this chat participant is on the
- * buddy list; @a FALSE otherwise.
- */
- PurpleConvChatBuddyFlags flags; /**< A bitwise OR of flags for this participant,
- * such as whether they are a channel operator.
- */
- GHashTable *attributes; /**< A hash table of attributes about the user, such as
- * real name, user@host, etc.
- */
- gpointer ui_data; /** < The UI can put whatever it wants here. */
-};
-
-/**
- * Description of a conversation message
- *
- * @since 2.2.0
- */
-struct _PurpleConvMessage
-{
- char *who;
- char *what;
- PurpleMessageFlags flags;
- time_t when;
- PurpleConversation *conv; /**< @since 2.3.0 */
- char *alias; /**< @since 2.3.0 */
-};
-
-/**
- * A core representation of a conversation between two or more people.
- *
- * The conversation can be an IM or a chat.
- */
-struct _PurpleConversation
-{
- PurpleConversationType type; /**< The type of conversation. */
-
- PurpleAccount *account; /**< The user using this conversation. */
-
-
- char *name; /**< The name of the conversation. */
- char *title; /**< The window title. */
-
- gboolean logging; /**< The status of logging. */
-
- GList *logs; /**< This conversation's logs */
-
- union
- {
- PurpleConvIm *im; /**< IM-specific data. */
- PurpleConvChat *chat; /**< Chat-specific data. */
- void *misc; /**< Misc. data. */
-
- } u;
-
- PurpleConversationUiOps *ui_ops; /**< UI-specific operations. */
- void *ui_data; /**< UI-specific data. */
-
- GHashTable *data; /**< Plugin-specific data. */
-
- PurpleConnectionFlags features; /**< The supported features */
- GList *message_history; /**< Message history, as a GList of PurpleConvMessage's */
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Conversation API */
@@ -469,13 +353,11 @@ PurpleAccount *purple_conversation_get_account(const PurpleConversation *conv);
/**
* Returns the specified conversation's purple_connection.
*
- * This is the same as purple_conversation_get_user(conv)->gc.
- *
* @param conv The conversation.
*
* @return The conversation's purple_connection.
*/
-PurpleConnection *purple_conversation_get_gc(const PurpleConversation *conv);
+PurpleConnection *purple_conversation_get_connection(const PurpleConversation *conv);
/**
* Sets the specified conversation's title.
@@ -744,8 +626,6 @@ void purple_conversation_foreach(void (*func)(PurpleConversation *conv));
* @return A GList of PurpleConvMessage's. The must not modify the list or the data within.
* The list contains the newest message at the beginning, and the oldest message at
* the end.
- *
- * @since 2.2.0
*/
GList *purple_conversation_get_message_history(PurpleConversation *conv);
@@ -753,8 +633,6 @@ GList *purple_conversation_get_message_history(PurpleConversation *conv);
* Clear the message history of a conversation.
*
* @param conv The conversation
- *
- * @since 2.2.0
*/
void purple_conversation_clear_message_history(PurpleConversation *conv);
@@ -764,10 +642,8 @@ void purple_conversation_clear_message_history(PurpleConversation *conv);
* @param msg A PurpleConvMessage
*
* @return The name of the sender of the message
- *
- * @since 2.2.0
*/
-const char *purple_conversation_message_get_sender(PurpleConvMessage *msg);
+const char *purple_conversation_message_get_sender(const PurpleConvMessage *msg);
/**
* Get the message from a PurpleConvMessage
@@ -775,10 +651,8 @@ const char *purple_conversation_message_get_sender(PurpleConvMessage *msg);
* @param msg A PurpleConvMessage
*
* @return The name of the sender of the message
- *
- * @since 2.2.0
*/
-const char *purple_conversation_message_get_message(PurpleConvMessage *msg);
+const char *purple_conversation_message_get_message(const PurpleConvMessage *msg);
/**
* Get the message-flags of a PurpleConvMessage
@@ -786,10 +660,8 @@ const char *purple_conversation_message_get_message(PurpleConvMessage *msg);
* @param msg A PurpleConvMessage
*
* @return The message flags
- *
- * @since 2.2.0
*/
-PurpleMessageFlags purple_conversation_message_get_flags(PurpleConvMessage *msg);
+PurpleMessageFlags purple_conversation_message_get_flags(const PurpleConvMessage *msg);
/**
* Get the timestamp of a PurpleConvMessage
@@ -797,10 +669,45 @@ PurpleMessageFlags purple_conversation_message_get_flags(PurpleConvMessage *msg)
* @param msg A PurpleConvMessage
*
* @return The timestamp of the message
+ */
+time_t purple_conversation_message_get_timestamp(const PurpleConvMessage *msg);
+
+/**
+ * Get the alias from a PurpleConvMessage
+ *
+ * @param msg A PurpleConvMessage
+ *
+ * @return The alias of the sender of the message
+ */
+const char *purple_conversation_message_get_alias(const PurpleConvMessage *msg);
+
+/**
+ * Get the conversation associated with the PurpleConvMessage
+ *
+ * @param msg A PurpleConvMessage
+ *
+ * @return The conversation
+ */
+PurpleConversation *purple_conversation_message_get_conv(const PurpleConvMessage *msg);
+
+/**
+ * Set the UI data associated with this conversation.
+ *
+ * @param conv The conversation.
+ * @param ui_data A pointer to associate with this conversation.
+ */
+void purple_conversation_set_ui_data(PurpleConversation *conv, gpointer ui_data);
+
+/**
+ * Get the UI data associated with this conversation.
+ *
+ * @param conv The conversation.
*
- * @since 2.2.0
+ * @return The UI data associated with this conversation. This is a
+ * convenience field provided to the UIs--it is not
+ * used by the libpurple core.
*/
-time_t purple_conversation_message_get_timestamp(PurpleConvMessage *msg);
+gpointer purple_conversation_get_ui_data(const PurpleConversation *conv);
/*@}*/
@@ -1061,22 +968,6 @@ void purple_conv_custom_smiley_close(PurpleConversation *conv, const char *smile
PurpleConversation *purple_conv_chat_get_conversation(const PurpleConvChat *chat);
/**
- * Sets the list of users in the chat room.
- *
- * @note Calling this function will not update the display of the users.
- * Please use purple_conv_chat_add_user(), purple_conv_chat_add_users(),
- * purple_conv_chat_remove_user(), and purple_conv_chat_remove_users() instead.
- *
- * @param chat The chat.
- * @param users The list of users.
- *
- * @return The list passed.
- *
- * @deprecated This function will be removed in 3.0.0. You shouldn't be using it anyway.
- */
-GList *purple_conv_chat_set_users(PurpleConvChat *chat, GList *users);
-
-/**
* Returns a list of users in the chat room. The members of the list
* are PurpleConvChatBuddy objects.
*
@@ -1362,8 +1253,6 @@ void purple_conv_chat_left(PurpleConvChat *chat);
* @param message The message to send with the invitation.
* @param confirm Prompt before sending the invitation. The user is always
* prompted if either \a user or \a message is @c NULL.
- *
- * @since 2.6.0
*/
void purple_conv_chat_invite_user(PurpleConvChat *chat, const char *user,
const char *message, gboolean confirm);
@@ -1400,13 +1289,59 @@ PurpleConvChatBuddy *purple_conv_chat_cb_new(const char *name, const char *alias
PurpleConvChatBuddy *purple_conv_chat_cb_find(PurpleConvChat *chat, const char *name);
/**
+ * Set the UI data associated with this chat buddy.
+ *
+ * @param cb The chat buddy
+ * @param ui_data A pointer to associate with this chat buddy.
+ */
+void purple_conv_chat_cb_set_ui_data(PurpleConvChatBuddy *cb, gpointer ui_data);
+
+/**
+ * Get the UI data associated with this chat buddy.
+ *
+ * @param cb The chat buddy.
+ *
+ * @return The UI data associated with this chat buddy. This is a
+ * convenience field provided to the UIs--it is not
+ * used by the libpurple core.
+ */
+gpointer purple_conv_chat_cb_get_ui_data(const PurpleConvChatBuddy *conv);
+
+/**
+ * Get the alias of a chat buddy
+ *
+ * @param cb The chat buddy.
+ *
+ * @return The alias of the chat buddy.
+ */
+const char *purple_conv_chat_cb_get_alias(const PurpleConvChatBuddy *cb);
+
+/**
* Get the name of a chat buddy
*
* @param cb The chat buddy.
*
* @return The name of the chat buddy.
*/
-const char *purple_conv_chat_cb_get_name(PurpleConvChatBuddy *cb);
+const char *purple_conv_chat_cb_get_name(const PurpleConvChatBuddy *cb);
+
+/**
+ * Get the flags of a chat buddy.
+ *
+ * @param cb The chat buddy.
+ *
+ * @return The flags of the chat buddy.
+ */
+PurpleConvChatBuddyFlags purple_conv_chat_cb_get_flags(const PurpleConvChatBuddy *cb);
+
+/**
+ * Indicates if this chat buddy is on the buddy list.
+ *
+ * @param cb The chat buddy.
+ *
+ * @return TRUE if the chat buddy is on the buddy list.
+ */
+gboolean purple_conv_chat_cb_is_buddy(const PurpleConvChatBuddy *cb);
/**
* Destroys a chat buddy
@@ -1423,8 +1358,6 @@ void purple_conv_chat_cb_destroy(PurpleConvChatBuddy *cb);
* @return A list of PurpleMenuAction items, harvested by the
* chat-extended-menu signal. The list and the menuaction
* items should be freed by the caller.
- *
- * @since 2.1.0
*/
GList * purple_conversation_get_extended_menu(PurpleConversation *conv);
@@ -1438,8 +1371,6 @@ GList * purple_conversation_get_extended_menu(PurpleConversation *conv);
* message, if not @c NULL. It must be freed by the caller with g_free().
*
* @return @c TRUE if the command was executed successfully, @c FALSE otherwise.
- *
- * @since 2.1.0
*/
gboolean purple_conversation_do_command(PurpleConversation *conv, const gchar *cmdline, const gchar *markup, gchar **error);
@@ -1469,8 +1400,6 @@ void purple_conversations_uninit(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_CONVERSATION_H_ */
diff --git a/libpurple/core.c b/libpurple/core.c
index c07fc35c9e..6a5783eb1e 100644
--- a/libpurple/core.c
+++ b/libpurple/core.c
@@ -371,386 +371,6 @@ purple_core_ensure_single_instance()
return is_single_instance;
}
-static gboolean
-move_and_symlink_dir(const char *path, const char *basename, const char *old_base, const char *new_base, const char *relative)
-{
- char *new_name = g_build_filename(new_base, basename, NULL);
-#ifndef _WIN32
- char *old_name;
-#endif
- if (g_rename(path, new_name))
- {
- purple_debug_error("core", "Error renaming %s to %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
- path, new_name, g_strerror(errno));
- g_free(new_name);
- return FALSE;
- }
- g_free(new_name);
-
-#ifndef _WIN32
- /* NOTE: This new_name is relative. */
- new_name = g_build_filename(relative, basename, NULL);
- old_name = g_build_filename(old_base, basename, NULL);
- if (symlink(new_name, old_name))
- {
- purple_debug_warning("core", "Error symlinking %s to %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
- old_name, new_name, g_strerror(errno));
- }
- g_free(old_name);
- g_free(new_name);
-#endif
-
- return TRUE;
-}
-
-gboolean
-purple_core_migrate(void)
-{
- const char *user_dir = purple_user_dir();
- char *old_user_dir = g_strconcat(purple_home_dir(),
- G_DIR_SEPARATOR_S ".gaim", NULL);
- char *status_file;
- FILE *fp;
- GDir *dir;
- GError *err;
- const char *entry;
-#ifndef _WIN32
- char *logs_dir;
-#endif
- char *old_icons_dir;
-
- if (!g_file_test(old_user_dir, G_FILE_TEST_EXISTS))
- {
- /* ~/.gaim doesn't exist, so there's nothing to migrate. */
- g_free(old_user_dir);
- return TRUE;
- }
-
- status_file = g_strconcat(user_dir, G_DIR_SEPARATOR_S "migrating", NULL);
-
- if (g_file_test(user_dir, G_FILE_TEST_EXISTS))
- {
- /* If we're here, we have both ~/.gaim and .purple. */
-
- if (!g_file_test(status_file, G_FILE_TEST_EXISTS))
- {
- /* There's no "migrating" status file,
- * so ~/.purple is all up to date. */
- g_free(status_file);
- g_free(old_user_dir);
- return TRUE;
- }
- }
-
- /* If we're here, it's time to migrate from ~/.gaim to ~/.purple. */
-
- /* Ensure the user directory exists */
- if (!g_file_test(user_dir, G_FILE_TEST_IS_DIR))
- {
- if (g_mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
- {
- purple_debug_error("core", "Error creating directory %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
- user_dir, g_strerror(errno));
- g_free(status_file);
- g_free(old_user_dir);
- return FALSE;
- }
- }
-
- /* This writes ~/.purple/migrating, which allows us to detect
- * incomplete migrations and properly retry. */
- if (!(fp = g_fopen(status_file, "w")))
- {
- purple_debug_error("core", "Error opening file %s for writing: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
- status_file, g_strerror(errno));
- g_free(status_file);
- g_free(old_user_dir);
- return FALSE;
- }
- fclose(fp);
-
- /* Open ~/.gaim so we can loop over its contents. */
- err = NULL;
- if (!(dir = g_dir_open(old_user_dir, 0, &err)))
- {
- purple_debug_error("core", "Error opening directory %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
- status_file,
- (err ? err->message : "Unknown error"));
- if (err)
- g_error_free(err);
- g_free(status_file);
- g_free(old_user_dir);
- return FALSE;
- }
-
- /* Loop over the contents of ~/.gaim */
- while ((entry = g_dir_read_name(dir)))
- {
- char *name = g_build_filename(old_user_dir, entry, NULL);
-
-#ifndef _WIN32
- /* Deal with symlinks... */
- if (g_file_test(name, G_FILE_TEST_IS_SYMLINK))
- {
- /* We're only going to duplicate a logs symlink. */
- if (purple_strequal(entry, "logs"))
- {
- char *link;
- err = NULL;
-
- if ((link = g_file_read_link(name, &err)) == NULL)
- {
- char *name_utf8 = g_filename_to_utf8(name, -1, NULL, NULL, NULL);
- purple_debug_error("core", "Error reading symlink %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
- name_utf8 ? name_utf8 : name, err->message);
- g_free(name_utf8);
- g_error_free(err);
- g_free(name);
- g_dir_close(dir);
- g_free(status_file);
- g_free(old_user_dir);
- return FALSE;
- }
-
- logs_dir = g_build_filename(user_dir, "logs", NULL);
-
- if (purple_strequal(link, "../.purple/logs") ||
- purple_strequal(link, logs_dir))
- {
- /* If the symlink points to the new directory, we're
- * likely just trying again after a failed migration,
- * so there's no need to fail here. */
- g_free(link);
- g_free(logs_dir);
- continue;
- }
-
- /* In case we are trying again after a failed migration, we need
- * to unlink any existing symlink. If it's a directory, this
- * will fail, and so will the symlink below, which is good
- * because the user should sort things out. */
- g_unlink(logs_dir);
-
- /* Relative links will most likely still be
- * valid from ~/.purple, though it's not
- * guaranteed. Oh well. */
- if (symlink(link, logs_dir))
- {
- purple_debug_error("core", "Error symlinking %s to %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
- logs_dir, link, g_strerror(errno));
- g_free(link);
- g_free(name);
- g_free(logs_dir);
- g_dir_close(dir);
- g_free(status_file);
- g_free(old_user_dir);
- return FALSE;
- }
-
- g_free(link);
- g_free(logs_dir);
- continue;
- }
-
- /* Ignore all other symlinks. */
- continue;
- }
-#endif
-
- /* Deal with directories... */
- if (g_file_test(name, G_FILE_TEST_IS_DIR))
- {
- if (purple_strequal(entry, "icons"))
- {
- /* This is a special case for the Album plugin, which
- * stores data in the icons folder. We're not copying
- * the icons directory over because previous bugs
- * meant that it filled up with junk for many users.
- * This is a great time to purge it. */
-
- GDir *icons_dir;
- char *new_icons_dir;
- const char *icons_entry;
-
- err = NULL;
- if (!(icons_dir = g_dir_open(name, 0, &err)))
- {
- purple_debug_error("core", "Error opening directory %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
- name,
- (err ? err->message : "Unknown error"));
- if (err)
- g_error_free(err);
- g_free(name);
- g_dir_close(dir);
- g_free(status_file);
- g_free(old_user_dir);
- return FALSE;
- }
-
- new_icons_dir = g_build_filename(user_dir, "icons", NULL);
- /* Ensure the new icon directory exists */
- if (!g_file_test(new_icons_dir, G_FILE_TEST_IS_DIR))
- {
- if (g_mkdir(new_icons_dir, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
- {
- purple_debug_error("core", "Error creating directory %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
- new_icons_dir, g_strerror(errno));
- g_free(new_icons_dir);
- g_dir_close(icons_dir);
- g_free(name);
- g_dir_close(dir);
- g_free(status_file);
- g_free(old_user_dir);
- return FALSE;
- }
- }
-
- while ((icons_entry = g_dir_read_name(icons_dir)))
- {
- char *icons_name = g_build_filename(name, icons_entry, NULL);
-
- if (g_file_test(icons_name, G_FILE_TEST_IS_DIR))
- {
- if (!move_and_symlink_dir(icons_name, icons_entry,
- name, new_icons_dir, "../../.purple/icons"))
- {
- g_free(icons_name);
- g_free(new_icons_dir);
- g_dir_close(icons_dir);
- g_free(name);
- g_dir_close(dir);
- g_free(status_file);
- g_free(old_user_dir);
- return FALSE;
- }
- }
- g_free(icons_name);
- }
-
- g_dir_close(icons_dir);
- }
- else if (purple_strequal(entry, "plugins"))
- {
- /* Do nothing, because we broke plugin compatibility.
- * This means that the plugins directory gets left behind. */
- }
- else
- {
- /* All other directories are moved and symlinked. */
- if (!move_and_symlink_dir(name, entry, old_user_dir, user_dir, "../.purple"))
- {
- g_free(name);
- g_dir_close(dir);
- g_free(status_file);
- g_free(old_user_dir);
- return FALSE;
- }
- }
- }
- else if (g_file_test(name, G_FILE_TEST_IS_REGULAR))
- {
- /* Regular files are copied. */
-
- char *new_name;
- FILE *new_file;
-
- if (!(fp = g_fopen(name, "rb")))
- {
- purple_debug_error("core", "Error opening file %s for reading: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
- name, g_strerror(errno));
- g_free(name);
- g_dir_close(dir);
- g_free(status_file);
- g_free(old_user_dir);
- return FALSE;
- }
-
- new_name = g_build_filename(user_dir, entry, NULL);
- if (!(new_file = g_fopen(new_name, "wb")))
- {
- purple_debug_error("core", "Error opening file %s for writing: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
- new_name, g_strerror(errno));
- fclose(fp);
- g_free(new_name);
- g_free(name);
- g_dir_close(dir);
- g_free(status_file);
- g_free(old_user_dir);
- return FALSE;
- }
-
- while (!feof(fp))
- {
- unsigned char buf[256];
- size_t size;
-
- size = fread(buf, 1, sizeof(buf), fp);
- if (size != sizeof(buf) && !feof(fp))
- {
- purple_debug_error("core", "Error reading %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
- name, g_strerror(errno));
- fclose(new_file);
- fclose(fp);
- g_free(new_name);
- g_free(name);
- g_dir_close(dir);
- g_free(status_file);
- g_free(old_user_dir);
- return FALSE;
- }
-
- if (!fwrite(buf, size, 1, new_file) && ferror(new_file) != 0)
- {
- purple_debug_error("core", "Error writing %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
- new_name, g_strerror(errno));
- fclose(new_file);
- fclose(fp);
- g_free(new_name);
- g_free(name);
- g_dir_close(dir);
- g_free(status_file);
- g_free(old_user_dir);
- return FALSE;
- }
- }
-
- if (fclose(new_file))
- {
- purple_debug_error("core", "Error writing: %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
- new_name, g_strerror(errno));
- }
- if (fclose(fp))
- {
- purple_debug_warning("core", "Error closing %s: %s\n",
- name, g_strerror(errno));
- }
- g_free(new_name);
- }
- else
- purple_debug_warning("core", "Not a regular file or directory: %s\n", name);
-
- g_free(name);
- }
-
- /* The migration was successful, so delete the status file. */
- if (g_unlink(status_file))
- {
- purple_debug_error("core", "Error unlinking file %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n",
- status_file, g_strerror(errno));
- g_free(status_file);
- return FALSE;
- }
-
- old_icons_dir = g_build_filename(old_user_dir, "icons", NULL);
- _purple_buddy_icon_set_old_icons_dir(old_icons_dir);
- g_free(old_icons_dir);
-
- g_free(old_user_dir);
-
- g_free(status_file);
- return TRUE;
-}
-
GHashTable* purple_core_get_ui_info() {
PurpleCoreUiOps *ops = purple_core_get_ui_ops();
diff --git a/libpurple/core.h b/libpurple/core.h
index c55591e234..19447b159f 100644
--- a/libpurple/core.h
+++ b/libpurple/core.h
@@ -76,9 +76,7 @@ typedef struct
void (*_purple_reserved3)(void);
} PurpleCoreUiOps;
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**
* Initializes the core of purple.
@@ -156,17 +154,6 @@ void purple_core_set_ui_ops(PurpleCoreUiOps *ops);
PurpleCoreUiOps *purple_core_get_ui_ops(void);
/**
- * Migrates from <tt>.gaim</tt> to <tt>.purple</tt>.
- *
- * UIs <strong>must not</strong> call this if they have been told to use a
- * custom user directory.
- *
- * @return A boolean indicating success or migration failure. On failure,
- * the application must display an error to the user and then exit.
- */
-gboolean purple_core_migrate(void);
-
-/**
* Ensures that only one instance is running. If libpurple is built with D-Bus
* support, this checks if another process owns the libpurple bus name and if
* so whether that process is using the same configuration directory as this
@@ -174,8 +161,6 @@ gboolean purple_core_migrate(void);
*
* @return @c TRUE if this is the first instance of libpurple running;
* @c FALSE if there is another instance running.
- *
- * @since 2.1.0
*/
gboolean purple_core_ensure_single_instance(void);
@@ -207,14 +192,10 @@ gboolean purple_core_ensure_single_instance(void);
* @return A GHashTable with strings for keys and values. This
* hash table must not be freed and should not be modified.
*
- * @since 2.1.0
- *
*/
GHashTable* purple_core_get_ui_info(void);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_CORE_H_ */
diff --git a/libpurple/dbus-analyze-functions.py b/libpurple/dbus-analyze-functions.py
index e9b7cc9d3b..32612bee61 100644
--- a/libpurple/dbus-analyze-functions.py
+++ b/libpurple/dbus-analyze-functions.py
@@ -29,7 +29,11 @@ excluded = [\
# Similar to the above:
"purple_account_set_register_callback",
"purple_account_unregister",
- "purple_connection_new_unregister",
+
+ # Similar to the above, again
+ "purple_menu_action_new",
+ "purple_menu_action_set_callback",
+ "purple_menu_action_get_callback",
# These functions are excluded because they involve setting arbitrary
# data via pointers for protocols and UIs. This just won't work.
@@ -491,7 +495,7 @@ class ServerBinding (Binding):
if self.function.name in stringlists:
self.cdecls.append("\tchar **%s;" % name)
self.ccode.append("\tlist = %s;" % self.call)
- self.ccode.append("\t%s = (char **)purple_%s_to_array(list, FALSE, &%s_LEN);" % \
+ self.ccode.append("\t%s = (char **)purple_%s_to_array(list, &%s_LEN);" % \
(name, type[0], name))
self.cparamsout.append("DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &%s, %s_LEN" \
% (name, name))
@@ -503,7 +507,7 @@ class ServerBinding (Binding):
else:
self.cdecls.append("\tdbus_int32_t *%s;" % name)
self.ccode.append("\tlist = %s;" % self.call)
- self.ccode.append("\t%s = purple_dbusify_%s(list, FALSE, &%s_LEN);" % \
+ self.ccode.append("\t%s = purple_dbusify_%s(list, &%s_LEN);" % \
(name, type[0], name))
if (not (self.function.name in constlists)):
self.ccode.append("\tg_%s_free(list);" % type[0].lower()[1:])
diff --git a/libpurple/dbus-bindings.h b/libpurple/dbus-bindings.h
index 5611ae58a7..4bd7fa6f96 100644
--- a/libpurple/dbus-bindings.h
+++ b/libpurple/dbus-bindings.h
@@ -32,9 +32,7 @@
#include <dbus/dbus-glib-lowlevel.h>
#include <glib.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
gint purple_dbus_pointer_to_id(gconstpointer node);
gpointer purple_dbus_id_to_pointer(gint id, PurpleDBusType *type);
@@ -84,14 +82,10 @@ purple_dbus_message_iter_get_args_valist (DBusMessageIter *iter,
int first_arg_type,
va_list var_args);
-dbus_int32_t* purple_dbusify_GList(GList *list, gboolean free_memory,
- dbus_int32_t *len);
-dbus_int32_t* purple_dbusify_GSList(GSList *list, gboolean free_memory,
- dbus_int32_t *len);
-gpointer* purple_GList_to_array(GList *list, gboolean free_memory,
- dbus_int32_t *len);
-gpointer* purple_GSList_to_array(GSList *list, gboolean free_memory,
- dbus_int32_t *len);
+dbus_int32_t* purple_dbusify_GList(GList *list, dbus_int32_t *len);
+dbus_int32_t* purple_dbusify_GSList(GSList *list, dbus_int32_t *len);
+gpointer* purple_GList_to_array(GList *list, dbus_int32_t *len);
+gpointer* purple_GSList_to_array(GSList *list, dbus_int32_t *len);
GHashTable *purple_dbus_iter_hash_table(DBusMessageIter *iter, DBusError *error);
const char* empty_to_null(const char *str);
@@ -107,8 +101,6 @@ void purple_dbus_register_bindings(void *handle, PurpleDBusBinding *bindings);
DBusConnection *purple_dbus_get_connection(void);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif
diff --git a/libpurple/dbus-server.c b/libpurple/dbus-server.c
index 86b8f5e122..72efc57107 100644
--- a/libpurple/dbus-server.c
+++ b/libpurple/dbus-server.c
@@ -300,7 +300,7 @@ null_to_empty(const char *s)
}
dbus_int32_t *
-purple_dbusify_GList(GList *list, gboolean free_memory, dbus_int32_t *len)
+purple_dbusify_GList(GList *list, dbus_int32_t *len)
{
dbus_int32_t *array;
int i;
@@ -311,14 +311,11 @@ purple_dbusify_GList(GList *list, gboolean free_memory, dbus_int32_t *len)
for (i = 0, elem = list; elem != NULL; elem = elem->next, i++)
array[i] = purple_dbus_pointer_to_id(elem->data);
- if (free_memory)
- g_list_free(list);
-
return array;
}
dbus_int32_t *
-purple_dbusify_GSList(GSList *list, gboolean free_memory, dbus_int32_t *len)
+purple_dbusify_GSList(GSList *list, dbus_int32_t *len)
{
dbus_int32_t *array;
int i;
@@ -329,14 +326,11 @@ purple_dbusify_GSList(GSList *list, gboolean free_memory, dbus_int32_t *len)
for (i = 0, elem = list; elem != NULL; elem = elem->next, i++)
array[i] = purple_dbus_pointer_to_id(elem->data);
- if (free_memory)
- g_slist_free(list);
-
return array;
}
gpointer *
-purple_GList_to_array(GList *list, gboolean free_memory, dbus_int32_t *len)
+purple_GList_to_array(GList *list, dbus_int32_t *len)
{
gpointer *array;
int i;
@@ -347,14 +341,11 @@ purple_GList_to_array(GList *list, gboolean free_memory, dbus_int32_t *len)
for (i = 0, elem = list; elem != NULL; elem = elem->next, i++)
array[i] = elem->data;
- if (free_memory)
- g_list_free(list);
-
return array;
}
gpointer *
-purple_GSList_to_array(GSList *list, gboolean free_memory, dbus_int32_t *len)
+purple_GSList_to_array(GSList *list, dbus_int32_t *len)
{
gpointer *array;
int i;
@@ -365,9 +356,6 @@ purple_GSList_to_array(GSList *list, gboolean free_memory, dbus_int32_t *len)
for (i = 0, elem = list; elem != NULL; elem = elem->next, i++)
array[i] = elem->data;
- if (free_memory)
- g_slist_free(list);
-
return array;
}
@@ -711,7 +699,7 @@ purple_dbus_message_append_purple_values(DBusMessageIter *iter,
g_return_val_if_fail(ptr, TRUE);
}
- switch (purple_values[i]->type)
+ switch (purple_value_get_type(purple_values[i]))
{
case PURPLE_TYPE_INT:
case PURPLE_TYPE_ENUM:
diff --git a/libpurple/dbus-server.h b/libpurple/dbus-server.h
index 5215dccbae..5810dab8c7 100644
--- a/libpurple/dbus-server.h
+++ b/libpurple/dbus-server.h
@@ -173,8 +173,6 @@ void *purple_dbus_get_handle(void);
/**
* Determines whether this instance owns the DBus service name
- *
- * @since 2.1.0
*/
gboolean purple_dbus_is_owner(void);
diff --git a/libpurple/dbus-useful.c b/libpurple/dbus-useful.c
index b288887b1f..4a685fc88f 100644
--- a/libpurple/dbus-useful.c
+++ b/libpurple/dbus-useful.c
@@ -25,7 +25,7 @@ purple_accounts_find_ext(const char *name, const char *protocol_id,
if (who && strcmp(purple_normalize(NULL, purple_account_get_username(account)), who))
continue;
- if (protocol_id && strcmp(account->protocol_id, protocol_id))
+ if (protocol_id && strcmp(purple_account_get_protocol_id(account), protocol_id))
continue;
if (account_test && !account_test(account))
diff --git a/libpurple/dbus-useful.h b/libpurple/dbus-useful.h
index 663c4c7a10..9d7b34dc5a 100644
--- a/libpurple/dbus-useful.h
+++ b/libpurple/dbus-useful.h
@@ -1,5 +1,7 @@
#include "conversation.h"
+G_BEGIN_DECLS
+
PurpleAccount *purple_accounts_find_ext(const char *name, const char *protocol_id,
gboolean (*account_test)(const PurpleAccount *account));
@@ -7,7 +9,5 @@ PurpleAccount *purple_accounts_find_any(const char *name, const char *protocol);
PurpleAccount *purple_accounts_find_connected(const char *name, const char *protocol);
-
-
-
+G_END_DECLS
diff --git a/libpurple/debug.c b/libpurple/debug.c
index ca17f62bde..095d90bb49 100644
--- a/libpurple/debug.c
+++ b/libpurple/debug.c
@@ -224,12 +224,5 @@ purple_debug_init(void)
purple_debug_set_verbose(TRUE);
purple_prefs_add_none("/purple/debug");
-
- /*
- * This pref is obsolete and no longer referenced anywhere. It only
- * survives here because it would be an API break if we removed it.
- * Remove this when we get to 3.0.0 :)
- */
- purple_prefs_add_bool("/purple/debug/timestamps", TRUE);
}
diff --git a/libpurple/debug.h b/libpurple/debug.h
index b90b86b99c..ba7cc92ef3 100644
--- a/libpurple/debug.h
+++ b/libpurple/debug.h
@@ -59,9 +59,7 @@ typedef struct
void (*_purple_reserved4)(void);
} PurpleDebugUiOps;
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Debug API */
@@ -161,8 +159,6 @@ gboolean purple_debug_is_enabled(void);
* plugins.
*
* @param verbose TRUE to enable verbose debugging or FALSE to disable it.
- *
- * @since 2.6.0
*/
void purple_debug_set_verbose(gboolean verbose);
@@ -170,8 +166,6 @@ void purple_debug_set_verbose(gboolean verbose);
* Check if verbose logging is enabled.
*
* @return TRUE if verbose debugging is enabled, FALSE if it is not.
- *
- * @since 2.6.0
*/
gboolean purple_debug_is_verbose(void);
@@ -183,8 +177,6 @@ gboolean purple_debug_is_verbose(void);
* @param unsafe TRUE to enable debug logging of messages that could
* potentially contain passwords and other sensitive information.
* FALSE to disable it.
- *
- * @since 2.6.0
*/
void purple_debug_set_unsafe(gboolean unsafe);
@@ -194,8 +186,6 @@ void purple_debug_set_unsafe(gboolean unsafe);
* @return TRUE if the debug logging of all messages is enabled, FALSE
* if messages that could potentially contain passwords and other
* sensitive information are not logged.
- *
- * @since 2.6.0
*/
gboolean purple_debug_is_unsafe(void);
@@ -236,8 +226,6 @@ void purple_debug_init(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_DEBUG_H_ */
diff --git a/libpurple/dnsquery.c b/libpurple/dnsquery.c
index 18246bc56b..bb98db553d 100644
--- a/libpurple/dnsquery.c
+++ b/libpurple/dnsquery.c
@@ -297,6 +297,10 @@ purple_dnsquery_resolver_run(int child_out, int child_in, gboolean show_debug)
}
rc = read(child_in, &dns_params, sizeof(dns_params_t));
if (rc < 0) {
+ if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
+ /* Try again */
+ continue;
+ }
fprintf(stderr, "dns[%d]: Error: Could not read dns_params: "
"%s\n", getpid(), strerror(errno));
break;
@@ -910,7 +914,7 @@ initiate_resolving(gpointer data)
}
PurpleDnsQueryData *
-purple_dnsquery_a_account(PurpleAccount *account, const char *hostname, int port,
+purple_dnsquery_a(PurpleAccount *account, const char *hostname, int port,
PurpleDnsQueryConnectFunction callback, gpointer data)
{
PurpleDnsQueryData *query_data;
@@ -940,13 +944,6 @@ purple_dnsquery_a_account(PurpleAccount *account, const char *hostname, int port
return query_data;
}
-PurpleDnsQueryData *
-purple_dnsquery_a(const char *hostname, int port,
- PurpleDnsQueryConnectFunction callback, gpointer data)
-{
- return purple_dnsquery_a_account(NULL, hostname, port, callback, data);
-}
-
void
purple_dnsquery_destroy(PurpleDnsQueryData *query_data)
{
diff --git a/libpurple/dnsquery.h b/libpurple/dnsquery.h
index dde19983f6..9c811b684f 100644
--- a/libpurple/dnsquery.h
+++ b/libpurple/dnsquery.h
@@ -76,9 +76,7 @@ typedef struct
void (*_purple_reserved4)(void);
} PurpleDnsQueryUiOps;
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name DNS query API */
@@ -88,7 +86,7 @@ extern "C" {
/**
* Perform an asynchronous DNS query.
*
- * @param account the account that the query is being done for (or NULL)
+ * @param account The account that the query is being done for (or NULL)
* @param hostname The hostname to resolve.
* @param port A port number which is stored in the struct sockaddr.
* @param callback The callback function to call after resolving.
@@ -98,27 +96,8 @@ extern "C" {
* a data structure that can be used to cancel the pending
* DNS query, if needed.
*
- * @since 2.8.0
*/
-PurpleDnsQueryData *purple_dnsquery_a_account(PurpleAccount *account, const char *hostname, int port, PurpleDnsQueryConnectFunction callback, gpointer data);
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_DNSQUERY_C_)
-/**
- * Perform an asynchronous DNS query.
- *
- * @param hostname The hostname to resolve.
- * @param port A port number which is stored in the struct sockaddr.
- * @param callback The callback function to call after resolving.
- * @param data Extra data to pass to the callback function.
- *
- * @return NULL if there was an error, otherwise return a reference to
- * a data structure that can be used to cancel the pending
- * DNS query, if needed.
- *
- * @deprecated Use purple_dnsquery_a_account instead
- */
-PurpleDnsQueryData *purple_dnsquery_a(const char *hostname, int port, PurpleDnsQueryConnectFunction callback, gpointer data);
-#endif
+PurpleDnsQueryData *purple_dnsquery_a(PurpleAccount *account, const char *hostname, int port, PurpleDnsQueryConnectFunction callback, gpointer data);
/**
* Cancel a DNS query and destroy the associated data structure.
@@ -173,8 +152,6 @@ void purple_dnsquery_uninit(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_DNSQUERY_H_ */
diff --git a/libpurple/dnssrv.c b/libpurple/dnssrv.c
index 04aff7ecff..f72117ae6b 100644
--- a/libpurple/dnssrv.c
+++ b/libpurple/dnssrv.c
@@ -725,15 +725,7 @@ res_thread(gpointer data)
#endif
PurpleSrvTxtQueryData *
-purple_srv_resolve(const char *protocol, const char *transport,
- const char *domain, PurpleSrvCallback cb, gpointer extradata)
-{
- return purple_srv_resolve_account(NULL, protocol, transport, domain,
- cb, extradata);
-}
-
-PurpleSrvTxtQueryData *
-purple_srv_resolve_account(PurpleAccount *account, const char *protocol,
+purple_srv_resolve(PurpleAccount *account, const char *protocol,
const char *transport, const char *domain, PurpleSrvCallback cb,
gpointer extradata)
{
@@ -798,6 +790,12 @@ purple_srv_resolve_account(PurpleAccount *account, const char *protocol,
return NULL;
}
+ /*
+ * TODO: We should put a cap on the number of forked processes that we
+ * allow at any given time. If we get too many requests they
+ * should be put into a queue and handled later. (This is what
+ * we do for A record lookups.)
+ */
pid = fork();
if (pid == -1) {
purple_debug_error("dnssrv", "Could not create process!\n");
@@ -863,13 +861,7 @@ purple_srv_resolve_account(PurpleAccount *account, const char *protocol,
#endif
}
-PurpleSrvTxtQueryData *purple_txt_resolve(const char *owner,
- const char *domain, PurpleTxtCallback cb, gpointer extradata)
-{
- return purple_txt_resolve_account(NULL, owner, domain, cb, extradata);
-}
-
-PurpleSrvTxtQueryData *purple_txt_resolve_account(PurpleAccount *account,
+PurpleSrvTxtQueryData *purple_txt_resolve(PurpleAccount *account,
const char *owner, const char *domain, PurpleTxtCallback cb,
gpointer extradata)
{
@@ -929,6 +921,12 @@ PurpleSrvTxtQueryData *purple_txt_resolve_account(PurpleAccount *account,
return NULL;
}
+ /*
+ * TODO: We should put a cap on the number of forked processes that we
+ * allow at any given time. If we get too many requests they
+ * should be put into a queue and handled later. (This is what
+ * we do for A record lookups.)
+ */
pid = fork();
if (pid == -1) {
purple_debug_error("dnssrv", "Could not create process!\n");
@@ -994,18 +992,6 @@ PurpleSrvTxtQueryData *purple_txt_resolve_account(PurpleAccount *account,
#endif
}
-void
-purple_txt_cancel(PurpleSrvTxtQueryData *query_data)
-{
- purple_srv_txt_query_destroy(query_data);
-}
-
-void
-purple_srv_cancel(PurpleSrvTxtQueryData *query_data)
-{
- purple_srv_txt_query_destroy(query_data);
-}
-
const gchar *
purple_txt_response_get_content(PurpleTxtResponse *resp)
{
diff --git a/libpurple/dnssrv.h b/libpurple/dnssrv.h
index 7435c10e0c..747d8bda17 100644
--- a/libpurple/dnssrv.h
+++ b/libpurple/dnssrv.h
@@ -24,18 +24,10 @@
#ifndef _PURPLE_DNSSRV_H
#define _PURPLE_DNSSRV_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct _PurpleSrvTxtQueryData PurpleSrvTxtQueryData;
typedef struct _PurpleSrvResponse PurpleSrvResponse;
typedef struct _PurpleTxtResponse PurpleTxtResponse;
-/* For compatibility, should be removed for 3.0.0
- */
-typedef struct _PurpleSrvTxtQueryData PurpleSrvQueryData;
-
#include <glib.h>
enum PurpleDnsType {
@@ -74,7 +66,7 @@ typedef struct
/** Called just before @a query_data is freed; this should cancel any
* further use of @a query_data the UI would make. Unneeded if
- * #resolve_host is not implemented.
+ * #resolve is not implemented.
*/
void (*destroy)(PurpleSrvTxtQueryData *query_data);
@@ -100,89 +92,45 @@ typedef void (*PurpleSrvCallback)(PurpleSrvResponse *resp, int results, gpointer
*/
typedef void (*PurpleTxtCallback)(GList *responses, gpointer data);
-/**
- * Queries an SRV record.
- *
- * @param account the account that the query is being done for (or NULL)
- * @param protocol Name of the protocol (e.g. "sip")
- * @param transport Name of the transport ("tcp" or "udp")
- * @param domain Domain name to query (e.g. "blubb.com")
- * @param cb A callback which will be called with the results
- * @param extradata Extra data to be passed to the callback
- *
- * @since 2.8.0
- */
-PurpleSrvTxtQueryData *purple_srv_resolve_account(PurpleAccount *account, const char *protocol, const char *transport, const char *domain, PurpleSrvCallback cb, gpointer extradata);
+G_BEGIN_DECLS
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_DNSSRV_C_)
/**
* Queries an SRV record.
*
- * @param protocol Name of the protocol (e.g. "sip")
+ * @param account The account that the query is being done for (or NULL)
+ * @param protocol Name of the protocol (e.g. "sip")
* @param transport Name of the transport ("tcp" or "udp")
- * @param domain Domain name to query (e.g. "blubb.com")
- * @param cb A callback which will be called with the results
- * @param extradata Extra data to be passed to the callback
- *
- * @deprecated Use purple_srv_resolve_account instead
- */
-PurpleSrvTxtQueryData *purple_srv_resolve(const char *protocol, const char *transport, const char *domain, PurpleSrvCallback cb, gpointer extradata);
-#endif
-
-/**
- * Cancel an SRV or DNS query.
- *
- * @param query_data The request to cancel.
- *
- * @deprecated Use purple_srv_txt_query_destroy instead
- */
-void purple_srv_cancel(PurpleSrvTxtQueryData *query_data);
-
-/**
- * Queries an TXT record.
- *
- * @param account the account that the query is being done for (or NULL)
- * @param owner Name of the protocol (e.g. "_xmppconnect")
- * @param domain Domain name to query (e.g. "blubb.com")
- * @param cb A callback which will be called with the results
+ * @param domain Domain name to query (e.g. "blubb.com")
+ * @param cb A callback which will be called with the results
* @param extradata Extra data to be passed to the callback
*
- * @since 2.8.0
+ * @return NULL if there was an error, otherwise return a reference to
+ * a data structure that can be used to cancel the pending
+ * DNS query, if needed.
*/
-PurpleSrvTxtQueryData *purple_txt_resolve_account(PurpleAccount *account, const char *owner, const char *domain, PurpleTxtCallback cb, gpointer extradata);
+PurpleSrvTxtQueryData *purple_srv_resolve(PurpleAccount *account, const char *protocol, const char *transport, const char *domain, PurpleSrvCallback cb, gpointer extradata);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_DNSSRV_C_)
/**
* Queries an TXT record.
*
- * @param owner Name of the protocol (e.g. "_xmppconnect")
- * @param domain Domain name to query (e.g. "blubb.com")
- * @param cb A callback which will be called with the results
+ * @param account The account that the query is being done for (or NULL)
+ * @param owner Name of the protocol (e.g. "_xmppconnect")
+ * @param domain Domain name to query (e.g. "blubb.com")
+ * @param cb A callback which will be called with the results
* @param extradata Extra data to be passed to the callback
*
- * @deprecated Use purple_txt_resolve_account instead
- *
- * @since 2.6.0
+ * @return NULL if there was an error, otherwise return a reference to
+ * a data structure that can be used to cancel the pending
+ * DNS query, if needed.
*/
-PurpleSrvTxtQueryData *purple_txt_resolve(const char *owner, const char *domain, PurpleTxtCallback cb, gpointer extradata);
-#endif
-
-/**
- * Cancel an TXT DNS query.
- *
- * @param query_data The request to cancel.
- * @since 2.6.0
- *
- * @deprecated Use purple_srv_txt_query_destroy instead
- */
-void purple_txt_cancel(PurpleSrvTxtQueryData *query_data);
+PurpleSrvTxtQueryData *purple_txt_resolve(PurpleAccount *account, const char *owner, const char *domain, PurpleTxtCallback cb, gpointer extradata);
/**
* Get the value of the current TXT record.
*
* @param response The TXT response record
- * @returns The value of the current TXT record.
- * @since 2.6.0
+ *
+ * @return The value of the current TXT record.
*/
const gchar *purple_txt_response_get_content(PurpleTxtResponse *response);
@@ -190,7 +138,6 @@ const gchar *purple_txt_response_get_content(PurpleTxtResponse *response);
* Destroy a TXT DNS response object.
*
* @param response The PurpleTxtResponse to destroy.
- * @since 2.6.0
*/
void purple_txt_response_destroy(PurpleTxtResponse *response);
@@ -220,7 +167,7 @@ void purple_srv_txt_query_set_ui_ops(PurpleSrvTxtQueryUiOps *ops);
PurpleSrvTxtQueryUiOps *purple_srv_txt_query_get_ui_ops(void);
/**
- * Get the query from a PurpleDnsQueryData
+ * Get the query from a PurpleSrvTxtQueryData
*
* @param query_data The SRV/TXT query
* @return The query.
@@ -228,15 +175,14 @@ PurpleSrvTxtQueryUiOps *purple_srv_txt_query_get_ui_ops(void);
char *purple_srv_txt_query_get_query(PurpleSrvTxtQueryData *query_data);
/**
- * Get the type from a PurpleDnsQueryData (TXT or SRV)
+ * Get the type from a PurpleSrvTxtQueryData (TXT or SRV)
*
* @param query_data The query
* @return The query.
*/
int purple_srv_txt_query_get_type(PurpleSrvTxtQueryData *query_data);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_DNSSRV_H */
+
diff --git a/libpurple/eventloop.h b/libpurple/eventloop.h
index ca95f6cbe8..01465a150a 100644
--- a/libpurple/eventloop.h
+++ b/libpurple/eventloop.h
@@ -28,10 +28,6 @@
#include <glib.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/**
* An input condition.
*/
@@ -145,7 +141,6 @@ struct _PurpleEventLoopUiOps
* #timeout_add.
*
* @see purple_timeout_add_seconds()
- * @since 2.1.0
**/
guint (*timeout_add_seconds)(guint interval, GSourceFunc function,
gpointer data);
@@ -155,6 +150,8 @@ struct _PurpleEventLoopUiOps
void (*_purple_reserved4)(void);
};
+G_BEGIN_DECLS
+
/**************************************************************************/
/** @name Event Loop API */
/**************************************************************************/
@@ -192,8 +189,6 @@ guint purple_timeout_add(guint interval, GSourceFunc function, gpointer data);
* @param data data to pass to @a function.
* @return A handle to the timer which can be passed to
* purple_timeout_remove() to remove the timer.
- *
- * @since 2.1.0
*/
guint purple_timeout_add_seconds(guint interval, GSourceFunc function, gpointer data);
@@ -269,8 +264,6 @@ PurpleEventLoopUiOps *purple_eventloop_get_ui_ops(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_EVENTLOOP_H_ */
diff --git a/libpurple/example/nullclient.c b/libpurple/example/nullclient.c
index 31fc0a230f..113fcf8e2e 100644
--- a/libpurple/example/nullclient.c
+++ b/libpurple/example/nullclient.c
@@ -237,7 +237,7 @@ static void
signed_on(PurpleConnection *gc, gpointer null)
{
PurpleAccount *account = purple_connection_get_account(gc);
- printf("Account connected: %s %s\n", account->username, account->protocol_id);
+ printf("Account connected: %s %s\n", purple_account_get_username(account), purple_account_get_protocol_id(account));
}
static void
diff --git a/libpurple/ft.c b/libpurple/ft.c
index 598a7c2cf3..f7f90c214f 100644
--- a/libpurple/ft.c
+++ b/libpurple/ft.c
@@ -220,7 +220,7 @@ purple_xfer_unref(PurpleXfer *xfer)
purple_xfer_destroy(xfer);
}
-static void
+void
purple_xfer_set_status(PurpleXfer *xfer, PurpleXferStatusType status)
{
g_return_if_fail(xfer != NULL);
@@ -306,7 +306,8 @@ purple_xfer_conversation_write_internal(PurpleXfer *xfer,
int id = purple_imgstore_add_with_id(data, size, NULL);
message_with_img =
- g_strdup_printf("<img id='%d'> %s", id, escaped);
+ g_strdup_printf("<img src='" PURPLE_STORED_IMAGE_PROTOCOL "%d'> %s",
+ id, escaped);
purple_conversation_write(conv, NULL, message_with_img, flags,
time(NULL));
purple_imgstore_unref_by_id(id);
@@ -490,7 +491,7 @@ static void
purple_xfer_ask_recv(PurpleXfer *xfer)
{
char *buf, *size_buf;
- size_t size;
+ goffset size;
gconstpointer thumb;
gsize thumb_size;
@@ -720,6 +721,20 @@ purple_xfer_request_denied(PurpleXfer *xfer)
purple_xfer_unref(xfer);
}
+int purple_xfer_get_fd(PurpleXfer *xfer)
+{
+ g_return_val_if_fail(xfer != NULL, 0);
+
+ return xfer->fd;
+}
+
+int purple_xfer_get_watcher(PurpleXfer *xfer)
+{
+ g_return_val_if_fail(xfer != NULL, 0);
+
+ return xfer->watcher;
+}
+
PurpleXferType
purple_xfer_get_type(const PurpleXfer *xfer)
{
@@ -751,9 +766,8 @@ purple_xfer_get_status(const PurpleXfer *xfer)
return xfer->status;
}
-/* FIXME: Rename with cancelled for 3.0.0. */
gboolean
-purple_xfer_is_canceled(const PurpleXfer *xfer)
+purple_xfer_is_cancelled(const PurpleXfer *xfer)
{
g_return_val_if_fail(xfer != NULL, TRUE);
@@ -788,7 +802,7 @@ purple_xfer_get_local_filename(const PurpleXfer *xfer)
return xfer->local_filename;
}
-size_t
+goffset
purple_xfer_get_bytes_sent(const PurpleXfer *xfer)
{
g_return_val_if_fail(xfer != NULL, 0);
@@ -796,7 +810,7 @@ purple_xfer_get_bytes_sent(const PurpleXfer *xfer)
return xfer->bytes_sent;
}
-size_t
+goffset
purple_xfer_get_bytes_remaining(const PurpleXfer *xfer)
{
g_return_val_if_fail(xfer != NULL, 0);
@@ -804,7 +818,7 @@ purple_xfer_get_bytes_remaining(const PurpleXfer *xfer)
return xfer->bytes_remaining;
}
-size_t
+goffset
purple_xfer_get_size(const PurpleXfer *xfer)
{
g_return_val_if_fail(xfer != NULL, 0);
@@ -864,6 +878,20 @@ purple_xfer_get_end_time(const PurpleXfer *xfer)
return xfer->end_time;
}
+void purple_xfer_set_fd(PurpleXfer *xfer, int fd)
+{
+ g_return_if_fail(xfer != NULL);
+
+ xfer->fd = fd;
+}
+
+void purple_xfer_set_watcher(PurpleXfer *xfer, int watcher)
+{
+ g_return_if_fail(xfer != NULL);
+
+ xfer->watcher = watcher;
+}
+
void
purple_xfer_set_completed(PurpleXfer *xfer, gboolean completed)
{
@@ -938,7 +966,7 @@ purple_xfer_set_local_filename(PurpleXfer *xfer, const char *filename)
}
void
-purple_xfer_set_size(PurpleXfer *xfer, size_t size)
+purple_xfer_set_size(PurpleXfer *xfer, goffset size)
{
g_return_if_fail(xfer != NULL);
@@ -947,7 +975,15 @@ purple_xfer_set_size(PurpleXfer *xfer, size_t size)
}
void
-purple_xfer_set_bytes_sent(PurpleXfer *xfer, size_t bytes_sent)
+purple_xfer_set_local_port(PurpleXfer *xfer, unsigned int local_port)
+{
+ g_return_if_fail(xfer != NULL);
+
+ xfer->local_port = local_port;
+}
+
+void
+purple_xfer_set_bytes_sent(PurpleXfer *xfer, goffset bytes_sent)
{
g_return_if_fail(xfer != NULL);
@@ -1404,13 +1440,6 @@ purple_xfer_start(PurpleXfer *xfer, int fd, const char *ip,
purple_xfer_set_status(xfer, PURPLE_XFER_STATUS_STARTED);
- /*
- * FIXME 3.0.0 -- there's too much broken code depending on fd == 0
- * meaning "don't use a real fd"
- */
- if (fd == 0)
- fd = -1;
-
if (type == PURPLE_XFER_RECEIVE) {
cond = PURPLE_INPUT_READ;
@@ -1701,6 +1730,37 @@ purple_xfer_prepare_thumbnail(PurpleXfer *xfer, const gchar *formats)
}
}
+void
+purple_xfer_set_protocol_data(PurpleXfer *xfer, gpointer proto_data)
+{
+ g_return_if_fail(xfer != NULL);
+
+ xfer->proto_data = proto_data;
+}
+
+gpointer
+purple_xfer_get_protocol_data(const PurpleXfer *xfer)
+{
+ g_return_val_if_fail(xfer != NULL, NULL);
+
+ return xfer->proto_data;
+}
+
+void purple_xfer_set_ui_data(PurpleXfer *xfer, gpointer ui_data)
+{
+ g_return_if_fail(xfer != NULL);
+
+ xfer->ui_data = ui_data;
+}
+
+gpointer purple_xfer_get_ui_data(const PurpleXfer *xfer)
+{
+ g_return_val_if_fail(xfer != NULL, NULL);
+
+ return xfer->ui_data;
+}
+
+
/**************************************************************************
* File Transfer Subsystem API
**************************************************************************/
diff --git a/libpurple/ft.h b/libpurple/ft.h
index 3636cae247..0505db5841 100644
--- a/libpurple/ft.h
+++ b/libpurple/ft.h
@@ -87,7 +87,6 @@ typedef struct
*
* @return size if the write was successful, or a value between 0 and
* size on error.
- * @since 2.6.0
*/
gssize (*ui_write)(PurpleXfer *xfer, const guchar *buffer, gssize size);
@@ -102,7 +101,6 @@ typedef struct
* @returns The amount of data in the buffer, 0 if nothing is available,
* and a negative value if an error occurred and the transfer
* should be cancelled (libpurple will cancel).
- * @since 2.6.0
*/
gssize (*ui_read)(PurpleXfer *xfer, guchar **buffer, gssize size);
@@ -115,8 +113,6 @@ typedef struct
* @param xfer The file transfer structure
* @param buffer A pointer to the beginning of the unwritten data.
* @param size The amount of unwritten data.
- *
- * @since 2.6.0
*/
void (*data_not_sent)(PurpleXfer *xfer, const guchar *buffer, gsize size);
@@ -144,7 +140,7 @@ struct _PurpleXfer
char *message; /**< A message sent with the request */
char *filename; /**< The name sent over the network. */
char *local_filename; /**< The name on the local hard drive. */
- size_t size; /**< The size of the file. */
+ goffset size; /**< The size of the file. */
FILE *dest_fp; /**< The destination file pointer. */
@@ -155,8 +151,8 @@ struct _PurpleXfer
int fd; /**< The socket file descriptor. */
int watcher; /**< Watcher. */
- size_t bytes_sent; /**< The number of bytes sent. */
- size_t bytes_remaining; /**< The number of bytes remaining. */
+ goffset bytes_sent; /**< The number of bytes sent. */
+ goffset bytes_remaining; /**< The number of bytes remaining. */
time_t start_time; /**< When the transfer of data began. */
time_t end_time; /**< When the transfer of data ended. */
@@ -185,12 +181,10 @@ struct _PurpleXfer
PurpleXferUiOps *ui_ops; /**< UI-specific operations. */
void *ui_data; /**< UI-specific data. */
- void *data; /**< prpl-specific data. */
+ void *proto_data; /**< prpl-specific data. */
};
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name File Transfer API */
@@ -266,6 +260,24 @@ void purple_xfer_request_accepted(PurpleXfer *xfer, const char *filename);
void purple_xfer_request_denied(PurpleXfer *xfer);
/**
+ * Returns the socket file descriptor.
+ *
+ * @param xfer The file transfer.
+ *
+ * @return The socket file descriptor.
+ */
+int purple_xfer_get_fd(PurpleXfer *xfer);
+
+/**
+ * Returns the Watcher for the transfer.
+ *
+ * @param xfer The file transfer.
+ *
+ * @return The watcher.
+ */
+int purple_xfer_get_watcher(PurpleXfer *xfer);
+
+/**
* Returns the type of file transfer.
*
* @param xfer The file transfer.
@@ -289,8 +301,6 @@ PurpleAccount *purple_xfer_get_account(const PurpleXfer *xfer);
* @param xfer The file transfer.
*
* @return The name of the remote user.
- *
- * @since 2.1.0
*/
const char *purple_xfer_get_remote_user(const PurpleXfer *xfer);
@@ -309,9 +319,8 @@ PurpleXferStatusType purple_xfer_get_status(const PurpleXfer *xfer);
* @param xfer The file transfer.
*
* @return Whether or not the transfer was cancelled.
- * FIXME: This should be renamed using cancelled for 3.0.0.
*/
-gboolean purple_xfer_is_canceled(const PurpleXfer *xfer);
+gboolean purple_xfer_is_cancelled(const PurpleXfer *xfer);
/**
* Returns the completed state for a file transfer.
@@ -347,7 +356,7 @@ const char *purple_xfer_get_local_filename(const PurpleXfer *xfer);
*
* @return The number of bytes sent.
*/
-size_t purple_xfer_get_bytes_sent(const PurpleXfer *xfer);
+goffset purple_xfer_get_bytes_sent(const PurpleXfer *xfer);
/**
* Returns the number of bytes remaining to send or receive.
@@ -356,7 +365,7 @@ size_t purple_xfer_get_bytes_sent(const PurpleXfer *xfer);
*
* @return The number of bytes remaining.
*/
-size_t purple_xfer_get_bytes_remaining(const PurpleXfer *xfer);
+goffset purple_xfer_get_bytes_remaining(const PurpleXfer *xfer);
/**
* Returns the size of the file being sent or received.
@@ -365,7 +374,7 @@ size_t purple_xfer_get_bytes_remaining(const PurpleXfer *xfer);
*
* @return The total size of the file.
*/
-size_t purple_xfer_get_size(const PurpleXfer *xfer);
+goffset purple_xfer_get_size(const PurpleXfer *xfer);
/**
* Returns the current percentage of progress of the transfer.
@@ -411,7 +420,6 @@ unsigned int purple_xfer_get_remote_port(const PurpleXfer *xfer);
* @param xfer The file transfer.
*
* @return The time when the transfer started.
- * @since 2.4.0
*/
time_t purple_xfer_get_start_time(const PurpleXfer *xfer);
@@ -421,11 +429,26 @@ time_t purple_xfer_get_start_time(const PurpleXfer *xfer);
* @param xfer The file transfer.
*
* @return The time when the transfer ended.
- * @since 2.4.0
*/
time_t purple_xfer_get_end_time(const PurpleXfer *xfer);
/**
+ * Sets the socket file descriptor.
+ *
+ * @param xfer The file transfer.
+ * @param fd The file descriptor.
+ */
+void purple_xfer_set_fd(PurpleXfer *xfer, int fd);
+
+/**
+ * Sets the watcher for the file transfer.
+ *
+ * @param xfer The file transfer.
+ * @param watcher The watcher.
+ */
+void purple_xfer_set_watcher(PurpleXfer *xfer, int watcher);
+
+/**
* Sets the completed state for the file transfer.
*
* @param xfer The file transfer.
@@ -434,6 +457,14 @@ time_t purple_xfer_get_end_time(const PurpleXfer *xfer);
void purple_xfer_set_completed(PurpleXfer *xfer, gboolean completed);
/**
+ * Sets the current status for the file transfer.
+ *
+ * @param xfer The file transfer.
+ * @param status The current status.
+ */
+void purple_xfer_set_status(PurpleXfer *xfer, PurpleXferStatusType status);
+
+/**
* Sets the filename for the file transfer.
*
* @param xfer The file transfer.
@@ -463,7 +494,15 @@ void purple_xfer_set_local_filename(PurpleXfer *xfer, const char *filename);
* @param xfer The file transfer.
* @param size The size of the file.
*/
-void purple_xfer_set_size(PurpleXfer *xfer, size_t size);
+void purple_xfer_set_size(PurpleXfer *xfer, goffset size);
+
+/**
+ * Sets the local port of the file transfer.
+ *
+ * @param xfer The file transfer.
+ * @param local_port The local port.
+ */
+void purple_xfer_set_local_port(PurpleXfer *xfer, unsigned int local_port);
/**
* Sets the current working position in the active file transfer. This
@@ -478,7 +517,7 @@ void purple_xfer_set_size(PurpleXfer *xfer, size_t size);
* send. If we're receiving a file, this is the
* next byte that we expect to receive.
*/
-void purple_xfer_set_bytes_sent(PurpleXfer *xfer, size_t bytes_sent);
+void purple_xfer_set_bytes_sent(PurpleXfer *xfer, goffset bytes_sent);
/**
* Returns the UI operations structure for a file transfer.
@@ -596,11 +635,8 @@ gssize purple_xfer_write(PurpleXfer *xfer, const guchar *buffer, gsize size);
* file receive transfer. On send, @a fd must be specified, and
* @a ip and @a port are ignored.
*
- * Prior to libpurple 2.6.0, passing '0' to @a fd was special-cased to
- * allow the protocol plugin to facilitate the file transfer itself. As of
- * 2.6.0, this is supported (for backward compatibility), but will be
- * removed in libpurple 3.0.0. If a prpl detects that the running libpurple
- * is running 2.6.0 or higher, it should use the invalid fd '-1'.
+ * Passing @a fd as '-1' is a special-case and indicates to the
+ * protocol plugin to facilitate the file transfer itself.
*
* @param xfer The file transfer.
* @param fd The file descriptor for the socket.
@@ -677,8 +713,6 @@ void purple_xfer_conversation_write(PurpleXfer *xfer, char *message, gboolean is
* read/write/data_not_sent UI ops.
*
* @param xfer The file transfer which is ready.
- *
- * @since 2.6.0
*/
void purple_xfer_ui_ready(PurpleXfer *xfer);
@@ -688,8 +722,6 @@ void purple_xfer_ui_ready(PurpleXfer *xfer);
* ops and cannot/does not provide a raw fd to the core.
*
* @param xfer The file transfer which is ready.
- *
- * @since 2.6.0
*/
void purple_xfer_prpl_ready(PurpleXfer *xfer);
@@ -700,7 +732,6 @@ void purple_xfer_prpl_ready(PurpleXfer *xfer);
* @param len If not @c NULL, the length of the thumbnail data returned
* will be set in the location pointed to by this.
* @return The thumbnail data, or NULL if there is no thumbnail
- * @since 2.7.0
*/
gconstpointer purple_xfer_get_thumbnail(const PurpleXfer *xfer, gsize *len);
@@ -709,7 +740,6 @@ gconstpointer purple_xfer_get_thumbnail(const PurpleXfer *xfer, gsize *len);
*
* @param xfer The file transfer to get the mimetype for
* @return The mimetype of the thumbnail, or @c NULL if not thumbnail is set
- * @since 2.7.0
*/
const gchar *purple_xfer_get_thumbnail_mimetype(const PurpleXfer *xfer);
@@ -721,7 +751,6 @@ const gchar *purple_xfer_get_thumbnail_mimetype(const PurpleXfer *xfer);
* @param thumbnail A pointer to the thumbnail data, this will be copied
* @param size The size in bytes of the passed in thumbnail data
* @param mimetype The mimetype of the generated thumbnail
- * @since 2.7.0
*/
void purple_xfer_set_thumbnail(PurpleXfer *xfer, gconstpointer thumbnail,
gsize size, const gchar *mimetype);
@@ -733,10 +762,44 @@ void purple_xfer_set_thumbnail(PurpleXfer *xfer, gconstpointer thumbnail,
* @param xfer The file transfer to create a thumbnail for
* @param formats A comma-separated list of mimetypes for image formats
* the protocols can use for thumbnails.
- * @since 2.7.0
*/
void purple_xfer_prepare_thumbnail(PurpleXfer *xfer, const gchar *formats);
+/**
+ * Sets the protocol data for a file transfer.
+ *
+ * @param xfer The file transfer.
+ * @param proto_data The protocol data to set for the file transfer.
+ */
+void purple_xfer_set_protocol_data(PurpleXfer *xfer, gpointer proto_data);
+
+/**
+ * Gets the protocol data for a file transfer.
+ *
+ * @param xfer The file transfer.
+ *
+ * @return The protocol data for the file transfer.
+ */
+gpointer purple_xfer_get_protocol_data(const PurpleXfer *xfer);
+
+/**
+ * Set the UI data associated with this file transfer.
+ *
+ * @param xfer The file transfer.
+ * @param ui_data A pointer to associate with this file transfer.
+ */
+void purple_xfer_set_ui_data(PurpleXfer *xfer, gpointer ui_data);
+
+/**
+ * Get the UI data associated with this file transfer.
+ *
+ * @param xfer The file transfer.
+ *
+ * @return The UI data associated with this file transfer. This is a
+ * convenience field provided to the UIs--it is not
+ * used by the libpurple core.
+ */
+gpointer purple_xfer_get_ui_data(const PurpleXfer *xfer);
/*@}*/
@@ -778,8 +841,7 @@ PurpleXferUiOps *purple_xfers_get_ui_ops(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_FT_H_ */
+
diff --git a/libpurple/gaim-compat.h b/libpurple/gaim-compat.h
deleted file mode 100644
index 848b9c4d29..0000000000
--- a/libpurple/gaim-compat.h
+++ /dev/null
@@ -1,2317 +0,0 @@
-/**
- * @file gaim-compat.h Gaim Compat macros
- * @ingroup core
- */
-
-/* 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.
- *
- * 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
- */
-#ifndef _GAIM_COMPAT_H_
-#define _GAIM_COMPAT_H_
-
-#include <glib.h>
-
-/* from account.h */
-#define GaimAccountUiOps PurpleAccountUiOps
-#define GaimAccount PurpleAccount
-
-#define GaimFilterAccountFunc PurpleFilterAccountFunc
-#define GaimAccountRequestAuthorizationCb PurpleAccountRequestAuthorizationCb
-
-#define gaim_account_new purple_account_new
-#define gaim_account_destroy purple_account_destroy
-#define gaim_account_connect purple_account_connect
-#define gaim_account_register purple_account_register
-#define gaim_account_disconnect purple_account_disconnect
-#define gaim_account_notify_added purple_account_notify_added
-#define gaim_account_request_add purple_account_request_add
-#define gaim_account_request_close purple_account_request_close
-
-#define gaim_account_request_authorization purple_account_request_authorization
-#define gaim_account_request_change_password purple_account_request_change_password
-#define gaim_account_request_change_user_info purple_account_request_change_user_info
-
-#define gaim_account_set_username purple_account_set_username
-#define gaim_account_set_password purple_account_set_password
-#define gaim_account_set_alias purple_account_set_alias
-#define gaim_account_set_user_info purple_account_set_user_info
-#define gaim_account_set_buddy_icon_path purple_account_set_buddy_icon_path
-#define gaim_account_set_protocol_id purple_account_set_protocol_id
-#define gaim_account_set_connection purple_account_set_connection
-#define gaim_account_set_remember_password purple_account_set_remember_password
-#define gaim_account_set_check_mail purple_account_set_check_mail
-#define gaim_account_set_enabled purple_account_set_enabled
-#define gaim_account_set_proxy_info purple_account_set_proxy_info
-#define gaim_account_set_status_types purple_account_set_status_types
-#define gaim_account_set_status purple_account_set_status
-#define gaim_account_set_status_list purple_account_set_status_list
-
-#define gaim_account_clear_settings purple_account_clear_settings
-
-#define gaim_account_set_int purple_account_set_int
-#define gaim_account_set_string purple_account_set_string
-#define gaim_account_set_bool purple_account_set_bool
-
-#define gaim_account_set_ui_int purple_account_set_ui_int
-#define gaim_account_set_ui_string purple_account_set_ui_string
-#define gaim_account_set_ui_bool purple_account_set_ui_bool
-
-#define gaim_account_is_connected purple_account_is_connected
-#define gaim_account_is_connecting purple_account_is_connecting
-#define gaim_account_is_disconnected purple_account_is_disconnected
-
-#define gaim_account_get_username purple_account_get_username
-#define gaim_account_get_password purple_account_get_password
-#define gaim_account_get_alias purple_account_get_alias
-#define gaim_account_get_user_info purple_account_get_user_info
-#define gaim_account_get_buddy_icon_path purple_account_get_buddy_icon_path
-#define gaim_account_get_protocol_id purple_account_get_protocol_id
-#define gaim_account_get_protocol_name purple_account_get_protocol_name
-#define gaim_account_get_connection purple_account_get_connection
-#define gaim_account_get_remember_password purple_account_get_remember_password
-#define gaim_account_get_check_mail purple_account_get_check_mail
-#define gaim_account_get_enabled purple_account_get_enabled
-#define gaim_account_get_proxy_info purple_account_get_proxy_info
-#define gaim_account_get_active_status purple_account_get_active_status
-#define gaim_account_get_status purple_account_get_status
-#define gaim_account_get_status_type purple_account_get_status_type
-#define gaim_account_get_status_type_with_primitive \
- purple_account_get_status_type_with_primitive
-
-#define gaim_account_get_presence purple_account_get_presence
-#define gaim_account_is_status_active purple_account_is_status_active
-#define gaim_account_get_status_types purple_account_get_status_types
-
-#define gaim_account_get_int purple_account_get_int
-#define gaim_account_get_string purple_account_get_string
-#define gaim_account_get_bool purple_account_get_bool
-
-#define gaim_account_get_ui_int purple_account_get_ui_int
-#define gaim_account_get_ui_string purple_account_get_ui_string
-#define gaim_account_get_ui_bool purple_account_get_ui_bool
-
-
-#define gaim_account_get_log purple_account_get_log
-#define gaim_account_destroy_log purple_account_destroy_log
-
-#define gaim_account_add_buddy purple_account_add_buddy
-#define gaim_account_add_buddies purple_account_add_buddies
-#define gaim_account_remove_buddy purple_account_remove_buddy
-#define gaim_account_remove_buddies purple_account_remove_buddies
-
-#define gaim_account_remove_group purple_account_remove_group
-
-#define gaim_account_change_password purple_account_change_password
-
-#define gaim_account_supports_offline_message purple_account_supports_offline_message
-
-#define gaim_accounts_add purple_accounts_add
-#define gaim_accounts_remove purple_accounts_remove
-#define gaim_accounts_delete purple_accounts_delete
-#define gaim_accounts_reorder purple_accounts_reorder
-
-#define gaim_accounts_get_all purple_accounts_get_all
-#define gaim_accounts_get_all_active purple_accounts_get_all_active
-
-#define gaim_accounts_find purple_accounts_find
-
-#define gaim_accounts_restore_current_statuses purple_accounts_restore_current_statuses
-
-#define gaim_accounts_set_ui_ops purple_accounts_set_ui_ops
-#define gaim_accounts_get_ui_ops purple_accounts_get_ui_ops
-
-#define gaim_accounts_get_handle purple_accounts_get_handle
-
-#define gaim_accounts_init purple_accounts_init
-#define gaim_accounts_uninit purple_accounts_uninit
-
-/* from accountopt.h */
-
-#define GaimAccountOption PurpleAccountOption
-#define GaimAccountUserSplit PurpleAccountUserSplit
-
-#define gaim_account_option_new purple_account_option_new
-#define gaim_account_option_bool_new purple_account_option_bool_new
-#define gaim_account_option_int_new purple_account_option_int_new
-#define gaim_account_option_string_new purple_account_option_string_new
-#define gaim_account_option_list_new purple_account_option_list_new
-
-#define gaim_account_option_destroy purple_account_option_destroy
-
-#define gaim_account_option_set_default_bool purple_account_option_set_default_bool
-#define gaim_account_option_set_default_int purple_account_option_set_default_int
-#define gaim_account_option_set_default_string purple_account_option_set_default_string
-
-#define gaim_account_option_set_masked purple_account_option_set_masked
-
-#define gaim_account_option_set_list purple_account_option_set_list
-
-#define gaim_account_option_add_list_item purple_account_option_add_list_item
-
-#define gaim_account_option_get_type purple_account_option_get_type
-#define gaim_account_option_get_text purple_account_option_get_text
-#define gaim_account_option_get_setting purple_account_option_get_setting
-
-#define gaim_account_option_get_default_bool purple_account_option_get_default_bool
-#define gaim_account_option_get_default_int purple_account_option_get_default_int
-#define gaim_account_option_get_default_string purple_account_option_get_default_string
-#define gaim_account_option_get_default_list_value purple_account_option_get_default_list_value
-
-#define gaim_account_option_get_masked purple_account_option_get_masked
-#define gaim_account_option_get_list purple_account_option_get_list
-
-#define gaim_account_user_split_new purple_account_user_split_new
-#define gaim_account_user_split_destroy purple_account_user_split_destroy
-
-#define gaim_account_user_split_get_text purple_account_user_split_get_text
-#define gaim_account_user_split_get_default_value purple_account_user_split_get_default_value
-#define gaim_account_user_split_get_separator purple_account_user_split_get_separator
-
-/* from blist.h */
-
-#define GaimBuddyList PurpleBuddyList
-#define GaimBlistUiOps PurpleBlistUiOps
-#define GaimBlistNode PurpleBlistNode
-
-#define GaimChat PurpleChat
-#define GaimGroup PurpleGroup
-#define GaimContact PurpleContact
-#define GaimBuddy PurpleBuddy
-
-#define GAIM_BLIST_GROUP_NODE PURPLE_BLIST_GROUP_NODE
-#define GAIM_BLIST_CONTACT_NODE PURPLE_BLIST_CONTACT_NODE
-#define GAIM_BLIST_BUDDY_NODE PURPLE_BLIST_BUDDY_NODE
-#define GAIM_BLIST_CHAT_NODE PURPLE_BLIST_CHAT_NODE
-#define GAIM_BLIST_OTHER_NODE PURPLE_BLIST_OTHER_NODE
-#define GaimBlistNodeType PurpleBlistNodeType
-
-#define GAIM_BLIST_NODE_IS_CHAT PURPLE_BLIST_NODE_IS_CHAT
-#define GAIM_BLIST_NODE_IS_BUDDY PURPLE_BLIST_NODE_IS_BUDDY
-#define GAIM_BLIST_NODE_IS_CONTACT PURPLE_BLIST_NODE_IS_CONTACT
-#define GAIM_BLIST_NODE_IS_GROUP PURPLE_BLIST_NODE_IS_GROUP
-
-#define GAIM_BUDDY_IS_ONLINE PURPLE_BUDDY_IS_ONLINE
-
-#define GAIM_BLIST_NODE_FLAG_NO_SAVE PURPLE_BLIST_NODE_FLAG_NO_SAVE
-#define GaimBlistNodeFlags PurpleBlistNodeFlags
-
-#define GAIM_BLIST_NODE_HAS_FLAG PURPLE_BLIST_NODE_HAS_FLAG
-#define GAIM_BLIST_NODE_SHOULD_SAVE PURPLE_BLIST_NODE_SHOULD_SAVE
-
-#define GAIM_BLIST_NODE_NAME PURPLE_BLIST_NODE_NAME
-
-
-#define gaim_blist_new purple_blist_new
-#define gaim_set_blist purple_set_blist
-#define gaim_get_blist purple_get_blist
-
-#define gaim_blist_get_root purple_blist_get_root
-#define gaim_blist_node_next purple_blist_node_next
-
-#define gaim_blist_show purple_blist_show
-
-#define gaim_blist_destroy purple_blist_destroy
-
-#define gaim_blist_set_visible purple_blist_set_visible
-
-#define gaim_blist_update_buddy_status purple_blist_update_buddy_status
-#define gaim_blist_update_buddy_icon purple_blist_update_buddy_icon
-
-
-#define gaim_blist_alias_contact purple_blist_alias_contact
-#define gaim_blist_alias_buddy purple_blist_alias_buddy
-#define gaim_blist_server_alias_buddy purple_blist_server_alias_buddy
-#define gaim_blist_alias_chat purple_blist_alias_chat
-
-#define gaim_blist_rename_buddy purple_blist_rename_buddy
-#define gaim_blist_rename_group purple_blist_rename_group
-
-#define gaim_chat_new purple_chat_new
-#define gaim_blist_add_chat purple_blist_add_chat
-
-#define gaim_buddy_new purple_buddy_new
-#define gaim_buddy_set_icon purple_buddy_set_icon
-#define gaim_buddy_get_account purple_buddy_get_account
-#define gaim_buddy_get_name purple_buddy_get_name
-#define gaim_buddy_get_icon purple_buddy_get_icon
-#define gaim_buddy_get_contact purple_buddy_get_contact
-#define gaim_buddy_get_presence purple_buddy_get_presence
-
-#define gaim_blist_add_buddy purple_blist_add_buddy
-
-#define gaim_group_new purple_group_new
-
-#define gaim_blist_add_group purple_blist_add_group
-
-#define gaim_contact_new purple_contact_new
-
-#define gaim_blist_add_contact purple_blist_add_contact
-#define gaim_blist_merge_contact purple_blist_merge_contact
-
-#define gaim_contact_get_priority_buddy purple_contact_get_priority_buddy
-#define gaim_contact_set_alias purple_contact_set_alias
-#define gaim_contact_get_alias purple_contact_get_alias
-#define gaim_contact_on_account purple_contact_on_account
-
-#define gaim_contact_invalidate_priority_buddy purple_contact_invalidate_priority_buddy
-
-#define gaim_blist_remove_buddy purple_blist_remove_buddy
-#define gaim_blist_remove_contact purple_blist_remove_contact
-#define gaim_blist_remove_chat purple_blist_remove_chat
-#define gaim_blist_remove_group purple_blist_remove_group
-
-#define gaim_buddy_get_alias_only purple_buddy_get_alias_only
-#define gaim_buddy_get_server_alias purple_buddy_get_server_alias
-#define gaim_buddy_get_contact_alias purple_buddy_get_contact_alias
-#define gaim_buddy_get_local_alias purple_buddy_get_local_alias
-#define gaim_buddy_get_alias purple_buddy_get_alias
-
-#define gaim_chat_get_name purple_chat_get_name
-
-#define gaim_find_buddy purple_find_buddy
-#define gaim_find_buddy_in_group purple_find_buddy_in_group
-#define gaim_find_buddies purple_find_buddies
-
-#define gaim_find_group purple_find_group
-
-#define gaim_blist_find_chat purple_blist_find_chat
-
-#define gaim_chat_get_group purple_chat_get_group
-#define gaim_buddy_get_group purple_buddy_get_group
-
-#define gaim_group_get_accounts purple_group_get_accounts
-#define gaim_group_on_account purple_group_on_account
-
-#define gaim_blist_add_account purple_blist_add_account
-#define gaim_blist_remove_account purple_blist_remove_account
-
-#define gaim_blist_get_group_size purple_blist_get_group_size
-#define gaim_blist_get_group_online_count purple_blist_get_group_online_count
-
-#define gaim_blist_load purple_blist_load
-#define gaim_blist_schedule_save purple_blist_schedule_save
-
-#define gaim_blist_request_add_buddy purple_blist_request_add_buddy
-#define gaim_blist_request_add_chat purple_blist_request_add_chat
-#define gaim_blist_request_add_group purple_blist_request_add_group
-
-#define gaim_blist_node_set_bool purple_blist_node_set_bool
-#define gaim_blist_node_get_bool purple_blist_node_get_bool
-#define gaim_blist_node_set_int purple_blist_node_set_int
-#define gaim_blist_node_get_int purple_blist_node_get_int
-#define gaim_blist_node_set_string purple_blist_node_set_string
-#define gaim_blist_node_get_string purple_blist_node_get_string
-
-#define gaim_blist_node_remove_setting purple_blist_node_remove_setting
-
-#define gaim_blist_node_set_flags purple_blist_node_set_flags
-#define gaim_blist_node_get_flags purple_blist_node_get_flags
-
-#define gaim_blist_node_get_extended_menu purple_blist_node_get_extended_menu
-
-#define gaim_blist_set_ui_ops purple_blist_set_ui_ops
-#define gaim_blist_get_ui_ops purple_blist_get_ui_ops
-
-#define gaim_blist_get_handle purple_blist_get_handle
-
-#define gaim_blist_init purple_blist_init
-#define gaim_blist_uninit purple_blist_uninit
-
-
-#define GaimBuddyIcon PurpleBuddyIcon
-
-#define gaim_buddy_icon_new(account, username, icon_data, icon_len)\
- purple_buddy_icon_new(account, username, g_memdup(icon_data, icon_len), icon_len)
-#define gaim_buddy_icon_ref purple_buddy_icon_ref
-#define gaim_buddy_icon_unref purple_buddy_icon_unref
-#define gaim_buddy_icon_update purple_buddy_icon_update
-
-#define gaim_buddy_icon_set_data(icon, data, len) \
- purple_buddy_icon_set_data(icon, g_memdup(data, len), len, NULL);
-
-#define gaim_buddy_icon_get_account purple_buddy_icon_get_account
-#define gaim_buddy_icon_get_username purple_buddy_icon_get_username
-#define gaim_buddy_icon_get_data purple_buddy_icon_get_data
-#define gaim_buddy_icon_get_type purple_buddy_icon_get_extension
-
-#define gaim_buddy_icons_set_for_user(icon, data, len) \
- purple_buddy_icons_set_for_user(icon, g_memdup(data, len), len, NULL)
-#define gaim_buddy_icons_set_caching purple_buddy_icons_set_caching
-#define gaim_buddy_icons_is_caching purple_buddy_icons_is_caching
-#define gaim_buddy_icons_set_cache_dir purple_buddy_icons_set_cache_dir
-#define gaim_buddy_icons_get_cache_dir purple_buddy_icons_get_cache_dir
-#define gaim_buddy_icons_get_handle purple_buddy_icons_get_handle
-
-#define gaim_buddy_icons_init purple_buddy_icons_init
-#define gaim_buddy_icons_uninit purple_buddy_icons_uninit
-
-#define gaim_buddy_icon_get_scale_size purple_buddy_icon_get_scale_size
-
-/* from cipher.h */
-
-#define GAIM_CIPHER PURPLE_CIPHER
-#define GAIM_CIPHER_OPS PURPLE_CIPHER_OPS
-#define GAIM_CIPHER_CONTEXT PURPLE_CIPHER_CONTEXT
-
-#define GaimCipher PurpleCipher
-#define GaimCipherOps PurpleCipherOps
-#define GaimCipherContext PurpleCipherContext
-
-#define GAIM_CIPHER_CAPS_SET_OPT PURPLE_CIPHER_CAPS_SET_OPT
-#define GAIM_CIPHER_CAPS_GET_OPT PURPLE_CIPHER_CAPS_GET_OPT
-#define GAIM_CIPHER_CAPS_INIT PURPLE_CIPHER_CAPS_INIT
-#define GAIM_CIPHER_CAPS_RESET PURPLE_CIPHER_CAPS_RESET
-#define GAIM_CIPHER_CAPS_UNINIT PURPLE_CIPHER_CAPS_UNINIT
-#define GAIM_CIPHER_CAPS_SET_IV PURPLE_CIPHER_CAPS_SET_IV
-#define GAIM_CIPHER_CAPS_APPEND PURPLE_CIPHER_CAPS_APPEND
-#define GAIM_CIPHER_CAPS_DIGEST PURPLE_CIPHER_CAPS_DIGEST
-#define GAIM_CIPHER_CAPS_ENCRYPT PURPLE_CIPHER_CAPS_ENCRYPT
-#define GAIM_CIPHER_CAPS_DECRYPT PURPLE_CIPHER_CAPS_DECRYPT
-#define GAIM_CIPHER_CAPS_SET_SALT PURPLE_CIPHER_CAPS_SET_SALT
-#define GAIM_CIPHER_CAPS_GET_SALT_SIZE PURPLE_CIPHER_CAPS_GET_SALT_SIZE
-#define GAIM_CIPHER_CAPS_SET_KEY PURPLE_CIPHER_CAPS_SET_KEY
-#define GAIM_CIPHER_CAPS_GET_KEY_SIZE PURPLE_CIPHER_CAPS_GET_KEY_SIZE
-#define GAIM_CIPHER_CAPS_UNKNOWN PURPLE_CIPHER_CAPS_UNKNOWN
-
-#define gaim_cipher_get_name purple_cipher_get_name
-#define gaim_cipher_get_capabilities purple_cipher_get_capabilities
-#define gaim_cipher_digest_region purple_cipher_digest_region
-
-#define gaim_ciphers_find_cipher purple_ciphers_find_cipher
-#define gaim_ciphers_register_cipher purple_ciphers_register_cipher
-#define gaim_ciphers_unregister_cipher purple_ciphers_unregister_cipher
-#define gaim_ciphers_get_ciphers purple_ciphers_get_ciphers
-
-#define gaim_ciphers_get_handle purple_ciphers_get_handle
-#define gaim_ciphers_init purple_ciphers_init
-#define gaim_ciphers_uninit purple_ciphers_uninit
-
-#define gaim_cipher_context_set_option purple_cipher_context_set_option
-#define gaim_cipher_context_get_option purple_cipher_context_get_option
-
-#define gaim_cipher_context_new purple_cipher_context_new
-#define gaim_cipher_context_new_by_name purple_cipher_context_new_by_name
-#define gaim_cipher_context_reset purple_cipher_context_reset
-#define gaim_cipher_context_destroy purple_cipher_context_destroy
-#define gaim_cipher_context_set_iv purple_cipher_context_set_iv
-#define gaim_cipher_context_append purple_cipher_context_append
-#define gaim_cipher_context_digest purple_cipher_context_digest
-#define gaim_cipher_context_digest_to_str purple_cipher_context_digest_to_str
-#define gaim_cipher_context_encrypt purple_cipher_context_encrypt
-#define gaim_cipher_context_decrypt purple_cipher_context_decrypt
-#define gaim_cipher_context_set_salt purple_cipher_context_set_salt
-#define gaim_cipher_context_get_salt_size purple_cipher_context_get_salt_size
-#define gaim_cipher_context_set_key purple_cipher_context_set_key
-#define gaim_cipher_context_get_key_size purple_cipher_context_get_key_size
-#define gaim_cipher_context_set_data purple_cipher_context_set_data
-#define gaim_cipher_context_get_data purple_cipher_context_get_data
-
-#define gaim_cipher_http_digest_calculate_session_key \
- purple_cipher_http_digest_calculate_session_key
-
-#define gaim_cipher_http_digest_calculate_response \
- purple_cipher_http_digest_calculate_response
-
-/* from circbuffer.h */
-
-#define GaimCircBuffer PurpleCircBuffer
-
-#define gaim_circ_buffer_new purple_circ_buffer_new
-#define gaim_circ_buffer_destroy purple_circ_buffer_destroy
-#define gaim_circ_buffer_append purple_circ_buffer_append
-#define gaim_circ_buffer_get_max_read purple_circ_buffer_get_max_read
-#define gaim_circ_buffer_mark_read purple_circ_buffer_mark_read
-
-/* from cmds.h */
-
-#define GaimCmdPriority PurpleCmdPriority
-#define GaimCmdFlag PurpleCmdFlag
-#define GaimCmdStatus PurpleCmdStatus
-#define GaimCmdRet PurpleCmdRet
-
-#define GAIM_CMD_STATUS_OK PURPLE_CMD_STATUS_OK
-#define GAIM_CMD_STATUS_FAILED PURPLE_CMD_STATUS_FAILED
-#define GAIM_CMD_STATUS_NOT_FOUND PURPLE_CMD_STATUS_NOT_FOUND
-#define GAIM_CMD_STATUS_WRONG_ARGS PURPLE_CMD_STATUS_WRONG_ARGS
-#define GAIM_CMD_STATUS_WRONG_PRPL PURPLE_CMD_STATUS_WRONG_PRPL
-#define GAIM_CMD_STATUS_WRONG_TYPE PURPLE_CMD_STATUS_WRONG_TYPE
-
-#define GAIM_CMD_FUNC PURPLE_CMD_FUNC
-
-#define GAIM_CMD_RET_OK PURPLE_CMD_RET_OK
-#define GAIM_CMD_RET_FAILED PURPLE_CMD_RET_FAILED
-#define GAIM_CMD_RET_CONTINUE PURPLE_CMD_RET_CONTINUE
-
-#define GAIM_CMD_P_VERY_LOW PURPLE_CMD_P_VERY_LOW
-#define GAIM_CMD_P_LOW PURPLE_CMD_P_LOW
-#define GAIM_CMD_P_DEFAULT PURPLE_CMD_P_DEFAULT
-#define GAIM_CMD_P_PRPL PURPLE_CMD_P_PRPL
-#define GAIM_CMD_P_PLUGIN PURPLE_CMD_P_PLUGIN
-#define GAIM_CMD_P_ALIAS PURPLE_CMD_P_ALIAS
-#define GAIM_CMD_P_HIGH PURPLE_CMD_P_HIGH
-#define GAIM_CMD_P_VERY_HIGH PURPLE_CMD_P_VERY_HIGH
-
-#define GAIM_CMD_FLAG_IM PURPLE_CMD_FLAG_IM
-#define GAIM_CMD_FLAG_CHAT PURPLE_CMD_FLAG_CHAT
-#define GAIM_CMD_FLAG_PRPL_ONLY PURPLE_CMD_FLAG_PRPL_ONLY
-#define GAIM_CMD_FLAG_ALLOW_WRONG_ARGS PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS
-
-
-#define GaimCmdFunc PurpleCmdFunc
-
-#define GaimCmdId PurpleCmdId
-
-#define gaim_cmd_register purple_cmd_register
-#define gaim_cmd_unregister purple_cmd_unregister
-#define gaim_cmd_do_command purple_cmd_do_command
-#define gaim_cmd_list purple_cmd_list
-#define gaim_cmd_help purple_cmd_help
-
-/* from connection.h */
-
-#define GaimConnection PurpleConnection
-
-#define GAIM_CONNECTION_HTML PURPLE_CONNECTION_HTML
-#define GAIM_CONNECTION_NO_BGCOLOR PURPLE_CONNECTION_NO_BGCOLOR
-#define GAIM_CONNECTION_AUTO_RESP PURPLE_CONNECTION_AUTO_RESP
-#define GAIM_CONNECTION_FORMATTING_WBFO PURPLE_CONNECTION_FORMATTING_WBFO
-#define GAIM_CONNECTION_NO_NEWLINES PURPLE_CONNECTION_NO_NEWLINES
-#define GAIM_CONNECTION_NO_FONTSIZE PURPLE_CONNECTION_NO_FONTSIZE
-#define GAIM_CONNECTION_NO_URLDESC PURPLE_CONNECTION_NO_URLDESC
-#define GAIM_CONNECTION_NO_IMAGES PURPLE_CONNECTION_NO_IMAGES
-
-#define GaimConnectionFlags PurpleConnectionFlags
-
-#define GAIM_DISCONNECTED PURPLE_DISCONNECTED
-#define GAIM_CONNECTED PURPLE_CONNECTED
-#define GAIM_CONNECTING PURPLE_CONNECTING
-
-#define GaimConnectionState PurpleConnectionState
-
-#define GaimConnectionUiOps PurpleConnectionUiOps
-
-#define gaim_connection_new purple_connection_new
-#define gaim_connection_destroy purple_connection_destroy
-
-#define gaim_connection_set_state purple_connection_set_state
-#define gaim_connection_set_account purple_connection_set_account
-#define gaim_connection_set_display_name purple_connection_set_display_name
-#define gaim_connection_get_state purple_connection_get_state
-
-#define GAIM_CONNECTION_IS_CONNECTED PURPLE_CONNECTION_IS_CONNECTED
-
-#define gaim_connection_get_account purple_connection_get_account
-#define gaim_connection_get_password purple_connection_get_password
-#define gaim_connection_get_display_name purple_connection_get_display_name
-
-#define gaim_connection_update_progress purple_connection_update_progress
-
-#define gaim_connection_notice purple_connection_notice
-#define gaim_connection_error purple_connection_error
-
-#define gaim_connections_disconnect_all purple_connections_disconnect_all
-
-#define gaim_connections_get_all purple_connections_get_all
-#define gaim_connections_get_connecting purple_connections_get_connecting
-
-#define GAIM_CONNECTION_IS_VALID PURPLE_CONNECTION_IS_VALID
-
-#define gaim_connections_set_ui_ops purple_connections_set_ui_ops
-#define gaim_connections_get_ui_ops purple_connections_get_ui_ops
-
-#define gaim_connections_init purple_connections_init
-#define gaim_connections_uninit purple_connections_uninit
-#define gaim_connections_get_handle purple_connections_get_handle
-
-
-/* from conversation.h */
-
-#define GaimConversationUiOps PurpleConversationUiOps
-#define GaimConversation PurpleConversation
-#define GaimConvIm PurpleConvIm
-#define GaimConvChat PurpleConvChat
-#define GaimConvChatBuddy PurpleConvChatBuddy
-
-#define GAIM_CONV_TYPE_UNKNOWN PURPLE_CONV_TYPE_UNKNOWN
-#define GAIM_CONV_TYPE_IM PURPLE_CONV_TYPE_IM
-#define GAIM_CONV_TYPE_CHAT PURPLE_CONV_TYPE_CHAT
-#define GAIM_CONV_TYPE_MISC PURPLE_CONV_TYPE_MISC
-#define GAIM_CONV_TYPE_ANY PURPLE_CONV_TYPE_ANY
-
-#define GaimConversationType PurpleConversationType
-
-#define GAIM_CONV_UPDATE_ADD PURPLE_CONV_UPDATE_ADD
-#define GAIM_CONV_UPDATE_REMOVE PURPLE_CONV_UPDATE_REMOVE
-#define GAIM_CONV_UPDATE_ACCOUNT PURPLE_CONV_UPDATE_ACCOUNT
-#define GAIM_CONV_UPDATE_TYPING PURPLE_CONV_UPDATE_TYPING
-#define GAIM_CONV_UPDATE_UNSEEN PURPLE_CONV_UPDATE_UNSEEN
-#define GAIM_CONV_UPDATE_LOGGING PURPLE_CONV_UPDATE_LOGGING
-#define GAIM_CONV_UPDATE_TOPIC PURPLE_CONV_UPDATE_TOPIC
-#define GAIM_CONV_ACCOUNT_ONLINE PURPLE_CONV_ACCOUNT_ONLINE
-#define GAIM_CONV_ACCOUNT_OFFLINE PURPLE_CONV_ACCOUNT_OFFLINE
-#define GAIM_CONV_UPDATE_AWAY PURPLE_CONV_UPDATE_AWAY
-#define GAIM_CONV_UPDATE_ICON PURPLE_CONV_UPDATE_ICON
-#define GAIM_CONV_UPDATE_TITLE PURPLE_CONV_UPDATE_TITLE
-#define GAIM_CONV_UPDATE_CHATLEFT PURPLE_CONV_UPDATE_CHATLEFT
-#define GAIM_CONV_UPDATE_FEATURES PURPLE_CONV_UPDATE_FEATURES
-
-#define GaimConvUpdateType PurpleConvUpdateType
-
-#define GAIM_NOT_TYPING PURPLE_NOT_TYPING
-#define GAIM_TYPING PURPLE_TYPING
-#define GAIM_TYPED PURPLE_TYPED
-
-#define GaimTypingState PurpleTypingState
-
-#define GAIM_MESSAGE_SEND PURPLE_MESSAGE_SEND
-#define GAIM_MESSAGE_RECV PURPLE_MESSAGE_RECV
-#define GAIM_MESSAGE_SYSTEM PURPLE_MESSAGE_SYSTEM
-#define GAIM_MESSAGE_AUTO_RESP PURPLE_MESSAGE_AUTO_RESP
-#define GAIM_MESSAGE_ACTIVE_ONLY PURPLE_MESSAGE_ACTIVE_ONLY
-#define GAIM_MESSAGE_NICK PURPLE_MESSAGE_NICK
-#define GAIM_MESSAGE_NO_LOG PURPLE_MESSAGE_NO_LOG
-#define GAIM_MESSAGE_WHISPER PURPLE_MESSAGE_WHISPER
-#define GAIM_MESSAGE_ERROR PURPLE_MESSAGE_ERROR
-#define GAIM_MESSAGE_DELAYED PURPLE_MESSAGE_DELAYED
-#define GAIM_MESSAGE_RAW PURPLE_MESSAGE_RAW
-#define GAIM_MESSAGE_IMAGES PURPLE_MESSAGE_IMAGES
-
-#define GaimMessageFlags PurpleMessageFlags
-
-#define GAIM_CBFLAGS_NONE PURPLE_CBFLAGS_NONE
-#define GAIM_CBFLAGS_VOICE PURPLE_CBFLAGS_VOICE
-#define GAIM_CBFLAGS_HALFOP PURPLE_CBFLAGS_HALFOP
-#define GAIM_CBFLAGS_OP PURPLE_CBFLAGS_OP
-#define GAIM_CBFLAGS_FOUNDER PURPLE_CBFLAGS_FOUNDER
-#define GAIM_CBFLAGS_TYPING PURPLE_CBFLAGS_TYPING
-
-#define GaimConvChatBuddyFlags PurpleConvChatBuddyFlags
-
-#define gaim_conversations_set_ui_ops purple_conversations_set_ui_ops
-
-#define gaim_conversation_new purple_conversation_new
-#define gaim_conversation_destroy purple_conversation_destroy
-#define gaim_conversation_present purple_conversation_present
-#define gaim_conversation_get_type purple_conversation_get_type
-#define gaim_conversation_set_ui_ops purple_conversation_set_ui_ops
-#define gaim_conversation_get_ui_ops purple_conversation_get_ui_ops
-#define gaim_conversation_set_account purple_conversation_set_account
-#define gaim_conversation_get_account purple_conversation_get_account
-#define gaim_conversation_get_gc purple_conversation_get_gc
-#define gaim_conversation_set_title purple_conversation_set_title
-#define gaim_conversation_get_title purple_conversation_get_title
-#define gaim_conversation_autoset_title purple_conversation_autoset_title
-#define gaim_conversation_set_name purple_conversation_set_name
-#define gaim_conversation_get_name purple_conversation_get_name
-#define gaim_conversation_set_logging purple_conversation_set_logging
-#define gaim_conversation_is_logging purple_conversation_is_logging
-#define gaim_conversation_close_logs purple_conversation_close_logs
-#define gaim_conversation_get_im_data purple_conversation_get_im_data
-
-#define GAIM_CONV_IM PURPLE_CONV_IM
-
-#define gaim_conversation_get_chat_data purple_conversation_get_chat_data
-
-#define GAIM_CONV_CHAT PURPLE_CONV_CHAT
-
-#define gaim_conversation_set_data purple_conversation_set_data
-#define gaim_conversation_get_data purple_conversation_get_data
-
-#define gaim_get_conversations purple_get_conversations
-#define gaim_get_ims purple_get_ims
-#define gaim_get_chats purple_get_chats
-
-#define gaim_find_conversation_with_account \
- purple_find_conversation_with_account
-
-#define gaim_conversation_write purple_conversation_write
-#define gaim_conversation_set_features purple_conversation_set_features
-#define gaim_conversation_get_features purple_conversation_get_features
-#define gaim_conversation_has_focus purple_conversation_has_focus
-#define gaim_conversation_update purple_conversation_update
-#define gaim_conversation_foreach purple_conversation_foreach
-
-#define gaim_conv_im_get_conversation purple_conv_im_get_conversation
-#define gaim_conv_im_set_icon purple_conv_im_set_icon
-#define gaim_conv_im_get_icon purple_conv_im_get_icon
-#define gaim_conv_im_set_typing_state purple_conv_im_set_typing_state
-#define gaim_conv_im_get_typing_state purple_conv_im_get_typing_state
-
-#define gaim_conv_im_start_typing_timeout purple_conv_im_start_typing_timeout
-#define gaim_conv_im_stop_typing_timeout purple_conv_im_stop_typing_timeout
-#define gaim_conv_im_get_typing_timeout purple_conv_im_get_typing_timeout
-#define gaim_conv_im_set_type_again purple_conv_im_set_type_again
-#define gaim_conv_im_get_type_again purple_conv_im_get_type_again
-
-#define gaim_conv_im_start_send_typed_timeout \
- purple_conv_im_start_send_typed_timeout
-
-#define gaim_conv_im_stop_send_typed_timeout \
- purple_conv_im_stop_send_typed_timeout
-
-#define gaim_conv_im_get_send_typed_timeout \
- purple_conv_im_get_send_typed_timeout
-
-#define gaim_conv_present_error purple_conv_present_error
-#define gaim_conv_send_confirm purple_conv_send_confirm
-
-#define gaim_conv_im_update_typing purple_conv_im_update_typing
-#define gaim_conv_im_write purple_conv_im_write
-#define gaim_conv_im_send purple_conv_im_send
-#define gaim_conv_im_send_with_flags purple_conv_im_send_with_flags
-
-#define gaim_conv_custom_smiley_add purple_conv_custom_smiley_add
-#define gaim_conv_custom_smiley_write purple_conv_custom_smiley_write
-#define gaim_conv_custom_smiley_close purple_conv_custom_smiley_close
-
-#define gaim_conv_chat_get_conversation purple_conv_chat_get_conversation
-#define gaim_conv_chat_set_users purple_conv_chat_set_users
-#define gaim_conv_chat_get_users purple_conv_chat_get_users
-#define gaim_conv_chat_ignore purple_conv_chat_ignore
-#define gaim_conv_chat_unignore purple_conv_chat_unignore
-#define gaim_conv_chat_set_ignored purple_conv_chat_set_ignored
-#define gaim_conv_chat_get_ignored purple_conv_chat_get_ignored
-#define gaim_conv_chat_get_ignored_user purple_conv_chat_get_ignored_user
-#define gaim_conv_chat_is_user_ignored purple_conv_chat_is_user_ignored
-#define gaim_conv_chat_set_topic purple_conv_chat_set_topic
-#define gaim_conv_chat_get_topic purple_conv_chat_get_topic
-#define gaim_conv_chat_set_id purple_conv_chat_set_id
-#define gaim_conv_chat_get_id purple_conv_chat_get_id
-#define gaim_conv_chat_write purple_conv_chat_write
-#define gaim_conv_chat_send purple_conv_chat_send
-#define gaim_conv_chat_send_with_flags purple_conv_chat_send_with_flags
-#define gaim_conv_chat_add_user purple_conv_chat_add_user
-#define gaim_conv_chat_add_users purple_conv_chat_add_users
-#define gaim_conv_chat_rename_user purple_conv_chat_rename_user
-#define gaim_conv_chat_remove_user purple_conv_chat_remove_user
-#define gaim_conv_chat_remove_users purple_conv_chat_remove_users
-#define gaim_conv_chat_find_user purple_conv_chat_find_user
-#define gaim_conv_chat_user_set_flags purple_conv_chat_user_set_flags
-#define gaim_conv_chat_user_get_flags purple_conv_chat_user_get_flags
-#define gaim_conv_chat_clear_users purple_conv_chat_clear_users
-#define gaim_conv_chat_set_nick purple_conv_chat_set_nick
-#define gaim_conv_chat_get_nick purple_conv_chat_get_nick
-#define gaim_conv_chat_left purple_conv_chat_left
-#define gaim_conv_chat_has_left purple_conv_chat_has_left
-
-#define gaim_find_chat purple_find_chat
-
-#define gaim_conv_chat_cb_new purple_conv_chat_cb_new
-#define gaim_conv_chat_cb_find purple_conv_chat_cb_find
-#define gaim_conv_chat_cb_get_name purple_conv_chat_cb_get_name
-#define gaim_conv_chat_cb_destroy purple_conv_chat_cb_destroy
-
-#define gaim_conversations_get_handle purple_conversations_get_handle
-#define gaim_conversations_init purple_conversations_init
-#define gaim_conversations_uninit purple_conversations_uninit
-
-/* from core.h */
-
-#define GaimCore PurpleCore
-
-#define GaimCoreUiOps PurpleCoreUiOps
-
-#define gaim_core_init purple_core_init
-#define gaim_core_quit purple_core_quit
-
-#define gaim_core_quit_cb purple_core_quit_cb
-#define gaim_core_get_version purple_core_get_version
-#define gaim_core_get_ui purple_core_get_ui
-#define gaim_get_core purple_get_core
-#define gaim_core_set_ui_ops purple_core_set_ui_ops
-#define gaim_core_get_ui_ops purple_core_get_ui_ops
-
-/* from debug.h */
-
-#define GAIM_DEBUG_ALL PURPLE_DEBUG_ALL
-#define GAIM_DEBUG_MISC PURPLE_DEBUG_MISC
-#define GAIM_DEBUG_INFO PURPLE_DEBUG_INFO
-#define GAIM_DEBUG_WARNING PURPLE_DEBUG_WARNING
-#define GAIM_DEBUG_ERROR PURPLE_DEBUG_ERROR
-#define GAIM_DEBUG_FATAL PURPLE_DEBUG_FATAL
-
-#define GaimDebugLevel PurpleDebugLevel
-
-#define GaimDebugUiOps PurpleDebugUiOps
-
-
-#define gaim_debug purple_debug
-#define gaim_debug_misc purple_debug_misc
-#define gaim_debug_info purple_debug_info
-#define gaim_debug_warning purple_debug_warning
-#define gaim_debug_error purple_debug_error
-#define gaim_debug_fatal purple_debug_fatal
-
-#define gaim_debug_set_enabled purple_debug_set_enabled
-#define gaim_debug_is_enabled purple_debug_is_enabled
-
-#define gaim_debug_set_ui_ops purple_debug_set_ui_ops
-#define gaim_debug_get_ui_ops purple_debug_get_ui_ops
-
-#define gaim_debug_init purple_debug_init
-
-/* from desktopitem.h */
-
-#define GAIM_DESKTOP_ITEM_TYPE_NULL PURPLE_DESKTOP_ITEM_TYPE_NULL
-#define GAIM_DESKTOP_ITEM_TYPE_OTHER PURPLE_DESKTOP_ITEM_TYPE_OTHER
-#define GAIM_DESKTOP_ITEM_TYPE_APPLICATION PURPLE_DESKTOP_ITEM_TYPE_APPLICATION
-#define GAIM_DESKTOP_ITEM_TYPE_LINK PURPLE_DESKTOP_ITEM_TYPE_LINK
-#define GAIM_DESKTOP_ITEM_TYPE_FSDEVICE PURPLE_DESKTOP_ITEM_TYPE_FSDEVICE
-#define GAIM_DESKTOP_ITEM_TYPE_MIME_TYPE PURPLE_DESKTOP_ITEM_TYPE_MIME_TYPE
-#define GAIM_DESKTOP_ITEM_TYPE_DIRECTORY PURPLE_DESKTOP_ITEM_TYPE_DIRECTORY
-#define GAIM_DESKTOP_ITEM_TYPE_SERVICE PURPLE_DESKTOP_ITEM_TYPE_SERVICE
-#define GAIM_DESKTOP_ITEM_TYPE_SERVICE_TYPE PURPLE_DESKTOP_ITEM_TYPE_SERVICE_TYPE
-
-#define GaimDesktopItemType PurpleDesktopItemType
-
-#define GaimDesktopItem PurpleDesktopItem
-
-#define GAIM_TYPE_DESKTOP_ITEM PURPLE_TYPE_DESKTOP_ITEM
-#define gaim_desktop_item_get_type purple_desktop_item_get_type
-
-/* standard */
-/* ugh, i'm just copying these as strings, rather than pidginifying them */
-#define GAIM_DESKTOP_ITEM_ENCODING "Encoding" /* string */
-#define GAIM_DESKTOP_ITEM_VERSION "Version" /* numeric */
-#define GAIM_DESKTOP_ITEM_NAME "Name" /* localestring */
-#define GAIM_DESKTOP_ITEM_GENERIC_NAME "GenericName" /* localestring */
-#define GAIM_DESKTOP_ITEM_TYPE "Type" /* string */
-#define GAIM_DESKTOP_ITEM_FILE_PATTERN "FilePattern" /* regexp(s) */
-#define GAIM_DESKTOP_ITEM_TRY_EXEC "TryExec" /* string */
-#define GAIM_DESKTOP_ITEM_NO_DISPLAY "NoDisplay" /* boolean */
-#define GAIM_DESKTOP_ITEM_COMMENT "Comment" /* localestring */
-#define GAIM_DESKTOP_ITEM_EXEC "Exec" /* string */
-#define GAIM_DESKTOP_ITEM_ACTIONS "Actions" /* strings */
-#define GAIM_DESKTOP_ITEM_ICON "Icon" /* string */
-#define GAIM_DESKTOP_ITEM_MINI_ICON "MiniIcon" /* string */
-#define GAIM_DESKTOP_ITEM_HIDDEN "Hidden" /* boolean */
-#define GAIM_DESKTOP_ITEM_PATH "Path" /* string */
-#define GAIM_DESKTOP_ITEM_TERMINAL "Terminal" /* boolean */
-#define GAIM_DESKTOP_ITEM_TERMINAL_OPTIONS "TerminalOptions" /* string */
-#define GAIM_DESKTOP_ITEM_SWALLOW_TITLE "SwallowTitle" /* string */
-#define GAIM_DESKTOP_ITEM_SWALLOW_EXEC "SwallowExec" /* string */
-#define GAIM_DESKTOP_ITEM_MIME_TYPE "MimeType" /* regexp(s) */
-#define GAIM_DESKTOP_ITEM_PATTERNS "Patterns" /* regexp(s) */
-#define GAIM_DESKTOP_ITEM_DEFAULT_APP "DefaultApp" /* string */
-#define GAIM_DESKTOP_ITEM_DEV "Dev" /* string */
-#define GAIM_DESKTOP_ITEM_FS_TYPE "FSType" /* string */
-#define GAIM_DESKTOP_ITEM_MOUNT_POINT "MountPoint" /* string */
-#define GAIM_DESKTOP_ITEM_READ_ONLY "ReadOnly" /* boolean */
-#define GAIM_DESKTOP_ITEM_UNMOUNT_ICON "UnmountIcon" /* string */
-#define GAIM_DESKTOP_ITEM_SORT_ORDER "SortOrder" /* strings */
-#define GAIM_DESKTOP_ITEM_URL "URL" /* string */
-#define GAIM_DESKTOP_ITEM_DOC_PATH "X-GNOME-DocPath" /* string */
-
-#define gaim_desktop_item_new_from_file purple_desktop_item_new_from_file
-#define gaim_desktop_item_get_entry_type purple_desktop_item_get_entry_type
-#define gaim_desktop_item_get_string purple_desktop_item_get_string
-#define gaim_desktop_item_copy purple_desktop_item_copy
-#define gaim_desktop_item_unref purple_desktop_item_unref
-
-/* from dnsquery.h */
-
-#define GaimDnsQueryData PurpleDnsQueryData
-#define GaimDnsQueryConnectFunction PurpleDnsQueryConnectFunction
-
-#define gaim_dnsquery_a purple_dnsquery_a
-#define gaim_dnsquery_destroy purple_dnsquery_destroy
-#define gaim_dnsquery_init purple_dnsquery_init
-#define gaim_dnsquery_uninit purple_dnsquery_uninit
-#define gaim_dnsquery_set_ui_ops purple_dnsquery_set_ui_ops
-#define gaim_dnsquery_get_host purple_dnsquery_get_host
-#define gaim_dnsquery_get_port purple_dnsquery_get_port
-
-/* from dnssrv.h */
-
-#define GaimSrvResponse PurpleSrvResponse
-#define GaimSrvQueryData PurpleSrvTxtQueryData
-#define GaimSrvCallback PurpleSrvCallback
-
-#define gaim_srv_resolve purple_srv_resolve
-#define gaim_srv_cancel purple_srv_cancel
-
-/* from eventloop.h */
-
-#define GAIM_INPUT_READ PURPLE_INPUT_READ
-#define GAIM_INPUT_WRITE PURPLE_INPUT_WRITE
-
-#define GaimInputCondition PurpleInputCondition
-#define GaimInputFunction PurpleInputFunction
-#define GaimEventLoopUiOps PurpleEventLoopUiOps
-
-#define gaim_timeout_add purple_timeout_add
-#define gaim_timeout_remove purple_timeout_remove
-#define gaim_input_add purple_input_add
-#define gaim_input_remove purple_input_remove
-
-#define gaim_eventloop_set_ui_ops purple_eventloop_set_ui_ops
-#define gaim_eventloop_get_ui_ops purple_eventloop_get_ui_ops
-
-/* from ft.h */
-
-#define GaimXfer PurpleXfer
-
-#define GAIM_XFER_UNKNOWN PURPLE_XFER_UNKNOWN
-#define GAIM_XFER_SEND PURPLE_XFER_SEND
-#define GAIM_XFER_RECEIVE PURPLE_XFER_RECEIVE
-
-#define GaimXferType PurpleXferType
-
-#define GAIM_XFER_STATUS_UNKNOWN PURPLE_XFER_STATUS_UNKNOWN
-#define GAIM_XFER_STATUS_NOT_STARTED PURPLE_XFER_STATUS_NOT_STARTED
-#define GAIM_XFER_STATUS_ACCEPTED PURPLE_XFER_STATUS_ACCEPTED
-#define GAIM_XFER_STATUS_STARTED PURPLE_XFER_STATUS_STARTED
-#define GAIM_XFER_STATUS_DONE PURPLE_XFER_STATUS_DONE
-#define GAIM_XFER_STATUS_CANCEL_LOCAL PURPLE_XFER_STATUS_CANCEL_LOCAL
-#define GAIM_XFER_STATUS_CANCEL_REMOTE PURPLE_XFER_STATUS_CANCEL_REMOTE
-
-#define GaimXferStatusType PurpleXferStatusType
-
-#define GaimXferUiOps PurpleXferUiOps
-
-#define gaim_xfer_new purple_xfer_new
-#define gaim_xfer_ref purple_xfer_ref
-#define gaim_xfer_unref purple_xfer_unref
-#define gaim_xfer_request purple_xfer_request
-#define gaim_xfer_request_accepted purple_xfer_request_accepted
-#define gaim_xfer_request_denied purple_xfer_request_denied
-#define gaim_xfer_get_type purple_xfer_get_type
-#define gaim_xfer_get_account purple_xfer_get_account
-#define gaim_xfer_get_status purple_xfer_get_status
-#define gaim_xfer_is_canceled purple_xfer_is_canceled
-#define gaim_xfer_is_completed purple_xfer_is_completed
-#define gaim_xfer_get_filename purple_xfer_get_filename
-#define gaim_xfer_get_local_filename purple_xfer_get_local_filename
-#define gaim_xfer_get_bytes_sent purple_xfer_get_bytes_sent
-#define gaim_xfer_get_bytes_remaining purple_xfer_get_bytes_remaining
-#define gaim_xfer_get_size purple_xfer_get_size
-#define gaim_xfer_get_progress purple_xfer_get_progress
-#define gaim_xfer_get_local_port purple_xfer_get_local_port
-#define gaim_xfer_get_remote_ip purple_xfer_get_remote_ip
-#define gaim_xfer_get_remote_port purple_xfer_get_remote_port
-#define gaim_xfer_set_completed purple_xfer_set_completed
-#define gaim_xfer_set_message purple_xfer_set_message
-#define gaim_xfer_set_filename purple_xfer_set_filename
-#define gaim_xfer_set_local_filename purple_xfer_set_local_filename
-#define gaim_xfer_set_size purple_xfer_set_size
-#define gaim_xfer_set_bytes_sent purple_xfer_set_bytes_sent
-#define gaim_xfer_get_ui_ops purple_xfer_get_ui_ops
-#define gaim_xfer_set_read_fnc purple_xfer_set_read_fnc
-#define gaim_xfer_set_write_fnc purple_xfer_set_write_fnc
-#define gaim_xfer_set_ack_fnc purple_xfer_set_ack_fnc
-#define gaim_xfer_set_request_denied_fnc purple_xfer_set_request_denied_fnc
-#define gaim_xfer_set_init_fnc purple_xfer_set_init_fnc
-#define gaim_xfer_set_start_fnc purple_xfer_set_start_fnc
-#define gaim_xfer_set_end_fnc purple_xfer_set_end_fnc
-#define gaim_xfer_set_cancel_send_fnc purple_xfer_set_cancel_send_fnc
-#define gaim_xfer_set_cancel_recv_fnc purple_xfer_set_cancel_recv_fnc
-
-#define gaim_xfer_read purple_xfer_read
-#define gaim_xfer_write purple_xfer_write
-#define gaim_xfer_start purple_xfer_start
-#define gaim_xfer_end purple_xfer_end
-#define gaim_xfer_add purple_xfer_add
-#define gaim_xfer_cancel_local purple_xfer_cancel_local
-#define gaim_xfer_cancel_remote purple_xfer_cancel_remote
-#define gaim_xfer_error purple_xfer_error
-#define gaim_xfer_update_progress purple_xfer_update_progress
-#define gaim_xfer_conversation_write purple_xfer_conversation_write
-
-#define gaim_xfers_get_handle purple_xfers_get_handle
-#define gaim_xfers_init purple_xfers_init
-#define gaim_xfers_uninit purple_xfers_uninit
-#define gaim_xfers_set_ui_ops purple_xfers_set_ui_ops
-#define gaim_xfers_get_ui_ops purple_xfers_get_ui_ops
-
-/* from gaim-client.h */
-
-#define gaim_init purple_init
-
-/* from idle.h */
-
-#define GaimIdleUiOps PurpleIdleUiOps
-
-#define gaim_idle_touch purple_idle_touch
-#define gaim_idle_set purple_idle_set
-#define gaim_idle_set_ui_ops purple_idle_set_ui_ops
-#define gaim_idle_get_ui_ops purple_idle_get_ui_ops
-#define gaim_idle_init purple_idle_init
-#define gaim_idle_uninit purple_idle_uninit
-
-/* from imgstore.h */
-
-#define GaimStoredImage PurpleStoredImage
-
-#define gaim_imgstore_add(data, size, filename) \
- purple_imgstore_add_with_id(g_memdup(data, size), size, filename)
-#define gaim_imgstore_get purple_imgstore_find_by_id
-#define gaim_imgstore_get_data purple_imgstore_get_data
-#define gaim_imgstore_get_size purple_imgstore_get_size
-#define gaim_imgstore_get_filename purple_imgstore_get_filename
-#define gaim_imgstore_ref purple_imgstore_ref_by_id
-#define gaim_imgstore_unref purple_imgstore_unref_by_id
-
-
-/* from log.h */
-
-#define GaimLog PurpleLog
-#define GaimLogLogger PurpleLogLogger
-#define GaimLogCommonLoggerData PurpleLogCommonLoggerData
-#define GaimLogSet PurpleLogSet
-
-#define GAIM_LOG_IM PURPLE_LOG_IM
-#define GAIM_LOG_CHAT PURPLE_LOG_CHAT
-#define GAIM_LOG_SYSTEM PURPLE_LOG_SYSTEM
-
-#define GaimLogType PurpleLogType
-
-#define GAIM_LOG_READ_NO_NEWLINE PURPLE_LOG_READ_NO_NEWLINE
-
-#define GaimLogReadFlags PurpleLogReadFlags
-
-#define GaimLogSetCallback PurpleLogSetCallback
-
-#define gaim_log_new purple_log_new
-#define gaim_log_free purple_log_free
-#define gaim_log_write purple_log_write
-#define gaim_log_read purple_log_read
-
-#define gaim_log_get_logs purple_log_get_logs
-#define gaim_log_get_log_sets purple_log_get_log_sets
-#define gaim_log_get_system_logs purple_log_get_system_logs
-#define gaim_log_get_size purple_log_get_size
-#define gaim_log_get_total_size purple_log_get_total_size
-#define gaim_log_get_log_dir purple_log_get_log_dir
-#define gaim_log_compare purple_log_compare
-#define gaim_log_set_compare purple_log_set_compare
-#define gaim_log_set_free purple_log_set_free
-
-#define gaim_log_common_writer purple_log_common_writer
-#define gaim_log_common_lister purple_log_common_lister
-#define gaim_log_common_total_sizer purple_log_common_total_sizer
-#define gaim_log_common_sizer purple_log_common_sizer
-
-#define gaim_log_logger_new purple_log_logger_new
-#define gaim_log_logger_free purple_log_logger_free
-#define gaim_log_logger_add purple_log_logger_add
-#define gaim_log_logger_remove purple_log_logger_remove
-#define gaim_log_logger_set purple_log_logger_set
-#define gaim_log_logger_get purple_log_logger_get
-
-#define gaim_log_logger_get_options purple_log_logger_get_options
-
-#define gaim_log_init purple_log_init
-#define gaim_log_get_handle purple_log_get_handle
-#define gaim_log_uninit purple_log_uninit
-
-/* from mime.h */
-
-#define GaimMimeDocument PurpleMimeDocument
-#define GaimMimePart PurpleMimePart
-
-#define gaim_mime_document_new purple_mime_document_new
-#define gaim_mime_document_free purple_mime_document_free
-#define gaim_mime_document_parse purple_mime_document_parse
-#define gaim_mime_document_parsen purple_mime_document_parsen
-#define gaim_mime_document_write purple_mime_document_write
-#define gaim_mime_document_get_fields purple_mime_document_get_fields
-#define gaim_mime_document_get_field purple_mime_document_get_field
-#define gaim_mime_document_set_field purple_mime_document_set_field
-#define gaim_mime_document_get_parts purple_mime_document_get_parts
-
-#define gaim_mime_part_new purple_mime_part_new
-#define gaim_mime_part_get_fields purple_mime_part_get_fields
-#define gaim_mime_part_get_field purple_mime_part_get_field
-#define gaim_mime_part_get_field_decoded purple_mime_part_get_field_decoded
-#define gaim_mime_part_set_field purple_mime_part_set_field
-#define gaim_mime_part_get_data purple_mime_part_get_data
-#define gaim_mime_part_get_data_decoded purple_mime_part_get_data_decoded
-#define gaim_mime_part_get_length purple_mime_part_get_length
-#define gaim_mime_part_set_data purple_mime_part_set_data
-
-
-/* from network.h */
-
-#define GaimNetworkListenData PurpleNetworkListenData
-
-#define GaimNetworkListenCallback PurpleNetworkListenCallback
-
-#define gaim_network_ip_atoi purple_network_ip_atoi
-#define gaim_network_set_public_ip purple_network_set_public_ip
-#define gaim_network_get_public_ip purple_network_get_public_ip
-#define gaim_network_get_local_system_ip purple_network_get_local_system_ip
-#define gaim_network_get_my_ip purple_network_get_my_ip
-
-#define gaim_network_listen purple_network_listen
-#define gaim_network_listen_range purple_network_listen_range
-#define gaim_network_listen_cancel purple_network_listen_cancel
-#define gaim_network_get_port_from_fd purple_network_get_port_from_fd
-
-#define gaim_network_is_available purple_network_is_available
-
-#define gaim_network_init purple_network_init
-#define gaim_network_uninit purple_network_uninit
-
-/* from notify.h */
-
-
-#define GaimNotifyUserInfoEntry PurpleNotifyUserInfoEntry
-#define GaimNotifyUserInfo PurpleNotifyUserInfo
-
-#define GaimNotifyCloseCallback PurpleNotifyCloseCallback
-
-#define GAIM_NOTIFY_MESSAGE PURPLE_NOTIFY_MESSAGE
-#define GAIM_NOTIFY_EMAIL PURPLE_NOTIFY_EMAIL
-#define GAIM_NOTIFY_EMAILS PURPLE_NOTIFY_EMAILS
-#define GAIM_NOTIFY_FORMATTED PURPLE_NOTIFY_FORMATTED
-#define GAIM_NOTIFY_SEARCHRESULTS PURPLE_NOTIFY_SEARCHRESULTS
-#define GAIM_NOTIFY_USERINFO PURPLE_NOTIFY_USERINFO
-#define GAIM_NOTIFY_URI PURPLE_NOTIFY_URI
-
-#define GaimNotifyType PurpleNotifyType
-
-#define GAIM_NOTIFY_MSG_ERROR PURPLE_NOTIFY_MSG_ERROR
-#define GAIM_NOTIFY_MSG_WARNING PURPLE_NOTIFY_MSG_WARNING
-#define GAIM_NOTIFY_MSG_INFO PURPLE_NOTIFY_MSG_INFO
-
-#define GaimNotifyMsgType PurpleNotifyMsgType
-
-#define GAIM_NOTIFY_BUTTON_LABELED PURPLE_NOTIFY_BUTTON_LABELED
-#define GAIM_NOTIFY_BUTTON_CONTINUE PURPLE_NOTIFY_BUTTON_CONTINUE
-#define GAIM_NOTIFY_BUTTON_ADD PURPLE_NOTIFY_BUTTON_ADD
-#define GAIM_NOTIFY_BUTTON_INFO PURPLE_NOTIFY_BUTTON_INFO
-#define GAIM_NOTIFY_BUTTON_IM PURPLE_NOTIFY_BUTTON_IM
-#define GAIM_NOTIFY_BUTTON_JOIN PURPLE_NOTIFY_BUTTON_JOIN
-#define GAIM_NOTIFY_BUTTON_INVITE PURPLE_NOTIFY_BUTTON_INVITE
-
-#define GaimNotifySearchButtonType PurpleNotifySearchButtonType
-
-#define GaimNotifySearchResults PurpleNotifySearchResults
-
-#define GAIM_NOTIFY_USER_INFO_ENTRY_PAIR PURPLE_NOTIFY_USER_INFO_ENTRY_PAIR
-#define GAIM_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK
-#define GAIM_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER
-
-#define GaimNotifyUserInfoEntryType PurpleNotifyUserInfoEntryType
-
-#define GaimNotifySearchColumn PurpleNotifySearchColumn
-#define GaimNotifySearchResultsCallback PurpleNotifySearchResultsCallback
-#define GaimNotifySearchButton PurpleNotifySearchButton
-
-#define GaimNotifyUiOps PurpleNotifyUiOps
-
-#define gaim_notify_searchresults purple_notify_searchresults
-#define gaim_notify_searchresults_free purple_notify_searchresults_free
-#define gaim_notify_searchresults_new_rows purple_notify_searchresults_new_rows
-#define gaim_notify_searchresults_button_add purple_notify_searchresults_button_add
-#define gaim_notify_searchresults_button_add_labeled purple_notify_searchresults_button_add_labeled
-#define gaim_notify_searchresults_new purple_notify_searchresults_new
-#define gaim_notify_searchresults_column_new purple_notify_searchresults_column_new
-#define gaim_notify_searchresults_column_add purple_notify_searchresults_column_add
-#define gaim_notify_searchresults_row_add purple_notify_searchresults_row_add
-#define gaim_notify_searchresults_get_rows_count purple_notify_searchresults_get_rows_count
-#define gaim_notify_searchresults_get_columns_count purple_notify_searchresults_get_columns_count
-#define gaim_notify_searchresults_row_get purple_notify_searchresults_row_get
-#define gaim_notify_searchresults_column_get_title purple_notify_searchresults_column_get_title
-
-#define gaim_notify_message purple_notify_message
-#define gaim_notify_email purple_notify_email
-#define gaim_notify_emails purple_notify_emails
-#define gaim_notify_formatted purple_notify_formatted
-#define gaim_notify_userinfo purple_notify_userinfo
-
-#define gaim_notify_user_info_new purple_notify_user_info_new
-#define gaim_notify_user_info_destroy purple_notify_user_info_destroy
-#define gaim_notify_user_info_get_entries purple_notify_user_info_get_entries
-#define gaim_notify_user_info_get_text_with_newline purple_notify_user_info_get_text_with_newline
-#define gaim_notify_user_info_add_pair purple_notify_user_info_add_pair
-#define gaim_notify_user_info_prepend_pair purple_notify_user_info_prepend_pair
-#define gaim_notify_user_info_remove_entry purple_notify_user_info_remove_entry
-#define gaim_notify_user_info_entry_new purple_notify_user_info_entry_new
-#define gaim_notify_user_info_add_section_break purple_notify_user_info_add_section_break
-#define gaim_notify_user_info_add_section_header purple_notify_user_info_add_section_header
-#define gaim_notify_user_info_remove_last_item purple_notify_user_info_remove_last_item
-#define gaim_notify_user_info_entry_get_label purple_notify_user_info_entry_get_label
-#define gaim_notify_user_info_entry_set_label purple_notify_user_info_entry_set_label
-#define gaim_notify_user_info_entry_get_value purple_notify_user_info_entry_get_value
-#define gaim_notify_user_info_entry_set_value purple_notify_user_info_entry_set_value
-#define gaim_notify_user_info_entry_get_type purple_notify_user_info_entry_get_type
-#define gaim_notify_user_info_entry_set_type purple_notify_user_info_entry_set_type
-
-#define gaim_notify_uri purple_notify_uri
-#define gaim_notify_close purple_notify_close
-#define gaim_notify_close_with_handle purple_notify_close_with_handle
-
-#define gaim_notify_info purple_notify_info
-#define gaim_notify_warning purple_notify_warning
-#define gaim_notify_error purple_notify_error
-
-#define gaim_notify_set_ui_ops purple_notify_set_ui_ops
-#define gaim_notify_get_ui_ops purple_notify_get_ui_ops
-
-#define gaim_notify_get_handle purple_notify_get_handle
-
-#define gaim_notify_init purple_notify_init
-#define gaim_notify_uninit purple_notify_uninit
-
-/* from ntlm.h */
-
-#define gaim_ntlm_gen_type1 purple_ntlm_gen_type1
-#define gaim_ntlm_parse_type2 purple_ntlm_parse_type2
-#define gaim_ntlm_gen_type3 purple_ntlm_gen_type3
-
-/* from plugin.h */
-
-#ifdef GAIM_PLUGINS
-#ifndef PURPLE_PLUGINS
-#define PURPLE_PLUGINS
-#endif
-#endif
-
-#define GaimPlugin PurplePlugin
-#define GaimPluginInfo PurplePluginInfo
-#define GaimPluginUiInfo PurplePluginUiInfo
-#define GaimPluginLoaderInfo PurplePluginLoaderInfo
-#define GaimPluginAction PurplePluginAction
-#define GaimPluginPriority PurplePluginPriority
-
-#define GAIM_PLUGIN_UNKNOWN PURPLE_PLUGIN_UNKNOWN
-#define GAIM_PLUGIN_STANDARD PURPLE_PLUGIN_STANDARD
-#define GAIM_PLUGIN_LOADER PURPLE_PLUGIN_LOADER
-#define GAIM_PLUGIN_PROTOCOL PURPLE_PLUGIN_PROTOCOL
-
-#define GaimPluginType PurplePluginType
-
-#define GAIM_PRIORITY_DEFAULT PURPLE_PRIORITY_DEFAULT
-#define GAIM_PRIORITY_HIGHEST PURPLE_PRIORITY_HIGHEST
-#define GAIM_PRIORITY_LOWEST PURPLE_PRIORITY_LOWEST
-
-#define GAIM_PLUGIN_FLAG_INVISIBLE PURPLE_PLUGIN_FLAG_INVISIBLE
-
-#define GAIM_PLUGIN_MAGIC PURPLE_PLUGIN_MAGIC
-
-#define GAIM_PLUGIN_LOADER_INFO PURPLE_PLUGIN_LOADER_INFO
-#define GAIM_PLUGIN_HAS_PREF_FRAME PURPLE_PLUGIN_HAS_PREF_FRAME
-#define GAIM_PLUGIN_UI_INFO PURPLE_PLUGIN_UI_INFO
-
-#define GAIM_PLUGIN_HAS_ACTIONS PURPLE_PLUGIN_HAS_ACTIONS
-#define GAIM_PLUGIN_ACTIONS PURPLE_PLUGIN_ACTIONS
-
-#define GAIM_INIT_PLUGIN PURPLE_INIT_PLUGIN
-
-#define gaim_plugin_new purple_plugin_new
-#define gaim_plugin_probe purple_plugin_probe
-#define gaim_plugin_register purple_plugin_register
-#define gaim_plugin_load purple_plugin_load
-#define gaim_plugin_unload purple_plugin_unload
-#define gaim_plugin_reload purple_plugin_reload
-#define gaim_plugin_destroy purple_plugin_destroy
-#define gaim_plugin_is_loaded purple_plugin_is_loaded
-#define gaim_plugin_is_unloadable purple_plugin_is_unloadable
-#define gaim_plugin_get_id purple_plugin_get_id
-#define gaim_plugin_get_name purple_plugin_get_name
-#define gaim_plugin_get_version purple_plugin_get_version
-#define gaim_plugin_get_summary purple_plugin_get_summary
-#define gaim_plugin_get_description purple_plugin_get_description
-#define gaim_plugin_get_author purple_plugin_get_author
-#define gaim_plugin_get_homepage purple_plugin_get_homepage
-
-#define gaim_plugin_ipc_register purple_plugin_ipc_register
-#define gaim_plugin_ipc_unregister purple_plugin_ipc_unregister
-#define gaim_plugin_ipc_unregister_all purple_plugin_ipc_unregister_all
-#define gaim_plugin_ipc_get_params purple_plugin_ipc_get_params
-#define gaim_plugin_ipc_call purple_plugin_ipc_call
-
-#define gaim_plugins_add_search_path purple_plugins_add_search_path
-#define gaim_plugins_unload_all purple_plugins_unload_all
-#define gaim_plugins_destroy_all purple_plugins_destroy_all
-#define gaim_plugins_save_loaded purple_plugins_save_loaded
-#define gaim_plugins_load_saved purple_plugins_load_saved
-#define gaim_plugins_probe purple_plugins_probe
-#define gaim_plugins_enabled purple_plugins_enabled
-
-#define gaim_plugins_register_probe_notify_cb purple_plugins_register_probe_notify_cb
-#define gaim_plugins_unregister_probe_notify_cb purple_plugins_unregister_probe_notify_cb
-#define gaim_plugins_register_load_notify_cb purple_plugins_register_load_notify_cb
-#define gaim_plugins_unregister_load_notify_cb purple_plugins_unregister_load_notify_cb
-#define gaim_plugins_register_unload_notify_cb purple_plugins_register_unload_notify_cb
-#define gaim_plugins_unregister_unload_notify_cb purple_plugins_unregister_unload_notify_cb
-
-#define gaim_plugins_find_with_name purple_plugins_find_with_name
-#define gaim_plugins_find_with_filename purple_plugins_find_with_filename
-#define gaim_plugins_find_with_basename purple_plugins_find_with_basename
-#define gaim_plugins_find_with_id purple_plugins_find_with_id
-
-#define gaim_plugins_get_loaded purple_plugins_get_loaded
-#define gaim_plugins_get_protocols purple_plugins_get_protocols
-#define gaim_plugins_get_all purple_plugins_get_all
-
-#define gaim_plugins_get_handle purple_plugins_get_handle
-#define gaim_plugins_init purple_plugins_init
-#define gaim_plugins_uninit purple_plugins_uninit
-
-#define gaim_plugin_action_new purple_plugin_action_new
-#define gaim_plugin_action_free purple_plugin_action_free
-
-/* pluginpref.h */
-
-#define GaimPluginPrefFrame PurplePluginPrefFrame
-#define GaimPluginPref PurplePluginPref
-
-#define GAIM_STRING_FORMAT_TYPE_NONE PURPLE_STRING_FORMAT_TYPE_NONE
-#define GAIM_STRING_FORMAT_TYPE_MULTILINE PURPLE_STRING_FORMAT_TYPE_MULTILINE
-#define GAIM_STRING_FORMAT_TYPE_HTML PURPLE_STRING_FORMAT_TYPE_HTML
-
-#define GaimStringFormatType PurpleStringFormatType
-
-#define GAIM_PLUGIN_PREF_NONE PURPLE_PLUGIN_PREF_NONE
-#define GAIM_PLUGIN_PREF_CHOICE PURPLE_PLUGIN_PREF_CHOICE
-#define GAIM_PLUGIN_PREF_INFO PURPLE_PLUGIN_PREF_INFO
-#define GAIM_PLUGIN_PREF_STRING_FORMAT PURPLE_PLUGIN_PREF_STRING_FORMAT
-
-#define GaimPluginPrefType PurplePluginPrefType
-
-#define gaim_plugin_pref_frame_new purple_plugin_pref_frame_new
-#define gaim_plugin_pref_frame_destroy purple_plugin_pref_frame_destroy
-#define gaim_plugin_pref_frame_add purple_plugin_pref_frame_add
-#define gaim_plugin_pref_frame_get_prefs purple_plugin_pref_frame_get_prefs
-
-#define gaim_plugin_pref_new purple_plugin_pref_new
-#define gaim_plugin_pref_new_with_name purple_plugin_pref_new_with_name
-#define gaim_plugin_pref_new_with_label purple_plugin_pref_new_with_label
-#define gaim_plugin_pref_new_with_name_and_label purple_plugin_pref_new_with_name_and_label
-#define gaim_plugin_pref_destroy purple_plugin_pref_destroy
-#define gaim_plugin_pref_set_name purple_plugin_pref_set_name
-#define gaim_plugin_pref_get_name purple_plugin_pref_get_name
-#define gaim_plugin_pref_set_label purple_plugin_pref_set_label
-#define gaim_plugin_pref_get_label purple_plugin_pref_get_label
-#define gaim_plugin_pref_set_bounds purple_plugin_pref_set_bounds
-#define gaim_plugin_pref_get_bounds purple_plugin_pref_get_bounds
-#define gaim_plugin_pref_set_type purple_plugin_pref_set_type
-#define gaim_plugin_pref_get_type purple_plugin_pref_get_type
-#define gaim_plugin_pref_add_choice purple_plugin_pref_add_choice
-#define gaim_plugin_pref_get_choices purple_plugin_pref_get_choices
-#define gaim_plugin_pref_set_max_length purple_plugin_pref_set_max_length
-#define gaim_plugin_pref_get_max_length purple_plugin_pref_get_max_length
-#define gaim_plugin_pref_set_masked purple_plugin_pref_set_masked
-#define gaim_plugin_pref_get_masked purple_plugin_pref_get_masked
-#define gaim_plugin_pref_set_format_type purple_plugin_pref_set_format_type
-#define gaim_plugin_pref_get_format_type purple_plugin_pref_get_format_type
-
-/* from pounce.h */
-
-#define GaimPounce PurplePounce
-
-#define GAIM_POUNCE_NONE PURPLE_POUNCE_NONE
-#define GAIM_POUNCE_SIGNON PURPLE_POUNCE_SIGNON
-#define GAIM_POUNCE_SIGNOFF PURPLE_POUNCE_SIGNOFF
-#define GAIM_POUNCE_AWAY PURPLE_POUNCE_AWAY
-#define GAIM_POUNCE_AWAY_RETURN PURPLE_POUNCE_AWAY_RETURN
-#define GAIM_POUNCE_IDLE PURPLE_POUNCE_IDLE
-#define GAIM_POUNCE_IDLE_RETURN PURPLE_POUNCE_IDLE_RETURN
-#define GAIM_POUNCE_TYPING PURPLE_POUNCE_TYPING
-#define GAIM_POUNCE_TYPED PURPLE_POUNCE_TYPED
-#define GAIM_POUNCE_TYPING_STOPPED PURPLE_POUNCE_TYPING_STOPPED
-#define GAIM_POUNCE_MESSAGE_RECEIVED PURPLE_POUNCE_MESSAGE_RECEIVED
-#define GaimPounceEvent PurplePounceEvent
-
-#define GAIM_POUNCE_OPTION_NONE PURPLE_POUNCE_OPTION_NONE
-#define GAIM_POUNCE_OPTION_AWAY PURPLE_POUNCE_OPTION_AWAY
-#define GaimPounceOption PurplePounceOption
-
-#define GaimPounceCb PurplePounceCb
-
-#define gaim_pounce_new purple_pounce_new
-#define gaim_pounce_destroy purple_pounce_destroy
-#define gaim_pounce_destroy_all_by_account purple_pounce_destroy_all_by_account
-#define gaim_pounce_set_events purple_pounce_set_events
-#define gaim_pounce_set_options purple_pounce_set_options
-#define gaim_pounce_set_pouncer purple_pounce_set_pouncer
-#define gaim_pounce_set_pouncee purple_pounce_set_pouncee
-#define gaim_pounce_set_save purple_pounce_set_save
-#define gaim_pounce_action_register purple_pounce_action_register
-#define gaim_pounce_action_set_enabled purple_pounce_action_set_enabled
-#define gaim_pounce_action_set_attribute purple_pounce_action_set_attribute
-#define gaim_pounce_set_data purple_pounce_set_data
-#define gaim_pounce_get_events purple_pounce_get_events
-#define gaim_pounce_get_options purple_pounce_get_options
-#define gaim_pounce_get_pouncer purple_pounce_get_pouncer
-#define gaim_pounce_get_pouncee purple_pounce_get_pouncee
-#define gaim_pounce_get_save purple_pounce_get_save
-#define gaim_pounce_action_is_enabled purple_pounce_action_is_enabled
-#define gaim_pounce_action_get_attribute purple_pounce_action_get_attribute
-#define gaim_pounce_get_data purple_pounce_get_data
-#define gaim_pounce_execute purple_pounce_execute
-
-#define gaim_find_pounce purple_find_pounce
-#define gaim_pounces_load purple_pounces_load
-#define gaim_pounces_register_handler purple_pounces_register_handler
-#define gaim_pounces_unregister_handler purple_pounces_unregister_handler
-#define gaim_pounces_get_all purple_pounces_get_all
-#define gaim_pounces_get_handle purple_pounces_get_handle
-#define gaim_pounces_init purple_pounces_init
-#define gaim_pounces_uninit purple_pounces_uninit
-
-/* from prefs.h */
-
-
-#define GAIM_PREF_NONE PURPLE_PREF_NONE
-#define GAIM_PREF_BOOLEAN PURPLE_PREF_BOOLEAN
-#define GAIM_PREF_INT PURPLE_PREF_INT
-#define GAIM_PREF_STRING PURPLE_PREF_STRING
-#define GAIM_PREF_STRING_LIST PURPLE_PREF_STRING_LIST
-#define GAIM_PREF_PATH PURPLE_PREF_PATH
-#define GAIM_PREF_PATH_LIST PURPLE_PREF_PATH_LIST
-#define GaimPrefType PurplePrefType
-
-#define GaimPrefCallback PurplePrefCallback
-
-#define gaim_prefs_get_handle purple_prefs_get_handle
-#define gaim_prefs_init purple_prefs_init
-#define gaim_prefs_uninit purple_prefs_uninit
-#define gaim_prefs_add_none purple_prefs_add_none
-#define gaim_prefs_add_bool purple_prefs_add_bool
-#define gaim_prefs_add_int purple_prefs_add_int
-#define gaim_prefs_add_string purple_prefs_add_string
-#define gaim_prefs_add_string_list purple_prefs_add_string_list
-#define gaim_prefs_add_path purple_prefs_add_path
-#define gaim_prefs_add_path_list purple_prefs_add_path_list
-#define gaim_prefs_remove purple_prefs_remove
-#define gaim_prefs_rename purple_prefs_rename
-#define gaim_prefs_rename_boolean_toggle purple_prefs_rename_boolean_toggle
-#define gaim_prefs_destroy purple_prefs_destroy
-#define gaim_prefs_set_generic purple_prefs_set_generic
-#define gaim_prefs_set_bool purple_prefs_set_bool
-#define gaim_prefs_set_int purple_prefs_set_int
-#define gaim_prefs_set_string purple_prefs_set_string
-#define gaim_prefs_set_string_list purple_prefs_set_string_list
-#define gaim_prefs_set_path purple_prefs_set_path
-#define gaim_prefs_set_path_list purple_prefs_set_path_list
-#define gaim_prefs_exists purple_prefs_exists
-#define gaim_prefs_get_type purple_prefs_get_type
-#define gaim_prefs_get_bool purple_prefs_get_bool
-#define gaim_prefs_get_int purple_prefs_get_int
-#define gaim_prefs_get_string purple_prefs_get_string
-#define gaim_prefs_get_string_list purple_prefs_get_string_list
-#define gaim_prefs_get_path purple_prefs_get_path
-#define gaim_prefs_get_path_list purple_prefs_get_path_list
-#define gaim_prefs_connect_callback purple_prefs_connect_callback
-#define gaim_prefs_disconnect_callback purple_prefs_disconnect_callback
-#define gaim_prefs_disconnect_by_handle purple_prefs_disconnect_by_handle
-#define gaim_prefs_trigger_callback purple_prefs_trigger_callback
-#define gaim_prefs_load purple_prefs_load
-#define gaim_prefs_update_old purple_prefs_update_old
-
-/* from privacy.h */
-
-#define GAIM_PRIVACY_ALLOW_ALL PURPLE_PRIVACY_ALLOW_ALL
-#define GAIM_PRIVACY_DENY_ALL PURPLE_PRIVACY_DENY_ALL
-#define GAIM_PRIVACY_ALLOW_USERS PURPLE_PRIVACY_ALLOW_USERS
-#define GAIM_PRIVACY_DENY_USERS PURPLE_PRIVACY_DENY_USERS
-#define GAIM_PRIVACY_ALLOW_BUDDYLIST PURPLE_PRIVACY_ALLOW_BUDDYLIST
-#define GaimPrivacyType PurplePrivacyType
-
-#define GaimPrivacyUiOps PurplePrivacyUiOps
-
-#define gaim_privacy_permit_add purple_privacy_permit_add
-#define gaim_privacy_permit_remove purple_privacy_permit_remove
-#define gaim_privacy_deny_add purple_privacy_deny_add
-#define gaim_privacy_deny_remove purple_privacy_deny_remove
-#define gaim_privacy_allow purple_privacy_allow
-#define gaim_privacy_deny purple_privacy_deny
-#define gaim_privacy_check purple_privacy_check
-#define gaim_privacy_set_ui_ops purple_privacy_set_ui_ops
-#define gaim_privacy_get_ui_ops purple_privacy_get_ui_ops
-#define gaim_privacy_init purple_privacy_init
-
-/* from proxy.h */
-
-#define GAIM_PROXY_USE_GLOBAL PURPLE_PROXY_USE_GLOBAL
-#define GAIM_PROXY_NONE PURPLE_PROXY_NONE
-#define GAIM_PROXY_HTTP PURPLE_PROXY_HTTP
-#define GAIM_PROXY_SOCKS4 PURPLE_PROXY_SOCKS4
-#define GAIM_PROXY_SOCKS5 PURPLE_PROXY_SOCKS5
-#define GAIM_PROXY_USE_ENVVAR PURPLE_PROXY_USE_ENVVAR
-#define GaimProxyType PurpleProxyType
-
-#define GaimProxyInfo PurpleProxyInfo
-
-#define GaimProxyConnectData PurpleProxyConnectData
-#define GaimProxyConnectFunction PurpleProxyConnectFunction
-
-#define gaim_proxy_info_new purple_proxy_info_new
-#define gaim_proxy_info_destroy purple_proxy_info_destroy
-#define gaim_proxy_info_set_type purple_proxy_info_set_type
-#define gaim_proxy_info_set_host purple_proxy_info_set_host
-#define gaim_proxy_info_set_port purple_proxy_info_set_port
-#define gaim_proxy_info_set_username purple_proxy_info_set_username
-#define gaim_proxy_info_set_password purple_proxy_info_set_password
-#define gaim_proxy_info_get_type purple_proxy_info_get_type
-#define gaim_proxy_info_get_host purple_proxy_info_get_host
-#define gaim_proxy_info_get_port purple_proxy_info_get_port
-#define gaim_proxy_info_get_username purple_proxy_info_get_username
-#define gaim_proxy_info_get_password purple_proxy_info_get_password
-
-#define gaim_global_proxy_get_info purple_global_proxy_get_info
-#define gaim_proxy_get_handle purple_proxy_get_handle
-#define gaim_proxy_init purple_proxy_init
-#define gaim_proxy_uninit purple_proxy_uninit
-#define gaim_proxy_get_setup purple_proxy_get_setup
-
-#define gaim_proxy_connect purple_proxy_connect
-#define gaim_proxy_connect_socks5 purple_proxy_connect_socks5
-#define gaim_proxy_connect_cancel purple_proxy_connect_cancel
-#define gaim_proxy_connect_cancel_with_handle purple_proxy_connect_cancel_with_handle
-
-/* from prpl.h */
-
-#define GaimPluginProtocolInfo PurplePluginProtocolInfo
-
-#define GAIM_ICON_SCALE_DISPLAY PURPLE_ICON_SCALE_DISPLAY
-#define GAIM_ICON_SCALE_SEND PURPLE_ICON_SCALE_SEND
-#define GaimIconScaleRules PurpleIconScaleRules
-
-#define GaimBuddyIconSpec PurpleBuddyIconSpec
-
-#define GaimProtocolOptions PurpleProtocolOptions
-
-#define GAIM_IS_PROTOCOL_PLUGIN PURPLE_IS_PROTOCOL_PLUGIN
-
-#define GAIM_PLUGIN_PROTOCOL_INFO PURPLE_PLUGIN_PROTOCOL_INFO
-
-#define gaim_prpl_got_account_idle purple_prpl_got_account_idle
-#define gaim_prpl_got_account_login_time purple_prpl_got_account_login_time
-#define gaim_prpl_got_account_status purple_prpl_got_account_status
-#define gaim_prpl_got_user_idle purple_prpl_got_user_idle
-#define gaim_prpl_got_user_login_time purple_prpl_got_user_login_time
-#define gaim_prpl_got_user_status purple_prpl_got_user_status
-#define gaim_prpl_change_account_status purple_prpl_change_account_status
-#define gaim_prpl_get_statuses purple_prpl_get_statuses
-
-#define gaim_find_prpl purple_find_prpl
-
-/* from request.h */
-
-#define GAIM_DEFAULT_ACTION_NONE PURPLE_DEFAULT_ACTION_NONE
-
-#define GAIM_REQUEST_INPUT PURPLE_REQUEST_INPUT
-#define GAIM_REQUEST_CHOICE PURPLE_REQUEST_CHOICE
-#define GAIM_REQUEST_ACTION PURPLE_REQUEST_ACTION
-#define GAIM_REQUEST_FIELDS PURPLE_REQUEST_FIELDS
-#define GAIM_REQUEST_FILE PURPLE_REQUEST_FILE
-#define GAIM_REQUEST_FOLDER PURPLE_REQUEST_FOLDER
-#define GaimRequestType PurpleRequestType
-
-#define GAIM_REQUEST_FIELD_NONE PURPLE_REQUEST_FIELD_NONE
-#define GAIM_REQUEST_FIELD_STRING PURPLE_REQUEST_FIELD_STRING
-#define GAIM_REQUEST_FIELD_INTEGER PURPLE_REQUEST_FIELD_INTEGER
-#define GAIM_REQUEST_FIELD_BOOLEAN PURPLE_REQUEST_FIELD_BOOLEAN
-#define GAIM_REQUEST_FIELD_CHOICE PURPLE_REQUEST_FIELD_CHOICE
-#define GAIM_REQUEST_FIELD_LIST PURPLE_REQUEST_FIELD_LIST
-#define GAIM_REQUEST_FIELD_LABEL PURPLE_REQUEST_FIELD_LABEL
-#define GAIM_REQUEST_FIELD_IMAGE PURPLE_REQUEST_FIELD_IMAGE
-#define GAIM_REQUEST_FIELD_ACCOUNT PURPLE_REQUEST_FIELD_ACCOUNT
-#define GaimRequestFieldType PurpleRequestFieldType
-
-#define GaimRequestFields PurpleRequestFields
-
-#define GaimRequestFieldGroup PurpleRequestFieldGroup
-
-#define GaimRequestField PurpleRequestField
-
-#define GaimRequestUiOps PurpleRequestUiOps
-
-#define GaimRequestInputCb PurpleRequestInputCb
-#define GaimRequestActionCb PurpleRequestActionCb
-#define GaimRequestChoiceCb PurpleRequestChoiceCb
-#define GaimRequestFieldsCb PurpleRequestFieldsCb
-#define GaimRequestFileCb PurpleRequestFileCb
-
-#define gaim_request_fields_new purple_request_fields_new
-#define gaim_request_fields_destroy purple_request_fields_destroy
-#define gaim_request_fields_add_group purple_request_fields_add_group
-#define gaim_request_fields_get_groups purple_request_fields_get_groups
-#define gaim_request_fields_exists purple_request_fields_exists
-#define gaim_request_fields_get_required purple_request_fields_get_required
-#define gaim_request_fields_is_field_required purple_request_fields_is_field_required
-#define gaim_request_fields_all_required_filled purple_request_fields_all_required_filled
-#define gaim_request_fields_get_field purple_request_fields_get_field
-#define gaim_request_fields_get_string purple_request_fields_get_string
-#define gaim_request_fields_get_integer purple_request_fields_get_integer
-#define gaim_request_fields_get_bool purple_request_fields_get_bool
-#define gaim_request_fields_get_choice purple_request_fields_get_choice
-#define gaim_request_fields_get_account purple_request_fields_get_account
-
-#define gaim_request_field_group_new purple_request_field_group_new
-#define gaim_request_field_group_destroy purple_request_field_group_destroy
-#define gaim_request_field_group_add_field purple_request_field_group_add_field
-#define gaim_request_field_group_get_title purple_request_field_group_get_title
-#define gaim_request_field_group_get_fields purple_request_field_group_get_fields
-
-#define gaim_request_field_new purple_request_field_new
-#define gaim_request_field_destroy purple_request_field_destroy
-#define gaim_request_field_set_label purple_request_field_set_label
-#define gaim_request_field_set_visible purple_request_field_set_visible
-#define gaim_request_field_set_type_hint purple_request_field_set_type_hint
-#define gaim_request_field_set_required purple_request_field_set_required
-#define gaim_request_field_get_type purple_request_field_get_type
-#define gaim_request_field_get_id purple_request_field_get_id
-#define gaim_request_field_get_label purple_request_field_get_label
-#define gaim_request_field_is_visible purple_request_field_is_visible
-#define gaim_request_field_get_type_hint purple_request_field_get_type_hint
-#define gaim_request_field_is_required purple_request_field_is_required
-
-#define gaim_request_field_string_new purple_request_field_string_new
-#define gaim_request_field_string_set_default_value \
- purple_request_field_string_set_default_value
-#define gaim_request_field_string_set_value purple_request_field_string_set_value
-#define gaim_request_field_string_set_masked purple_request_field_string_set_masked
-#define gaim_request_field_string_set_editable purple_request_field_string_set_editable
-#define gaim_request_field_string_get_default_value \
- purple_request_field_string_get_default_value
-#define gaim_request_field_string_get_value purple_request_field_string_get_value
-#define gaim_request_field_string_is_multiline purple_request_field_string_is_multiline
-#define gaim_request_field_string_is_masked purple_request_field_string_is_masked
-#define gaim_request_field_string_is_editable purple_request_field_string_is_editable
-
-#define gaim_request_field_int_new purple_request_field_int_new
-#define gaim_request_field_int_set_default_value \
- purple_request_field_int_set_default_value
-#define gaim_request_field_int_set_value purple_request_field_int_set_value
-#define gaim_request_field_int_get_default_value \
- purple_request_field_int_get_default_value
-#define gaim_request_field_int_get_value purple_request_field_int_get_value
-
-#define gaim_request_field_bool_new purple_request_field_bool_new
-#define gaim_request_field_bool_set_default_value \
- purple_request_field_book_set_default_value
-#define gaim_request_field_bool_set_value purple_request_field_bool_set_value
-#define gaim_request_field_bool_get_default_value \
- purple_request_field_bool_get_default_value
-#define gaim_request_field_bool_get_value purple_request_field_bool_get_value
-
-#define gaim_request_field_choice_new purple_request_field_choice_new
-#define gaim_request_field_choice_add purple_request_field_choice_add
-#define gaim_request_field_choice_set_default_value \
- purple_request_field_choice_set_default_value
-#define gaim_request_field_choice_set_value purple_request_field_choice_set_value
-#define gaim_request_field_choice_get_default_value \
- purple_request_field_choice_get_default_value
-#define gaim_request_field_choice_get_value purple_request_field_choice_get_value
-#define gaim_request_field_choice_get_labels purple_request_field_choice_get_labels
-
-#define gaim_request_field_list_new purple_request_field_list_new
-#define gaim_request_field_list_set_multi_select purple_request_field_list_set_multi_select
-#define gaim_request_field_list_get_multi_select purple_request_field_list_get_multi_select
-#define gaim_request_field_list_get_data purple_request_field_list_get_data
-#define gaim_request_field_list_add purple_request_field_list_add
-#define gaim_request_field_list_add_selected purple_request_field_list_add_selected
-#define gaim_request_field_list_clear_selected purple_request_field_list_clear_selected
-#define gaim_request_field_list_set_selected purple_request_field_list_set_selected
-#define gaim_request_field_list_is_selected purple_request_field_list_is_selected
-#define gaim_request_field_list_get_selected purple_request_field_list_get_selected
-#define gaim_request_field_list_get_items purple_request_field_list_get_items
-
-#define gaim_request_field_label_new purple_request_field_label_new
-
-#define gaim_request_field_image_new purple_request_field_image_new
-#define gaim_request_field_image_set_scale purple_request_field_image_set_scale
-#define gaim_request_field_image_get_buffer purple_request_field_image_get_buffer
-#define gaim_request_field_image_get_size purple_request_field_image_get_size
-#define gaim_request_field_image_get_scale_x purple_request_field_image_get_scale_x
-#define gaim_request_field_image_get_scale_y purple_request_field_image_get_scale_y
-
-#define gaim_request_field_account_new purple_request_field_account_new
-#define gaim_request_field_account_set_default_value purple_request_field_account_set_default_value
-#define gaim_request_field_account_set_value purple_request_field_account_set_value
-#define gaim_request_field_account_set_show_all purple_request_field_account_set_show_all
-#define gaim_request_field_account_set_filter purple_request_field_account_set_filter
-#define gaim_request_field_account_get_default_value purple_request_field_account_get_default_value
-#define gaim_request_field_account_get_value purple_request_field_account_get_value
-#define gaim_request_field_account_get_show_all purple_request_field_account_get_show_all
-#define gaim_request_field_account_get_filter purple_request_field_account_get_filter
-
-#define gaim_request_input purple_request_input
-#define gaim_request_choice purple_request_choice
-#define gaim_request_choice_varg purple_request_choice_varg
-#define gaim_request_action purple_request_action
-#define gaim_request_action_varg purple_request_action_varg
-#define gaim_request_fields(handle, title, primary, secondary, fields, ok_text, ok_cb, cancel_text, cancel_cb, user_data) purple_request_fields(handle, title, primary, secondary, fields, ok_text, ok_cb, cancel_text, cancel_cb, NULL, NULL, NULL, user_data)
-#define gaim_request_close purple_request_close
-#define gaim_request_close_with_handle purple_request_close_with_handle
-
-#define gaim_request_yes_no purple_request_yes_no
-#define gaim_request_ok_cancel purple_request_ok_cancel
-#define gaim_request_accept_cancel purple_request_accept_cancel
-
-#define gaim_request_file purple_request_file
-#define gaim_request_folder purple_request_folder
-
-#define gaim_request_set_ui_ops purple_request_set_ui_ops
-#define gaim_request_get_ui_ops purple_request_get_ui_ops
-
-/* from roomlist.h */
-
-#define GaimRoomlist PurpleRoomlist
-#define GaimRoomlistRoom PurpleRoomlistRoom
-#define GaimRoomlistField PurpleRoomlistField
-#define GaimRoomlistUiOps PurpleRoomlistUiOps
-
-#define GAIM_ROOMLIST_ROOMTYPE_CATEGORY PURPLE_ROOMLIST_ROOMTYPE_CATEGORY
-#define GAIM_ROOMLIST_ROOMTYPE_ROOM PURPLE_ROOMLIST_ROOMTYPE_ROOM
-#define GaimRoomlistRoomType PurpleRoomlistRoomType
-
-#define GAIM_ROOMLIST_FIELD_BOOL PURPLE_ROOMLIST_BOOL
-#define GAIM_ROOMLIST_FIELD_INT PURPLE_ROOMLIST_INT
-#define GAIM_ROOMLIST_FIELD_STRING PURPLE_ROOMLIST_STRING
-#define GaimRoomlistFieldType PurpleRoomlistFieldType
-
-#define gaim_roomlist_show_with_account purple_roomlist_show_with_account
-#define gaim_roomlist_new purple_roomlist_new
-#define gaim_roomlist_ref purple_roomlist_ref
-#define gaim_roomlist_unref purple_roomlist_unref
-#define gaim_roomlist_set_fields purple_roomlist_set_fields
-#define gaim_roomlist_set_in_progress purple_roomlist_set_in_progress
-#define gaim_roomlist_get_in_progress purple_roomlist_get_in_progress
-#define gaim_roomlist_room_add purple_roomlist_room_add
-
-#define gaim_roomlist_get_list purple_roomlist_get_list
-#define gaim_roomlist_cancel_get_list purple_roomlist_cancel_get_list
-#define gaim_roomlist_expand_category purple_roomlist_expand_category
-
-#define gaim_roomlist_room_new purple_roomlist_room_new
-#define gaim_roomlist_room_add_field purple_roomlist_room_add_field
-#define gaim_roomlist_room_join purple_roomlist_room_join
-#define gaim_roomlist_field_new purple_roomlist_field_new
-
-#define gaim_roomlist_set_ui_ops purple_roomlist_set_ui_ops
-#define gaim_roomlist_get_ui_ops purple_roomlist_get_ui_ops
-
-/* from savedstatuses.h */
-
-#define GaimSavedStatus PurpleSavedStatus
-#define GaimSavedStatusSub PurpleSavedStatusSub
-
-#define gaim_savedstatus_new purple_savedstatus_new
-#define gaim_savedstatus_set_title purple_savedstatus_set_title
-#define gaim_savedstatus_set_type purple_savedstatus_set_type
-#define gaim_savedstatus_set_message purple_savedstatus_set_message
-#define gaim_savedstatus_set_substatus purple_savedstatus_set_substatus
-#define gaim_savedstatus_unset_substatus purple_savedstatus_unset_substatus
-#define gaim_savedstatus_delete purple_savedstatus_delete
-
-#define gaim_savedstatuses_get_all purple_savedstatuses_get_all
-#define gaim_savedstatuses_get_popular purple_savedstatuses_get_popular
-#define gaim_savedstatus_get_current purple_savedstatus_get_current
-#define gaim_savedstatus_get_default purple_savedstatus_get_default
-#define gaim_savedstatus_get_idleaway purple_savedstatus_get_idleaway
-#define gaim_savedstatus_is_idleaway purple_savedstatus_is_idleaway
-#define gaim_savedstatus_set_idleaway purple_savedstatus_set_idleaway
-#define gaim_savedstatus_get_startup purple_savedstatus_get_startup
-#define gaim_savedstatus_find purple_savedstatus_find
-#define gaim_savedstatus_find_by_creation_time purple_savedstatus_find_by_creation_time
-#define gaim_savedstatus_find_transient_by_type_and_message \
- purple_savedstatus_find_transient_by_type_and_message
-
-#define gaim_savedstatus_is_transient purple_savedstatus_is_transient
-#define gaim_savedstatus_get_title purple_savedstatus_get_title
-#define gaim_savedstatus_get_type purple_savedstatus_get_type
-#define gaim_savedstatus_get_message purple_savedstatus_get_message
-#define gaim_savedstatus_get_creation_time purple_savedstatus_get_creation_time
-#define gaim_savedstatus_has_substatuses purple_savedstatus_has_substatuses
-#define gaim_savedstatus_get_substatus purple_savedstatus_get_substatus
-#define gaim_savedstatus_substatus_get_type purple_savedstatus_substatus_get_type
-#define gaim_savedstatus_substatus_get_message purple_savedstatus_substatus_get_message
-#define gaim_savedstatus_activate purple_savedstatus_activate
-#define gaim_savedstatus_activate_for_account purple_savedstatus_activate_for_account
-
-#define gaim_savedstatuses_get_handle purple_savedstatuses_get_handle
-#define gaim_savedstatuses_init purple_savedstatuses_init
-#define gaim_savedstatuses_uninit purple_savedstatuses_uninit
-
-/* from signals.h */
-
-#define GAIM_CALLBACK PURPLE_CALLBACK
-
-#define GaimCallback PurpleCallback
-#define GaimSignalMarshalFunc PurpleSignalMarshalFunc
-
-#define GAIM_SIGNAL_PRIORITY_DEFAULT PURPLE_SIGNAL_PRIORITY_DEFAULT
-#define GAIM_SIGNAL_PRIORITY_HIGHEST PURPLE_SIGNAL_PRIORITY_HIGHEST
-#define GAIM_SIGNAL_PRIORITY_LOWEST PURPLE_SIGNAL_PRIORITY_LOWEST
-
-#define gaim_signal_register purple_signal_register
-#define gaim_signal_unregister purple_signal_unregister
-
-#define gaim_signals_unregister_by_instance purple_signals_unregister_by_instance
-
-#define gaim_signal_get_values purple_signal_get_values
-#define gaim_signal_connect_priority purple_signal_connect_priority
-#define gaim_signal_connect purple_signal_connect
-#define gaim_signal_connect_priority_vargs purple_signal_connect_priority_vargs
-#define gaim_signal_connect_vargs purple_signal_connect_vargs
-#define gaim_signal_disconnect purple_signal_disconnect
-
-#define gaim_signals_disconnect_by_handle purple_signals_disconnect_by_handle
-
-#define gaim_signal_emit purple_signal_emit
-#define gaim_signal_emit_vargs purple_signal_emit_vargs
-#define gaim_signal_emit_return_1 purple_signal_emit_vargs
-#define gaim_signal_emit_vargs_return_1 purple_signal_emit_vargs_return_1
-
-#define gaim_signals_init purple_signals_init
-#define gaim_signals_uninit purple_signals_uninit
-
-#define gaim_marshal_VOID \
- purple_marshal_VOID
-#define gaim_marshal_VOID__INT \
- purple_marshal_VOID__INT
-#define gaim_marshal_VOID__INT_INT \
- purple_marshal_VOID_INT_INT
-#define gaim_marshal_VOID__POINTER \
- purple_marshal_VOID__POINTER
-#define gaim_marshal_VOID__POINTER_UINT \
- purple_marshal_VOID__POINTER_UINT
-#define gaim_marshal_VOID__POINTER_INT_INT \
- purple_marshal_VOID__POINTER_INT_INT
-#define gaim_marshal_VOID__POINTER_POINTER \
- purple_marshal_VOID__POINTER_POINTER
-#define gaim_marshal_VOID__POINTER_POINTER_UINT \
- purple_marshal_VOID__POINTER_POINTER_UINT
-#define gaim_marshal_VOID__POINTER_POINTER_UINT_UINT \
- purple_marshal_VOID__POINTER_POINTER_UINT_UINT
-#define gaim_marshal_VOID__POINTER_POINTER_POINTER \
- purple_marshal_VOID__POINTER_POINTER_POINTER
-#define gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER \
- purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER
-#define gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER_POINTER \
- purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_POINTER
-#define gaim_marshal_VOID__POINTER_POINTER_POINTER_UINT \
- purple_marshal_VOID__POINTER_POINTER_POINTER_UINT
-#define gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT \
- purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT
-#define gaim_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT \
- purple_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT
-
-#define gaim_marshal_INT__INT \
- purple_marshal_INT__INT
-#define gaim_marshal_INT__INT_INT \
- purple_marshal_INT__INT_INT
-#define gaim_marshal_INT__POINTER_POINTER_POINTER_POINTER_POINTER \
- purple_marshal_INT__POINTER_POINTER_POINTER_POINTER_POINTER
-
-#define gaim_marshal_BOOLEAN__POINTER \
- purple_marshal_BOOLEAN__POINTER
-#define gaim_marshal_BOOLEAN__POINTER_POINTER \
- purple_marshal_BOOLEAN__POINTER_POINTER
-#define gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER \
- purple_marshal_BOOLEAN__POINTER_POINTER_POINTER
-#define gaim_marshal_BOOLEAN__POINTER_POINTER_UINT \
- purple_marshal_BOOLEAN__POINTER_POINTER_UINT
-#define gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_UINT \
- purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_UINT
-#define gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER \
- purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER
-#define gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER \
- purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER
-
-#define gaim_marshal_BOOLEAN__INT_POINTER \
- purple_marshal_BOOLEAN__INT_POINTER
-
-#define gaim_marshal_POINTER__POINTER_INT \
- purple_marshal_POINTER__POINTER_INT
-#define gaim_marshal_POINTER__POINTER_INT64 \
- purple_marshal_POINTER__POINTER_INT64
-#define gaim_marshal_POINTER__POINTER_INT_BOOLEAN \
- purple_marshal_POINTER__POINTER_INT_BOOLEAN
-#define gaim_marshal_POINTER__POINTER_INT64_BOOLEAN \
- purple_marshal_POINTER__POINTER_INT64_BOOLEAN
-#define gaim_marshal_POINTER__POINTER_POINTER \
- purple_marshal_POINTER__POINTER_POINTER
-
-/* from sound.h */
-
-#define GAIM_SOUND_BUDDY_ARRIVE PURPLE_SOUND_BUDDY_ARRIVE
-#define GAIM_SOUND_BUDDY_LEAVE PURPLE_SOUND_BUDDY_LEAVE
-#define GAIM_SOUND_RECEIVE PURPLE_SOUND_RECEIVE
-#define GAIM_SOUND_FIRST_RECEIVE PURPLE_SOUND_FIRST_RECEIVE
-#define GAIM_SOUND_SEND PURPLE_SOUND_SEND
-#define GAIM_SOUND_CHAT_JOIN PURPLE_SOUND_CHAT_JOIN
-#define GAIM_SOUND_CHAT_LEAVE PURPLE_SOUND_CHAT_LEAVE
-#define GAIM_SOUND_CHAT_YOU_SAY PURPLE_SOUND_CHAT_YOU_SAY
-#define GAIM_SOUND_CHAT_SAY PURPLE_SOUND_CHAT_SAY
-#define GAIM_SOUND_POUNCE_DEFAULT PURPLE_SOUND_POUNCE_DEFAULT
-#define GAIM_SOUND_CHAT_NICK PURPLE_SOUND_CHAT_NICK
-#define GAIM_NUM_SOUNDS PURPLE_NUM_SOUNDS
-#define GaimSoundEventID PurpleSoundEventID
-
-#define GaimSoundUiOps PurpleSoundUiOps
-
-#define gaim_sound_play_file purple_sound_play_file
-#define gaim_sound_play_event purple_sound_play_event
-#define gaim_sound_set_ui_ops purple_sound_set_ui_ops
-#define gaim_sound_get_ui_ops purple_sound_get_ui_ops
-#define gaim_sound_init purple_sound_init
-#define gaim_sound_uninit purple_sound_uninit
-
-#define gaim_sounds_get_handle purple_sounds_get_handle
-
-/* from sslconn.h */
-
-#define GAIM_SSL_DEFAULT_PORT PURPLE_SSL_DEFAULT_PORT
-
-#define GAIM_SSL_HANDSHAKE_FAILED PURPLE_SSL_HANDSHAKE_FAILED
-#define GAIM_SSL_CONNECT_FAILED PURPLE_SSL_CONNECT_FAILED
-#define GaimSslErrorType PurpleSslErrorType
-
-#define GaimSslConnection PurpleSslConnection
-
-#define GaimSslInputFunction PurpleSslInputFunction
-#define GaimSslErrorFunction PurpleSslErrorFunction
-
-#define GaimSslOps PurpleSslOps
-
-#define gaim_ssl_is_supported purple_ssl_is_supported
-#define gaim_ssl_connect purple_ssl_connect
-#define gaim_ssl_connect_fd purple_ssl_connect_fd
-#define gaim_ssl_input_add purple_ssl_input_add
-#define gaim_ssl_close purple_ssl_close
-#define gaim_ssl_read purple_ssl_read
-#define gaim_ssl_write purple_ssl_write
-
-#define gaim_ssl_set_ops purple_ssl_set_ops
-#define gaim_ssl_get_ops purple_ssl_get_ops
-#define gaim_ssl_init purple_ssl_init
-#define gaim_ssl_uninit purple_ssl_uninit
-
-/* from status.h */
-
-#define GaimStatusType PurpleStatusType
-#define GaimStatusAttr PurpleStatusAttr
-#define GaimPresence PurplePresence
-#define GaimStatus PurpleStatus
-
-#define GAIM_PRESENCE_CONTEXT_UNSET PURPLE_PRESENCE_CONTEXT_UNSET
-#define GAIM_PRESENCE_CONTEXT_ACCOUNT PURPLE_PRESENCE_CONTEXT_ACCOUNT
-#define GAIM_PRESENCE_CONTEXT_CONV PURPLE_PRESENCE_CONTEXT_CONV
-#define GAIM_PRESENCE_CONTEXT_BUDDY PURPLE_PRESENCE_CONTEXT_BUDDY
-#define GaimPresenceContext PurplePresenceContext
-
-#define GAIM_STATUS_UNSET PURPLE_STATUS_UNSET
-#define GAIM_STATUS_OFFLINE PURPLE_STATUS_OFFLINE
-#define GAIM_STATUS_AVAILABLE PURPLE_STATUS_AVAILABLE
-#define GAIM_STATUS_UNAVAILABLE PURPLE_STATUS_UNAVAILABLE
-#define GAIM_STATUS_INVISIBLE PURPLE_STATUS_INVISIBLE
-#define GAIM_STATUS_AWAY PURPLE_STATUS_AWAY
-#define GAIM_STATUS_EXTENDED_AWAY PURPLE_STATUS_EXTENDED_AWAY
-#define GAIM_STATUS_MOBILE PURPLE_STATUS_MOBILE
-#define GAIM_STATUS_NUM_PRIMITIVES PURPLE_STATUS_NUM_PRIMITIVES
-#define GaimStatusPrimitive PurpleStatusPrimitive
-
-#define gaim_primitive_get_id_from_type purple_primitive_get_id_from_type
-#define gaim_primitive_get_name_from_type purple_primitive_get_name_from_type
-#define gaim_primitive_get_type_from_id purple_primitive_get_type_from_id
-
-#define gaim_status_type_new_full purple_status_type_new_full
-#define gaim_status_type_new purple_status_type_new
-#define gaim_status_type_new_with_attrs purple_status_type_new_with_attrs
-#define gaim_status_type_destroy purple_status_type_destroy
-#define gaim_status_type_set_primary_attr purple_status_type_set_primary_attr
-#define gaim_status_type_add_attr purple_status_type_add_attr
-#define gaim_status_type_add_attrs purple_status_type_add_attrs
-#define gaim_status_type_add_attrs_vargs purple_status_type_add_attrs_vargs
-#define gaim_status_type_get_primitive purple_status_type_get_primitive
-#define gaim_status_type_get_id purple_status_type_get_id
-#define gaim_status_type_get_name purple_status_type_get_name
-#define gaim_status_type_is_saveable purple_status_type_is_saveable
-#define gaim_status_type_is_user_settable purple_status_type_is_user_settable
-#define gaim_status_type_is_independent purple_status_type_is_independent
-#define gaim_status_type_is_exclusive purple_status_type_is_exclusive
-#define gaim_status_type_is_available purple_status_type_is_available
-#define gaim_status_type_get_primary_attr purple_status_type_get_primary_attr
-#define gaim_status_type_get_attr purple_status_type_get_attr
-#define gaim_status_type_get_attrs purple_status_type_get_attrs
-#define gaim_status_type_find_with_id purple_status_type_find_with_id
-
-#define gaim_status_attr_new purple_status_attr_new
-#define gaim_status_attr_destroy purple_status_attr_destroy
-#define gaim_status_attr_get_id purple_status_attr_get_id
-#define gaim_status_attr_get_name purple_status_attr_get_name
-#define gaim_status_attr_get_value purple_status_attr_get_value
-
-#define gaim_status_new purple_status_new
-#define gaim_status_destroy purple_status_destroy
-#define gaim_status_set_active purple_status_set_active
-#define gaim_status_set_active_with_attrs purple_status_set_active_with_attrs
-#define gaim_status_set_active_with_attrs_list purple_status_set_active_with_attrs_list
-#define gaim_status_set_attr_boolean purple_status_set_attr_boolean
-#define gaim_status_set_attr_int purple_status_set_attr_int
-#define gaim_status_set_attr_string purple_status_set_attr_string
-#define gaim_status_get_type purple_status_get_type
-#define gaim_status_get_presence purple_status_get_presence
-#define gaim_status_get_id purple_status_get_id
-#define gaim_status_get_name purple_status_get_name
-#define gaim_status_is_independent purple_status_is_independent
-#define gaim_status_is_exclusive purple_status_is_exclusive
-#define gaim_status_is_available purple_status_is_available
-#define gaim_status_is_active purple_status_is_active
-#define gaim_status_is_online purple_status_is_online
-#define gaim_status_get_attr_value purple_status_get_attr_value
-#define gaim_status_get_attr_boolean purple_status_get_attr_boolean
-#define gaim_status_get_attr_int purple_status_get_attr_int
-#define gaim_status_get_attr_string purple_status_get_attr_string
-#define gaim_status_compare purple_status_compare
-
-#define gaim_presence_new purple_presence_new
-#define gaim_presence_new_for_account purple_presence_new_for_account
-#define gaim_presence_new_for_conv purple_presence_new_for_conv
-#define gaim_presence_new_for_buddy purple_presence_new_for_buddy
-#define gaim_presence_destroy purple_presence_destroy
-#define gaim_presence_add_status purple_presence_add_status
-#define gaim_presence_add_list purple_presence_add_list
-#define gaim_presence_set_status_active purple_presence_set_status_active
-#define gaim_presence_switch_status purple_presence_switch_status
-#define gaim_presence_set_idle purple_presence_set_idle
-#define gaim_presence_set_login_time purple_presence_set_login_time
-#define gaim_presence_get_context purple_presence_get_context
-#define gaim_presence_get_account purple_presence_get_account
-#define gaim_presence_get_conversation purple_presence_get_conversation
-#define gaim_presence_get_chat_user purple_presence_get_chat_user
-#define gaim_presence_get_statuses purple_presence_get_statuses
-#define gaim_presence_get_status purple_presence_get_status
-#define gaim_presence_get_active_status purple_presence_get_active_status
-#define gaim_presence_is_available purple_presence_is_available
-#define gaim_presence_is_online purple_presence_is_online
-#define gaim_presence_is_status_active purple_presence_is_status_active
-#define gaim_presence_is_status_primitive_active \
- purple_presence_is_status_primitive_active
-#define gaim_presence_is_idle purple_presence_is_idle
-#define gaim_presence_get_idle_time purple_presence_get_idle_time
-#define gaim_presence_get_login_time purple_presence_get_login_time
-#define gaim_presence_compare purple_presence_compare
-
-#define gaim_status_get_handle purple_status_get_handle
-#define gaim_status_init purple_status_init
-#define gaim_status_uninit purple_status_uninit
-
-/* from stringref.h */
-
-#define GaimStringref PurpleStringref
-
-#define gaim_stringref_new purple_stringref_new
-#define gaim_stringref_new_noref purple_stringref_new_noref
-#define gaim_stringref_printf purple_stringref_printf
-#define gaim_stringref_ref purple_stringref_ref
-#define gaim_stringref_unref purple_stringref_unref
-#define gaim_stringref_value purple_stringref_value
-#define gaim_stringref_cmp purple_stringref_cmp
-#define gaim_stringref_len purple_stringref_len
-
-/* from stun.h */
-
-#define GaimStunNatDiscovery PurpleStunNatDiscovery
-
-#define GAIM_STUN_STATUS_UNDISCOVERED PURPLE_STUN_STATUS_UNDISCOVERED
-#define GAIM_STUN_STATUS_UNKNOWN PURPLE_STUN_STATUS_UNKNOWN
-#define GAIM_STUN_STATUS_DISCOVERING PURPLE_STUN_STATUS_DISCOVERING
-#define GAIM_STUN_STATUS_DISCOVERED PURPLE_STUN_STATUS_DISCOVERED
-#define GaimStunStatus PurpleStunStatus
-
-#define GAIM_STUN_NAT_TYPE_PUBLIC_IP PURPLE_STUN_NAT_TYPE_PUBLIC_IP
-#define GAIM_STUN_NAT_TYPE_UNKNOWN_NAT PURPLE_STUN_NAT_TYPE_UNKNOWN_NAT
-#define GAIM_STUN_NAT_TYPE_FULL_CONE PURPLE_STUN_NAT_TYPE_FULL_CONE
-#define GAIM_STUN_NAT_TYPE_RESTRICTED_CONE PURPLE_STUN_NAT_TYPE_RESTRICTED_CONE
-#define GAIM_STUN_NAT_TYPE_PORT_RESTRICTED_CONE PURPLE_STUN_NAT_TYPE_PORT_RESTRICTED_CONE
-#define GAIM_STUN_NAT_TYPE_SYMMETRIC PURPLE_STUN_NAT_TYPE_SYMMETRIC
-#define GaimStunNatType PurpleStunNatType
-
-/* why didn't this have a Gaim prefix before? */
-#define StunCallback PurpleStunCallback
-
-#define gaim_stun_discover purple_stun_discover
-#define gaim_stun_init purple_stun_init
-
-/* from upnp.h */
-
-/* suggested rename: PurpleUPnpMappingHandle */
-#define UPnPMappingAddRemove PurpleUPnPMappingAddRemove
-
-#define GaimUPnPCallback PurpleUPnPCallback
-
-#define gaim_upnp_discover purple_upnp_discover
-#define gaim_upnp_get_public_ip purple_upnp_get_public_ip
-#define gaim_upnp_cancel_port_mapping purple_upnp_cancel_port_mapping
-#define gaim_upnp_set_port_mapping purple_upnp_set_port_mapping
-
-#define gaim_upnp_remove_port_mapping purple_upnp_remove_port_mapping
-
-/* from util.h */
-
-#define GaimUtilFetchUrlData PurpleUtilFetchUrlData
-#define GaimMenuAction PurpleMenuAction
-
-#define GaimInfoFieldFormatCallback PurpleIntoFieldFormatCallback
-
-#define GaimKeyValuePair PurpleKeyValuePair
-
-#define gaim_menu_action_new purple_menu_action_new
-#define gaim_menu_action_free purple_menu_action_free
-
-#define gaim_base16_encode purple_base16_encode
-#define gaim_base16_decode purple_base16_decode
-#define gaim_base64_encode purple_base64_encode
-#define gaim_base64_decode purple_base64_decode
-#define gaim_quotedp_decode purple_quotedp_decode
-
-#define gaim_mime_decode_field purple_mime_deco_field
-
-#define gaim_utf8_strftime purple_utf8_strftime
-#define gaim_date_format_short purple_date_format_short
-#define gaim_date_format_long purple_date_format_long
-#define gaim_date_format_full purple_date_format_full
-#define gaim_time_format purple_time_format
-#define gaim_time_build purple_time_build
-
-#define GAIM_NO_TZ_OFF PURPLE_NO_TZ_OFF
-
-#define gaim_str_to_time purple_str_to_time
-
-#define gaim_markup_find_tag purple_markup_find_tag
-#define gaim_markup_extract_info_field purple_markup_extract_info_field
-#define gaim_markup_html_to_xhtml purple_markup_html_to_xhtml
-#define gaim_markup_strip_html purple_markup_strip_html
-#define gaim_markup_linkify purple_markup_linkify
-#define gaim_markup_slice purple_markup_slice
-#define gaim_markup_get_tag_name purple_markup_get_tag_name
-#define gaim_unescape_html purple_unescape_html
-
-#define gaim_home_dir purple_home_dir
-#define gaim_user_dir purple_user_dir
-
-#define gaim_util_set_user_dir purple_util_set_user_dir
-
-#define gaim_build_dir purple_build_dir
-
-#define gaim_util_write_data_to_file purple_util_write_data_to_file
-
-#define gaim_util_read_xml_from_file purple_util_read_xml_from_file
-
-#define gaim_mkstemp purple_mkstemp
-
-#define gaim_program_is_valid purple_program_is_valid
-
-#define gaim_running_gnome purple_running_gnome
-#define gaim_running_kde purple_running_kde
-#define gaim_running_osx purple_running_osx
-
-#define gaim_fd_get_ip purple_fd_get_ip
-
-#define gaim_normalize purple_normalize
-#define gaim_normalize_nocase purple_normalize_nocase
-
-#define gaim_strdup_withhtml purple_strdup_withhtml
-
-#define gaim_str_has_prefix purple_str_has_prefix
-#define gaim_str_has_suffix purple_str_has_suffix
-#define gaim_str_add_cr purple_str_add_cr
-#define gaim_str_strip_char purple_str_strip_char
-
-#define gaim_util_chrreplace purple_util_chrreplace
-
-#define gaim_strreplace purple_strreplace
-
-#define gaim_utf8_ncr_encode purple_utf8_ncr_encode
-#define gaim_utf8_ncr_decode purple_utf8_ncr_decode
-
-#define gaim_strcasereplace purple_strcasereplace
-#define gaim_strcasestr purple_strcasestr
-
-#define gaim_str_size_to_units purple_str_size_to_units
-#define gaim_str_seconds_to_string purple_str_seconds_to_string
-#define gaim_str_binary_to_ascii purple_str_binary_to_ascii
-
-
-#define gaim_got_protocol_handler_uri purple_got_protocol_handler_uri
-
-#define gaim_url_parse purple_url_parse
-
-#define GaimUtilFetchUrlCallback PurpleUtilFetchUrlCallback
-#define gaim_util_fetch_url purple_util_fetch_url
-#define gaim_util_fetch_url_request purple_util_fetch_url_request
-#define gaim_util_fetch_url_cancel purple_util_fetch_url_cancel
-
-#define gaim_url_decode purple_url_decode
-#define gaim_url_encode purple_url_encode
-
-#define gaim_email_is_valid purple_email_is_valid
-
-#define gaim_uri_list_extract_uris purple_uri_list_extract_uris
-#define gaim_uri_list_extract_filenames purple_uri_list_extract_filenames
-
-#define gaim_utf8_try_convert purple_utf8_try_convert
-#define gaim_utf8_salvage purple_utf8_salvage
-#define gaim_utf8_strcasecmp purple_utf8_strcasecmp
-#define gaim_utf8_has_word purple_utf8_has_word
-
-#define gaim_print_utf8_to_console purple_print_utf8_to_console
-
-#define gaim_message_meify purple_message_meify
-
-#define gaim_text_strip_mnemonic purple_text_strip_mnemonic
-
-#define gaim_unescape_filename purple_unescape_filename
-#define gaim_escape_filename purple_escape_filename
-
-/* from value.h */
-
-#define GAIM_TYPE_UNKNOWN PURPLE_TYPE_UNKNOWN
-#define GAIM_TYPE_SUBTYPE PURPLE_TYPE_SUBTYPE
-#define GAIM_TYPE_CHAR PURPLE_TYPE_CHAR
-#define GAIM_TYPE_UCHAR PURPLE_TYPE_UCHAR
-#define GAIM_TYPE_BOOLEAN PURPLE_TYPE_BOOLEAN
-#define GAIM_TYPE_SHORT PURPLE_TYPE_SHORT
-#define GAIM_TYPE_USHORT PURPLE_TYPE_USHORT
-#define GAIM_TYPE_INT PURPLE_TYPE_INT
-#define GAIM_TYPE_UINT PURPLE_TYPE_UINT
-#define GAIM_TYPE_LONG PURPLE_TYPE_LONG
-#define GAIM_TYPE_ULONG PURPLE_TYPE_ULONG
-#define GAIM_TYPE_INT64 PURPLE_TYPE_INT64
-#define GAIM_TYPE_UINT64 PURPLE_TYPE_UINT64
-#define GAIM_TYPE_STRING PURPLE_TYPE_STRING
-#define GAIM_TYPE_OBJECT PURPLE_TYPE_OBJECT
-#define GAIM_TYPE_POINTER PURPLE_TYPE_POINTER
-#define GAIM_TYPE_ENUM PURPLE_TYPE_ENUM
-#define GAIM_TYPE_BOXED PURPLE_TYPE_BOXED
-#define GaimType PurpleType
-
-
-#define GAIM_SUBTYPE_UNKNOWN PURPLE_SUBTYPE_UNKNOWN
-#define GAIM_SUBTYPE_ACCOUNT PURPLE_SUBTYPE_ACCOUNT
-#define GAIM_SUBTYPE_BLIST PURPLE_SUBTYPE_BLIST
-#define GAIM_SUBTYPE_BLIST_BUDDY PURPLE_SUBTYPE_BLIST_BUDDY
-#define GAIM_SUBTYPE_BLIST_GROUP PURPLE_SUBTYPE_BLIST_GROUP
-#define GAIM_SUBTYPE_BLIST_CHAT PURPLE_SUBTYPE_BLIST_CHAT
-#define GAIM_SUBTYPE_BUDDY_ICON PURPLE_SUBTYPE_BUDDY_ICON
-#define GAIM_SUBTYPE_CONNECTION PURPLE_SUBTYPE_CONNECTION
-#define GAIM_SUBTYPE_CONVERSATION PURPLE_SUBTYPE_CONVERSATION
-#define GAIM_SUBTYPE_PLUGIN PURPLE_SUBTYPE_PLUGIN
-#define GAIM_SUBTYPE_BLIST_NODE PURPLE_SUBTYPE_BLIST_NODE
-#define GAIM_SUBTYPE_CIPHER PURPLE_SUBTYPE_CIPHER
-#define GAIM_SUBTYPE_STATUS PURPLE_SUBTYPE_STATUS
-#define GAIM_SUBTYPE_LOG PURPLE_SUBTYPE_LOG
-#define GAIM_SUBTYPE_XFER PURPLE_SUBTYPE_XFER
-#define GAIM_SUBTYPE_SAVEDSTATUS PURPLE_SUBTYPE_SAVEDSTATUS
-#define GAIM_SUBTYPE_XMLNODE PURPLE_SUBTYPE_XMLNODE
-#define GAIM_SUBTYPE_USERINFO PURPLE_SUBTYPE_USERINFO
-#define GaimSubType PurpleSubType
-
-#define GaimValue PurpleValue
-
-#define gaim_value_new purple_value_new
-#define gaim_value_new_outgoing purple_value_new_outgoing
-#define gaim_value_destroy purple_value_destroy
-#define gaim_value_dup purple_value_dup
-#define gaim_value_purple_buddy_icon_get_extensionget_type purple_value_get_type
-#define gaim_value_get_subtype purple_value_get_subtype
-#define gaim_value_get_specific_type purple_value_get_specific_type
-#define gaim_value_is_outgoing purple_value_is_outgoing
-#define gaim_value_set_char purple_value_set_char
-#define gaim_value_set_uchar purple_value_set_uchar
-#define gaim_value_set_boolean purple_value_set_boolean
-#define gaim_value_set_short purple_value_set_short
-#define gaim_value_set_ushort purple_value_set_ushort
-#define gaim_value_set_int purple_value_set_int
-#define gaim_value_set_uint purple_value_set_uint
-#define gaim_value_set_long purple_value_set_long
-#define gaim_value_set_ulong purple_value_set_ulong
-#define gaim_value_set_int64 purple_value_set_int64
-#define gaim_value_set_uint64 purple_value_set_uint64
-#define gaim_value_set_string purple_value_set_string
-#define gaim_value_set_object purple_value_set_object
-#define gaim_value_set_pointer purple_value_set_pointer
-#define gaim_value_set_enum purple_value_set_enum
-#define gaim_value_set_boxed purple_value_set_boxed
-#define gaim_value_get_char purple_value_get_char
-#define gaim_value_get_uchar purple_value_get_uchar
-#define gaim_value_get_boolean purple_value_get_boolean
-#define gaim_value_get_short purple_value_get_short
-#define gaim_value_get_ushort purple_value_get_ushort
-#define gaim_value_get_int purple_value_get_int
-#define gaim_value_get_uint purple_value_get_uint
-#define gaim_value_get_long purple_value_get_long
-#define gaim_value_get_ulong purple_value_get_ulong
-#define gaim_value_get_int64 purple_value_get_int64
-#define gaim_value_get_uint64 purple_value_get_uint64
-#define gaim_value_get_string purple_value_get_string
-#define gaim_value_get_object purple_value_get_object
-#define gaim_value_get_pointer purple_value_get_pointer
-#define gaim_value_get_enum purple_value_get_enum
-#define gaim_value_get_boxed purple_value_get_boxed
-
-/* from version.h */
-
-#define GAIM_MAJOR_VERSION PURPLE_MAJOR_VERSION
-#define GAIM_MINOR_VERSION PURPLE_MINOR_VERSION
-#define GAIM_MICRO_VERSION PURPLE_MICRO_VERSION
-
-#define GAIM_VERSION_CHECK PURPLE_VERSION_CHECK
-
-/* from whiteboard.h */
-
-#define GaimWhiteboardPrplOps PurpleWhiteboardPrplOps
-#define GaimWhiteboard PurpleWhiteboard
-#define GaimWhiteboardUiOps PurpleWhiteboardUiOps
-
-#define gaim_whiteboard_set_ui_ops purple_whiteboard_set_ui_ops
-#define gaim_whiteboard_set_prpl_ops purple_whiteboard_set_prpl_ops
-
-#define gaim_whiteboard_create purple_whiteboard_create
-#define gaim_whiteboard_destroy purple_whiteboard_destroy
-#define gaim_whiteboard_start purple_whiteboard_start
-#define gaim_whiteboard_get_session purple_whiteboard_get_session
-#define gaim_whiteboard_draw_list_destroy purple_whiteboard_draw_list_destroy
-#define gaim_whiteboard_get_dimensions purple_whiteboard_get_dimensions
-#define gaim_whiteboard_set_dimensions purple_whiteboard_set_dimensions
-#define gaim_whiteboard_draw_point purple_whiteboard_draw_point
-#define gaim_whiteboard_send_draw_list purple_whiteboard_send_draw_list
-#define gaim_whiteboard_draw_line purple_whiteboard_draw_line
-#define gaim_whiteboard_clear purple_whiteboard_clear
-#define gaim_whiteboard_send_clear purple_whiteboard_send_clear
-#define gaim_whiteboard_send_brush purple_whiteboard_send_brush
-#define gaim_whiteboard_get_brush purple_whiteboard_get_brush
-#define gaim_whiteboard_set_brush purple_whiteboard_set_brush
-
-/* for static plugins */
-#define gaim_init_ssl_plugin purple_init_ssl_plugin
-#define gaim_init_ssl_openssl_plugin purple_init_ssl_openssl_plugin
-#define gaim_init_ssl_gnutls_plugin purple_init_ssl_gnutls_plugin
-#define gaim_init_gg_plugin purple_init_gg_plugin
-#define gaim_init_jabber_plugin purple_init_jabber_plugin
-#define gaim_init_sametime_plugin purple_init_sametime_plugin
-#define gaim_init_msn_plugin purple_init_msn_plugin
-#define gaim_init_novell_plugin purple_init_novell_plugin
-#define gaim_init_qq_plugin purple_init_qq_plugin
-#define gaim_init_simple_plugin purple_init_simple_plugin
-#define gaim_init_yahoo_plugin purple_init_yahoo_plugin
-#define gaim_init_zephyr_plugin purple_init_zephyr_plugin
-#define gaim_init_aim_plugin purple_init_aim_plugin
-#define gaim_init_icq_plugin purple_init_icq_plugin
-
-#endif /* _GAIM_COMPAT_H_ */
diff --git a/libpurple/idle.h b/libpurple/idle.h
index f01c75bc60..76c78d1258 100644
--- a/libpurple/idle.h
+++ b/libpurple/idle.h
@@ -41,9 +41,7 @@ typedef struct
void (*_purple_reserved4)(void);
} PurpleIdleUiOps;
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Idle API */
@@ -97,8 +95,6 @@ void purple_idle_uninit(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_IDLE_H_ */
diff --git a/libpurple/imgstore.h b/libpurple/imgstore.h
index cd29bc6f5d..4c0aabbafd 100644
--- a/libpurple/imgstore.h
+++ b/libpurple/imgstore.h
@@ -29,14 +29,14 @@
#include <glib.h>
+#define PURPLE_STORED_IMAGE_PROTOCOL "purple-image:"
+
/** A reference-counted immutable wrapper around an image's data and its
* filename.
*/
typedef struct _PurpleStoredImage PurpleStoredImage;
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**
* Add an image to the store.
@@ -68,7 +68,6 @@ purple_imgstore_add(gpointer data, size_t size, const char *filename);
* @param path The path to the image.
*
* @return The stored image.
- * @since 2.X.X
*/
PurpleStoredImage *
purple_imgstore_new_from_file(const char *path);
@@ -207,8 +206,6 @@ void purple_imgstore_init(void);
*/
void purple_imgstore_uninit(void);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_IMGSTORE_H_ */
diff --git a/libpurple/internal.h b/libpurple/internal.h
index dfc1195daa..330e92bdcd 100644
--- a/libpurple/internal.h
+++ b/libpurple/internal.h
@@ -151,12 +151,6 @@
#include <glib-object.h>
-/* Safer ways to work with static buffers. When using non-static
- * buffers, either use g_strdup_* functions (preferred) or use
- * g_strlcpy/g_strlcpy directly. */
-#define purple_strlcpy(dest, src) g_strlcpy(dest, src, sizeof(dest))
-#define purple_strlcat(dest, src) g_strlcat(dest, src, sizeof(dest))
-
#define PURPLE_WEBSITE "http://pidgin.im/"
#define PURPLE_DEVEL_WEBSITE "http://developer.pidgin.im/"
@@ -176,12 +170,6 @@ _purple_buddy_icons_account_loaded_cb(void);
void
_purple_buddy_icons_blist_loaded_cb(void);
-/* This is for the purple_core_migrate() code to tell the buddy
- * icon subsystem about the old icons directory so it can
- * migrate any icons in use. */
-void
-_purple_buddy_icon_set_old_icons_dir(const char *dirname);
-
/**
* Creates a connection to the specified account and either connects
* or attempts to register a new account. If you are logging in,
diff --git a/libpurple/log.c b/libpurple/log.c
index 41a1890fcf..22a2933f78 100644
--- a/libpurple/log.c
+++ b/libpurple/log.c
@@ -1103,7 +1103,7 @@ static void log_get_log_sets_common(GHashTable *sets)
/* Find the account for username in the list of accounts for protocol. */
username_unescaped = purple_unescape_filename(username);
for (account_iter = g_list_first(accounts) ; account_iter != NULL ; account_iter = account_iter->next) {
- if (purple_strequal(((PurpleAccount *)account_iter->data)->username, username_unescaped)) {
+ if (purple_strequal(purple_account_get_username((PurpleAccount *)account_iter->data), username_unescaped)) {
account = account_iter->data;
break;
}
diff --git a/libpurple/log.h b/libpurple/log.h
index 59249b5162..1e12844d5a 100644
--- a/libpurple/log.h
+++ b/libpurple/log.h
@@ -181,9 +181,7 @@ struct _PurpleLogSet {
* IMPORTANT: Update that code if you add members here. */
};
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/***************************************/
/** @name Log Functions */
@@ -301,8 +299,6 @@ int purple_log_get_total_size(PurpleLogType type, const char *name, PurpleAccoun
* @param name The name of the log
* @param account The account
* @return The activity score
- *
- * @since 2.6.0
*/
int purple_log_get_activity_score(PurpleLogType type, const char *name, PurpleAccount *account);
@@ -576,8 +572,6 @@ void purple_log_uninit(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_LOG_H_ */
diff --git a/libpurple/media-gst.h b/libpurple/media-gst.h
index 91d9986d8a..37581ec4f9 100644
--- a/libpurple/media-gst.h
+++ b/libpurple/media-gst.h
@@ -32,8 +32,6 @@
#include <gst/gst.h>
-G_BEGIN_DECLS
-
#define PURPLE_TYPE_MEDIA_ELEMENT_TYPE (purple_media_element_type_get_type())
#define PURPLE_TYPE_MEDIA_ELEMENT_INFO (purple_media_element_info_get_type())
#define PURPLE_MEDIA_ELEMENT_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_MEDIA_ELEMENT_INFO, PurpleMediaElementInfo))
@@ -73,16 +71,12 @@ typedef enum {
PURPLE_MEDIA_ELEMENT_SINK = 1 << 10, /** can be set as an active sink */
} PurpleMediaElementType;
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**
* Gets the element type's GType.
*
* @return The element type's GType.
- *
- * @since 2.6.0
*/
GType purple_media_element_type_get_type(void);
@@ -90,8 +84,6 @@ GType purple_media_element_type_get_type(void);
* Gets the element info's GType.
*
* @return The element info's GType.
- *
- * @since 2.6.0
*/
GType purple_media_element_info_get_type(void);
@@ -102,8 +94,6 @@ GType purple_media_element_info_get_type(void);
* @param sess_id The session id of the session to get the source from.
*
* @return The source retrieved.
- *
- * @since 2.6.0
*/
GstElement *purple_media_get_src(PurpleMedia *media, const gchar *sess_id);
@@ -115,8 +105,6 @@ GstElement *purple_media_get_src(PurpleMedia *media, const gchar *sess_id);
* @param participant Optionally, the participant of the stream to get the tee from.
*
* @return The GstTee element from the chosen session/stream.
- *
- * @since 2.6.0
*/
GstElement *purple_media_get_tee(PurpleMedia *media,
const gchar *session_id, const gchar *participant);
@@ -128,8 +116,6 @@ GstElement *purple_media_get_tee(PurpleMedia *media,
* @param manager The media manager to get the pipeline from.
*
* @return The pipeline.
- *
- * @since 2.6.0
*/
GstElement *purple_media_manager_get_pipeline(PurpleMediaManager *manager);
@@ -141,8 +127,6 @@ GstElement *purple_media_manager_get_pipeline(PurpleMediaManager *manager);
* @param media The media call this element is requested for.
* @param session_id The id of the session this element is requested for or NULL.
* @param participant The remote user this element is requested for or NULL.
- *
- * @since 2.6.0
*/
GstElement *purple_media_manager_get_element(PurpleMediaManager *manager,
PurpleMediaSessionType type, PurpleMedia *media,
@@ -167,8 +151,6 @@ PurpleMediaElementInfo *purple_media_manager_get_active_element(
*
* @param manager The media manager to set the media formats.
* @param caps Set of allowed media formats.
- *
- * @since 2.8.0
*/
void purple_media_manager_set_video_caps(PurpleMediaManager *manager,
GstCaps *caps);
@@ -179,8 +161,6 @@ void purple_media_manager_set_video_caps(PurpleMediaManager *manager,
* @param manager The media manager to get the media formats from.
*
* @return @c GstCaps limiting the video source's formats.
- *
- * @since 2.8.0
*/
GstCaps *purple_media_manager_get_video_caps(PurpleMediaManager *manager);
@@ -192,10 +172,6 @@ GstElement *purple_media_element_info_call_create(
PurpleMediaElementInfo *info, PurpleMedia *media,
const gchar *session_id, const gchar *participant);
-#ifdef __cplusplus
-}
-#endif
-
G_END_DECLS
#endif /* _PURPLE_MEDIA_GST_H_ */
diff --git a/libpurple/media.h b/libpurple/media.h
index b001b7511c..b55ed14f69 100644
--- a/libpurple/media.h
+++ b/libpurple/media.h
@@ -27,14 +27,12 @@
#ifndef _PURPLE_MEDIA_H_
#define _PURPLE_MEDIA_H_
-#include "media/candidate.h"
-#include "media/codec.h"
-#include "media/enum-types.h"
-
#include <glib.h>
#include <glib-object.h>
-G_BEGIN_DECLS
+#include "media/candidate.h"
+#include "media/codec.h"
+#include "media/enum-types.h"
#define PURPLE_TYPE_MEDIA (purple_media_get_type())
#define PURPLE_MEDIA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_MEDIA, PurpleMedia))
@@ -49,16 +47,12 @@ typedef struct _PurpleMedia PurpleMedia;
#include "signals.h"
#include "util.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**
* Gets the media class's GType
*
* @return The media class's GType.
- *
- * @since 2.6.0
*/
GType purple_media_get_type(void);
@@ -68,8 +62,6 @@ GType purple_media_get_type(void);
* @param media The media session from which to retrieve session IDs.
*
* @return GList of session IDs. The caller must free the list.
- *
- * @since 2.6.0
*/
GList *purple_media_get_session_ids(PurpleMedia *media);
@@ -79,8 +71,6 @@ GList *purple_media_get_session_ids(PurpleMedia *media);
* @param media The media session to retrieve the account from.
*
* @return The account retrieved.
- *
- * @since 2.6.0
*/
PurpleAccount *purple_media_get_account(PurpleMedia *media);
@@ -90,8 +80,6 @@ PurpleAccount *purple_media_get_account(PurpleMedia *media);
* @param media The media session to retrieve the prpl data from.
*
* @return The prpl data retrieved.
- *
- * @since 2.6.0
*/
gpointer purple_media_get_prpl_data(PurpleMedia *media);
@@ -100,8 +88,6 @@ gpointer purple_media_get_prpl_data(PurpleMedia *media);
*
* @param media The media session to set the prpl data on.
* @param prpl_data The data to set on the media session.
- *
- * @since 2.6.0
*/
void purple_media_set_prpl_data(PurpleMedia *media, gpointer prpl_data);
@@ -111,8 +97,6 @@ void purple_media_set_prpl_data(PurpleMedia *media, gpointer prpl_data);
* @param media The media object to set the state on.
* @param error The format of the error message to send in the signal.
* @param ... The arguments to plug into the format.
- *
- * @since 2.6.0
*/
void purple_media_error(PurpleMedia *media, const gchar *error, ...);
@@ -122,8 +106,6 @@ void purple_media_error(PurpleMedia *media, const gchar *error, ...);
* @param media The media object with which to end streams.
* @param session_id The session to end streams on.
* @param participant The participant to end streams with.
- *
- * @since 2.6.0
*/
void purple_media_end(PurpleMedia *media, const gchar *session_id,
const gchar *participant);
@@ -136,8 +118,6 @@ void purple_media_end(PurpleMedia *media, const gchar *session_id,
* @param session_id The id of the session of the stream being signaled.
* @param participant The participant of the stream being signaled.
* @param local TRUE if the info originated locally, FALSE if on the remote end.
- *
- * @since 2.6.0
*/
void purple_media_stream_info(PurpleMedia *media, PurpleMediaInfoType type,
const gchar *session_id, const gchar *participant,
@@ -158,8 +138,6 @@ void purple_media_stream_info(PurpleMedia *media, PurpleMediaInfoType type,
* @param media The media object to set the parameters on.
* @param num_params The number of parameters to pass
* @param params Array of @c GParameter to pass
- *
- * @since 2.8.0
*/
void purple_media_set_params(PurpleMedia *media,
guint num_params, GParameter *params);
@@ -172,8 +150,6 @@ void purple_media_set_params(PurpleMedia *media,
* @param media The media object
*
* @return NULL-terminated array of names of supported parameters.
- *
- * @since 2.8.0
*/
const gchar **purple_media_get_available_params(PurpleMedia *media);
@@ -184,8 +160,6 @@ const gchar **purple_media_get_available_params(PurpleMedia *media);
* @param param name of parameter
*
* @return @c TRUE if backend recognizes the parameter, @c FALSE otherwise.
- *
- * @since 2.8.0
*/
gboolean purple_media_param_is_supported(PurpleMedia *media, const gchar *param);
@@ -205,8 +179,6 @@ gboolean purple_media_param_is_supported(PurpleMedia *media, const gchar *param)
* @param params The parameters to pass to Farsight.
*
* @return @c TRUE The stream was added successfully, @c FALSE otherwise.
- *
- * @since 2.6.0
*/
gboolean purple_media_add_stream(PurpleMedia *media, const gchar *sess_id,
const gchar *who, PurpleMediaSessionType type,
@@ -220,8 +192,6 @@ gboolean purple_media_add_stream(PurpleMedia *media, const gchar *sess_id,
* @param sess_id The session id of the session to get the type from.
*
* @return The retreived session type.
- *
- * @since 2.6.0
*/
PurpleMediaSessionType purple_media_get_session_type(PurpleMedia *media, const gchar *sess_id);
@@ -231,8 +201,6 @@ PurpleMediaSessionType purple_media_get_session_type(PurpleMedia *media, const g
* @param media The media object to get the manager instance from.
*
* @return The PurpleMediaManager instance retrieved.
- *
- * @since 2.6.0
*/
struct _PurpleMediaManager *purple_media_get_manager(PurpleMedia *media);
@@ -243,8 +211,6 @@ struct _PurpleMediaManager *purple_media_get_manager(PurpleMedia *media);
* @param sess_id The session id of the session to get the codecs from.
*
* @return The retreieved codecs.
- *
- * @since 2.6.0
*/
GList *purple_media_get_codecs(PurpleMedia *media, const gchar *sess_id);
@@ -255,8 +221,6 @@ GList *purple_media_get_codecs(PurpleMedia *media, const gchar *sess_id);
* @param sess_id The session id of the session find the stream in.
* @param participant The name of the remote user to add the candidates for.
* @param remote_candidates The remote candidates to add.
- *
- * @since 2.6.0
*/
void purple_media_add_remote_candidates(PurpleMedia *media,
const gchar *sess_id,
@@ -269,8 +233,6 @@ void purple_media_add_remote_candidates(PurpleMedia *media,
* @param media The media object to find the session in.
* @param sess_id The session id of the session to find the stream in.
* @param participant The name of the remote user to get the candidates from.
- *
- * @since 2.6.0
*/
GList *purple_media_get_local_candidates(PurpleMedia *media,
const gchar *sess_id,
@@ -285,8 +247,6 @@ GList *purple_media_get_local_candidates(PurpleMedia *media,
* from.
*
* @return The active candidates retrieved.
- *
- * @since 2.8.0
*/
GList *purple_media_get_active_local_candidates(PurpleMedia *media,
const gchar *sess_id, const gchar *participant);
@@ -300,8 +260,6 @@ GList *purple_media_get_active_local_candidates(PurpleMedia *media,
* from.
*
* @return The remote candidates retrieved.
- *
- * @since 2.8.0
*/
GList *purple_media_get_active_remote_candidates(PurpleMedia *media,
const gchar *sess_id, const gchar *participant);
@@ -315,8 +273,6 @@ GList *purple_media_get_active_remote_candidates(PurpleMedia *media,
* @param codecs The list of remote codecs to set.
*
* @return @c TRUE The codecs were set successfully, or @c FALSE otherwise.
- *
- * @since 2.6.0
*/
gboolean purple_media_set_remote_codecs(PurpleMedia *media, const gchar *sess_id,
const gchar *participant, GList *codecs);
@@ -329,8 +285,6 @@ gboolean purple_media_set_remote_codecs(PurpleMedia *media, const gchar *sess_id
* @param participant The remote user to check for.
*
* @return @c TRUE All streams for the given session_id/participant combination have candidates prepared, @c FALSE otherwise.
- *
- * @since 2.6.0
*/
gboolean purple_media_candidates_prepared(PurpleMedia *media,
const gchar *session_id, const gchar *participant);
@@ -343,8 +297,6 @@ gboolean purple_media_candidates_prepared(PurpleMedia *media,
* @param codec The codec to set the session to stream.
*
* @return @c TRUE The codec was successfully changed, or @c FALSE otherwise.
- *
- * @since 2.6.0
*/
gboolean purple_media_set_send_codec(PurpleMedia *media, const gchar *sess_id, PurpleMediaCodec *codec);
@@ -355,8 +307,6 @@ gboolean purple_media_set_send_codec(PurpleMedia *media, const gchar *sess_id, P
* @param sess_id The session id of the session to check.
*
* @return @c TRUE The codecs are ready, or @c FALSE otherwise.
- *
- * @since 2.6.0
*/
gboolean purple_media_codecs_ready(PurpleMedia *media, const gchar *sess_id);
@@ -368,8 +318,6 @@ gboolean purple_media_codecs_ready(PurpleMedia *media, const gchar *sess_id);
* @param participant The participant of the stream to check.
*
* @return TRUE if the local user is the stream's initator, else FALSE.
- *
- * @since 2.6.0
*/
gboolean purple_media_is_initiator(PurpleMedia *media,
const gchar *sess_id, const gchar *participant);
@@ -382,8 +330,6 @@ gboolean purple_media_is_initiator(PurpleMedia *media,
* @param participant The participant to check.
*
* @return @c TRUE The selected streams have been accepted, or @c FALSE otherwise.
- *
- * @since 2.6.0
*/
gboolean purple_media_accepted(PurpleMedia *media, const gchar *sess_id,
const gchar *participant);
@@ -394,8 +340,6 @@ gboolean purple_media_accepted(PurpleMedia *media, const gchar *sess_id,
* @param media The media object the sessions are in.
* @param session_id The session to select (if any).
* @param level The level to set the volume to.
- *
- * @since 2.6.0
*/
void purple_media_set_input_volume(PurpleMedia *media, const gchar *session_id, double level);
@@ -406,8 +350,6 @@ void purple_media_set_input_volume(PurpleMedia *media, const gchar *session_id,
* @param session_id The session to limit the streams to (if any).
* @param participant The participant to limit the streams to (if any).
* @param level The level to set the volume to.
- *
- * @since 2.6.0
*/
void purple_media_set_output_volume(PurpleMedia *media, const gchar *session_id,
const gchar *participant, double level);
@@ -421,8 +363,6 @@ void purple_media_set_output_volume(PurpleMedia *media, const gchar *session_id,
* @param window_id The window id use for embedding the video in.
*
* @return An id to reference the output window.
- *
- * @since 2.6.0
*/
gulong purple_media_set_output_window(PurpleMedia *media,
const gchar *session_id, const gchar *participant,
@@ -432,15 +372,9 @@ gulong purple_media_set_output_window(PurpleMedia *media,
* Removes all output windows from a given media session.
*
* @param media The instance to remove all output windows from.
- *
- * @since 2.6.0
*/
void purple_media_remove_output_windows(PurpleMedia *media);
-#ifdef __cplusplus
-}
-#endif
-
G_END_DECLS
#endif /* _PURPLE_MEDIA_H_ */
diff --git a/libpurple/media/backend-fs2.h b/libpurple/media/backend-fs2.h
index 47fb02dac5..e79f84db47 100644
--- a/libpurple/media/backend-fs2.h
+++ b/libpurple/media/backend-fs2.h
@@ -50,8 +50,6 @@ typedef struct _PurpleMediaBackendFs2 PurpleMediaBackendFs2;
* Gets the type of the Farsight 2 media backend object.
*
* @return The Farsight 2 media backend's GType
- *
- * @since 2.7.0
*/
GType purple_media_backend_fs2_get_type(void);
diff --git a/libpurple/media/backend-iface.h b/libpurple/media/backend-iface.h
index 94105fbaca..a0c96a6fed 100644
--- a/libpurple/media/backend-iface.h
+++ b/libpurple/media/backend-iface.h
@@ -77,8 +77,6 @@ struct _PurpleMediaBackendIface
* Gets the media backend's GType.
*
* @return The media backend's GType.
- *
- * @since 2.7.0
*/
GType purple_media_backend_get_type(void);
@@ -95,8 +93,6 @@ GType purple_media_backend_get_type(void);
* @param params The additional parameters to pass when creating the stream.
*
* @return True if the stream was successfully created, othewise False.
- *
- * @since 2.7.0
*/
gboolean purple_media_backend_add_stream(PurpleMediaBackend *self,
const gchar *sess_id, const gchar *who,
@@ -111,8 +107,6 @@ gboolean purple_media_backend_add_stream(PurpleMediaBackend *self,
* @param sess_id The session id associated with the stream.
* @param participant The participant associated with the stream.
* @param remote_candidates The list of remote candidates to add.
- *
- * @since 2.7.0
*/
void purple_media_backend_add_remote_candidates(PurpleMediaBackend *self,
const gchar *sess_id, const gchar *participant,
@@ -128,8 +122,6 @@ void purple_media_backend_add_remote_candidates(PurpleMediaBackend *self,
* @param sess_id The session id of the session to check.
*
* @return True if the codecs are ready, otherwise False.
- *
- * @since 2.7.0
*/
gboolean purple_media_backend_codecs_ready(PurpleMediaBackend *self,
const gchar *sess_id);
@@ -144,8 +136,6 @@ gboolean purple_media_backend_codecs_ready(PurpleMediaBackend *self,
* @param sess_id The session id of the session to use.
*
* @return The codec intersection list.
- *
- * @since 2.7.0
*/
GList *purple_media_backend_get_codecs(PurpleMediaBackend *self,
const gchar *sess_id);
@@ -158,8 +148,6 @@ GList *purple_media_backend_get_codecs(PurpleMediaBackend *self,
* @param particilant The participant associated with the stream.
*
* @return The list of local candidates.
- *
- * @since 2.7.0
*/
GList *purple_media_backend_get_local_candidates(PurpleMediaBackend *self,
const gchar *sess_id, const gchar *participant);
@@ -173,8 +161,6 @@ GList *purple_media_backend_get_local_candidates(PurpleMediaBackend *self,
* @param codecs The list of remote codecs to set.
*
* @return True if the remote codecs were set successfully, otherwise False.
- *
- * @since 2.7.0
*/
gboolean purple_media_backend_set_remote_codecs(PurpleMediaBackend *self,
const gchar *sess_id, const gchar *participant,
@@ -188,8 +174,6 @@ gboolean purple_media_backend_set_remote_codecs(PurpleMediaBackend *self,
* @param codec The codec to set.
*
* @return True if set successfully, otherwise False.
- *
- * @since 2.7.0
*/
gboolean purple_media_backend_set_send_codec(PurpleMediaBackend *self,
const gchar *sess_id, PurpleMediaCodec *codec);
@@ -200,8 +184,6 @@ gboolean purple_media_backend_set_send_codec(PurpleMediaBackend *self,
* @param self The media backend to set the parameters on.
* @param num_params The number of parameters to pass to backend
* @param params Array of @c GParameter to pass to backend
- *
- * @since 2.8.0
*/
void purple_media_backend_set_params(PurpleMediaBackend *self,
guint num_params, GParameter *params);
@@ -214,8 +196,6 @@ void purple_media_backend_set_params(PurpleMediaBackend *self,
* @param self The media backend
*
* @return NULL-terminated array of names of supported parameters.
- *
- * @since 2.8.0
*/
const gchar **purple_media_backend_get_available_params(PurpleMediaBackend *self);
diff --git a/libpurple/media/candidate.h b/libpurple/media/candidate.h
index 1dfa0fd05e..85a103bf05 100644
--- a/libpurple/media/candidate.h
+++ b/libpurple/media/candidate.h
@@ -47,8 +47,6 @@ typedef struct _PurpleMediaCandidate PurpleMediaCandidate;
* Gets the type of the media candidate structure.
*
* @return The media canditate's GType
- *
- * @since 2.6.0
*/
GType purple_media_candidate_get_type(void);
@@ -63,8 +61,6 @@ GType purple_media_candidate_get_type(void);
* @param port The network port.
*
* @return The newly created PurpleMediaCandidate instance.
- *
- * @since 2.6.0
*/
PurpleMediaCandidate *purple_media_candidate_new(
const gchar *foundation, guint component_id,
@@ -78,8 +74,6 @@ PurpleMediaCandidate *purple_media_candidate_new(
* @param candidate The candidate to copy.
*
* @return The copy of the PurpleMediaCandidate.
- *
- * @since 2.7.0
*/
PurpleMediaCandidate *purple_media_candidate_copy(
PurpleMediaCandidate *candidate);
@@ -90,8 +84,6 @@ PurpleMediaCandidate *purple_media_candidate_copy(
* @param candidates The list of candidates to be copied.
*
* @return The copy of the GList.
- *
- * @since 2.6.0
*/
GList *purple_media_candidate_list_copy(GList *candidates);
@@ -99,8 +91,6 @@ GList *purple_media_candidate_list_copy(GList *candidates);
* Frees a GList of PurpleMediaCandidate and its contents.
*
* @param candidates The list of candidates to be freed.
- *
- * @since 2.6.0
*/
void purple_media_candidate_list_free(GList *candidates);
@@ -110,8 +100,6 @@ void purple_media_candidate_list_free(GList *candidates);
* @param candidate The candidate to get the foundation from.
*
* @return The foundation.
- *
- * @since 2.6.0
*/
gchar *purple_media_candidate_get_foundation(PurpleMediaCandidate *candidate);
@@ -121,8 +109,6 @@ gchar *purple_media_candidate_get_foundation(PurpleMediaCandidate *candidate);
* @param candidate The candidate to get the compnent id from.
*
* @return The component id.
- *
- * @since 2.6.0
*/
guint purple_media_candidate_get_component_id(PurpleMediaCandidate *candidate);
@@ -132,8 +118,6 @@ guint purple_media_candidate_get_component_id(PurpleMediaCandidate *candidate);
* @param candidate The candidate to get the IP address from.
*
* @return The IP address.
- *
- * @since 2.6.0
*/
gchar *purple_media_candidate_get_ip(PurpleMediaCandidate *candidate);
@@ -143,8 +127,6 @@ gchar *purple_media_candidate_get_ip(PurpleMediaCandidate *candidate);
* @param candidate The candidate to get the port from.
*
* @return The port.
- *
- * @since 2.6.0
*/
guint16 purple_media_candidate_get_port(PurpleMediaCandidate *candidate);
@@ -156,8 +138,6 @@ guint16 purple_media_candidate_get_port(PurpleMediaCandidate *candidate);
* @param candidate The candidate to get the base IP address from.
*
* @return The base IP address.
- *
- * @since 2.6.0
*/
gchar *purple_media_candidate_get_base_ip(PurpleMediaCandidate *candidate);
@@ -169,8 +149,6 @@ gchar *purple_media_candidate_get_base_ip(PurpleMediaCandidate *candidate);
* @param candidate The candidate to get the base port.
*
* @return The base port.
- *
- * @since 2.6.0
*/
guint16 purple_media_candidate_get_base_port(PurpleMediaCandidate *candidate);
@@ -180,8 +158,6 @@ guint16 purple_media_candidate_get_base_port(PurpleMediaCandidate *candidate);
* @param candidate The candidate to get the protocol from.
*
* @return The protocol.
- *
- * @since 2.6.0
*/
PurpleMediaNetworkProtocol purple_media_candidate_get_protocol(
PurpleMediaCandidate *candidate);
@@ -192,8 +168,6 @@ PurpleMediaNetworkProtocol purple_media_candidate_get_protocol(
* @param candidate The candidate to get the priority from.
*
* @return The priority.
- *
- * @since 2.6.0
*/
guint32 purple_media_candidate_get_priority(PurpleMediaCandidate *candidate);
@@ -203,8 +177,6 @@ guint32 purple_media_candidate_get_priority(PurpleMediaCandidate *candidate);
* @param candidate The candidate to get the candidate type from.
*
* @return The candidate type.
- *
- * @since 2.6.0
*/
PurpleMediaCandidateType purple_media_candidate_get_candidate_type(
PurpleMediaCandidate *candidate);
@@ -217,8 +189,6 @@ PurpleMediaCandidateType purple_media_candidate_get_candidate_type(
* @param The candidate to get the username from.
*
* @return The username.
- *
- * @since 2.6.0
*/
gchar *purple_media_candidate_get_username(PurpleMediaCandidate *candidate);
@@ -230,8 +200,6 @@ gchar *purple_media_candidate_get_username(PurpleMediaCandidate *candidate);
* @param The candidate to get the password from.
*
* @return The password.
- *
- * @since 2.6.0
*/
gchar *purple_media_candidate_get_password(PurpleMediaCandidate *candidate);
@@ -241,8 +209,6 @@ gchar *purple_media_candidate_get_password(PurpleMediaCandidate *candidate);
* @param The candidate to get the TTL from.
*
* @return The TTL.
- *
- * @since 2.6.0
*/
guint purple_media_candidate_get_ttl(PurpleMediaCandidate *candidate);
diff --git a/libpurple/media/codec.h b/libpurple/media/codec.h
index 46a4ee194e..5bdcdd4f15 100644
--- a/libpurple/media/codec.h
+++ b/libpurple/media/codec.h
@@ -50,8 +50,6 @@ G_BEGIN_DECLS
* Gets the type of the media codec structure.
*
* @return The media codec's GType
- *
- * @since 2.6.0
*/
GType purple_media_codec_get_type(void);
@@ -64,8 +62,6 @@ GType purple_media_codec_get_type(void);
* @param clock_rate The clock rate this codec encodes at, if applicable.
*
* @return The newly created PurpleMediaCodec.
- *
- * @since 2.6.0
*/
PurpleMediaCodec *purple_media_codec_new(int id, const char *encoding_name,
PurpleMediaSessionType media_type, guint clock_rate);
@@ -76,8 +72,6 @@ PurpleMediaCodec *purple_media_codec_new(int id, const char *encoding_name,
* @param The codec to get the id from.
*
* @return The codec id.
- *
- * @since 2.6.0
*/
guint purple_media_codec_get_id(PurpleMediaCodec *codec);
@@ -87,8 +81,6 @@ guint purple_media_codec_get_id(PurpleMediaCodec *codec);
* @param The codec to get the encoding name from.
*
* @return The encoding name.
- *
- * @since 2.6.0
*/
gchar *purple_media_codec_get_encoding_name(PurpleMediaCodec *codec);
@@ -98,8 +90,6 @@ gchar *purple_media_codec_get_encoding_name(PurpleMediaCodec *codec);
* @param The codec to get the clock rate from.
*
* @return The clock rate.
- *
- * @since 2.6.0
*/
guint purple_media_codec_get_clock_rate(PurpleMediaCodec *codec);
@@ -109,8 +99,6 @@ guint purple_media_codec_get_clock_rate(PurpleMediaCodec *codec);
* @param The codec to get the number of channels from.
*
* @return The number of channels.
- *
- * @since 2.6.0
*/
guint purple_media_codec_get_channels(PurpleMediaCodec *codec);
@@ -123,8 +111,6 @@ guint purple_media_codec_get_channels(PurpleMediaCodec *codec);
*
* @return The list of optional parameters. The list is owned by the codec and
* should not be freed.
- *
- * @since 2.6.0
*/
GList *purple_media_codec_get_optional_parameters(PurpleMediaCodec *codec);
@@ -134,8 +120,6 @@ GList *purple_media_codec_get_optional_parameters(PurpleMediaCodec *codec);
* @param codec The codec to add the parameter to.
* @param name The name of the parameter to add.
* @param value The value of the parameter to add.
- *
- * @since 2.6.0
*/
void purple_media_codec_add_optional_parameter(PurpleMediaCodec *codec,
const gchar *name, const gchar *value);
@@ -145,8 +129,6 @@ void purple_media_codec_add_optional_parameter(PurpleMediaCodec *codec,
*
* @param codec The codec to remove the parameter from.
* @param param A pointer to the parameter to remove.
- *
- * @since 2.6.0
*/
void purple_media_codec_remove_optional_parameter(PurpleMediaCodec *codec,
PurpleKeyValuePair *param);
@@ -159,8 +141,6 @@ void purple_media_codec_remove_optional_parameter(PurpleMediaCodec *codec,
* @param value The value to search for or NULL.
*
* @return The value found or NULL.
- *
- * @since 2.6.0
*/
PurpleKeyValuePair *purple_media_codec_get_optional_parameter(
PurpleMediaCodec *codec, const gchar *name,
@@ -172,8 +152,6 @@ PurpleKeyValuePair *purple_media_codec_get_optional_parameter(
* @param codec The codec to copy.
*
* @return The copy of the codec.
- *
- * @since 2.7.0
*/
PurpleMediaCodec *purple_media_codec_copy(PurpleMediaCodec *codec);
@@ -183,8 +161,6 @@ PurpleMediaCodec *purple_media_codec_copy(PurpleMediaCodec *codec);
* @param codecs The list of codecs to be copied.
*
* @return The copy of the GList.
- *
- * @since 2.6.0
*/
GList *purple_media_codec_list_copy(GList *codecs);
@@ -192,8 +168,6 @@ GList *purple_media_codec_list_copy(GList *codecs);
* Frees a GList of PurpleMediaCodec and its contents.
*
* @param codecs The list of codecs to be freed.
- *
- * @since 2.6.0
*/
void purple_media_codec_list_free(GList *codecs);
@@ -203,8 +177,6 @@ void purple_media_codec_list_free(GList *codecs);
* @param codec The codec to create the string of.
*
* @return The new string representation.
- *
- * @since 2.6.0
*/
gchar *purple_media_codec_to_string(const PurpleMediaCodec *codec);
diff --git a/libpurple/media/enum-types.h b/libpurple/media/enum-types.h
index dd163d56ab..5e23e11e05 100644
--- a/libpurple/media/enum-types.h
+++ b/libpurple/media/enum-types.h
@@ -107,8 +107,6 @@ typedef enum {
* Gets the media candidate type's GType
*
* @return The media candidate type's GType.
- *
- * @since 2.6.0
*/
GType purple_media_candidate_type_get_type(void);
@@ -116,8 +114,6 @@ GType purple_media_candidate_type_get_type(void);
* Gets the type of the media caps flags
*
* @return The media caps flags' GType
- *
- * @since 2.7.0
*/
GType purple_media_caps_get_type(void);
@@ -125,8 +121,6 @@ GType purple_media_caps_get_type(void);
* Gets the type of the info type enum
*
* @return The info type enum's GType
- *
- * @since 2.6.0
*/
GType purple_media_info_type_get_type(void);
@@ -134,8 +128,6 @@ GType purple_media_info_type_get_type(void);
* Gets the media network protocol's GType
*
* @return The media network protocol's GType.
- *
- * @since 2.6.0
*/
GType purple_media_network_protocol_get_type(void);
@@ -143,8 +135,6 @@ GType purple_media_network_protocol_get_type(void);
* Gets the media session type's GType
*
* @return The media session type's GType.
- *
- * @since 2.6.0
*/
GType purple_media_session_type_get_type(void);
@@ -152,8 +142,6 @@ GType purple_media_session_type_get_type(void);
* Gets the type of the state-changed enum
*
* @return The state-changed enum's GType
- *
- * @since 2.6.0
*/
GType purple_media_state_changed_get_type(void);
diff --git a/libpurple/mediamanager.h b/libpurple/mediamanager.h
index d9f54ad543..b3d8f315d6 100644
--- a/libpurple/mediamanager.h
+++ b/libpurple/mediamanager.h
@@ -38,8 +38,6 @@ typedef struct _PurpleMediaManagerClass PurpleMediaManagerClass;
#include "account.h"
#include "media.h"
-G_BEGIN_DECLS
-
#define PURPLE_TYPE_MEDIA_MANAGER (purple_media_manager_get_type())
#define PURPLE_MEDIA_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_MEDIA_MANAGER, PurpleMediaManager))
#define PURPLE_MEDIA_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_MEDIA_MANAGER, PurpleMediaManagerClass))
@@ -47,9 +45,7 @@ G_BEGIN_DECLS
#define PURPLE_IS_MEDIA_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_MEDIA_MANAGER))
#define PURPLE_MEDIA_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_MEDIA_MANAGER, PurpleMediaManagerClass))
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Media Manager API */
@@ -60,8 +56,6 @@ extern "C" {
* Gets the media manager's GType.
*
* @return The media manager's GType.
- *
- * @since 2.6.0
*/
GType purple_media_manager_get_type(void);
@@ -69,8 +63,6 @@ GType purple_media_manager_get_type(void);
* Gets the "global" media manager object. It's created if it doesn't already exist.
*
* @return The "global" instance of the media manager object.
- *
- * @since 2.6.0
*/
PurpleMediaManager *purple_media_manager_get(void);
@@ -84,8 +76,6 @@ PurpleMediaManager *purple_media_manager_get(void);
* @param initiator TRUE if the local user is the initiator of this media call, FALSE otherwise.
*
* @return A newly created media session.
- *
- * @since 2.6.0
*/
PurpleMedia *purple_media_manager_create_media(PurpleMediaManager *manager,
PurpleAccount *account,
@@ -99,8 +89,6 @@ PurpleMedia *purple_media_manager_create_media(PurpleMediaManager *manager,
* @param manager The media manager to get all of the sessions from.
*
* @return A list of all the media sessions.
- *
- * @since 2.6.0
*/
GList *purple_media_manager_get_media(PurpleMediaManager *manager);
@@ -111,8 +99,6 @@ GList *purple_media_manager_get_media(PurpleMediaManager *manager);
* @param account The account the sessions are on.
*
* @return A list of the media sessions on the given account.
- *
- * @since 2.6.0
*/
GList *purple_media_manager_get_media_by_account(
PurpleMediaManager *manager, PurpleAccount *account);
@@ -122,8 +108,6 @@ GList *purple_media_manager_get_media_by_account(
*
* @param manager The media manager to remove the media session from.
* @param media The media session to remove.
- *
- * @since 2.6.0
*/
void
purple_media_manager_remove_media(PurpleMediaManager *manager,
@@ -140,8 +124,6 @@ purple_media_manager_remove_media(PurpleMediaManager *manager,
* @param participant The participant the output windows are registered with.
*
* @return TRUE if it succeeded, FALSE if it failed.
- *
- * @since 2.6.0
*/
gboolean purple_media_manager_create_output_window(
PurpleMediaManager *manager, PurpleMedia *media,
@@ -157,8 +139,6 @@ gboolean purple_media_manager_create_output_window(
* @param window_id The window ID to embed the video in.
*
* @return A unique ID to the registered output window, 0 if it failed.
- *
- * @since 2.6.0
*/
gulong purple_media_manager_set_output_window(PurpleMediaManager *manager,
PurpleMedia *media, const gchar *session_id,
@@ -171,8 +151,6 @@ gulong purple_media_manager_set_output_window(PurpleMediaManager *manager,
* @param output_window_id The ID of the output window.
*
* @return TRUE if it found the output window and was successful, else FALSE.
- *
- * @since 2.6.0
*/
gboolean purple_media_manager_remove_output_window(
PurpleMediaManager *manager, gulong output_window_id);
@@ -184,8 +162,6 @@ gboolean purple_media_manager_remove_output_window(
* @param media The media instance the output windows were registered for.
* @param session_id The session the output windows were registered for.
* @param participant The participant the output windows were registered for.
- *
- * @since 2.6.0
*/
void purple_media_manager_remove_output_windows(
PurpleMediaManager *manager, PurpleMedia *media,
@@ -196,8 +172,6 @@ void purple_media_manager_remove_output_windows(
*
* @param manager The manager to set the caps on.
* @param caps The caps to set.
- *
- * @since 2.6.0
*/
void purple_media_manager_set_ui_caps(PurpleMediaManager *manager,
PurpleMediaCaps caps);
@@ -208,8 +182,6 @@ void purple_media_manager_set_ui_caps(PurpleMediaManager *manager,
* @param manager The manager to get caps from.
*
* @return caps The caps retrieved.
- *
- * @since 2.6.0
*/
PurpleMediaCaps purple_media_manager_get_ui_caps(PurpleMediaManager *manager);
@@ -218,8 +190,6 @@ PurpleMediaCaps purple_media_manager_get_ui_caps(PurpleMediaManager *manager);
*
* @param manager The manager to set the caps on.
* @param backend_type The media backend type to use.
- *
- * @since 2.7.0
*/
void purple_media_manager_set_backend_type(PurpleMediaManager *manager,
GType backend_type);
@@ -230,17 +200,11 @@ void purple_media_manager_set_backend_type(PurpleMediaManager *manager,
* @param manager The manager to get the media backend type from.
*
* @return The type of media backend type media objects will use.
- *
- * @since 2.7.0
*/
GType purple_media_manager_get_backend_type(PurpleMediaManager *manager);
/*}@*/
-#ifdef __cplusplus
-}
-#endif
-
G_END_DECLS
#endif /* _PURPLE_MEDIA_MANAGER_H_ */
diff --git a/libpurple/mime.h b/libpurple/mime.h
index b568a49288..abf25d36b1 100644
--- a/libpurple/mime.h
+++ b/libpurple/mime.h
@@ -26,10 +26,6 @@
#include <glib.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/**
* @file mime.h
* @ingroup core
@@ -48,6 +44,8 @@ typedef struct _PurpleMimeDocument PurpleMimeDocument;
*/
typedef struct _PurpleMimePart PurpleMimePart;
+G_BEGIN_DECLS
+
/**
* Allocate an empty MIME document.
*/
@@ -211,8 +209,6 @@ gsize purple_mime_part_get_length(PurpleMimePart *part);
void purple_mime_part_set_data(PurpleMimePart *part, const char *data);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif
diff --git a/libpurple/nat-pmp.h b/libpurple/nat-pmp.h
index 077c74c30c..44470c689b 100644
--- a/libpurple/nat-pmp.h
+++ b/libpurple/nat-pmp.h
@@ -41,6 +41,8 @@ typedef enum {
PURPLE_PMP_TYPE_TCP
} PurplePmpType;
+G_BEGIN_DECLS
+
/**
* Initialize nat-pmp
*/
@@ -54,24 +56,28 @@ char *purple_pmp_get_public_ip(void);
/**
* Remove the NAT-PMP mapping for a specified type on a specified port
*
- * @param type The PurplePmpType
+ * @param type The PurplePmpType
* @param privateport The private port on which we are listening locally
- * @param publicport The public port on which we are expecting a response
- * @param lifetime The lifetime of the mapping. It is recommended that this be PURPLE_PMP_LIFETIME.
+ * @param publicport The public port on which we are expecting a response
+ * @param lifetime The lifetime of the mapping. It is recommended that this
+ * be PURPLE_PMP_LIFETIME.
*
- * @returns TRUE if succesful; FALSE if unsuccessful
+ * @returns TRUE if successful; FALSE if unsuccessful
*/
-gboolean purple_pmp_create_map(PurplePmpType type, unsigned short privateport, unsigned short publicport, int lifetime);
+gboolean purple_pmp_create_map(PurplePmpType type, unsigned short privateport,
+ unsigned short publicport, int lifetime);
/**
* Remove the NAT-PMP mapping for a specified type on a specified port
*
- * @param type The PurplePmpType
+ * @param type The PurplePmpType
* @param privateport The private port on which the mapping was previously made
*
- * @returns TRUE if succesful; FALSE if unsuccessful
+ * @returns TRUE if successful; FALSE if unsuccessful
*/
gboolean purple_pmp_destroy_map(PurplePmpType type, unsigned short privateport);
+G_END_DECLS
+
#endif
diff --git a/libpurple/network.c b/libpurple/network.c
index 3f55cf1ffb..f0e4508477 100644
--- a/libpurple/network.c
+++ b/libpurple/network.c
@@ -391,14 +391,9 @@ purple_network_finish_pmp_map_cb(gpointer data)
return FALSE;
}
-static gboolean listen_map_external = TRUE;
-void purple_network_listen_map_external(gboolean map_external)
-{
- listen_map_external = map_external;
-}
-
static PurpleNetworkListenData *
-purple_network_do_listen(unsigned short port, int socket_family, int socket_type, PurpleNetworkListenCallback cb, gpointer cb_data)
+purple_network_do_listen(unsigned short port, int socket_family, int socket_type, gboolean map_external,
+ PurpleNetworkListenCallback cb, gpointer cb_data)
{
int listenfd = -1;
int flags;
@@ -503,7 +498,7 @@ purple_network_do_listen(unsigned short port, int socket_family, int socket_type
listen_data->cb_data = cb_data;
listen_data->socket_type = socket_type;
- if (!purple_socket_speaks_ipv4(listenfd) || !listen_map_external ||
+ if (!purple_socket_speaks_ipv4(listenfd) || !map_external ||
!purple_prefs_get_bool("/purple/network/map_ports"))
{
purple_debug_info("network", "Skipping external port mapping.\n");
@@ -531,27 +526,19 @@ purple_network_do_listen(unsigned short port, int socket_family, int socket_type
}
PurpleNetworkListenData *
-purple_network_listen_family(unsigned short port, int socket_family,
- int socket_type, PurpleNetworkListenCallback cb,
+purple_network_listen(unsigned short port, int socket_family, int socket_type,
+ gboolean map_external, PurpleNetworkListenCallback cb,
gpointer cb_data)
{
g_return_val_if_fail(port != 0, NULL);
- return purple_network_do_listen(port, socket_family, socket_type,
+ return purple_network_do_listen(port, socket_family, socket_type, map_external,
cb, cb_data);
}
PurpleNetworkListenData *
-purple_network_listen(unsigned short port, int socket_type,
- PurpleNetworkListenCallback cb, gpointer cb_data)
-{
- return purple_network_listen_family(port, AF_UNSPEC, socket_type,
- cb, cb_data);
-}
-
-PurpleNetworkListenData *
-purple_network_listen_range_family(unsigned short start, unsigned short end,
- int socket_family, int socket_type,
+purple_network_listen_range(unsigned short start, unsigned short end,
+ int socket_family, int socket_type, gboolean map_external,
PurpleNetworkListenCallback cb,
gpointer cb_data)
{
@@ -566,7 +553,7 @@ purple_network_listen_range_family(unsigned short start, unsigned short end,
}
for (; start <= end; start++) {
- ret = purple_network_do_listen(start, AF_UNSPEC, socket_type, cb, cb_data);
+ ret = purple_network_do_listen(start, AF_UNSPEC, socket_type, map_external, cb, cb_data);
if (ret != NULL)
break;
}
@@ -574,15 +561,6 @@ purple_network_listen_range_family(unsigned short start, unsigned short end,
return ret;
}
-PurpleNetworkListenData *
-purple_network_listen_range(unsigned short start, unsigned short end,
- int socket_type, PurpleNetworkListenCallback cb,
- gpointer cb_data)
-{
- return purple_network_listen_range_family(start, end, AF_UNSPEC,
- socket_type, cb, cb_data);
-}
-
void purple_network_listen_cancel(PurpleNetworkListenData *listen_data)
{
if (listen_data->mapping_data != NULL)
@@ -1003,7 +981,7 @@ purple_network_set_stun_server(const gchar *stun_server)
if (stun_server && stun_server[0] != '\0') {
if (purple_network_is_available()) {
purple_debug_info("network", "running DNS query for STUN server\n");
- purple_dnsquery_a_account(NULL, stun_server, 3478, purple_network_ip_lookup_cb,
+ purple_dnsquery_a(NULL, stun_server, 3478, purple_network_ip_lookup_cb,
&stun_ip);
} else {
purple_debug_info("network",
@@ -1021,7 +999,7 @@ purple_network_set_turn_server(const gchar *turn_server)
if (turn_server && turn_server[0] != '\0') {
if (purple_network_is_available()) {
purple_debug_info("network", "running DNS query for TURN server\n");
- purple_dnsquery_a_account(NULL, turn_server,
+ purple_dnsquery_a(NULL, turn_server,
purple_prefs_get_int("/purple/network/turn_port"),
purple_network_ip_lookup_cb, &turn_ip);
} else {
diff --git a/libpurple/network.h b/libpurple/network.h
index 333f8e7f30..788c487865 100644
--- a/libpurple/network.h
+++ b/libpurple/network.h
@@ -26,9 +26,9 @@
#ifndef _PURPLE_NETWORK_H_
#define _PURPLE_NETWORK_H_
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include <glib.h>
+
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Network API */
@@ -92,7 +92,6 @@ const char *purple_network_get_local_system_ip(int fd);
*
* @note The caller must free this list. If libpurple was built with
* support for it, this function also enumerates IPv6 addresses.
- * @since 2.7.0
*
* @return A list of local IP addresses.
*/
@@ -118,18 +117,6 @@ GList *purple_network_get_all_local_system_ips(void);
const char *purple_network_get_my_ip(int fd);
/**
- * Should calls to purple_network_listen() and purple_network_listen_range()
- * map the port externally using NAT-PMP or UPnP?
- * The default value is TRUE
- *
- * @param map_external Should the open port be mapped externally?
- * @deprecated In 3.0.0 a boolean will be added to the functions mentioned
- * above to perform the same function.
- * @since 2.3.0
- */
-void purple_network_listen_map_external(gboolean map_external);
-
-/**
* Attempts to open a listening port ONLY on the specified port number.
* You probably want to use purple_network_listen_range() instead of this.
* This function is useful, for example, if you wanted to write a telnet
@@ -142,9 +129,22 @@ void purple_network_listen_map_external(gboolean map_external);
* close the listening socket, and add a new watcher on the new socket accept
* returned.
*
+ * Libpurple does not currently do any port mapping (stateful firewall hole
+ * poking) for IPv6-only listeners (if an IPv6 socket supports v4-mapped
+ * addresses, a mapping is done).
+ *
* @param port The port number to bind to. Must be greater than 0.
+ * @param socket_family The protocol family of the socket. This should be
+ * AF_INET for IPv4 or AF_INET6 for IPv6. IPv6 sockets
+ * may or may not be able to accept IPv4 connections
+ * based on the system configuration (use
+ * purple_socket_speaks_ipv4 to check). If an IPv6
+ * socket doesn't accept V4-mapped addresses, you will
+ * need a second listener to support both v4 and v6.
* @param socket_type The type of socket to open for listening.
* This will be either SOCK_STREAM for TCP or SOCK_DGRAM for UDP.
+ * @param map_external Should the open port be mapped externally using
+ * NAT-PNP or UPnP? (default should be TRUE)
* @param cb The callback to be invoked when the port to listen on is available.
* The file descriptor of the listening socket will be specified in
* this callback, or -1 if no socket could be established.
@@ -155,28 +155,8 @@ void purple_network_listen_map_external(gboolean map_external);
* socket to listen on.
*/
PurpleNetworkListenData *purple_network_listen(unsigned short port,
- int socket_type, PurpleNetworkListenCallback cb, gpointer cb_data);
-
-/**
- * \copydoc purple_network_listen
- *
- * Libpurple does not currently do any port mapping (stateful firewall hole
- * poking) for IPv6-only listeners (if an IPv6 socket supports v4-mapped
- * addresses, a mapping is done).
- *
- * @param socket_family The protocol family of the socket. This should be
- * AF_INET for IPv4 or AF_INET6 for IPv6. IPv6 sockets
- * may or may not be able to accept IPv4 connections
- * based on the system configuration (use
- * purple_socket_speaks_ipv4 to check). If an IPv6
- * socket doesn't accept V4-mapped addresses, you will
- * need a second listener to support both v4 and v6.
- * @since 2.7.0
- * @deprecated This function will be renamed to purple_network_listen in 3.0.0.
- */
-PurpleNetworkListenData *purple_network_listen_family(unsigned short port,
- int socket_family, int socket_type, PurpleNetworkListenCallback cb,
- gpointer cb_data);
+ int socket_family, int socket_type, gboolean map_external,
+ PurpleNetworkListenCallback cb, gpointer cb_data);
/**
* Opens a listening port selected from a range of ports. The range of
@@ -192,13 +172,26 @@ PurpleNetworkListenData *purple_network_listen_family(unsigned short port,
* the listening socket, and add a new watcher on the new socket accept
* returned.
*
+ * Libpurple does not currently do any port mapping (stateful firewall hole
+ * poking) for IPv6-only listeners (if an IPv6 socket supports v4-mapped
+ * addresses, a mapping is done).
+ *
* @param start The port number to bind to, or 0 to pick a random port.
* Users are allowed to override this arg in prefs.
* @param end The highest possible port in the range of ports to listen on,
* or 0 to pick a random port. Users are allowed to override this
* arg in prefs.
+ * @param socket_family The protocol family of the socket. This should be
+ * AF_INET for IPv4 or AF_INET6 for IPv6. IPv6 sockets
+ * may or may not be able to accept IPv4 connections
+ * based on the system configuration (use
+ * purple_socket_speaks_ipv4 to check). If an IPv6
+ * socket doesn't accept V4-mapped addresses, you will
+ * need a second listener to support both v4 and v6.
* @param socket_type The type of socket to open for listening.
* This will be either SOCK_STREAM for TCP or SOCK_DGRAM for UDP.
+ * @param map_external Should the open port be mapped externally using
+ * NAT-PNP or UPnP? (default should be TRUE)
* @param cb The callback to be invoked when the port to listen on is available.
* The file descriptor of the listening socket will be specified in
* this callback, or -1 if no socket could be established.
@@ -208,31 +201,10 @@ PurpleNetworkListenData *purple_network_listen_family(unsigned short port,
* the pending listener, or NULL if unable to obtain a local
* socket to listen on.
*/
-PurpleNetworkListenData *purple_network_listen_range(unsigned short start,
- unsigned short end, int socket_type,
- PurpleNetworkListenCallback cb, gpointer cb_data);
-
-/**
- * \copydoc purple_network_listen_range
- *
- * Libpurple does not currently do any port mapping (stateful firewall hole
- * poking) for IPv6-only listeners (if an IPv6 socket supports v4-mapped
- * addresses, a mapping is done).
- *
- * @param socket_family The protocol family of the socket. This should be
- * AF_INET for IPv4 or AF_INET6 for IPv6. IPv6 sockets
- * may or may not be able to accept IPv4 connections
- * based on the system configuration (use
- * purple_socket_speaks_ipv4 to check). If an IPv6
- * socket doesn't accept V4-mapped addresses, you will
- * need a second listener to support both v4 and v6.
- * @since 2.7.0
- * @deprecated This function will be renamed to purple_network_listen_range
- * in 3.0.0.
- */
-PurpleNetworkListenData *purple_network_listen_range_family(
+PurpleNetworkListenData *purple_network_listen_range(
unsigned short start, unsigned short end, int socket_family,
- int socket_type, PurpleNetworkListenCallback cb, gpointer cb_data);
+ int socket_type, gboolean map_external,
+ PurpleNetworkListenCallback cb, gpointer cb_data);
/**
* This can be used to cancel any in-progress listener connection
@@ -267,8 +239,6 @@ gboolean purple_network_is_available(void);
* This is what backs the --force-online command line argument in Pidgin,
* for example. This is useful for offline testing, especially when
* combined with nullprpl.
- *
- * @since 2.6.0
*/
void purple_network_force_online(void);
@@ -284,7 +254,6 @@ void *purple_network_get_handle(void);
* Will result in a DNS query being executed asynchronous
*
* @param stun_server The host name of the STUN server to set
- * @since 2.6.0
*/
void purple_network_set_stun_server(const gchar *stun_server);
@@ -292,7 +261,6 @@ void purple_network_set_stun_server(const gchar *stun_server);
* Get the IP address of the STUN server as a string representation
*
* @return the IP address
- * @since 2.6.0
*/
const gchar *purple_network_get_stun_ip(void);
@@ -301,7 +269,6 @@ const gchar *purple_network_get_stun_ip(void);
* Will result in a DNS query being executed asynchronous
*
* @param turn_server The host name of the TURN server to set
- * @since 2.6.0
*/
void purple_network_set_turn_server(const gchar *turn_server);
@@ -309,7 +276,6 @@ void purple_network_set_turn_server(const gchar *turn_server);
* Get the IP address of the TURN server as a string representation
*
* @return the IP address
- * @since 2.6.0
*/
const gchar *purple_network_get_turn_ip(void);
@@ -317,7 +283,6 @@ const gchar *purple_network_get_turn_ip(void);
* Remove a port mapping (UPnP or NAT-PMP) associated with listening socket
*
* @param fd Socket to remove the port mapping for
- * @since 2.6.0
*/
void purple_network_remove_port_mapping(gint fd);
@@ -336,7 +301,6 @@ void purple_network_remove_port_mapping(gint fd);
* The caller is responsible for freeing this.
* @returns 0 on success, -1 if the out is NULL, or an error code
* that currently corresponds to the Idna_rc enum in libidn.
- * @since 2.6.0
*/
int purple_network_convert_idn_to_ascii(const gchar *in, gchar **out);
@@ -352,8 +316,6 @@ void purple_network_uninit(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_NETWORK_H_ */
diff --git a/libpurple/notify.c b/libpurple/notify.c
index 45514bd95d..288dc8591c 100644
--- a/libpurple/notify.c
+++ b/libpurple/notify.c
@@ -53,7 +53,17 @@ struct _PurpleNotifyUserInfoEntry
struct _PurpleNotifyUserInfo
{
- GList *user_info_entries;
+ GQueue entries;
+};
+
+/**
+ * Single column of a search result.
+ */
+struct _PurpleNotifySearchColumn
+{
+ char *title; /**< Title of the column. */
+ gboolean visible; /**< Should the column be visible to the user. Defaults to TRUE. */
+
};
void *
@@ -363,42 +373,31 @@ purple_notify_searchresults_column_new(const char *title)
sc = g_new0(PurpleNotifySearchColumn, 1);
sc->title = g_strdup(title);
+ sc->visible = TRUE;
return sc;
}
-guint
-purple_notify_searchresults_get_columns_count(PurpleNotifySearchResults *results)
+const char *purple_notify_searchresult_column_get_title(const PurpleNotifySearchColumn *column)
{
- g_return_val_if_fail(results != NULL, 0);
-
- return g_list_length(results->columns);
-}
-
-guint
-purple_notify_searchresults_get_rows_count(PurpleNotifySearchResults *results)
-{
- g_return_val_if_fail(results != NULL, 0);
-
- return g_list_length(results->rows);
+ g_return_val_if_fail(column != NULL, NULL);
+
+ return column->title;
}
-char *
-purple_notify_searchresults_column_get_title(PurpleNotifySearchResults *results,
- unsigned int column_id)
+void purple_notify_searchresult_column_set_visible(PurpleNotifySearchColumn *column, gboolean visible)
{
- g_return_val_if_fail(results != NULL, NULL);
+ g_return_if_fail(column != NULL);
- return ((PurpleNotifySearchColumn *)g_list_nth_data(results->columns, column_id))->title;
+ column->visible = visible;
}
-GList *
-purple_notify_searchresults_row_get(PurpleNotifySearchResults *results,
- unsigned int row_id)
+gboolean
+purple_notify_searchresult_column_is_visible(const PurpleNotifySearchColumn *column)
{
- g_return_val_if_fail(results != NULL, NULL);
+ g_return_val_if_fail(column != NULL, FALSE);
- return g_list_nth_data(results->rows, row_id);
+ return column->visible;
}
void *
@@ -472,7 +471,7 @@ purple_notify_user_info_new()
user_info = g_new0(PurpleNotifyUserInfo, 1);
PURPLE_DBUS_REGISTER_POINTER(user_info, PurpleNotifyUserInfo);
- user_info->user_info_entries = NULL;
+ g_queue_init(&user_info->entries);
return user_info;
}
@@ -482,23 +481,23 @@ purple_notify_user_info_destroy(PurpleNotifyUserInfo *user_info)
{
GList *l;
- for (l = user_info->user_info_entries; l != NULL; l = l->next) {
+ for (l = user_info->entries.head; l != NULL; l = l->next) {
PurpleNotifyUserInfoEntry *user_info_entry = l->data;
purple_notify_user_info_entry_destroy(user_info_entry);
}
- g_list_free(user_info->user_info_entries);
+ g_queue_clear(&user_info->entries);
PURPLE_DBUS_UNREGISTER_POINTER(user_info);
g_free(user_info);
}
-GList *
+GQueue *
purple_notify_user_info_get_entries(PurpleNotifyUserInfo *user_info)
{
g_return_val_if_fail(user_info != NULL, NULL);
- return user_info->user_info_entries;
+ return &user_info->entries;
}
char *
@@ -509,7 +508,7 @@ purple_notify_user_info_get_text_with_newline(PurpleNotifyUserInfo *user_info, c
text = g_string_new("");
- for (l = user_info->user_info_entries; l != NULL; l = l->next) {
+ for (l = user_info->entries.head; l != NULL; l = l->next) {
PurpleNotifyUserInfoEntry *user_info_entry = l->data;
/* Add a newline before a section header */
if (user_info_entry->type == PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER)
@@ -593,33 +592,41 @@ purple_notify_user_info_entry_set_type(PurpleNotifyUserInfoEntry *user_info_entr
}
void
-purple_notify_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
+purple_notify_user_info_add_pair_html(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
{
PurpleNotifyUserInfoEntry *entry;
entry = purple_notify_user_info_entry_new(label, value);
- user_info->user_info_entries = g_list_append(user_info->user_info_entries, entry);
+ g_queue_push_tail(&user_info->entries, entry);
}
void
purple_notify_user_info_add_pair_plaintext(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
{
gchar *escaped;
- PurpleNotifyUserInfoEntry *entry;
escaped = g_markup_escape_text(value, -1);
- entry = purple_notify_user_info_entry_new(label, escaped);
+ purple_notify_user_info_add_pair_html(user_info, label, escaped);
g_free(escaped);
- user_info->user_info_entries = g_list_append(user_info->user_info_entries, entry);
}
void
-purple_notify_user_info_prepend_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
+purple_notify_user_info_prepend_pair_html(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
{
PurpleNotifyUserInfoEntry *entry;
entry = purple_notify_user_info_entry_new(label, value);
- user_info->user_info_entries = g_list_prepend(user_info->user_info_entries, entry);
+ g_queue_push_head(&user_info->entries, entry);
+}
+
+void
+purple_notify_user_info_prepend_pair_plaintext(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
+{
+ gchar *escaped;
+
+ escaped = g_markup_escape_text(value, -1);
+ purple_notify_user_info_prepend_pair_html(user_info, label, escaped);
+ g_free(escaped);
}
void
@@ -628,7 +635,7 @@ purple_notify_user_info_remove_entry(PurpleNotifyUserInfo *user_info, PurpleNoti
g_return_if_fail(user_info != NULL);
g_return_if_fail(entry != NULL);
- user_info->user_info_entries = g_list_remove(user_info->user_info_entries, entry);
+ g_queue_remove(&user_info->entries, entry);
}
void
@@ -639,7 +646,7 @@ purple_notify_user_info_add_section_header(PurpleNotifyUserInfo *user_info, cons
entry = purple_notify_user_info_entry_new(label, NULL);
entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER;
- user_info->user_info_entries = g_list_append(user_info->user_info_entries, entry);
+ g_queue_push_tail(&user_info->entries, entry);
}
void
@@ -650,7 +657,7 @@ purple_notify_user_info_prepend_section_header(PurpleNotifyUserInfo *user_info,
entry = purple_notify_user_info_entry_new(label, NULL);
entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER;
- user_info->user_info_entries = g_list_prepend(user_info->user_info_entries, entry);
+ g_queue_push_head(&user_info->entries, entry);
}
void
@@ -661,7 +668,7 @@ purple_notify_user_info_add_section_break(PurpleNotifyUserInfo *user_info)
entry = purple_notify_user_info_entry_new(NULL, NULL);
entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK;
- user_info->user_info_entries = g_list_append(user_info->user_info_entries, entry);
+ g_queue_push_tail(&user_info->entries, entry);
}
void
@@ -672,17 +679,17 @@ purple_notify_user_info_prepend_section_break(PurpleNotifyUserInfo *user_info)
entry = purple_notify_user_info_entry_new(NULL, NULL);
entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK;
- user_info->user_info_entries = g_list_prepend(user_info->user_info_entries, entry);
+ g_queue_push_head(&user_info->entries, entry);
}
void
purple_notify_user_info_remove_last_item(PurpleNotifyUserInfo *user_info)
{
- GList *last = g_list_last(user_info->user_info_entries);
- if (last) {
- purple_notify_user_info_entry_destroy(last->data);
- user_info->user_info_entries = g_list_delete_link(user_info->user_info_entries, last);
- }
+ PurpleNotifyUserInfoEntry *entry;
+
+ entry = g_queue_pop_tail(&user_info->entries);
+ if (entry)
+ purple_notify_user_info_entry_destroy(entry);
}
void *
diff --git a/libpurple/notify.h b/libpurple/notify.h
index dc410b600c..ea7ab2b7c5 100644
--- a/libpurple/notify.h
+++ b/libpurple/notify.h
@@ -32,10 +32,13 @@
#include <glib.h>
typedef struct _PurpleNotifyUserInfoEntry PurpleNotifyUserInfoEntry;
-typedef struct _PurpleNotifyUserInfo PurpleNotifyUserInfo;
+typedef struct _PurpleNotifyUserInfo PurpleNotifyUserInfo;
+/** @copydoc _PurpleNotifySearchColumn */
+typedef struct _PurpleNotifySearchColumn PurpleNotifySearchColumn;
#include "connection.h"
+
/**
* Notification close callbacks.
*/
@@ -106,14 +109,6 @@ typedef enum
PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER
} PurpleNotifyUserInfoEntryType;
-/**
- * Single column of a search result.
- */
-typedef struct
-{
- char *title; /**< Title of the column. */
-
-} PurpleNotifySearchColumn;
/**
@@ -180,9 +175,7 @@ typedef struct
} PurpleNotifyUiOps;
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
@@ -266,7 +259,8 @@ void purple_notify_searchresults_button_add_labeled(PurpleNotifySearchResults *r
PurpleNotifySearchResults *purple_notify_searchresults_new(void);
/**
- * Returns a newly created search result column object.
+ * Returns a newly created search result column object. The column defaults
+ * to being visible.
*
* @param title Title of the column. NOTE: Title will get g_strdup()ed.
*
@@ -275,108 +269,48 @@ PurpleNotifySearchResults *purple_notify_searchresults_new(void);
PurpleNotifySearchColumn *purple_notify_searchresults_column_new(const char *title);
/**
- * Adds a new column to the search result object.
+ * Returns the title of the column
*
- * @param results The result object to which the column will be added.
- * @param column The column that will be added to the result object.
- */
-void purple_notify_searchresults_column_add(PurpleNotifySearchResults *results,
- PurpleNotifySearchColumn *column);
-
-/**
- * Adds a new row of the results to the search results object.
+ * @param column The search column object.
*
- * @param results The search results object.
- * @param row The row of the results.
+ * @return The title of the column
*/
-void purple_notify_searchresults_row_add(PurpleNotifySearchResults *results,
- GList *row);
+const char *purple_notify_searchresult_column_get_title(const PurpleNotifySearchColumn *column);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_)
/**
- * 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.
+ * Sets whether or not a search result column is visible.
*
- * @return Number of the result rows.
+ * @param column The search column object.
+ * @param visible TRUE if visible, or FALSE if not.
*/
-guint purple_notify_searchresults_get_rows_count(PurpleNotifySearchResults *results);
-#endif
+void purple_notify_searchresult_column_set_visible(PurpleNotifySearchColumn *column, gboolean visible);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_)
/**
- * Returns a number of the columns in the search results object.
+ * Returns whether or not a search result column is visible.
*
- * @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.
+ * @param column The search column object.
*
- * @return Number of the columns.
+ * @return TRUE if the search result column is visible. FALSE otherwise.
*/
-guint purple_notify_searchresults_get_columns_count(PurpleNotifySearchResults *results);
-#endif
+gboolean purple_notify_searchresult_column_is_visible(const PurpleNotifySearchColumn *column);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_)
/**
- * 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.
+ * Adds a new column to the search result object.
*
- * @return Row of the results.
+ * @param results The result object to which the column will be added.
+ * @param column The column that will be added to the result object.
*/
-GList *purple_notify_searchresults_row_get(PurpleNotifySearchResults *results,
- unsigned int row_id);
-#endif
+void purple_notify_searchresults_column_add(PurpleNotifySearchResults *results,
+ PurpleNotifySearchColumn *column);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_)
/**
- * 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.
+ * Adds a new row of the results to the search results object.
*
- * @return Title of the column.
+ * @param results The search results object.
+ * @param row The row of the results.
*/
-char *purple_notify_searchresults_column_get_title(PurpleNotifySearchResults *results,
- unsigned int column_id);
-#endif
+void purple_notify_searchresults_row_add(PurpleNotifySearchResults *results,
+ GList *row);
/*@}*/
@@ -506,20 +440,20 @@ void purple_notify_user_info_destroy(PurpleNotifyUserInfo *user_info);
* Retrieve the array of PurpleNotifyUserInfoEntry objects from a
* PurpleNotifyUserInfo
*
- * This GList may be manipulated directly with normal GList functions such
- * as g_list_insert(). Only PurpleNotifyUserInfoEntry are allowed in the
- * list. If a PurpleNotifyUserInfoEntry item is added to the list, it
- * should not be g_free()'d by the caller; PurpleNotifyUserInfo will g_free
- * it when destroyed.
+ * This GQueue may be manipulated directly with normal GQueue functions such
+ * as g_queue_push_tail(). Only PurpleNotifyUserInfoEntry are allowed in the
+ * queue. If a PurpleNotifyUserInfoEntry item is added to the queue, it
+ * should not be freed by the caller; PurpleNotifyUserInfo will free it when
+ * destroyed.
*
* To remove a PurpleNotifyUserInfoEntry, use
- * purple_notify_user_info_remove_entry(). Do not use the GList directly.
+ * purple_notify_user_info_remove_entry(). Do not use the GQueue directly.
*
* @param user_info The PurpleNotifyUserInfo
*
- * @constreturn A GList of PurpleNotifyUserInfoEntry objects
+ * @constreturn A GQueue of PurpleNotifyUserInfoEntry objects.
*/
-GList *purple_notify_user_info_get_entries(PurpleNotifyUserInfo *user_info);
+GQueue *purple_notify_user_info_get_entries(PurpleNotifyUserInfo *user_info);
/**
* Create a textual representation of a PurpleNotifyUserInfo, separating
@@ -547,34 +481,25 @@ char *purple_notify_user_info_get_text_with_newline(PurpleNotifyUserInfo *user_i
* the UI should treat label as independent and not
* include a colon if it would otherwise.
*/
-/*
- * TODO: In 3.0.0 this function should be renamed to
- * purple_notify_user_info_add_pair_html(). And optionally
- * purple_notify_user_info_add_pair_plaintext() could be renamed to
- * purple_notify_user_info_add_pair().
- */
-void purple_notify_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value);
+void purple_notify_user_info_add_pair_html(PurpleNotifyUserInfo *user_info, const char *label, const char *value);
/**
- * Like purple_notify_user_info_add_pair, but value should be plaintext
+ * Like purple_notify_user_info_add_pair_html, but value should be plaintext
* and will be escaped using g_markup_escape_text().
*/
void purple_notify_user_info_add_pair_plaintext(PurpleNotifyUserInfo *user_info, const char *label, const char *value);
/**
- * Prepend a label/value pair to a PurpleNotifyUserInfo object
- *
- * @param user_info The PurpleNotifyUserInfo
- * @param label A label, which for example might be displayed by a
- * UI with a colon after it ("Status:"). Do not include
- * a colon. If NULL, value will be displayed without a
- * label.
- * @param value The value, which might be displayed by a UI after
- * the label. If NULL, label will still be displayed;
- * the UI should then treat label as independent and not
- * include a colon if it would otherwise.
+ * Like purple_notify_user_info_add_pair_html, but the pair is inserted
+ * at the beginning of the list.
*/
-void purple_notify_user_info_prepend_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value);
+void purple_notify_user_info_prepend_pair_html(PurpleNotifyUserInfo *user_info, const char *label, const char *value);
+
+/**
+ * Like purple_notify_user_info_prepend_pair_html, but value should be plaintext
+ * and will be escaped using g_markup_escape_text().
+ */
+void purple_notify_user_info_prepend_pair_plaintext(PurpleNotifyUserInfo *user_info, const char *label, const char *value);
#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_)
/**
@@ -597,9 +522,11 @@ void purple_notify_user_info_remove_entry(PurpleNotifyUserInfo *user_info, Purpl
*
* If added to a PurpleNotifyUserInfo object, this should not be free()'d,
* as PurpleNotifyUserInfo will do so when destroyed.
- * purple_notify_user_info_add_pair() and
- * purple_notify_user_info_prepend_pair() are convenience methods for
- * creating entries and adding them to a PurpleNotifyUserInfo.
+ * purple_notify_user_info_add_pair_html(),
+ * purple_notify_user_info_add_pair_plaintext(),
+ * purple_notify_user_info_prepend_pair_html() and
+ * purple_notify_user_info_prepend_pair_plaintext() are convenience
+ * methods for creating entries and adding them to a PurpleNotifyUserInfo.
*
* @param label A label, which for example might be displayed by a UI
* with a colon after it ("Status:"). Do not include a
@@ -624,7 +551,6 @@ void purple_notify_user_info_add_section_break(PurpleNotifyUserInfo *user_info);
* Prepend a section break. A UI might display this as a horizontal line.
*
* @param user_info The PurpleNotifyUserInfo
- * @since 2.5.0
*/
void purple_notify_user_info_prepend_section_break(PurpleNotifyUserInfo *user_info);
@@ -643,7 +569,6 @@ void purple_notify_user_info_add_section_header(PurpleNotifyUserInfo *user_info,
*
* @param user_info The PurpleNotifyUserInfo
* @param label The name of the section
- * @since 2.5.0
*/
void purple_notify_user_info_prepend_section_header(PurpleNotifyUserInfo *user_info, const char *label);
@@ -807,8 +732,6 @@ void purple_notify_uninit(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_NOTIFY_H_ */
diff --git a/libpurple/ntlm.h b/libpurple/ntlm.h
index e61a4f5f07..e67df3f828 100644
--- a/libpurple/ntlm.h
+++ b/libpurple/ntlm.h
@@ -27,9 +27,7 @@
#ifndef _PURPLE_NTLM_H
#define _PURPLE_NTLM_H
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**
* Generates the base64 encoded type 1 message needed for NTLM authentication
@@ -66,8 +64,6 @@ guint8 *purple_ntlm_parse_type2(const gchar *type2, guint32 *flags);
*/
gchar *purple_ntlm_gen_type3(const gchar *username, const gchar *passw, const gchar *hostname, const gchar *domain, const guint8 *nonce, guint32 *flags);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_NTLM_H */
diff --git a/libpurple/plugin.c b/libpurple/plugin.c
index 4f2b4023ab..c97a9f3d67 100644
--- a/libpurple/plugin.c
+++ b/libpurple/plugin.c
@@ -64,13 +64,6 @@ static GList *plugin_loaders = NULL;
static GList *plugins_to_disable = NULL;
#endif
-static void (*probe_cb)(void *) = NULL;
-static void *probe_cb_data = NULL;
-static void (*load_cb)(PurplePlugin *, void *) = NULL;
-static void *load_cb_data = NULL;
-static void (*unload_cb)(PurplePlugin *, void *) = NULL;
-static void *unload_cb_data = NULL;
-
#ifdef PURPLE_PLUGINS
static gboolean
@@ -615,9 +608,6 @@ purple_plugin_load(PurplePlugin *plugin)
plugin->loaded = TRUE;
- if (load_cb != NULL)
- load_cb(plugin, load_cb_data);
-
purple_signal_emit(purple_plugins_get_handle(), "plugin-load", plugin);
return TRUE;
@@ -745,9 +735,6 @@ purple_plugin_unload(PurplePlugin *plugin)
g_free(plugin->error);
plugin->error = NULL;
- if (unload_cb != NULL)
- unload_cb(plugin, unload_cb_data);
-
purple_signal_emit(purple_plugins_get_handle(), "plugin-unload", plugin);
purple_prefs_disconnect_by_handle(plugin);
@@ -1439,10 +1426,6 @@ purple_plugins_probe(const char *ext)
(GCompareFunc)compare_prpl);
}
}
-
- if (probe_cb != NULL)
- probe_cb(probe_cb_data);
-
#endif /* PURPLE_PLUGINS */
}
@@ -1513,50 +1496,6 @@ purple_plugins_enabled(void)
#endif
}
-void
-purple_plugins_register_probe_notify_cb(void (*func)(void *), void *data)
-{
- probe_cb = func;
- probe_cb_data = data;
-}
-
-void
-purple_plugins_unregister_probe_notify_cb(void (*func)(void *))
-{
- probe_cb = NULL;
- probe_cb_data = NULL;
-}
-
-void
-purple_plugins_register_load_notify_cb(void (*func)(PurplePlugin *, void *),
- void *data)
-{
- load_cb = func;
- load_cb_data = data;
-}
-
-void
-purple_plugins_unregister_load_notify_cb(void (*func)(PurplePlugin *, void *))
-{
- load_cb = NULL;
- load_cb_data = NULL;
-}
-
-void
-purple_plugins_register_unload_notify_cb(void (*func)(PurplePlugin *, void *),
- void *data)
-{
- unload_cb = func;
- unload_cb_data = data;
-}
-
-void
-purple_plugins_unregister_unload_notify_cb(void (*func)(PurplePlugin *, void *))
-{
- unload_cb = NULL;
- unload_cb_data = NULL;
-}
-
PurplePlugin *
purple_plugins_find_with_name(const char *name)
{
diff --git a/libpurple/plugin.h b/libpurple/plugin.h
index 9225aecd92..c4ae3b889f 100644
--- a/libpurple/plugin.h
+++ b/libpurple/plugin.h
@@ -239,9 +239,7 @@ struct _PurplePluginAction {
#endif
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Plugin API */
@@ -317,8 +315,6 @@ gboolean purple_plugin_unload(PurplePlugin *plugin);
* startup" by excluding said plugins from the list of plugins to save. The
* UI needs to call purple_plugins_save_loaded() after calling this for it
* to have any effect.
- *
- * @since 2.3.0
*/
void purple_plugin_disable(PurplePlugin *plugin);
@@ -515,8 +511,6 @@ void purple_plugins_add_search_path(const char *path);
* Returns a list of plugin search paths.
*
* @constreturn A list of searched paths.
- *
- * @since 2.6.0
*/
GList *purple_plugins_get_search_paths(void);
@@ -566,72 +560,6 @@ void purple_plugins_probe(const char *ext);
*/
gboolean purple_plugins_enabled(void);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_PLUGIN_C_)
-/**
- * Registers a function that will be called when probing is finished.
- *
- * @param func The callback function.
- * @param data Data to pass to the callback.
- * @deprecated If you need this, ask for a plugin-probe signal to be added.
- */
-void purple_plugins_register_probe_notify_cb(void (*func)(void *), void *data);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_PLUGIN_C_)
-/**
- * Unregisters a function that would be called when probing is finished.
- *
- * @param func The callback function.
- * @deprecated If you need this, ask for a plugin-probe signal to be added.
- */
-void purple_plugins_unregister_probe_notify_cb(void (*func)(void *));
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_PLUGIN_C_)
-/**
- * Registers a function that will be called when a plugin is loaded.
- *
- * @param func The callback function.
- * @param data Data to pass to the callback.
- * @deprecated Use the plugin-load signal instead.
- */
-void purple_plugins_register_load_notify_cb(void (*func)(PurplePlugin *, void *),
- void *data);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_PLUGIN_C_)
-/**
- * Unregisters a function that would be called when a plugin is loaded.
- *
- * @param func The callback function.
- * @deprecated Use the plugin-load signal instead.
- */
-void purple_plugins_unregister_load_notify_cb(void (*func)(PurplePlugin *, void *));
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_PLUGIN_C_)
-/**
- * Registers a function that will be called when a plugin is unloaded.
- *
- * @param func The callback function.
- * @param data Data to pass to the callback.
- * @deprecated Use the plugin-unload signal instead.
- */
-void purple_plugins_register_unload_notify_cb(void (*func)(PurplePlugin *, void *),
- void *data);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_PLUGIN_C_)
-/**
- * Unregisters a function that would be called when a plugin is unloaded.
- *
- * @param func The callback function.
- * @deprecated Use the plugin-unload signal instead.
- */
-void purple_plugins_unregister_unload_notify_cb(void (*func)(PurplePlugin *,
- void *));
-#endif
-
/**
* Finds a plugin with the specified name.
*
@@ -733,8 +661,6 @@ PurplePluginAction *purple_plugin_action_new(const char* label, void (*callback)
*/
void purple_plugin_action_free(PurplePluginAction *action);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_PLUGIN_H_ */
diff --git a/libpurple/pluginpref.h b/libpurple/pluginpref.h
index 6ce04ad9ab..85112321b7 100644
--- a/libpurple/pluginpref.h
+++ b/libpurple/pluginpref.h
@@ -50,9 +50,7 @@ typedef enum {
#include <glib.h>
#include "prefs.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Plugin Preference API */
@@ -262,8 +260,6 @@ PurpleStringFormatType purple_plugin_pref_get_format_type(PurplePluginPref *pref
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_PLUGINPREF_H_ */
diff --git a/libpurple/plugins/autoaccept.c b/libpurple/plugins/autoaccept.c
index 1e5a2d36d7..280cc537cb 100644
--- a/libpurple/plugins/autoaccept.c
+++ b/libpurple/plugins/autoaccept.c
@@ -73,10 +73,10 @@ static void
auto_accept_complete_cb(PurpleXfer *xfer, PurpleXfer *my)
{
if (xfer == my && purple_prefs_get_bool(PREF_NOTIFY) &&
- !purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, xfer->who, xfer->account))
+ !purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_xfer_get_remote_user(xfer), purple_xfer_get_account(xfer)))
{
char *message = g_strdup_printf(_("Autoaccepted file transfer of \"%s\" from \"%s\" completed."),
- xfer->filename, xfer->who);
+ purple_xfer_get_filename(xfer), purple_xfer_get_remote_user(xfer));
purple_notify_info(NULL, _("Autoaccept complete"), message, NULL);
g_free(message);
}
@@ -93,8 +93,8 @@ file_recv_request_cb(PurpleXfer *xfer, gpointer handle)
int accept_setting;
- account = xfer->account;
- node = PURPLE_BLIST_NODE(purple_find_buddy(account, xfer->who));
+ account = purple_xfer_get_account(xfer);
+ node = PURPLE_BLIST_NODE(purple_find_buddy(account, purple_xfer_get_remote_user(xfer)));
/* If person is on buddy list, use the buddy setting; otherwise, use the
stranger setting. */
@@ -121,7 +121,7 @@ file_recv_request_cb(PurpleXfer *xfer, gpointer handle)
gchar *ext;
if (purple_prefs_get_bool(PREF_NEWDIR))
- dirname = g_build_filename(pref, purple_normalize(account, xfer->who), NULL);
+ dirname = g_build_filename(pref, purple_normalize(account, purple_xfer_get_remote_user(xfer)), NULL);
else
dirname = g_build_filename(pref, NULL);
@@ -133,9 +133,9 @@ file_recv_request_cb(PurpleXfer *xfer, gpointer handle)
/* Escape filename (if escaping is turned on) */
if (purple_prefs_get_bool(PREF_ESCAPE)) {
- escape = purple_escape_filename(xfer->filename);
+ escape = purple_escape_filename(purple_xfer_get_filename(xfer));
} else {
- escape = xfer->filename;
+ escape = purple_xfer_get_filename(xfer);
}
filename = g_build_filename(dirname, escape, NULL);
@@ -174,7 +174,7 @@ file_recv_request_cb(PurpleXfer *xfer, gpointer handle)
PURPLE_CALLBACK(auto_accept_complete_cb), xfer);
break;
case FT_REJECT:
- xfer->status = PURPLE_XFER_STATUS_CANCEL_LOCAL;
+ purple_xfer_set_status(xfer, PURPLE_XFER_STATUS_CANCEL_LOCAL);
break;
}
}
diff --git a/libpurple/plugins/log_reader.c b/libpurple/plugins/log_reader.c
index 800bc38ae4..3520221656 100644
--- a/libpurple/plugins/log_reader.c
+++ b/libpurple/plugins/log_reader.c
@@ -92,7 +92,7 @@ static GList *adium_logger_list(PurpleLogType type, const char *sn, PurpleAccoun
prpl_name = g_ascii_strup(prpl_info->list_icon(account, NULL), -1);
- temp = g_strdup_printf("%s.%s", prpl_name, account->username);
+ temp = g_strdup_printf("%s.%s", prpl_name, purple_account_get_username(account));
path = g_build_filename(logdir, temp, sn, NULL);
g_free(temp);
@@ -635,7 +635,7 @@ static GList *msn_logger_list(PurpleLogType type, const char *sn, PurpleAccount
g_return_val_if_fail(sn != NULL, NULL);
g_return_val_if_fail(account != NULL, NULL);
- if (strcmp(account->protocol_id, "prpl-msn"))
+ if (strcmp(purple_account_get_protocol_id(account), "prpl-msn"))
return NULL;
logdir = purple_prefs_get_string("/plugins/core/log_reader/msn/log_directory");
@@ -658,7 +658,7 @@ static GList *msn_logger_list(PurpleLogType type, const char *sn, PurpleAccount
return list;
}
} else {
- username = g_strdup(purple_normalize(account, account->username));
+ username = g_strdup(purple_normalize(account, purple_account_get_username(account)));
}
if (buddy) {
@@ -974,7 +974,7 @@ static char * msn_logger_read (PurpleLog *log, PurpleLogReadFlags *flags)
their_name = from_name;
if (from_name && purple_prefs_get_bool("/plugins/core/log_reader/use_name_heuristics")) {
- const char *friendly_name = purple_connection_get_display_name(log->account->gc);
+ const char *friendly_name = purple_connection_get_display_name(purple_account_get_connection(log->account));
if (friendly_name != NULL) {
int friendly_name_length = strlen(friendly_name);
@@ -987,13 +987,10 @@ static char * msn_logger_read (PurpleLog *log, PurpleLogReadFlags *flags)
if (buddy)
their_name = purple_buddy_get_alias(buddy);
- if (log->account->alias)
- {
- alias = log->account->alias;
+ alias = purple_account_get_alias(log->account);
+ if (alias) {
alias_length = strlen(alias);
- }
- else
- {
+ } else {
alias = "";
alias_length = 0;
}
@@ -1115,10 +1112,10 @@ static char * msn_logger_read (PurpleLog *log, PurpleLogReadFlags *flags)
text = g_string_append(text, "<b>");
if (name_guessed == NAME_GUESS_ME) {
- if (log->account->alias)
- text = g_string_append(text, log->account->alias);
+ if (purple_account_get_alias(log->account))
+ text = g_string_append(text, purple_account_get_alias(log->account));
else
- text = g_string_append(text, log->account->username);
+ text = g_string_append(text, purple_account_get_username(log->account));
}
else if (name_guessed == NAME_GUESS_THEM)
text = g_string_append(text, their_name);
@@ -1781,7 +1778,7 @@ static GList *qip_logger_list(PurpleLogType type, const char *sn, PurpleAccount
g_return_val_if_fail(account != NULL, NULL);
/* QIP only supports ICQ. */
- if (strcmp(account->protocol_id, "prpl-icq"))
+ if (strcmp(purple_account_get_protocol_id(account), "prpl-icq"))
return NULL;
logdir = purple_prefs_get_string("/plugins/core/log_reader/qip/log_directory");
@@ -1798,7 +1795,7 @@ static GList *qip_logger_list(PurpleLogType type, const char *sn, PurpleAccount
if (!prpl_info->list_icon)
return NULL;
- username = g_strdup(purple_normalize(account, account->username));
+ username = g_strdup(purple_normalize(account, purple_account_get_username(account)));
filename = g_strdup_printf("%s.txt", purple_normalize(account, sn));
path = g_build_filename(logdir, username, "History", filename, NULL);
g_free(username);
@@ -2206,7 +2203,6 @@ static GList *amsn_logger_parse_file(char *filename, const char *sn, PurpleAccou
log->logger = amsn_logger;
log->logger_data = data;
list = g_list_prepend(list, log);
- found_start = FALSE;
purple_debug_info("aMSN logger",
"Found log for %s:"
@@ -2241,10 +2237,10 @@ static GList *amsn_logger_list(PurpleLogType type, const char *sn, PurpleAccount
return NULL;
/* aMSN only works with MSN/WLM */
- if (strcmp(account->protocol_id, "prpl-msn"))
+ if (strcmp(purple_account_get_protocol_id(account), "prpl-msn"))
return NULL;
- username = g_strdup(purple_normalize(account, account->username));
+ username = g_strdup(purple_normalize(account, purple_account_get_username(account)));
buddy_log = g_strdup_printf("%s.log", purple_normalize(account, sn));
log_path = g_build_filename(logdir, username, "logs", NULL);
diff --git a/libpurple/plugins/offlinemsg.c b/libpurple/plugins/offlinemsg.c
index b58da95a8b..1803f82430 100644
--- a/libpurple/plugins/offlinemsg.c
+++ b/libpurple/plugins/offlinemsg.c
@@ -80,6 +80,7 @@ record_pounce(OfflineMsg *offline)
PurplePounceEvent event;
PurplePounceOption option;
PurpleConversation *conv;
+ char *temp;
event = PURPLE_POUNCE_SIGNON;
option = PURPLE_POUNCE_OPTION_NONE;
@@ -88,7 +89,12 @@ record_pounce(OfflineMsg *offline)
event, option);
purple_pounce_action_set_enabled(pounce, "send-message", TRUE);
- purple_pounce_action_set_attribute(pounce, "send-message", "message", offline->message);
+
+ temp = g_strdup_printf("(%s) %s", _("Offline message"),
+ offline->message);
+ purple_pounce_action_set_attribute(pounce, "send-message", "message",
+ temp);
+ g_free(temp);
conv = offline->conv;
if (!purple_conversation_get_data(conv, "plugin_pack:offlinemsg"))
diff --git a/libpurple/plugins/perl/common/Account.xs b/libpurple/plugins/perl/common/Account.xs
index 4976b84299..2a400d0379 100644
--- a/libpurple/plugins/perl/common/Account.xs
+++ b/libpurple/plugins/perl/common/Account.xs
@@ -199,9 +199,10 @@ purple_account_destroy_log(account)
Purple::Account account
void
-purple_account_add_buddies(account, list)
+purple_account_add_buddies(account, list, message)
Purple::Account account
SV * list
+ const char *message
PREINIT:
GList *t_GL;
int i, t_len;
@@ -212,13 +213,14 @@ PPCODE:
for (i = 0; i <= t_len; i++)
t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(list), i, 0)));
- purple_account_add_buddies(account, t_GL);
+ purple_account_add_buddies(account, t_GL, message);
g_list_free(t_GL);
void
-purple_account_add_buddy(account, buddy)
- Purple::Account account
- Purple::BuddyList::Buddy buddy
+purple_account_add_buddy(account, buddy, message)
+ Purple::Account account
+ Purple::BuddyList::Buddy buddy
+ const char * message
void
purple_account_change_password(account, a, b)
diff --git a/libpurple/plugins/perl/common/BuddyList.xs b/libpurple/plugins/perl/common/BuddyList.xs
index 65f10184f0..d6c1f3b076 100644
--- a/libpurple/plugins/perl/common/BuddyList.xs
+++ b/libpurple/plugins/perl/common/BuddyList.xs
@@ -82,11 +82,6 @@ Purple::BuddyList::Buddy
purple_contact_get_priority_buddy(contact)
Purple::BuddyList::Contact contact
-void
-purple_contact_set_alias(contact, alias)
- Purple::BuddyList::Contact contact
- const char * alias
-
const char *
purple_contact_get_alias(contact)
Purple::BuddyList::Contact contact
@@ -200,10 +195,6 @@ purple_blist_update_buddy_status(buddy, old_status)
Purple::Status old_status
void
-purple_blist_update_buddy_icon(buddy)
- Purple::BuddyList::Buddy buddy
-
-void
purple_blist_rename_buddy(buddy, name)
Purple::BuddyList::Buddy buddy
const char * name
@@ -430,9 +421,5 @@ purple_buddy_get_contact_alias(buddy)
Purple::BuddyList::Buddy buddy
const char *
-purple_buddy_get_local_alias(buddy)
- Purple::BuddyList::Buddy buddy
-
-const char *
purple_buddy_get_alias(buddy)
Purple::BuddyList::Buddy buddy
diff --git a/libpurple/plugins/perl/common/Certificate.xs b/libpurple/plugins/perl/common/Certificate.xs
index 02888722ec..3209d81af5 100644
--- a/libpurple/plugins/perl/common/Certificate.xs
+++ b/libpurple/plugins/perl/common/Certificate.xs
@@ -68,10 +68,6 @@ void
purple_certificate_destroy(crt)
Purple::Certificate crt
-void
-purple_certificate_display_x509(crt)
- Purple::Certificate crt
-
## changed order of arguments, so that $cert->export($file) could be used
gboolean
purple_certificate_export(crt, filename)
@@ -202,7 +198,7 @@ purple_certificate_check_signature_chain(...)
l = g_list_prepend(l, purple_perl_ref_object(ST(i)));
}
l = g_list_reverse(l);
- ret = purple_certificate_check_signature_chain(l);
+ ret = purple_certificate_check_signature_chain(l, NULL);
g_list_free(l);
if(ret) XSRETURN_YES;
XSRETURN_NO;
diff --git a/libpurple/plugins/perl/common/Connection.xs b/libpurple/plugins/perl/common/Connection.xs
index 74bd3ba8bd..dc0c2660e1 100644
--- a/libpurple/plugins/perl/common/Connection.xs
+++ b/libpurple/plugins/perl/common/Connection.xs
@@ -36,15 +36,6 @@ purple_connection_notice(gc, text)
const char *text
void
-purple_connection_error(gc, reason)
- Purple::Connection gc
- const char *reason
-
-void
-purple_connection_destroy(gc)
- Purple::Connection gc
-
-void
purple_connection_set_state(gc, state)
Purple::Connection gc
Purple::ConnectionState state
diff --git a/libpurple/plugins/perl/common/Conversation.xs b/libpurple/plugins/perl/common/Conversation.xs
index 3239b57d99..3263aafc4c 100644
--- a/libpurple/plugins/perl/common/Conversation.xs
+++ b/libpurple/plugins/perl/common/Conversation.xs
@@ -146,7 +146,7 @@ purple_conversation_get_account(conv)
Purple::Conversation conv
Purple::Connection
-purple_conversation_get_gc(conv)
+purple_conversation_get_connection(conv)
Purple::Conversation conv
void
@@ -338,24 +338,6 @@ purple_conv_chat_get_conversation(chat)
Purple::Conversation::Chat chat
void
-purple_conv_chat_set_users(chat, users)
- Purple::Conversation::Chat chat
- SV * users
-PREINIT:
- GList *l, *t_GL;
- int i, t_len;
-PPCODE:
- t_GL = NULL;
- t_len = av_len((AV *)SvRV(users));
-
- for (i = 0; i <= t_len; i++)
- t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(users), i, 0)));
-
- for (l = purple_conv_chat_set_users(chat, t_GL); l != NULL; l = l->next) {
- XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::ListEntry")));
- }
-
-void
purple_conv_chat_get_users(chat)
Purple::Conversation::Chat chat
PREINIT:
diff --git a/libpurple/plugins/perl/common/FT.xs b/libpurple/plugins/perl/common/FT.xs
index 58d1985a72..eca4cfa04e 100644
--- a/libpurple/plugins/perl/common/FT.xs
+++ b/libpurple/plugins/perl/common/FT.xs
@@ -113,7 +113,7 @@ purple_xfer_get_type(xfer)
Purple::Xfer xfer
gboolean
-purple_xfer_is_canceled(xfer)
+purple_xfer_is_cancelled(xfer)
Purple::Xfer xfer
gboolean
diff --git a/libpurple/plugins/perl/common/Network.xs b/libpurple/plugins/perl/common/Network.xs
index 7b3ae1c91d..1388b3abed 100644
--- a/libpurple/plugins/perl/common/Network.xs
+++ b/libpurple/plugins/perl/common/Network.xs
@@ -23,17 +23,21 @@ purple_network_ip_atoi(ip)
const char *ip
Purple::NetworkListenData
-purple_network_listen(port, socket_type, cb, cb_data)
+purple_network_listen(port, socket_family, socket_type, map_external, cb, cb_data)
unsigned short port
+ int socket_family
int socket_type
+ gboolean map_external
Purple::NetworkListenCallback cb
gpointer cb_data
Purple::NetworkListenData
-purple_network_listen_range(start, end, socket_type, cb, cb_data)
+purple_network_listen_range(start, end, socket_family, socket_type, map_external, cb, cb_data)
unsigned short start
unsigned short end
+ int socket_family
int socket_type
+ gboolean map_external
Purple::NetworkListenCallback cb
gpointer cb_data
diff --git a/libpurple/plugins/perl/common/Notify.xs b/libpurple/plugins/perl/common/Notify.xs
index 87bb928f9c..1ec708e9dc 100644
--- a/libpurple/plugins/perl/common/Notify.xs
+++ b/libpurple/plugins/perl/common/Notify.xs
@@ -135,7 +135,7 @@ purple_notify_user_info_get_entries(user_info)
PREINIT:
GList *l;
PPCODE:
- l = purple_notify_user_info_get_entries(user_info);
+ l = purple_notify_user_info_get_entries(user_info)->head;
for (; l != NULL; l = l->next) {
XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::NotifyUserInfoEntry")));
}
@@ -145,12 +145,12 @@ purple_notify_user_info_get_text_with_newline(user_info, newline)
Purple::NotifyUserInfo user_info
const char *newline
-void purple_notify_user_info_add_pair(user_info, label, value)
+void purple_notify_user_info_add_pair_html(user_info, label, value)
Purple::NotifyUserInfo user_info
const char *label
const char *value
-void purple_notify_user_info_prepend_pair(user_info, label, value)
+void purple_notify_user_info_prepend_pair_html(user_info, label, value)
Purple::NotifyUserInfo user_info
const char *label
const char *value
diff --git a/libpurple/plugins/perl/common/Request.xs b/libpurple/plugins/perl/common/Request.xs
index 499a6756a8..244f1b2db5 100644
--- a/libpurple/plugins/perl/common/Request.xs
+++ b/libpurple/plugins/perl/common/Request.xs
@@ -374,12 +374,6 @@ purple_request_field_list_new(class, id, text)
C_ARGS: id, text
void
-purple_request_field_list_add(field, item, data)
- Purple::Request::Field field
- const char *item
- void * data
-
-void
purple_request_field_list_add_icon(field, item, icon_path, data)
Purple::Request::Field field
const char *item
diff --git a/libpurple/plugins/perl/common/SSLConn.xs b/libpurple/plugins/perl/common/SSLConn.xs
index dbc337ca37..3730e80683 100644
--- a/libpurple/plugins/perl/common/SSLConn.xs
+++ b/libpurple/plugins/perl/common/SSLConn.xs
@@ -16,13 +16,6 @@ purple_ssl_input_add(gsc, func, data)
Purple::Ssl::Connection gsc
Purple::SslInputFunction func
-Purple::Ssl::Connection
-purple_ssl_connect_fd(account, fd, func, error_func, data)
- Purple::Account account
- int fd
- PurpleSslInputFunction func
- PurpleSslErrorFunction error_func
-
*/
MODULE = Purple::SSL PACKAGE = Purple::SSL PREFIX = purple_ssl_
diff --git a/libpurple/plugins/perl/common/Status.xs b/libpurple/plugins/perl/common/Status.xs
index 7c8d615680..8965870ade 100644
--- a/libpurple/plugins/perl/common/Status.xs
+++ b/libpurple/plugins/perl/common/Status.xs
@@ -74,28 +74,6 @@ BOOT:
newCONSTSUB(primitive_stash, (char *)civ->name, newSViv(civ->iv));
}
-void
-purple_presence_add_list(presence, source_list)
- Purple::Presence presence
- SV *source_list
-PREINIT:
- GList *t_GL;
- int i, t_len;
-PPCODE:
- t_GL = NULL;
- t_len = av_len((AV *)SvRV(source_list));
-
- for (i = 0; i <= t_len; i++) {
- t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(source_list), i, 0)));
- }
- purple_presence_add_list(presence, t_GL);
- g_list_free(t_GL);
-
-void
-purple_presence_add_status(presence, status)
- Purple::Presence presence
- Purple::Status status
-
gint
purple_presence_compare(presence1, presence2)
Purple::Presence presence1
@@ -329,29 +307,10 @@ purple_status_set_active(status, active)
Purple::Status status
gboolean active
-void
-purple_status_set_attr_boolean(status, id, value)
- Purple::Status status
- const char *id
- gboolean value
-
-void
-purple_status_set_attr_string(status, id, value)
- Purple::Status status
- const char *id
- const char *value
-
MODULE = Purple::Status PACKAGE = Purple::StatusType PREFIX = purple_status_type_
PROTOTYPES: ENABLE
void
-purple_status_type_add_attr(status_type, id, name, value)
- Purple::StatusType status_type
- const char *id
- const char *name
- Purple::Value value
-
-void
purple_status_type_destroy(status_type)
Purple::StatusType status_type
@@ -397,10 +356,6 @@ const char *
purple_status_type_get_name(status_type)
Purple::StatusType status_type
-const char *
-purple_status_type_get_primary_attr(status_type)
- Purple::StatusType status_type
-
Purple::StatusPrimitive
purple_status_type_get_primitive(status_type)
Purple::StatusType status_type
@@ -440,8 +395,3 @@ purple_status_type_new_full(primitive, id, name, saveable, user_settable, indepe
gboolean saveable
gboolean user_settable
gboolean independent
-
-void
-purple_status_type_set_primary_attr(status_type, attr_id)
- Purple::StatusType status_type
- const char *attr_id
diff --git a/libpurple/plugins/perl/common/Util.xs b/libpurple/plugins/perl/common/Util.xs
index b339cc75af..7426c9b458 100644
--- a/libpurple/plugins/perl/common/Util.xs
+++ b/libpurple/plugins/perl/common/Util.xs
@@ -202,6 +202,14 @@ gboolean
purple_ip_address_is_valid(ip)
const char* ip
+gboolean
+purple_ipv4_address_is_valid(ip)
+ const char* ip
+
+gboolean
+purple_ipv6_address_is_valid(ip)
+ const char* ip
+
const char*
purple_normalize_nocase(account, str)
Purple::Account account
@@ -454,12 +462,13 @@ PROTOTYPES: ENABLE
#XXX: expand...
void
-purple_util_fetch_url(plugin, url, full, user_agent, http11, cb)
+purple_util_fetch_url(plugin, url, full, user_agent, http11, max_len, cb)
Purple::Plugin plugin
const char *url
gboolean full
const char *user_agent
gboolean http11
+ gssize max_len
SV * cb
PREINIT:
PurpleUtilFetchUrlData *data;
@@ -468,7 +477,7 @@ PPCODE:
SV *sv = purple_perl_sv_from_fun(plugin, cb);
if (sv != NULL) {
- data = purple_util_fetch_url(url, full, user_agent, http11,
+ data = purple_util_fetch_url(url, full, user_agent, http11, max_len,
purple_perl_util_url_cb, sv);
XPUSHs(sv_2mortal(purple_perl_bless_object(data, "Purple::Util::FetchUrlData")));
} else {
diff --git a/libpurple/plugins/ssl/Makefile.am b/libpurple/plugins/ssl/Makefile.am
index f95ef88f58..d874abd4ef 100644
--- a/libpurple/plugins/ssl/Makefile.am
+++ b/libpurple/plugins/ssl/Makefile.am
@@ -9,30 +9,15 @@ ssl_nss_la_LDFLAGS = -module -avoid-version
if PLUGINS
-# I'm sorry to report that Automake Conditionals don't support
-# if USE_GNUTLS && USE_NSS
-# but only support testing a single variable. Hence:
-
-if USE_GNUTLS
-if USE_NSS
plugin_LTLIBRARIES = \
- ssl.la \
- ssl-gnutls.la \
- ssl-nss.la
-else
-plugin_LTLIBRARIES = \
- ssl.la \
+ ssl.la
+if USE_GNUTLS
+plugin_LTLIBRARIES += \
ssl-gnutls.la
endif
-else
if USE_NSS
-plugin_LTLIBRARIES = \
- ssl.la \
+plugin_LTLIBRARIES += \
ssl-nss.la
-else
-plugin_LTLIBRARIES = \
- ssl.la
-endif
endif
ssl_la_SOURCES = ssl.c
@@ -56,3 +41,4 @@ AM_CPPFLAGS = \
ssl_gnutls_la_CFLAGS = $(AM_CPPFLAGS) $(GNUTLS_CFLAGS)
ssl_nss_la_CFLAGS = $(AM_CPPFLAGS) $(NSS_CFLAGS)
+
diff --git a/libpurple/plugins/ssl/ssl-gnutls.c b/libpurple/plugins/ssl/ssl-gnutls.c
index 00b691ba81..19393fa2f6 100644
--- a/libpurple/plugins/ssl/ssl-gnutls.c
+++ b/libpurple/plugins/ssl/ssl-gnutls.c
@@ -1142,6 +1142,86 @@ x509_times (PurpleCertificate *crt, time_t *activation, time_t *expiration)
return success;
}
+static GByteArray *
+x509_get_der_data(PurpleCertificate *crt)
+{
+ gnutls_x509_crt crt_dat;
+ GByteArray *data;
+ size_t len;
+ int ret;
+
+ crt_dat = X509_GET_GNUTLS_DATA(crt);
+ g_return_val_if_fail(crt_dat, NULL);
+
+ /* Obtain the output size required */
+ len = 0;
+ ret = gnutls_x509_crt_export(crt_dat, GNUTLS_X509_FMT_DER, NULL, &len);
+ g_return_val_if_fail(ret == GNUTLS_E_SHORT_MEMORY_BUFFER, NULL);
+
+ /* Now allocate a buffer and *really* export it */
+ data = g_byte_array_sized_new(len);
+ data->len = len;
+ ret = gnutls_x509_crt_export(crt_dat, GNUTLS_X509_FMT_DER, data->data, &len);
+ if (ret != 0) {
+ purple_debug_error("gnutls/x509",
+ "Failed to export cert to buffer with code %d\n",
+ ret);
+ g_byte_array_free(data, TRUE);
+ return NULL;
+ }
+
+ return data;
+}
+
+static gchar *
+x509_display_string(PurpleCertificate *crt)
+{
+ gchar *sha_asc;
+ GByteArray *sha_bin;
+ gchar *cn;
+ time_t activation, expiration;
+ gchar *activ_str, *expir_str;
+ gchar *text;
+
+ /* Pull out the SHA1 checksum */
+ sha_bin = x509_sha1sum(crt);
+ sha_asc = purple_base16_encode_chunked(sha_bin->data, sha_bin->len);
+
+ /* Get the cert Common Name */
+ /* TODO: Will break on CA certs */
+ cn = x509_common_name(crt);
+
+ /* Get the certificate times */
+ /* TODO: Check the times against localtime */
+ /* TODO: errorcheck? */
+ if (!x509_times(crt, &activation, &expiration)) {
+ purple_debug_error("certificate",
+ "Failed to get certificate times!\n");
+ activation = expiration = 0;
+ }
+ activ_str = g_strdup(ctime(&activation));
+ expir_str = g_strdup(ctime(&expiration));
+
+ /* Make messages */
+ text = g_strdup_printf(_("Common name: %s\n\n"
+ "Fingerprint (SHA1): %s\n\n"
+ "Activation date: %s\n"
+ "Expiration date: %s\n"),
+ cn ? cn : "(null)",
+ sha_asc ? sha_asc : "(null)",
+ activ_str ? activ_str : "(null)",
+ expir_str ? expir_str : "(null)");
+
+ /* Cleanup */
+ g_free(cn);
+ g_free(sha_asc);
+ g_free(activ_str);
+ g_free(expir_str);
+ g_byte_array_free(sha_bin, TRUE);
+
+ return text;
+}
+
/* X.509 certificate operations provided by this plugin */
static PurpleCertificateScheme x509_gnutls = {
"x509", /* Scheme name */
@@ -1158,9 +1238,9 @@ static PurpleCertificateScheme x509_gnutls = {
x509_check_name, /* Check subject name */
x509_times, /* Activation/Expiration time */
x509_importcerts_from_file, /* Multiple certificates import function */
+ x509_get_der_data, /* Binary DER data */
+ x509_display_string, /* Display representation */
- NULL,
- NULL,
NULL
};
diff --git a/libpurple/plugins/ssl/ssl-nss.c b/libpurple/plugins/ssl/ssl-nss.c
index 6ed90db538..6dc6f00071 100644
--- a/libpurple/plugins/ssl/ssl-nss.c
+++ b/libpurple/plugins/ssl/ssl-nss.c
@@ -930,6 +930,78 @@ x509_times (PurpleCertificate *crt, time_t *activation, time_t *expiration)
return TRUE;
}
+static GByteArray *
+x509_get_der_data(PurpleCertificate *crt)
+{
+ CERTCertificate *crt_dat;
+ SECItem *dercrt;
+ GByteArray *data;
+
+ crt_dat = X509_NSS_DATA(crt);
+ g_return_val_if_fail(crt_dat, NULL);
+
+ dercrt = SEC_ASN1EncodeItem(NULL, NULL, crt_dat,
+ SEC_ASN1_GET(SEC_SignedCertificateTemplate));
+ g_return_val_if_fail(dercrt != NULL, FALSE);
+
+ data = g_byte_array_sized_new(dercrt->len);
+ memcpy(data->data, dercrt->data, dercrt->len);
+ data->len = dercrt->len;
+
+ SECITEM_FreeItem(dercrt, PR_TRUE);
+
+ return data;
+}
+
+static gchar *
+x509_display_string(PurpleCertificate *crt)
+{
+ gchar *sha_asc;
+ GByteArray *sha_bin;
+ gchar *cn;
+ time_t activation, expiration;
+ gchar *activ_str, *expir_str;
+ gchar *text;
+
+ /* Pull out the SHA1 checksum */
+ sha_bin = x509_sha1sum(crt);
+ sha_asc = purple_base16_encode_chunked(sha_bin->data, sha_bin->len);
+
+ /* Get the cert Common Name */
+ /* TODO: Will break on CA certs */
+ cn = x509_common_name(crt);
+
+ /* Get the certificate times */
+ /* TODO: Check the times against localtime */
+ /* TODO: errorcheck? */
+ if (!x509_times(crt, &activation, &expiration)) {
+ purple_debug_error("certificate",
+ "Failed to get certificate times!\n");
+ activation = expiration = 0;
+ }
+ activ_str = g_strdup(ctime(&activation));
+ expir_str = g_strdup(ctime(&expiration));
+
+ /* Make messages */
+ text = g_strdup_printf(_("Common name: %s\n\n"
+ "Fingerprint (SHA1): %s\n\n"
+ "Activation date: %s\n"
+ "Expiration date: %s\n"),
+ cn ? cn : "(null)",
+ sha_asc ? sha_asc : "(null)",
+ activ_str ? activ_str : "(null)",
+ expir_str ? expir_str : "(null)");
+
+ /* Cleanup */
+ g_free(cn);
+ g_free(sha_asc);
+ g_free(activ_str);
+ g_free(expir_str);
+ g_byte_array_free(sha_bin, TRUE);
+
+ return text;
+}
+
static PurpleCertificateScheme x509_nss = {
"x509", /* Scheme name */
N_("X.509 Certificates"), /* User-visible scheme name */
@@ -945,9 +1017,9 @@ static PurpleCertificateScheme x509_nss = {
x509_check_name, /* Check subject name */
x509_times, /* Activation/Expiration time */
x509_importcerts_from_file, /* Multiple certificate import function */
+ x509_get_der_data, /* Binary DER data */
+ x509_display_string, /* Display representation */
- NULL,
- NULL,
NULL
};
diff --git a/libpurple/plugins/statenotify.c b/libpurple/plugins/statenotify.c
index bfbe595e50..ca74854e90 100644
--- a/libpurple/plugins/statenotify.c
+++ b/libpurple/plugins/statenotify.c
@@ -30,7 +30,7 @@ write_status(PurpleBuddy *buddy, const char *message)
if (conv == NULL)
return;
- g_return_if_fail(conv->type == PURPLE_CONV_TYPE_IM);
+ g_return_if_fail(purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM);
/* Prevent duplicate notifications for buddies in multiple groups */
if (buddy != purple_find_buddy(account, buddy_name))
@@ -42,7 +42,7 @@ write_status(PurpleBuddy *buddy, const char *message)
g_snprintf(buf, sizeof(buf), message, escaped);
g_free(escaped);
- purple_conv_im_write(conv->u.im, NULL, buf, PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_ACTIVE_ONLY | PURPLE_MESSAGE_NO_LINKIFY, time(NULL));
+ purple_conv_im_write(PURPLE_CONV_IM(conv), NULL, buf, PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_ACTIVE_ONLY | PURPLE_MESSAGE_NO_LINKIFY, time(NULL));
}
static void
diff --git a/libpurple/plugins/tcl/tcl_cmds.c b/libpurple/plugins/tcl/tcl_cmds.c
index c7a0b3fe0e..440e9c53cc 100644
--- a/libpurple/plugins/tcl/tcl_cmds.c
+++ b/libpurple/plugins/tcl/tcl_cmds.c
@@ -1640,13 +1640,13 @@ int tcl_cmd_status_attr(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj
int tcl_cmd_status_type(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
const char *cmds[] = { "attr", "attrs", "available", "exclusive", "id",
- "independent", "name", "primary_attr",
+ "independent", "name",
"primitive", "saveable", "user_settable",
NULL };
enum { CMD_STATUS_TYPE_ATTR, CMD_STATUS_TYPE_ATTRS,
CMD_STATUS_TYPE_AVAILABLE, CMD_STATUS_TYPE_EXCLUSIVE,
CMD_STATUS_TYPE_ID, CMD_STATUS_TYPE_INDEPENDENT,
- CMD_STATUS_TYPE_NAME, CMD_STATUS_TYPE_PRIMARY_ATTR,
+ CMD_STATUS_TYPE_NAME,
CMD_STATUS_TYPE_PRIMITIVE, CMD_STATUS_TYPE_SAVEABLE,
CMD_STATUS_TYPE_USER_SETTABLE } cmd;
PurpleStatusType *status_type;
@@ -1751,18 +1751,6 @@ int tcl_cmd_status_type(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj
Tcl_NewStringObj(purple_primitive_get_id_from_type
(purple_status_type_get_primitive(status_type)), -1));
break;
- case CMD_STATUS_TYPE_PRIMARY_ATTR:
-#if !(defined PURPLE_DISABLE_DEPRECATED)
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "statustype");
- return TCL_ERROR;
- }
- if ((status_type = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusType)) == NULL)
- return TCL_ERROR;
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj(purple_status_type_get_primary_attr(status_type), -1));
-#endif
- break;
case CMD_STATUS_TYPE_SAVEABLE:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "statustype");
diff --git a/libpurple/pounce.c b/libpurple/pounce.c
index 460c801040..4130f0087f 100644
--- a/libpurple/pounce.c
+++ b/libpurple/pounce.c
@@ -32,6 +32,31 @@
#include "pounce.h"
#include "util.h"
+/**
+ * A buddy pounce structure.
+ *
+ * Buddy pounces are actions triggered by a buddy-related event. For
+ * example, a sound can be played or an IM window opened when a buddy
+ * signs on or returns from away. Such responses are handled in the
+ * UI. The events themselves are done in the core.
+ */
+struct _PurplePounce
+{
+ char *ui_type; /**< The type of UI. */
+
+ PurplePounceEvent events; /**< The event(s) to pounce on. */
+ PurplePounceOption options; /**< The pounce options */
+ PurpleAccount *pouncer; /**< The user who is pouncing. */
+
+ char *pouncee; /**< The buddy to pounce on. */
+
+ GHashTable *actions; /**< The registered actions. */
+
+ gboolean save; /**< Whether or not the pounce should
+ be saved after activation. */
+ void *data; /**< Pounce-specific data. */
+};
+
typedef struct
{
GString *buffer;
@@ -180,7 +205,7 @@ pounce_to_xmlnode(PurplePounce *pounce)
xmlnode_set_attrib(node, "ui", pounce->ui_type);
child = xmlnode_new_child(node, "account");
- xmlnode_set_attrib(child, "protocol", pouncer->protocol_id);
+ xmlnode_set_attrib(child, "protocol", purple_account_get_protocol_id(pouncer));
xmlnode_insert_data(child,
purple_normalize(pouncer, purple_account_get_username(pouncer)), -1);
@@ -405,12 +430,8 @@ end_element_handler(GMarkupParseContext *context, const gchar *element_name,
}
if (purple_strequal(element_name, "account")) {
- char *tmp;
g_free(data->account_name);
data->account_name = g_strdup(buffer);
- tmp = data->protocol_id;
- data->protocol_id = g_strdup(_purple_oscar_convert(buffer, tmp));
- g_free(tmp);
}
else if (purple_strequal(element_name, "pouncee")) {
g_free(data->pouncee);
diff --git a/libpurple/pounce.h b/libpurple/pounce.h
index 434fe318bb..68a607876f 100644
--- a/libpurple/pounce.h
+++ b/libpurple/pounce.h
@@ -59,34 +59,7 @@ typedef enum
/** A pounce callback. */
typedef void (*PurplePounceCb)(PurplePounce *, PurplePounceEvent, void *);
-/**
- * A buddy pounce structure.
- *
- * Buddy pounces are actions triggered by a buddy-related event. For
- * example, a sound can be played or an IM window opened when a buddy
- * signs on or returns from away. Such responses are handled in the
- * UI. The events themselves are done in the core.
- */
-struct _PurplePounce
-{
- char *ui_type; /**< The type of UI. */
-
- PurplePounceEvent events; /**< The event(s) to pounce on. */
- PurplePounceOption options; /**< The pounce options */
- PurpleAccount *pouncer; /**< The user who is pouncing. */
-
- char *pouncee; /**< The buddy to pounce on. */
-
- GHashTable *actions; /**< The registered actions. */
-
- gboolean save; /**< Whether or not the pounce should
- be saved after activation. */
- void *data; /**< Pounce-specific data. */
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Buddy Pounce API */
@@ -126,8 +99,6 @@ void purple_pounce_destroy_all_by_account(PurpleAccount *account);
* Destroys all buddy pounces for a buddy
*
* @param buddy The buddy whose pounces are to be removed
- *
- * @since 2.8.0
*/
void purple_pounce_destroy_all_by_buddy(PurpleBuddy *buddy);
@@ -359,7 +330,6 @@ GList *purple_pounces_get_all(void);
*
* @return The list of buddy pounces. The list should be freed by
* the caller when it's no longer used.
- * @since 2.1.0
*/
GList *purple_pounces_get_all_for_ui(const char *ui);
@@ -382,8 +352,6 @@ void purple_pounces_uninit(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_POUNCE_H_ */
diff --git a/libpurple/prefs.c b/libpurple/prefs.c
index a24b4c4b62..b6d0e8b053 100644
--- a/libpurple/prefs.c
+++ b/libpurple/prefs.c
@@ -1357,6 +1357,7 @@ purple_prefs_update_old()
purple_prefs_remove("/purple/conversations/chat/show_leave");
purple_prefs_remove("/purple/conversations/combine_chat_im");
purple_prefs_remove("/purple/conversations/use_alias_for_title");
+ purple_prefs_remove("/purple/debug/timestamps");
purple_prefs_remove("/purple/logging/log_signon_signoff");
purple_prefs_remove("/purple/logging/log_idle_state");
purple_prefs_remove("/purple/logging/log_away_state");
diff --git a/libpurple/prefs.h b/libpurple/prefs.h
index 2d02f3f2e7..ad8cdd5fc1 100644
--- a/libpurple/prefs.h
+++ b/libpurple/prefs.h
@@ -32,7 +32,7 @@
/**
* Preference data types.
*/
-typedef enum _PurplePrefType
+typedef enum
{
PURPLE_PREF_NONE, /**< No type. */
PURPLE_PREF_BOOLEAN, /**< Boolean. */
@@ -62,9 +62,7 @@ typedef enum _PurplePrefType
typedef void (*PurplePrefCallback) (const char *name, PurplePrefType type,
gconstpointer val, gpointer data);
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Prefs API
@@ -317,8 +315,6 @@ GList *purple_prefs_get_path_list(const char *name);
* @return A list of newly allocated strings denoting the names of the children.
* Returns @c NULL if there are no children or if pref doesn't exist.
* The caller must free all the strings and the list.
- *
- * @since 2.1.0
*/
GList *purple_prefs_get_children_names(const char *name);
@@ -364,8 +360,6 @@ void purple_prefs_update_old(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_PREFS_H_ */
diff --git a/libpurple/privacy.c b/libpurple/privacy.c
index 00dd7e4493..9f9d28838f 100644
--- a/libpurple/privacy.c
+++ b/libpurple/privacy.c
@@ -264,9 +264,9 @@ purple_privacy_allow(PurpleAccount *account, const char *who, gboolean local,
gboolean restore)
{
GSList *list;
- PurplePrivacyType type = account->perm_deny;
+ PurplePrivacyType type = purple_account_get_privacy_type(account);
- switch (account->perm_deny) {
+ switch (type) {
case PURPLE_PRIVACY_ALLOW_ALL:
return;
case PURPLE_PRIVACY_ALLOW_USERS:
@@ -287,13 +287,13 @@ purple_privacy_allow(PurpleAccount *account, const char *who, gboolean local,
}
}
purple_privacy_permit_add(account, who, local);
- account->perm_deny = PURPLE_PRIVACY_ALLOW_USERS;
+ purple_account_set_privacy_type(account, PURPLE_PRIVACY_ALLOW_USERS);
break;
case PURPLE_PRIVACY_ALLOW_BUDDYLIST:
if (!purple_find_buddy(account, who)) {
add_all_buddies_to_permit_list(account, local);
purple_privacy_permit_add(account, who, local);
- account->perm_deny = PURPLE_PRIVACY_ALLOW_USERS;
+ purple_account_set_privacy_type(account, PURPLE_PRIVACY_ALLOW_USERS);
}
break;
default:
@@ -301,7 +301,7 @@ purple_privacy_allow(PurpleAccount *account, const char *who, gboolean local,
}
/* Notify the server if the privacy setting was changed */
- if (type != account->perm_deny && purple_account_is_connected(account))
+ if (type != purple_account_get_privacy_type(account) && purple_account_is_connected(account))
serv_set_permit_deny(purple_account_get_connection(account));
}
@@ -316,9 +316,9 @@ purple_privacy_deny(PurpleAccount *account, const char *who, gboolean local,
gboolean restore)
{
GSList *list;
- PurplePrivacyType type = account->perm_deny;
+ PurplePrivacyType type = purple_account_get_privacy_type(account);
- switch (account->perm_deny) {
+ switch (type) {
case PURPLE_PRIVACY_ALLOW_ALL:
if (!restore) {
/* Empty the deny-list. */
@@ -331,7 +331,7 @@ purple_privacy_deny(PurpleAccount *account, const char *who, gboolean local,
}
}
purple_privacy_deny_add(account, who, local);
- account->perm_deny = PURPLE_PRIVACY_DENY_USERS;
+ purple_account_set_privacy_type(account, PURPLE_PRIVACY_DENY_USERS);
break;
case PURPLE_PRIVACY_ALLOW_USERS:
purple_privacy_permit_remove(account, who, local);
@@ -345,7 +345,7 @@ purple_privacy_deny(PurpleAccount *account, const char *who, gboolean local,
if (purple_find_buddy(account, who)) {
add_all_buddies_to_permit_list(account, local);
purple_privacy_permit_remove(account, who, local);
- account->perm_deny = PURPLE_PRIVACY_ALLOW_USERS;
+ purple_account_set_privacy_type(account, PURPLE_PRIVACY_ALLOW_USERS);
}
break;
default:
@@ -353,7 +353,7 @@ purple_privacy_deny(PurpleAccount *account, const char *who, gboolean local,
}
/* Notify the server if the privacy setting was changed */
- if (type != account->perm_deny && purple_account_is_connected(account))
+ if (type != purple_account_get_privacy_type(account) && purple_account_is_connected(account))
serv_set_permit_deny(purple_account_get_connection(account));
}
@@ -362,7 +362,7 @@ purple_privacy_check(PurpleAccount *account, const char *who)
{
GSList *list;
- switch (account->perm_deny) {
+ switch (purple_account_get_privacy_type(account)) {
case PURPLE_PRIVACY_ALLOW_ALL:
return TRUE;
diff --git a/libpurple/privacy.h b/libpurple/privacy.h
index 0250541128..19ef9d6494 100644
--- a/libpurple/privacy.h
+++ b/libpurple/privacy.h
@@ -29,7 +29,7 @@
/**
* Privacy data types.
*/
-typedef enum _PurplePrivacyType
+typedef enum
{
PURPLE_PRIVACY_ALLOW_ALL = 1,
PURPLE_PRIVACY_DENY_ALL,
@@ -40,10 +40,6 @@ typedef enum _PurplePrivacyType
#include "account.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/**
* Privacy core/UI operations.
*/
@@ -60,6 +56,8 @@ typedef struct
void (*_purple_reserved4)(void);
} PurplePrivacyUiOps;
+G_BEGIN_DECLS
+
/**
* Adds a user to the account's permit list.
*
@@ -187,8 +185,6 @@ PurplePrivacyUiOps *purple_privacy_get_ui_ops(void);
*/
void purple_privacy_init(void);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_PRIVACY_H_ */
diff --git a/libpurple/protocols/Makefile.am b/libpurple/protocols/Makefile.am
index 7fea4bd5fc..c4a74361da 100644
--- a/libpurple/protocols/Makefile.am
+++ b/libpurple/protocols/Makefile.am
@@ -1,5 +1,5 @@
EXTRA_DIST = Makefile.mingw
-DIST_SUBDIRS = bonjour gg irc jabber msn myspace mxit novell null oscar sametime silc silc10 simple yahoo zephyr
+DIST_SUBDIRS = bonjour gg irc jabber msn mxit myspace novell null oscar sametime silc simple yahoo zephyr
SUBDIRS = $(DYNAMIC_PRPLS) $(STATIC_PRPLS)
diff --git a/libpurple/protocols/bonjour/bonjour.c b/libpurple/protocols/bonjour/bonjour.c
index ac527c07e9..c9b9a8ee6a 100644
--- a/libpurple/protocols/bonjour/bonjour.c
+++ b/libpurple/protocols/bonjour/bonjour.c
@@ -51,7 +51,7 @@ const char *
bonjour_get_jid(PurpleAccount *account)
{
PurpleConnection *conn = purple_account_get_connection(account);
- BonjourData *bd = conn->proto_data;
+ BonjourData *bd = purple_connection_get_protocol_data(conn);
return bd->jid;
}
@@ -94,7 +94,7 @@ bonjour_login(PurpleAccount *account)
#ifdef _WIN32
if (!dns_sd_available()) {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("Unable to find Apple's \"Bonjour for Windows\" toolkit, see "
"http://d.pidgin.im/BonjourWindows for more information."));
@@ -102,8 +102,9 @@ bonjour_login(PurpleAccount *account)
}
#endif /* _WIN32 */
- gc->flags |= PURPLE_CONNECTION_HTML;
- gc->proto_data = bd = g_new0(BonjourData, 1);
+ purple_connection_set_flags(gc, PURPLE_CONNECTION_HTML);
+ bd = g_new0(BonjourData, 1);
+ purple_connection_set_protocol_data(gc, bd);
/* Start waiting for jabber connections (iChat style) */
bd->jabber_data = g_new0(BonjourJabber, 1);
@@ -114,7 +115,7 @@ bonjour_login(PurpleAccount *account)
if (bonjour_jabber_start(bd->jabber_data) == -1) {
/* Send a message about the connection error */
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to listen for incoming IM connections"));
return;
@@ -141,7 +142,7 @@ bonjour_login(PurpleAccount *account)
bd->dns_sd_data->account = account;
if (!bonjour_dns_sd_start(bd->dns_sd_data))
{
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to establish connection with the local mDNS server. Is it running?"));
return;
@@ -157,7 +158,7 @@ static void
bonjour_close(PurpleConnection *connection)
{
PurpleGroup *bonjour_group;
- BonjourData *bd = connection->proto_data;
+ BonjourData *bd = purple_connection_get_protocol_data(connection);
bonjour_group = purple_find_group(BONJOUR_GROUP_NAME);
@@ -192,7 +193,7 @@ bonjour_close(PurpleConnection *connection)
if (bd != NULL)
g_free(bd->jid);
g_free(bd);
- connection->proto_data = NULL;
+ purple_connection_set_protocol_data(connection, NULL);
}
static const char *
@@ -204,10 +205,12 @@ bonjour_list_icon(PurpleAccount *account, PurpleBuddy *buddy)
static int
bonjour_send_im(PurpleConnection *connection, const char *to, const char *msg, PurpleMessageFlags flags)
{
+ BonjourData *bd = purple_connection_get_protocol_data(connection);
+
if(!to || !msg)
return 0;
- return bonjour_jabber_send_message(((BonjourData*)(connection->proto_data))->jabber_data, to, msg);
+ return bonjour_jabber_send_message(bd->jabber_data, to, msg);
}
static void
@@ -220,7 +223,7 @@ bonjour_set_status(PurpleAccount *account, PurpleStatus *status)
gchar *stripped;
gc = purple_account_get_connection(account);
- bd = gc->proto_data;
+ bd = purple_connection_get_protocol_data(gc);
presence = purple_account_get_presence(account);
message = purple_status_get_attr_string(status, "message");
@@ -253,7 +256,7 @@ bonjour_set_status(PurpleAccount *account, PurpleStatus *status)
* if there is no add_buddy callback.
*/
static void
-bonjour_fake_add_buddy(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group) {
+bonjour_fake_add_buddy(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group, const char *message) {
purple_debug_error("bonjour", "Buddy '%s' manually added; removing. "
"Bonjour buddies must be discovered and not manually added.\n",
purple_buddy_get_name(buddy));
@@ -306,7 +309,7 @@ bonjour_status_types(PurpleAccount *account)
static void
bonjour_convo_closed(PurpleConnection *connection, const char *who)
{
- PurpleBuddy *buddy = purple_find_buddy(connection->account, who);
+ PurpleBuddy *buddy = purple_find_buddy(purple_connection_get_account(connection), who);
BonjourBuddy *bb;
if (buddy == NULL || (bb = purple_buddy_get_protocol_data(buddy)) == NULL)
@@ -325,7 +328,7 @@ bonjour_convo_closed(PurpleConnection *connection, const char *who)
static
void bonjour_set_buddy_icon(PurpleConnection *conn, PurpleStoredImage *img)
{
- BonjourData *bd = conn->proto_data;
+ BonjourData *bd = purple_connection_get_protocol_data(conn);
bonjour_dns_sd_update_buddy_icon(bd->dns_sd_data);
}
@@ -371,9 +374,12 @@ bonjour_tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboole
else
status_description = purple_status_get_name(status);
- purple_notify_user_info_add_pair(user_info, _("Status"), status_description);
- if (message != NULL)
- purple_notify_user_info_add_pair(user_info, _("Message"), message);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), status_description);
+ if (message != NULL) {
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Message"), message);
+ }
if (bb == NULL) {
purple_debug_error("bonjour", "Got tooltip request for a buddy without protocol data.\n");
@@ -382,20 +388,35 @@ bonjour_tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboole
/* Only show first/last name if there is a nickname set (to avoid duplication) */
if (bb->nick != NULL && *bb->nick != '\0') {
- if (bb->first != NULL && *bb->first != '\0')
- purple_notify_user_info_add_pair(user_info, _("First name"), bb->first);
- if (bb->last != NULL && *bb->last != '\0')
- purple_notify_user_info_add_pair(user_info, _("Last name"), bb->last);
+ if (bb->first != NULL && *bb->first != '\0') {
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("First name"), bb->first);
+ }
+ if (bb->last != NULL && *bb->last != '\0') {
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Last name"), bb->last);
+ }
}
- if (bb->email != NULL && *bb->email != '\0')
- purple_notify_user_info_add_pair(user_info, _("Email"), bb->email);
+ if (bb->email != NULL && *bb->email != '\0') {
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Email"), bb->email);
+ }
- if (bb->AIM != NULL && *bb->AIM != '\0')
- purple_notify_user_info_add_pair(user_info, _("AIM Account"), bb->AIM);
+ if (bb->AIM != NULL && *bb->AIM != '\0') {
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("AIM Account"), bb->AIM);
+ }
- if (bb->jid != NULL && *bb->jid != '\0')
- purple_notify_user_info_add_pair(user_info, _("XMPP Account"), bb->jid);
+ if (bb->jid != NULL && *bb->jid != '\0') {
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("XMPP Account"), bb->jid);
+ }
}
static void
@@ -418,7 +439,7 @@ bonjour_do_group_change(PurpleBuddy *buddy, const char *new_group) {
static void
bonjour_group_buddy(PurpleConnection *connection, const char *who, const char *old_group, const char *new_group)
{
- PurpleBuddy *buddy = purple_find_buddy(connection->account, who);
+ PurpleBuddy *buddy = purple_find_buddy(purple_connection_get_account(connection), who);
bonjour_do_group_change(buddy, new_group);
@@ -443,7 +464,7 @@ bonjour_rename_group(PurpleConnection *connection, const char *old_name, PurpleG
static gboolean
bonjour_can_receive_file(PurpleConnection *connection, const char *who)
{
- PurpleBuddy *buddy = purple_find_buddy(connection->account, who);
+ PurpleBuddy *buddy = purple_find_buddy(purple_connection_get_account(connection), who);
return (buddy != NULL && purple_buddy_get_protocol_data(buddy) != NULL);
}
@@ -463,6 +484,7 @@ static PurplePlugin *my_protocol = NULL;
static PurplePluginProtocolInfo prpl_info =
{
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
OPT_PROTO_NO_PASSWORD,
NULL, /* user_splits */
NULL, /* protocol_options */
@@ -503,7 +525,6 @@ static PurplePluginProtocolInfo prpl_info =
NULL, /* keepalive */
NULL, /* register_user */
NULL, /* get_cb_info */
- NULL, /* get_cb_away */
NULL, /* alias_buddy */
bonjour_group_buddy, /* group_buddy */
bonjour_rename_group, /* rename_group */
@@ -528,15 +549,12 @@ static PurplePluginProtocolInfo prpl_info =
NULL, /* unregister_user */
NULL, /* send_attention */
NULL, /* get_attention_types */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
NULL, /* get_account_text_table */
NULL, /* initiate_media */
NULL, /* get_media_caps */
NULL, /* get_moods */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */
};
static PurplePluginInfo info =
diff --git a/libpurple/protocols/bonjour/bonjour_ft.c b/libpurple/protocols/bonjour/bonjour_ft.c
index c551e533ef..4d08badd0e 100644
--- a/libpurple/protocols/bonjour/bonjour_ft.c
+++ b/libpurple/protocols/bonjour/bonjour_ft.c
@@ -38,7 +38,7 @@ static void
bonjour_xfer_init(PurpleXfer *xfer);
static void
bonjour_xfer_receive(PurpleConnection *pc, const char *id, const char *sid, const char *from,
- const int filesize, const char *filename, int option);
+ const goffset filesize, const char *filename, int option);
static void bonjour_free_xfer(PurpleXfer *xfer);
/* Look for specific xfer handle */
@@ -90,12 +90,12 @@ static void bonjour_xfer_cancel_send(PurpleXfer *xfer)
static void bonjour_xfer_request_denied(PurpleXfer *xfer)
{
- XepXfer *xf = xfer->data;
+ XepXfer *xf = purple_xfer_get_protocol_data(xfer);
purple_debug_info("bonjour", "Bonjour-xfer-request-denied.\n");
if(xf)
- xep_ft_si_reject(xf->data, xf->sid, xfer->who, "403", "cancel");
+ xep_ft_si_reject(xf->data, xf->sid, purple_xfer_get_remote_user(xfer), "403", "cancel");
bonjour_free_xfer(xfer);
}
@@ -136,8 +136,8 @@ static void bonjour_xfer_end(PurpleXfer *xfer)
* otherwise there is a RST resulting in an error on the client side */
if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND && purple_xfer_is_completed(xfer)) {
struct socket_cleanup *sc = g_new0(struct socket_cleanup, 1);
- sc->fd = xfer->fd;
- xfer->fd = -1;
+ sc->fd = purple_xfer_get_fd(xfer);
+ purple_xfer_set_fd(xfer, -1);
sc->handle = purple_input_add(sc->fd, PURPLE_INPUT_READ,
_wait_for_socket_close, sc);
}
@@ -162,11 +162,11 @@ bonjour_si_xfer_find(BonjourData *bd, const char *sid, const char *from)
xfer = xfers->data;
if(xfer == NULL)
break;
- xf = xfer->data;
+ xf = purple_xfer_get_protocol_data(xfer);
if(xf == NULL)
break;
- if(xf->sid && xfer->who && !strcmp(xf->sid, sid) &&
- !strcmp(xfer->who, from))
+ if(xf->sid && purple_xfer_get_remote_user(xfer) && !strcmp(xf->sid, sid) &&
+ !strcmp(purple_xfer_get_remote_user(xfer), from))
return xfer;
}
@@ -180,7 +180,7 @@ xep_ft_si_offer(PurpleXfer *xfer, const gchar *to)
{
xmlnode *si_node, *feature, *field, *file, *x;
XepIq *iq;
- XepXfer *xf = xfer->data;
+ XepXfer *xf = purple_xfer_get_protocol_data(xfer);
BonjourData *bd = NULL;
char buf[32];
@@ -210,8 +210,8 @@ xep_ft_si_offer(PurpleXfer *xfer, const gchar *to)
file = xmlnode_new_child(si_node, "file");
xmlnode_set_namespace(file, "http://jabber.org/protocol/si/profile/file-transfer");
- xmlnode_set_attrib(file, "name", xfer->filename);
- g_snprintf(buf, sizeof(buf), "%" G_GSIZE_FORMAT, xfer->size);
+ xmlnode_set_attrib(file, "name", purple_xfer_get_filename(xfer));
+ g_snprintf(buf, sizeof(buf), "%" G_GOFFSET_FORMAT, purple_xfer_get_size(xfer));
xmlnode_set_attrib(file, "size", buf);
feature = xmlnode_new_child(si_node, "feature");
@@ -240,7 +240,7 @@ xep_ft_si_offer(PurpleXfer *xfer, const gchar *to)
}
static void
-xep_ft_si_result(PurpleXfer *xfer, char *to)
+xep_ft_si_result(PurpleXfer *xfer, const char *to)
{
xmlnode *si_node, *feature, *field, *value, *x;
XepIq *iq;
@@ -249,7 +249,7 @@ xep_ft_si_result(PurpleXfer *xfer, char *to)
if(!to || !xfer)
return;
- xf = xfer->data;
+ xf = purple_xfer_get_protocol_data(xfer);
if(!xf)
return;
@@ -290,14 +290,14 @@ bonjour_free_xfer(PurpleXfer *xfer)
return;
}
- purple_debug_info("bonjour", "bonjour-free-xfer-%p.\n", xfer);
+ purple_debug_misc("bonjour", "bonjour-free-xfer-%p.\n", xfer);
- xf = (XepXfer*)xfer->data;
+ xf = purple_xfer_get_protocol_data(xfer);
if(xf != NULL) {
BonjourData *bd = (BonjourData*)xf->data;
if(bd != NULL) {
bd->xfer_lists = g_slist_remove(bd->xfer_lists, xfer);
- purple_debug_info("bonjour", "B free xfer from lists(%p).\n", bd->xfer_lists);
+ purple_debug_misc("bonjour", "B free xfer from lists(%p).\n", bd->xfer_lists);
}
if (xf->proxy_connection != NULL)
purple_proxy_connect_cancel(xf->proxy_connection);
@@ -311,10 +311,10 @@ bonjour_free_xfer(PurpleXfer *xfer)
g_free(xf->buddy_ip);
g_free(xf->sid);
g_free(xf);
- xfer->data = NULL;
+ purple_xfer_set_protocol_data(xfer, NULL);
}
- purple_debug_info("bonjour", "Need close socket=%d.\n", xfer->fd);
+ purple_debug_misc("bonjour", "Need close socket.\n");
}
PurpleXfer *
@@ -328,13 +328,14 @@ bonjour_new_xfer(PurpleConnection *gc, const char *who)
return NULL;
purple_debug_info("bonjour", "Bonjour-new-xfer to %s.\n", who);
- bd = (BonjourData*) gc->proto_data;
+ bd = purple_connection_get_protocol_data(gc);
if(bd == NULL)
return NULL;
/* Build the file transfer handle */
- xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who);
- xfer->data = xep_xfer = g_new0(XepXfer, 1);
+ xfer = purple_xfer_new(purple_connection_get_account(gc), PURPLE_XFER_SEND, who);
+ xep_xfer = g_new0(XepXfer, 1);
+ purple_xfer_set_protocol_data(xfer, xep_xfer);
xep_xfer->data = bd;
purple_debug_info("bonjour", "Bonjour-new-xfer bd=%p data=%p.\n", bd, xep_xfer->data);
@@ -379,13 +380,13 @@ bonjour_xfer_init(PurpleXfer *xfer)
BonjourBuddy *bb;
XepXfer *xf;
- xf = (XepXfer*)xfer->data;
+ xf = purple_xfer_get_protocol_data(xfer);
if(xf == NULL)
return;
purple_debug_info("bonjour", "Bonjour-xfer-init.\n");
- buddy = purple_find_buddy(xfer->account, xfer->who);
+ buddy = purple_find_buddy(purple_xfer_get_account(xfer), purple_xfer_get_remote_user(xfer));
/* this buddy is offline. */
if (buddy == NULL || (bb = purple_buddy_get_protocol_data(buddy)) == NULL)
return;
@@ -396,10 +397,10 @@ bonjour_xfer_init(PurpleXfer *xfer)
if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
/* initiate file transfer, send SI offer. */
purple_debug_info("bonjour", "Bonjour xfer type is PURPLE_XFER_SEND.\n");
- xep_ft_si_offer(xfer, xfer->who);
+ xep_ft_si_offer(xfer, purple_xfer_get_remote_user(xfer));
} else {
/* accept file transfer request, send SI result. */
- xep_ft_si_result(xfer, xfer->who);
+ xep_ft_si_result(xfer, purple_xfer_get_remote_user(xfer));
purple_debug_info("bonjour", "Bonjour xfer type is PURPLE_XFER_RECEIVE.\n");
}
}
@@ -416,7 +417,7 @@ xep_si_parse(PurpleConnection *pc, xmlnode *packet, PurpleBuddy *pb)
g_return_if_fail(packet != NULL);
g_return_if_fail(pb != NULL);
- bd = (BonjourData*) pc->proto_data;
+ bd = purple_connection_get_protocol_data(pc);
if(bd == NULL)
return;
@@ -553,9 +554,8 @@ __xep_bytestreams_parse(PurpleBuddy *pb, PurpleXfer *xfer, xmlnode *query,
const char *jid, *host, *port;
int portnum;
xmlnode *streamhost;
- XepXfer *xf = NULL;
+ XepXfer *xf = purple_xfer_get_protocol_data(xfer);
- xf = (XepXfer*)xfer->data;
for(streamhost = xmlnode_get_child(query, "streamhost");
streamhost;
streamhost = xmlnode_get_next_twin(streamhost)) {
@@ -598,7 +598,7 @@ xep_bytestreams_parse(PurpleConnection *pc, xmlnode *packet, PurpleBuddy *pb)
g_return_if_fail(packet != NULL);
g_return_if_fail(pb != NULL);
- bd = (BonjourData*) pc->proto_data;
+ bd = purple_connection_get_protocol_data(pc);
if(bd == NULL)
return;
@@ -632,7 +632,7 @@ xep_bytestreams_parse(PurpleConnection *pc, xmlnode *packet, PurpleBuddy *pb)
static void
bonjour_xfer_receive(PurpleConnection *pc, const char *id, const char *sid, const char *from,
- const int filesize, const char *filename, int option)
+ const goffset filesize, const char *filename, int option)
{
PurpleXfer *xfer;
XepXfer *xf;
@@ -641,15 +641,16 @@ bonjour_xfer_receive(PurpleConnection *pc, const char *id, const char *sid, cons
if(pc == NULL || id == NULL || from == NULL)
return;
- bd = (BonjourData*) pc->proto_data;
+ bd = purple_connection_get_protocol_data(pc);
if(bd == NULL)
return;
purple_debug_info("bonjour", "bonjour-xfer-receive.\n");
/* Build the file transfer handle */
- xfer = purple_xfer_new(pc->account, PURPLE_XFER_RECEIVE, from);
- xfer->data = xf = g_new0(XepXfer, 1);
+ xfer = purple_xfer_new(purple_connection_get_account(pc), PURPLE_XFER_RECEIVE, from);
+ xf = g_new0(XepXfer, 1);
+ purple_xfer_set_protocol_data(xfer, xf);
xf->data = bd;
purple_xfer_set_filename(xfer, filename);
xf->iq_id = g_strdup(id);
@@ -671,7 +672,7 @@ static void
bonjour_sock5_request_cb(gpointer data, gint source, PurpleInputCondition cond)
{
PurpleXfer *xfer = data;
- XepXfer *xf = xfer->data;
+ XepXfer *xf = purple_xfer_get_protocol_data(xfer);
int acceptfd;
int len = 0;
@@ -689,8 +690,6 @@ bonjour_sock5_request_cb(gpointer data, gint source, PurpleInputCondition cond)
/* This should cancel the ft */
purple_debug_error("bonjour", "Error accepting incoming SOCKS5 connection. (%d)\n", errno);
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
close(source);
purple_xfer_cancel_remote(xfer);
return;
@@ -705,29 +704,26 @@ bonjour_sock5_request_cb(gpointer data, gint source, PurpleInputCondition cond)
fcntl(acceptfd, F_SETFD, FD_CLOEXEC);
#endif
- purple_input_remove(xfer->watcher);
+ purple_input_remove(purple_xfer_get_watcher(xfer));
close(source);
- xfer->watcher = purple_input_add(acceptfd, PURPLE_INPUT_READ,
- bonjour_sock5_request_cb, xfer);
+ purple_xfer_set_watcher(xfer, purple_input_add(acceptfd, PURPLE_INPUT_READ,
+ bonjour_sock5_request_cb, xfer));
xf->sock5_req_state++;
xf->rxlen = 0;
}
break;
case 0x01:
- xfer->fd = source;
+ purple_xfer_set_fd(xfer, source);
len = read(source, xf->rx_buf + xf->rxlen, 3);
if(len < 0 && errno == EAGAIN)
return;
else if(len <= 0){
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
- close(source);
purple_xfer_cancel_remote(xfer);
return;
} else {
- purple_input_remove(xfer->watcher);
- xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE,
- bonjour_sock5_request_cb, xfer);
+ purple_input_remove(purple_xfer_get_watcher(xfer));
+ purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_WRITE,
+ bonjour_sock5_request_cb, xfer));
xf->sock5_req_state++;
xf->rxlen = 0;
bonjour_sock5_request_cb(xfer, source, PURPLE_INPUT_WRITE);
@@ -740,15 +736,13 @@ bonjour_sock5_request_cb(gpointer data, gint source, PurpleInputCondition cond)
if (len < 0 && errno == EAGAIN)
return;
else if (len < 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
close(source);
purple_xfer_cancel_remote(xfer);
return;
} else {
- purple_input_remove(xfer->watcher);
- xfer->watcher = purple_input_add(source, PURPLE_INPUT_READ,
- bonjour_sock5_request_cb, xfer);
+ purple_input_remove(purple_xfer_get_watcher(xfer));
+ purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_READ,
+ bonjour_sock5_request_cb, xfer));
xf->sock5_req_state++;
xf->rxlen = 0;
}
@@ -757,9 +751,9 @@ bonjour_sock5_request_cb(gpointer data, gint source, PurpleInputCondition cond)
len = read(source, xf->rx_buf + xf->rxlen, 20);
if(len<=0){
} else {
- purple_input_remove(xfer->watcher);
- xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE,
- bonjour_sock5_request_cb, xfer);
+ purple_input_remove(purple_xfer_get_watcher(xfer));
+ purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_WRITE,
+ bonjour_sock5_request_cb, xfer));
xf->sock5_req_state++;
xf->rxlen = 0;
bonjour_sock5_request_cb(xfer, source, PURPLE_INPUT_WRITE);
@@ -778,14 +772,12 @@ bonjour_sock5_request_cb(gpointer data, gint source, PurpleInputCondition cond)
if (len < 0 && errno == EAGAIN) {
return;
} else if (len < 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
close(source);
purple_xfer_cancel_remote(xfer);
return;
} else {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
+ purple_input_remove(purple_xfer_get_watcher(xfer));
+ purple_xfer_set_watcher(xfer, 0);
xf->rxlen = 0;
/*close(source);*/
purple_xfer_start(xfer, source, NULL, -1);
@@ -814,25 +806,25 @@ bonjour_bytestreams_listen(int sock, gpointer data)
return;
}
- xfer->watcher = purple_input_add(sock, PURPLE_INPUT_READ,
- bonjour_sock5_request_cb, xfer);
- xf = (XepXfer*)xfer->data;
+ purple_xfer_set_watcher(xfer, purple_input_add(sock, PURPLE_INPUT_READ,
+ bonjour_sock5_request_cb, xfer));
+ xf = purple_xfer_get_protocol_data(xfer);
xf->listen_data = NULL;
bd = xf->data;
- iq = xep_iq_new(bd, XEP_IQ_SET, xfer->who, bonjour_get_jid(bd->jabber_data->account), xf->sid);
+ iq = xep_iq_new(bd, XEP_IQ_SET, purple_xfer_get_remote_user(xfer), bonjour_get_jid(bd->jabber_data->account), xf->sid);
query = xmlnode_new_child(iq->node, "query");
xmlnode_set_namespace(query, "http://jabber.org/protocol/bytestreams");
xmlnode_set_attrib(query, "sid", xf->sid);
xmlnode_set_attrib(query, "mode", "tcp");
- xfer->local_port = purple_network_get_port_from_fd(sock);
+ purple_xfer_set_local_port(xfer, purple_network_get_port_from_fd(sock));
local_ips = bonjour_jabber_get_local_ips(sock);
- port = g_strdup_printf("%hu", xfer->local_port);
+ port = g_strdup_printf("%hu", purple_xfer_get_local_port(xfer));
while(local_ips) {
streamhost = xmlnode_new_child(query, "streamhost");
xmlnode_set_attrib(streamhost, "jid", xf->sid);
@@ -854,12 +846,10 @@ bonjour_bytestreams_init(PurpleXfer *xfer)
return;
purple_debug_info("bonjour", "Bonjour-bytestreams-init.\n");
- xf = xfer->data;
+ xf = purple_xfer_get_protocol_data(xfer);
- purple_network_listen_map_external(FALSE);
- xf->listen_data = purple_network_listen_range(0, 0, SOCK_STREAM,
+ xf->listen_data = purple_network_listen_range(0, 0, AF_UNSPEC, SOCK_STREAM, FALSE,
bonjour_bytestreams_listen, xfer);
- purple_network_listen_map_external(TRUE);
if (xf->listen_data == NULL)
purple_xfer_cancel_local(xfer);
@@ -870,7 +860,7 @@ static void
bonjour_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_message)
{
PurpleXfer *xfer = data;
- XepXfer *xf = xfer->data;
+ XepXfer *xf = purple_xfer_get_protocol_data(xfer);
XepIq *iq;
xmlnode *q_node, *tmp_node;
BonjourData *bd;
@@ -880,7 +870,7 @@ bonjour_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_me
if(source < 0) {
purple_debug_error("bonjour", "Error connecting via SOCKS5 - %s\n",
error_message ? error_message : "(null)");
- xep_ft_si_reject(xf->data, xf->iq_id, xfer->who, "404", "cancel");
+ xep_ft_si_reject(xf->data, xf->iq_id, purple_xfer_get_remote_user(xfer), "404", "cancel");
/* Cancel the connection */
purple_xfer_cancel_local(xfer);
return;
@@ -893,7 +883,7 @@ bonjour_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_me
/* Here, start the file transfer.*/
/* Notify Initiator of Connection */
- iq = xep_iq_new(bd, XEP_IQ_RESULT, xfer->who, bonjour_get_jid(bd->jabber_data->account), xf->iq_id);
+ iq = xep_iq_new(bd, XEP_IQ_RESULT, purple_xfer_get_remote_user(xfer), bonjour_get_jid(bd->jabber_data->account), xf->iq_id);
q_node = xmlnode_new_child(iq->node, "query");
xmlnode_set_namespace(q_node, "http://jabber.org/protocol/bytestreams");
tmp_node = xmlnode_new_child(q_node, "streamhost-used");
@@ -919,7 +909,7 @@ bonjour_bytestreams_connect(PurpleXfer *xfer, PurpleBuddy *pb)
purple_debug_info("bonjour", "bonjour-bytestreams-connect.\n");
- xf = (XepXfer*)xfer->data;
+ xf = purple_xfer_get_protocol_data(xfer);
if(!xf)
return;
@@ -948,7 +938,7 @@ bonjour_bytestreams_connect(PurpleXfer *xfer, PurpleBuddy *pb)
bonjour_bytestreams_connect_cb, xfer);
if(xf->proxy_connection == NULL) {
- xep_ft_si_reject(xf->data, xf->iq_id, xfer->who, "404", "cancel");
+ xep_ft_si_reject(xf->data, xf->iq_id, purple_xfer_get_remote_user(xfer), "404", "cancel");
/* Cancel the connection */
purple_xfer_cancel_local(xfer);
}
diff --git a/libpurple/protocols/bonjour/jabber.c b/libpurple/protocols/bonjour/jabber.c
index 391fa8ec2a..a750e07260 100644
--- a/libpurple/protocols/bonjour/jabber.c
+++ b/libpurple/protocols/bonjour/jabber.c
@@ -206,7 +206,9 @@ _jabber_parse_and_write_message_to_ui(xmlnode *message_node, PurpleBuddy *pb)
g_string_append_printf(str, " face='%s'", font_face);
if (font_size)
g_string_append_printf(str, " size='%s'", font_size);
- if (ichat_text_color)
+ if (font_color)
+ g_string_append_printf(str, " color='%s'", font_color);
+ else if (ichat_text_color)
g_string_append_printf(str, " color='%s'", ichat_text_color);
if (ichat_balloon_color)
g_string_append_printf(str, " back='%s'", ichat_balloon_color);
@@ -748,7 +750,7 @@ start_serversocket_listening(int port, int socket, struct sockaddr *addr, size_t
#if 0
/* TODO: Why isn't this being used? */
- data->socket = purple_network_listen(jdata->port, SOCK_STREAM);
+ data->socket = purple_network_listen(jdata->port, AF_UNSPEC, SOCK_STREAM, TRUE);
if (jdata->socket == -1)
{
@@ -933,7 +935,9 @@ bonjour_jabber_conv_match_by_name(BonjourJabberConversation *bconv) {
while(tmp) {
ip = tmp->data;
if (ip != NULL && g_ascii_strcasecmp(ip, bconv->ip) == 0) {
- BonjourJabber *jdata = ((BonjourData*) bconv->account->gc->proto_data)->jabber_data;
+ PurpleConnection *pc = purple_account_get_connection(bconv->account);
+ BonjourData *bd = purple_connection_get_protocol_data(pc);
+ BonjourJabber *jdata = bd->jabber_data;
purple_debug_info("bonjour", "Matched buddy %s to incoming conversation \"from\" attrib and IP (%s)\n",
purple_buddy_get_name(pb), bconv->ip);
@@ -966,7 +970,9 @@ bonjour_jabber_conv_match_by_name(BonjourJabberConversation *bconv) {
void
bonjour_jabber_conv_match_by_ip(BonjourJabberConversation *bconv) {
- BonjourJabber *jdata = ((BonjourData*) bconv->account->gc->proto_data)->jabber_data;
+ PurpleConnection *pc = purple_account_get_connection(bconv->account);
+ BonjourData *bd = purple_connection_get_protocol_data(pc);
+ BonjourJabber *jdata = bd->jabber_data;
struct _match_buddies_by_address_t *mbba;
GSList *buddies;
@@ -1126,7 +1132,9 @@ _async_bonjour_jabber_close_conversation_cb(gpointer data) {
void
async_bonjour_jabber_close_conversation(BonjourJabberConversation *bconv) {
- BonjourJabber *jdata = ((BonjourData*) bconv->account->gc->proto_data)->jabber_data;
+ PurpleConnection *pc = purple_account_get_connection(bconv->account);
+ BonjourData *bd = purple_connection_get_protocol_data(pc);
+ BonjourJabber *jdata = bd->jabber_data;
jdata->pending_conversations = g_slist_remove(jdata->pending_conversations, bconv);
@@ -1146,8 +1154,9 @@ bonjour_jabber_close_conversation(BonjourJabberConversation *bconv)
if (bconv != NULL) {
BonjourData *bd = NULL;
- if(PURPLE_CONNECTION_IS_VALID(bconv->account->gc)) {
- bd = bconv->account->gc->proto_data;
+ PurpleConnection *pc = purple_account_get_connection(bconv->account);
+ if (PURPLE_CONNECTION_IS_VALID(pc)) {
+ bd = purple_connection_get_protocol_data(pc);
bd->jabber_data->pending_conversations = g_slist_remove(bd->jabber_data->pending_conversations, bconv);
}
@@ -1161,7 +1170,7 @@ bonjour_jabber_close_conversation(BonjourJabberConversation *bconv)
tmp_next = xfers->next;
/* We only need to cancel this if it hasn't actually started transferring. */
/* This will change if we ever support IBB transfers. */
- if (strcmp(xfer->who, purple_buddy_get_name(bconv->pb)) == 0
+ if (strcmp(purple_xfer_get_remote_user(xfer), purple_buddy_get_name(bconv->pb)) == 0
&& (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_NOT_STARTED
|| purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_UNKNOWN)) {
purple_xfer_cancel_remote(xfer);
@@ -1219,7 +1228,7 @@ bonjour_jabber_stop(BonjourJabber *jdata)
purple_input_remove(jdata->watcher_id6);
/* Close all the conversation sockets and remove all the watchers after sending end streams */
- if (jdata->account->gc != NULL) {
+ if (!purple_account_is_disconnected(jdata->account)) {
GSList *buddies, *l;
buddies = purple_find_buddies(jdata->account, NULL);
diff --git a/libpurple/protocols/bonjour/mdns_avahi.c b/libpurple/protocols/bonjour/mdns_avahi.c
index 5f28a70a43..07dc63e161 100644
--- a/libpurple/protocols/bonjour/mdns_avahi.c
+++ b/libpurple/protocols/bonjour/mdns_avahi.c
@@ -618,7 +618,7 @@ void _mdns_delete_buddy(BonjourBuddy *buddy) {
void _mdns_retrieve_buddy_icon(BonjourBuddy* buddy) {
PurpleConnection *conn = purple_account_get_connection(buddy->account);
- BonjourData *bd = conn->proto_data;
+ BonjourData *bd = purple_connection_get_protocol_data(conn);
AvahiSessionImplData *session_idata = bd->dns_sd_data->mdns_impl_data;
AvahiBuddyImplData *idata = buddy->mdns_impl_data;
gchar *name;
diff --git a/libpurple/protocols/bonjour/mdns_common.c b/libpurple/protocols/bonjour/mdns_common.c
index 9319e36160..1f87b6496e 100644
--- a/libpurple/protocols/bonjour/mdns_common.c
+++ b/libpurple/protocols/bonjour/mdns_common.c
@@ -257,7 +257,7 @@ void
bonjour_dns_sd_set_jid(PurpleAccount *account, const char *hostname)
{
PurpleConnection *conn = purple_account_get_connection(account);
- BonjourData *bd = conn->proto_data;
+ BonjourData *bd = purple_connection_get_protocol_data(conn);
const char *tmp, *account_name = purple_account_get_username(account);
/* Previously we allowed the hostname part of the jid to be set
diff --git a/libpurple/protocols/bonjour/mdns_types.h b/libpurple/protocols/bonjour/mdns_types.h
index c843f140d6..b8ec2d2857 100644
--- a/libpurple/protocols/bonjour/mdns_types.h
+++ b/libpurple/protocols/bonjour/mdns_types.h
@@ -37,7 +37,7 @@ typedef struct _BonjourDnsSd {
gchar *msg;
} BonjourDnsSd;
-typedef enum _PublishType {
+typedef enum {
PUBLISH_START,
PUBLISH_UPDATE
} PublishType;
diff --git a/libpurple/protocols/bonjour/mdns_win32.c b/libpurple/protocols/bonjour/mdns_win32.c
index 9f1798cf43..d7ee2e8e86 100644
--- a/libpurple/protocols/bonjour/mdns_win32.c
+++ b/libpurple/protocols/bonjour/mdns_win32.c
@@ -105,7 +105,7 @@ _mdns_handle_event(gpointer data, gint source, PurpleInputCondition condition) {
purple_debug_error("bonjour", "Error (%d) handling mDNS response.\n", errorCode);
/* This happens when the mDNSResponder goes down, I haven't seen it happen any other time (in my limited testing) */
if (errorCode == kDNSServiceErr_Unknown) {
- purple_connection_error_reason(srh->account->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(srh->account->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Error communicating with local mDNSResponder."));
}
}
@@ -177,7 +177,7 @@ _mdns_resolve_host_callback(DNSServiceRef sdRef, DNSServiceFlags flags,
args->resolver_query = NULL;
if ((pb = purple_find_buddy(args->account, args->res_data->name))) {
- if (pb->proto_data != args->bb) {
+ if (purple_buddy_get_protocol_data(pb) != args->bb) {
purple_debug_error("bonjour", "Found purple buddy for %s not matching bonjour buddy record.",
args->res_data->name);
goto cleanup;
@@ -348,7 +348,7 @@ _mdns_service_browse_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32
/* Is there an existing buddy? */
if ((pb = purple_find_buddy(account, serviceName)))
- bb = pb->proto_data;
+ bb = purple_buddy_get_protocol_data(pb);
/* Is there a pending buddy? */
else {
while (tmp) {
@@ -368,7 +368,7 @@ _mdns_service_browse_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32
if (pb == NULL)
pending_buddies = g_slist_prepend(pending_buddies, bb);
else
- pb->proto_data = bb;
+ purple_buddy_set_protocol_data(pb, bb);
}
rd = g_new0(Win32SvcResolverData, 1);
@@ -408,7 +408,7 @@ _mdns_service_browse_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32
GSList *l;
/* There may be multiple presences, we should only get rid of this one */
Win32SvcResolverData *rd_search;
- BonjourBuddy *bb = pb->proto_data;
+ BonjourBuddy *bb = purple_buddy_get_protocol_data(pb);
Win32BuddyImplData *idata;
g_return_if_fail(bb != NULL);
diff --git a/libpurple/protocols/gg/Makefile.am b/libpurple/protocols/gg/Makefile.am
index cd64052e4a..de65da176c 100644
--- a/libpurple/protocols/gg/Makefile.am
+++ b/libpurple/protocols/gg/Makefile.am
@@ -1,5 +1,7 @@
EXTRA_DIST = \
Makefile.mingw \
+ win32-resolver.c \
+ win32-resolver.h \
lib/common.c \
lib/compat.h \
lib/COPYING \
diff --git a/libpurple/protocols/gg/Makefile.mingw b/libpurple/protocols/gg/Makefile.mingw
index 9ac7833657..5531c14728 100644
--- a/libpurple/protocols/gg/Makefile.mingw
+++ b/libpurple/protocols/gg/Makefile.mingw
@@ -60,7 +60,8 @@ C_SRC = \
confer.c \
gg.c \
search.c \
- gg-utils.c
+ gg-utils.c \
+ win32-resolver.c
OBJECTS = $(C_SRC:%.c=%.o)
diff --git a/libpurple/protocols/gg/buddylist.c b/libpurple/protocols/gg/buddylist.c
index 5f361d2b74..4aefe8093e 100644
--- a/libpurple/protocols/gg/buddylist.c
+++ b/libpurple/protocols/gg/buddylist.c
@@ -38,7 +38,7 @@
/* void ggp_buddylist_send(PurpleConnection *gc) {{{ */
void ggp_buddylist_send(PurpleConnection *gc)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
PurpleAccount *account = purple_connection_get_account(gc);
GSList *buddies;
uin_t *userlist;
@@ -90,7 +90,7 @@ void ggp_buddylist_load(PurpleConnection *gc, char *buddylist)
gchar **data_tbl;
gchar *name, *show, *g;
- if (strlen(users_tbl[i]) == 0)
+ if (!*users_tbl[i])
continue;
data_tbl = g_strsplit(users_tbl[i], ";", 8);
diff --git a/libpurple/protocols/gg/confer.c b/libpurple/protocols/gg/confer.c
index dad03d6518..1f2530a8fb 100644
--- a/libpurple/protocols/gg/confer.c
+++ b/libpurple/protocols/gg/confer.c
@@ -42,7 +42,7 @@ void ggp_confer_participants_add_uin(PurpleConnection *gc, const gchar *chat_nam
const uin_t uin)
{
PurpleConversation *conv;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
GGPChat *chat;
GList *l;
gchar *str_uin;
@@ -73,7 +73,7 @@ void ggp_confer_participants_add_uin(PurpleConnection *gc, const gchar *chat_nam
void ggp_confer_participants_add(PurpleConnection *gc, const gchar *chat_name,
const uin_t *recipients, int count)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
GList *l;
gchar *str_uin;
@@ -111,7 +111,7 @@ void ggp_confer_participants_add(PurpleConnection *gc, const gchar *chat_name,
const char *ggp_confer_find_by_participants(PurpleConnection *gc,
const uin_t *recipients, int count)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
GGPChat *chat = NULL;
GList *l;
int matches;
@@ -149,7 +149,7 @@ const char *ggp_confer_find_by_participants(PurpleConnection *gc,
/* const char *ggp_confer_add_new(PurpleConnection *gc, const char *name) {{{ */
const char *ggp_confer_add_new(PurpleConnection *gc, const char *name)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
GGPChat *chat;
chat = g_new0(GGPChat, 1);
diff --git a/libpurple/protocols/gg/gg-utils.c b/libpurple/protocols/gg/gg-utils.c
index 96e3b295ce..7c89e155d4 100644
--- a/libpurple/protocols/gg/gg-utils.c
+++ b/libpurple/protocols/gg/gg-utils.c
@@ -143,5 +143,18 @@ void ggp_status_fake_to_self(PurpleAccount *account)
msg ? "message" : NULL, msg, NULL);
}
+guint ggp_http_input_add(struct gg_http *http_req, PurpleInputFunction func,
+ gpointer user_data)
+{
+ PurpleInputCondition cond = 0;
+ int check = http_req->check;
+
+ if (check & GG_CHECK_READ)
+ cond |= PURPLE_INPUT_READ;
+ if (check & GG_CHECK_WRITE)
+ cond |= PURPLE_INPUT_WRITE;
+
+ return purple_input_add(http_req->fd, cond, func, user_data);
+}
/* vim: set ts=8 sts=0 sw=8 noet: */
diff --git a/libpurple/protocols/gg/gg-utils.h b/libpurple/protocols/gg/gg-utils.h
index 48e8188250..7c7b800263 100644
--- a/libpurple/protocols/gg/gg-utils.h
+++ b/libpurple/protocols/gg/gg-utils.h
@@ -101,6 +101,21 @@ void
ggp_status_fake_to_self(PurpleAccount *account);
+/**
+ * Adds an input handler in purple event loop for http request.
+ *
+ * @see purple_input_add
+ *
+ * @param http_req Http connection to watch.
+ * @param func The callback function for data.
+ * @param user_data User-specified data.
+ *
+ * @return The resulting handle (will be greater than 0).
+ */
+guint
+ggp_http_input_add(struct gg_http *http_req, PurpleInputFunction func,
+ gpointer user_data);
+
#endif /* _PURPLE_GG_UTILS_H */
/* vim: set ts=8 sts=0 sw=8 noet: */
diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c
index b27fe2480c..140d0be586 100644
--- a/libpurple/protocols/gg/gg.c
+++ b/libpurple/protocols/gg/gg.c
@@ -39,14 +39,16 @@
#include "request.h"
#include "xmlnode.h"
-#include <libgadu.h>
-
#include "gg.h"
#include "confer.h"
#include "search.h"
#include "buddylist.h"
#include "gg-utils.h"
+#ifdef _WIN32
+# include "win32-resolver.h"
+#endif
+
static PurplePlugin *my_protocol = NULL;
/* Prototypes */
@@ -97,7 +99,7 @@ static int ggp_setup_proxy(PurpleAccount *account)
static void ggp_async_token_handler(gpointer _gc, gint fd, PurpleInputCondition cond)
{
PurpleConnection *gc = _gc;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
GGPToken *token = info->token;
GGPTokenCallback cb;
@@ -170,7 +172,7 @@ static void ggp_token_request(PurpleConnection *gc, GGPTokenCallback cb)
if (ggp_setup_proxy(account) == -1)
return;
- info = gc->proto_data;
+ info = purple_connection_get_protocol_data(gc);
if ((req = gg_token(1)) == NULL) {
purple_notify_error(account,
@@ -199,7 +201,7 @@ static void ggp_token_request(PurpleConnection *gc, GGPTokenCallback cb)
static void ggp_action_buddylist_get(PurplePluginAction *action)
{
PurpleConnection *gc = (PurpleConnection *)action->context;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
purple_debug_info("gg", "Downloading...\n");
@@ -214,7 +216,7 @@ static void ggp_action_buddylist_get(PurplePluginAction *action)
static void ggp_action_buddylist_put(PurplePluginAction *action)
{
PurpleConnection *gc = (PurpleConnection *)action->context;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
char *buddylist = ggp_buddylist_dump(purple_connection_get_account(gc));
@@ -235,7 +237,7 @@ static void ggp_action_buddylist_put(PurplePluginAction *action)
static void ggp_action_buddylist_delete(PurplePluginAction *action)
{
PurpleConnection *gc = (PurpleConnection *)action->context;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
purple_debug_info("gg", "Deleting...\n");
@@ -334,7 +336,7 @@ static void ggp_callback_register_account_ok(PurpleConnection *gc,
PurpleRequestFields *fields)
{
PurpleAccount *account;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
struct gg_http *h = NULL;
struct gg_pubdir *s;
uin_t uin;
@@ -354,14 +356,14 @@ static void ggp_callback_register_account_ok(PurpleConnection *gc,
if (email == NULL || p1 == NULL || p2 == NULL || t == NULL ||
*email == '\0' || *p1 == '\0' || *p2 == '\0' || *t == '\0') {
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("You must fill in all registration fields"));
goto exit_err;
}
if (g_utf8_collate(p1, p2) != 0) {
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
_("Passwords do not match"));
goto exit_err;
@@ -371,7 +373,7 @@ static void ggp_callback_register_account_ok(PurpleConnection *gc,
token->id, t);
h = gg_register3(email, p1, token->id, t, 0);
if (h == NULL || !(s = h->data) || !s->success) {
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("Unable to register new account. An unknown error occurred."));
goto exit_err;
@@ -389,8 +391,8 @@ static void ggp_callback_register_account_ok(PurpleConnection *gc,
purple_notify_info(NULL, _("New Gadu-Gadu Account Registered"),
_("Registration completed successfully!"), NULL);
- if(account->registration_cb)
- (account->registration_cb)(account, TRUE, account->registration_cb_user_data);
+ purple_account_register_completed(account, TRUE);
+
/* TODO: the currently open Accounts Window will not be updated withthe
* new username and etc, we need to somehow have it refresh at this
* point
@@ -400,8 +402,7 @@ static void ggp_callback_register_account_ok(PurpleConnection *gc,
purple_account_disconnect(account);
exit_err:
- if(account->registration_cb)
- (account->registration_cb)(account, FALSE, account->registration_cb_user_data);
+ purple_account_register_completed(account, FALSE);
gg_register_free(h);
g_free(email);
@@ -415,10 +416,10 @@ exit_err:
static void ggp_callback_register_account_cancel(PurpleConnection *gc,
PurpleRequestFields *fields)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
GGPToken *token = info->token;
- purple_account_disconnect(gc->account);
+ purple_account_disconnect(purple_connection_get_account(gc));
g_free(token->id);
g_free(token->data);
@@ -433,7 +434,7 @@ static void ggp_register_user_dialog(PurpleConnection *gc)
PurpleRequestFieldGroup *group;
PurpleRequestField *field;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
GGPToken *token = info->token;
@@ -483,7 +484,7 @@ static void ggp_register_user_dialog(PurpleConnection *gc)
static void ggp_callback_show_next(PurpleConnection *gc, GList *row, gpointer user_data)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
GGPSearchForm *form = user_data;
guint32 seq;
@@ -520,7 +521,7 @@ static void ggp_callback_im(PurpleConnection *gc, GList *row, gpointer user_data
static void ggp_callback_find_buddies(PurpleConnection *gc, PurpleRequestFields *fields)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
GGPSearchForm *form;
guint32 seq;
@@ -616,75 +617,137 @@ static void ggp_find_buddies(PurplePluginAction *action)
gc);
}
-/* ----- CHANGE PASSWORD ------------------------------------------------ */
+/* ----- CHANGE PASSWORD ---------------------------------------------------- */
-static void ggp_callback_change_passwd_ok(PurpleConnection *gc, PurpleRequestFields *fields)
+typedef struct
{
+ guint inpa;
+ struct gg_http *http_req;
+ gchar *new_password;
PurpleAccount *account;
- GGPInfo *info = gc->proto_data;
+} ggp_change_passwd_request;
+
+static void ggp_callback_change_passwd_handler(gpointer _req, gint fd,
+ PurpleInputCondition cond)
+{
+ ggp_change_passwd_request *req = _req;
+ const char *messagesTitle =
+ _("Change password for the Gadu-Gadu account");
+
+ purple_input_remove(req->inpa);
+
+ if (gg_change_passwd_watch_fd(req->http_req) == -1 ||
+ req->http_req->state == GG_STATE_ERROR)
+ goto exit_error;
+
+ if (req->http_req->state != GG_STATE_DONE)
+ {
+ req->inpa = ggp_http_input_add(req->http_req,
+ ggp_callback_change_passwd_handler, req);
+ return;
+ }
+
+ if (req->http_req->data != NULL &&
+ ((struct gg_pubdir*)req->http_req->data)->success == 1)
+ {
+ purple_account_set_password(req->account, req->new_password);
+ purple_notify_info(req->account, messagesTitle,
+ _("Password was changed successfully!"), NULL);
+ goto exit_cleanup;
+ }
+
+exit_error:
+ purple_notify_error(req->account, messagesTitle,
+ _("Unable to change password. Error occurred.\n"), NULL);
+
+exit_cleanup:
+ gg_change_passwd_free(req->http_req);
+ g_free(req->new_password);
+ g_free(req);
+}
+
+static void ggp_callback_change_passwd_ok(PurpleConnection *gc,
+ PurpleRequestFields *fields)
+{
+ PurpleAccount *account;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
struct gg_http *h;
- gchar *cur, *p1, *p2, *t;
-
- cur = charset_convert(
- purple_request_fields_get_string(fields, "password_cur"),
- "UTF-8", "CP1250");
- p1 = charset_convert(
- purple_request_fields_get_string(fields, "password1"),
- "UTF-8", "CP1250");
- p2 = charset_convert(
- purple_request_fields_get_string(fields, "password2"),
- "UTF-8", "CP1250");
- t = charset_convert(
- purple_request_fields_get_string(fields, "token"),
- "UTF-8", "CP1250");
+ gchar *cur, *p1, *p2, *t, *mail;
+ const char *messagesTitle =
+ _("Change password for the Gadu-Gadu account");
+
+ cur = g_strdup(purple_request_fields_get_string(fields,
+ "password_cur"));
+ p1 = g_strdup(purple_request_fields_get_string(fields, "password1"));
+ p2 = g_strdup(purple_request_fields_get_string(fields, "password2"));
+ t = g_strdup(purple_request_fields_get_string(fields, "token"));
+ mail = g_strdup(purple_request_fields_get_string(fields, "email"));
account = purple_connection_get_account(gc);
if (cur == NULL || p1 == NULL || p2 == NULL || t == NULL ||
- *cur == '\0' || *p1 == '\0' || *p2 == '\0' || *t == '\0') {
- purple_notify_error(account, NULL, _("Fill in the fields."), NULL);
+ mail == NULL || *cur == '\0' || *p1 == '\0' || *p2 == '\0' ||
+ *t == '\0' || *mail == '\0') {
+ purple_notify_error(account, messagesTitle,
+ _("Fill in the fields."), NULL);
goto exit_err;
}
if (g_utf8_collate(p1, p2) != 0) {
- purple_notify_error(account, NULL,
- _("New passwords do not match."), NULL);
+ purple_notify_error(account, messagesTitle,
+ _("New passwords do not match."), NULL);
goto exit_err;
}
- if (g_utf8_collate(cur, purple_account_get_password(account)) != 0) {
- purple_notify_error(account, NULL,
- _("Your current password is different from the one that you specified."),
+ if (strlen(p1) > 15) {
+ purple_notify_error(account, messagesTitle,
+ _("New password should be at most 15 characters long."),
NULL);
goto exit_err;
}
- purple_debug_info("gg", "Changing password\n");
-
- /* XXX: this email should be a pref... */
- h = gg_change_passwd4(ggp_get_uin(account),
- "user@example.net", purple_account_get_password(account),
- p1, info->token->id, t, 0);
-
- if (h == NULL) {
- purple_notify_error(account, NULL,
- _("Unable to change password. Error occurred.\n"),
- NULL);
+ if (g_utf8_collate(cur, purple_account_get_password(account)) != 0) {
+ purple_notify_error(account, messagesTitle,
+ _("Your current password is different from the one that"
+ " you specified."), NULL);
goto exit_err;
}
- purple_account_set_password(account, p1);
+ if (!purple_email_is_valid(mail)) {
+ purple_notify_error(account, messagesTitle,
+ _("Invalid email address"), NULL);
+ goto exit_err;
+ }
- gg_change_passwd_free(h);
+ purple_debug_info("gg", "Changing password with email \"%s\"...\n",
+ mail);
- purple_notify_info(account, _("Change password for the Gadu-Gadu account"),
- _("Password was changed successfully!"), NULL);
+ h = gg_change_passwd4(ggp_get_uin(account), mail,
+ purple_account_get_password(account), p1, info->token->id, t,
+ 1);
+ if (h == NULL)
+ purple_notify_error(account, messagesTitle,
+ _("Unable to change password. Error occurred.\n"),
+ NULL);
+ else
+ {
+ ggp_change_passwd_request *req =
+ g_new(ggp_change_passwd_request, 1);
+ req->http_req = h;
+ req->new_password = g_strdup(p1);
+ req->account = account;
+
+ req->inpa = ggp_http_input_add(h,
+ ggp_callback_change_passwd_handler, req);
+ }
+
exit_err:
g_free(cur);
g_free(p1);
g_free(p2);
g_free(t);
+ g_free(mail);
g_free(info->token->id);
g_free(info->token->data);
g_free(info->token);
@@ -696,12 +759,11 @@ static void ggp_change_passwd_dialog(PurpleConnection *gc)
PurpleRequestFieldGroup *group;
PurpleRequestField *field;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
GGPToken *token = info->token;
char *msg;
-
fields = purple_request_fields_new();
group = purple_request_field_group_new(NULL);
purple_request_fields_add_group(fields, group);
@@ -721,6 +783,11 @@ static void ggp_change_passwd_dialog(PurpleConnection *gc)
purple_request_field_string_set_masked(field, TRUE);
purple_request_field_group_add_field(group, field);
+ field = purple_request_field_string_new("email",
+ _("Email Address"), "", FALSE);
+ purple_request_field_string_set_masked(field, FALSE);
+ purple_request_field_group_add_field(group, field);
+
field = purple_request_field_string_new("token",
_("Enter current token"), "", FALSE);
purple_request_field_string_set_masked(field, FALSE);
@@ -732,8 +799,8 @@ static void ggp_change_passwd_dialog(PurpleConnection *gc)
purple_request_field_group_add_field(group, field);
msg = g_strdup_printf("%s %d",
- _("Please, enter your current password and your new password for UIN: "),
- ggp_get_uin(purple_connection_get_account(gc)));
+ _("Please, enter your current password and your new password "
+ "for UIN: "), ggp_get_uin(purple_connection_get_account(gc)));
purple_request_fields(gc,
_("Change Gadu-Gadu Password"),
@@ -758,7 +825,7 @@ static void ggp_change_passwd(PurplePluginAction *action)
static void ggp_action_change_status_broadcasting_ok(PurpleConnection *gc, PurpleRequestFields *fields)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
int selected_field;
PurpleAccount *account = purple_connection_get_account(gc);
PurpleStatus *status;
@@ -778,7 +845,7 @@ static void ggp_action_change_status_broadcasting_ok(PurpleConnection *gc, Purpl
static void ggp_action_change_status_broadcasting(PurplePluginAction *action)
{
PurpleConnection *gc = (PurpleConnection *)action->context;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
PurpleRequestFields *fields;
PurpleRequestFieldGroup *group;
@@ -848,7 +915,7 @@ static void ggp_bmenu_add_to_chat(PurpleBlistNode *node, gpointer ignored)
buddy = (PurpleBuddy *)node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- info = gc->proto_data;
+ info = purple_connection_get_protocol_data(gc);
fields = purple_request_fields_new();
group = purple_request_field_group_new(NULL);
@@ -857,7 +924,7 @@ static void ggp_bmenu_add_to_chat(PurpleBlistNode *node, gpointer ignored)
field = purple_request_field_list_new("name", "Chat name");
for (l = info->chats; l != NULL; l = l->next) {
GGPChat *chat = l->data;
- purple_request_field_list_add(field, chat->name, chat->name);
+ purple_request_field_list_add_icon(field, chat->name, NULL, chat->name);
}
purple_request_field_group_add_field(group, field);
@@ -879,7 +946,7 @@ static void ggp_bmenu_add_to_chat(PurpleBlistNode *node, gpointer ignored)
static void ggp_add_deny(PurpleConnection *gc, const char *who)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
uin_t uin = ggp_str_to_uin(who);
purple_debug_info("gg", "ggp_add_deny: %u\n", uin);
@@ -890,7 +957,7 @@ static void ggp_add_deny(PurpleConnection *gc, const char *who)
static void ggp_rem_deny(PurpleConnection *gc, const char *who)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
uin_t uin = ggp_str_to_uin(who);
purple_debug_info("gg", "ggp_rem_deny: %u\n", uin);
@@ -1024,7 +1091,8 @@ static void gg_get_avatar_url_cb(PurpleUtilFetchUrlData *url_data, gpointer user
purple_debug_info("gg", "gg_get_avatar_url_cb: "
"requesting avatar for %s\n", uin);
- url_data = purple_util_fetch_url_request_len_with_account(account,
+ /* FIXME: This should be cancelled somewhere if not needed. */
+ url_data = purple_util_fetch_url_request(account,
bigavatar, TRUE, "Mozilla/4.0 (compatible; MSIE 5.0)",
FALSE, NULL, FALSE, -1, gg_fetch_avatar_cb, data);
}
@@ -1052,7 +1120,8 @@ static void ggp_update_buddy_avatar(PurpleConnection *gc, uin_t uin)
avatarurl = g_strdup_printf("http://api.gadu-gadu.pl/avatars/%u/0.xml", uin);
- url_data = purple_util_fetch_url_request_len_with_account(
+ /* FIXME: This should be cancelled somewhere if not needed. */
+ url_data = purple_util_fetch_url_request(
purple_connection_get_account(gc), avatarurl, TRUE,
"Mozilla/4.0 (compatible; MSIE 5.5)", FALSE, NULL, FALSE, -1,
gg_get_avatar_url_cb, gc);
@@ -1086,7 +1155,7 @@ static void ggp_generic_status_handler(PurpleConnection *gc, uin_t uin,
break;
case GG_STATUS_FFC:
case GG_STATUS_FFC_DESCR:
- st = purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE);
+ st = "freeforchat";
break;
case GG_STATUS_AVAIL:
case GG_STATUS_AVAIL_DESCR:
@@ -1096,6 +1165,10 @@ static void ggp_generic_status_handler(PurpleConnection *gc, uin_t uin,
case GG_STATUS_BUSY_DESCR:
st = purple_primitive_get_id_from_type(PURPLE_STATUS_AWAY);
break;
+ case GG_STATUS_INVISIBLE:
+ case GG_STATUS_INVISIBLE_DESCR:
+ st = purple_primitive_get_id_from_type(PURPLE_STATUS_INVISIBLE);
+ break;
case GG_STATUS_DND:
case GG_STATUS_DND_DESCR:
st = purple_primitive_get_id_from_type(PURPLE_STATUS_UNAVAILABLE);
@@ -1194,27 +1267,37 @@ static void ggp_pubdir_handle_info(PurpleConnection *gc, gg_pubdir50_t req,
val = ggp_search_get_result(req, 0, GG_PUBDIR50_STATUS);
/* XXX: Use of ggp_str_to_uin() is an ugly hack! */
- purple_notify_user_info_add_pair(user_info, _("Status"), ggp_status_by_id(ggp_str_to_uin(val)));
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), ggp_status_by_id(ggp_str_to_uin(val)));
g_free(val);
who = ggp_search_get_result(req, 0, GG_PUBDIR50_UIN);
- purple_notify_user_info_add_pair(user_info, _("UIN"), who);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("UIN"), who);
val = ggp_search_get_result(req, 0, GG_PUBDIR50_FIRSTNAME);
- purple_notify_user_info_add_pair(user_info, _("First Name"), val);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("First Name"), val);
g_free(val);
val = ggp_search_get_result(req, 0, GG_PUBDIR50_NICKNAME);
- purple_notify_user_info_add_pair(user_info, _("Nickname"), val);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Nickname"), val);
g_free(val);
val = ggp_search_get_result(req, 0, GG_PUBDIR50_CITY);
- purple_notify_user_info_add_pair(user_info, _("City"), val);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("City"), val);
g_free(val);
val = ggp_search_get_result(req, 0, GG_PUBDIR50_BIRTHYEAR);
if (strncmp(val, "0", 1)) {
- purple_notify_user_info_add_pair(user_info, _("Birth Year"), val);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Birth Year"), val);
}
g_free(val);
@@ -1225,15 +1308,12 @@ static void ggp_pubdir_handle_info(PurpleConnection *gc, gg_pubdir50_t req,
if (NULL != buddy) {
PurpleStatus *status;
const char *msg;
- char *text;
status = purple_presence_get_active_status(purple_buddy_get_presence(buddy));
msg = purple_status_get_attr_string(status, "message");
if (msg != NULL) {
- text = g_markup_escape_text(msg, -1);
- purple_notify_user_info_add_pair(user_info, _("Message"), text);
- g_free(text);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Message"), msg);
}
}
@@ -1342,7 +1422,7 @@ static void ggp_pubdir_handle_full(PurpleConnection *gc, gg_pubdir50_t req,
static void ggp_pubdir_reply_handler(PurpleConnection *gc, gg_pubdir50_t req)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
GGPSearchForm *form;
int res_count;
guint32 seq;
@@ -1384,7 +1464,7 @@ static void ggp_pubdir_reply_handler(PurpleConnection *gc, gg_pubdir50_t req)
static void ggp_recv_image_handler(PurpleConnection *gc, const struct gg_event *ev)
{
gint imgid = 0;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
GList *entry = g_list_first(info->pending_richtext_messages);
gchar *handlerid = g_strdup_printf("IMGID_HANDLER-%i", ev->event.image_reply.crc32);
@@ -1432,11 +1512,12 @@ static void ggp_recv_image_handler(PurpleConnection *gc, const struct gg_event *
*/
static void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event *ev)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
PurpleConversation *conv;
gchar *from;
gchar *msg;
gchar *tmp;
+ time_t mtime;
if (ev->event.msg.message == NULL)
{
@@ -1565,8 +1646,13 @@ static void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event
from, msg, ev->event.msg.msgclass,
ev->event.msg.recipients_count);
+ if (ev->event.msg.msgclass & GG_CLASS_QUEUED)
+ mtime = ev->event.msg.time;
+ else
+ mtime = time(NULL);
+
if (ev->event.msg.recipients_count == 0) {
- serv_got_im(gc, from, msg, 0, ev->event.msg.time);
+ serv_got_im(gc, from, msg, 0, mtime);
} else {
const char *chat_name;
int chat_id;
@@ -1592,7 +1678,7 @@ static void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event
buddy_name = ggp_buddy_get_name(gc, ev->event.msg.sender);
serv_got_chat_in(gc, chat_id, buddy_name,
- PURPLE_MESSAGE_RECV, msg, ev->event.msg.time);
+ PURPLE_MESSAGE_RECV, msg, mtime);
g_free(buddy_name);
}
g_free(msg);
@@ -1601,7 +1687,7 @@ static void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event
static void ggp_send_image_handler(PurpleConnection *gc, const struct gg_event *ev)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
PurpleStoredImage *image;
gint imgid = GPOINTER_TO_INT(g_hash_table_lookup(info->pending_images, GINT_TO_POINTER(ev->event.image_request.crc32)));
@@ -1707,14 +1793,14 @@ static void ggp_xml_event_handler(PurpleConnection *gc, char *data)
static void ggp_callback_recv(gpointer _gc, gint fd, PurpleInputCondition cond)
{
PurpleConnection *gc = _gc;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
struct gg_event *ev;
int i;
if (!(ev = gg_watch_fd(info->session))) {
purple_debug_error("gg",
"ggp_callback_recv: gg_watch_fd failed -- CRITICAL!\n");
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to read from socket"));
return;
@@ -1842,7 +1928,7 @@ static void ggp_async_login_handler(gpointer _gc, gint fd, PurpleInputCondition
g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc));
- info = gc->proto_data;
+ info = purple_connection_get_protocol_data(gc);
purple_debug_info("gg", "login_handler: session: check = %d; state = %d;\n",
info->session->check, info->session->state);
@@ -1880,7 +1966,7 @@ static void ggp_async_login_handler(gpointer _gc, gint fd, PurpleInputCondition
if (!(ev = gg_watch_fd(info->session))) {
purple_debug_error("gg", "login_handler: gg_watch_fd failed!\n");
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to read from socket"));
return;
@@ -1889,11 +1975,12 @@ static void ggp_async_login_handler(gpointer _gc, gint fd, PurpleInputCondition
purple_debug_info("gg", "login_handler: session: check = %d; state = %d;\n",
info->session->check, info->session->state);
- purple_input_remove(gc->inpa);
+ purple_input_remove(info->inpa);
+ info->inpa = 0;
/** XXX I think that this shouldn't be done if ev->type is GG_EVENT_CONN_FAILED or GG_EVENT_CONN_SUCCESS -datallah */
if (info->session->fd >= 0)
- gc->inpa = purple_input_add(info->session->fd,
+ info->inpa = purple_input_add(info->session->fd,
(info->session->check == 1) ? PURPLE_INPUT_WRITE :
PURPLE_INPUT_READ,
ggp_async_login_handler, gc);
@@ -1906,8 +1993,8 @@ static void ggp_async_login_handler(gpointer _gc, gint fd, PurpleInputCondition
case GG_EVENT_CONN_SUCCESS:
{
purple_debug_info("gg", "GG_EVENT_CONN_SUCCESS\n");
- purple_input_remove(gc->inpa);
- gc->inpa = purple_input_add(info->session->fd,
+ purple_input_remove(info->inpa);
+ info->inpa = purple_input_add(info->session->fd,
PURPLE_INPUT_READ,
ggp_callback_recv, gc);
@@ -1917,17 +2004,69 @@ static void ggp_async_login_handler(gpointer _gc, gint fd, PurpleInputCondition
}
break;
case GG_EVENT_CONN_FAILED:
- purple_input_remove(gc->inpa);
- gc->inpa = 0;
- purple_connection_error_reason (gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Connection failed"));
+ purple_input_remove(info->inpa);
+ info->inpa = 0;
+ purple_debug_info("gg", "Connection failure: %d\n",
+ ev->event.failure);
+ switch (ev->event.failure) {
+ case GG_FAILURE_RESOLVING:
+ purple_connection_error(gc,
+ PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ _("Unable to resolve "
+ "hostname"));
+ break;
+ case GG_FAILURE_PASSWORD:
+ purple_connection_error(gc,
+ PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
+ _("Incorrect password"));
+ break;
+ case GG_FAILURE_TLS:
+ purple_connection_error(gc,
+ PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
+ _("SSL Connection Failed"));
+ break;
+ case GG_FAILURE_INTRUDER:
+ purple_connection_error(gc,
+ PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
+ _("Your account has been "
+ "disabled because too many "
+ "incorrect passwords were "
+ "entered"));
+ break;
+ case GG_FAILURE_UNAVAILABLE:
+ purple_connection_error(gc,
+ PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ _("Service temporarily "
+ "unavailable"));
+ break;
+ case GG_FAILURE_PROXY:
+ purple_connection_error(gc,
+ PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ _("Error connecting to proxy "
+ "server"));
+ break;
+ case GG_FAILURE_HUB:
+ purple_connection_error(gc,
+ PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ _("Error connecting to master "
+ "server"));
+ break;
+ default:
+ purple_connection_error(gc,
+ PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ _("Connection failed"));
+ }
break;
case GG_EVENT_MSG:
if (ev->event.msg.sender == 0)
+ {
+ if (ev->event.msg.message == NULL)
+ break;
+
/* system messages are mostly ads */
purple_debug_info("gg", "System message:\n%s\n",
ev->event.msg.message);
+ }
else
purple_debug_warning("gg", "GG_EVENT_MSG: message from user %u "
"unexpected while connecting:\n%s\n",
@@ -1951,6 +2090,19 @@ static const char *ggp_list_icon(PurpleAccount *account, PurpleBuddy *buddy)
return "gadu-gadu";
}
+static const char *ggp_normalize(const PurpleAccount *account, const char *who)
+{
+ static char normalized[21]; /* maximum unsigned long long int size */
+
+ uin_t uin = ggp_str_to_uin(who);
+ if (uin <= 0)
+ return NULL;
+
+ g_snprintf(normalized, sizeof(normalized), "%u", uin);
+
+ return normalized;
+}
+
static char *ggp_status_text(PurpleBuddy *b)
{
PurpleStatus *status;
@@ -1975,7 +2127,7 @@ static char *ggp_status_text(PurpleBuddy *b)
static void ggp_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full)
{
PurpleStatus *status;
- char *text, *tmp;
+ char *tmp;
const char *msg, *name, *alias;
g_return_if_fail(b != NULL);
@@ -1985,21 +2137,19 @@ static void ggp_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gb
name = purple_status_get_name(status);
alias = purple_buddy_get_alias(b);
- purple_notify_user_info_add_pair (user_info, _("Alias"), alias);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), alias);
if (msg != NULL) {
- text = g_markup_escape_text(msg, -1);
if (PURPLE_BUDDY_IS_ONLINE(b)) {
- tmp = g_strdup_printf("%s: %s", name, text);
- purple_notify_user_info_add_pair(user_info, _("Status"), tmp);
+ tmp = g_strdup_printf("%s: %s", name, msg);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), tmp);
g_free(tmp);
} else {
- purple_notify_user_info_add_pair(user_info, _("Message"), text);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Message"), msg);
}
- g_free(text);
/* We don't want to duplicate 'Status: Offline'. */
} else if (PURPLE_BUDDY_IS_ONLINE(b)) {
- purple_notify_user_info_add_pair(user_info, _("Status"), name);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), name);
}
}
@@ -2008,50 +2158,60 @@ static GList *ggp_status_types(PurpleAccount *account)
PurpleStatusType *type;
GList *types = NULL;
- type = purple_status_type_new_with_attrs(
- PURPLE_STATUS_AVAILABLE, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- NULL);
+ type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
+ NULL, NULL, TRUE, TRUE, FALSE,
+ "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ NULL);
types = g_list_append(types, type);
/*
- * Without this selecting Invisible as own status doesn't
- * work. It's not used and not needed to show status of buddies.
+ * New status for GG 8.0: PoGGadaj ze mna (chatty).
+ * NOTE: at this time, this is used only to set our own status.
*/
- type = purple_status_type_new_with_attrs(
- PURPLE_STATUS_INVISIBLE, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- NULL);
+ type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
+ "freeforchat", _("Chatty"), TRUE, TRUE, FALSE,
+ "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ NULL);
types = g_list_append(types, type);
- type = purple_status_type_new_with_attrs(
- PURPLE_STATUS_AWAY, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- NULL);
+ type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY,
+ NULL, NULL, TRUE, TRUE, FALSE,
+ "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ NULL);
types = g_list_append(types, type);
- /*
- * New statuses for GG 8.0 like PoGGadaj ze mna (not yet because
- * libpurple can't support Chatty status) and Nie przeszkadzac
+ /*
+ * New status for GG 8.0: Nie przeszkadzac (do not disturb).
*/
- type = purple_status_type_new_with_attrs(
- PURPLE_STATUS_UNAVAILABLE, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- NULL);
+ type = purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE,
+ NULL, NULL, TRUE, TRUE, FALSE,
+ "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ NULL);
+ types = g_list_append(types, type);
+
+ /*
+ * It's used on buddy list if and only if it's showing our own
+ * (invisible) status.
+ */
+ type = purple_status_type_new_with_attrs(PURPLE_STATUS_INVISIBLE,
+ NULL, NULL, TRUE, TRUE, FALSE,
+ "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ NULL);
types = g_list_append(types, type);
/*
* This status is necessary to display guys who are blocking *us*.
*/
- type = purple_status_type_new_with_attrs(
- PURPLE_STATUS_INVISIBLE, "blocked", _("Blocked"), TRUE, FALSE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), NULL);
+ type = purple_status_type_new_with_attrs(PURPLE_STATUS_INVISIBLE,
+ "blocked", _("Blocked"), TRUE, FALSE, FALSE,
+ "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ NULL);
types = g_list_append(types, type);
- type = purple_status_type_new_with_attrs(
- PURPLE_STATUS_OFFLINE, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- NULL);
+ type = purple_status_type_new_with_attrs(PURPLE_STATUS_OFFLINE,
+ NULL, NULL, TRUE, TRUE, FALSE,
+ "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ NULL);
types = g_list_append(types, type);
return types;
@@ -2062,13 +2222,15 @@ static GList *ggp_blist_node_menu(PurpleBlistNode *node)
PurpleMenuAction *act;
GList *m = NULL;
PurpleAccount *account;
+ PurpleConnection *gc;
GGPInfo *info;
if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
return NULL;
account = purple_buddy_get_account((PurpleBuddy *) node);
- info = purple_account_get_connection(account)->proto_data;
+ gc = purple_account_get_connection(account);
+ info = purple_connection_get_protocol_data(gc);
if (info->chats) {
act = purple_menu_action_new(_("Add to chat"),
PURPLE_CALLBACK(ggp_bmenu_add_to_chat),
@@ -2120,11 +2282,25 @@ static void ggp_login(PurpleAccount *account)
info->pending_images = g_hash_table_new(g_direct_hash, g_direct_equal);
info->status_broadcasting = purple_account_get_bool(account, "status_broadcasting", TRUE);
- gc->proto_data = info;
+ purple_connection_set_protocol_data(gc, info);
glp->uin = ggp_get_uin(account);
- glp->password = (char *)purple_account_get_password(account);
+ glp->password = charset_convert(purple_account_get_password(account),
+ "UTF-8", "CP1250");
+
+ if (glp->uin == 0) {
+ purple_connection_error(gc,
+ PURPLE_CONNECTION_ERROR_INVALID_USERNAME,
+ _("The username specified is invalid."));
+ g_free(glp);
+ return;
+ }
+
glp->image_size = 255;
+ glp->status_flags = GG_STATUS_FLAG_UNKNOWN;
+
+ if (purple_account_get_bool(account, "show_links_from_strangers", 1))
+ glp->status_flags |= GG_STATUS_FLAG_SPAM;
presence = purple_account_get_presence(account);
status = purple_presence_get_active_status(presence);
@@ -2136,13 +2312,26 @@ static void ggp_login(PurpleAccount *account)
glp->async = 1;
glp->status = ggp_to_gg_status(status, &glp->status_descr);
- encryption_type = purple_account_get_string(account, "encryption", "none");
- purple_debug_info("gg", "Requested encryption type: %s\n", encryption_type);
+ encryption_type = purple_account_get_string(account, "encryption",
+ "opportunistic_tls");
+ purple_debug_info("gg", "Requested encryption type: %s\n",
+ encryption_type);
if (strcmp(encryption_type, "opportunistic_tls") == 0)
- glp->tls = 1;
- else
- glp->tls = 0;
- purple_debug_info("gg", "TLS enabled: %d\n", glp->tls);
+ glp->tls = GG_SSL_ENABLED;
+ else if (strcmp(encryption_type, "require_tls") == 0) {
+ if (gg_libgadu_check_feature(GG_LIBGADU_FEATURE_SSL))
+ glp->tls = GG_SSL_REQUIRED;
+ else {
+ purple_connection_error(gc,
+ PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
+ _("SSL support unavailable"));
+ g_free(glp);
+ return;
+ }
+ }
+ else /* encryption_type == "none" */
+ glp->tls = GG_SSL_DISABLED;
+ purple_debug_info("gg", "TLS mode: %d\n", glp->tls);
if (!info->status_broadcasting)
glp->status = glp->status|GG_STATUS_FRIENDS_MASK;
@@ -2157,7 +2346,7 @@ static void ggp_login(PurpleAccount *account)
if (addr == NULL) {
gchar *tmp = g_strdup_printf(_("Unable to resolve hostname '%s': %s"),
address, g_strerror(errno));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, /* should this be a settings error? */
tmp);
g_free(tmp);
@@ -2172,30 +2361,31 @@ static void ggp_login(PurpleAccount *account)
info->session = gg_login(glp);
purple_connection_update_progress(gc, _("Connecting"), 0, 2);
if (info->session == NULL) {
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Connection failed"));
g_free(glp);
return;
}
- gc->inpa = purple_input_add(info->session->fd, PURPLE_INPUT_READ,
+ info->inpa = purple_input_add(info->session->fd, PURPLE_INPUT_READ,
ggp_async_login_handler, gc);
}
static void ggp_close(PurpleConnection *gc)
{
+ PurpleAccount *account;
+ GGPInfo *info;;
if (gc == NULL) {
purple_debug_info("gg", "gc == NULL\n");
return;
}
- if (gc->proto_data) {
- PurpleAccount *account = purple_connection_get_account(gc);
- PurpleStatus *status;
- GGPInfo *info = gc->proto_data;
+ account = purple_connection_get_account(gc);
+ info = purple_connection_get_protocol_data(gc);
- status = purple_account_get_active_status(account);
+ if (info) {
+ PurpleStatus *status = purple_account_get_active_status(account);
if (info->session != NULL) {
ggp_set_status(account, status);
@@ -2213,20 +2403,21 @@ static void ggp_close(PurpleConnection *gc)
ggp_search_destroy(info->searches);
g_list_free(info->pending_richtext_messages);
g_hash_table_destroy(info->pending_images);
+
+ if (info->inpa > 0)
+ purple_input_remove(info->inpa);
+
+ purple_connection_set_protocol_data(gc, NULL);
g_free(info);
- gc->proto_data = NULL;
}
- if (gc->inpa > 0)
- purple_input_remove(gc->inpa);
-
purple_debug_info("gg", "Connection closed.\n");
}
static int ggp_send_im(PurpleConnection *gc, const char *who, const char *msg,
PurpleMessageFlags flags)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
char *tmp, *plain;
int ret = 1;
unsigned char format[1024];
@@ -2344,6 +2535,7 @@ static int ggp_send_im(PurpleConnection *gc, const char *who, const char *msg,
static unsigned int ggp_send_typing(PurpleConnection *gc, const char *name, PurpleTypingState state)
{
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
int dummy_length; // we don't send real length of typed message
if (state == PURPLE_TYPED) // not supported
@@ -2355,7 +2547,7 @@ static unsigned int ggp_send_typing(PurpleConnection *gc, const char *name, Purp
dummy_length = 0;
gg_typing_notification(
- ((GGPInfo*)gc->proto_data)->session,
+ info->session,
ggp_str_to_uin(name),
dummy_length);
@@ -2364,7 +2556,7 @@ static unsigned int ggp_send_typing(PurpleConnection *gc, const char *name, Purp
static void ggp_get_info(PurpleConnection *gc, const char *name)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
GGPSearchForm *form;
guint32 seq;
@@ -2392,6 +2584,9 @@ static int ggp_to_gg_status(PurpleStatus *status, char **msg)
if (strcmp(status_id, "available") == 0) {
new_status = GG_STATUS_AVAIL;
new_status_descr = GG_STATUS_AVAIL_DESCR;
+ } else if (strcmp(status_id, "freeforchat") == 0) {
+ new_status = GG_STATUS_FFC;
+ new_status_descr = GG_STATUS_FFC_DESCR;
} else if (strcmp(status_id, "away") == 0) {
new_status = GG_STATUS_BUSY;
new_status_descr = GG_STATUS_BUSY_DESCR;
@@ -2440,7 +2635,7 @@ static void ggp_set_status(PurpleAccount *account, PurpleStatus *status)
return;
gc = purple_account_get_connection(account);
- info = gc->proto_data;
+ info = purple_connection_get_protocol_data(gc);
new_status = ggp_to_gg_status(status, &new_msg);
@@ -2458,10 +2653,10 @@ static void ggp_set_status(PurpleAccount *account, PurpleStatus *status)
}
-static void ggp_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
+static void ggp_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, const char *message)
{
PurpleAccount *account;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
const gchar *name = purple_buddy_get_name(buddy);
gg_add_notify(info->session, ggp_str_to_uin(name));
@@ -2475,14 +2670,14 @@ static void ggp_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup
static void ggp_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
PurpleGroup *group)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
gg_remove_notify(info->session, ggp_str_to_uin(purple_buddy_get_name(buddy)));
}
static void ggp_join_chat(PurpleConnection *gc, GHashTable *data)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
GGPChat *chat;
char *chat_name;
GList *l;
@@ -2520,7 +2715,7 @@ static char *ggp_get_chat_name(GHashTable *data) {
static int ggp_chat_send(PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags)
{
PurpleConversation *conv;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
GGPChat *chat = NULL;
GList *l;
/* char *msg, *plain; */
@@ -2534,7 +2729,7 @@ static int ggp_chat_send(PurpleConnection *gc, int id, const char *message, Purp
for (l = info->chats; l != NULL; l = l->next) {
chat = l->data;
- if (g_utf8_collate(chat->name, conv->name) == 0) {
+ if (g_utf8_collate(chat->name, purple_conversation_get_name(conv)) == 0) {
break;
}
@@ -2575,14 +2770,14 @@ static int ggp_chat_send(PurpleConnection *gc, int id, const char *message, Purp
static void ggp_keepalive(PurpleConnection *gc)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
/* purple_debug_info("gg", "Keeping connection alive....\n"); */
if (gg_ping(info->session) < 0) {
purple_debug_info("gg", "Not connected to the server "
"or gg_session is not correct\n");
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Not connected to the server"));
}
@@ -2600,14 +2795,16 @@ static GList *ggp_actions(PurplePlugin *plugin, gpointer context)
GList *m = NULL;
PurplePluginAction *act;
+ act = purple_plugin_action_new(_("Change password..."),
+ ggp_change_passwd);
+ m = g_list_append(m, act);
+
act = purple_plugin_action_new(_("Find buddies..."),
ggp_find_buddies);
m = g_list_append(m, act);
- m = g_list_append(m, NULL);
-
- act = purple_plugin_action_new(_("Change password..."),
- ggp_change_passwd);
+ act = purple_plugin_action_new(_("Change status broadcasting"),
+ ggp_action_change_status_broadcasting);
m = g_list_append(m, act);
m = g_list_append(m, NULL);
@@ -2632,10 +2829,6 @@ static GList *ggp_actions(PurplePlugin *plugin, gpointer context)
ggp_action_buddylist_load);
m = g_list_append(m, act);
- act = purple_plugin_action_new(_("Change status broadcasting"),
- ggp_action_change_status_broadcasting);
- m = g_list_append(m, act);
-
return m;
}
@@ -2646,6 +2839,7 @@ static gboolean ggp_offline_message(const PurpleBuddy *buddy)
static PurplePluginProtocolInfo prpl_info =
{
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
OPT_PROTO_REGISTER_NOSCREENNAME | OPT_PROTO_IM_IMAGE,
NULL, /* user_splits */
NULL, /* protocol_options */
@@ -2686,13 +2880,12 @@ static PurplePluginProtocolInfo prpl_info =
ggp_keepalive, /* keepalive */
ggp_register_user, /* register_user */
NULL, /* get_cb_info */
- NULL, /* get_cb_away */
NULL, /* alias_buddy */
NULL, /* group_buddy */
NULL, /* rename_group */
NULL, /* buddy_free */
NULL, /* convo_closed */
- NULL, /* normalize */
+ ggp_normalize, /* normalize */
NULL, /* set_buddy_icon */
NULL, /* remove_group */
NULL, /* get_cb_real_name */
@@ -2711,15 +2904,12 @@ static PurplePluginProtocolInfo prpl_info =
NULL, /* unregister_user */
NULL, /* send_attention */
NULL, /* get_attention_types */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
NULL, /* get_account_text_table */
NULL, /* initiate_media */
NULL, /* can_do_media */
NULL, /* get_moods */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */
};
static PurplePluginInfo info = {
@@ -2785,11 +2975,6 @@ static void init_plugin(PurplePlugin *plugin)
PurpleAccountOption *option;
GList *encryption_options = NULL;
- option = purple_account_option_string_new(_("Nickname"),
- "nick", _("Gadu-Gadu User"));
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
- option);
-
option = purple_account_option_string_new(_("GG server"),
"gg_server", "");
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
@@ -2802,22 +2987,29 @@ static void init_plugin(PurplePlugin *plugin)
list = g_list_append(list, kvp); \
}
- ADD_VALUE(encryption_options, _("Don't use encryption"), "none");
ADD_VALUE(encryption_options, _("Use encryption if available"),
"opportunistic_tls");
-#if 0
- /* TODO */
ADD_VALUE(encryption_options, _("Require encryption"), "require_tls");
-#endif
+ ADD_VALUE(encryption_options, _("Don't use encryption"), "none");
option = purple_account_option_list_new(_("Connection security"),
"encryption", encryption_options);
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
option);
+ option = purple_account_option_bool_new(_("Show links from strangers"),
+ "show_links_from_strangers", 1);
+ prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+ option);
+
my_protocol = plugin;
gg_debug_handler = purple_gg_debug_handler;
+
+#ifdef _WIN32
+ gg_global_set_custom_resolver(ggp_resolver_win32thread_start,
+ ggp_resolver_win32thread_cleanup);
+#endif
}
PURPLE_INIT_PLUGIN(gg, init_plugin, info);
diff --git a/libpurple/protocols/gg/gg.h b/libpurple/protocols/gg/gg.h
index 3e75a082b3..7d6c0edda3 100644
--- a/libpurple/protocols/gg/gg.h
+++ b/libpurple/protocols/gg/gg.h
@@ -24,6 +24,7 @@
#ifndef _PURPLE_GG_H
#define _PURPLE_GG_H
+#undef printf
#include <libgadu.h>
#include "internal.h"
#include "search.h"
@@ -58,6 +59,7 @@ typedef struct
typedef struct {
struct gg_session *session;
+ guint inpa;
GGPToken *token;
GList *chats;
GGPSearches *searches;
diff --git a/libpurple/protocols/gg/lib/common.c b/libpurple/protocols/gg/lib/common.c
index 4bb053f943..acac5fb35f 100644
--- a/libpurple/protocols/gg/lib/common.c
+++ b/libpurple/protocols/gg/lib/common.c
@@ -24,22 +24,14 @@
*
* \brief Funkcje wykorzystywane przez różne moduły biblioteki
*/
-#ifndef _WIN32
-# include <sys/types.h>
-# include <sys/ioctl.h>
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-# ifdef sun
-# include <sys/filio.h>
-# endif
+#include "compat.h"
+#include <sys/types.h>
+#ifdef sun
+# include <sys/filio.h>
#endif
#include <errno.h>
#include <fcntl.h>
-#ifndef _WIN32
-# include <netdb.h>
-#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -92,7 +84,7 @@ char *gg_vsaprintf(const char *format, va_list ap)
}
buf = tmp;
res = vsnprintf(buf, size, format, ap);
- } while (res == size - 1 || res == -1);
+ } while (res >= size - 1 || res == -1);
}
#else
{
diff --git a/libpurple/protocols/gg/lib/compat.h b/libpurple/protocols/gg/lib/compat.h
index 46fe305e71..3c4e64967b 100644
--- a/libpurple/protocols/gg/lib/compat.h
+++ b/libpurple/protocols/gg/lib/compat.h
@@ -28,6 +28,21 @@
#ifndef __COMPAT_H
#define __COMPAT_H
+#ifdef _WIN32
+# include <ws2tcpip.h>
+# include <winsock2.h>
+# define EINPROGRESS WSAEINPROGRESS
+# define ETIMEDOUT WSAETIMEDOUT
+# define ENOTCONN WSAENOTCONN
+# define ECONNRESET WSAECONNRESET
+#else
+# include <sys/ioctl.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <netdb.h>
+#endif
+
#ifdef sun
# define INADDR_NONE ((in_addr_t) 0xffffffff)
#endif
diff --git a/libpurple/protocols/gg/lib/dcc.c b/libpurple/protocols/gg/lib/dcc.c
index d479f124bd..38a17cec9a 100644
--- a/libpurple/protocols/gg/lib/dcc.c
+++ b/libpurple/protocols/gg/lib/dcc.c
@@ -26,16 +26,11 @@
* \brief Obsługa połączeń bezpośrednich do wersji Gadu-Gadu 6.x
*/
+#include "compat.h"
#include <sys/types.h>
#include <sys/stat.h>
-#ifndef _WIN32
-# include <sys/ioctl.h>
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-# ifdef sun
-# include <sys/filio.h>
-# endif
+#ifdef sun
+# include <sys/filio.h>
#endif
#include <ctype.h>
@@ -601,7 +596,7 @@ struct gg_event *gg_dcc_watch_fd(struct gg_dcc *h)
struct sockaddr_in sin;
struct gg_dcc *c;
int fd, one = 1;
- unsigned int sin_len = sizeof(sin);
+ socklen_t sin_len = sizeof(sin);
if ((fd = accept(h->fd, (struct sockaddr*) &sin, &sin_len)) == -1) {
gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() can't accept() new connection (errno=%d, %s)\n", errno, strerror(errno));
@@ -648,7 +643,8 @@ struct gg_event *gg_dcc_watch_fd(struct gg_dcc *h)
struct gg_dcc_small_packet small;
struct gg_dcc_big_packet big;
int size, tmp, res;
- unsigned int utmp, res_size = sizeof(res);
+ unsigned int utmp;
+ socklen_t res_size = sizeof(res);
char buf[1024], ack[] = "UDAG";
struct gg_dcc_file_info_packet {
diff --git a/libpurple/protocols/gg/lib/dcc7.c b/libpurple/protocols/gg/lib/dcc7.c
index 9b045cfdd9..6d938c7543 100644
--- a/libpurple/protocols/gg/lib/dcc7.c
+++ b/libpurple/protocols/gg/lib/dcc7.c
@@ -31,14 +31,8 @@
#include <sys/types.h>
#include <sys/stat.h>
-#ifndef _WIN32
-# include <sys/ioctl.h>
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-# ifdef sun
-# include <sys/filio.h>
-# endif
+#ifdef sun
+# include <sys/filio.h>
#endif
#include <time.h>
@@ -1095,7 +1089,7 @@ struct gg_event *gg_dcc7_watch_fd(struct gg_dcc7 *dcc)
case GG_STATE_CONNECTING:
{
int res = 0, error = 0;
- unsigned int error_size = sizeof(error);
+ socklen_t error_size = sizeof(error);
gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() GG_STATE_CONNECTING\n");
@@ -1384,7 +1378,7 @@ struct gg_event *gg_dcc7_watch_fd(struct gg_dcc7 *dcc)
case GG_STATE_CONNECTING_RELAY:
{
int res;
- unsigned int res_size = sizeof(res);
+ socklen_t res_size = sizeof(res);
struct gg_dcc7_relay_req pkt;
gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() GG_STATE_CONNECTING_RELAY\n");
diff --git a/libpurple/protocols/gg/lib/events.c b/libpurple/protocols/gg/lib/events.c
index d5dc509bf5..167b16a7e3 100644
--- a/libpurple/protocols/gg/lib/events.c
+++ b/libpurple/protocols/gg/lib/events.c
@@ -28,17 +28,10 @@
*/
#include <sys/types.h>
-#ifndef _WIN32
-# include <sys/ioctl.h>
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-#endif
#include <ctype.h>
#include "compat.h"
#include "libgadu.h"
-#include "libgadu-config.h"
#include "protocol.h"
#include "libgadu-internal.h"
#include "encoding.h"
diff --git a/libpurple/protocols/gg/lib/handlers.c b/libpurple/protocols/gg/lib/handlers.c
index 4d64286135..b9b4057c1e 100644
--- a/libpurple/protocols/gg/lib/handlers.c
+++ b/libpurple/protocols/gg/lib/handlers.c
@@ -27,21 +27,13 @@
*/
#include <sys/types.h>
-#ifndef _WIN32
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-#endif
#include <ctype.h>
-#ifndef _WIN32
-# ifdef sun
-# include <sys/filio.h>
-# endif
+#ifdef sun
+# include <sys/filio.h>
#endif
#include "compat.h"
#include "libgadu.h"
-#include "libgadu-config.h"
#include "resolver.h"
#include "session.h"
#include "protocol.h"
@@ -51,9 +43,6 @@
#include "deflate.h"
#include <errno.h>
-#ifndef _WIN32
-# include <netdb.h>
-#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -92,7 +81,7 @@ static int gg_session_handle_welcome(struct gg_session *gs, uint32_t type, const
uint8_t hash_buf[64];
uint32_t local_ip;
struct sockaddr_in sin;
- unsigned int sin_len = sizeof(sin);
+ socklen_t sin_len = sizeof(sin);
if (len < sizeof(struct gg_welcome)) {
ge->type = GG_EVENT_CONN_FAILED;
diff --git a/libpurple/protocols/gg/lib/http.c b/libpurple/protocols/gg/lib/http.c
index 7d014f8a33..b35f729f37 100644
--- a/libpurple/protocols/gg/lib/http.c
+++ b/libpurple/protocols/gg/lib/http.c
@@ -25,11 +25,6 @@
*/
#include <sys/types.h>
-#ifndef _WIN32
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-#endif
#include "compat.h"
#include "libgadu.h"
@@ -37,9 +32,6 @@
#include <ctype.h>
#include <errno.h>
-#ifndef _WIN32
-# include <netdb.h>
-#endif
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
@@ -258,7 +250,7 @@ int gg_http_watch_fd(struct gg_http *h)
}
if (h->state == GG_STATE_SENDING_QUERY) {
- size_t res;
+ ssize_t res;
if ((res = write(h->fd, h->query, strlen(h->query))) < 1) {
gg_debug(GG_DEBUG_MISC, "=> http, write() failed (len=%d, res=%d, errno=%d)\n", strlen(h->query), res, errno);
diff --git a/libpurple/protocols/gg/lib/libgadu-config.h b/libpurple/protocols/gg/lib/libgadu-config.h
index 8fa28ae370..4ca5aea111 100644
--- a/libpurple/protocols/gg/lib/libgadu-config.h
+++ b/libpurple/protocols/gg/lib/libgadu-config.h
@@ -8,8 +8,30 @@
/* Defined if libgadu was compiled for bigendian machine. */
#undef __GG_LIBGADU_BIGENDIAN
#ifdef WORDS_BIGENDIAN
-#define __GG_LIBGADU_BIGENDIAN
-#endif /* WORDS_BIGENDIAN */
+# define __GG_LIBGADU_BIGENDIAN
+#endif
+
+/* Defined if this machine has gethostbyname_r(). */
+#undef GG_CONFIG_HAVE_GETHOSTBYNAME_R
+
+/* Defined if this machine has _exit(). */
+#define GG_CONFIG_HAVE__EXIT
+
+/* Defined if libgadu was compiled and linked with fork support. */
+#undef GG_CONFIG_HAVE_FORK
+#ifndef _WIN32
+# define GG_CONFIG_HAVE_FORK
+#endif
+
+/* Defined if libgadu was compiled and linked with pthread support. */
+/* We don't like pthreads. */
+#undef __GG_LIBGADU_HAVE_PTHREAD
+
+/* Defined if this machine has C99-compiliant vsnprintf(). */
+#undef __GG_LIBGADU_HAVE_C99_VSNPRINTF
+#ifndef _WIN32
+# define __GG_LIBGADU_HAVE_C99_VSNPRINTF
+#endif
/* Defined if this machine has va_copy(). */
#define __GG_LIBGADU_HAVE_VA_COPY
@@ -20,40 +42,29 @@
/* Defined if this machine supports long long. */
#undef __GG_LIBGADU_HAVE_LONG_LONG
#ifdef HAVE_LONG_LONG
-#define __GG_LIBGADU_HAVE_LONG_LONG
-#endif /* HAVE_LONG_LONG */
-
-/* Defined if libgadu was compiled and linked with pthread support. */
-/* We don't like pthreads. */
-#undef __GG_LIBGADU_HAVE_PTHREAD
+# define __GG_LIBGADU_HAVE_LONG_LONG
+#endif
-/* Defined if libgadu was compiled and linked with GnuTLS encryption support. */
+/* Defined if libgadu was compiled and linked with GnuTLS support. */
+#undef GG_CONFIG_HAVE_GNUTLS
#ifdef HAVE_GNUTLS
# define GG_CONFIG_HAVE_GNUTLS
-#else
-# undef GG_CONFIG_HAVE_GNUTLS
#endif
-/* Defined if libgadu was compiled and linked with TLS support. */
+/* Defined if libgadu was compiled and linked with OpenSSL support. */
/* Always undefined in Purple. */
#undef __GG_LIBGADU_HAVE_OPENSSL
-/* Include file containing uintXX_t declarations. */
+/* Defined if libgadu was compiled and linked with zlib support. */
+#undef GG_CONFIG_HAVE_ZLIB
+
+/* Defined if uintX_t types are defined in <stdint.h>. */
+#undef GG_CONFIG_HAVE_STDINT_H
#if HAVE_STDINT_H
-#include <stdint.h>
+# define GG_CONFIG_HAVE_STDINT_H
#endif
-/* Defined if this machine has C99-compiliant vsnprintf(). */
-#ifndef _WIN32
-#define __GG_LIBGADU_HAVE_C99_VSNPRINTF
-#else
-#undef __GG_LIBGADU_HAVE_C99_VSNPRINTF
-#endif
#define vnsprintf g_vnsprintf
-#ifdef _WIN32
-#define random (long) rand
#endif
-
-#endif /* __GG_LIBGADU_CONFIG_H */
diff --git a/libpurple/protocols/gg/lib/libgadu.c b/libpurple/protocols/gg/lib/libgadu.c
index fa26fa1047..b46e046884 100644
--- a/libpurple/protocols/gg/lib/libgadu.c
+++ b/libpurple/protocols/gg/lib/libgadu.c
@@ -29,23 +29,12 @@
*/
#include <sys/types.h>
-#ifdef _WIN32
-# include <io.h>
-# include <fcntl.h>
-# include <errno.h>
-# define SHUT_RDWR SD_BOTH
-#else
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-# ifdef sun
-# include <sys/filio.h>
-# endif
+#ifdef sun
+# include <sys/filio.h>
#endif
#include "compat.h"
#include "libgadu.h"
-#include "libgadu-config.h"
#include "protocol.h"
#include "resolver.h"
#include "libgadu-internal.h"
@@ -55,10 +44,7 @@
#include "message.h"
#include "deflate.h"
-#ifndef _WIN32
-# include <errno.h> /* on Win32 this is included above */
-# include <netdb.h>
-#endif
+#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -1122,7 +1108,6 @@ void gg_logoff(struct gg_session *sess)
sess->resolver_cleanup(&sess->resolver, 1);
if (sess->fd != -1) {
- shutdown(sess->fd, SHUT_RDWR);
close(sess->fd);
sess->fd = -1;
}
diff --git a/libpurple/protocols/gg/lib/libgadu.h b/libpurple/protocols/gg/lib/libgadu.h
index aad79b301e..c9f4f3e0c2 100644
--- a/libpurple/protocols/gg/lib/libgadu.h
+++ b/libpurple/protocols/gg/lib/libgadu.h
@@ -33,7 +33,7 @@
#ifndef __GG_LIBGADU_H
#define __GG_LIBGADU_H
-#ifdef _WIN32
+#if defined(__cplusplus) || defined(_WIN32)
#pragma pack(push, 1)
#endif
@@ -53,6 +53,12 @@ extern "C" {
/* Defined if this machine has gethostbyname_r(). */
#undef GG_CONFIG_HAVE_GETHOSTBYNAME_R
+/* Defined if this machine has _exit(). */
+#undef GG_CONFIG_HAVE__EXIT
+
+/* Defined if libgadu was compiled and linked with fork support. */
+#undef GG_CONFIG_HAVE_FORK
+
/* Defined if libgadu was compiled and linked with pthread support. */
#undef GG_CONFIG_HAVE_PTHREAD
@@ -95,6 +101,8 @@ extern "C" {
/* Defined if uintX_t types are defined in <sys/types.h>. */
#undef GG_CONFIG_HAVE_SYS_TYPES_H
+#include "libgadu-config.h"
+
#ifdef GG_CONFIG_HAVE_OPENSSL
#include <openssl/ssl.h>
#endif
@@ -115,24 +123,12 @@ extern "C" {
# include <sys/types.h>
# else
-#ifndef __AC_STDINT_H
-#define __AC_STDINT_H
-
/* ISO C 9X: 7.18 Integer types <stdint.h> */
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
-#if !defined(__CYGWIN__) && !defined(__SunOS) && !defined(_INCLUDE_HPUX_SOURCE)
-#define __int8_t_defined
-typedef signed char int8_t;
-typedef signed short int16_t;
-typedef signed int int32_t;
-#endif
-
-#endif /* __AC_STDINT_H */
-
# endif
# endif
# endif
@@ -195,7 +191,6 @@ typedef enum {
GG_RESOLVER_DEFAULT = 0, /**< Domyślny sposób rozwiązywania nazw (jeden z poniższych) */
GG_RESOLVER_FORK, /**< Rozwiązywanie nazw bazujące na procesach */
GG_RESOLVER_PTHREAD, /**< Rozwiązywanie nazw bazujące na wątkach */
- GG_RESOLVER_WIN32,
GG_RESOLVER_CUSTOM, /**< Funkcje rozwiązywania nazw dostarczone przed aplikację */
GG_RESOLVER_INVALID = -1 /**< Nieprawidłowy sposób rozwiązywania nazw (wynik \c gg_session_get_resolver) */
} gg_resolver_t;
@@ -1442,7 +1437,6 @@ int gg_pubdir50_handle_reply(struct gg_event *e, const char *packet, int length)
int gg_file_hash_sha1(int fd, uint8_t *result) GG_DEPRECATED;
-#undef printf
#ifdef __GNUC__
char *gg_saprintf(const char *format, ...) __attribute__ ((format (printf, 1, 2))) GG_DEPRECATED;
#else
@@ -2298,14 +2292,14 @@ struct gg_dcc7_dunno1 {
#define GG_DCC7_TIMEOUT_FILE_ACK 300 /* 5 minut */
#define GG_DCC7_TIMEOUT_VOICE_ACK 300 /* 5 minut */
-#ifdef _WIN32
-#pragma pack(pop)
-#endif
-
#ifdef __cplusplus
}
#endif
+#if defined(__cplusplus) || defined(_WIN32)
+#pragma pack(pop)
+#endif
+
#endif /* __GG_LIBGADU_H */
/*
diff --git a/libpurple/protocols/gg/lib/pubdir.c b/libpurple/protocols/gg/lib/pubdir.c
index dad5e44da3..e0f2b2b590 100644
--- a/libpurple/protocols/gg/lib/pubdir.c
+++ b/libpurple/protocols/gg/lib/pubdir.c
@@ -35,7 +35,6 @@
#include <unistd.h>
#include "libgadu.h"
-#include "libgadu-config.h"
/**
* Rejestruje nowego użytkownika.
@@ -194,7 +193,7 @@ struct gg_http *gg_unregister3(uin_t uin, const char *password, const char *toke
return NULL;
}
- __pwd = gg_saprintf("%ld", random());
+ __pwd = gg_saprintf("%d", rand());
__fmpwd = gg_urlencode(password);
__tokenid = gg_urlencode(tokenid);
__tokenval = gg_urlencode(tokenval);
diff --git a/libpurple/protocols/gg/lib/pubdir50.c b/libpurple/protocols/gg/lib/pubdir50.c
index 9222ea56ed..1d1bd55382 100644
--- a/libpurple/protocols/gg/lib/pubdir50.c
+++ b/libpurple/protocols/gg/lib/pubdir50.c
@@ -31,7 +31,6 @@
#include <time.h>
#include "libgadu.h"
-#include "libgadu-config.h"
#include "libgadu-internal.h"
#include "encoding.h"
diff --git a/libpurple/protocols/gg/lib/resolver.c b/libpurple/protocols/gg/lib/resolver.c
index 529b9cb9cb..f1f6b14258 100644
--- a/libpurple/protocols/gg/lib/resolver.c
+++ b/libpurple/protocols/gg/lib/resolver.c
@@ -26,26 +26,21 @@
* \brief Funkcje rozwiązywania nazw
*/
-#ifndef _WIN32
-# include <sys/wait.h>
-# include <netdb.h>
-#endif
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#ifndef _WIN32
-# include <signal.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-#endif
#include "libgadu.h"
-#include "libgadu-config.h"
#include "resolver.h"
#include "compat.h"
#include "session.h"
+#ifdef GG_CONFIG_HAVE_FORK
+#include <sys/wait.h>
+#include <signal.h>
+#endif
+
/** Sposób rozwiązywania nazw serwerów */
static gg_resolver_t gg_global_resolver_type = GG_RESOLVER_DEFAULT;
@@ -249,7 +244,8 @@ int gg_gethostbyname_real(const char *hostname, struct in_addr **result, int *co
#endif /* GG_CONFIG_HAVE_GETHOSTBYNAME_R */
}
-#if defined(GG_CONFIG_HAVE_PTHREAD) || !defined(_WIN32)
+#if defined(GG_CONFIG_HAVE_PTHREAD) || defined(GG_CONFIG_HAVE_FORK)
+
/**
* \internal Rozwiązuje nazwę i zapisuje wynik do podanego desktyptora.
*
@@ -287,7 +283,8 @@ static int gg_resolver_run(int fd, const char *hostname)
return res;
}
-#endif
+
+#endif /* GG_CONFIG_HAVE_PTHREAD || GG_CONFIG_HAVE_FORK */
/**
* \internal Odpowiednik \c gethostbyname zapewniający współbieżność.
@@ -312,6 +309,8 @@ struct in_addr *gg_gethostbyname(const char *hostname)
return result;
}
+#ifdef GG_CONFIG_HAVE_FORK
+
/**
* \internal Struktura przekazywana do wątku rozwiązującego nazwę.
*/
@@ -319,280 +318,6 @@ struct gg_resolver_fork_data {
int pid; /*< Identyfikator procesu */
};
-#ifdef _WIN32
-/**
- * Deal with the fact that you can't select() on a win32 file fd.
- * This makes it practically impossible to tie into purple's event loop.
- *
- * -This is thanks to Tor Lillqvist.
- * XXX - Move this to where the rest of the the win32 compatiblity stuff goes when we push the changes back to libgadu.
- */
-static int
-socket_pipe (int *fds)
-{
- SOCKET temp, socket1 = -1, socket2 = -1;
- struct sockaddr_in saddr;
- int len;
- u_long arg;
- fd_set read_set, write_set;
- struct timeval tv;
-
- temp = socket(AF_INET, SOCK_STREAM, 0);
-
- if (temp == INVALID_SOCKET) {
- goto out0;
- }
-
- arg = 1;
- if (ioctlsocket(temp, FIONBIO, &arg) == SOCKET_ERROR) {
- goto out0;
- }
-
- memset(&saddr, 0, sizeof(saddr));
- saddr.sin_family = AF_INET;
- saddr.sin_port = 0;
- saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
- if (bind(temp, (struct sockaddr *)&saddr, sizeof (saddr))) {
- goto out0;
- }
-
- if (listen(temp, 1) == SOCKET_ERROR) {
- goto out0;
- }
-
- len = sizeof(saddr);
- if (getsockname(temp, (struct sockaddr *)&saddr, &len)) {
- goto out0;
- }
-
- socket1 = socket(AF_INET, SOCK_STREAM, 0);
-
- if (socket1 == INVALID_SOCKET) {
- goto out0;
- }
-
- arg = 1;
- if (ioctlsocket(socket1, FIONBIO, &arg) == SOCKET_ERROR) {
- goto out1;
- }
-
- if (connect(socket1, (struct sockaddr *)&saddr, len) != SOCKET_ERROR ||
- WSAGetLastError() != WSAEWOULDBLOCK) {
- goto out1;
- }
-
- FD_ZERO(&read_set);
- FD_SET(temp, &read_set);
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- if (select(0, &read_set, NULL, NULL, NULL) == SOCKET_ERROR) {
- goto out1;
- }
-
- if (!FD_ISSET(temp, &read_set)) {
- goto out1;
- }
-
- socket2 = accept(temp, (struct sockaddr *) &saddr, &len);
- if (socket2 == INVALID_SOCKET) {
- goto out1;
- }
-
- FD_ZERO(&write_set);
- FD_SET(socket1, &write_set);
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- if (select(0, NULL, &write_set, NULL, NULL) == SOCKET_ERROR) {
- goto out2;
- }
-
- if (!FD_ISSET(socket1, &write_set)) {
- goto out2;
- }
-
- arg = 0;
- if (ioctlsocket(socket1, FIONBIO, &arg) == SOCKET_ERROR) {
- goto out2;
- }
-
- arg = 0;
- if (ioctlsocket(socket2, FIONBIO, &arg) == SOCKET_ERROR) {
- goto out2;
- }
-
- fds[0] = socket1;
- fds[1] = socket2;
-
- closesocket (temp);
-
- return 0;
-
-out2:
- closesocket (socket2);
-out1:
- closesocket (socket1);
-out0:
- closesocket (temp);
- errno = EIO; /* XXX */
-
- return -1;
-}
-#endif
-
-
-
-#ifdef _WIN32
-struct gg_resolve_win32thread_data {
- char *hostname;
- int fd;
-};
-
-static DWORD WINAPI gg_resolve_win32thread_thread(LPVOID arg)
-{
- struct gg_resolve_win32thread_data *d = arg;
- struct in_addr addr_ip[2], *addr_list;
- int addr_count;
-
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread_thread() host: %s, fd: %i called\n", d->hostname, d->fd);
-
- if ((addr_ip[0].s_addr = inet_addr(d->hostname)) == INADDR_NONE) {
- /* W przypadku błędu gg_gethostbyname_real() zwróci -1
- * i nie zmieni &addr. Tam jest już INADDR_NONE,
- * więc nie musimy robić nic więcej. */
- if (gg_gethostbyname_real(d->hostname, &addr_list, &addr_count, 0) == -1)
- {
- addr_list = addr_ip;
- }
- } else {
- addr_list = addr_ip;
- addr_ip[1].s_addr = INADDR_NONE;
- addr_count = 1;
- }
-
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread_thread() count = %d\n", addr_count);
-
- write(d->fd, addr_list, (addr_count+1) * sizeof(struct in_addr));
- close(d->fd);
-
- free(d->hostname);
- d->hostname = NULL;
-
- free(d);
-
- if (addr_list != addr_ip)
- free(addr_list);
-
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread_thread() done\n");
-
- return 0;
-}
-
-
-static int gg_resolve_win32thread(int *fd, void **resolver, const char *hostname)
-{
- struct gg_resolve_win32thread_data *d = NULL;
- HANDLE h;
- DWORD dwTId;
- int pipes[2], new_errno;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_resolve_win32thread(%p, %p, \"%s\");\n", fd, resolver, hostname);
-
- if (!resolver || !fd || !hostname) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() invalid arguments\n");
- errno = EFAULT;
- return -1;
- }
-
- if (socket_pipe(pipes) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() unable to create pipes (errno=%d, %s)\n", errno, strerror(errno));
- return -1;
- }
-
- if (!(d = malloc(sizeof(*d)))) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() out of memory\n");
- new_errno = errno;
- goto cleanup;
- }
-
- d->hostname = NULL;
-
- if (!(d->hostname = strdup(hostname))) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() out of memory\n");
- new_errno = errno;
- goto cleanup;
- }
-
- d->fd = pipes[1];
-
- h = CreateThread(NULL, 0, gg_resolve_win32thread_thread,
- d, 0, &dwTId);
-
- if (h == NULL) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() unable to create thread\n");
- new_errno = errno;
- goto cleanup;
- }
-
- *resolver = h;
- *fd = pipes[0];
-
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() done\n");
-
- return 0;
-
-cleanup:
- if (d) {
- free(d->hostname);
- free(d);
- }
-
- close(pipes[0]);
- close(pipes[1]);
-
- errno = new_errno;
-
- return -1;
-
-}
-
-static void gg_resolve_win32thread_cleanup(void **priv_data, int force)
-{
- struct gg_resolve_win32thread_data *data;
-
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread_cleanup() force: %i called\n", force);
-
- if (priv_data == NULL || *priv_data == NULL)
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread_cleanup() priv_data: NULL\n");
- return;
-
- data = (struct gg_resolve_win32thread_data*) *priv_data;
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread_cleanup() data: %s called\n", data->hostname);
- *priv_data = NULL;
-
- if (force) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread_cleanup() force called\n", force);
- //pthread_cancel(data->thread);
- //pthread_join(data->thread, NULL);
- }
-
- free(data->hostname);
- data->hostname = NULL;
-
- if (data->fd != -1) {
- close(data->fd);
- data->fd = -1;
- }
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread_cleanup() done\n");
- free(data);
-}
-#endif
-
-#ifndef _WIN32
/**
* \internal Rozwiązuje nazwę serwera w osobnym procesie.
*
@@ -644,12 +369,17 @@ static int gg_resolver_fork_start(int *fd, void **priv_data, const char *hostnam
}
if (data->pid == 0) {
+ int status;
+
close(pipes[0]);
- if (gg_resolver_run(pipes[1], hostname) == -1)
- _exit(1);
- else
- _exit(0);
+ status = (gg_resolver_run(pipes[1], hostname) == -1) ? 1 : 0;
+
+#ifdef GG_CONFIG_HAVE__EXIT
+ _exit(status);
+#else
+ exit(status);
+#endif
}
close(pipes[1]);
@@ -698,7 +428,8 @@ static void gg_resolver_fork_cleanup(void **priv_data, int force)
free(data);
}
-#endif
+
+#endif /* GG_CONFIG_HAVE_FORK */
#ifdef GG_CONFIG_HAVE_PTHREAD
@@ -868,25 +599,15 @@ int gg_session_set_resolver(struct gg_session *gs, gg_resolver_t type)
return 0;
}
-#if !defined(GG_CONFIG_HAVE_PTHREAD) || !defined(GG_CONFIG_PTHREAD_DEFAULT)
-# ifdef _WIN32
- type = GG_RESOLVER_WIN32;
-# else
- type = GG_RESOLVER_FORK;
-# endif
-#else
+#if defined(GG_CONFIG_HAVE_PTHREAD) && defined(GG_CONFIG_PTHREAD_DEFAULT)
type = GG_RESOLVER_PTHREAD;
+#elif defined(GG_CONFIG_HAVE_FORK)
+ type = GG_RESOLVER_FORK;
#endif
}
switch (type) {
-#ifdef _WIN32
- case GG_RESOLVER_WIN32:
- gs->resolver_type = type;
- gs->resolver_start = gg_resolve_win32thread;
- gs->resolver_cleanup = gg_resolve_win32thread_cleanup;
- return 0;
-#else
+#ifdef GG_CONFIG_HAVE_FORK
case GG_RESOLVER_FORK:
gs->resolver_type = type;
gs->resolver_start = gg_resolver_fork_start;
@@ -989,25 +710,15 @@ int gg_http_set_resolver(struct gg_http *gh, gg_resolver_t type)
return 0;
}
-#if !defined(GG_CONFIG_HAVE_PTHREAD) || !defined(GG_CONFIG_PTHREAD_DEFAULT)
-# ifdef _WIN32
- type = GG_RESOLVER_WIN32;
-# else
- type = GG_RESOLVER_FORK;
-# endif
-#else
+#if defined(GG_CONFIG_HAVE_PTHREAD) && defined(GG_CONFIG_PTHREAD_DEFAULT)
type = GG_RESOLVER_PTHREAD;
+#elif defined(GG_CONFIG_HAVE_FORK)
+ type = GG_RESOLVER_FORK;
#endif
}
switch (type) {
-#ifdef _WIN32
- case GG_RESOLVER_WIN32:
- gh->resolver_type = type;
- gh->resolver_start = gg_resolve_win32thread;
- gh->resolver_cleanup = gg_resolve_win32thread_cleanup;
- return 0;
-#else
+#ifdef GG_CONFIG_HAVE_FORK
case GG_RESOLVER_FORK:
gh->resolver_type = type;
gh->resolver_start = gg_resolver_fork_start;
@@ -1085,13 +796,7 @@ int gg_global_set_resolver(gg_resolver_t type)
gg_global_resolver_cleanup = NULL;
return 0;
-#ifdef _WIN32
- case GG_RESOLVER_WIN32:
- gg_global_resolver_type = type;
- gg_global_resolver_start = gg_resolve_win32thread;
- gg_global_resolver_cleanup = gg_resolve_win32thread_cleanup;
- return 0;
-#else
+#ifdef GG_CONFIG_HAVE_FORK
case GG_RESOLVER_FORK:
gg_global_resolver_type = type;
gg_global_resolver_start = gg_resolver_fork_start;
diff --git a/libpurple/protocols/gg/lib/resolver.h b/libpurple/protocols/gg/lib/resolver.h
index 80a1adec90..09b230cec8 100644
--- a/libpurple/protocols/gg/lib/resolver.h
+++ b/libpurple/protocols/gg/lib/resolver.h
@@ -19,9 +19,7 @@
#ifndef LIBGADU_RESOLVER_H
#define LIBGADU_RESOLVER_H
-#ifndef _WIN32
-# include <arpa/inet.h>
-#endif
+#include "compat.h"
int gg_gethostbyname_real(const char *hostname, struct in_addr **result, int *count, int pthread);
diff --git a/libpurple/protocols/gg/search.c b/libpurple/protocols/gg/search.c
index 67bb1bda18..d3ec62b06b 100644
--- a/libpurple/protocols/gg/search.c
+++ b/libpurple/protocols/gg/search.c
@@ -135,7 +135,7 @@ void ggp_search_destroy(GGPSearches *searches)
/* guint32 ggp_search_start(PurpleConnection *gc, GGPSearchForm *form) {{{ */
guint32 ggp_search_start(PurpleConnection *gc, GGPSearchForm *form)
{
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc);
gg_pubdir50_t req;
guint seq, offset;
diff --git a/libpurple/protocols/gg/win32-resolver.c b/libpurple/protocols/gg/win32-resolver.c
new file mode 100644
index 0000000000..63a65e0963
--- /dev/null
+++ b/libpurple/protocols/gg/win32-resolver.c
@@ -0,0 +1,322 @@
+/**
+ * @file win32-resolver.c
+ *
+ * purple
+ *
+ * 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 "win32-resolver.h"
+
+#include <errno.h>
+#include <resolver.h>
+#include "debug.h"
+
+#ifndef _WIN32
+#error "win32thread resolver is not supported on current platform"
+#endif
+
+/**
+ * Deal with the fact that you can't select() on a win32 file fd.
+ * This makes it practically impossible to tie into purple's event loop.
+ *
+ * -This is thanks to Tor Lillqvist.
+ */
+static int ggp_resolver_win32thread_socket_pipe(int *fds)
+{
+ SOCKET temp, socket1 = -1, socket2 = -1;
+ struct sockaddr_in saddr;
+ int len;
+ u_long arg;
+ fd_set read_set, write_set;
+ struct timeval tv;
+
+ purple_debug_misc("gg", "ggp_resolver_win32thread_socket_pipe(&%d)\n",
+ *fds);
+
+ temp = socket(AF_INET, SOCK_STREAM, 0);
+
+ if (temp == INVALID_SOCKET) {
+ goto out0;
+ }
+
+ arg = 1;
+ if (ioctlsocket(temp, FIONBIO, &arg) == SOCKET_ERROR) {
+ goto out0;
+ }
+
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.sin_family = AF_INET;
+ saddr.sin_port = 0;
+ saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ if (bind(temp, (struct sockaddr *)&saddr, sizeof (saddr))) {
+ goto out0;
+ }
+
+ if (listen(temp, 1) == SOCKET_ERROR) {
+ goto out0;
+ }
+
+ len = sizeof(saddr);
+ if (getsockname(temp, (struct sockaddr *)&saddr, &len)) {
+ goto out0;
+ }
+
+ socket1 = socket(AF_INET, SOCK_STREAM, 0);
+
+ if (socket1 == INVALID_SOCKET) {
+ goto out0;
+ }
+
+ arg = 1;
+ if (ioctlsocket(socket1, FIONBIO, &arg) == SOCKET_ERROR) {
+ goto out1;
+ }
+
+ if (connect(socket1, (struct sockaddr *)&saddr, len) != SOCKET_ERROR ||
+ WSAGetLastError() != WSAEWOULDBLOCK) {
+ goto out1;
+ }
+
+ FD_ZERO(&read_set);
+ FD_SET(temp, &read_set);
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ if (select(0, &read_set, NULL, NULL, NULL) == SOCKET_ERROR) {
+ goto out1;
+ }
+
+ if (!FD_ISSET(temp, &read_set)) {
+ goto out1;
+ }
+
+ socket2 = accept(temp, (struct sockaddr *) &saddr, &len);
+ if (socket2 == INVALID_SOCKET) {
+ goto out1;
+ }
+
+ FD_ZERO(&write_set);
+ FD_SET(socket1, &write_set);
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ if (select(0, NULL, &write_set, NULL, NULL) == SOCKET_ERROR) {
+ goto out2;
+ }
+
+ if (!FD_ISSET(socket1, &write_set)) {
+ goto out2;
+ }
+
+ arg = 0;
+ if (ioctlsocket(socket1, FIONBIO, &arg) == SOCKET_ERROR) {
+ goto out2;
+ }
+
+ arg = 0;
+ if (ioctlsocket(socket2, FIONBIO, &arg) == SOCKET_ERROR) {
+ goto out2;
+ }
+
+ fds[0] = socket1;
+ fds[1] = socket2;
+
+ closesocket (temp);
+
+ return 0;
+
+out2:
+ closesocket (socket2);
+out1:
+ closesocket (socket1);
+out0:
+ closesocket (temp);
+ errno = EIO; /* XXX */
+
+ return -1;
+}
+
+struct ggp_resolver_win32thread_data {
+ char *hostname;
+ int fd;
+};
+
+/**
+ * Copy-paste from gg_resolver_run().
+ */
+static DWORD WINAPI ggp_resolver_win32thread_thread(LPVOID arg)
+{
+ struct ggp_resolver_win32thread_data *data = arg;
+ struct in_addr addr_ip[2], *addr_list;
+ int addr_count;
+
+ purple_debug_info("gg", "ggp_resolver_win32thread_thread() host: %s, "
+ "fd: %i called\n", data->hostname, data->fd);
+
+ if ((addr_ip[0].s_addr = inet_addr(data->hostname)) == INADDR_NONE) {
+ if (gg_gethostbyname_real(data->hostname, &addr_list,
+ &addr_count, 0) == -1) {
+ addr_list = addr_ip;
+ /* addr_ip[0] już zawiera INADDR_NONE */
+ }
+ } else {
+ addr_list = addr_ip;
+ addr_ip[1].s_addr = INADDR_NONE;
+ addr_count = 1;
+ }
+
+ purple_debug_misc("gg", "ggp_resolver_win32thread_thread() "
+ "count = %d\n", addr_count);
+
+ write(data->fd, addr_list, (addr_count + 1) * sizeof(struct in_addr));
+ close(data->fd);
+
+ free(data->hostname);
+ data->hostname = NULL;
+
+ free(data);
+
+ if (addr_list != addr_ip)
+ free(addr_list);
+
+ purple_debug_misc("gg", "ggp_resolver_win32thread_thread() done\n");
+
+ return 0;
+}
+
+
+int ggp_resolver_win32thread_start(int *fd, void **private_data,
+ const char *hostname)
+{
+ struct ggp_resolver_win32thread_data *data = NULL;
+ HANDLE h;
+ DWORD dwTId;
+ int pipes[2], new_errno;
+
+ purple_debug_info("gg", "ggp_resolver_win32thread_start(%p, %p, "
+ "\"%s\");\n", fd, private_data, hostname);
+
+ if (!private_data || !fd || !hostname) {
+ purple_debug_error("gg", "ggp_resolver_win32thread_start() "
+ "invalid arguments\n");
+ errno = EFAULT;
+ return -1;
+ }
+
+ purple_debug_misc("gg", "ggp_resolver_win32thread_start() creating "
+ "pipes...\n");
+
+ if (ggp_resolver_win32thread_socket_pipe(pipes) == -1) {
+ purple_debug_error("gg", "ggp_resolver_win32thread_start() "
+ "unable to create pipes (errno=%d, %s)\n",
+ errno, strerror(errno));
+ return -1;
+ }
+
+ if (!(data = malloc(sizeof(*data)))) {
+ purple_debug_error("gg", "ggp_resolver_win32thread_start() out "
+ "of memory\n");
+ new_errno = errno;
+ goto cleanup;
+ }
+
+ data->hostname = NULL;
+
+ if (!(data->hostname = strdup(hostname))) {
+ purple_debug_error("gg", "ggp_resolver_win32thread_start() out "
+ "of memory\n");
+ new_errno = errno;
+ goto cleanup;
+ }
+
+ data->fd = pipes[1];
+
+ purple_debug_misc("gg", "ggp_resolver_win32thread_start() creating "
+ "thread...\n");
+
+ h = CreateThread(NULL, 0, ggp_resolver_win32thread_thread, data, 0,
+ &dwTId);
+
+ if (h == NULL) {
+ purple_debug_error("gg", "ggp_resolver_win32thread_start() "
+ "unable to create thread\n");
+ new_errno = errno;
+ goto cleanup;
+ }
+
+ *private_data = h;
+ *fd = pipes[0];
+
+ purple_debug_misc("gg", "ggp_resolver_win32thread_start() done\n");
+
+ return 0;
+
+cleanup:
+ if (data) {
+ free(data->hostname);
+ free(data);
+ }
+
+ close(pipes[0]);
+ close(pipes[1]);
+
+ errno = new_errno;
+
+ return -1;
+
+}
+
+void ggp_resolver_win32thread_cleanup(void **private_data, int force)
+{
+ struct ggp_resolver_win32thread_data *data;
+
+ purple_debug_info("gg", "ggp_resolver_win32thread_cleanup() force: %i "
+ "called\n", force);
+
+ if (private_data == NULL || *private_data == NULL) {
+ purple_debug_error("gg", "ggp_resolver_win32thread_cleanup() "
+ "private_data: NULL\n");
+ return;
+ }
+ return; /* XXX */
+
+ data = (struct ggp_resolver_win32thread_data*) *private_data;
+ purple_debug_misc("gg", "ggp_resolver_win32thread_cleanup() data: "
+ "%s called\n", data->hostname);
+ *private_data = NULL;
+
+ if (force) {
+ purple_debug_misc("gg", "ggp_resolver_win32thread_cleanup() "
+ "force called\n");
+ //pthread_cancel(data->thread);
+ //pthread_join(data->thread, NULL);
+ }
+
+ free(data->hostname);
+ data->hostname = NULL;
+
+ if (data->fd != -1) {
+ close(data->fd);
+ data->fd = -1;
+ }
+ purple_debug_info("gg", "ggp_resolver_win32thread_cleanup() done\n");
+ free(data);
+}
+
+/* vim: set ts=8 sts=0 sw=8 noet: */
diff --git a/libpurple/protocols/gg/win32-resolver.h b/libpurple/protocols/gg/win32-resolver.h
new file mode 100644
index 0000000000..ab20571364
--- /dev/null
+++ b/libpurple/protocols/gg/win32-resolver.h
@@ -0,0 +1,46 @@
+/**
+ * @file win32-resolver.h
+ *
+ * purple
+ *
+ * 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
+ */
+
+#ifndef _PURPLE_GG_WIN32_RESOLVER
+#define _PURPLE_GG_WIN32_RESOLVER
+
+/**
+ * Starts hostname resolving in new win32 thread.
+ *
+ * @param fd Pointer to variable, where pipe descriptor will be saved.
+ * @param private_data Pointer to variable, where pointer to private data will
+ * be saved.
+ * @param hostname Hostname to resolve.
+ */
+int ggp_resolver_win32thread_start(int *fd, void **private_data,
+ const char *hostname);
+
+/**
+ * Cleans up resources after hostname resolving.
+ *
+ * @param private_data Pointer to variable storing pointer to private data.
+ * @param force TRUE, if resources should be cleaned up even, if
+ * resolving process didn't finished.
+ */
+void ggp_resolver_win32thread_cleanup(void **private_data, int force);
+
+#endif /* _PURPLE_GG_WIN32_RESOLVER */
+
+/* vim: set ts=8 sts=0 sw=8 noet: */
diff --git a/libpurple/protocols/irc/cmds.c b/libpurple/protocols/irc/cmds.c
index b725b76e57..5a704a243f 100644
--- a/libpurple/protocols/irc/cmds.c
+++ b/libpurple/protocols/irc/cmds.c
@@ -423,7 +423,7 @@ int irc_cmd_quit(struct irc_conn *irc, const char *cmd, const char *target, cons
irc->quitting = TRUE;
- if (!irc->account->disconnecting)
+ if (!purple_account_is_disconnecting(irc->account))
purple_account_set_status(irc->account, "offline", TRUE, NULL);
}
diff --git a/libpurple/protocols/irc/dcc_send.c b/libpurple/protocols/irc/dcc_send.c
index 7082fd3ade..132bfceef9 100644
--- a/libpurple/protocols/irc/dcc_send.c
+++ b/libpurple/protocols/irc/dcc_send.c
@@ -34,11 +34,12 @@
struct irc_xfer_rx_data {
gchar *ip;
+ unsigned int remote_port;
};
static void irc_dccsend_recv_destroy(PurpleXfer *xfer)
{
- struct irc_xfer_rx_data *xd = xfer->data;
+ struct irc_xfer_rx_data *xd = purple_xfer_get_protocol_data(xfer);
g_free(xd->ip);
g_free(xd);
@@ -51,10 +52,10 @@ static void irc_dccsend_recv_destroy(PurpleXfer *xfer)
*/
static void irc_dccsend_recv_ack(PurpleXfer *xfer, const guchar *data, size_t size) {
guint32 l;
- size_t result;
+ gssize result;
- l = htonl(xfer->bytes_sent);
- result = write(xfer->fd, &l, sizeof(l));
+ l = htonl(purple_xfer_get_bytes_sent(xfer));
+ result = purple_xfer_write(xfer, (guchar *)&l, sizeof(l));
if (result != sizeof(l)) {
purple_debug_error("irc", "unable to send acknowledgement: %s\n", g_strerror(errno));
/* TODO: We should probably close the connection here or something. */
@@ -62,9 +63,9 @@ static void irc_dccsend_recv_ack(PurpleXfer *xfer, const guchar *data, size_t si
}
static void irc_dccsend_recv_init(PurpleXfer *xfer) {
- struct irc_xfer_rx_data *xd = xfer->data;
+ struct irc_xfer_rx_data *xd = purple_xfer_get_protocol_data(xfer);
- purple_xfer_start(xfer, -1, xd->ip, xfer->remote_port);
+ purple_xfer_start(xfer, -1, xd->ip, xd->remote_port);
g_free(xd->ip);
xd->ip = NULL;
}
@@ -114,10 +115,10 @@ void irc_dccsend_recv(struct irc_conn *irc, const char *from, const char *msg) {
if (xfer)
{
xd = g_new0(struct irc_xfer_rx_data, 1);
- xfer->data = xd;
+ purple_xfer_set_protocol_data(xfer, xd);
purple_xfer_set_filename(xfer, filename->str);
- xfer->remote_port = atoi(token[i+1]);
+ xd->remote_port = atoi(token[i+1]);
nip = strtoul(token[i], NULL, 10);
if (nip) {
@@ -157,7 +158,7 @@ struct irc_xfer_send_data {
static void irc_dccsend_send_destroy(PurpleXfer *xfer)
{
- struct irc_xfer_send_data *xd = xfer->data;
+ struct irc_xfer_send_data *xd = purple_xfer_get_protocol_data(xfer);
if (xd == NULL)
return;
@@ -178,7 +179,7 @@ static void irc_dccsend_send_destroy(PurpleXfer *xfer)
static void irc_dccsend_send_read(gpointer data, int source, PurpleInputCondition cond)
{
PurpleXfer *xfer = data;
- struct irc_xfer_send_data *xd = xfer->data;
+ struct irc_xfer_send_data *xd = purple_xfer_get_protocol_data(xfer);
char buffer[64];
int len;
@@ -228,13 +229,13 @@ static void irc_dccsend_send_read(gpointer data, int source, PurpleInputConditio
static gssize irc_dccsend_send_write(const guchar *buffer, size_t size, PurpleXfer *xfer)
{
gssize s;
- int ret;
+ gssize ret;
s = MIN(purple_xfer_get_bytes_remaining(xfer), size);
if (!s)
return 0;
- ret = write(xfer->fd, buffer, s);
+ ret = purple_xfer_write(xfer, buffer, s);
if (ret < 0 && errno == EAGAIN)
ret = 0;
@@ -244,7 +245,7 @@ static gssize irc_dccsend_send_write(const guchar *buffer, size_t size, PurpleXf
static void irc_dccsend_send_connected(gpointer data, int source, PurpleInputCondition cond) {
PurpleXfer *xfer = (PurpleXfer *) data;
- struct irc_xfer_send_data *xd = xfer->data;
+ struct irc_xfer_send_data *xd = purple_xfer_get_protocol_data(xfer);
int conn, flags;
conn = accept(xd->fd, NULL, 0);
@@ -257,8 +258,8 @@ static void irc_dccsend_send_connected(gpointer data, int source, PurpleInputCon
return;
}
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
+ purple_input_remove(purple_xfer_get_watcher(xfer));
+ purple_xfer_set_watcher(xfer, 0);
close(xd->fd);
xd->fd = -1;
@@ -285,7 +286,7 @@ irc_dccsend_network_listen_cb(int sock, gpointer data)
struct in_addr addr;
unsigned short int port;
- xd = xfer->data;
+ xd = purple_xfer_get_protocol_data(xfer);
xd->listen_data = NULL;
if (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL
@@ -294,9 +295,9 @@ irc_dccsend_network_listen_cb(int sock, gpointer data)
return;
}
- xd = xfer->data;
+ xd = purple_xfer_get_protocol_data(xfer);
gc = purple_account_get_connection(purple_xfer_get_account(xfer));
- irc = gc->proto_data;
+ irc = purple_connection_get_protocol_data(gc);
purple_xfer_unref(xfer);
@@ -312,17 +313,17 @@ irc_dccsend_network_listen_cb(int sock, gpointer data)
port = purple_network_get_port_from_fd(sock);
purple_debug_misc("irc", "port is %hu\n", port);
/* Monitor the listening socket */
- xfer->watcher = purple_input_add(sock, PURPLE_INPUT_READ,
- irc_dccsend_send_connected, xfer);
+ purple_xfer_set_watcher(xfer, purple_input_add(sock, PURPLE_INPUT_READ,
+ irc_dccsend_send_connected, xfer));
/* Send the intended recipient the DCC request */
- arg[0] = xfer->who;
+ arg[0] = purple_xfer_get_remote_user(xfer);
inet_aton(purple_network_get_my_ip(irc->fd), &addr);
- arg[1] = tmp = g_strdup_printf("\001DCC SEND \"%s\" %u %hu %" G_GSIZE_FORMAT "\001",
- xfer->filename, ntohl(addr.s_addr),
- port, xfer->size);
+ arg[1] = tmp = g_strdup_printf("\001DCC SEND \"%s\" %u %hu %" G_GOFFSET_FORMAT "\001",
+ purple_xfer_get_filename(xfer), ntohl(addr.s_addr),
+ port, purple_xfer_get_size(xfer));
- irc_cmd_privmsg(gc->proto_data, "msg", NULL, arg);
+ irc_cmd_privmsg(purple_connection_get_protocol_data(gc), "msg", NULL, arg);
g_free(tmp);
}
@@ -331,14 +332,14 @@ irc_dccsend_network_listen_cb(int sock, gpointer data)
*/
static void irc_dccsend_send_init(PurpleXfer *xfer) {
PurpleConnection *gc = purple_account_get_connection(purple_xfer_get_account(xfer));
- struct irc_xfer_send_data *xd = xfer->data;
+ struct irc_xfer_send_data *xd = purple_xfer_get_protocol_data(xfer);
- xfer->filename = g_path_get_basename(xfer->local_filename);
+ purple_xfer_set_filename(xfer, g_path_get_basename(purple_xfer_get_local_filename(xfer)));
purple_xfer_ref(xfer);
/* Create a listening socket */
- xd->listen_data = purple_network_listen_range(0, 0, SOCK_STREAM,
+ xd->listen_data = purple_network_listen_range(0, 0, AF_UNSPEC, SOCK_STREAM, TRUE,
irc_dccsend_network_listen_cb, xfer);
if (xd->listen_data == NULL) {
purple_xfer_unref(xfer);
@@ -359,7 +360,7 @@ PurpleXfer *irc_dccsend_new_xfer(PurpleConnection *gc, const char *who) {
{
xd = g_new0(struct irc_xfer_send_data, 1);
xd->fd = -1;
- xfer->data = xd;
+ purple_xfer_set_protocol_data(xfer, xd);
/* Setup our I/O op functions */
purple_xfer_set_init_fnc(xfer, irc_dccsend_send_init);
diff --git a/libpurple/protocols/irc/irc.c b/libpurple/protocols/irc/irc.c
index 7d523b8074..a4d689d4b3 100644
--- a/libpurple/protocols/irc/irc.c
+++ b/libpurple/protocols/irc/irc.c
@@ -68,11 +68,11 @@ static void irc_view_motd(PurplePluginAction *action)
struct irc_conn *irc;
char *title;
- if (gc == NULL || gc->proto_data == NULL) {
+ if (gc == NULL || purple_connection_get_protocol_data(gc) == NULL) {
purple_debug(PURPLE_DEBUG_ERROR, "irc", "got MOTD request for NULL gc\n");
return;
}
- irc = gc->proto_data;
+ irc = purple_connection_get_protocol_data(gc);
if (irc->motd == NULL) {
purple_notify_error(gc, _("Error displaying MOTD"), _("No MOTD available"),
_("There is no MOTD associated with this connection."));
@@ -98,7 +98,7 @@ static int do_send(struct irc_conn *irc, const char *buf, gsize len)
static int irc_send_raw(PurpleConnection *gc, const char *buf, int len)
{
- struct irc_conn *irc = (struct irc_conn*)gc->proto_data;
+ struct irc_conn *irc = purple_connection_get_protocol_data(gc);
if (len == -1) {
len = strlen(buf);
}
@@ -128,7 +128,7 @@ irc_send_cb(gpointer data, gint source, PurpleInputCondition cond)
PurpleConnection *gc = purple_account_get_connection(irc->account);
gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
g_strerror(errno));
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
@@ -172,7 +172,7 @@ int irc_send_len(struct irc_conn *irc, const char *buf, int buflen)
PurpleConnection *gc = purple_account_get_connection(irc->account);
gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
g_strerror(errno));
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
} else if (ret < buflen) {
@@ -331,16 +331,17 @@ static void irc_login(PurpleAccount *account)
const char *username = purple_account_get_username(account);
gc = purple_account_get_connection(account);
- gc->flags |= PURPLE_CONNECTION_NO_NEWLINES;
+ purple_connection_set_flags(gc, PURPLE_CONNECTION_NO_NEWLINES);
if (strpbrk(username, " \t\v\r\n") != NULL) {
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
_("IRC nick and server may not contain whitespace"));
return;
}
- gc->proto_data = irc = g_new0(struct irc_conn, 1);
+ irc = g_new0(struct irc_conn, 1);
+ purple_connection_set_protocol_data(gc, irc);
irc->fd = -1;
irc->account = account;
irc->outbuf = purple_circ_buffer_new(512);
@@ -365,7 +366,7 @@ static void irc_login(PurpleAccount *account)
purple_account_get_int(account, "port", IRC_DEFAULT_SSL_PORT),
irc_login_cb_ssl, irc_ssl_connect_failure, gc);
} else {
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
_("SSL support unavailable"));
return;
@@ -378,7 +379,7 @@ static void irc_login(PurpleAccount *account)
purple_account_get_int(account, "port", IRC_DEFAULT_PORT),
irc_login_cb, gc) == NULL)
{
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect"));
return;
@@ -390,7 +391,7 @@ static gboolean do_login(PurpleConnection *gc) {
char *buf, *tmp = NULL;
char *server;
const char *username, *realname;
- struct irc_conn *irc = gc->proto_data;
+ struct irc_conn *irc = purple_connection_get_protocol_data(gc);
const char *pass = purple_connection_get_password(gc);
if (pass && *pass) {
@@ -460,12 +461,12 @@ static void irc_login_cb_ssl(gpointer data, PurpleSslConnection *gsc,
static void irc_login_cb(gpointer data, gint source, const gchar *error_message)
{
PurpleConnection *gc = data;
- struct irc_conn *irc = gc->proto_data;
+ struct irc_conn *irc = purple_connection_get_protocol_data(gc);
if (source < 0) {
gchar *tmp = g_strdup_printf(_("Unable to connect: %s"),
error_message);
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
@@ -474,7 +475,7 @@ static void irc_login_cb(gpointer data, gint source, const gchar *error_message)
irc->fd = source;
if (do_login(gc)) {
- gc->inpa = purple_input_add(irc->fd, PURPLE_INPUT_READ, irc_input_cb, gc);
+ irc->inpa = purple_input_add(irc->fd, PURPLE_INPUT_READ, irc_input_cb, gc);
}
}
@@ -483,7 +484,7 @@ irc_ssl_connect_failure(PurpleSslConnection *gsc, PurpleSslErrorType error,
gpointer data)
{
PurpleConnection *gc = data;
- struct irc_conn *irc = gc->proto_data;
+ struct irc_conn *irc = purple_connection_get_protocol_data(gc);
irc->gsc = NULL;
@@ -492,7 +493,7 @@ irc_ssl_connect_failure(PurpleSslConnection *gsc, PurpleSslErrorType error,
static void irc_close(PurpleConnection *gc)
{
- struct irc_conn *irc = gc->proto_data;
+ struct irc_conn *irc = purple_connection_get_protocol_data(gc);
if (irc == NULL)
return;
@@ -500,8 +501,10 @@ static void irc_close(PurpleConnection *gc)
if (irc->gsc || (irc->fd >= 0))
irc_cmd_quit(irc, "quit", NULL, NULL);
- if (gc->inpa)
- purple_input_remove(gc->inpa);
+ if (irc->inpa) {
+ purple_input_remove(irc->inpa);
+ irc->inpa = 0;
+ }
g_free(irc->inbuf);
if (irc->gsc) {
@@ -531,7 +534,7 @@ static void irc_close(PurpleConnection *gc)
static int irc_im_send(PurpleConnection *gc, const char *who, const char *what, PurpleMessageFlags flags)
{
- struct irc_conn *irc = gc->proto_data;
+ struct irc_conn *irc = purple_connection_get_protocol_data(gc);
char *plain;
const char *args[2];
@@ -547,7 +550,7 @@ static int irc_im_send(PurpleConnection *gc, const char *who, const char *what,
static void irc_get_info(PurpleConnection *gc, const char *who)
{
- struct irc_conn *irc = gc->proto_data;
+ struct irc_conn *irc = purple_connection_get_protocol_data(gc);
const char *args[2];
args[0] = who;
args[1] = NULL;
@@ -562,7 +565,7 @@ static void irc_set_status(PurpleAccount *account, PurpleStatus *status)
const char *status_id = purple_status_get_id(status);
g_return_if_fail(gc != NULL);
- irc = gc->proto_data;
+ irc = purple_connection_get_protocol_data(gc);
if (!purple_status_is_active(status))
return;
@@ -579,9 +582,9 @@ static void irc_set_status(PurpleAccount *account, PurpleStatus *status)
}
}
-static void irc_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
+static void irc_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, const char *message)
{
- struct irc_conn *irc = (struct irc_conn *)gc->proto_data;
+ struct irc_conn *irc = purple_connection_get_protocol_data(gc);
struct irc_buddy *ib;
const char *bname = purple_buddy_get_name(buddy);
@@ -606,7 +609,7 @@ static void irc_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup
static void irc_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
{
- struct irc_conn *irc = (struct irc_conn *)gc->proto_data;
+ struct irc_conn *irc = purple_connection_get_protocol_data(gc);
struct irc_buddy *ib;
ib = g_hash_table_lookup(irc->buddies, purple_buddy_get_name(buddy));
@@ -617,9 +620,10 @@ static void irc_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGro
static void read_input(struct irc_conn *irc, int len)
{
+ PurpleConnection *connection = purple_account_get_connection(irc->account);
char *cur, *end;
- irc->account->gc->last_received = time(NULL);
+ purple_connection_update_last_received(connection);
irc->inbufused += len;
irc->inbuf[irc->inbufused] = '\0';
@@ -651,7 +655,7 @@ static void irc_input_cb_ssl(gpointer data, PurpleSslConnection *gsc,
{
PurpleConnection *gc = data;
- struct irc_conn *irc = gc->proto_data;
+ struct irc_conn *irc = purple_connection_get_protocol_data(gc);
int len;
if(!g_list_find(purple_connections_get_all(), gc)) {
@@ -672,12 +676,12 @@ static void irc_input_cb_ssl(gpointer data, PurpleSslConnection *gsc,
} else if (len < 0) {
gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
g_strerror(errno));
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
} else if (len == 0) {
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Server closed the connection"));
return;
@@ -689,7 +693,7 @@ static void irc_input_cb_ssl(gpointer data, PurpleSslConnection *gsc,
static void irc_input_cb(gpointer data, gint source, PurpleInputCondition cond)
{
PurpleConnection *gc = data;
- struct irc_conn *irc = gc->proto_data;
+ struct irc_conn *irc = purple_connection_get_protocol_data(gc);
int len;
if (irc->inbuflen < irc->inbufused + IRC_INITIAL_BUFSIZE) {
@@ -703,12 +707,12 @@ static void irc_input_cb(gpointer data, gint source, PurpleInputCondition cond)
} else if (len < 0) {
gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
g_strerror(errno));
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
} else if (len == 0) {
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Server closed the connection"));
return;
@@ -719,7 +723,7 @@ static void irc_input_cb(gpointer data, gint source, PurpleInputCondition cond)
static void irc_chat_join (PurpleConnection *gc, GHashTable *data)
{
- struct irc_conn *irc = gc->proto_data;
+ struct irc_conn *irc = purple_connection_get_protocol_data(gc);
const char *args[2];
args[0] = g_hash_table_lookup(data, "channel");
@@ -733,7 +737,7 @@ static char *irc_get_chat_name(GHashTable *data) {
static void irc_chat_invite(PurpleConnection *gc, int id, const char *message, const char *name)
{
- struct irc_conn *irc = gc->proto_data;
+ struct irc_conn *irc = purple_connection_get_protocol_data(gc);
PurpleConversation *convo = purple_find_chat(gc, id);
const char *args[2];
@@ -749,7 +753,7 @@ static void irc_chat_invite(PurpleConnection *gc, int id, const char *message, c
static void irc_chat_leave (PurpleConnection *gc, int id)
{
- struct irc_conn *irc = gc->proto_data;
+ struct irc_conn *irc = purple_connection_get_protocol_data(gc);
PurpleConversation *convo = purple_find_chat(gc, id);
const char *args[2];
@@ -764,7 +768,7 @@ static void irc_chat_leave (PurpleConnection *gc, int id)
static int irc_chat_send(PurpleConnection *gc, int id, const char *what, PurpleMessageFlags flags)
{
- struct irc_conn *irc = gc->proto_data;
+ struct irc_conn *irc = purple_connection_get_protocol_data(gc);
PurpleConversation *convo = purple_find_chat(gc, id);
const char *args[2];
char *tmp;
@@ -779,7 +783,7 @@ static int irc_chat_send(PurpleConnection *gc, int id, const char *what, PurpleM
}
#endif
purple_markup_html_to_xhtml(what, NULL, &tmp);
- args[0] = convo->name;
+ args[0] = purple_conversation_get_name(convo);
args[1] = tmp;
irc_cmd_privmsg(irc, "msg", NULL, args);
@@ -818,7 +822,7 @@ static void irc_chat_set_topic(PurpleConnection *gc, int id, const char *topic)
const char *name = NULL;
struct irc_conn *irc;
- irc = gc->proto_data;
+ irc = purple_connection_get_protocol_data(gc);
name = purple_conversation_get_name(purple_find_chat(gc, id));
if (name == NULL)
@@ -836,7 +840,7 @@ static PurpleRoomlist *irc_roomlist_get_list(PurpleConnection *gc)
PurpleRoomlistField *f;
char *buf;
- irc = gc->proto_data;
+ irc = purple_connection_get_protocol_data(gc);
if (irc->roomlist)
purple_roomlist_unref(irc->roomlist);
@@ -863,13 +867,14 @@ static PurpleRoomlist *irc_roomlist_get_list(PurpleConnection *gc)
static void irc_roomlist_cancel(PurpleRoomlist *list)
{
- PurpleConnection *gc = purple_account_get_connection(list->account);
+ PurpleAccount *account = purple_roomlist_get_account(list);
+ PurpleConnection *gc = purple_account_get_connection(account);
struct irc_conn *irc;
if (gc == NULL)
return;
- irc = gc->proto_data;
+ irc = purple_connection_get_protocol_data(gc);
purple_roomlist_set_in_progress(list, FALSE);
@@ -881,13 +886,14 @@ static void irc_roomlist_cancel(PurpleRoomlist *list)
static void irc_keepalive(PurpleConnection *gc)
{
- struct irc_conn *irc = gc->proto_data;
+ struct irc_conn *irc = purple_connection_get_protocol_data(gc);
if ((time(NULL) - irc->recv_time) > PING_TIMEOUT)
irc_cmd_ping(irc, NULL, NULL, NULL);
}
static PurplePluginProtocolInfo prpl_info =
{
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
OPT_PROTO_CHAT_TOPIC | OPT_PROTO_PASSWORD_OPTIONAL |
OPT_PROTO_SLASH_COMMANDS_NATIVE,
NULL, /* user_splits */
@@ -929,7 +935,6 @@ static PurplePluginProtocolInfo prpl_info =
irc_keepalive, /* keepalive */
NULL, /* register_user */
NULL, /* get_cb_info */
- NULL, /* get_cb_away */
NULL, /* alias_buddy */
NULL, /* group_buddy */
NULL, /* rename_group */
@@ -954,15 +959,12 @@ static PurplePluginProtocolInfo prpl_info =
NULL, /* unregister_user */
NULL, /* send_attention */
NULL, /* get_attention_types */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
NULL, /* get_account_text_table */
NULL, /* initiate_media */
NULL, /* get_media_caps */
NULL, /* get_moods */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */
};
static gboolean load_plugin (PurplePlugin *plugin) {
diff --git a/libpurple/protocols/irc/irc.h b/libpurple/protocols/irc/irc.h
index 398e1c2efd..70f58f2df8 100644
--- a/libpurple/protocols/irc/irc.h
+++ b/libpurple/protocols/irc/irc.h
@@ -54,6 +54,7 @@ struct irc_conn {
GHashTable *cmds;
char *server;
int fd;
+ guint inpa;
guint timer;
GHashTable *buddies;
diff --git a/libpurple/protocols/irc/msgs.c b/libpurple/protocols/irc/msgs.c
index 0eb2c5e264..ab4accacd4 100644
--- a/libpurple/protocols/irc/msgs.c
+++ b/libpurple/protocols/irc/msgs.c
@@ -92,7 +92,7 @@ static void irc_connected(struct irc_conn *irc, const char *nick)
/* If we're away then set our away message */
status = purple_account_get_active_status(irc->account);
if (!purple_status_get_type(status) != PURPLE_STATUS_AVAILABLE) {
- PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
prpl_info->set_status(irc->account, status);
}
@@ -419,44 +419,40 @@ void irc_msg_endwhois(struct irc_conn *irc, const char *name, const char *from,
tmp = g_strdup_printf("%s%s%s", tmp2,
(irc->whois.ircop ? _(" <i>(ircop)</i>") : ""),
(irc->whois.identified ? _(" <i>(identified)</i>") : ""));
- purple_notify_user_info_add_pair(user_info, _("Nick"), tmp);
+ purple_notify_user_info_add_pair_html(user_info, _("Nick"), tmp);
g_free(tmp2);
g_free(tmp);
if (irc->whois.away) {
- tmp = g_markup_escape_text(irc->whois.away, strlen(irc->whois.away));
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Away"), irc->whois.away);
g_free(irc->whois.away);
- purple_notify_user_info_add_pair(user_info, _("Away"), tmp);
- g_free(tmp);
}
if (irc->whois.userhost) {
- tmp = g_markup_escape_text(irc->whois.name, strlen(irc->whois.name));
- g_free(irc->whois.name);
- purple_notify_user_info_add_pair(user_info, _("Username"), irc->whois.userhost);
- purple_notify_user_info_add_pair(user_info, _("Real name"), tmp);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Username"), irc->whois.userhost);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Real name"), irc->whois.name);
g_free(irc->whois.userhost);
- g_free(tmp);
+ g_free(irc->whois.name);
}
if (irc->whois.server) {
tmp = g_strdup_printf("%s (%s)", irc->whois.server, irc->whois.serverinfo);
- purple_notify_user_info_add_pair(user_info, _("Server"), tmp);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Server"), tmp);
g_free(tmp);
g_free(irc->whois.server);
g_free(irc->whois.serverinfo);
}
if (irc->whois.channels) {
- purple_notify_user_info_add_pair(user_info, _("Currently on"), irc->whois.channels->str);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Currently on"), irc->whois.channels->str);
g_string_free(irc->whois.channels, TRUE);
}
if (irc->whois.idle) {
gchar *timex = purple_str_seconds_to_string(irc->whois.idle);
- purple_notify_user_info_add_pair(user_info, _("Idle for"), timex);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Idle for"), timex);
g_free(timex);
- purple_notify_user_info_add_pair(user_info,
+ purple_notify_user_info_add_pair_plaintext(user_info,
_("Online since"), purple_date_format_full(localtime(&irc->whois.signon)));
}
- if (!strcmp(irc->whois.nick, "Paco-Paco")) {
- purple_notify_user_info_add_pair(user_info,
+ if (!strcmp(irc->whois.nick, "elb")) {
+ purple_notify_user_info_add_pair_plaintext(user_info,
_("<b>Defining adjective:</b>"), _("Glorious"));
}
@@ -528,16 +524,16 @@ void irc_msg_who(struct irc_conn *irc, const char *name, const char *from, char
g_free(userhost);
g_free(realname);
- flags = cb->flags;
+ flags = purple_conv_chat_cb_get_flags(cb);
/* FIXME: I'm not sure this is really a good idea, now
* that we no longer do periodic WHO. It seems to me
* like it's more likely to be confusing than not.
* Comments? */
if (args[6][0] == 'G' && !(flags & PURPLE_CBFLAGS_AWAY)) {
- purple_conv_chat_user_set_flags(chat, cb->name, flags | PURPLE_CBFLAGS_AWAY);
+ purple_conv_chat_user_set_flags(chat, purple_conv_chat_cb_get_name(cb), flags | PURPLE_CBFLAGS_AWAY);
} else if(args[6][0] == 'H' && (flags & PURPLE_CBFLAGS_AWAY)) {
- purple_conv_chat_user_set_flags(chat, cb->name, flags & ~PURPLE_CBFLAGS_AWAY);
+ purple_conv_chat_user_set_flags(chat, purple_conv_chat_cb_get_name(cb), flags & ~PURPLE_CBFLAGS_AWAY);
}
}
}
@@ -1146,7 +1142,7 @@ void irc_msg_badnick(struct irc_conn *irc, const char *name, const char *from, c
_("Your selected nickname was rejected by the server. It probably contains invalid characters."));
} else {
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
_("Your selected account name was rejected by the server. It probably contains invalid characters."));
}
diff --git a/libpurple/protocols/irc/parse.c b/libpurple/protocols/irc/parse.c
index 83527f0be7..9a8fb8298f 100644
--- a/libpurple/protocols/irc/parse.c
+++ b/libpurple/protocols/irc/parse.c
@@ -171,11 +171,11 @@ static PurpleCmdRet irc_parse_purple_cmd(PurpleConversation *conv, const gchar *
struct irc_conn *irc;
struct _irc_user_cmd *cmdent;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
if (!gc)
return PURPLE_CMD_RET_FAILED;
- irc = gc->proto_data;
+ irc = purple_connection_get_protocol_data(gc);
if ((cmdent = g_hash_table_lookup(irc->cmds, cmd)) == NULL)
return PURPLE_CMD_RET_FAILED;
@@ -670,11 +670,11 @@ void irc_parse_msg(struct irc_conn *irc, char *input)
} else if (!strncmp(input, "ERROR ", 6)) {
if (g_utf8_validate(input, -1, NULL)) {
char *tmp = g_strdup_printf("%s\n%s", _("Disconnected."), input);
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
} else
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Disconnected."));
return;
diff --git a/libpurple/protocols/jabber/Makefile.am b/libpurple/protocols/jabber/Makefile.am
index 9fdd3a9476..0e6d7fa790 100644
--- a/libpurple/protocols/jabber/Makefile.am
+++ b/libpurple/protocols/jabber/Makefile.am
@@ -103,19 +103,25 @@ if STATIC_JABBER
st = -DPURPLE_STATIC_PRPL
noinst_LTLIBRARIES = libjabber.la
-libjabber_la_SOURCES = $(JABBERSOURCES) libxmpp.c
+libjabber_la_SOURCES = $(JABBERSOURCES) libfacebook.c libgtalk.c libxmpp.c
libjabber_la_CFLAGS = $(AM_CFLAGS)
else
st =
-pkg_LTLIBRARIES = libjabber.la libxmpp.la
+pkg_LTLIBRARIES = libjabber.la libfacebook.la libgtalk.la libxmpp.la
libjabber_la_SOURCES = $(JABBERSOURCES)
libjabber_la_LIBADD = $(GLIB_LIBS) $(SASL_LIBS) $(LIBXML_LIBS) $(IDN_LIBS)\
$(FARSIGHT_LIBS) \
$(GSTREAMER_LIBS) \
$(GSTINTERFACES_LIBS)
+libfacebook_la_SOURCES = libfacebook.c
+libfacebook_la_LIBADD = libjabber.la
+
+libgtalk_la_SOURCES = libgtalk.c
+libgtalk_la_LIBADD = libjabber.la
+
libxmpp_la_SOURCES = libxmpp.c
libxmpp_la_LIBADD = libjabber.la
diff --git a/libpurple/protocols/jabber/Makefile.mingw b/libpurple/protocols/jabber/Makefile.mingw
index 4e9f9f9db6..3d19d5d51b 100644
--- a/libpurple/protocols/jabber/Makefile.mingw
+++ b/libpurple/protocols/jabber/Makefile.mingw
@@ -8,6 +8,8 @@ PIDGIN_TREE_TOP := ../../..
include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
TARGET = libjabber
+FACEBOOK_TARGET = libfacebook
+GTALK_TARGET = libgtalk
XMPP_TARGET = libxmpp
TYPE = PLUGIN
@@ -90,6 +92,12 @@ C_SRC = \
OBJECTS = $(C_SRC:%.c=%.o)
+FACEBOOK_C_SRC = libfacebook.c
+FACEBOOK_OBJECTS = $(FACEBOOK_C_SRC:%.c=%.o)
+
+GTALK_C_SRC = libgtalk.c
+GTALK_OBJECTS = $(GTALK_C_SRC:%.c=%.o)
+
XMPP_C_SRC = libxmpp.c
XMPP_OBJECTS = $(XMPP_C_SRC:%.c=%.o)
@@ -129,9 +137,11 @@ include $(PIDGIN_COMMON_RULES)
##
.PHONY: all install clean
-all: $(TARGET).dll $(XMPP_TARGET).dll
+all: $(TARGET).dll $(FACEBOOK_TARGET).dll $(GTALK_TARGET).dll $(XMPP_TARGET).dll
install: all $(DLL_INSTALL_DIR)
+ cp $(FACEBOOK_TARGET).dll $(DLL_INSTALL_DIR)
+ cp $(GTALK_TARGET).dll $(DLL_INSTALL_DIR)
cp $(XMPP_TARGET).dll $(DLL_INSTALL_DIR)
cp $(TARGET).dll $(PURPLE_INSTALL_DIR)
ifeq ($(CYRUS_SASL), 1)
@@ -145,6 +155,12 @@ $(OBJECTS): $(PURPLE_CONFIG_H)
$(TARGET).dll $(TARGET).dll.a: $(PURPLE_DLL).a $(OBJECTS)
$(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--out-implib,$(TARGET).dll.a -o $(TARGET).dll
+$(FACEBOOK_TARGET).dll: $(TARGET).dll.a $(FACEBOOK_OBJECTS)
+ $(CC) -shared $(FACEBOOK_OBJECTS) $(LIB_PATHS) $(LIBS) -ljabber $(DLL_LD_FLAGS) -o $(FACEBOOK_TARGET).dll
+
+$(GTALK_TARGET).dll: $(TARGET).dll.a $(GTALK_OBJECTS)
+ $(CC) -shared $(GTALK_OBJECTS) $(LIB_PATHS) $(LIBS) -ljabber $(DLL_LD_FLAGS) -o $(GTALK_TARGET).dll
+
$(XMPP_TARGET).dll: $(TARGET).dll.a $(XMPP_OBJECTS)
$(CC) -shared $(XMPP_OBJECTS) $(LIB_PATHS) $(LIBS) -ljabber $(DLL_LD_FLAGS) -o $(XMPP_TARGET).dll
@@ -153,6 +169,8 @@ $(XMPP_TARGET).dll: $(TARGET).dll.a $(XMPP_OBJECTS)
##
clean:
rm -f $(OBJECTS) $(TARGET).dll $(TARGET).dll.a
+ rm -f $(FACEBOOK_OBJECTS) $(FACEBOOK_TARGET).dll
+ rm -f $(GTALK_OBJECTS) $(GTALK_TARGET).dll
rm -f $(XMPP_OBJECTS) $(XMPP_TARGET).dll
include $(PIDGIN_COMMON_TARGETS)
diff --git a/libpurple/protocols/jabber/adhoccommands.c b/libpurple/protocols/jabber/adhoccommands.c
index 214f5dfdef..60dc73305d 100644
--- a/libpurple/protocols/jabber/adhoccommands.c
+++ b/libpurple/protocols/jabber/adhoccommands.c
@@ -228,7 +228,8 @@ void jabber_adhoc_execute_action(PurpleBlistNode *node, gpointer data) {
JabberAdHocCommands *cmd = data;
PurpleBuddy *buddy = (PurpleBuddy *) node;
PurpleAccount *account = purple_buddy_get_account(buddy);
- JabberStream *js = purple_account_get_connection(account)->proto_data;
+ PurpleConnection *gc = purple_account_get_connection(account);
+ JabberStream *js = purple_connection_get_protocol_data(gc);
jabber_adhoc_execute(js, cmd);
}
@@ -321,7 +322,7 @@ static void jabber_adhoc_server_execute(PurplePluginAction *action) {
JabberAdHocCommands *cmd = action->user_data;
if(cmd) {
PurpleConnection *gc = (PurpleConnection *) action->context;
- JabberStream *js = gc->proto_data;
+ JabberStream *js = purple_connection_get_protocol_data(gc);
jabber_adhoc_execute(js, cmd);
}
diff --git a/libpurple/protocols/jabber/auth.c b/libpurple/protocols/jabber/auth.c
index dfabe4fb0d..141a91605e 100644
--- a/libpurple/protocols/jabber/auth.c
+++ b/libpurple/protocols/jabber/auth.c
@@ -77,7 +77,7 @@ static void allow_plaintext_auth(PurpleAccount *account)
static void disallow_plaintext_auth(PurpleAccount *account)
{
- purple_connection_error_reason(purple_account_get_connection(account),
+ purple_connection_error(purple_account_get_connection(account),
PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
_("Server requires plaintext authentication over an unencrypted stream"));
}
@@ -145,7 +145,7 @@ jabber_auth_start(JabberStream *js, xmlnode *packet)
mechs = xmlnode_get_child(packet, "mechanisms");
if(!mechs) {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Invalid response from server"));
return;
@@ -186,7 +186,7 @@ jabber_auth_start(JabberStream *js, xmlnode *packet)
if (js->auth_mech == NULL) {
/* Found no good mechanisms... */
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
_("Server does not use any supported authentication method"));
return;
@@ -194,7 +194,7 @@ jabber_auth_start(JabberStream *js, xmlnode *packet)
state = js->auth_mech->start(js, mechs, &response, &msg);
if (state == JABBER_SASL_STATE_FAIL) {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
msg ? msg : _("Unknown Error"));
} else if (response) {
@@ -231,7 +231,7 @@ static void auth_old_result_cb(JabberStream *js, const char *from,
purple_account_set_password(account, NULL);
}
- purple_connection_error_reason(js->gc, reason, msg);
+ purple_connection_error(js->gc, reason, msg);
g_free(msg);
}
}
@@ -247,7 +247,7 @@ static void auth_old_cb(JabberStream *js, const char *from,
if (type == JABBER_IQ_ERROR) {
PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
char *msg = jabber_parse_error(js, packet, &reason);
- purple_connection_error_reason(js->gc, reason, msg);
+ purple_connection_error(js->gc, reason, msg);
g_free(msg);
} else if (type == JABBER_IQ_RESULT) {
query = xmlnode_get_child(packet, "query");
@@ -321,7 +321,7 @@ static void auth_old_cb(JabberStream *js, const char *from,
}
finish_plaintext_authentication(js);
} else {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
_("Server does not use any supported authentication method"));
return;
@@ -345,7 +345,7 @@ void jabber_auth_start_old(JabberStream *js)
if (!jabber_stream_is_ssl(js) &&
g_str_equal("require_tls",
purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
_("You require encryption, but it is not available on this server."));
return;
@@ -394,7 +394,7 @@ jabber_auth_handle_challenge(JabberStream *js, xmlnode *packet)
const char *ns = xmlnode_get_namespace(packet);
if (!purple_strequal(ns, NS_XMPP_SASL)) {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Invalid response from server"));
return;
@@ -405,7 +405,7 @@ jabber_auth_handle_challenge(JabberStream *js, xmlnode *packet)
char *msg = NULL;
JabberSaslState state = js->auth_mech->handle_challenge(js, packet, &response, &msg);
if (state == JABBER_SASL_STATE_FAIL) {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
msg ? msg : _("Invalid challenge from server"));
} else if (response) {
@@ -423,7 +423,7 @@ void jabber_auth_handle_success(JabberStream *js, xmlnode *packet)
const char *ns = xmlnode_get_namespace(packet);
if (!purple_strequal(ns, NS_XMPP_SASL)) {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Invalid response from server"));
return;
@@ -434,12 +434,12 @@ void jabber_auth_handle_success(JabberStream *js, xmlnode *packet)
JabberSaslState state = js->auth_mech->handle_success(js, packet, &msg);
if (state == JABBER_SASL_STATE_FAIL) {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
msg ? msg : _("Invalid response from server"));
return;
} else if (state == JABBER_SASL_STATE_CONTINUE) {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
msg ? msg : _("Server thinks authentication is complete, but client does not"));
return;
@@ -479,11 +479,11 @@ void jabber_auth_handle_failure(JabberStream *js, xmlnode *packet)
msg = jabber_parse_error(js, packet, &reason);
if (!msg) {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Invalid response from server"));
} else {
- purple_connection_error_reason(js->gc, reason, msg);
+ purple_connection_error(js->gc, reason, msg);
g_free(msg);
}
}
diff --git a/libpurple/protocols/jabber/auth_cyrus.c b/libpurple/protocols/jabber/auth_cyrus.c
index 0f9e5cae32..f52e94bb86 100644
--- a/libpurple/protocols/jabber/auth_cyrus.c
+++ b/libpurple/protocols/jabber/auth_cyrus.c
@@ -34,7 +34,7 @@ static void jabber_sasl_build_callbacks(JabberStream *);
static void disallow_plaintext_auth(PurpleAccount *account)
{
- purple_connection_error_reason(purple_account_get_connection(account),
+ purple_connection_error(purple_account_get_connection(account),
PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
_("Server may require plaintext authentication over an unencrypted stream"));
}
@@ -46,7 +46,7 @@ static void start_cyrus_wrapper(JabberStream *js)
JabberSaslState state = jabber_auth_start_cyrus(js, &response, &error);
if (state == JABBER_SASL_STATE_FAIL) {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
error);
g_free(error);
@@ -167,7 +167,6 @@ static void
auth_no_pass_cb(PurpleConnection *gc, PurpleRequestFields *fields)
{
PurpleAccount *account;
- JabberStream *js;
/* The password prompt dialog doesn't get disposed if the account disconnects */
if (!PURPLE_CONNECTION_IS_VALID(gc))
@@ -361,30 +360,30 @@ jabber_sasl_build_callbacks(JabberStream *js)
id = 0;
js->sasl_cb[id].id = SASL_CB_GETREALM;
- js->sasl_cb[id].proc = jabber_sasl_cb_realm;
+ js->sasl_cb[id].proc = (void *)jabber_sasl_cb_realm;
js->sasl_cb[id].context = (void *)js;
id++;
js->sasl_cb[id].id = SASL_CB_AUTHNAME;
- js->sasl_cb[id].proc = jabber_sasl_cb_simple;
+ js->sasl_cb[id].proc = (void *)jabber_sasl_cb_simple;
js->sasl_cb[id].context = (void *)js;
id++;
js->sasl_cb[id].id = SASL_CB_USER;
- js->sasl_cb[id].proc = jabber_sasl_cb_simple;
+ js->sasl_cb[id].proc = (void *)jabber_sasl_cb_simple;
js->sasl_cb[id].context = (void *)js;
id++;
account = purple_connection_get_account(js->gc);
if (purple_account_get_password(account) != NULL ) {
js->sasl_cb[id].id = SASL_CB_PASS;
- js->sasl_cb[id].proc = jabber_sasl_cb_secret;
+ js->sasl_cb[id].proc = (void *)jabber_sasl_cb_secret;
js->sasl_cb[id].context = (void *)js;
id++;
}
js->sasl_cb[id].id = SASL_CB_LOG;
- js->sasl_cb[id].proc = jabber_sasl_cb_log;
+ js->sasl_cb[id].proc = (void *)jabber_sasl_cb_log;
js->sasl_cb[id].context = (void*)js;
id++;
diff --git a/libpurple/protocols/jabber/auth_plain.c b/libpurple/protocols/jabber/auth_plain.c
index 402b0c285a..a609237bbf 100644
--- a/libpurple/protocols/jabber/auth_plain.c
+++ b/libpurple/protocols/jabber/auth_plain.c
@@ -75,7 +75,7 @@ static void allow_plaintext_auth(PurpleAccount *account)
static void disallow_plaintext_auth(PurpleAccount *account)
{
- purple_connection_error_reason(purple_account_get_connection(account),
+ purple_connection_error(purple_account_get_connection(account),
PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
_("Server requires plaintext authentication over an unencrypted stream"));
}
diff --git a/libpurple/protocols/jabber/bosh.c b/libpurple/protocols/jabber/bosh.c
index 2e6acce664..aa568b9096 100644
--- a/libpurple/protocols/jabber/bosh.c
+++ b/libpurple/protocols/jabber/bosh.c
@@ -436,7 +436,7 @@ static gboolean jabber_bosh_connection_error_check(PurpleBOSHConnection *conn, x
if (type != NULL && !strcmp(type, "terminate")) {
conn->state = BOSH_CONN_OFFLINE;
- purple_connection_error_reason(conn->js->gc,
+ purple_connection_error(conn->js->gc,
PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("The BOSH connection manager terminated your session."));
return TRUE;
@@ -539,7 +539,7 @@ static void boot_response_cb(PurpleBOSHConnection *conn, xmlnode *node) {
if (sid) {
conn->sid = g_strdup(sid);
} else {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("No session ID given"));
return;
@@ -556,7 +556,7 @@ static void boot_response_cb(PurpleBOSHConnection *conn, xmlnode *node) {
minor = atoi(dot + 1);
if (major != 1 || minor < 6) {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unsupported version of BOSH protocol"));
return;
@@ -733,7 +733,7 @@ static void http_connection_disconnected(PurpleHTTPConnection *conn)
return;
if (++conn->bosh->failed_connections == MAX_FAILED_CONNECTIONS) {
- purple_connection_error_reason(conn->bosh->js->gc,
+ purple_connection_error(conn->bosh->js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to establish a connection with the server"));
} else {
@@ -939,7 +939,7 @@ connection_established_cb(gpointer data, gint source, const gchar *error)
gchar *tmp;
tmp = g_strdup_printf(_("Unable to establish a connection with the server: %s"),
error);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
}
@@ -965,18 +965,18 @@ static void http_connection_connect(PurpleHTTPConnection *conn)
ssl_connection_error_cb,
conn);
if (!conn->psc) {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
_("Unable to establish SSL connection"));
}
} else {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
_("SSL support unavailable"));
}
} else if (purple_proxy_connect(conn, account, bosh->host, bosh->port,
connection_established_cb, conn) == NULL) {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect"));
}
@@ -1023,7 +1023,7 @@ http_connection_send_cb(gpointer data, gint source, PurpleInputCondition cond)
*/
gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
g_strerror(errno));
- purple_connection_error_reason(conn->bosh->js->gc,
+ purple_connection_error(conn->bosh->js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
tmp);
g_free(tmp);
@@ -1079,7 +1079,7 @@ http_connection_send_request(PurpleHTTPConnection *conn, const GString *req)
*/
gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
g_strerror(errno));
- purple_connection_error_reason(conn->bosh->js->gc,
+ purple_connection_error(conn->bosh->js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
tmp);
g_free(tmp);
diff --git a/libpurple/protocols/jabber/buddy.c b/libpurple/protocols/jabber/buddy.c
index cfe7f3e06d..1aa5cb4702 100644
--- a/libpurple/protocols/jabber/buddy.c
+++ b/libpurple/protocols/jabber/buddy.c
@@ -465,10 +465,22 @@ void jabber_set_info(PurpleConnection *gc, const char *info)
xmlnode *vc_node;
const struct tag_attr *tag_attr;
- /* if we have't grabbed the remote vcard yet, we can't
+ /* if we haven't grabbed the remote vcard yet, we can't
* assume that what we have here is correct */
- if(!js->vcard_fetched)
+ if(!js->vcard_fetched) {
+ PurpleStoredImage *image;
+ g_free(js->initial_avatar_hash);
+ image = purple_buddy_icons_find_account_icon(purple_connection_get_account(gc));
+ if (image != NULL) {
+ js->initial_avatar_hash =
+ jabber_calculate_data_hash(purple_imgstore_get_data(image),
+ purple_imgstore_get_size(image), "sha1");
+ purple_imgstore_unref(image);
+ } else {
+ js->initial_avatar_hash = NULL;
+ }
return;
+ }
if (js->vcard_timer) {
purple_timeout_remove(js->vcard_timer);
@@ -489,7 +501,7 @@ void jabber_set_info(PurpleConnection *gc, const char *info)
vc_node = NULL;
}
- if ((img = purple_buddy_icons_find_account_icon(gc->account))) {
+ if ((img = purple_buddy_icons_find_account_icon(purple_connection_get_account(gc)))) {
gconstpointer avatar_data;
gsize avatar_len;
xmlnode *photo, *binval, *type;
@@ -545,7 +557,7 @@ void jabber_set_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img)
PurpleAccount *account = purple_connection_get_account(gc);
/* Publish the avatar as specified in XEP-0084 */
- jabber_avatar_set(gc->proto_data, img);
+ jabber_avatar_set(purple_connection_get_protocol_data(gc), img);
/* Set the image in our vCard */
jabber_set_info(gc, purple_account_get_user_info(account));
@@ -630,7 +642,7 @@ void jabber_setup_set_info(PurplePluginAction *action)
/*
* Get existing, XML-formatted, user info
*/
- if((user_info = purple_account_get_user_info(gc->account)) != NULL)
+ if((user_info = purple_account_get_user_info(purple_connection_get_account(gc))) != NULL)
x_vc_data = xmlnode_from_str(user_info, -1);
/*
@@ -719,11 +731,16 @@ add_jbr_info(JabberBuddyInfo *jbi, const char *resource,
g_strdup_printf("%s%s%s", jbr->client.name,
(jbr->client.version ? " " : ""),
(jbr->client.version ? jbr->client.version : ""));
- purple_notify_user_info_prepend_pair(user_info, _("Client"), tmp);
+ /* TODO: Check whether it's correct to call prepend_pair_html,
+ or if we should be using prepend_pair_plaintext */
+ purple_notify_user_info_prepend_pair_html(user_info, _("Client"), tmp);
g_free(tmp);
- if (jbr->client.os)
- purple_notify_user_info_prepend_pair(user_info, _("Operating System"), jbr->client.os);
+ if (jbr->client.os) {
+ /* TODO: Check whether it's correct to call prepend_pair_html,
+ or if we should be using prepend_pair_plaintext */
+ purple_notify_user_info_prepend_pair_html(user_info, _("Operating System"), jbr->client.os);
+ }
}
if (jbr && jbr->tz_off != PURPLE_NO_TZ_OFF) {
@@ -739,13 +756,13 @@ add_jbr_info(JabberBuddyInfo *jbi, const char *resource,
jbr->tz_off < 0 ? '-' : '+',
abs(jbr->tz_off / (60*60)),
abs((jbr->tz_off % (60*60)) / 60));
- purple_notify_user_info_prepend_pair(user_info, _("Local Time"), timestamp);
+ purple_notify_user_info_prepend_pair_plaintext(user_info, _("Local Time"), timestamp);
g_free(timestamp);
}
if (jbir && jbir->idle_seconds > 0) {
char *idle = purple_str_seconds_to_string(jbir->idle_seconds);
- purple_notify_user_info_prepend_pair(user_info, _("Idle"), idle);
+ purple_notify_user_info_prepend_pair_plaintext(user_info, _("Idle"), idle);
g_free(idle);
}
@@ -767,15 +784,15 @@ add_jbr_info(JabberBuddyInfo *jbi, const char *resource,
tmp = g_strdup_printf("%s%s%s", (status_name ? status_name : ""),
((status_name && purdy) ? ": " : ""),
(purdy ? purdy : ""));
- purple_notify_user_info_prepend_pair(user_info, _("Status"), tmp);
+ purple_notify_user_info_prepend_pair_html(user_info, _("Status"), tmp);
g_snprintf(priority, sizeof(priority), "%d", jbr->priority);
- purple_notify_user_info_prepend_pair(user_info, _("Priority"), priority);
+ purple_notify_user_info_prepend_pair_plaintext(user_info, _("Priority"), priority);
g_free(tmp);
g_free(purdy);
} else {
- purple_notify_user_info_prepend_pair(user_info, _("Status"), _("Unknown"));
+ purple_notify_user_info_prepend_pair_plaintext(user_info, _("Status"), _("Unknown"));
}
}
@@ -794,7 +811,7 @@ static void jabber_buddy_info_show_if_ready(JabberBuddyInfo *jbi)
resource_name = jabber_get_resource(jbi->jid);
/* If we have one or more pairs from the vcard, put a section break above it */
- if (purple_notify_user_info_get_entries(user_info))
+ if (g_queue_get_length(purple_notify_user_info_get_entries(user_info)))
purple_notify_user_info_prepend_section_break(user_info);
/* Add the information about the user's resource(s) */
@@ -815,8 +832,11 @@ static void jabber_buddy_info_show_if_ready(JabberBuddyInfo *jbi)
add_jbr_info(jbi, jbr->name, jbr);
- if (jbr->name)
- purple_notify_user_info_prepend_pair(user_info, _("Resource"), jbr->name);
+ if (jbr->name) {
+ /* TODO: Check whether it's correct to call prepend_pair_html,
+ or if we should be using prepend_pair_plaintext */
+ purple_notify_user_info_prepend_pair_html(user_info, _("Resource"), jbr->name);
+ }
}
}
@@ -836,7 +856,7 @@ static void jabber_buddy_info_show_if_ready(JabberBuddyInfo *jbi)
title = _("Logged Off");
message = g_strdup_printf(_("%s ago"), last);
}
- purple_notify_user_info_prepend_pair(user_info, title, message);
+ purple_notify_user_info_prepend_pair_plaintext(user_info, title, message);
g_free(last);
g_free(message);
}
@@ -846,7 +866,9 @@ static void jabber_buddy_info_show_if_ready(JabberBuddyInfo *jbi)
g_strdup_printf("%s%s%s", _("Offline"),
jbi->last_message ? ": " : "",
jbi->last_message ? jbi->last_message : "");
- purple_notify_user_info_prepend_pair(user_info, _("Status"), status);
+ /* TODO: Check whether it's correct to call prepend_pair_html,
+ or if we should be using prepend_pair_plaintext */
+ purple_notify_user_info_prepend_pair_html(user_info, _("Status"), status);
g_free(status);
}
}
@@ -1124,7 +1146,7 @@ static void jabber_vcard_parse(JabberStream *js, const char *from,
char *mailto;
escaped = g_markup_escape_text(userid, -1);
mailto = g_strdup_printf("<a href=\"mailto:%s\">%s</a>", escaped, escaped);
- purple_notify_user_info_add_pair(user_info, _("Email"), mailto);
+ purple_notify_user_info_add_pair_html(user_info, _("Email"), mailto);
g_free(mailto);
g_free(escaped);
@@ -1137,7 +1159,7 @@ static void jabber_vcard_parse(JabberStream *js, const char *from,
escaped = g_markup_escape_text(userid, -1);
mailto = g_strdup_printf("<a href=\"mailto:%s\">%s</a>", escaped, escaped);
- purple_notify_user_info_add_pair(user_info, _("Email"), mailto);
+ purple_notify_user_info_add_pair_html(user_info, _("Email"), mailto);
g_free(mailto);
g_free(escaped);
@@ -1182,9 +1204,10 @@ static void jabber_vcard_parse(JabberStream *js, const char *from,
char *hash;
jbi->vcard_imgids = g_slist_prepend(jbi->vcard_imgids, GINT_TO_POINTER(purple_imgstore_add_with_id(g_memdup(data, size), size, "logo.png")));
- img_text = g_strdup_printf("<img id='%d'>", GPOINTER_TO_INT(jbi->vcard_imgids->data));
+ img_text = g_strdup_printf("<img src='" PURPLE_STORED_IMAGE_PROTOCOL "%d'>",
+ GPOINTER_TO_INT(jbi->vcard_imgids->data));
- purple_notify_user_info_add_pair(user_info, (photo ? _("Photo") : _("Logo")), img_text);
+ purple_notify_user_info_add_pair_html(user_info, (photo ? _("Photo") : _("Logo")), img_text);
hash = jabber_calculate_data_hash(data, size, "sha1");
purple_buddy_icons_set_for_user(account, bare_jid, data, size, hash);
@@ -1338,7 +1361,7 @@ static void jabber_last_parse(JabberStream *js, const char *from,
if (jbr ==
jabber_buddy_find_resource(jb, NULL)) {
- purple_prpl_got_user_idle(js->gc->account,
+ purple_prpl_got_user_idle(purple_connection_get_account(js->gc),
buddy_name, jbr->idle, jbr->idle);
}
}
@@ -2233,10 +2256,10 @@ void jabber_user_search(JabberStream *js, const char *directory)
make sure we aren't persisting an old value */
if(js->user_directories && js->user_directories->data &&
!strcmp(directory, js->user_directories->data)) {
- purple_account_set_string(js->gc->account, "user_directory", "");
+ purple_account_set_string(purple_connection_get_account(js->gc), "user_directory", "");
}
else {
- purple_account_set_string(js->gc->account, "user_directory", directory);
+ purple_account_set_string(purple_connection_get_account(js->gc), "user_directory", directory);
}
iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:search");
@@ -2251,7 +2274,7 @@ void jabber_user_search_begin(PurplePluginAction *action)
{
PurpleConnection *gc = (PurpleConnection *) action->context;
JabberStream *js = purple_connection_get_protocol_data(gc);
- const char *def_val = purple_account_get_string(js->gc->account, "user_directory", "");
+ const char *def_val = purple_account_get_string(purple_connection_get_account(js->gc), "user_directory", "");
if(!*def_val && js->user_directories)
def_val = js->user_directories->data;
diff --git a/libpurple/protocols/jabber/caps.c b/libpurple/protocols/jabber/caps.c
index ead8b1a002..c9f5922cca 100644
--- a/libpurple/protocols/jabber/caps.c
+++ b/libpurple/protocols/jabber/caps.c
@@ -794,11 +794,11 @@ static GList* jabber_caps_xdata_get_fields(const xmlnode *x)
for (value = xmlnode_get_child(field, "value"); value; value = xmlnode_get_next_twin(value)) {
gchar *val = xmlnode_get_data(value);
- xdatafield->values = g_list_append(xdatafield->values, val);
+ xdatafield->values = g_list_prepend(xdatafield->values, val);
}
xdatafield->values = g_list_sort(xdatafield->values, (GCompareFunc)strcmp);
- fields = g_list_append(fields, xdatafield);
+ fields = g_list_prepend(fields, xdatafield);
}
fields = g_list_sort(fields, jabber_caps_xdata_field_compare);
@@ -875,21 +875,25 @@ gchar *jabber_caps_calculate_hash(JabberCapsClientInfo *info, const char *hash)
g_free(formtype);
while (fields) {
- GList *value;
JabberDataFormField *field = (JabberDataFormField*)fields->data;
if (!g_str_equal(field->var, "FORM_TYPE")) {
/* Append the "var" attribute */
append_escaped_string(context, field->var);
/* Append <value/> elements' cdata */
- for (value = field->values; value; value = value->next) {
- append_escaped_string(context, value->data);
- g_free(value->data);
+ while (field->values) {
+ append_escaped_string(context, field->values->data);
+ g_free(field->values->data);
+ field->values = g_list_delete_link(field->values,
+ field->values);
}
+ } else {
+ g_list_foreach(field->values, (GFunc) g_free, NULL);
+ g_list_free(field->values);
}
g_free(field->var);
- g_list_free(field->values);
+ g_free(field);
fields = g_list_delete_link(fields, fields);
}
@@ -958,7 +962,7 @@ void jabber_caps_broadcast_change()
const char *prpl_id = purple_account_get_protocol_id(account);
if (g_str_equal("prpl-jabber", prpl_id) && purple_account_is_connected(account)) {
PurpleConnection *gc = purple_account_get_connection(account);
- jabber_presence_send(gc->proto_data, TRUE);
+ jabber_presence_send(purple_connection_get_protocol_data(gc), TRUE);
}
}
diff --git a/libpurple/protocols/jabber/chat.c b/libpurple/protocols/jabber/chat.c
index dfc52d6539..b4a3ec0e89 100644
--- a/libpurple/protocols/jabber/chat.c
+++ b/libpurple/protocols/jabber/chat.c
@@ -70,7 +70,7 @@ GList *jabber_chat_info(PurpleConnection *gc)
GHashTable *jabber_chat_info_defaults(PurpleConnection *gc, const char *chat_name)
{
GHashTable *defaults;
- JabberStream *js = gc->proto_data;
+ JabberStream *js = purple_connection_get_protocol_data(gc);
defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
@@ -146,7 +146,7 @@ JabberChat *jabber_chat_find_by_conv(PurpleConversation *conv)
int id;
if (!gc)
return NULL;
- js = gc->proto_data;
+ js = purple_connection_get_protocol_data(gc);
id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv));
return jabber_chat_find_by_id(js, id);
}
@@ -154,7 +154,7 @@ JabberChat *jabber_chat_find_by_conv(PurpleConversation *conv)
void jabber_chat_invite(PurpleConnection *gc, int id, const char *msg,
const char *name)
{
- JabberStream *js = gc->proto_data;
+ JabberStream *js = purple_connection_get_protocol_data(gc);
JabberChat *chat;
xmlnode *message, *body, *x, *invite;
char *room_jid;
@@ -360,7 +360,7 @@ void jabber_chat_join(PurpleConnection *gc, GHashTable *data)
{
char *room, *server, *handle, *passwd;
JabberID *jid;
- JabberStream *js = gc->proto_data;
+ JabberStream *js = purple_connection_get_protocol_data(gc);
char *tmp;
room = g_hash_table_lookup(data, "room");
@@ -418,10 +418,9 @@ void jabber_chat_join(PurpleConnection *gc, GHashTable *data)
void jabber_chat_leave(PurpleConnection *gc, int id)
{
- JabberStream *js = gc->proto_data;
+ JabberStream *js = purple_connection_get_protocol_data(gc);
JabberChat *chat = jabber_chat_find_by_id(js, id);
-
if(!chat)
return;
@@ -459,7 +458,7 @@ gboolean jabber_chat_find_buddy(PurpleConversation *conv, const char *name)
char *jabber_chat_buddy_real_name(PurpleConnection *gc, int id, const char *who)
{
- JabberStream *js = gc->proto_data;
+ JabberStream *js = purple_connection_get_protocol_data(gc);
JabberChat *chat;
JabberChatMember *jcm;
@@ -887,13 +886,13 @@ static void roomlist_ok_cb(JabberStream *js, const char *server)
char *jabber_roomlist_room_serialize(PurpleRoomlistRoom *room)
{
-
- return g_strdup_printf("%s@%s", (char*)room->fields->data, (char*)room->fields->next->data);
+ GList *fields = purple_roomlist_room_get_fields(room);
+ return g_strdup_printf("%s@%s", (char*)fields->data, (char*)fields->next->data);
}
PurpleRoomlist *jabber_roomlist_get_list(PurpleConnection *gc)
{
- JabberStream *js = gc->proto_data;
+ JabberStream *js = purple_connection_get_protocol_data(gc);
GList *fields = NULL;
PurpleRoomlistField *f;
@@ -928,11 +927,13 @@ PurpleRoomlist *jabber_roomlist_get_list(PurpleConnection *gc)
void jabber_roomlist_cancel(PurpleRoomlist *list)
{
+ PurpleAccount *account;
PurpleConnection *gc;
JabberStream *js;
- gc = purple_account_get_connection(list->account);
- js = gc->proto_data;
+ account = purple_roomlist_get_account(list);
+ gc = purple_account_get_connection(account);
+ js = purple_connection_get_protocol_data(gc);
purple_roomlist_set_in_progress(list, FALSE);
diff --git a/libpurple/protocols/jabber/disco.c b/libpurple/protocols/jabber/disco.c
index e66a0cb05d..1b5a3deac1 100644
--- a/libpurple/protocols/jabber/disco.c
+++ b/libpurple/protocols/jabber/disco.c
@@ -387,7 +387,7 @@ jabber_disco_finish_server_info_result_cb(JabberStream *js)
}
/* If there are manually specified bytestream proxies, query them */
- ft_proxies = purple_account_get_string(js->gc->account, "ft_proxies", NULL);
+ ft_proxies = purple_account_get_string(purple_connection_get_account(js->gc), "ft_proxies", NULL);
if (ft_proxies) {
JabberIq *iq;
JabberBytestreamsStreamhost *sh;
@@ -485,7 +485,7 @@ jabber_disco_stun_srv_resolve_cb(PurpleSrvResponse *resp, int results, gpointer
resp[0].hostname, resp[0].port);
account = purple_connection_get_account(js->gc);
js->stun_query =
- purple_dnsquery_a_account(account, resp[0].hostname, resp[0].port,
+ purple_dnsquery_a(account, resp[0].hostname, resp[0].port,
jabber_disco_stun_lookup_cb, js);
}
}
@@ -524,8 +524,10 @@ jabber_disco_server_info_result_cb(JabberStream *js, const char *from,
if(category && type && !strcmp(category, "pubsub") && !strcmp(type,"pep")) {
PurpleConnection *gc = js->gc;
js->pep = TRUE;
- gc->flags |= PURPLE_CONNECTION_SUPPORT_MOODS |
- PURPLE_CONNECTION_SUPPORT_MOOD_MESSAGES;
+ purple_connection_set_flags(gc,
+ purple_connection_get_flags(gc)
+ | PURPLE_CONNECTION_SUPPORT_MOODS
+ | PURPLE_CONNECTION_SUPPORT_MOOD_MESSAGES);
}
if (!category || strcmp(category, "server"))
continue;
@@ -550,7 +552,7 @@ jabber_disco_server_info_result_cb(JabberStream *js, const char *from,
} else if (purple_network_get_stun_ip() == NULL ||
purple_strequal(purple_network_get_stun_ip(), "")) {
js->srv_query_data =
- purple_srv_resolve_account(
+ purple_srv_resolve(
purple_connection_get_account(js->gc), "stun", "udp",
js->user->domain,
jabber_disco_stun_srv_resolve_cb, js);
diff --git a/libpurple/protocols/jabber/google/gmail.c b/libpurple/protocols/jabber/google/gmail.c
index 5f86b8efac..b5461e8168 100644
--- a/libpurple/protocols/jabber/google/gmail.c
+++ b/libpurple/protocols/jabber/google/gmail.c
@@ -150,7 +150,7 @@ jabber_gmail_poke(JabberStream *js, const char *from, JabberIqType type,
JabberIq *iq;
/* bail if the user isn't interested */
- if (!purple_account_get_check_mail(js->gc->account))
+ if (!purple_account_get_check_mail(purple_connection_get_account(js->gc)))
return;
/* Is this an initial incoming mail notification? If so, send a request for more info */
diff --git a/libpurple/protocols/jabber/google/google_presence.c b/libpurple/protocols/jabber/google/google_presence.c
index c5ec55d946..b0095adcd4 100644
--- a/libpurple/protocols/jabber/google/google_presence.c
+++ b/libpurple/protocols/jabber/google/google_presence.c
@@ -27,12 +27,12 @@ void jabber_google_presence_incoming(JabberStream *js, const char *user, JabberB
if (!js->googletalk)
return;
if (jbr->status && purple_str_has_prefix(jbr->status, "♫ ")) {
- purple_prpl_got_user_status(js->gc->account, user, "tune",
+ purple_prpl_got_user_status(purple_connection_get_account(js->gc), user, "tune",
PURPLE_TUNE_TITLE, jbr->status + strlen("♫ "), NULL);
g_free(jbr->status);
jbr->status = NULL;
} else {
- purple_prpl_got_user_status_deactive(js->gc->account, user, "tune");
+ purple_prpl_got_user_status_deactive(purple_connection_get_account(js->gc), user, "tune");
}
}
diff --git a/libpurple/protocols/jabber/google/jingleinfo.c b/libpurple/protocols/jabber/google/jingleinfo.c
index b49642a40e..81deb9d08c 100644
--- a/libpurple/protocols/jabber/google/jingleinfo.c
+++ b/libpurple/protocols/jabber/google/jingleinfo.c
@@ -117,7 +117,7 @@ jabber_google_jingle_info_common(JabberStream *js, const char *from,
purple_dnsquery_destroy(js->stun_query);
account = purple_connection_get_account(js->gc);
- js->stun_query = purple_dnsquery_a_account(account, host, port,
+ js->stun_query = purple_dnsquery_a(account, host, port,
jabber_google_stun_lookup_cb, js);
}
}
diff --git a/libpurple/protocols/jabber/google/relay.c b/libpurple/protocols/jabber/google/relay.c
index 4b48a8034e..bdc6fd644a 100644
--- a/libpurple/protocols/jabber/google/relay.c
+++ b/libpurple/protocols/jabber/google/relay.c
@@ -137,7 +137,7 @@ jabber_google_do_relay_request(JabberStream *js, GoogleSession *session,
purple_debug_info("jabber",
"sending Google relay request %s to %s\n", request, url);
url_data =
- purple_util_fetch_url_request(url, FALSE, NULL, FALSE, request, FALSE,
+ purple_util_fetch_url_request(NULL, url, FALSE, NULL, FALSE, request, FALSE, -1,
jabber_google_relay_fetch_cb, data);
if (url_data) {
js->google_relay_requests =
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
index 7c5135f1a7..59344f2f29 100644
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -119,7 +119,7 @@ jabber_session_initialized_cb(JabberStream *js, const char *from,
if(js->unregistration)
jabber_unregister_account_cb(js);
} else {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
("Error initializing session"));
}
@@ -153,7 +153,7 @@ static void jabber_bind_result_cb(JabberStream *js, const char *from,
js->user = jabber_id_new(full_jid);
if (js->user == NULL) {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Invalid response from server"));
g_free(full_jid);
@@ -170,7 +170,7 @@ static void jabber_bind_result_cb(JabberStream *js, const char *from,
} else {
PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
char *msg = jabber_parse_error(js, packet, &reason);
- purple_connection_error_reason(js->gc, reason, msg);
+ purple_connection_error(js->gc, reason, msg);
g_free(msg);
return;
@@ -247,14 +247,14 @@ jabber_process_starttls(JabberStream *js, xmlnode *packet)
starttls = xmlnode_get_child(packet, "starttls");
if(xmlnode_get_child(starttls, "required")) {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
_("Server requires TLS/SSL, but no TLS/SSL support was found."));
return TRUE;
}
if (g_str_equal("require_tls", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
_("You require encryption, but no TLS/SSL support was found."));
return TRUE;
@@ -275,7 +275,7 @@ void jabber_stream_features_parse(JabberStream *js, xmlnode *packet)
return;
}
} else if (g_str_equal(connection_security, "require_tls") && !jabber_stream_is_ssl(js)) {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
_("You require encryption, but it is not available on this server."));
return;
@@ -320,7 +320,7 @@ static void jabber_stream_handle_error(JabberStream *js, xmlnode *packet)
PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
char *msg = jabber_parse_error(js, packet, &reason);
- purple_connection_error_reason(js->gc, reason, msg);
+ purple_connection_error(js->gc, reason, msg);
g_free(msg);
}
@@ -407,7 +407,7 @@ static void jabber_send_cb(gpointer data, gint source, PurpleInputCondition cond
else if (ret <= 0) {
gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
g_strerror(errno));
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
@@ -440,10 +440,10 @@ static gboolean do_jabber_send_raw(JabberStream *js, const char *data, int len)
* we're disconnecting, don't generate (possibly another) error that
* (for some UIs) would mask the first.
*/
- if (!account->disconnecting) {
+ if (!purple_account_is_disconnecting(account)) {
gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
g_strerror(errno));
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
}
@@ -544,7 +544,7 @@ void jabber_send_raw(JabberStream *js, const char *data, int len)
purple_debug_error("jabber",
"sasl_encode error %d: %s\n", rc,
sasl_errdetail(js->sasl));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
error);
g_free(error);
@@ -616,8 +616,8 @@ void jabber_send(JabberStream *js, xmlnode *packet)
static gboolean jabber_keepalive_timeout(PurpleConnection *gc)
{
- JabberStream *js = gc->proto_data;
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ JabberStream *js = purple_connection_get_protocol_data(gc);
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Ping timed out"));
js->keepalive_timeout = 0;
return FALSE;
@@ -642,7 +642,7 @@ jabber_recv_cb_ssl(gpointer data, PurpleSslConnection *gsc,
PurpleInputCondition cond)
{
PurpleConnection *gc = data;
- JabberStream *js = gc->proto_data;
+ JabberStream *js = purple_connection_get_protocol_data(gc);
int len;
static char buf[4096];
@@ -653,7 +653,7 @@ jabber_recv_cb_ssl(gpointer data, PurpleSslConnection *gsc,
}
while((len = purple_ssl_read(gsc, buf, sizeof(buf) - 1)) > 0) {
- gc->last_received = time(NULL);
+ purple_connection_update_last_received(gc);
buf[len] = '\0';
purple_debug_info("jabber", "Recv (ssl)(%d): %s\n", len, buf);
jabber_parser_process(js, buf, len);
@@ -670,7 +670,7 @@ jabber_recv_cb_ssl(gpointer data, PurpleSslConnection *gsc,
else
tmp = g_strdup_printf(_("Lost connection with server: %s"),
g_strerror(errno));
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
}
@@ -687,7 +687,7 @@ jabber_recv_cb(gpointer data, gint source, PurpleInputCondition condition)
g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc));
if((len = read(js->fd, buf, sizeof(buf) - 1)) > 0) {
- gc->last_received = time(NULL);
+ purple_connection_update_last_received(gc);
#ifdef HAVE_CYRUS_SASL
if (js->sasl_maxbuf > 0) {
const char *out;
@@ -702,7 +702,7 @@ jabber_recv_cb(gpointer data, gint source, PurpleInputCondition condition)
purple_debug_error("jabber",
"sasl_decode_error %d: %s\n", rc,
sasl_errdetail(js->sasl));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
error);
} else if (olen > 0) {
@@ -728,7 +728,7 @@ jabber_recv_cb(gpointer data, gint source, PurpleInputCondition condition)
else
tmp = g_strdup_printf(_("Lost connection with server: %s"),
g_strerror(errno));
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
}
@@ -747,7 +747,7 @@ jabber_login_callback_ssl(gpointer data, PurpleSslConnection *gsc,
g_return_if_reached();
}
- js = gc->proto_data;
+ js = purple_connection_get_protocol_data(gc);
if(js->state == JABBER_STREAM_CONNECTING)
jabber_send_raw(js, "<?xml version='1.0' ?>", -1);
@@ -789,7 +789,7 @@ txt_resolved_cb(GList *responses, gpointer data)
if (!found) {
purple_debug_warning("jabber", "Unable to find alternative XMPP connection "
"methods after failing to connect directly.\n");
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect"));
return;
@@ -813,7 +813,7 @@ jabber_login_callback(gpointer data, gint source, const gchar *error)
try_srv_connect(js);
} else {
purple_debug_info("jabber","Couldn't connect directly to %s. Trying to find alternative connection methods, like BOSH.\n", js->user->domain);
- js->srv_query_data = purple_txt_resolve_account(
+ js->srv_query_data = purple_txt_resolve(
purple_connection_get_account(gc), "_xmppconnect",
js->user->domain, txt_resolved_cb, js);
}
@@ -829,7 +829,7 @@ jabber_login_callback(gpointer data, gint source, const gchar *error)
jabber_send_raw(js, "<?xml version='1.0' ?>", -1);
jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING);
- gc->inpa = purple_input_add(js->fd, PURPLE_INPUT_READ, jabber_recv_cb, gc);
+ js->inpa = purple_input_add(js->fd, PURPLE_INPUT_READ, jabber_recv_cb, gc);
}
static void
@@ -842,7 +842,7 @@ jabber_ssl_connect_failure(PurpleSslConnection *gsc, PurpleSslErrorType error,
/* If the connection is already disconnected, we don't need to do anything else */
g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc));
- js = gc->proto_data;
+ js = purple_connection_get_protocol_data(gc);
js->gsc = NULL;
purple_connection_ssl_error (gc, error);
@@ -850,9 +850,9 @@ jabber_ssl_connect_failure(PurpleSslConnection *gsc, PurpleSslErrorType error,
static void tls_init(JabberStream *js)
{
- purple_input_remove(js->gc->inpa);
- js->gc->inpa = 0;
- js->gsc = purple_ssl_connect_with_host_fd(js->gc->account, js->fd,
+ purple_input_remove(js->inpa);
+ js->inpa = 0;
+ js->gsc = purple_ssl_connect_with_host_fd(purple_connection_get_account(js->gc), js->fd,
jabber_login_callback_ssl, jabber_ssl_connect_failure, js->certificate_CN, js->gc);
/* The fd is no longer our concern */
js->fd = -1;
@@ -874,7 +874,7 @@ static gboolean jabber_login_connect(JabberStream *js, const char *domain, const
if (purple_proxy_connect(js->gc, purple_connection_get_account(js->gc),
host, port, jabber_login_callback, js->gc) == NULL) {
if (fatal_failure) {
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect"));
}
@@ -928,7 +928,8 @@ jabber_stream_new(PurpleAccount *account)
gchar *user;
gchar *slash;
- js = gc->proto_data = g_new0(JabberStream, 1);
+ js = g_new0(JabberStream, 1);
+ purple_connection_set_protocol_data(gc, js);
js->gc = gc;
js->fd = -1;
@@ -940,7 +941,7 @@ jabber_stream_new(PurpleAccount *account)
js->user = jabber_id_new(user);
if (!js->user) {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
_("Invalid XMPP ID"));
g_free(user);
@@ -949,7 +950,7 @@ jabber_stream_new(PurpleAccount *account)
}
if (!js->user->node || *(js->user->node) == '\0') {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
_("Invalid XMPP ID. Username portion must be set."));
g_free(user);
@@ -958,7 +959,7 @@ jabber_stream_new(PurpleAccount *account)
}
if (!js->user->domain || *(js->user->domain) == '\0') {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
_("Invalid XMPP ID. Domain must be set."));
g_free(user);
@@ -978,7 +979,7 @@ jabber_stream_new(PurpleAccount *account)
g_free(user);
if (!js->user_jb) {
/* This basically *can't* fail, but for good measure... */
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
_("Invalid XMPP ID"));
/* Destroying the connection will free the JabberStream */
@@ -1037,7 +1038,7 @@ jabber_stream_connect(JabberStream *js)
if (js->bosh)
jabber_bosh_connection_connect(js->bosh);
else {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
_("Malformed BOSH URL"));
}
@@ -1054,12 +1055,12 @@ jabber_stream_connect(JabberStream *js)
purple_account_get_int(account, "port", 5223),
jabber_login_callback_ssl, jabber_ssl_connect_failure, gc);
if (!js->gsc) {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
_("Unable to establish SSL connection"));
}
} else {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
_("SSL support unavailable"));
}
@@ -1073,7 +1074,7 @@ jabber_stream_connect(JabberStream *js)
jabber_login_connect(js, js->user->domain, connect_server,
purple_account_get_int(account, "port", 5222), TRUE);
} else {
- js->srv_query_data = purple_srv_resolve_account(account, "xmpp-client",
+ js->srv_query_data = purple_srv_resolve(account, "xmpp-client",
"tcp", js->user->domain, srv_resolved_cb, js);
}
}
@@ -1085,8 +1086,7 @@ jabber_login(PurpleAccount *account)
JabberStream *js;
PurpleStoredImage *image;
- gc->flags |= PURPLE_CONNECTION_HTML |
- PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY;
+ purple_connection_set_flags(gc, PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY);
js = jabber_stream_new(account);
if (js == NULL)
return;
@@ -1144,8 +1144,7 @@ jabber_registration_result_cb(JabberStream *js, const char *from,
if(js->registration) {
buf = g_strdup_printf(_("Registration of %s@%s successful"),
js->user->node, js->user->domain);
- if(account->registration_cb)
- (account->registration_cb)(account, TRUE, account->registration_cb_user_data);
+ purple_account_register_completed(account, TRUE);
} else {
g_return_if_fail(to != NULL);
buf = g_strdup_printf(_("Registration to %s successful"),
@@ -1163,8 +1162,7 @@ jabber_registration_result_cb(JabberStream *js, const char *from,
purple_notify_error(NULL, _("Registration Failed"),
_("Registration Failed"), msg);
g_free(msg);
- if(account->registration_cb)
- (account->registration_cb)(account, FALSE, account->registration_cb_user_data);
+ purple_account_register_completed(account, FALSE);
}
g_free(to);
if(js->registration)
@@ -1264,7 +1262,7 @@ jabber_register_cb(JabberRegisterCBData *cbdata, PurpleRequestFields *fields)
cbdata->js->user->node = g_strdup(value);
}
if(cbdata->js->registration && !strcmp(id, "password"))
- purple_account_set_password(cbdata->js->gc->account, value);
+ purple_account_set_password(purple_connection_get_account(cbdata->js->gc), value);
}
}
}
@@ -1273,7 +1271,7 @@ jabber_register_cb(JabberRegisterCBData *cbdata, PurpleRequestFields *fields)
username = g_strdup_printf("%s@%s%s%s", cbdata->js->user->node, cbdata->js->user->domain,
cbdata->js->user->resource ? "/" : "",
cbdata->js->user->resource ? cbdata->js->user->resource : "");
- purple_account_set_username(cbdata->js->gc->account, username);
+ purple_account_set_username(purple_connection_get_account(cbdata->js->gc), username);
g_free(username);
}
@@ -1288,8 +1286,7 @@ jabber_register_cancel_cb(JabberRegisterCBData *cbdata, PurpleRequestFields *fie
{
PurpleAccount *account = purple_connection_get_account(cbdata->js->gc);
if(account && cbdata->js->registration) {
- if(account->registration_cb)
- (account->registration_cb)(account, FALSE, account->registration_cb_user_data);
+ purple_account_register_completed(account, FALSE);
jabber_connection_schedule_close(cbdata->js);
}
g_free(cbdata->who);
@@ -1358,8 +1355,7 @@ void jabber_register_parse(JabberStream *js, const char *from, JabberIqType type
if(js->registration) {
purple_notify_error(NULL, _("Already Registered"),
_("Already Registered"), NULL);
- if(account->registration_cb)
- (account->registration_cb)(account, FALSE, account->registration_cb_user_data);
+ purple_account_register_completed(account, FALSE);
jabber_connection_schedule_close(js);
return;
}
@@ -1380,8 +1376,8 @@ void jabber_register_parse(JabberStream *js, const char *from, JabberIqType type
if(js->registration) {
js->gc->wants_to_die = TRUE;
- if(account->registration_cb) /* succeeded, but we have no login info */
- (account->registration_cb)(account, TRUE, account->registration_cb_user_data);
+ /* succeeded, but we have no login info */
+ purple_account_register_completed(account, TRUE);
jabber_connection_schedule_close(js);
}
return;
@@ -1422,7 +1418,7 @@ void jabber_register_parse(JabberStream *js, const char *from, JabberIqType type
if((node = xmlnode_get_child(query, "name"))) {
if(js->registration)
field = purple_request_field_string_new("name", _("Name"),
- purple_account_get_alias(js->gc->account), FALSE);
+ purple_account_get_alias(purple_connection_get_account(js->gc)), FALSE);
else {
char *data = xmlnode_get_data(node);
field = purple_request_field_string_new("name", _("Name"), data, FALSE);
@@ -1556,17 +1552,17 @@ void jabber_unregister_account(PurpleAccount *account, PurpleAccountUnregistrati
PurpleConnection *gc = purple_account_get_connection(account);
JabberStream *js;
- if(gc->state != PURPLE_CONNECTED) {
- if(gc->state != PURPLE_CONNECTING)
+ if (purple_connection_get_state(gc) != PURPLE_CONNECTED) {
+ if (purple_connection_get_state(gc) != PURPLE_CONNECTING)
jabber_login(account);
- js = gc->proto_data;
+ js = purple_connection_get_protocol_data(gc);
js->unregistration = TRUE;
js->unregistration_cb = cb;
js->unregistration_user_data = user_data;
return;
}
- js = gc->proto_data;
+ js = purple_connection_get_protocol_data(gc);
if (js->unregistration) {
purple_debug_error("jabber", "Unregistration in process; ignoring duplicate request.\n");
@@ -1598,13 +1594,15 @@ void jabber_close(PurpleConnection *gc)
jabber_send_raw(js, "</stream:stream>", -1);
if (js->srv_query_data)
- purple_srv_cancel(js->srv_query_data);
+ purple_srv_txt_query_destroy(js->srv_query_data);
if(js->gsc) {
purple_ssl_close(js->gsc);
} else if (js->fd > 0) {
- if(js->gc->inpa)
- purple_input_remove(js->gc->inpa);
+ if(js->inpa) {
+ purple_input_remove(js->inpa);
+ js->inpa = 0;
+ }
close(js->fd);
}
@@ -1726,7 +1724,7 @@ void jabber_close(PurpleConnection *gc)
g_free(js);
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
}
void jabber_stream_set_state(JabberStream *js, JabberStreamState state)
@@ -1780,7 +1778,7 @@ char *jabber_get_next_id(JabberStream *js)
void jabber_idle_set(PurpleConnection *gc, int idle)
{
- JabberStream *js = gc->proto_data;
+ JabberStream *js = purple_connection_get_protocol_data(gc);
js->idle = idle ? time(NULL) - idle : idle;
@@ -1871,8 +1869,7 @@ static void jabber_blocklist_parse(JabberStream *js, const char *from,
return;
/* This is the only privacy method supported by XEP-0191 */
- if (account->perm_deny != PURPLE_PRIVACY_DENY_USERS)
- account->perm_deny = PURPLE_PRIVACY_DENY_USERS;
+ purple_account_set_privacy_type(account, PURPLE_PRIVACY_DENY_USERS);
/*
* TODO: When account->deny is something more than a hash table, this can
@@ -2133,7 +2130,7 @@ const char* jabber_list_emblem(PurpleBuddy *b)
if(!gc)
return NULL;
- js = gc->proto_data;
+ js = purple_connection_get_protocol_data(gc);
if(js)
jb = jabber_buddy_find(js, purple_buddy_get_name(b), FALSE);
@@ -2174,8 +2171,8 @@ char *jabber_status_text(PurpleBuddy *b)
PurpleAccount *account = purple_buddy_get_account(b);
PurpleConnection *gc = purple_account_get_connection(account);
- if (gc && gc->proto_data)
- jb = jabber_buddy_find(gc->proto_data, purple_buddy_get_name(b), FALSE);
+ if (gc && purple_connection_get_protocol_data(gc))
+ jb = jabber_buddy_find(purple_connection_get_protocol_data(gc), purple_buddy_get_name(b), FALSE);
if(jb && !PURPLE_BUDDY_IS_ONLINE(b) && (jb->subscription & JABBER_SUB_PENDING || !(jb->subscription & JABBER_SUB_TO))) {
ret = g_strdup(_("Not Authorized"));
@@ -2225,7 +2222,7 @@ jabber_tooltip_add_resource_text(JabberBuddyResource *jbr,
label = g_strdup_printf("%s%s", _("Status"), (res ? res : ""));
value = g_strdup_printf("%s%s%s", state, (text ? ": " : ""), (text ? text : ""));
- purple_notify_user_info_add_pair(user_info, label, value);
+ purple_notify_user_info_add_pair_html(user_info, label, value);
g_free(label);
g_free(value);
g_free(text);
@@ -2238,7 +2235,7 @@ jabber_tooltip_add_resource_text(JabberBuddyResource *jbr,
gchar *idle_str =
purple_str_seconds_to_string(time(NULL) - jbr->idle);
label = g_strdup_printf("%s%s", _("Idle"), (res ? res : ""));
- purple_notify_user_info_add_pair(user_info, label, idle_str);
+ purple_notify_user_info_add_pair_plaintext(user_info, label, idle_str);
g_free(idle_str);
g_free(label);
}
@@ -2250,6 +2247,7 @@ void jabber_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboole
JabberBuddy *jb;
PurpleAccount *account;
PurpleConnection *gc;
+ JabberStream *js;
g_return_if_fail(b != NULL);
@@ -2258,9 +2256,11 @@ void jabber_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboole
gc = purple_account_get_connection(account);
g_return_if_fail(gc != NULL);
- g_return_if_fail(gc->proto_data != NULL);
- jb = jabber_buddy_find(gc->proto_data, purple_buddy_get_name(b), FALSE);
+ js = purple_connection_get_protocol_data(gc);
+ g_return_if_fail(js != NULL);
+
+ jb = jabber_buddy_find(js, purple_buddy_get_name(b), FALSE);
if(jb) {
JabberBuddyResource *jbr = NULL;
@@ -2310,10 +2310,10 @@ void jabber_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboole
char *moodplustext =
g_strdup_printf("%s (%s)", description ? _(description) : mood, moodtext);
- purple_notify_user_info_add_pair(user_info, _("Mood"), moodplustext);
+ purple_notify_user_info_add_pair_html(user_info, _("Mood"), moodplustext);
g_free(moodplustext);
} else
- purple_notify_user_info_add_pair(user_info, _("Mood"),
+ purple_notify_user_info_add_pair_html(user_info, _("Mood"),
description ? _(description) : mood);
}
if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_TUNE)) {
@@ -2323,7 +2323,7 @@ void jabber_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboole
const char *album = purple_status_get_attr_string(tune, PURPLE_TUNE_ALBUM);
char *playing = purple_util_format_song_info(title, artist, album, NULL);
if (playing) {
- purple_notify_user_info_add_pair(user_info, _("Now Listening"), playing);
+ purple_notify_user_info_add_pair_html(user_info, _("Now Listening"), playing);
g_free(playing);
}
}
@@ -2344,12 +2344,12 @@ void jabber_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboole
sub = _("None");
}
- purple_notify_user_info_add_pair(user_info, _("Subscription"), sub);
+ purple_notify_user_info_add_pair_html(user_info, _("Subscription"), sub);
}
if(!PURPLE_BUDDY_IS_ONLINE(b) && jb->error_msg) {
- purple_notify_user_info_add_pair(user_info, _("Error"), jb->error_msg);
+ purple_notify_user_info_add_pair_html(user_info, _("Error"), jb->error_msg);
}
}
}
@@ -2484,7 +2484,7 @@ jabber_password_change_result_cb(JabberStream *js, const char *from,
purple_notify_info(js->gc, _("Password Changed"), _("Password Changed"),
_("Your password has been changed."));
- purple_account_set_password(js->gc->account, (char *)data);
+ purple_account_set_password(purple_connection_get_account(js->gc), (char *)data);
} else {
char *msg = jabber_parse_error(js, packet, NULL);
@@ -2531,7 +2531,7 @@ static void jabber_password_change(PurplePluginAction *action)
{
PurpleConnection *gc = (PurpleConnection *) action->context;
- JabberStream *js = gc->proto_data;
+ JabberStream *js = purple_connection_get_protocol_data(gc);
PurpleRequestFields *fields;
PurpleRequestFieldGroup *group;
PurpleRequestField *field;
@@ -2563,7 +2563,7 @@ static void jabber_password_change(PurplePluginAction *action)
GList *jabber_actions(PurplePlugin *plugin, gpointer context)
{
PurpleConnection *gc = (PurpleConnection *) context;
- JabberStream *js = gc->proto_data;
+ JabberStream *js = purple_connection_get_protocol_data(gc);
GList *m = NULL;
PurplePluginAction *act;
@@ -2634,7 +2634,7 @@ PurpleChat *jabber_find_blist_chat(PurpleAccount *account, const char *name)
void jabber_convo_closed(PurpleConnection *gc, const char *who)
{
- JabberStream *js = gc->proto_data;
+ JabberStream *js = purple_connection_get_protocol_data(gc);
JabberID *jid;
JabberBuddy *jb;
JabberBuddyResource *jbr;
@@ -2739,8 +2739,8 @@ char *jabber_parse_error(JabberStream *js,
} else if(xmlnode_get_child(packet, "not-authorized")) {
SET_REASON(PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED);
/* Clear the pasword if it isn't being saved */
- if (!purple_account_get_remember_password(js->gc->account))
- purple_account_set_password(js->gc->account, NULL);
+ if (!purple_account_get_remember_password(purple_connection_get_account(js->gc)))
+ purple_account_set_password(purple_connection_get_account(js->gc), NULL);
text = _("Not Authorized");
} else if(xmlnode_get_child(packet, "temporary-auth-failure")) {
text = _("Temporary Authentication Failure");
@@ -2997,7 +2997,7 @@ static PurpleCmdRet jabber_cmd_chat_invite(PurpleConversation *conv,
if(!args || !args[0])
return PURPLE_CMD_RET_FAILED;
- jabber_chat_invite(purple_conversation_get_gc(conv),
+ jabber_chat_invite(purple_conversation_get_connection(conv),
purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), args[1] ? args[1] : "",
args[0]);
@@ -3044,7 +3044,7 @@ static PurpleCmdRet jabber_cmd_chat_join(PurpleConversation *conv,
if (args[1])
g_hash_table_insert(components, "password", args[1]);
- jabber_chat_join(purple_conversation_get_gc(conv), components);
+ jabber_chat_join(purple_conversation_get_connection(conv), components);
g_hash_table_destroy(components);
jabber_id_free(jid);
@@ -3078,7 +3078,7 @@ static PurpleCmdRet jabber_cmd_chat_msg(PurpleConversation *conv,
who = g_strdup_printf("%s@%s/%s", chat->room, chat->server, args[0]);
- jabber_message_send_im(purple_conversation_get_gc(conv), who, args[1], 0);
+ jabber_message_send_im(purple_conversation_get_connection(conv), who, args[1], 0);
g_free(who);
return PURPLE_CMD_RET_OK;
@@ -3159,13 +3159,14 @@ static gboolean _jabber_send_buzz(JabberStream *js, const char *username, char *
static PurpleCmdRet jabber_cmd_buzz(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- JabberStream *js = conv->account->gc->proto_data;
+ PurpleAccount *account = purple_conversation_get_account(conv);
+ JabberStream *js = purple_connection_get_protocol_data(purple_account_get_connection(account));
const gchar *who;
gchar *description;
PurpleBuddy *buddy;
const char *alias;
PurpleAttentionType *attn =
- purple_get_attention_type_from_code(conv->account, 0);
+ purple_get_attention_type_from_code(account, 0);
if (!args || !args[0]) {
/* use the buddy from conversation, if it's a one-to-one conversation */
@@ -3178,7 +3179,7 @@ static PurpleCmdRet jabber_cmd_buzz(PurpleConversation *conv,
who = args[0];
}
- buddy = purple_find_buddy(conv->account, who);
+ buddy = purple_find_buddy(account, who);
if (buddy != NULL)
alias = purple_buddy_get_contact_alias(buddy);
else
@@ -3206,7 +3207,7 @@ GList *jabber_attention_types(PurpleAccount *account)
gboolean jabber_send_attention(PurpleConnection *gc, const char *username, guint code)
{
- JabberStream *js = gc->proto_data;
+ JabberStream *js = purple_connection_get_protocol_data(gc);
gchar *error = NULL;
if (!_jabber_send_buzz(js, username, &error)) {
@@ -3289,8 +3290,8 @@ jabber_initiate_media(PurpleAccount *account, const char *who,
PurpleMediaSessionType type)
{
#ifdef USE_VV
- JabberStream *js = (JabberStream *)
- purple_account_get_connection(account)->proto_data;
+ PurpleConnection *gc = purple_account_get_connection(account);
+ JabberStream *js = purple_connection_get_protocol_data(gc);
JabberBuddy *jb;
JabberBuddyResource *jbr = NULL;
char *resource;
@@ -3301,7 +3302,6 @@ jabber_initiate_media(PurpleAccount *account, const char *who,
return FALSE;
}
-
if((resource = jabber_get_resource(who)) != NULL) {
/* they've specified a resource, no need to ask or
* default or anything, just do it */
@@ -3432,8 +3432,8 @@ jabber_initiate_media(PurpleAccount *account, const char *who,
PurpleMediaCaps jabber_get_media_caps(PurpleAccount *account, const char *who)
{
#ifdef USE_VV
- JabberStream *js = (JabberStream *)
- purple_account_get_connection(account)->proto_data;
+ PurpleConnection *gc = purple_account_get_connection(account);
+ JabberStream *js = purple_connection_get_protocol_data(gc);
JabberBuddy *jb;
JabberBuddyResource *jbr;
PurpleMediaCaps total = PURPLE_MEDIA_CAPS_NONE;
@@ -3521,7 +3521,7 @@ PurpleMediaCaps jabber_get_media_caps(PurpleAccount *account, const char *who)
gboolean jabber_can_receive_file(PurpleConnection *gc, const char *who)
{
- JabberStream *js = gc->proto_data;
+ JabberStream *js = purple_connection_get_protocol_data(gc);
if (js) {
JabberBuddy *jb = jabber_buddy_find(js, who, FALSE);
@@ -3571,19 +3571,36 @@ static PurpleCmdRet
jabber_cmd_mood(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- JabberStream *js = conv->account->gc->proto_data;
+ PurpleAccount *account = purple_conversation_get_account(conv);
+ JabberStream *js = purple_connection_get_protocol_data(purple_account_get_connection(account));
if (js->pep) {
- /* if no argument was given, unset mood */
+ gboolean ret;
+
if (!args || !args[0]) {
- jabber_mood_set(js, NULL, NULL);
- } else if (!args[1]) {
- jabber_mood_set(js, args[0], NULL);
+ /* No arguments; unset mood */
+ ret = jabber_mood_set(js, NULL, NULL);
} else {
- jabber_mood_set(js, args[0], args[1]);
+ /* At least one argument. Relying on the list of arguments
+ * being NULL-terminated.
+ */
+ ret = jabber_mood_set(js, args[0], args[1]);
+ if (!ret) {
+ /* Let's try again */
+ char *tmp = g_strjoin(" ", args[0], args[1], NULL);
+ ret = jabber_mood_set(js, "undefined", tmp);
+ g_free(tmp);
+ }
}
- return PURPLE_CMD_RET_OK;
+ if (ret) {
+ return PURPLE_CMD_RET_OK;
+ } else {
+ purple_conversation_write(conv, NULL,
+ _("Failed to specify mood"),
+ PURPLE_MESSAGE_ERROR, time(NULL));
+ return PURPLE_CMD_RET_FAILED;
+ }
} else {
/* account does not support PEP, can't set a mood */
purple_conversation_write(conv, NULL,
@@ -3712,7 +3729,7 @@ static void jabber_register_commands(PurplePlugin *plugin)
PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_IM |
PURPLE_CMD_FLAG_PRPL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS,
"prpl-jabber", jabber_cmd_mood,
- _("mood: Set current user mood"), NULL);
+ _("mood &lt;mood&gt; [text]: Set current user mood"), NULL);
commands = g_slist_prepend(commands, GUINT_TO_POINTER(id));
g_hash_table_insert(jabber_cmds, plugin, commands);
@@ -3755,7 +3772,7 @@ jabber_ipc_contact_has_feature(PurpleAccount *account, const gchar *jid,
if (!purple_account_is_connected(account))
return FALSE;
- js = gc->proto_data;
+ js = purple_connection_get_protocol_data(gc);
if (!(resource = jabber_get_resource(jid)) ||
!(jb = jabber_buddy_find(js, jid, FALSE)) ||
diff --git a/libpurple/protocols/jabber/jabber.h b/libpurple/protocols/jabber/jabber.h
index 543d0af2d8..00bc0a3675 100644
--- a/libpurple/protocols/jabber/jabber.h
+++ b/libpurple/protocols/jabber/jabber.h
@@ -99,6 +99,7 @@ typedef enum {
struct _JabberStream
{
int fd;
+ guint inpa;
PurpleSrvTxtQueryData *srv_query_data;
diff --git a/libpurple/protocols/jabber/jutil.c b/libpurple/protocols/jabber/jutil.c
index 38246dd5e7..0156eb5d56 100644
--- a/libpurple/protocols/jabber/jutil.c
+++ b/libpurple/protocols/jabber/jutil.c
@@ -583,11 +583,16 @@ jabber_id_new(const char *str)
const char *jabber_normalize(const PurpleAccount *account, const char *in)
{
- PurpleConnection *gc = account ? account->gc : NULL;
- JabberStream *js = gc ? gc->proto_data : NULL;
+ PurpleConnection *gc = NULL;
+ JabberStream *js = NULL;
static char buf[3072]; /* maximum legal length of a jabber jid */
JabberID *jid;
+ if (account)
+ gc = purple_account_get_connection(account);
+ if (gc)
+ js = purple_connection_get_protocol_data(gc);
+
jid = jabber_id_new_internal(in, TRUE);
if(!jid)
return NULL;
diff --git a/libpurple/protocols/jabber/libfacebook.c b/libpurple/protocols/jabber/libfacebook.c
new file mode 100644
index 0000000000..b426eac356
--- /dev/null
+++ b/libpurple/protocols/jabber/libfacebook.c
@@ -0,0 +1,326 @@
+/* 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
+ * source distribution.
+ *
+ * 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
+ *
+ */
+
+/* libfacebook is the Facebook XMPP protocol plugin. It is linked against
+ * libjabbercommon, which may be used to support other protocols (Bonjour)
+ * which may need to share code.
+ */
+
+#include "internal.h"
+
+#include "accountopt.h"
+#include "core.h"
+#include "debug.h"
+#include "version.h"
+
+#include "iq.h"
+#include "jabber.h"
+#include "chat.h"
+#include "disco.h"
+#include "message.h"
+#include "roster.h"
+#include "si.h"
+#include "message.h"
+#include "presence.h"
+#include "google/google.h"
+#include "pep.h"
+#include "usermood.h"
+#include "usertune.h"
+#include "caps.h"
+#include "data.h"
+#include "ibb.h"
+
+static const char *
+facebook_list_icon(PurpleAccount *a, PurpleBuddy *b)
+{
+ return "facebook";
+}
+
+static PurplePlugin *my_protocol = NULL;
+
+static PurplePluginProtocolInfo prpl_info =
+{
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
+ OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME | OPT_PROTO_MAIL_CHECK |
+#ifdef HAVE_CYRUS_SASL
+ OPT_PROTO_PASSWORD_OPTIONAL |
+#endif
+ OPT_PROTO_SLASH_COMMANDS_NATIVE,
+ NULL, /* user_splits */
+ NULL, /* protocol_options */
+ {"png", 32, 32, 96, 96, 0, PURPLE_ICON_SCALE_SEND | PURPLE_ICON_SCALE_DISPLAY}, /* icon_spec */
+ facebook_list_icon, /* list_icon */
+ jabber_list_emblem, /* list_emblems */
+ jabber_status_text, /* status_text */
+ jabber_tooltip_text, /* tooltip_text */
+ jabber_status_types, /* status_types */
+ jabber_blist_node_menu, /* blist_node_menu */
+ jabber_chat_info, /* chat_info */
+ jabber_chat_info_defaults, /* chat_info_defaults */
+ jabber_login, /* login */
+ jabber_close, /* close */
+ jabber_message_send_im, /* send_im */
+ jabber_set_info, /* set_info */
+ jabber_send_typing, /* send_typing */
+ jabber_buddy_get_info, /* get_info */
+ jabber_set_status, /* set_status */
+ jabber_idle_set, /* set_idle */
+ NULL, /* change_passwd */
+ NULL, /* add_buddy */
+ NULL, /* add_buddies */
+ NULL, /* remove_buddy */
+ NULL, /* remove_buddies */
+ NULL, /* add_permit */
+ NULL, /* add_deny */
+ NULL, /* rem_permit */
+ NULL, /* rem_deny */
+ NULL, /* set_permit_deny */
+ jabber_chat_join, /* join_chat */
+ NULL, /* reject_chat */
+ jabber_get_chat_name, /* get_chat_name */
+ jabber_chat_invite, /* chat_invite */
+ jabber_chat_leave, /* chat_leave */
+ NULL, /* chat_whisper */
+ jabber_message_send_chat, /* chat_send */
+ jabber_keepalive, /* keepalive */
+ NULL, /* register_user */
+ NULL, /* get_cb_info */
+ NULL, /* alias_buddy */
+ NULL, /* group_buddy */
+ NULL, /* rename_group */
+ NULL, /* buddy_free */
+ jabber_convo_closed, /* convo_closed */
+ jabber_normalize, /* normalize */
+ jabber_set_buddy_icon, /* set_buddy_icon */
+ NULL, /* remove_group */
+ jabber_chat_buddy_real_name, /* get_cb_real_name */
+ jabber_chat_set_topic, /* set_chat_topic */
+ jabber_find_blist_chat, /* find_blist_chat */
+ jabber_roomlist_get_list, /* roomlist_get_list */
+ jabber_roomlist_cancel, /* roomlist_cancel */
+ NULL, /* roomlist_expand_category */
+ NULL, /* can_receive_file */
+ NULL, /* send_file */
+ NULL, /* new_xfer */
+ jabber_offline_message, /* offline_message */
+ NULL, /* whiteboard_prpl_ops */
+ jabber_prpl_send_raw, /* send_raw */
+ jabber_roomlist_room_serialize, /* roomlist_room_serialize */
+ NULL, /* unregister_user */
+ NULL, /* send_attention */
+ NULL, /* attention_types */
+ NULL, /* get_account_text_table */
+ NULL, /* initiate_media */
+ NULL, /* get_media_caps */
+ NULL, /* get_moods */
+ NULL, /* set_public_alias */
+ NULL /* get_public_alias */
+};
+
+static gboolean load_plugin(PurplePlugin *plugin)
+{
+ jabber_plugin_init(plugin);
+
+ return TRUE;
+}
+
+static gboolean unload_plugin(PurplePlugin *plugin)
+{
+ jabber_plugin_uninit(plugin);
+
+ return TRUE;
+}
+
+static PurplePluginInfo info =
+{
+ PURPLE_PLUGIN_MAGIC,
+ PURPLE_MAJOR_VERSION,
+ PURPLE_MINOR_VERSION,
+ PURPLE_PLUGIN_PROTOCOL, /**< type */
+ NULL, /**< ui_requirement */
+ 0, /**< flags */
+ NULL, /**< dependencies */
+ PURPLE_PRIORITY_DEFAULT, /**< priority */
+
+ "prpl-facebook-xmpp", /**< id */
+ "Facebook (XMPP)", /**< name */
+ DISPLAY_VERSION, /**< version */
+ /** summary */
+ N_("Facebook XMPP Protocol Plugin"),
+ /** description */
+ N_("Facebook XMPP Protocol Plugin"),
+ NULL, /**< author */
+ PURPLE_WEBSITE, /**< homepage */
+
+ load_plugin, /**< load */
+ unload_plugin, /**< unload */
+ NULL, /**< destroy */
+
+ NULL, /**< ui_info */
+ &prpl_info, /**< extra_info */
+ NULL, /**< prefs_info */
+ jabber_actions,
+
+ /* padding */
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static PurpleAccount *find_acct(const char *prpl, const char *acct_id)
+{
+ PurpleAccount *acct = NULL;
+
+ /* If we have a specific acct, use it */
+ if (acct_id) {
+ acct = purple_accounts_find(acct_id, prpl);
+ if (acct && !purple_account_is_connected(acct))
+ acct = NULL;
+ } else { /* Otherwise find an active account for the protocol */
+ GList *l = purple_accounts_get_all();
+ while (l) {
+ if (!strcmp(prpl, purple_account_get_protocol_id(l->data))
+ && purple_account_is_connected(l->data)) {
+ acct = l->data;
+ break;
+ }
+ l = l->next;
+ }
+ }
+
+ return acct;
+}
+
+static gboolean xmpp_uri_handler(const char *proto, const char *user, GHashTable *params)
+{
+ char *acct_id = params ? g_hash_table_lookup(params, "account") : NULL;
+ PurpleAccount *acct;
+
+ if (g_ascii_strcasecmp(proto, "xmpp"))
+ return FALSE;
+
+ acct = find_acct(purple_plugin_get_id(my_protocol), acct_id);
+
+ if (!acct)
+ return FALSE;
+
+ /* xmpp:romeo@montague.net?message;subject=Test%20Message;body=Here%27s%20a%20test%20message */
+ /* params is NULL if the URI has no '?' (or anything after it) */
+ if (!params || g_hash_table_lookup_extended(params, "message", NULL, NULL)) {
+ char *body = g_hash_table_lookup(params, "body");
+ if (user && *user) {
+ PurpleConversation *conv =
+ purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, user);
+ purple_conversation_present(conv);
+ if (body && *body)
+ purple_conv_send_confirm(conv, body);
+ }
+ } else if (g_hash_table_lookup_extended(params, "roster", NULL, NULL)) {
+ char *name = g_hash_table_lookup(params, "name");
+ if (user && *user)
+ purple_blist_request_add_buddy(acct, user, NULL, name);
+ } else if (g_hash_table_lookup_extended(params, "join", NULL, NULL)) {
+ PurpleConnection *gc = purple_account_get_connection(acct);
+ if (user && *user) {
+ GHashTable *params = jabber_chat_info_defaults(gc, user);
+ jabber_chat_join(gc, params);
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static void
+init_plugin(PurplePlugin *plugin)
+{
+ PurpleAccountUserSplit *split;
+ PurpleAccountOption *option;
+ GList *encryption_values = NULL;
+
+ /* Translators: 'domain' is used here in the context of Internet domains, e.g. pidgin.im */
+ split = purple_account_user_split_new(_("Domain"), "chat.facebook.com", '@');
+ purple_account_user_split_set_reverse(split, FALSE);
+ prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
+
+ split = purple_account_user_split_new(_("Resource"), "", '/');
+ purple_account_user_split_set_reverse(split, FALSE);
+ prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
+
+#define ADD_VALUE(list, desc, v) { \
+ PurpleKeyValuePair *kvp = g_new0(PurpleKeyValuePair, 1); \
+ kvp->key = g_strdup((desc)); \
+ kvp->value = g_strdup((v)); \
+ list = g_list_prepend(list, kvp); \
+}
+
+ ADD_VALUE(encryption_values, _("Use encryption if available"), "opportunistic_tls");
+ ADD_VALUE(encryption_values, _("Require encryption"), "require_tls");
+ ADD_VALUE(encryption_values, _("Use old-style SSL"), "old_ssl");
+#if 0
+ ADD_VALUE(encryption_values, "None", "none");
+#endif
+ encryption_values = g_list_reverse(encryption_values);
+
+#undef ADD_VALUE
+
+ option = purple_account_option_list_new(_("Connection security"), "connection_security", encryption_values);
+ prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+ option);
+
+ option = purple_account_option_bool_new(
+ _("Allow plaintext auth over unencrypted streams"),
+ "auth_plain_in_clear", FALSE);
+ prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+ option);
+
+ option = purple_account_option_int_new(_("Connect port"), "port", 5222);
+ prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+ option);
+
+ option = purple_account_option_string_new(_("Connect server"),
+ "connect_server", NULL);
+ prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+ option);
+
+ option = purple_account_option_string_new(_("BOSH URL"),
+ "bosh_url", NULL);
+ prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+ option);
+
+ /* this should probably be part of global smiley theme settings later on,
+ shared with MSN */
+ option = purple_account_option_bool_new(_("Show Custom Smileys"),
+ "custom_smileys", TRUE);
+ prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+ option);
+
+ my_protocol = plugin;
+
+ purple_signal_connect(purple_get_core(), "uri-handler", plugin,
+ PURPLE_CALLBACK(xmpp_uri_handler), NULL);
+}
+
+PURPLE_INIT_PLUGIN(facebookxmpp, init_plugin, info);
+
diff --git a/libpurple/protocols/jabber/libgtalk.c b/libpurple/protocols/jabber/libgtalk.c
new file mode 100644
index 0000000000..d52d1842c2
--- /dev/null
+++ b/libpurple/protocols/jabber/libgtalk.c
@@ -0,0 +1,334 @@
+/* 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
+ * source distribution.
+ *
+ * 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
+ *
+ */
+
+/* libgtalk is the Google Talk XMPP protocol plugin. It is linked against
+ * libjabbercommon, which may be used to support other protocols (Bonjour) which
+ * may need to share code.
+ */
+
+#include "internal.h"
+
+#include "accountopt.h"
+#include "core.h"
+#include "debug.h"
+#include "version.h"
+
+#include "iq.h"
+#include "jabber.h"
+#include "chat.h"
+#include "disco.h"
+#include "message.h"
+#include "roster.h"
+#include "si.h"
+#include "message.h"
+#include "presence.h"
+#include "google/google.h"
+#include "pep.h"
+#include "usermood.h"
+#include "usertune.h"
+#include "caps.h"
+#include "data.h"
+#include "ibb.h"
+
+static const char *
+gtalk_list_icon(PurpleAccount *a, PurpleBuddy *b)
+{
+ return "google-talk";
+}
+
+static PurplePlugin *my_protocol = NULL;
+
+static PurplePluginProtocolInfo prpl_info =
+{
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
+ OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME | OPT_PROTO_MAIL_CHECK |
+#ifdef HAVE_CYRUS_SASL
+ OPT_PROTO_PASSWORD_OPTIONAL |
+#endif
+ OPT_PROTO_SLASH_COMMANDS_NATIVE,
+ NULL, /* user_splits */
+ NULL, /* protocol_options */
+ {"png", 32, 32, 96, 96, 0, PURPLE_ICON_SCALE_SEND | PURPLE_ICON_SCALE_DISPLAY}, /* icon_spec */
+ gtalk_list_icon, /* list_icon */
+ jabber_list_emblem, /* list_emblems */
+ jabber_status_text, /* status_text */
+ jabber_tooltip_text, /* tooltip_text */
+ jabber_status_types, /* status_types */
+ jabber_blist_node_menu, /* blist_node_menu */
+ jabber_chat_info, /* chat_info */
+ jabber_chat_info_defaults, /* chat_info_defaults */
+ jabber_login, /* login */
+ jabber_close, /* close */
+ jabber_message_send_im, /* send_im */
+ jabber_set_info, /* set_info */
+ jabber_send_typing, /* send_typing */
+ jabber_buddy_get_info, /* get_info */
+ jabber_set_status, /* set_status */
+ jabber_idle_set, /* set_idle */
+ NULL, /* change_passwd */
+ jabber_roster_add_buddy, /* add_buddy */
+ NULL, /* add_buddies */
+ jabber_roster_remove_buddy, /* remove_buddy */
+ NULL, /* remove_buddies */
+ NULL, /* add_permit */
+ jabber_add_deny, /* add_deny */
+ NULL, /* rem_permit */
+ jabber_rem_deny, /* rem_deny */
+ NULL, /* set_permit_deny */
+ jabber_chat_join, /* join_chat */
+ NULL, /* reject_chat */
+ jabber_get_chat_name, /* get_chat_name */
+ jabber_chat_invite, /* chat_invite */
+ jabber_chat_leave, /* chat_leave */
+ NULL, /* chat_whisper */
+ jabber_message_send_chat, /* chat_send */
+ jabber_keepalive, /* keepalive */
+ NULL, /* register_user */
+ NULL, /* get_cb_info */
+ jabber_roster_alias_change, /* alias_buddy */
+ jabber_roster_group_change, /* group_buddy */
+ jabber_roster_group_rename, /* rename_group */
+ NULL, /* buddy_free */
+ jabber_convo_closed, /* convo_closed */
+ jabber_normalize, /* normalize */
+ jabber_set_buddy_icon, /* set_buddy_icon */
+ NULL, /* remove_group */
+ jabber_chat_buddy_real_name, /* get_cb_real_name */
+ jabber_chat_set_topic, /* set_chat_topic */
+ jabber_find_blist_chat, /* find_blist_chat */
+ jabber_roomlist_get_list, /* roomlist_get_list */
+ jabber_roomlist_cancel, /* roomlist_cancel */
+ NULL, /* roomlist_expand_category */
+ jabber_can_receive_file, /* can_receive_file */
+ jabber_si_xfer_send, /* send_file */
+ jabber_si_new_xfer, /* new_xfer */
+ jabber_offline_message, /* offline_message */
+ NULL, /* whiteboard_prpl_ops */
+ jabber_prpl_send_raw, /* send_raw */
+ jabber_roomlist_room_serialize, /* roomlist_room_serialize */
+ NULL, /* unregister_user */
+ jabber_send_attention, /* send_attention */
+ jabber_attention_types, /* attention_types */
+ NULL, /* get_account_text_table */
+ jabber_initiate_media, /* initiate_media */
+ jabber_get_media_caps, /* get_media_caps */
+ jabber_get_moods, /* get_moods */
+ NULL, /* set_public_alias */
+ NULL /* get_public_alias */
+};
+
+static gboolean load_plugin(PurplePlugin *plugin)
+{
+ jabber_plugin_init(plugin);
+
+ return TRUE;
+}
+
+static gboolean unload_plugin(PurplePlugin *plugin)
+{
+ jabber_plugin_uninit(plugin);
+
+ return TRUE;
+}
+
+static PurplePluginInfo info =
+{
+ PURPLE_PLUGIN_MAGIC,
+ PURPLE_MAJOR_VERSION,
+ PURPLE_MINOR_VERSION,
+ PURPLE_PLUGIN_PROTOCOL, /**< type */
+ NULL, /**< ui_requirement */
+ 0, /**< flags */
+ NULL, /**< dependencies */
+ PURPLE_PRIORITY_DEFAULT, /**< priority */
+
+ "prpl-gtalk", /**< id */
+ "Google Talk (XMPP)", /**< name */
+ DISPLAY_VERSION, /**< version */
+ /** summary */
+ N_("Google Talk Protocol Plugin"),
+ /** description */
+ N_("Google Talk Protocol Plugin"),
+ NULL, /**< author */
+ PURPLE_WEBSITE, /**< homepage */
+
+ load_plugin, /**< load */
+ unload_plugin, /**< unload */
+ NULL, /**< destroy */
+
+ NULL, /**< ui_info */
+ &prpl_info, /**< extra_info */
+ NULL, /**< prefs_info */
+ jabber_actions,
+
+ /* padding */
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static PurpleAccount *find_acct(const char *prpl, const char *acct_id)
+{
+ PurpleAccount *acct = NULL;
+
+ /* If we have a specific acct, use it */
+ if (acct_id) {
+ acct = purple_accounts_find(acct_id, prpl);
+ if (acct && !purple_account_is_connected(acct))
+ acct = NULL;
+ } else { /* Otherwise find an active account for the protocol */
+ GList *l = purple_accounts_get_all();
+ while (l) {
+ if (!strcmp(prpl, purple_account_get_protocol_id(l->data))
+ && purple_account_is_connected(l->data)) {
+ acct = l->data;
+ break;
+ }
+ l = l->next;
+ }
+ }
+
+ return acct;
+}
+
+static gboolean xmpp_uri_handler(const char *proto, const char *user, GHashTable *params)
+{
+ char *acct_id = params ? g_hash_table_lookup(params, "account") : NULL;
+ PurpleAccount *acct;
+
+ if (g_ascii_strcasecmp(proto, "xmpp"))
+ return FALSE;
+
+ acct = find_acct(purple_plugin_get_id(my_protocol), acct_id);
+
+ if (!acct)
+ return FALSE;
+
+ /* xmpp:romeo@montague.net?message;subject=Test%20Message;body=Here%27s%20a%20test%20message */
+ /* params is NULL if the URI has no '?' (or anything after it) */
+ if (!params || g_hash_table_lookup_extended(params, "message", NULL, NULL)) {
+ char *body = g_hash_table_lookup(params, "body");
+ if (user && *user) {
+ PurpleConversation *conv =
+ purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, user);
+ purple_conversation_present(conv);
+ if (body && *body)
+ purple_conv_send_confirm(conv, body);
+ }
+ } else if (g_hash_table_lookup_extended(params, "roster", NULL, NULL)) {
+ char *name = g_hash_table_lookup(params, "name");
+ if (user && *user)
+ purple_blist_request_add_buddy(acct, user, NULL, name);
+ } else if (g_hash_table_lookup_extended(params, "join", NULL, NULL)) {
+ PurpleConnection *gc = purple_account_get_connection(acct);
+ if (user && *user) {
+ GHashTable *params = jabber_chat_info_defaults(gc, user);
+ jabber_chat_join(gc, params);
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static void
+init_plugin(PurplePlugin *plugin)
+{
+ PurpleAccountUserSplit *split;
+ PurpleAccountOption *option;
+ GList *encryption_values = NULL;
+
+ /* Translators: 'domain' is used here in the context of Internet domains, e.g. pidgin.im */
+ split = purple_account_user_split_new(_("Domain"), "gmail.com", '@');
+ purple_account_user_split_set_reverse(split, FALSE);
+ prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
+
+ split = purple_account_user_split_new(_("Resource"), "", '/');
+ purple_account_user_split_set_reverse(split, FALSE);
+ prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
+
+#define ADD_VALUE(list, desc, v) { \
+ PurpleKeyValuePair *kvp = g_new0(PurpleKeyValuePair, 1); \
+ kvp->key = g_strdup((desc)); \
+ kvp->value = g_strdup((v)); \
+ list = g_list_prepend(list, kvp); \
+}
+
+ ADD_VALUE(encryption_values, _("Require encryption"), "require_tls");
+ ADD_VALUE(encryption_values, _("Use encryption if available"), "opportunistic_tls");
+ ADD_VALUE(encryption_values, _("Use old-style SSL"), "old_ssl");
+#if 0
+ ADD_VALUE(encryption_values, "None", "none");
+#endif
+ encryption_values = g_list_reverse(encryption_values);
+
+#undef ADD_VALUE
+
+ option = purple_account_option_list_new(_("Connection security"), "connection_security", encryption_values);
+ prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+ option);
+
+ option = purple_account_option_bool_new(
+ _("Allow plaintext auth over unencrypted streams"),
+ "auth_plain_in_clear", FALSE);
+ prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+ option);
+
+ option = purple_account_option_int_new(_("Connect port"), "port", 5222);
+ prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+ option);
+
+ option = purple_account_option_string_new(_("Connect server"),
+ "connect_server", NULL);
+ prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+ option);
+
+ option = purple_account_option_string_new(_("File transfer proxies"),
+ "ft_proxies",
+ /* TODO: Is this an acceptable default?
+ * Also, keep this in sync as they add more servers */
+ JABBER_DEFAULT_FT_PROXIES);
+ prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+ option);
+
+ option = purple_account_option_string_new(_("BOSH URL"),
+ "bosh_url", NULL);
+ prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+ option);
+
+ /* this should probably be part of global smiley theme settings later on,
+ shared with MSN */
+ option = purple_account_option_bool_new(_("Show Custom Smileys"),
+ "custom_smileys", TRUE);
+ prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+ option);
+
+ my_protocol = plugin;
+
+ purple_signal_connect(purple_get_core(), "uri-handler", plugin,
+ PURPLE_CALLBACK(xmpp_uri_handler), NULL);
+}
+
+PURPLE_INIT_PLUGIN(gtalk, init_plugin, info);
+
diff --git a/libpurple/protocols/jabber/libxmpp.c b/libpurple/protocols/jabber/libxmpp.c
index f34052b6e4..53b7b9bd75 100644
--- a/libpurple/protocols/jabber/libxmpp.c
+++ b/libpurple/protocols/jabber/libxmpp.c
@@ -53,6 +53,7 @@ static PurplePlugin *my_protocol = NULL;
static PurplePluginProtocolInfo prpl_info =
{
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME | OPT_PROTO_MAIL_CHECK |
#ifdef HAVE_CYRUS_SASL
OPT_PROTO_PASSWORD_OPTIONAL |
@@ -97,7 +98,6 @@ static PurplePluginProtocolInfo prpl_info =
jabber_keepalive, /* keepalive */
jabber_register_account, /* register_user */
NULL, /* get_cb_info */
- NULL, /* get_cb_away */
jabber_roster_alias_change, /* alias_buddy */
jabber_roster_group_change, /* group_buddy */
jabber_roster_group_rename, /* rename_group */
@@ -122,16 +122,12 @@ static PurplePluginProtocolInfo prpl_info =
jabber_unregister_account, /* unregister_user */
jabber_send_attention, /* send_attention */
jabber_attention_types, /* attention_types */
-
- sizeof(PurplePluginProtocolInfo), /* struct_size */
NULL, /* get_account_text_table */
jabber_initiate_media, /* initiate_media */
jabber_get_media_caps, /* get_media_caps */
jabber_get_moods, /* get_moods */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */
};
static gboolean load_plugin(PurplePlugin *plugin)
diff --git a/libpurple/protocols/jabber/message.c b/libpurple/protocols/jabber/message.c
index 609be702f5..95edd960fc 100644
--- a/libpurple/protocols/jabber/message.c
+++ b/libpurple/protocols/jabber/message.c
@@ -638,6 +638,8 @@ void jabber_message_parse(JabberStream *js, xmlnode *packet)
jabber_message_add_remote_smileys(js, to, packet);
}
+ xmlnode_strip_prefixes(child);
+
/* reformat xhtml so that img tags with a "cid:" src gets
translated to the bare text of the emoticon (the "alt" attrib) */
/* this is done also when custom smiley retrieval is turned off,
@@ -1148,13 +1150,13 @@ int jabber_message_send_im(PurpleConnection *gc, const char *who, const char *ms
resource = jabber_get_resource(who);
- jb = jabber_buddy_find(gc->proto_data, who, TRUE);
+ jb = jabber_buddy_find(purple_connection_get_protocol_data(gc), who, TRUE);
jbr = jabber_buddy_find_resource(jb, resource);
g_free(resource);
jm = g_new0(JabberMessage, 1);
- jm->js = gc->proto_data;
+ jm->js = purple_connection_get_protocol_data(gc);
jm->type = JABBER_MESSAGE_CHAT;
jm->chat_state = JM_STATE_ACTIVE;
jm->to = g_strdup(who);
@@ -1211,14 +1213,14 @@ int jabber_message_send_chat(PurpleConnection *gc, int id, const char *msg, Purp
if(!msg || !gc)
return 0;
- js = gc->proto_data;
+ js = purple_connection_get_protocol_data(gc);
chat = jabber_chat_find_by_id(js, id);
if(!chat)
return 0;
jm = g_new0(JabberMessage, 1);
- jm->js = gc->proto_data;
+ jm->js = purple_connection_get_protocol_data(gc);
jm->type = JABBER_MESSAGE_GROUPCHAT;
jm->to = g_strdup_printf("%s@%s", chat->room, chat->server);
jm->id = jabber_get_next_id(jm->js);
diff --git a/libpurple/protocols/jabber/oob.c b/libpurple/protocols/jabber/oob.c
index 430d17ac7e..e32a59fcc9 100644
--- a/libpurple/protocols/jabber/oob.c
+++ b/libpurple/protocols/jabber/oob.c
@@ -48,13 +48,13 @@ typedef struct _JabberOOBXfer {
static void jabber_oob_xfer_init(PurpleXfer *xfer)
{
- JabberOOBXfer *jox = xfer->data;
+ JabberOOBXfer *jox = purple_xfer_get_protocol_data(xfer);
purple_xfer_start(xfer, -1, jox->address, jox->port);
}
static void jabber_oob_xfer_free(PurpleXfer *xfer)
{
- JabberOOBXfer *jox = xfer->data;
+ JabberOOBXfer *jox = purple_xfer_get_protocol_data(xfer);
jox->js->oob_file_transfers = g_list_remove(jox->js->oob_file_transfers,
xfer);
@@ -67,16 +67,16 @@ static void jabber_oob_xfer_free(PurpleXfer *xfer)
purple_input_remove(jox->writeh);
g_free(jox);
- xfer->data = NULL;
+ purple_xfer_set_protocol_data(xfer, NULL);
}
static void jabber_oob_xfer_end(PurpleXfer *xfer)
{
- JabberOOBXfer *jox = xfer->data;
+ JabberOOBXfer *jox = purple_xfer_get_protocol_data(xfer);
JabberIq *iq;
iq = jabber_iq_new(jox->js, JABBER_IQ_RESULT);
- xmlnode_set_attrib(iq->node, "to", xfer->who);
+ xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
jabber_iq_set_id(iq, jox->iq_id);
jabber_iq_send(iq);
@@ -86,10 +86,10 @@ static void jabber_oob_xfer_end(PurpleXfer *xfer)
static void jabber_oob_xfer_request_send(gpointer data, gint source, PurpleInputCondition cond) {
PurpleXfer *xfer = data;
- JabberOOBXfer *jox = xfer->data;
+ JabberOOBXfer *jox = purple_xfer_get_protocol_data(xfer);
int len, total_len = strlen(jox->write_buffer);
- len = write(xfer->fd, jox->write_buffer + jox->written_len,
+ len = purple_xfer_write(xfer, (guchar*) jox->write_buffer + jox->written_len,
total_len - jox->written_len);
if(len < 0 && errno == EAGAIN)
@@ -110,7 +110,7 @@ static void jabber_oob_xfer_request_send(gpointer data, gint source, PurpleInput
static void jabber_oob_xfer_start(PurpleXfer *xfer)
{
- JabberOOBXfer *jox = xfer->data;
+ JabberOOBXfer *jox = purple_xfer_get_protocol_data(xfer);
if(jox->write_buffer == NULL) {
jox->write_buffer = g_strdup_printf(
@@ -119,26 +119,26 @@ static void jabber_oob_xfer_start(PurpleXfer *xfer)
jox->written_len = 0;
}
- jox->writeh = purple_input_add(xfer->fd, PURPLE_INPUT_WRITE,
+ jox->writeh = purple_input_add(purple_xfer_get_fd(xfer), PURPLE_INPUT_WRITE,
jabber_oob_xfer_request_send, xfer);
- jabber_oob_xfer_request_send(xfer, xfer->fd, PURPLE_INPUT_WRITE);
+ jabber_oob_xfer_request_send(xfer, purple_xfer_get_fd(xfer), PURPLE_INPUT_WRITE);
}
static gssize jabber_oob_xfer_read(guchar **buffer, PurpleXfer *xfer) {
- JabberOOBXfer *jox = xfer->data;
+ JabberOOBXfer *jox = purple_xfer_get_protocol_data(xfer);
char test[2048];
char *tmp, *lenstr;
int len;
- if((len = read(xfer->fd, test, sizeof(test))) > 0) {
+ if((len = read(purple_xfer_get_fd(xfer), test, sizeof(test))) > 0) {
jox->headers = g_string_append_len(jox->headers, test, len);
if((tmp = strstr(jox->headers->str, "\r\n\r\n"))) {
*tmp = '\0';
lenstr = strstr(jox->headers->str, "Content-Length: ");
if(lenstr) {
- int size;
- sscanf(lenstr, "Content-Length: %d", &size);
+ goffset size;
+ sscanf(lenstr, "Content-Length: %" G_GOFFSET_FORMAT, &size);
purple_xfer_set_size(xfer, size);
}
purple_xfer_set_read_fnc(xfer, NULL);
@@ -158,12 +158,12 @@ static gssize jabber_oob_xfer_read(guchar **buffer, PurpleXfer *xfer) {
}
static void jabber_oob_xfer_recv_error(PurpleXfer *xfer, const char *code) {
- JabberOOBXfer *jox = xfer->data;
+ JabberOOBXfer *jox = purple_xfer_get_protocol_data(xfer);
JabberIq *iq;
xmlnode *y, *z;
iq = jabber_iq_new(jox->js, JABBER_IQ_ERROR);
- xmlnode_set_attrib(iq->node, "to", xfer->who);
+ xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
jabber_iq_set_id(iq, jox->iq_id);
y = xmlnode_new_child(iq->node, "error");
xmlnode_set_attrib(y, "code", code);
@@ -218,10 +218,10 @@ void jabber_oob_parse(JabberStream *js, const char *from, JabberIqType type,
jox->headers = g_string_new("");
jox->iq_id = g_strdup(id);
- xfer = purple_xfer_new(js->gc->account, PURPLE_XFER_RECEIVE, from);
+ xfer = purple_xfer_new(purple_connection_get_account(js->gc), PURPLE_XFER_RECEIVE, from);
if (xfer)
{
- xfer->data = jox;
+ purple_xfer_set_protocol_data(xfer, jox);
if(!(filename = g_strdup(g_strrstr(jox->page, "/"))))
filename = g_strdup(jox->page);
diff --git a/libpurple/protocols/jabber/parser.c b/libpurple/protocols/jabber/parser.c
index 5e3aa950ef..d407c634fc 100644
--- a/libpurple/protocols/jabber/parser.c
+++ b/libpurple/protocols/jabber/parser.c
@@ -52,7 +52,7 @@ jabber_parser_element_start_libxml(void *user_data,
*/
purple_debug_error("jabber", "Expecting stream header, got %s with "
"xmlns %s\n", element_name, namespace);
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
_("XMPP stream header missing"));
return;
@@ -73,7 +73,7 @@ jabber_parser_element_start_libxml(void *user_data,
if (js->protocol_version.major > 1) {
/* TODO: Send <unsupported-version/> error */
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
_("XMPP Version Mismatch"));
g_free(attrib);
@@ -98,7 +98,7 @@ jabber_parser_element_start_libxml(void *user_data,
/* This was underspecified in rfc3920 as only being a SHOULD, so
* we cannot rely on it. See #12331 and Oracle's server.
*/
- purple_connection_error_reason(js->gc,
+ purple_connection_error(js->gc,
PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
_("XMPP stream missing ID"));
#else
@@ -300,7 +300,7 @@ void jabber_parser_process(JabberStream *js, const char *buf, int len)
break;
case XML_ERR_FATAL:
purple_debug_error("jabber", "xmlParseChunk returned fatal %i\n", ret);
- purple_connection_error_reason (js->gc,
+ purple_connection_error (js->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("XML Parse error"));
break;
diff --git a/libpurple/protocols/jabber/presence.c b/libpurple/protocols/jabber/presence.c
index 7e0a11b93b..a95bf4bb3f 100644
--- a/libpurple/protocols/jabber/presence.c
+++ b/libpurple/protocols/jabber/presence.c
@@ -299,11 +299,6 @@ void jabber_presence_send(JabberStream *js, gboolean force)
jabber_presence_fake_to_self(js, status);
}
-xmlnode *jabber_presence_create(JabberBuddyState state, const char *msg, int priority)
-{
- return jabber_presence_create_js(NULL, state, msg, priority);
-}
-
xmlnode *jabber_presence_create_js(JabberStream *js, JabberBuddyState state, const char *msg, int priority)
{
xmlnode *show, *status, *presence, *pri, *c;
@@ -393,7 +388,7 @@ static void authorize_add_cb(gpointer data)
{
struct _jabber_add_permit *jap = data;
if(PURPLE_CONNECTION_IS_VALID(jap->gc))
- jabber_presence_subscription_set(jap->gc->proto_data,
+ jabber_presence_subscription_set(purple_connection_get_protocol_data(jap->gc),
jap->who, "subscribed");
g_free(jap->who);
g_free(jap);
@@ -403,7 +398,7 @@ static void deny_add_cb(gpointer data)
{
struct _jabber_add_permit *jap = data;
if(PURPLE_CONNECTION_IS_VALID(jap->gc))
- jabber_presence_subscription_set(jap->gc->proto_data,
+ jabber_presence_subscription_set(purple_connection_get_protocol_data(jap->gc),
jap->who, "unsubscribed");
g_free(jap->who);
g_free(jap);
@@ -464,7 +459,7 @@ jabber_vcard_parse_avatar(JabberStream *js, const char *from,
hash = jabber_calculate_data_hash(data, size, "sha1");
}
- purple_buddy_icons_set_for_user(js->gc->account, from, data, size, hash);
+ purple_buddy_icons_set_for_user(purple_connection_get_account(js->gc), from, data, size, hash);
g_free(hash);
}
diff --git a/libpurple/protocols/jabber/presence.h b/libpurple/protocols/jabber/presence.h
index e83309278a..98322fd9ae 100644
--- a/libpurple/protocols/jabber/presence.h
+++ b/libpurple/protocols/jabber/presence.h
@@ -92,7 +92,6 @@ void jabber_set_status(PurpleAccount *account, PurpleStatus *status);
*/
void jabber_presence_send(JabberStream *js, gboolean force);
-xmlnode *jabber_presence_create(JabberBuddyState state, const char *msg, int priority); /* DEPRECATED */
xmlnode *jabber_presence_create_js(JabberStream *js, JabberBuddyState state, const char *msg, int priority);
void jabber_presence_parse(JabberStream *js, xmlnode *packet);
void jabber_presence_subscription_set(JabberStream *js, const char *who,
diff --git a/libpurple/protocols/jabber/roster.c b/libpurple/protocols/jabber/roster.c
index 9683dbcbb6..1dd565be35 100644
--- a/libpurple/protocols/jabber/roster.c
+++ b/libpurple/protocols/jabber/roster.c
@@ -96,7 +96,7 @@ static void remove_purple_buddies(JabberStream *js, const char *jid)
{
GSList *buddies, *l;
- buddies = purple_find_buddies(js->gc->account, jid);
+ buddies = purple_find_buddies(purple_connection_get_account(js->gc), jid);
for(l = buddies; l; l = l->next)
purple_blist_remove_buddy(l->data);
@@ -110,7 +110,7 @@ static void add_purple_buddy_to_groups(JabberStream *js, const char *jid,
GSList *buddies, *l;
PurpleAccount *account = purple_connection_get_account(js->gc);
- buddies = purple_find_buddies(js->gc->account, jid);
+ buddies = purple_find_buddies(purple_connection_get_account(js->gc), jid);
if(!groups) {
if(!buddies)
@@ -304,7 +304,7 @@ static void jabber_roster_update(JabberStream *js, const char *name,
if (js->currently_parsing_roster_push)
return;
- if(!(b = purple_find_buddy(js->gc->account, name)))
+ if(!(b = purple_find_buddy(purple_connection_get_account(js->gc), name)))
return;
if (groups) {
@@ -314,7 +314,7 @@ static void jabber_roster_update(JabberStream *js, const char *name,
"groups]: groups: %s\n", name, tmp);
g_free(tmp);
} else {
- GSList *buddies = purple_find_buddies(js->gc->account, name);
+ GSList *buddies = purple_find_buddies(purple_connection_get_account(js->gc), name);
char *tmp;
if(!buddies)
@@ -358,9 +358,9 @@ static void jabber_roster_update(JabberStream *js, const char *name,
}
void jabber_roster_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
- PurpleGroup *group)
+ PurpleGroup *group, const char *message)
{
- JabberStream *js = gc->proto_data;
+ JabberStream *js = purple_connection_get_protocol_data(gc);
char *who;
JabberID *jid;
JabberBuddy *jb;
@@ -413,7 +413,7 @@ void jabber_roster_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
} else if(!jb || !(jb->subscription & JABBER_SUB_TO)) {
jabber_presence_subscription_set(js, who, "subscribe");
} else if((jbr =jabber_buddy_find_resource(jb, NULL))) {
- purple_prpl_got_user_status(gc->account, who,
+ purple_prpl_got_user_status(purple_connection_get_account(gc), who,
jabber_buddy_state_get_status_id(jbr->state),
"priority", jbr->priority, jbr->status ? "message" : NULL, jbr->status, NULL);
}
@@ -423,7 +423,7 @@ void jabber_roster_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
void jabber_roster_alias_change(PurpleConnection *gc, const char *name, const char *alias)
{
- PurpleBuddy *b = purple_find_buddy(gc->account, name);
+ PurpleBuddy *b = purple_find_buddy(purple_connection_get_account(gc), name);
if(b != NULL) {
purple_blist_alias_buddy(b, alias);
@@ -431,7 +431,7 @@ void jabber_roster_alias_change(PurpleConnection *gc, const char *name, const ch
purple_debug_info("jabber", "jabber_roster_alias_change(): Aliased %s to %s\n",
name, alias ? alias : "(null)");
- jabber_roster_update(gc->proto_data, name, NULL);
+ jabber_roster_update(purple_connection_get_protocol_data(gc), name, NULL);
}
}
@@ -446,7 +446,7 @@ void jabber_roster_group_change(PurpleConnection *gc, const char *name,
if(!old_group || !new_group || !strcmp(old_group, new_group))
return;
- buddies = purple_find_buddies(gc->account, name);
+ buddies = purple_find_buddies(purple_connection_get_account(gc), name);
while(buddies) {
b = buddies->data;
g = purple_buddy_get_group(b);
@@ -461,7 +461,7 @@ void jabber_roster_group_change(PurpleConnection *gc, const char *name,
purple_debug_info("jabber", "jabber_roster_group_change(): Moving %s from %s to %s\n",
name, old_group, new_group);
- jabber_roster_update(gc->proto_data, name, groups);
+ jabber_roster_update(purple_connection_get_protocol_data(gc), name, groups);
}
void jabber_roster_group_rename(PurpleConnection *gc, const char *old_name,
@@ -496,9 +496,9 @@ void jabber_roster_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
purple_debug_info("jabber", "jabber_roster_remove_buddy(): Removing %s from %s\n",
purple_buddy_get_name(buddy), purple_group_get_name(group));
- jabber_roster_update(gc->proto_data, name, groups);
+ jabber_roster_update(purple_connection_get_protocol_data(gc), name, groups);
} else {
- JabberIq *iq = jabber_iq_new_query(gc->proto_data, JABBER_IQ_SET,
+ JabberIq *iq = jabber_iq_new_query(purple_connection_get_protocol_data(gc), JABBER_IQ_SET,
"jabber:iq:roster");
xmlnode *query = xmlnode_get_child(iq->node, "query");
xmlnode *item = xmlnode_new_child(query, "item");
diff --git a/libpurple/protocols/jabber/roster.h b/libpurple/protocols/jabber/roster.h
index 4bc4384e03..367fd05d7f 100644
--- a/libpurple/protocols/jabber/roster.h
+++ b/libpurple/protocols/jabber/roster.h
@@ -32,7 +32,7 @@ void jabber_roster_parse(JabberStream *js, const char *from,
JabberIqType type, const char *id, xmlnode *query);
void jabber_roster_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
- PurpleGroup *group);
+ PurpleGroup *group, const char *message);
void jabber_roster_alias_change(PurpleConnection *gc, const char *name,
const char *alias);
void jabber_roster_group_change(PurpleConnection *gc, const char *name,
diff --git a/libpurple/protocols/jabber/si.c b/libpurple/protocols/jabber/si.c
index 034b2d30fb..c97988042b 100644
--- a/libpurple/protocols/jabber/si.c
+++ b/libpurple/protocols/jabber/si.c
@@ -87,9 +87,9 @@ jabber_si_xfer_find(JabberStream *js, const char *sid, const char *from)
for(xfers = js->file_transfers; xfers; xfers = xfers->next) {
PurpleXfer *xfer = xfers->data;
- JabberSIXfer *jsx = xfer->data;
- if(jsx->stream_id && xfer->who &&
- !strcmp(jsx->stream_id, sid) && !strcmp(xfer->who, from))
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
+ if(jsx->stream_id && purple_xfer_get_remote_user(xfer) &&
+ !strcmp(jsx->stream_id, sid) && !strcmp(purple_xfer_get_remote_user(xfer), from))
return xfer;
}
@@ -118,7 +118,7 @@ static void
jabber_si_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_message)
{
PurpleXfer *xfer = data;
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
JabberIq *iq;
xmlnode *query, *su;
JabberBytestreamsStreamhost *streamhost = jsx->streamhosts->data;
@@ -143,7 +143,7 @@ jabber_si_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_
}
/* unknown file transfer type is assumed to be RECEIVE */
- if(xfer->type == PURPLE_XFER_SEND)
+ if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND)
{
xmlnode *activate;
iq = jabber_iq_new_query(jsx->js, JABBER_IQ_SET, NS_BYTESTREAMS);
@@ -151,14 +151,14 @@ jabber_si_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_
query = xmlnode_get_child(iq->node, "query");
xmlnode_set_attrib(query, "sid", jsx->stream_id);
activate = xmlnode_new_child(query, "activate");
- xmlnode_insert_data(activate, xfer->who, -1);
+ xmlnode_insert_data(activate, purple_xfer_get_remote_user(xfer), -1);
/* TODO: We need to wait for an activation result before starting */
}
else
{
iq = jabber_iq_new_query(jsx->js, JABBER_IQ_RESULT, NS_BYTESTREAMS);
- xmlnode_set_attrib(iq->node, "to", xfer->who);
+ xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
jabber_iq_set_id(iq, jsx->iq_id);
query = xmlnode_get_child(iq->node, "query");
su = xmlnode_new_child(query, "streamhost-used");
@@ -174,7 +174,7 @@ static gboolean
connect_timeout_cb(gpointer data)
{
PurpleXfer *xfer = data;
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
purple_debug_info("jabber", "Streamhost connection timeout of %d seconds exceeded.\n", STREAMHOST_CONNECT_TIMEOUT);
@@ -203,7 +203,7 @@ static gboolean
jabber_si_bytestreams_ibb_timeout_cb(gpointer data)
{
PurpleXfer *xfer = (PurpleXfer *) data;
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
if (jsx && !jsx->ibb_session) {
purple_debug_info("jabber",
@@ -218,7 +218,7 @@ jabber_si_bytestreams_ibb_timeout_cb(gpointer data)
static void jabber_si_bytestreams_attempt_connect(PurpleXfer *xfer)
{
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
JabberBytestreamsStreamhost *streamhost;
JabberID *dstjid;
@@ -229,7 +229,7 @@ static void jabber_si_bytestreams_attempt_connect(PurpleXfer *xfer)
if(jsx->iq_id)
jabber_iq_set_id(iq, jsx->iq_id);
- xmlnode_set_attrib(iq->node, "to", xfer->who);
+ xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
error = xmlnode_new_child(iq->node, "error");
xmlnode_set_attrib(error, "code", "404");
xmlnode_set_attrib(error, "type", "cancel");
@@ -271,7 +271,7 @@ static void jabber_si_bytestreams_attempt_connect(PurpleXfer *xfer)
purple_proxy_info_destroy(jsx->gpi);
jsx->gpi = NULL;
- dstjid = jabber_id_new(xfer->who);
+ dstjid = jabber_id_new(purple_xfer_get_remote_user(xfer));
/* TODO: Deal with zeroconf */
@@ -284,7 +284,7 @@ static void jabber_si_bytestreams_attempt_connect(PurpleXfer *xfer)
purple_proxy_info_set_port(jsx->gpi, streamhost->port);
/* unknown file transfer type is assumed to be RECEIVE */
- if(xfer->type == PURPLE_XFER_SEND)
+ if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND)
dstaddr = g_strdup_printf("%s%s@%s/%s%s@%s/%s", jsx->stream_id, jsx->js->user->node, jsx->js->user->domain,
jsx->js->user->resource, dstjid->node, dstjid->domain, dstjid->resource);
else
@@ -302,7 +302,7 @@ static void jabber_si_bytestreams_attempt_connect(PurpleXfer *xfer)
g_free(dstaddr);
/* When selecting a streamhost, timeout after STREAMHOST_CONNECT_TIMEOUT seconds, otherwise it takes forever */
- if (xfer->type != PURPLE_XFER_SEND && jsx->connect_data != NULL)
+ if (purple_xfer_get_type(xfer) != PURPLE_XFER_SEND && jsx->connect_data != NULL)
jsx->connect_timeout = purple_timeout_add_seconds(
STREAMHOST_CONNECT_TIMEOUT, connect_timeout_cb, xfer);
@@ -337,7 +337,7 @@ void jabber_bytestreams_parse(JabberStream *js, const char *from,
if(!(xfer = jabber_si_xfer_find(js, sid, from)))
return;
- jsx = xfer->data;
+ jsx = purple_xfer_get_protocol_data(xfer);
if(!jsx->accepted)
return;
@@ -375,15 +375,13 @@ jabber_si_xfer_bytestreams_send_read_again_resp_cb(gpointer data, gint source,
PurpleInputCondition cond)
{
PurpleXfer *xfer = data;
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
int len;
len = write(source, jsx->rxqueue + jsx->rxlen, jsx->rxmaxlen - jsx->rxlen);
if (len < 0 && errno == EAGAIN)
return;
else if (len < 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
g_free(jsx->rxqueue);
jsx->rxqueue = NULL;
close(source);
@@ -395,8 +393,8 @@ jabber_si_xfer_bytestreams_send_read_again_resp_cb(gpointer data, gint source,
if (jsx->rxlen < jsx->rxmaxlen)
return;
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
+ purple_input_remove(purple_xfer_get_watcher(xfer));
+ purple_xfer_set_watcher(xfer, 0);
g_free(jsx->rxqueue);
jsx->rxqueue = NULL;
@@ -412,7 +410,7 @@ jabber_si_xfer_bytestreams_send_read_again_cb(gpointer data, gint source,
PurpleInputCondition cond)
{
PurpleXfer *xfer = data;
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
char buffer[42]; /* 40 for DST.ADDR + 2 bytes for port number*/
int len;
char *dstaddr, *hash;
@@ -426,8 +424,6 @@ jabber_si_xfer_bytestreams_send_read_again_cb(gpointer data, gint source,
if(len < 0 && errno == EAGAIN)
return;
else if(len <= 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
close(source);
purple_xfer_cancel_remote(xfer);
return;
@@ -441,8 +437,6 @@ jabber_si_xfer_bytestreams_send_read_again_cb(gpointer data, gint source,
purple_debug_info("jabber", "Invalid socks5 conn req. header[0x%x,0x%x,0x%x,0x%x,0x%x]\n",
jsx->rxqueue[0], jsx->rxqueue[1], jsx->rxqueue[2],
jsx->rxqueue[3], jsx->rxqueue[4]);
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
close(source);
purple_xfer_cancel_remote(xfer);
return;
@@ -455,8 +449,6 @@ jabber_si_xfer_bytestreams_send_read_again_cb(gpointer data, gint source,
if(len < 0 && errno == EAGAIN)
return;
else if(len <= 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
close(source);
purple_xfer_cancel_remote(xfer);
return;
@@ -470,12 +462,12 @@ jabber_si_xfer_bytestreams_send_read_again_cb(gpointer data, gint source,
if(jsx->rxlen - 5 < jsx->rxqueue[4] + 2)
return;
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
+ purple_input_remove(purple_xfer_get_watcher(xfer));
+ purple_xfer_set_watcher(xfer, 0);
dstaddr = g_strdup_printf("%s%s@%s/%s%s", jsx->stream_id,
jsx->js->user->node, jsx->js->user->domain,
- jsx->js->user->resource, xfer->who);
+ jsx->js->user->resource, purple_xfer_get_remote_user(xfer));
/* Per XEP-0065, the 'host' must be SHA1(SID + from JID + to JID) */
hash = jabber_calculate_data_hash(dstaddr, strlen(dstaddr), "sha1");
@@ -516,8 +508,8 @@ jabber_si_xfer_bytestreams_send_read_again_cb(gpointer data, gint source,
jsx->rxqueue[5+strlen(host)] = 0x00;
jsx->rxqueue[6+strlen(host)] = 0x00;
- xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE,
- jabber_si_xfer_bytestreams_send_read_again_resp_cb, xfer);
+ purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_WRITE,
+ jabber_si_xfer_bytestreams_send_read_again_resp_cb, xfer));
jabber_si_xfer_bytestreams_send_read_again_resp_cb(xfer, source,
PURPLE_INPUT_WRITE);
}
@@ -527,15 +519,13 @@ jabber_si_xfer_bytestreams_send_read_response_cb(gpointer data, gint source,
PurpleInputCondition cond)
{
PurpleXfer *xfer = data;
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
int len;
len = write(source, jsx->rxqueue + jsx->rxlen, jsx->rxmaxlen - jsx->rxlen);
if (len < 0 && errno == EAGAIN)
return;
else if (len < 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
g_free(jsx->rxqueue);
jsx->rxqueue = NULL;
close(source);
@@ -547,13 +537,11 @@ jabber_si_xfer_bytestreams_send_read_response_cb(gpointer data, gint source,
if (jsx->rxlen < jsx->rxmaxlen)
return;
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
-
/* If we sent a "Success", wait for a response, otherwise give up and cancel */
if (jsx->rxqueue[1] == 0x00) {
- xfer->watcher = purple_input_add(source, PURPLE_INPUT_READ,
- jabber_si_xfer_bytestreams_send_read_again_cb, xfer);
+ purple_input_remove(purple_xfer_get_watcher(xfer));
+ purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_READ,
+ jabber_si_xfer_bytestreams_send_read_again_cb, xfer));
g_free(jsx->rxqueue);
jsx->rxqueue = NULL;
jsx->rxlen = 0;
@@ -568,14 +556,14 @@ jabber_si_xfer_bytestreams_send_read_cb(gpointer data, gint source,
PurpleInputCondition cond)
{
PurpleXfer *xfer = data;
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
int i;
int len;
char buffer[256];
purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_read_cb\n");
- xfer->fd = source;
+ purple_xfer_set_fd(xfer, source);
/** Try to read the SOCKS5 header */
if(jsx->rxlen < 2) {
@@ -584,9 +572,6 @@ jabber_si_xfer_bytestreams_send_read_cb(gpointer data, gint source,
if(len < 0 && errno == EAGAIN)
return;
else if(len <= 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
- close(source);
purple_xfer_cancel_remote(xfer);
return;
}
@@ -603,9 +588,6 @@ jabber_si_xfer_bytestreams_send_read_cb(gpointer data, gint source,
if(len < 0 && errno == EAGAIN)
return;
else if(len <= 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
- close(source);
purple_xfer_cancel_remote(xfer);
return;
}
@@ -618,13 +600,9 @@ jabber_si_xfer_bytestreams_send_read_cb(gpointer data, gint source,
if(jsx->rxlen -2 < jsx->rxqueue[1])
return;
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
-
purple_debug_info("jabber", "checking to make sure we're socks FIVE\n");
if(jsx->rxqueue[0] != 0x05) {
- close(source);
purple_xfer_cancel_remote(xfer);
return;
}
@@ -641,9 +619,10 @@ jabber_si_xfer_bytestreams_send_read_cb(gpointer data, gint source,
jsx->rxqueue = g_malloc(jsx->rxmaxlen);
jsx->rxqueue[0] = 0x05;
jsx->rxqueue[1] = 0x00;
- xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE,
+ purple_input_remove(purple_xfer_get_watcher(xfer));
+ purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_WRITE,
jabber_si_xfer_bytestreams_send_read_response_cb,
- xfer);
+ xfer));
jabber_si_xfer_bytestreams_send_read_response_cb(xfer,
source, PURPLE_INPUT_WRITE);
jsx->rxqueue = NULL;
@@ -658,8 +637,9 @@ jabber_si_xfer_bytestreams_send_read_cb(gpointer data, gint source,
jsx->rxqueue = g_malloc(jsx->rxmaxlen);
jsx->rxqueue[0] = 0x05;
jsx->rxqueue[1] = 0xFF;
- xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE,
- jabber_si_xfer_bytestreams_send_read_response_cb, xfer);
+ purple_input_remove(purple_xfer_get_watcher(xfer));
+ purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_WRITE,
+ jabber_si_xfer_bytestreams_send_read_response_cb, xfer));
jabber_si_xfer_bytestreams_send_read_response_cb(xfer,
source, PURPLE_INPUT_WRITE);
}
@@ -680,7 +660,7 @@ jabber_si_xfer_bytestreams_send_connected_cb(gpointer data, gint source,
PurpleInputCondition cond)
{
PurpleXfer *xfer = data;
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
int acceptfd, flags;
purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_connected_cb\n");
@@ -694,7 +674,7 @@ jabber_si_xfer_bytestreams_send_connected_cb(gpointer data, gint source,
return;
}
- purple_input_remove(xfer->watcher);
+ purple_input_remove(purple_xfer_get_watcher(xfer));
close(source);
jsx->local_streamhost_fd = -1;
@@ -704,8 +684,8 @@ jabber_si_xfer_bytestreams_send_connected_cb(gpointer data, gint source,
fcntl(acceptfd, F_SETFD, FD_CLOEXEC);
#endif
- xfer->watcher = purple_input_add(acceptfd, PURPLE_INPUT_READ,
- jabber_si_xfer_bytestreams_send_read_cb, xfer);
+ purple_xfer_set_watcher(xfer, purple_input_add(acceptfd, PURPLE_INPUT_READ,
+ jabber_si_xfer_bytestreams_send_read_cb, xfer));
}
static void
@@ -727,12 +707,12 @@ jabber_si_connect_proxy_cb(JabberStream *js, const char *from,
return;
}
+ jsx = purple_xfer_get_protocol_data(xfer);
+
/* In the case of a direct file transfer, this is expected to return */
- if(!xfer->data)
+ if(!jsx)
return;
- jsx = xfer->data;
-
if(type != JABBER_IQ_RESULT) {
purple_debug_info("jabber",
"jabber_si_xfer_connect_proxy_cb: type = error\n");
@@ -781,7 +761,7 @@ jabber_si_connect_proxy_cb(JabberStream *js, const char *from,
jsx->js->user->domain, jsx->js->user->resource);
if (!strcmp(jid, my_jid)) {
purple_debug_info("jabber", "Got local SOCKS5 streamhost-used.\n");
- purple_xfer_start(xfer, xfer->fd, NULL, -1);
+ purple_xfer_start(xfer, purple_xfer_get_fd(xfer), NULL, -1);
} else {
/* if available, try to revert to IBB... */
if (jsx->stream_method & STREAM_METHOD_IBB) {
@@ -805,9 +785,9 @@ jabber_si_connect_proxy_cb(JabberStream *js, const char *from,
}
/* Clean up the local streamhost - it isn't going to be used.*/
- if (xfer->watcher > 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
+ if (purple_xfer_get_watcher(xfer) > 0) {
+ purple_input_remove(purple_xfer_get_watcher(xfer));
+ purple_xfer_set_watcher(xfer, 0);
}
if (jsx->local_streamhost_fd >= 0) {
close(jsx->local_streamhost_fd);
@@ -835,7 +815,7 @@ jabber_si_xfer_bytestreams_listen_cb(int sock, gpointer data)
JabberBytestreamsStreamhost *sh, *sh2;
int streamhost_count = 0;
- jsx = xfer->data;
+ jsx = purple_xfer_get_protocol_data(xfer);
jsx->listen_data = NULL;
/* I'm not sure under which conditions this can happen
@@ -848,7 +828,7 @@ jabber_si_xfer_bytestreams_listen_cb(int sock, gpointer data)
purple_xfer_unref(xfer);
iq = jabber_iq_new_query(jsx->js, JABBER_IQ_SET, NS_BYTESTREAMS);
- xmlnode_set_attrib(iq->node, "to", xfer->who);
+ xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
query = xmlnode_get_child(iq->node, "query");
xmlnode_set_attrib(query, "sid", jsx->stream_id);
@@ -865,8 +845,8 @@ jabber_si_xfer_bytestreams_listen_cb(int sock, gpointer data)
jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node,
jsx->js->user->domain, jsx->js->user->resource);
- xfer->local_port = purple_network_get_port_from_fd(sock);
- g_snprintf(port, sizeof(port), "%hu", xfer->local_port);
+ purple_xfer_set_local_port(xfer, purple_network_get_port_from_fd(sock));
+ g_snprintf(port, sizeof(port), "%hu", purple_xfer_get_local_port(xfer));
public_ip = purple_network_get_my_ip(jsx->js->fd);
@@ -896,8 +876,8 @@ jabber_si_xfer_bytestreams_listen_cb(int sock, gpointer data)
g_free(jid);
/* The listener for the local proxy */
- xfer->watcher = purple_input_add(sock, PURPLE_INPUT_READ,
- jabber_si_xfer_bytestreams_send_connected_cb, xfer);
+ purple_xfer_set_watcher(xfer, purple_input_add(sock, PURPLE_INPUT_READ,
+ jabber_si_xfer_bytestreams_send_connected_cb, xfer));
}
for (tmp = jsx->js->bs_proxies; tmp; tmp = tmp->next) {
@@ -969,7 +949,7 @@ jabber_si_xfer_bytestreams_send_init(PurpleXfer *xfer)
purple_xfer_ref(xfer);
- jsx = xfer->data;
+ jsx = purple_xfer_get_protocol_data(xfer);
/* TODO: This should probably be done with an account option instead of
* piggy-backing on the TOR proxy type. */
@@ -979,7 +959,7 @@ jabber_si_xfer_bytestreams_send_init(PurpleXfer *xfer)
purple_debug_info("jabber", "Skipping attempting local streamhost.\n");
jsx->listen_data = NULL;
} else
- jsx->listen_data = purple_network_listen_range(0, 0, SOCK_STREAM,
+ jsx->listen_data = purple_network_listen_range(0, 0, AF_UNSPEC, SOCK_STREAM, TRUE,
jabber_si_xfer_bytestreams_listen_cb, xfer);
if (jsx->listen_data == NULL) {
@@ -1017,7 +997,7 @@ jabber_si_xfer_ibb_recv_data_cb(JabberIBBSession *sess, gpointer data,
gsize size)
{
PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess);
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
if (size <= purple_xfer_get_bytes_remaining(xfer)) {
purple_debug_info("jabber", "about to write %" G_GSIZE_FORMAT " bytes from IBB stream\n",
@@ -1037,7 +1017,7 @@ jabber_si_xfer_ibb_recv_data_cb(JabberIBBSession *sess, gpointer data,
static gssize
jabber_si_xfer_ibb_read(guchar **out_buffer, PurpleXfer *xfer)
{
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
guchar *buffer;
gsize size;
gsize tmp;
@@ -1060,7 +1040,7 @@ jabber_si_xfer_ibb_open_cb(JabberStream *js, const char *who, const char *id,
const gchar *sid = xmlnode_get_attrib(open, "sid");
PurpleXfer *xfer = jabber_si_xfer_find(js, sid, who);
if (xfer) {
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
JabberIBBSession *sess =
jabber_ibb_session_create_from_xmlnode(js, who, id, open, xfer);
@@ -1105,7 +1085,7 @@ jabber_si_xfer_ibb_open_cb(JabberStream *js, const char *who, const char *id,
static gssize
jabber_si_xfer_ibb_write(const guchar *buffer, size_t len, PurpleXfer *xfer)
{
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
JabberIBBSession *sess = jsx->ibb_session;
gsize packet_size = len < jabber_ibb_session_get_max_data_size(sess) ?
len : jabber_ibb_session_get_max_data_size(sess);
@@ -1119,7 +1099,7 @@ static void
jabber_si_xfer_ibb_sent_cb(JabberIBBSession *sess)
{
PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess);
- gsize remaining = purple_xfer_get_bytes_remaining(xfer);
+ goffset remaining = purple_xfer_get_bytes_remaining(xfer);
if (remaining == 0) {
/* close the session */
@@ -1149,7 +1129,7 @@ jabber_si_xfer_ibb_opened_cb(JabberIBBSession *sess)
static void
jabber_si_xfer_ibb_send_init(JabberStream *js, PurpleXfer *xfer)
{
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
jsx->ibb_session = jabber_ibb_session_create(js, jsx->stream_id,
purple_xfer_get_remote_user(xfer), xfer);
@@ -1206,7 +1186,7 @@ static void jabber_si_xfer_send_method_cb(JabberStream *js, const char *from,
for(field = xmlnode_get_child(x, "field"); field; field = xmlnode_get_next_twin(field)) {
const char *var = xmlnode_get_attrib(field, "var");
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
if(var && !strcmp(var, "stream-method")) {
if((value = xmlnode_get_child(field, "value"))) {
@@ -1237,7 +1217,7 @@ static void jabber_si_xfer_send_method_cb(JabberStream *js, const char *from,
static void jabber_si_xfer_send_request(PurpleXfer *xfer)
{
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
JabberIq *iq;
xmlnode *si, *file, *feature, *x, *field, *option, *value;
char buf[32];
@@ -1247,10 +1227,10 @@ static void jabber_si_xfer_send_request(PurpleXfer *xfer)
purple_xfer_prepare_thumbnail(xfer, "jpeg,png");
#endif
- xfer->filename = g_path_get_basename(xfer->local_filename);
+ purple_xfer_set_filename(xfer, g_path_get_basename(purple_xfer_get_local_filename(xfer)));
iq = jabber_iq_new(jsx->js, JABBER_IQ_SET);
- xmlnode_set_attrib(iq->node, "to", xfer->who);
+ xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
si = xmlnode_new_child(iq->node, "si");
xmlnode_set_namespace(si, "http://jabber.org/protocol/si");
jsx->stream_id = jabber_get_next_id(jsx->js);
@@ -1259,8 +1239,8 @@ static void jabber_si_xfer_send_request(PurpleXfer *xfer)
file = xmlnode_new_child(si, "file");
xmlnode_set_namespace(file, NS_SI_FILE_TRANSFER);
- xmlnode_set_attrib(file, "name", xfer->filename);
- g_snprintf(buf, sizeof(buf), "%" G_GSIZE_FORMAT, xfer->size);
+ xmlnode_set_attrib(file, "name", purple_xfer_get_filename(xfer));
+ g_snprintf(buf, sizeof(buf), "%" G_GOFFSET_FORMAT, purple_xfer_get_size(xfer));
xmlnode_set_attrib(file, "size", buf);
/* maybe later we'll do hash and date attribs */
@@ -1309,7 +1289,7 @@ static void jabber_si_xfer_send_request(PurpleXfer *xfer)
static void jabber_si_xfer_free(PurpleXfer *xfer)
{
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
if (jsx) {
JabberStream *js = jsx->js;
@@ -1324,10 +1304,9 @@ static void jabber_si_xfer_free(PurpleXfer *xfer)
jabber_iq_remove_callback_by_id(js, jsx->iq_id);
if (jsx->local_streamhost_fd >= 0)
close(jsx->local_streamhost_fd);
- if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND &&
- xfer->fd >= 0) {
+ if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND && purple_xfer_get_fd(xfer) >= 0) {
purple_debug_info("jabber", "remove port mapping\n");
- purple_network_remove_port_mapping(xfer->fd);
+ purple_network_remove_port_mapping(purple_xfer_get_fd(xfer));
}
if (jsx->connect_timeout > 0)
purple_timeout_remove(jsx->connect_timeout);
@@ -1356,7 +1335,7 @@ static void jabber_si_xfer_free(PurpleXfer *xfer)
/* XXX: free other stuff */
g_free(jsx->rxqueue);
g_free(jsx);
- xfer->data = NULL;
+ purple_xfer_set_protocol_data(xfer, NULL);
}
}
@@ -1367,7 +1346,7 @@ static void jabber_si_xfer_free(PurpleXfer *xfer)
*/
static void jabber_si_xfer_cancel_send(PurpleXfer *xfer)
{
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
/* if there is an IBB session active, send close on that */
if (jsx->ibb_session) {
@@ -1380,7 +1359,7 @@ static void jabber_si_xfer_cancel_send(PurpleXfer *xfer)
static void jabber_si_xfer_request_denied(PurpleXfer *xfer)
{
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
JabberStream *js = jsx->js;
/*
@@ -1391,7 +1370,7 @@ static void jabber_si_xfer_request_denied(PurpleXfer *xfer)
JabberIq *iq;
xmlnode *error, *child;
iq = jabber_iq_new(js, JABBER_IQ_ERROR);
- xmlnode_set_attrib(iq->node, "to", xfer->who);
+ xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
jabber_iq_set_id(iq, jsx->iq_id);
error = xmlnode_new_child(iq->node, "error");
@@ -1412,7 +1391,7 @@ static void jabber_si_xfer_request_denied(PurpleXfer *xfer)
static void jabber_si_xfer_cancel_recv(PurpleXfer *xfer)
{
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
/* if there is an IBB session active, send close */
if (jsx->ibb_session) {
jabber_ibb_session_close(jsx->ibb_session);
@@ -1432,7 +1411,7 @@ static void jabber_si_xfer_send_disco_cb(JabberStream *js, const char *who,
JabberCapabilities capabilities, gpointer data)
{
PurpleXfer *xfer = (PurpleXfer *) data;
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
if (capabilities & JABBER_CAP_IBB) {
purple_debug_info("jabber",
@@ -1458,8 +1437,8 @@ static void resource_select_cancel_cb(PurpleXfer *xfer, PurpleRequestFields *fie
static void do_transfer_send(PurpleXfer *xfer, const char *resource)
{
- JabberSIXfer *jsx = xfer->data;
- char **who_v = g_strsplit(xfer->who, "/", 2);
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
+ char **who_v = g_strsplit(purple_xfer_get_remote_user(xfer), "/", 2);
char *who;
JabberBuddy *jb;
JabberBuddyResource *jbr = NULL;
@@ -1508,7 +1487,7 @@ static void resource_select_ok_cb(PurpleXfer *xfer, PurpleRequestFields *fields)
static void jabber_si_xfer_init(PurpleXfer *xfer)
{
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
JabberIq *iq;
if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
JabberBuddy *jb;
@@ -1516,7 +1495,7 @@ static void jabber_si_xfer_init(PurpleXfer *xfer)
char *resource;
GList *resources = NULL;
- if(NULL != (resource = jabber_get_resource(xfer->who))) {
+ if(NULL != (resource = jabber_get_resource(purple_xfer_get_remote_user(xfer)))) {
/* they've specified a resource, no need to ask or
* default or anything, just do it */
@@ -1525,7 +1504,7 @@ static void jabber_si_xfer_init(PurpleXfer *xfer)
return;
}
- jb = jabber_buddy_find(jsx->js, xfer->who, TRUE);
+ jb = jabber_buddy_find(jsx->js, purple_xfer_get_remote_user(xfer), TRUE);
if (jb) {
GList *l;
@@ -1549,11 +1528,11 @@ static void jabber_si_xfer_init(PurpleXfer *xfer)
char *msg;
if(!jb) {
- msg = g_strdup_printf(_("Unable to send file to %s, invalid JID"), xfer->who);
+ msg = g_strdup_printf(_("Unable to send file to %s, invalid JID"), purple_xfer_get_remote_user(xfer));
} else if(jb->subscription & JABBER_SUB_TO) {
- msg = g_strdup_printf(_("Unable to send file to %s, user is not online"), xfer->who);
+ msg = g_strdup_printf(_("Unable to send file to %s, user is not online"), purple_xfer_get_remote_user(xfer));
} else {
- msg = g_strdup_printf(_("Unable to send file to %s, not subscribed to user presence"), xfer->who);
+ msg = g_strdup_printf(_("Unable to send file to %s, not subscribed to user presence"), purple_xfer_get_remote_user(xfer));
}
purple_notify_error(jsx->js->gc, _("File Send Failed"), _("File Send Failed"), msg);
@@ -1566,7 +1545,7 @@ static void jabber_si_xfer_init(PurpleXfer *xfer)
} else {
/* we've got multiple resources, we need to pick one to send to */
GList *l;
- char *msg = g_strdup_printf(_("Please select the resource of %s to which you would like to send a file"), xfer->who);
+ char *msg = g_strdup_printf(_("Please select the resource of %s to which you would like to send a file"), purple_xfer_get_remote_user(xfer));
PurpleRequestFields *fields = purple_request_fields_new();
PurpleRequestField *field = purple_request_field_choice_new("resource", _("Resource"), 0);
PurpleRequestFieldGroup *group = purple_request_field_group_new(NULL);
@@ -1582,7 +1561,7 @@ static void jabber_si_xfer_init(PurpleXfer *xfer)
purple_request_fields(jsx->js->gc, _("Select a Resource"), msg, NULL, fields,
_("Send File"), G_CALLBACK(resource_select_ok_cb), _("Cancel"), G_CALLBACK(resource_select_cancel_cb),
- jsx->js->gc->account, xfer->who, NULL, xfer);
+ purple_connection_get_account(jsx->js->gc), purple_xfer_get_remote_user(xfer), NULL, xfer);
g_free(msg);
}
@@ -1592,7 +1571,7 @@ static void jabber_si_xfer_init(PurpleXfer *xfer)
xmlnode *si, *feature, *x, *field, *value;
iq = jabber_iq_new(jsx->js, JABBER_IQ_RESULT);
- xmlnode_set_attrib(iq->node, "to", xfer->who);
+ xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
if(jsx->iq_id)
jabber_iq_set_id(iq, jsx->iq_id);
else
@@ -1636,12 +1615,13 @@ PurpleXfer *jabber_si_new_xfer(PurpleConnection *gc, const char *who)
PurpleXfer *xfer;
JabberSIXfer *jsx;
- js = gc->proto_data;
+ js = purple_connection_get_protocol_data(gc);
- xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who);
+ xfer = purple_xfer_new(purple_connection_get_account(gc), PURPLE_XFER_SEND, who);
if (xfer)
{
- xfer->data = jsx = g_new0(JabberSIXfer, 1);
+ jsx = g_new0(JabberSIXfer, 1);
+ purple_xfer_set_protocol_data(xfer, jsx);
jsx->js = js;
jsx->local_streamhost_fd = -1;
@@ -1696,8 +1676,7 @@ void jabber_si_parse(JabberStream *js, const char *from, JabberIqType type,
xmlnode *thumbnail;
#endif
const char *stream_id, *filename, *filesize_c, *profile;
- guint64 filesize_64 = 0;
- size_t filesize = 0;
+ goffset filesize = 0;
if(!(profile = xmlnode_get_attrib(si, "profile")) ||
strcmp(profile, NS_SI_FILE_TRANSFER))
@@ -1713,17 +1692,7 @@ void jabber_si_parse(JabberStream *js, const char *from, JabberIqType type,
return;
if((filesize_c = xmlnode_get_attrib(file, "size")))
- filesize_64 = g_ascii_strtoull(filesize_c, NULL, 10);
- /* TODO 3.0.0: When the core uses a guint64, this is redundant.
- * See #8477.
- */
- if (filesize_64 > G_MAXSIZE) {
- /* Should this pop up a warning? */
- purple_debug_warning("jabber", "Unable to transfer file (too large)"
- " -- see #8477 for more details.");
- return;
- }
- filesize = filesize_64;
+ filesize = g_ascii_strtoull(filesize_c, NULL, 10);
if(!(feature = xmlnode_get_child(si, "feature")))
return;
@@ -1774,10 +1743,10 @@ void jabber_si_parse(JabberStream *js, const char *from, JabberIqType type,
jsx->stream_id = g_strdup(stream_id);
jsx->iq_id = g_strdup(id);
- xfer = purple_xfer_new(js->gc->account, PURPLE_XFER_RECEIVE, from);
+ xfer = purple_xfer_new(purple_connection_get_account(js->gc), PURPLE_XFER_RECEIVE, from);
g_return_if_fail(xfer != NULL);
- xfer->data = jsx;
+ purple_xfer_set_protocol_data(xfer, jsx);
purple_xfer_set_filename(xfer, filename);
if(filesize > 0)
diff --git a/libpurple/protocols/jabber/useravatar.c b/libpurple/protocols/jabber/useravatar.c
index 37c0b5a0cb..60a16fac91 100644
--- a/libpurple/protocols/jabber/useravatar.c
+++ b/libpurple/protocols/jabber/useravatar.c
@@ -377,7 +377,7 @@ update_buddy_metadata(JabberStream *js, const char *from, xmlnode *items)
JabberBuddyAvatarUpdateURLInfo *info = g_new0(JabberBuddyAvatarUpdateURLInfo, 1);
info->js = js;
- url_data = purple_util_fetch_url_len(url, TRUE, NULL, TRUE,
+ url_data = purple_util_fetch_url(url, TRUE, NULL, TRUE,
MAX_HTTP_BUDDYICON_BYTES,
do_buddy_avatar_update_fromurl, info);
if (url_data) {
diff --git a/libpurple/protocols/jabber/usermood.c b/libpurple/protocols/jabber/usermood.c
index 39138b2c1d..2968093767 100644
--- a/libpurple/protocols/jabber/usermood.c
+++ b/libpurple/protocols/jabber/usermood.c
@@ -115,10 +115,26 @@ static PurpleMood moods[] = {
{"undefined", N_("Undefined"), NULL},
{"weak", N_("Weak"), NULL},
{"worried", N_("Worried"), NULL},
- /* Mark the last record. */
+ /* Mar last record. */
{NULL, NULL, NULL}
};
+static const PurpleMood*
+find_mood_by_name(const gchar *name)
+{
+ int i;
+
+ g_return_val_if_fail(name && *name, NULL);
+
+ for (i = 0; moods[i].mood != NULL; ++i) {
+ if (g_str_equal(name, moods[i].mood)) {
+ return &moods[i];
+ }
+ }
+
+ return NULL;
+}
+
static void jabber_mood_cb(JabberStream *js, const char *from, xmlnode *items) {
/* it doesn't make sense to have more than one item here, so let's just pick the first one */
xmlnode *item = xmlnode_get_child(items, "item");
@@ -139,15 +155,13 @@ static void jabber_mood_cb(JabberStream *js, const char *from, xmlnode *items) {
if (!moodtext) /* only pick the first one */
moodtext = xmlnode_get_data(moodinfo);
} else {
- int i;
- for (i = 0; moods[i].mood; ++i) {
- /* verify that the mood is known (valid) */
- if (!strcmp(moodinfo->name, moods[i].mood)) {
- newmood = moods[i].mood;
- break;
- }
- }
+ const PurpleMood *target_mood;
+
+ /* verify that the mood is known (valid) */
+ target_mood = find_mood_by_name(moodinfo->name);
+ newmood = target_mood ? target_mood->mood : NULL;
}
+
if (newmood != NULL && moodtext != NULL)
break;
}
@@ -155,12 +169,12 @@ static void jabber_mood_cb(JabberStream *js, const char *from, xmlnode *items) {
break;
}
if (newmood != NULL) {
- purple_prpl_got_user_status(js->gc->account, from, "mood",
+ purple_prpl_got_user_status(purple_connection_get_account(js->gc), from, "mood",
PURPLE_MOOD_NAME, newmood,
PURPLE_MOOD_COMMENT, moodtext,
NULL);
} else {
- purple_prpl_got_user_status_deactive(js->gc->account, from, "mood");
+ purple_prpl_got_user_status_deactive(purple_connection_get_account(js->gc), from, "mood");
}
g_free(moodtext);
}
@@ -170,26 +184,41 @@ void jabber_mood_init(void) {
jabber_pep_register_handler("http://jabber.org/protocol/mood", jabber_mood_cb);
}
-void jabber_mood_set(JabberStream *js, const char *mood, const char *text) {
+gboolean
+jabber_mood_set(JabberStream *js, const char *mood, const char *text)
+{
+ const PurpleMood *target_mood = NULL;
xmlnode *publish, *moodnode;
+ if (mood && *mood) {
+ target_mood = find_mood_by_name(mood);
+ /* Mood specified, but is invalid --
+ * fail so that the command can handle this.
+ */
+ if (!target_mood)
+ return FALSE;
+ }
+
publish = xmlnode_new("publish");
xmlnode_set_attrib(publish,"node","http://jabber.org/protocol/mood");
moodnode = xmlnode_new_child(xmlnode_new_child(publish, "item"), "mood");
xmlnode_set_namespace(moodnode, "http://jabber.org/protocol/mood");
- if (mood && *mood) {
- /* if mood is NULL, set an empty mood node, meaning: unset mood */
+
+ if (target_mood) {
+ /* If target_mood is not NULL, then
+ * target_mood->mood == mood, and is a valid element name.
+ */
xmlnode_new_child(moodnode, mood);
- }
- if (text && *text) {
- xmlnode *textnode = xmlnode_new_child(moodnode, "text");
- xmlnode_insert_data(textnode, text, -1);
+ /* Only set text when setting a mood */
+ if (text && *text) {
+ xmlnode *textnode = xmlnode_new_child(moodnode, "text");
+ xmlnode_insert_data(textnode, text, -1);
+ }
}
jabber_pep_publish(js, publish);
- /* publish is freed by jabber_pep_publish -> jabber_iq_send -> jabber_iq_free
- (yay for well-defined memory management rules) */
+ return TRUE;
}
PurpleMood *jabber_get_moods(PurpleAccount *account)
diff --git a/libpurple/protocols/jabber/usermood.h b/libpurple/protocols/jabber/usermood.h
index ad90ce3b1d..eced59f116 100644
--- a/libpurple/protocols/jabber/usermood.h
+++ b/libpurple/protocols/jabber/usermood.h
@@ -30,9 +30,20 @@
void jabber_mood_init(void);
-void jabber_mood_set(JabberStream *js,
- const char *mood, /* must be one of the valid strings defined in the XEP */
- const char *text /* might be NULL */);
+/**
+ * Sets / unsets the mood for the specified account. The mood passed in
+ * must either be NULL, "", or one of the moods returned by
+ * jabber_get_moods().
+ *
+ * @param js The JabberStream object.
+ * @param mood The mood to set, NULL, or ""
+ * @param text Optional text that goes along with a mood. Only used when
+ * setting a mood (not when unsetting a mood).
+ *
+ * @return FALSE if an invalid mood was specified, or TRUE otherwise.
+ */
+gboolean
+jabber_mood_set(JabberStream *js, const char *mood, const char *text);
PurpleMood *jabber_get_moods(PurpleAccount *account);
diff --git a/libpurple/protocols/jabber/usertune.c b/libpurple/protocols/jabber/usertune.c
index 03e485ef1b..99c3ed87d9 100644
--- a/libpurple/protocols/jabber/usertune.c
+++ b/libpurple/protocols/jabber/usertune.c
@@ -92,7 +92,7 @@ static void jabber_tune_cb(JabberStream *js, const char *from, xmlnode *items) {
}
if (valid) {
- purple_prpl_got_user_status(js->gc->account, from, "tune",
+ purple_prpl_got_user_status(purple_connection_get_account(js->gc), from, "tune",
PURPLE_TUNE_ARTIST, tuneinfodata.artist,
PURPLE_TUNE_TITLE, tuneinfodata.title,
PURPLE_TUNE_ALBUM, tuneinfodata.album,
@@ -100,7 +100,7 @@ static void jabber_tune_cb(JabberStream *js, const char *from, xmlnode *items) {
PURPLE_TUNE_TIME, tuneinfodata.time,
PURPLE_TUNE_URL, tuneinfodata.url, NULL);
} else {
- purple_prpl_got_user_status_deactive(js->gc->account, from, "tune");
+ purple_prpl_got_user_status_deactive(purple_connection_get_account(js->gc), from, "tune");
}
g_free(tuneinfodata.artist);
@@ -117,7 +117,7 @@ void jabber_tune_init(void) {
void jabber_tune_set(PurpleConnection *gc, const PurpleJabberTuneInfo *tuneinfo) {
xmlnode *publish, *tunenode;
- JabberStream *js = gc->proto_data;
+ JabberStream *js = purple_connection_get_protocol_data(gc);
publish = xmlnode_new("publish");
xmlnode_set_attrib(publish,"node","http://jabber.org/protocol/tune");
diff --git a/libpurple/protocols/msn/contact.c b/libpurple/protocols/msn/contact.c
index 0e7ebcc652..274eb6b4e2 100644
--- a/libpurple/protocols/msn/contact.c
+++ b/libpurple/protocols/msn/contact.c
@@ -740,6 +740,20 @@ msn_parse_addressbook_contacts(MsnSession *session, xmlnode *node)
}
passportName = xmlnode_get_child(contactInfo, "passportName");
+ if (passportName != NULL) {
+ xmlnode *messenger_user;
+ /* ignore non-messenger contacts */
+ if ((messenger_user = xmlnode_get_child(contactInfo, "isMessengerUser"))) {
+ char *is_messenger_user = xmlnode_get_data(messenger_user);
+
+ if (is_messenger_user && !strcmp(is_messenger_user, "false")) {
+ passportName = NULL;
+ }
+
+ g_free(is_messenger_user);
+ }
+ }
+
if (passportName == NULL) {
xmlnode *emailsNode, *contactEmailNode, *emailNode;
xmlnode *messengerEnabledNode;
@@ -773,19 +787,6 @@ msn_parse_addressbook_contacts(MsnSession *session, xmlnode *node)
}
}
} else {
- xmlnode *messenger_user;
- /* ignore non-messenger contacts */
- if ((messenger_user = xmlnode_get_child(contactInfo, "isMessengerUser"))) {
- char *is_messenger_user = xmlnode_get_data(messenger_user);
-
- if (is_messenger_user && !strcmp(is_messenger_user, "false")) {
- g_free(is_messenger_user);
- continue;
- }
-
- g_free(is_messenger_user);
- }
-
passport = xmlnode_get_data(passportName);
}
@@ -992,7 +993,7 @@ msn_get_address_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
purple_debug_misc("msn", "Got the Address Book!\n");
if (msn_parse_addressbook(session, resp->xml)) {
- msn_send_privacy(session->account->gc);
+ msn_send_privacy(purple_account_get_connection(session->account));
msn_notification_dump_contact(session);
} else {
/* This is making us loop infinitely when we fail to parse the
@@ -1275,7 +1276,7 @@ msn_add_contact_to_group(MsnSession *session, MsnCallbackState *state,
body = g_markup_escape_text(user->invite_message, -1);
/* Ignore the cast, we treat it as const anyway. */
- tmp = (char *)purple_connection_get_display_name(session->account->gc);
+ tmp = (char *)purple_connection_get_display_name(purple_account_get_connection(session->account));
tmp = tmp ? g_markup_escape_text(tmp, -1) : g_strdup("");
invite = g_strdup_printf(MSN_CONTACT_INVITE_MESSAGE_XML, body, tmp);
diff --git a/libpurple/protocols/msn/error.c b/libpurple/protocols/msn/error.c
index 68690ef384..18df67a8d5 100644
--- a/libpurple/protocols/msn/error.c
+++ b/libpurple/protocols/msn/error.c
@@ -274,7 +274,7 @@ msn_error_handle(MsnSession *session, unsigned int type)
if (debug)
purple_debug_warning("msn", "error %d: %s\n", type, buf);
else
- purple_notify_error(session->account->gc, NULL, buf, NULL);
+ purple_notify_error(purple_account_get_connection(session->account), NULL, buf, NULL);
g_free(buf);
}
diff --git a/libpurple/protocols/msn/httpconn.c b/libpurple/protocols/msn/httpconn.c
index 5bdcd61c15..36718342bd 100644
--- a/libpurple/protocols/msn/httpconn.c
+++ b/libpurple/protocols/msn/httpconn.c
@@ -285,8 +285,10 @@ read_cb(gpointer data, gint source, PurpleInputCondition cond)
httpconn = data;
servconn = httpconn->servconn;
- if (servconn->type == MSN_SERVCONN_NS)
- servconn->session->account->gc->last_received = time(NULL);
+ if (servconn->type == MSN_SERVCONN_NS) {
+ PurpleConnection *gc = purple_account_get_connection(servconn->session->account);
+ purple_connection_update_last_received(gc);
+ }
len = read(httpconn->fd, buf, sizeof(buf) - 1);
if (len < 0 && errno == EAGAIN)
diff --git a/libpurple/protocols/msn/msg.c b/libpurple/protocols/msn/msg.c
index 2584bc98f0..755bf0b21d 100644
--- a/libpurple/protocols/msn/msg.c
+++ b/libpurple/protocols/msn/msg.c
@@ -413,8 +413,7 @@ msn_message_set_bin_data(MsnMessage *msg, const void *data, size_t len)
if (len > 1664)
len = 1664;
- if (msg->body != NULL)
- g_free(msg->body);
+ g_free(msg->body);
if (data != NULL && len > 0)
{
@@ -661,7 +660,7 @@ msn_plain_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
const char *passport;
const char *value;
- gc = cmdproc->session->account->gc;
+ gc = purple_account_get_connection(cmdproc->session->account);
body = msn_message_get_bin_data(msg, &body_len);
body_enc = g_markup_escape_text(body, body_len);
@@ -722,7 +721,7 @@ msn_plain_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
swboard->flag |= MSN_SB_FLAG_IM;
}
}
- else if (!g_str_equal(passport, purple_account_get_username(gc->account)))
+ else if (!g_str_equal(passport, purple_account_get_username(purple_connection_get_account(gc))))
{
/* Don't im ourselves ... */
serv_got_im(gc, passport, body_final, 0, time(NULL));
@@ -747,7 +746,7 @@ msn_control_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
PurpleConnection *gc;
char *passport;
- gc = cmdproc->session->account->gc;
+ gc = purple_account_get_connection(cmdproc->session->account);
passport = msg->remote_user;
if (msn_message_get_header_value(msg, "TypingUser") == NULL)
@@ -796,7 +795,7 @@ datacast_inform_user(MsnSwitchBoard *swboard, const char *who,
if (swboard->conv == NULL) {
if (chat)
- swboard->conv = purple_find_chat(account->gc, swboard->chat_id);
+ swboard->conv = purple_find_chat(purple_account_get_connection(account), swboard->chat_id);
else {
swboard->conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
who, account);
@@ -1004,7 +1003,7 @@ void msn_emoticon_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
msn_slplink_request_object(slplink, smile, got_emoticon, NULL, obj);
}
- msn_object_destroy(obj);
+ msn_object_destroy(obj, FALSE);
obj = NULL;
who = NULL;
sha1 = NULL;
@@ -1025,21 +1024,23 @@ msn_datacast_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
/* Nudge */
PurpleAccount *account;
const char *user;
+ PurpleConnection *gc;
account = cmdproc->session->account;
user = msg->remote_user;
+ gc = purple_account_get_connection(account);
if (cmdproc->servconn->type == MSN_SERVCONN_SB) {
MsnSwitchBoard *swboard = cmdproc->data;
if (swboard->current_users > 1 ||
((swboard->conv != NULL) &&
purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))
- purple_prpl_got_attention_in_chat(account->gc, swboard->chat_id, user, MSN_NUDGE);
+ purple_prpl_got_attention_in_chat(gc, swboard->chat_id, user, MSN_NUDGE);
else
- purple_prpl_got_attention(account->gc, user, MSN_NUDGE);
+ purple_prpl_got_attention(gc, user, MSN_NUDGE);
} else {
- purple_prpl_got_attention(account->gc, user, MSN_NUDGE);
+ purple_prpl_got_attention(gc, user, MSN_NUDGE);
}
} else if (!strcmp(id, "2")) {
@@ -1059,7 +1060,7 @@ msn_datacast_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
slplink = msn_session_get_slplink(session, who);
msn_slplink_request_object(slplink, data, got_wink_cb, NULL, obj);
- msn_object_destroy(obj);
+ msn_object_destroy(obj, FALSE);
} else if (!strcmp(id, "3")) {
@@ -1079,7 +1080,7 @@ msn_datacast_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
slplink = msn_session_get_slplink(session, who);
msn_slplink_request_object(slplink, data, got_voiceclip_cb, NULL, obj);
- msn_object_destroy(obj);
+ msn_object_destroy(obj, FALSE);
} else if (!strcmp(id, "4")) {
/* Action */
diff --git a/libpurple/protocols/msn/msn.c b/libpurple/protocols/msn/msn.c
index 1286590abf..17e3362c00 100644
--- a/libpurple/protocols/msn/msn.c
+++ b/libpurple/protocols/msn/msn.c
@@ -119,7 +119,7 @@ msn_send_attention(PurpleConnection *gc, const char *username, guint type)
MsnSwitchBoard *swboard;
msg = msn_message_new_nudge();
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
swboard = msn_session_get_swboard(session, username, MSN_SB_FLAG_IM);
msn_switchboard_send_msg(swboard, msg, TRUE);
@@ -326,7 +326,7 @@ msn_set_prp(PurpleConnection *gc, const char *type, const char *entry)
MsnSession *session;
MsnTransaction *trans;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
cmdproc = session->notification->cmdproc;
if (entry == NULL || *entry == '\0')
@@ -384,7 +384,7 @@ send_to_mobile(PurpleConnection *gc, const char *who, const char *entry)
const char *mobile_number = NULL;
gsize payload_len;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
cmdproc = session->notification->cmdproc;
page = msn_page_new();
@@ -647,7 +647,7 @@ msn_show_set_home_phone(PurplePluginAction *action)
MsnSession *session;
gc = (PurpleConnection *) action->context;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
purple_request_input(gc, NULL, _("Set your home phone number."), NULL,
msn_user_get_home_phone(session->user), FALSE, FALSE, NULL,
@@ -664,7 +664,7 @@ msn_show_set_work_phone(PurplePluginAction *action)
MsnSession *session;
gc = (PurpleConnection *) action->context;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
purple_request_input(gc, NULL, _("Set your work phone number."), NULL,
msn_user_get_work_phone(session->user), FALSE, FALSE, NULL,
@@ -681,7 +681,7 @@ msn_show_set_mobile_phone(PurplePluginAction *action)
MsnSession *session;
gc = (PurpleConnection *) action->context;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
purple_request_input(gc, NULL, _("Set your mobile phone number."), NULL,
msn_user_get_mobile_phone(session->user), FALSE, FALSE, NULL,
@@ -719,7 +719,7 @@ msn_show_blocked_text(PurplePluginAction *action)
MsnSession *session;
char *title;
- session = pc->proto_data;
+ session = purple_connection_get_protocol_data(pc);
title = g_strdup_printf(_("Blocked Text for %s"), session->account->username);
if (session->blocked_text == NULL) {
@@ -743,7 +743,7 @@ msn_show_hotmail_inbox(PurplePluginAction *action)
MsnSession *session;
gc = (PurpleConnection *) action->context;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
if (!session->passport_info.email_enabled) {
purple_notify_error(gc, NULL,
@@ -810,11 +810,11 @@ msn_send_privacy(PurpleConnection *gc)
MsnTransaction *trans;
account = purple_connection_get_account(gc);
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
cmdproc = session->notification->cmdproc;
- if (account->perm_deny == PURPLE_PRIVACY_ALLOW_ALL ||
- account->perm_deny == PURPLE_PRIVACY_DENY_USERS)
+ if (purple_account_get_privacy_type(account) == PURPLE_PRIVACY_ALLOW_ALL ||
+ purple_account_get_privacy_type(account) == PURPLE_PRIVACY_DENY_USERS)
trans = msn_transaction_new(cmdproc, "BLP", "%s", "AL");
else
trans = msn_transaction_new(cmdproc, "BLP", "%s", "BL");
@@ -840,7 +840,7 @@ initiate_chat_cb(PurpleBlistNode *node, gpointer data)
account = purple_buddy_get_account(buddy);
gc = purple_account_get_connection(account);
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
swboard = msn_switchboard_new(session);
msn_switchboard_request(swboard);
@@ -869,7 +869,7 @@ t_msn_xfer_init(PurpleXfer *xfer)
static void
t_msn_xfer_cancel_send(PurpleXfer *xfer)
{
- MsnSlpLink *slplink = xfer->data;
+ MsnSlpLink *slplink = purple_xfer_get_protocol_data(xfer);
msn_slplink_unref(slplink);
}
@@ -879,13 +879,13 @@ msn_new_xfer(PurpleConnection *gc, const char *who)
MsnSession *session;
PurpleXfer *xfer;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
- xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who);
+ xfer = purple_xfer_new(purple_connection_get_account(gc), PURPLE_XFER_SEND, who);
g_return_val_if_fail(xfer != NULL, NULL);
- xfer->data = msn_slplink_ref(msn_session_get_slplink(session, who));
+ purple_xfer_set_protocol_data(xfer, msn_slplink_ref(msn_session_get_slplink(session, who)));
purple_xfer_set_init_fnc(xfer, t_msn_xfer_init);
purple_xfer_set_cancel_send_fnc(xfer, t_msn_xfer_cancel_send);
@@ -918,7 +918,7 @@ msn_can_receive_file(PurpleConnection *gc, const char *who)
g_free(normal);
if (ret) {
- MsnSession *session = gc->proto_data;
+ MsnSession *session = purple_connection_get_protocol_data(gc);
if (session) {
MsnUser *user = msn_userlist_find_user(session->userlist, who);
if (user) {
@@ -1078,7 +1078,7 @@ msn_tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboolean f
if (psm != NULL && *psm) {
purple_notify_user_info_add_pair_plaintext(user_info, tmp2, psm);
} else {
- purple_notify_user_info_add_pair(user_info, _("Status"), tmp2);
+ purple_notify_user_info_add_pair_html(user_info, _("Status"), tmp2);
}
g_free(tmp2);
@@ -1091,17 +1091,17 @@ msn_tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboolean f
}
} else {
if (purple_presence_is_idle(presence)) {
- purple_notify_user_info_add_pair(user_info, _("Status"),
- _("Idle"));
+ purple_notify_user_info_add_pair_plaintext(user_info,
+ _("Status"), _("Idle"));
} else {
- purple_notify_user_info_add_pair(user_info, _("Status"),
- purple_status_get_name(status));
+ purple_notify_user_info_add_pair_plaintext(user_info,
+ _("Status"), purple_status_get_name(status));
}
}
}
if (currentmedia) {
- purple_notify_user_info_add_pair(user_info, mediatype, currentmedia);
+ purple_notify_user_info_add_pair_html(user_info, mediatype, currentmedia);
g_free(currentmedia);
}
}
@@ -1119,23 +1119,26 @@ msn_tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboolean f
{
const char *phone;
- purple_notify_user_info_add_pair(user_info, _("Has you"),
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Has you"),
((user->list_op & (1 << MSN_LIST_RL)) ? _("Yes") : _("No")));
- purple_notify_user_info_add_pair(user_info, _("Blocked"),
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Blocked"),
((user->list_op & (1 << MSN_LIST_BL)) ? _("Yes") : _("No")));
phone = msn_user_get_home_phone(user);
- if (phone != NULL)
- purple_notify_user_info_add_pair(user_info, _("Home Phone Number"), phone);
+ if (phone != NULL) {
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Home Phone Number"), phone);
+ }
phone = msn_user_get_work_phone(user);
- if (phone != NULL)
- purple_notify_user_info_add_pair(user_info, _("Work Phone Number"), phone);
+ if (phone != NULL) {
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Work Phone Number"), phone);
+ }
phone = msn_user_get_mobile_phone(user);
- if (phone != NULL)
- purple_notify_user_info_add_pair(user_info, _("Mobile Phone Number"), phone);
+ if (phone != NULL) {
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Mobile Phone Number"), phone);
+ }
}
}
@@ -1213,7 +1216,7 @@ msn_actions(PurplePlugin *plugin, gpointer context)
PurplePluginAction *act;
gc = (PurpleConnection *) context;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
act = purple_plugin_action_new(_("Set Friendly Name..."),
msn_show_set_friendly_name);
@@ -1333,7 +1336,7 @@ msn_login(PurpleAccount *account)
if (!purple_ssl_is_supported())
{
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
_("SSL support is needed for MSN. Please install a supported "
"SSL library."));
@@ -1350,9 +1353,10 @@ msn_login(PurpleAccount *account)
session = msn_session_new(account);
- gc->proto_data = session;
- gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_FORMATTING_WBFO | PURPLE_CONNECTION_NO_BGCOLOR |
- PURPLE_CONNECTION_NO_FONTSIZE | PURPLE_CONNECTION_NO_URLDESC | PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY;
+ purple_connection_set_protocol_data(gc, session);
+ purple_connection_set_flags(gc,
+ PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_FORMATTING_WBFO | PURPLE_CONNECTION_NO_BGCOLOR |
+ PURPLE_CONNECTION_NO_FONTSIZE | PURPLE_CONNECTION_NO_URLDESC | PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY);
msn_session_set_login_step(session, MSN_LOGIN_STEP_START);
@@ -1374,7 +1378,7 @@ msn_login(PurpleAccount *account)
}
if (!msn_session_connect(session, host, port, http_method))
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect"));
}
@@ -1384,13 +1388,13 @@ msn_close(PurpleConnection *gc)
{
MsnSession *session;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
g_return_if_fail(session != NULL);
msn_session_destroy(session);
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
}
static gboolean
@@ -1450,7 +1454,7 @@ msn_send_emoticons(MsnSwitchBoard *swboard, GString *body)
static void msn_emoticon_destroy(MsnEmoticon *emoticon)
{
if (emoticon->obj)
- msn_object_destroy(emoticon->obj);
+ msn_object_destroy(emoticon->obj, FALSE);
g_free(emoticon->smile);
g_free(emoticon);
}
@@ -1523,7 +1527,7 @@ msn_send_im(PurpleConnection *gc, const char *who, const char *message,
PurpleMessageFlags flags)
{
PurpleAccount *account;
- PurpleBuddy *buddy = purple_find_buddy(gc->account, who);
+ PurpleBuddy *buddy = purple_find_buddy(purple_connection_get_account(gc), who);
MsnSession *session;
MsnSwitchBoard *swboard;
MsnMessage *msg;
@@ -1536,7 +1540,7 @@ msn_send_im(PurpleConnection *gc, const char *who, const char *message,
account = purple_connection_get_account(gc);
username = purple_account_get_username(account);
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
swboard = msn_session_find_swboard(session, who);
if (!strncmp("tel:+", who, 5)) {
@@ -1642,7 +1646,7 @@ msn_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state)
MsnMessage *msg;
account = purple_connection_get_account(gc);
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
/*
* TODO: I feel like this should be "if (state != PURPLE_TYPING)"
@@ -1691,7 +1695,7 @@ msn_set_status(PurpleAccount *account, PurpleStatus *status)
if (gc != NULL)
{
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
msn_change_status(session);
}
}
@@ -1701,7 +1705,7 @@ msn_set_idle(PurpleConnection *gc, int idle)
{
MsnSession *session;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
msn_change_status(session);
}
@@ -1831,7 +1835,7 @@ msn_rem_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
MsnSession *session;
MsnUserList *userlist;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
userlist = session->userlist;
if (!session->logged_in)
@@ -1848,7 +1852,7 @@ msn_add_permit(PurpleConnection *gc, const char *who)
MsnUserList *userlist;
MsnUser *user;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
userlist = session->userlist;
user = msn_userlist_find_user(userlist, who);
@@ -1876,7 +1880,7 @@ msn_add_deny(PurpleConnection *gc, const char *who)
MsnUserList *userlist;
MsnUser *user;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
userlist = session->userlist;
user = msn_userlist_find_user(userlist, who);
@@ -1903,7 +1907,7 @@ msn_rem_permit(PurpleConnection *gc, const char *who)
MsnUserList *userlist;
MsnUser *user;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
userlist = session->userlist;
if (!session->logged_in)
@@ -1926,7 +1930,7 @@ msn_rem_deny(PurpleConnection *gc, const char *who)
MsnUserList *userlist;
MsnUser *user;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
userlist = session->userlist;
if (!session->logged_in)
@@ -1955,7 +1959,7 @@ msn_chat_invite(PurpleConnection *gc, int id, const char *msg,
MsnSession *session;
MsnSwitchBoard *swboard;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
swboard = msn_session_find_swboard_with_id(session, id);
@@ -1980,7 +1984,7 @@ msn_chat_leave(PurpleConnection *gc, int id)
MsnSwitchBoard *swboard;
PurpleConversation *conv;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
swboard = msn_session_find_swboard_with_id(session, id);
@@ -2017,7 +2021,7 @@ msn_chat_send(PurpleConnection *gc, int id, const char *message, PurpleMessageFl
GString *emoticons = NULL;
account = purple_connection_get_account(gc);
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
username = purple_account_get_username(account);
swboard = msn_session_find_swboard_with_id(session, id);
@@ -2083,7 +2087,7 @@ msn_keepalive(PurpleConnection *gc)
MsnSession *session;
MsnTransaction *trans;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
if (!session->http_method)
{
@@ -2101,7 +2105,7 @@ static void msn_alias_buddy(PurpleConnection *pc, const char *name, const char *
{
MsnSession *session;
- session = pc->proto_data;
+ session = purple_connection_get_protocol_data(pc);
msn_update_contact(session, name, MSN_UPDATE_ALIAS, alias);
}
@@ -2113,7 +2117,7 @@ msn_group_buddy(PurpleConnection *gc, const char *who,
MsnSession *session;
MsnUserList *userlist;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
userlist = session->userlist;
msn_userlist_move_buddy(userlist, who, old_group_name, new_group_name);
@@ -2126,7 +2130,7 @@ msn_rename_group(PurpleConnection *gc, const char *old_name,
MsnSession *session;
const char *gname;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
g_return_if_fail(session != NULL);
g_return_if_fail(session->userlist != NULL);
@@ -2150,7 +2154,7 @@ msn_convo_closed(PurpleConnection *gc, const char *who)
MsnSwitchBoard *swboard;
PurpleConversation *conv;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
swboard = msn_session_find_swboard(session, who);
@@ -2186,7 +2190,7 @@ msn_set_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img)
MsnSession *session;
MsnUser *user;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
user = session->user;
msn_user_set_buddy_icon(user, img);
@@ -2200,7 +2204,7 @@ msn_remove_group(PurpleConnection *gc, PurpleGroup *group)
MsnSession *session;
const char *gname;
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
gname = purple_group_get_name(group);
purple_debug_info("msn", "Remove group %s\n", gname);
@@ -2241,7 +2245,7 @@ msn_tooltip_extract_info_text(PurpleNotifyUserInfo *user_info, MsnGetInfoData *i
{
char *nicktext = g_markup_escape_text(alias, -1);
tmp = g_strdup_printf("<font sml=\"msn\">%s</font>", nicktext);
- purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp);
+ purple_notify_user_info_add_pair_html(user_info, _("Nickname"), tmp);
g_free(tmp);
g_free(nicktext);
}
@@ -2340,7 +2344,7 @@ msn_got_info(PurpleUtilFetchUrlData *url_data, gpointer data,
if (error_message != NULL || url_text == NULL || strcmp(url_text, "") == 0)
{
- purple_notify_user_info_add_pair(user_info,
+ purple_notify_user_info_add_pair_html(user_info,
_("Error retrieving profile"), NULL);
purple_notify_userinfo(info_data->gc, info_data->name, user_info, NULL, NULL);
@@ -2659,7 +2663,7 @@ msn_got_info(PurpleUtilFetchUrlData *url_data, gpointer data,
if (user_url != NULL)
{
tmp = g_strdup_printf("<a href=\"%s\">%s</a>", user_url, user_url);
- purple_notify_user_info_add_pair(user_info, _("Homepage"), tmp);
+ purple_notify_user_info_add_pair_html(user_info, _("Homepage"), tmp);
g_free(tmp);
g_free(user_url);
@@ -2682,9 +2686,9 @@ msn_got_info(PurpleUtilFetchUrlData *url_data, gpointer data,
char *p = strstr(url_buffer, "<form id=\"profile_form\" name=\"profile_form\" action=\"http&#58;&#47;&#47;spaces.live.com&#47;profile.aspx&#63;cid&#61;0\"");
PurpleBuddy *b = purple_find_buddy
(purple_connection_get_account(info_data->gc), info_data->name);
- purple_notify_user_info_add_pair(user_info,
+ purple_notify_user_info_add_pair_html(user_info,
_("Error retrieving profile"), NULL);
- purple_notify_user_info_add_pair(user_info, NULL,
+ purple_notify_user_info_add_pair_plaintext(user_info, NULL,
((p && b) ? _("The user has not created a public profile.") :
(p ? _("MSN reported not being able to find the user's profile. "
"This either means that the user does not exist, "
@@ -2699,7 +2703,7 @@ msn_got_info(PurpleUtilFetchUrlData *url_data, gpointer data,
purple_notify_user_info_add_section_break(user_info);
tmp = g_strdup_printf("<a href=\"%s%s\">%s</a>",
PROFILE_URL, info_data->name, _("View web profile"));
- purple_notify_user_info_add_pair(user_info, NULL, tmp);
+ purple_notify_user_info_add_pair_html(user_info, NULL, tmp);
g_free(tmp);
#if PHOTO_SUPPORT
@@ -2718,7 +2722,7 @@ msn_got_info(PurpleUtilFetchUrlData *url_data, gpointer data,
/* Try to put the photo in there too, if there's one */
if (photo_url_text)
{
- url_data = purple_util_fetch_url_len(photo_url_text, FALSE, NULL, FALSE,
+ url_data = purple_util_fetch_url(photo_url_text, FALSE, NULL, FALSE,
MAX_HTTP_BUDDYICON_BYTES,
msn_got_photo, info2_data);
session->url_datas = g_slist_prepend(session->url_datas, url_data);
@@ -2780,7 +2784,7 @@ msn_got_photo(PurpleUtilFetchUrlData *url_data, gpointer user_data,
purple_debug_info("msn", "%s is %" G_GSIZE_FORMAT " bytes\n", photo_url_text, len);
id = purple_imgstore_add_with_id(g_memdup(url_text, len), len, NULL);
g_snprintf(buf, sizeof(buf), "<img id=\"%d\"><br>", id);
- purple_notify_user_info_prepend_pair(user_info, NULL, buf);
+ purple_notify_user_info_prepend_pair_html(user_info, NULL, buf);
}
}
@@ -2817,7 +2821,7 @@ msn_get_info(PurpleConnection *gc, const char *name)
url_data = purple_util_fetch_url(url, FALSE,
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
- TRUE, msn_got_info, data);
+ TRUE, -1, msn_got_info, data);
session->url_datas = g_slist_prepend(session->url_datas, url_data);
g_free(url);
@@ -2906,6 +2910,7 @@ static gboolean msn_uri_handler(const char *proto, const char *cmd, GHashTable *
static PurplePluginProtocolInfo prpl_info =
{
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
OPT_PROTO_MAIL_CHECK|OPT_PROTO_INVITE_MESSAGE,
NULL, /* user_splits */
NULL, /* protocol_options */
@@ -2927,7 +2932,7 @@ static PurplePluginProtocolInfo prpl_info =
msn_set_status, /* set_away */
msn_set_idle, /* set_idle */
NULL, /* change_passwd */
- NULL, /* add_buddy */
+ msn_add_buddy, /* add_buddy */
NULL, /* add_buddies */
msn_rem_buddy, /* remove_buddy */
NULL, /* remove_buddies */
@@ -2946,7 +2951,6 @@ static PurplePluginProtocolInfo prpl_info =
msn_keepalive, /* keepalive */
NULL, /* register_user */
NULL, /* get_cb_info */
- NULL, /* get_cb_away */
msn_alias_buddy, /* alias_buddy */
msn_group_buddy, /* group_buddy */
msn_rename_group, /* rename_group */
@@ -2971,15 +2975,12 @@ static PurplePluginProtocolInfo prpl_info =
NULL, /* unregister_user */
msn_send_attention, /* send_attention */
msn_attention_types, /* attention_types */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
msn_get_account_text_table, /* get_account_text_table */
NULL, /* initiate_media */
NULL, /* get_media_caps */
NULL, /* get_moods */
msn_set_public_alias, /* set_public_alias */
- msn_get_public_alias, /* get_public_alias */
- msn_add_buddy, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ msn_get_public_alias /* get_public_alias */
};
static PurplePluginInfo info =
diff --git a/libpurple/protocols/msn/nexus.c b/libpurple/protocols/msn/nexus.c
index 693b6db559..e99a19e452 100644
--- a/libpurple/protocols/msn/nexus.c
+++ b/libpurple/protocols/msn/nexus.c
@@ -389,7 +389,7 @@ msn_nexus_connect(MsnNexus *nexus)
msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE);
username = purple_account_get_username(session->account);
- password = purple_connection_get_password(session->account->gc);
+ password = purple_connection_get_password(purple_account_get_connection(session->account));
if (g_utf8_strlen(password, -1) > 16) {
/* max byte size for 16 utf8 characters is 64 + 1 for the null */
gchar truncated[65];
diff --git a/libpurple/protocols/msn/notification.c b/libpurple/protocols/msn/notification.c
index 5dadc3ee7d..ebc6eee977 100644
--- a/libpurple/protocols/msn/notification.c
+++ b/libpurple/protocols/msn/notification.c
@@ -1203,7 +1203,7 @@ ipg_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len)
if (id && strcmp(id, "1")) {
PurpleConversation *conv
= purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY,
- who, gc->account);
+ who, purple_connection_get_account(gc));
if (conv != NULL) {
const char *error;
if (!strcmp(id, "407"))
@@ -1402,7 +1402,7 @@ url_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
session = cmdproc->session;
account = session->account;
- gc = account->gc;
+ gc = purple_account_get_connection(account);
rru = cmd->params[1];
url = cmd->params[2];
@@ -2041,7 +2041,7 @@ initial_email_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
const char *unread;
session = cmdproc->session;
- gc = session->account->gc;
+ gc = purple_account_get_connection(session->account);
if (strcmp(msg->remote_user, "Hotmail"))
/* This isn't an official message. */
@@ -2092,7 +2092,7 @@ initial_mdata_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
const char *mdata, *unread;
session = cmdproc->session;
- gc = session->account->gc;
+ gc = purple_account_get_connection(session->account);
if (strcmp(msg->remote_user, "Hotmail"))
/* This isn't an official message. */
@@ -2164,7 +2164,7 @@ email_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
char *from, *subject, *tmp;
session = cmdproc->session;
- gc = session->account->gc;
+ gc = purple_account_get_connection(session->account);
if (strcmp(msg->remote_user, "Hotmail"))
/* This isn't an official message. */
@@ -2249,7 +2249,7 @@ system_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
}
if (*buf != '\0')
- purple_notify_info(cmdproc->session->account->gc, NULL, buf, NULL);
+ purple_notify_info(purple_account_get_connection(cmdproc->session->account), NULL, buf, NULL);
}
g_hash_table_destroy(table);
diff --git a/libpurple/protocols/msn/object.c b/libpurple/protocols/msn/object.c
index bee264109a..b635902c85 100644
--- a/libpurple/protocols/msn/object.c
+++ b/libpurple/protocols/msn/object.c
@@ -103,7 +103,7 @@ msn_object_new_from_string(const char *str)
if (obj->creator == NULL || obj->size == 0 || obj->type == 0
|| obj->sha1d == NULL) {
purple_debug_error("msn", "Discarding invalid msnobj: '%s'\n", str);
- msn_object_destroy(obj);
+ msn_object_destroy(obj, FALSE);
return NULL;
}
@@ -111,12 +111,12 @@ msn_object_new_from_string(const char *str)
/* Location/friendly are required for non-buddyicon objects */
if (obj->type != MSN_OBJECT_USERTILE) {
purple_debug_error("msn", "Discarding invalid msnobj: '%s'\n", str);
- msn_object_destroy(obj);
+ msn_object_destroy(obj, FALSE);
return NULL;
/* Buddy icon object can contain Url/Url1 instead */
} else if (obj->url == NULL || obj->url1 == NULL) {
purple_debug_error("msn", "Discarding invalid msnobj: '%s'\n", str);
- msn_object_destroy(obj);
+ msn_object_destroy(obj, FALSE);
return NULL;
}
}
@@ -193,10 +193,13 @@ msn_object_new_from_image(PurpleStoredImage *img, const char *location,
}
void
-msn_object_destroy(MsnObject *obj)
+msn_object_destroy(MsnObject *obj, gboolean only_remote)
{
g_return_if_fail(obj != NULL);
+ if (only_remote && obj->local)
+ return;
+
g_free(obj->creator);
g_free(obj->location);
g_free(obj->friendly);
diff --git a/libpurple/protocols/msn/object.h b/libpurple/protocols/msn/object.h
index 81572dc799..cdd5bfbc16 100644
--- a/libpurple/protocols/msn/object.h
+++ b/libpurple/protocols/msn/object.h
@@ -86,9 +86,10 @@ MsnObject *msn_object_new_from_image(PurpleStoredImage *img,
/**
* Destroys an MsnObject structure.
*
- * @param obj The object structure.
+ * @param obj The object structure.
+ * @param only_remote Only destroy non-local objects.
*/
-void msn_object_destroy(MsnObject *obj);
+void msn_object_destroy(MsnObject *obj, gboolean only_remote);
/**
* Outputs a string representation of an MsnObject.
diff --git a/libpurple/protocols/msn/oim.c b/libpurple/protocols/msn/oim.c
index 8045592833..97a28985c1 100644
--- a/libpurple/protocols/msn/oim.c
+++ b/libpurple/protocols/msn/oim.c
@@ -828,7 +828,7 @@ msn_parse_oim_xml(MsnOim *oim, xmlnode *node)
/* XXX/khc: pretty sure this is wrong */
if (count > 0)
- purple_notify_emails(session->account->gc, count, FALSE, NULL,
+ purple_notify_emails(purple_account_get_connection(session->account), count, FALSE, NULL,
NULL, passports, urls, NULL, NULL);
g_free(unread);
}
diff --git a/libpurple/protocols/msn/sbconn.c b/libpurple/protocols/msn/sbconn.c
index a9a6288844..3acb5dd217 100644
--- a/libpurple/protocols/msn/sbconn.c
+++ b/libpurple/protocols/msn/sbconn.c
@@ -121,6 +121,8 @@ release_msg(MsnSwitchBoard *swboard, MsnMessage *msg)
}
#endif
}
+ } else {
+ msn_transaction_set_saveable(trans, FALSE);
}
trans->payload = payload;
diff --git a/libpurple/protocols/msn/servconn.c b/libpurple/protocols/msn/servconn.c
index 617216cee2..697134ed57 100644
--- a/libpurple/protocols/msn/servconn.c
+++ b/libpurple/protocols/msn/servconn.c
@@ -421,8 +421,10 @@ read_cb(gpointer data, gint source, PurpleInputCondition cond)
servconn = data;
- if (servconn->type == MSN_SERVCONN_NS)
- servconn->session->account->gc->last_received = time(NULL);
+ if (servconn->type == MSN_SERVCONN_NS) {
+ PurpleConnection *gc = purple_account_get_connection(servconn->session->account);
+ purple_connection_update_last_received(gc);
+ }
len = read(servconn->fd, buf, sizeof(buf) - 1);
if (len < 0 && errno == EAGAIN)
diff --git a/libpurple/protocols/msn/session.c b/libpurple/protocols/msn/session.c
index 1775c0acf1..bcd684f036 100644
--- a/libpurple/protocols/msn/session.c
+++ b/libpurple/protocols/msn/session.c
@@ -420,7 +420,7 @@ msn_session_set_error(MsnSession *session, MsnErrorType error,
msn_session_disconnect(session);
- purple_connection_error_reason(gc, reason, msg);
+ purple_connection_error(gc, reason, msg);
g_free(msg);
}
@@ -459,7 +459,7 @@ msn_session_set_login_step(MsnSession *session, MsnLoginStep step)
if (session->logged_in)
return;
- gc = session->account->gc;
+ gc = purple_account_get_connection(session->account);
session->login_step = step;
diff --git a/libpurple/protocols/msn/slp.c b/libpurple/protocols/msn/slp.c
index 85c78b260a..22a86da656 100644
--- a/libpurple/protocols/msn/slp.c
+++ b/libpurple/protocols/msn/slp.c
@@ -253,7 +253,7 @@ msn_request_user_display(MsnUser *user)
data->session = session;
data->remote_user = user->passport;
data->sha1 = info;
- url_data = purple_util_fetch_url_len(url, TRUE, NULL, TRUE, 200*1024,
+ url_data = purple_util_fetch_url(url, TRUE, NULL, TRUE, 200*1024,
fetched_user_display, data);
session->url_datas = g_slist_prepend(session->url_datas, url_data);
} else {
@@ -291,7 +291,7 @@ send_file_cb(MsnSlpCall *slpcall)
static gchar *
gen_context(PurpleXfer *xfer, const char *file_name, const char *file_path)
{
- gsize size = 0;
+ goffset size = 0;
MsnFileContext context;
gchar *u8 = NULL;
gchar *ret;
@@ -322,7 +322,7 @@ gen_context(PurpleXfer *xfer, const char *file_name, const char *file_path)
preview = purple_xfer_get_thumbnail(xfer, &preview_len);
- context.length = MSN_FILE_CONTEXT_SIZE;
+ context.length = MSN_FILE_CONTEXT_SIZE_V2;
context.version = 2; /* V.3 contains additional unnecessary data */
context.file_size = size;
if (preview)
@@ -336,15 +336,17 @@ gen_context(PurpleXfer *xfer, const char *file_name, const char *file_path)
}
memset(&context.file_name[currentChar], 0x00, (MAX_FILE_NAME_LEN - currentChar) * 2);
+#if 0
memset(&context.unknown1, 0, sizeof(context.unknown1));
context.unknown2 = 0xffffffff;
+#endif
/* Mind the cast, as in, don't free it after! */
context.preview = (char *)preview;
context.preview_len = preview_len;
u8 = msn_file_context_to_wire(&context);
- ret = purple_base64_encode((const guchar *)u8, MSN_FILE_CONTEXT_SIZE + preview_len);
+ ret = purple_base64_encode((const guchar *)u8, MSN_FILE_CONTEXT_SIZE_V2 + preview_len);
g_free(uni);
g_free(u8);
@@ -364,7 +366,7 @@ msn_request_ft(PurpleXfer *xfer)
fn = purple_xfer_get_filename(xfer);
fp = purple_xfer_get_local_filename(xfer);
- slplink = xfer->data;
+ slplink = purple_xfer_get_protocol_data(xfer);
g_return_if_fail(slplink != NULL);
g_return_if_fail(fp != NULL);
@@ -384,7 +386,7 @@ msn_request_ft(PurpleXfer *xfer)
purple_xfer_set_read_fnc(xfer, msn_xfer_read);
purple_xfer_set_write_fnc(xfer, msn_xfer_write);
- xfer->data = slpcall;
+ purple_xfer_set_protocol_data(xfer, slpcall);
context = gen_context(xfer, fn, fp);
diff --git a/libpurple/protocols/msn/slpcall.c b/libpurple/protocols/msn/slpcall.c
index 2f06124921..2a98e80384 100644
--- a/libpurple/protocols/msn/slpcall.c
+++ b/libpurple/protocols/msn/slpcall.c
@@ -113,7 +113,7 @@ msn_slpcall_destroy(MsnSlpCall *slpcall)
if (slpcall->xfer != NULL) {
if (purple_xfer_get_type(slpcall->xfer) == PURPLE_XFER_RECEIVE)
g_byte_array_free(slpcall->u.incoming_data, TRUE);
- slpcall->xfer->data = NULL;
+ purple_xfer_set_protocol_data(slpcall->xfer, NULL);
purple_xfer_unref(slpcall->xfer);
}
@@ -485,7 +485,7 @@ got_sessionreq(MsnSlpCall *slpcall, const char *branch,
if (img)
purple_imgstore_ref(img);
}
- msn_object_destroy(obj);
+ msn_object_destroy(obj, FALSE);
if (img != NULL) {
/* DATA PREP */
@@ -512,7 +512,6 @@ got_sessionreq(MsnSlpCall *slpcall, const char *branch,
MsnFileContext *file_context;
char *buf;
gsize bin_len;
- guint32 file_size;
char *file_name;
account = slpcall->slplink->session->account;
@@ -529,8 +528,6 @@ got_sessionreq(MsnSlpCall *slpcall, const char *branch,
file_context = msn_file_context_from_wire(buf, bin_len);
if (file_context != NULL) {
- file_size = file_context->file_size;
-
file_name = g_convert((const gchar *)&file_context->file_name,
MAX_FILE_NAME_LEN * 2,
"UTF-8", "UTF-16LE",
@@ -538,7 +535,7 @@ got_sessionreq(MsnSlpCall *slpcall, const char *branch,
purple_xfer_set_filename(xfer, file_name ? file_name : "");
g_free(file_name);
- purple_xfer_set_size(xfer, file_size);
+ purple_xfer_set_size(xfer, file_context->file_size);
purple_xfer_set_init_fnc(xfer, msn_xfer_init);
purple_xfer_set_request_denied_fnc(xfer, msn_xfer_cancel);
purple_xfer_set_cancel_recv_fnc(xfer, msn_xfer_cancel);
@@ -550,7 +547,7 @@ got_sessionreq(MsnSlpCall *slpcall, const char *branch,
slpcall->xfer = xfer;
purple_xfer_ref(slpcall->xfer);
- xfer->data = slpcall;
+ purple_xfer_set_protocol_data(xfer, slpcall);
if (file_context->preview) {
purple_xfer_set_thumbnail(xfer, file_context->preview,
@@ -731,7 +728,9 @@ got_invite(MsnSlpCall *slpcall,
dc->listen_data = purple_network_listen_range(
0, 0,
+ AF_UNSPEC,
SOCK_STREAM,
+ TRUE,
msn_dc_listen_socket_created_cb,
dc
);
@@ -832,7 +831,9 @@ got_ok(MsnSlpCall *slpcall,
dc->listen_data = purple_network_listen_range(
0, 0,
+ AF_UNSPEC,
SOCK_STREAM,
+ TRUE,
msn_dc_listen_socket_created_cb,
dc
);
@@ -1141,8 +1142,6 @@ msn_slp_process_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg)
if (slpcall->cb)
slpcall->cb(slpcall, body, body_len);
-
- slpcall->wasted = TRUE;
}
}
else if (msn_p2p_info_is_ack(slpmsg->p2p_info))
diff --git a/libpurple/protocols/msn/slplink.c b/libpurple/protocols/msn/slplink.c
index eea9ee27d8..582bfe158b 100644
--- a/libpurple/protocols/msn/slplink.c
+++ b/libpurple/protocols/msn/slplink.c
@@ -465,7 +465,7 @@ init_first_msg(MsnSlpLink *slplink, MsnP2PInfo *info)
purple_xfer_ref(xfer);
purple_xfer_start(xfer, -1, NULL, 0);
- if (xfer->data == NULL) {
+ if (purple_xfer_get_protocol_data(xfer) == NULL) {
purple_xfer_unref(xfer);
msn_slpmsg_destroy(slpmsg);
g_return_val_if_reached(NULL);
diff --git a/libpurple/protocols/msn/slpmsg.c b/libpurple/protocols/msn/slpmsg.c
index 4a75e3abc9..1246397384 100644
--- a/libpurple/protocols/msn/slpmsg.c
+++ b/libpurple/protocols/msn/slpmsg.c
@@ -239,7 +239,7 @@ MsnSlpMessage *msn_slpmsg_dataprep_new(MsnSlpCall *slpcall)
}
-MsnSlpMessage *msn_slpmsg_file_new(MsnSlpCall *slpcall, size_t size)
+MsnSlpMessage *msn_slpmsg_file_new(MsnSlpCall *slpcall, goffset size)
{
MsnSlpMessage *slpmsg;
diff --git a/libpurple/protocols/msn/slpmsg.h b/libpurple/protocols/msn/slpmsg.h
index 11e9901bc1..fb045e7c3a 100644
--- a/libpurple/protocols/msn/slpmsg.h
+++ b/libpurple/protocols/msn/slpmsg.h
@@ -133,7 +133,7 @@ MsnSlpMessage *msn_slpmsg_dataprep_new(MsnSlpCall *slpcall);
*
* @return A new SlpMessage with the file transfer info.
*/
-MsnSlpMessage *msn_slpmsg_file_new(MsnSlpCall *slpcall, size_t size);
+MsnSlpMessage *msn_slpmsg_file_new(MsnSlpCall *slpcall, goffset size);
/**
* Serialize the MsnSlpMessage in a way it can be used to be transmited
diff --git a/libpurple/protocols/msn/switchboard.c b/libpurple/protocols/msn/switchboard.c
index cc4ef75b5a..96cb269889 100644
--- a/libpurple/protocols/msn/switchboard.c
+++ b/libpurple/protocols/msn/switchboard.c
@@ -312,7 +312,7 @@ msn_switchboard_add_user(MsnSwitchBoard *swboard, const char *user)
swboard->chat_id = msn_switchboard_get_chat_id();
swboard->flag |= MSN_SB_FLAG_IM;
- swboard->conv = serv_got_joined_chat(account->gc,
+ swboard->conv = serv_got_joined_chat(purple_account_get_connection(account),
swboard->chat_id,
"MSN Chat");
@@ -747,7 +747,7 @@ out_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
PurpleConnection *gc;
MsnSwitchBoard *swboard;
- gc = cmdproc->session->account->gc;
+ gc = purple_account_get_connection(cmdproc->session->account);
swboard = cmdproc->data;
if (swboard->current_users > 1)
@@ -828,7 +828,8 @@ msn_switchboard_show_ink(MsnSwitchBoard *swboard, const char *passport,
}
imgid = purple_imgstore_add_with_id(image_data, image_len, NULL);
- image_msg = g_strdup_printf("<IMG ID='%d'>", imgid);
+ image_msg = g_strdup_printf("<IMG SRC='" PURPLE_STORED_IMAGE_PROTOCOL "%d'>",
+ imgid);
if (swboard->current_users > 1 ||
((swboard->conv != NULL) &&
diff --git a/libpurple/protocols/msn/user.c b/libpurple/protocols/msn/user.c
index a9565be27c..d8290e8a43 100644
--- a/libpurple/protocols/msn/user.c
+++ b/libpurple/protocols/msn/user.c
@@ -76,7 +76,7 @@ msn_user_destroy(MsnUser *user)
}
if (user->msnobj != NULL)
- msn_object_destroy(user->msnobj);
+ msn_object_destroy(user->msnobj, FALSE);
g_free(user->passport);
g_free(user->friendly_name);
@@ -406,7 +406,7 @@ msn_user_is_yahoo(PurpleAccount *account, const char *name)
gc = purple_account_get_connection(account);
if (gc != NULL)
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
if ((session != NULL) && (user = msn_userlist_find_user(session->userlist, name)) != NULL)
{
@@ -566,7 +566,7 @@ queue_buddy_icon_request(MsnUser *user)
return;
}
- if (!buddy_icon_cached(account->gc, obj)) {
+ if (!buddy_icon_cached(purple_account_get_connection(account), obj)) {
MsnUserList *userlist;
userlist = user->userlist;
@@ -588,8 +588,8 @@ msn_user_set_object(MsnUser *user, MsnObject *obj)
{
g_return_if_fail(user != NULL);
- if (user->msnobj != NULL && !msn_object_find_local(msn_object_get_sha1(obj)))
- msn_object_destroy(user->msnobj);
+ if (user->msnobj != NULL)
+ msn_object_destroy(user->msnobj, TRUE);
user->msnobj = obj;
diff --git a/libpurple/protocols/msn/userlist.c b/libpurple/protocols/msn/userlist.c
index 8ad73813ff..32ea5c818b 100644
--- a/libpurple/protocols/msn/userlist.c
+++ b/libpurple/protocols/msn/userlist.c
@@ -54,7 +54,7 @@ msn_accept_add_cb(gpointer data)
if (PURPLE_CONNECTION_IS_VALID(pa->gc))
{
- MsnSession *session = pa->gc->proto_data;
+ MsnSession *session = purple_connection_get_protocol_data(pa->gc);
MsnUserList *userlist = session->userlist;
PurpleAccount *account = purple_connection_get_account(pa->gc);
@@ -79,7 +79,7 @@ msn_cancel_add_cb(gpointer data)
if (PURPLE_CONNECTION_IS_VALID(pa->gc))
{
- MsnSession *session = pa->gc->proto_data;
+ MsnSession *session = purple_connection_get_protocol_data(pa->gc);
MsnUserList *userlist = session->userlist;
MsnCallbackState *state = msn_callback_state_new(session);
diff --git a/libpurple/protocols/msn/xfer.c b/libpurple/protocols/msn/xfer.c
index 4da276dacd..30f7789ea4 100644
--- a/libpurple/protocols/msn/xfer.c
+++ b/libpurple/protocols/msn/xfer.c
@@ -42,7 +42,7 @@ msn_xfer_init(PurpleXfer *xfer)
purple_debug_info("msn", "xfer_init\n");
- slpcall = xfer->data;
+ slpcall = purple_xfer_get_protocol_data(xfer);
/* Send Ok */
content = g_strdup_printf("SessionID: %lu\r\n\r\n",
@@ -62,9 +62,9 @@ msn_xfer_cancel(PurpleXfer *xfer)
char *content;
g_return_if_fail(xfer != NULL);
- g_return_if_fail(xfer->data != NULL);
- slpcall = xfer->data;
+ slpcall = purple_xfer_get_protocol_data(xfer);
+ g_return_if_fail(slpcall != NULL);
if (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL)
{
@@ -102,7 +102,7 @@ msn_xfer_write(const guchar *data, gsize len, PurpleXfer *xfer)
g_return_val_if_fail(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND, -1);
- slpcall = xfer->data;
+ slpcall = purple_xfer_get_protocol_data(xfer);
/* Not sure I trust it'll be there */
g_return_val_if_fail(slpcall != NULL, -1);
@@ -126,7 +126,7 @@ msn_xfer_read(guchar **data, PurpleXfer *xfer)
g_return_val_if_fail(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE, -1);
- slpcall = xfer->data;
+ slpcall = purple_xfer_get_protocol_data(xfer);
/* Not sure I trust it'll be there */
g_return_val_if_fail(slpcall != NULL, -1);
@@ -166,7 +166,7 @@ msn_file_context_to_wire(MsnFileContext *context)
{
gchar *ret, *tmp;
- tmp = ret = g_new(gchar, MSN_FILE_CONTEXT_SIZE + context->preview_len + 1);
+ tmp = ret = g_new(gchar, MSN_FILE_CONTEXT_SIZE_V2 + context->preview_len + 1);
msn_push32le(tmp, context->length);
msn_push32le(tmp, context->version);
@@ -174,9 +174,15 @@ msn_file_context_to_wire(MsnFileContext *context)
msn_push32le(tmp, context->type);
memcpy(tmp, context->file_name, MAX_FILE_NAME_LEN * 2);
tmp += MAX_FILE_NAME_LEN * 2;
+#if 0
memcpy(tmp, context->unknown1, sizeof(context->unknown1));
tmp += sizeof(context->unknown1);
msn_push32le(tmp, context->unknown2);
+#else
+ memset(tmp, 0, sizeof(gchar[30]));
+ tmp += sizeof(gchar[30]);
+ msn_push32le(tmp, 0xffffffff);
+#endif
if (context->preview) {
memcpy(tmp, context->preview, context->preview_len);
}
@@ -190,21 +196,30 @@ msn_file_context_from_wire(const char *buf, gsize len)
{
MsnFileContext *context;
- if (!buf || len < MSN_FILE_CONTEXT_SIZE)
+ if (!buf || len < MSN_FILE_CONTEXT_SIZE_V0)
return NULL;
context = g_new(MsnFileContext, 1);
context->length = msn_pop32le(buf);
context->version = msn_pop32le(buf);
- if (context->version == 2) {
+ if (context->version == 0) {
+ if (context->length != MSN_FILE_CONTEXT_SIZE_V0) {
+ g_free(context);
+ return NULL;
+ }
+ } else if (context->version == 2) {
/* The length field is broken for this version. No check. */
- context->length = MSN_FILE_CONTEXT_SIZE;
+ context->length = MSN_FILE_CONTEXT_SIZE_V2;
+ if (len < MSN_FILE_CONTEXT_SIZE_V2) {
+ g_free(context);
+ return NULL;
+ }
} else if (context->version == 3) {
- if (context->length != MSN_FILE_CONTEXT_SIZE + 63) {
+ if (context->length != MSN_FILE_CONTEXT_SIZE_V3) {
g_free(context);
return NULL;
- } else if (len < MSN_FILE_CONTEXT_SIZE + 63) {
+ } else if (len < MSN_FILE_CONTEXT_SIZE_V3) {
g_free(context);
return NULL;
}
@@ -218,9 +233,15 @@ msn_file_context_from_wire(const char *buf, gsize len)
context->type = msn_pop32le(buf);
memcpy(context->file_name, buf, MAX_FILE_NAME_LEN * 2);
buf += MAX_FILE_NAME_LEN * 2;
- memcpy(context->unknown1, buf, sizeof(context->unknown1));
- buf += sizeof(context->unknown1);
- context->unknown2 = msn_pop32le(buf);
+ if (context->version > 0) {
+#if 0
+ memcpy(context->unknown1, buf, sizeof(context->unknown1));
+ buf += sizeof(context->unknown1);
+ context->unknown2 = msn_pop32le(buf);
+#else
+ buf += sizeof(gchar[30]) + sizeof(guint32);
+#endif
+ }
if (context->type == 0 && len > context->length) {
context->preview_len = len - context->length;
diff --git a/libpurple/protocols/msn/xfer.h b/libpurple/protocols/msn/xfer.h
index 23e19f37c3..78f6a81b98 100644
--- a/libpurple/protocols/msn/xfer.h
+++ b/libpurple/protocols/msn/xfer.h
@@ -39,13 +39,17 @@ typedef struct
guint64 file_size; /*< Size of file */
guint32 type; /*< Transfer type */
gunichar2 file_name[MAX_FILE_NAME_LEN]; /*< Self-explanatory */
+#if 0
gchar unknown1[30]; /*< Used somehow for background sharing */
guint32 unknown2; /*< Possibly for background sharing as well */
+#endif
gchar *preview; /*< File preview data, 96x96 PNG */
gsize preview_len;
} MsnFileContext;
-#define MSN_FILE_CONTEXT_SIZE (4*4 + 1*8 + 2*MAX_FILE_NAME_LEN + 30)
+#define MSN_FILE_CONTEXT_SIZE_V0 (4*3 + 1*8 + 2*MAX_FILE_NAME_LEN)
+#define MSN_FILE_CONTEXT_SIZE_V2 (MSN_FILE_CONTEXT_SIZE_V0 + 4*1 + 30)
+#define MSN_FILE_CONTEXT_SIZE_V3 (MSN_FILE_CONTEXT_SIZE_V2 + 63)
void msn_xfer_init(PurpleXfer *xfer);
void msn_xfer_cancel(PurpleXfer *xfer);
diff --git a/libpurple/protocols/mxit/actions.c b/libpurple/protocols/mxit/actions.c
index 214c8a791d..35ad2ad747 100644
--- a/libpurple/protocols/mxit/actions.c
+++ b/libpurple/protocols/mxit/actions.c
@@ -43,7 +43,7 @@
*/
static void mxit_profile_cb( PurpleConnection* gc, PurpleRequestFields* fields )
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc ) ;
PurpleRequestField* field = NULL;
const char* name = NULL;
const char* bday = NULL;
@@ -84,13 +84,6 @@ out:
g_string_append( attributes, attrib );
acount++;
- /* force hidden if disabled */
- if ( profile->hidden == FALSE ) {
- g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_HIDENUMBER, CP_PROFILE_TYPE_BOOL, "1" );
- g_string_append( attributes, attrib );
- acount++;
- }
-
/* update birthday */
g_strlcpy( profile->birthday, bday, sizeof( profile->birthday ) );
g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_BIRTHDATE, CP_PROFILE_TYPE_UTF8, profile->birthday );
@@ -165,7 +158,7 @@ out:
/* update where am i */
name = purple_request_fields_get_string( fields, "whereami" );
- if ( !name)
+ if ( !name )
profile->whereami[0] = '\0';
else
g_strlcpy( profile->whereami, name, sizeof( profile->whereami ) );
@@ -207,7 +200,7 @@ out:
static void mxit_profile_action( PurplePluginAction* action )
{
PurpleConnection* gc = (PurpleConnection*) action->context;
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
struct MXitProfile* profile = session->profile;
PurpleRequestFields* fields = NULL;
@@ -304,7 +297,7 @@ static void mxit_profile_action( PurplePluginAction* action )
*/
static void mxit_change_pin_cb( PurpleConnection* gc, PurpleRequestFields* fields )
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
const char* pin = NULL;
const char* pin2 = NULL;
const char* err = NULL;
@@ -366,7 +359,7 @@ out:
static void mxit_change_pin_action( PurplePluginAction* action )
{
PurpleConnection* gc = (PurpleConnection*) action->context;
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
PurpleRequestFields* fields = NULL;
PurpleRequestFieldGroup* group = NULL;
@@ -375,16 +368,16 @@ static void mxit_change_pin_action( PurplePluginAction* action )
purple_debug_info( MXIT_PLUGIN_ID, "mxit_change_pin_action\n" );
fields = purple_request_fields_new();
- group = purple_request_field_group_new(NULL);
- purple_request_fields_add_group(fields, group);
+ group = purple_request_field_group_new( NULL );
+ purple_request_fields_add_group( fields, group );
/* pin */
- field = purple_request_field_string_new( "pin", _( "PIN" ), session->acc->password, FALSE );
+ field = purple_request_field_string_new( "pin", _( "PIN" ), purple_account_get_password( session->acc ), FALSE );
purple_request_field_string_set_masked( field, TRUE );
purple_request_field_group_add_field( group, field );
/* verify pin */
- field = purple_request_field_string_new( "pin2", _( "Verify PIN" ), session->acc->password, FALSE );
+ field = purple_request_field_string_new( "pin2", _( "Verify PIN" ), purple_account_get_password( session->acc ), FALSE );
purple_request_field_string_set_masked( field, TRUE );
purple_request_field_group_add_field( group, field );
@@ -402,7 +395,7 @@ static void mxit_change_pin_action( PurplePluginAction* action )
static void mxit_splash_action( PurplePluginAction* action )
{
PurpleConnection* gc = (PurpleConnection*) action->context;
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
if ( splash_current( session ) != NULL )
splash_display( session );
@@ -439,7 +432,7 @@ static void mxit_about_action( PurplePluginAction* action )
static void mxit_suggested_friends_action( PurplePluginAction* action )
{
PurpleConnection* gc = (PurpleConnection*) action->context;
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
const char* profilelist[] = {
CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_FULLNAME, CP_PROFILE_FIRSTNAME,
CP_PROFILE_LASTNAME, CP_PROFILE_REGCOUNTRY, CP_PROFILE_STATUS, CP_PROFILE_AVATAR,
@@ -456,7 +449,7 @@ static void mxit_suggested_friends_action( PurplePluginAction* action )
*/
static void mxit_user_search_cb( PurpleConnection *gc, const char *input )
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
const char* profilelist[] = {
CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_FULLNAME, CP_PROFILE_FIRSTNAME,
CP_PROFILE_LASTNAME, CP_PROFILE_REGCOUNTRY, CP_PROFILE_STATUS, CP_PROFILE_AVATAR,
@@ -479,10 +472,10 @@ static void mxit_user_search_action( PurplePluginAction* action )
_( "Search for a MXit contact" ),
_( "Type search information" ),
NULL, FALSE, FALSE, NULL,
- _("_Search"), G_CALLBACK( mxit_user_search_cb ),
- _("_Cancel"), NULL,
+ _( "_Search" ), G_CALLBACK( mxit_user_search_cb ),
+ _( "_Cancel" ), NULL,
purple_connection_get_account( gc ), NULL, NULL,
- gc);
+ gc );
}
diff --git a/libpurple/protocols/mxit/cipher.c b/libpurple/protocols/mxit/cipher.c
index 9ca5ff648c..f079cc2cc3 100644
--- a/libpurple/protocols/mxit/cipher.c
+++ b/libpurple/protocols/mxit/cipher.c
@@ -1,7 +1,7 @@
/*
* MXit Protocol libPurple Plugin
*
- * -- user password encryption --
+ * -- encryption --
*
* Pieter Loubser <libpurple@mxit.com>
*
@@ -31,30 +31,70 @@
#include "aes.h"
-/* password encryption */
+/* encryption */
#define INITIAL_KEY "6170383452343567"
#define SECRET_HEADER "<mxit/>"
+#define ENCRYPT_HEADER "<mxitencrypted ver=\"5.2\"/>"
/*------------------------------------------------------------------------
- * Pad the secret data using ISO10126 Padding.
+ * Add ISO10126 Padding to the data.
*
- * @param secret The data to pad (caller must ensure buffer has enough space for padding)
- * @return The total number of 128-bit blocks used
+ * @param data The data to pad.
*/
-static int pad_secret_data( char* secret )
+static void padding_add( GString* data )
{
- int blocks = 0;
- int passlen;
- int padding;
+ unsigned int blocks = ( data->len / 16 ) + 1;
+ unsigned int padding = ( blocks * 16 ) - data->len;
- passlen = strlen( secret );
- blocks = ( passlen / 16 ) + 1;
- padding = ( blocks * 16 ) - passlen;
- secret[passlen] = 0x50;
- secret[(blocks * 16) - 1] = padding;
+ g_string_set_size( data, blocks * 16 );
+ data->str[data->len - 1] = padding;
+}
+
+
+/*------------------------------------------------------------------------
+ * Remove ISO10126 Padding from the data.
+ *
+ * @param data The data from which to remove padding.
+ */
+static void padding_remove( GString* data )
+{
+ unsigned int padding;
+
+ if ( data->len == 0 )
+ return;
+
+ padding = data->str[data->len - 1];
+ g_string_truncate( data, data->len - padding );
+}
+
+
+/*------------------------------------------------------------------------
+ * Generate the Transport-Layer crypto key.
+ * (Note: this function is not-thread safe)
+ *
+ * @param session The MXit Session object
+ * @return The transport-layer crypto key.
+ */
+static char* transport_layer_key( struct MXitSession* session )
+{
+ static char key[16 + 1];
+ const char* password = purple_account_get_password( session->acc );
+ int passlen = strlen( password );
+
+ /* initialize with initial key */
+ g_strlcpy( key, INITIAL_KEY, sizeof( key ) );
+
+ /* client key (8 bytes) */
+ memcpy( key, session->clientkey, strlen( session->clientkey ) );
+
+ /* add last 8 characters of the PIN (no padding if less characters) */
+ if ( passlen <= 8 )
+ memcpy( key + 8, password, passlen );
+ else
+ memcpy( key + 8, password + ( passlen - 8 ), 8 );
- return blocks;
+ return key;
}
@@ -67,42 +107,131 @@ static int pad_secret_data( char* secret )
*/
char* mxit_encrypt_password( struct MXitSession* session )
{
- char key[64];
+ char key[16 + 1];
char exkey[512];
- char pass[64];
+ GString* pass = NULL;
char encrypted[64];
char* base64;
- int blocks;
- int size;
int i;
purple_debug_info( MXIT_PLUGIN_ID, "mxit_encrypt_password\n" );
memset( encrypted, 0x00, sizeof( encrypted ) );
- memset( exkey, 0x00, sizeof( exkey ) );
- memset( pass, 0x58, sizeof( pass ) );
- pass[sizeof( pass ) - 1] = '\0';
- /* build the custom AES encryption key */
+ /* build the AES encryption key */
g_strlcpy( key, INITIAL_KEY, sizeof( key ) );
memcpy( key, session->clientkey, strlen( session->clientkey ) );
ExpandKey( (unsigned char*) key, (unsigned char*) exkey );
- /* build the custom data to be encrypted */
- g_strlcpy( pass, SECRET_HEADER, sizeof( pass ) );
- strcat( pass, session->acc->password );
+ /* build the secret data to be encrypted: SECRET_HEADER + password */
+ pass = g_string_new( SECRET_HEADER );
+ g_string_append( pass, purple_account_get_password( session->acc) );
+ padding_add( pass ); /* add ISO10126 padding */
- /* pad the secret data */
- blocks = pad_secret_data( pass );
- size = blocks * 16;
-
- /* now encrypt the password. we encrypt each block separately (ECB mode) */
- for ( i = 0; i < size; i += 16 )
- Encrypt( (unsigned char*) pass + i, (unsigned char*) exkey, (unsigned char*) encrypted + i );
+ /* now encrypt the secret. we encrypt each block separately (ECB mode) */
+ for ( i = 0; i < pass->len; i += 16 )
+ Encrypt( (unsigned char*) pass->str + i, (unsigned char*) exkey, (unsigned char*) encrypted + i );
/* now base64 encode the encrypted password */
- base64 = purple_base64_encode( (unsigned char*) encrypted, size );
+ base64 = purple_base64_encode( (unsigned char*) encrypted, pass->len );
+
+ g_string_free( pass, TRUE );
return base64;
}
+
+/*------------------------------------------------------------------------
+ * Decrypt a message using transport-layer encryption.
+ *
+ * @param session The MXit session object
+ * @param message The encrypted message data (is base64-encoded).
+ * @return The decrypted message. Must be g_free'd when no longer needed.
+ */
+char* mxit_decrypt_message( struct MXitSession* session, char* message )
+{
+ guchar* raw_message;
+ gsize raw_len;
+ char exkey[512];
+ GString* decoded = NULL;
+ int i;
+
+ /* remove optional header: <mxitencrypted ver="5.2"/> */
+ if ( strncmp( message, ENCRYPT_HEADER, strlen( ENCRYPT_HEADER ) ) == 0 )
+ message += strlen( ENCRYPT_HEADER );
+
+ /* base64 decode the message */
+ raw_message = purple_base64_decode( message, &raw_len );
+
+ /* build the AES key */
+ ExpandKey( (unsigned char*) transport_layer_key( session ), (unsigned char*) exkey );
+
+ /* AES decrypt each block */
+ decoded = g_string_sized_new( raw_len );
+ for ( i = 0; i < raw_len; i += 16 ) {
+ char block[16];
+
+ Decrypt( (unsigned char*) raw_message + i, (unsigned char*) exkey, (unsigned char*) block );
+ g_string_append_len( decoded, block, 16 );
+ }
+ g_free( raw_message );
+
+ /* check that the decrypted message starts with header: <mxit/> */
+ if ( strncmp( decoded->str, SECRET_HEADER, strlen( SECRET_HEADER ) != 0 ) ) {
+ g_string_free( decoded, TRUE );
+ return NULL; /* message could not be decrypted */
+ }
+
+ /* remove ISO10126 padding */
+ padding_remove( decoded );
+
+ /* remove encryption header */
+ g_string_erase( decoded, 0, strlen( SECRET_HEADER ) );
+
+ return g_string_free( decoded, FALSE );
+}
+
+
+/*------------------------------------------------------------------------
+ * Encrypt a message using transport-layer encryption.
+ *
+ * @param session The MXit session object
+ * @param message The message data.
+ * @return The encrypted message. Must be g_free'd when no longer needed.
+ */
+char* mxit_encrypt_message( struct MXitSession* session, char* message )
+{
+ GString* raw_message = NULL;
+ char exkey[512];
+ GString* encoded = NULL;
+ gchar* base64;
+ int i;
+
+ purple_debug_info( MXIT_PLUGIN_ID, "encrypt message: '%s'\n", message );
+
+ /* append encryption header to message data */
+ raw_message = g_string_new( SECRET_HEADER );
+ g_string_append( raw_message, message );
+ padding_add( raw_message ); /* add ISO10126 padding */
+
+ /* build the AES key */
+ ExpandKey( (unsigned char*) transport_layer_key( session ), (unsigned char*) exkey );
+
+ /* AES encrypt each block */
+ encoded = g_string_sized_new( raw_message->len );
+ for ( i = 0; i < raw_message->len; i += 16 ) {
+ char block[16];
+
+ Encrypt( (unsigned char*) raw_message->str + i, (unsigned char*) exkey, (unsigned char*) block );
+ g_string_append_len( encoded, block, 16 );
+ }
+ g_string_free( raw_message, TRUE );
+
+ /* base64 encode the encrypted message */
+ base64 = purple_base64_encode( (unsigned char *) encoded->str, encoded->len );
+ g_string_free( encoded, TRUE );
+
+ purple_debug_info( MXIT_PLUGIN_ID, "encrypted message: '%s'\n", base64 );
+
+ return base64;
+}
diff --git a/libpurple/protocols/mxit/cipher.h b/libpurple/protocols/mxit/cipher.h
index 188a0609b1..1c1c4c0070 100644
--- a/libpurple/protocols/mxit/cipher.h
+++ b/libpurple/protocols/mxit/cipher.h
@@ -1,7 +1,7 @@
/*
* MXit Protocol libPurple Plugin
*
- * -- user password encryption --
+ * -- encryption --
*
* Pieter Loubser <libpurple@mxit.com>
*
@@ -32,5 +32,7 @@ struct MXitSession;
char* mxit_encrypt_password( struct MXitSession* session );
+char* mxit_decrypt_message( struct MXitSession* session, char* message );
+char* mxit_encrypt_message( struct MXitSession* session, char* message );
#endif /* _MXIT_CIPHER_H_ */
diff --git a/libpurple/protocols/mxit/filexfer.c b/libpurple/protocols/mxit/filexfer.c
index bc053fa752..ec948e1c91 100644
--- a/libpurple/protocols/mxit/filexfer.c
+++ b/libpurple/protocols/mxit/filexfer.c
@@ -97,11 +97,11 @@ const char* file_mime_type( const char* filename, const char* buf, int buflen )
*/
static void mxit_xfer_free( PurpleXfer* xfer )
{
- struct mxitxfer* mx = (struct mxitxfer*) xfer->data;;
+ struct mxitxfer* mx = purple_xfer_get_protocol_data( xfer );
if ( mx ) {
+ purple_xfer_set_protocol_data( xfer, NULL );
g_free( mx );
- xfer->data = NULL;
}
}
@@ -117,16 +117,16 @@ static void mxit_xfer_free( PurpleXfer* xfer )
*/
static void mxit_xfer_init( PurpleXfer* xfer )
{
- struct mxitxfer* mx = (struct mxitxfer*) xfer->data;
+ struct mxitxfer* mx = purple_xfer_get_protocol_data( xfer );
purple_debug_info( MXIT_PLUGIN_ID, "mxit_xfer_init\n" );
if ( purple_xfer_get_type( xfer ) == PURPLE_XFER_SEND ) {
/* we are trying to send a file to MXit */
- if ( purple_xfer_get_size( xfer ) > CP_MAX_FILESIZE ) {
+ if ( purple_xfer_get_size( xfer ) > ( CP_MAX_PACKET - 1000 ) ) { /* need to reserve some space for packet headers */
/* the file is too big */
- purple_xfer_error( xfer->type, xfer->account, xfer->who, _( "The file you are trying to send is too large!" ) );
+ purple_xfer_error( purple_xfer_get_type( xfer ), purple_xfer_get_account( xfer ), purple_xfer_get_remote_user( xfer ), _( "The file you are trying to send is too large!" ) );
purple_xfer_cancel_local( xfer );
return;
}
@@ -139,7 +139,7 @@ static void mxit_xfer_init( PurpleXfer* xfer )
* we have just accepted a file transfer request from MXit. send a confirmation
* to the MXit server so that can send us the file
*/
- mxit_send_file_accept( mx->session, mx->fileid, purple_xfer_get_size( xfer ), 0 );
+ mxit_send_file_accept( mx->session, mx->fileid, (int) purple_xfer_get_size( xfer ), 0 );
}
}
@@ -151,6 +151,7 @@ static void mxit_xfer_init( PurpleXfer* xfer )
*/
static void mxit_xfer_start( PurpleXfer* xfer )
{
+ goffset filesize;
unsigned char* buffer;
int size;
int wrote;
@@ -163,10 +164,12 @@ static void mxit_xfer_start( PurpleXfer* xfer )
* a buffer and copy the file data into memory and then we can send it to
* the contact. we will send the whole file with one go.
*/
- buffer = g_malloc( xfer->bytes_remaining );
- size = fread( buffer, xfer->bytes_remaining, 1, xfer->dest_fp );
+ filesize = purple_xfer_get_bytes_remaining( xfer );
+ buffer = g_malloc( filesize );
+ size = fread( buffer, filesize, 1, xfer->dest_fp );
+ // TODO: If (size != 1) -> file read error
- wrote = purple_xfer_write( xfer, buffer, xfer->bytes_remaining );
+ wrote = purple_xfer_write( xfer, buffer, filesize );
if ( wrote > 0 )
purple_xfer_set_bytes_sent( xfer, wrote );
@@ -215,7 +218,7 @@ static void mxit_xfer_cancel_send( PurpleXfer* xfer )
*/
static gssize mxit_xfer_write( const guchar* buffer, size_t size, PurpleXfer* xfer )
{
- struct mxitxfer* mx = (struct mxitxfer*) xfer->data;
+ struct mxitxfer* mx = purple_xfer_get_protocol_data( xfer );
purple_debug_info( MXIT_PLUGIN_ID, "mxit_xfer_write\n" );
@@ -245,7 +248,7 @@ static gssize mxit_xfer_write( const guchar* buffer, size_t size, PurpleXfer* xf
*/
static void mxit_xfer_request_denied( PurpleXfer* xfer )
{
- struct mxitxfer* mx = (struct mxitxfer*) xfer->data;
+ struct mxitxfer* mx = purple_xfer_get_protocol_data( xfer );
purple_debug_info( MXIT_PLUGIN_ID, "mxit_xfer_request_denied\n" );
@@ -295,7 +298,7 @@ gboolean mxit_xfer_enabled( PurpleConnection* gc, const char* who )
*/
PurpleXfer* mxit_xfer_new( PurpleConnection* gc, const char* who )
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
PurpleXfer* xfer = NULL;
struct mxitxfer* mx = NULL;
@@ -305,7 +308,7 @@ PurpleXfer* mxit_xfer_new( PurpleConnection* gc, const char* who )
/* create file info and attach it to the file transfer */
mx = g_new0( struct mxitxfer, 1 );
mx->session = session;
- xfer->data = mx;
+ purple_xfer_set_protocol_data( xfer, mx );
/* configure callbacks (reference: "libpurple/ft.h") */
purple_xfer_set_init_fnc( xfer, mxit_xfer_init );
@@ -362,7 +365,7 @@ void mxit_xfer_rx_offer( struct MXitSession* session, const char* username, cons
mx = g_new0( struct mxitxfer, 1 );
mx->session = session;
memcpy( mx->fileid, fileid, MXIT_CHUNK_FILEID_LEN );
- xfer->data = mx;
+ purple_xfer_set_protocol_data( xfer, mx );
purple_xfer_set_filename( xfer, filename );
if( filesize > 0 )
@@ -395,9 +398,9 @@ static PurpleXfer* find_mxit_xfer( struct MXitSession* session, const char* file
while ( item ) {
xfer = item->data;
- if ( xfer->account == session->acc ) {
+ if ( purple_xfer_get_account( xfer ) == session->acc ) {
/* transfer is associated with this MXit account */
- struct mxitxfer* mx = xfer->data;
+ struct mxitxfer* mx = purple_xfer_get_protocol_data( xfer );
/* does the fileid match? */
if ( ( mx ) && ( memcmp( mx->fileid, fileid, MXIT_CHUNK_FILEID_LEN ) == 0 ) )
@@ -424,19 +427,17 @@ static PurpleXfer* find_mxit_xfer( struct MXitSession* session, const char* file
void mxit_xfer_rx_file( struct MXitSession* session, const char* fileid, const char* data, int datalen )
{
PurpleXfer* xfer = NULL;
- struct mxitxfer* mx = NULL;
purple_debug_info( MXIT_PLUGIN_ID, "mxit_xfer_rx_file: (size=%i)\n", datalen );
/* find the file-transfer object */
xfer = find_mxit_xfer( session, fileid );
if ( xfer ) {
- mx = xfer->data;
-
/* this is the transfer we have been looking for */
purple_xfer_ref( xfer );
purple_xfer_start( xfer, -1, NULL, 0 );
fwrite( data, datalen, 1, xfer->dest_fp );
+ // TODO: Handle error from fwrite()
purple_xfer_unref( xfer );
purple_xfer_set_completed( xfer, TRUE );
purple_xfer_end( xfer );
diff --git a/libpurple/protocols/mxit/formcmds.c b/libpurple/protocols/mxit/formcmds.c
index 7011268e25..d387313988 100644
--- a/libpurple/protocols/mxit/formcmds.c
+++ b/libpurple/protocols/mxit/formcmds.c
@@ -86,7 +86,6 @@ struct ii_url_request
static void mxit_cb_ii_returned(PurpleUtilFetchUrlData* url_data, gpointer user_data, const gchar* url_text, gsize len, const gchar* error_message)
{
struct ii_url_request* iireq = (struct ii_url_request*) user_data;
- char* ii_data;
int* intptr = NULL;
int id;
@@ -106,12 +105,8 @@ static void mxit_cb_ii_returned(PurpleUtilFetchUrlData* url_data, gpointer user_
goto done;
}
- /* make a copy of the data */
- ii_data = g_malloc(len);
- memcpy(ii_data, (const char*) url_text, len);
-
- /* we now have the inline image, store it in the imagestore */
- id = purple_imgstore_add_with_id(ii_data, len, NULL);
+ /* we now have the inline image, store a copy in the imagestore */
+ id = purple_imgstore_add_with_id(g_memdup(url_text, len), len, NULL);
/* map the inline image id to purple image id */
intptr = g_malloc(sizeof(int));
@@ -253,8 +248,8 @@ static void command_clear(struct MXitSession* session, const char* from, GHashTa
/*------------------------------------------------------------------------
* Process a Reply MXit command.
- * [::op=cmd|type=reply|replymsg=back|selmsg=b) Back|id=12345:]
- * [::op=cmd|nm=rep|type=reply|replymsg=back|selmsg=b) Back|id=12345:]
+ * [::op=cmd|type=reply|replymsg=back|selmsg=b) Back|displaymsg=Processing|id=12345:]
+ * [::op=cmd|nm=rep|type=reply|replymsg=back|selmsg=b) Back|displaymsg=Processing|id=12345:]
*
* @param mx The received message data object
* @param hash The MXit command <key,value> map
@@ -265,22 +260,26 @@ static void command_reply(struct RXMsgData* mx, GHashTable* hash)
char* selmsg;
char* nm;
- selmsg = g_hash_table_lookup(hash, "selmsg"); /* find the selection message */
- replymsg = g_hash_table_lookup(hash, "replymsg"); /* find the reply message */
+ selmsg = g_hash_table_lookup(hash, "selmsg"); /* selection message */
+ replymsg = g_hash_table_lookup(hash, "replymsg"); /* reply message */
nm = g_hash_table_lookup(hash, "nm"); /* name parameter */
- if ((selmsg) && (replymsg) && (nm)) {
+
+ if ((selmsg == NULL) || (replymsg == NULL))
+ return; /* these parameters are required */
+
+ if (nm) { /* indicates response must be a structured response */
gchar* seltext = g_markup_escape_text(purple_url_decode(selmsg), -1);
- gchar* replycmd = g_strdup_printf("::type=reply|nm=%s|res=%s|err=0:", nm, replymsg);
+ gchar* replycmd = g_strdup_printf("type=reply|nm=%s|res=%s|err=0", nm, replymsg);
- mxit_add_html_link( mx, replycmd, seltext );
+ mxit_add_html_link( mx, replycmd, TRUE, seltext );
g_free(seltext);
g_free(replycmd);
}
- else if ((selmsg) && (replymsg)) {
+ else {
gchar* seltext = g_markup_escape_text(purple_url_decode(selmsg), -1);
- mxit_add_html_link( mx, purple_url_decode(replymsg), seltext );
+ mxit_add_html_link( mx, purple_url_decode(replymsg), FALSE, seltext );
g_free(seltext);
}
@@ -317,6 +316,7 @@ static void command_platformreq(GHashTable* hash, GString* msg)
/*------------------------------------------------------------------------
* Process an inline image MXit command.
+ * [::op=img|dat=ASDF23408asdflkj2309flkjsadf%3d%3d|algn=1|w=120|h=12|t=100|replymsg=text:]
*
* @param mx The received message data object
* @param hash The MXit command <key,value> map
@@ -327,7 +327,6 @@ static void command_image(struct RXMsgData* mx, GHashTable* hash, GString* msg)
const char* img;
const char* reply;
guchar* rawimg;
- char link[256];
gsize rawimglen;
int imgid;
@@ -336,8 +335,9 @@ static void command_image(struct RXMsgData* mx, GHashTable* hash, GString* msg)
rawimg = purple_base64_decode(img, &rawimglen);
//purple_util_write_data_to_file_absolute("/tmp/mxitinline.png", (char*) rawimg, rawimglen);
imgid = purple_imgstore_add_with_id(rawimg, rawimglen, NULL);
- g_snprintf(link, sizeof(link), "<img id=\"%i\">", imgid);
- g_string_append_printf(msg, "%s", link);
+ g_string_append_printf(msg,
+ "<img src=\"" PURPLE_STORED_IMAGE_PROTOCOL "%i\">",
+ imgid);
mx->flags |= PURPLE_MESSAGE_IMAGES;
}
else {
@@ -362,7 +362,7 @@ static void command_image(struct RXMsgData* mx, GHashTable* hash, GString* msg)
purple_debug_info(MXIT_PLUGIN_ID, "sending request for inline image '%s'\n", iireq->url);
/* request the image (reference: "libpurple/util.h") */
- purple_util_fetch_url_request(iireq->url, TRUE, NULL, TRUE, NULL, FALSE, mxit_cb_ii_returned, iireq);
+ purple_util_fetch_url(iireq->url, TRUE, NULL, TRUE, -1, mxit_cb_ii_returned, iireq);
mx->img_count++;
}
}
@@ -372,7 +372,7 @@ static void command_image(struct RXMsgData* mx, GHashTable* hash, GString* msg)
reply = g_hash_table_lookup(hash, "replymsg");
if (reply) {
g_string_append_printf(msg, "\n");
- mxit_add_html_link(mx, reply, _( "click here" ));
+ mxit_add_html_link(mx, reply, FALSE, _( "click here" ));
}
}
diff --git a/libpurple/protocols/mxit/http.c b/libpurple/protocols/mxit/http.c
index fcfcf54071..447248d9e6 100644
--- a/libpurple/protocols/mxit/http.c
+++ b/libpurple/protocols/mxit/http.c
@@ -273,7 +273,7 @@ static void mxit_cb_http_connect( gpointer user_data, gint source, const gchar*
/* source is the file descriptor of the new connection */
if ( source < 0 ) {
purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_http_connect failed: %s\n", error_message );
- purple_connection_error( req->session->con, _( "Unable to connect to the MXit HTTP server. Please check your server settings." ) );
+ purple_connection_error( req->session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Unable to connect to the MXit HTTP server. Please check your server settings." ) );
return;
}
diff --git a/libpurple/protocols/mxit/login.c b/libpurple/protocols/mxit/login.c
index 4a6318852b..66bf26db88 100644
--- a/libpurple/protocols/mxit/login.c
+++ b/libpurple/protocols/mxit/login.c
@@ -49,30 +49,33 @@ static void get_clientinfo( struct MXitSession* session );
*/
static struct MXitSession* mxit_create_object( PurpleAccount* account )
{
+ PurpleConnection* con = purple_account_get_connection( account );
struct MXitSession* session = NULL;
- PurpleConnection* con = NULL;
/* currently the wapsite does not handle a '+' in front of the username (mxitid) so we just strip it */
- if ( account->username[0] == '+' ) {
- char* fixed;
+ {
+ const char* username = purple_account_get_username( account );
- /* cut off the '+' */
- fixed = g_strdup( &account->username[1] );
- purple_account_set_username( account, fixed );
- g_free( fixed );
+ if ( username[0] == '+' ) {
+ char* fixed = g_strdup( &username[1] );
+ purple_account_set_username( account, fixed );
+ g_free( fixed );
+ }
}
session = g_new0( struct MXitSession, 1 );
-
- /* configure the connection (reference: "libpurple/connection.h") */
- con = purple_account_get_connection( account );
- con->proto_data = session;
- con->flags |= PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC | PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_SUPPORT_MOODS;
session->con = con;
-
- /* add account */
session->acc = account;
+ /* configure the connection (reference: "libpurple/connection.h") */
+ purple_connection_set_protocol_data( con, session );
+ purple_connection_set_flags( con,
+ PURPLE_CONNECTION_NO_BGCOLOR
+ | PURPLE_CONNECTION_NO_URLDESC
+ | PURPLE_CONNECTION_HTML
+ | PURPLE_CONNECTION_SUPPORT_MOODS
+ );
+
/* configure the session (reference: "libpurple/account.h") */
g_strlcpy( session->server, purple_account_get_string( account, MXIT_CONFIG_SERVER_ADDR, DEFAULT_SERVER ), sizeof( session->server ) );
g_strlcpy( session->http_server, purple_account_get_string( account, MXIT_CONFIG_HTTPSERVER, DEFAULT_HTTP_SERVER ), sizeof( session->http_server ) );
@@ -165,7 +168,7 @@ static void mxit_cb_connect( gpointer user_data, gint source, const gchar* error
/* source is the file descriptor of the new connection */
if ( source < 0 ) {
purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_connect failed: %s\n", error_message );
- purple_connection_error( session->con, _( "Unable to connect to the MXit server. Please check your server settings." ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Unable to connect to the MXit server. Please check your server settings." ) );
return;
}
@@ -173,7 +176,7 @@ static void mxit_cb_connect( gpointer user_data, gint source, const gchar* error
session->fd = source;
/* start listening on the open connection for messages from the server (reference: "libpurple/eventloop.h") */
- session->con->inpa = purple_input_add( session->fd, PURPLE_INPUT_READ, mxit_cb_rx, session );
+ session->inpa = purple_input_add( session->fd, PURPLE_INPUT_READ, mxit_cb_rx, session );
mxit_connected( session );
}
@@ -202,7 +205,7 @@ static void mxit_login_connect( struct MXitSession* session )
/* socket connection */
data = purple_proxy_connect( session->con, session->acc, session->server, session->port, mxit_cb_connect, session );
if ( !data ) {
- purple_connection_error( session->con, _( "Unable to connect to the MXit server. Please check your server settings." ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Unable to connect to the MXit server. Please check your server settings." ) );
return;
}
}
@@ -221,7 +224,7 @@ static void mxit_login_connect( struct MXitSession* session )
*/
static void mxit_cb_register_ok( PurpleConnection *gc, PurpleRequestFields *fields )
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
struct MXitProfile* profile = session->profile;
const char* str;
const char* pin;
@@ -303,7 +306,7 @@ static void mxit_cb_register_cancel( PurpleConnection *gc, PurpleRequestFields *
purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_register_cancel\n" );
/* disconnect */
- purple_account_disconnect( gc->account );
+ purple_account_disconnect( purple_connection_get_account( gc ) );
}
@@ -391,7 +394,7 @@ static void mxit_cb_clientinfo2( PurpleUtilFetchUrlData* url_data, gpointer user
if ( !url_text ) {
/* no reply from the WAP site */
- purple_connection_error( session->con, _( "Error contacting the MXit WAP site. Please try again later." ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Error contacting the MXit WAP site. Please try again later." ) );
return;
}
@@ -400,7 +403,7 @@ static void mxit_cb_clientinfo2( PurpleUtilFetchUrlData* url_data, gpointer user
if ( !parts ) {
/* wapserver error */
- purple_connection_error( session->con, _( "MXit is currently unable to process the request. Please try again later." ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "MXit is currently unable to process the request. Please try again later." ) );
return;
}
@@ -410,26 +413,26 @@ static void mxit_cb_clientinfo2( PurpleUtilFetchUrlData* url_data, gpointer user
/* valid reply! */
break;
case '1' :
- purple_connection_error( session->con, _( "Wrong security code entered. Please try again later." ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Wrong security code entered. Please try again later." ) );
return;
case '2' :
- purple_connection_error( session->con, _( "Your session has expired. Please try again later." ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Your session has expired. Please try again later." ) );
return;
case '5' :
- purple_connection_error( session->con, _( "Invalid country selected. Please try again." ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Invalid country selected. Please try again." ) );
return;
case '6' :
- purple_connection_error( session->con, _( "The MXit ID you entered is not registered. Please register first." ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "The MXit ID you entered is not registered. Please register first." ) );
return;
case '7' :
- purple_connection_error( session->con, _( "The MXit ID you entered is already registered. Please choose another." ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "The MXit ID you entered is already registered. Please choose another." ) );
/* this user's account already exists, so we need to change the registration login flag to be login */
purple_account_set_int( session->acc, MXIT_CONFIG_STATE, MXIT_STATE_LOGIN );
return;
case '3' :
case '4' :
default :
- purple_connection_error( session->con, _( "Internal error. Please try again later." ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Internal error. Please try again later." ) );
return;
}
@@ -507,7 +510,7 @@ static void free_logindata( struct login_data* data )
*/
static void mxit_cb_captcha_ok( PurpleConnection* gc, PurpleRequestFields* fields )
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
PurpleUtilFetchUrlData* url_data;
PurpleRequestField* field;
const char* captcha_resp;
@@ -548,10 +551,24 @@ static void mxit_cb_captcha_ok( PurpleConnection* gc, PurpleRequestFields* field
state = purple_account_get_int( session->acc, MXIT_CONFIG_STATE, MXIT_STATE_LOGIN );
url = g_strdup_printf( "%s?type=getpid&sessionid=%s&login=%s&ver=%i.%i.%i&clientid=%s&cat=%s&chalresp=%s&cc=%s&loc=%s&path=%i&brand=%s&model=%s&h=%i&w=%i&ts=%li",
- session->logindata->wapserver, session->logindata->sessionid, purple_url_encode( session->acc->username ), PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION, PURPLE_MICRO_VERSION, MXIT_CLIENT_ID, MXIT_CP_ARCH,
- captcha_resp, session->logindata->cc, session->logindata->locale, ( state == MXIT_STATE_REGISTER1 ) ? 0 : 1, MXIT_CP_PLATFORM, MXIT_CP_OS,
- MXIT_CAPTCHA_HEIGHT, MXIT_CAPTCHA_WIDTH, time( NULL ) );
- url_data = purple_util_fetch_url_request( url, TRUE, MXIT_HTTP_USERAGENT, TRUE, NULL, FALSE, mxit_cb_clientinfo2, session );
+ session->logindata->wapserver,
+ session->logindata->sessionid,
+ purple_url_encode( purple_account_get_username( session->acc ) ),
+ PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION, PURPLE_MICRO_VERSION,
+ MXIT_CLIENT_ID,
+ MXIT_CP_ARCH,
+ captcha_resp,
+ session->logindata->cc,
+ session->logindata->locale,
+ ( state == MXIT_STATE_REGISTER1 ) ? 0 : 1,
+ MXIT_CP_PLATFORM,
+ MXIT_CP_OS,
+ MXIT_CAPTCHA_HEIGHT,
+ MXIT_CAPTCHA_WIDTH,
+ time( NULL )
+ );
+ /* FIXME: This should be cancelled somewhere if not needed. */
+ url_data = purple_util_fetch_url_request( session->acc, url, TRUE, MXIT_HTTP_USERAGENT, TRUE, NULL, FALSE, -1, mxit_cb_clientinfo2, session );
#ifdef DEBUG_PROTOCOL
purple_debug_info( MXIT_PLUGIN_ID, "HTTP REQUEST: '%s'\n", url );
@@ -571,7 +588,7 @@ static void mxit_cb_captcha_ok( PurpleConnection* gc, PurpleRequestFields* field
*/
static void mxit_cb_captcha_cancel( PurpleConnection* gc, PurpleRequestFields* fields )
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
/* free up the login resources */
free_logindata( session->logindata );
@@ -611,7 +628,7 @@ static void mxit_cb_clientinfo1( PurpleUtilFetchUrlData* url_data, gpointer user
if ( !url_text ) {
/* no reply from the WAP site */
- purple_connection_error( session->con, _( "Error contacting the MXit WAP site. Please try again later." ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Error contacting the MXit WAP site. Please try again later." ) );
return;
}
@@ -620,7 +637,7 @@ static void mxit_cb_clientinfo1( PurpleUtilFetchUrlData* url_data, gpointer user
if ( ( !parts ) || ( parts[0][0] != '0' ) ) {
/* server could not find the user */
- purple_connection_error( session->con, _( "MXit is currently unable to process the request. Please try again later." ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "MXit is currently unable to process the request. Please try again later." ) );
return;
}
@@ -658,7 +675,7 @@ static void mxit_cb_clientinfo1( PurpleUtilFetchUrlData* url_data, gpointer user
/* oops, this is not good, time to bail */
break;
}
- purple_request_field_list_add( field, country[1], g_strdup( country[0] ) );
+ purple_request_field_list_add_icon( field, country[1], NULL, g_strdup( country[0] ) );
if ( strcmp( country[1], parts[6] ) == 0 ) {
/* based on the user's IP, this is his current country code, so we default to it */
purple_request_field_list_add_selected( field, country[1] );
@@ -679,7 +696,7 @@ static void mxit_cb_clientinfo1( PurpleUtilFetchUrlData* url_data, gpointer user
/* oops, this is not good, time to bail */
break;
}
- purple_request_field_list_add( field, locale[1], g_strdup( locale[0] ) );
+ purple_request_field_list_add_icon( field, locale[1], NULL, g_strdup( locale[0] ) );
g_strfreev( locale );
}
purple_request_field_list_add_selected( field, "English" );
@@ -715,7 +732,8 @@ static void get_clientinfo( struct MXitSession* session )
/* reference: "libpurple/util.h" */
url = g_strdup_printf( "%s/res/?type=challenge&getcountries=true&getlanguage=true&getimage=true&h=%i&w=%i&ts=%li", wapserver, MXIT_CAPTCHA_HEIGHT, MXIT_CAPTCHA_WIDTH, time( NULL ) );
- url_data = purple_util_fetch_url_request( url, TRUE, MXIT_HTTP_USERAGENT, TRUE, NULL, FALSE, mxit_cb_clientinfo1, session );
+ /* FIXME: This should be cancelled somewhere if not needed. */
+ url_data = purple_util_fetch_url_request( session->acc, url, TRUE, MXIT_HTTP_USERAGENT, TRUE, NULL, FALSE, -1, mxit_cb_clientinfo1, session );
#ifdef DEBUG_PROTOCOL
purple_debug_info( MXIT_PLUGIN_ID, "HTTP REQUEST: '%s'\n", url );
@@ -743,7 +761,7 @@ void mxit_login( PurpleAccount* account )
* if we don't have any info saved from a previous login, we need to get it from the MXit WAP site.
* we do cache it, so this step is only done on the very first login for each account.
*/
- if ( ( session->distcode == NULL ) || ( strlen( session->distcode ) == 0 ) ) {
+ if ( ( session->distcode == NULL ) || ( !*session->distcode ) ) {
/* this must be the very first login, so we need to retrieve the user information */
get_clientinfo( session );
}
@@ -764,9 +782,9 @@ void mxit_reconnect( struct MXitSession* session )
purple_debug_info( MXIT_PLUGIN_ID, "mxit_reconnect\n" );
/* remove the input cb function */
- if ( session->con->inpa ) {
- purple_input_remove( session->con->inpa );
- session->con->inpa = 0;
+ if ( session->inpa ) {
+ purple_input_remove( session->inpa );
+ session->inpa = 0;
}
/* close existing connection */
diff --git a/libpurple/protocols/mxit/markup.c b/libpurple/protocols/mxit/markup.c
index 2a417ae71f..9a5fab851b 100644
--- a/libpurple/protocols/mxit/markup.c
+++ b/libpurple/protocols/mxit/markup.c
@@ -124,10 +124,11 @@ static void hex_dump( const char* buf, int len )
* Adds a link to a message
*
* @param mx The Markup message object
- * @param linkname This is the what will be returned when the link gets clicked
- * @param displayname This is the name for the link which will be displayed in the UI
+ * @param replydata This is the what will be returned when the link gets clicked
+ * @param isStructured Indicates that the reply is a structured reply
+ * @param displaytext This is the text for the link which will be displayed in the UI
*/
-void mxit_add_html_link( struct RXMsgData* mx, const char* linkname, const char* displayname )
+void mxit_add_html_link( struct RXMsgData* mx, const char* replydata, gboolean isStructured, const char* displaytext )
{
#ifdef MXIT_LINK_CLICK
char retstr[256];
@@ -135,15 +136,24 @@ void mxit_add_html_link( struct RXMsgData* mx, const char* linkname, const char*
char link[256];
int len;
- len = g_snprintf( retstr, sizeof( retstr ), "%s|%s|%s|%s|%s", MXIT_LINK_KEY, purple_account_get_username( mx->session->acc ),
- purple_account_get_protocol_id( mx->session->acc ), mx->from, linkname );
+ /*
+ * The link content is encoded as follows:
+ * MXIT_LINK_KEY | ACCOUNT_USER | ACCOUNT_PROTO | REPLY_TO | REPLY_FORMAT | REPLY_DATA
+ */
+ len = g_snprintf( retstr, sizeof( retstr ), "%s|%s|%s|%s|%i|%s",
+ MXIT_LINK_KEY,
+ purple_account_get_username( mx->session->acc ),
+ purple_account_get_protocol_id( mx->session->acc ),
+ mx->from,
+ isStructured ? 1 : 0,
+ replydata );
retstr64 = purple_base64_encode( (const unsigned char*) retstr, len );
g_snprintf( link, sizeof( link ), "%s%s", MXIT_LINK_PREFIX, retstr64 );
g_free( retstr64 );
- g_string_append_printf( mx->msg, "<a href=\"%s\">%s</a>", link, displayname );
+ g_string_append_printf( mx->msg, "<a href=\"%s\">%s</a>", link, displaytext );
#else
- g_string_append_printf( mx->msg, "<b>%s</b>", linkname );
+ g_string_append_printf( mx->msg, "<b>%s</b>", replydata );
#endif
}
@@ -392,7 +402,9 @@ void mxit_show_message( struct RXMsgData* mx )
}
else {
/* insert img tag */
- g_snprintf( tag, sizeof( tag ), "<img id=\"%i\">", *img_id );
+ g_snprintf( tag, sizeof( tag ),
+ "<img src=\"" PURPLE_STORED_IMAGE_PROTOCOL "%i\">",
+ *img_id );
g_string_insert( mx->msg, start, tag );
}
@@ -619,7 +631,8 @@ static void emoticon_request( struct RXMsgData* mx, const char* id )
/* reference: "libpurple/util.h" */
url = g_strdup_printf( "%s/res/?type=emo&mlh=%i&sc=%s&ts=%li", wapserver, MXIT_EMOTICON_SIZE, id, time( NULL ) );
- url_data = purple_util_fetch_url_request( url, TRUE, NULL, TRUE, NULL, FALSE, emoticon_returned, mx );
+ /* FIXME: This should be cancelled somewhere if not needed. */
+ url_data = purple_util_fetch_url( url, TRUE, NULL, TRUE, -1, emoticon_returned, mx );
g_free( url );
}
@@ -736,6 +749,7 @@ void mxit_parse_markup( struct RXMsgData* mx, char* message, int len, short msgt
gboolean tag_bold = FALSE;
gboolean tag_under = FALSE;
gboolean tag_italic = FALSE;
+ int font_size = 0;
#ifdef MXIT_DEBUG_MARKUP
purple_debug_info( MXIT_PLUGIN_ID, "Markup RX (original): '%s'\n", message );
@@ -824,7 +838,7 @@ void mxit_parse_markup( struct RXMsgData* mx, char* message, int len, short msgt
if ( ch ) {
/* end found */
*ch = '\0';
- mxit_add_html_link( mx, &message[i + 1], &message[i + 1] );
+ mxit_add_html_link( mx, &message[i + 1], FALSE, &message[i + 1] );
*ch = '$';
i += ( ch - &message[i + 1] ) + 1;
}
@@ -863,59 +877,54 @@ void mxit_parse_markup( struct RXMsgData* mx, char* message, int len, short msgt
}
break;
case '.' :
- if ( !( msgflags & CP_MSG_EMOTICON ) ) {
- g_string_append_c( mx->msg, message[i] );
- break;
- }
- else if ( i + 1 >= len ) {
+ if ( i + 1 >= len ) {
/* message too short */
g_string_append_c( mx->msg, '.' );
break;
}
- switch ( message[i+1] ) {
- case '+' :
- /* increment text size */
- g_string_append( mx->msg, "<font size=\"+1\">" );
- i++;
- break;
- case '-' :
- /* decrement text size */
- g_string_append( mx->msg, "<font size=\"-1\">" );
- i++;
- break;
- case '{' :
- /* custom emoticon */
- if ( i + 2 >= len ) {
- /* message too short */
- g_string_append_c( mx->msg, '.' );
- break;
- }
-
- parse_emoticon_str( &message[i+2], tmpstr1 );
- if ( tmpstr1[0] != '\0' ) {
- mx->got_img = TRUE;
-
- if ( g_hash_table_lookup( mx->session->iimages, tmpstr1 ) ) {
- /* emoticon found in the cache, so we do not have to request it from the WAPsite */
- }
- else {
- /* request emoticon from the WAPsite */
- mx->img_count++;
- emoticon_request( mx, tmpstr1 );
- }
-
- g_string_append_printf( mx->msg, MXIT_II_TAG"%s>", tmpstr1 );
- i += strlen( tmpstr1 ) + 2;
- }
- else
- g_string_append_c( mx->msg, '.' );
-
- break;
- default :
- g_string_append_c( mx->msg, '.' );
- break;
+ if ( ( msgflags & CP_MSG_EMOTICON ) && ( message[i+1] == '{' ) ) {
+ /* custom emoticon */
+ if ( i + 2 >= len ) {
+ /* message too short */
+ g_string_append_c( mx->msg, '.' );
+ break;
+ }
+
+ parse_emoticon_str( &message[i+2], tmpstr1 );
+ if ( tmpstr1[0] != '\0' ) {
+ mx->got_img = TRUE;
+
+ if ( g_hash_table_lookup( mx->session->iimages, tmpstr1 ) ) {
+ /* emoticon found in the cache, so we do not have to request it from the WAPsite */
+ }
+ else {
+ /* request emoticon from the WAPsite */
+ mx->img_count++;
+ emoticon_request( mx, tmpstr1 );
+ }
+
+ g_string_append_printf( mx->msg, MXIT_II_TAG"%s>", tmpstr1 );
+ i += strlen( tmpstr1 ) + 2;
+ }
+ else
+ g_string_append_c( mx->msg, '.' );
+ }
+ else if ( ( msgflags & CP_MSG_MARKUP ) && ( message[i+1] == '+' ) ) {
+ /* increment text size */
+ font_size++;
+ g_string_append_printf( mx->msg, "<font size=\"%+i\">", font_size );
+ i++;
}
+ else if ( ( msgflags & CP_MSG_MARKUP ) && ( message[i+1] == '-' ) ) {
+ /* decrement text size */
+ font_size--;
+ g_string_append_printf( mx->msg, "<font size=\"%+i\">", font_size );
+ i++;
+ }
+ else
+ g_string_append_c( mx->msg, '.' );
+
break;
case '\\' :
if ( i + 1 >= len ) {
@@ -1060,7 +1069,7 @@ char* mxit_convert_markup_tx( const char* message, int* msgtype )
* Font colour: <font color=#">...</font>
* Links: <a href="">...</a>
* Newline: <br>
- * Inline image: <IMG ID="">
+ * Inline image: <IMG SRC="">
* The following characters are also encoded:
* &amp; &quot; &lt; &gt;
*/
@@ -1127,11 +1136,11 @@ char* mxit_convert_markup_tx( const char* message, int* msgtype )
g_free( tag );
}
}
- else if ( purple_str_has_prefix( &message[i], "<IMG ID=" ) ) {
+ else if ( purple_str_has_prefix( &message[i], "<IMG SRC=" PURPLE_STORED_IMAGE_PROTOCOL) ) {
/* inline image */
int imgid;
- if ( sscanf( &message[i+9], "%i", &imgid ) ) {
+ if ( sscanf( &message[i+sizeof("<IMG SRC=" PURPLE_STORED_IMAGE_PROTOCOL)-1], "%i", &imgid ) ) {
inline_image_add( mx, imgid );
*msgtype = CP_MSGTYPE_COMMAND; /* inline image must be sent as a MXit command */
}
diff --git a/libpurple/protocols/mxit/markup.h b/libpurple/protocols/mxit/markup.h
index bffc5b80d9..9d19d8cd35 100644
--- a/libpurple/protocols/mxit/markup.h
+++ b/libpurple/protocols/mxit/markup.h
@@ -31,7 +31,7 @@
void mxit_parse_markup( struct RXMsgData* mx, char* message, int len, short msgtype, int msgflags );
char* mxit_convert_markup_tx( const char* message, int* msgtype );
-void mxit_add_html_link( struct RXMsgData* mx, const char* linkname, const char* displayname );
+void mxit_add_html_link( struct RXMsgData* mx, const char* replydata, gboolean isStructured, const char* displaytext );
void mxit_show_message( struct RXMsgData* mx );
void mxit_free_emoticon_cache( struct MXitSession* session );
diff --git a/libpurple/protocols/mxit/multimx.c b/libpurple/protocols/mxit/multimx.c
index 8e0de5d7d4..09691abcb8 100644
--- a/libpurple/protocols/mxit/multimx.c
+++ b/libpurple/protocols/mxit/multimx.c
@@ -277,7 +277,11 @@ void multimx_invite(struct MXitSession* session, struct contact* contact, const
GHashTable *components;
struct multimx* multimx = NULL;
- purple_debug_info(MXIT_PLUGIN_ID, "Groupchat invite to '%s' by '%s'\n", contact->alias, creator);
+ purple_debug_info(MXIT_PLUGIN_ID, "Groupchat invite to '%s' (roomid='%s') by '%s'\n", contact->alias, contact->username, creator);
+
+ /* Check if the room already exists (ie, already joined or invite pending) */
+ if (find_room_by_username(session, contact->username) != NULL)
+ return;
/* Create a new room */
multimx = room_create(session, contact->username, contact->alias, STATE_INVITED);
@@ -307,7 +311,7 @@ void multimx_created(struct MXitSession* session, struct contact* contact)
multimx = find_room_by_username(session, contact->username);
if (multimx == NULL) {
multimx = room_create(session, contact->username, contact->alias, TRUE);
- }
+ }
else if (multimx->state == STATE_INVITED) {
/* After successfully accepting an invitation */
multimx->state = STATE_JOINED;
@@ -454,7 +458,7 @@ GList* mxit_chat_info(PurpleConnection *gc)
*/
void mxit_chat_join(PurpleConnection *gc, GHashTable *components)
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data(gc);
const char* roomname = NULL;
struct multimx* multimx = NULL;
@@ -496,7 +500,7 @@ void mxit_chat_join(PurpleConnection *gc, GHashTable *components)
*/
void mxit_chat_reject(PurpleConnection *gc, GHashTable* components)
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data(gc);
const char* roomname = NULL;
struct multimx* multimx = NULL;
@@ -539,7 +543,7 @@ char* mxit_chat_name(GHashTable *components)
*/
void mxit_chat_invite(PurpleConnection *gc, int id, const char *msg, const char *username)
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data(gc);
struct multimx* multimx = NULL;
PurpleBuddy* buddy;
PurpleConversation *convo;
@@ -585,7 +589,7 @@ void mxit_chat_invite(PurpleConnection *gc, int id, const char *msg, const char
*/
void mxit_chat_leave(PurpleConnection *gc, int id)
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data(gc);
struct multimx* multimx = NULL;
purple_debug_info(MXIT_PLUGIN_ID, "Groupchat %i leave\n", id);
@@ -616,7 +620,7 @@ void mxit_chat_leave(PurpleConnection *gc, int id)
*/
int mxit_chat_send(PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags)
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data(gc);
struct multimx* multimx = NULL;
const char* nickname;
diff --git a/libpurple/protocols/mxit/mxit.c b/libpurple/protocols/mxit/mxit.c
index 869484c2af..ec606ff211 100644
--- a/libpurple/protocols/mxit/mxit.c
+++ b/libpurple/protocols/mxit/mxit.c
@@ -58,7 +58,7 @@ static int not_link_ref_count = 0;
static void* mxit_link_click( const char* link64 )
{
PurpleAccount* account;
- PurpleConnection* con;
+ PurpleConnection* gc;
gchar** parts = NULL;
gchar* link = NULL;
gsize len;
@@ -75,10 +75,10 @@ static void* mxit_link_click( const char* link64 )
link = (gchar*) purple_base64_decode( link64 + strlen( MXIT_LINK_PREFIX ), &len );
purple_debug_info( MXIT_PLUGIN_ID, "Clicked Link: '%s'\n", link );
- parts = g_strsplit( link, "|", 5 );
+ parts = g_strsplit( link, "|", 6 );
/* check if this is a valid mxit link */
- if ( ( !parts ) || ( !parts[0] ) || ( !parts[1] ) || ( !parts[2] ) || ( !parts[3] ) || ( !parts[4] ) ) {
+ if ( ( !parts ) || ( !parts[0] ) || ( !parts[1] ) || ( !parts[2] ) || ( !parts[3] ) || ( !parts[4] ) || ( !parts[5] ) ) {
/* this is not for us */
goto skip;
}
@@ -91,15 +91,15 @@ static void* mxit_link_click( const char* link64 )
account = purple_accounts_find( parts[1], parts[2] );
if ( !account )
goto skip;
- con = purple_account_get_connection( account );
- if ( !con )
+ gc = purple_account_get_connection( account );
+ if ( !gc )
goto skip;
/* determine if it's a command-response to send */
- is_command = g_str_has_prefix( parts[4], "::type=reply|" );
+ is_command = ( atoi( parts[4] ) == 1 );
/* send click message back to MXit */
- mxit_send_message( con->proto_data, parts[3], parts[4], FALSE, is_command );
+ mxit_send_message( purple_connection_get_protocol_data( gc ), parts[3], parts[5], FALSE, is_command );
g_free( link );
link = NULL;
@@ -129,7 +129,7 @@ skip:
/*------------------------------------------------------------------------
* Register MXit to receive URI click notifications from the UI
*/
-void mxit_register_uri_handler(void)
+void mxit_register_uri_handler( void )
{
not_link_ref_count++;
if ( not_link_ref_count == 1 ) {
@@ -176,7 +176,7 @@ static void mxit_cb_chat_created( PurpleConversation* conv, struct MXitSession*
const char* who;
char* tmp;
- gc = purple_conversation_get_gc( conv );
+ gc = purple_conversation_get_connection( conv );
if ( session->con != gc ) {
/* not our conversation */
return;
@@ -198,7 +198,7 @@ static void mxit_cb_chat_created( PurpleConversation* conv, struct MXitSession*
if ( !buddy )
return;
- contact = purple_buddy_get_protocol_data(buddy);
+ contact = purple_buddy_get_protocol_data( buddy );
if ( !contact )
return;
@@ -214,7 +214,7 @@ static void mxit_cb_chat_created( PurpleConversation* conv, struct MXitSession*
case MXIT_TYPE_INFO :
tmp = g_strdup_printf("<font color=\"#999999\">%s</font>\n", _( "Loading menu..." ));
serv_got_im( session->con, who, tmp, PURPLE_MESSAGE_NOTIFY, time( NULL ) );
- g_free(tmp);
+ g_free( tmp );
mxit_send_message( session, who, " ", FALSE, FALSE );
default :
break;
@@ -268,7 +268,7 @@ static const char* mxit_list_icon( PurpleAccount* account, PurpleBuddy* buddy )
*/
static const char* mxit_list_emblem( PurpleBuddy* buddy )
{
- struct contact* contact = purple_buddy_get_protocol_data(buddy);
+ struct contact* contact = purple_buddy_get_protocol_data( buddy );
if ( !contact )
return NULL;
@@ -309,19 +309,18 @@ static const char* mxit_list_emblem( PurpleBuddy* buddy )
*/
char* mxit_status_text( PurpleBuddy* buddy )
{
- struct contact* contact = purple_buddy_get_protocol_data(buddy);
+ char* text = NULL;
+ struct contact* contact = purple_buddy_get_protocol_data( buddy );
if ( !contact )
return NULL;
- if ( contact->statusMsg ) {
- /* status message */
- return g_strdup( contact-> statusMsg );
- }
- else {
- /* mood */
- return g_strdup( mxit_convert_mood_to_name( contact->mood ) );
- }
+ if ( contact->statusMsg ) /* status message */
+ text = g_strdup( contact-> statusMsg );
+ else if ( contact->mood != MXIT_MOOD_NONE ) /* mood */
+ text = g_strdup( mxit_convert_mood_to_name( contact->mood ) );
+
+ return text;
}
@@ -334,34 +333,33 @@ char* mxit_status_text( PurpleBuddy* buddy )
*/
static void mxit_tooltip( PurpleBuddy* buddy, PurpleNotifyUserInfo* info, gboolean full )
{
- struct contact* contact = purple_buddy_get_protocol_data(buddy);
+ struct contact* contact = purple_buddy_get_protocol_data( buddy );
if ( !contact )
return;
/* status (reference: "libpurple/notify.h") */
if ( contact->presence != MXIT_PRESENCE_OFFLINE )
- purple_notify_user_info_add_pair( info, _( "Status" ), mxit_convert_presence_to_name( contact->presence ) );
+ purple_notify_user_info_add_pair_plaintext( info, _( "Status" ), mxit_convert_presence_to_name( contact->presence ) );
/* status message */
- if ( contact->statusMsg )
- purple_notify_user_info_add_pair( info, _( "Status Message" ), contact->statusMsg );
+ if ( contact->statusMsg ) {
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html( info, _( "Status Message" ), contact->statusMsg );
+ }
/* mood */
if ( contact->mood != MXIT_MOOD_NONE )
- purple_notify_user_info_add_pair( info, _( "Mood" ), mxit_convert_mood_to_name( contact->mood ) );
+ purple_notify_user_info_add_pair_plaintext( info, _( "Mood" ), mxit_convert_mood_to_name( contact->mood ) );
/* subscription type */
if ( contact->subtype != 0 )
- purple_notify_user_info_add_pair( info, _( "Subscription" ), mxit_convert_subtype_to_name( contact->subtype ) );
+ purple_notify_user_info_add_pair_plaintext( info, _( "Subscription" ), mxit_convert_subtype_to_name( contact->subtype ) );
/* rejection message */
if ( ( contact->subtype == MXIT_SUBTYPE_REJECTED ) && ( contact->msg != NULL ) )
- purple_notify_user_info_add_pair( info, _( "Rejection Message" ), contact->msg );
-
- /* hidden number */
- if ( contact->flags & MXIT_CFLAG_HIDDEN )
- purple_notify_user_info_add_pair( info, _( "Hidden Number" ), _( "Yes" ) );
+ purple_notify_user_info_add_pair_plaintext( info, _( "Rejection Message" ), contact->msg );
}
@@ -372,7 +370,7 @@ static void mxit_tooltip( PurpleBuddy* buddy, PurpleNotifyUserInfo* info, gboole
*/
static void mxit_close( PurpleConnection* gc )
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
/* disable signals */
mxit_disable_signals( session );
@@ -408,7 +406,7 @@ static int mxit_send_im( PurpleConnection* gc, const char* who, const char* mess
{
purple_debug_info( MXIT_PLUGIN_ID, "Sending message '%s' to buddy '%s'\n", message, who );
- mxit_send_message( gc->proto_data, who, message, TRUE, FALSE );
+ mxit_send_message( purple_connection_get_protocol_data( gc ), who, message, TRUE, FALSE );
return 1; /* echo to conversation window */
}
@@ -422,14 +420,14 @@ static int mxit_send_im( PurpleConnection* gc, const char* who, const char* mess
*/
static void mxit_set_status( PurpleAccount* account, PurpleStatus* status )
{
- struct MXitSession* session = purple_account_get_connection( account )->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( purple_account_get_connection( account ) );
const char* statusid;
int presence;
char* statusmsg1;
char* statusmsg2;
/* Handle mood changes */
- if (purple_status_type_get_primitive(purple_status_get_type(status)) == PURPLE_STATUS_MOOD) {
+ if ( purple_status_type_get_primitive(purple_status_get_type( status ) ) == PURPLE_STATUS_MOOD ) {
const char* moodid = purple_status_get_attr_string( status, PURPLE_MOOD_NAME );
int mood;
@@ -492,7 +490,7 @@ static void mxit_free_buddy( PurpleBuddy* buddy )
purple_debug_info( MXIT_PLUGIN_ID, "mxit_free_buddy\n" );
- contact = purple_buddy_get_protocol_data(buddy);
+ contact = purple_buddy_get_protocol_data( buddy );
if ( contact ) {
if ( contact->statusMsg )
g_free( contact->statusMsg );
@@ -503,7 +501,7 @@ static void mxit_free_buddy( PurpleBuddy* buddy )
g_free( contact );
}
- purple_buddy_set_protocol_data(buddy, NULL);
+ purple_buddy_set_protocol_data( buddy, NULL );
}
@@ -515,7 +513,7 @@ static void mxit_free_buddy( PurpleBuddy* buddy )
*/
static void mxit_keepalive( PurpleConnection *gc )
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
/* if not logged in, there is nothing to do */
if ( !( session->flags & MXIT_FLAG_LOGGEDIN ) )
@@ -543,7 +541,7 @@ static void mxit_keepalive( PurpleConnection *gc )
*/
static void mxit_set_buddy_icon( PurpleConnection *gc, PurpleStoredImage *img )
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
if ( img == NULL )
mxit_set_avatar( session, NULL, 0 );
@@ -562,7 +560,7 @@ static void mxit_get_info( PurpleConnection *gc, const char *who )
{
PurpleBuddy* buddy;
struct contact* contact;
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
const char* profilelist[] = { CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_FULLNAME,
CP_PROFILE_FIRSTNAME, CP_PROFILE_LASTNAME, CP_PROFILE_REGCOUNTRY, CP_PROFILE_LASTSEEN,
CP_PROFILE_STATUS, CP_PROFILE_AVATAR, CP_PROFILE_WHEREAMI, CP_PROFILE_ABOUTME };
@@ -612,14 +610,10 @@ static GHashTable* mxit_get_text_table( PurpleAccount* acc )
*/
static void mxit_reinvite( PurpleBlistNode *node, gpointer ignored )
{
- PurpleBuddy* buddy;
+ PurpleBuddy* buddy = (PurpleBuddy *) node;
+ PurpleConnection* gc = purple_account_get_connection( purple_buddy_get_account( buddy ) );
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
struct contact* contact;
- PurpleConnection* gc;
- struct MXitSession* session;
-
- buddy = (PurpleBuddy *)node;
- gc = purple_account_get_connection( purple_buddy_get_account( buddy ) );
- session = gc->proto_data;
contact = purple_buddy_get_protocol_data( (PurpleBuddy*) node );
if ( !contact )
@@ -653,15 +647,28 @@ static GList* mxit_blist_menu( PurpleBlistNode *node )
if ( ( contact->subtype == MXIT_SUBTYPE_DELETED ) || ( contact->subtype == MXIT_SUBTYPE_REJECTED ) || ( contact->subtype == MXIT_SUBTYPE_NONE ) ) {
/* contact is in Deleted, Rejected or None state */
act = purple_menu_action_new( _( "Re-Invite" ), PURPLE_CALLBACK( mxit_reinvite ), NULL, NULL );
- m = g_list_append(m, act);
+ m = g_list_append( m, act );
}
return m;
}
+
+/*------------------------------------------------------------------------
+ * Return Chat-room default settings.
+ *
+ * @return Chat defaults list
+ */
+static GHashTable *mxit_chat_info_defaults( PurpleConnection *gc, const char *chat_name )
+{
+ return g_hash_table_new_full( g_str_hash, g_str_equal, NULL, g_free );
+}
+
+
/*========================================================================================================================*/
static PurplePluginProtocolInfo proto_info = {
+ sizeof( PurplePluginProtocolInfo ), /* struct_size */
OPT_PROTO_REGISTER_NOSCREENNAME | OPT_PROTO_UNIQUE_CHATNAME | OPT_PROTO_IM_IMAGE | OPT_PROTO_INVITE_MESSAGE, /* options */
NULL, /* user_splits */
NULL, /* protocol_options */
@@ -680,7 +687,7 @@ static PurplePluginProtocolInfo proto_info = {
mxit_status_types, /* status types [roster.c] */
mxit_blist_menu, /* blist_node_menu */
mxit_chat_info, /* chat_info [multimx.c] */
- NULL, /* chat_info_defaults */
+ mxit_chat_info_defaults,/* chat_info_defaults */
mxit_login, /* login [login.c] */
mxit_close, /* close */
mxit_send_im, /* send_im */
@@ -690,7 +697,7 @@ static PurplePluginProtocolInfo proto_info = {
mxit_set_status, /* set_status */
NULL, /* set_idle */
NULL, /* change_passwd */
- NULL, /* add_buddy [roster.c] */
+ mxit_add_buddy, /* add_buddy [roster.c] */
NULL, /* add_buddies */
mxit_remove_buddy, /* remove_buddy [roster.c] */
NULL, /* remove_buddies */
@@ -709,7 +716,6 @@ static PurplePluginProtocolInfo proto_info = {
mxit_keepalive, /* keepalive */
mxit_register, /* register_user */
NULL, /* get_cb_info */
- NULL, /* get_cb_away */
mxit_buddy_alias, /* alias_buddy [roster.c] */
mxit_buddy_group, /* group_buddy [roster.c] */
mxit_rename_group, /* rename_group [roster.c] */
@@ -734,15 +740,12 @@ static PurplePluginProtocolInfo proto_info = {
NULL, /* unregister_user */
NULL, /* send_attention */
NULL, /* attention_types */
- sizeof( PurplePluginProtocolInfo ), /* struct_size */
mxit_get_text_table, /* get_account_text_table */
mxit_media_initiate, /* initiate_media */
mxit_media_caps, /* get_media_caps */
mxit_get_moods, /* get_moods */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- mxit_add_buddy, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */
};
diff --git a/libpurple/protocols/mxit/mxit.h b/libpurple/protocols/mxit/mxit.h
index ff85d98376..2f4bcebff3 100644
--- a/libpurple/protocols/mxit/mxit.h
+++ b/libpurple/protocols/mxit/mxit.h
@@ -161,6 +161,7 @@ struct MXitSession {
/* libpurple */
PurpleAccount* acc; /* pointer to the libpurple internal account struct */
PurpleConnection* con; /* pointer to the libpurple internal connection struct */
+ guint inpa; /* the input watcher */
/* transmit */
struct tx_queue queue; /* transmit packet queue (FIFO mode) */
@@ -191,7 +192,7 @@ char* mxit_status_text( PurpleBuddy* buddy );
void mxit_enable_signals( struct MXitSession* session );
#ifdef MXIT_LINK_CLICK
-void mxit_register_uri_handler(void);
+void mxit_register_uri_handler( void );
#endif
diff --git a/libpurple/protocols/mxit/profile.c b/libpurple/protocols/mxit/profile.c
index ba222e414e..a8b7a680fc 100644
--- a/libpurple/protocols/mxit/profile.c
+++ b/libpurple/protocols/mxit/profile.c
@@ -115,16 +115,16 @@ static int calculateAge( const char* date )
struct tm now, bdate;
int age;
- if ( ( !date ) || ( strlen( date ) == 0 ) )
+ if ( ( !date ) || ( !*date ) )
return 0;
/* current time */
- t = time(NULL);
+ t = time( NULL );
localtime_r( &t, &now );
/* decode hdate */
memset( &bdate, 0, sizeof( struct tm ) );
- purple_str_to_time(date, FALSE, &bdate, NULL, NULL);
+ purple_str_to_time( date, FALSE, &bdate, NULL, NULL );
/* calculate difference */
age = now.tm_year - bdate.tm_year;
@@ -170,54 +170,56 @@ void mxit_show_profile( struct MXitSession* session, const char* username, struc
buddy = purple_find_buddy( session->acc, username );
if ( buddy ) {
- purple_notify_user_info_add_pair( info, _( "Alias" ), purple_buddy_get_alias( buddy ) );
+ purple_notify_user_info_add_pair_plaintext( info, _( "Alias" ), purple_buddy_get_alias( buddy ) );
purple_notify_user_info_add_section_break( info );
- contact = purple_buddy_get_protocol_data(buddy);
+ contact = purple_buddy_get_protocol_data( buddy );
}
- purple_notify_user_info_add_pair( info, _( "Display Name" ), profile->nickname );
+ purple_notify_user_info_add_pair_plaintext( info, _( "Display Name" ), profile->nickname );
tmp = g_strdup_printf("%s (%i)", profile->birthday, calculateAge( profile->birthday ) );
- purple_notify_user_info_add_pair( info, _( "Birthday" ), tmp );
+ purple_notify_user_info_add_pair_plaintext( info, _( "Birthday" ), tmp );
g_free( tmp );
- purple_notify_user_info_add_pair( info, _( "Gender" ), profile->male ? _( "Male" ) : _( "Female" ) );
+ purple_notify_user_info_add_pair_plaintext( info, _( "Gender" ), profile->male ? _( "Male" ) : _( "Female" ) );
/* optional information */
- purple_notify_user_info_add_pair( info, _( "First Name" ), profile->firstname );
- purple_notify_user_info_add_pair( info, _( "Last Name" ), profile->lastname );
- purple_notify_user_info_add_pair( info, _( "Country" ), profile->regcountry );
+ purple_notify_user_info_add_pair_plaintext( info, _( "First Name" ), profile->firstname );
+ purple_notify_user_info_add_pair_plaintext( info, _( "Last Name" ), profile->lastname );
+
+ purple_notify_user_info_add_pair_plaintext( info, _( "Country" ), profile->regcountry );
+
+ if ( *profile->aboutme )
+ purple_notify_user_info_add_pair_plaintext( info, _( "About Me" ), profile->aboutme );
- if ( strlen( profile->aboutme ) > 0 )
- purple_notify_user_info_add_pair( info, _( "About Me" ), profile->aboutme );
- if ( strlen( profile->whereami ) > 0 )
- purple_notify_user_info_add_pair( info, _( "Where I Live" ), profile->whereami );
+ if ( *profile->whereami )
+ purple_notify_user_info_add_pair_plaintext( info, _( "Where I Live" ), profile->whereami );
purple_notify_user_info_add_section_break( info );
if ( contact ) {
/* presence */
- purple_notify_user_info_add_pair( info, _( "Status" ), mxit_convert_presence_to_name( contact->presence ) );
+ purple_notify_user_info_add_pair_plaintext( info, _( "Status" ), mxit_convert_presence_to_name( contact->presence ) );
/* last online */
if ( contact->presence == MXIT_PRESENCE_OFFLINE )
- purple_notify_user_info_add_pair( info, _( "Last Online" ), ( profile->lastonline == 0 ) ? _( "Unknown" ) : datetime( profile->lastonline ) );
+ purple_notify_user_info_add_pair_plaintext( info, _( "Last Online" ), ( profile->lastonline == 0 ) ? _( "Unknown" ) : datetime( profile->lastonline ) );
/* mood */
if ( contact->mood != MXIT_MOOD_NONE )
- purple_notify_user_info_add_pair( info, _( "Mood" ), mxit_convert_mood_to_name( contact->mood ) );
+ purple_notify_user_info_add_pair_plaintext( info, _( "Mood" ), mxit_convert_mood_to_name( contact->mood ) );
else
- purple_notify_user_info_add_pair( info, _( "Mood" ), _( "None" ) );
+ purple_notify_user_info_add_pair_plaintext( info, _( "Mood" ), _( "None" ) );
/* status message */
- if ( contact->statusMsg )
- purple_notify_user_info_add_pair( info, _( "Status Message" ), contact->statusMsg );
+ if ( contact->statusMsg ) {
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html( info, _( "Status Message" ), contact->statusMsg );
+ }
/* subscription type */
- purple_notify_user_info_add_pair( info, _( "Subscription" ), mxit_convert_subtype_to_name( contact->subtype ) );
-
- /* hidden number */
- purple_notify_user_info_add_pair( info, _( "Hidden Number" ), ( contact->flags & MXIT_CFLAG_HIDDEN ) ? _( "Yes" ) : _( "No" ) );
+ purple_notify_user_info_add_pair_plaintext( info, _( "Subscription" ), mxit_convert_subtype_to_name( contact->subtype ) );
}
else {
/* this is an invite */
@@ -226,17 +228,22 @@ void mxit_show_profile( struct MXitSession* session, const char* username, struc
/* invite found */
if ( contact->msg )
- purple_notify_user_info_add_pair( info, _( "Invite Message" ), contact->msg );
+ purple_notify_user_info_add_pair_plaintext( info, _( "Invite Message" ), contact->msg );
if ( contact->imgid ) {
/* this invite has a avatar */
char* img_text;
- img_text = g_strdup_printf( "<img id='%d'>", contact->imgid );
- purple_notify_user_info_add_pair( info, _( "Photo" ), img_text );
+ img_text = g_strdup_printf( "<img src='" PURPLE_STORED_IMAGE_PROTOCOL "%d'>",
+ contact->imgid );
+ purple_notify_user_info_add_pair_html( info, _( "Photo" ), img_text );
+ g_free(img_text);
}
- if ( contact->statusMsg )
- purple_notify_user_info_add_pair( info, _( "Status Message" ), contact->statusMsg );
+ if ( contact->statusMsg ) {
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html( info, _( "Status Message" ), contact->statusMsg );
+ }
}
}
@@ -284,6 +291,7 @@ void mxit_show_search_results( struct MXitSession* session, int searchType, int
/* define columns */
column = purple_notify_searchresults_column_new( _( "UserId" ) );
+ purple_notify_searchresult_column_set_visible( column, FALSE );
purple_notify_searchresults_column_add( results, column );
column = purple_notify_searchresults_column_new( _( "Display Name" ) );
purple_notify_searchresults_column_add( results, column );
@@ -298,7 +306,7 @@ void mxit_show_search_results( struct MXitSession* session, int searchType, int
column = purple_notify_searchresults_column_new( _( "Where I live" ) );
purple_notify_searchresults_column_add( results, column );
- while (entries != NULL) {
+ while ( entries != NULL ) {
struct MXitProfile* profile = ( struct MXitProfile *) entries->data;
GList* row;
gchar* tmp = purple_base64_encode( (unsigned char *) profile->userid, strlen( profile->userid ) );
@@ -328,5 +336,5 @@ void mxit_show_search_results( struct MXitSession* session, int searchType, int
purple_notify_searchresults( session->con, NULL, text, NULL, results, NULL, NULL );
- g_free( text);
+ g_free( text );
}
diff --git a/libpurple/protocols/mxit/profile.h b/libpurple/protocols/mxit/profile.h
index 77c2d30745..4748652b7b 100644
--- a/libpurple/protocols/mxit/profile.h
+++ b/libpurple/protocols/mxit/profile.h
@@ -50,7 +50,6 @@ struct MXitProfile {
int flags; /* user's profile flags */
gint64 lastonline; /* user's last-online timestamp */
- gboolean hidden; /* set if the user's mxitid should remain hidden */
};
struct MXitSession;
diff --git a/libpurple/protocols/mxit/protocol.c b/libpurple/protocols/mxit/protocol.c
index d86ab0ac66..733723b936 100644
--- a/libpurple/protocols/mxit/protocol.c
+++ b/libpurple/protocols/mxit/protocol.c
@@ -86,7 +86,7 @@ void mxit_popup( int type, const char* heading, const char* message )
void mxit_strip_domain( char* username )
{
if ( g_str_has_suffix( username, "@m" ) )
- username[ strlen(username) - 2 ] = '\0';
+ username[ strlen( username ) - 2 ] = '\0';
}
@@ -311,7 +311,7 @@ static void mxit_write_http_get( struct MXitSession* session, struct tx_packet*
#endif
/* send the HTTP request */
- session->http_out_req = purple_util_fetch_url_request( url, TRUE, MXIT_HTTP_USERAGENT, TRUE, NULL, FALSE, mxit_cb_http_rx, session );
+ session->http_out_req = purple_util_fetch_url_request( session->acc, url, TRUE, MXIT_HTTP_USERAGENT, TRUE, NULL, FALSE, -1, mxit_cb_http_rx, session );
g_free( url );
if ( part )
@@ -408,7 +408,7 @@ static void mxit_send_packet( struct MXitSession* session, struct tx_packet* pac
res = mxit_write_sock_packet( session->fd, data, datalen );
if ( res < 0 ) {
/* we must have lost the connection, so terminate it so that we can reconnect */
- purple_connection_error( session->con, _( "We have lost the connection to MXit. Please reconnect." ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "We have lost the connection to MXit. Please reconnect." ) );
}
}
else {
@@ -458,7 +458,7 @@ static void mxit_queue_packet( struct MXitSession* session, const char* data, in
packet->headerlen = 0;
/* create generic packet header */
- hlen = snprintf( header, sizeof( header ), "id=%s%c", session->acc->username, CP_REC_TERM ); /* client msisdn */
+ hlen = snprintf( header, sizeof( header ), "id=%s%c", purple_account_get_username( session->acc), CP_REC_TERM ); /* client msisdn */
if ( session->http ) {
/* http connection only */
@@ -530,7 +530,7 @@ static void mxit_manage_queue( struct MXitSession* session )
if ( session->last_tx <= mxit_now_milli() - ( MXIT_ACK_TIMEOUT * 1000 ) ) {
/* ack timeout! so we close the connection here */
purple_debug_info( MXIT_PLUGIN_ID, "mxit_manage_queue: Timeout awaiting ACK for command '%i'\n", session->outack );
- purple_connection_error( session->con, _( "Timeout while waiting for a response from the MXit server." ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Timeout while waiting for a response from the MXit server." ) );
}
return;
}
@@ -704,9 +704,9 @@ void mxit_send_register( struct MXitSession* session )
locale = purple_account_get_string( session->acc, MXIT_CONFIG_LOCALE, MXIT_DEFAULT_LOCALE );
/* Voice and Video supported */
- if (mxit_audio_enabled() && mxit_video_enabled())
- features |= (MXIT_CF_VOICE | MXIT_CF_VIDEO);
- else if (mxit_audio_enabled())
+ if ( mxit_audio_enabled() && mxit_video_enabled() )
+ features |= ( MXIT_CF_VOICE | MXIT_CF_VIDEO );
+ else if ( mxit_audio_enabled() )
features |= MXIT_CF_VOICE;
/* generate client version string (eg, P-2.7.10-Y-PURPLE) */
@@ -718,7 +718,7 @@ void mxit_send_register( struct MXitSession* session )
"%s%c%i%c%s%c%s%c" /* dateOfBirth\1gender\1location\1capabilities\1 */
"%s%c%i%c%s%c%s" /* dc\1features\1dialingcode\1locale */
"%c%i%c%i", /* \1protocolVer\1lastRosterUpdate */
- session->encpwd, CP_FLD_TERM, clientVersion, CP_FLD_TERM, CP_MAX_FILESIZE, CP_FLD_TERM, profile->nickname, CP_FLD_TERM,
+ session->encpwd, CP_FLD_TERM, clientVersion, CP_FLD_TERM, CP_MAX_PACKET, CP_FLD_TERM, profile->nickname, CP_FLD_TERM,
profile->birthday, CP_FLD_TERM, ( profile->male ) ? 1 : 0, CP_FLD_TERM, MXIT_DEFAULT_LOC, CP_FLD_TERM, MXIT_CP_CAP, CP_FLD_TERM,
session->distcode, CP_FLD_TERM, features, CP_FLD_TERM, session->dialcode, CP_FLD_TERM, locale,
CP_FLD_TERM, MXIT_CP_PROTO_VESION, CP_FLD_TERM, 0
@@ -748,9 +748,9 @@ void mxit_send_login( struct MXitSession* session )
locale = purple_account_get_string( session->acc, MXIT_CONFIG_LOCALE, MXIT_DEFAULT_LOCALE );
/* Voice and Video supported */
- if (mxit_audio_enabled() && mxit_video_enabled())
- features |= (MXIT_CF_VOICE | MXIT_CF_VIDEO);
- else if (mxit_audio_enabled())
+ if ( mxit_audio_enabled() && mxit_video_enabled() )
+ features |= ( MXIT_CF_VOICE | MXIT_CF_VIDEO );
+ else if ( mxit_audio_enabled() )
features |= MXIT_CF_VOICE;
/* generate client version string (eg, P-2.7.10-Y-PURPLE) */
@@ -765,7 +765,7 @@ void mxit_send_login( struct MXitSession* session )
session->encpwd, CP_FLD_TERM, clientVersion, CP_FLD_TERM, 1, CP_FLD_TERM,
MXIT_CP_CAP, CP_FLD_TERM, session->distcode, CP_FLD_TERM, features, CP_FLD_TERM,
session->dialcode, CP_FLD_TERM, locale, CP_FLD_TERM,
- CP_MAX_FILESIZE, CP_FLD_TERM, MXIT_CP_PROTO_VESION, CP_FLD_TERM, 0
+ CP_MAX_PACKET, CP_FLD_TERM, MXIT_CP_PROTO_VESION, CP_FLD_TERM, 0
);
/* include "custom resource" information */
@@ -835,7 +835,7 @@ void mxit_send_extprofile_request( struct MXitSession* session, const char* user
/* add attributes */
for ( i = 0; i < nr_attrib; i++ )
- datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] );
+ datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] );
/* queue packet for transmission */
mxit_queue_packet( session, data, datalen, CP_CMD_EXTPROFILE_GET );
@@ -868,7 +868,7 @@ void mxit_send_extprofile_update( struct MXitSession* session, const char* passw
/* add attributes */
for ( i = 1; i < nr_attrib * 3; i+=3 )
- datalen += sprintf( data + datalen, "%c%s%c%s%c%s", /* \1name\1type\1value */
+ datalen += sprintf( data + datalen, "%c%s%c%s%c%s", /* \1name\1type\1value */
CP_FLD_TERM, parts[i], CP_FLD_TERM, parts[i + 1], CP_FLD_TERM, parts[i + 2] );
/* queue packet for transmission */
@@ -900,7 +900,7 @@ void mxit_send_suggest_friends( struct MXitSession* session, int max, unsigned i
/* add attributes */
for ( i = 0; i < nr_attrib; i++ )
- datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] );
+ datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] );
/* queue packet for transmission */
mxit_queue_packet( session, data, datalen, CP_CMD_SUGGESTCONTACTS );
@@ -929,7 +929,7 @@ void mxit_send_suggest_search( struct MXitSession* session, int max, const char*
/* add attributes */
for ( i = 0; i < nr_attrib; i++ )
- datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] );
+ datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] );
/* queue packet for transmission */
mxit_queue_packet( session, data, datalen, CP_CMD_SUGGESTCONTACTS );
@@ -1175,7 +1175,7 @@ void mxit_send_groupchat_create( struct MXitSession* session, const char* groupn
/* add usernames */
for ( i = 0; i < nr_usernames; i++ )
- datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, usernames[i] );
+ datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, usernames[i] );
/* queue packet for transmission */
mxit_queue_packet( session, data, datalen, CP_CMD_GRPCHAT_CREATE );
@@ -1204,7 +1204,7 @@ void mxit_send_groupchat_invite( struct MXitSession* session, const char* roomid
/* add usernames */
for ( i = 0; i < nr_usernames; i++ )
- datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, usernames[i] );
+ datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, usernames[i] );
/* queue packet for transmission */
mxit_queue_packet( session, data, datalen, CP_CMD_GRPCHAT_INVITE );
@@ -1448,7 +1448,7 @@ static void mxit_parse_cmd_login( struct MXitSession* session, struct record** r
PurpleStatus* status;
int presence;
const char* statusmsg;
- const char* profilelist[] = { CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_HIDENUMBER, CP_PROFILE_FULLNAME,
+ const char* profilelist[] = { CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_FULLNAME,
CP_PROFILE_TITLE, CP_PROFILE_FIRSTNAME, CP_PROFILE_LASTNAME, CP_PROFILE_EMAIL,
CP_PROFILE_MOBILENR, CP_PROFILE_WHEREAMI, CP_PROFILE_ABOUTME, CP_PROFILE_FLAGS };
@@ -1516,6 +1516,7 @@ static void mxit_parse_cmd_message( struct MXitSession* session, struct record**
{
struct RXMsgData* mx = NULL;
char* message = NULL;
+ char* sender = NULL;
int msglen = 0;
int msgflags = 0;
int msgtype = 0;
@@ -1529,10 +1530,11 @@ static void mxit_parse_cmd_message( struct MXitSession* session, struct record**
msglen = strlen( message );
/* strip off dummy domain */
- mxit_strip_domain( records[0]->fields[0]->data );
+ sender = records[0]->fields[0]->data;
+ mxit_strip_domain( sender );
#ifdef DEBUG_PROTOCOL
- purple_debug_info( MXIT_PLUGIN_ID, "Message received from '%s'\n", records[0]->fields[0]->data );
+ purple_debug_info( MXIT_PLUGIN_ID, "Message received from '%s'\n", sender );
#endif
/* decode message flags (if any) */
@@ -1540,33 +1542,42 @@ static void mxit_parse_cmd_message( struct MXitSession* session, struct record**
msgflags = atoi( records[0]->fields[4]->data );
msgtype = atoi( records[0]->fields[2]->data );
- if ( msgflags & CP_MSG_ENCRYPTED ) {
- /* this is an encrypted message. we do not currently support those so ignore it */
+ if ( msgflags & CP_MSG_PWD_ENCRYPTED ) {
+ /* this is a password encrypted message. we do not currently support those so ignore it */
PurpleBuddy* buddy;
const char* name;
char msg[128];
- buddy = purple_find_buddy( session->acc, records[0]->fields[0]->data );
+ buddy = purple_find_buddy( session->acc, sender );
if ( buddy )
name = purple_buddy_get_alias( buddy );
else
- name = records[0]->fields[0]->data;
+ name = sender;
g_snprintf( msg, sizeof( msg ), _( "%s sent you an encrypted message, but it is not supported on this client." ), name );
mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "Message Error" ), msg );
return;
}
+ else if ( msgflags & CP_MSG_TL_ENCRYPTED ) {
+ /* this is a transport-layer encrypted message. */
+ message = mxit_decrypt_message( session, message );
+ if ( !message ) {
+ /* could not be decrypted */
+ serv_got_im( session->con, sender, _( "An encrypted message was received which could not be decrypted." ), PURPLE_MESSAGE_ERROR, time( NULL ) );
+ return;
+ }
+ }
if ( msgflags & CP_MSG_NOTIFY_DELIVERY ) {
/* delivery notification is requested */
if ( records[0]->fcount >= 4 )
- mxit_send_msgevent( session, records[0]->fields[0]->data, records[0]->fields[3]->data, CP_MSGEVENT_DELIVERED );
+ mxit_send_msgevent( session, sender, records[0]->fields[3]->data, CP_MSGEVENT_DELIVERED );
}
/* create and initialise new markup struct */
mx = g_new0( struct RXMsgData, 1 );
mx->msg = g_string_sized_new( msglen );
mx->session = session;
- mx->from = g_strdup( records[0]->fields[0]->data );
+ mx->from = g_strdup( sender );
mx->timestamp = atoi( records[0]->fields[1]->data );
mx->got_img = FALSE;
mx->chatid = -1;
@@ -1597,6 +1608,10 @@ static void mxit_parse_cmd_message( struct MXitSession* session, struct record**
* so the image received callback function will eventually display
* the message. */
}
+
+ /* cleanup */
+ if ( msgflags & CP_MSG_TL_ENCRYPTED )
+ g_free( message );
}
@@ -1633,7 +1648,7 @@ static void mxit_parse_cmd_new_sub( struct MXitSession* session, struct record**
if ( rec->fcount >= 5 ) {
/* there is a personal invite message attached */
- if ( ( rec->fields[4]->data ) && ( strlen( rec->fields[4]->data ) > 0 ) )
+ if ( ( rec->fields[4]->data ) && ( *rec->fields[4]->data ) )
contact->msg = strdup( rec->fields[4]->data );
}
@@ -1810,10 +1825,6 @@ static void mxit_parse_cmd_extprofile( struct MXitSession* session, struct recor
/* gender */
profile->male = ( fvalue[0] == '1' );
}
- else if ( strcmp( CP_PROFILE_HIDENUMBER, fname ) == 0 ) {
- /* hide number */
- profile->hidden = ( fvalue[0] == '1' );
- }
else if ( strcmp( CP_PROFILE_FULLNAME, fname ) == 0 ) {
/* nickname */
g_strlcpy( profile->nickname, fvalue, sizeof( profile->nickname ) );
@@ -1879,7 +1890,7 @@ static void mxit_parse_cmd_extprofile( struct MXitSession* session, struct recor
contact = get_mxit_invite_contact( session, mxitId );
if ( contact ) {
/* this is an invite, so update its profile info */
- if ( ( statusMsg ) && ( strlen( statusMsg ) > 0 ) ) {
+ if ( ( statusMsg ) && ( *statusMsg ) ) {
/* update the status message */
if ( contact->statusMsg )
g_free( contact->statusMsg );
@@ -1890,7 +1901,7 @@ static void mxit_parse_cmd_extprofile( struct MXitSession* session, struct recor
if ( contact->profile )
g_free( contact->profile );
contact->profile = profile;
- if ( ( avatarId ) && ( strlen( avatarId ) > 0 ) ) {
+ if ( ( avatarId ) && ( *avatarId ) ) {
/* avatar must be requested for this invite before we can display it */
mxit_get_avatar( session, mxitId, avatarId );
if ( contact->avatarId )
@@ -1908,7 +1919,7 @@ static void mxit_parse_cmd_extprofile( struct MXitSession* session, struct recor
if ( avatarId )
mxit_update_buddy_avatar( session, mxitId, avatarId );
- if ( ( statusMsg ) && ( strlen( statusMsg ) > 0 ) ) {
+ if ( ( statusMsg ) && ( *statusMsg ) ) {
/* update the status message */
PurpleBuddy* buddy = NULL;
@@ -2125,13 +2136,13 @@ static void mxit_parse_cmd_media( struct MXitSession* session, struct record** r
contact = get_mxit_invite_contact( session, chunk.mxitid );
if ( contact ) {
/* this is an invite (add image to the internal image store) */
- contact->imgid = purple_imgstore_add_with_id( chunk.data, chunk.length, NULL );
+ contact->imgid = purple_imgstore_add_with_id( g_memdup( chunk.data, chunk.length ), chunk.length, NULL );
/* show the profile */
mxit_show_profile( session, chunk.mxitid, contact->profile );
}
else {
/* this is a contact's avatar, so update it */
- purple_buddy_icons_set_for_user( session->acc, chunk.mxitid, g_memdup( chunk.data, chunk.length), chunk.length, chunk.avatarid );
+ purple_buddy_icons_set_for_user( session->acc, chunk.mxitid, g_memdup( chunk.data, chunk.length ), chunk.length, chunk.avatarid );
}
}
}
@@ -2192,7 +2203,7 @@ static void mxit_perform_redirect( struct MXitSession* session, const char* url
session->port = atoi( host[2] );
}
else {
- purple_connection_error( session->con, _( "Cannot perform redirect using the specified protocol" ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Cannot perform redirect using the specified protocol" ) );
goto redirect_fail;
}
@@ -2270,7 +2281,7 @@ static int process_success_response( struct MXitSession* session, struct rx_pack
case CP_CMD_PRESENCE :
/* presence update */
- mxit_parse_cmd_presence(session, &packet->records[2], packet->rcount - 3 );
+ mxit_parse_cmd_presence( session, &packet->records[2], packet->rcount - 3 );
break;
case CP_CMD_RX_MSG :
@@ -2361,7 +2372,7 @@ static int process_error_response( struct MXitSession* session, struct rx_packet
if ( packet->errcode == MXIT_ERRCODE_LOGGEDOUT ) {
/* we are not currently logged in, so we need to reconnect */
- purple_connection_error( session->con, _( errdesc ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( errdesc ) );
}
/* packet command */
@@ -2375,12 +2386,12 @@ static int process_error_response( struct MXitSession* session, struct rx_packet
}
else {
snprintf( errmsg, sizeof( errmsg ), _( "Login error: %s (%i)" ), errdesc, packet->errcode );
- purple_connection_error( session->con, errmsg );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, errmsg );
return -1;
}
case CP_CMD_LOGOUT :
snprintf( errmsg, sizeof( errmsg ), _( "Logout error: %s (%i)" ), errdesc, packet->errcode );
- purple_connection_error_reason( session->con, PURPLE_CONNECTION_ERROR_NAME_IN_USE, _( errmsg ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NAME_IN_USE, _( errmsg ) );
return -1;
case CP_CMD_CONTACT :
mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "Contact Error" ), _( errdesc ) );
@@ -2643,7 +2654,7 @@ int mxit_parse_packet( struct MXitSession* session )
if ( packet.rcount < 2 ) {
/* bad packet */
- purple_connection_error( session->con, _( "Invalid packet received from MXit." ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Invalid packet received from MXit." ) );
free_rx_packet( &packet );
continue;
}
@@ -2708,12 +2719,12 @@ void mxit_cb_rx( gpointer user_data, gint source, PurpleInputCondition cond )
len = read( session->fd, &ch, 1 );
if ( len < 0 ) {
/* connection error */
- purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x01)" ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x01)" ) );
return;
}
else if ( len == 0 ) {
/* connection closed */
- purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x02)" ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x02)" ) );
return;
}
else {
@@ -2723,7 +2734,7 @@ void mxit_cb_rx( gpointer user_data, gint source, PurpleInputCondition cond )
session->rx_lbuf[session->rx_i] = '\0';
session->rx_res = atoi( &session->rx_lbuf[3] );
if ( session->rx_res > CP_MAX_PACKET ) {
- purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x03)" ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x03)" ) );
}
session->rx_state = RX_STATE_DATA;
session->rx_i = 0;
@@ -2734,7 +2745,7 @@ void mxit_cb_rx( gpointer user_data, gint source, PurpleInputCondition cond )
session->rx_i++;
if ( session->rx_i >= sizeof( session->rx_lbuf ) ) {
/* malformed packet length record (too long) */
- purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x04)" ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x04)" ) );
return;
}
}
@@ -2745,12 +2756,12 @@ void mxit_cb_rx( gpointer user_data, gint source, PurpleInputCondition cond )
len = read( session->fd, &session->rx_dbuf[session->rx_i], session->rx_res );
if ( len < 0 ) {
/* connection error */
- purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x05)" ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x05)" ) );
return;
}
else if ( len == 0 ) {
/* connection closed */
- purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x06)" ) );
+ purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x06)" ) );
return;
}
else {
@@ -2808,9 +2819,9 @@ void mxit_close_connection( struct MXitSession* session )
}
/* remove the input cb function */
- if ( session->con->inpa ) {
- purple_input_remove( session->con->inpa );
- session->con->inpa = 0;
+ if ( session->inpa ) {
+ purple_input_remove( session->inpa );
+ session->inpa = 0;
}
/* remove HTTP poll timer */
diff --git a/libpurple/protocols/mxit/protocol.h b/libpurple/protocols/mxit/protocol.h
index bcec555bea..203ce445a2 100644
--- a/libpurple/protocols/mxit/protocol.h
+++ b/libpurple/protocols/mxit/protocol.h
@@ -34,8 +34,7 @@
#define CP_PKT_TERM '\x02' /* packet terminator */
-#define CP_MAX_PACKET ( 1024 * 1024 ) /* maximum client protocol packet size (1 MiB) */
-#define CP_MAX_FILESIZE ( 150 * 1000 ) /* maximum client protocol file transfer size (150 KB) */
+#define CP_MAX_PACKET ( 1 * 1000 * 1000 ) /* maximum client protocol packet size (1 MB) */
#define MXIT_EMOTICON_SIZE 18 /* icon size for custom emoticons */
#define CP_MAX_STATUS_MSG 250 /* maximum status message length (in characters) */
@@ -77,6 +76,7 @@
#define MXIT_CF_GAMING_UPDATE 0x800000
#define MXIT_CF_VOICE 0x1000000
#define MXIT_CF_VIDEO 0x2000000
+#define MXIT_CF_TOUCHSCREEN 0x4000000
/* Client features supported by this implementation */
#define MXIT_CP_FEATURES ( MXIT_CF_FILE_TRANSFER | MXIT_CF_FILE_ACCESS | MXIT_CF_AUDIO | MXIT_CF_MARKUP | MXIT_CF_EXT_MARKUP | MXIT_CF_NO_GATEWAYS | MXIT_CF_IMAGES | MXIT_CF_COMMANDS | MXIT_CF_VIBES | MXIT_CF_MIDP2 )
@@ -155,7 +155,10 @@
/* message flags */
#define CP_MSG_NOTIFY_DELIVERY 0x0002 /* request delivery notification */
#define CP_MSG_NOTIFY_READ 0x0004 /* request read notification */
-#define CP_MSG_ENCRYPTED 0x0010 /* message is encrypted */
+#define CP_MSG_PWD_ENCRYPTED 0x0010 /* message is password encrypted */
+#define CP_MSG_TL_ENCRYPTED 0x0020 /* message is transport encrypted */
+#define CP_MSG_RPLY_PWD_ENCRYPT 0x0040 /* reply should be password encrypted */
+#define CP_MSG_RPLY_TL_ENCRYPT 0x0080 /* reply should be transport encrypted */
#define CP_MSG_MARKUP 0x0200 /* message may contain markup */
#define CP_MSG_EMOTICON 0x0400 /* message may contain custom emoticons */
@@ -179,7 +182,7 @@
/* extended profile attribute fields */
#define CP_PROFILE_BIRTHDATE "birthdate" /* Birthdate (String - ISO 8601 format) */
#define CP_PROFILE_GENDER "gender" /* Gender (Boolean - 0=female, 1=male) */
-#define CP_PROFILE_HIDENUMBER "hidenumber" /* Hide Number (Boolean - 0=false, 1=true) */
+// #define CP_PROFILE_HIDENUMBER "hidenumber" /* Hide Number (Boolean - 0=false, 1=true) (DEPRECATED) */
#define CP_PROFILE_FULLNAME "fullname" /* Fullname (UTF8 String) */
#define CP_PROFILE_STATUS "statusmsg" /* Status Message (UTF8 String) */
#define CP_PROFILE_PREVSTATUS "prevstatusmsgs" /* Previous Status Messages (UTF8 String) */
diff --git a/libpurple/protocols/mxit/roster.c b/libpurple/protocols/mxit/roster.c
index 1dbbed78a2..d815be0f23 100644
--- a/libpurple/protocols/mxit/roster.c
+++ b/libpurple/protocols/mxit/roster.c
@@ -82,9 +82,9 @@ GList* mxit_status_types( PurpleAccount* account )
}
/* add Mood option */
- type = purple_status_type_new_with_attrs(PURPLE_STATUS_MOOD, "mood", NULL, FALSE, TRUE, TRUE,
+ type = purple_status_type_new_with_attrs( PURPLE_STATUS_MOOD, "mood", NULL, FALSE, TRUE, TRUE,
PURPLE_MOOD_NAME, _("Mood Name"), purple_value_new( PURPLE_TYPE_STRING ),
- NULL);
+ NULL );
statuslist = g_list_append( statuslist, type );
return statuslist;
@@ -135,21 +135,21 @@ const char* mxit_convert_presence_to_name( short no )
/* moods (reference: libpurple/status.h) */
static PurpleMood mxit_moods[] = {
- {"angry", N_("Angry"), NULL},
- {"excited", N_("Excited"), NULL},
- {"grumpy", N_("Grumpy"), NULL},
- {"happy", N_("Happy"), NULL},
- {"in_love", N_("In love"), NULL},
- {"invincible", N_("Invincible"), NULL},
- {"sad", N_("Sad"), NULL},
- {"hot", N_("Hot"), NULL},
- {"sick", N_("Sick"), NULL},
- {"sleepy", N_("Sleepy"), NULL},
- {"bored", N_("Bored"), NULL},
- {"cold", N_("Cold"), NULL},
- {"confused", N_("Confused"), NULL},
- {"hungry", N_("Hungry"), NULL},
- {"stressed", N_("Stressed"), NULL},
+ { "angry", N_( "Angry" ), NULL },
+ { "excited", N_( "Excited" ), NULL },
+ { "grumpy", N_( "Grumpy" ), NULL },
+ { "happy", N_( "Happy" ), NULL },
+ { "in_love", N_( "In love" ), NULL },
+ { "invincible", N_( "Invincible" ), NULL },
+ { "sad", N_( "Sad" ), NULL },
+ { "hot", N_( "Hot" ), NULL },
+ { "sick", N_( "Sick" ), NULL },
+ { "sleepy", N_( "Sleepy" ), NULL },
+ { "bored", N_( "Bored" ), NULL },
+ { "cold", N_( "Cold" ), NULL },
+ { "confused", N_( "Confused" ), NULL },
+ { "hungry", N_( "Hungry" ), NULL },
+ { "stressed", N_( "Stressed" ), NULL },
/* Mark the last record. */
{ NULL, NULL, NULL }
};
@@ -293,14 +293,15 @@ static void dump_contact( struct contact* contact )
*/
static PurpleBuddy* mxit_update_buddy_group( struct MXitSession* session, PurpleBuddy* buddy, PurpleGroup* group )
{
- struct contact* contact = NULL;
PurpleGroup* current_group = purple_buddy_get_group( buddy );
- PurpleBuddy* newbuddy = NULL;
/* make sure the groups actually differs */
if ( strcmp( current_group->name, group->name ) != 0 ) {
/* groupnames does not match, so we need to make the update */
+ struct contact* contact = purple_buddy_get_protocol_data( buddy );
+ PurpleBuddy* newbuddy = NULL;
+
purple_debug_info( MXIT_PLUGIN_ID, "Moving '%s' from group '%s' to '%s'\n", buddy->alias, current_group->name, group->name );
/*
@@ -310,10 +311,10 @@ static PurpleBuddy* mxit_update_buddy_group( struct MXitSession* session, Purple
* again. This is really not ideal and very irritating, but how else then?
*/
- /* create new buddy */
+ /* create new buddy, and transfer 'contact' data */
newbuddy = purple_buddy_new( session->acc, buddy->name, buddy->alias );
- newbuddy->proto_data = buddy->proto_data;
- buddy->proto_data = NULL;
+ purple_buddy_set_protocol_data( newbuddy, contact );
+ purple_buddy_set_protocol_data( buddy, NULL );
/* remove the buddy */
purple_blist_remove_buddy( buddy );
@@ -322,7 +323,6 @@ static PurpleBuddy* mxit_update_buddy_group( struct MXitSession* session, Purple
purple_blist_add_buddy( newbuddy, NULL, group, NULL );
/* now re-instate his presence again */
- contact = newbuddy->proto_data;
if ( contact ) {
/* update the buddy's status (reference: "libpurple/prpl.h") */
@@ -396,7 +396,7 @@ void mxit_update_contact( struct MXitSession* session, struct contact* contact )
/* create new buddy */
buddy = purple_buddy_new( session->acc, contact->username, contact->alias );
- purple_buddy_set_protocol_data(buddy, contact);
+ purple_buddy_set_protocol_data( buddy, contact );
/* add new buddy to list */
purple_blist_add_buddy( buddy, NULL, group, NULL );
@@ -728,7 +728,7 @@ gboolean is_mxit_chatroom_contact( struct MXitSession* session, const char* user
*/
void mxit_add_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* group, const char* message )
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
GSList* list = NULL;
PurpleBuddy* mxbuddy = NULL;
unsigned int i;
@@ -804,7 +804,7 @@ void mxit_add_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* grou
*/
void mxit_remove_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* group )
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
const gchar * buddy_name = purple_buddy_get_name( buddy );
purple_debug_info( MXIT_PLUGIN_ID, "mxit_remove_buddy '%s'\n", buddy_name );
@@ -822,7 +822,7 @@ void mxit_remove_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* g
*/
void mxit_buddy_alias( PurpleConnection* gc, const char* who, const char* alias )
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
PurpleBuddy* buddy = NULL;
PurpleGroup* group = NULL;
@@ -856,7 +856,7 @@ void mxit_buddy_alias( PurpleConnection* gc, const char* who, const char* alias
*/
void mxit_buddy_group( PurpleConnection* gc, const char* who, const char* old_group, const char* new_group )
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
PurpleBuddy* buddy = NULL;
purple_debug_info( MXIT_PLUGIN_ID, "mxit_buddy_group from '%s' to '%s'\n", old_group, new_group );
@@ -883,7 +883,7 @@ void mxit_buddy_group( PurpleConnection* gc, const char* who, const char* old_gr
*/
void mxit_rename_group( PurpleConnection* gc, const char* old_name, PurpleGroup* group, GList* moved_buddies )
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data( gc );
PurpleBuddy* buddy = NULL;
GList* item = NULL;
diff --git a/libpurple/protocols/mxit/roster.h b/libpurple/protocols/mxit/roster.h
index 5185dee3dc..6ee12024b6 100644
--- a/libpurple/protocols/mxit/roster.h
+++ b/libpurple/protocols/mxit/roster.h
@@ -74,7 +74,7 @@
/* MXit contact flags */
-#define MXIT_CFLAG_HIDDEN 0x02
+//#define MXIT_CFLAG_HIDDEN 0x02 /* (DEPRECATED) */
#define MXIT_CFLAG_GATEWAY 0x04
#define MXIT_CFLAG_FOCUS_SEND_BLANK 0x20000
@@ -96,7 +96,7 @@
/* client protocol constants */
#define MXIT_CP_MAX_JID_LEN 64
#define MXIT_CP_MAX_GROUP_LEN 32
-#define MXIT_CP_MAX_ALIAS_LEN 48
+#define MXIT_CP_MAX_ALIAS_LEN 100
#define MXIT_DEFAULT_GROUP "MXit"
@@ -106,8 +106,8 @@
*/
struct contact {
char username[MXIT_CP_MAX_JID_LEN+1]; /* unique contact name (with domain) */
- char alias[MXIT_CP_MAX_GROUP_LEN+1]; /* contact alias (what will be seen) */
- char groupname[MXIT_CP_MAX_ALIAS_LEN+1]; /* contact group name */
+ char alias[MXIT_CP_MAX_ALIAS_LEN+1]; /* contact alias (what will be seen) */
+ char groupname[MXIT_CP_MAX_GROUP_LEN+1]; /* contact group name */
short type; /* contact type */
short mood; /* contact current mood */
diff --git a/libpurple/protocols/mxit/splashscreen.c b/libpurple/protocols/mxit/splashscreen.c
index 9706e33f82..4a49ad20f7 100644
--- a/libpurple/protocols/mxit/splashscreen.c
+++ b/libpurple/protocols/mxit/splashscreen.c
@@ -144,7 +144,7 @@ void splash_update(struct MXitSession* session, const char* splashId, const char
*/
static void splash_click_ok(PurpleConnection* gc, PurpleRequestFields* fields)
{
- struct MXitSession* session = (struct MXitSession*) gc->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data(gc);
const char* splashId;
/* Get current splash ID */
@@ -187,7 +187,8 @@ void splash_display(struct MXitSession* session)
imgid = purple_imgstore_add_with_id(g_memdup(imgdata, imglen), imglen, NULL);
/* Generate and display message */
- g_snprintf(buf, sizeof(buf), "<img id=\"%d\">", imgid);
+ g_snprintf(buf, sizeof(buf),
+ "<img src=\"" PURPLE_STORED_IMAGE_PROTOCOL "%d\">", imgid);
/* Open a request-type popup to display the image */
{
diff --git a/libpurple/protocols/mxit/voicevideo.c b/libpurple/protocols/mxit/voicevideo.c
index c8f5b34708..9c6581900e 100644
--- a/libpurple/protocols/mxit/voicevideo.c
+++ b/libpurple/protocols/mxit/voicevideo.c
@@ -63,7 +63,7 @@ gboolean mxit_video_enabled(void)
*/
PurpleMediaCaps mxit_media_caps(PurpleAccount *account, const char *who)
{
- struct MXitSession* session = purple_account_get_connection(account)->proto_data;
+ struct MXitSession* session = purple_connection_get_protocol_data(purple_account_get_connection(account));
PurpleBuddy* buddy;
struct contact* contact;
PurpleMediaCaps capa = PURPLE_MEDIA_CAPS_NONE;
@@ -71,7 +71,7 @@ PurpleMediaCaps mxit_media_caps(PurpleAccount *account, const char *who)
purple_debug_info(MXIT_PLUGIN_ID, "mxit_media_caps: buddy '%s'\n", who);
/* We need to have a voice/video server */
- if (strlen(session->voip_server) == 0)
+ if (!*session->voip_server)
return PURPLE_MEDIA_CAPS_NONE;
/* find the buddy information for this contact (reference: "libpurple/blist.h") */
@@ -95,7 +95,7 @@ PurpleMediaCaps mxit_media_caps(PurpleAccount *account, const char *who)
/* and only when they're online */
if (contact->presence == MXIT_PRESENCE_OFFLINE)
- return MXIT_PRESENCE_OFFLINE;
+ return PURPLE_MEDIA_CAPS_NONE;
/* they support voice-only */
if (contact->capabilities & MXIT_PFLAG_VOICE)
diff --git a/libpurple/protocols/myspace/myspace.c b/libpurple/protocols/myspace/myspace.c
index 9cc52f5df4..6295806b47 100644
--- a/libpurple/protocols/myspace/myspace.c
+++ b/libpurple/protocols/myspace/myspace.c
@@ -254,7 +254,7 @@ msim_send_bm(MsimSession *session, const gchar *who, const gchar *text,
g_return_val_if_fail(who != NULL, FALSE);
g_return_val_if_fail(text != NULL, FALSE);
- from_username = session->account->username;
+ from_username = purple_account_get_username(session->account);
g_return_val_if_fail(from_username != NULL, FALSE);
@@ -429,11 +429,9 @@ msim_tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info,
user = msim_get_user_from_buddy(buddy, TRUE);
if (PURPLE_BUDDY_IS_ONLINE(buddy)) {
- MsimSession *session;
PurpleAccount *account = purple_buddy_get_account(buddy);
PurpleConnection *gc = purple_account_get_connection(account);
-
- session = (MsimSession *)gc->proto_data;
+ MsimSession *session = purple_connection_get_protocol_data(gc);
/* TODO: if (full), do something different? */
@@ -698,7 +696,7 @@ msim_login_challenge(MsimSession *session, MsimMessage *msg)
if (nc_len != MSIM_AUTH_CHALLENGE_LENGTH) {
purple_debug_info("msim", "bad nc length: %" G_GSIZE_MODIFIER
"x != 0x%x\n", nc_len, MSIM_AUTH_CHALLENGE_LENGTH);
- purple_connection_error_reason (session->gc,
+ purple_connection_error (session->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unexpected challenge length from server"));
return FALSE;
@@ -707,14 +705,14 @@ msim_login_challenge(MsimSession *session, MsimMessage *msg)
purple_connection_update_progress(session->gc, _("Logging in"), 2, 4);
response_len = 0;
- response = msim_compute_login_response(nc, account->username, account->password, &response_len);
+ response = msim_compute_login_response(nc, purple_account_get_username(account), purple_account_get_password(account), &response_len);
g_free(nc);
ret = msim_send(session,
"login2", MSIM_TYPE_INTEGER, MSIM_AUTH_ALGORITHM,
/* This is actually user's email address. */
- "username", MSIM_TYPE_STRING, g_strdup(account->username),
+ "username", MSIM_TYPE_STRING, g_strdup(purple_account_get_username(account)),
/* GString will be freed in msim_msg_free() in msim_send(). */
"response", MSIM_TYPE_BINARY, g_string_new_len(response, response_len),
"clientver", MSIM_TYPE_INTEGER, MSIM_CLIENT_VERSION,
@@ -754,8 +752,8 @@ msim_unrecognized(MsimSession *session, MsimMessage *msg, gchar *note)
*/
purple_debug_info("msim", "Unrecognized data on account for %s\n",
- (session && session->account && session->account->username) ?
- session->account->username : "(NULL)");
+ (session && session->account && purple_account_get_username(session->account)) ?
+ purple_account_get_username(session->account) : "(NULL)");
if (note) {
purple_debug_info("msim", "(Note: %s)\n", note);
}
@@ -835,7 +833,7 @@ msim_check_alive(gpointer data)
purple_debug_info("msim",
"msim_check_alive: %zu > interval of %d, presumed dead\n",
delta, MSIM_KEEPALIVE_INTERVAL);
- purple_connection_error_reason(session->gc,
+ purple_connection_error(session->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Lost connection with server"));
@@ -1840,7 +1838,7 @@ msim_error(MsimSession *session, MsimMessage *msg)
if (!purple_account_get_remember_password(session->account))
purple_account_set_password(session->account, NULL);
#ifdef MSIM_MAX_PASSWORD_LENGTH
- if (session->account->password && (strlen(session->account->password) > MSIM_MAX_PASSWORD_LENGTH)) {
+ if (purple_account_get_password(session->account) && (strlen(purple_account_get_password(session->account)) > MSIM_MAX_PASSWORD_LENGTH)) {
gchar *suggestion;
suggestion = g_strdup_printf(_("%s Your password is "
@@ -1848,7 +1846,7 @@ msim_error(MsimSession *session, MsimMessage *msg)
"maximum length of %d. Please shorten your "
"password at http://profileedit.myspace.com/index.cfm?fuseaction=accountSettings.changePassword and try again."),
full_errmsg,
- strlen(session->account->password),
+ strlen(purple_account_get_password(session->account)),
MSIM_MAX_PASSWORD_LENGTH);
/* Replace full_errmsg. */
@@ -1866,7 +1864,7 @@ msim_error(MsimSession *session, MsimMessage *msg)
purple_account_set_password(session->account, NULL);
break;
}
- purple_connection_error_reason(session->gc, reason, full_errmsg);
+ purple_connection_error(session->gc, reason, full_errmsg);
} else {
purple_notify_error(session->account, _("MySpaceIM Error"), full_errmsg, NULL);
}
@@ -2022,12 +2020,12 @@ msim_input_cb(gpointer gc_uncasted, gint source, PurpleInputCondition cond)
g_return_if_fail(source >= 0); /* Note: 0 is a valid fd */
gc = (PurpleConnection *)(gc_uncasted);
- session = gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
/* libpurple/eventloop.h only defines these two */
if (cond != PURPLE_INPUT_READ && cond != PURPLE_INPUT_WRITE) {
purple_debug_info("msim_input_cb", "unknown condition=%d\n", cond);
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Invalid input condition"));
return;
@@ -2069,12 +2067,12 @@ msim_input_cb(gpointer gc_uncasted, gint source, PurpleInputCondition cond)
tmp = g_strdup_printf(_("Lost connection with server: %s"),
g_strerror(errno));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
} else if (n == 0) {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Server closed the connection"));
return;
@@ -2092,7 +2090,7 @@ msim_input_cb(gpointer gc_uncasted, gint source, PurpleInputCondition cond)
purple_debug_info("msim", "msim_input_cb: strlen=%d, but read %d bytes"
"--null byte encountered?\n",
strlen(session->rxbuf + session->rxoff), n);
- /*purple_connection_error_reason (gc,
+ /*purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
"Invalid message - null byte on input"); */
return;
@@ -2117,7 +2115,7 @@ msim_input_cb(gpointer gc_uncasted, gint source, PurpleInputCondition cond)
msg = msim_parse(session->rxbuf);
if (!msg) {
purple_debug_info("msim", "msim_input_cb: couldn't parse rxbuf\n");
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to parse message"));
break;
@@ -2157,20 +2155,19 @@ msim_connect_cb(gpointer data, gint source, const gchar *error_message)
g_return_if_fail(data != NULL);
gc = (PurpleConnection *)data;
- session = (MsimSession *)gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
if (source < 0) {
gchar *tmp = g_strdup_printf(_("Unable to connect: %s"),
error_message);
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
}
session->fd = source;
-
- gc->inpa = purple_input_add(source, PURPLE_INPUT_READ, msim_input_cb, gc);
+ session->inpa = purple_input_add(source, PURPLE_INPUT_READ, msim_input_cb, gc);
}
/**
@@ -2186,13 +2183,13 @@ msim_login(PurpleAccount *acct)
int port;
g_return_if_fail(acct != NULL);
- g_return_if_fail(acct->username != NULL);
+ g_return_if_fail(purple_account_get_username(acct) != NULL);
- purple_debug_info("msim", "logging in %s\n", acct->username);
+ purple_debug_info("msim", "logging in %s\n", purple_account_get_username(acct));
gc = purple_account_get_connection(acct);
- gc->proto_data = msim_session_new(acct);
- gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_URLDESC;
+ purple_connection_set_protocol_data(gc, msim_session_new(acct));
+ purple_connection_set_flags(gc, PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_URLDESC);
/*
* Lets wipe out our local list of blocked buddies. We'll get a
@@ -2219,7 +2216,7 @@ msim_login(PurpleAccount *acct)
if (!purple_proxy_connect(gc, acct, host, port, msim_connect_cb, gc)) {
/* TODO: try other ports if in auto mode, then save
* working port and try that first next time. */
- purple_connection_error_reason (gc,
+ purple_connection_error (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect"));
return;
@@ -2259,14 +2256,15 @@ msim_close(PurpleConnection *gc)
buddies = g_slist_delete_link(buddies, buddies);
}
- session = (MsimSession *)gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
if (session == NULL)
return;
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
- if (session->gc->inpa) {
- purple_input_remove(session->gc->inpa);
+ if (session->inpa) {
+ purple_input_remove(session->inpa);
+ session->inpa = 0;
}
if (session->fd >= 0) {
close(session->fd);
@@ -2304,7 +2302,7 @@ msim_send_im(PurpleConnection *gc, const gchar *who, const gchar *message,
/* 'flags' has many options, not used here. */
- session = (MsimSession *)gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
message_msim = html_to_msim_markup(session, message);
@@ -2344,7 +2342,7 @@ msim_send_typing(PurpleConnection *gc, const gchar *name,
g_return_val_if_fail(gc != NULL, 0);
g_return_val_if_fail(name != NULL, 0);
- session = (MsimSession *)gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
switch (state) {
case PURPLE_TYPING:
@@ -2430,7 +2428,7 @@ msim_get_info(PurpleConnection *gc, const gchar *username)
g_return_if_fail(gc != NULL);
g_return_if_fail(username != NULL);
- session = (MsimSession *)gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
/* Obtain uid of buddy. */
user = msim_find_user(session, username);
@@ -2487,6 +2485,7 @@ msim_set_status_code(MsimSession *session, guint status_code, gchar *statstring)
static void
msim_set_status(PurpleAccount *account, PurpleStatus *status)
{
+ PurpleConnection *gc = purple_account_get_connection(account);
PurpleStatusType *type;
PurplePresence *pres;
MsimSession *session;
@@ -2495,7 +2494,7 @@ msim_set_status(PurpleAccount *account, PurpleStatus *status)
gchar *stripped;
gchar *unrecognized_msg;
- session = (MsimSession *)account->gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
type = purple_status_get_type(status);
pres = purple_status_get_presence(status);
@@ -2544,7 +2543,7 @@ msim_set_status(PurpleAccount *account, PurpleStatus *status)
/* If we should be idle, set that status. Time is irrelevant here. */
if (purple_presence_is_idle(pres) && status_code != MSIM_STATUS_CODE_OFFLINE_OR_HIDDEN)
- msim_set_idle(account->gc, 1);
+ msim_set_idle(purple_account_get_connection(account), 1);
}
/**
@@ -2558,7 +2557,7 @@ msim_set_idle(PurpleConnection *gc, int time)
g_return_if_fail(gc != NULL);
- session = (MsimSession *)gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
status = purple_account_get_active_status(session->account);
@@ -2628,7 +2627,7 @@ msim_update_blocklist_for_buddy(MsimSession *session, const char *name, gboolean
* Add a buddy to user's buddy list.
*/
static void
-msim_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
+msim_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, const char *message)
{
MsimSession *session;
MsimMessage *msg;
@@ -2636,7 +2635,7 @@ msim_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
MsimMessage *body;
const char *name, *gname;
- session = (MsimSession *)gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
name = purple_buddy_get_name(buddy);
gname = group ? purple_group_get_name(group) : NULL;
@@ -2709,7 +2708,7 @@ msim_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
MsimMessage *persist_msg;
const char *name;
- session = (MsimSession *)gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
name = purple_buddy_get_name(buddy);
delbuddy_msg = msim_msg_new(
@@ -2766,7 +2765,7 @@ msim_add_deny(PurpleConnection *gc, const char *name)
MsimSession *session;
MsimMessage *msg, *body;
- session = (MsimSession *)gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
/* Remove from buddy list */
msg = msim_msg_new(
@@ -2818,7 +2817,7 @@ msim_rem_deny(PurpleConnection *gc, const char *name)
MsimSession *session;
MsimMessage *msg, *body;
- session = (MsimSession *)gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
/*
* Remove from our list of blocked contacts, so we know they
@@ -2865,7 +2864,7 @@ static const char *msim_normalize(const PurpleAccount *account, const char *str)
const char *username;
/* If the account does not exist, we can't look up the user. */
- if (!account || !account->gc)
+ if (!account || !purple_account_get_connection(account))
return str;
id = atol(str);
@@ -2948,7 +2947,7 @@ msim_send_really_raw(PurpleConnection *gc, const char *buf, int total_bytes)
g_return_val_if_fail(buf != NULL, -1);
g_return_val_if_fail(total_bytes >= 0, -1);
- session = (MsimSession *)gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
/* Loop until all data is sent, or a failure occurs. */
total_bytes_sent = 0;
@@ -3008,6 +3007,7 @@ msim_get_account_text_table(PurpleAccount *unused)
* Callbacks called by Purple, to access this plugin.
*/
static PurplePluginProtocolInfo prpl_info = {
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
/* options */
OPT_PROTO_USE_POINTSIZE /* specify font size in sane point size */
| OPT_PROTO_MAIL_CHECK,
@@ -3052,7 +3052,6 @@ static PurplePluginProtocolInfo prpl_info = {
NULL, /* keepalive */
NULL, /* register_user */
NULL, /* get_cb_info */
- NULL, /* get_cb_away */
NULL, /* alias_buddy */
NULL, /* group_buddy */
NULL, /* rename_group */
@@ -3077,15 +3076,12 @@ static PurplePluginProtocolInfo prpl_info = {
NULL, /* unregister_user */
msim_send_attention, /* send_attention */
msim_attention_types, /* attention_types */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
msim_get_account_text_table, /* get_account_text_table */
NULL, /* initiate_media */
NULL, /* get_media_caps */
NULL, /* get_moods */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */
};
/**
@@ -3151,7 +3147,7 @@ static void msim_import_friends(PurplePluginAction *action)
gchar *group_name;
gc = (PurpleConnection *)action->context;
- session = (MsimSession *)gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
group_name = "MySpace Friends";
@@ -3530,6 +3526,7 @@ static gboolean
msim_uri_handler(const gchar *proto, const gchar *cmd, GHashTable *params)
{
PurpleAccount *account;
+ PurpleConnection *gc;
MsimSession *session;
GList *l;
gchar *uid_str, *cid_str;
@@ -3578,7 +3575,8 @@ msim_uri_handler(const gchar *proto, const gchar *cmd, GHashTable *params)
return FALSE;
}
- session = (MsimSession *)account->gc->proto_data;
+ gc = purple_account_get_connection(account);
+ session = purple_connection_get_protocol_data(gc);
g_return_val_if_fail(session != NULL, FALSE);
/* Lookup userid to username. TODO: push this down, to IM sending/contact
diff --git a/libpurple/protocols/myspace/session.h b/libpurple/protocols/myspace/session.h
index 34e1ba96cd..b8b902e769 100644
--- a/libpurple/protocols/myspace/session.h
+++ b/libpurple/protocols/myspace/session.h
@@ -38,6 +38,7 @@ typedef struct _MsimSession
int privacy_mode; /**< This is a bitmask */
int offline_message_mode;
gint fd; /**< File descriptor to/from server */
+ guint inpa; /**< The input watcher */
/* TODO: Remove. */
GHashTable *user_lookup_cb; /**< Username -> userid lookup callback */
diff --git a/libpurple/protocols/myspace/user.c b/libpurple/protocols/myspace/user.c
index 738045043a..357c6a180d 100644
--- a/libpurple/protocols/myspace/user.c
+++ b/libpurple/protocols/myspace/user.c
@@ -117,27 +117,33 @@ msim_append_user_info(MsimSession *session, PurpleNotifyUserInfo *user_info, Msi
/* Useful to identify the account the tooltip refers to.
* Other prpls show this. */
if (user->username) {
- purple_notify_user_info_add_pair(user_info, _("User"), user->username);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("User"), user->username);
}
/* a/s/l...the vitals */
if (user->age) {
char age[16];
g_snprintf(age, sizeof(age), "%d", user->age);
- purple_notify_user_info_add_pair(user_info, _("Age"), age);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Age"), age);
}
if (user->gender && *user->gender) {
- purple_notify_user_info_add_pair(user_info, _("Gender"), user->gender);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Gender"), user->gender);
}
if (user->location && *user->location) {
- purple_notify_user_info_add_pair(user_info, _("Location"), user->location);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Location"), user->location);
}
/* Other information */
if (user->headline && *user->headline) {
- purple_notify_user_info_add_pair(user_info, _("Headline"), user->headline);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Headline"), user->headline);
}
if (user->buddy != NULL) {
@@ -153,7 +159,9 @@ msim_append_user_info(MsimSession *session, PurpleNotifyUserInfo *user_info, Msi
str = msim_format_now_playing(artist, title);
if (str && *str) {
- purple_notify_user_info_add_pair(user_info, _("Song"), str);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Song"), str);
}
g_free(str);
}
@@ -163,7 +171,7 @@ msim_append_user_info(MsimSession *session, PurpleNotifyUserInfo *user_info, Msi
if (user->total_friends) {
char friends[16];
g_snprintf(friends, sizeof(friends), "%d", user->total_friends);
- purple_notify_user_info_add_pair(user_info, _("Total Friends"), friends);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Total Friends"), friends);
}
if (full) {
@@ -180,8 +188,11 @@ msim_append_user_info(MsimSession *session, PurpleNotifyUserInfo *user_info, Msi
} else if (cv) {
client = g_strdup_printf("Build %d", cv);
}
- if (client && *client)
- purple_notify_user_info_add_pair(user_info, _("Client Version"), client);
+ if (client && *client) {
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Client Version"), client);
+ }
g_free(client);
}
@@ -195,7 +206,7 @@ msim_append_user_info(MsimSession *session, PurpleNotifyUserInfo *user_info, Msi
else
profile = g_strdup_printf("<a href=\"http://myspace.com/%d\">%s</a>",
user->id, _("View web profile"));
- purple_notify_user_info_add_pair(user_info, NULL, profile);
+ purple_notify_user_info_add_pair_html(user_info, NULL, profile);
g_free(profile);
}
}
@@ -373,7 +384,7 @@ msim_store_user_info_each(const gchar *key_str, gchar *value_str, MsimUser *user
if (!previous_url || !g_str_equal(previous_url, user->image_url)) {
if (user->url_data != NULL)
purple_util_fetch_url_cancel(user->url_data);
- user->url_data = purple_util_fetch_url(user->image_url, TRUE, NULL, TRUE, msim_downloaded_buddy_icon, (gpointer)user);
+ user->url_data = purple_util_fetch_url(user->image_url, TRUE, NULL, TRUE, -1, msim_downloaded_buddy_icon, (gpointer)user);
}
} else if (g_str_equal(key_str, "LastImageUpdated")) {
/* TODO: use somewhere */
@@ -401,7 +412,7 @@ msim_store_user_info_each(const gchar *key_str, gchar *value_str, MsimUser *user
*
* @param session
* @param msg The user information reply, with any amount of information.
- * @param user The structure to save to, or NULL to save in PurpleBuddy->proto_data.
+ * @param user The structure to save to, or NULL to save in PurpleBuddy's protocol_data.
*
* Variable information is saved to the passed MsimUser structure. Permanent
* information (UserID) is stored in the blist node of the buddy list (and
@@ -636,7 +647,7 @@ static void msim_username_is_set_cb(MsimSession *session, const MsimMessage *use
if (!body) {
purple_debug_info("msim_username_is_set_cb", "No body");
/* Error: No body! */
- purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg);
+ purple_connection_error(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg);
}
username = msim_msg_get_string(body, "UserName");
code = msim_msg_get_integer(body,"Code");
@@ -678,13 +689,13 @@ static void msim_username_is_set_cb(MsimSession *session, const MsimMessage *use
NULL)) {
/* Error! */
/* Can't set... Disconnect */
- purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg);
+ purple_connection_error(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg);
}
} else {
/* Error! */
purple_debug_info("msim","username_is_set Error: Invalid cmd/dsn/lid combination");
- purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg);
+ purple_connection_error(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg);
}
}
@@ -747,7 +758,7 @@ static void msim_set_username_confirmed_cb(PurpleConnection *gc)
g_return_if_fail(gc != NULL);
- session = (MsimSession *)gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
user_msg = msim_msg_new(
"user", MSIM_TYPE_STRING, g_strdup(msim_username_to_set),
@@ -782,7 +793,7 @@ static void msim_username_is_available_cb(MsimSession *session, const MsimMessag
if (!body) {
purple_debug_info("msim_username_is_available_cb", "No body for %s?!\n", username);
- purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ purple_connection_error(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("An error occurred while trying to set the username. "
"Please try again, or visit http://editprofile.myspace.com/index.cfm?"
"fuseaction=profile.username to set your username."));
@@ -840,7 +851,7 @@ static void msim_check_username_availability_cb(PurpleConnection *gc, const char
g_return_if_fail(gc != NULL);
- session = (MsimSession *)gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
purple_debug_info("msim_check_username_availability_cb", "Checking username: %s\n", username_to_check);
@@ -867,7 +878,7 @@ void msim_do_not_set_username_cb(PurpleConnection *gc)
purple_debug_info("msim", "Don't set username");
/* Protocol won't log in now without a username set.. Disconnect */
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("No username set"));
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("No username set"));
}
/**
diff --git a/libpurple/protocols/myspace/zap.c b/libpurple/protocols/myspace/zap.c
index ed45e56d24..653b4d9f34 100644
--- a/libpurple/protocols/myspace/zap.c
+++ b/libpurple/protocols/myspace/zap.c
@@ -132,10 +132,10 @@ msim_send_attention(PurpleConnection *gc, const gchar *username, guint code)
PurpleAttentionType *attn;
PurpleBuddy *buddy;
- session = (MsimSession *)gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
/* Look for this attention type, by the code index given. */
- types = msim_attention_types(gc->account);
+ types = msim_attention_types(purple_connection_get_account(gc));
attn = (PurpleAttentionType *)g_list_nth_data(types, code);
if (!attn) {
@@ -175,7 +175,7 @@ msim_send_zap_from_menu(PurpleBlistNode *node, gpointer zap_num_ptr)
/* Find the session */
account = purple_buddy_get_account(buddy);
gc = purple_account_get_connection(account);
- session = (MsimSession *)gc->proto_data;
+ session = purple_connection_get_protocol_data(gc);
zap = GPOINTER_TO_INT(zap_num_ptr);
diff --git a/libpurple/protocols/novell/novell.c b/libpurple/protocols/novell/novell.c
index 8413e2470f..416e0b0279 100644
--- a/libpurple/protocols/novell/novell.c
+++ b/libpurple/protocols/novell/novell.c
@@ -131,8 +131,8 @@ _login_resp_cb(NMUser * user, NMERR_T ret_code,
/* Don't attempt to auto-reconnect if our
* password was invalid.
*/
- if (!purple_account_get_remember_password(gc->account))
- purple_account_set_password(gc->account, NULL);
+ if (!purple_account_get_remember_password(purple_connection_get_account(gc)))
+ purple_account_set_password(purple_connection_get_account(gc), NULL);
reason = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
break;
default:
@@ -140,7 +140,7 @@ _login_resp_cb(NMUser * user, NMERR_T ret_code,
reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
}
- purple_connection_error_reason(gc, reason, err);
+ purple_connection_error(gc, reason, err);
g_free(err);
}
}
@@ -741,16 +741,16 @@ _get_details_resp_add_privacy_item(NMUser *user, NMERR_T ret_code,
if (allowed) {
- if (!g_slist_find_custom(gc->account->permit,
+ if (!g_slist_find_custom(purple_connection_get_account(gc)->permit,
display_id, (GCompareFunc)purple_utf8_strcasecmp)) {
- purple_privacy_permit_add(gc->account, display_id, TRUE);
+ purple_privacy_permit_add(purple_connection_get_account(gc), display_id, TRUE);
}
} else {
- if (!g_slist_find_custom(gc->account->permit,
+ if (!g_slist_find_custom(purple_connection_get_account(gc)->permit,
display_id, (GCompareFunc)purple_utf8_strcasecmp)) {
- purple_privacy_deny_add(gc->account, display_id, TRUE);
+ purple_privacy_deny_add(purple_connection_get_account(gc), display_id, TRUE);
}
}
@@ -789,10 +789,10 @@ _create_privacy_item_deny_resp_cb(NMUser *user, NMERR_T ret_code,
if (display_id) {
- if (!g_slist_find_custom(gc->account->deny,
+ if (!g_slist_find_custom(purple_connection_get_account(gc)->deny,
display_id, (GCompareFunc)purple_utf8_strcasecmp)) {
- purple_privacy_deny_add(gc->account, display_id, TRUE);
+ purple_privacy_deny_add(purple_connection_get_account(gc), display_id, TRUE);
}
} else {
@@ -840,11 +840,11 @@ _create_privacy_item_permit_resp_cb(NMUser *user, NMERR_T ret_code,
if (display_id) {
- if (!g_slist_find_custom(gc->account->permit,
+ if (!g_slist_find_custom(purple_connection_get_account(gc)->permit,
display_id,
(GCompareFunc)purple_utf8_strcasecmp)) {
- purple_privacy_permit_add(gc->account, display_id, TRUE);
+ purple_privacy_permit_add(purple_connection_get_account(gc), display_id, TRUE);
}
} else {
@@ -1126,7 +1126,7 @@ _check_for_disconnect(NMUser * user, NMERR_T err)
if (_is_disconnect_error(err)) {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Error communicating with server. Closing connection."));
return TRUE;
@@ -1177,7 +1177,6 @@ _update_buddy_status(NMUser *user, PurpleBuddy * buddy, int novellstatus, int gm
const char *dn;
const char *name;
int idle = 0;
- gboolean loggedin = TRUE;
account = purple_buddy_get_account(buddy);
name = purple_buddy_get_name(buddy);
@@ -1194,7 +1193,6 @@ _update_buddy_status(NMUser *user, PurpleBuddy * buddy, int novellstatus, int gm
break;
case NM_STATUS_OFFLINE:
status_id = NOVELL_STATUS_TYPE_OFFLINE;
- loggedin = FALSE;
break;
case NM_STATUS_AWAY_IDLE:
status_id = NOVELL_STATUS_TYPE_AWAY;
@@ -1202,7 +1200,6 @@ _update_buddy_status(NMUser *user, PurpleBuddy * buddy, int novellstatus, int gm
break;
default:
status_id = NOVELL_STATUS_TYPE_OFFLINE;
- loggedin = FALSE;
break;
}
@@ -1404,15 +1401,15 @@ _sync_privacy_lists(NMUser *user)
/* Set the Purple privacy setting */
if (user->default_deny) {
if (user->allow_list == NULL) {
- gc->account->perm_deny = PURPLE_PRIVACY_DENY_ALL;
+ purple_account_set_privacy_type(purple_connection_get_account(gc), PURPLE_PRIVACY_DENY_ALL);
} else {
- gc->account->perm_deny = PURPLE_PRIVACY_ALLOW_USERS;
+ purple_account_set_privacy_type(purple_connection_get_account(gc), PURPLE_PRIVACY_ALLOW_USERS);
}
} else {
if (user->deny_list == NULL) {
- gc->account->perm_deny = PURPLE_PRIVACY_ALLOW_ALL;
+ purple_account_set_privacy_type(purple_connection_get_account(gc), PURPLE_PRIVACY_ALLOW_ALL);
} else {
- gc->account->perm_deny = PURPLE_PRIVACY_DENY_USERS;
+ purple_account_set_privacy_type(purple_connection_get_account(gc), PURPLE_PRIVACY_DENY_USERS);
}
}
@@ -1424,9 +1421,9 @@ _sync_privacy_lists(NMUser *user)
else
name =(char *)node->data;
- if (!g_slist_find_custom(gc->account->permit,
+ if (!g_slist_find_custom(purple_connection_get_account(gc)->permit,
name, (GCompareFunc)purple_utf8_strcasecmp)) {
- purple_privacy_permit_add(gc->account, name , TRUE);
+ purple_privacy_permit_add(purple_connection_get_account(gc), name , TRUE);
}
}
@@ -1437,15 +1434,15 @@ _sync_privacy_lists(NMUser *user)
else
name =(char *)node->data;
- if (!g_slist_find_custom(gc->account->deny,
+ if (!g_slist_find_custom(purple_connection_get_account(gc)->deny,
name, (GCompareFunc)purple_utf8_strcasecmp)) {
- purple_privacy_deny_add(gc->account, name, TRUE);
+ purple_privacy_deny_add(purple_connection_get_account(gc), name, TRUE);
}
}
/* Remove stuff */
- for (node = gc->account->permit; node; node = node->next) {
+ for (node = purple_connection_get_account(gc)->permit; node; node = node->next) {
dn = nm_lookup_dn(user, (char *)node->data);
if (dn != NULL &&
!g_slist_find_custom(user->allow_list,
@@ -1456,13 +1453,13 @@ _sync_privacy_lists(NMUser *user)
if (rem_list) {
for (node = rem_list; node; node = node->next) {
- purple_privacy_permit_remove(gc->account, (char *)node->data, TRUE);
+ purple_privacy_permit_remove(purple_connection_get_account(gc), (char *)node->data, TRUE);
}
g_slist_free(rem_list);
rem_list = NULL;
}
- for (node = gc->account->deny; node; node = node->next) {
+ for (node = purple_connection_get_account(gc)->deny; node; node = node->next) {
dn = nm_lookup_dn(user, (char *)node->data);
if (dn != NULL &&
!g_slist_find_custom(user->deny_list,
@@ -1473,7 +1470,7 @@ _sync_privacy_lists(NMUser *user)
if (rem_list) {
for (node = rem_list; node; node = node->next) {
- purple_privacy_deny_remove(gc->account, (char *)node->data, TRUE);
+ purple_privacy_deny_remove(purple_connection_get_account(gc), (char *)node->data, TRUE);
}
g_slist_free(rem_list);
}
@@ -1515,20 +1512,27 @@ _show_info(PurpleConnection * gc, NMUserRecord * user_record, char * name)
tag = _("User ID");
value = nm_user_record_get_userid(user_record);
if (value) {
- purple_notify_user_info_add_pair(user_info, tag, value);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, tag, value);
}
-/* tag = _("DN");
+#if 0
+ tag = _("DN");
value = nm_user_record_get_dn(user_record);
if (value) {
- purple_notify_user_info_add_pair(user_info, tag, value);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, tag, value);
}
-*/
+#endif /* if 0 */
tag = _("Full name");
value = nm_user_record_get_full_name(user_record);
if (value) {
- purple_notify_user_info_add_pair(user_info, tag, value);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, tag, value);
}
count = nm_user_record_get_property_count(user_record);
@@ -1538,7 +1542,9 @@ _show_info(PurpleConnection * gc, NMUserRecord * user_record, char * name)
tag = _map_property_tag(nm_property_get_tag(property));
value = nm_property_get_value(property);
if (tag && value) {
- purple_notify_user_info_add_pair(user_info, tag, value);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, tag, value);
}
nm_release_property(property);
}
@@ -1620,7 +1626,7 @@ _initiate_conference_cb(PurpleBlistNode *node, gpointer ignored)
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user == NULL)
return;
@@ -1676,7 +1682,7 @@ novell_ssl_connect_error(PurpleSslConnection * gsc,
NMUser *user;
gc = data;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
user->conn->ssl_conn->data = NULL;
purple_connection_ssl_error (gc, error);
@@ -1693,7 +1699,7 @@ novell_ssl_recv_cb(gpointer data, PurpleSslConnection * gsc,
if (gc == NULL)
return;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user == NULL)
return;
@@ -1702,7 +1708,7 @@ novell_ssl_recv_cb(gpointer data, PurpleSslConnection * gsc,
if (_is_disconnect_error(rc)) {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Error communicating with server. Closing connection."));
} else {
@@ -1727,7 +1733,7 @@ novell_ssl_connected_cb(gpointer data, PurpleSslConnection * gsc,
if (gc == NULL || gsc == NULL)
return;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if ((user == NULL) || (conn = user->conn) == NULL)
return;
@@ -1743,7 +1749,7 @@ novell_ssl_connected_cb(gpointer data, PurpleSslConnection * gsc,
conn->connected = TRUE;
purple_ssl_input_add(gsc, novell_ssl_recv_cb, gc);
} else {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect"));
}
@@ -2028,7 +2034,7 @@ _evt_user_disconnect(NMUser * user, NMEvent * event)
{
if (!purple_account_get_remember_password(account))
purple_account_set_password(account, NULL);
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NAME_IN_USE,
_("You have signed on from another location"));
}
@@ -2184,7 +2190,7 @@ novell_login(PurpleAccount * account)
*/
/* ...but for now just error out with a nice message. */
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
_("Unable to connect to server. Please enter the "
"address of the server to which you wish to connect."));
@@ -2197,7 +2203,7 @@ novell_login(PurpleAccount * account)
user = nm_initialize_user(name, server, port, account, _event_callback);
if (user && user->conn) {
/* save user */
- gc->proto_data = user;
+ purple_connection_set_protocol_data(gc, user);
/* connect to the server */
purple_connection_update_progress(gc, _("Connecting"),
@@ -2213,7 +2219,7 @@ novell_login(PurpleAccount * account)
user->conn->addr, user->conn->port,
novell_ssl_connected_cb, novell_ssl_connect_error, gc);
if (user->conn->ssl_conn->data == NULL) {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
_("SSL support unavailable"));
}
@@ -2229,7 +2235,7 @@ novell_close(PurpleConnection * gc)
if (gc == NULL)
return;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user) {
conn = user->conn;
if (conn && conn->ssl_conn) {
@@ -2237,7 +2243,7 @@ novell_close(PurpleConnection * gc)
}
nm_deinitialize_user(user);
}
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
}
static int
@@ -2257,7 +2263,7 @@ novell_send_im(PurpleConnection * gc, const char *name,
message_body == NULL || *message_body == '\0')
return 0;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user == NULL)
return 0;
@@ -2343,7 +2349,7 @@ novell_send_typing(PurpleConnection * gc, const char *name, PurpleTypingState st
if (gc == NULL || name == NULL)
return 0;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user == NULL)
return 0;
@@ -2377,7 +2383,7 @@ novell_convo_closed(PurpleConnection * gc, const char *who)
if (gc == NULL || who == NULL)
return;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user && (dn = nm_lookup_dn(user, who))) {
conf = nm_find_conversation(user, dn);
if (conf) {
@@ -2399,7 +2405,7 @@ novell_chat_leave(PurpleConnection * gc, int id)
if (gc == NULL)
return;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user == NULL)
return;
@@ -2431,7 +2437,7 @@ novell_chat_invite(PurpleConnection *gc, int id,
if (gc == NULL)
return;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user == NULL)
return;
@@ -2470,7 +2476,7 @@ novell_chat_send(PurpleConnection * gc, int id, const char *text, PurpleMessageF
if (gc == NULL || text == NULL)
return -1;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user == NULL)
return -1;
@@ -2536,7 +2542,7 @@ novell_chat_send(PurpleConnection * gc, int id, const char *text, PurpleMessageF
}
static void
-novell_add_buddy(PurpleConnection * gc, PurpleBuddy *buddy, PurpleGroup * group)
+novell_add_buddy(PurpleConnection * gc, PurpleBuddy *buddy, PurpleGroup * group, const char *message)
{
NMFolder *folder = NULL;
NMContact *contact;
@@ -2610,7 +2616,7 @@ novell_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group
if (gc == NULL || buddy == NULL || group == NULL)
return;
- user = (NMUser *) gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user && (dn = nm_lookup_dn(user, purple_buddy_get_name(buddy)))) {
gname = purple_group_get_name(group);
if (strcmp(gname, NM_ROOT_FOLDER_NAME) == 0) {
@@ -2642,7 +2648,7 @@ novell_remove_group(PurpleConnection * gc, PurpleGroup *group)
if (gc == NULL || group == NULL)
return;
- user = (NMUser *) gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user) {
NMFolder *folder = nm_find_folder(user, purple_group_get_name(group));
@@ -2667,7 +2673,7 @@ novell_alias_buddy(PurpleConnection * gc, const char *name, const char *alias)
if (gc == NULL || name == NULL || alias == NULL)
return;
- user = (NMUser *) gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user && (dn = nm_lookup_dn(user, name))) {
/* Alias all of instances of the contact */
@@ -2726,7 +2732,7 @@ novell_group_buddy(PurpleConnection * gc,
old_group_name == NULL || new_group_name == NULL)
return;
- user = (NMUser *) gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user && (dn = nm_lookup_dn(user, name))) {
/* Find the old folder */
@@ -2784,7 +2790,7 @@ novell_rename_group(PurpleConnection * gc, const char *old_name,
return;
}
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user) {
const char *gname = purple_group_get_name(group);
/* Does new folder exist already? */
@@ -2830,7 +2836,7 @@ novell_tooltip_text(PurpleBuddy * buddy, PurpleNotifyUserInfo * user_info, gbool
return;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- if (gc == NULL || (user = gc->proto_data) == NULL)
+ if (gc == NULL || (user = purple_connection_get_protocol_data(gc)) == NULL)
return;
if (PURPLE_BUDDY_IS_ONLINE(buddy)) {
@@ -2860,10 +2866,13 @@ novell_tooltip_text(PurpleBuddy * buddy, PurpleNotifyUserInfo * user_info, gbool
break;
}
- purple_notify_user_info_add_pair(user_info, _("Status"), status_str);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), status_str);
- if (text)
- purple_notify_user_info_add_pair(user_info, _("Message"), text);
+ if (text) {
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Message"), text);
+ }
}
}
}
@@ -2879,7 +2888,7 @@ novell_set_idle(PurpleConnection * gc, int time)
if (gc == NULL)
return;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user == NULL)
return;
@@ -2908,7 +2917,7 @@ novell_get_info(PurpleConnection * gc, const char *name)
if (gc == NULL || name == NULL)
return;
- user = (NMUser *) gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user) {
user_record = nm_find_user_record(user, name);
@@ -2937,17 +2946,19 @@ novell_status_text(PurpleBuddy * buddy)
if (buddy && account) {
PurpleConnection *gc = purple_account_get_connection(account);
- if (gc && gc->proto_data) {
- NMUser *user = gc->proto_data;
+ if (gc) {
+ NMUser *user = purple_connection_get_protocol_data(gc);
- dn = nm_lookup_dn(user, purple_buddy_get_name(buddy));
- if (dn) {
- NMUserRecord *user_record = nm_find_user_record(user, dn);
+ if (user) {
+ dn = nm_lookup_dn(user, purple_buddy_get_name(buddy));
+ if (dn) {
+ NMUserRecord *user_record = nm_find_user_record(user, dn);
- if (user_record) {
- text = nm_user_record_get_status_text(user_record);
- if (text)
- return g_strdup(text);
+ if (user_record) {
+ text = nm_user_record_get_status_text(user_record);
+ if (text)
+ return g_strdup(text);
+ }
}
}
}
@@ -3023,7 +3034,7 @@ novell_set_status(PurpleAccount *account, PurpleStatus *status)
return;
gc = purple_account_get_connection(account);
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user == NULL)
return;
@@ -3070,14 +3081,14 @@ novell_add_permit(PurpleConnection *gc, const char *who)
if (gc == NULL || who == NULL)
return;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user == NULL)
return;
/* Remove first -- we will add it back in when we get
* the okay from the server
*/
- purple_privacy_permit_remove(gc->account, who, TRUE);
+ purple_privacy_permit_remove(purple_connection_get_account(gc), who, TRUE);
if (nm_user_is_privacy_locked(user)) {
_show_privacy_locked_error(gc, user);
@@ -3114,14 +3125,14 @@ novell_add_deny(PurpleConnection *gc, const char *who)
if (gc == NULL || who == NULL)
return;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user == NULL)
return;
/* Remove first -- we will add it back in when we get
* the okay from the server
*/
- purple_privacy_deny_remove(gc->account, who, TRUE);
+ purple_privacy_deny_remove(purple_connection_get_account(gc), who, TRUE);
if (nm_user_is_privacy_locked(user)) {
_show_privacy_locked_error(gc, user);
@@ -3158,7 +3169,7 @@ novell_rem_permit(PurpleConnection *gc, const char *who)
if (gc == NULL || who == NULL)
return;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user == NULL)
return;
@@ -3188,7 +3199,7 @@ novell_rem_deny(PurpleConnection *gc, const char *who)
if (gc == NULL || who == NULL)
return;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user == NULL)
return;
@@ -3223,7 +3234,7 @@ novell_set_permit_deny(PurpleConnection *gc)
if (gc == NULL)
return;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user == NULL)
return;
@@ -3239,7 +3250,7 @@ novell_set_permit_deny(PurpleConnection *gc)
return;
}
- switch (gc->account->perm_deny) {
+ switch (purple_account_get_privacy_type(purple_connection_get_account(gc))) {
case PURPLE_PRIVACY_ALLOW_ALL:
rc = nm_send_set_privacy_default(user, FALSE,
@@ -3295,14 +3306,14 @@ novell_set_permit_deny(PurpleConnection *gc)
if (user_record) {
name = nm_user_record_get_display_id(user_record);
- if (!g_slist_find_custom(gc->account->permit,
+ if (!g_slist_find_custom(purple_connection_get_account(gc)->permit,
name, (GCompareFunc)purple_utf8_strcasecmp)) {
- purple_privacy_permit_add(gc->account, name , TRUE);
+ purple_privacy_permit_add(purple_connection_get_account(gc), name , TRUE);
}
}
}
- for (node = gc->account->permit; node; node = node->next) {
+ for (node = purple_connection_get_account(gc)->permit; node; node = node->next) {
name = NULL;
dn = nm_lookup_dn(user, (char *)node->data);
if (dn) {
@@ -3316,7 +3327,7 @@ novell_set_permit_deny(PurpleConnection *gc)
g_strdup(dn));
}
} else {
- purple_privacy_permit_remove(gc->account, (char *)node->data, TRUE);
+ purple_privacy_permit_remove(purple_connection_get_account(gc), (char *)node->data, TRUE);
}
}
}
@@ -3337,14 +3348,14 @@ novell_set_permit_deny(PurpleConnection *gc)
if (user_record) {
name = nm_user_record_get_display_id(user_record);
- if (!g_slist_find_custom(gc->account->deny,
+ if (!g_slist_find_custom(purple_connection_get_account(gc)->deny,
name, (GCompareFunc)purple_utf8_strcasecmp)) {
- purple_privacy_deny_add(gc->account, name , TRUE);
+ purple_privacy_deny_add(purple_connection_get_account(gc), name , TRUE);
}
}
}
- for (node = gc->account->deny; node; node = node->next) {
+ for (node = purple_connection_get_account(gc)->deny; node; node = node->next) {
name = NULL;
dn = nm_lookup_dn(user, (char *)node->data);
@@ -3359,7 +3370,7 @@ novell_set_permit_deny(PurpleConnection *gc)
g_strdup(name));
}
} else {
- purple_privacy_deny_remove(gc->account, (char *)node->data, TRUE);
+ purple_privacy_deny_remove(purple_connection_get_account(gc), (char *)node->data, TRUE);
}
}
@@ -3451,7 +3462,7 @@ novell_keepalive(PurpleConnection *gc)
if (gc == NULL)
return;
- user = gc->proto_data;
+ user = purple_connection_get_protocol_data(gc);
if (user == NULL)
return;
@@ -3460,6 +3471,7 @@ novell_keepalive(PurpleConnection *gc)
}
static PurplePluginProtocolInfo prpl_info = {
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
0,
NULL, /* user_splits */
NULL, /* protocol_options */
@@ -3500,7 +3512,6 @@ static PurplePluginProtocolInfo prpl_info = {
novell_keepalive, /* keepalive */
NULL, /* register_user */
NULL, /* get_cb_info */
- NULL, /* get_cb_away */
novell_alias_buddy, /* alias_buddy */
novell_group_buddy, /* group_buddy */
novell_rename_group, /* rename_group */
@@ -3525,15 +3536,12 @@ static PurplePluginProtocolInfo prpl_info = {
NULL, /* unregister_user */
NULL, /* send_attention */
NULL, /* get_attention_types */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
NULL, /* get_account_text_table */
NULL, /* initiate_media */
NULL, /* get_media_caps */
NULL, /* get_moods */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */
};
static PurplePluginInfo info = {
diff --git a/libpurple/protocols/null/nullprpl.c b/libpurple/protocols/null/nullprpl.c
index 1fdb0e4fb1..8516f728ab 100644
--- a/libpurple/protocols/null/nullprpl.c
+++ b/libpurple/protocols/null/nullprpl.c
@@ -113,7 +113,7 @@ static void call_if_nullprpl(gpointer data, gpointer userdata) {
PurpleConnection *gc = (PurpleConnection *)(data);
GcFuncData *gcfdata = (GcFuncData *)userdata;
- if (!strcmp(gc->account->protocol_id, NULLPRPL_ID))
+ if (!strcmp(purple_account_get_protocol_id(purple_connection_get_account(gc)), NULLPRPL_ID))
gcfdata->fn(gcfdata->from, gc, gcfdata->userdata);
}
@@ -138,11 +138,11 @@ static void call_chat_func(gpointer data, gpointer userdata) {
PurpleConnection *to = (PurpleConnection *)data;
ChatFuncData *cfdata = (ChatFuncData *)userdata;
- int id = cfdata->from_chat->id;
+ int id = purple_conv_chat_get_id(cfdata->from_chat);
PurpleConversation *conv = purple_find_chat(to, id);
if (conv) {
PurpleConvChat *chat = purple_conversation_get_chat_data(conv);
- cfdata->fn(cfdata->from_chat, chat, id, conv->name, cfdata->userdata);
+ cfdata->fn(cfdata->from_chat, chat, id, purple_conversation_get_name(conv), cfdata->userdata);
}
}
@@ -160,11 +160,11 @@ static void foreach_gc_in_chat(ChatFunc fn, PurpleConnection *from,
static void discover_status(PurpleConnection *from, PurpleConnection *to,
gpointer userdata) {
- const char *from_username = from->account->username;
- const char *to_username = to->account->username;
+ const char *from_username = purple_account_get_username(purple_connection_get_account(from));
+ const char *to_username = purple_account_get_username(purple_connection_get_account(to));
- if (purple_find_buddy(from->account, to_username)) {
- PurpleStatus *status = purple_account_get_active_status(to->account);
+ if (purple_find_buddy(purple_connection_get_account(from), to_username)) {
+ PurpleStatus *status = purple_account_get_active_status(purple_connection_get_account(to));
const char *status_id = purple_status_get_id(status);
const char *message = purple_status_get_attr_string(status, "message");
@@ -173,7 +173,7 @@ static void discover_status(PurpleConnection *from, PurpleConnection *to,
!strcmp(status_id, NULL_STATUS_OFFLINE)) {
purple_debug_info("nullprpl", "%s sees that %s is %s: %s\n",
from_username, to_username, status_id, message);
- purple_prpl_got_user_status(from->account, to_username, status_id,
+ purple_prpl_got_user_status(purple_connection_get_account(from), to_username, status_id,
(message) ? "message" : NULL, message, NULL);
} else {
purple_debug_error("nullprpl",
@@ -186,7 +186,7 @@ static void discover_status(PurpleConnection *from, PurpleConnection *to,
static void report_status_change(PurpleConnection *from, PurpleConnection *to,
gpointer userdata) {
purple_debug_info("nullprpl", "notifying %s that %s changed status\n",
- to->account->username, from->account->username);
+ purple_account_get_username(purple_connection_get_account(to)), purple_account_get_username(purple_connection_get_account(from)));
discover_status(to, from, NULL);
}
@@ -199,7 +199,7 @@ static void nullprpl_input_user_info(PurplePluginAction *action)
PurpleConnection *gc = (PurpleConnection *)action->context;
PurpleAccount *acct = purple_connection_get_account(gc);
purple_debug_info("nullprpl", "showing 'Set User Info' dialog for %s\n",
- acct->username);
+ purple_account_get_username(acct));
purple_account_request_change_user_info(acct);
}
@@ -225,7 +225,7 @@ static const char *nullprpl_list_icon(PurpleAccount *acct, PurpleBuddy *buddy)
static char *nullprpl_status_text(PurpleBuddy *buddy) {
purple_debug_info("nullprpl", "getting %s's status text for %s\n",
- buddy->name, buddy->account->username);
+ buddy->name, purple_account_get_username(buddy->account));
if (purple_find_buddy(buddy->account, buddy->name)) {
PurplePresence *presence = purple_buddy_get_presence(buddy);
@@ -234,7 +234,7 @@ static char *nullprpl_status_text(PurpleBuddy *buddy) {
const char *message = purple_status_get_attr_string(status, "message");
char *text;
- if (message && strlen(message) > 0)
+ if (message && *message)
text = g_strdup_printf("%s: %s", name, message);
else
text = g_strdup(name);
@@ -258,19 +258,23 @@ static void nullprpl_tooltip_text(PurpleBuddy *buddy,
PurplePresence *presence = purple_buddy_get_presence(buddy);
PurpleStatus *status = purple_presence_get_active_status(presence);
char *msg = nullprpl_status_text(buddy);
- purple_notify_user_info_add_pair(info, purple_status_get_name(status),
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(info, purple_status_get_name(status),
msg);
g_free(msg);
if (full) {
- const char *user_info = purple_account_get_user_info(gc->account);
+ const char *user_info = purple_account_get_user_info(purple_connection_get_account(gc));
if (user_info)
- purple_notify_user_info_add_pair(info, _("User info"), user_info);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(info, _("User info"), user_info);
}
} else {
/* they're not logged in */
- purple_notify_user_info_add_pair(info, _("User info"), _("not logged in"));
+ purple_notify_user_info_add_pair_plaintext(info, _("User info"), _("not logged in"));
}
purple_debug_info("nullprpl", "showing %s tooltip for %s\n",
@@ -283,7 +287,7 @@ static GList *nullprpl_status_types(PurpleAccount *acct)
PurpleStatusType *type;
purple_debug_info("nullprpl", "returning status types for %s: %s, %s, %s\n",
- acct->username,
+ purple_account_get_username(acct),
NULL_STATUS_ONLINE, NULL_STATUS_AWAY, NULL_STATUS_OFFLINE);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
@@ -362,7 +366,7 @@ static void nullprpl_login(PurpleAccount *acct)
PurpleConnection *gc = purple_account_get_connection(acct);
GList *offline_messages;
- purple_debug_info("nullprpl", "logging in %s\n", acct->username);
+ purple_debug_info("nullprpl", "logging in %s\n", purple_account_get_username(acct));
purple_connection_update_progress(gc, _("Connecting"),
0, /* which connection step this is */
@@ -381,12 +385,12 @@ static void nullprpl_login(PurpleAccount *acct)
/* fetch stored offline messages */
purple_debug_info("nullprpl", "checking for offline messages for %s\n",
- acct->username);
- offline_messages = g_hash_table_lookup(goffline_messages, acct->username);
+ purple_account_get_username(acct));
+ offline_messages = g_hash_table_lookup(goffline_messages, purple_account_get_username(acct));
while (offline_messages) {
GOfflineMessage *message = (GOfflineMessage *)offline_messages->data;
purple_debug_info("nullprpl", "delivering offline message to %s: %s\n",
- acct->username, message->message);
+ purple_account_get_username(acct), message->message);
serv_got_im(gc, message->from, message->message, message->flags,
message->mtime);
offline_messages = g_list_next(offline_messages);
@@ -397,7 +401,7 @@ static void nullprpl_login(PurpleAccount *acct)
}
g_list_free(offline_messages);
- g_hash_table_remove(goffline_messages, &acct->username);
+ g_hash_table_remove(goffline_messages, purple_account_get_username(acct));
}
static void nullprpl_close(PurpleConnection *gc)
@@ -409,7 +413,7 @@ static void nullprpl_close(PurpleConnection *gc)
static int nullprpl_send_im(PurpleConnection *gc, const char *who,
const char *message, PurpleMessageFlags flags)
{
- const char *from_username = gc->account->username;
+ const char *from_username = purple_account_get_username(purple_connection_get_account(gc));
PurpleMessageFlags receive_flags = ((flags & ~PURPLE_MESSAGE_SEND)
| PURPLE_MESSAGE_RECV);
PurpleAccount *to_acct = purple_accounts_find(who, NULLPRPL_ID);
@@ -419,13 +423,13 @@ static int nullprpl_send_im(PurpleConnection *gc, const char *who,
from_username, who, message);
/* is the sender blocked by the recipient's privacy settings? */
- if (to_acct && !purple_privacy_check(to_acct, gc->account->username)) {
+ if (to_acct && !purple_privacy_check(to_acct, purple_account_get_username(purple_connection_get_account(gc)))) {
char *msg = g_strdup_printf(
_("Your message was blocked by %s's privacy settings."), who);
purple_debug_info("nullprpl",
"discarding; %s is blocked by %s's privacy settings\n",
from_username, who);
- purple_conv_present_error(who, gc->account, msg);
+ purple_conv_present_error(who, purple_connection_get_account(gc), msg);
g_free(msg);
return 0;
}
@@ -457,7 +461,7 @@ static int nullprpl_send_im(PurpleConnection *gc, const char *who,
static void nullprpl_set_info(PurpleConnection *gc, const char *info) {
purple_debug_info("nullprpl", "setting %s's user info to %s\n",
- gc->account->username, info);
+ purple_account_get_username(purple_connection_get_account(gc)), info);
}
static const char *typing_state_to_string(PurpleTypingState typing) {
@@ -471,10 +475,10 @@ static const char *typing_state_to_string(PurpleTypingState typing) {
static void notify_typing(PurpleConnection *from, PurpleConnection *to,
gpointer typing) {
- const char *from_username = from->account->username;
+ const char *from_username = purple_account_get_username(purple_connection_get_account(from));
const char *action = typing_state_to_string((PurpleTypingState)typing);
purple_debug_info("nullprpl", "notifying %s that %s %s\n",
- to->account->username, from_username, action);
+ purple_account_get_username(purple_connection_get_account(to)), from_username, action);
serv_got_typing(to,
from_username,
@@ -485,7 +489,7 @@ static void notify_typing(PurpleConnection *from, PurpleConnection *to,
static unsigned int nullprpl_send_typing(PurpleConnection *gc, const char *name,
PurpleTypingState typing) {
- purple_debug_info("nullprpl", "%s %s\n", gc->account->username,
+ purple_debug_info("nullprpl", "%s %s\n", purple_account_get_username(purple_connection_get_account(gc)),
typing_state_to_string(typing));
foreach_nullprpl_gc(notify_typing, gc, (gpointer)typing);
return 0;
@@ -497,7 +501,7 @@ static void nullprpl_get_info(PurpleConnection *gc, const char *username) {
PurpleAccount *acct;
purple_debug_info("nullprpl", "Fetching %s's user info for %s\n", username,
- gc->account->username);
+ purple_account_get_username(purple_connection_get_account(gc)));
if (!get_nullprpl_gc(username)) {
char *msg = g_strdup_printf(_("%s is not logged in."), username);
@@ -510,7 +514,9 @@ static void nullprpl_get_info(PurpleConnection *gc, const char *username) {
body = purple_account_get_user_info(acct);
else
body = _("No user info.");
- purple_notify_user_info_add_pair(info, "Info", body);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(info, "Info", body);
/* show a buddy's user info in a nice dialog box */
purple_notify_userinfo(gc, /* connection the buddy info came through */
@@ -523,35 +529,35 @@ static void nullprpl_get_info(PurpleConnection *gc, const char *username) {
static void nullprpl_set_status(PurpleAccount *acct, PurpleStatus *status) {
const char *msg = purple_status_get_attr_string(status, "message");
purple_debug_info("nullprpl", "setting %s's status to %s: %s\n",
- acct->username, purple_status_get_name(status), msg);
+ purple_account_get_username(acct), purple_status_get_name(status), msg);
- foreach_nullprpl_gc(report_status_change, get_nullprpl_gc(acct->username),
+ foreach_nullprpl_gc(report_status_change, get_nullprpl_gc(purple_account_get_username(acct)),
NULL);
}
static void nullprpl_set_idle(PurpleConnection *gc, int idletime) {
purple_debug_info("nullprpl",
"purple reports that %s has been idle for %d seconds\n",
- gc->account->username, idletime);
+ purple_account_get_username(purple_connection_get_account(gc)), idletime);
}
static void nullprpl_change_passwd(PurpleConnection *gc, const char *old_pass,
const char *new_pass) {
purple_debug_info("nullprpl", "%s wants to change their password\n",
- gc->account->username);
+ purple_account_get_username(purple_connection_get_account(gc)));
}
static void nullprpl_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
- PurpleGroup *group)
+ PurpleGroup *group, const char *message)
{
- const char *username = gc->account->username;
+ const char *username = purple_account_get_username(purple_connection_get_account(gc));
PurpleConnection *buddy_gc = get_nullprpl_gc(buddy->name);
purple_debug_info("nullprpl", "adding %s to %s's buddy list\n", buddy->name,
username);
if (buddy_gc) {
- PurpleAccount *buddy_acct = buddy_gc->account;
+ PurpleAccount *buddy_acct = purple_connection_get_account(buddy_gc);
discover_status(gc, buddy_gc, NULL);
@@ -565,20 +571,20 @@ static void nullprpl_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
username,
NULL, /* local account id (rarely used) */
NULL, /* alias */
- NULL); /* message */
+ message); /* message */
}
}
}
static void nullprpl_add_buddies(PurpleConnection *gc, GList *buddies,
- GList *groups) {
+ GList *groups, const char *message) {
GList *buddy = buddies;
GList *group = groups;
purple_debug_info("nullprpl", "adding multiple buddies\n");
while (buddy && group) {
- nullprpl_add_buddy(gc, (PurpleBuddy *)buddy->data, (PurpleGroup *)group->data);
+ nullprpl_add_buddy(gc, (PurpleBuddy *)buddy->data, (PurpleGroup *)group->data, message);
buddy = g_list_next(buddy);
group = g_list_next(group);
}
@@ -588,7 +594,7 @@ static void nullprpl_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
PurpleGroup *group)
{
purple_debug_info("nullprpl", "removing %s from %s's buddy list\n",
- buddy->name, gc->account->username);
+ buddy->name, purple_account_get_username(purple_connection_get_account(gc)));
}
static void nullprpl_remove_buddies(PurpleConnection *gc, GList *buddies,
@@ -614,22 +620,22 @@ static void nullprpl_remove_buddies(PurpleConnection *gc, GList *buddies,
*/
static void nullprpl_add_permit(PurpleConnection *gc, const char *name) {
purple_debug_info("nullprpl", "%s adds %s to their allowed list\n",
- gc->account->username, name);
+ purple_account_get_username(purple_connection_get_account(gc)), name);
}
static void nullprpl_add_deny(PurpleConnection *gc, const char *name) {
purple_debug_info("nullprpl", "%s adds %s to their blocked list\n",
- gc->account->username, name);
+ purple_account_get_username(purple_connection_get_account(gc)), name);
}
static void nullprpl_rem_permit(PurpleConnection *gc, const char *name) {
purple_debug_info("nullprpl", "%s removes %s from their allowed list\n",
- gc->account->username, name);
+ purple_account_get_username(purple_connection_get_account(gc)), name);
}
static void nullprpl_rem_deny(PurpleConnection *gc, const char *name) {
purple_debug_info("nullprpl", "%s removes %s from their blocked list\n",
- gc->account->username, name);
+ purple_account_get_username(purple_connection_get_account(gc)), name);
}
static void nullprpl_set_permit_deny(PurpleConnection *gc) {
@@ -642,9 +648,9 @@ static void joined_chat(PurpleConvChat *from, PurpleConvChat *to,
int id, const char *room, gpointer userdata) {
/* tell their chat window that we joined */
purple_debug_info("nullprpl", "%s sees that %s joined chat room %s\n",
- to->nick, from->nick, room);
+ purple_conv_chat_get_nick(to), purple_conv_chat_get_nick(from), room);
purple_conv_chat_add_user(to,
- from->nick,
+ purple_conv_chat_get_nick(from),
NULL, /* user-provided join message, IRC style */
PURPLE_CBFLAGS_NONE,
TRUE); /* show a join message */
@@ -652,9 +658,9 @@ static void joined_chat(PurpleConvChat *from, PurpleConvChat *to,
if (from != to) {
/* add them to our chat window */
purple_debug_info("nullprpl", "%s sees that %s is in chat room %s\n",
- from->nick, to->nick, room);
+ purple_conv_chat_get_nick(from), purple_conv_chat_get_nick(to), room);
purple_conv_chat_add_user(from,
- to->nick,
+ purple_conv_chat_get_nick(to),
NULL, /* user-provided join message, IRC style */
PURPLE_CBFLAGS_NONE,
FALSE); /* show a join message */
@@ -662,7 +668,7 @@ static void joined_chat(PurpleConvChat *from, PurpleConvChat *to,
}
static void nullprpl_join_chat(PurpleConnection *gc, GHashTable *components) {
- const char *username = gc->account->username;
+ const char *username = purple_account_get_username(purple_connection_get_account(gc));
const char *room = g_hash_table_lookup(components, "room");
int chat_id = g_str_hash(room);
purple_debug_info("nullprpl", "%s is joining chat room %s\n", username, room);
@@ -686,7 +692,7 @@ static void nullprpl_join_chat(PurpleConnection *gc, GHashTable *components) {
static void nullprpl_reject_chat(PurpleConnection *gc, GHashTable *components) {
const char *invited_by = g_hash_table_lookup(components, "invited_by");
const char *room = g_hash_table_lookup(components, "room");
- const char *username = gc->account->username;
+ const char *username = purple_account_get_username(purple_connection_get_account(gc));
PurpleConnection *invited_by_gc = get_nullprpl_gc(invited_by);
char *message = g_strdup_printf(
"%s %s %s.",
@@ -713,9 +719,9 @@ static char *nullprpl_get_chat_name(GHashTable *components) {
static void nullprpl_chat_invite(PurpleConnection *gc, int id,
const char *message, const char *who) {
- const char *username = gc->account->username;
+ const char *username = purple_account_get_username(purple_connection_get_account(gc));
PurpleConversation *conv = purple_find_chat(gc, id);
- const char *room = conv->name;
+ const char *room = purple_conversation_get_name(conv);
PurpleAccount *to_acct = purple_accounts_find(who, NULLPRPL_ID);
purple_debug_info("nullprpl", "%s is inviting %s to join chat room %s\n",
@@ -746,9 +752,9 @@ static void left_chat_room(PurpleConvChat *from, PurpleConvChat *to,
if (from != to) {
/* tell their chat window that we left */
purple_debug_info("nullprpl", "%s sees that %s left chat room %s\n",
- to->nick, from->nick, room);
+ purple_conv_chat_get_nick(to), purple_conv_chat_get_nick(from), room);
purple_conv_chat_remove_user(to,
- from->nick,
+ purple_conv_chat_get_nick(from),
NULL); /* user-provided message, IRC style */
}
}
@@ -756,7 +762,7 @@ static void left_chat_room(PurpleConvChat *from, PurpleConvChat *to,
static void nullprpl_chat_leave(PurpleConnection *gc, int id) {
PurpleConversation *conv = purple_find_chat(gc, id);
purple_debug_info("nullprpl", "%s is leaving chat room %s\n",
- gc->account->username, conv->name);
+ purple_account_get_username(purple_connection_get_account(gc)), purple_conversation_get_name(conv));
/* tell everyone that we left */
foreach_gc_in_chat(left_chat_room, gc, id, NULL);
@@ -775,17 +781,17 @@ static PurpleCmdRet send_whisper(PurpleConversation *conv, const gchar *cmd,
to_username = args[0];
message = args[1];
- if (!to_username || strlen(to_username) == 0) {
+ if (!to_username || !*to_username) {
*error = g_strdup(_("Whisper is missing recipient."));
return PURPLE_CMD_RET_FAILED;
- } else if (!message || strlen(message) == 0) {
+ } else if (!message || !*message) {
*error = g_strdup(_("Whisper is missing message."));
return PURPLE_CMD_RET_FAILED;
}
- from_username = conv->account->username;
+ from_username = purple_account_get_username(purple_conversation_get_account(conv));
purple_debug_info("nullprpl", "%s whispers to %s in chat room %s: %s\n",
- from_username, to_username, conv->name, message);
+ from_username, to_username, purple_conversation_get_name(conv), message);
chat = purple_conversation_get_chat_data(conv);
chat_buddy = purple_conv_chat_cb_find(chat, to_username);
@@ -807,7 +813,7 @@ static PurpleCmdRet send_whisper(PurpleConversation *conv, const gchar *cmd,
g_free(message_to);
/* send the whisper */
- serv_chat_whisper(to, chat->id, from_username, message);
+ serv_chat_whisper(to, purple_conv_chat_get_id(chat), from_username, message);
return PURPLE_CMD_RET_OK;
}
@@ -815,11 +821,11 @@ static PurpleCmdRet send_whisper(PurpleConversation *conv, const gchar *cmd,
static void nullprpl_chat_whisper(PurpleConnection *gc, int id, const char *who,
const char *message) {
- const char *username = gc->account->username;
+ const char *username = purple_account_get_username(purple_connection_get_account(gc));
PurpleConversation *conv = purple_find_chat(gc, id);
purple_debug_info("nullprpl",
"%s receives whisper from %s in chat room %s: %s\n",
- username, who, conv->name, message);
+ username, who, purple_conversation_get_name(conv), message);
/* receive whisper on recipient's account */
serv_got_chat_in(gc, id, who, PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_WHISPER,
@@ -829,24 +835,24 @@ static void nullprpl_chat_whisper(PurpleConnection *gc, int id, const char *who,
static void receive_chat_message(PurpleConvChat *from, PurpleConvChat *to,
int id, const char *room, gpointer userdata) {
const char *message = (const char *)userdata;
- PurpleConnection *to_gc = get_nullprpl_gc(to->nick);
+ PurpleConnection *to_gc = get_nullprpl_gc(purple_conv_chat_get_nick(to));
purple_debug_info("nullprpl",
"%s receives message from %s in chat room %s: %s\n",
- to->nick, from->nick, room, message);
- serv_got_chat_in(to_gc, id, from->nick, PURPLE_MESSAGE_RECV, message,
+ purple_conv_chat_get_nick(to), purple_conv_chat_get_nick(from), room, message);
+ serv_got_chat_in(to_gc, id, purple_conv_chat_get_nick(from), PURPLE_MESSAGE_RECV, message,
time(NULL));
}
static int nullprpl_chat_send(PurpleConnection *gc, int id, const char *message,
PurpleMessageFlags flags) {
- const char *username = gc->account->username;
+ const char *username = purple_account_get_username(purple_connection_get_account(gc));
PurpleConversation *conv = purple_find_chat(gc, id);
if (conv) {
purple_debug_info("nullprpl",
"%s is sending message to chat room %s: %s\n", username,
- conv->name, message);
+ purple_conversation_get_name(conv), message);
/* send message to everyone in the chat room */
foreach_gc_in_chat(receive_chat_message, gc, id, (gpointer)message);
@@ -862,14 +868,14 @@ static int nullprpl_chat_send(PurpleConnection *gc, int id, const char *message,
static void nullprpl_register_user(PurpleAccount *acct) {
purple_debug_info("nullprpl", "registering account for %s\n",
- acct->username);
+ purple_account_get_username(acct));
}
static void nullprpl_get_cb_info(PurpleConnection *gc, int id, const char *who) {
PurpleConversation *conv = purple_find_chat(gc, id);
purple_debug_info("nullprpl",
"retrieving %s's info for %s in chat room %s\n", who,
- gc->account->username, conv->name);
+ purple_account_get_username(purple_connection_get_account(gc)), purple_conversation_get_name(conv));
nullprpl_get_info(gc, who);
}
@@ -877,25 +883,25 @@ static void nullprpl_get_cb_info(PurpleConnection *gc, int id, const char *who)
static void nullprpl_alias_buddy(PurpleConnection *gc, const char *who,
const char *alias) {
purple_debug_info("nullprpl", "%s sets %s's alias to %s\n",
- gc->account->username, who, alias);
+ purple_account_get_username(purple_connection_get_account(gc)), who, alias);
}
static void nullprpl_group_buddy(PurpleConnection *gc, const char *who,
const char *old_group,
const char *new_group) {
purple_debug_info("nullprpl", "%s has moved %s from group %s to group %s\n",
- gc->account->username, who, old_group, new_group);
+ purple_account_get_username(purple_connection_get_account(gc)), who, old_group, new_group);
}
static void nullprpl_rename_group(PurpleConnection *gc, const char *old_name,
PurpleGroup *group, GList *moved_buddies) {
purple_debug_info("nullprpl", "%s has renamed group %s to %s\n",
- gc->account->username, old_name, group->name);
+ purple_account_get_username(purple_connection_get_account(gc)), old_name, group->name);
}
static void nullprpl_convo_closed(PurpleConnection *gc, const char *who) {
purple_debug_info("nullprpl", "%s's conversation with %s was closed\n",
- gc->account->username, who);
+ purple_account_get_username(purple_connection_get_account(gc)), who);
}
/* normalize a username (e.g. remove whitespace, add default domain, etc.)
@@ -909,25 +915,25 @@ static const char *nullprpl_normalize(const PurpleAccount *acct,
static void nullprpl_set_buddy_icon(PurpleConnection *gc,
PurpleStoredImage *img) {
purple_debug_info("nullprpl", "setting %s's buddy icon to %s\n",
- gc->account->username,
+ purple_account_get_username(purple_connection_get_account(gc)),
img ? purple_imgstore_get_filename(img) : "(null)");
}
static void nullprpl_remove_group(PurpleConnection *gc, PurpleGroup *group) {
purple_debug_info("nullprpl", "%s has removed group %s\n",
- gc->account->username, group->name);
+ purple_account_get_username(purple_connection_get_account(gc)), group->name);
}
static void set_chat_topic_fn(PurpleConvChat *from, PurpleConvChat *to,
int id, const char *room, gpointer userdata) {
const char *topic = (const char *)userdata;
- const char *username = from->conv->account->username;
+ const char *username = purple_account_get_username(purple_conversation_get_account(purple_conv_chat_get_conversation(from)));
char *msg;
purple_conv_chat_set_topic(to, username, topic);
- if (topic && strlen(topic) > 0)
+ if (topic && *topic)
msg = g_strdup_printf(_("%s sets topic to: %s"), username, topic);
else
msg = g_strdup_printf(_("%s clears topic"), username);
@@ -948,7 +954,7 @@ static void nullprpl_set_chat_topic(PurpleConnection *gc, int id,
return;
purple_debug_info("nullprpl", "%s sets topic of chat room '%s' to '%s'\n",
- gc->account->username, conv->name, topic);
+ purple_account_get_username(purple_connection_get_account(gc)), purple_conversation_get_name(conv), topic);
last_topic = purple_conv_chat_get_topic(chat);
if ((!topic && !last_topic) ||
@@ -964,8 +970,8 @@ static gboolean nullprpl_finish_get_roomlist(gpointer roomlist) {
}
static PurpleRoomlist *nullprpl_roomlist_get_list(PurpleConnection *gc) {
- const char *username = gc->account->username;
- PurpleRoomlist *roomlist = purple_roomlist_new(gc->account);
+ const char *username = purple_account_get_username(purple_connection_get_account(gc));
+ PurpleRoomlist *roomlist = purple_roomlist_new(purple_connection_get_account(gc));
GList *fields = NULL;
PurpleRoomlistField *field;
GList *chats;
@@ -988,8 +994,8 @@ static PurpleRoomlist *nullprpl_roomlist_get_list(PurpleConnection *gc) {
for (chats = purple_get_chats(); chats; chats = g_list_next(chats)) {
PurpleConversation *conv = (PurpleConversation *)chats->data;
PurpleRoomlistRoom *room;
- const char *name = conv->name;
- int id = purple_conversation_get_chat_data(conv)->id;
+ const char *name = purple_conversation_get_name(conv);
+ int id = purple_conv_chat_get_id(purple_conversation_get_chat_data(conv));
/* have we already added this room? */
if (g_list_find_custom(seen_ids, name, (GCompareFunc)strcmp))
@@ -1013,14 +1019,17 @@ static PurpleRoomlist *nullprpl_roomlist_get_list(PurpleConnection *gc) {
}
static void nullprpl_roomlist_cancel(PurpleRoomlist *list) {
+ PurpleAccount *account = purple_roomlist_get_account(list);
purple_debug_info("nullprpl", "%s asked to cancel room list request\n",
- list->account->username);
+ purple_account_get_username(account));
}
static void nullprpl_roomlist_expand_category(PurpleRoomlist *list,
PurpleRoomlistRoom *category) {
+ PurpleAccount *account = purple_roomlist_get_account(list);
purple_debug_info("nullprpl", "%s asked to expand room list category %s\n",
- list->account->username, category->name);
+ purple_account_get_username(account),
+ purple_roomlist_room_get_name(category));
}
/* nullprpl doesn't support file transfer...yet... */
@@ -1043,6 +1052,7 @@ static gboolean nullprpl_offline_message(const PurpleBuddy *buddy) {
static PurplePluginProtocolInfo prpl_info =
{
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
OPT_PROTO_NO_PASSWORD | OPT_PROTO_CHAT_TOPIC, /* options */
NULL, /* user_splits, initialized in nullprpl_init() */
NULL, /* protocol_options, initialized in nullprpl_init() */
@@ -1091,7 +1101,6 @@ static PurplePluginProtocolInfo prpl_info =
NULL, /* keepalive */
nullprpl_register_user, /* register_user */
nullprpl_get_cb_info, /* get_cb_info */
- NULL, /* get_cb_away */
nullprpl_alias_buddy, /* alias_buddy */
nullprpl_group_buddy, /* group_buddy */
nullprpl_rename_group, /* rename_group */
@@ -1116,15 +1125,12 @@ static PurplePluginProtocolInfo prpl_info =
NULL, /* unregister_user */
NULL, /* send_attention */
NULL, /* get_attention_types */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
NULL, /* get_account_text_table */
NULL, /* initiate_media */
NULL, /* get_media_caps */
NULL, /* get_moods */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */
};
static void nullprpl_init(PurplePlugin *plugin)
diff --git a/libpurple/protocols/oscar/authorization.c b/libpurple/protocols/oscar/authorization.c
index 29b285d58c..fe45a511a4 100644
--- a/libpurple/protocols/oscar/authorization.c
+++ b/libpurple/protocols/oscar/authorization.c
@@ -49,7 +49,7 @@ oscar_auth_sendrequest(PurpleConnection *gc, const char *bname, const char *msg)
purple_debug_info("oscar", "ssi: adding buddy %s to group %s\n",
bname, gname);
aim_ssi_sendauthrequest(od, bname, msg ? msg : _("Please authorize me so I can add you to my buddy list."));
- if (!aim_ssi_itemlist_finditem(od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY))
+ if (!aim_ssi_itemlist_finditem(&od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY))
{
aim_ssi_addbuddy(od, bname, gname, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, TRUE);
diff --git a/libpurple/protocols/oscar/clientlogin.c b/libpurple/protocols/oscar/clientlogin.c
index a6e37fc2df..26ad4c67a8 100644
--- a/libpurple/protocols/oscar/clientlogin.c
+++ b/libpurple/protocols/oscar/clientlogin.c
@@ -182,7 +182,7 @@ static gboolean parse_start_oscar_session_response(PurpleConnection *gc, const g
/* Note to translators: %s in this string is a URL */
msg = generate_error_message(response_node,
get_start_oscar_session_url(od));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
g_free(msg);
return FALSE;
@@ -204,7 +204,7 @@ static gboolean parse_start_oscar_session_response(PurpleConnection *gc, const g
"missing statusCode: %s\n", response);
msg = generate_error_message(response_node,
get_start_oscar_session_url(od));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
g_free(msg);
xmlnode_free(response_node);
@@ -232,7 +232,7 @@ static gboolean parse_start_oscar_session_response(PurpleConnection *gc, const g
"was %s: %s\n", tmp, response);
if ((code == 401 && status_detail != 1014) || code == 607)
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("You have been connecting and disconnecting too "
"frequently. Wait ten minutes and try again. If "
@@ -242,7 +242,7 @@ static gboolean parse_start_oscar_session_response(PurpleConnection *gc, const g
char *msg;
msg = generate_error_message(response_node,
get_start_oscar_session_url(od));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_OTHER_ERROR, msg);
g_free(msg);
}
@@ -261,7 +261,7 @@ static gboolean parse_start_oscar_session_response(PurpleConnection *gc, const g
"something: %s\n", response);
msg = generate_error_message(response_node,
get_start_oscar_session_url(od));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
g_free(msg);
xmlnode_free(response_node);
@@ -277,7 +277,7 @@ static gboolean parse_start_oscar_session_response(PurpleConnection *gc, const g
purple_debug_warning("oscar", "We haven't received a tlsCertName to use. We will not do SSL to BOS.\n");
} else {
purple_debug_error("oscar", "startOSCARSession was missing tlsCertName: %s\n", response);
- purple_connection_error_reason(
+ purple_connection_error(
gc,
PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
_("You required encryption in your account settings, but one of the servers doesn't support it."));
@@ -299,7 +299,7 @@ static gboolean parse_start_oscar_session_response(PurpleConnection *gc, const g
"something: %s\n", response);
msg = generate_error_message(response_node,
get_start_oscar_session_url(od));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
g_free(msg);
g_free(*host);
@@ -337,7 +337,7 @@ static void start_oscar_session_cb(PurpleUtilFetchUrlData *url_data, gpointer us
tmp = g_strdup_printf(_("Error requesting %s: %s"),
get_start_oscar_session_url(od), error_message ?
error_message : _("The server returned an empty response"));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
@@ -384,7 +384,7 @@ static void send_start_oscar_session(OscarData *od, const char *token, const cha
g_free(signature);
/* Make the request */
- od->url_data = purple_util_fetch_url_request_len_with_account(account,
+ od->url_data = purple_util_fetch_url_request(account,
url, TRUE, NULL, FALSE, NULL, FALSE, -1,
start_oscar_session_cb, od);
g_free(url);
@@ -395,7 +395,7 @@ static void send_start_oscar_session(OscarData *od, const char *token, const cha
* and extracts the useful information.
*
* @param gc The PurpleConnection. If the response data does
- * not indicate then purple_connection_error_reason()
+ * not indicate then purple_connection_error()
* will be called to close this connection.
* @param response The response data from the clientLogin request.
* @param response_len The length of the above response, or -1 if
@@ -431,7 +431,7 @@ static gboolean parse_client_login_response(PurpleConnection *gc, const gchar *r
"response as XML: %s\n", response);
msg = generate_error_message(response_node,
get_client_login_url(od));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
g_free(msg);
return FALSE;
@@ -455,7 +455,7 @@ static gboolean parse_client_login_response(PurpleConnection *gc, const gchar *r
"missing statusCode: %s\n", response);
msg = generate_error_message(response_node,
get_client_login_url(od));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
g_free(msg);
xmlnode_free(response_node);
@@ -482,23 +482,23 @@ static gboolean parse_client_login_response(PurpleConnection *gc, const gchar *r
PurpleAccount *account = purple_connection_get_account(gc);
if (!purple_account_get_remember_password(account))
purple_account_set_password(account, NULL);
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
_("Incorrect password"));
} else if (status_code == 330 && status_detail_code == 3015) {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
_("Server requested that you fill out a CAPTCHA in order to "
"sign in, but this client does not currently support CAPTCHAs."));
} else if (status_code == 401 && status_detail_code == 3019) {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("AOL does not allow your screen name to authenticate here"));
} else {
char *msg;
msg = generate_error_message(response_node,
get_client_login_url(od));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_OTHER_ERROR, msg);
g_free(msg);
}
@@ -517,7 +517,7 @@ static gboolean parse_client_login_response(PurpleConnection *gc, const gchar *r
"something: %s\n", response);
msg = generate_error_message(response_node,
get_client_login_url(od));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
g_free(msg);
xmlnode_free(response_node);
@@ -535,7 +535,7 @@ static gboolean parse_client_login_response(PurpleConnection *gc, const gchar *r
"something: %s\n", response);
msg = generate_error_message(response_node,
get_client_login_url(od));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
g_free(msg);
g_free(*token);
@@ -572,7 +572,7 @@ static void client_login_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data
tmp = g_strdup_printf(_("Error requesting %s: %s"),
get_client_login_url(od), error_message ?
error_message : _("The server returned an empty response"));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
@@ -646,7 +646,7 @@ void send_client_login(OscarData *od, const char *username)
g_string_free(body, TRUE);
/* Send the POST request */
- od->url_data = purple_util_fetch_url_request_len_with_account(
+ od->url_data = purple_util_fetch_url_request(
purple_connection_get_account(gc), get_client_login_url(od),
TRUE, NULL, FALSE, request->str, FALSE, -1,
client_login_cb, od);
diff --git a/libpurple/protocols/oscar/family_auth.c b/libpurple/protocols/oscar/family_auth.c
index ac011df63d..eb7e7b9738 100644
--- a/libpurple/protocols/oscar/family_auth.c
+++ b/libpurple/protocols/oscar/family_auth.c
@@ -27,6 +27,7 @@
*/
#include "oscar.h"
+#include "oscarcommon.h"
#include <ctype.h>
@@ -506,14 +507,29 @@ aim_request_login(OscarData *od, FlapConnection *conn, const char *sn)
static int
keyparse(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
{
- int keylen, ret = 1;
- aim_rxcallback_t userfunc;
+ int keylen;
char *keystr;
GSList *tlvlist;
gboolean truncate_pass;
+ PurpleConnection *gc;
+ PurpleAccount *account;
+ ClientInfo aiminfo = CLIENTINFO_PURPLE_AIM;
+ ClientInfo icqinfo = CLIENTINFO_PURPLE_ICQ;
+
+ gc = od->gc;
+ account = purple_connection_get_account(gc);
keylen = byte_stream_get16(bs);
keystr = byte_stream_getstr(bs, keylen);
+ if (!g_utf8_validate(keystr, -1, NULL)) {
+ purple_debug_warning("oscar", "Received SNAC %04hx/%04hx with "
+ "invalid UTF-8 keystr.\n", snac->family, snac->subtype);
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ _("Received unexpected response from server"));
+ g_free(keystr);
+ return 1;
+ }
+
tlvlist = aim_tlvlist_read(bs);
/*
@@ -527,13 +543,18 @@ keyparse(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *fram
* for the netscape network. This SNAC had a type 0x0058 TLV with length 10.
* Data is 0x0007 0004 3e19 ae1e 0006 0004 0000 0005 */
- if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
- ret = userfunc(od, conn, frame, keystr, (int)truncate_pass);
+ aim_send_login(od, conn, purple_account_get_username(account),
+ purple_connection_get_password(gc), truncate_pass,
+ od->icq ? &icqinfo : &aiminfo, keystr,
+ purple_account_get_bool(account, "allow_multiple_logins", OSCAR_DEFAULT_ALLOW_MULTIPLE_LOGINS));
+
+ purple_connection_update_progress(gc,
+ _("Password sent"), 2, OSCAR_CONNECT_STEPS);
g_free(keystr);
aim_tlvlist_free(tlvlist);
- return ret;
+ return 1;
}
/**
diff --git a/libpurple/protocols/oscar/family_bart.c b/libpurple/protocols/oscar/family_bart.c
index cd7ca43839..cc5f1f2033 100644
--- a/libpurple/protocols/oscar/family_bart.c
+++ b/libpurple/protocols/oscar/family_bart.c
@@ -143,6 +143,12 @@ parseicon(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *fra
guint8 iconcsumtype, iconcsumlen, *iconcsum, *icon;
bn = byte_stream_getstr(bs, byte_stream_get8(bs));
+ if (!g_utf8_validate(bn, -1, NULL)) {
+ purple_debug_warning("oscar", "Received SNAC %04hx/%04hx with "
+ "invalid UTF-8 buddy name.\n", snac->family, snac->subtype);
+ g_free(bn);
+ return 1;
+ }
flags = byte_stream_get16(bs);
iconcsumtype = byte_stream_get8(bs);
iconcsumlen = byte_stream_get8(bs);
diff --git a/libpurple/protocols/oscar/family_feedbag.c b/libpurple/protocols/oscar/family_feedbag.c
index 8d8f614be2..c1ef2c32f3 100644
--- a/libpurple/protocols/oscar/family_feedbag.c
+++ b/libpurple/protocols/oscar/family_feedbag.c
@@ -21,9 +21,9 @@
/*
* Family 0x0013 - Server-Side/Stored Information.
*
- * Relatively new facility that allows certain types of information, such as
- * a user's buddy list, permit/deny list, and permit/deny preferences, to be
- * stored on the server, so that they can be accessed from any client.
+ * Deals with storing certain types of information, such as a user's buddy
+ * list, permit/deny list, and permit/deny preferences, on the server, so
+ * that they can be accessed from any client.
*
* We keep 2 copies of SSI data:
* 1) An exact copy of what is stored on the AIM servers.
@@ -40,14 +40,41 @@
*
* This is entirely too complicated.
* You don't know the half of it.
- *
*/
#include "oscar.h"
+#include "oscarcommon.h"
#include "debug.h"
static int aim_ssi_addmoddel(OscarData *od);
+static void aim_ssi_item_free(struct aim_ssi_item *item)
+{
+ g_free(item->name);
+ aim_tlvlist_free(item->data);
+ g_free(item);
+}
+
+static void aim_ssi_item_set_name(struct aim_ssi_itemlist *list, struct aim_ssi_item *item, const char *name)
+{
+ gchar key[3000];
+
+ if (item->name) {
+ /* Remove old name from hash table */
+ snprintf(key, sizeof(key), "%hx%s", item->type, oscar_normalize(NULL, item->name));
+ g_hash_table_remove(list->idx_all_named_items, key);
+ }
+
+ g_free(item->name);
+ item->name = g_strdup(name);
+
+ if (name) {
+ /* Add new name to hash table */
+ snprintf(key, sizeof(key), "%hx%s", item->type, oscar_normalize(NULL, item->name));
+ g_hash_table_insert(list->idx_all_named_items, g_strdup(key), item);
+ }
+}
+
/**
* List types based on http://dev.aol.com/aim/oscar/#FEEDBAG (archive.org)
* and http://iserverd.khstu.ru/oscar/ssi_item.html
@@ -113,7 +140,7 @@ aim_ssi_item_debug_append(GString *str, char *prefix, struct aim_ssi_item *item)
* @return Return a pointer to the modified item.
*/
static void
-aim_ssi_itemlist_rebuildgroup(struct aim_ssi_item *list, const char *name)
+aim_ssi_itemlist_rebuildgroup(struct aim_ssi_itemlist *list, const char *name)
{
int newlen;
struct aim_ssi_item *cur, *group;
@@ -125,11 +152,11 @@ aim_ssi_itemlist_rebuildgroup(struct aim_ssi_item *list, const char *name)
/* Find the length for the new additional data */
newlen = 0;
if (group->gid == 0x0000) {
- for (cur=list; cur; cur=cur->next)
+ for (cur=list->data; cur; cur=cur->next)
if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid != 0x0000))
newlen += 2;
} else {
- for (cur=list; cur; cur=cur->next)
+ for (cur=list->data; cur; cur=cur->next)
if ((cur->gid == group->gid) && (cur->type == AIM_SSI_TYPE_BUDDY))
newlen += 2;
}
@@ -138,14 +165,14 @@ aim_ssi_itemlist_rebuildgroup(struct aim_ssi_item *list, const char *name)
if (newlen > 0) {
guint8 *newdata;
- newdata = (guint8 *)g_malloc((newlen)*sizeof(guint8));
+ newdata = g_new(guint8, newlen);
newlen = 0;
if (group->gid == 0x0000) {
- for (cur=list; cur; cur=cur->next)
+ for (cur=list->data; cur; cur=cur->next)
if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid != 0x0000))
newlen += aimutil_put16(newdata+newlen, cur->gid);
} else {
- for (cur=list; cur; cur=cur->next)
+ for (cur=list->data; cur; cur=cur->next)
if ((cur->gid == group->gid) && (cur->type == AIM_SSI_TYPE_BUDDY))
newlen += aimutil_put16(newdata+newlen, cur->bid);
}
@@ -167,15 +194,12 @@ aim_ssi_itemlist_rebuildgroup(struct aim_ssi_item *list, const char *name)
* @param data The additional data for the new item.
* @return A pointer to the newly created item.
*/
-static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_item **list, const char *name, guint16 gid, guint16 bid, guint16 type, GSList *data)
+static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_itemlist *list, const char *name, guint16 gid, guint16 bid, guint16 type, GSList *data)
{
gboolean exists;
struct aim_ssi_item *cur, *new;
- new = g_new(struct aim_ssi_item, 1);
-
- /* Set the name */
- new->name = g_strdup(name);
+ new = g_new0(struct aim_ssi_item, 1);
/* Set the group ID# and buddy ID# */
new->gid = gid;
@@ -185,7 +209,7 @@ static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_item **list, con
do {
new->gid += 0x0001;
exists = FALSE;
- for (cur = *list; cur != NULL; cur = cur->next)
+ for (cur = list->data; cur != NULL; cur = cur->next)
if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid == new->gid)) {
exists = TRUE;
break;
@@ -202,7 +226,7 @@ static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_item **list, con
do {
new->bid += 0x0001;
exists = FALSE;
- for (cur = *list; cur != NULL; cur = cur->next)
+ for (cur = list->data; cur != NULL; cur = cur->next)
if (cur->bid == new->bid || cur->gid == new->bid) {
exists = TRUE;
break;
@@ -214,7 +238,7 @@ static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_item **list, con
do {
new->bid += 0x0001;
exists = FALSE;
- for (cur = *list; cur != NULL; cur = cur->next)
+ for (cur = list->data; cur != NULL; cur = cur->next)
if (cur->bid == new->bid && cur->gid == new->gid) {
exists = TRUE;
break;
@@ -226,23 +250,29 @@ static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_item **list, con
/* Set the type */
new->type = type;
+ /* Add it to the gid+bid hashtable */
+ g_hash_table_insert(list->idx_gid_bid, GINT_TO_POINTER((new->gid << 16) + new->bid), new);
+
+ /* Set the name - do this *AFTER* setting the type because type is used for the key */
+ aim_ssi_item_set_name(list, new, name);
+
/* Set the TLV list */
new->data = aim_tlvlist_copy(data);
/* Add the item to the list in the correct numerical position. Fancy, eh? */
- if (*list) {
- if ((new->gid < (*list)->gid) || ((new->gid == (*list)->gid) && (new->bid < (*list)->bid))) {
- new->next = *list;
- *list = new;
+ if (list->data) {
+ if ((new->gid < list->data->gid) || ((new->gid == list->data->gid) && (new->bid < list->data->bid))) {
+ new->next = list->data;
+ list->data = new;
} else {
struct aim_ssi_item *prev;
- for ((prev=*list, cur=(*list)->next); (cur && ((new->gid > cur->gid) || ((new->gid == cur->gid) && (new->bid > cur->bid)))); prev=cur, cur=cur->next);
+ for ((prev=list->data, cur=list->data->next); (cur && ((new->gid > cur->gid) || ((new->gid == cur->gid) && (new->bid > cur->bid)))); prev=cur, cur=cur->next);
new->next = prev->next;
prev->next = new;
}
} else {
- new->next = *list;
- *list = new;
+ new->next = list->data;
+ list->data = new;
}
return new;
@@ -255,25 +285,31 @@ static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_item **list, con
* @param del A pointer to the item you want to remove from the list.
* @return Return 0 if no errors, otherwise return the error number.
*/
-static int aim_ssi_itemlist_del(struct aim_ssi_item **list, struct aim_ssi_item *del)
+static int aim_ssi_itemlist_del(struct aim_ssi_itemlist *list, struct aim_ssi_item *del)
{
- if (!(*list) || !del)
+ gchar key[3000];
+
+ if (!(list->data) || !del)
return -EINVAL;
/* Remove the item from the list */
- if (*list == del) {
- *list = (*list)->next;
+ if (list->data == del) {
+ list->data = list->data->next;
} else {
struct aim_ssi_item *cur;
- for (cur=*list; (cur->next && (cur->next!=del)); cur=cur->next);
+ for (cur=list->data; (cur->next && (cur->next!=del)); cur=cur->next);
if (cur->next)
cur->next = del->next;
}
+ /* Remove from the hashtables */
+ g_hash_table_remove(list->idx_gid_bid, GINT_TO_POINTER((del->gid << 16) + del->bid));
+
+ snprintf(key, sizeof(key), "%hx%s", del->type, oscar_normalize(NULL, del->name));
+ g_hash_table_remove(list->idx_all_named_items, key);
+
/* Free the removed item */
- g_free(del->name);
- aim_tlvlist_free(del->data);
- g_free(del);
+ aim_ssi_item_free(del);
return 0;
}
@@ -320,10 +356,10 @@ static int aim_ssi_itemlist_cmp(struct aim_ssi_item *cur1, struct aim_ssi_item *
return 0;
}
-static gboolean aim_ssi_itemlist_valid(struct aim_ssi_item *list, struct aim_ssi_item *item)
+static gboolean aim_ssi_itemlist_valid(struct aim_ssi_itemlist *list, struct aim_ssi_item *item)
{
struct aim_ssi_item *cur;
- for (cur=list; cur; cur=cur->next)
+ for (cur=list->data; cur; cur=cur->next)
if (cur == item)
return TRUE;
return FALSE;
@@ -337,13 +373,10 @@ static gboolean aim_ssi_itemlist_valid(struct aim_ssi_item *list, struct aim_ssi
* @param bid The buddy ID# of the desired item.
* @return Return a pointer to the item if found, else return NULL;
*/
-struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_item *list, guint16 gid, guint16 bid)
+struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_itemlist *list, guint16 gid, guint16 bid)
{
- struct aim_ssi_item *cur;
- for (cur=list; cur; cur=cur->next)
- if ((cur->gid == gid) && (cur->bid == bid))
- return cur;
- return NULL;
+ guint32 id_key = (gid << 16) + bid;
+ return g_hash_table_lookup(list->idx_gid_bid, GINT_TO_POINTER(id_key));
}
/**
@@ -356,37 +389,30 @@ struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_item *list, guint16 gi
* @param type The type of the desired item.
* @return Return a pointer to the item if found, else return NULL.
*/
-struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_item *list, const char *gn, const char *bn, guint16 type)
+struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_itemlist *list, const char *gn, const char *bn, guint16 type)
{
struct aim_ssi_item *cur;
- if (!list)
+ gchar key[3000];
+
+ if (!list->data)
return NULL;
if (gn && bn) { /* For finding buddies in groups */
- for (cur=list; cur; cur=cur->next)
+ g_return_val_if_fail(type == AIM_SSI_TYPE_BUDDY, NULL);
+ for (cur=list->data; cur; cur=cur->next)
if ((cur->type == type) && (cur->name) && !(oscar_util_name_compare(cur->name, bn))) {
struct aim_ssi_item *curg;
- for (curg=list; curg; curg=curg->next)
+ for (curg=list->data; curg; curg=curg->next)
if ((curg->type == AIM_SSI_TYPE_GROUP) && (curg->gid == cur->gid) && (curg->name) && !(oscar_util_name_compare(curg->name, gn)))
return cur;
}
- } else if (gn) { /* For finding groups */
- for (cur=list; cur; cur=cur->next) {
- if ((cur->type == type) && (cur->bid == 0x0000) && (cur->name) && !(oscar_util_name_compare(cur->name, gn))) {
- return cur;
- }
- }
-
- } else if (bn) { /* For finding permits, denies, and ignores */
- for (cur=list; cur; cur=cur->next) {
- if ((cur->type == type) && (cur->name) && !(oscar_util_name_compare(cur->name, bn))) {
- return cur;
- }
- }
+ } else if (gn || bn) { /* For finding groups, permits, denies and ignores */
+ snprintf(key, sizeof(key), "%hx%s", type, oscar_normalize(NULL, gn ? gn : bn));
+ return g_hash_table_lookup(list->idx_all_named_items, key);
/* For stuff without names--permit deny setting, visibility mask, etc. */
- } else for (cur=list; cur; cur=cur->next) {
+ } else for (cur=list->data; cur; cur=cur->next) {
if ((cur->type == type) && (!cur->name))
return cur;
}
@@ -401,7 +427,7 @@ struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_item *list, const
* @param bn The group name of the desired item.
* @return Return a pointer to the name of the item if found, else return NULL;
*/
-struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_item *list, const char *bn)
+struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_itemlist *list, const char *bn)
{
if (!bn)
return NULL;
@@ -415,10 +441,10 @@ struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_item *list, const ch
* @param bn The buddy name of the desired item.
* @return Return a pointer to the name of the item if found, else return NULL;
*/
-char *aim_ssi_itemlist_findparentname(struct aim_ssi_item *list, const char *bn)
+char *aim_ssi_itemlist_findparentname(struct aim_ssi_itemlist *list, const char *bn)
{
struct aim_ssi_item *cur, *curg;
- if (!list || !bn)
+ if (!list->data || !bn)
return NULL;
if (!(cur = aim_ssi_itemlist_exists(list, bn)))
return NULL;
@@ -433,7 +459,7 @@ char *aim_ssi_itemlist_findparentname(struct aim_ssi_item *list, const char *bn)
* @param list A pointer to the current list of items.
* @return Return the current SSI permit deny setting, or 0 if no setting was found.
*/
-int aim_ssi_getpermdeny(struct aim_ssi_item *list)
+int aim_ssi_getpermdeny(struct aim_ssi_itemlist *list)
{
struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PDINFO);
if (cur) {
@@ -451,7 +477,7 @@ int aim_ssi_getpermdeny(struct aim_ssi_item *list)
* @param list A pointer to the current list of items.
* @return Return the current set of preferences.
*/
-guint32 aim_ssi_getpresence(struct aim_ssi_item *list)
+guint32 aim_ssi_getpresence(struct aim_ssi_itemlist *list)
{
struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS);
if (cur) {
@@ -472,17 +498,23 @@ guint32 aim_ssi_getpresence(struct aim_ssi_item *list)
* alias, or NULL if the buddy has no alias. You should free
* this returned value!
*/
-char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *bn)
+char *aim_ssi_getalias(struct aim_ssi_itemlist *list, const char *gn, const char *bn)
{
- struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, bn, AIM_SSI_TYPE_BUDDY);
- if (cur) {
- aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x0131, 1);
- if (tlv && tlv->length)
- return g_strndup((const gchar *)tlv->value, tlv->length);
+ struct aim_ssi_item *item = aim_ssi_itemlist_finditem(list, gn, bn, AIM_SSI_TYPE_BUDDY);
+ if (item) {
+ return aim_ssi_getalias_from_item(item);
}
return NULL;
}
+char *aim_ssi_getalias_from_item(struct aim_ssi_item *item)
+{
+ aim_tlv_t *tlv = aim_tlv_gettlv(item->data, 0x0131, 1);
+ if (tlv && tlv->length)
+ return g_strndup((const gchar *)tlv->value, tlv->length);
+ return NULL;
+}
+
/**
* Locally find the comment of the given buddy.
*
@@ -493,7 +525,7 @@ char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *bn
* comment, or NULL if the buddy has no comment. You should free
* this returned value!
*/
-char *aim_ssi_getcomment(struct aim_ssi_item *list, const char *gn, const char *bn)
+char *aim_ssi_getcomment(struct aim_ssi_itemlist *list, const char *gn, const char *bn)
{
struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, bn, AIM_SSI_TYPE_BUDDY);
if (cur) {
@@ -513,7 +545,7 @@ char *aim_ssi_getcomment(struct aim_ssi_item *list, const char *gn, const char *
* @param bn The name of the buddy.
* @return 1 if you are waiting for authorization; 0 if you are not
*/
-gboolean aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *bn)
+gboolean aim_ssi_waitingforauth(struct aim_ssi_itemlist *list, const char *gn, const char *bn)
{
struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, bn, AIM_SSI_TYPE_BUDDY);
if (cur) {
@@ -561,8 +593,8 @@ static int aim_ssi_sync(OscarData *od)
/* Deletions */
if (!od->ssi.pending) {
- for (cur1=od->ssi.official; cur1 && (n < 15); cur1=cur1->next) {
- if (!aim_ssi_itemlist_find(od->ssi.local, cur1->gid, cur1->bid)) {
+ for (cur1=od->ssi.official.data; cur1 && (n < 15); cur1=cur1->next) {
+ if (!aim_ssi_itemlist_find(&od->ssi.local, cur1->gid, cur1->bid)) {
n++;
new = g_new(struct aim_ssi_tmp, 1);
new->action = SNAC_SUBTYPE_FEEDBAG_DEL;
@@ -575,15 +607,15 @@ static int aim_ssi_sync(OscarData *od)
cur->next = new;
} else
od->ssi.pending = new;
- aim_ssi_item_debug_append(debugstr, "Deleting item ", cur1);
+ aim_ssi_item_debug_append(debugstr, "Deleting item ", cur1);
}
}
}
/* Additions */
if (!od->ssi.pending) {
- for (cur1=od->ssi.local; cur1 && (n < 15); cur1=cur1->next) {
- if (!aim_ssi_itemlist_find(od->ssi.official, cur1->gid, cur1->bid)) {
+ for (cur1=od->ssi.local.data; cur1 && (n < 15); cur1=cur1->next) {
+ if (!aim_ssi_itemlist_find(&od->ssi.official, cur1->gid, cur1->bid)) {
n++;
new = g_new(struct aim_ssi_tmp, 1);
new->action = SNAC_SUBTYPE_FEEDBAG_ADD;
@@ -596,15 +628,15 @@ static int aim_ssi_sync(OscarData *od)
cur->next = new;
} else
od->ssi.pending = new;
- aim_ssi_item_debug_append(debugstr, "Adding item ", cur1);
+ aim_ssi_item_debug_append(debugstr, "Adding item ", cur1);
}
}
}
/* Modifications */
if (!od->ssi.pending) {
- for (cur1=od->ssi.local; cur1 && (n < 15); cur1=cur1->next) {
- cur2 = aim_ssi_itemlist_find(od->ssi.official, cur1->gid, cur1->bid);
+ for (cur1=od->ssi.local.data; cur1 && (n < 15); cur1=cur1->next) {
+ cur2 = aim_ssi_itemlist_find(&od->ssi.official, cur1->gid, cur1->bid);
if (cur2 && (aim_ssi_itemlist_cmp(cur1, cur2))) {
n++;
new = g_new(struct aim_ssi_tmp, 1);
@@ -618,18 +650,18 @@ static int aim_ssi_sync(OscarData *od)
cur->next = new;
} else
od->ssi.pending = new;
- aim_ssi_item_debug_append(debugstr, "Modifying item ", cur1);
+ aim_ssi_item_debug_append(debugstr, "Modifying item ", cur1);
}
}
}
if (debugstr->len > 0) {
purple_debug_info("oscar", "%s", debugstr->str);
if (purple_debug_is_verbose()) {
- g_string_truncate(debugstr, 0);
- for (cur1 = od->ssi.local; cur1; cur1 = cur1->next)
+ g_string_truncate(debugstr, 0);
+ for (cur1 = od->ssi.local.data; cur1; cur1 = cur1->next)
aim_ssi_item_debug_append(debugstr, "\t", cur1);
purple_debug_misc("oscar", "Dumping item list of account %s:\n%s",
- purple_connection_get_account(od->gc)->username, debugstr->str);
+ purple_account_get_username(purple_connection_get_account(od->gc)), debugstr->str);
}
}
g_string_free(debugstr, TRUE);
@@ -673,22 +705,18 @@ aim_ssi_freelist(OscarData *od)
struct aim_ssi_item *cur, *del;
struct aim_ssi_tmp *curtmp, *deltmp;
- cur = od->ssi.official;
+ cur = od->ssi.official.data;
while (cur) {
del = cur;
cur = cur->next;
- g_free(del->name);
- aim_tlvlist_free(del->data);
- g_free(del);
+ aim_ssi_item_free(del);
}
- cur = od->ssi.local;
+ cur = od->ssi.local.data;
while (cur) {
del = cur;
cur = cur->next;
- g_free(del->name);
- aim_tlvlist_free(del->data);
- g_free(del);
+ aim_ssi_item_free(del);
}
curtmp = od->ssi.pending;
@@ -699,22 +727,49 @@ aim_ssi_freelist(OscarData *od)
}
od->ssi.numitems = 0;
- od->ssi.official = NULL;
- od->ssi.local = NULL;
+ od->ssi.official.data = NULL;
+ od->ssi.local.data = NULL;
od->ssi.pending = NULL;
od->ssi.timestamp = (time_t)0;
}
/**
- * This "cleans" the ssi list. It does the following:
- * 1) Makes sure all buddies, permits, and denies have names.
- * 2) Makes sure that all buddies are in a group that exist.
- * 3) Deletes any empty groups
+ * Look up the given TLV type in the item's data. If the value of
+ * the TLV is not a valid UTF-8 string then use purple_utf8_salvage()
+ * to replace invalid bytes with question marks.
+ */
+static void cleanlist_ensure_utf8_data(struct aim_ssi_item *item, guint16 tlvtype)
+{
+ aim_tlv_t *tlv;
+ gchar *value, *salvaged;
+
+ tlv = aim_tlv_gettlv(item->data, tlvtype, 1);
+ if (tlv && tlv->length && !g_utf8_validate((const gchar *)tlv->value, tlv->length, NULL)) {
+ purple_debug_warning("oscar", "cleanlist found invalid UTF-8 "
+ "for 0x%04hx field of 0x%04hx item with name %s. "
+ "Attempting to repair.\n",
+ tlvtype, item->type, item->name ? item->name : "(null)");
+ value = g_strndup((const gchar *)tlv->value, tlv->length);
+ salvaged = purple_utf8_salvage(value);
+ g_free(value);
+ if (*salvaged)
+ aim_tlvlist_replace_str(&item->data, tlvtype, salvaged);
+ else
+ aim_tlvlist_remove(&item->data, tlvtype);
+ g_free(salvaged);
+ }
+}
+
+/**
+ * This "cleans" the ssi list. It does things like:
+ * - Makes sure all buddies, permits, and denies have names
+ * - Makes sure all buddies are in a group that exist
+ * - Makes sure strings are valid UTF-8
*
* @param od The oscar odion.
* @return Return 0 if no errors, otherwise return the error number.
*/
-int aim_ssi_cleanlist(OscarData *od)
+static int aim_ssi_cleanlist(OscarData *od)
{
struct aim_ssi_item *cur, *next;
@@ -726,7 +781,7 @@ int aim_ssi_cleanlist(OscarData *od)
/* DESTROY any buddies that are directly in the master group. */
/* Do the same for buddies that are in a non-existant group. */
/* This will kind of mess up if you hit the item limit, but this function isn't too critical */
- cur = od->ssi.local;
+ cur = od->ssi.local.data;
while (cur) {
next = cur->next;
if (!cur->name) {
@@ -734,29 +789,42 @@ int aim_ssi_cleanlist(OscarData *od)
aim_ssi_delbuddy(od, NULL, NULL);
else if (cur->type == AIM_SSI_TYPE_PERMIT || cur->type == AIM_SSI_TYPE_DENY || cur->type == AIM_SSI_TYPE_ICQDENY)
aim_ssi_del_from_private_list(od, NULL, cur->type);
- } else if ((cur->type == AIM_SSI_TYPE_BUDDY) && ((cur->gid == 0x0000) || (!aim_ssi_itemlist_find(od->ssi.local, cur->gid, 0x0000)))) {
- char *alias = aim_ssi_getalias(od->ssi.local, NULL, cur->name);
- aim_ssi_addbuddy(od, cur->name, "orphans", NULL, alias, NULL, NULL, FALSE);
+ } else if ((cur->type == AIM_SSI_TYPE_BUDDY) && ((cur->gid == 0x0000) || (!aim_ssi_itemlist_find(&od->ssi.local, cur->gid, 0x0000)))) {
+ char *alias = aim_ssi_getalias(&od->ssi.local, NULL, cur->name);
+ aim_ssi_addbuddy(od, cur->name, _("Buddies"), NULL, alias, NULL, NULL, FALSE);
aim_ssi_delbuddy(od, cur->name, NULL);
g_free(alias);
}
cur = next;
}
- /* Make sure there aren't any duplicate buddies in a group, or duplicate permits or denies */
- cur = od->ssi.local;
+ cur = od->ssi.local.data;
while (cur) {
if ((cur->type == AIM_SSI_TYPE_BUDDY) || (cur->type == AIM_SSI_TYPE_PERMIT) || (cur->type == AIM_SSI_TYPE_DENY))
{
struct aim_ssi_item *cur2, *next2;
+
+ /* Make sure there aren't any duplicate permits or denies, or
+ duplicate buddies within a group */
cur2 = cur->next;
while (cur2) {
next2 = cur2->next;
- if ((cur->type == cur2->type) && (cur->gid == cur2->gid) && (cur->name != NULL) && (cur2->name != NULL) && (!oscar_util_name_compare(cur->name, cur2->name))) {
+ if (cur->type == cur2->type
+ && cur->gid == cur2->gid
+ && cur->name
+ && cur2->name
+ && !oscar_util_name_compare(cur->name, cur2->name))
+ {
aim_ssi_itemlist_del(&od->ssi.local, cur2);
}
cur2 = next2;
}
+
+ /* Make sure alias is valid UTF-8 */
+ cleanlist_ensure_utf8_data(cur, 0x0131);
+
+ /* Make sure comment is valid UTF-8 */
+ cleanlist_ensure_utf8_data(cur, 0x013c);
}
cur = cur->next;
}
@@ -785,16 +853,16 @@ int aim_ssi_addbuddy(OscarData *od, const char *name, const char *group, GSList
return -EINVAL;
/* Find the parent */
- if (!(parent = aim_ssi_itemlist_finditem(od->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP))) {
+ if (!(parent = aim_ssi_itemlist_finditem(&od->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP))) {
/* Find the parent's parent (the master group) */
- if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL)
+ if (aim_ssi_itemlist_find(&od->ssi.local, 0x0000, 0x0000) == NULL)
aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL);
/* Add the parent */
parent = aim_ssi_itemlist_add(&od->ssi.local, group, 0xFFFF, 0x0000, AIM_SSI_TYPE_GROUP, NULL);
/* Modify the parent's parent (the master group) */
- aim_ssi_itemlist_rebuildgroup(od->ssi.local, NULL);
+ aim_ssi_itemlist_rebuildgroup(&od->ssi.local, NULL);
}
/* Create a TLV list for the new buddy */
@@ -812,7 +880,7 @@ int aim_ssi_addbuddy(OscarData *od, const char *name, const char *group, GSList
aim_tlvlist_free(data);
/* Modify the parent group */
- aim_ssi_itemlist_rebuildgroup(od->ssi.local, group);
+ aim_ssi_itemlist_rebuildgroup(&od->ssi.local, group);
/* Sync our local list with the server list */
return aim_ssi_sync(od);
@@ -824,7 +892,7 @@ aim_ssi_add_to_private_list(OscarData *od, const char* name, guint16 list_type)
if (!od || !name || !od->ssi.received_data)
return -EINVAL;
- if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL)
+ if (aim_ssi_itemlist_find(&od->ssi.local, 0x0000, 0x0000) == NULL)
aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL);
aim_ssi_itemlist_add(&od->ssi.local, name, 0x0000, 0xFFFF, list_type, NULL);
@@ -839,7 +907,7 @@ aim_ssi_del_from_private_list(OscarData* od, const char* name, guint16 list_type
if (!od)
return -EINVAL;
- if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, NULL, name, list_type)))
+ if (!(del = aim_ssi_itemlist_finditem(&od->ssi.local, NULL, name, list_type)))
return -EINVAL;
aim_ssi_itemlist_del(&od->ssi.local, del);
@@ -862,14 +930,14 @@ int aim_ssi_delbuddy(OscarData *od, const char *name, const char *group)
return -EINVAL;
/* Find the buddy */
- if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, group, name, AIM_SSI_TYPE_BUDDY)))
+ if (!(del = aim_ssi_itemlist_finditem(&od->ssi.local, group, name, AIM_SSI_TYPE_BUDDY)))
return -EINVAL;
/* Remove the item from the list */
aim_ssi_itemlist_del(&od->ssi.local, del);
/* Modify the parent group */
- aim_ssi_itemlist_rebuildgroup(od->ssi.local, group);
+ aim_ssi_itemlist_rebuildgroup(&od->ssi.local, group);
/* Sync our local list with the server list */
return aim_ssi_sync(od);
@@ -891,7 +959,7 @@ int aim_ssi_delgroup(OscarData *od, const char *group)
return -EINVAL;
/* Find the group */
- if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP)))
+ if (!(del = aim_ssi_itemlist_finditem(&od->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP)))
return -EINVAL;
/* Don't delete the group if it's not empty */
@@ -903,7 +971,7 @@ int aim_ssi_delgroup(OscarData *od, const char *group)
aim_ssi_itemlist_del(&od->ssi.local, del);
/* Modify the parent group */
- aim_ssi_itemlist_rebuildgroup(od->ssi.local, group);
+ aim_ssi_itemlist_rebuildgroup(&od->ssi.local, NULL);
/* Sync our local list with the server list */
return aim_ssi_sync(od);
@@ -925,7 +993,7 @@ int aim_ssi_movebuddy(OscarData *od, const char *oldgn, const char *newgn, const
GSList *data;
/* Find the buddy */
- buddy = aim_ssi_itemlist_finditem(od->ssi.local, oldgn, bn, AIM_SSI_TYPE_BUDDY);
+ buddy = aim_ssi_itemlist_finditem(&od->ssi.local, oldgn, bn, AIM_SSI_TYPE_BUDDY);
if (buddy == NULL)
return -EINVAL;
@@ -958,11 +1026,11 @@ int aim_ssi_aliasbuddy(OscarData *od, const char *gn, const char *bn, const char
if (!od || !gn || !bn)
return -EINVAL;
- if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, gn, bn, AIM_SSI_TYPE_BUDDY)))
+ if (!(tmp = aim_ssi_itemlist_finditem(&od->ssi.local, gn, bn, AIM_SSI_TYPE_BUDDY)))
return -EINVAL;
/* Either add or remove the 0x0131 TLV from the TLV chain */
- if ((alias != NULL) && (strlen(alias) > 0))
+ if (alias && *alias)
aim_tlvlist_replace_str(&tmp->data, 0x0131, alias);
else
aim_tlvlist_remove(&tmp->data, 0x0131);
@@ -988,11 +1056,11 @@ int aim_ssi_editcomment(OscarData *od, const char *gn, const char *bn, const cha
if (!od || !gn || !bn)
return -EINVAL;
- if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, gn, bn, AIM_SSI_TYPE_BUDDY)))
+ if (!(tmp = aim_ssi_itemlist_finditem(&od->ssi.local, gn, bn, AIM_SSI_TYPE_BUDDY)))
return -EINVAL;
/* Either add or remove the 0x0131 TLV from the TLV chain */
- if ((comment != NULL) && (strlen(comment) > 0))
+ if (comment && *comment)
aim_tlvlist_replace_str(&tmp->data, 0x013c, comment);
else
aim_tlvlist_remove(&tmp->data, 0x013c);
@@ -1016,11 +1084,10 @@ int aim_ssi_rename_group(OscarData *od, const char *oldgn, const char *newgn)
if (!od || !oldgn || !newgn)
return -EINVAL;
- if (!(group = aim_ssi_itemlist_finditem(od->ssi.local, oldgn, NULL, AIM_SSI_TYPE_GROUP)))
+ if (!(group = aim_ssi_itemlist_finditem(&od->ssi.local, oldgn, NULL, AIM_SSI_TYPE_GROUP)))
return -EINVAL;
- g_free(group->name);
- group->name = g_strdup(newgn);
+ aim_ssi_item_set_name(&od->ssi.local, group, newgn);
/* Sync our local list with the server list */
return aim_ssi_sync(od);
@@ -1047,9 +1114,9 @@ int aim_ssi_setpermdeny(OscarData *od, guint8 permdeny)
return -EINVAL;
/* Find the PDINFO item, or add it if it does not exist */
- if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, NULL, NULL, AIM_SSI_TYPE_PDINFO))) {
+ if (!(tmp = aim_ssi_itemlist_finditem(&od->ssi.local, NULL, NULL, AIM_SSI_TYPE_PDINFO))) {
/* Make sure the master group exists */
- if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL)
+ if (aim_ssi_itemlist_find(&od->ssi.local, 0x0000, 0x0000) == NULL)
aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL);
tmp = aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0xFFFF, AIM_SSI_TYPE_PDINFO, NULL);
@@ -1079,9 +1146,9 @@ int aim_ssi_seticon(OscarData *od, const guint8 *iconsum, guint8 iconsumlen)
return -EINVAL;
/* Find the ICONINFO item, or add it if it does not exist */
- if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, NULL, "1", AIM_SSI_TYPE_ICONINFO))) {
+ if (!(tmp = aim_ssi_itemlist_finditem(&od->ssi.local, NULL, "1", AIM_SSI_TYPE_ICONINFO))) {
/* Make sure the master group exists */
- if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL)
+ if (aim_ssi_itemlist_find(&od->ssi.local, 0x0000, 0x0000) == NULL)
aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL);
tmp = aim_ssi_itemlist_add(&od->ssi.local, "1", 0x0000, 0xFFFF, AIM_SSI_TYPE_ICONINFO, NULL);
@@ -1139,9 +1206,9 @@ int aim_ssi_setpresence(OscarData *od, guint32 presence) {
return -EINVAL;
/* Find the PRESENCEPREFS item, or add it if it does not exist */
- if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS))) {
+ if (!(tmp = aim_ssi_itemlist_finditem(&od->ssi.local, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS))) {
/* Make sure the master group exists */
- if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL)
+ if (aim_ssi_itemlist_find(&od->ssi.local, 0x0000, 0x0000) == NULL)
aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL);
tmp = aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0xFFFF, AIM_SSI_TYPE_PRESENCEPREFS, NULL);
@@ -1257,7 +1324,7 @@ static int parsedata(OscarData *od, FlapConnection *conn, aim_module_t *mod, Fla
aim_tlvlist_free(data);
}
purple_debug_misc("oscar", "Reading items from tlvlist for account %s:\n%s",
- purple_connection_get_account(od->gc)->username, debugstr->str);
+ purple_account_get_username(purple_connection_get_account(od->gc)), debugstr->str);
g_string_free(debugstr, TRUE);
/* Read in the timestamp */
@@ -1266,9 +1333,12 @@ static int parsedata(OscarData *od, FlapConnection *conn, aim_module_t *mod, Fla
if (!(snac->flags & 0x0001)) {
/* Make a copy of the list */
struct aim_ssi_item *cur;
- for (cur=od->ssi.official; cur; cur=cur->next)
+ for (cur=od->ssi.official.data; cur; cur=cur->next)
aim_ssi_itemlist_add(&od->ssi.local, cur->name, cur->gid, cur->bid, cur->type, cur->data);
+ /* Clean the buddy list */
+ aim_ssi_cleanlist(od);
+
od->ssi.received_data = TRUE;
if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
@@ -1416,18 +1486,16 @@ static int parsemod(OscarData *od, FlapConnection *conn, aim_module_t *mod, Flap
data = NULL;
/* Replace the 2 local items with the given one */
- if ((item = aim_ssi_itemlist_find(od->ssi.local, gid, bid))) {
+ if ((item = aim_ssi_itemlist_find(&od->ssi.local, gid, bid))) {
item->type = type;
- g_free(item->name);
- item->name = g_strdup(name);
+ aim_ssi_item_set_name(&od->ssi.local, item, name);
aim_tlvlist_free(item->data);
item->data = aim_tlvlist_copy(data);
}
- if ((item = aim_ssi_itemlist_find(od->ssi.official, gid, bid))) {
+ if ((item = aim_ssi_itemlist_find(&od->ssi.official, gid, bid))) {
item->type = type;
- g_free(item->name);
- item->name = g_strdup(name);
+ aim_ssi_item_set_name(&od->ssi.official, item, name);
aim_tlvlist_free(item->data);
item->data = aim_tlvlist_copy(data);
}
@@ -1461,9 +1529,9 @@ static int parsedel(OscarData *od, FlapConnection *conn, aim_module_t *mod, Flap
byte_stream_get16(bs);
byte_stream_advance(bs, byte_stream_get16(bs));
- if ((del = aim_ssi_itemlist_find(od->ssi.local, gid, bid)))
+ if ((del = aim_ssi_itemlist_find(&od->ssi.local, gid, bid)))
aim_ssi_itemlist_del(&od->ssi.local, del);
- if ((del = aim_ssi_itemlist_find(od->ssi.official, gid, bid)))
+ if ((del = aim_ssi_itemlist_find(&od->ssi.official, gid, bid)))
aim_ssi_itemlist_del(&od->ssi.official, del);
if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
@@ -1504,7 +1572,8 @@ static int parseack(OscarData *od, FlapConnection *conn, aim_module_t *mod, Flap
if (cur->action == SNAC_SUBTYPE_FEEDBAG_ADD) {
/* Remove the item from the local list */
/* Make sure cur->item is still valid memory */
- if (aim_ssi_itemlist_valid(od->ssi.local, cur->item)) {
+ /* TODO: "Still valid memory"? That's bad form. */
+ if (aim_ssi_itemlist_valid(&od->ssi.local, cur->item)) {
cur->name = g_strdup(cur->item->name);
aim_ssi_itemlist_del(&od->ssi.local, cur->item);
}
@@ -1512,11 +1581,10 @@ static int parseack(OscarData *od, FlapConnection *conn, aim_module_t *mod, Flap
} else if (cur->action == SNAC_SUBTYPE_FEEDBAG_MOD) {
/* Replace the local item with the item from the official list */
- if (aim_ssi_itemlist_valid(od->ssi.local, cur->item)) {
+ if (aim_ssi_itemlist_valid(&od->ssi.local, cur->item)) {
struct aim_ssi_item *cur1;
- if ((cur1 = aim_ssi_itemlist_find(od->ssi.official, cur->item->gid, cur->item->bid))) {
- g_free(cur->item->name);
- cur->item->name = g_strdup(cur1->name);
+ if ((cur1 = aim_ssi_itemlist_find(&od->ssi.official, cur->item->gid, cur->item->bid))) {
+ aim_ssi_item_set_name(&od->ssi.official, cur->item, cur1->name);
aim_tlvlist_free(cur->item->data);
cur->item->data = aim_tlvlist_copy(cur1->data);
}
@@ -1525,7 +1593,7 @@ static int parseack(OscarData *od, FlapConnection *conn, aim_module_t *mod, Flap
} else if (cur->action == SNAC_SUBTYPE_FEEDBAG_DEL) {
/* Add the item back into the local list */
- if (aim_ssi_itemlist_valid(od->ssi.official, cur->item)) {
+ if (aim_ssi_itemlist_valid(&od->ssi.official, cur->item)) {
aim_ssi_itemlist_add(&od->ssi.local, cur->item->name, cur->item->gid, cur->item->bid, cur->item->type, cur->item->data);
} else
cur->item = NULL;
@@ -1535,18 +1603,17 @@ static int parseack(OscarData *od, FlapConnection *conn, aim_module_t *mod, Flap
/* Do the exact opposite */
if (cur->action == SNAC_SUBTYPE_FEEDBAG_ADD) {
/* Add the local item to the official list */
- if (aim_ssi_itemlist_valid(od->ssi.local, cur->item)) {
+ if (aim_ssi_itemlist_valid(&od->ssi.local, cur->item)) {
aim_ssi_itemlist_add(&od->ssi.official, cur->item->name, cur->item->gid, cur->item->bid, cur->item->type, cur->item->data);
} else
cur->item = NULL;
} else if (cur->action == SNAC_SUBTYPE_FEEDBAG_MOD) {
/* Replace the official item with the item from the local list */
- if (aim_ssi_itemlist_valid(od->ssi.local, cur->item)) {
+ if (aim_ssi_itemlist_valid(&od->ssi.local, cur->item)) {
struct aim_ssi_item *cur1;
- if ((cur1 = aim_ssi_itemlist_find(od->ssi.official, cur->item->gid, cur->item->bid))) {
- g_free(cur1->name);
- cur1->name = g_strdup(cur->item->name);
+ if ((cur1 = aim_ssi_itemlist_find(&od->ssi.official, cur->item->gid, cur->item->bid))) {
+ aim_ssi_item_set_name(&od->ssi.official, cur1, cur->item->name);
aim_tlvlist_free(cur1->data);
cur1->data = aim_tlvlist_copy(cur->item->data);
}
@@ -1555,7 +1622,7 @@ static int parseack(OscarData *od, FlapConnection *conn, aim_module_t *mod, Flap
} else if (cur->action == SNAC_SUBTYPE_FEEDBAG_DEL) {
/* Remove the item from the official list */
- if (aim_ssi_itemlist_valid(od->ssi.official, cur->item))
+ if (aim_ssi_itemlist_valid(&od->ssi.official, cur->item))
aim_ssi_itemlist_del(&od->ssi.official, cur->item);
cur->item = NULL;
}
diff --git a/libpurple/protocols/oscar/family_icbm.c b/libpurple/protocols/oscar/family_icbm.c
index 2b5a629143..dac757431c 100644
--- a/libpurple/protocols/oscar/family_icbm.c
+++ b/libpurple/protocols/oscar/family_icbm.c
@@ -650,6 +650,9 @@ aim_im_sendch2_odc_requestdirect(OscarData *od, guchar *cookie, const char *bn,
GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL;
ByteStream hdrbs;
+ g_return_if_fail(bn != NULL);
+ g_return_if_fail(ip != NULL);
+
conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM);
if (conn == NULL)
return;
@@ -1941,7 +1944,7 @@ int icq_im_xstatus_request(OscarData *od, const char *sn)
account = purple_connection_get_account(od->gc);
- statxml = g_strdup_printf(fmt, account->username);
+ statxml = g_strdup_printf(fmt, purple_account_get_username(account));
xmllen = strlen(statxml);
aim_icbm_makecookie(cookie);
@@ -2035,7 +2038,7 @@ int icq_relay_xstatus(OscarData *od, const char *sn, const guchar *cookie)
/* if (!strcmp(account->username, sn))
icq_im_xstatus_request(od, sn); */
- status = purple_presence_get_active_status(account->presence);
+ status = purple_presence_get_active_status(purple_account_get_presence(account));
if (!status)
return -EINVAL;
@@ -2051,7 +2054,7 @@ int icq_relay_xstatus(OscarData *od, const char *sn, const guchar *cookie)
if (!msg)
return -EINVAL;
- statxml = g_strdup_printf(fmt, account->username, title, msg);
+ statxml = g_strdup_printf(fmt, purple_account_get_username(account), title, msg);
len = strlen(statxml);
purple_debug_misc("oscar", "X-Status AutoReply: %s, %s\n", formatted_msg, msg);
@@ -2092,6 +2095,12 @@ static int mtn_receive(OscarData *od, FlapConnection *conn, aim_module_t *mod, F
channel = byte_stream_get16(bs);
bnlen = byte_stream_get8(bs);
bn = byte_stream_getstr(bs, bnlen);
+ if (!g_utf8_validate(bn, -1, NULL)) {
+ purple_debug_warning("oscar", "Received SNAC %04hx/%04hx with "
+ "invalid UTF-8 buddy name.\n", snac->family, snac->subtype);
+ g_free(bn);
+ return 1;
+ }
event = byte_stream_get16(bs);
if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
diff --git a/libpurple/protocols/oscar/family_locate.c b/libpurple/protocols/oscar/family_locate.c
index e399fe09f7..34628c252d 100644
--- a/libpurple/protocols/oscar/family_locate.c
+++ b/libpurple/protocols/oscar/family_locate.c
@@ -1355,7 +1355,7 @@ aim_locate_setcaps(OscarData *od, guint64 caps)
aim_snacid_t snacid;
GSList *tlvlist = NULL;
- if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)))
+ if (!(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)))
return -EINVAL;
aim_tlvlist_add_caps(&tlvlist, 0x0005, caps, mood);
diff --git a/libpurple/protocols/oscar/flap_connection.c b/libpurple/protocols/oscar/flap_connection.c
index 3aa62973d2..a7441c69ed 100644
--- a/libpurple/protocols/oscar/flap_connection.c
+++ b/libpurple/protocols/oscar/flap_connection.c
@@ -456,7 +456,7 @@ flap_connection_destroy_cb(gpointer data)
* TODO: If we don't have a SNAC_FAMILY_LOCATE connection then
* we should try to request one instead of disconnecting.
*/
- if (!account->disconnecting && ((od->oscar_connections == NULL)
+ if (!purple_account_is_disconnecting(account) && ((od->oscar_connections == NULL)
|| (!flap_connection_getbytype(od, SNAC_FAMILY_LOCATE))))
{
/* No more FLAP connections! Sign off this PurpleConnection! */
@@ -487,7 +487,7 @@ flap_connection_destroy_cb(gpointer data)
if (tmp != NULL)
{
- purple_connection_error_reason(od->gc, reason, tmp);
+ purple_connection_error(od->gc, reason, tmp);
g_free(tmp);
}
}
@@ -921,7 +921,7 @@ flap_connection_recv(FlapConnection *conn)
OSCAR_DISCONNECT_LOST_CONNECTION, g_strerror(errno));
break;
}
- conn->od->gc->last_received = time(NULL);
+ purple_connection_update_last_received(conn->od->gc);
/* If we don't even have a complete FLAP header then do nothing */
conn->header_received += read;
diff --git a/libpurple/protocols/oscar/libaim.c b/libpurple/protocols/oscar/libaim.c
index 0a169e9534..86d280da46 100644
--- a/libpurple/protocols/oscar/libaim.c
+++ b/libpurple/protocols/oscar/libaim.c
@@ -29,6 +29,7 @@
static PurplePluginProtocolInfo prpl_info =
{
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
OPT_PROTO_MAIL_CHECK | OPT_PROTO_IM_IMAGE | OPT_PROTO_INVITE_MESSAGE,
NULL, /* user_splits */
NULL, /* protocol_options */
@@ -50,7 +51,7 @@ static PurplePluginProtocolInfo prpl_info =
oscar_set_status, /* set_status */
oscar_set_idle, /* set_idle */
oscar_change_passwd, /* change_passwd */
- NULL, /* add_buddy */
+ oscar_add_buddy, /* add_buddy */
NULL, /* add_buddies */
oscar_remove_buddy, /* remove_buddy */
NULL, /* remove_buddies */
@@ -69,7 +70,6 @@ static PurplePluginProtocolInfo prpl_info =
oscar_keepalive, /* keepalive */
NULL, /* register_user */
NULL, /* get_cb_info */
- NULL, /* get_cb_away */
oscar_alias_buddy, /* alias_buddy */
oscar_move_buddy, /* group_buddy */
oscar_rename_group, /* rename_group */
@@ -94,15 +94,12 @@ static PurplePluginProtocolInfo prpl_info =
NULL, /* unregister_user */
NULL, /* send_attention */
NULL, /* get_attention_types */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
NULL, /* get_account_text_table */
NULL, /* initiate_media */
NULL, /* get_media_caps */
NULL, /* get_moods */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- oscar_add_buddy, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */
};
static PurplePluginInfo info =
diff --git a/libpurple/protocols/oscar/libicq.c b/libpurple/protocols/oscar/libicq.c
index 18f5451e59..238ee06c6f 100644
--- a/libpurple/protocols/oscar/libicq.c
+++ b/libpurple/protocols/oscar/libicq.c
@@ -38,6 +38,7 @@ icq_get_account_text_table(PurpleAccount *account)
static PurplePluginProtocolInfo prpl_info =
{
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
OPT_PROTO_MAIL_CHECK | OPT_PROTO_IM_IMAGE | OPT_PROTO_INVITE_MESSAGE,
NULL, /* user_splits */
NULL, /* protocol_options */
@@ -59,7 +60,7 @@ static PurplePluginProtocolInfo prpl_info =
oscar_set_status, /* set_status */
oscar_set_idle, /* set_idle */
oscar_change_passwd, /* change_passwd */
- NULL, /* add_buddy */
+ oscar_add_buddy, /* add_buddy */
NULL, /* add_buddies */
oscar_remove_buddy, /* remove_buddy */
NULL, /* remove_buddies */
@@ -78,7 +79,6 @@ static PurplePluginProtocolInfo prpl_info =
oscar_keepalive, /* keepalive */
NULL, /* register_user */
NULL, /* get_cb_info */
- NULL, /* get_cb_away */
oscar_alias_buddy, /* alias_buddy */
oscar_move_buddy, /* group_buddy */
oscar_rename_group, /* rename_group */
@@ -103,16 +103,12 @@ static PurplePluginProtocolInfo prpl_info =
NULL, /* unregister_user */
NULL, /* send_attention */
NULL, /* get_attention_types */
-
- sizeof(PurplePluginProtocolInfo), /* struct_size */
icq_get_account_text_table, /* get_account_text_table */
NULL, /* initiate_media */
NULL, /* can_do_media */
oscar_get_purple_moods, /* get_moods */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- oscar_add_buddy, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */
};
static PurplePluginInfo info =
diff --git a/libpurple/protocols/oscar/odc.c b/libpurple/protocols/oscar/odc.c
index b62de581d9..77bae6acec 100644
--- a/libpurple/protocols/oscar/odc.c
+++ b/libpurple/protocols/oscar/odc.c
@@ -376,7 +376,9 @@ peer_odc_handle_payload(PeerConnection *conn, const char *msg, size_t len, int e
if (imgid != 0)
{
/* Write the new image tag */
- g_string_append_printf(newmsg, "<IMG ID=\"%d\">", imgid);
+ g_string_append_printf(newmsg,
+ "<IMG SRC=\"" PURPLE_STORED_IMAGE_PROTOCOL "%d\">",
+ imgid);
}
/* Continue from the end of the tag */
diff --git a/libpurple/protocols/oscar/oft.c b/libpurple/protocols/oscar/oft.c
index 2b99ae4212..49cbcb06da 100644
--- a/libpurple/protocols/oscar/oft.c
+++ b/libpurple/protocols/oscar/oft.c
@@ -362,10 +362,10 @@ start_transfer_when_done_sending_data(gpointer data)
if (purple_circ_buffer_get_max_read(conn->buffer_outgoing) == 0)
{
+ int fd = conn->fd;
conn->sending_data_timer = 0;
- conn->xfer->fd = conn->fd;
conn->fd = -1;
- purple_xfer_start(conn->xfer, conn->xfer->fd, NULL, 0);
+ purple_xfer_start(conn->xfer, fd, NULL, 0);
return FALSE;
}
@@ -508,7 +508,7 @@ peer_oft_recv_frame_done(PeerConnection *conn, OftFrame *frame)
purple_input_remove(conn->watcher_incoming);
conn->watcher_incoming = 0;
- conn->xfer->fd = conn->fd;
+ purple_xfer_set_fd(conn->xfer, conn->fd);
conn->fd = -1;
conn->disconnect_reason = OSCAR_DISCONNECT_DONE;
peer_connection_schedule_destroy(conn, conn->disconnect_reason, NULL);
@@ -589,7 +589,7 @@ peer_oft_recvcb_init(PurpleXfer *xfer)
{
PeerConnection *conn;
- conn = xfer->data;
+ conn = purple_xfer_get_protocol_data(xfer);
conn->flags |= PEER_CONNECTION_FLAG_APPROVED;
peer_connection_trynext(conn);
}
@@ -599,11 +599,11 @@ peer_oft_recvcb_end(PurpleXfer *xfer)
{
PeerConnection *conn;
- conn = xfer->data;
+ conn = purple_xfer_get_protocol_data(xfer);
/* Tell the other person that we've received everything */
- conn->fd = conn->xfer->fd;
- conn->xfer->fd = -1;
+ conn->fd = purple_xfer_get_fd(conn->xfer);
+ purple_xfer_set_fd(conn->xfer, -1);
peer_oft_send_done(conn);
conn->disconnect_reason = OSCAR_DISCONNECT_DONE;
@@ -617,7 +617,7 @@ peer_oft_recvcb_ack_recv(PurpleXfer *xfer, const guchar *buffer, size_t size)
PeerConnection *conn;
/* Update our rolling checksum. Like Walmart, yo. */
- conn = xfer->data;
+ conn = purple_xfer_get_protocol_data(xfer);
conn->xferdata.recvcsum = peer_oft_checksum_chunk(buffer,
size, conn->xferdata.recvcsum, purple_xfer_get_bytes_sent(xfer) & 1);
}
@@ -651,9 +651,9 @@ void
peer_oft_sendcb_init(PurpleXfer *xfer)
{
PeerConnection *conn;
- size_t size;
+ goffset size;
- conn = xfer->data;
+ conn = purple_xfer_get_protocol_data(xfer);
conn->flags |= PEER_CONNECTION_FLAG_APPROVED;
/* Make sure the file size can be represented in 32 bits */
@@ -665,9 +665,9 @@ peer_oft_sendcb_init(PurpleXfer *xfer)
size2 = purple_str_size_to_units(G_MAXUINT32);
tmp = g_strdup_printf(_("File %s is %s, which is larger than "
"the maximum size of %s."),
- xfer->local_filename, size1, size2);
+ purple_xfer_get_local_filename(xfer), size1, size2);
purple_xfer_error(purple_xfer_get_type(xfer),
- purple_xfer_get_account(xfer), xfer->who, tmp);
+ purple_xfer_get_account(xfer), purple_xfer_get_remote_user(xfer), tmp);
g_free(size1);
g_free(size2);
g_free(tmp);
@@ -689,9 +689,9 @@ peer_oft_sendcb_init(PurpleXfer *xfer)
strncpy((gchar *)conn->xferdata.idstring, "Cool FileXfer", 31);
conn->xferdata.modtime = 0;
conn->xferdata.cretime = 0;
- xfer->filename = g_path_get_basename(xfer->local_filename);
- conn->xferdata.name_length = MAX(64, strlen(xfer->filename) + 1);
- conn->xferdata.name = (guchar *)g_strndup(xfer->filename, conn->xferdata.name_length - 1);
+ purple_xfer_set_filename(xfer, g_path_get_basename(purple_xfer_get_local_filename(xfer)));
+ conn->xferdata.name_length = MAX(64, strlen(purple_xfer_get_filename(xfer)) + 1);
+ conn->xferdata.name = (guchar *)g_strndup(purple_xfer_get_filename(xfer), conn->xferdata.name_length - 1);
peer_oft_checksum_file(conn, xfer,
peer_oft_checksum_calculated_cb, G_MAXUINT32);
@@ -713,7 +713,7 @@ peer_oft_sendcb_ack(PurpleXfer *xfer, const guchar *buffer, size_t size)
{
PeerConnection *conn;
- conn = xfer->data;
+ conn = purple_xfer_get_protocol_data(xfer);
/*
* If we're done sending, intercept the socket from the core ft code
@@ -721,9 +721,9 @@ peer_oft_sendcb_ack(PurpleXfer *xfer, const guchar *buffer, size_t size)
*/
if (purple_xfer_get_bytes_remaining(xfer) <= 0)
{
- purple_input_remove(xfer->watcher);
- conn->fd = xfer->fd;
- xfer->fd = -1;
+ purple_input_remove(purple_xfer_get_watcher(xfer));
+ conn->fd = purple_xfer_get_fd(xfer);
+ purple_xfer_set_fd(xfer, -1);
conn->watcher_incoming = purple_input_add(conn->fd,
PURPLE_INPUT_READ, peer_connection_recv_cb, conn);
}
@@ -742,7 +742,7 @@ peer_oft_cb_generic_cancel(PurpleXfer *xfer)
{
PeerConnection *conn;
- conn = xfer->data;
+ conn = purple_xfer_get_protocol_data(xfer);
if (conn == NULL)
return;
diff --git a/libpurple/protocols/oscar/oscar.c b/libpurple/protocols/oscar/oscar.c
index 1f3ba9e509..61facc8aea 100644
--- a/libpurple/protocols/oscar/oscar.c
+++ b/libpurple/protocols/oscar/oscar.c
@@ -55,8 +55,6 @@
#define AIMHASHDATA "http://pidgin.im/aim_data.php3"
-#define OSCAR_CONNECT_STEPS 6
-
static guint64 purple_caps =
OSCAR_CAPABILITY_CHAT
| OSCAR_CAPABILITY_BUDDYICON
@@ -89,7 +87,6 @@ struct oscar_ask_directim_data
/* Only used when connecting with the old-style BUCP login */
static int purple_parse_auth_resp (OscarData *, FlapConnection *, FlapFrame *, ...);
-static int purple_parse_login (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_parse_auth_securid_request(OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_handle_redirect (OscarData *, FlapConnection *, FlapFrame *, ...);
@@ -308,7 +305,7 @@ connection_common_error_cb(FlapConnection *conn, const gchar *error_message)
gchar *msg;
msg = g_strdup_printf(_("Unable to connect to authentication server: %s"),
error_message);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
g_free(msg);
}
else if (conn->type == SNAC_FAMILY_LOCATE)
@@ -316,7 +313,7 @@ connection_common_error_cb(FlapConnection *conn, const gchar *error_message)
gchar *msg;
msg = g_strdup_printf(_("Unable to connect to BOS server: %s"),
error_message);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
g_free(msg);
}
else
@@ -578,7 +575,7 @@ idle_reporting_pref_cb(const char *name, PurplePrefType type,
gc = data;
od = purple_connection_get_protocol_data(gc);
report_idle = strcmp((const char *)value, "none") != 0;
- presence = aim_ssi_getpresence(od->ssi.local);
+ presence = aim_ssi_getpresence(&od->ssi.local);
if (report_idle)
aim_ssi_setpresence(od, presence | AIM_SSI_PRESENCE_FLAG_SHOWIDLE);
@@ -600,7 +597,7 @@ recent_buddies_pref_cb(const char *name, PurplePrefType type,
gc = data;
od = purple_connection_get_protocol_data(gc);
- presence = aim_ssi_getpresence(od->ssi.local);
+ presence = aim_ssi_getpresence(&od->ssi.local);
if (value)
aim_ssi_setpresence(od, presence & ~AIM_SSI_PRESENCE_FLAG_NORECENTBUDDIES);
@@ -655,6 +652,7 @@ oscar_login(PurpleAccount *account)
GList *sorted_handlers;
GList *cur;
GString *msg = g_string_new("");
+ PurpleConnectionFlags flags;
gc = purple_account_get_connection(account);
od = oscar_data_new();
@@ -672,7 +670,6 @@ oscar_login(PurpleAccount *account)
/* These are only needed when connecting with the old-style BUCP login */
oscar_data_addhandler(od, SNAC_FAMILY_AUTH, 0x0003, purple_parse_auth_resp, 0);
- oscar_data_addhandler(od, SNAC_FAMILY_AUTH, 0x0007, purple_parse_login, 0);
oscar_data_addhandler(od, SNAC_FAMILY_AUTH, SNAC_SUBTYPE_AUTH_SECURID_REQUEST, purple_parse_auth_securid_request, 0);
oscar_data_addhandler(od, SNAC_FAMILY_BART, SNAC_SUBTYPE_BART_RESPONSE, purple_icon_parseicon, 0);
@@ -735,28 +732,30 @@ oscar_login(PurpleAccount *account)
if (!oscar_util_valid_name(purple_account_get_username(account))) {
gchar *buf;
buf = g_strdup_printf(_("Unable to sign on as %s because the username is invalid. Usernames must be a valid email address, or start with a letter and contain only letters, numbers and spaces, or contain only numbers."), purple_account_get_username(account));
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, buf);
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, buf);
g_free(buf);
return;
}
- gc->flags |= PURPLE_CONNECTION_HTML;
+ flags = PURPLE_CONNECTION_HTML;
if (g_str_equal(purple_account_get_protocol_id(account), "prpl-icq")) {
od->icq = TRUE;
} else {
- gc->flags |= PURPLE_CONNECTION_AUTO_RESP;
+ flags |= PURPLE_CONNECTION_AUTO_RESP;
}
/* Set this flag based on the protocol_id rather than the username,
because that is what's tied to the get_moods prpl callback. */
if (g_str_equal(purple_account_get_protocol_id(account), "prpl-icq"))
- gc->flags |= PURPLE_CONNECTION_SUPPORT_MOODS;
+ flags |= PURPLE_CONNECTION_SUPPORT_MOODS;
+
+ purple_connection_set_flags(gc, flags);
od->default_port = purple_account_get_int(account, "port", OSCAR_DEFAULT_LOGIN_PORT);
encryption_type = purple_account_get_string(account, "encryption", OSCAR_DEFAULT_ENCRYPTION);
if (!purple_ssl_is_supported() && strcmp(encryption_type, OSCAR_REQUIRE_ENCRYPTION) == 0) {
- purple_connection_error_reason(
+ purple_connection_error(
gc,
PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
_("You required encryption in your account settings, but encryption is not supported by your system."));
@@ -825,7 +824,7 @@ oscar_login(PurpleAccount *account)
}
if (newconn->gsc == NULL && newconn->connect_data == NULL) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect"));
return;
}
@@ -1000,7 +999,7 @@ static int purple_memrequest(OscarData *od, FlapConnection *conn, FlapFrame *fr,
pos->len = len;
pos->modname = g_strdup(modname);
- if (purple_proxy_connect(pos->gc, pos->gc->account, "pidgin.im", 80,
+ if (purple_proxy_connect(pos->gc, purple_connection_get_account(pos->gc), "pidgin.im", 80,
straight_to_hell, pos) == NULL)
{
char buf[256];
@@ -1048,7 +1047,7 @@ int oscar_connect_to_bos(PurpleConnection *gc, OscarData *od, const char *host,
if (conn->gsc == NULL && conn->connect_data == NULL)
{
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect"));
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect"));
return 0;
}
@@ -1087,41 +1086,41 @@ purple_parse_auth_resp(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
switch (info->errorcode) {
case 0x01:
/* Unregistered username */
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_INVALID_USERNAME, _("Username does not exist"));
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_INVALID_USERNAME, _("Username does not exist"));
break;
case 0x05:
/* Incorrect password */
if (!purple_account_get_remember_password(account))
purple_account_set_password(account, NULL);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Incorrect password"));
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Incorrect password"));
break;
case 0x11:
/* Suspended account */
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Your account is currently suspended"));
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Your account is currently suspended"));
break;
case 0x02:
case 0x14:
/* service temporarily unavailable */
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("The AOL Instant Messenger service is temporarily unavailable."));
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("The AOL Instant Messenger service is temporarily unavailable."));
break;
case 0x18:
/* username connecting too frequently */
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Your username has been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer."));
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Your username has been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer."));
break;
case 0x1c:
{
/* client too old */
g_snprintf(buf, sizeof(buf), _("The client version you are using is too old. Please upgrade at %s"),
oscar_get_ui_info_string("website", PURPLE_WEBSITE));
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, buf);
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, buf);
break;
}
case 0x1d:
/* IP address connecting too frequently */
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Your IP address has been connecting and disconnecting too frequently. Wait a minute and try again. If you continue to try, you will need to wait even longer."));
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Your IP address has been connecting and disconnecting too frequently. Wait a minute and try again. If you continue to try, you will need to wait even longer."));
break;
default:
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Unknown reason"));
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Unknown reason"));
break;
}
purple_debug_info("oscar", "Login Error Code 0x%04hx\n", info->errorcode);
@@ -1169,7 +1168,7 @@ purple_parse_auth_resp(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
g_free(host);
if (newconn->gsc == NULL && newconn->connect_data == NULL)
{
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect"));
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect"));
return 0;
}
@@ -1199,7 +1198,7 @@ purple_parse_auth_securid_request_no_cb(gpointer user_data, const char *value)
PurpleConnection *gc = user_data;
/* Disconnect */
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
_("The SecurID key entered is invalid"));
}
@@ -1229,38 +1228,6 @@ purple_parse_auth_securid_request(OscarData *od, FlapConnection *conn, FlapFrame
return 1;
}
-/**
- * Only used when connecting with the old-style BUCP login.
- */
-static int
-purple_parse_login(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
-{
- PurpleConnection *gc;
- PurpleAccount *account;
- ClientInfo aiminfo = CLIENTINFO_PURPLE_AIM;
- ClientInfo icqinfo = CLIENTINFO_PURPLE_ICQ;
- va_list ap;
- char *key;
- gboolean truncate_pass;
-
- gc = od->gc;
- account = purple_connection_get_account(gc);
-
- va_start(ap, fr);
- key = va_arg(ap, char *);
- truncate_pass = va_arg(ap, int);
- va_end(ap);
-
- aim_send_login(od, conn, purple_account_get_username(account),
- purple_connection_get_password(gc), truncate_pass,
- od->icq ? &icqinfo : &aiminfo, key,
- purple_account_get_bool(account, "allow_multiple_logins", OSCAR_DEFAULT_ALLOW_MULTIPLE_LOGINS));
-
- purple_connection_update_progress(gc, _("Password sent"), 2, OSCAR_CONNECT_STEPS);
-
- return 1;
-}
-
static int
purple_handle_redirect(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
{
@@ -1292,7 +1259,7 @@ purple_handle_redirect(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
purple_debug_warning("oscar", "We won't use SSL for FLAP type 0x%04hx.\n", redir->group);
} else if (strcmp(encryption_type, OSCAR_REQUIRE_ENCRYPTION) == 0) {
purple_debug_error("oscar", "FLAP server %s:%d of type 0x%04hx doesn't support encryption.", host, port, redir->group);
- purple_connection_error_reason(
+ purple_connection_error(
gc,
PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
_("You required encryption in your account settings, but one of the servers doesn't support it."));
@@ -1547,7 +1514,7 @@ static int purple_parse_offgoing(OscarData *od, FlapConnection *conn, FlapFrame
purple_prpl_got_user_status(account, info->bn, OSCAR_STATUS_ID_OFFLINE, NULL);
purple_prpl_got_user_status_deactive(account, info->bn, OSCAR_STATUS_ID_MOBILE);
- g_hash_table_remove(od->buddyinfo, purple_normalize(gc->account, info->bn));
+ g_hash_table_remove(od->buddyinfo, purple_normalize(purple_connection_get_account(gc), info->bn));
return 1;
}
@@ -2278,7 +2245,7 @@ purple_parse_clientauto_ch2(OscarData *od, const char *who, guint16 reason, cons
return 0;
}
-static int purple_parse_clientauto_ch4(OscarData *od, char *who, guint16 reason, guint32 state, char *msg) {
+static int purple_parse_clientauto_ch4(OscarData *od, const char *who, guint16 reason, guint32 state, char *msg) {
PurpleConnection *gc = od->gc;
switch(reason) {
@@ -2286,16 +2253,20 @@ static int purple_parse_clientauto_ch4(OscarData *od, char *who, guint16 reason,
char *statusmsg, **splitmsg;
PurpleNotifyUserInfo *user_info;
- /* Split at (carriage return/newline)'s, then rejoin later with BRs between. */
statusmsg = oscar_icqstatus(state);
+
+ /* Split at (carriage return/newline)'s, then rejoin later with BRs between. */
+ /* TODO: Don't we need to escape each piece? */
splitmsg = g_strsplit(msg, "\r\n", 0);
user_info = purple_notify_user_info_new();
- purple_notify_user_info_add_pair(user_info, _("UIN"), who);
- purple_notify_user_info_add_pair(user_info, _("Status"), statusmsg);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("UIN"), who);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Status"), statusmsg);
purple_notify_user_info_add_section_break(user_info);
- purple_notify_user_info_add_pair(user_info, NULL, g_strjoinv("<BR>", splitmsg));
+ purple_notify_user_info_add_pair_html(user_info, NULL, g_strjoinv("<BR>", splitmsg));
g_free(statusmsg);
g_strfreev(splitmsg);
@@ -2309,16 +2280,20 @@ static int purple_parse_clientauto_ch4(OscarData *od, char *who, guint16 reason,
char *statusmsg, **splitmsg;
PurpleNotifyUserInfo *user_info;
- /* Split at (carriage return/newline)'s, then rejoin later with BRs between. */
statusmsg = oscar_icqstatus(state);
+
+ /* Split at (carriage return/newline)'s, then rejoin later with BRs between. */
+ /* TODO: Don't we need to escape each piece? */
splitmsg = g_strsplit(msg, "\r\n", 0);
user_info = purple_notify_user_info_new();
- purple_notify_user_info_add_pair(user_info, _("UIN"), who);
- purple_notify_user_info_add_pair(user_info, _("Status"), statusmsg);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("UIN"), who);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Status"), statusmsg);
purple_notify_user_info_add_section_break(user_info);
- purple_notify_user_info_add_pair(user_info, NULL, g_strjoinv("<BR>", splitmsg));
+ purple_notify_user_info_add_pair_html(user_info, NULL, g_strjoinv("<BR>", splitmsg));
g_free(statusmsg);
g_strfreev(splitmsg);
@@ -2808,7 +2783,7 @@ static int purple_parse_locaterights(OscarData *od, FlapConnection *conn, FlapFr
od->rights.maxsiglen = od->rights.maxawaymsglen = (guint)maxsiglen;
aim_locate_setcaps(od, purple_caps);
- oscar_set_info_and_status(account, TRUE, account->user_info, TRUE,
+ oscar_set_info_and_status(account, TRUE, purple_account_get_user_info(account), TRUE,
purple_account_get_active_status(account));
return 1;
@@ -3168,9 +3143,9 @@ oscar_send_typing(PurpleConnection *gc, const char *name, PurpleTypingState stat
else {
/* Don't send if this turkey is in our deny list */
GSList *list;
- for (list=gc->account->deny; (list && oscar_util_name_compare(name, list->data)); list=list->next);
+ for (list=purple_connection_get_account(gc)->deny; (list && oscar_util_name_compare(name, list->data)); list=list->next);
if (!list) {
- struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(gc->account, name));
+ struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(purple_connection_get_account(gc), name));
if (bi && bi->typingnot) {
if (state == PURPLE_TYPING)
aim_im_sendmtn(od, 0x0001, name, 0x0002);
@@ -3211,10 +3186,12 @@ purple_odc_send_im(PeerConnection *conn, const char *message, PurpleMessageFlags
g_string_append_len(msg, last, start - last);
}
- id = g_datalist_get_data(&attribs, "id");
+ id = g_datalist_get_data(&attribs, "src");
/* ... if it refers to a valid purple image ... */
- if (id && (image = purple_imgstore_find_by_id(atoi(id)))) {
+ if (id
+ && strlen(id) > (sizeof(PURPLE_STORED_IMAGE_PROTOCOL) - 1)
+ && (image = purple_imgstore_find_by_id(atoi(id + sizeof(PURPLE_STORED_IMAGE_PROTOCOL) - 1)))) {
/* ... append the message from start to the tag ... */
unsigned long size = purple_imgstore_get_size(image);
const char *filename = purple_imgstore_get_filename(image);
@@ -3470,13 +3447,11 @@ oscar_set_info(PurpleConnection *gc, const char *rawinfo)
static guint32
oscar_get_extended_status(PurpleConnection *gc)
{
- OscarData *od;
PurpleAccount *account;
PurpleStatus *status;
const gchar *status_id;
guint32 data = 0x00000000;
- od = purple_connection_get_protocol_data(gc);
account = purple_connection_get_account(gc);
status = purple_account_get_active_status(account);
status_id = purple_status_get_id(status);
@@ -3716,7 +3691,7 @@ oscar_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, co
}
if (od->ssi.received_data) {
- if (!aim_ssi_itemlist_finditem(od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY)) {
+ if (!aim_ssi_itemlist_finditem(&od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY)) {
purple_debug_info("oscar",
"ssi: adding buddy %s to group %s\n", bname, gname);
aim_ssi_addbuddy(od, bname, gname, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, 0);
@@ -3728,8 +3703,8 @@ oscar_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, co
purple_prpl_got_user_status(account, bname,
OSCAR_STATUS_ID_MOBILE, NULL);
}
- } else if (aim_ssi_waitingforauth(od->ssi.local,
- aim_ssi_itemlist_findparentname(od->ssi.local, bname),
+ } else if (aim_ssi_waitingforauth(&od->ssi.local,
+ aim_ssi_itemlist_findparentname(&od->ssi.local, bname),
bname)) {
/* Not authorized -- Re-request authorization */
oscar_auth_sendrequest(gc, bname, msg);
@@ -3767,7 +3742,7 @@ void oscar_alias_buddy(PurpleConnection *gc, const char *name, const char *alias
OscarData *od = purple_connection_get_protocol_data(gc);
if (od->ssi.received_data) {
- char *gname = aim_ssi_itemlist_findparentname(od->ssi.local, name);
+ char *gname = aim_ssi_itemlist_findparentname(&od->ssi.local, name);
if (gname) {
purple_debug_info("oscar",
"ssi: changing the alias for buddy %s to %s\n", name, alias ? alias : "(none)");
@@ -3784,7 +3759,7 @@ void oscar_rename_group(PurpleConnection *gc, const char *old_name, PurpleGroup
if (od->ssi.received_data) {
const char *gname = purple_group_get_name(group);
- if (aim_ssi_itemlist_finditem(od->ssi.local, gname, NULL, AIM_SSI_TYPE_GROUP)) {
+ if (aim_ssi_itemlist_finditem(&od->ssi.local, gname, NULL, AIM_SSI_TYPE_GROUP)) {
GList *cur, *groups = NULL;
PurpleAccount *account = purple_connection_get_account(gc);
@@ -3798,7 +3773,7 @@ void oscar_rename_group(PurpleConnection *gc, const char *old_name, PurpleGroup
}
purple_account_remove_buddies(account, moved_buddies, groups);
- purple_account_add_buddies(account, moved_buddies);
+ purple_account_add_buddies(account, moved_buddies, NULL);
g_list_free(groups);
purple_debug_info("oscar",
"ssi: moved all buddies from group %s to %s\n", old_name, gname);
@@ -3915,9 +3890,6 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
purple_debug_info("oscar", "ssi: syncing local list and server list\n");
- /* Clean the buddy list */
- aim_ssi_cleanlist(od);
-
/*** Begin code for pruning buddies from local list if they're not in server list ***/
/* Buddies */
@@ -3935,7 +3907,7 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
gname = purple_group_get_name(g);
bname = purple_buddy_get_name(b);
- if (aim_ssi_itemlist_exists(od->ssi.local, bname)) {
+ if (aim_ssi_itemlist_exists(&od->ssi.local, bname)) {
/* If the buddy is an ICQ user then load his nickname */
const char *servernick = purple_blist_node_get_string((PurpleBlistNode*)b, "servernick");
char *alias;
@@ -3944,7 +3916,7 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
serv_got_alias(gc, bname, servernick);
/* Store local alias on server */
- alias = aim_ssi_getalias(od->ssi.local, gname, bname);
+ alias = aim_ssi_getalias(&od->ssi.local, gname, bname);
balias = purple_buddy_get_local_buddy_alias(b);
if (!alias && balias && *balias)
aim_ssi_aliasbuddy(od, gname, bname, balias);
@@ -3967,7 +3939,7 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
while (next != NULL) {
cur = next;
next = next->next;
- if (!aim_ssi_itemlist_finditem(od->ssi.local, NULL, cur->data, AIM_SSI_TYPE_PERMIT)) {
+ if (!aim_ssi_itemlist_finditem(&od->ssi.local, NULL, cur->data, AIM_SSI_TYPE_PERMIT)) {
purple_debug_info("oscar",
"ssi: removing permit %s from local list\n", (const char *)cur->data);
purple_privacy_permit_remove(account, cur->data, TRUE);
@@ -3980,7 +3952,7 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
while (next != NULL) {
cur = next;
next = next->next;
- if (!aim_ssi_itemlist_finditem(od->ssi.local, NULL, cur->data, deny_entry_type)) {
+ if (!aim_ssi_itemlist_finditem(&od->ssi.local, NULL, cur->data, deny_entry_type)) {
purple_debug_info("oscar",
"ssi: removing deny %s from local list\n", (const char *)cur->data);
purple_privacy_deny_remove(account, cur->data, TRUE);
@@ -3988,7 +3960,7 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
}
/* Presence settings (idle time visibility) */
- tmp = aim_ssi_getpresence(od->ssi.local);
+ tmp = aim_ssi_getpresence(&od->ssi.local);
if (tmp != 0xFFFFFFFF) {
const char *idle_reporting_pref;
gboolean report_idle;
@@ -4006,7 +3978,7 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
/*** Begin code for adding from server list to local list ***/
- for (curitem=od->ssi.local; curitem; curitem=curitem->next) {
+ for (curitem=od->ssi.local.data; curitem; curitem=curitem->next) {
if (curitem->name && !g_utf8_validate(curitem->name, -1, NULL)) {
/* Got node with invalid UTF-8 in the name. Skip it. */
purple_debug_warning("oscar", "ssi: server list contains item of "
@@ -4020,17 +3992,17 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
struct aim_ssi_item *groupitem;
char *gname, *gname_utf8, *alias, *alias_utf8;
- groupitem = aim_ssi_itemlist_find(od->ssi.local, curitem->gid, 0x0000);
+ groupitem = aim_ssi_itemlist_find(&od->ssi.local, curitem->gid, 0x0000);
gname = groupitem ? groupitem->name : NULL;
gname_utf8 = oscar_utf8_try_convert(account, od, gname);
- g = purple_find_group(gname_utf8 ? gname_utf8 : _("Orphans"));
+ g = purple_find_group(gname_utf8 ? gname_utf8 : _("Buddies"));
if (g == NULL) {
- g = purple_group_new(gname_utf8 ? gname_utf8 : _("Orphans"));
+ g = purple_group_new(gname_utf8 ? gname_utf8 : _("Buddies"));
purple_blist_add_group(g, NULL);
}
- alias = aim_ssi_getalias(od->ssi.local, gname, curitem->name);
+ alias = aim_ssi_getalias_from_item(curitem);
alias_utf8 = oscar_utf8_try_convert(account, od, alias);
b = purple_find_buddy_in_group(account, curitem->name, g);
@@ -4099,12 +4071,12 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
* a part of your status and not really related to blocking.
*/
if (!od->icq && curitem->data) {
- guint8 perm_deny = aim_ssi_getpermdeny(od->ssi.local);
- if (perm_deny != 0 && perm_deny != account->perm_deny)
+ guint8 perm_deny = aim_ssi_getpermdeny(&od->ssi.local);
+ if (perm_deny != 0 && perm_deny != purple_account_get_privacy_type(account))
{
purple_debug_info("oscar",
- "ssi: changing permdeny from %d to %hhu\n", account->perm_deny, perm_deny);
- account->perm_deny = perm_deny;
+ "ssi: changing permdeny from %d to %hhu\n", purple_account_get_privacy_type(account), perm_deny);
+ purple_account_set_privacy_type(account, perm_deny);
}
}
} break;
@@ -4228,10 +4200,10 @@ purple_ssi_parseaddmod(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
if ((type != 0x0000) || (name == NULL))
return 1;
- gname = aim_ssi_itemlist_findparentname(od->ssi.local, name);
+ gname = aim_ssi_itemlist_findparentname(&od->ssi.local, name);
gname_utf8 = gname ? oscar_utf8_try_convert(account, od, gname) : NULL;
- alias = aim_ssi_getalias(od->ssi.local, gname, name);
+ alias = aim_ssi_getalias(&od->ssi.local, gname, name);
alias_utf8 = oscar_utf8_try_convert(account, od, alias);
g_free(alias);
@@ -4250,13 +4222,13 @@ purple_ssi_parseaddmod(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
*/
b = purple_buddy_new(account, name, alias_utf8);
- if (!(g = purple_find_group(gname_utf8 ? gname_utf8 : _("Orphans")))) {
- g = purple_group_new(gname_utf8 ? gname_utf8 : _("Orphans"));
+ if (!(g = purple_find_group(gname_utf8 ? gname_utf8 : _("Buddies")))) {
+ g = purple_group_new(gname_utf8 ? gname_utf8 : _("Buddies"));
purple_blist_add_group(g, NULL);
}
purple_debug_info("oscar",
- "ssi: adding buddy %s to group %s to local list\n", name, gname_utf8 ? gname_utf8 : _("Orphans"));
+ "ssi: adding buddy %s to group %s to local list\n", name, gname_utf8 ? gname_utf8 : _("Buddies"));
purple_blist_add_buddy(b, NULL, g, NULL);
/* Mobile users should always be online */
@@ -4269,7 +4241,7 @@ purple_ssi_parseaddmod(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
}
- ssi_item = aim_ssi_itemlist_finditem(od->ssi.local,
+ ssi_item = aim_ssi_itemlist_finditem(&od->ssi.local,
gname, name, AIM_SSI_TYPE_BUDDY);
if (ssi_item == NULL)
{
@@ -4608,7 +4580,6 @@ const char *oscar_list_emblem(PurpleBuddy *b)
PurpleAccount *account = NULL;
PurplePresence *presence;
PurpleStatus *status;
- const char *status_id;
aim_userinfo_t *userinfo = NULL;
const char *name;
@@ -4623,13 +4594,12 @@ const char *oscar_list_emblem(PurpleBuddy *b)
presence = purple_buddy_get_presence(b);
status = purple_presence_get_active_status(presence);
- status_id = purple_status_get_id(status);
if (purple_presence_is_online(presence) == FALSE) {
char *gname;
if ((name) && (od) && (od->ssi.received_data) &&
- (gname = aim_ssi_itemlist_findparentname(od->ssi.local, name)) &&
- (aim_ssi_waitingforauth(od->ssi.local, gname, name))) {
+ (gname = aim_ssi_itemlist_findparentname(&od->ssi.local, name)) &&
+ (aim_ssi_waitingforauth(&od->ssi.local, gname, name))) {
return "not-authorized";
}
}
@@ -4682,7 +4652,6 @@ char *oscar_status_text(PurpleBuddy *b)
OscarData *od;
const PurplePresence *presence;
const PurpleStatus *status;
- const char *id;
const char *message;
gchar *ret = NULL;
@@ -4691,13 +4660,12 @@ char *oscar_status_text(PurpleBuddy *b)
od = purple_connection_get_protocol_data(gc);
presence = purple_buddy_get_presence(b);
status = purple_presence_get_active_status(presence);
- id = purple_status_get_id(status);
if ((od != NULL) && !purple_presence_is_online(presence))
{
const char *name = purple_buddy_get_name(b);
- char *gname = aim_ssi_itemlist_findparentname(od->ssi.local, name);
- if (aim_ssi_waitingforauth(od->ssi.local, gname, name))
+ char *gname = aim_ssi_itemlist_findparentname(&od->ssi.local, name);
+ if (aim_ssi_waitingforauth(&od->ssi.local, gname, name))
ret = g_strdup(_("Not Authorized"));
else
ret = g_strdup(_("Offline"));
@@ -4733,7 +4701,7 @@ void oscar_set_aim_permdeny(PurpleConnection *gc) {
* values of libpurple's PurplePrivacyType and the values used
* by the oscar protocol.
*/
- aim_ssi_setpermdeny(od, account->perm_deny);
+ aim_ssi_setpermdeny(od, purple_account_get_privacy_type(account));
}
void oscar_add_permit(PurpleConnection *gc, const char *who) {
@@ -4940,7 +4908,7 @@ static void oscar_buddycb_edit_comment(PurpleBlistNode *node, gpointer ignore) {
data = g_new(struct name_data, 1);
- comment = aim_ssi_getcomment(od->ssi.local, purple_group_get_name(g), name);
+ comment = aim_ssi_getcomment(&od->ssi.local, purple_group_get_name(g), name);
comment_utf8 = comment ? oscar_utf8_try_convert(account, od, comment) : NULL;
data->gc = gc;
@@ -5032,7 +5000,7 @@ oscar_close_directim(gpointer object, gpointer ignored)
name = purple_buddy_get_name(buddy);
account = purple_buddy_get_account(buddy);
gc = purple_account_get_connection(account);
- od = gc->proto_data;
+ od = purple_connection_get_protocol_data(gc);
conn = peer_connection_find_by_type(od, name, OSCAR_CAPABILITY_DIRECTIM);
if (conn != NULL)
@@ -5161,8 +5129,8 @@ oscar_buddy_menu(PurpleBuddy *buddy) {
* waiting for authorization.
*/
char *gname;
- gname = aim_ssi_itemlist_findparentname(od->ssi.local, bname);
- if (gname && aim_ssi_waitingforauth(od->ssi.local, gname, bname))
+ gname = aim_ssi_itemlist_findparentname(&od->ssi.local, bname);
+ if (gname && aim_ssi_waitingforauth(&od->ssi.local, gname, bname))
{
act = purple_menu_action_new(_("Re-request Authorization"),
PURPLE_CALLBACK(oscar_auth_sendrequest_menu),
@@ -5313,7 +5281,7 @@ static void oscar_show_awaitingauth(PurplePluginAction *action)
buddy = cur->data;
bname = purple_buddy_get_name(buddy);
gname = purple_group_get_name(purple_buddy_get_group(buddy));
- if (aim_ssi_waitingforauth(od->ssi.local, gname, bname)) {
+ if (aim_ssi_waitingforauth(&od->ssi.local, gname, bname)) {
filtered_buddies = g_slist_prepend(filtered_buddies, buddy);
}
}
@@ -5468,7 +5436,7 @@ oscar_new_xfer(PurpleConnection *gc, const char *who)
conn->flags |= PEER_CONNECTION_FLAG_APPROVED;
aim_icbm_makecookie(conn->cookie);
conn->xfer = xfer;
- xfer->data = conn;
+ purple_xfer_set_protocol_data(xfer, conn);
}
return xfer;
diff --git a/libpurple/protocols/oscar/oscar.h b/libpurple/protocols/oscar/oscar.h
index fe01cecc48..399efdc364 100644
--- a/libpurple/protocols/oscar/oscar.h
+++ b/libpurple/protocols/oscar/oscar.h
@@ -114,6 +114,8 @@ extern "C" {
#define AIM_MD5_STRING "AOL Instant Messenger (SM)"
+#define OSCAR_CONNECT_STEPS 6
+
/*
* Client info. Filled in by the client and passed in to
* aim_send_login(). The information ends up getting passed to OSCAR
@@ -308,9 +310,14 @@ struct _IcbmCookie
#include "peer.h"
-/*
- * AIM Session: The main client-data interface.
- *
+struct aim_ssi_itemlist {
+ struct aim_ssi_item *data;
+ GHashTable *idx_gid_bid;
+ GHashTable *idx_all_named_items;
+};
+
+/**
+ * The main client-data interface.
*/
struct _OscarData
{
@@ -387,8 +394,8 @@ struct _OscarData
struct {
gboolean received_data;
guint16 numitems;
- struct aim_ssi_item *official;
- struct aim_ssi_item *local;
+ struct aim_ssi_itemlist official;
+ struct aim_ssi_itemlist local;
struct aim_ssi_tmp *pending;
time_t timestamp;
gboolean waiting_for_ack;
@@ -916,15 +923,16 @@ struct aim_ssi_tmp
/* 0x001a */ int aim_ssi_sendauthreply(OscarData *od, const char *bn, guint8 reply, const char *msg);
/* Client functions for retrieving SSI data */
-struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_item *list, guint16 gid, guint16 bid);
-struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_item *list, const char *gn, const char *bn, guint16 type);
-struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_item *list, const char *bn);
-char *aim_ssi_itemlist_findparentname(struct aim_ssi_item *list, const char *bn);
-int aim_ssi_getpermdeny(struct aim_ssi_item *list);
-guint32 aim_ssi_getpresence(struct aim_ssi_item *list);
-char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *bn);
-char *aim_ssi_getcomment(struct aim_ssi_item *list, const char *gn, const char *bn);
-gboolean aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *bn);
+struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_itemlist *list, guint16 gid, guint16 bid);
+struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_itemlist *list, const char *gn, const char *bn, guint16 type);
+struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_itemlist *list, const char *bn);
+char *aim_ssi_itemlist_findparentname(struct aim_ssi_itemlist *list, const char *bn);
+int aim_ssi_getpermdeny(struct aim_ssi_itemlist *list);
+guint32 aim_ssi_getpresence(struct aim_ssi_itemlist *list);
+char *aim_ssi_getalias(struct aim_ssi_itemlist *list, const char *gn, const char *bn);
+char *aim_ssi_getalias_from_item(struct aim_ssi_item *item);
+char *aim_ssi_getcomment(struct aim_ssi_itemlist *list, const char *gn, const char *bn);
+gboolean aim_ssi_waitingforauth(struct aim_ssi_itemlist *list, const char *gn, const char *bn);
/* Client functions for changing SSI data */
int aim_ssi_addbuddy(OscarData *od, const char *name, const char *group, GSList *tlvlist, const char *alias, const char *comment, const char *smsnum, gboolean needauth);
@@ -934,7 +942,6 @@ int aim_ssi_movebuddy(OscarData *od, const char *oldgn, const char *newgn, const
int aim_ssi_aliasbuddy(OscarData *od, const char *gn, const char *bn, const char *alias);
int aim_ssi_editcomment(OscarData *od, const char *gn, const char *bn, const char *alias);
int aim_ssi_rename_group(OscarData *od, const char *oldgn, const char *newgn);
-int aim_ssi_cleanlist(OscarData *od);
int aim_ssi_deletelist(OscarData *od);
int aim_ssi_setpermdeny(OscarData *od, guint8 permdeny);
int aim_ssi_setpresence(OscarData *od, guint32 presence);
diff --git a/libpurple/protocols/oscar/oscar_data.c b/libpurple/protocols/oscar/oscar_data.c
index 5498bba986..6f7ac700e1 100644
--- a/libpurple/protocols/oscar/oscar_data.c
+++ b/libpurple/protocols/oscar/oscar_data.c
@@ -47,6 +47,12 @@ oscar_data_new(void)
od->buddyinfo = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
od->handlerlist = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
+ od->ssi.local.idx_gid_bid = g_hash_table_new(g_direct_hash, g_direct_equal);
+ od->ssi.local.idx_all_named_items = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+
+ od->ssi.official.idx_gid_bid = g_hash_table_new(g_direct_hash, g_direct_equal);
+ od->ssi.official.idx_all_named_items = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+
/*
* Register all the modules for this session...
*/
@@ -126,6 +132,12 @@ oscar_data_destroy(OscarData *od)
g_hash_table_destroy(od->buddyinfo);
g_hash_table_destroy(od->handlerlist);
+ g_hash_table_destroy(od->ssi.local.idx_gid_bid);
+ g_hash_table_destroy(od->ssi.local.idx_all_named_items);
+
+ g_hash_table_destroy(od->ssi.official.idx_gid_bid);
+ g_hash_table_destroy(od->ssi.official.idx_all_named_items);
+
g_free(od);
}
diff --git a/libpurple/protocols/oscar/peer.c b/libpurple/protocols/oscar/peer.c
index 333a5b2940..6dd51ce4e7 100644
--- a/libpurple/protocols/oscar/peer.c
+++ b/libpurple/protocols/oscar/peer.c
@@ -212,7 +212,7 @@ peer_connection_destroy_cb(gpointer data)
if (conn->xfer != NULL)
{
PurpleXferStatusType status;
- conn->xfer->data = NULL;
+ purple_xfer_set_protocol_data(conn->xfer, NULL);
status = purple_xfer_get_status(conn->xfer);
if ((status != PURPLE_XFER_STATUS_DONE) &&
(status != PURPLE_XFER_STATUS_CANCEL_LOCAL) &&
@@ -603,15 +603,11 @@ void
peer_connection_listen_cb(gpointer data, gint source, PurpleInputCondition cond)
{
PeerConnection *conn;
- OscarData *od;
- PurpleConnection *gc;
struct sockaddr addr;
socklen_t addrlen = sizeof(addr);
int flags;
conn = data;
- od = conn->od;
- gc = od->gc;
purple_debug_info("oscar", "Accepting connection on listener socket.\n");
@@ -851,7 +847,7 @@ peer_connection_trynext(PeerConnection *conn)
*/
conn->flags |= PEER_CONNECTION_FLAG_IS_INCOMING;
- conn->listen_data = purple_network_listen_range(5190, 5290, SOCK_STREAM,
+ conn->listen_data = purple_network_listen_range(5190, 5290, AF_UNSPEC, SOCK_STREAM, TRUE,
peer_connection_establish_listener_cb, conn);
if (conn->listen_data != NULL)
{
@@ -1081,7 +1077,7 @@ peer_connection_got_proposition(OscarData *od, const gchar *bn, const gchar *mes
conn->xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE, bn);
if (conn->xfer)
{
- conn->xfer->data = conn;
+ purple_xfer_set_protocol_data(conn->xfer, conn);
purple_xfer_ref(conn->xfer);
purple_xfer_set_size(conn->xfer, args->info.sendfile.totsize);
diff --git a/libpurple/protocols/oscar/userinfo.c b/libpurple/protocols/oscar/userinfo.c
index 76c119247e..60e96af75c 100644
--- a/libpurple/protocols/oscar/userinfo.c
+++ b/libpurple/protocols/oscar/userinfo.c
@@ -131,21 +131,16 @@ oscar_caps_to_string(guint64 caps)
}
static void
-oscar_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *name, const char *value)
-{
- if (value && value[0]) {
- purple_notify_user_info_add_pair(user_info, name, value);
- }
-}
-
-static void
oscar_user_info_convert_and_add(PurpleAccount *account, OscarData *od, PurpleNotifyUserInfo *user_info,
const char *name, const char *value)
{
gchar *utf8;
if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, od, value))) {
- purple_notify_user_info_add_pair(user_info, name, utf8);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext. Will
+ need to check callers of this function. */
+ purple_notify_user_info_add_pair_html(user_info, name, utf8);
g_free(utf8);
}
}
@@ -158,7 +153,10 @@ oscar_user_info_convert_and_add_hyperlink(PurpleAccount *account, OscarData *od,
if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, od, value))) {
gchar *tmp = g_strdup_printf("<a href=\"%s%s\">%s</a>", url_prefix, utf8, utf8);
- purple_notify_user_info_add_pair(user_info, name, tmp);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext. Will
+ need to check callers of this function. */
+ purple_notify_user_info_add_pair_html(user_info, name, tmp);
g_free(utf8);
g_free(tmp);
}
@@ -263,8 +261,8 @@ oscar_user_info_append_status(PurpleConnection *gc, PurpleNotifyUserInfo *user_i
message = tmp;
}
- } else if (aim_ssi_waitingforauth(od->ssi.local,
- aim_ssi_itemlist_findparentname(od->ssi.local, purple_buddy_get_name(b)),
+ } else if (aim_ssi_waitingforauth(&od->ssi.local,
+ aim_ssi_itemlist_findparentname(&od->ssi.local, purple_buddy_get_name(b)),
purple_buddy_get_name(b)))
{
/* Note if an offline buddy is not authorized */
@@ -295,12 +293,12 @@ oscar_user_info_append_status(PurpleConnection *gc, PurpleNotifyUserInfo *user_i
} else {
description = g_strdup(_(mood));
}
- purple_notify_user_info_add_pair(user_info, _("Mood"), description);
+ purple_notify_user_info_add_pair_html(user_info, _("Mood"), description);
g_free(description);
}
}
- purple_notify_user_info_add_pair(user_info, _("Status"), message);
+ purple_notify_user_info_add_pair_html(user_info, _("Status"), message);
g_free(message);
}
@@ -309,8 +307,6 @@ oscar_user_info_append_extra_info(PurpleConnection *gc, PurpleNotifyUserInfo *us
{
OscarData *od;
PurpleAccount *account;
- PurplePresence *presence = NULL;
- PurpleStatus *status = NULL;
PurpleGroup *g = NULL;
struct buddyinfo *bi = NULL;
char *tmp;
@@ -332,31 +328,29 @@ oscar_user_info_append_extra_info(PurpleConnection *gc, PurpleNotifyUserInfo *us
bname = purple_buddy_get_name(b);
g = purple_buddy_get_group(b);
gname = purple_group_get_name(g);
- presence = purple_buddy_get_presence(b);
- status = purple_presence_get_active_status(presence);
}
if (userinfo != NULL)
bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, userinfo->bn));
if ((bi != NULL) && (bi->ipaddr != 0)) {
- tmp = g_strdup_printf("%hhu.%hhu.%hhu.%hhu",
- (bi->ipaddr & 0xff000000) >> 24,
- (bi->ipaddr & 0x00ff0000) >> 16,
- (bi->ipaddr & 0x0000ff00) >> 8,
- (bi->ipaddr & 0x000000ff));
- oscar_user_info_add_pair(user_info, _("IP Address"), tmp);
- g_free(tmp);
+ char tmp2[40];
+ sprintf(tmp2, "%hhu.%hhu.%hhu.%hhu",
+ (bi->ipaddr & 0xff000000) >> 24,
+ (bi->ipaddr & 0x00ff0000) >> 16,
+ (bi->ipaddr & 0x0000ff00) >> 8,
+ (bi->ipaddr & 0x000000ff));
+ purple_notify_user_info_add_pair_plaintext(user_info, _("IP Address"), tmp2);
}
if ((userinfo != NULL) && (userinfo->warnlevel != 0)) {
- tmp = g_strdup_printf("%d", (int)(userinfo->warnlevel/10.0 + .5));
- oscar_user_info_add_pair(user_info, _("Warning Level"), tmp);
- g_free(tmp);
+ char tmp2[12];
+ sprintf(tmp2, "%d", (int)(userinfo->warnlevel/10.0 + .5));
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Warning Level"), tmp2);
}
if ((b != NULL) && (bname != NULL) && (g != NULL) && (gname != NULL)) {
- tmp = aim_ssi_getcomment(od->ssi.local, gname, bname);
+ tmp = aim_ssi_getcomment(&od->ssi.local, gname, bname);
if (tmp != NULL) {
char *tmp2 = g_markup_escape_text(tmp, strlen(tmp));
g_free(tmp);
@@ -372,7 +366,7 @@ oscar_user_info_display_error(OscarData *od, guint16 error_reason, gchar *buddy)
{
PurpleNotifyUserInfo *user_info = purple_notify_user_info_new();
gchar *buf = g_strdup_printf(_("User information not available: %s"), oscar_get_msgerr_reason(error_reason));
- purple_notify_user_info_add_pair(user_info, NULL, buf);
+ purple_notify_user_info_add_pair_plaintext(user_info, NULL, buf);
purple_notify_userinfo(od->gc, buddy, user_info, NULL, NULL);
purple_notify_user_info_destroy(user_info);
purple_conv_present_error(buddy, purple_connection_get_account(od->gc), buf);
@@ -402,16 +396,16 @@ oscar_user_info_display_icq(OscarData *od, struct aim_icq_info *info)
else
bi = NULL;
- purple_notify_user_info_add_pair(user_info, _("UIN"), who);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("UIN"), who);
oscar_user_info_convert_and_add(account, od, user_info, _("Nick"), info->nick);
if ((bi != NULL) && (bi->ipaddr != 0)) {
- char *tstr = g_strdup_printf("%hhu.%hhu.%hhu.%hhu",
- (bi->ipaddr & 0xff000000) >> 24,
- (bi->ipaddr & 0x00ff0000) >> 16,
- (bi->ipaddr & 0x0000ff00) >> 8,
- (bi->ipaddr & 0x000000ff));
- purple_notify_user_info_add_pair(user_info, _("IP Address"), tstr);
- g_free(tstr);
+ char tstr[40];
+ sprintf(tstr, "%hhu.%hhu.%hhu.%hhu",
+ (bi->ipaddr & 0xff000000) >> 24,
+ (bi->ipaddr & 0x00ff0000) >> 16,
+ (bi->ipaddr & 0x0000ff00) >> 8,
+ (bi->ipaddr & 0x000000ff));
+ purple_notify_user_info_add_pair_plaintext(user_info, _("IP Address"), tstr);
}
oscar_user_info_convert_and_add(account, od, user_info, _("First Name"), info->first);
oscar_user_info_convert_and_add(account, od, user_info, _("Last Name"), info->last);
@@ -425,7 +419,7 @@ oscar_user_info_display_icq(OscarData *od, struct aim_icq_info *info)
oscar_user_info_convert_and_add(account, od, user_info, _("Mobile Phone"), info->mobile);
if (info->gender != 0)
- purple_notify_user_info_add_pair(user_info, _("Gender"), (info->gender == 1 ? _("Female") : _("Male")));
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Gender"), (info->gender == 1 ? _("Female") : _("Male")));
if ((info->birthyear > 1900) && (info->birthmonth > 0) && (info->birthday > 0)) {
/* Initialize the struct properly or strftime() will crash
@@ -437,7 +431,7 @@ oscar_user_info_display_icq(OscarData *od, struct aim_icq_info *info)
tm->tm_mon = (int)info->birthmonth - 1;
tm->tm_year = (int)info->birthyear - 1900;
- /* Ignore dst setting of today to avoid timezone shift between
+ /* Ignore dst setting of today to avoid timezone shift between
* dates in summer and winter time. */
tm->tm_isdst = -1;
@@ -451,8 +445,9 @@ oscar_user_info_display_icq(OscarData *od, struct aim_icq_info *info)
if ((info->age > 0) && (info->age < 255)) {
char age[5];
snprintf(age, sizeof(age), "%hhd", info->age);
- purple_notify_user_info_add_pair(user_info, _("Age"), age);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Age"), age);
}
+ /* TODO: Is it correct to pass info->email here...? */
oscar_user_info_convert_and_add_hyperlink(account, od, user_info, _("Personal Web Page"), info->email, "");
if (buddy != NULL)
oscar_user_info_append_status(gc, user_info, buddy, /* aim_userinfo_t */ NULL, /* use_html_status */ TRUE);
@@ -482,6 +477,7 @@ oscar_user_info_display_icq(OscarData *od, struct aim_icq_info *info)
oscar_user_info_convert_and_add(account, od, user_info, _("Company"), info->workcompany);
oscar_user_info_convert_and_add(account, od, user_info, _("Division"), info->workdivision);
oscar_user_info_convert_and_add(account, od, user_info, _("Position"), info->workposition);
+ /* TODO: Is it correct to pass info->email here...? */
oscar_user_info_convert_and_add_hyperlink(account, od, user_info, _("Web Page"), info->email, "");
}
@@ -505,7 +501,7 @@ oscar_user_info_display_aim(OscarData *od, aim_userinfo_t *userinfo)
if ((userinfo->present & AIM_USERINFO_PRESENT_IDLE) && userinfo->idletime != 0) {
tmp = purple_str_seconds_to_string(userinfo->idletime*60);
- oscar_user_info_add_pair(user_info, _("Idle"), tmp);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Idle"), tmp);
g_free(tmp);
}
@@ -514,17 +510,18 @@ oscar_user_info_display_aim(OscarData *od, aim_userinfo_t *userinfo)
if ((userinfo->present & AIM_USERINFO_PRESENT_ONLINESINCE) && !oscar_util_valid_name_sms(userinfo->bn)) {
/* An SMS contact is always online; its Online Since value is not useful */
time_t t = userinfo->onlinesince;
- oscar_user_info_add_pair(user_info, _("Online Since"), purple_date_format_full(localtime(&t)));
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Online Since"), purple_date_format_full(localtime(&t)));
}
if (userinfo->present & AIM_USERINFO_PRESENT_MEMBERSINCE) {
time_t t = userinfo->membersince;
- oscar_user_info_add_pair(user_info, _("Member Since"), purple_date_format_full(localtime(&t)));
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Member Since"), purple_date_format_full(localtime(&t)));
}
if (userinfo->capabilities != 0) {
tmp = oscar_caps_to_string(userinfo->capabilities);
- oscar_user_info_add_pair(user_info, _("Capabilities"), tmp);
+ if (tmp && *tmp)
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Capabilities"), tmp);
g_free(tmp);
}
@@ -533,7 +530,11 @@ oscar_user_info_display_aim(OscarData *od, aim_userinfo_t *userinfo)
info_utf8 = oscar_encoding_to_utf8(userinfo->info_encoding, userinfo->info, userinfo->info_len);
tmp = oscar_util_format_string(info_utf8, purple_account_get_username(account));
purple_notify_user_info_add_section_break(user_info);
- oscar_user_info_add_pair(user_info, _("Profile"), tmp);
+ if (tmp && *tmp) {
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Profile"), tmp);
+ }
g_free(tmp);
g_free(info_utf8);
}
@@ -542,9 +543,9 @@ oscar_user_info_display_aim(OscarData *od, aim_userinfo_t *userinfo)
base_profile_url = oscar_util_valid_name_icq(userinfo->bn) ? "http://www.icq.com/people" : "http://profiles.aim.com";
tmp = g_strdup_printf("<a href=\"%s/%s\">%s</a>",
base_profile_url, purple_normalize(account, userinfo->bn), _("View web profile"));
- purple_notify_user_info_add_pair(user_info, NULL, tmp);
+ purple_notify_user_info_add_pair_html(user_info, NULL, tmp);
g_free(tmp);
purple_notify_userinfo(gc, userinfo->bn, user_info, NULL, NULL);
purple_notify_user_info_destroy(user_info);
-} \ No newline at end of file
+}
diff --git a/libpurple/protocols/oscar/visibility.c b/libpurple/protocols/oscar/visibility.c
index d6aa589d8c..3c091a9781 100644
--- a/libpurple/protocols/oscar/visibility.c
+++ b/libpurple/protocols/oscar/visibility.c
@@ -51,7 +51,7 @@ get_buddy_list_type(OscarData *od)
static gboolean
is_buddy_on_list(OscarData *od, const char *bname)
{
- return aim_ssi_itemlist_finditem(od->ssi.local, NULL, bname, get_buddy_list_type(od)) != NULL;
+ return aim_ssi_itemlist_finditem(&od->ssi.local, NULL, bname, get_buddy_list_type(od)) != NULL;
}
static void
@@ -102,7 +102,7 @@ show_private_list(PurplePluginAction *action, guint16 list_type, const gchar *ti
buddy = cur->data;
bname = purple_buddy_get_name(buddy);
- if (aim_ssi_itemlist_finditem(od->ssi.local, NULL, bname, list_type)) {
+ if (aim_ssi_itemlist_finditem(&od->ssi.local, NULL, bname, list_type)) {
filtered_buddies = g_slist_prepend(filtered_buddies, buddy);
}
}
diff --git a/libpurple/protocols/sametime/sametime.c b/libpurple/protocols/sametime/sametime.c
index 62c8173b53..938184ec31 100644
--- a/libpurple/protocols/sametime/sametime.c
+++ b/libpurple/protocols/sametime/sametime.c
@@ -197,7 +197,7 @@ static guint log_handler[2] = { 0, 0 };
/** the purple plugin data.
- available as gc->proto_data and mwSession_getClientData */
+ available as purple_connection_get_protocol_data(gc) and mwSession_getClientData */
struct mwPurplePluginData {
struct mwSession *session;
@@ -217,6 +217,7 @@ struct mwPurplePluginData {
/** socket fd */
int socket;
+ guint inpa; /* input watcher */
gint outpa; /* like inpa, but the other way */
/** circular buffer for outgoing data */
@@ -320,7 +321,7 @@ static struct mwSession *gc_to_session(PurpleConnection *gc) {
g_return_val_if_fail(gc != NULL, NULL);
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
g_return_val_if_fail(pd != NULL, NULL);
return pd->session;
@@ -413,7 +414,7 @@ static int mw_session_io_write(struct mwSession *session,
g_strerror(errno));
DEBUG_ERROR("write returned %" G_GSSIZE_FORMAT ", %" G_GSIZE_FORMAT
" bytes left unwritten\n", ret, len);
- purple_connection_error_reason(pd->gc,
+ purple_connection_error(pd->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
tmp);
g_free(tmp);
@@ -449,9 +450,9 @@ static void mw_session_io_close(struct mwSession *session) {
pd->socket = 0;
}
- if(gc->inpa) {
- purple_input_remove(gc->inpa);
- gc->inpa = 0;
+ if(pd->inpa) {
+ purple_input_remove(pd->inpa);
+ pd->inpa = 0;
}
}
@@ -499,7 +500,7 @@ static void mw_aware_list_on_aware(struct mwAwareList *list,
gc = mwAwareList_getClientData(list);
acct = purple_connection_get_account(gc);
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
idle = aware->status.time;
stat = aware->status.status;
id = aware->id.user;
@@ -851,7 +852,7 @@ static void buddy_add(struct mwPurplePluginData *pd,
static PurpleBuddy *buddy_ensure(PurpleConnection *gc, PurpleGroup *group,
struct mwSametimeUser *stuser) {
- struct mwPurplePluginData *pd = gc->proto_data;
+ struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc);
PurpleBuddy *buddy;
PurpleAccount *acct = purple_connection_get_account(gc);
@@ -861,7 +862,7 @@ static PurpleBuddy *buddy_ensure(PurpleConnection *gc, PurpleGroup *group,
enum mwSametimeUserType type = mwSametimeUser_getType(stuser);
g_return_val_if_fail(id != NULL, NULL);
- g_return_val_if_fail(strlen(id) > 0, NULL);
+ g_return_val_if_fail(*id, NULL);
buddy = purple_find_buddy_in_group(acct, id, group);
if(! buddy) {
@@ -973,7 +974,7 @@ static PurpleGroup *group_ensure(PurpleConnection *gc,
if(type == mwSametimeGroup_DYNAMIC) {
purple_blist_node_set_string(gn, GROUP_KEY_OWNER, owner);
- group_add(gc->proto_data, group);
+ group_add(purple_connection_get_protocol_data(gc), group);
}
return group;
@@ -1279,7 +1280,7 @@ static void conversation_created_cb(PurpleConversation *g_conv,
struct mwIdBlock who = { 0, 0 };
struct mwConversation *conv;
- gc = purple_conversation_get_gc(g_conv);
+ gc = purple_conversation_get_connection(g_conv);
if(pd->gc != gc)
return; /* not ours */
@@ -1403,7 +1404,7 @@ static void blist_init(PurpleAccount *acct) {
}
if(add_buds) {
- purple_account_add_buddies(acct, add_buds);
+ purple_account_add_buddies(acct, add_buds, NULL);
g_list_free(add_buds);
}
}
@@ -1618,7 +1619,7 @@ static void mw_session_stateChange(struct mwSession *session,
default:
reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
}
- purple_connection_error_reason(gc, reason, err);
+ purple_connection_error(gc, reason, err);
g_free(err);
}
break;
@@ -1760,14 +1761,14 @@ static void read_cb(gpointer data, gint source, PurpleInputCondition cond) {
pd->socket = 0;
}
- if(pd->gc->inpa) {
- purple_input_remove(pd->gc->inpa);
- pd->gc->inpa = 0;
+ if(pd->inpa) {
+ purple_input_remove(pd->inpa);
+ pd->inpa = 0;
}
if(! ret) {
DEBUG_INFO("connection reset\n");
- purple_connection_error_reason(pd->gc,
+ purple_connection_error(pd->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Server closed the connection"));
@@ -1778,7 +1779,7 @@ static void read_cb(gpointer data, gint source, PurpleInputCondition cond) {
DEBUG_INFO("error in read callback: %s\n", err_str);
msg = g_strdup_printf(_("Lost connection with server: %s"), err_str);
- purple_connection_error_reason(pd->gc,
+ purple_connection_error(pd->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
msg);
g_free(msg);
@@ -1791,7 +1792,6 @@ static void read_cb(gpointer data, gint source, PurpleInputCondition cond) {
static void connect_cb(gpointer data, gint source, const gchar *error_message) {
struct mwPurplePluginData *pd = data;
- PurpleConnection *gc = pd->gc;
if(source < 0) {
/* connection failed */
@@ -1804,7 +1804,7 @@ static void connect_cb(gpointer data, gint source, const gchar *error_message) {
/* this is a regular connect, error out */
gchar *tmp = g_strdup_printf(_("Unable to connect: %s"),
error_message);
- purple_connection_error_reason(pd->gc,
+ purple_connection_error(pd->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
tmp);
g_free(tmp);
@@ -1819,7 +1819,7 @@ static void connect_cb(gpointer data, gint source, const gchar *error_message) {
}
pd->socket = source;
- gc->inpa = purple_input_add(source, PURPLE_INPUT_READ,
+ pd->inpa = purple_input_add(source, PURPLE_INPUT_READ,
read_cb, pd);
mwSession_start(pd->session);
@@ -2144,7 +2144,7 @@ static struct mwServiceConference *mw_srvc_conf_new(struct mwSession *s) {
static void ft_incoming_cancel(PurpleXfer *xfer) {
/* incoming transfer rejected or cancelled in-progress */
- struct mwFileTransfer *ft = xfer->data;
+ struct mwFileTransfer *ft = purple_xfer_get_protocol_data(xfer);
if(ft) mwFileTransfer_reject(ft);
}
@@ -2160,9 +2160,9 @@ static void ft_incoming_init(PurpleXfer *xfer) {
struct mwFileTransfer *ft;
FILE *fp;
- ft = xfer->data;
+ ft = purple_xfer_get_protocol_data(xfer);
- fp = g_fopen(xfer->local_filename, "wb");
+ fp = g_fopen(purple_xfer_get_local_filename(xfer), "wb");
if(! fp) {
mwFileTransfer_cancel(ft);
return;
@@ -2207,7 +2207,7 @@ static void mw_ft_offered(struct mwFileTransfer *ft) {
{
purple_xfer_ref(xfer);
mwFileTransfer_setClientData(ft, xfer, (GDestroyNotify) purple_xfer_unref);
- xfer->data = ft;
+ purple_xfer_set_protocol_data(xfer, ft);
purple_xfer_set_init_fnc(xfer, ft_incoming_init);
purple_xfer_set_cancel_recv_fnc(xfer, ft_incoming_cancel);
@@ -2236,8 +2236,7 @@ static void ft_send(struct mwFileTransfer *ft, FILE *fp) {
if(fread(buf, (size_t) o.len, 1, fp)) {
/* calculate progress and display it */
- xfer->bytes_sent += o.len;
- xfer->bytes_remaining -= o.len;
+ purple_xfer_set_bytes_sent(xfer, purple_xfer_get_bytes_sent(xfer) + o.len);
purple_xfer_update_progress(xfer);
mwFileTransfer_send(ft, &o);
@@ -2269,7 +2268,7 @@ static void mw_ft_opened(struct mwFileTransfer *ft) {
}
if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
- xfer->dest_fp = g_fopen(xfer->local_filename, "rb");
+ xfer->dest_fp = g_fopen(purple_xfer_get_local_filename(xfer), "rb");
ft_send(ft, xfer->dest_fp);
}
}
@@ -2286,7 +2285,7 @@ static void mw_ft_closed(struct mwFileTransfer *ft, guint32 code) {
xfer = mwFileTransfer_getClientData(ft);
if(xfer) {
- xfer->data = NULL;
+ purple_xfer_set_protocol_data(xfer, NULL);
if(! mwFileTransfer_getRemaining(ft)) {
purple_xfer_set_completed(xfer, TRUE);
@@ -2339,8 +2338,7 @@ static void mw_ft_recv(struct mwFileTransfer *ft,
}
/* update the progress */
- xfer->bytes_sent += data->len;
- xfer->bytes_remaining -= data->len;
+ purple_xfer_set_bytes_sent(xfer, purple_xfer_get_bytes_sent(xfer) + data->len);
purple_xfer_update_progress(xfer);
/* let the other side know we got it, and to send some more */
@@ -2353,7 +2351,7 @@ static void mw_ft_ack(struct mwFileTransfer *ft) {
xfer = mwFileTransfer_getClientData(ft);
g_return_if_fail(xfer != NULL);
- g_return_if_fail(xfer->watcher == 0);
+ g_return_if_fail(purple_xfer_get_watcher(xfer) == 0);
if(! mwFileTransfer_getRemaining(ft)) {
purple_xfer_set_completed(xfer, TRUE);
@@ -2487,12 +2485,12 @@ static void convo_error(struct mwConversation *conv, guint32 err) {
text = g_strconcat(_("Unable to send message: "), tmp, NULL);
gconv = convo_get_gconv(conv);
- if(gconv && !purple_conv_present_error(idb->user, gconv->account, text)) {
+ if(gconv && !purple_conv_present_error(idb->user, purple_conversation_get_account(gconv), text)) {
g_free(text);
text = g_strdup_printf(_("Unable to send message to %s:"),
(idb->user)? idb->user: "(unknown)");
- purple_notify_error(purple_account_get_connection(gconv->account),
+ purple_notify_error(purple_account_get_connection(purple_conversation_get_account(gconv)),
NULL, text, tmp);
}
@@ -2530,10 +2528,10 @@ static void convo_nofeatures(struct mwConversation *conv) {
gconv = convo_get_gconv(conv);
if(! gconv) return;
- gc = purple_conversation_get_gc(gconv);
+ gc = purple_conversation_get_connection(gconv);
if(! gc) return;
- purple_conversation_set_features(gconv, gc->flags);
+ purple_conversation_set_features(gconv, purple_connection_get_flags(gc));
}
@@ -2835,7 +2833,7 @@ static void im_recv_mime(struct mwConversation *conv,
if(align) g_string_append_printf(atstr, " align=\"%s\"", align);
if(border) g_string_append_printf(atstr, " border=\"%s\"", border);
- mov = g_snprintf(start, len, "<img%s id=\"%i\"", atstr->str, img);
+ mov = g_snprintf(start, len, "<img%s src=\"" PURPLE_STORED_IMAGE_PROTOCOL "%i\"", atstr->str, img);
while(mov < len) start[mov++] = ' ';
g_string_free(atstr, TRUE);
@@ -3199,7 +3197,7 @@ static struct mwPurplePluginData *mwPurplePluginData_new(PurpleConnection *gc) {
mwSession_addCipher(pd->session, mwCipher_new_RC2_128(pd->session));
mwSession_setClientData(pd->session, pd, NULL);
- gc->proto_data = pd;
+ purple_connection_set_protocol_data(gc, pd);
return pd;
}
@@ -3208,7 +3206,7 @@ static struct mwPurplePluginData *mwPurplePluginData_new(PurpleConnection *gc) {
static void mwPurplePluginData_free(struct mwPurplePluginData *pd) {
g_return_if_fail(pd != NULL);
- pd->gc->proto_data = NULL;
+ purple_connection_set_protocol_data(pd->gc, NULL);
mwSession_removeService(pd->session, mwService_AWARE);
mwSession_removeService(pd->session, mwService_CONFERENCE);
@@ -3270,7 +3268,7 @@ static char *mw_prpl_status_text(PurpleBuddy *b) {
const char *ret = NULL;
if ((gc = purple_account_get_connection(purple_buddy_get_account(b)))
- && (pd = gc->proto_data))
+ && (pd = purple_connection_get_protocol_data(gc)))
ret = mwServiceAware_getText(pd->srvc_aware, &t);
return (ret && g_utf8_validate(ret, -1, NULL)) ? g_markup_escape_text(ret, -1): NULL;
@@ -3333,29 +3331,27 @@ static void mw_prpl_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info
char *tmp;
if ((gc = purple_account_get_connection(purple_buddy_get_account(b)))
- && (pd = gc->proto_data))
+ && (pd = purple_connection_get_protocol_data(gc)))
message = mwServiceAware_getText(pd->srvc_aware, &idb);
status = status_text(b);
if(message != NULL && g_utf8_validate(message, -1, NULL) && purple_utf8_strcasecmp(status, message)) {
- tmp = g_markup_escape_text(message, -1);
- purple_notify_user_info_add_pair(user_info, status, tmp);
- g_free(tmp);
+ purple_notify_user_info_add_pair_plaintext(user_info, status, message);
} else {
- purple_notify_user_info_add_pair(user_info, _("Status"), status);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), status);
}
if(full && pd != NULL) {
tmp = user_supports_text(pd->srvc_aware, purple_buddy_get_name(b));
if(tmp) {
- purple_notify_user_info_add_pair(user_info, _("Supports"), tmp);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Supports"), tmp);
g_free(tmp);
}
if(buddy_is_external(b)) {
- purple_notify_user_info_add_pair(user_info, NULL, _("External User"));
+ purple_notify_user_info_add_pair_plaintext(user_info, NULL, _("External User"));
}
}
}
@@ -3412,7 +3408,7 @@ static void conf_create_prompt_join(PurpleBuddy *buddy,
acct = purple_buddy_get_account(buddy);
gc = purple_account_get_connection(acct);
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
srvc = pd->srvc_conf;
f = purple_request_fields_get_field(fields, CHAT_KEY_TOPIC);
@@ -3578,7 +3574,7 @@ static void blist_menu_conf(PurpleBlistNode *node, gpointer data) {
gc = purple_account_get_connection(acct);
g_return_if_fail(gc != NULL);
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
g_return_if_fail(pd != NULL);
/*
@@ -3617,7 +3613,7 @@ static void blist_menu_announce(PurpleBlistNode *node, gpointer data) {
gc = purple_account_get_connection(acct);
g_return_if_fail(gc != NULL);
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
g_return_if_fail(pd != NULL);
rcpt_name = g_strdup_printf("@U %s", buddy->name);
@@ -3705,7 +3701,7 @@ static void mw_prpl_login(PurpleAccount *account) {
pd = mwPurplePluginData_new(gc);
/* while we do support images, the default is to not offer it */
- gc->flags |= PURPLE_CONNECTION_NO_IMAGES;
+ purple_connection_set_flags(gc, PURPLE_CONNECTION_NO_IMAGES);
user = g_strdup(purple_account_get_username(account));
@@ -3725,7 +3721,7 @@ static void mw_prpl_login(PurpleAccount *account) {
/* somehow, we don't have a host to connect to. Well, we need one
to actually continue, so let's ask the user directly. */
g_free(user);
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
_("A server is required to connect this account"));
return;
@@ -3770,7 +3766,7 @@ static void mw_prpl_login(PurpleAccount *account) {
purple_connection_update_progress(gc, _("Connecting"), 1, MW_CONNECT_STEPS);
if (purple_proxy_connect(gc, account, host, port, connect_cb, pd) == NULL) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect"));
}
}
@@ -3781,7 +3777,7 @@ static void mw_prpl_close(PurpleConnection *gc) {
g_return_if_fail(gc != NULL);
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
g_return_if_fail(pd != NULL);
/* get rid of the blist save timeout */
@@ -3795,12 +3791,12 @@ static void mw_prpl_close(PurpleConnection *gc) {
mwSession_stop(pd->session, 0x00);
/* no longer necessary */
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
/* stop watching the socket */
- if(gc->inpa) {
- purple_input_remove(gc->inpa);
- gc->inpa = 0;
+ if(pd->inpa) {
+ purple_input_remove(pd->inpa);
+ pd->inpa = 0;
}
/* clean up the rest */
@@ -3986,7 +3982,7 @@ static int mw_prpl_send_im(PurpleConnection *gc,
struct mwConversation *conv;
g_return_val_if_fail(gc != NULL, 0);
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
g_return_val_if_fail(pd != NULL, 0);
@@ -4061,7 +4057,7 @@ static unsigned int mw_prpl_send_typing(PurpleConnection *gc,
gpointer t = GINT_TO_POINTER(!! state);
g_return_val_if_fail(gc != NULL, 0);
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
g_return_val_if_fail(pd != NULL, 0);
@@ -4157,53 +4153,54 @@ static void mw_prpl_get_info(PurpleConnection *gc, const char *who) {
g_return_if_fail(who != NULL);
g_return_if_fail(*who != '\0');
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
acct = purple_connection_get_account(gc);
b = purple_find_buddy(acct, who);
user_info = purple_notify_user_info_new();
if(purple_str_has_prefix(who, "@E ")) {
- purple_notify_user_info_add_pair(user_info, _("External User"), NULL);
+ purple_notify_user_info_add_pair_html(user_info, _("External User"), NULL);
}
- purple_notify_user_info_add_pair(user_info, _("User ID"), who);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("User ID"), who);
if(b) {
guint32 type;
if(purple_buddy_get_server_alias(b)) {
- purple_notify_user_info_add_pair(user_info, _("Full Name"), purple_buddy_get_server_alias(b));
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Full Name"), purple_buddy_get_server_alias(b));
}
type = purple_blist_node_get_int((PurpleBlistNode *) b, BUDDY_KEY_CLIENT);
if(type) {
- tmp = g_strdup(mw_client_name(type));
- if (!tmp)
+ tmp2 = mw_client_name(type);
+ if (tmp2) {
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Last Known Client"), tmp2);
+ } else {
tmp = g_strdup_printf(_("Unknown (0x%04x)<br>"), type);
-
- purple_notify_user_info_add_pair(user_info, _("Last Known Client"), tmp);
-
- g_free(tmp);
+ purple_notify_user_info_add_pair_html(user_info, _("Last Known Client"), tmp);
+ g_free(tmp);
+ }
}
}
tmp = user_supports_text(pd->srvc_aware, who);
if(tmp) {
- purple_notify_user_info_add_pair(user_info, _("Supports"), tmp);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Supports"), tmp);
g_free(tmp);
}
if(b) {
- purple_notify_user_info_add_pair(user_info, _("Status"), status_text(b));
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), status_text(b));
/* XXX Is this adding a status message in its own section rather than with the "Status" label? */
tmp2 = mwServiceAware_getText(pd->srvc_aware, &idb);
if(tmp2 && g_utf8_validate(tmp2, -1, NULL)) {
- tmp = g_markup_escape_text(tmp2, -1);
purple_notify_user_info_add_section_break(user_info);
- purple_notify_user_info_add_pair(user_info, NULL, tmp);
- g_free(tmp);
+ purple_notify_user_info_add_pair_plaintext(user_info, NULL, tmp2);
}
}
@@ -4401,7 +4398,7 @@ static void add_buddy_resolved(struct mwServiceResolve *srvc,
buddy = data->buddy;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
if(results)
res = results->data;
@@ -4480,9 +4477,10 @@ static void add_buddy_resolved(struct mwServiceResolve *srvc,
static void mw_prpl_add_buddy(PurpleConnection *gc,
PurpleBuddy *buddy,
- PurpleGroup *group) {
+ PurpleGroup *group,
+ const char *message) {
- struct mwPurplePluginData *pd = gc->proto_data;
+ struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc);
struct mwServiceResolve *srvc;
GList *query;
enum mwResolveFlag flags;
@@ -4527,13 +4525,14 @@ static void foreach_add_buddies(PurpleGroup *group, GList *buddies,
static void mw_prpl_add_buddies(PurpleConnection *gc,
GList *buddies,
- GList *groups) {
+ GList *groups,
+ const char *message) {
struct mwPurplePluginData *pd;
GHashTable *group_sets;
struct mwAwareIdBlock *idbs, *idb;
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
/* map PurpleGroup:GList of mwAwareIdBlock */
group_sets = g_hash_table_new(g_direct_hash, g_direct_equal);
@@ -4584,7 +4583,7 @@ static void mw_prpl_remove_buddy(PurpleConnection *gc,
GList *rem = g_list_prepend(NULL, &idb);
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
group = purple_buddy_get_group(buddy);
list = list_ensure(pd, group);
@@ -4631,13 +4630,13 @@ static void mw_prpl_set_permit_deny(PurpleConnection *gc) {
acct = purple_connection_get_account(gc);
g_return_if_fail(acct != NULL);
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
g_return_if_fail(pd != NULL);
session = pd->session;
g_return_if_fail(session != NULL);
- switch(acct->perm_deny) {
+ switch(purple_account_get_privacy_type(acct)) {
case PURPLE_PRIVACY_DENY_USERS:
DEBUG_INFO("PURPLE_PRIVACY_DENY_USERS\n");
privacy_fill(&privacy, acct->deny);
@@ -4661,7 +4660,7 @@ static void mw_prpl_set_permit_deny(PurpleConnection *gc) {
break;
default:
- DEBUG_INFO("acct->perm_deny is 0x%x\n", acct->perm_deny);
+ DEBUG_INFO("acct->perm_deny is 0x%x\n", purple_account_get_privacy_type(acct));
return;
}
@@ -4715,7 +4714,7 @@ static void mw_prpl_join_chat(PurpleConnection *gc,
struct mwPurplePluginData *pd;
char *c, *t;
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
c = g_hash_table_lookup(components, CHAT_KEY_NAME);
t = g_hash_table_lookup(components, CHAT_KEY_TOPIC);
@@ -4757,7 +4756,7 @@ static void mw_prpl_reject_chat(PurpleConnection *gc,
struct mwServiceConference *srvc;
char *c;
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
srvc = pd->srvc_conf;
if(g_hash_table_lookup(components, CHAT_KEY_IS_PLACE)) {
@@ -4789,7 +4788,7 @@ static void mw_prpl_chat_invite(PurpleConnection *gc,
struct mwPlace *place;
struct mwIdBlock idb = { (char *) who, NULL };
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
g_return_if_fail(pd != NULL);
conf = ID_TO_CONF(pd, id);
@@ -4813,7 +4812,7 @@ static void mw_prpl_chat_leave(PurpleConnection *gc,
struct mwPurplePluginData *pd;
struct mwConference *conf;
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
g_return_if_fail(pd != NULL);
conf = ID_TO_CONF(pd, id);
@@ -4849,7 +4848,7 @@ static int mw_prpl_chat_send(PurpleConnection *gc,
char *msg;
int ret;
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
g_return_val_if_fail(pd != NULL, 0);
conf = ID_TO_CONF(pd, id);
@@ -4887,7 +4886,7 @@ static void mw_prpl_alias_buddy(PurpleConnection *gc,
const char *who,
const char *alias) {
- struct mwPurplePluginData *pd = gc->proto_data;
+ struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc);
g_return_if_fail(pd != NULL);
/* it's a change to the buddy list, so we've gotta reflect that in
@@ -4905,7 +4904,7 @@ static void mw_prpl_group_buddy(PurpleConnection *gc,
struct mwAwareIdBlock idb = { mwAware_USER, (char *) who, NULL };
GList *gl = g_list_prepend(NULL, &idb);
- struct mwPurplePluginData *pd = gc->proto_data;
+ struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc);
PurpleGroup *group;
struct mwAwareList *list;
@@ -4931,7 +4930,7 @@ static void mw_prpl_rename_group(PurpleConnection *gc,
PurpleGroup *group,
GList *buddies) {
- struct mwPurplePluginData *pd = gc->proto_data;
+ struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc);
g_return_if_fail(pd != NULL);
/* it's a change in the buddy list, so we've gotta reflect that in
@@ -4951,7 +4950,7 @@ static void mw_prpl_buddy_free(PurpleBuddy *buddy) {
static void mw_prpl_convo_closed(PurpleConnection *gc, const char *who) {
- struct mwPurplePluginData *pd = gc->proto_data;
+ struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc);
struct mwServiceIm *srvc;
struct mwConversation *conv;
struct mwIdBlock idb = { (char *) who, NULL };
@@ -4986,7 +4985,7 @@ static void mw_prpl_remove_group(PurpleConnection *gc, PurpleGroup *group) {
struct mwPurplePluginData *pd;
struct mwAwareList *list;
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
g_return_if_fail(pd != NULL);
g_return_if_fail(pd->group_list_map != NULL);
@@ -5010,7 +5009,7 @@ static gboolean mw_prpl_can_receive_file(PurpleConnection *gc,
g_return_val_if_fail(gc != NULL, FALSE);
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
g_return_val_if_fail(pd != NULL, FALSE);
srvc = pd->srvc_aware;
@@ -5042,12 +5041,12 @@ static void ft_outgoing_init(PurpleXfer *xfer) {
acct = purple_xfer_get_account(xfer);
gc = purple_account_get_connection(acct);
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
srvc = pd->srvc_ft;
filename = purple_xfer_get_local_filename(xfer);
filesize = purple_xfer_get_size(xfer);
- idb.user = xfer->who;
+ idb.user = purple_xfer_get_remote_user(xfer);
purple_xfer_update_progress(xfer);
@@ -5056,7 +5055,7 @@ static void ft_outgoing_init(PurpleXfer *xfer) {
if(! fp) {
char *msg = g_strdup_printf(_("Error reading file %s: \n%s\n"),
filename, g_strerror(errno));
- purple_xfer_error(purple_xfer_get_type(xfer), acct, xfer->who, msg);
+ purple_xfer_error(purple_xfer_get_type(xfer), acct, purple_xfer_get_remote_user(xfer), msg);
g_free(msg);
return;
}
@@ -5071,14 +5070,14 @@ static void ft_outgoing_init(PurpleXfer *xfer) {
purple_xfer_ref(xfer);
mwFileTransfer_setClientData(ft, xfer, (GDestroyNotify) purple_xfer_unref);
- xfer->data = ft;
+ purple_xfer_set_protocol_data(xfer, ft);
mwFileTransfer_offer(ft);
}
static void ft_outgoing_cancel(PurpleXfer *xfer) {
- struct mwFileTransfer *ft = xfer->data;
+ struct mwFileTransfer *ft = purple_xfer_get_protocol_data(xfer);
DEBUG_INFO("ft_outgoing_cancel called\n");
@@ -5119,6 +5118,7 @@ static void mw_prpl_send_file(PurpleConnection *gc,
static PurplePluginProtocolInfo mw_prpl_info = {
+ sizeof(PurplePluginProtocolInfo),
OPT_PROTO_IM_IMAGE,
NULL, /*< set in mw_plugin_init */
NULL, /*< set in mw_plugin_init */
@@ -5159,7 +5159,6 @@ static PurplePluginProtocolInfo mw_prpl_info = {
mw_prpl_keepalive,
NULL,
NULL,
- NULL,
mw_prpl_alias_buddy,
mw_prpl_group_buddy,
mw_prpl_rename_group,
@@ -5184,9 +5183,6 @@ static PurplePluginProtocolInfo mw_prpl_info = {
NULL,
NULL,
NULL,
- sizeof(PurplePluginProtocolInfo),
- NULL,
- NULL,
NULL,
NULL,
NULL,
@@ -5514,7 +5510,7 @@ static void remote_group_action_cb(PurpleConnection *gc, const char *name) {
enum mwResolveFlag flags;
guint32 req;
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
srvc = pd->srvc_resolve;
query = g_list_prepend(NULL, (char *) name);
@@ -5639,7 +5635,7 @@ static void search_action_cb(PurpleConnection *gc, const char *name) {
enum mwResolveFlag flags;
guint32 req;
- pd = gc->proto_data;
+ pd = purple_connection_get_protocol_data(gc);
srvc = pd->srvc_resolve;
query = g_list_prepend(NULL, (char *) name);
diff --git a/libpurple/protocols/silc/buddy.c b/libpurple/protocols/silc/buddy.c
index 224c753366..e79b3dde85 100644
--- a/libpurple/protocols/silc/buddy.c
+++ b/libpurple/protocols/silc/buddy.c
@@ -72,7 +72,7 @@ silcpurple_buddy_keyagr_cb(SilcClient client,
void *context)
{
PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
if (!sg->conn)
return;
@@ -146,7 +146,7 @@ static void
silcpurple_buddy_keyagr_do(PurpleConnection *gc, const char *name,
gboolean force_local)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcDList clients;
SilcClientEntry client_entry;
SilcClientConnectionParams params;
@@ -314,7 +314,7 @@ void silcpurple_buddy_keyagr_request(SilcClient client,
a->port = port;
purple_request_action(client->application, _("Key Agreement Request"), tmp,
- hostname ? tmp2 : NULL, 1, gc->account, client_entry->nickname,
+ hostname ? tmp2 : NULL, 1, purple_connection_get_account(gc), client_entry->nickname,
NULL, a, 2, _("Yes"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb),
_("No"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb));
}
@@ -346,7 +346,7 @@ silcpurple_buddy_resetkey(PurpleBlistNode *node, gpointer data)
b = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(b));
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
/* Find client entry */
clients = silc_client_get_clients_local(sg->client, sg->conn,
@@ -426,7 +426,7 @@ silcpurple_buddy_privkey_resolved(SilcClient client,
static void
silcpurple_buddy_privkey(PurpleConnection *gc, const char *name)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcPurplePrivkey p;
SilcDList clients;
SilcClientEntry client_entry;
@@ -457,7 +457,7 @@ silcpurple_buddy_privkey(PurpleConnection *gc, const char *name)
_("Set IM Password"), NULL, FALSE, TRUE, NULL,
_("OK"), G_CALLBACK(silcpurple_buddy_privkey_cb),
_("Cancel"), G_CALLBACK(silcpurple_buddy_privkey_cb),
- gc->account, NULL, NULL, p);
+ purple_connection_get_account(gc), NULL, NULL, p);
silc_client_list_free(sg->client, sg->conn, clients);
}
@@ -554,7 +554,7 @@ silcpurple_buddy_getkey_resolved(SilcClient client,
static void
silcpurple_buddy_getkey(PurpleConnection *gc, const char *name)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
SilcClientEntry client_entry;
@@ -618,7 +618,7 @@ silcpurple_buddy_showkey(PurpleBlistNode *node, gpointer data)
b = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(b));
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
pkfile = purple_blist_node_get_string(node, "public-key");
if (!silc_pkcs_load_public_key(pkfile, &public_key)) {
@@ -669,7 +669,7 @@ silcpurple_add_buddy_resolved(SilcClient client,
void silcpurple_get_info(PurpleConnection *gc, const char *who)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
SilcClientEntry client_entry;
@@ -686,7 +686,7 @@ void silcpurple_get_info(PurpleConnection *gc, const char *who)
if (strlen(who) > 2 && who[0] == '*' && who[1] == '@')
nick = who + 2;
- b = purple_find_buddy(gc->account, nick);
+ b = purple_find_buddy(purple_connection_get_account(gc), nick);
if (b) {
/* See if we have this buddy's public key. If we do use that
to search the details. */
@@ -1338,7 +1338,7 @@ silcpurple_add_buddy_resolved(SilcClient client,
static void
silcpurple_add_buddy_i(PurpleConnection *gc, PurpleBuddy *b, gboolean init)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
SilcPurpleBuddyRes r;
@@ -1396,7 +1396,7 @@ silcpurple_add_buddy_i(PurpleConnection *gc, PurpleBuddy *b, gboolean init)
silc_buffer_free(attrs);
}
-void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
+void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, const char *message)
{
/* Don't add if the buddy is already on the list.
*
@@ -1437,7 +1437,7 @@ void silcpurple_idle_set(PurpleConnection *gc, int idle)
const char *server;
int port;
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (sg == NULL)
return;
@@ -1467,7 +1467,7 @@ char *silcpurple_status_text(PurpleBuddy *b)
{
PurpleAccount *account = purple_buddy_get_account(b);
PurpleConnection *gc = purple_account_get_connection(account);
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
SilcClientID *client_id = purple_buddy_get_protocol_data(b);
@@ -1533,7 +1533,7 @@ void silcpurple_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gb
{
PurpleAccount *account = purple_buddy_get_account(b);
PurpleConnection *gc = purple_account_get_connection(account);
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
SilcClientID *client_id = purple_buddy_get_protocol_data(b);
@@ -1547,54 +1547,72 @@ void silcpurple_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gb
return;
if (client_entry->nickname)
- purple_notify_user_info_add_pair(user_info, _("Nickname"),
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Nickname"),
client_entry->nickname);
if (client_entry->username && client_entry->hostname) {
g_snprintf(tmp, sizeof(tmp), "%s@%s", client_entry->username, client_entry->hostname);
- purple_notify_user_info_add_pair(user_info, _("Username"), tmp);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Username"), tmp);
}
if (client_entry->mode) {
memset(tmp, 0, sizeof(tmp));
silcpurple_get_umode_string(client_entry->mode,
tmp, sizeof(tmp) - strlen(tmp));
- purple_notify_user_info_add_pair(user_info, _("User Modes"), tmp);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("User Modes"), tmp);
}
silcpurple_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr);
if (statusstr) {
- purple_notify_user_info_add_pair(user_info, _("Message"), statusstr);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Message"), statusstr);
g_free(statusstr);
}
if (full) {
if (moodstr) {
- purple_notify_user_info_add_pair(user_info, _("Mood"), moodstr);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Mood"), moodstr);
g_free(moodstr);
}
if (contactstr) {
- purple_notify_user_info_add_pair(user_info, _("Preferred Contact"), contactstr);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Preferred Contact"), contactstr);
g_free(contactstr);
}
if (langstr) {
- purple_notify_user_info_add_pair(user_info, _("Preferred Language"), langstr);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Preferred Language"), langstr);
g_free(langstr);
}
if (devicestr) {
- purple_notify_user_info_add_pair(user_info, _("Device"), devicestr);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Device"), devicestr);
g_free(devicestr);
}
if (tzstr) {
- purple_notify_user_info_add_pair(user_info, _("Timezone"), tzstr);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Timezone"), tzstr);
g_free(tzstr);
}
if (geostr) {
- purple_notify_user_info_add_pair(user_info, _("Geolocation"), geostr);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Geolocation"), geostr);
g_free(geostr);
}
}
@@ -1611,7 +1629,7 @@ silcpurple_buddy_kill(PurpleBlistNode *node, gpointer data)
b = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(b));
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
/* Call KILL */
silc_client_command_call(sg->client, sg->conn, NULL, "KILL",
@@ -1635,7 +1653,7 @@ GList *silcpurple_buddy_menu(PurpleBuddy *buddy)
{
PurpleAccount *account = purple_buddy_get_account(buddy);
PurpleConnection *gc = purple_account_get_connection(account);
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClientConnection conn = sg->conn;
const char *pkfile = NULL;
SilcClientEntry client_entry = NULL;
@@ -1701,7 +1719,7 @@ GList *silcpurple_buddy_menu(PurpleBuddy *buddy)
void silcpurple_buddy_set_icon(PurpleConnection *gc, PurpleStoredImage *img)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
SilcMime mime;
diff --git a/libpurple/protocols/silc/chat.c b/libpurple/protocols/silc/chat.c
index d20667a7c2..fe7be1ab8b 100644
--- a/libpurple/protocols/silc/chat.c
+++ b/libpurple/protocols/silc/chat.c
@@ -91,7 +91,7 @@ silcpurple_chat_getinfo_res(SilcClient client,
static void
silcpurple_chat_getinfo(PurpleConnection *gc, GHashTable *components)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
const char *chname;
char tmp[256], *tmp2;
GString *s;
@@ -500,7 +500,7 @@ silcpurple_chat_chauth(PurpleBlistNode *node, gpointer data)
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
g_hash_table_lookup(purple_chat_get_components(chat), "channel"),
@@ -587,7 +587,7 @@ silcpurple_chat_prv(PurpleBlistNode *node, gpointer data)
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
p = silc_calloc(1, sizeof(*p));
if (!p)
@@ -637,7 +637,7 @@ silcpurple_chat_permanent_reset(PurpleBlistNode *node, gpointer data)
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
g_hash_table_lookup(purple_chat_get_components(chat), "channel"),
@@ -656,7 +656,7 @@ silcpurple_chat_permanent(PurpleBlistNode *node, gpointer data)
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (!sg->conn)
return;
@@ -733,7 +733,7 @@ silcpurple_chat_ulimit(PurpleBlistNode *node, gpointer data)
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (!sg->conn)
return;
@@ -768,7 +768,7 @@ silcpurple_chat_resettopic(PurpleBlistNode *node, gpointer data)
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
g_hash_table_lookup(purple_chat_get_components(chat), "channel"),
@@ -786,7 +786,7 @@ silcpurple_chat_settopic(PurpleBlistNode *node, gpointer data)
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
g_hash_table_lookup(purple_chat_get_components(chat), "channel"),
@@ -804,7 +804,7 @@ silcpurple_chat_resetprivate(PurpleBlistNode *node, gpointer data)
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
g_hash_table_lookup(purple_chat_get_components(chat), "channel"),
@@ -822,7 +822,7 @@ silcpurple_chat_setprivate(PurpleBlistNode *node, gpointer data)
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
g_hash_table_lookup(purple_chat_get_components(chat), "channel"),
@@ -840,7 +840,7 @@ silcpurple_chat_resetsecret(PurpleBlistNode *node, gpointer data)
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
g_hash_table_lookup(purple_chat_get_components(chat), "channel"),
@@ -858,7 +858,7 @@ silcpurple_chat_setsecret(PurpleBlistNode *node, gpointer data)
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
g_hash_table_lookup(purple_chat_get_components(chat), "channel"),
@@ -882,7 +882,7 @@ GList *silcpurple_chat_menu(PurpleChat *chat)
{
GHashTable *components = purple_chat_get_components(chat);
PurpleConnection *gc = purple_account_get_connection(purple_chat_get_account(chat));
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClientConnection conn = sg->conn;
const char *chname = NULL;
SilcChannelEntry channel = NULL;
@@ -1020,7 +1020,7 @@ char *silcpurple_get_chat_name(GHashTable *data)
void silcpurple_chat_join(PurpleConnection *gc, GHashTable *data)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
const char *channel, *passphrase, *parentch;
@@ -1103,7 +1103,7 @@ void silcpurple_chat_join(PurpleConnection *gc, GHashTable *data)
void silcpurple_chat_invite(PurpleConnection *gc, int id, const char *msg,
const char *name)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
SilcHashTableList htl;
@@ -1148,7 +1148,7 @@ void silcpurple_chat_invite(PurpleConnection *gc, int id, const char *msg,
void silcpurple_chat_leave(PurpleConnection *gc, int id)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
SilcHashTableList htl;
@@ -1218,7 +1218,7 @@ void silcpurple_chat_leave(PurpleConnection *gc, int id)
int silcpurple_chat_send(PurpleConnection *gc, int id, const char *msg,
PurpleMessageFlags msgflags)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
SilcHashTableList htl;
@@ -1340,7 +1340,7 @@ int silcpurple_chat_send(PurpleConnection *gc, int id, const char *msg,
void silcpurple_chat_set_topic(PurpleConnection *gc, int id, const char *topic)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
SilcHashTableList htl;
@@ -1384,7 +1384,7 @@ void silcpurple_chat_set_topic(PurpleConnection *gc, int id, const char *topic)
PurpleRoomlist *silcpurple_roomlist_get_list(PurpleConnection *gc)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
GList *fields = NULL;
@@ -1419,12 +1419,13 @@ PurpleRoomlist *silcpurple_roomlist_get_list(PurpleConnection *gc)
void silcpurple_roomlist_cancel(PurpleRoomlist *list)
{
- PurpleConnection *gc = purple_account_get_connection(list->account);
+ PurpleAccount *account = purple_roomlist_get_account(list);
+ PurpleConnection *gc = purple_account_get_connection(account);
SilcPurple sg;
if (!gc)
return;
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
purple_roomlist_set_in_progress(list, FALSE);
if (sg->roomlist == list) {
diff --git a/libpurple/protocols/silc/ft.c b/libpurple/protocols/silc/ft.c
index 0fad6d66e4..a2c2d30f25 100644
--- a/libpurple/protocols/silc/ft.c
+++ b/libpurple/protocols/silc/ft.c
@@ -76,7 +76,7 @@ silcpurple_ftp_monitor(SilcClient client,
if (status == SILC_CLIENT_FILE_MONITOR_CLOSED) {
/* All started sessions terminate here */
- xfer->xfer->data = NULL;
+ purple_xfer_set_protocol_data(xfer->xfer, NULL);
purple_xfer_unref(xfer->xfer);
silc_free(xfer);
return;
@@ -86,7 +86,7 @@ silcpurple_ftp_monitor(SilcClient client,
purple_notify_error(gc, _("Secure File Transfer"),
_("Error during file transfer"),
_("Remote disconnected"));
- xfer->xfer->status = PURPLE_XFER_STATUS_CANCEL_REMOTE;
+ purple_xfer_set_status(xfer->xfer, PURPLE_XFER_STATUS_CANCEL_REMOTE);
purple_xfer_update_progress(xfer->xfer);
silc_client_file_close(client, conn, session_id);
return;
@@ -122,7 +122,7 @@ silcpurple_ftp_monitor(SilcClient client,
_("Error during file transfer"),
_("File transfer session does not exist"));
}
- xfer->xfer->status = PURPLE_XFER_STATUS_CANCEL_REMOTE;
+ purple_xfer_set_status(xfer->xfer, PURPLE_XFER_STATUS_CANCEL_REMOTE);
purple_xfer_update_progress(xfer->xfer);
silc_client_file_close(client, conn, session_id);
return;
@@ -132,8 +132,7 @@ silcpurple_ftp_monitor(SilcClient client,
if (!offset && filesize)
purple_xfer_set_size(xfer->xfer, filesize);
if (offset && filesize) {
- xfer->xfer->bytes_sent = offset;
- xfer->xfer->bytes_remaining = filesize - offset;
+ purple_xfer_set_bytes_sent(xfer->xfer, offset);
}
purple_xfer_update_progress(xfer->xfer);
@@ -150,12 +149,12 @@ silcpurple_ftp_monitor(SilcClient client,
static void
silcpurple_ftp_cancel(PurpleXfer *x)
{
- SilcPurpleXfer xfer = x->data;
+ SilcPurpleXfer xfer = purple_xfer_get_protocol_data(x);
if (!xfer)
return;
- xfer->xfer->status = PURPLE_XFER_STATUS_CANCEL_LOCAL;
+ purple_xfer_set_status(xfer->xfer, PURPLE_XFER_STATUS_CANCEL_LOCAL);
purple_xfer_update_progress(xfer->xfer);
silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id);
}
@@ -163,7 +162,7 @@ silcpurple_ftp_cancel(PurpleXfer *x)
static void
silcpurple_ftp_ask_name_cancel(PurpleXfer *x)
{
- SilcPurpleXfer xfer = x->data;
+ SilcPurpleXfer xfer = purple_xfer_get_protocol_data(x);
if (!xfer)
return;
@@ -176,7 +175,7 @@ silcpurple_ftp_ask_name_cancel(PurpleXfer *x)
static void
silcpurple_ftp_ask_name_ok(PurpleXfer *x)
{
- SilcPurpleXfer xfer = x->data;
+ SilcPurpleXfer xfer = purple_xfer_get_protocol_data(x);
const char *name;
if (!xfer)
@@ -212,7 +211,7 @@ silcpurple_ftp_ask_name(SilcClient client,
static void
silcpurple_ftp_request_result(PurpleXfer *x)
{
- SilcPurpleXfer xfer = x->data;
+ SilcPurpleXfer xfer = purple_xfer_get_protocol_data(x);
SilcClientFileError status;
PurpleConnection *gc = xfer->sg->gc;
SilcClientConnectionParams params;
@@ -222,8 +221,6 @@ silcpurple_ftp_request_result(PurpleXfer *x)
if (purple_xfer_get_status(x) != PURPLE_XFER_STATUS_ACCEPTED)
return;
- if (!xfer)
- return;
silc_socket_stream_get_info(silc_packet_stream_get_stream(xfer->sg->conn->stream),
&sock, NULL, NULL, NULL);
@@ -310,7 +307,7 @@ void silcpurple_ftp_request(SilcClient client, SilcClientConnection conn,
const char *hostname, SilcUInt16 port)
{
PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcPurpleXfer xfer;
xfer = silc_calloc(1, sizeof(*xfer));
@@ -337,7 +334,7 @@ void silcpurple_ftp_request(SilcClient client, SilcClientConnection conn,
purple_xfer_set_cancel_recv_fnc(xfer->xfer, silcpurple_ftp_cancel);
xfer->xfer->remote_ip = g_strdup(hostname);
xfer->xfer->remote_port = port;
- xfer->xfer->data = xfer;
+ purple_xfer_set_protocol_data(xfer->xfer, xfer);
/* File transfer request */
purple_xfer_request(xfer->xfer);
@@ -346,7 +343,7 @@ void silcpurple_ftp_request(SilcClient client, SilcClientConnection conn,
static void
silcpurple_ftp_send_cancel(PurpleXfer *x)
{
- SilcPurpleXfer xfer = x->data;
+ SilcPurpleXfer xfer = purple_xfer_get_protocol_data(x);
if (!xfer)
return;
@@ -358,7 +355,7 @@ silcpurple_ftp_send_cancel(PurpleXfer *x)
static void
silcpurple_ftp_send(PurpleXfer *x)
{
- SilcPurpleXfer xfer = x->data;
+ SilcPurpleXfer xfer = purple_xfer_get_protocol_data(x);
const char *name;
char *local_ip = NULL, *remote_ip = NULL;
gboolean local = TRUE;
@@ -435,7 +432,7 @@ silcpurple_ftp_send_file_resolved(SilcClient client,
PurpleXfer *silcpurple_ftp_new_xfer(PurpleConnection *gc, const char *name)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
SilcDList clients;
@@ -467,7 +464,7 @@ PurpleXfer *silcpurple_ftp_new_xfer(PurpleConnection *gc, const char *name)
purple_xfer_set_init_fnc(xfer->xfer, silcpurple_ftp_send);
purple_xfer_set_request_denied_fnc(xfer->xfer, silcpurple_ftp_request_denied);
purple_xfer_set_cancel_send_fnc(xfer->xfer, silcpurple_ftp_send_cancel);
- xfer->xfer->data = xfer;
+ purple_xfer_set_protocol_data(xfer->xfer, xfer);
silc_free(clients);
diff --git a/libpurple/protocols/silc/ops.c b/libpurple/protocols/silc/ops.c
index ca57760862..dc53279150 100644
--- a/libpurple/protocols/silc/ops.c
+++ b/libpurple/protocols/silc/ops.c
@@ -72,7 +72,7 @@ void silc_say(SilcClient client, SilcClientConnection conn,
gc = client->application;
if (gc != NULL)
- purple_connection_error_reason(gc, reason, tmp);
+ purple_connection_error(gc, reason, tmp);
else
purple_notify_error(NULL, _("Error"), _("Error occurred"), tmp);
}
@@ -88,7 +88,7 @@ silcpurple_mime_message(SilcClient client, SilcClientConnection conn,
gboolean recursive)
{
PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
const char *type;
const unsigned char *data;
SilcUInt32 data_len;
@@ -210,7 +210,9 @@ silcpurple_mime_message(SilcClient client, SilcClientConnection conn,
imgid = purple_imgstore_add_with_id(g_memdup(data, data_len), data_len, "");
if (imgid) {
cflags |= PURPLE_MESSAGE_IMAGES | PURPLE_MESSAGE_RECV;
- g_snprintf(tmp, sizeof(tmp), "<IMG ID=\"%d\">", imgid);
+ g_snprintf(tmp, sizeof(tmp),
+ "<IMG SRC=\"" PURPLE_STORED_IMAGE_PROTOCOL "%d\">",
+ imgid);
if (channel)
serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)),
@@ -224,7 +226,6 @@ silcpurple_mime_message(SilcClient client, SilcClientConnection conn,
tmp, cflags, time(NULL));
purple_imgstore_unref_by_id(imgid);
- cflags = 0;
ret = TRUE;
}
goto out;
@@ -264,7 +265,7 @@ silc_channel_message(SilcClient client, SilcClientConnection conn,
SilcUInt32 message_len)
{
PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
PurpleConversation *convo = NULL;
char *msg, *tmp;
@@ -361,7 +362,7 @@ silc_private_message(SilcClient client, SilcClientConnection conn,
SilcUInt32 message_len)
{
PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
PurpleConversation *convo = NULL;
char *msg, *tmp;
@@ -445,7 +446,7 @@ silc_notify(SilcClient client, SilcClientConnection conn,
{
va_list va;
PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
PurpleAccount *account = purple_connection_get_account(gc);
PurpleConversation *convo;
SilcClientEntry client_entry, client_entry2;
@@ -955,7 +956,7 @@ silc_command(SilcClient client, SilcClientConnection conn,
SilcUInt32 argc, unsigned char **argv)
{
PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
switch (command) {
@@ -1092,7 +1093,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
SilcStatus error, va_list ap)
{
PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
PurpleConversation *convo;
switch (command) {
@@ -1176,7 +1177,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
SilcUInt32 idle, *user_modes;
SilcDList channels;
SilcClientEntry client_entry;
- char tmp[1024], *tmp2;
+ char tmp[1024];
char *moodstr, *statusstr, *contactstr, *langstr, *devicestr, *tzstr, *geostr;
PurpleNotifyUserInfo *user_info;
@@ -1198,71 +1199,80 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
user_modes = va_arg(ap, SilcUInt32 *);
user_info = purple_notify_user_info_new();
- tmp2 = g_markup_escape_text(client_entry->nickname, -1);
- purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp2);
- g_free(tmp2);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Nickname"), client_entry->nickname);
if (client_entry->realname) {
- tmp2 = g_markup_escape_text(client_entry->realname, -1);
- purple_notify_user_info_add_pair(user_info, _("Real Name"), tmp2);
- g_free(tmp2);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Real Name"), client_entry->realname);
}
- tmp2 = g_markup_escape_text(client_entry->username, -1);
if (*client_entry->hostname) {
- gchar *tmp3;
- tmp3 = g_strdup_printf("%s@%s", tmp2, client_entry->hostname);
- purple_notify_user_info_add_pair(user_info, _("Username"), tmp3);
- g_free(tmp3);
+ gchar *tmp2;
+ tmp2 = g_strdup_printf("%s@%s", client_entry->username, client_entry->hostname);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Username"), tmp2);
+ g_free(tmp2);
} else
- purple_notify_user_info_add_pair(user_info, _("Username"), tmp2);
- g_free(tmp2);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Username"), client_entry->username);
if (client_entry->mode) {
memset(tmp, 0, sizeof(tmp));
silcpurple_get_umode_string(client_entry->mode,
tmp, sizeof(tmp) - strlen(tmp));
- purple_notify_user_info_add_pair(user_info, _("User Modes"), tmp);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("User Modes"), tmp);
}
silcpurple_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr);
if (moodstr) {
- purple_notify_user_info_add_pair(user_info, _("Mood"), moodstr);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Mood"), moodstr);
g_free(moodstr);
}
if (statusstr) {
- tmp2 = g_markup_escape_text(statusstr, -1);
- purple_notify_user_info_add_pair(user_info, _("Status Text"), tmp2);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Status Text"), statusstr);
g_free(statusstr);
- g_free(tmp2);
}
if (contactstr) {
- purple_notify_user_info_add_pair(user_info, _("Preferred Contact"), contactstr);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Preferred Contact"), contactstr);
g_free(contactstr);
}
if (langstr) {
- purple_notify_user_info_add_pair(user_info, _("Preferred Language"), langstr);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Preferred Language"), langstr);
g_free(langstr);
}
if (devicestr) {
- purple_notify_user_info_add_pair(user_info, _("Device"), devicestr);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Device"), devicestr);
g_free(devicestr);
}
if (tzstr) {
- purple_notify_user_info_add_pair(user_info, _("Timezone"), tzstr);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Timezone"), tzstr);
g_free(tzstr);
}
if (geostr) {
- purple_notify_user_info_add_pair(user_info, _("Geolocation"), geostr);
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Geolocation"), geostr);
g_free(geostr);
}
- if (*client_entry->server)
- purple_notify_user_info_add_pair(user_info, _("Server"), client_entry->server);
+ if (*client_entry->server) {
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Server"), client_entry->server);
+ }
if (channels && user_modes) {
SilcChannelPayload entry;
@@ -1280,9 +1290,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
silc_strncat(tmp, sizeof(tmp) - 1, " ", 1);
silc_free(m);
}
- tmp2 = g_markup_escape_text(tmp, -1);
- purple_notify_user_info_add_pair(user_info, _("Currently on"), tmp2);
- g_free(tmp2);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Currently on"), tmp);
}
if (client_entry->public_key) {
@@ -1293,8 +1301,8 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
if (pk) {
fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
- purple_notify_user_info_add_pair(user_info, _("Public Key Fingerprint"), fingerprint);
- purple_notify_user_info_add_pair(user_info, _("Public Key Babbleprint"), babbleprint);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Public Key Fingerprint"), fingerprint);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Public Key Babbleprint"), babbleprint);
silc_free(fingerprint);
silc_free(babbleprint);
silc_free(pk);
@@ -1318,7 +1326,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
case SILC_COMMAND_WHOWAS:
{
SilcClientEntry client_entry;
- char *nickname, *realname, *username, *tmp;
+ char *nickname, *realname, *username;
PurpleNotifyUserInfo *user_info;
if (status != SILC_STATUS_OK) {
@@ -1336,27 +1344,23 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
break;
user_info = purple_notify_user_info_new();
- tmp = g_markup_escape_text(nickname, -1);
- purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp);
- g_free(tmp);
- if (realname) {
- tmp = g_markup_escape_text(realname, -1);
- purple_notify_user_info_add_pair(user_info, _("Real Name"), tmp);
- g_free(tmp);
- }
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Nickname"), nickname);
+ if (realname)
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Real Name"), realname);
if (username) {
- tmp = g_markup_escape_text(username, -1);
if (client_entry && *client_entry->hostname) {
- gchar *tmp3;
- tmp3 = g_strdup_printf("%s@%s", tmp, client_entry->hostname);
- purple_notify_user_info_add_pair(user_info, _("Username"), tmp3);
- g_free(tmp3);
+ gchar *tmp;
+ tmp = g_strdup_printf("%s@%s", username, client_entry->hostname);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Username"), tmp);
+ g_free(tmp);
} else
- purple_notify_user_info_add_pair(user_info, _("Username"), tmp);
- g_free(tmp);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Username"), username);
+ }
+ if (client_entry && *client_entry->server) {
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("Server"), client_entry->server);
}
- if (client_entry && *client_entry->server)
- purple_notify_user_info_add_pair(user_info, _("Server"), client_entry->server);
if (client_entry && client_entry->public_key) {
@@ -1367,8 +1371,8 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
if (pk) {
fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
- purple_notify_user_info_add_pair(user_info, _("Public Key Fingerprint"), fingerprint);
- purple_notify_user_info_add_pair(user_info, _("Public Key Babbleprint"), babbleprint);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Public Key Fingerprint"), fingerprint);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Public Key Babbleprint"), babbleprint);
silc_free(fingerprint);
silc_free(babbleprint);
silc_free(pk);
@@ -1735,7 +1739,7 @@ silc_get_auth_method(SilcClient client, SilcClientConnection conn,
SilcGetAuthMeth completion, void *context)
{
PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcPurpleAskPassphrase internal;
const char *password;
@@ -1786,7 +1790,7 @@ silc_verify_public_key(SilcClient client, SilcClientConnection conn,
SilcVerifyPublicKey completion, void *context)
{
PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
if (!sg->conn && (conn_type == SILC_CONN_SERVER ||
conn_type == SILC_CONN_ROUTER)) {
diff --git a/libpurple/protocols/silc/pk.c b/libpurple/protocols/silc/pk.c
index 6d25db910d..66d2c9fb55 100644
--- a/libpurple/protocols/silc/pk.c
+++ b/libpurple/protocols/silc/pk.c
@@ -79,7 +79,7 @@ static void silcpurple_verify_details_cb(PublicKeyVerify verify)
static void silcpurple_verify_details(PublicKeyVerify verify, gint id)
{
PurpleConnection *gc = verify->client->application;
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
silcpurple_show_public_key(sg, verify->entity_name, verify->public_key,
G_CALLBACK(silcpurple_verify_details_cb),
diff --git a/libpurple/protocols/silc/silc.c b/libpurple/protocols/silc/silc.c
index ae30ee9d81..c44054b6c7 100644
--- a/libpurple/protocols/silc/silc.c
+++ b/libpurple/protocols/silc/silc.c
@@ -78,7 +78,7 @@ silcpurple_set_status(PurpleAccount *account, PurpleStatus *status)
const char *state;
if (gc != NULL)
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (status == NULL)
return;
@@ -125,7 +125,7 @@ silcpurple_set_status(PurpleAccount *account, PurpleStatus *status)
static void
silcpurple_keepalive(PurpleConnection *gc)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
silc_packet_send(sg->conn->stream, SILC_PACKET_HEARTBEAT, 0,
NULL, 0);
}
@@ -180,7 +180,7 @@ silcpurple_scheduler(SilcSchedule schedule,
{
SilcClient client = (SilcClient)context;
PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcPurpleTask ptask = NULL;
if (added) {
@@ -252,7 +252,7 @@ silcpurple_connect_cb(SilcClient client, SilcClientConnection conn,
struct utsname u;
#endif
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
switch (status) {
case SILC_CLIENT_CONN_SUCCESS:
@@ -316,7 +316,7 @@ silcpurple_connect_cb(SilcClient client, SilcClientConnection conn,
/* Close the connection */
if (!sg->detaching)
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Disconnected by server"));
else
@@ -325,30 +325,30 @@ silcpurple_connect_cb(SilcClient client, SilcClientConnection conn,
break;
case SILC_CLIENT_CONN_ERROR:
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Error connecting to SILC Server"));
g_unlink(silcpurple_session_file(purple_account_get_username(sg->account)));
break;
case SILC_CLIENT_CONN_ERROR_KE:
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
_("Key Exchange failed"));
break;
case SILC_CLIENT_CONN_ERROR_AUTH:
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
_("Authentication failed"));
break;
case SILC_CLIENT_CONN_ERROR_RESUME:
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("Resuming detached session failed. "
"Press Reconnect to create new connection."));
g_unlink(silcpurple_session_file(purple_account_get_username(sg->account)));
break;
case SILC_CLIENT_CONN_ERROR_TIMEOUT:
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Connection timed out"));
break;
}
@@ -367,16 +367,16 @@ silcpurple_stream_created(SilcSocketStreamStatus status, SilcStream stream,
SilcClientConnectionParams params;
const char *dfile;
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (status != SILC_SOCKET_OK) {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Connection failed"));
silc_pkcs_public_key_free(sg->public_key);
silc_pkcs_private_key_free(sg->private_key);
silc_free(sg);
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
return;
}
@@ -400,7 +400,7 @@ silcpurple_stream_created(SilcSocketStreamStatus status, SilcStream stream,
}
/* Perform SILC Key Exchange. */
- silc_client_key_exchange(sg->client, &params, sg->public_key,
+ silc_client_key_exchange(client, &params, sg->public_key,
sg->private_key, stream, SILC_CONN_SERVER,
silcpurple_connect_cb, gc);
@@ -415,15 +415,15 @@ silcpurple_login_connected(gpointer data, gint source, const gchar *error_messag
g_return_if_fail(gc != NULL);
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (source < 0) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Connection failed"));
silc_pkcs_public_key_free(sg->public_key);
silc_pkcs_private_key_free(sg->private_key);
silc_free(sg);
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
return;
}
@@ -447,9 +447,9 @@ static void silcpurple_continue_running(SilcPurple sg)
purple_account_get_int(account, "port", 706),
silcpurple_login_connected, gc) == NULL)
{
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect"));
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
silc_free(sg);
return;
}
@@ -457,7 +457,7 @@ static void silcpurple_continue_running(SilcPurple sg)
static void silcpurple_got_password_cb(PurpleConnection *gc, PurpleRequestFields *fields)
{
- SilcPurple sg = (SilcPurple)gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
PurpleAccount *account = purple_connection_get_account(gc);
char pkd[256], prd[256];
const char *password;
@@ -473,7 +473,7 @@ static void silcpurple_got_password_cb(PurpleConnection *gc, PurpleRequestFields
if (!password || !*password)
{
purple_notify_error(gc, NULL, _("Password is required to sign on."), NULL);
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
silc_free(sg);
return;
}
@@ -490,9 +490,9 @@ static void silcpurple_got_password_cb(PurpleConnection *gc, PurpleRequestFields
(char *)purple_account_get_string(account, "private-key", prd),
password,
&sg->public_key, &sg->private_key)) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("Unable to load SILC key pair"));
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
silc_free(sg);
return;
}
@@ -505,10 +505,10 @@ static void silcpurple_no_password_cb(PurpleConnection *gc, PurpleRequestFields
/* The password prompt dialog doesn't get disposed if the account disconnects */
if (!PURPLE_CONNECTION_IS_VALID(gc))
return;
- sg = gc->proto_data;
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ sg = purple_connection_get_protocol_data(gc);
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("Unable to load SILC key pair"));
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
silc_free(sg);
}
@@ -528,16 +528,16 @@ static void silcpurple_running(SilcClient client, void *context)
g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcpurple_silcdir());
if (!silc_load_key_pair((char *)purple_account_get_string(account, "public-key", pkd),
(char *)purple_account_get_string(account, "private-key", prd),
- (gc->password == NULL) ? "" : gc->password,
+ (purple_connection_get_password(gc) == NULL) ? "" : purple_connection_get_password(gc),
&sg->public_key, &sg->private_key)) {
if (!purple_account_get_password(account)) {
purple_account_request_password(account, G_CALLBACK(silcpurple_got_password_cb),
G_CALLBACK(silcpurple_no_password_cb), gc);
return;
}
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("Unable to load SILC key pair"));
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
silc_free(sg);
return;
}
@@ -555,10 +555,10 @@ silcpurple_login(PurpleAccount *account)
char *username, *hostname, *realname, **up;
int i;
- gc = account->gc;
+ gc = purple_account_get_connection(account);
if (!gc)
return;
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
memset(&params, 0, sizeof(params));
strcat(params.nickname_format, "%n#a");
@@ -566,7 +566,7 @@ silcpurple_login(PurpleAccount *account)
/* Allocate SILC client */
client = silc_client_alloc(&ops, &params, gc, NULL);
if (!client) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("Out of memory"));
return;
}
@@ -612,14 +612,14 @@ silcpurple_login(PurpleAccount *account)
sg->client = client;
sg->gc = gc;
sg->account = account;
- gc->proto_data = sg;
+ purple_connection_set_protocol_data(gc, sg);
/* Init SILC client */
if (!silc_client_init(client, username, hostname, realname,
silcpurple_running, sg)) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("Unable to initialize SILC protocol"));
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
silc_free(sg);
silc_free(hostname);
g_free(username);
@@ -630,9 +630,9 @@ silcpurple_login(PurpleAccount *account)
/* Check the ~/.silc dir and create it, and new key pair if necessary. */
if (!silcpurple_check_silc_dir(gc)) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("Error loading SILC key pair"));
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
silc_free(sg);
return;
}
@@ -669,7 +669,7 @@ silcpurple_close_final(gpointer *context)
static void
silcpurple_close(PurpleConnection *gc)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
#if __SILC_TOOLKIT_VERSION >= SILC_VERSION(1,1,1)
SilcPurpleTask task;
#endif /* __SILC_TOOLKIT_VERSION */
@@ -733,7 +733,7 @@ silcpurple_attrs_cancel(PurpleConnection *gc, PurpleRequestFields *fields)
static void
silcpurple_attrs_cb(PurpleConnection *gc, PurpleRequestFields *fields)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
PurpleRequestField *f;
@@ -744,7 +744,7 @@ silcpurple_attrs_cb(PurpleConnection *gc, PurpleRequestFields *fields)
SilcVCardStruct vcard;
const char *val;
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (!sg)
return;
@@ -905,7 +905,7 @@ static void
silcpurple_attrs(PurplePluginAction *action)
{
PurpleConnection *gc = (PurpleConnection *) action->context;
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
PurpleRequestFields *fields;
@@ -922,7 +922,7 @@ silcpurple_attrs(PurplePluginAction *action)
gboolean device = TRUE;
char status[1024], tz[16];
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (!sg)
return;
@@ -1061,7 +1061,7 @@ silcpurple_attrs(PurplePluginAction *action)
fields,
_("OK"), G_CALLBACK(silcpurple_attrs_cb),
_("Cancel"), G_CALLBACK(silcpurple_attrs_cancel),
- gc->account, NULL, NULL, gc);
+ purple_connection_get_account(gc), NULL, NULL, gc);
}
static void
@@ -1072,7 +1072,7 @@ silcpurple_detach(PurplePluginAction *action)
if (!gc)
return;
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (!sg)
return;
@@ -1090,7 +1090,7 @@ silcpurple_view_motd(PurplePluginAction *action)
if (!gc)
return;
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (!sg)
return;
@@ -1125,7 +1125,7 @@ silcpurple_create_keypair_cb(PurpleConnection *gc, PurpleRequestFields *fields)
int keylen = SILCPURPLE_DEF_PKCS_LEN;
SilcPublicKey public_key;
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (!sg)
return;
@@ -1208,7 +1208,7 @@ static void
silcpurple_create_keypair(PurplePluginAction *action)
{
PurpleConnection *gc = (PurpleConnection *) action->context;
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
PurpleRequestFields *fields;
PurpleRequestFieldGroup *g;
PurpleRequestField *f;
@@ -1226,9 +1226,9 @@ silcpurple_create_keypair(PurplePluginAction *action)
g_snprintf(pkd2, sizeof(pkd2), "%s" G_DIR_SEPARATOR_S"public_key.pub", silcpurple_silcdir());
g_snprintf(prd2, sizeof(prd2), "%s" G_DIR_SEPARATOR_S"private_key.prv", silcpurple_silcdir());
g_snprintf(pkd, sizeof(pkd) - 1, "%s",
- purple_account_get_string(gc->account, "public-key", pkd2));
+ purple_account_get_string(purple_connection_get_account(gc), "public-key", pkd2));
g_snprintf(prd, sizeof(prd) - 1, "%s",
- purple_account_get_string(gc->account, "private-key", prd2));
+ purple_account_get_string(purple_connection_get_account(gc), "private-key", prd2));
fields = purple_request_fields_new();
@@ -1269,7 +1269,7 @@ silcpurple_create_keypair(PurplePluginAction *action)
_("Create New SILC Key Pair"), NULL, fields,
_("Generate Key Pair"), G_CALLBACK(silcpurple_create_keypair_cb),
_("Cancel"), G_CALLBACK(silcpurple_create_keypair_cancel),
- gc->account, NULL, NULL, gc);
+ purple_connection_get_account(gc), NULL, NULL, gc);
g_strfreev(u);
silc_free(hostname);
@@ -1287,7 +1287,7 @@ silcpurple_change_passwd(PurpleConnection *gc, const char *old, const char *new)
{
char prd[256];
g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.pub", silcpurple_silcdir());
- silc_change_private_key_passphrase(purple_account_get_string(gc->account,
+ silc_change_private_key_passphrase(purple_account_get_string(purple_connection_get_account(gc),
"private-key",
prd), old ? old : "", new ? new : "");
}
@@ -1356,7 +1356,7 @@ silcpurple_send_im_resolved(SilcClient client,
void *context)
{
PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcPurpleIM im = context;
PurpleConversation *convo;
char tmp[256];
@@ -1433,7 +1433,7 @@ static int
silcpurple_send_im(PurpleConnection *gc, const char *who, const char *message,
PurpleMessageFlags flags)
{
- SilcPurple sg = gc->proto_data;
+ SilcPurple sg = purple_connection_get_protocol_data(gc);
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
SilcDList clients;
@@ -1548,14 +1548,14 @@ static PurpleCmdRet silcpurple_cmd_chat_part(PurpleConversation *conv,
PurpleConversation *convo = conv;
int id = 0;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
if (gc == NULL)
return PURPLE_CMD_RET_FAILED;
if(args && args[0])
convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[0],
- gc->account);
+ purple_connection_get_account(gc));
if (convo != NULL)
id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo));
@@ -1577,7 +1577,7 @@ static PurpleCmdRet silcpurple_cmd_chat_topic(PurpleConversation *conv,
char *buf, *tmp, *tmp2;
const char *topic;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv));
if (gc == NULL || id == 0)
@@ -1593,7 +1593,7 @@ static PurpleCmdRet silcpurple_cmd_chat_topic(PurpleConversation *conv,
g_free(tmp2);
} else
buf = g_strdup(_("No topic is set"));
- purple_conv_chat_write(PURPLE_CONV_CHAT(conv), gc->account->username, buf,
+ purple_conv_chat_write(PURPLE_CONV_CHAT(conv), purple_account_get_username(purple_connection_get_account(gc)), buf,
PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
g_free(buf);
@@ -1623,7 +1623,7 @@ static PurpleCmdRet silcpurple_cmd_chat_join(PurpleConversation *conv,
if(args[1])
g_hash_table_replace(comp, "passphrase", args[1]);
- silcpurple_chat_join(purple_conversation_get_gc(conv), comp);
+ silcpurple_chat_join(purple_conversation_get_connection(conv), comp);
g_hash_table_destroy(comp);
return PURPLE_CMD_RET_OK;
@@ -1633,7 +1633,7 @@ static PurpleCmdRet silcpurple_cmd_chat_list(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
PurpleConnection *gc;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
purple_roomlist_show_with_account(purple_connection_get_account(gc));
return PURPLE_CMD_RET_OK;
}
@@ -1643,7 +1643,7 @@ static PurpleCmdRet silcpurple_cmd_whois(PurpleConversation *conv,
{
PurpleConnection *gc;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
if (gc == NULL)
return PURPLE_CMD_RET_FAILED;
@@ -1659,7 +1659,7 @@ static PurpleCmdRet silcpurple_cmd_msg(PurpleConversation *conv,
int ret;
PurpleConnection *gc;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
if (gc == NULL)
return PURPLE_CMD_RET_FAILED;
@@ -1685,7 +1685,7 @@ static PurpleCmdRet silcpurple_cmd_query(PurpleConversation *conv,
return PURPLE_CMD_RET_FAILED;
}
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
if (gc == NULL)
return PURPLE_CMD_RET_FAILED;
@@ -1713,12 +1713,12 @@ static PurpleCmdRet silcpurple_cmd_motd(PurpleConversation *conv,
SilcPurple sg;
char *tmp;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
if (gc == NULL)
return PURPLE_CMD_RET_FAILED;
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (sg == NULL)
return PURPLE_CMD_RET_FAILED;
@@ -1742,12 +1742,12 @@ static PurpleCmdRet silcpurple_cmd_detach(PurpleConversation *conv,
PurpleConnection *gc;
SilcPurple sg;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
if (gc == NULL)
return PURPLE_CMD_RET_FAILED;
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (sg == NULL)
return PURPLE_CMD_RET_FAILED;
@@ -1767,12 +1767,12 @@ static PurpleCmdRet silcpurple_cmd_cmode(PurpleConversation *conv,
char *silccmd, *silcargs, *msg, tmp[256];
const char *chname;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
- if (gc == NULL || !args || gc->proto_data == NULL)
+ if (gc == NULL || !args || purple_connection_get_protocol_data(gc) == NULL)
return PURPLE_CMD_RET_FAILED;
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (args[0])
chname = args[0];
@@ -1818,12 +1818,12 @@ static PurpleCmdRet silcpurple_cmd_generic(PurpleConversation *conv,
SilcPurple sg;
char *silccmd, *silcargs;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
if (gc == NULL)
return PURPLE_CMD_RET_FAILED;
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (sg == NULL)
return PURPLE_CMD_RET_FAILED;
@@ -1850,12 +1850,12 @@ static PurpleCmdRet silcpurple_cmd_quit(PurpleConversation *conv,
const char *ui_name = NULL, *ui_website = NULL;
char *quit_msg;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
if (gc == NULL)
return PURPLE_CMD_RET_FAILED;
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (sg == NULL)
return PURPLE_CMD_RET_FAILED;
@@ -1887,12 +1887,12 @@ static PurpleCmdRet silcpurple_cmd_call(PurpleConversation *conv,
PurpleConnection *gc;
SilcPurple sg;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
if (gc == NULL)
return PURPLE_CMD_RET_FAILED;
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
if (sg == NULL)
return PURPLE_CMD_RET_FAILED;
@@ -2050,6 +2050,7 @@ static PurpleWhiteboardPrplOps silcpurple_wb_ops =
static PurplePluginProtocolInfo prpl_info =
{
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME |
OPT_PROTO_PASSWORD_OPTIONAL | OPT_PROTO_IM_IMAGE |
OPT_PROTO_SLASH_COMMANDS_NATIVE,
@@ -2092,7 +2093,6 @@ static PurplePluginProtocolInfo prpl_info =
silcpurple_keepalive, /* keepalive */
NULL, /* register_user */
NULL, /* get_cb_info */
- NULL, /* get_cb_away */
NULL, /* alias_buddy */
NULL, /* group_buddy */
NULL, /* rename_group */
@@ -2117,15 +2117,12 @@ static PurplePluginProtocolInfo prpl_info =
NULL, /* unregister_user */
NULL, /* send_attention */
NULL, /* get_attention_types */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
NULL, /* get_account_text_table */
NULL, /* initiate_media */
NULL, /* get_media_caps */
NULL, /* get_moods */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */
};
static PurplePluginInfo info =
diff --git a/libpurple/protocols/silc/silcpurple.h b/libpurple/protocols/silc/silcpurple.h
index 937e0cc358..4c0cdb8a75 100644
--- a/libpurple/protocols/silc/silcpurple.h
+++ b/libpurple/protocols/silc/silcpurple.h
@@ -105,7 +105,7 @@ void silcpurple_verify_public_key(SilcClient client, SilcClientConnection conn,
SilcVerifyPublicKey completion,
void *context);
GList *silcpurple_buddy_menu(PurpleBuddy *buddy);
-void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group);
+void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, const char *message);
void silcpurple_send_buddylist(PurpleConnection *gc);
void silcpurple_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group);
void silcpurple_buddy_keyagr_request(SilcClient client,
diff --git a/libpurple/protocols/silc/util.c b/libpurple/protocols/silc/util.c
index 68eac3275a..3dc6c0118d 100644
--- a/libpurple/protocols/silc/util.c
+++ b/libpurple/protocols/silc/util.c
@@ -198,9 +198,9 @@ gboolean silcpurple_check_silc_dir(PurpleConnection *gc)
g_snprintf(pkd, sizeof(pkd), "%s" G_DIR_SEPARATOR_S "public_key.pub", silcpurple_silcdir());
g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcpurple_silcdir());
g_snprintf(file_public_key, sizeof(file_public_key) - 1, "%s",
- purple_account_get_string(gc->account, "public-key", pkd));
+ purple_account_get_string(purple_connection_get_account(gc), "public-key", pkd));
g_snprintf(file_private_key, sizeof(file_public_key) - 1, "%s",
- purple_account_get_string(gc->account, "private-key", prd));
+ purple_account_get_string(purple_connection_get_account(gc), "private-key", prd));
if ((g_stat(file_public_key, &st)) == -1) {
/* If file doesn't exist */
@@ -210,10 +210,9 @@ gboolean silcpurple_check_silc_dir(PurpleConnection *gc)
SILCPURPLE_DEF_PKCS_LEN,
file_public_key,
file_private_key, NULL,
- (gc->password == NULL)
- ? "" : gc->password,
+ (purple_connection_get_password(gc) == NULL) ? "" : purple_connection_get_password(gc),
NULL, NULL, FALSE)) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("Unable to create SILC key pair"));
return FALSE;
}
@@ -253,10 +252,9 @@ gboolean silcpurple_check_silc_dir(PurpleConnection *gc)
SILCPURPLE_DEF_PKCS_LEN,
file_public_key,
file_private_key, NULL,
- (gc->password == NULL)
- ? "" : gc->password,
+ (purple_connection_get_password(gc) == NULL) ? "" : purple_connection_get_password(gc),
NULL, NULL, FALSE)) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("Unable to create SILC key pair"));
return FALSE;
}
diff --git a/libpurple/protocols/silc/wb.c b/libpurple/protocols/silc/wb.c
index 984925e823..b7dcde7a4f 100644
--- a/libpurple/protocols/silc/wb.c
+++ b/libpurple/protocols/silc/wb.c
@@ -105,18 +105,16 @@ typedef struct {
PurpleWhiteboard *silcpurple_wb_init(SilcPurple sg, SilcClientEntry client_entry)
{
- SilcClientConnection conn;
PurpleWhiteboard *wb;
SilcPurpleWb wbs;
- conn = sg->conn;
wb = purple_whiteboard_get_session(sg->account, client_entry->nickname);
if (!wb)
wb = purple_whiteboard_create(sg->account, client_entry->nickname, 0);
if (!wb)
return NULL;
- if (!wb->proto_data) {
+ if (!purple_whiteboard_get_protocol_data(wb)) {
wbs = silc_calloc(1, sizeof(*wbs));
if (!wbs)
return NULL;
@@ -126,7 +124,7 @@ PurpleWhiteboard *silcpurple_wb_init(SilcPurple sg, SilcClientEntry client_entry
wbs->height = SILCPURPLE_WB_HEIGHT;
wbs->brush_size = SILCPURPLE_WB_BRUSH_SMALL;
wbs->brush_color = SILCPURPLE_WB_COLOR_BLACK;
- wb->proto_data = wbs;
+ purple_whiteboard_set_protocol_data(wb, wbs);
/* Start the whiteboard */
purple_whiteboard_start(wb);
@@ -147,7 +145,7 @@ PurpleWhiteboard *silcpurple_wb_init_ch(SilcPurple sg, SilcChannelEntry channel)
if (!wb)
return NULL;
- if (!wb->proto_data) {
+ if (!purple_whiteboard_get_protocol_data(wb)) {
wbs = silc_calloc(1, sizeof(*wbs));
if (!wbs)
return NULL;
@@ -157,7 +155,7 @@ PurpleWhiteboard *silcpurple_wb_init_ch(SilcPurple sg, SilcChannelEntry channel)
wbs->height = SILCPURPLE_WB_HEIGHT;
wbs->brush_size = SILCPURPLE_WB_BRUSH_SMALL;
wbs->brush_color = SILCPURPLE_WB_COLOR_BLACK;
- wb->proto_data = wbs;
+ purple_whiteboard_set_protocol_data(wb, wbs);
/* Start the whiteboard */
purple_whiteboard_start(wb);
@@ -168,9 +166,10 @@ PurpleWhiteboard *silcpurple_wb_init_ch(SilcPurple sg, SilcChannelEntry channel)
}
static void
-silcpurple_wb_parse(SilcPurpleWb wbs, PurpleWhiteboard *wb,
+silcpurple_wb_parse(PurpleWhiteboard *wb,
unsigned char *message, SilcUInt32 message_len)
{
+ SilcPurpleWb wbs = purple_whiteboard_get_protocol_data(wb);
SilcUInt8 command;
SilcUInt16 width, height, brush_size;
SilcUInt32 brush_color, x, y, dx, dy;
@@ -238,15 +237,15 @@ silcpurple_wb_request_cb(SilcPurpleWbRequest req, gint id)
{
PurpleWhiteboard *wb;
- if (id != 1)
- goto out;
+ if (id != 1)
+ goto out;
if (!req->channel)
wb = silcpurple_wb_init(req->sg, req->sender);
else
wb = silcpurple_wb_init_ch(req->sg, req->channel);
- silcpurple_wb_parse(wb->proto_data, wb, req->message, req->message_len);
+ silcpurple_wb_parse(wb, req->message, req->message_len);
out:
silc_free(req->message);
@@ -264,7 +263,7 @@ silcpurple_wb_request(SilcClient client, const unsigned char *message,
SilcPurple sg;
gc = client->application;
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
/* Open whiteboard automatically if requested */
if (purple_account_get_bool(sg->account, "open-wb", FALSE)) {
@@ -275,7 +274,7 @@ silcpurple_wb_request(SilcClient client, const unsigned char *message,
else
wb = silcpurple_wb_init_ch(sg, channel);
- silcpurple_wb_parse(wb->proto_data, wb,
+ silcpurple_wb_parse(wb,
(unsigned char *)message,
message_len);
return;
@@ -318,12 +317,11 @@ void silcpurple_wb_receive(SilcClient client, SilcClientConnection conn,
SilcUInt32 message_len)
{
SilcPurple sg;
- PurpleConnection *gc;
+ PurpleConnection *gc;
PurpleWhiteboard *wb;
- SilcPurpleWb wbs;
gc = client->application;
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
wb = purple_whiteboard_get_session(sg->account, sender->nickname);
if (!wb) {
@@ -333,8 +331,7 @@ void silcpurple_wb_receive(SilcClient client, SilcClientConnection conn,
return;
}
- wbs = wb->proto_data;
- silcpurple_wb_parse(wbs, wb, (unsigned char *)message, message_len);
+ silcpurple_wb_parse(wb, (unsigned char *)message, message_len);
}
/* Process incoming whiteboard message on channel */
@@ -347,12 +344,11 @@ void silcpurple_wb_receive_ch(SilcClient client, SilcClientConnection conn,
SilcUInt32 message_len)
{
SilcPurple sg;
- PurpleConnection *gc;
+ PurpleConnection *gc;
PurpleWhiteboard *wb;
- SilcPurpleWb wbs;
gc = client->application;
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
wb = purple_whiteboard_get_session(sg->account, channel->channel_name);
if (!wb) {
@@ -362,25 +358,24 @@ void silcpurple_wb_receive_ch(SilcClient client, SilcClientConnection conn,
return;
}
- wbs = wb->proto_data;
- silcpurple_wb_parse(wbs, wb, (unsigned char *)message, message_len);
+ silcpurple_wb_parse(wb, (unsigned char *)message, message_len);
}
/* Send whiteboard message */
void silcpurple_wb_send(PurpleWhiteboard *wb, GList *draw_list)
{
- SilcPurpleWb wbs = wb->proto_data;
+ SilcPurpleWb wbs = purple_whiteboard_get_protocol_data(wb);
SilcBuffer packet;
GList *list;
int len;
- PurpleConnection *gc;
- SilcPurple sg;
+ PurpleConnection *gc;
+ SilcPurple sg;
g_return_if_fail(draw_list);
- gc = purple_account_get_connection(wb->account);
+ gc = purple_account_get_connection(purple_whiteboard_get_account(wb));
g_return_if_fail(gc);
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
g_return_if_fail(sg);
len = SILCPURPLE_WB_HEADER;
@@ -435,20 +430,22 @@ void silcpurple_wb_start(PurpleWhiteboard *wb)
void silcpurple_wb_end(PurpleWhiteboard *wb)
{
- silc_free(wb->proto_data);
- wb->proto_data = NULL;
+ SilcPurpleWb wbs = purple_whiteboard_get_protocol_data(wb);
+
+ silc_free(wbs);
+ purple_whiteboard_set_protocol_data(wb, NULL);
}
void silcpurple_wb_get_dimensions(const PurpleWhiteboard *wb, int *width, int *height)
{
- SilcPurpleWb wbs = wb->proto_data;
+ SilcPurpleWb wbs = purple_whiteboard_get_protocol_data(wb);
*width = wbs->width;
*height = wbs->height;
}
void silcpurple_wb_set_dimensions(PurpleWhiteboard *wb, int width, int height)
{
- SilcPurpleWb wbs = wb->proto_data;
+ SilcPurpleWb wbs = purple_whiteboard_get_protocol_data(wb);
wbs->width = width > SILCPURPLE_WB_WIDTH_MAX ? SILCPURPLE_WB_WIDTH_MAX :
width;
wbs->height = height > SILCPURPLE_WB_HEIGHT_MAX ? SILCPURPLE_WB_HEIGHT_MAX :
@@ -460,14 +457,14 @@ void silcpurple_wb_set_dimensions(PurpleWhiteboard *wb, int width, int height)
void silcpurple_wb_get_brush(const PurpleWhiteboard *wb, int *size, int *color)
{
- SilcPurpleWb wbs = wb->proto_data;
+ SilcPurpleWb wbs = purple_whiteboard_get_protocol_data(wb);
*size = wbs->brush_size;
*color = wbs->brush_color;
}
void silcpurple_wb_set_brush(PurpleWhiteboard *wb, int size, int color)
{
- SilcPurpleWb wbs = wb->proto_data;
+ SilcPurpleWb wbs = purple_whiteboard_get_protocol_data(wb);
wbs->brush_size = size;
wbs->brush_color = color;
@@ -477,15 +474,15 @@ void silcpurple_wb_set_brush(PurpleWhiteboard *wb, int size, int color)
void silcpurple_wb_clear(PurpleWhiteboard *wb)
{
- SilcPurpleWb wbs = wb->proto_data;
+ SilcPurpleWb wbs = purple_whiteboard_get_protocol_data(wb);
SilcBuffer packet;
int len;
- PurpleConnection *gc;
- SilcPurple sg;
+ PurpleConnection *gc;
+ SilcPurple sg;
- gc = purple_account_get_connection(wb->account);
+ gc = purple_account_get_connection(purple_whiteboard_get_account(wb));
g_return_if_fail(gc);
- sg = gc->proto_data;
+ sg = purple_connection_get_protocol_data(gc);
g_return_if_fail(sg);
len = SILCPURPLE_WB_HEADER;
diff --git a/libpurple/protocols/silc10/Makefile.am b/libpurple/protocols/silc10/Makefile.am
deleted file mode 100644
index 87db235724..0000000000
--- a/libpurple/protocols/silc10/Makefile.am
+++ /dev/null
@@ -1,36 +0,0 @@
-EXTRA_DIST = \
- Makefile.mingw \
- README \
- TODO
-
-pkgdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
-
-SILCSOURCES = silc.c silcpurple.h buddy.c chat.c ft.c ops.c pk.c util.c wb.c wb.h
-
-AM_CFLAGS = $(st)
-
-libsilcpurple_la_LDFLAGS = -module -avoid-version
-
-if STATIC_SILC
-
-st = -DPURPLE_STATIC_PRPL $(SILC_CFLAGS)
-noinst_LTLIBRARIES = libsilcpurple.la
-libsilcpurple_la_SOURCES = $(SILCSOURCES)
-libsilcpurple_la_CFLAGS = $(AM_CFLAGS)
-libsilcpurple_la_LIBADD = $(SILC_LIBS)
-
-else
-
-st = $(SILC_CFLAGS)
-pkg_LTLIBRARIES = libsilcpurple.la
-libsilcpurple_la_SOURCES = $(SILCSOURCES)
-libsilcpurple_la_LIBADD = $(GLIB_LIBS) $(SILC_LIBS)
-
-endif
-
-AM_CPPFLAGS = \
- -I$(top_srcdir)/libpurple \
- -I$(top_builddir)/libpurple \
- $(DEBUG_CFLAGS) \
- $(GLIB_CFLAGS) \
- $(SILC_CFLAGS)
diff --git a/libpurple/protocols/silc10/Makefile.mingw b/libpurple/protocols/silc10/Makefile.mingw
deleted file mode 100644
index d087b331a8..0000000000
--- a/libpurple/protocols/silc10/Makefile.mingw
+++ /dev/null
@@ -1,93 +0,0 @@
-#
-# Makefile.mingw
-#
-# Description: Makefile for win32 (mingw) version of libsilc protocol plugin
-#
-
-PIDGIN_TREE_TOP := ../../..
-include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
-
-DEFINES := $(subst -DWIN32_LEAN_AND_MEAN,,$(DEFINES))
-
-TARGET = libsilc
-NEEDED_DLLS = $(SILC_TOOLKIT)/lib/silc.dll \
- $(SILC_TOOLKIT)/lib/silcclient.dll
-TYPE = PLUGIN
-
-# Static or Plugin...
-ifeq ($(TYPE),STATIC)
- DEFINES += -DSTATIC
- DLL_INSTALL_DIR = $(PURPLE_INSTALL_DIR)
-else
-ifeq ($(TYPE),PLUGIN)
- DLL_INSTALL_DIR = $(PURPLE_INSTALL_PLUGINS_DIR)
-endif
-endif
-
-##
-## INCLUDE PATHS
-##
-INCLUDE_PATHS += -I. \
- -I$(GTK_TOP)/include \
- -I$(GTK_TOP)/include/glib-2.0 \
- -I$(GTK_TOP)/lib/glib-2.0/include \
- -I$(PURPLE_TOP) \
- -I$(PURPLE_TOP)/win32 \
- -I$(PIDGIN_TREE_TOP) \
- -I$(SILC_TOOLKIT)/include
-
-LIB_PATHS += -L$(GTK_TOP)/lib \
- -L$(PURPLE_TOP) \
- -L$(SILC_TOOLKIT)/lib
-
-##
-## SOURCES, OBJECTS
-##
-C_SRC = silc.c \
- buddy.c \
- chat.c \
- ft.c \
- ops.c \
- pk.c \
- util.c \
- wb.c
-
-OBJECTS = $(C_SRC:%.c=%.o)
-
-##
-## LIBRARIES
-##
-LIBS = \
- -lglib-2.0 \
- -lws2_32 \
- -lintl \
- -lpurple \
- -lsilc \
- -lsilcclient
-
-include $(PIDGIN_COMMON_RULES)
-
-##
-## TARGET DEFINITIONS
-##
-.PHONY: all install clean
-
-all: $(TARGET).dll
-
-install: all $(DLL_INSTALL_DIR) $(PURPLE_INSTALL_DIR)
- cp $(TARGET).dll $(DLL_INSTALL_DIR)
- cp $(NEEDED_DLLS) $(PURPLE_INSTALL_DIR)
-
-$(OBJECTS): $(PURPLE_CONFIG_H)
-
-$(TARGET).dll: $(PURPLE_DLL).a $(OBJECTS)
- $(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--image-base,0x64000000 -o $(TARGET).dll
-
-##
-## CLEAN RULES
-##
-clean:
- rm -f $(OBJECTS)
- rm -f $(TARGET).dll
-
-include $(PIDGIN_COMMON_TARGETS)
diff --git a/libpurple/protocols/silc10/README b/libpurple/protocols/silc10/README
deleted file mode 100644
index 90cbdb5025..0000000000
--- a/libpurple/protocols/silc10/README
+++ /dev/null
@@ -1,31 +0,0 @@
-SILC Purple Plugin
-==================
-
-This is the Purple protocol plugin of the protocol called Secure Internet
-Live Conferencing (SILC). The implementation will use the SILC Toolkit,
-freely available from the http://silcnet.org/ site, for the actual SILC
-protocol implementation.
-
-To include SILC into Purple, one needs to first compile and install
-the SILC Toolkit. It is done as follows:
-
- ./configure --enable-shared
- make
- make install
-
-This will compile shared libraries of the SILC Toolkit. If the --prefix
-is not given to ./configure, the binaries are installed into the
-/usr/local/silc directory.
-
-Once the Toolkit is installed one needs to tell Purple's ./configure
-script where the SILC Toolkit is located. It is done as simply as:
-
- ./configure
-
-if pkg-config is installed in your system. If it is isn't it's done as:
-
- ./configure --with-silc-libs=/path/to/silc/lib
- --with-silc-includes=/path/to/silc/include
-
-If the SILC Toolkit cannot be found then the SILC protocol plugin will
-not be compiled.
diff --git a/libpurple/protocols/silc10/TODO b/libpurple/protocols/silc10/TODO
deleted file mode 100644
index 285ca58485..0000000000
--- a/libpurple/protocols/silc10/TODO
+++ /dev/null
@@ -1,8 +0,0 @@
-Features TODO (maybe)
-=====================
-
-Preferences
- - Add joined channels to buddy list automatically (during
- session)
- - Add joined channels to buddy list automatically permanently
-
diff --git a/libpurple/protocols/silc10/buddy.c b/libpurple/protocols/silc10/buddy.c
deleted file mode 100644
index aaedee6088..0000000000
--- a/libpurple/protocols/silc10/buddy.c
+++ /dev/null
@@ -1,1748 +0,0 @@
-/*
-
- silcpurple_buddy.c
-
- Author: Pekka Riikonen <priikone@silcnet.org>
-
- Copyright (C) 2004 Pekka Riikonen
-
- 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; version 2 of the License.
-
- 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.
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-#include "silcpurple.h"
-#include "wb.h"
-
-/***************************** Key Agreement *********************************/
-
-static void
-silcpurple_buddy_keyagr(PurpleBlistNode *node, gpointer data);
-
-static void
-silcpurple_buddy_keyagr_do(PurpleConnection *gc, const char *name,
- gboolean force_local);
-
-typedef struct {
- char *nick;
- PurpleConnection *gc;
-} *SilcPurpleResolve;
-
-static void
-silcpurple_buddy_keyagr_resolved(SilcClient client,
- SilcClientConnection conn,
- SilcClientEntry *clients,
- SilcUInt32 clients_count,
- void *context)
-{
- PurpleConnection *gc = client->application;
- SilcPurpleResolve r = context;
- char tmp[256];
-
- if (!clients) {
- g_snprintf(tmp, sizeof(tmp),
- _("User %s is not present in the network"), r->nick);
- purple_notify_error(gc, _("Key Agreement"),
- _("Cannot perform the key agreement"), tmp);
- silc_free(r->nick);
- silc_free(r);
- return;
- }
-
- silcpurple_buddy_keyagr_do(gc, r->nick, FALSE);
- silc_free(r->nick);
- silc_free(r);
-}
-
-typedef struct {
- gboolean responder;
-} *SilcPurpleKeyAgr;
-
-static void
-silcpurple_buddy_keyagr_cb(SilcClient client,
- SilcClientConnection conn,
- SilcClientEntry client_entry,
- SilcKeyAgreementStatus status,
- SilcSKEKeyMaterial *key,
- void *context)
-{
- PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
- SilcPurpleKeyAgr a = context;
-
- if (!sg->conn)
- return;
-
- switch (status) {
- case SILC_KEY_AGREEMENT_OK:
- {
- PurpleConversation *convo;
- char tmp[128];
-
- /* Set the private key for this client */
- silc_client_del_private_message_key(client, conn, client_entry);
- silc_client_add_private_message_key_ske(client, conn, client_entry,
- NULL, NULL, key, a->responder);
- silc_ske_free_key_material(key);
-
-
- /* Open IM window */
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- client_entry->nickname, sg->account);
- if (convo) {
- /* we don't have windows in the core anymore...but we may want to
- * provide some method for asking the UI to show the window
- purple_conv_window_show(purple_conversation_get_window(convo));
- */
- } else {
- convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, sg->account,
- client_entry->nickname);
- }
- g_snprintf(tmp, sizeof(tmp), "%s [private key]", client_entry->nickname);
- purple_conversation_set_title(convo, tmp);
- }
- break;
-
- case SILC_KEY_AGREEMENT_ERROR:
- purple_notify_error(gc, _("Key Agreement"),
- _("Error occurred during key agreement"), NULL);
- break;
-
- case SILC_KEY_AGREEMENT_FAILURE:
- purple_notify_error(gc, _("Key Agreement"), _("Key Agreement failed"), NULL);
- break;
-
- case SILC_KEY_AGREEMENT_TIMEOUT:
- purple_notify_error(gc, _("Key Agreement"),
- _("Timeout during key agreement"), NULL);
- break;
-
- case SILC_KEY_AGREEMENT_ABORTED:
- purple_notify_error(gc, _("Key Agreement"),
- _("Key agreement was aborted"), NULL);
- break;
-
- case SILC_KEY_AGREEMENT_ALREADY_STARTED:
- purple_notify_error(gc, _("Key Agreement"),
- _("Key agreement is already started"), NULL);
- break;
-
- case SILC_KEY_AGREEMENT_SELF_DENIED:
- purple_notify_error(gc, _("Key Agreement"),
- _("Key agreement cannot be started with yourself"),
- NULL);
- break;
-
- default:
- break;
- }
-
- silc_free(a);
-}
-
-static void
-silcpurple_buddy_keyagr_do(PurpleConnection *gc, const char *name,
- gboolean force_local)
-{
- SilcPurple sg = gc->proto_data;
- SilcClientEntry *clients;
- SilcUInt32 clients_count;
- char *local_ip = NULL, *remote_ip = NULL;
- gboolean local = TRUE;
- char *nickname;
- SilcPurpleKeyAgr a;
-
- if (!sg->conn || !name)
- return;
-
- if (!silc_parse_userfqdn(name, &nickname, NULL))
- return;
-
- /* Find client entry */
- clients = silc_client_get_clients_local(sg->client, sg->conn, nickname, name,
- &clients_count);
- if (!clients) {
- /* Resolve unknown user */
- SilcPurpleResolve r = silc_calloc(1, sizeof(*r));
- if (!r)
- return;
- r->nick = g_strdup(name);
- r->gc = gc;
- silc_client_get_clients(sg->client, sg->conn, nickname, NULL,
- silcpurple_buddy_keyagr_resolved, r);
- silc_free(nickname);
- return;
- }
-
- /* Resolve the local IP from the outgoing socket connection. We resolve
- it to check whether we have a private range IP address or public IP
- address. If we have public then we will assume that we are not behind
- NAT and will provide automatically the point of connection to the
- agreement. If we have private range address we assume that we are
- behind NAT and we let the responder provide the point of connection.
-
- The algorithm also checks the remote IP address of server connection.
- If it is private range address and we have private range address we
- assume that we are chatting in LAN and will provide the point of
- connection.
-
- Naturally this algorithm does not always get things right. */
-
- if (silc_net_check_local_by_sock(sg->conn->sock->sock, NULL, &local_ip)) {
- /* Check if the IP is private */
- if (!force_local && silcpurple_ip_is_private(local_ip)) {
- local = FALSE;
-
- /* Local IP is private, resolve the remote server IP to see whether
- we are talking to Internet or just on LAN. */
- if (silc_net_check_host_by_sock(sg->conn->sock->sock, NULL,
- &remote_ip))
- if (silcpurple_ip_is_private(remote_ip))
- /* We assume we are in LAN. Let's provide
- the connection point. */
- local = TRUE;
- }
- }
-
- if (force_local)
- local = TRUE;
-
- if (local && !local_ip)
- local_ip = silc_net_localip();
-
- a = silc_calloc(1, sizeof(*a));
- if (!a)
- return;
- a->responder = local;
-
- /* Send the key agreement request */
- silc_client_send_key_agreement(sg->client, sg->conn, clients[0],
- local ? local_ip : NULL, NULL, 0, 60,
- silcpurple_buddy_keyagr_cb, a);
-
- silc_free(local_ip);
- silc_free(remote_ip);
- silc_free(clients);
-}
-
-typedef struct {
- SilcClient client;
- SilcClientConnection conn;
- SilcClientID client_id;
- char *hostname;
- SilcUInt16 port;
-} *SilcPurpleKeyAgrAsk;
-
-static void
-silcpurple_buddy_keyagr_request_cb(SilcPurpleKeyAgrAsk a, gint id)
-{
- SilcPurpleKeyAgr ai;
- SilcClientEntry client_entry;
-
- if (id != 1)
- goto out;
-
- /* Get the client entry. */
- client_entry = silc_client_get_client_by_id(a->client, a->conn,
- &a->client_id);
- if (!client_entry) {
- purple_notify_error(a->client->application, _("Key Agreement"),
- _("The remote user is not present in the network any more"),
- NULL);
- goto out;
- }
-
- /* If the hostname was provided by the requestor perform the key agreement
- now. Otherwise, we will send him a request to connect to us. */
- if (a->hostname) {
- ai = silc_calloc(1, sizeof(*ai));
- if (!ai)
- goto out;
- ai->responder = FALSE;
- silc_client_perform_key_agreement(a->client, a->conn, client_entry,
- a->hostname, a->port,
- silcpurple_buddy_keyagr_cb, ai);
- } else {
- /* Send request. Force us as the point of connection since requestor
- did not provide the point of connection. */
- silcpurple_buddy_keyagr_do(a->client->application,
- client_entry->nickname, TRUE);
- }
-
- out:
- silc_free(a->hostname);
- silc_free(a);
-}
-
-void silcpurple_buddy_keyagr_request(SilcClient client,
- SilcClientConnection conn,
- SilcClientEntry client_entry,
- const char *hostname, SilcUInt16 port)
-{
- char tmp[128], tmp2[128];
- SilcPurpleKeyAgrAsk a;
- PurpleConnection *gc = client->application;
-
- g_snprintf(tmp, sizeof(tmp),
- _("Key agreement request received from %s. Would you like to "
- "perform the key agreement?"), client_entry->nickname);
- if (hostname)
- g_snprintf(tmp2, sizeof(tmp2),
- _("The remote user is waiting key agreement on:\n"
- "Remote host: %s\nRemote port: %d"), hostname, port);
-
- a = silc_calloc(1, sizeof(*a));
- if (!a)
- return;
- a->client = client;
- a->conn = conn;
- a->client_id = *client_entry->id;
- if (hostname)
- a->hostname = strdup(hostname);
- a->port = port;
-
- purple_request_action(client->application, _("Key Agreement Request"), tmp,
- hostname ? tmp2 : NULL, 1, gc->account, client_entry->nickname,
- NULL, a, 2, _("Yes"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb),
- _("No"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb));
-}
-
-static void
-silcpurple_buddy_keyagr(PurpleBlistNode *node, gpointer data)
-{
- PurpleBuddy *buddy;
-
- buddy = (PurpleBuddy *)node;
- silcpurple_buddy_keyagr_do(buddy->account->gc, buddy->name, FALSE);
-}
-
-
-/**************************** Static IM Key **********************************/
-
-static void
-silcpurple_buddy_resetkey(PurpleBlistNode *node, gpointer data)
-{
- PurpleBuddy *b;
- PurpleConnection *gc;
- SilcPurple sg;
- char *nickname;
- SilcClientEntry *clients;
- SilcUInt32 clients_count;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
-
- b = (PurpleBuddy *) node;
- gc = purple_account_get_connection(b->account);
- sg = gc->proto_data;
-
- if (!silc_parse_userfqdn(b->name, &nickname, NULL))
- return;
-
- /* Find client entry */
- clients = silc_client_get_clients_local(sg->client, sg->conn,
- nickname, b->name,
- &clients_count);
- if (!clients) {
- silc_free(nickname);
- return;
- }
-
- clients[0]->prv_resp = FALSE;
- silc_client_del_private_message_key(sg->client, sg->conn,
- clients[0]);
- silc_free(clients);
- silc_free(nickname);
-}
-
-typedef struct {
- SilcClient client;
- SilcClientConnection conn;
- SilcClientID client_id;
-} *SilcPurplePrivkey;
-
-static void
-silcpurple_buddy_privkey(PurpleConnection *gc, const char *name);
-
-static void
-silcpurple_buddy_privkey_cb(SilcPurplePrivkey p, const char *passphrase)
-{
- SilcClientEntry client_entry;
-
- if (!passphrase || !(*passphrase)) {
- silc_free(p);
- return;
- }
-
- /* Get the client entry. */
- client_entry = silc_client_get_client_by_id(p->client, p->conn,
- &p->client_id);
- if (!client_entry) {
- purple_notify_error(p->client->application, _("IM With Password"),
- _("The remote user is not present in the network any more"),
- NULL);
- silc_free(p);
- return;
- }
-
- /* Set the private message key */
- silc_client_del_private_message_key(p->client, p->conn,
- client_entry);
- silc_client_add_private_message_key(p->client, p->conn,
- client_entry, NULL, NULL,
- (unsigned char *)passphrase,
- strlen(passphrase), FALSE,
- client_entry->prv_resp);
- if (!client_entry->prv_resp)
- silc_client_send_private_message_key_request(p->client,
- p->conn,
- client_entry);
- silc_free(p);
-}
-
-static void
-silcpurple_buddy_privkey_resolved(SilcClient client,
- SilcClientConnection conn,
- SilcClientEntry *clients,
- SilcUInt32 clients_count,
- void *context)
-{
- char tmp[256];
-
- if (!clients) {
- g_snprintf(tmp, sizeof(tmp),
- _("User %s is not present in the network"),
- (const char *)context);
- purple_notify_error(client->application, _("IM With Password"),
- _("Cannot set IM key"), tmp);
- g_free(context);
- return;
- }
-
- silcpurple_buddy_privkey(client->application, context);
- silc_free(context);
-}
-
-static void
-silcpurple_buddy_privkey(PurpleConnection *gc, const char *name)
-{
- SilcPurple sg = gc->proto_data;
- char *nickname;
- SilcPurplePrivkey p;
- SilcClientEntry *clients;
- SilcUInt32 clients_count;
-
- if (!name)
- return;
- if (!silc_parse_userfqdn(name, &nickname, NULL))
- return;
-
- /* Find client entry */
- clients = silc_client_get_clients_local(sg->client, sg->conn,
- nickname, name,
- &clients_count);
- if (!clients) {
- silc_client_get_clients(sg->client, sg->conn, nickname, NULL,
- silcpurple_buddy_privkey_resolved,
- g_strdup(name));
- silc_free(nickname);
- return;
- }
-
- p = silc_calloc(1, sizeof(*p));
- if (!p)
- return;
- p->client = sg->client;
- p->conn = sg->conn;
- p->client_id = *clients[0]->id;
- purple_request_input(gc, _("IM With Password"), NULL,
- _("Set IM Password"), NULL, FALSE, TRUE, NULL,
- _("OK"), G_CALLBACK(silcpurple_buddy_privkey_cb),
- _("Cancel"), G_CALLBACK(silcpurple_buddy_privkey_cb),
- gc->account, NULL, NULL, p);
-
- silc_free(clients);
- silc_free(nickname);
-}
-
-static void
-silcpurple_buddy_privkey_menu(PurpleBlistNode *node, gpointer data)
-{
- PurpleBuddy *buddy;
- PurpleConnection *gc;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
-
- buddy = (PurpleBuddy *) node;
- gc = purple_account_get_connection(buddy->account);
-
- silcpurple_buddy_privkey(gc, buddy->name);
-}
-
-
-/**************************** Get Public Key *********************************/
-
-typedef struct {
- SilcClient client;
- SilcClientConnection conn;
- SilcClientID client_id;
-} *SilcPurpleBuddyGetkey;
-
-static void
-silcpurple_buddy_getkey(PurpleConnection *gc, const char *name);
-
-static void
-silcpurple_buddy_getkey_cb(SilcPurpleBuddyGetkey g,
- SilcClientCommandReplyContext cmd)
-{
- SilcClientEntry client_entry;
- unsigned char *pk;
- SilcUInt32 pk_len;
-
- /* Get the client entry. */
- client_entry = silc_client_get_client_by_id(g->client, g->conn,
- &g->client_id);
- if (!client_entry) {
- purple_notify_error(g->client->application, _("Get Public Key"),
- _("The remote user is not present in the network any more"),
- NULL);
- silc_free(g);
- return;
- }
-
- if (!client_entry->public_key) {
- silc_free(g);
- return;
- }
-
- /* Now verify the public key */
- pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len);
- silcpurple_verify_public_key(g->client, g->conn, client_entry->nickname,
- SILC_SOCKET_TYPE_CLIENT,
- pk, pk_len, SILC_SKE_PK_TYPE_SILC,
- NULL, NULL);
- silc_free(pk);
- silc_free(g);
-}
-
-static void
-silcpurple_buddy_getkey_resolved(SilcClient client,
- SilcClientConnection conn,
- SilcClientEntry *clients,
- SilcUInt32 clients_count,
- void *context)
-{
- char tmp[256];
-
- if (!clients) {
- g_snprintf(tmp, sizeof(tmp),
- _("User %s is not present in the network"),
- (const char *)context);
- purple_notify_error(client->application, _("Get Public Key"),
- _("Cannot fetch the public key"), tmp);
- g_free(context);
- return;
- }
-
- silcpurple_buddy_getkey(client->application, context);
- silc_free(context);
-}
-
-static void
-silcpurple_buddy_getkey(PurpleConnection *gc, const char *name)
-{
- SilcPurple sg = gc->proto_data;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- SilcClientEntry *clients;
- SilcUInt32 clients_count;
- SilcPurpleBuddyGetkey g;
- char *nickname;
-
- if (!name)
- return;
-
- if (!silc_parse_userfqdn(name, &nickname, NULL))
- return;
-
- /* Find client entry */
- clients = silc_client_get_clients_local(client, conn, nickname, name,
- &clients_count);
- if (!clients) {
- silc_client_get_clients(client, conn, nickname, NULL,
- silcpurple_buddy_getkey_resolved,
- g_strdup(name));
- silc_free(nickname);
- return;
- }
-
- /* Call GETKEY */
- g = silc_calloc(1, sizeof(*g));
- if (!g)
- return;
- g->client = client;
- g->conn = conn;
- g->client_id = *clients[0]->id;
- silc_client_command_call(client, conn, NULL, "GETKEY",
- clients[0]->nickname, NULL);
- silc_client_command_pending(conn, SILC_COMMAND_GETKEY,
- conn->cmd_ident,
- (SilcCommandCb)silcpurple_buddy_getkey_cb, g);
- silc_free(clients);
- silc_free(nickname);
-}
-
-static void
-silcpurple_buddy_getkey_menu(PurpleBlistNode *node, gpointer data)
-{
- PurpleBuddy *buddy;
- PurpleConnection *gc;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
-
- buddy = (PurpleBuddy *) node;
- gc = purple_account_get_connection(buddy->account);
-
- silcpurple_buddy_getkey(gc, buddy->name);
-}
-
-static void
-silcpurple_buddy_showkey(PurpleBlistNode *node, gpointer data)
-{
- PurpleBuddy *b;
- PurpleConnection *gc;
- SilcPurple sg;
- SilcPublicKey public_key;
- const char *pkfile;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
-
- b = (PurpleBuddy *) node;
- gc = purple_account_get_connection(b->account);
- sg = gc->proto_data;
-
- pkfile = purple_blist_node_get_string(node, "public-key");
- if (!silc_pkcs_load_public_key(pkfile, &public_key, SILC_PKCS_FILE_PEM) &&
- !silc_pkcs_load_public_key(pkfile, &public_key, SILC_PKCS_FILE_BIN)) {
- purple_notify_error(gc,
- _("Show Public Key"),
- _("Could not load public key"), NULL);
- return;
- }
-
- silcpurple_show_public_key(sg, b->name, public_key, NULL, NULL);
- silc_pkcs_public_key_free(public_key);
-}
-
-
-/**************************** Buddy routines *********************************/
-
-/* The buddies are implemented by using the WHOIS and WATCH commands that
- can be used to search users by their public key. Since nicknames aren't
- unique in SILC we cannot trust the buddy list using their nickname. We
- associate public keys to buddies and use those to search and watch
- in the network.
-
- The problem is that Purple does not return PurpleBuddy contexts to the
- callbacks but the buddy names. Naturally, this is not going to work
- with SILC. But, for now, we have to do what we can... */
-
-typedef struct {
- SilcClient client;
- SilcClientConnection conn;
- SilcClientID client_id;
- PurpleBuddy *b;
- unsigned char *offline_pk;
- SilcUInt32 offline_pk_len;
- unsigned int offline : 1;
- unsigned int pubkey_search : 1;
- unsigned int init : 1;
-} *SilcPurpleBuddyRes;
-
-static void
-silcpurple_add_buddy_ask_pk_cb(SilcPurpleBuddyRes r, gint id);
-static void
-silcpurple_add_buddy_resolved(SilcClient client,
- SilcClientConnection conn,
- SilcClientEntry *clients,
- SilcUInt32 clients_count,
- void *context);
-
-void silcpurple_get_info(PurpleConnection *gc, const char *who)
-{
- SilcPurple sg = gc->proto_data;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- SilcClientEntry client_entry;
- PurpleBuddy *b;
- const char *filename, *nick = who;
- char tmp[256];
-
- if (!who)
- return;
- if (strlen(who) > 1 && who[0] == '@')
- nick = who + 1;
- if (strlen(who) > 1 && who[0] == '*')
- nick = who + 1;
- if (strlen(who) > 2 && who[0] == '*' && who[1] == '@')
- nick = who + 2;
-
- b = purple_find_buddy(gc->account, nick);
- if (b) {
- /* See if we have this buddy's public key. If we do use that
- to search the details. */
- filename = purple_blist_node_get_string((PurpleBlistNode *)b, "public-key");
- if (filename) {
- /* Call WHOIS. The user info is displayed in the WHOIS
- command reply. */
- silc_client_command_call(client, conn, NULL, "WHOIS",
- "-details", "-pubkey", filename, NULL);
- return;
- }
-
- if (!b->proto_data) {
- g_snprintf(tmp, sizeof(tmp),
- _("User %s is not present in the network"), b->name);
- purple_notify_error(gc, _("User Information"),
- _("Cannot get user information"), tmp);
- return;
- }
-
- client_entry = silc_client_get_client_by_id(client, conn, b->proto_data);
- if (client_entry) {
- /* Call WHOIS. The user info is displayed in the WHOIS
- command reply. */
- silc_client_command_call(client, conn, NULL, "WHOIS",
- client_entry->nickname, "-details", NULL);
- }
- } else {
- /* Call WHOIS just with nickname. */
- silc_client_command_call(client, conn, NULL, "WHOIS", nick, NULL);
- }
-}
-
-static void
-silcpurple_add_buddy_pk_no(SilcPurpleBuddyRes r)
-{
- char tmp[512];
- g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not trusted"),
- r->b->name);
- purple_notify_error(r->client->application, _("Add Buddy"), tmp,
- _("You cannot receive buddy notifications until you "
- "import his/her public key. You can use the Get Public Key "
- "command to get the public key."));
- purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_OFFLINE, NULL);
-}
-
-static void
-silcpurple_add_buddy_save(bool success, void *context)
-{
- SilcPurpleBuddyRes r = context;
- PurpleBuddy *b = r->b;
- SilcClient client = r->client;
- SilcClientEntry client_entry;
- SilcAttributePayload attr;
- SilcAttribute attribute;
- SilcVCardStruct vcard;
- SilcAttributeObjMime message, extension;
-#ifdef SILC_ATTRIBUTE_USER_ICON
- SilcAttributeObjMime usericon;
-#endif
- SilcAttributeObjPk serverpk, usersign, serversign;
- gboolean usign_success = TRUE, ssign_success = TRUE;
- char filename[512], filename2[512], *fingerprint = NULL, *tmp;
- SilcUInt32 len;
- int i;
-
- if (!success) {
- /* The user did not trust the public key. */
- silcpurple_add_buddy_pk_no(r);
- silc_free(r);
- return;
- }
-
- if (r->offline) {
- /* User is offline. Associate the imported public key with
- this user. */
- fingerprint = silc_hash_fingerprint(NULL, r->offline_pk,
- r->offline_pk_len);
- for (i = 0; i < strlen(fingerprint); i++)
- if (fingerprint[i] == ' ')
- fingerprint[i] = '_';
- g_snprintf(filename, sizeof(filename) - 1,
- "%s" G_DIR_SEPARATOR_S "clientkeys" G_DIR_SEPARATOR_S "clientkey_%s.pub",
- silcpurple_silcdir(), fingerprint);
- purple_blist_node_set_string((PurpleBlistNode *)b, "public-key", filename);
- purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_OFFLINE, NULL);
- silc_free(fingerprint);
- silc_free(r->offline_pk);
- silc_free(r);
- return;
- }
-
- /* Get the client entry. */
- client_entry = silc_client_get_client_by_id(r->client, r->conn,
- &r->client_id);
- if (!client_entry) {
- silc_free(r);
- return;
- }
-
- memset(&vcard, 0, sizeof(vcard));
- memset(&message, 0, sizeof(message));
- memset(&extension, 0, sizeof(extension));
-#ifdef SILC_ATTRIBUTE_USER_ICON
- memset(&usericon, 0, sizeof(usericon));
-#endif
- memset(&serverpk, 0, sizeof(serverpk));
- memset(&usersign, 0, sizeof(usersign));
- memset(&serversign, 0, sizeof(serversign));
-
- /* Now that we have the public key and we trust it now we
- save the attributes of the buddy and update its status. */
-
- if (client_entry->attrs) {
- silc_dlist_start(client_entry->attrs);
- while ((attr = silc_dlist_get(client_entry->attrs))
- != SILC_LIST_END) {
- attribute = silc_attribute_get_attribute(attr);
-
- switch (attribute) {
- case SILC_ATTRIBUTE_USER_INFO:
- if (!silc_attribute_get_object(attr, (void *)&vcard,
- sizeof(vcard)))
- continue;
- break;
-
- case SILC_ATTRIBUTE_STATUS_MESSAGE:
- if (!silc_attribute_get_object(attr, (void *)&message,
- sizeof(message)))
- continue;
- break;
-
- case SILC_ATTRIBUTE_EXTENSION:
- if (!silc_attribute_get_object(attr, (void *)&extension,
- sizeof(extension)))
- continue;
- break;
-
-#ifdef SILC_ATTRIBUTE_USER_ICON
- case SILC_ATTRIBUTE_USER_ICON:
- if (!silc_attribute_get_object(attr, (void *)&usericon,
- sizeof(usericon)))
- continue;
- break;
-#endif
-
- case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY:
- if (serverpk.type)
- continue;
- if (!silc_attribute_get_object(attr, (void *)&serverpk,
- sizeof(serverpk)))
- continue;
- break;
-
- case SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE:
- if (usersign.data)
- continue;
- if (!silc_attribute_get_object(attr, (void *)&usersign,
- sizeof(usersign)))
- continue;
- break;
-
- case SILC_ATTRIBUTE_SERVER_DIGITAL_SIGNATURE:
- if (serversign.data)
- continue;
- if (!silc_attribute_get_object(attr, (void *)&serversign,
- sizeof(serversign)))
- continue;
- break;
-
- default:
- break;
- }
- }
- }
-
- /* Verify the attribute signatures */
-
- if (usersign.data) {
- SilcPKCS pkcs;
- unsigned char *verifyd;
- SilcUInt32 verify_len;
-
- silc_pkcs_alloc((unsigned char*)"rsa", &pkcs);
- verifyd = silc_attribute_get_verify_data(client_entry->attrs,
- FALSE, &verify_len);
- if (verifyd && silc_pkcs_public_key_set(pkcs, client_entry->public_key)){
- if (!silc_pkcs_verify_with_hash(pkcs, client->sha1hash,
- usersign.data,
- usersign.data_len,
- verifyd, verify_len))
- usign_success = FALSE;
- }
- silc_free(verifyd);
- }
-
- if (serversign.data && !strcmp(serverpk.type, "silc-rsa")) {
- SilcPublicKey public_key;
- SilcPKCS pkcs;
- unsigned char *verifyd;
- SilcUInt32 verify_len;
-
- if (silc_pkcs_public_key_decode(serverpk.data, serverpk.data_len,
- &public_key)) {
- silc_pkcs_alloc((unsigned char *)"rsa", &pkcs);
- verifyd = silc_attribute_get_verify_data(client_entry->attrs,
- TRUE, &verify_len);
- if (verifyd && silc_pkcs_public_key_set(pkcs, public_key)) {
- if (!silc_pkcs_verify_with_hash(pkcs, client->sha1hash,
- serversign.data,
- serversign.data_len,
- verifyd, verify_len))
- ssign_success = FALSE;
- }
- silc_pkcs_public_key_free(public_key);
- silc_free(verifyd);
- }
- }
-
- fingerprint = silc_fingerprint(client_entry->fingerprint,
- client_entry->fingerprint_len);
- for (i = 0; i < strlen(fingerprint); i++)
- if (fingerprint[i] == ' ')
- fingerprint[i] = '_';
-
- if (usign_success || ssign_success) {
- struct passwd *pw;
- struct stat st;
-
- memset(filename2, 0, sizeof(filename2));
-
- /* Filename for dir */
- tmp = fingerprint + strlen(fingerprint) - 9;
- g_snprintf(filename, sizeof(filename) - 1,
- "%s" G_DIR_SEPARATOR_S "friends" G_DIR_SEPARATOR_S "%s",
- silcpurple_silcdir(), tmp);
-
- pw = getpwuid(getuid());
- if (!pw)
- return;
-
- /* Create dir if it doesn't exist */
- if ((g_stat(filename, &st)) == -1) {
- if (errno == ENOENT) {
- if (pw->pw_uid == geteuid()) {
- int ret = g_mkdir(filename, 0755);
- if (ret < 0)
- return;
- }
- }
- }
-
- /* Save VCard */
- g_snprintf(filename2, sizeof(filename2) - 1,
- "%s" G_DIR_SEPARATOR_S "vcard", filename);
- if (vcard.full_name) {
- tmp = (char *)silc_vcard_encode(&vcard, &len);
- silc_file_writefile(filename2, tmp, len);
- silc_free(tmp);
- }
-
- /* Save status message */
- if (message.mime) {
- memset(filename2, 0, sizeof(filename2));
- g_snprintf(filename2, sizeof(filename2) - 1,
- "%s" G_DIR_SEPARATOR_S "status_message.mime",
- filename);
- silc_file_writefile(filename2, (char *)message.mime,
- message.mime_len);
- }
-
- /* Save extension data */
- if (extension.mime) {
- memset(filename2, 0, sizeof(filename2));
- g_snprintf(filename2, sizeof(filename2) - 1,
- "%s" G_DIR_SEPARATOR_S "extension.mime",
- filename);
- silc_file_writefile(filename2, (char *)extension.mime,
- extension.mime_len);
- }
-
-#ifdef SILC_ATTRIBUTE_USER_ICON
- /* Save user icon */
- if (usericon.mime) {
- SilcMime m = silc_mime_decode(usericon.mime,
- usericon.mime_len);
- if (m) {
- const char *type = silc_mime_get_field(m, "Content-Type");
- if (!strcmp(type, "image/jpeg") ||
- !strcmp(type, "image/gif") ||
- !strcmp(type, "image/bmp") ||
- !strcmp(type, "image/png")) {
- const unsigned char *data;
- SilcUInt32 data_len;
- data = silc_mime_get_data(m, &data_len);
- if (data) {
- /* TODO: Check if SILC gives us something to use as the checksum instead */
- purple_buddy_icons_set_for_user(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), g_memdup(data, data_len), data_len, NULL);
- }
- }
- silc_mime_free(m);
- }
- }
-#endif
- }
-
- /* Save the public key path to buddy properties, as it is used
- to identify the buddy in the network (and not the nickname). */
- memset(filename, 0, sizeof(filename));
- g_snprintf(filename, sizeof(filename) - 1,
- "%s" G_DIR_SEPARATOR_S "clientkeys" G_DIR_SEPARATOR_S "clientkey_%s.pub",
- silcpurple_silcdir(), fingerprint);
- purple_blist_node_set_string((PurpleBlistNode *)b, "public-key", filename);
-
- /* Update online status */
- purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_AVAILABLE, NULL);
-
- /* Finally, start watching this user so we receive its status
- changes from the server */
- g_snprintf(filename2, sizeof(filename2) - 1, "+%s", filename);
- silc_client_command_call(r->client, r->conn, NULL, "WATCH", "-pubkey",
- filename2, NULL);
-
- silc_free(fingerprint);
- silc_free(r);
-}
-
-static void
-silcpurple_add_buddy_ask_import(void *user_data, const char *name)
-{
- SilcPurpleBuddyRes r = (SilcPurpleBuddyRes)user_data;
- SilcPublicKey public_key;
-
- /* Load the public key */
- if (!silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_PEM) &&
- !silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_BIN)) {
- silcpurple_add_buddy_ask_pk_cb(r, 0);
- purple_notify_error(r->client->application,
- _("Add Buddy"), _("Could not load public key"), NULL);
- return;
- }
-
- /* Now verify the public key */
- r->offline_pk = silc_pkcs_public_key_encode(public_key, &r->offline_pk_len);
- silcpurple_verify_public_key(r->client, r->conn, r->b->name,
- SILC_SOCKET_TYPE_CLIENT,
- r->offline_pk, r->offline_pk_len,
- SILC_SKE_PK_TYPE_SILC,
- silcpurple_add_buddy_save, r);
-}
-
-static void
-silcpurple_add_buddy_ask_pk_cancel(void *user_data, const char *name)
-{
- SilcPurpleBuddyRes r = (SilcPurpleBuddyRes)user_data;
-
- /* The user did not import public key. The buddy is unusable. */
- silcpurple_add_buddy_pk_no(r);
- silc_free(r);
-}
-
-static void
-silcpurple_add_buddy_ask_pk_cb(SilcPurpleBuddyRes r, gint id)
-{
- if (id != 0) {
- /* The user did not import public key. The buddy is unusable. */
- silcpurple_add_buddy_pk_no(r);
- silc_free(r);
- return;
- }
-
- /* Open file selector to select the public key. */
- purple_request_file(r->client->application, _("Open..."), NULL, FALSE,
- G_CALLBACK(silcpurple_add_buddy_ask_import),
- G_CALLBACK(silcpurple_add_buddy_ask_pk_cancel),
- purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r);
-
-}
-
-static void
-silcpurple_add_buddy_ask_pk(SilcPurpleBuddyRes r)
-{
- char tmp[512];
- g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not present in the network"),
- r->b->name);
- purple_request_action(r->client->application, _("Add Buddy"), tmp,
- _("To add the buddy you must import his/her public key. "
- "Press Import to import a public key."), 0,
- purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r, 2,
- _("Cancel"), G_CALLBACK(silcpurple_add_buddy_ask_pk_cb),
- _("_Import..."), G_CALLBACK(silcpurple_add_buddy_ask_pk_cb));
-}
-
-static void
-silcpurple_add_buddy_getkey_cb(SilcPurpleBuddyRes r,
- SilcClientCommandReplyContext cmd)
-{
- SilcClientEntry client_entry;
- unsigned char *pk;
- SilcUInt32 pk_len;
-
- /* Get the client entry. */
- client_entry = silc_client_get_client_by_id(r->client, r->conn,
- &r->client_id);
- if (!client_entry || !client_entry->public_key) {
- /* The buddy is offline/nonexistent. We will require user
- to associate a public key with the buddy or the buddy
- cannot be added. */
- r->offline = TRUE;
- silcpurple_add_buddy_ask_pk(r);
- return;
- }
-
- /* Now verify the public key */
- pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len);
- silcpurple_verify_public_key(r->client, r->conn, client_entry->nickname,
- SILC_SOCKET_TYPE_CLIENT,
- pk, pk_len, SILC_SKE_PK_TYPE_SILC,
- silcpurple_add_buddy_save, r);
- silc_free(pk);
-}
-
-static void
-silcpurple_add_buddy_select_cb(SilcPurpleBuddyRes r, PurpleRequestFields *fields)
-{
- PurpleRequestField *f;
- GList *list;
- SilcClientEntry client_entry;
-
- f = purple_request_fields_get_field(fields, "list");
- list = purple_request_field_list_get_selected(f);
- if (!list) {
- /* The user did not select any user. */
- silcpurple_add_buddy_pk_no(r);
- silc_free(r);
- return;
- }
-
- client_entry = purple_request_field_list_get_data(f, list->data);
- silcpurple_add_buddy_resolved(r->client, r->conn, &client_entry, 1, r);
-}
-
-static void
-silcpurple_add_buddy_select_cancel(SilcPurpleBuddyRes r, PurpleRequestFields *fields)
-{
- /* The user did not select any user. */
- silcpurple_add_buddy_pk_no(r);
- silc_free(r);
-}
-
-static void
-silcpurple_add_buddy_select(SilcPurpleBuddyRes r,
- SilcClientEntry *clients,
- SilcUInt32 clients_count)
-{
- PurpleRequestFields *fields;
- PurpleRequestFieldGroup *g;
- PurpleRequestField *f;
- char tmp[512], tmp2[128];
- int i;
- char *fingerprint;
-
- fields = purple_request_fields_new();
- g = purple_request_field_group_new(NULL);
- f = purple_request_field_list_new("list", NULL);
- purple_request_field_group_add_field(g, f);
- purple_request_field_list_set_multi_select(f, FALSE);
- purple_request_fields_add_group(fields, g);
-
- for (i = 0; i < clients_count; i++) {
- fingerprint = NULL;
- if (clients[i]->fingerprint) {
- fingerprint = silc_fingerprint(clients[i]->fingerprint,
- clients[i]->fingerprint_len);
- g_snprintf(tmp2, sizeof(tmp2), "\n%s", fingerprint);
- }
- g_snprintf(tmp, sizeof(tmp), "%s - %s (%s@%s)%s",
- clients[i]->realname, clients[i]->nickname,
- clients[i]->username, clients[i]->hostname ?
- clients[i]->hostname : "",
- fingerprint ? tmp2 : "");
- purple_request_field_list_add_icon(f, tmp, NULL, clients[i]);
- silc_free(fingerprint);
- }
-
- purple_request_fields(r->client->application, _("Add Buddy"),
- _("Select correct user"),
- r->pubkey_search
- ? _("More than one user was found with the same public key. Select "
- "the correct user from the list to add to the buddy list.")
- : _("More than one user was found with the same name. Select "
- "the correct user from the list to add to the buddy list."),
- fields,
- _("OK"), G_CALLBACK(silcpurple_add_buddy_select_cb),
- _("Cancel"), G_CALLBACK(silcpurple_add_buddy_select_cancel),
- purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r);
-}
-
-static void
-silcpurple_add_buddy_resolved(SilcClient client,
- SilcClientConnection conn,
- SilcClientEntry *clients,
- SilcUInt32 clients_count,
- void *context)
-{
- SilcPurpleBuddyRes r = context;
- PurpleBuddy *b = r->b;
- SilcAttributePayload pub;
- SilcAttributeObjPk userpk;
- unsigned char *pk;
- SilcUInt32 pk_len;
- const char *filename;
-
- filename = purple_blist_node_get_string((PurpleBlistNode *)b, "public-key");
-
- /* If the buddy is offline/nonexistent, we will require user
- to associate a public key with the buddy or the buddy
- cannot be added. */
- if (!clients_count) {
- if (r->init) {
- silc_free(r);
- return;
- }
-
- r->offline = TRUE;
- /* If the user has already associated a public key, try loading it
- * before prompting the user to load it again */
- if (filename != NULL)
- silcpurple_add_buddy_ask_import(r, filename);
- else
- silcpurple_add_buddy_ask_pk(r);
- return;
- }
-
- /* If more than one client was found with nickname, we need to verify
- from user which one is the correct. */
- if (clients_count > 1 && !r->pubkey_search) {
- if (r->init) {
- silc_free(r);
- return;
- }
-
- silcpurple_add_buddy_select(r, clients, clients_count);
- return;
- }
-
- /* If we searched using public keys and more than one entry was found
- the same person is logged on multiple times. */
- if (clients_count > 1 && r->pubkey_search && b->name) {
- if (r->init) {
- /* Find the entry that closest matches to the
- buddy nickname. */
- int i;
- for (i = 0; i < clients_count; i++) {
- if (!g_ascii_strncasecmp(b->name, clients[i]->nickname,
- strlen(b->name))) {
- clients[0] = clients[i];
- break;
- }
- }
- } else {
- /* Verify from user which one is correct */
- silcpurple_add_buddy_select(r, clients, clients_count);
- return;
- }
- }
-
- /* The client was found. Now get its public key and verify
- that before adding the buddy. */
- memset(&userpk, 0, sizeof(userpk));
- b->proto_data = silc_memdup(clients[0]->id, sizeof(*clients[0]->id));
- r->client_id = *clients[0]->id;
-
- /* Get the public key from attributes, if not present then
- resolve it with GETKEY unless we have it cached already. */
- if (clients[0]->attrs && !clients[0]->public_key) {
- pub = silcpurple_get_attr(clients[0]->attrs,
- SILC_ATTRIBUTE_USER_PUBLIC_KEY);
- if (!pub || !silc_attribute_get_object(pub, (void *)&userpk,
- sizeof(userpk))) {
- /* Get public key with GETKEY */
- silc_client_command_call(client, conn, NULL,
- "GETKEY", clients[0]->nickname, NULL);
- silc_client_command_pending(conn, SILC_COMMAND_GETKEY,
- conn->cmd_ident,
- (SilcCommandCb)silcpurple_add_buddy_getkey_cb,
- r);
- return;
- }
- if (!silc_pkcs_public_key_decode(userpk.data, userpk.data_len,
- &clients[0]->public_key))
- return;
- silc_free(userpk.data);
- } else if (filename && !clients[0]->public_key) {
- if (!silc_pkcs_load_public_key(filename, &clients[0]->public_key,
- SILC_PKCS_FILE_PEM) &&
- !silc_pkcs_load_public_key(filename, &clients[0]->public_key,
- SILC_PKCS_FILE_BIN)) {
- /* Get public key with GETKEY */
- silc_client_command_call(client, conn, NULL,
- "GETKEY", clients[0]->nickname, NULL);
- silc_client_command_pending(conn, SILC_COMMAND_GETKEY,
- conn->cmd_ident,
- (SilcCommandCb)silcpurple_add_buddy_getkey_cb,
- r);
- return;
- }
- } else if (!clients[0]->public_key) {
- /* Get public key with GETKEY */
- silc_client_command_call(client, conn, NULL,
- "GETKEY", clients[0]->nickname, NULL);
- silc_client_command_pending(conn, SILC_COMMAND_GETKEY,
- conn->cmd_ident,
- (SilcCommandCb)silcpurple_add_buddy_getkey_cb,
- r);
- return;
- }
-
- /* We have the public key, verify it. */
- pk = silc_pkcs_public_key_encode(clients[0]->public_key, &pk_len);
- silcpurple_verify_public_key(client, conn, clients[0]->nickname,
- SILC_SOCKET_TYPE_CLIENT,
- pk, pk_len, SILC_SKE_PK_TYPE_SILC,
- silcpurple_add_buddy_save, r);
- silc_free(pk);
-}
-
-static void
-silcpurple_add_buddy_i(PurpleConnection *gc, PurpleBuddy *b, gboolean init)
-{
- SilcPurple sg = gc->proto_data;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- SilcPurpleBuddyRes r;
- SilcBuffer attrs;
- const char *filename, *name = b->name;
-
- r = silc_calloc(1, sizeof(*r));
- if (!r)
- return;
- r->client = client;
- r->conn = conn;
- r->b = b;
- r->init = init;
-
- /* See if we have this buddy's public key. If we do use that
- to search the details. */
- filename = purple_blist_node_get_string((PurpleBlistNode *)b, "public-key");
- if (filename) {
- SilcPublicKey public_key;
- SilcAttributeObjPk userpk;
-
- if (!silc_pkcs_load_public_key(filename, &public_key,
- SILC_PKCS_FILE_PEM) &&
- !silc_pkcs_load_public_key(filename, &public_key,
- SILC_PKCS_FILE_BIN))
- return;
-
- /* Get all attributes, and use the public key to search user */
- name = NULL;
- attrs = silc_client_attributes_request(SILC_ATTRIBUTE_USER_INFO,
- SILC_ATTRIBUTE_SERVICE,
- SILC_ATTRIBUTE_STATUS_MOOD,
- SILC_ATTRIBUTE_STATUS_FREETEXT,
- SILC_ATTRIBUTE_STATUS_MESSAGE,
- SILC_ATTRIBUTE_PREFERRED_LANGUAGE,
- SILC_ATTRIBUTE_PREFERRED_CONTACT,
- SILC_ATTRIBUTE_TIMEZONE,
- SILC_ATTRIBUTE_GEOLOCATION,
-#ifdef SILC_ATTRIBUTE_USER_ICON
- SILC_ATTRIBUTE_USER_ICON,
-#endif
- SILC_ATTRIBUTE_DEVICE_INFO, 0);
- userpk.type = "silc-rsa";
- userpk.data = silc_pkcs_public_key_encode(public_key, &userpk.data_len);
- attrs = silc_attribute_payload_encode(attrs,
- SILC_ATTRIBUTE_USER_PUBLIC_KEY,
- SILC_ATTRIBUTE_FLAG_VALID,
- &userpk, sizeof(userpk));
- silc_free(userpk.data);
- silc_pkcs_public_key_free(public_key);
- r->pubkey_search = TRUE;
- } else {
- /* Get all attributes */
- attrs = silc_client_attributes_request(0);
- }
-
- /* Resolve */
- silc_client_get_clients_whois(client, conn, name, NULL, attrs,
- silcpurple_add_buddy_resolved, r);
- silc_buffer_free(attrs);
-}
-
-void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
-{
- /* Don't add if the buddy is already on the list.
- *
- * SILC doesn't have groups, so we don't need to do anything
- * for a move. */
- if (purple_buddy_get_protocol_data(buddy) == NULL)
- silcpurple_add_buddy_i(gc, buddy, FALSE);
-}
-
-void silcpurple_send_buddylist(PurpleConnection *gc)
-{
- PurpleBuddyList *blist;
- PurpleBlistNode *gnode, *cnode, *bnode;
- PurpleBuddy *buddy;
- PurpleAccount *account;
-
- account = purple_connection_get_account(gc);
-
- if ((blist = purple_get_blist()) != NULL)
- {
- for (gnode = blist->root; gnode != NULL; gnode = gnode->next)
- {
- if (!PURPLE_BLIST_NODE_IS_GROUP(gnode))
- continue;
- for (cnode = gnode->child; cnode != NULL; cnode = cnode->next)
- {
- if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode))
- continue;
- for (bnode = cnode->child; bnode != NULL; bnode = bnode->next)
- {
- if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode))
- continue;
- buddy = (PurpleBuddy *)bnode;
- if (purple_buddy_get_account(buddy) == account)
- silcpurple_add_buddy_i(gc, buddy, TRUE);
- }
- }
- }
- }
-}
-
-void silcpurple_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
- PurpleGroup *group)
-{
- silc_free(buddy->proto_data);
-}
-
-void silcpurple_idle_set(PurpleConnection *gc, int idle)
-
-{
- SilcPurple sg;
- SilcClient client;
- SilcClientConnection conn;
- SilcAttributeObjService service;
- const char *server;
- int port;
-
- sg = gc->proto_data;
- if (sg == NULL)
- return;
-
- client = sg->client;
- if (client == NULL)
- return;
-
- conn = sg->conn;
- if (conn == NULL)
- return;
-
- server = purple_account_get_string(sg->account, "server",
- "silc.silcnet.org");
- port = purple_account_get_int(sg->account, "port", 706),
-
- memset(&service, 0, sizeof(service));
- silc_client_attribute_del(client, conn,
- SILC_ATTRIBUTE_SERVICE, NULL);
- service.port = port;
- g_snprintf(service.address, sizeof(service.address), "%s", server);
- service.idle = idle;
- silc_client_attribute_add(client, conn, SILC_ATTRIBUTE_SERVICE,
- &service, sizeof(service));
-}
-
-char *silcpurple_status_text(PurpleBuddy *b)
-{
- SilcPurple sg = b->account->gc->proto_data;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- SilcClientID *client_id = b->proto_data;
- SilcClientEntry client_entry;
- SilcAttributePayload attr;
- SilcAttributeMood mood = 0;
-
- /* Get the client entry. */
- client_entry = silc_client_get_client_by_id(client, conn, client_id);
- if (!client_entry)
- return NULL;
-
- /* If user is online, we show the mood status, if available.
- If user is offline or away that status is indicated. */
-
- if (client_entry->mode & SILC_UMODE_DETACHED)
- return g_strdup(_("Detached"));
- if (client_entry->mode & SILC_UMODE_GONE)
- return g_strdup(_("Away"));
- if (client_entry->mode & SILC_UMODE_INDISPOSED)
- return g_strdup(_("Indisposed"));
- if (client_entry->mode & SILC_UMODE_BUSY)
- return g_strdup(_("Busy"));
- if (client_entry->mode & SILC_UMODE_PAGE)
- return g_strdup(_("Wake Me Up"));
- if (client_entry->mode & SILC_UMODE_HYPER)
- return g_strdup(_("Hyper Active"));
- if (client_entry->mode & SILC_UMODE_ROBOT)
- return g_strdup(_("Robot"));
-
- attr = silcpurple_get_attr(client_entry->attrs, SILC_ATTRIBUTE_STATUS_MOOD);
- if (attr && silc_attribute_get_object(attr, &mood, sizeof(mood))) {
- /* The mood is a bit mask, so we could show multiple moods,
- but let's show only one for now. */
- if (mood & SILC_ATTRIBUTE_MOOD_HAPPY)
- return g_strdup(_("Happy"));
- if (mood & SILC_ATTRIBUTE_MOOD_SAD)
- return g_strdup(_("Sad"));
- if (mood & SILC_ATTRIBUTE_MOOD_ANGRY)
- return g_strdup(_("Angry"));
- if (mood & SILC_ATTRIBUTE_MOOD_JEALOUS)
- return g_strdup(_("Jealous"));
- if (mood & SILC_ATTRIBUTE_MOOD_ASHAMED)
- return g_strdup(_("Ashamed"));
- if (mood & SILC_ATTRIBUTE_MOOD_INVINCIBLE)
- return g_strdup(_("Invincible"));
- if (mood & SILC_ATTRIBUTE_MOOD_INLOVE)
- return g_strdup(_("In Love"));
- if (mood & SILC_ATTRIBUTE_MOOD_SLEEPY)
- return g_strdup(_("Sleepy"));
- if (mood & SILC_ATTRIBUTE_MOOD_BORED)
- return g_strdup(_("Bored"));
- if (mood & SILC_ATTRIBUTE_MOOD_EXCITED)
- return g_strdup(_("Excited"));
- if (mood & SILC_ATTRIBUTE_MOOD_ANXIOUS)
- return g_strdup(_("Anxious"));
- }
-
- return NULL;
-}
-
-void silcpurple_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full)
-{
- SilcPurple sg = b->account->gc->proto_data;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- SilcClientID *client_id = b->proto_data;
- SilcClientEntry client_entry;
- char *moodstr, *statusstr, *contactstr, *langstr, *devicestr, *tzstr, *geostr;
- char tmp[256];
-
- /* Get the client entry. */
- client_entry = silc_client_get_client_by_id(client, conn, client_id);
- if (!client_entry)
- return;
-
- if (client_entry->nickname)
- purple_notify_user_info_add_pair(user_info, _("Nickname"),
- client_entry->nickname);
- if (client_entry->username && client_entry->hostname) {
- g_snprintf(tmp, sizeof(tmp), "%s@%s", client_entry->username, client_entry->hostname);
- purple_notify_user_info_add_pair(user_info, _("Username"), tmp);
- }
- if (client_entry->mode) {
- memset(tmp, 0, sizeof(tmp));
- silcpurple_get_umode_string(client_entry->mode,
- tmp, sizeof(tmp) - strlen(tmp));
- purple_notify_user_info_add_pair(user_info, _("User Modes"), tmp);
- }
-
- silcpurple_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr);
-
- if (statusstr) {
- purple_notify_user_info_add_pair(user_info, _("Message"), statusstr);
- g_free(statusstr);
- }
-
- if (full) {
- if (moodstr) {
- purple_notify_user_info_add_pair(user_info, _("Mood"), moodstr);
- g_free(moodstr);
- }
-
- if (contactstr) {
- purple_notify_user_info_add_pair(user_info, _("Preferred Contact"), contactstr);
- g_free(contactstr);
- }
-
- if (langstr) {
- purple_notify_user_info_add_pair(user_info, _("Preferred Language"), langstr);
- g_free(langstr);
- }
-
- if (devicestr) {
- purple_notify_user_info_add_pair(user_info, _("Device"), devicestr);
- g_free(devicestr);
- }
-
- if (tzstr) {
- purple_notify_user_info_add_pair(user_info, _("Timezone"), tzstr);
- g_free(tzstr);
- }
-
- if (geostr) {
- purple_notify_user_info_add_pair(user_info, _("Geolocation"), geostr);
- g_free(geostr);
- }
- }
-}
-
-static void
-silcpurple_buddy_kill(PurpleBlistNode *node, gpointer data)
-{
- PurpleBuddy *b;
- PurpleConnection *gc;
- SilcPurple sg;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
-
- b = (PurpleBuddy *) node;
- gc = purple_account_get_connection(b->account);
- sg = gc->proto_data;
-
- /* Call KILL */
- silc_client_command_call(sg->client, sg->conn, NULL, "KILL",
- b->name, "Killed by operator", NULL);
-}
-
-typedef struct {
- SilcPurple sg;
- SilcClientEntry client_entry;
-} *SilcPurpleBuddyWb;
-
-static void
-silcpurple_buddy_wb(PurpleBlistNode *node, gpointer data)
-{
- SilcPurpleBuddyWb wb = data;
- silcpurple_wb_init(wb->sg, wb->client_entry);
- silc_free(wb);
-}
-
-GList *silcpurple_buddy_menu(PurpleBuddy *buddy)
-{
- PurpleConnection *gc = purple_account_get_connection(buddy->account);
- SilcPurple sg = gc->proto_data;
- SilcClientConnection conn = sg->conn;
- const char *pkfile = NULL;
- SilcClientEntry client_entry = NULL;
- PurpleMenuAction *act;
- GList *m = NULL;
- SilcPurpleBuddyWb wb;
-
- pkfile = purple_blist_node_get_string((PurpleBlistNode *) buddy, "public-key");
- client_entry = silc_client_get_client_by_id(sg->client,
- sg->conn,
- buddy->proto_data);
-
- if (client_entry && client_entry->send_key) {
- act = purple_menu_action_new(_("Reset IM Key"),
- PURPLE_CALLBACK(silcpurple_buddy_resetkey),
- NULL, NULL);
- m = g_list_append(m, act);
-
- } else {
- act = purple_menu_action_new(_("IM with Key Exchange"),
- PURPLE_CALLBACK(silcpurple_buddy_keyagr),
- NULL, NULL);
- m = g_list_append(m, act);
-
- act = purple_menu_action_new(_("IM with Password"),
- PURPLE_CALLBACK(silcpurple_buddy_privkey_menu),
- NULL, NULL);
- m = g_list_append(m, act);
- }
-
- if (pkfile) {
- act = purple_menu_action_new(_("Show Public Key"),
- PURPLE_CALLBACK(silcpurple_buddy_showkey),
- NULL, NULL);
- m = g_list_append(m, act);
-
- } else {
- act = purple_menu_action_new(_("Get Public Key..."),
- PURPLE_CALLBACK(silcpurple_buddy_getkey_menu),
- NULL, NULL);
- m = g_list_append(m, act);
- }
-
- if (conn && conn->local_entry->mode & SILC_UMODE_ROUTER_OPERATOR) {
- act = purple_menu_action_new(_("Kill User"),
- PURPLE_CALLBACK(silcpurple_buddy_kill),
- NULL, NULL);
- m = g_list_append(m, act);
- }
-
- if (client_entry) {
- wb = silc_calloc(1, sizeof(*wb));
- wb->sg = sg;
- wb->client_entry = client_entry;
- act = purple_menu_action_new(_("Draw On Whiteboard"),
- PURPLE_CALLBACK(silcpurple_buddy_wb),
- (void *)wb, NULL);
- m = g_list_append(m, act);
- }
- return m;
-}
-
-#ifdef SILC_ATTRIBUTE_USER_ICON
-void silcpurple_buddy_set_icon(PurpleConnection *gc, PurpleStoredImage *img)
-{
- SilcPurple sg = gc->proto_data;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- SilcMime mime;
- char type[32];
- unsigned char *icon;
- const char *t;
- SilcAttributeObjMime obj;
-
- /* Remove */
- if (!img) {
- silc_client_attribute_del(client, conn,
- SILC_ATTRIBUTE_USER_ICON, NULL);
- return;
- }
-
- /* Add */
- mime = silc_mime_alloc();
- if (!mime)
- return;
-
- t = purple_imgstore_get_extension(img);
- if (!t || !strcmp(t, "icon")) {
- silc_mime_free(mime);
- return;
- }
- if (!strcmp(t, "jpg"))
- t = "jpeg";
- g_snprintf(type, sizeof(type), "image/%s", t);
- silc_mime_add_field(mime, "Content-Type", type);
- silc_mime_add_data(mime, purple_imgstore_get_data(img), purple_imgstore_get_size(img));
-
- obj.mime = icon = silc_mime_encode(mime, &obj.mime_len);
- if (obj.mime)
- silc_client_attribute_add(client, conn,
- SILC_ATTRIBUTE_USER_ICON, &obj, sizeof(obj));
-
- silc_free(icon);
- silc_mime_free(mime);
-}
-#endif
diff --git a/libpurple/protocols/silc10/chat.c b/libpurple/protocols/silc10/chat.c
deleted file mode 100644
index cc6f509604..0000000000
--- a/libpurple/protocols/silc10/chat.c
+++ /dev/null
@@ -1,1456 +0,0 @@
-/*
-
- silcpurple_chat.c
-
- Author: Pekka Riikonen <priikone@silcnet.org>
-
- Copyright (C) 2004 Pekka Riikonen
-
- 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; version 2 of the License.
-
- 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.
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-#include "silcpurple.h"
-#include "wb.h"
-
-/***************************** Channel Routines ******************************/
-
-GList *silcpurple_chat_info(PurpleConnection *gc)
-{
- GList *ci = NULL;
- struct proto_chat_entry *pce;
-
- pce = g_new0(struct proto_chat_entry, 1);
- pce->label = _("_Channel:");
- pce->identifier = "channel";
- pce->required = TRUE;
- ci = g_list_append(ci, pce);
-
- pce = g_new0(struct proto_chat_entry, 1);
- pce->label = _("_Passphrase:");
- pce->identifier = "passphrase";
- pce->secret = TRUE;
- ci = g_list_append(ci, pce);
-
- return ci;
-}
-
-GHashTable *silcpurple_chat_info_defaults(PurpleConnection *gc, const char *chat_name)
-{
- GHashTable *defaults;
-
- defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
-
- if (chat_name != NULL)
- g_hash_table_insert(defaults, "channel", g_strdup(chat_name));
-
- return defaults;
-}
-
-static void
-silcpurple_chat_getinfo(PurpleConnection *gc, GHashTable *components);
-
-static void
-silcpurple_chat_getinfo_res(SilcClient client,
- SilcClientConnection conn,
- SilcChannelEntry *channels,
- SilcUInt32 channels_count,
- void *context)
-{
- GHashTable *components = context;
- PurpleConnection *gc = client->application;
- const char *chname;
- char tmp[256];
-
- chname = g_hash_table_lookup(components, "channel");
- if (!chname)
- return;
-
- if (!channels) {
- g_snprintf(tmp, sizeof(tmp),
- _("Channel %s does not exist in the network"), chname);
- purple_notify_error(gc, _("Channel Information"),
- _("Cannot get channel information"), tmp);
- return;
- }
-
- silcpurple_chat_getinfo(gc, components);
-}
-
-
-static void
-silcpurple_chat_getinfo(PurpleConnection *gc, GHashTable *components)
-{
- SilcPurple sg = gc->proto_data;
- const char *chname;
- char *buf, tmp[256], *tmp2;
- GString *s;
- SilcChannelEntry channel;
- SilcHashTableList htl;
- SilcChannelUser chu;
-
- if (!components)
- return;
-
- chname = g_hash_table_lookup(components, "channel");
- if (!chname)
- return;
- channel = silc_client_get_channel(sg->client, sg->conn,
- (char *)chname);
- if (!channel) {
- silc_client_get_channel_resolve(sg->client, sg->conn,
- (char *)chname,
- silcpurple_chat_getinfo_res,
- components);
- return;
- }
-
- s = g_string_new("");
- tmp2 = g_markup_escape_text(channel->channel_name, -1);
- g_string_append_printf(s, _("<b>Channel Name:</b> %s"), tmp2);
- g_free(tmp2);
- if (channel->user_list && silc_hash_table_count(channel->user_list))
- g_string_append_printf(s, _("<br><b>User Count:</b> %d"),
- (int)silc_hash_table_count(channel->user_list));
-
- silc_hash_table_list(channel->user_list, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
- if (chu->mode & SILC_CHANNEL_UMODE_CHANFO) {
- tmp2 = g_markup_escape_text(chu->client->nickname, -1);
- g_string_append_printf(s, _("<br><b>Channel Founder:</b> %s"),
- tmp2);
- g_free(tmp2);
- break;
- }
- }
- silc_hash_table_list_reset(&htl);
-
- if (channel->channel_key)
- g_string_append_printf(s, _("<br><b>Channel Cipher:</b> %s"),
- silc_cipher_get_name(channel->channel_key));
- if (channel->hmac)
- /* Definition of HMAC: http://en.wikipedia.org/wiki/HMAC */
- g_string_append_printf(s, _("<br><b>Channel HMAC:</b> %s"),
- silc_hmac_get_name(channel->hmac));
-
- if (channel->topic) {
- tmp2 = g_markup_escape_text(channel->topic, -1);
- g_string_append_printf(s, _("<br><b>Channel Topic:</b><br>%s"), tmp2);
- g_free(tmp2);
- }
-
- if (channel->mode) {
- g_string_append_printf(s, _("<br><b>Channel Modes:</b> "));
- silcpurple_get_chmode_string(channel->mode, tmp, sizeof(tmp));
- g_string_append(s, tmp);
- }
-
- if (channel->founder_key) {
- char *fingerprint, *babbleprint;
- unsigned char *pk;
- SilcUInt32 pk_len;
- pk = silc_pkcs_public_key_encode(channel->founder_key, &pk_len);
- fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
-
- g_string_append_printf(s, _("<br><b>Founder Key Fingerprint:</b><br>%s"), fingerprint);
- g_string_append_printf(s, _("<br><b>Founder Key Babbleprint:</b><br>%s"), babbleprint);
-
- silc_free(fingerprint);
- silc_free(babbleprint);
- silc_free(pk);
- }
-
- buf = g_string_free(s, FALSE);
- purple_notify_formatted(gc, NULL, _("Channel Information"), NULL, buf, NULL, NULL);
- g_free(buf);
-}
-
-
-static void
-silcpurple_chat_getinfo_menu(PurpleBlistNode *node, gpointer data)
-{
- PurpleChat *chat = (PurpleChat *)node;
- silcpurple_chat_getinfo(chat->account->gc, chat->components);
-}
-
-
-#if 0 /* XXX For now these are not implemented. We need better
- listview dialog from Purple for these. */
-/************************** Channel Invite List ******************************/
-
-static void
-silcpurple_chat_invitelist(PurpleBlistNode *node, gpointer data);
-{
-
-}
-
-
-/**************************** Channel Ban List *******************************/
-
-static void
-silcpurple_chat_banlist(PurpleBlistNode *node, gpointer data);
-{
-
-}
-#endif
-
-
-/************************* Channel Authentication ****************************/
-
-typedef struct {
- SilcPurple sg;
- SilcChannelEntry channel;
- PurpleChat *c;
- SilcBuffer pubkeys;
-} *SilcPurpleChauth;
-
-static void
-silcpurple_chat_chpk_add(void *user_data, const char *name)
-{
- SilcPurpleChauth sgc = (SilcPurpleChauth)user_data;
- SilcPurple sg = sgc->sg;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- SilcPublicKey public_key;
- SilcBuffer chpks, pk, chidp;
- unsigned char mode[4];
- SilcUInt32 m;
-
- /* Load the public key */
- if (!silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_PEM) &&
- !silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_BIN)) {
- silcpurple_chat_chauth_show(sgc->sg, sgc->channel, sgc->pubkeys);
- silc_buffer_free(sgc->pubkeys);
- silc_free(sgc);
- purple_notify_error(client->application,
- _("Add Channel Public Key"),
- _("Could not load public key"), NULL);
- return;
- }
-
- pk = silc_pkcs_public_key_payload_encode(public_key);
- chpks = silc_buffer_alloc_size(2);
- SILC_PUT16_MSB(1, chpks->head);
- chpks = silc_argument_payload_encode_one(chpks, pk->data,
- pk->len, 0x00);
- silc_buffer_free(pk);
-
- m = sgc->channel->mode;
- m |= SILC_CHANNEL_MODE_CHANNEL_AUTH;
-
- /* Send CMODE */
- SILC_PUT32_MSB(m, mode);
- chidp = silc_id_payload_encode(sgc->channel->id, SILC_ID_CHANNEL);
- silc_client_command_send(client, conn, SILC_COMMAND_CMODE,
- ++conn->cmd_ident, 3,
- 1, chidp->data, chidp->len,
- 2, mode, sizeof(mode),
- 9, chpks->data, chpks->len);
- silc_buffer_free(chpks);
- silc_buffer_free(chidp);
- silc_buffer_free(sgc->pubkeys);
- silc_free(sgc);
-}
-
-static void
-silcpurple_chat_chpk_cancel(void *user_data, const char *name)
-{
- SilcPurpleChauth sgc = (SilcPurpleChauth)user_data;
- silcpurple_chat_chauth_show(sgc->sg, sgc->channel, sgc->pubkeys);
- silc_buffer_free(sgc->pubkeys);
- silc_free(sgc);
-}
-
-static void
-silcpurple_chat_chpk_cb(SilcPurpleChauth sgc, PurpleRequestFields *fields)
-{
- SilcPurple sg = sgc->sg;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- PurpleRequestField *f;
- GList *list;
- SilcPublicKey public_key;
- SilcBuffer chpks, pk, chidp;
- SilcUInt16 c = 0, ct;
- unsigned char mode[4];
- SilcUInt32 m;
-
- f = purple_request_fields_get_field(fields, "list");
- if (!purple_request_field_list_get_selected(f)) {
- /* Add new public key */
- purple_request_file(sg->gc, _("Open Public Key..."), NULL, FALSE,
- G_CALLBACK(silcpurple_chat_chpk_add),
- G_CALLBACK(silcpurple_chat_chpk_cancel),
- purple_connection_get_account(sg->gc), NULL, NULL, sgc);
- return;
- }
-
- list = purple_request_field_list_get_items(f);
- chpks = silc_buffer_alloc_size(2);
-
- for (ct = 0; list; list = list->next, ct++) {
- public_key = purple_request_field_list_get_data(f, list->data);
- if (purple_request_field_list_is_selected(f, list->data)) {
- /* Delete this public key */
- pk = silc_pkcs_public_key_payload_encode(public_key);
- chpks = silc_argument_payload_encode_one(chpks, pk->data,
- pk->len, 0x01);
- silc_buffer_free(pk);
- c++;
- }
- silc_pkcs_public_key_free(public_key);
- }
- if (!c) {
- silc_buffer_free(chpks);
- return;
- }
- SILC_PUT16_MSB(c, chpks->head);
-
- m = sgc->channel->mode;
- if (ct == c)
- m &= ~SILC_CHANNEL_MODE_CHANNEL_AUTH;
-
- /* Send CMODE */
- SILC_PUT32_MSB(m, mode);
- chidp = silc_id_payload_encode(sgc->channel->id, SILC_ID_CHANNEL);
- silc_client_command_send(client, conn, SILC_COMMAND_CMODE,
- ++conn->cmd_ident, 3,
- 1, chidp->data, chidp->len,
- 2, mode, sizeof(mode),
- 9, chpks->data, chpks->len);
- silc_buffer_free(chpks);
- silc_buffer_free(chidp);
- silc_buffer_free(sgc->pubkeys);
- silc_free(sgc);
-}
-
-static void
-silcpurple_chat_chauth_ok(SilcPurpleChauth sgc, PurpleRequestFields *fields)
-{
- SilcPurple sg = sgc->sg;
- PurpleRequestField *f;
- const char *curpass, *val;
- int set;
-
- f = purple_request_fields_get_field(fields, "passphrase");
- val = purple_request_field_string_get_value(f);
- curpass = purple_blist_node_get_string((PurpleBlistNode *)sgc->c, "passphrase");
-
- if (!val && curpass)
- set = 0;
- else if (val && !curpass)
- set = 1;
- else if (val && curpass && strcmp(val, curpass))
- set = 1;
- else
- set = -1;
-
- if (set == 1) {
- silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
- sgc->channel->channel_name, "+a", val, NULL);
- purple_blist_node_set_string((PurpleBlistNode *)sgc->c, "passphrase", val);
- } else if (set == 0) {
- silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
- sgc->channel->channel_name, "-a", NULL);
- purple_blist_node_remove_setting((PurpleBlistNode *)sgc->c, "passphrase");
- }
-
- silc_buffer_free(sgc->pubkeys);
- silc_free(sgc);
-}
-
-void silcpurple_chat_chauth_show(SilcPurple sg, SilcChannelEntry channel,
- SilcBuffer channel_pubkeys)
-{
- SilcUInt16 argc;
- SilcArgumentPayload chpks;
- unsigned char *pk;
- SilcUInt32 pk_len, type;
- char *fingerprint, *babbleprint;
- SilcPublicKey pubkey;
- SilcPublicKeyIdentifier ident;
- char tmp2[1024], t[512];
- PurpleRequestFields *fields;
- PurpleRequestFieldGroup *g;
- PurpleRequestField *f;
- SilcPurpleChauth sgc;
- const char *curpass = NULL;
-
- sgc = silc_calloc(1, sizeof(*sgc));
- if (!sgc)
- return;
- sgc->sg = sg;
- sgc->channel = channel;
-
- fields = purple_request_fields_new();
-
- if (sgc->c)
- curpass = purple_blist_node_get_string((PurpleBlistNode *)sgc->c, "passphrase");
-
- g = purple_request_field_group_new(NULL);
- f = purple_request_field_string_new("passphrase", _("Channel Passphrase"),
- curpass, FALSE);
- purple_request_field_string_set_masked(f, TRUE);
- purple_request_field_group_add_field(g, f);
- purple_request_fields_add_group(fields, g);
-
- g = purple_request_field_group_new(NULL);
- f = purple_request_field_label_new("l1", _("Channel Public Keys List"));
- purple_request_field_group_add_field(g, f);
- purple_request_fields_add_group(fields, g);
-
- g_snprintf(t, sizeof(t),
- _("Channel authentication is used to secure the channel from "
- "unauthorized access. The authentication may be based on "
- "passphrase and digital signatures. If passphrase is set, it "
- "is required to be able to join. If channel public keys are set "
- "then only users whose public keys are listed are able to join."));
-
- if (!channel_pubkeys) {
- f = purple_request_field_list_new("list", NULL);
- purple_request_field_group_add_field(g, f);
- purple_request_fields(sg->gc, _("Channel Authentication"),
- _("Channel Authentication"), t, fields,
- _("Add / Remove"), G_CALLBACK(silcpurple_chat_chpk_cb),
- _("OK"), G_CALLBACK(silcpurple_chat_chauth_ok),
- purple_connection_get_account(sg->gc), NULL, NULL, sgc);
- return;
- }
- sgc->pubkeys = silc_buffer_copy(channel_pubkeys);
-
- g = purple_request_field_group_new(NULL);
- f = purple_request_field_list_new("list", NULL);
- purple_request_field_group_add_field(g, f);
- purple_request_fields_add_group(fields, g);
-
- SILC_GET16_MSB(argc, channel_pubkeys->data);
- chpks = silc_argument_payload_parse(channel_pubkeys->data + 2,
- channel_pubkeys->len - 2, argc);
- if (!chpks)
- return;
-
- pk = silc_argument_get_first_arg(chpks, &type, &pk_len);
- while (pk) {
- fingerprint = silc_hash_fingerprint(NULL, pk + 4, pk_len - 4);
- babbleprint = silc_hash_babbleprint(NULL, pk + 4, pk_len - 4);
- silc_pkcs_public_key_payload_decode(pk, pk_len, &pubkey);
- ident = silc_pkcs_decode_identifier(pubkey->identifier);
-
- g_snprintf(tmp2, sizeof(tmp2), "%s\n %s\n %s",
- ident->realname ? ident->realname : ident->username ?
- ident->username : "", fingerprint, babbleprint);
- purple_request_field_list_add_icon(f, tmp2, NULL, pubkey);
-
- silc_free(fingerprint);
- silc_free(babbleprint);
- silc_pkcs_free_identifier(ident);
- pk = silc_argument_get_next_arg(chpks, &type, &pk_len);
- }
-
- purple_request_field_list_set_multi_select(f, FALSE);
- purple_request_fields(sg->gc, _("Channel Authentication"),
- _("Channel Authentication"), t, fields,
- _("Add / Remove"), G_CALLBACK(silcpurple_chat_chpk_cb),
- _("OK"), G_CALLBACK(silcpurple_chat_chauth_ok),
- purple_connection_get_account(sg->gc), NULL, NULL, sgc);
-
- silc_argument_payload_free(chpks);
-}
-
-static void
-silcpurple_chat_chauth(PurpleBlistNode *node, gpointer data)
-{
- PurpleChat *chat;
- PurpleConnection *gc;
- SilcPurple sg;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
- chat = (PurpleChat *) node;
- gc = purple_account_get_connection(chat->account);
- sg = gc->proto_data;
-
- silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
- g_hash_table_lookup(chat->components, "channel"),
- "+C", NULL);
-}
-
-
-/************************** Channel Private Groups **************************/
-
-/* Private groups are "virtual" channels. They are groups inside a channel.
- This is implemented by using channel private keys. By knowing a channel
- private key user becomes part of that group and is able to talk on that
- group. Other users, on the same channel, won't be able to see the
- messages of that group. It is possible to have multiple groups inside
- a channel - and thus having multiple private keys on the channel. */
-
-typedef struct {
- SilcPurple sg;
- PurpleChat *c;
- const char *channel;
-} *SilcPurpleCharPrv;
-
-static void
-silcpurple_chat_prv_add(SilcPurpleCharPrv p, PurpleRequestFields *fields)
-{
- SilcPurple sg = p->sg;
- char tmp[512];
- PurpleRequestField *f;
- const char *name, *passphrase, *alias;
- GHashTable *comp;
- PurpleGroup *g;
- PurpleChat *cn;
-
- f = purple_request_fields_get_field(fields, "name");
- name = purple_request_field_string_get_value(f);
- if (!name) {
- silc_free(p);
- return;
- }
- f = purple_request_fields_get_field(fields, "passphrase");
- passphrase = purple_request_field_string_get_value(f);
- f = purple_request_fields_get_field(fields, "alias");
- alias = purple_request_field_string_get_value(f);
-
- /* Add private group to buddy list */
- g_snprintf(tmp, sizeof(tmp), "%s [Private Group]", name);
- comp = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
- g_hash_table_replace(comp, g_strdup("channel"), g_strdup(tmp));
- g_hash_table_replace(comp, g_strdup("passphrase"), g_strdup(passphrase));
-
- cn = purple_chat_new(sg->account, alias, comp);
- g = (PurpleGroup *)p->c->node.parent;
- purple_blist_add_chat(cn, g, (PurpleBlistNode *)p->c);
-
- /* Associate to a real channel */
- purple_blist_node_set_string((PurpleBlistNode *)cn, "parentch", p->channel);
-
- /* Join the group */
- silcpurple_chat_join(sg->gc, comp);
-
- silc_free(p);
-}
-
-static void
-silcpurple_chat_prv_cancel(SilcPurpleCharPrv p, PurpleRequestFields *fields)
-{
- silc_free(p);
-}
-
-static void
-silcpurple_chat_prv(PurpleBlistNode *node, gpointer data)
-{
- PurpleChat *chat;
- PurpleConnection *gc;
- SilcPurple sg;
-
- SilcPurpleCharPrv p;
- PurpleRequestFields *fields;
- PurpleRequestFieldGroup *g;
- PurpleRequestField *f;
- char tmp[512];
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
- chat = (PurpleChat *) node;
- gc = purple_account_get_connection(chat->account);
- sg = gc->proto_data;
-
- p = silc_calloc(1, sizeof(*p));
- if (!p)
- return;
- p->sg = sg;
-
- p->channel = g_hash_table_lookup(chat->components, "channel");
- p->c = purple_blist_find_chat(sg->account, p->channel);
-
- fields = purple_request_fields_new();
-
- g = purple_request_field_group_new(NULL);
- f = purple_request_field_string_new("name", _("Group Name"),
- NULL, FALSE);
- purple_request_field_group_add_field(g, f);
-
- f = purple_request_field_string_new("passphrase", _("Passphrase"),
- NULL, FALSE);
- purple_request_field_string_set_masked(f, TRUE);
- purple_request_field_group_add_field(g, f);
-
- f = purple_request_field_string_new("alias", _("Alias"),
- NULL, FALSE);
- purple_request_field_group_add_field(g, f);
- purple_request_fields_add_group(fields, g);
-
- g_snprintf(tmp, sizeof(tmp),
- _("Please enter the %s channel private group name and passphrase."),
- p->channel);
- purple_request_fields(gc, _("Add Channel Private Group"), NULL, tmp, fields,
- _("Add"), G_CALLBACK(silcpurple_chat_prv_add),
- _("Cancel"), G_CALLBACK(silcpurple_chat_prv_cancel),
- purple_connection_get_account(gc), NULL, NULL, p);
-}
-
-
-/****************************** Channel Modes ********************************/
-
-static void
-silcpurple_chat_permanent_reset(PurpleBlistNode *node, gpointer data)
-{
- PurpleChat *chat;
- PurpleConnection *gc;
- SilcPurple sg;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
- chat = (PurpleChat *) node;
- gc = purple_account_get_connection(chat->account);
- sg = gc->proto_data;
-
- silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
- g_hash_table_lookup(chat->components, "channel"),
- "-f", NULL);
-}
-
-static void
-silcpurple_chat_permanent(PurpleBlistNode *node, gpointer data)
-{
- PurpleChat *chat;
- PurpleConnection *gc;
- SilcPurple sg;
- const char *channel;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
- chat = (PurpleChat *) node;
- gc = purple_account_get_connection(chat->account);
- sg = gc->proto_data;
-
- if (!sg->conn)
- return;
-
- /* XXX we should have ability to define which founder
- key to use. Now we use the user's own public key
- (default key). */
-
- /* Call CMODE */
- channel = g_hash_table_lookup(chat->components, "channel");
- silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", channel,
- "+f", NULL);
-}
-
-typedef struct {
- SilcPurple sg;
- char *channel;
-} *SilcPurpleChatInput;
-
-static void
-silcpurple_chat_ulimit_cb(SilcPurpleChatInput s, const char *limit)
-{
- SilcChannelEntry channel;
- int ulimit = 0;
-
- channel = silc_client_get_channel(s->sg->client, s->sg->conn,
- (char *)s->channel);
- if (!channel)
- return;
- if (limit)
- ulimit = atoi(limit);
-
- if (!limit || !(*limit) || *limit == '0') {
- if (limit && ulimit == channel->user_limit) {
- silc_free(s);
- return;
- }
- silc_client_command_call(s->sg->client, s->sg->conn, NULL, "CMODE",
- s->channel, "-l", NULL);
-
- silc_free(s);
- return;
- }
-
- if (ulimit == channel->user_limit) {
- silc_free(s);
- return;
- }
-
- /* Call CMODE */
- silc_client_command_call(s->sg->client, s->sg->conn, NULL, "CMODE",
- s->channel, "+l", limit, NULL);
-
- silc_free(s);
-}
-
-static void
-silcpurple_chat_ulimit(PurpleBlistNode *node, gpointer data)
-{
- PurpleChat *chat;
- PurpleConnection *gc;
- SilcPurple sg;
-
- SilcPurpleChatInput s;
- SilcChannelEntry channel;
- char *ch;
- char tmp[32];
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
- chat = (PurpleChat *) node;
- gc = purple_account_get_connection(chat->account);
- sg = gc->proto_data;
-
- if (!sg->conn)
- return;
-
- ch = g_strdup(g_hash_table_lookup(chat->components, "channel"));
- channel = silc_client_get_channel(sg->client, sg->conn, (char *)ch);
- if (!channel)
- return;
-
- s = silc_calloc(1, sizeof(*s));
- if (!s)
- return;
- s->channel = ch;
- s->sg = sg;
- g_snprintf(tmp, sizeof(tmp), "%d", (int)channel->user_limit);
- purple_request_input(gc, _("User Limit"), NULL,
- _("Set user limit on channel. Set to zero to reset user limit."),
- tmp, FALSE, FALSE, NULL,
- _("OK"), G_CALLBACK(silcpurple_chat_ulimit_cb),
- _("Cancel"), G_CALLBACK(silcpurple_chat_ulimit_cb),
- purple_connection_get_account(gc), NULL, NULL, s);
-}
-
-static void
-silcpurple_chat_resettopic(PurpleBlistNode *node, gpointer data)
-{
- PurpleChat *chat;
- PurpleConnection *gc;
- SilcPurple sg;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
- chat = (PurpleChat *) node;
- gc = purple_account_get_connection(chat->account);
- sg = gc->proto_data;
-
- silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
- g_hash_table_lookup(chat->components, "channel"),
- "-t", NULL);
-}
-
-static void
-silcpurple_chat_settopic(PurpleBlistNode *node, gpointer data)
-{
- PurpleChat *chat;
- PurpleConnection *gc;
- SilcPurple sg;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
- chat = (PurpleChat *) node;
- gc = purple_account_get_connection(chat->account);
- sg = gc->proto_data;
-
- silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
- g_hash_table_lookup(chat->components, "channel"),
- "+t", NULL);
-}
-
-static void
-silcpurple_chat_resetprivate(PurpleBlistNode *node, gpointer data)
-{
- PurpleChat *chat;
- PurpleConnection *gc;
- SilcPurple sg;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
- chat = (PurpleChat *) node;
- gc = purple_account_get_connection(chat->account);
- sg = gc->proto_data;
-
- silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
- g_hash_table_lookup(chat->components, "channel"),
- "-p", NULL);
-}
-
-static void
-silcpurple_chat_setprivate(PurpleBlistNode *node, gpointer data)
-{
- PurpleChat *chat;
- PurpleConnection *gc;
- SilcPurple sg;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
- chat = (PurpleChat *) node;
- gc = purple_account_get_connection(chat->account);
- sg = gc->proto_data;
-
- silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
- g_hash_table_lookup(chat->components, "channel"),
- "+p", NULL);
-}
-
-static void
-silcpurple_chat_resetsecret(PurpleBlistNode *node, gpointer data)
-{
- PurpleChat *chat;
- PurpleConnection *gc;
- SilcPurple sg;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
- chat = (PurpleChat *) node;
- gc = purple_account_get_connection(chat->account);
- sg = gc->proto_data;
-
- silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
- g_hash_table_lookup(chat->components, "channel"),
- "-s", NULL);
-}
-
-static void
-silcpurple_chat_setsecret(PurpleBlistNode *node, gpointer data)
-{
- PurpleChat *chat;
- PurpleConnection *gc;
- SilcPurple sg;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
-
- chat = (PurpleChat *) node;
- gc = purple_account_get_connection(chat->account);
- sg = gc->proto_data;
-
- silc_client_command_call(sg->client, sg->conn, NULL, "CMODE",
- g_hash_table_lookup(chat->components, "channel"),
- "+s", NULL);
-}
-
-typedef struct {
- SilcPurple sg;
- SilcChannelEntry channel;
-} *SilcPurpleChatWb;
-
-static void
-silcpurple_chat_wb(PurpleBlistNode *node, gpointer data)
-{
- SilcPurpleChatWb wb = data;
- silcpurple_wb_init_ch(wb->sg, wb->channel);
- silc_free(wb);
-}
-
-GList *silcpurple_chat_menu(PurpleChat *chat)
-{
- GHashTable *components = chat->components;
- PurpleConnection *gc = purple_account_get_connection(chat->account);
- SilcPurple sg = gc->proto_data;
- SilcClientConnection conn = sg->conn;
- const char *chname = NULL;
- SilcChannelEntry channel = NULL;
- SilcChannelUser chu = NULL;
- SilcUInt32 mode = 0;
-
- GList *m = NULL;
- PurpleMenuAction *act;
-
- if (components)
- chname = g_hash_table_lookup(components, "channel");
- if (chname)
- channel = silc_client_get_channel(sg->client, sg->conn,
- (char *)chname);
- if (channel) {
- chu = silc_client_on_channel(channel, conn->local_entry);
- if (chu)
- mode = chu->mode;
- }
-
- if (strstr(chname, "[Private Group]"))
- return NULL;
-
- act = purple_menu_action_new(_("Get Info"),
- PURPLE_CALLBACK(silcpurple_chat_getinfo_menu),
- NULL, NULL);
- m = g_list_append(m, act);
-
-#if 0 /* XXX For now these are not implemented. We need better
- listview dialog from Purple for these. */
- if (mode & SILC_CHANNEL_UMODE_CHANOP) {
- act = purple_menu_action_new(_("Invite List"),
- PURPLE_CALLBACK(silcpurple_chat_invitelist),
- NULL, NULL);
- m = g_list_append(m, act);
-
- act = purple_menu_action_new(_("Ban List"),
- PURPLE_CALLBACK(silcpurple_chat_banlist),
- NULL, NULL);
- m = g_list_append(m, act);
- }
-#endif
-
- if (chu) {
- act = purple_menu_action_new(_("Add Private Group"),
- PURPLE_CALLBACK(silcpurple_chat_prv),
- NULL, NULL);
- m = g_list_append(m, act);
- }
-
- if (mode & SILC_CHANNEL_UMODE_CHANFO) {
- act = purple_menu_action_new(_("Channel Authentication"),
- PURPLE_CALLBACK(silcpurple_chat_chauth),
- NULL, NULL);
- m = g_list_append(m, act);
-
- if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
- act = purple_menu_action_new(_("Reset Permanent"),
- PURPLE_CALLBACK(silcpurple_chat_permanent_reset),
- NULL, NULL);
- m = g_list_append(m, act);
- } else {
- act = purple_menu_action_new(_("Set Permanent"),
- PURPLE_CALLBACK(silcpurple_chat_permanent),
- NULL, NULL);
- m = g_list_append(m, act);
- }
- }
-
- if (mode & SILC_CHANNEL_UMODE_CHANOP) {
- act = purple_menu_action_new(_("Set User Limit"),
- PURPLE_CALLBACK(silcpurple_chat_ulimit),
- NULL, NULL);
- m = g_list_append(m, act);
-
- if (channel->mode & SILC_CHANNEL_MODE_TOPIC) {
- act = purple_menu_action_new(_("Reset Topic Restriction"),
- PURPLE_CALLBACK(silcpurple_chat_resettopic),
- NULL, NULL);
- m = g_list_append(m, act);
- } else {
- act = purple_menu_action_new(_("Set Topic Restriction"),
- PURPLE_CALLBACK(silcpurple_chat_settopic),
- NULL, NULL);
- m = g_list_append(m, act);
- }
-
- if (channel->mode & SILC_CHANNEL_MODE_PRIVATE) {
- act = purple_menu_action_new(_("Reset Private Channel"),
- PURPLE_CALLBACK(silcpurple_chat_resetprivate),
- NULL, NULL);
- m = g_list_append(m, act);
- } else {
- act = purple_menu_action_new(_("Set Private Channel"),
- PURPLE_CALLBACK(silcpurple_chat_setprivate),
- NULL, NULL);
- m = g_list_append(m, act);
- }
-
- if (channel->mode & SILC_CHANNEL_MODE_SECRET) {
- act = purple_menu_action_new(_("Reset Secret Channel"),
- PURPLE_CALLBACK(silcpurple_chat_resetsecret),
- NULL, NULL);
- m = g_list_append(m, act);
- } else {
- act = purple_menu_action_new(_("Set Secret Channel"),
- PURPLE_CALLBACK(silcpurple_chat_setsecret),
- NULL, NULL);
- m = g_list_append(m, act);
- }
- }
-
- if (channel) {
- SilcPurpleChatWb wb;
- wb = silc_calloc(1, sizeof(*wb));
- wb->sg = sg;
- wb->channel = channel;
- act = purple_menu_action_new(_("Draw On Whiteboard"),
- PURPLE_CALLBACK(silcpurple_chat_wb),
- (void *)wb, NULL);
- m = g_list_append(m, act);
- }
-
- return m;
-}
-
-
-/******************************* Joining Etc. ********************************/
-
-void silcpurple_chat_join_done(SilcClient client,
- SilcClientConnection conn,
- SilcClientEntry *clients,
- SilcUInt32 clients_count,
- void *context)
-{
- PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
- SilcChannelEntry channel = context;
- PurpleConversation *convo;
- SilcUInt32 retry = SILC_PTR_TO_32(channel->context);
- SilcHashTableList htl;
- SilcChannelUser chu;
- GList *users = NULL, *flags = NULL;
- char tmp[256];
-
- if (!clients && retry < 1) {
- /* Resolving users failed, try again. */
- channel->context = SILC_32_TO_PTR(retry + 1);
- silc_client_get_clients_by_channel(client, conn, channel,
- silcpurple_chat_join_done, channel);
- return;
- }
-
- /* Add channel to Purple */
- channel->context = SILC_32_TO_PTR(++sg->channel_ids);
- serv_got_joined_chat(gc, sg->channel_ids, channel->channel_name);
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- channel->channel_name, sg->account);
- if (!convo)
- return;
-
- /* Add all users to channel */
- silc_hash_table_list(channel->user_list, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
- PurpleConvChatBuddyFlags f = PURPLE_CBFLAGS_NONE;
- if (!chu->client->nickname)
- continue;
- chu->context = SILC_32_TO_PTR(sg->channel_ids);
-
- if (chu->mode & SILC_CHANNEL_UMODE_CHANFO)
- f |= PURPLE_CBFLAGS_FOUNDER;
- if (chu->mode & SILC_CHANNEL_UMODE_CHANOP)
- f |= PURPLE_CBFLAGS_OP;
- users = g_list_append(users, g_strdup(chu->client->nickname));
- flags = g_list_append(flags, GINT_TO_POINTER(f));
-
- if (chu->mode & SILC_CHANNEL_UMODE_CHANFO) {
- if (chu->client == conn->local_entry)
- g_snprintf(tmp, sizeof(tmp),
- _("You are channel founder on <I>%s</I>"),
- channel->channel_name);
- else
- g_snprintf(tmp, sizeof(tmp),
- _("Channel founder on <I>%s</I> is <I>%s</I>"),
- channel->channel_name, chu->client->nickname);
-
- purple_conversation_write(convo, NULL, tmp,
- PURPLE_MESSAGE_SYSTEM, time(NULL));
-
- }
- }
- silc_hash_table_list_reset(&htl);
-
- purple_conv_chat_add_users(PURPLE_CONV_CHAT(convo), users, NULL, flags, FALSE);
- g_list_free(users);
- g_list_free(flags);
-
- /* Set topic */
- if (channel->topic)
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), NULL, channel->topic);
-
- /* Set nick */
- purple_conv_chat_set_nick(PURPLE_CONV_CHAT(convo), conn->local_entry->nickname);
-}
-
-char *silcpurple_get_chat_name(GHashTable *data)
-{
- return g_strdup(g_hash_table_lookup(data, "channel"));
-}
-
-void silcpurple_chat_join(PurpleConnection *gc, GHashTable *data)
-{
- SilcPurple sg = gc->proto_data;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- const char *channel, *passphrase, *parentch;
-
- if (!conn)
- return;
-
- channel = g_hash_table_lookup(data, "channel");
- passphrase = g_hash_table_lookup(data, "passphrase");
-
- /* Check if we are joining a private group. Handle it
- purely locally as it's not a real channel */
- if (strstr(channel, "[Private Group]")) {
- SilcChannelEntry channel_entry;
- SilcChannelPrivateKey key;
- PurpleChat *c;
- SilcPurplePrvgrp grp;
-
- c = purple_blist_find_chat(sg->account, channel);
- parentch = purple_blist_node_get_string((PurpleBlistNode *)c, "parentch");
- if (!parentch)
- return;
-
- channel_entry = silc_client_get_channel(sg->client, sg->conn,
- (char *)parentch);
- if (!channel_entry ||
- !silc_client_on_channel(channel_entry, sg->conn->local_entry)) {
- char tmp[512];
- g_snprintf(tmp, sizeof(tmp),
- _("You have to join the %s channel before you are "
- "able to join the private group"), parentch);
- purple_notify_error(gc, _("Join Private Group"),
- _("Cannot join private group"), tmp);
- return;
- }
-
- /* Add channel private key */
- if (!silc_client_add_channel_private_key(client, conn,
- channel_entry, channel,
- NULL, NULL,
- (unsigned char *)passphrase,
- strlen(passphrase), &key))
- return;
-
- /* Join the group */
- grp = silc_calloc(1, sizeof(*grp));
- if (!grp)
- return;
- grp->id = ++sg->channel_ids + SILCPURPLE_PRVGRP;
- grp->chid = SILC_PTR_TO_32(channel_entry->context);
- grp->parentch = parentch;
- grp->channel = channel;
- grp->key = key;
- sg->grps = g_list_append(sg->grps, grp);
- serv_got_joined_chat(gc, grp->id, channel);
- return;
- }
-
- /* XXX We should have other properties here as well:
- 1. whether to try to authenticate to the channel
- 1a. with default key,
- 1b. with specific key.
- 2. whether to try to authenticate to become founder.
- 2a. with default key,
- 2b. with specific key.
-
- Since now such variety is not possible in the join dialog
- we always use -founder and -auth options, which try to
- do both 1 and 2 with default keys. */
-
- /* Call JOIN */
- if ((passphrase != NULL) && (*passphrase != '\0'))
- silc_client_command_call(client, conn, NULL, "JOIN",
- channel, passphrase, "-auth", "-founder", NULL);
- else
- silc_client_command_call(client, conn, NULL, "JOIN",
- channel, "-auth", "-founder", NULL);
-}
-
-void silcpurple_chat_invite(PurpleConnection *gc, int id, const char *msg,
- const char *name)
-{
- SilcPurple sg = gc->proto_data;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- SilcHashTableList htl;
- SilcChannelUser chu;
- gboolean found = FALSE;
-
- if (!conn)
- return;
-
- /* See if we are inviting on a private group. Invite
- to the actual channel */
- if (id > SILCPURPLE_PRVGRP) {
- GList *l;
- SilcPurplePrvgrp prv;
-
- for (l = sg->grps; l; l = l->next)
- if (((SilcPurplePrvgrp)l->data)->id == id)
- break;
- if (!l)
- return;
- prv = l->data;
- id = prv->chid;
- }
-
- /* Find channel by id */
- silc_hash_table_list(conn->local_entry->channels, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
- if (SILC_PTR_TO_32(chu->channel->context) == id ) {
- found = TRUE;
- break;
- }
- }
- silc_hash_table_list_reset(&htl);
- if (!found)
- return;
-
- /* Call INVITE */
- silc_client_command_call(client, conn, NULL, "INVITE",
- chu->channel->channel_name,
- name, NULL);
-}
-
-void silcpurple_chat_leave(PurpleConnection *gc, int id)
-{
- SilcPurple sg = gc->proto_data;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- SilcHashTableList htl;
- SilcChannelUser chu;
- gboolean found = FALSE;
- GList *l;
- SilcPurplePrvgrp prv;
-
- if (!conn)
- return;
-
- /* See if we are leaving a private group */
- if (id > SILCPURPLE_PRVGRP) {
- SilcChannelEntry channel;
-
- for (l = sg->grps; l; l = l->next)
- if (((SilcPurplePrvgrp)l->data)->id == id)
- break;
- if (!l)
- return;
- prv = l->data;
- channel = silc_client_get_channel(sg->client, sg->conn,
- (char *)prv->parentch);
- if (!channel)
- return;
- silc_client_del_channel_private_key(client, conn,
- channel, prv->key);
- silc_free(prv);
- sg->grps = g_list_remove(sg->grps, prv);
- serv_got_chat_left(gc, id);
- return;
- }
-
- /* Find channel by id */
- silc_hash_table_list(conn->local_entry->channels, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
- if (SILC_PTR_TO_32(chu->channel->context) == id ) {
- found = TRUE;
- break;
- }
- }
- silc_hash_table_list_reset(&htl);
- if (!found)
- return;
-
- /* Call LEAVE */
- silc_client_command_call(client, conn, NULL, "LEAVE",
- chu->channel->channel_name, NULL);
-
- serv_got_chat_left(gc, id);
-
- /* Leave from private groups on this channel as well */
- for (l = sg->grps; l; l = l->next)
- if (((SilcPurplePrvgrp)l->data)->chid == id) {
- prv = l->data;
- silc_client_del_channel_private_key(client, conn,
- chu->channel,
- prv->key);
- serv_got_chat_left(gc, prv->id);
- silc_free(prv);
- sg->grps = g_list_remove(sg->grps, prv);
- if (!sg->grps)
- break;
- }
-}
-
-int silcpurple_chat_send(PurpleConnection *gc, int id, const char *msg, PurpleMessageFlags msgflags)
-{
- SilcPurple sg = gc->proto_data;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- SilcHashTableList htl;
- SilcChannelUser chu;
- SilcChannelEntry channel = NULL;
- SilcChannelPrivateKey key = NULL;
- SilcUInt32 flags;
- int ret;
- char *msg2, *tmp;
- gboolean found = FALSE;
- gboolean sign = purple_account_get_bool(sg->account, "sign-verify", FALSE);
-
- if (!msg || !conn)
- return 0;
-
- flags = SILC_MESSAGE_FLAG_UTF8;
-
- tmp = msg2 = purple_unescape_html(msg);
-
- if (!g_ascii_strncasecmp(msg2, "/me ", 4))
- {
- msg2 += 4;
- if (!*msg2) {
- g_free(tmp);
- return 0;
- }
- flags |= SILC_MESSAGE_FLAG_ACTION;
- } else if (strlen(msg) > 1 && msg[0] == '/') {
- if (!silc_client_command_call(client, conn, msg + 1))
- purple_notify_error(gc, _("Call Command"), _("Cannot call command"),
- _("Unknown command"));
- g_free(tmp);
- return 0;
- }
-
-
- if (sign)
- flags |= SILC_MESSAGE_FLAG_SIGNED;
-
- /* Get the channel private key if we are sending on
- private group */
- if (id > SILCPURPLE_PRVGRP) {
- GList *l;
- SilcPurplePrvgrp prv;
-
- for (l = sg->grps; l; l = l->next)
- if (((SilcPurplePrvgrp)l->data)->id == id)
- break;
- if (!l) {
- g_free(tmp);
- return 0;
- }
- prv = l->data;
- channel = silc_client_get_channel(sg->client, sg->conn,
- (char *)prv->parentch);
- if (!channel) {
- g_free(tmp);
- return 0;
- }
- key = prv->key;
- }
-
- if (!channel) {
- /* Find channel by id */
- silc_hash_table_list(conn->local_entry->channels, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
- if (SILC_PTR_TO_32(chu->channel->context) == id ) {
- found = TRUE;
- break;
- }
- }
- silc_hash_table_list_reset(&htl);
- if (!found) {
- g_free(tmp);
- return 0;
- }
- channel = chu->channel;
- }
-
- /* Send channel message */
- ret = silc_client_send_channel_message(client, conn, channel, key,
- flags, (unsigned char *)msg2,
- strlen(msg2), TRUE);
- if (ret) {
- serv_got_chat_in(gc, id, purple_connection_get_display_name(gc), msgflags, msg,
- time(NULL));
- }
- g_free(tmp);
-
- return ret;
-}
-
-void silcpurple_chat_set_topic(PurpleConnection *gc, int id, const char *topic)
-{
- SilcPurple sg = gc->proto_data;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- SilcHashTableList htl;
- SilcChannelUser chu;
- gboolean found = FALSE;
-
- if (!conn)
- return;
-
- /* See if setting topic on private group. Set it
- on the actual channel */
- if (id > SILCPURPLE_PRVGRP) {
- GList *l;
- SilcPurplePrvgrp prv;
-
- for (l = sg->grps; l; l = l->next)
- if (((SilcPurplePrvgrp)l->data)->id == id)
- break;
- if (!l)
- return;
- prv = l->data;
- id = prv->chid;
- }
-
- /* Find channel by id */
- silc_hash_table_list(conn->local_entry->channels, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
- if (SILC_PTR_TO_32(chu->channel->context) == id ) {
- found = TRUE;
- break;
- }
- }
- silc_hash_table_list_reset(&htl);
- if (!found)
- return;
-
- /* Call TOPIC */
- silc_client_command_call(client, conn, NULL, "TOPIC",
- chu->channel->channel_name, topic, NULL);
-}
-
-PurpleRoomlist *silcpurple_roomlist_get_list(PurpleConnection *gc)
-{
- SilcPurple sg = gc->proto_data;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- GList *fields = NULL;
- PurpleRoomlistField *f;
-
- if (!conn)
- return NULL;
-
- if (sg->roomlist)
- purple_roomlist_unref(sg->roomlist);
-
- sg->roomlist_cancelled = FALSE;
-
- sg->roomlist = purple_roomlist_new(purple_connection_get_account(gc));
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", "channel", TRUE);
- fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_INT,
- _("Users"), "users", FALSE);
- fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING,
- _("Topic"), "topic", FALSE);
- fields = g_list_append(fields, f);
- purple_roomlist_set_fields(sg->roomlist, fields);
-
- /* Call LIST */
- silc_client_command_call(client, conn, "LIST");
-
- purple_roomlist_set_in_progress(sg->roomlist, TRUE);
-
- return sg->roomlist;
-}
-
-void silcpurple_roomlist_cancel(PurpleRoomlist *list)
-{
- PurpleConnection *gc = purple_account_get_connection(list->account);
- SilcPurple sg;
-
- if (!gc)
- return;
- sg = gc->proto_data;
-
- purple_roomlist_set_in_progress(list, FALSE);
- if (sg->roomlist == list) {
- purple_roomlist_unref(sg->roomlist);
- sg->roomlist = NULL;
- sg->roomlist_cancelled = TRUE;
- }
-}
diff --git a/libpurple/protocols/silc10/ft.c b/libpurple/protocols/silc10/ft.c
deleted file mode 100644
index 39e74495b7..0000000000
--- a/libpurple/protocols/silc10/ft.c
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
-
- silcpurple_ft.c
-
- Author: Pekka Riikonen <priikone@silcnet.org>
-
- Copyright (C) 2004 Pekka Riikonen
-
- 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; version 2 of the License.
-
- 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.
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-#include "silcpurple.h"
-
-/****************************** File Transfer ********************************/
-
-/* This implements the secure file transfer protocol (SFTP) using the SILC
- SFTP library implementation. The API we use from the SILC Toolkit is the
- SILC Client file transfer API, as it provides a simple file transfer we
- need in this case. We could use the SILC SFTP API directly, but it would
- be an overkill since we'd effectively re-implement the file transfer what
- the SILC Client's file transfer API already provides.
-
- From Purple we do NOT use the FT API to do the transfer as it is very limiting.
- In fact it does not suite to file transfers like SFTP at all. For example,
- it assumes that read operations are synchronous what they are not in SFTP.
- It also assumes that the file transfer socket is to be handled by the Purple
- eventloop, and this naturally is something we don't want to do in case of
- SILC Toolkit. The FT API suites well to purely stream based file transfers
- like HTTP GET and similar.
-
- For this reason, we directly access the Purple GKT FT API and hack the FT
- API to merely provide the user interface experience and all the magic
- is done in the SILC Toolkit. Ie. we update the statistics information in
- the FT API for user interface, and that's it. A bit dirty but until the
- FT API gets better this is the way to go. Good thing that FT API allowed
- us to do this. */
-
-typedef struct {
- SilcPurple sg;
- SilcClientEntry client_entry;
- SilcUInt32 session_id;
- char *hostname;
- SilcUInt16 port;
- PurpleXfer *xfer;
-
- SilcClientFileName completion;
- void *completion_context;
-} *SilcPurpleXfer;
-
-static void
-silcpurple_ftp_monitor(SilcClient client,
- SilcClientConnection conn,
- SilcClientMonitorStatus status,
- SilcClientFileError error,
- SilcUInt64 offset,
- SilcUInt64 filesize,
- SilcClientEntry client_entry,
- SilcUInt32 session_id,
- const char *filepath,
- void *context)
-{
- SilcPurpleXfer xfer = context;
- PurpleConnection *gc = xfer->sg->gc;
- char tmp[256];
-
- if (status == SILC_CLIENT_FILE_MONITOR_CLOSED) {
- purple_xfer_unref(xfer->xfer);
- silc_free(xfer);
- return;
- }
-
- if (status == SILC_CLIENT_FILE_MONITOR_KEY_AGREEMENT)
- return;
-
- if (status == SILC_CLIENT_FILE_MONITOR_ERROR) {
- if (error == SILC_CLIENT_FILE_NO_SUCH_FILE) {
- g_snprintf(tmp, sizeof(tmp), "No such file %s",
- filepath ? filepath : "[N/A]");
- purple_notify_error(gc, _("Secure File Transfer"),
- _("Error during file transfer"), tmp);
- } else if (error == SILC_CLIENT_FILE_PERMISSION_DENIED) {
- purple_notify_error(gc, _("Secure File Transfer"),
- _("Error during file transfer"),
- _("Permission denied"));
- } else if (error == SILC_CLIENT_FILE_KEY_AGREEMENT_FAILED) {
- purple_notify_error(gc, _("Secure File Transfer"),
- _("Error during file transfer"),
- _("Key agreement failed"));
- } else if (error == SILC_CLIENT_FILE_UNKNOWN_SESSION) {
- purple_notify_error(gc, _("Secure File Transfer"),
- _("Error during file transfer"),
- _("File transfer session does not exist"));
- } else {
- purple_notify_error(gc, _("Secure File Transfer"),
- _("Error during file transfer"), NULL);
- }
- silc_client_file_close(client, conn, session_id);
- purple_xfer_unref(xfer->xfer);
- silc_free(xfer);
- return;
- }
-
- /* Update file transfer UI */
- if (!offset && filesize)
- purple_xfer_set_size(xfer->xfer, filesize);
- if (offset && filesize) {
- xfer->xfer->bytes_sent = offset;
- xfer->xfer->bytes_remaining = filesize - offset;
- }
- purple_xfer_update_progress(xfer->xfer);
-
- if (status == SILC_CLIENT_FILE_MONITOR_SEND ||
- status == SILC_CLIENT_FILE_MONITOR_RECEIVE) {
- if (offset == filesize) {
- /* Download finished */
- purple_xfer_set_completed(xfer->xfer, TRUE);
- silc_client_file_close(client, conn, session_id);
- }
- }
-}
-
-static void
-silcpurple_ftp_cancel(PurpleXfer *x)
-{
- SilcPurpleXfer xfer = x->data;
- xfer->xfer->status = PURPLE_XFER_STATUS_CANCEL_LOCAL;
- purple_xfer_update_progress(xfer->xfer);
- silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id);
-}
-
-static void
-silcpurple_ftp_ask_name_cancel(PurpleXfer *x)
-{
- SilcPurpleXfer xfer = x->data;
-
- /* Cancel the transmission */
- xfer->completion(NULL, xfer->completion_context);
- silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id);
-}
-
-static void
-silcpurple_ftp_ask_name_ok(PurpleXfer *x)
-{
- SilcPurpleXfer xfer = x->data;
- const char *name;
-
- name = purple_xfer_get_local_filename(x);
- g_unlink(name);
- xfer->completion(name, xfer->completion_context);
-}
-
-static void
-silcpurple_ftp_ask_name(SilcClient client,
- SilcClientConnection conn,
- SilcUInt32 session_id,
- const char *remote_filename,
- SilcClientFileName completion,
- void *completion_context,
- void *context)
-{
- SilcPurpleXfer xfer = context;
-
- xfer->completion = completion;
- xfer->completion_context = completion_context;
-
- purple_xfer_set_init_fnc(xfer->xfer, silcpurple_ftp_ask_name_ok);
- purple_xfer_set_request_denied_fnc(xfer->xfer, silcpurple_ftp_ask_name_cancel);
-
- /* Request to save the file */
- purple_xfer_set_filename(xfer->xfer, remote_filename);
- purple_xfer_request(xfer->xfer);
-}
-
-static void
-silcpurple_ftp_request_result(PurpleXfer *x)
-{
- SilcPurpleXfer xfer = x->data;
- SilcClientFileError status;
- PurpleConnection *gc = xfer->sg->gc;
-
- if (purple_xfer_get_status(x) != PURPLE_XFER_STATUS_ACCEPTED)
- return;
-
- /* Start the file transfer */
- status = silc_client_file_receive(xfer->sg->client, xfer->sg->conn,
- silcpurple_ftp_monitor, xfer,
- NULL, xfer->session_id,
- silcpurple_ftp_ask_name, xfer);
- switch (status) {
- case SILC_CLIENT_FILE_OK:
- return;
- break;
-
- case SILC_CLIENT_FILE_UNKNOWN_SESSION:
- purple_notify_error(gc, _("Secure File Transfer"),
- _("No file transfer session active"), NULL);
- break;
-
- case SILC_CLIENT_FILE_ALREADY_STARTED:
- purple_notify_error(gc, _("Secure File Transfer"),
- _("File transfer already started"), NULL);
- break;
-
- case SILC_CLIENT_FILE_KEY_AGREEMENT_FAILED:
- purple_notify_error(gc, _("Secure File Transfer"),
- _("Could not perform key agreement for file transfer"),
- NULL);
- break;
-
- default:
- purple_notify_error(gc, _("Secure File Transfer"),
- _("Could not start the file transfer"), NULL);
- break;
- }
-
- /* Error */
- purple_xfer_unref(xfer->xfer);
- g_free(xfer->hostname);
- silc_free(xfer);
-}
-
-static void
-silcpurple_ftp_request_denied(PurpleXfer *x)
-{
-
-}
-
-void silcpurple_ftp_request(SilcClient client, SilcClientConnection conn,
- SilcClientEntry client_entry, SilcUInt32 session_id,
- const char *hostname, SilcUInt16 port)
-{
- PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
- SilcPurpleXfer xfer;
-
- xfer = silc_calloc(1, sizeof(*xfer));
- if (!xfer) {
- silc_client_file_close(sg->client, sg->conn, session_id);
- return;
- }
-
- xfer->sg = sg;
- xfer->client_entry = client_entry;
- xfer->session_id = session_id;
- xfer->hostname = g_strdup(hostname);
- xfer->port = port;
- xfer->xfer = purple_xfer_new(xfer->sg->account, PURPLE_XFER_RECEIVE,
- xfer->client_entry->nickname);
- if (!xfer->xfer) {
- silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id);
- g_free(xfer->hostname);
- silc_free(xfer);
- return;
- }
- purple_xfer_set_init_fnc(xfer->xfer, silcpurple_ftp_request_result);
- purple_xfer_set_request_denied_fnc(xfer->xfer, silcpurple_ftp_request_denied);
- purple_xfer_set_cancel_recv_fnc(xfer->xfer, silcpurple_ftp_cancel);
- xfer->xfer->remote_ip = g_strdup(hostname);
- xfer->xfer->remote_port = port;
- xfer->xfer->data = xfer;
-
- /* File transfer request */
- purple_xfer_request(xfer->xfer);
-}
-
-static void
-silcpurple_ftp_send_cancel(PurpleXfer *x)
-{
- SilcPurpleXfer xfer = x->data;
- silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id);
- purple_xfer_unref(xfer->xfer);
- g_free(xfer->hostname);
- silc_free(xfer);
-}
-
-static void
-silcpurple_ftp_send(PurpleXfer *x)
-{
- SilcPurpleXfer xfer = x->data;
- const char *name;
- char *local_ip = NULL, *remote_ip = NULL;
- gboolean local = TRUE;
-
- name = purple_xfer_get_local_filename(x);
-
- /* Do the same magic what we do with key agreement (see silcpurple_buddy.c)
- to see if we are behind NAT. */
- if (silc_net_check_local_by_sock(xfer->sg->conn->sock->sock,
- NULL, &local_ip)) {
- /* Check if the IP is private */
- if (silcpurple_ip_is_private(local_ip)) {
- local = FALSE;
- /* Local IP is private, resolve the remote server IP to see whether
- we are talking to Internet or just on LAN. */
- if (silc_net_check_host_by_sock(xfer->sg->conn->sock->sock, NULL,
- &remote_ip))
- if (silcpurple_ip_is_private(remote_ip))
- /* We assume we are in LAN. Let's provide the connection point. */
- local = TRUE;
- }
- }
-
- if (local && !local_ip)
- local_ip = silc_net_localip();
-
- /* Send the file */
- silc_client_file_send(xfer->sg->client, xfer->sg->conn,
- silcpurple_ftp_monitor, xfer,
- local_ip, 0, !local, xfer->client_entry,
- name, &xfer->session_id);
-
- silc_free(local_ip);
- silc_free(remote_ip);
-}
-
-static void
-silcpurple_ftp_send_file_resolved(SilcClient client,
- SilcClientConnection conn,
- SilcClientEntry *clients,
- SilcUInt32 clients_count,
- void *context)
-{
- PurpleConnection *gc = client->application;
- char tmp[256];
-
- if (!clients) {
- g_snprintf(tmp, sizeof(tmp),
- _("User %s is not present in the network"),
- (const char *)context);
- purple_notify_error(gc, _("Secure File Transfer"),
- _("Cannot send file"), tmp);
- silc_free(context);
- return;
- }
-
- silcpurple_ftp_send_file(client->application, (const char *)context, NULL);
- silc_free(context);
-}
-
-PurpleXfer *silcpurple_ftp_new_xfer(PurpleConnection *gc, const char *name)
-{
- SilcPurple sg = gc->proto_data;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- SilcClientEntry *clients;
- SilcUInt32 clients_count;
- SilcPurpleXfer xfer;
- char *nickname;
-
- g_return_val_if_fail(name != NULL, NULL);
-
- if (!silc_parse_userfqdn(name, &nickname, NULL))
- return NULL;
-
- /* Find client entry */
- clients = silc_client_get_clients_local(client, conn, nickname, name,
- &clients_count);
- if (!clients) {
- silc_client_get_clients(client, conn, nickname, NULL,
- silcpurple_ftp_send_file_resolved,
- strdup(name));
- silc_free(nickname);
- return NULL;
- }
-
- xfer = silc_calloc(1, sizeof(*xfer));
-
- g_return_val_if_fail(xfer != NULL, NULL);
-
- xfer->sg = sg;
- xfer->client_entry = clients[0];
- xfer->xfer = purple_xfer_new(xfer->sg->account, PURPLE_XFER_SEND,
- xfer->client_entry->nickname);
- if (!xfer->xfer) {
- silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id);
- g_free(xfer->hostname);
- silc_free(xfer);
- return NULL;
- }
- purple_xfer_set_init_fnc(xfer->xfer, silcpurple_ftp_send);
- purple_xfer_set_request_denied_fnc(xfer->xfer, silcpurple_ftp_request_denied);
- purple_xfer_set_cancel_send_fnc(xfer->xfer, silcpurple_ftp_send_cancel);
- xfer->xfer->data = xfer;
-
- silc_free(clients);
- silc_free(nickname);
-
- return xfer->xfer;
-}
-
-void silcpurple_ftp_send_file(PurpleConnection *gc, const char *name, const char *file)
-{
- PurpleXfer *xfer = silcpurple_ftp_new_xfer(gc, name);
-
- g_return_if_fail(xfer != NULL);
-
- /* Choose file to send */
- if (file)
- purple_xfer_request_accepted(xfer, file);
- else
- purple_xfer_request(xfer);
-}
diff --git a/libpurple/protocols/silc10/ops.c b/libpurple/protocols/silc10/ops.c
deleted file mode 100644
index 6095c49b18..0000000000
--- a/libpurple/protocols/silc10/ops.c
+++ /dev/null
@@ -1,2063 +0,0 @@
-/*
-
- silcpurple_ops.c
-
- Author: Pekka Riikonen <priikone@silcnet.org>
-
- Copyright (C) 2004 Pekka Riikonen
-
- 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; version 2 of the License.
-
- 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.
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-#include "silcpurple.h"
-#include "imgstore.h"
-#include "wb.h"
-
-static void
-silc_channel_message(SilcClient client, SilcClientConnection conn,
- SilcClientEntry sender, SilcChannelEntry channel,
- SilcMessagePayload payload, SilcChannelPrivateKey key,
- SilcMessageFlags flags, const unsigned char *message,
- SilcUInt32 message_len);
-static void
-silc_private_message(SilcClient client, SilcClientConnection conn,
- SilcClientEntry sender, SilcMessagePayload payload,
- SilcMessageFlags flags, const unsigned char *message,
- SilcUInt32 message_len);
-
-/* Message sent to the application by library. `conn' associates the
- message to a specific connection. `conn', however, may be NULL.
- The `type' indicates the type of the message sent by the library.
- The application can for example filter the message according the
- type. */
-
-static void
-silc_say(SilcClient client, SilcClientConnection conn,
- SilcClientMessageType type, char *msg, ...)
-{
- /* Nothing */
-}
-
-#ifdef HAVE_SILCMIME_H
-/* Processes incoming MIME message. Can be private message or channel
- message. */
-
-static void
-silcpurple_mime_message(SilcClient client, SilcClientConnection conn,
- SilcClientEntry sender, SilcChannelEntry channel,
- SilcMessagePayload payload, SilcChannelPrivateKey key,
- SilcMessageFlags flags, SilcMime mime,
- gboolean recursive)
-{
- PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
- const char *type;
- const unsigned char *data;
- SilcUInt32 data_len;
- PurpleMessageFlags cflags = 0;
- PurpleConversation *convo = NULL;
-
- if (!mime)
- return;
-
- /* Check for fragmented MIME message */
- if (silc_mime_is_partial(mime)) {
- if (!sg->mimeass)
- sg->mimeass = silc_mime_assembler_alloc();
-
- /* Defragment */
- mime = silc_mime_assemble(sg->mimeass, mime);
- if (!mime)
- /* More fragments to come */
- return;
-
- /* Process the complete message */
- silcpurple_mime_message(client, conn, sender, channel,
- payload, key, flags, mime, FALSE);
- return;
- }
-
- /* Check for multipart message */
- if (silc_mime_is_multipart(mime)) {
- SilcMime p;
- const char *mtype;
- SilcDList parts = silc_mime_get_multiparts(mime, &mtype);
-
- /* Only "mixed" type supported */
- if (strcmp(mtype, "mixed"))
- goto out;
-
- silc_dlist_start(parts);
- while ((p = silc_dlist_get(parts)) != SILC_LIST_END) {
- /* Recursively process parts */
- silcpurple_mime_message(client, conn, sender, channel,
- payload, key, flags, p, TRUE);
- }
- goto out;
- }
-
- /* Get content type and MIME data */
- type = silc_mime_get_field(mime, "Content-Type");
- if (!type)
- goto out;
- data = silc_mime_get_data(mime, &data_len);
- if (!data)
- goto out;
-
- /* Process according to content type */
-
- /* Plain text */
- if (strstr(type, "text/plain")) {
- /* Default is UTF-8, don't check for other charsets */
- if (!strstr(type, "utf-8"))
- goto out;
-
- if (channel)
- silc_channel_message(client, conn, sender, channel,
- payload, key,
- SILC_MESSAGE_FLAG_UTF8, data,
- data_len);
- else
- silc_private_message(client, conn, sender, payload,
- SILC_MESSAGE_FLAG_UTF8, data,
- data_len);
- goto out;
- }
-
- /* Image */
- if (strstr(type, "image/png") ||
- strstr(type, "image/jpeg") ||
- strstr(type, "image/gif") ||
- strstr(type, "image/tiff")) {
- char tmp[32];
- int imgid;
-
- /* Get channel convo (if message is for channel) */
- if (key && channel) {
- GList *l;
- SilcPurplePrvgrp prv;
-
- for (l = sg->grps; l; l = l->next)
- if (((SilcPurplePrvgrp)l->data)->key == key) {
- prv = l->data;
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- prv->channel, sg->account);
- break;
- }
- }
- if (channel && !convo)
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- channel->channel_name, sg->account);
- if (channel && !convo)
- goto out;
-
- imgid = purple_imgstore_add_with_id(g_memdup(data, data_len), data_len, "");
- if (imgid) {
- cflags |= PURPLE_MESSAGE_IMAGES | PURPLE_MESSAGE_RECV;
- g_snprintf(tmp, sizeof(tmp), "<IMG ID=\"%d\">", imgid);
-
- if (channel)
- serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)),
- sender->nickname ?
- sender->nickname :
- "<unknown>", cflags,
- tmp, time(NULL));
- else
- serv_got_im(gc, sender->nickname ?
- sender->nickname : "<unknown>",
- tmp, cflags, time(NULL));
-
- purple_imgstore_unref_by_id(imgid);
- cflags = 0;
- }
- goto out;
- }
-
- /* Whiteboard message */
- if (strstr(type, "application/x-wb") &&
- !purple_account_get_bool(sg->account, "block-wb", FALSE)) {
- if (channel)
- silcpurple_wb_receive_ch(client, conn, sender, channel,
- payload, flags, data, data_len);
- else
- silcpurple_wb_receive(client, conn, sender, payload,
- flags, data, data_len);
- goto out;
- }
-
- out:
- if (!recursive)
- silc_mime_free(mime);
-}
-#endif /* HAVE_SILCMIME_H */
-
-/* Message for a channel. The `sender' is the sender of the message
- The `channel' is the channel. The `message' is the message. Note
- that `message' maybe NULL. The `flags' indicates message flags
- and it is used to determine how the message can be interpreted
- (like it may tell the message is multimedia message). */
-
-static void
-silc_channel_message(SilcClient client, SilcClientConnection conn,
- SilcClientEntry sender, SilcChannelEntry channel,
- SilcMessagePayload payload, SilcChannelPrivateKey key,
- SilcMessageFlags flags, const unsigned char *message,
- SilcUInt32 message_len)
-{
- PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
- PurpleConversation *convo = NULL;
- char *msg, *tmp;
-
- if (!message)
- return;
-
- if (key) {
- GList *l;
- SilcPurplePrvgrp prv;
-
- for (l = sg->grps; l; l = l->next)
- if (((SilcPurplePrvgrp)l->data)->key == key) {
- prv = l->data;
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- prv->channel, sg->account);
- break;
- }
- }
- if (!convo)
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- channel->channel_name, sg->account);
- if (!convo)
- return;
-
- if (flags & SILC_MESSAGE_FLAG_SIGNED &&
- purple_account_get_bool(sg->account, "sign-verify", FALSE)) {
- /* XXX */
- }
-
- if (flags & SILC_MESSAGE_FLAG_DATA) {
- /* Process MIME message */
-#ifdef HAVE_SILCMIME_H
- SilcMime mime;
- mime = silc_mime_decode(message, message_len);
- silcpurple_mime_message(client, conn, sender, channel, payload,
- key, flags, mime, FALSE);
-#else
- char type[128], enc[128];
- unsigned char *data;
- SilcUInt32 data_len;
-
- memset(type, 0, sizeof(type));
- memset(enc, 0, sizeof(enc));
-
- if (!silc_mime_parse(message, message_len, NULL, 0,
- type, sizeof(type) - 1, enc, sizeof(enc) - 1, &data,
- &data_len))
- return;
-
- if (!strcmp(type, "application/x-wb") &&
- !strcmp(enc, "binary") &&
- !purple_account_get_bool(sg->account, "block-wb", FALSE))
- silcpurple_wb_receive_ch(client, conn, sender, channel,
- payload, flags, data, data_len);
-#endif
- return;
- }
-
- if (flags & SILC_MESSAGE_FLAG_ACTION) {
- msg = g_strdup_printf("/me %s",
- (const char *)message);
- if (!msg)
- return;
-
- tmp = g_markup_escape_text(msg, -1);
- /* Send to Purple */
- serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)),
- sender->nickname ?
- sender->nickname : "<unknown>", 0,
- tmp, time(NULL));
- g_free(tmp);
- g_free(msg);
- return;
- }
-
- if (flags & SILC_MESSAGE_FLAG_NOTICE) {
- msg = g_strdup_printf("(notice) <I>%s</I> %s",
- sender->nickname ?
- sender->nickname : "<unknown>",
- (const char *)message);
- if (!msg)
- return;
-
- /* Send to Purple */
- purple_conversation_write(convo, NULL, (const char *)msg,
- PURPLE_MESSAGE_SYSTEM, time(NULL));
- g_free(msg);
- return;
- }
-
- if (flags & SILC_MESSAGE_FLAG_UTF8) {
- tmp = g_markup_escape_text((const char *)message, -1);
- /* Send to Purple */
- serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)),
- sender->nickname ?
- sender->nickname : "<unknown>", 0,
- tmp, time(NULL));
- g_free(tmp);
- }
-}
-
-
-/* Private message to the client. The `sender' is the sender of the
- message. The message is `message'and maybe NULL. The `flags'
- indicates message flags and it is used to determine how the message
- can be interpreted (like it may tell the message is multimedia
- message). */
-
-static void
-silc_private_message(SilcClient client, SilcClientConnection conn,
- SilcClientEntry sender, SilcMessagePayload payload,
- SilcMessageFlags flags, const unsigned char *message,
- SilcUInt32 message_len)
-{
- PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
- PurpleConversation *convo = NULL;
- char *msg, *tmp;
-
- if (!message)
- return;
-
- if (sender->nickname)
- /* XXX - Should this be PURPLE_CONV_TYPE_IM? */
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY,
- sender->nickname, sg->account);
-
- if (flags & SILC_MESSAGE_FLAG_SIGNED &&
- purple_account_get_bool(sg->account, "sign-verify", FALSE)) {
- /* XXX */
- }
-
- if (flags & SILC_MESSAGE_FLAG_DATA) {
-#ifdef HAVE_SILCMIME_H
- /* Process MIME message */
- SilcMime mime;
- mime = silc_mime_decode(message, message_len);
- silcpurple_mime_message(client, conn, sender, NULL, payload,
- NULL, flags, mime, FALSE);
-#else
- char type[128], enc[128];
- unsigned char *data;
- SilcUInt32 data_len;
-
- memset(type, 0, sizeof(type));
- memset(enc, 0, sizeof(enc));
-
- if (!silc_mime_parse(message, message_len, NULL, 0,
- type, sizeof(type) - 1, enc, sizeof(enc) - 1, &data,
- &data_len))
- return;
-
- if (!strcmp(type, "application/x-wb") &&
- !strcmp(enc, "binary") &&
- !purple_account_get_bool(sg->account, "block-wb", FALSE))
- silcpurple_wb_receive(client, conn, sender, payload,
- flags, data, data_len);
-#endif
- return;
- }
-
- if (flags & SILC_MESSAGE_FLAG_ACTION && convo) {
- msg = g_strdup_printf("/me %s",
- (const char *)message);
- if (!msg)
- return;
-
- tmp = g_markup_escape_text(msg, -1);
- /* Send to Purple */
- serv_got_im(gc, sender->nickname ?
- sender->nickname : "<unknown>",
- tmp, 0, time(NULL));
- g_free(msg);
- g_free(tmp);
- return;
- }
-
- if (flags & SILC_MESSAGE_FLAG_NOTICE && convo) {
- msg = g_strdup_printf("(notice) <I>%s</I> %s",
- sender->nickname ?
- sender->nickname : "<unknown>",
- (const char *)message);
- if (!msg)
- return;
-
- /* Send to Purple */
- purple_conversation_write(convo, NULL, (const char *)msg,
- PURPLE_MESSAGE_SYSTEM, time(NULL));
- g_free(msg);
- return;
- }
-
- if (flags & SILC_MESSAGE_FLAG_UTF8) {
- tmp = g_markup_escape_text((const char *)message, -1);
- /* Send to Purple */
- serv_got_im(gc, sender->nickname ?
- sender->nickname : "<unknown>",
- tmp, 0, time(NULL));
- g_free(tmp);
- }
-}
-
-
-/* Notify message to the client. The notify arguments are sent in the
- same order as servers sends them. The arguments are same as received
- from the server except for ID's. If ID is received application receives
- the corresponding entry to the ID. For example, if Client ID is received
- application receives SilcClientEntry. Also, if the notify type is
- for channel the channel entry is sent to application (even if server
- does not send it because client library gets the channel entry from
- the Channel ID in the packet's header). */
-
-static void
-silc_notify(SilcClient client, SilcClientConnection conn,
- SilcNotifyType type, ...)
-{
- va_list va;
- PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
- PurpleConversation *convo;
- SilcClientEntry client_entry, client_entry2;
- SilcChannelEntry channel;
- SilcServerEntry server_entry;
- SilcIdType idtype;
- void *entry;
- SilcUInt32 mode;
- SilcHashTableList htl;
- SilcChannelUser chu;
- char buf[512], buf2[512], *tmp, *name;
- SilcNotifyType notify;
- PurpleBuddy *b;
- int i;
-
- va_start(va, type);
- memset(buf, 0, sizeof(buf));
-
- switch (type) {
-
- case SILC_NOTIFY_TYPE_NONE:
- break;
-
- case SILC_NOTIFY_TYPE_INVITE:
- {
- GHashTable *components;
- va_arg(va, SilcChannelEntry);
- name = va_arg(va, char *);
- client_entry = va_arg(va, SilcClientEntry);
-
- components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
- g_hash_table_insert(components, strdup("channel"), strdup(name));
- serv_got_chat_invite(gc, name, client_entry->nickname, NULL, components);
- }
- break;
-
- case SILC_NOTIFY_TYPE_JOIN:
- client_entry = va_arg(va, SilcClientEntry);
- channel = va_arg(va, SilcChannelEntry);
-
- /* If we joined channel, do nothing */
- if (client_entry == conn->local_entry)
- break;
-
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- channel->channel_name, sg->account);
- if (!convo)
- break;
-
- /* Join user to channel */
- g_snprintf(buf, sizeof(buf), "%s@%s",
- client_entry->username, client_entry->hostname);
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(convo),
- g_strdup(client_entry->nickname), buf, PURPLE_CBFLAGS_NONE, TRUE);
-
- break;
-
- case SILC_NOTIFY_TYPE_LEAVE:
- client_entry = va_arg(va, SilcClientEntry);
- channel = va_arg(va, SilcChannelEntry);
-
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- channel->channel_name, sg->account);
- if (!convo)
- break;
-
- /* Remove user from channel */
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo),
- client_entry->nickname, NULL);
-
- break;
-
- case SILC_NOTIFY_TYPE_SIGNOFF:
- client_entry = va_arg(va, SilcClientEntry);
- tmp = va_arg(va, char *);
-
- if (!client_entry->nickname)
- break;
-
- /* Remove from all channels */
- silc_hash_table_list(client_entry->channels, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- chu->channel->channel_name, sg->account);
- if (!convo)
- continue;
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo),
- client_entry->nickname,
- tmp);
- }
- silc_hash_table_list_reset(&htl);
-
- break;
-
- case SILC_NOTIFY_TYPE_TOPIC_SET:
- {
- char *esc, *tmp2;
- idtype = va_arg(va, int);
- entry = va_arg(va, void *);
- tmp = va_arg(va, char *);
- channel = va_arg(va, SilcChannelEntry);
-
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- channel->channel_name, sg->account);
- if (!convo)
- break;
-
- if (!tmp)
- break;
-
- esc = g_markup_escape_text(tmp, -1);
- tmp2 = purple_markup_linkify(esc);
- g_free(esc);
-
- if (idtype == SILC_ID_CLIENT) {
- client_entry = (SilcClientEntry)entry;
- g_snprintf(buf, sizeof(buf),
- _("%s has changed the topic of <I>%s</I> to: %s"),
- client_entry->nickname, channel->channel_name, tmp2);
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), client_entry->nickname,
- buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo),
- client_entry->nickname, tmp);
- } else if (idtype == SILC_ID_SERVER) {
- server_entry = (SilcServerEntry)entry;
- g_snprintf(buf, sizeof(buf),
- _("%s has changed the topic of <I>%s</I> to: %s"),
- server_entry->server_name, channel->channel_name, tmp2);
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), server_entry->server_name,
- buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo),
- server_entry->server_name, tmp);
- } else if (idtype == SILC_ID_CHANNEL) {
- channel = (SilcChannelEntry)entry;
- g_snprintf(buf, sizeof(buf),
- _("%s has changed the topic of <I>%s</I> to: %s"),
- channel->channel_name, channel->channel_name, tmp2);
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), channel->channel_name,
- buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo),
- channel->channel_name, tmp);
- } else {
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), NULL, tmp);
- }
-
- g_free(tmp2);
-
- break;
-
- }
- case SILC_NOTIFY_TYPE_NICK_CHANGE:
- client_entry = va_arg(va, SilcClientEntry);
- client_entry2 = va_arg(va, SilcClientEntry);
-
- if (!strcmp(client_entry->nickname, client_entry2->nickname))
- break;
-
- /* Change nick on all channels */
- silc_hash_table_list(client_entry2->channels, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- chu->channel->channel_name, sg->account);
- if (!convo)
- continue;
- if (purple_conv_chat_find_user(PURPLE_CONV_CHAT(convo), client_entry->nickname))
- purple_conv_chat_rename_user(PURPLE_CONV_CHAT(convo),
- client_entry->nickname,
- client_entry2->nickname);
- }
- silc_hash_table_list_reset(&htl);
-
- break;
-
- case SILC_NOTIFY_TYPE_CMODE_CHANGE:
- idtype = va_arg(va, int);
- entry = va_arg(va, void *);
- mode = va_arg(va, SilcUInt32);
- (void)va_arg(va, char *);
- (void)va_arg(va, char *);
- (void)va_arg(va, char *);
- (void)va_arg(va, SilcPublicKey);
- (void)va_arg(va, SilcBuffer);
- channel = va_arg(va, SilcChannelEntry);
-
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- channel->channel_name, sg->account);
- if (!convo)
- break;
-
- if (idtype == SILC_ID_CLIENT)
- name = ((SilcClientEntry)entry)->nickname;
- else if (idtype == SILC_ID_SERVER)
- name = ((SilcServerEntry)entry)->server_name;
- else
- name = ((SilcChannelEntry)entry)->channel_name;
- if (!name)
- break;
-
- if (mode) {
- silcpurple_get_chmode_string(mode, buf2, sizeof(buf2));
- g_snprintf(buf, sizeof(buf),
- _("<I>%s</I> set channel <I>%s</I> modes to: %s"), name,
- channel->channel_name, buf2);
- } else {
- g_snprintf(buf, sizeof(buf),
- _("<I>%s</I> removed all channel <I>%s</I> modes"), name,
- channel->channel_name);
- }
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), channel->channel_name,
- buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
- break;
-
- case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
- {
- PurpleConvChatBuddyFlags flags = PURPLE_CBFLAGS_NONE;
- idtype = va_arg(va, int);
- entry = va_arg(va, void *);
- mode = va_arg(va, SilcUInt32);
- client_entry2 = va_arg(va, SilcClientEntry);
- channel = va_arg(va, SilcChannelEntry);
-
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- channel->channel_name, sg->account);
- if (!convo)
- break;
-
- if (idtype == SILC_ID_CLIENT)
- name = ((SilcClientEntry)entry)->nickname;
- else if (idtype == SILC_ID_SERVER)
- name = ((SilcServerEntry)entry)->server_name;
- else
- name = ((SilcChannelEntry)entry)->channel_name;
- if (!name)
- break;
-
- if (mode) {
- silcpurple_get_chumode_string(mode, buf2, sizeof(buf2));
- g_snprintf(buf, sizeof(buf),
- _("<I>%s</I> set <I>%s's</I> modes to: %s"), name,
- client_entry2->nickname, buf2);
- if (mode & SILC_CHANNEL_UMODE_CHANFO)
- flags |= PURPLE_CBFLAGS_FOUNDER;
- if (mode & SILC_CHANNEL_UMODE_CHANOP)
- flags |= PURPLE_CBFLAGS_OP;
- } else {
- g_snprintf(buf, sizeof(buf),
- _("<I>%s</I> removed all <I>%s's</I> modes"), name,
- client_entry2->nickname);
- }
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), channel->channel_name,
- buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
- purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(convo), client_entry2->nickname, flags);
- break;
- }
-
- case SILC_NOTIFY_TYPE_MOTD:
- tmp = va_arg(va, char *);
- silc_free(sg->motd);
- sg->motd = silc_memdup(tmp, strlen(tmp));
- break;
-
- case SILC_NOTIFY_TYPE_KICKED:
- client_entry = va_arg(va, SilcClientEntry);
- tmp = va_arg(va, char *);
- client_entry2 = va_arg(va, SilcClientEntry);
- channel = va_arg(va, SilcChannelEntry);
-
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- channel->channel_name, sg->account);
- if (!convo)
- break;
-
- if (client_entry == conn->local_entry) {
- /* Remove us from channel */
- g_snprintf(buf, sizeof(buf),
- _("You have been kicked off <I>%s</I> by <I>%s</I> (%s)"),
- channel->channel_name, client_entry2->nickname,
- tmp ? tmp : "");
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), client_entry->nickname,
- buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
- serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)));
- } else {
- /* Remove user from channel */
- g_snprintf(buf, sizeof(buf), _("Kicked by %s (%s)"),
- client_entry2->nickname, tmp ? tmp : "");
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo),
- client_entry->nickname,
- buf);
- }
-
- break;
-
- case SILC_NOTIFY_TYPE_KILLED:
- client_entry = va_arg(va, SilcClientEntry);
- tmp = va_arg(va, char *);
- idtype = va_arg(va, int);
- entry = va_arg(va, SilcClientEntry);
-
- if (!client_entry->nickname)
- break;
-
- if (client_entry == conn->local_entry) {
- if (idtype == SILC_ID_CLIENT) {
- client_entry2 = (SilcClientEntry)entry;
- g_snprintf(buf, sizeof(buf),
- _("You have been killed by %s (%s)"),
- client_entry2->nickname, tmp ? tmp : "");
- } else if (idtype == SILC_ID_SERVER) {
- server_entry = (SilcServerEntry)entry;
- g_snprintf(buf, sizeof(buf),
- _("You have been killed by %s (%s)"),
- server_entry->server_name, tmp ? tmp : "");
- } else if (idtype == SILC_ID_CHANNEL) {
- channel = (SilcChannelEntry)entry;
- g_snprintf(buf, sizeof(buf),
- _("You have been killed by %s (%s)"),
- channel->channel_name, tmp ? tmp : "");
- }
-
- /* Remove us from all channels */
- silc_hash_table_list(client_entry->channels, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- chu->channel->channel_name, sg->account);
- if (!convo)
- continue;
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), client_entry->nickname,
- buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
- serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)));
- }
- silc_hash_table_list_reset(&htl);
-
- } else {
- if (idtype == SILC_ID_CLIENT) {
- client_entry2 = (SilcClientEntry)entry;
- g_snprintf(buf, sizeof(buf),
- _("Killed by %s (%s)"),
- client_entry2->nickname, tmp ? tmp : "");
- } else if (idtype == SILC_ID_SERVER) {
- server_entry = (SilcServerEntry)entry;
- g_snprintf(buf, sizeof(buf),
- _("Killed by %s (%s)"),
- server_entry->server_name, tmp ? tmp : "");
- } else if (idtype == SILC_ID_CHANNEL) {
- channel = (SilcChannelEntry)entry;
- g_snprintf(buf, sizeof(buf),
- _("Killed by %s (%s)"),
- channel->channel_name, tmp ? tmp : "");
- }
-
- /* Remove user from all channels */
- silc_hash_table_list(client_entry->channels, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- chu->channel->channel_name, sg->account);
- if (!convo)
- continue;
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo),
- client_entry->nickname, tmp);
- }
- silc_hash_table_list_reset(&htl);
- }
-
- break;
-
- case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
- break;
-
- case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
- {
- int i;
- SilcClientEntry *clients;
- SilcUInt32 clients_count;
-
- (void)va_arg(va, void *);
- clients = va_arg(va, SilcClientEntry *);
- clients_count = va_arg(va, SilcUInt32);
-
- for (i = 0; i < clients_count; i++) {
- if (!clients[i]->nickname)
- break;
-
- /* Remove from all channels */
- silc_hash_table_list(clients[i]->channels, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
- convo =
- purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- chu->channel->channel_name, sg->account);
- if (!convo)
- continue;
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo),
- clients[i]->nickname,
- _("Server signoff"));
- }
- silc_hash_table_list_reset(&htl);
- }
- }
- break;
-
- case SILC_NOTIFY_TYPE_ERROR:
- {
- SilcStatus error = va_arg(va, int);
- purple_notify_error(gc, "Error Notify",
- silc_get_status_message(error),
- NULL);
- }
- break;
-
- case SILC_NOTIFY_TYPE_WATCH:
- {
- SilcPublicKey public_key;
- unsigned char *pk;
- SilcUInt32 pk_len;
- char *fingerprint;
-
- client_entry = va_arg(va, SilcClientEntry);
- (void)va_arg(va, char *);
- mode = va_arg(va, SilcUInt32);
- notify = va_arg(va, int);
- public_key = va_arg(va, SilcPublicKey);
-
- b = NULL;
- if (public_key) {
- PurpleBlistNode *gnode, *cnode, *bnode;
- const char *f;
-
- pk = silc_pkcs_public_key_encode(public_key, &pk_len);
- if (!pk)
- break;
- fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- for (i = 0; i < strlen(fingerprint); i++)
- if (fingerprint[i] == ' ')
- fingerprint[i] = '_';
- g_snprintf(buf, sizeof(buf) - 1,
- "%s" G_DIR_SEPARATOR_S "clientkeys"
- G_DIR_SEPARATOR_S "clientkey_%s.pub",
- silcpurple_silcdir(), fingerprint);
- silc_free(fingerprint);
- silc_free(pk);
-
- /* Find buddy by associated public key */
- for (gnode = purple_get_blist()->root; gnode;
- gnode = gnode->next) {
- if (!PURPLE_BLIST_NODE_IS_GROUP(gnode))
- continue;
- for (cnode = gnode->child; cnode; cnode = cnode->next) {
- if( !PURPLE_BLIST_NODE_IS_CONTACT(cnode))
- continue;
- for (bnode = cnode->child; bnode;
- bnode = bnode->next) {
- if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode))
- continue;
- b = (PurpleBuddy *)bnode;
- if (b->account != gc->account)
- continue;
- f = purple_blist_node_get_string(bnode, "public-key");
- if (f && !strcmp(f, buf))
- goto cont;
- b = NULL;
- }
- }
- }
- }
- cont:
- if (!b) {
- /* Find buddy by nickname */
- b = purple_find_buddy(sg->account, client_entry->nickname);
- if (!b) {
- purple_debug_warning("silc", "WATCH for %s, unknown buddy\n",
- client_entry->nickname);
- break;
- }
- }
-
- silc_free(b->proto_data);
- b->proto_data = silc_memdup(client_entry->id,
- sizeof(*client_entry->id));
- if (notify == SILC_NOTIFY_TYPE_NICK_CHANGE) {
- break;
- } else if (notify == SILC_NOTIFY_TYPE_UMODE_CHANGE) {
- /* See if client was away and is now present */
- if (!(mode & (SILC_UMODE_GONE | SILC_UMODE_INDISPOSED |
- SILC_UMODE_BUSY | SILC_UMODE_PAGE |
- SILC_UMODE_DETACHED)) &&
- (client_entry->mode & SILC_UMODE_GONE ||
- client_entry->mode & SILC_UMODE_INDISPOSED ||
- client_entry->mode & SILC_UMODE_BUSY ||
- client_entry->mode & SILC_UMODE_PAGE ||
- client_entry->mode & SILC_UMODE_DETACHED)) {
- client_entry->mode = mode;
- purple_prpl_got_user_status(purple_buddy_get_account(b), purple_buddy_get_name(b), SILCPURPLE_STATUS_ID_AVAILABLE, NULL);
- }
- else if ((mode & SILC_UMODE_GONE) ||
- (mode & SILC_UMODE_INDISPOSED) ||
- (mode & SILC_UMODE_BUSY) ||
- (mode & SILC_UMODE_PAGE) ||
- (mode & SILC_UMODE_DETACHED)) {
- client_entry->mode = mode;
- purple_prpl_got_user_status(purple_buddy_get_account(b), purple_buddy_get_name(b), SILCPURPLE_STATUS_ID_OFFLINE, NULL);
- }
- } else if (notify == SILC_NOTIFY_TYPE_SIGNOFF ||
- notify == SILC_NOTIFY_TYPE_SERVER_SIGNOFF ||
- notify == SILC_NOTIFY_TYPE_KILLED) {
- client_entry->mode = mode;
- purple_prpl_got_user_status(purple_buddy_get_account(b), purple_buddy_get_name(b), SILCPURPLE_STATUS_ID_OFFLINE, NULL);
- } else if (notify == SILC_NOTIFY_TYPE_NONE) {
- client_entry->mode = mode;
- purple_prpl_got_user_status(purple_buddy_get_account(b), purple_buddy_get_name(b), SILCPURPLE_STATUS_ID_AVAILABLE, NULL);
- }
- }
- break;
-
- default:
- purple_debug_info("silc", "Unhandled notification: %d\n", type);
- break;
- }
-
- va_end(va);
-}
-
-
-/* Command handler. This function is called always in the command function.
- If error occurs it will be called as well. `conn' is the associated
- client connection. `cmd_context' is the command context that was
- originally sent to the command. `success' is FALSE if error occurred
- during command. `command' is the command being processed. It must be
- noted that this is not reply from server. This is merely called just
- after application has called the command. Just to tell application
- that the command really was processed. */
-
-static void
-silc_command(SilcClient client, SilcClientConnection conn,
- SilcClientCommandContext cmd_context, bool success,
- SilcCommand command, SilcStatus status)
-{
- PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
-
- switch (command) {
-
- case SILC_COMMAND_CMODE:
- if (cmd_context->argc == 3 &&
- !strcmp((char *)cmd_context->argv[2], "+C"))
- sg->chpk = TRUE;
- else
- sg->chpk = FALSE;
- break;
-
- default:
- break;
- }
-}
-
-#if 0
-static void
-silcpurple_whois_more(SilcClientEntry client_entry, gint id)
-{
- SilcAttributePayload attr;
- SilcAttribute attribute;
- char *buf;
- GString *s;
- SilcVCardStruct vcard;
- int i;
-
- if (id != 0)
- return;
-
- memset(&vcard, 0, sizeof(vcard));
-
- s = g_string_new("");
-
- silc_dlist_start(client_entry->attrs);
- while ((attr = silc_dlist_get(client_entry->attrs)) != SILC_LIST_END) {
- attribute = silc_attribute_get_attribute(attr);
- switch (attribute) {
-
- case SILC_ATTRIBUTE_USER_INFO:
- if (!silc_attribute_get_object(attr, (void *)&vcard,
- sizeof(vcard)))
- continue;
- g_string_append_printf(s, "%s:\n\n", _("Personal Information"));
- if (vcard.full_name)
- g_string_append_printf(s, "%s:\t\t%s\n",
- _("Full Name"),
- vcard.full_name);
- if (vcard.first_name)
- g_string_append_printf(s, "%s:\t%s\n",
- _("First Name"),
- vcard.first_name);
- if (vcard.middle_names)
- g_string_append_printf(s, "%s:\t%s\n",
- _("Middle Name"),
- vcard.middle_names);
- if (vcard.family_name)
- g_string_append_printf(s, "%s:\t%s\n",
- _("Family Name"),
- vcard.family_name);
- if (vcard.nickname)
- g_string_append_printf(s, "%s:\t\t%s\n",
- _("Nickname"),
- vcard.nickname);
- if (vcard.bday)
- g_string_append_printf(s, "%s:\t\t%s\n",
- _("Birth Day"),
- vcard.bday);
- if (vcard.title)
- g_string_append_printf(s, "%s:\t\t%s\n",
- _("Job Title"),
- vcard.title);
- if (vcard.role)
- g_string_append_printf(s, "%s:\t\t%s\n",
- _("Job Role"),
- vcard.role);
- if (vcard.org_name)
- g_string_append_printf(s, "%s:\t%s\n",
- _("Organization"),
- vcard.org_name);
- if (vcard.org_unit)
- g_string_append_printf(s, "%s:\t\t%s\n",
- _("Unit"),
- vcard.org_unit);
- if (vcard.url)
- g_string_append_printf(s, "%s:\t%s\n",
- _("Homepage"),
- vcard.url);
- if (vcard.label)
- g_string_append_printf(s, "%s:\t%s\n",
- _("Address"),
- vcard.label);
- for (i = 0; i < vcard.num_tels; i++) {
- if (vcard.tels[i].telnum)
- g_string_append_printf(s, "%s:\t\t\t%s\n",
- _("Phone"),
- vcard.tels[i].telnum);
- }
- for (i = 0; i < vcard.num_emails; i++) {
- if (vcard.emails[i].address)
- g_string_append_printf(s, "%s:\t\t%s\n",
- _("Email"),
- vcard.emails[i].address);
- }
- if (vcard.note)
- g_string_append_printf(s, "\n%s:\t\t%s\n",
- _("Note"),
- vcard.note);
- break;
- }
- }
-
- buf = g_string_free(s, FALSE);
- purple_notify_info(NULL, _("User Information"), _("User Information"),
- buf);
- g_free(buf);
-}
-#endif
-
-/* Command reply handler. This function is called always in the command reply
- function. If error occurs it will be called as well. Normal scenario
- is that it will be called after the received command data has been parsed
- and processed. The function is used to pass the received command data to
- the application.
-
- `conn' is the associated client connection. `cmd_payload' is the command
- payload data received from server and it can be ignored. It is provided
- if the application would like to re-parse the received command data,
- however, it must be noted that the data is parsed already by the library
- thus the payload can be ignored. `success' is FALSE if error occurred.
- In this case arguments are not sent to the application. The `status' is
- the command reply status server returned. The `command' is the command
- reply being processed. The function has variable argument list and each
- command defines the number and type of arguments it passes to the
- application (on error they are not sent). */
-
-static void
-silc_command_reply(SilcClient client, SilcClientConnection conn,
- SilcCommandPayload cmd_payload, bool success,
- SilcCommand command, SilcStatus status, ...)
-{
- PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
- PurpleConversation *convo;
- va_list vp;
-
- va_start(vp, status);
-
- switch (command) {
- case SILC_COMMAND_JOIN:
- {
- SilcChannelEntry channel_entry;
-
- if (!success) {
- purple_notify_error(gc, _("Join Chat"), _("Cannot join channel"),
- silc_get_status_message(status));
- return;
- }
-
- (void)va_arg(vp, char *);
- channel_entry = va_arg(vp, SilcChannelEntry);
-
- /* Resolve users on channel */
- silc_client_get_clients_by_channel(client, conn, channel_entry,
- silcpurple_chat_join_done,
- channel_entry);
- }
- break;
-
- case SILC_COMMAND_LEAVE:
- break;
-
- case SILC_COMMAND_USERS:
- break;
-
- case SILC_COMMAND_WHOIS:
- {
- SilcUInt32 idle, mode;
- SilcBuffer channels, user_modes;
- SilcClientEntry client_entry;
- char tmp[1024], *tmp2;
- char *moodstr, *statusstr, *contactstr, *langstr, *devicestr, *tzstr, *geostr;
- PurpleNotifyUserInfo *user_info;
-
- if (!success) {
- purple_notify_error(gc, _("User Information"),
- _("Cannot get user information"),
- silc_get_status_message(status));
- break;
- }
-
- client_entry = va_arg(vp, SilcClientEntry);
- if (!client_entry->nickname)
- break;
- (void)va_arg(vp, char *);
- (void)va_arg(vp, char *);
- (void)va_arg(vp, char *);
- channels = va_arg(vp, SilcBuffer);
- mode = va_arg(vp, SilcUInt32);
- idle = va_arg(vp, SilcUInt32);
- (void)va_arg(vp, unsigned char *);
- user_modes = va_arg(vp, SilcBuffer);
-
- user_info = purple_notify_user_info_new();
- tmp2 = g_markup_escape_text(client_entry->nickname, -1);
- purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp2);
- g_free(tmp2);
- if (client_entry->realname) {
- tmp2 = g_markup_escape_text(client_entry->realname, -1);
- purple_notify_user_info_add_pair(user_info, _("Real Name"), tmp2);
- g_free(tmp2);
- }
- if (client_entry->username) {
- tmp2 = g_markup_escape_text(client_entry->username, -1);
- if (client_entry->hostname) {
- gchar *tmp3;
- tmp3 = g_strdup_printf("%s@%s", tmp2, client_entry->hostname);
- purple_notify_user_info_add_pair(user_info, _("Username"), tmp3);
- g_free(tmp3);
- } else
- purple_notify_user_info_add_pair(user_info, _("Username"), tmp2);
- g_free(tmp2);
- }
-
- if (client_entry->mode) {
- memset(tmp, 0, sizeof(tmp));
- silcpurple_get_umode_string(client_entry->mode,
- tmp, sizeof(tmp) - strlen(tmp));
- purple_notify_user_info_add_pair(user_info, _("User Modes"), tmp);
- }
-
- silcpurple_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr);
- if (moodstr) {
- purple_notify_user_info_add_pair(user_info, _("Mood"), moodstr);
- g_free(moodstr);
- }
-
- if (statusstr) {
- tmp2 = g_markup_escape_text(statusstr, -1);
- purple_notify_user_info_add_pair(user_info, _("Status Text"), tmp2);
- g_free(statusstr);
- g_free(tmp2);
- }
-
- if (contactstr) {
- purple_notify_user_info_add_pair(user_info, _("Preferred Contact"), contactstr);
- g_free(contactstr);
- }
-
- if (langstr) {
- purple_notify_user_info_add_pair(user_info, _("Preferred Language"), langstr);
- g_free(langstr);
- }
-
- if (devicestr) {
- purple_notify_user_info_add_pair(user_info, _("Device"), devicestr);
- g_free(devicestr);
- }
-
- if (tzstr) {
- purple_notify_user_info_add_pair(user_info, _("Timezone"), tzstr);
- g_free(tzstr);
- }
-
- if (geostr) {
- purple_notify_user_info_add_pair(user_info, _("Geolocation"), geostr);
- g_free(geostr);
- }
-
- if (client_entry->server)
- purple_notify_user_info_add_pair(user_info, _("Server"), client_entry->server);
-
- if (channels && user_modes) {
- SilcUInt32 *umodes;
- SilcDList list =
- silc_channel_payload_parse_list(channels->data,
- channels->len);
- if (list && silc_get_mode_list(user_modes,
- silc_dlist_count(list),
- &umodes)) {
- SilcChannelPayload entry;
- int i = 0;
-
- memset(tmp, 0, sizeof(tmp));
- silc_dlist_start(list);
- while ((entry = silc_dlist_get(list))
- != SILC_LIST_END) {
- SilcUInt32 name_len;
- char *m = silc_client_chumode_char(umodes[i++]);
- char *name = (char *)silc_channel_get_name(entry, &name_len);
- if (m)
- silc_strncat(tmp, sizeof(tmp) - 1, m, strlen(m));
- silc_strncat(tmp, sizeof(tmp) - 1, name, name_len);
- silc_strncat(tmp, sizeof(tmp) - 1, " ", 1);
- silc_free(m);
-
- }
- tmp2 = g_markup_escape_text(tmp, -1);
- purple_notify_user_info_add_pair(user_info, _("Currently on"), tmp2);
- g_free(tmp2);
- silc_free(umodes);
- }
- }
-
- if (client_entry->public_key) {
- char *fingerprint, *babbleprint;
- unsigned char *pk;
- SilcUInt32 pk_len;
- pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len);
- fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
- purple_notify_user_info_add_pair(user_info, _("Public Key Fingerprint"), fingerprint);
- purple_notify_user_info_add_pair(user_info, _("Public Key Babbleprint"), babbleprint);
- silc_free(fingerprint);
- silc_free(babbleprint);
- silc_free(pk);
- }
-
-#if 0 /* XXX for now, let's not show attrs here */
- if (client_entry->attrs)
- purple_request_action(gc, _("User Information"),
- _("User Information"),
- buf, 1, client_entry, 2,
- _("OK"), G_CALLBACK(silcpurple_whois_more),
- _("_More..."), G_CALLBACK(silcpurple_whois_more), gc->account, NULL, NULL);
- else
-#endif
- purple_notify_userinfo(gc, client_entry->nickname, user_info, NULL, NULL);
- purple_notify_user_info_destroy(user_info);
- }
- break;
-
- case SILC_COMMAND_WHOWAS:
- {
- SilcClientEntry client_entry;
- char *nickname, *realname, *username, *tmp;
- PurpleNotifyUserInfo *user_info;
-
- if (!success) {
- purple_notify_error(gc, _("User Information"),
- _("Cannot get user information"),
- silc_get_status_message(status));
- break;
- }
-
- client_entry = va_arg(vp, SilcClientEntry);
- nickname = va_arg(vp, char *);
- username = va_arg(vp, char *);
- realname = va_arg(vp, char *);
- if (!nickname)
- break;
-
- user_info = purple_notify_user_info_new();
- tmp = g_markup_escape_text(nickname, -1);
- purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp);
- g_free(tmp);
- if (realname) {
- tmp = g_markup_escape_text(realname, -1);
- purple_notify_user_info_add_pair(user_info, _("Real Name"), tmp);
- g_free(tmp);
- }
- if (username) {
- tmp = g_markup_escape_text(username, -1);
- if (client_entry && client_entry->hostname) {
- gchar *tmp3;
- tmp3 = g_strdup_printf("%s@%s", tmp, client_entry->hostname);
- purple_notify_user_info_add_pair(user_info, _("Username"), tmp3);
- g_free(tmp3);
- } else
- purple_notify_user_info_add_pair(user_info, _("Username"), tmp);
- g_free(tmp);
- }
- if (client_entry && client_entry->server)
- purple_notify_user_info_add_pair(user_info, _("Server"), client_entry->server);
-
-
- if (client_entry && client_entry->public_key) {
- char *fingerprint, *babbleprint;
- unsigned char *pk;
- SilcUInt32 pk_len;
- pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len);
- fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
- purple_notify_user_info_add_pair(user_info, _("Public Key Fingerprint"), fingerprint);
- purple_notify_user_info_add_pair(user_info, _("Public Key Babbleprint"), babbleprint);
- silc_free(fingerprint);
- silc_free(babbleprint);
- silc_free(pk);
- }
-
- purple_notify_userinfo(gc, nickname, user_info, NULL, NULL);
- purple_notify_user_info_destroy(user_info);
- }
- break;
-
- case SILC_COMMAND_DETACH:
- if (!success) {
- purple_notify_error(gc, _("Detach From Server"), _("Cannot detach"),
- silc_get_status_message(status));
- return;
- }
- break;
-
- case SILC_COMMAND_TOPIC:
- {
- SilcChannelEntry channel;
-
- if (!success) {
- purple_notify_error(gc, _("Topic"), _("Cannot set topic"),
- silc_get_status_message(status));
- return;
- }
-
- channel = va_arg(vp, SilcChannelEntry);
-
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- channel->channel_name, sg->account);
- if (!convo) {
- purple_debug_error("silc", "Got a topic for %s, which doesn't exist\n",
- channel->channel_name);
- break;
- }
-
- /* Set topic */
- if (channel->topic)
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), NULL, channel->topic);
- }
- break;
-
- case SILC_COMMAND_NICK:
- {
- /* I don't think we should need to do this because the server should
- * be sending a SILC_NOTIFY_TYPE_NICK_CHANGE when we change our own
- * nick, but it isn't, so we deal with it here instead. Stu. */
- SilcClientEntry local_entry;
- SilcHashTableList htl;
- SilcChannelUser chu;
- const char *oldnick;
-
- if (!success) {
- purple_notify_error(gc, _("Nick"), _("Failed to change nickname"),
- silc_get_status_message(status));
- return;
- }
-
- local_entry = va_arg(vp, SilcClientEntry);
-
- /* Change nick on all channels */
- silc_hash_table_list(local_entry->channels, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- chu->channel->channel_name, sg->account);
- if (!convo)
- continue;
- oldnick = purple_conv_chat_get_nick(PURPLE_CONV_CHAT(convo));
- if (strcmp(oldnick, purple_normalize(purple_conversation_get_account(convo), local_entry->nickname))) {
- purple_conv_chat_rename_user(PURPLE_CONV_CHAT(convo),
- oldnick, local_entry->nickname);
- purple_conv_chat_set_nick(PURPLE_CONV_CHAT(convo), local_entry->nickname);
- }
- }
- silc_hash_table_list_reset(&htl);
-
- purple_connection_set_display_name(gc, local_entry->nickname);
- }
- break;
-
- case SILC_COMMAND_LIST:
- {
- char *topic, *name;
- int usercount;
- PurpleRoomlistRoom *room;
-
- if (sg->roomlist_cancelled)
- break;
-
- if (!success) {
- purple_notify_error(gc, _("Error"), _("Error retrieving room list"),
- silc_get_status_message(status));
- purple_roomlist_set_in_progress(sg->roomlist, FALSE);
- purple_roomlist_unref(sg->roomlist);
- sg->roomlist = NULL;
- return;
- }
-
- (void)va_arg(vp, SilcChannelEntry);
- name = va_arg(vp, char *);
- if (!name) {
- purple_notify_error(gc, _("Roomlist"), _("Cannot get room list"),
- silc_get_status_message(status));
- purple_roomlist_set_in_progress(sg->roomlist, FALSE);
- purple_roomlist_unref(sg->roomlist);
- sg->roomlist = NULL;
- return;
- }
- topic = va_arg(vp, char *);
- usercount = va_arg(vp, int);
-
- room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, name, NULL);
- purple_roomlist_room_add_field(sg->roomlist, room, name);
- purple_roomlist_room_add_field(sg->roomlist, room,
- SILC_32_TO_PTR(usercount));
- purple_roomlist_room_add_field(sg->roomlist, room,
- topic ? topic : "");
- purple_roomlist_room_add(sg->roomlist, room);
-
- if (status == SILC_STATUS_LIST_END ||
- status == SILC_STATUS_OK) {
- purple_roomlist_set_in_progress(sg->roomlist, FALSE);
- purple_roomlist_unref(sg->roomlist);
- sg->roomlist = NULL;
- }
- }
- break;
-
- case SILC_COMMAND_GETKEY:
- {
- SilcPublicKey public_key;
-
- if (!success) {
- purple_notify_error(gc, _("Get Public Key"),
- _("Cannot fetch the public key"),
- silc_get_status_message(status));
- return;
- }
-
- (void)va_arg(vp, SilcUInt32);
- (void)va_arg(vp, void *);
- public_key = va_arg(vp, SilcPublicKey);
-
- if (!public_key)
- purple_notify_error(gc, _("Get Public Key"),
- _("Cannot fetch the public key"),
- _("No public key was received"));
- }
- break;
-
- case SILC_COMMAND_INFO:
- {
-
- char *server_name;
- char *server_info;
- char tmp[256];
-
- if (!success) {
- purple_notify_error(gc, _("Server Information"),
- _("Cannot get server information"),
- silc_get_status_message(status));
- return;
- }
-
- (void)va_arg(vp, SilcServerEntry);
- server_name = va_arg(vp, char *);
- server_info = va_arg(vp, char *);
-
- if (server_name && server_info) {
- g_snprintf(tmp, sizeof(tmp), "Server: %s\n%s",
- server_name, server_info);
- purple_notify_info(gc, NULL, _("Server Information"), tmp);
- }
- }
- break;
-
- case SILC_COMMAND_STATS:
- {
- SilcUInt32 starttime, uptime, my_clients, my_channels, my_server_ops,
- my_router_ops, cell_clients, cell_channels, cell_servers,
- clients, channels, servers, routers, server_ops, router_ops;
- SilcUInt32 buffer_length;
- SilcBufferStruct buf;
-
- unsigned char *server_stats;
- char *msg;
-
- if (!success) {
- purple_notify_error(gc, _("Server Statistics"),
- _("Cannot get server statistics"),
- silc_get_status_message(status));
- return;
- }
-
- server_stats = va_arg(vp, unsigned char *);
- buffer_length = va_arg(vp, SilcUInt32);
- if (!server_stats || !buffer_length) {
- purple_notify_error(gc, _("Server Statistics"),
- _("No server statistics available"), NULL);
- break;
- }
- silc_buffer_set(&buf, server_stats, buffer_length);
- silc_buffer_unformat(&buf,
- SILC_STR_UI_INT(&starttime),
- SILC_STR_UI_INT(&uptime),
- SILC_STR_UI_INT(&my_clients),
- SILC_STR_UI_INT(&my_channels),
- SILC_STR_UI_INT(&my_server_ops),
- SILC_STR_UI_INT(&my_router_ops),
- SILC_STR_UI_INT(&cell_clients),
- SILC_STR_UI_INT(&cell_channels),
- SILC_STR_UI_INT(&cell_servers),
- SILC_STR_UI_INT(&clients),
- SILC_STR_UI_INT(&channels),
- SILC_STR_UI_INT(&servers),
- SILC_STR_UI_INT(&routers),
- SILC_STR_UI_INT(&server_ops),
- SILC_STR_UI_INT(&router_ops),
- SILC_STR_END);
-
- msg = g_strdup_printf(_("Local server start time: %s\n"
- "Local server uptime: %s\n"
- "Local server clients: %d\n"
- "Local server channels: %d\n"
- "Local server operators: %d\n"
- "Local router operators: %d\n"
- "Local cell clients: %d\n"
- "Local cell channels: %d\n"
- "Local cell servers: %d\n"
- "Total clients: %d\n"
- "Total channels: %d\n"
- "Total servers: %d\n"
- "Total routers: %d\n"
- "Total server operators: %d\n"
- "Total router operators: %d\n"),
- silc_get_time(starttime),
- purple_str_seconds_to_string((int)uptime),
- (int)my_clients, (int)my_channels, (int)my_server_ops, (int)my_router_ops,
- (int)cell_clients, (int)cell_channels, (int)cell_servers,
- (int)clients, (int)channels, (int)servers, (int)routers,
- (int)server_ops, (int)router_ops);
-
- purple_notify_info(gc, NULL,
- _("Network Statistics"), msg);
- g_free(msg);
- }
- break;
-
- case SILC_COMMAND_PING:
- {
- if (!success) {
- purple_notify_error(gc, _("Ping"), _("Ping failed"),
- silc_get_status_message(status));
- return;
- }
-
- purple_notify_info(gc, _("Ping"), _("Ping reply received from server"),
- NULL);
- }
- break;
-
- case SILC_COMMAND_KILL:
- if (!success) {
- purple_notify_error(gc, _("Kill User"),
- _("Could not kill user"),
- silc_get_status_message(status));
- return;
- }
- break;
-
- case SILC_COMMAND_CMODE:
- {
- SilcChannelEntry channel_entry;
- SilcBuffer channel_pubkeys;
-
- if (!success)
- return;
-
- channel_entry = va_arg(vp, SilcChannelEntry);
- (void)va_arg(vp, SilcUInt32);
- (void)va_arg(vp, SilcPublicKey);
- channel_pubkeys = va_arg(vp, SilcBuffer);
-
- if (sg->chpk)
- silcpurple_chat_chauth_show(sg, channel_entry, channel_pubkeys);
- }
- break;
-
- default:
- if (success)
- purple_debug_info("silc", "Unhandled command: %d (succeeded)\n", command);
- else
- purple_debug_info("silc", "Unhandled command: %d (failed: %s)\n", command,
- silc_get_status_message(status));
- break;
- }
-
- va_end(vp);
-}
-
-
-/* Called to indicate that connection was either successfully established
- or connecting failed. This is also the first time application receives
- the SilcClientConnection object which it should save somewhere.
- If the `success' is FALSE the application must always call the function
- silc_client_close_connection. */
-
-static void
-silc_connected(SilcClient client, SilcClientConnection conn,
- SilcClientConnectionStatus status)
-{
- PurpleConnection *gc = client->application;
- SilcPurple sg;
-
- if (gc == NULL) {
- silc_client_close_connection(client, conn);
- return;
- }
- sg = gc->proto_data;
-
- switch (status) {
- case SILC_CLIENT_CONN_SUCCESS:
- case SILC_CLIENT_CONN_SUCCESS_RESUME:
- purple_connection_set_state(gc, PURPLE_CONNECTED);
-
- /* Send the server our buddy list */
- silcpurple_send_buddylist(gc);
-
- g_unlink(silcpurple_session_file(purple_account_get_username(sg->account)));
-
- /* Send any UMODEs configured for account */
- if (purple_account_get_bool(sg->account, "block-ims", FALSE)) {
- silc_client_command_call(sg->client, sg->conn, NULL,
- "UMODE", "+P", NULL);
- }
-
- return;
- break;
- case SILC_CLIENT_CONN_ERROR:
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Error during connecting to SILC Server"));
- g_unlink(silcpurple_session_file(purple_account_get_username(sg->account)));
- break;
-
- case SILC_CLIENT_CONN_ERROR_KE:
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
- _("Key Exchange failed"));
- break;
-
- case SILC_CLIENT_CONN_ERROR_AUTH:
- purple_connection_error_reason(gc,
- PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
- _("Authentication failed"));
- break;
-
- case SILC_CLIENT_CONN_ERROR_RESUME:
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
- _("Resuming detached session failed. "
- "Press Reconnect to create new connection."));
- g_unlink(silcpurple_session_file(purple_account_get_username(sg->account)));
- break;
-
- case SILC_CLIENT_CONN_ERROR_TIMEOUT:
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Connection timed out"));
- break;
- }
-
- /* Error */
- sg->conn = NULL;
- silc_client_close_connection(client, conn);
-}
-
-
-/* Called to indicate that connection was disconnected to the server.
- The `status' may tell the reason of the disconnection, and if the
- `message' is non-NULL it may include the disconnection message
- received from server. */
-
-static void
-silc_disconnected(SilcClient client, SilcClientConnection conn,
- SilcStatus status, const char *message)
-{
- PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
-
- if (sg->resuming && !sg->detaching)
- g_unlink(silcpurple_session_file(purple_account_get_username(sg->account)));
-
- sg->conn = NULL;
-
- /* Close the connection */
- if (!sg->detaching)
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Disconnected by server"));
- else
- /* TODO: Does this work correctly? Maybe we need to set wants_to_die? */
- purple_account_disconnect(purple_connection_get_account(gc));
-}
-
-
-typedef struct {
- SilcGetAuthMeth completion;
- void *context;
-} *SilcPurpleGetAuthMethod;
-
-/* Callback called when we've received the authentication method information
- from the server after we've requested it. */
-
-static void silc_get_auth_method_callback(SilcClient client,
- SilcClientConnection conn,
- SilcAuthMethod auth_meth,
- void *context)
-{
- SilcPurpleGetAuthMethod internal = context;
-
- switch (auth_meth) {
- case SILC_AUTH_NONE:
- /* No authentication required. */
- (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
- break;
-
- case SILC_AUTH_PASSWORD:
- /* By returning NULL here the library will ask the passphrase from us
- by calling the silc_ask_passphrase. */
- (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
- break;
-
- case SILC_AUTH_PUBLIC_KEY:
- /* Do not get the authentication data now, the library will generate
- it using our default key, if we do not provide it here. */
- (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
- break;
- }
-
- silc_free(internal);
-}
-
-/* Find authentication method and authentication data by hostname and
- port. The hostname may be IP address as well. When the authentication
- method has been resolved the `completion' callback with the found
- authentication method and authentication data is called. The `conn'
- may be NULL. */
-
-static void
-silc_get_auth_method(SilcClient client, SilcClientConnection conn,
- char *hostname, SilcUInt16 port,
- SilcGetAuthMeth completion, void *context)
-{
- PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
- SilcPurpleGetAuthMethod internal;
- const char *password;
-
- /* Progress */
- if (sg->resuming)
- purple_connection_update_progress(gc, _("Resuming session"), 4, 5);
- else
- purple_connection_update_progress(gc, _("Authenticating connection"), 4, 5);
-
- /* Check configuration if we have this connection configured. If we
- have then return that data immediately, as it's faster way. */
- if (purple_account_get_bool(sg->account, "pubkey-auth", FALSE)) {
- completion(TRUE, SILC_AUTH_PUBLIC_KEY, NULL, 0, context);
- return;
- }
- password = purple_connection_get_password(gc);
- if (password && *password) {
- completion(TRUE, SILC_AUTH_PASSWORD, (unsigned char *)password, strlen(password), context);
- return;
- }
-
- /* Resolve the authentication method from server, as we may not know it. */
- internal = silc_calloc(1, sizeof(*internal));
- if (!internal)
- return;
- internal->completion = completion;
- internal->context = context;
- silc_client_request_authentication_method(client, conn,
- silc_get_auth_method_callback,
- internal);
-}
-
-
-/* Verifies received public key. The `conn_type' indicates which entity
- (server, client etc.) has sent the public key. If user decides to trust
- the application may save the key as trusted public key for later
- use. The `completion' must be called after the public key has been
- verified. */
-
-static void
-silc_verify_public_key(SilcClient client, SilcClientConnection conn,
- SilcSocketType conn_type, unsigned char *pk,
- SilcUInt32 pk_len, SilcSKEPKType pk_type,
- SilcVerifyPublicKey completion, void *context)
-{
- PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
-
- if (!sg->conn && (conn_type == SILC_SOCKET_TYPE_SERVER ||
- conn_type == SILC_SOCKET_TYPE_ROUTER)) {
- /* Progress */
- if (sg->resuming)
- purple_connection_update_progress(gc, _("Resuming session"), 3, 5);
- else
- purple_connection_update_progress(gc, _("Verifying server public key"),
- 3, 5);
- }
-
- /* Verify public key */
- silcpurple_verify_public_key(client, conn, NULL, conn_type, pk,
- pk_len, pk_type, completion, context);
-}
-
-typedef struct {
- SilcAskPassphrase completion;
- void *context;
-} *SilcPurpleAskPassphrase;
-
-static void
-silc_ask_passphrase_cb(SilcPurpleAskPassphrase internal, const char *passphrase)
-{
- if (!passphrase || !(*passphrase))
- internal->completion(NULL, 0, internal->context);
- else
- internal->completion((unsigned char *)passphrase,
- strlen(passphrase), internal->context);
- silc_free(internal);
-}
-
-/* Ask (interact, that is) a passphrase from user. The passphrase is
- returned to the library by calling the `completion' callback with
- the `context'. The returned passphrase SHOULD be in UTF-8 encoded,
- if not then the library will attempt to encode. */
-
-static void
-silc_ask_passphrase(SilcClient client, SilcClientConnection conn,
- SilcAskPassphrase completion, void *context)
-{
- PurpleConnection *gc = client->application;
- SilcPurpleAskPassphrase internal = silc_calloc(1, sizeof(*internal));
-
- if (!internal)
- return;
- internal->completion = completion;
- internal->context = context;
- purple_request_input(gc, _("Passphrase"), NULL,
- _("Passphrase required"), NULL, FALSE, TRUE, NULL,
- _("OK"), G_CALLBACK(silc_ask_passphrase_cb),
- _("Cancel"), G_CALLBACK(silc_ask_passphrase_cb),
- purple_connection_get_account(gc), NULL, NULL, internal);
-}
-
-
-/* Notifies application that failure packet was received. This is called
- if there is some protocol active in the client. The `protocol' is the
- protocol context. The `failure' is opaque pointer to the failure
- indication. Note, that the `failure' is protocol dependant and
- application must explicitly cast it to correct type. Usually `failure'
- is 32 bit failure type (see protocol specs for all protocol failure
- types). */
-
-static void
-silc_failure(SilcClient client, SilcClientConnection conn,
- SilcProtocol protocol, void *failure)
-{
- PurpleConnection *gc = client->application;
- char buf[128];
-
- memset(buf, 0, sizeof(buf));
-
- if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
- SilcSKEStatus status = (SilcSKEStatus)SILC_PTR_TO_32(failure);
-
- if (status == SILC_SKE_STATUS_BAD_VERSION)
- g_snprintf(buf, sizeof(buf),
- _("Failure: Version mismatch, upgrade your client"));
- if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY)
- g_snprintf(buf, sizeof(buf),
- _("Failure: Remote does not trust/support your public key"));
- if (status == SILC_SKE_STATUS_UNKNOWN_GROUP)
- g_snprintf(buf, sizeof(buf),
- _("Failure: Remote does not support proposed KE group"));
- if (status == SILC_SKE_STATUS_UNKNOWN_CIPHER)
- g_snprintf(buf, sizeof(buf),
- _("Failure: Remote does not support proposed cipher"));
- if (status == SILC_SKE_STATUS_UNKNOWN_PKCS)
- g_snprintf(buf, sizeof(buf),
- _("Failure: Remote does not support proposed PKCS"));
- if (status == SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION)
- g_snprintf(buf, sizeof(buf),
- _("Failure: Remote does not support proposed hash function"));
- if (status == SILC_SKE_STATUS_UNKNOWN_HMAC)
- g_snprintf(buf, sizeof(buf),
- _("Failure: Remote does not support proposed HMAC"));
- if (status == SILC_SKE_STATUS_INCORRECT_SIGNATURE)
- g_snprintf(buf, sizeof(buf), _("Failure: Incorrect signature"));
- if (status == SILC_SKE_STATUS_INVALID_COOKIE)
- g_snprintf(buf, sizeof(buf), _("Failure: Invalid cookie"));
-
- /* Show the error on the progress bar. A more generic error message
- is going to be showed to user after this in the silc_connected. */
- purple_connection_update_progress(gc, buf, 2, 5);
- }
-
- if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) {
- SilcUInt32 err = SILC_PTR_TO_32(failure);
-
- if (err == SILC_AUTH_FAILED)
- g_snprintf(buf, sizeof(buf), _("Failure: Authentication failed"));
-
- /* Show the error on the progress bar. A more generic error message
- is going to be showed to user after this in the silc_connected. */
- purple_connection_update_progress(gc, buf, 4, 5);
- }
-}
-
-/* Asks whether the user would like to perform the key agreement protocol.
- This is called after we have received an key agreement packet or an
- reply to our key agreement packet. This returns TRUE if the user wants
- the library to perform the key agreement protocol and FALSE if it is not
- desired (application may start it later by calling the function
- silc_client_perform_key_agreement). If TRUE is returned also the
- `completion' and `context' arguments must be set by the application. */
-
-static bool
-silc_key_agreement(SilcClient client, SilcClientConnection conn,
- SilcClientEntry client_entry, const char *hostname,
- SilcUInt16 port, SilcKeyAgreementCallback *completion,
- void **context)
-{
- silcpurple_buddy_keyagr_request(client, conn, client_entry, hostname, port);
- *completion = NULL;
- *context = NULL;
- return FALSE;
-}
-
-
-/* Notifies application that file transfer protocol session is being
- requested by the remote client indicated by the `client_entry' from
- the `hostname' and `port'. The `session_id' is the file transfer
- session and it can be used to either accept or reject the file
- transfer request, by calling the silc_client_file_receive or
- silc_client_file_close, respectively. */
-
-static void
-silc_ftp(SilcClient client, SilcClientConnection conn,
- SilcClientEntry client_entry, SilcUInt32 session_id,
- const char *hostname, SilcUInt16 port)
-{
- silcpurple_ftp_request(client, conn, client_entry, session_id,
- hostname, port);
-}
-
-
-/* Delivers SILC session detachment data indicated by `detach_data' to the
- application. If application has issued SILC_COMMAND_DETACH command
- the client session in the SILC network is not quit. The client remains
- in the network but is detached. The detachment data may be used later
- to resume the session in the SILC Network. The appliation is
- responsible of saving the `detach_data', to for example in a file.
-
- The detachment data can be given as argument to the functions
- silc_client_connect_to_server, or silc_client_add_connection when
- creating connection to remote server, inside SilcClientConnectionParams
- structure. If it is provided the client library will attempt to resume
- the session in the network. After the connection is created
- successfully, the application is responsible of setting the user
- interface for user into the same state it was before detaching (showing
- same channels, channel modes, etc). It can do this by fetching the
- information (like joined channels) from the client library. */
-
-static void
-silc_detach(SilcClient client, SilcClientConnection conn,
- const unsigned char *detach_data, SilcUInt32 detach_data_len)
-{
- PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
- const char *file;
-
- /* Save the detachment data to file. */
- file = silcpurple_session_file(purple_account_get_username(sg->account));
- g_unlink(file);
- silc_file_writefile(file, (char *)detach_data, detach_data_len);
-}
-
-SilcClientOperations ops = {
- silc_say,
- silc_channel_message,
- silc_private_message,
- silc_notify,
- silc_command,
- silc_command_reply,
- silc_connected,
- silc_disconnected,
- silc_get_auth_method,
- silc_verify_public_key,
- silc_ask_passphrase,
- silc_failure,
- silc_key_agreement,
- silc_ftp,
- silc_detach
-};
diff --git a/libpurple/protocols/silc10/pk.c b/libpurple/protocols/silc10/pk.c
deleted file mode 100644
index 0bd399d6d5..0000000000
--- a/libpurple/protocols/silc10/pk.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
-
- silcpurple_pk.c
-
- Author: Pekka Riikonen <priikone@silcnet.org>
-
- Copyright (C) 2004 Pekka Riikonen
-
- 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; version 2 of the License.
-
- 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.
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-#include "silcpurple.h"
-
-/************************* Public Key Verification ***************************/
-
-typedef struct {
- SilcClient client;
- SilcClientConnection conn;
- char *filename;
- char *entity;
- char *entity_name;
- char *fingerprint;
- char *babbleprint;
- unsigned char *pk;
- SilcUInt32 pk_len;
- SilcSKEPKType pk_type;
- SilcVerifyPublicKey completion;
- void *context;
- gboolean changed;
-} *PublicKeyVerify;
-
-static void silcpurple_verify_ask(const char *entity,
- const char *fingerprint,
- const char *babbleprint,
- PublicKeyVerify verify);
-
-static void silcpurple_verify_cb(PublicKeyVerify verify, gint id)
-{
- if (id != 2) {
- if (verify->completion)
- verify->completion(FALSE, verify->context);
- } else {
- if (verify->completion)
- verify->completion(TRUE, verify->context);
-
- /* Save the key for future checking */
- silc_pkcs_save_public_key_data(verify->filename, verify->pk,
- verify->pk_len, SILC_PKCS_FILE_PEM);
- }
-
- silc_free(verify->filename);
- silc_free(verify->entity);
- silc_free(verify->entity_name);
- silc_free(verify->fingerprint);
- silc_free(verify->babbleprint);
- silc_free(verify->pk);
- silc_free(verify);
-}
-
-static void silcpurple_verify_details_cb(PublicKeyVerify verify)
-{
- /* What a hack. We have to display the accept dialog _again_
- because Purple closes the dialog after you press the button. Purple
- should have option for the dialogs whether the buttons close them
- or not. */
- silcpurple_verify_ask(verify->entity, verify->fingerprint,
- verify->babbleprint, verify);
-}
-
-static void silcpurple_verify_details(PublicKeyVerify verify, gint id)
-{
- SilcPublicKey public_key;
- PurpleConnection *gc = verify->client->application;
- SilcPurple sg = gc->proto_data;
-
- silc_pkcs_public_key_decode(verify->pk, verify->pk_len,
- &public_key);
- silcpurple_show_public_key(sg, verify->entity_name, public_key,
- G_CALLBACK(silcpurple_verify_details_cb),
- verify);
- silc_pkcs_public_key_free(public_key);
-}
-
-static void silcpurple_verify_ask(const char *entity,
- const char *fingerprint,
- const char *babbleprint,
- PublicKeyVerify verify)
-{
- PurpleConnection *gc = verify->client->application;
- char tmp[256], tmp2[256];
-
- if (verify->changed) {
- g_snprintf(tmp, sizeof(tmp),
- _("Received %s's public key. Your local copy does not match this "
- "key. Would you still like to accept this public key?"),
- entity);
- } else {
- g_snprintf(tmp, sizeof(tmp),
- _("Received %s's public key. Would you like to accept this "
- "public key?"), entity);
- }
- g_snprintf(tmp2, sizeof(tmp2),
- _("Fingerprint and babbleprint for the %s key are:\n\n"
- "%s\n%s\n"), entity, fingerprint, babbleprint);
-
- purple_request_action(gc, _("Verify Public Key"), tmp, tmp2,
- PURPLE_DEFAULT_ACTION_NONE,
- purple_connection_get_account(gc), entity, NULL, verify, 3,
- _("Yes"), G_CALLBACK(silcpurple_verify_cb),
- _("No"), G_CALLBACK(silcpurple_verify_cb),
- _("_View..."), G_CALLBACK(silcpurple_verify_details));
-}
-
-void silcpurple_verify_public_key(SilcClient client, SilcClientConnection conn,
- const char *name, SilcSocketType conn_type,
- unsigned char *pk, SilcUInt32 pk_len,
- SilcSKEPKType pk_type,
- SilcVerifyPublicKey completion, void *context)
-{
- PurpleConnection *gc = client->application;
- int i;
- char file[256], filename[256], filename2[256], *ipf, *hostf = NULL;
- char *fingerprint, *babbleprint;
- struct passwd *pw;
- struct stat st;
- char *entity = ((conn_type == SILC_SOCKET_TYPE_SERVER ||
- conn_type == SILC_SOCKET_TYPE_ROUTER) ?
- "server" : "client");
- PublicKeyVerify verify;
-
- if (pk_type != SILC_SKE_PK_TYPE_SILC) {
- purple_notify_error(gc, _("Verify Public Key"),
- _("Unsupported public key type"), NULL);
- if (completion)
- completion(FALSE, context);
- return;
- }
-
- pw = getpwuid(getuid());
- if (!pw) {
- if (completion)
- completion(FALSE, context);
- return;
- }
-
- memset(filename, 0, sizeof(filename));
- memset(filename2, 0, sizeof(filename2));
- memset(file, 0, sizeof(file));
-
- if (conn_type == SILC_SOCKET_TYPE_SERVER ||
- conn_type == SILC_SOCKET_TYPE_ROUTER) {
- if (!name) {
- g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
- conn->sock->ip, conn->sock->port);
- g_snprintf(filename, sizeof(filename) - 1,
- "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s",
- silcpurple_silcdir(), entity, file);
-
- g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
- conn->sock->hostname, conn->sock->port);
- g_snprintf(filename2, sizeof(filename2) - 1,
- "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s",
- silcpurple_silcdir(), entity, file);
-
- ipf = filename;
- hostf = filename2;
- } else {
- g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
- name, conn->sock->port);
- g_snprintf(filename, sizeof(filename) - 1,
- "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s",
- silcpurple_silcdir(), entity, file);
-
- ipf = filename;
- }
- } else {
- /* Replace all whitespaces with `_'. */
- fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- for (i = 0; i < strlen(fingerprint); i++)
- if (fingerprint[i] == ' ')
- fingerprint[i] = '_';
-
- g_snprintf(file, sizeof(file) - 1, "%skey_%s.pub", entity, fingerprint);
- g_snprintf(filename, sizeof(filename) - 1,
- "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s",
- silcpurple_silcdir(), entity, file);
- silc_free(fingerprint);
-
- ipf = filename;
- }
-
- verify = silc_calloc(1, sizeof(*verify));
- if (!verify)
- return;
- verify->client = client;
- verify->conn = conn;
- verify->filename = strdup(ipf);
- verify->entity = strdup(entity);
- verify->entity_name = (conn_type != SILC_SOCKET_TYPE_CLIENT ?
- (name ? strdup(name) : strdup(conn->sock->hostname))
- : NULL);
- verify->pk = silc_memdup(pk, pk_len);
- verify->pk_len = pk_len;
- verify->pk_type = pk_type;
- verify->completion = completion;
- verify->context = context;
- fingerprint = verify->fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- babbleprint = verify->babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
-
- /* Check whether this key already exists */
- if (g_stat(ipf, &st) < 0 && (!hostf || g_stat(hostf, &st) < 0)) {
- /* Key does not exist, ask user to verify the key and save it */
- silcpurple_verify_ask(name ? name : entity,
- fingerprint, babbleprint, verify);
- return;
- } else {
- /* The key already exists, verify it. */
- SilcPublicKey public_key;
- unsigned char *encpk;
- SilcUInt32 encpk_len;
-
- /* Load the key file, try for both IP filename and hostname filename */
- if (!silc_pkcs_load_public_key(ipf, &public_key,
- SILC_PKCS_FILE_PEM) &&
- !silc_pkcs_load_public_key(ipf, &public_key,
- SILC_PKCS_FILE_BIN) &&
- (!hostf || (!silc_pkcs_load_public_key(hostf, &public_key,
- SILC_PKCS_FILE_PEM) &&
- !silc_pkcs_load_public_key(hostf, &public_key,
- SILC_PKCS_FILE_BIN)))) {
- silcpurple_verify_ask(name ? name : entity,
- fingerprint, babbleprint, verify);
- return;
- }
-
- /* Encode the key data */
- encpk = silc_pkcs_public_key_encode(public_key, &encpk_len);
- if (!encpk) {
- silcpurple_verify_ask(name ? name : entity,
- fingerprint, babbleprint, verify);
- return;
- }
-
- /* Compare the keys */
- if (memcmp(encpk, pk, encpk_len)) {
- /* Ask user to verify the key and save it */
- verify->changed = TRUE;
- silcpurple_verify_ask(name ? name : entity,
- fingerprint, babbleprint, verify);
- return;
- }
-
- /* Local copy matched */
- if (completion)
- completion(TRUE, context);
- silc_free(verify->filename);
- silc_free(verify->entity);
- silc_free(verify->entity_name);
- silc_free(verify->pk);
- silc_free(verify->fingerprint);
- silc_free(verify->babbleprint);
- silc_free(verify);
- }
-}
diff --git a/libpurple/protocols/silc10/silc.c b/libpurple/protocols/silc10/silc.c
deleted file mode 100644
index e29c22ea45..0000000000
--- a/libpurple/protocols/silc10/silc.c
+++ /dev/null
@@ -1,1965 +0,0 @@
-/*
-
- silcpurple.c
-
- Author: Pekka Riikonen <priikone@silcnet.org>
-
- Copyright (C) 2004 - 2005 Pekka Riikonen
-
- 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; version 2 of the License.
-
- 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.
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-#include "silcpurple.h"
-#include "version.h"
-#include "wb.h"
-#include "core.h"
-
-extern SilcClientOperations ops;
-static PurplePlugin *silc_plugin = NULL;
-
-static const char *
-silcpurple_list_icon(PurpleAccount *a, PurpleBuddy *b)
-{
- return (const char *)"silc";
-}
-
-static GList *
-silcpurple_away_states(PurpleAccount *account)
-{
- PurpleStatusType *type;
- GList *types = NULL;
-
- type = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE, SILCPURPLE_STATUS_ID_AVAILABLE, NULL, TRUE, TRUE, FALSE);
- types = g_list_append(types, type);
- type = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE, SILCPURPLE_STATUS_ID_HYPER, _("Hyper Active"), TRUE, TRUE, FALSE);
- types = g_list_append(types, type);
- type = purple_status_type_new_full(PURPLE_STATUS_AWAY, SILCPURPLE_STATUS_ID_AWAY, NULL, TRUE, TRUE, FALSE);
- types = g_list_append(types, type);
- type = purple_status_type_new_full(PURPLE_STATUS_UNAVAILABLE, SILCPURPLE_STATUS_ID_BUSY, _("Busy"), TRUE, TRUE, FALSE);
- types = g_list_append(types, type);
- type = purple_status_type_new_full(PURPLE_STATUS_AWAY, SILCPURPLE_STATUS_ID_INDISPOSED, _("Indisposed"), TRUE, TRUE, FALSE);
- types = g_list_append(types, type);
- type = purple_status_type_new_full(PURPLE_STATUS_AWAY, SILCPURPLE_STATUS_ID_PAGE, _("Wake Me Up"), TRUE, TRUE, FALSE);
- types = g_list_append(types, type);
- type = purple_status_type_new_full(PURPLE_STATUS_OFFLINE, SILCPURPLE_STATUS_ID_OFFLINE, NULL, TRUE, TRUE, FALSE);
- types = g_list_append(types, type);
-
- return types;
-}
-
-static void
-silcpurple_set_status(PurpleAccount *account, PurpleStatus *status)
-{
- PurpleConnection *gc = purple_account_get_connection(account);
- SilcPurple sg = NULL;
- SilcUInt32 mode;
- SilcBuffer idp;
- unsigned char mb[4];
- const char *state;
-
- if (gc != NULL)
- sg = gc->proto_data;
-
- if (status == NULL)
- return;
-
- state = purple_status_get_id(status);
-
- if (state == NULL)
- return;
-
- if ((sg == NULL) || (sg->conn == NULL))
- return;
-
- mode = sg->conn->local_entry->mode;
- mode &= ~(SILC_UMODE_GONE |
- SILC_UMODE_HYPER |
- SILC_UMODE_BUSY |
- SILC_UMODE_INDISPOSED |
- SILC_UMODE_PAGE);
-
- if (!strcmp(state, "hyper"))
- mode |= SILC_UMODE_HYPER;
- else if (!strcmp(state, "away"))
- mode |= SILC_UMODE_GONE;
- else if (!strcmp(state, "busy"))
- mode |= SILC_UMODE_BUSY;
- else if (!strcmp(state, "indisposed"))
- mode |= SILC_UMODE_INDISPOSED;
- else if (!strcmp(state, "page"))
- mode |= SILC_UMODE_PAGE;
-
- /* Send UMODE */
- idp = silc_id_payload_encode(sg->conn->local_id, SILC_ID_CLIENT);
- SILC_PUT32_MSB(mode, mb);
- silc_client_command_send(sg->client, sg->conn, SILC_COMMAND_UMODE,
- ++sg->conn->cmd_ident, 2,
- 1, idp->data, idp->len,
- 2, mb, sizeof(mb));
- silc_buffer_free(idp);
-}
-
-
-/*************************** Connection Routines *****************************/
-
-static void
-silcpurple_keepalive(PurpleConnection *gc)
-{
- SilcPurple sg = gc->proto_data;
- silc_client_send_packet(sg->client, sg->conn, SILC_PACKET_HEARTBEAT,
- NULL, 0);
-}
-
-static gboolean
-silcpurple_scheduler(gpointer *context)
-{
- SilcPurple sg = (SilcPurple)context;
- silc_client_run_one(sg->client);
- return TRUE;
-}
-
-static void
-silcpurple_nickname_parse(const char *nickname,
- char **ret_nickname)
-{
- silc_parse_userfqdn(nickname, ret_nickname, NULL);
-}
-
-static void
-silcpurple_login_connected(gpointer data, gint source, const gchar *error_message)
-{
- PurpleConnection *gc = data;
- SilcPurple sg;
- SilcClient client;
- SilcClientConnection conn;
- PurpleAccount *account;
- SilcClientConnectionParams params;
- SilcUInt32 mask;
- const char *dfile, *tmp;
-#ifdef SILC_ATTRIBUTE_USER_ICON
- PurpleStoredImage *img;
-#endif
-#ifdef HAVE_SYS_UTSNAME_H
- struct utsname u;
-#endif
-
-
- g_return_if_fail(gc != NULL);
-
- sg = gc->proto_data;
-
- if (source < 0) {
- purple_connection_error_reason(gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Connection failed"));
- return;
- }
-
- client = sg->client;
- account = sg->account;
-
- /* Get session detachment data, if available */
- memset(&params, 0, sizeof(params));
- dfile = silcpurple_session_file(purple_account_get_username(sg->account));
- params.detach_data = (unsigned char *)silc_file_readfile(dfile, &params.detach_data_len);
- if (params.detach_data)
- params.detach_data[params.detach_data_len] = 0;
-
- /* Add connection to SILC client library */
- conn = silc_client_add_connection(
- sg->client, &params,
- (char *)purple_account_get_string(account, "server",
- "silc.silcnet.org"),
- purple_account_get_int(account, "port", 706), sg);
- if (!conn) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Unable to initialize SILC Client connection"));
- gc->proto_data = NULL;
- return;
- }
- sg->conn = conn;
-
- /* Progress */
- if (params.detach_data) {
- purple_connection_update_progress(gc, _("Resuming session"), 2, 5);
- sg->resuming = TRUE;
- } else {
- purple_connection_update_progress(gc, _("Performing key exchange"), 2, 5);
- }
-
- /* Perform SILC Key Exchange. The "silc_connected" will be called
- eventually. */
- silc_client_start_key_exchange(sg->client, sg->conn, source);
-
- /* Set default attributes */
- mask = SILC_ATTRIBUTE_MOOD_NORMAL;
- silc_client_attribute_add(client, conn,
- SILC_ATTRIBUTE_STATUS_MOOD,
- SILC_32_TO_PTR(mask),
- sizeof(SilcUInt32));
- mask = SILC_ATTRIBUTE_CONTACT_CHAT;
- silc_client_attribute_add(client, conn,
- SILC_ATTRIBUTE_PREFERRED_CONTACT,
- SILC_32_TO_PTR(mask),
- sizeof(SilcUInt32));
-#ifdef HAVE_SYS_UTSNAME_H
- if (!uname(&u)) {
- SilcAttributeObjDevice dev;
- memset(&dev, 0, sizeof(dev));
- dev.type = SILC_ATTRIBUTE_DEVICE_COMPUTER;
- dev.version = u.release;
- dev.model = u.sysname;
- silc_client_attribute_add(client, conn,
- SILC_ATTRIBUTE_DEVICE_INFO,
- (void *)&dev, sizeof(dev));
- }
-#endif
-#ifdef _WIN32
- tmp = _tzname[0];
-#else
- tmp = tzname[0];
-#endif
- silc_client_attribute_add(client, conn,
- SILC_ATTRIBUTE_TIMEZONE,
- (void *)tmp, strlen(tmp));
-
-#ifdef SILC_ATTRIBUTE_USER_ICON
- /* Set our buddy icon */
- img = purple_buddy_icons_find_account_icon(account);
- silcpurple_buddy_set_icon(gc, img);
- purple_imgstore_unref(img);
-#endif
-
- silc_free(params.detach_data);
-}
-
-static void
-silcpurple_login(PurpleAccount *account)
-{
- SilcPurple sg;
- SilcClient client;
- SilcClientParams params;
- PurpleConnection *gc;
- char pkd[256], prd[256];
- const char *cipher, *hmac;
- char *realname;
- int i;
-
- gc = account->gc;
- if (!gc)
- return;
- gc->proto_data = NULL;
-
- memset(&params, 0, sizeof(params));
- strcat(params.nickname_format, "%n@%h%a");
- params.nickname_parse = silcpurple_nickname_parse;
- params.ignore_requested_attributes = FALSE;
-
- /* Allocate SILC client */
- client = silc_client_alloc(&ops, &params, gc, NULL);
- if (!client) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
- _("Out of memory"));
- return;
- }
-
- /* Get username, real name and local hostname for SILC library */
- if (purple_account_get_username(account)) {
- const char *u = purple_account_get_username(account);
- char **up = g_strsplit(u, "@", 2);
- client->username = strdup(up[0]);
- g_strfreev(up);
- } else {
- client->username = silc_get_username();
- purple_account_set_username(account, client->username);
- }
- realname = silc_get_real_name();
- if (purple_account_get_user_info(account)) {
- client->realname = strdup(purple_account_get_user_info(account));
- free(realname);
- } else if ((silc_get_real_name() != NULL) && (*realname != '\0')) {
- client->realname = realname;
- purple_account_set_user_info(account, client->realname);
- } else {
- free(realname);
- client->realname = strdup(_("John Noname"));
- }
- client->hostname = silc_net_localhost();
-
- purple_connection_set_display_name(gc, client->username);
-
- /* Register requested cipher and HMAC */
- cipher = purple_account_get_string(account, "cipher", SILC_DEFAULT_CIPHER);
- for (i = 0; silc_default_ciphers[i].name; i++)
- if (!strcmp(silc_default_ciphers[i].name, cipher)) {
- silc_cipher_register(&(silc_default_ciphers[i]));
- break;
- }
- hmac = purple_account_get_string(account, "hmac", SILC_DEFAULT_HMAC);
- for (i = 0; silc_default_hmacs[i].name; i++)
- if (!strcmp(silc_default_hmacs[i].name, hmac)) {
- silc_hmac_register(&(silc_default_hmacs[i]));
- break;
- }
-
- /* Init SILC client */
- if (!silc_client_init(client)) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
- _("Unable to initialize SILC protocol"));
- return;
- }
-
- /* Check the ~/.silc dir and create it, and new key pair if necessary. */
- if (!silcpurple_check_silc_dir(gc)) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
- _("Error loading SILC key pair"));
- return;
- }
-
- /* Progress */
- purple_connection_update_progress(gc, _("Connecting to SILC Server"), 1, 5);
-
- /* Load SILC key pair */
- g_snprintf(pkd, sizeof(pkd), "%s" G_DIR_SEPARATOR_S "public_key.pub", silcpurple_silcdir());
- g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcpurple_silcdir());
- if (!silc_load_key_pair((char *)purple_account_get_string(account, "public-key", pkd),
- (char *)purple_account_get_string(account, "private-key", prd),
- (gc->password == NULL) ? "" : gc->password, &client->pkcs,
- &client->public_key, &client->private_key)) {
- g_snprintf(pkd, sizeof(pkd), _("Unable to load SILC key pair: %s"), g_strerror(errno));
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
- pkd);
- return;
- }
-
- sg = silc_calloc(1, sizeof(*sg));
- if (!sg)
- return;
- memset(sg, 0, sizeof(*sg));
- sg->client = client;
- sg->gc = gc;
- sg->account = account;
- gc->proto_data = sg;
-
- /* Connect to the SILC server */
- if (purple_proxy_connect(gc, account,
- purple_account_get_string(account, "server",
- "silc.silcnet.org"),
- purple_account_get_int(account, "port", 706),
- silcpurple_login_connected, gc) == NULL)
- {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Unable to create connection"));
- return;
- }
-
- /* Schedule SILC using Glib's event loop */
- sg->scheduler = purple_timeout_add(300, (GSourceFunc)silcpurple_scheduler, sg);
-}
-
-static int
-silcpurple_close_final(gpointer *context)
-{
- SilcPurple sg = (SilcPurple)context;
- silc_client_stop(sg->client);
- silc_client_free(sg->client);
-#ifdef HAVE_SILCMIME_H
- if (sg->mimeass)
- silc_mime_assembler_free(sg->mimeass);
-#endif
- silc_free(sg);
- return 0;
-}
-
-static void
-silcpurple_close(PurpleConnection *gc)
-{
- SilcPurple sg = gc->proto_data;
- GHashTable *ui_info;
- const char *ui_name = NULL, *ui_website = NULL;
- char *quit_msg;
-
- g_return_if_fail(sg != NULL);
-
- ui_info = purple_core_get_ui_info();
-
- if(ui_info) {
- ui_name = g_hash_table_lookup(ui_info, "name");
- ui_website = g_hash_table_lookup(ui_info, "website");
- }
-
- if(!ui_name || !ui_website) {
- ui_name = "Pidgin";
- ui_website = PURPLE_WEBSITE;
- }
- quit_msg = g_strdup_printf(_("Download %s: %s"),
- ui_name, ui_website);
-
- /* Send QUIT */
- silc_client_command_call(sg->client, sg->conn, NULL,
- "QUIT", quit_msg, NULL);
- g_free(quit_msg);
-
- if (sg->conn)
- silc_client_close_connection(sg->client, sg->conn);
-
- purple_timeout_remove(sg->scheduler);
- purple_timeout_add(1, (GSourceFunc)silcpurple_close_final, sg);
-}
-
-
-/****************************** Protocol Actions *****************************/
-
-static void
-silcpurple_attrs_cancel(PurpleConnection *gc, PurpleRequestFields *fields)
-{
- /* Nothing */
-}
-
-static void
-silcpurple_attrs_cb(PurpleConnection *gc, PurpleRequestFields *fields)
-{
- SilcPurple sg = gc->proto_data;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- PurpleRequestField *f;
- char *tmp;
- SilcUInt32 tmp_len, mask;
- SilcAttributeObjService service;
- SilcAttributeObjDevice dev;
- SilcVCardStruct vcard;
- const char *val;
-
- sg = gc->proto_data;
- if (!sg)
- return;
-
- memset(&service, 0, sizeof(service));
- memset(&dev, 0, sizeof(dev));
- memset(&vcard, 0, sizeof(vcard));
-
- silc_client_attribute_del(client, conn,
- SILC_ATTRIBUTE_USER_INFO, NULL);
- silc_client_attribute_del(client, conn,
- SILC_ATTRIBUTE_SERVICE, NULL);
- silc_client_attribute_del(client, conn,
- SILC_ATTRIBUTE_STATUS_MOOD, NULL);
- silc_client_attribute_del(client, conn,
- SILC_ATTRIBUTE_STATUS_FREETEXT, NULL);
- silc_client_attribute_del(client, conn,
- SILC_ATTRIBUTE_STATUS_MESSAGE, NULL);
- silc_client_attribute_del(client, conn,
- SILC_ATTRIBUTE_PREFERRED_LANGUAGE, NULL);
- silc_client_attribute_del(client, conn,
- SILC_ATTRIBUTE_PREFERRED_CONTACT, NULL);
- silc_client_attribute_del(client, conn,
- SILC_ATTRIBUTE_TIMEZONE, NULL);
- silc_client_attribute_del(client, conn,
- SILC_ATTRIBUTE_GEOLOCATION, NULL);
- silc_client_attribute_del(client, conn,
- SILC_ATTRIBUTE_DEVICE_INFO, NULL);
-
- /* Set mood */
- mask = 0;
- f = purple_request_fields_get_field(fields, "mood_normal");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_MOOD_NORMAL;
- f = purple_request_fields_get_field(fields, "mood_happy");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_MOOD_HAPPY;
- f = purple_request_fields_get_field(fields, "mood_sad");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_MOOD_SAD;
- f = purple_request_fields_get_field(fields, "mood_angry");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_MOOD_ANGRY;
- f = purple_request_fields_get_field(fields, "mood_jealous");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_MOOD_JEALOUS;
- f = purple_request_fields_get_field(fields, "mood_ashamed");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_MOOD_ASHAMED;
- f = purple_request_fields_get_field(fields, "mood_invincible");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_MOOD_INVINCIBLE;
- f = purple_request_fields_get_field(fields, "mood_inlove");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_MOOD_INLOVE;
- f = purple_request_fields_get_field(fields, "mood_sleepy");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_MOOD_SLEEPY;
- f = purple_request_fields_get_field(fields, "mood_bored");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_MOOD_BORED;
- f = purple_request_fields_get_field(fields, "mood_excited");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_MOOD_EXCITED;
- f = purple_request_fields_get_field(fields, "mood_anxious");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_MOOD_ANXIOUS;
- silc_client_attribute_add(client, conn,
- SILC_ATTRIBUTE_STATUS_MOOD,
- SILC_32_TO_PTR(mask),
- sizeof(SilcUInt32));
-
- /* Set preferred contact */
- mask = 0;
- f = purple_request_fields_get_field(fields, "contact_chat");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_CONTACT_CHAT;
- f = purple_request_fields_get_field(fields, "contact_email");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_CONTACT_EMAIL;
- f = purple_request_fields_get_field(fields, "contact_call");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_CONTACT_CALL;
- f = purple_request_fields_get_field(fields, "contact_sms");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_CONTACT_SMS;
- f = purple_request_fields_get_field(fields, "contact_mms");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_CONTACT_MMS;
- f = purple_request_fields_get_field(fields, "contact_video");
- if (f && purple_request_field_bool_get_value(f))
- mask |= SILC_ATTRIBUTE_CONTACT_VIDEO;
- if (mask)
- silc_client_attribute_add(client, conn,
- SILC_ATTRIBUTE_PREFERRED_CONTACT,
- SILC_32_TO_PTR(mask),
- sizeof(SilcUInt32));
-
- /* Set status text */
- val = NULL;
- f = purple_request_fields_get_field(fields, "status_text");
- if (f)
- val = purple_request_field_string_get_value(f);
- if (val && *val)
- silc_client_attribute_add(client, conn,
- SILC_ATTRIBUTE_STATUS_FREETEXT,
- (void *)val, strlen(val));
-
- /* Set vcard */
- val = NULL;
- f = purple_request_fields_get_field(fields, "vcard");
- if (f)
- val = purple_request_field_string_get_value(f);
- if (val && *val) {
- purple_account_set_string(sg->account, "vcard", val);
- tmp = silc_file_readfile(val, &tmp_len);
- if (tmp) {
- tmp[tmp_len] = 0;
- if (silc_vcard_decode((unsigned char *)tmp, tmp_len, &vcard))
- silc_client_attribute_add(client, conn,
- SILC_ATTRIBUTE_USER_INFO,
- (void *)&vcard,
- sizeof(vcard));
- }
- silc_vcard_free(&vcard);
- silc_free(tmp);
- } else {
- purple_account_set_string(sg->account, "vcard", "");
- }
-
-#ifdef HAVE_SYS_UTSNAME_H
- /* Set device info */
- f = purple_request_fields_get_field(fields, "device");
- if (f && purple_request_field_bool_get_value(f)) {
- struct utsname u;
- if (!uname(&u)) {
- dev.type = SILC_ATTRIBUTE_DEVICE_COMPUTER;
- dev.version = u.release;
- dev.model = u.sysname;
- silc_client_attribute_add(client, conn,
- SILC_ATTRIBUTE_DEVICE_INFO,
- (void *)&dev, sizeof(dev));
- }
- }
-#endif
-
- /* Set timezone */
- val = NULL;
- f = purple_request_fields_get_field(fields, "timezone");
- if (f)
- val = purple_request_field_string_get_value(f);
- if (val && *val)
- silc_client_attribute_add(client, conn,
- SILC_ATTRIBUTE_TIMEZONE,
- (void *)val, strlen(val));
-}
-
-static void
-silcpurple_attrs(PurplePluginAction *action)
-{
- PurpleConnection *gc = (PurpleConnection *) action->context;
- SilcPurple sg = gc->proto_data;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- PurpleRequestFields *fields;
- PurpleRequestFieldGroup *g;
- PurpleRequestField *f;
- SilcHashTable attrs;
- SilcAttributePayload attr;
- gboolean mnormal = TRUE, mhappy = FALSE, msad = FALSE,
- mangry = FALSE, mjealous = FALSE, mashamed = FALSE,
- minvincible = FALSE, minlove = FALSE, msleepy = FALSE,
- mbored = FALSE, mexcited = FALSE, manxious = FALSE;
- gboolean cemail = FALSE, ccall = FALSE, csms = FALSE,
- cmms = FALSE, cchat = TRUE, cvideo = FALSE;
- gboolean device = TRUE;
- char status[1024];
-
- sg = gc->proto_data;
- if (!sg)
- return;
-
- memset(status, 0, sizeof(status));
-
- attrs = silc_client_attributes_get(client, conn);
- if (attrs) {
- if (silc_hash_table_find(attrs,
- SILC_32_TO_PTR(SILC_ATTRIBUTE_STATUS_MOOD),
- NULL, (void *)&attr)) {
- SilcUInt32 mood = 0;
- silc_attribute_get_object(attr, &mood, sizeof(mood));
- mnormal = !mood;
- mhappy = (mood & SILC_ATTRIBUTE_MOOD_HAPPY);
- msad = (mood & SILC_ATTRIBUTE_MOOD_SAD);
- mangry = (mood & SILC_ATTRIBUTE_MOOD_ANGRY);
- mjealous = (mood & SILC_ATTRIBUTE_MOOD_JEALOUS);
- mashamed = (mood & SILC_ATTRIBUTE_MOOD_ASHAMED);
- minvincible = (mood & SILC_ATTRIBUTE_MOOD_INVINCIBLE);
- minlove = (mood & SILC_ATTRIBUTE_MOOD_INLOVE);
- msleepy = (mood & SILC_ATTRIBUTE_MOOD_SLEEPY);
- mbored = (mood & SILC_ATTRIBUTE_MOOD_BORED);
- mexcited = (mood & SILC_ATTRIBUTE_MOOD_EXCITED);
- manxious = (mood & SILC_ATTRIBUTE_MOOD_ANXIOUS);
- }
-
- if (silc_hash_table_find(attrs,
- SILC_32_TO_PTR(SILC_ATTRIBUTE_PREFERRED_CONTACT),
- NULL, (void *)&attr)) {
- SilcUInt32 contact = 0;
- silc_attribute_get_object(attr, &contact, sizeof(contact));
- cemail = (contact & SILC_ATTRIBUTE_CONTACT_EMAIL);
- ccall = (contact & SILC_ATTRIBUTE_CONTACT_CALL);
- csms = (contact & SILC_ATTRIBUTE_CONTACT_SMS);
- cmms = (contact & SILC_ATTRIBUTE_CONTACT_MMS);
- cchat = (contact & SILC_ATTRIBUTE_CONTACT_CHAT);
- cvideo = (contact & SILC_ATTRIBUTE_CONTACT_VIDEO);
- }
-
- if (silc_hash_table_find(attrs,
- SILC_32_TO_PTR(SILC_ATTRIBUTE_STATUS_FREETEXT),
- NULL, (void *)&attr))
- silc_attribute_get_object(attr, &status, sizeof(status));
-
- if (!silc_hash_table_find(attrs,
- SILC_32_TO_PTR(SILC_ATTRIBUTE_DEVICE_INFO),
- NULL, (void *)&attr))
- device = FALSE;
- }
-
- fields = purple_request_fields_new();
-
- g = purple_request_field_group_new(NULL);
- f = purple_request_field_label_new("l3", _("Your Current Mood"));
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("mood_normal", _("Normal"), mnormal);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("mood_happy", _("Happy"), mhappy);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("mood_sad", _("Sad"), msad);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("mood_angry", _("Angry"), mangry);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("mood_jealous", _("Jealous"), mjealous);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("mood_ashamed", _("Ashamed"), mashamed);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("mood_invincible", _("Invincible"), minvincible);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("mood_inlove", _("In love"), minlove);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("mood_sleepy", _("Sleepy"), msleepy);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("mood_bored", _("Bored"), mbored);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("mood_excited", _("Excited"), mexcited);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("mood_anxious", _("Anxious"), manxious);
- purple_request_field_group_add_field(g, f);
-
- f = purple_request_field_label_new("l4", _("\nYour Preferred Contact Methods"));
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("contact_chat", _("Chat"), cchat);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("contact_email", _("Email"), cemail);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("contact_call", _("Phone"), ccall);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("contact_sms", _("SMS"), csms);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("contact_mms", _("MMS"), cmms);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("contact_video", _("Video conferencing"), cvideo);
- purple_request_field_group_add_field(g, f);
- purple_request_fields_add_group(fields, g);
-
- g = purple_request_field_group_new(NULL);
- f = purple_request_field_string_new("status_text", _("Your Current Status"),
- status[0] ? status : NULL, TRUE);
- purple_request_field_group_add_field(g, f);
- purple_request_fields_add_group(fields, g);
-
- g = purple_request_field_group_new(NULL);
-#if 0
- f = purple_request_field_label_new("l2", _("Online Services"));
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_bool_new("services",
- _("Let others see what services you are using"),
- TRUE);
- purple_request_field_group_add_field(g, f);
-#endif
-#ifdef HAVE_SYS_UTSNAME_H
- f = purple_request_field_bool_new("device",
- _("Let others see what computer you are using"),
- device);
- purple_request_field_group_add_field(g, f);
-#endif
- purple_request_fields_add_group(fields, g);
-
- g = purple_request_field_group_new(NULL);
- f = purple_request_field_string_new("vcard", _("Your VCard File"),
- purple_account_get_string(sg->account, "vcard", ""),
- FALSE);
- purple_request_field_group_add_field(g, f);
-#ifdef _WIN32
- f = purple_request_field_string_new("timezone", _("Timezone"), _tzname[0], FALSE);
-#else
- f = purple_request_field_string_new("timezone", _("Timezone"), tzname[0], FALSE);
-#endif
- purple_request_field_group_add_field(g, f);
- purple_request_fields_add_group(fields, g);
-
- purple_request_fields(gc, _("User Online Status Attributes"),
- _("User Online Status Attributes"),
- _("You can let other users see your online status information "
- "and your personal information. Please fill the information "
- "you would like other users to see about yourself."),
- fields,
- _("OK"), G_CALLBACK(silcpurple_attrs_cb),
- _("Cancel"), G_CALLBACK(silcpurple_attrs_cancel),
- gc->account, NULL, NULL, gc);
-}
-
-static void
-silcpurple_detach(PurplePluginAction *action)
-{
- PurpleConnection *gc = (PurpleConnection *) action->context;
- SilcPurple sg;
-
- if (!gc)
- return;
- sg = gc->proto_data;
- if (!sg)
- return;
-
- /* Call DETACH */
- silc_client_command_call(sg->client, sg->conn, "DETACH");
- sg->detaching = TRUE;
-}
-
-static void
-silcpurple_view_motd(PurplePluginAction *action)
-{
- PurpleConnection *gc = (PurpleConnection *) action->context;
- SilcPurple sg;
- char *tmp;
-
- if (!gc)
- return;
- sg = gc->proto_data;
- if (!sg)
- return;
-
- if (!sg->motd) {
- purple_notify_error(
- gc, _("Message of the Day"), _("No Message of the Day available"),
- _("There is no Message of the Day associated with this connection"));
- return;
- }
-
- tmp = g_markup_escape_text(sg->motd, -1);
- purple_notify_formatted(gc, NULL, _("Message of the Day"), NULL,
- tmp, NULL, NULL);
- g_free(tmp);
-}
-
-static void
-silcpurple_create_keypair_cancel(PurpleConnection *gc, PurpleRequestFields *fields)
-{
- /* Nothing */
-}
-
-static void
-silcpurple_create_keypair_cb(PurpleConnection *gc, PurpleRequestFields *fields)
-{
- SilcPurple sg = gc->proto_data;
- PurpleRequestField *f;
- const char *val, *pkfile = NULL, *prfile = NULL;
- const char *pass1 = NULL, *pass2 = NULL, *un = NULL, *hn = NULL;
- const char *rn = NULL, *e = NULL, *o = NULL, *c = NULL;
- char *identifier;
- int keylen = SILCPURPLE_DEF_PKCS_LEN;
- SilcPublicKey public_key;
-
- sg = gc->proto_data;
- if (!sg)
- return;
-
- val = NULL;
- f = purple_request_fields_get_field(fields, "pass1");
- if (f)
- val = purple_request_field_string_get_value(f);
- if (val && *val)
- pass1 = val;
- else
- pass1 = "";
- val = NULL;
- f = purple_request_fields_get_field(fields, "pass2");
- if (f)
- val = purple_request_field_string_get_value(f);
- if (val && *val)
- pass2 = val;
- else
- pass2 = "";
-
- if (strcmp(pass1, pass2)) {
- purple_notify_error(
- gc, _("Create New SILC Key Pair"), _("Passphrases do not match"), NULL);
- return;
- }
-
- val = NULL;
- f = purple_request_fields_get_field(fields, "key");
- if (f)
- val = purple_request_field_string_get_value(f);
- if (val && *val)
- keylen = atoi(val);
- f = purple_request_fields_get_field(fields, "pkfile");
- if (f)
- pkfile = purple_request_field_string_get_value(f);
- f = purple_request_fields_get_field(fields, "prfile");
- if (f)
- prfile = purple_request_field_string_get_value(f);
-
- f = purple_request_fields_get_field(fields, "un");
- if (f)
- un = purple_request_field_string_get_value(f);
- f = purple_request_fields_get_field(fields, "hn");
- if (f)
- hn = purple_request_field_string_get_value(f);
- f = purple_request_fields_get_field(fields, "rn");
- if (f)
- rn = purple_request_field_string_get_value(f);
- f = purple_request_fields_get_field(fields, "e");
- if (f)
- e = purple_request_field_string_get_value(f);
- f = purple_request_fields_get_field(fields, "o");
- if (f)
- o = purple_request_field_string_get_value(f);
- f = purple_request_fields_get_field(fields, "c");
- if (f)
- c = purple_request_field_string_get_value(f);
-
- identifier = silc_pkcs_encode_identifier((char *)un, (char *)hn,
- (char *)rn, (char *)e, (char *)o, (char *)c);
-
- /* Create the key pair */
- if (!silc_create_key_pair(SILCPURPLE_DEF_PKCS, keylen, pkfile, prfile,
- identifier, pass1, NULL, &public_key, NULL,
- FALSE)) {
- purple_notify_error(
- gc, _("Create New SILC Key Pair"), _("Key Pair Generation failed"), NULL);
- return;
- }
-
- silcpurple_show_public_key(sg, NULL, public_key, NULL, NULL);
-
- silc_pkcs_public_key_free(public_key);
- silc_free(identifier);
-}
-
-static void
-silcpurple_create_keypair(PurplePluginAction *action)
-{
- PurpleConnection *gc = (PurpleConnection *) action->context;
- SilcPurple sg = gc->proto_data;
- PurpleRequestFields *fields;
- PurpleRequestFieldGroup *g;
- PurpleRequestField *f;
- const char *username, *realname;
- char *hostname, **u;
- char tmp[256], pkd[256], pkd2[256], prd[256], prd2[256];
-
- username = purple_account_get_username(sg->account);
- u = g_strsplit(username, "@", 2);
- username = u[0];
- realname = purple_account_get_user_info(sg->account);
- hostname = silc_net_localhost();
- g_snprintf(tmp, sizeof(tmp), "%s@%s", username, hostname);
-
- g_snprintf(pkd2, sizeof(pkd2), "%s" G_DIR_SEPARATOR_S"public_key.pub", silcpurple_silcdir());
- g_snprintf(prd2, sizeof(prd2), "%s" G_DIR_SEPARATOR_S"private_key.prv", silcpurple_silcdir());
- g_snprintf(pkd, sizeof(pkd) - 1, "%s",
- purple_account_get_string(gc->account, "public-key", pkd2));
- g_snprintf(prd, sizeof(prd) - 1, "%s",
- purple_account_get_string(gc->account, "private-key", prd2));
-
- fields = purple_request_fields_new();
-
- g = purple_request_field_group_new(NULL);
- f = purple_request_field_string_new("key", _("Key length"), "2048", FALSE);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_string_new("pkfile", _("Public key file"), pkd, FALSE);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_string_new("prfile", _("Private key file"), prd, FALSE);
- purple_request_field_group_add_field(g, f);
- purple_request_fields_add_group(fields, g);
-
- g = purple_request_field_group_new(NULL);
- f = purple_request_field_string_new("un", _("Username"), username ? username : "", FALSE);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_string_new("hn", _("Hostname"), hostname ? hostname : "", FALSE);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_string_new("rn", _("Real name"), realname ? realname : "", FALSE);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_string_new("e", _("Email"), tmp, FALSE);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_string_new("o", _("Organization"), "", FALSE);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_string_new("c", _("Country"), "", FALSE);
- purple_request_field_group_add_field(g, f);
- purple_request_fields_add_group(fields, g);
-
- g = purple_request_field_group_new(NULL);
- f = purple_request_field_string_new("pass1", _("Passphrase"), "", FALSE);
- purple_request_field_string_set_masked(f, TRUE);
- purple_request_field_group_add_field(g, f);
- f = purple_request_field_string_new("pass2", _("Passphrase (retype)"), "", FALSE);
- purple_request_field_string_set_masked(f, TRUE);
- purple_request_field_group_add_field(g, f);
- purple_request_fields_add_group(fields, g);
-
- purple_request_fields(gc, _("Create New SILC Key Pair"),
- _("Create New SILC Key Pair"), NULL, fields,
- _("Generate Key Pair"), G_CALLBACK(silcpurple_create_keypair_cb),
- _("Cancel"), G_CALLBACK(silcpurple_create_keypair_cancel),
- gc->account, NULL, NULL, gc);
-
- g_strfreev(u);
- silc_free(hostname);
-}
-
-static void
-silcpurple_change_pass(PurplePluginAction *action)
-{
- PurpleConnection *gc = (PurpleConnection *) action->context;
- purple_account_request_change_password(purple_connection_get_account(gc));
-}
-
-static void
-silcpurple_change_passwd(PurpleConnection *gc, const char *old, const char *new)
-{
- char prd[256];
- g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.pub", silcpurple_silcdir());
- silc_change_private_key_passphrase(purple_account_get_string(gc->account,
- "private-key",
- prd), old ? old : "", new ? new : "");
-}
-
-static void
-silcpurple_show_set_info(PurplePluginAction *action)
-{
- PurpleConnection *gc = (PurpleConnection *) action->context;
- purple_account_request_change_user_info(purple_connection_get_account(gc));
-}
-
-static void
-silcpurple_set_info(PurpleConnection *gc, const char *text)
-{
-}
-
-static GList *
-silcpurple_actions(PurplePlugin *plugin, gpointer context)
-{
- GList *list = NULL;
- PurplePluginAction *act;
-
- act = purple_plugin_action_new(_("Online Status"),
- silcpurple_attrs);
- list = g_list_append(list, act);
-
- act = purple_plugin_action_new(_("Detach From Server"),
- silcpurple_detach);
- list = g_list_append(list, act);
-
- act = purple_plugin_action_new(_("View Message of the Day"),
- silcpurple_view_motd);
- list = g_list_append(list, act);
-
- act = purple_plugin_action_new(_("Create SILC Key Pair..."),
- silcpurple_create_keypair);
- list = g_list_append(list, act);
-
- act = purple_plugin_action_new(_("Change Password..."),
- silcpurple_change_pass);
- list = g_list_append(list, act);
-
- act = purple_plugin_action_new(_("Set User Info..."),
- silcpurple_show_set_info);
- list = g_list_append(list, act);
-
- return list;
-}
-
-
-/******************************* IM Routines *********************************/
-
-typedef struct {
- char *nick;
- char *message;
- SilcUInt32 message_len;
- SilcMessageFlags flags;
- PurpleMessageFlags gflags;
-} *SilcPurpleIM;
-
-static void
-silcpurple_send_im_resolved(SilcClient client,
- SilcClientConnection conn,
- SilcClientEntry *clients,
- SilcUInt32 clients_count,
- void *context)
-{
- PurpleConnection *gc = client->application;
- SilcPurple sg = gc->proto_data;
- SilcPurpleIM im = context;
- PurpleConversation *convo;
- char tmp[256], *nickname = NULL;
- SilcClientEntry client_entry;
-#ifdef HAVE_SILCMIME_H
- SilcDList list;
-#endif
-
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, im->nick,
- sg->account);
- if (!convo)
- return;
-
- if (!clients)
- goto err;
-
- if (clients_count > 1) {
- silc_parse_userfqdn(im->nick, &nickname, NULL);
-
- /* Find the correct one. The im->nick might be a formatted nick
- so this will find the correct one. */
- clients = silc_client_get_clients_local(client, conn,
- nickname, im->nick,
- &clients_count);
- if (!clients)
- goto err;
- client_entry = clients[0];
- silc_free(clients);
- } else {
- client_entry = clients[0];
- }
-
-#ifdef HAVE_SILCMIME_H
- /* Check for images */
- if (im->gflags & PURPLE_MESSAGE_IMAGES) {
- list = silcpurple_image_message(im->message, (SilcUInt32 *)&im->flags);
- if (list) {
- /* Send one or more MIME message. If more than one, they
- are MIME fragments due to over large message */
- SilcBuffer buf;
-
- silc_dlist_start(list);
- while ((buf = silc_dlist_get(list)) != SILC_LIST_END)
- silc_client_send_private_message(client, conn,
- client_entry, im->flags,
- buf->data, buf->len,
- TRUE);
- silc_mime_partial_free(list);
- purple_conv_im_write(PURPLE_CONV_IM(convo), conn->local_entry->nickname,
- im->message, 0, time(NULL));
- goto out;
- }
- }
-#endif
-
- /* Send the message */
- silc_client_send_private_message(client, conn, client_entry, im->flags,
- (unsigned char *)im->message, im->message_len, TRUE);
- purple_conv_im_write(PURPLE_CONV_IM(convo), conn->local_entry->nickname,
- im->message, 0, time(NULL));
- goto out;
-
- err:
- g_snprintf(tmp, sizeof(tmp),
- _("User <I>%s</I> is not present in the network"), im->nick);
- purple_conversation_write(convo, NULL, tmp, PURPLE_MESSAGE_SYSTEM, time(NULL));
-
- out:
- g_free(im->nick);
- g_free(im->message);
- silc_free(im);
- silc_free(nickname);
-}
-
-static int
-silcpurple_send_im(PurpleConnection *gc, const char *who, const char *message,
- PurpleMessageFlags flags)
-{
- SilcPurple sg = gc->proto_data;
- SilcClient client = sg->client;
- SilcClientConnection conn = sg->conn;
- SilcClientEntry *clients;
- SilcUInt32 clients_count, mflags;
- char *nickname, *msg, *tmp;
- int ret = 0;
- gboolean sign = purple_account_get_bool(sg->account, "sign-verify", FALSE);
-#ifdef HAVE_SILCMIME_H
- SilcDList list;
-#endif
-
- if (!who || !message)
- return 0;
-
- mflags = SILC_MESSAGE_FLAG_UTF8;
-
- tmp = msg = purple_unescape_html(message);
-
- if (!g_ascii_strncasecmp(msg, "/me ", 4)) {
- msg += 4;
- if (!*msg) {
- g_free(tmp);
- return 0;
- }
- mflags |= SILC_MESSAGE_FLAG_ACTION;
- } else if (strlen(msg) > 1 && msg[0] == '/') {
- if (!silc_client_command_call(client, conn, msg + 1))
- purple_notify_error(gc, _("Call Command"), _("Cannot call command"),
- _("Unknown command"));
- g_free(tmp);
- return 0;
- }
-
-
- if (!silc_parse_userfqdn(who, &nickname, NULL)) {
- g_free(tmp);
- return 0;
- }
-
- if (sign)
- mflags |= SILC_MESSAGE_FLAG_SIGNED;
-
- /* Find client entry */
- clients = silc_client_get_clients_local(client, conn, nickname, who,
- &clients_count);
- if (!clients) {
- /* Resolve unknown user */
- SilcPurpleIM im = silc_calloc(1, sizeof(*im));
- if (!im) {
- g_free(tmp);
- return 0;
- }
- im->nick = g_strdup(who);
- im->message = g_strdup(message);
- im->message_len = strlen(im->message);
- im->flags = mflags;
- im->gflags = flags;
- silc_client_get_clients(client, conn, nickname, NULL,
- silcpurple_send_im_resolved, im);
- silc_free(nickname);
- g_free(tmp);
- return 0;
- }
-
-#ifdef HAVE_SILCMIME_H
- /* Check for images */
- if (flags & PURPLE_MESSAGE_IMAGES) {
- list = silcpurple_image_message(message, &mflags);
- if (list) {
- /* Send one or more MIME message. If more than one, they
- are MIME fragments due to over large message */
- SilcBuffer buf;
-
- silc_dlist_start(list);
- while ((buf = silc_dlist_get(list)) != SILC_LIST_END)
- ret =
- silc_client_send_private_message(client, conn,
- clients[0], mflags,
- buf->data, buf->len,
- TRUE);
- silc_mime_partial_free(list);
- g_free(tmp);
- silc_free(nickname);
- silc_free(clients);
- return ret;
- }
- }
-#endif
-
- /* Send private message directly */
- ret = silc_client_send_private_message(client, conn, clients[0],
- mflags,
- (unsigned char *)msg,
- strlen(msg), TRUE);
-
- g_free(tmp);
- silc_free(nickname);
- silc_free(clients);
- return ret;
-}
-
-
-static GList *silcpurple_blist_node_menu(PurpleBlistNode *node) {
- /* split this single menu building function back into the two
- original: one for buddies and one for chats */
-
- if(PURPLE_BLIST_NODE_IS_CHAT(node)) {
- return silcpurple_chat_menu((PurpleChat *) node);
- } else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
- return silcpurple_buddy_menu((PurpleBuddy *) node);
- } else {
- g_return_val_if_reached(NULL);
- }
-}
-
-/********************************* Commands **********************************/
-
-static PurpleCmdRet silcpurple_cmd_chat_part(PurpleConversation *conv,
- const char *cmd, char **args, char **error, void *data)
-{
- PurpleConnection *gc;
- PurpleConversation *convo = conv;
- int id = 0;
-
- gc = purple_conversation_get_gc(conv);
-
- if (gc == NULL)
- return PURPLE_CMD_RET_FAILED;
-
- if(args && args[0])
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[0],
- gc->account);
-
- if (convo != NULL)
- id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo));
-
- if (id == 0)
- return PURPLE_CMD_RET_FAILED;
-
- silcpurple_chat_leave(gc, id);
-
- return PURPLE_CMD_RET_OK;
-
-}
-
-static PurpleCmdRet silcpurple_cmd_chat_topic(PurpleConversation *conv,
- const char *cmd, char **args, char **error, void *data)
-{
- PurpleConnection *gc;
- int id = 0;
- char *buf, *tmp, *tmp2;
- const char *topic;
-
- gc = purple_conversation_get_gc(conv);
- id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv));
-
- if (gc == NULL || id == 0)
- return PURPLE_CMD_RET_FAILED;
-
- if (!args || !args[0]) {
- topic = purple_conv_chat_get_topic (PURPLE_CONV_CHAT(conv));
- if (topic) {
- tmp = g_markup_escape_text(topic, -1);
- tmp2 = purple_markup_linkify(tmp);
- buf = g_strdup_printf(_("current topic is: %s"), tmp2);
- g_free(tmp);
- g_free(tmp2);
- } else
- buf = g_strdup(_("No topic is set"));
- purple_conv_chat_write(PURPLE_CONV_CHAT(conv), gc->account->username, buf,
- PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
- g_free(buf);
-
- }
-
- if (args && args[0] && (strlen(args[0]) > 255)) {
- *error = g_strdup(_("Topic too long"));
- return PURPLE_CMD_RET_FAILED;
- }
-
- silcpurple_chat_set_topic(gc, id, args ? args[0] : NULL);
-
- return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_chat_join(PurpleConversation *conv,
- const char *cmd, char **args, char **error, void *data)
-{
- GHashTable *comp;
-
- if(!args || !args[0])
- return PURPLE_CMD_RET_FAILED;
-
- comp = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
-
- g_hash_table_replace(comp, "channel", args[0]);
- if(args[1])
- g_hash_table_replace(comp, "passphrase", args[1]);
-
- silcpurple_chat_join(purple_conversation_get_gc(conv), comp);
-
- g_hash_table_destroy(comp);
- return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_chat_list(PurpleConversation *conv,
- const char *cmd, char **args, char **error, void *data)
-{
- PurpleConnection *gc;
- gc = purple_conversation_get_gc(conv);
- purple_roomlist_show_with_account(purple_connection_get_account(gc));
- return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_whois(PurpleConversation *conv,
- const char *cmd, char **args, char **error, void *data)
-{
- PurpleConnection *gc;
-
- gc = purple_conversation_get_gc(conv);
-
- if (gc == NULL)
- return PURPLE_CMD_RET_FAILED;
-
- silcpurple_get_info(gc, args[0]);
-
- return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_msg(PurpleConversation *conv,
- const char *cmd, char **args, char **error, void *data)
-{
- int ret;
- PurpleConnection *gc;
-
- gc = purple_conversation_get_gc(conv);
-
- if (gc == NULL)
- return PURPLE_CMD_RET_FAILED;
-
- ret = silcpurple_send_im(gc, args[0], args[1], PURPLE_MESSAGE_SEND);
-
- if (ret)
- return PURPLE_CMD_RET_OK;
- else
- return PURPLE_CMD_RET_FAILED;
-}
-
-static PurpleCmdRet silcpurple_cmd_query(PurpleConversation *conv,
- const char *cmd, char **args, char **error, void *data)
-{
- int ret = 1;
- PurpleConversation *convo;
- PurpleConnection *gc;
- PurpleAccount *account;
-
- if (!args || !args[0]) {
- *error = g_strdup(_("You must specify a nick"));
- return PURPLE_CMD_RET_FAILED;
- }
-
- gc = purple_conversation_get_gc(conv);
-
- if (gc == NULL)
- return PURPLE_CMD_RET_FAILED;
-
- account = purple_connection_get_account(gc);
-
- convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, args[0]);
-
- if (args[1]) {
- ret = silcpurple_send_im(gc, args[0], args[1], PURPLE_MESSAGE_SEND);
- purple_conv_im_write(PURPLE_CONV_IM(convo), purple_connection_get_display_name(gc),
- args[1], PURPLE_MESSAGE_SEND, time(NULL));
- }
-
- if (ret)
- return PURPLE_CMD_RET_OK;
- else
- return PURPLE_CMD_RET_FAILED;
-}
-
-static PurpleCmdRet silcpurple_cmd_motd(PurpleConversation *conv,
- const char *cmd, char **args, char **error, void *data)
-{
- PurpleConnection *gc;
- SilcPurple sg;
- char *tmp;
-
- gc = purple_conversation_get_gc(conv);
-
- if (gc == NULL)
- return PURPLE_CMD_RET_FAILED;
-
- sg = gc->proto_data;
-
- if (sg == NULL)
- return PURPLE_CMD_RET_FAILED;
-
- if (!sg->motd) {
- *error = g_strdup(_("There is no Message of the Day associated with this connection"));
- return PURPLE_CMD_RET_FAILED;
- }
-
- tmp = g_markup_escape_text(sg->motd, -1);
- purple_notify_formatted(gc, NULL, _("Message of the Day"), NULL,
- tmp, NULL, NULL);
- g_free(tmp);
-
- return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_detach(PurpleConversation *conv,
- const char *cmd, char **args, char **error, void *data)
-{
- PurpleConnection *gc;
- SilcPurple sg;
-
- gc = purple_conversation_get_gc(conv);
-
- if (gc == NULL)
- return PURPLE_CMD_RET_FAILED;
-
- sg = gc->proto_data;
-
- if (sg == NULL)
- return PURPLE_CMD_RET_FAILED;
-
- silc_client_command_call(sg->client, sg->conn, "DETACH");
- sg->detaching = TRUE;
-
- return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_cmode(PurpleConversation *conv,
- const char *cmd, char **args, char **error, void *data)
-{
- PurpleConnection *gc;
- SilcPurple sg;
- SilcChannelEntry channel;
- char *silccmd, *silcargs, *msg, tmp[256];
- const char *chname;
-
- gc = purple_conversation_get_gc(conv);
-
- if (gc == NULL || !args || gc->proto_data == NULL)
- return PURPLE_CMD_RET_FAILED;
-
- sg = gc->proto_data;
-
- if (args[0])
- chname = args[0];
- else
- chname = purple_conversation_get_name(conv);
-
- if (!args[1]) {
- channel = silc_client_get_channel(sg->client, sg->conn,
- (char *)chname);
- if (!channel) {
- *error = g_strdup_printf(_("channel %s not found"), chname);
- return PURPLE_CMD_RET_FAILED;
- }
- if (channel->mode) {
- silcpurple_get_chmode_string(channel->mode, tmp, sizeof(tmp));
- msg = g_strdup_printf(_("channel modes for %s: %s"), chname, tmp);
- } else {
- msg = g_strdup_printf(_("no channel modes are set on %s"), chname);
- }
- purple_conv_chat_write(PURPLE_CONV_CHAT(conv), "",
- msg, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
- g_free(msg);
- return PURPLE_CMD_RET_OK;
- }
-
- silcargs = g_strjoinv(" ", args);
- silccmd = g_strconcat(cmd, " ", args ? silcargs : NULL, NULL);
- g_free(silcargs);
- if (!silc_client_command_call(sg->client, sg->conn, silccmd)) {
- g_free(silccmd);
- *error = g_strdup_printf(_("Failed to set cmodes for %s"), args[0]);
- return PURPLE_CMD_RET_FAILED;
- }
- g_free(silccmd);
-
- return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_generic(PurpleConversation *conv,
- const char *cmd, char **args, char **error, void *data)
-{
- PurpleConnection *gc;
- SilcPurple sg;
- char *silccmd, *silcargs;
-
- gc = purple_conversation_get_gc(conv);
-
- if (gc == NULL)
- return PURPLE_CMD_RET_FAILED;
-
- sg = gc->proto_data;
-
- if (sg == NULL)
- return PURPLE_CMD_RET_FAILED;
-
- silcargs = g_strjoinv(" ", args);
- silccmd = g_strconcat(cmd, " ", args ? silcargs : NULL, NULL);
- g_free(silcargs);
- if (!silc_client_command_call(sg->client, sg->conn, silccmd)) {
- g_free(silccmd);
- *error = g_strdup_printf(_("Unknown command: %s, (may be a client bug)"), cmd);
- return PURPLE_CMD_RET_FAILED;
- }
- g_free(silccmd);
-
- return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_quit(PurpleConversation *conv,
- const char *cmd, char **args, char **error, void *data)
-{
- PurpleConnection *gc;
- SilcPurple sg;
- GHashTable *ui_info;
- const char *ui_name = NULL, *ui_website = NULL;
- char *quit_msg;
-
- gc = purple_conversation_get_gc(conv);
-
- if (gc == NULL)
- return PURPLE_CMD_RET_FAILED;
-
- sg = gc->proto_data;
-
- if (sg == NULL)
- return PURPLE_CMD_RET_FAILED;
-
- ui_info = purple_core_get_ui_info();
-
- if(ui_info) {
- ui_name = g_hash_table_lookup(ui_info, "name");
- ui_website = g_hash_table_lookup(ui_info, "website");
- }
-
- if(!ui_name || !ui_website) {
- ui_name = "Pidgin";
- ui_website = PURPLE_WEBSITE;
- }
- quit_msg = g_strdup_printf(_("Download %s: %s"),
- ui_name, ui_website);
-
- silc_client_command_call(sg->client, sg->conn, NULL,
- "QUIT", (args && args[0]) ? args[0] : quit_msg, NULL);
- g_free(quit_msg);
-
- return PURPLE_CMD_RET_OK;
-}
-
-static PurpleCmdRet silcpurple_cmd_call(PurpleConversation *conv,
- const char *cmd, char **args, char **error, void *data)
-{
- PurpleConnection *gc;
- SilcPurple sg;
-
- gc = purple_conversation_get_gc(conv);
-
- if (gc == NULL)
- return PURPLE_CMD_RET_FAILED;
-
- sg = gc->proto_data;
-
- if (sg == NULL)
- return PURPLE_CMD_RET_FAILED;
-
- if (!silc_client_command_call(sg->client, sg->conn, args[0])) {
- *error = g_strdup_printf(_("Unknown command: %s"), args[0]);
- return PURPLE_CMD_RET_FAILED;
- }
-
- return PURPLE_CMD_RET_OK;
-}
-
-
-/************************** Plugin Initialization ****************************/
-
-static void
-silcpurple_register_commands(void)
-{
- purple_cmd_register("part", "w", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT |
- PURPLE_CMD_FLAG_PRPL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS,
- "prpl-silc", silcpurple_cmd_chat_part, _("part [channel]: Leave the chat"), NULL);
- purple_cmd_register("leave", "w", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT |
- PURPLE_CMD_FLAG_PRPL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS,
- "prpl-silc", silcpurple_cmd_chat_part, _("leave [channel]: Leave the chat"), NULL);
- purple_cmd_register("topic", "s", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
- PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc",
- silcpurple_cmd_chat_topic, _("topic [&lt;new topic&gt;]: View or change the topic"), NULL);
- purple_cmd_register("join", "ws", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT |
- PURPLE_CMD_FLAG_PRPL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS,
- "prpl-silc", silcpurple_cmd_chat_join,
- _("join &lt;channel&gt; [&lt;password&gt;]: Join a chat on this network"), NULL);
- purple_cmd_register("list", "", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
- PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc",
- silcpurple_cmd_chat_list, _("list: List channels on this network"), NULL);
- purple_cmd_register("whois", "w", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-silc",
- silcpurple_cmd_whois, _("whois &lt;nick&gt;: View nick's information"), NULL);
- purple_cmd_register("msg", "ws", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-silc", silcpurple_cmd_msg,
- _("msg &lt;nick&gt; &lt;message&gt;: Send a private message to a user"), NULL);
- purple_cmd_register("query", "ws", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
- PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_query,
- _("query &lt;nick&gt; [&lt;message&gt;]: Send a private message to a user"), NULL);
- purple_cmd_register("motd", "", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
- PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_motd,
- _("motd: View the server's Message Of The Day"), NULL);
- purple_cmd_register("detach", "", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-silc", silcpurple_cmd_detach,
- _("detach: Detach this session"), NULL);
- purple_cmd_register("quit", "s", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
- PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_quit,
- _("quit [message]: Disconnect from the server, with an optional message"), NULL);
- purple_cmd_register("call", "s", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-silc", silcpurple_cmd_call,
- _("call &lt;command&gt;: Call any silc client command"), NULL);
- /* These below just get passed through for the silc client library to deal
- * with */
- purple_cmd_register("kill", "ws", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
- PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic,
- _("kill &lt;nick&gt; [-pubkey|&lt;reason&gt;]: Kill nick"), NULL);
- purple_cmd_register("nick", "w", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-silc", silcpurple_cmd_generic,
- _("nick &lt;newnick&gt;: Change your nickname"), NULL);
- purple_cmd_register("whowas", "ww", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
- PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic,
- _("whowas &lt;nick&gt;: View nick's information"), NULL);
- purple_cmd_register("cmode", "wws", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
- PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_cmode,
- _("cmode &lt;channel&gt; [+|-&lt;modes&gt;] [arguments]: Change or display channel modes"), NULL);
- purple_cmd_register("cumode", "wws", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
- PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic,
- _("cumode &lt;channel&gt; +|-&lt;modes&gt; &lt;nick&gt;: Change nick's modes on channel"), NULL);
- purple_cmd_register("umode", "w", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-silc", silcpurple_cmd_generic,
- _("umode &lt;usermodes&gt;: Set your modes in the network"), NULL);
- purple_cmd_register("oper", "s", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-silc", silcpurple_cmd_generic,
- _("oper &lt;nick&gt; [-pubkey]: Get server operator privileges"), NULL);
- purple_cmd_register("invite", "ws", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
- PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic,
- _("invite &lt;channel&gt; [-|+]&lt;nick&gt;: invite nick or add/remove from channel invite list"), NULL);
- purple_cmd_register("kick", "wws", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
- PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic,
- _("kick &lt;channel&gt; &lt;nick&gt; [comment]: Kick client from channel"), NULL);
- purple_cmd_register("info", "w", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
- PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic,
- _("info [server]: View server administrative details"), NULL);
- purple_cmd_register("ban", "ww", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
- PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic,
- _("ban [&lt;channel&gt; +|-&lt;nick&gt;]: Ban client from channel"), NULL);
- purple_cmd_register("getkey", "w", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-silc", silcpurple_cmd_generic,
- _("getkey &lt;nick|server&gt;: Retrieve client's or server's public key"), NULL);
- purple_cmd_register("stats", "", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-silc", silcpurple_cmd_generic,
- _("stats: View server and network statistics"), NULL);
- purple_cmd_register("ping", "", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-silc", silcpurple_cmd_generic,
- _("ping: Send PING to the connected server"), NULL);
-#if 0 /* Purple doesn't handle these yet */
- purple_cmd_register("users", "w", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-silc", silcpurple_cmd_users,
- _("users &lt;channel&gt;: List users in channel"));
- purple_cmd_register("names", "ww", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
- PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_names,
- _("names [-count|-ops|-halfops|-voices|-normal] &lt;channel(s)&gt;: List specific users in channel(s)"));
-#endif
-}
-
-static PurpleWhiteboardPrplOps silcpurple_wb_ops =
-{
- silcpurple_wb_start,
- silcpurple_wb_end,
- silcpurple_wb_get_dimensions,
- silcpurple_wb_set_dimensions,
- silcpurple_wb_get_brush,
- silcpurple_wb_set_brush,
- silcpurple_wb_send,
- silcpurple_wb_clear,
-
- /* padding */
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-static PurplePluginProtocolInfo prpl_info =
-{
-#ifdef HAVE_SILCMIME_H
- OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME |
- OPT_PROTO_PASSWORD_OPTIONAL | OPT_PROTO_IM_IMAGE |
- OPT_PROTO_SLASH_COMMANDS_NATIVE,
-#else
- OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME |
- OPT_PROTO_PASSWORD_OPTIONAL |
- OPT_PROTO_SLASH_COMMANDS_NATIVE,
-#endif
- NULL, /* user_splits */
- NULL, /* protocol_options */
-#ifdef SILC_ATTRIBUTE_USER_ICON
- {"jpeg,gif,png,bmp", 0, 0, 96, 96, 0, PURPLE_ICON_SCALE_DISPLAY}, /* icon_spec */
-#else
- NO_BUDDY_ICONS,
-#endif
- silcpurple_list_icon, /* list_icon */
- NULL, /* list_emblems */
- silcpurple_status_text, /* status_text */
- silcpurple_tooltip_text, /* tooltip_text */
- silcpurple_away_states, /* away_states */
- silcpurple_blist_node_menu, /* blist_node_menu */
- silcpurple_chat_info, /* chat_info */
- silcpurple_chat_info_defaults,/* chat_info_defaults */
- silcpurple_login, /* login */
- silcpurple_close, /* close */
- silcpurple_send_im, /* send_im */
- silcpurple_set_info, /* set_info */
- NULL, /* send_typing */
- silcpurple_get_info, /* get_info */
- silcpurple_set_status, /* set_status */
- silcpurple_idle_set, /* set_idle */
- silcpurple_change_passwd, /* change_passwd */
- silcpurple_add_buddy, /* add_buddy */
- NULL, /* add_buddies */
- silcpurple_remove_buddy, /* remove_buddy */
- NULL, /* remove_buddies */
- NULL, /* add_permit */
- NULL, /* add_deny */
- NULL, /* rem_permit */
- NULL, /* rem_deny */
- NULL, /* set_permit_deny */
- silcpurple_chat_join, /* join_chat */
- NULL, /* reject_chat */
- silcpurple_get_chat_name, /* get_chat_name */
- silcpurple_chat_invite, /* chat_invite */
- silcpurple_chat_leave, /* chat_leave */
- NULL, /* chat_whisper */
- silcpurple_chat_send, /* chat_send */
- silcpurple_keepalive, /* keepalive */
- NULL, /* register_user */
- NULL, /* get_cb_info */
- NULL, /* get_cb_away */
- NULL, /* alias_buddy */
- NULL, /* group_buddy */
- NULL, /* rename_group */
- NULL, /* buddy_free */
- NULL, /* convo_closed */
- NULL, /* normalize */
-#ifdef SILC_ATTRIBUTE_USER_ICON
- silcpurple_buddy_set_icon, /* set_buddy_icon */
-#else
- NULL,
-#endif
- NULL, /* remove_group */
- NULL, /* get_cb_real_name */
- silcpurple_chat_set_topic, /* set_chat_topic */
- NULL, /* find_blist_chat */
- silcpurple_roomlist_get_list, /* roomlist_get_list */
- silcpurple_roomlist_cancel, /* roomlist_cancel */
- NULL, /* roomlist_expand_category */
- NULL, /* can_receive_file */
- silcpurple_ftp_send_file, /* send_file */
- silcpurple_ftp_new_xfer, /* new_xfer */
- NULL, /* offline_message */
- &silcpurple_wb_ops, /* whiteboard_prpl_ops */
- NULL, /* send_raw */
- NULL, /* roomlist_room_serialize */
- NULL, /* unregister_user */
- NULL, /* send_attention */
- NULL, /* get_attention_types */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
- NULL, /* get_account_text_table */
- NULL, /* initiate_media */
- NULL, /* get_media_caps */
- NULL, /* get_moods */
- NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
-};
-
-static PurplePluginInfo info =
-{
- PURPLE_PLUGIN_MAGIC,
- PURPLE_MAJOR_VERSION,
- PURPLE_MINOR_VERSION,
- PURPLE_PLUGIN_PROTOCOL, /**< type */
- NULL, /**< ui_requirement */
- 0, /**< flags */
- NULL, /**< dependencies */
- PURPLE_PRIORITY_DEFAULT, /**< priority */
-
- "prpl-silc", /**< id */
- "SILC", /**< name */
- "1.0", /**< version */
- /** summary */
- N_("SILC Protocol Plugin"),
- /** description */
- N_("Secure Internet Live Conferencing (SILC) Protocol"),
- "Pekka Riikonen", /**< author */
- "http://silcnet.org/", /**< homepage */
-
- NULL, /**< load */
- NULL, /**< unload */
- NULL, /**< destroy */
-
- NULL, /**< ui_info */
- &prpl_info, /**< extra_info */
- NULL, /**< prefs_info */
- silcpurple_actions,
-
- /* padding */
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-static void
-init_plugin(PurplePlugin *plugin)
-{
- PurpleAccountOption *option;
- PurpleAccountUserSplit *split;
- char tmp[256];
- int i;
- PurpleKeyValuePair *kvp;
- GList *list = NULL;
-
- silc_plugin = plugin;
-
- split = purple_account_user_split_new(_("Network"), "silcnet.org", '@');
- prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
-
- /* Account options */
- option = purple_account_option_string_new(_("Connect server"),
- "server",
- "silc.silcnet.org");
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_int_new(_("Port"), "port", 706);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- g_snprintf(tmp, sizeof(tmp), "%s" G_DIR_SEPARATOR_S "public_key.pub", silcpurple_silcdir());
- option = purple_account_option_string_new(_("Public Key file"),
- "public-key", tmp);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- g_snprintf(tmp, sizeof(tmp), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcpurple_silcdir());
- option = purple_account_option_string_new(_("Private Key file"),
- "private-key", tmp);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-
- for (i = 0; silc_default_ciphers[i].name; i++) {
- kvp = g_new0(PurpleKeyValuePair, 1);
- kvp->key = g_strdup(silc_default_ciphers[i].name);
- kvp->value = g_strdup(silc_default_ciphers[i].name);
- list = g_list_append(list, kvp);
- }
- option = purple_account_option_list_new(_("Cipher"), "cipher", list);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-
- list = NULL;
- for (i = 0; silc_default_hmacs[i].name; i++) {
- kvp = g_new0(PurpleKeyValuePair, 1);
- kvp->key = g_strdup(silc_default_hmacs[i].name);
- kvp->value = g_strdup(silc_default_hmacs[i].name);
- list = g_list_append(list, kvp);
- }
- option = purple_account_option_list_new(_("HMAC"), "hmac", list);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-
- option = purple_account_option_bool_new(_("Public key authentication"),
- "pubkey-auth", FALSE);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_bool_new(_("Block IMs without Key Exchange"),
- "block-ims", FALSE);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_bool_new(_("Block messages to whiteboard"),
- "block-wb", FALSE);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_bool_new(_("Automatically open whiteboard"),
- "open-wb", FALSE);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_bool_new(_("Digitally sign and verify all messages"),
- "sign-verify", FALSE);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-
- purple_prefs_remove("/plugins/prpl/silc");
-
- silcpurple_register_commands();
-
-#ifdef _WIN32
- silc_net_win32_init();
-#endif
-}
-
-PURPLE_INIT_PLUGIN(silc10, init_plugin, info);
diff --git a/libpurple/protocols/silc10/silcpurple.h b/libpurple/protocols/silc10/silcpurple.h
deleted file mode 100644
index a24d8a0b9d..0000000000
--- a/libpurple/protocols/silc10/silcpurple.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
-
- silcpurple.h
-
- Author: Pekka Riikonen <priikone@silcnet.org>
-
- Copyright (C) 2004 Pekka Riikonen
-
- 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; version 2 of the License.
-
- 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.
-
-*/
-
-#ifndef SILCPURPLE_H
-#define SILCPURPLE_H
-
-/* Purple includes */
-#include "internal.h"
-#include "account.h"
-#include "accountopt.h"
-#include "cmds.h"
-#include "conversation.h"
-#include "debug.h"
-#include "ft.h"
-#include "notify.h"
-#include "prpl.h"
-#include "request.h"
-#include "roomlist.h"
-#include "server.h"
-#include "util.h"
-
-/* Default public and private key file names */
-#define SILCPURPLE_PUBLIC_KEY_NAME "public_key.pub"
-#define SILCPURPLE_PRIVATE_KEY_NAME "private_key.prv"
-
-/* Default settings for creating key pair */
-#define SILCPURPLE_DEF_PKCS "rsa"
-#define SILCPURPLE_DEF_PKCS_LEN 2048
-
-#define SILCPURPLE_PRVGRP 0x001fffff
-
-/* Status IDs */
-#define SILCPURPLE_STATUS_ID_OFFLINE "offline"
-#define SILCPURPLE_STATUS_ID_AVAILABLE "available"
-#define SILCPURPLE_STATUS_ID_HYPER "hyper"
-#define SILCPURPLE_STATUS_ID_AWAY "away"
-#define SILCPURPLE_STATUS_ID_BUSY "busy"
-#define SILCPURPLE_STATUS_ID_INDISPOSED "indisposed"
-#define SILCPURPLE_STATUS_ID_PAGE "page"
-
-typedef struct {
- unsigned long id;
- const char *channel;
- unsigned long chid;
- const char *parentch;
- SilcChannelPrivateKey key;
-} *SilcPurplePrvgrp;
-
-/* The SILC Purple plugin context */
-typedef struct SilcPurpleStruct {
- SilcClient client;
- SilcClientConnection conn;
-
- guint scheduler;
- PurpleConnection *gc;
- PurpleAccount *account;
- unsigned long channel_ids;
- GList *grps;
-
- char *motd;
- PurpleRoomlist *roomlist;
-#ifdef HAVE_SILCMIME_H
- SilcMimeAssembler mimeass;
-#endif
- unsigned int detaching : 1;
- unsigned int resuming : 1;
- unsigned int roomlist_cancelled : 1;
- unsigned int chpk : 1;
-} *SilcPurple;
-
-
-gboolean silcpurple_check_silc_dir(PurpleConnection *gc);
-void silcpurple_chat_join_done(SilcClient client,
- SilcClientConnection conn,
- SilcClientEntry *clients,
- SilcUInt32 clients_count,
- void *context);
-const char *silcpurple_silcdir(void);
-const char *silcpurple_session_file(const char *account);
-void silcpurple_verify_public_key(SilcClient client, SilcClientConnection conn,
- const char *name, SilcSocketType conn_type,
- unsigned char *pk, SilcUInt32 pk_len,
- SilcSKEPKType pk_type,
- SilcVerifyPublicKey completion, void *context);
-GList *silcpurple_buddy_menu(PurpleBuddy *buddy);
-void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group);
-void silcpurple_send_buddylist(PurpleConnection *gc);
-void silcpurple_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group);
-void silcpurple_buddy_keyagr_request(SilcClient client,
- SilcClientConnection conn,
- SilcClientEntry client_entry,
- const char *hostname, SilcUInt16 port);
-void silcpurple_idle_set(PurpleConnection *gc, int idle);
-void silcpurple_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full);
-char *silcpurple_status_text(PurpleBuddy *b);
-gboolean silcpurple_ip_is_private(const char *ip);
-void silcpurple_ftp_send_file(PurpleConnection *gc, const char *name, const char *file);
-PurpleXfer *silcpurple_ftp_new_xfer(PurpleConnection *gc, const char *name);
-void silcpurple_ftp_request(SilcClient client, SilcClientConnection conn,
- SilcClientEntry client_entry, SilcUInt32 session_id,
- const char *hostname, SilcUInt16 port);
-void silcpurple_show_public_key(SilcPurple sg,
- const char *name, SilcPublicKey public_key,
- GCallback callback, void *context);
-void silcpurple_get_info(PurpleConnection *gc, const char *who);
-SilcAttributePayload
-silcpurple_get_attr(SilcDList attrs, SilcAttribute attribute);
-void silcpurple_get_umode_string(SilcUInt32 mode, char *buf,
- SilcUInt32 buf_size);
-void silcpurple_get_chmode_string(SilcUInt32 mode, char *buf,
- SilcUInt32 buf_size);
-void silcpurple_get_chumode_string(SilcUInt32 mode, char *buf,
- SilcUInt32 buf_size);
-GList *silcpurple_chat_info(PurpleConnection *gc);
-GHashTable *silcpurple_chat_info_defaults(PurpleConnection *gc, const char *chat_name);
-GList *silcpurple_chat_menu(PurpleChat *);
-void silcpurple_chat_join(PurpleConnection *gc, GHashTable *data);
-char *silcpurple_get_chat_name(GHashTable *data);
-void silcpurple_chat_invite(PurpleConnection *gc, int id, const char *msg,
- const char *name);
-void silcpurple_chat_leave(PurpleConnection *gc, int id);
-int silcpurple_chat_send(PurpleConnection *gc, int id, const char *msg, PurpleMessageFlags flags);
-void silcpurple_chat_set_topic(PurpleConnection *gc, int id, const char *topic);
-PurpleRoomlist *silcpurple_roomlist_get_list(PurpleConnection *gc);
-void silcpurple_roomlist_cancel(PurpleRoomlist *list);
-void silcpurple_chat_chauth_show(SilcPurple sg, SilcChannelEntry channel,
- SilcBuffer channel_pubkeys);
-void silcpurple_parse_attrs(SilcDList attrs, char **moodstr, char **statusstr,
- char **contactstr, char **langstr, char **devicestr,
- char **tzstr, char **geostr);
-#ifdef SILC_ATTRIBUTE_USER_ICON
-void silcpurple_buddy_set_icon(PurpleConnection *gc, PurpleStoredImage *img);
-#endif
-#ifdef HAVE_SILCMIME_H
-char *silcpurple_file2mime(const char *filename);
-SilcDList silcpurple_image_message(const char *msg, SilcUInt32 *mflags);
-#endif
-
-#ifdef _WIN32
-typedef int uid_t;
-
-struct passwd {
- char *pw_name; /* user name */
- char *pw_passwd; /* user password */
- int pw_uid; /* user id */
- int pw_gid; /* group id */
- char *pw_gecos; /* real name */
- char *pw_dir; /* home directory */
- char *pw_shell; /* shell program */
-};
-
-struct passwd *getpwuid(int uid);
-int getuid(void);
-int geteuid(void);
-#endif
-
-#endif /* SILCPURPLE_H */
diff --git a/libpurple/protocols/silc10/util.c b/libpurple/protocols/silc10/util.c
deleted file mode 100644
index 792afdea58..0000000000
--- a/libpurple/protocols/silc10/util.c
+++ /dev/null
@@ -1,776 +0,0 @@
-/*
-
- silcpurple_util.c
-
- Author: Pekka Riikonen <priikone@silcnet.org>
-
- Copyright (C) 2004 - 2005 Pekka Riikonen
-
- 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; version 2 of the License.
-
- 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.
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-#include "silcpurple.h"
-#include "imgstore.h"
-
-/**************************** Utility Routines *******************************/
-
-static char str[256], str2[256];
-
-const char *silcpurple_silcdir(void)
-{
- const char *hd = purple_home_dir();
- memset(str, 0, sizeof(str));
- g_snprintf(str, sizeof(str) - 1, "%s" G_DIR_SEPARATOR_S ".silc", hd ? hd : "/tmp");
- return (const char *)str;
-}
-
-const char *silcpurple_session_file(const char *account)
-{
- memset(str2, 0, sizeof(str2));
- g_snprintf(str2, sizeof(str2) - 1, "%s" G_DIR_SEPARATOR_S "%s_session",
- silcpurple_silcdir(), account);
- return (const char *)str2;
-}
-
-gboolean silcpurple_ip_is_private(const char *ip)
-{
- if (silc_net_is_ip4(ip)) {
- if (!strncmp(ip, "10.", 3)) {
- return TRUE;
- } else if (!strncmp(ip, "172.", 4) && strlen(ip) > 6) {
- char tmp[3];
- int s;
- memset(tmp, 0, sizeof(tmp));
- strncpy(tmp, ip + 4, 2);
- s = atoi(tmp);
- if (s >= 16 && s <= 31)
- return TRUE;
- } else if (!strncmp(ip, "192.168.", 8)) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/* This checks stats for various SILC files and directories. First it
- checks if ~/.silc directory exist and is owned by the correct user. If
- it doesn't exist, it will create the directory. After that it checks if
- user's Public and Private key files exists and creates them if needed. */
-
-gboolean silcpurple_check_silc_dir(PurpleConnection *gc)
-{
- char filename[256], file_public_key[256], file_private_key[256];
- char servfilename[256], clientfilename[256], friendsfilename[256];
- char pkd[256], prd[256];
- struct stat st;
- struct passwd *pw;
- int fd;
-
- pw = getpwuid(getuid());
- if (!pw) {
- purple_debug_error("silc", "silc: %s\n", g_strerror(errno));
- return FALSE;
- }
-
- g_snprintf(filename, sizeof(filename) - 1, "%s", silcpurple_silcdir());
- g_snprintf(servfilename, sizeof(servfilename) - 1, "%s" G_DIR_SEPARATOR_S "serverkeys",
- silcpurple_silcdir());
- g_snprintf(clientfilename, sizeof(clientfilename) - 1, "%s" G_DIR_SEPARATOR_S "clientkeys",
- silcpurple_silcdir());
- g_snprintf(friendsfilename, sizeof(friendsfilename) - 1, "%s" G_DIR_SEPARATOR_S "friends",
- silcpurple_silcdir());
-
- /*
- * Check ~/.silc directory
- */
- if ((g_stat(filename, &st)) == -1) {
- /* If dir doesn't exist */
- if (errno == ENOENT) {
- if (pw->pw_uid == geteuid()) {
- if ((g_mkdir(filename, 0755)) == -1) {
- purple_debug_error("silc", "Couldn't create '%s' directory\n", filename);
- return FALSE;
- }
- } else {
- purple_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n",
- filename);
- return FALSE;
- }
- } else {
- purple_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", filename, g_strerror(errno));
- return FALSE;
- }
- } else {
-#ifndef _WIN32
- /* Check the owner of the dir */
- if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
- purple_debug_error("silc", "You don't seem to own '%s' directory\n",
- filename);
- return FALSE;
- }
-#endif
- }
-
- /*
- * Check ~./silc/serverkeys directory
- */
- if ((g_stat(servfilename, &st)) == -1) {
- /* If dir doesn't exist */
- if (errno == ENOENT) {
- if (pw->pw_uid == geteuid()) {
- if ((g_mkdir(servfilename, 0755)) == -1) {
- purple_debug_error("silc", "Couldn't create '%s' directory\n", servfilename);
- return FALSE;
- }
- } else {
- purple_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n",
- servfilename);
- return FALSE;
- }
- } else {
- purple_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n",
- servfilename, g_strerror(errno));
- return FALSE;
- }
- }
-
- /*
- * Check ~./silc/clientkeys directory
- */
- if ((g_stat(clientfilename, &st)) == -1) {
- /* If dir doesn't exist */
- if (errno == ENOENT) {
- if (pw->pw_uid == geteuid()) {
- if ((g_mkdir(clientfilename, 0755)) == -1) {
- purple_debug_error("silc", "Couldn't create '%s' directory\n", clientfilename);
- return FALSE;
- }
- } else {
- purple_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n",
- clientfilename);
- return FALSE;
- }
- } else {
- purple_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n",
- clientfilename, g_strerror(errno));
- return FALSE;
- }
- }
-
- /*
- * Check ~./silc/friends directory
- */
- if ((g_stat(friendsfilename, &st)) == -1) {
- /* If dir doesn't exist */
- if (errno == ENOENT) {
- if (pw->pw_uid == geteuid()) {
- if ((g_mkdir(friendsfilename, 0755)) == -1) {
- purple_debug_error("silc", "Couldn't create '%s' directory\n", friendsfilename);
- return FALSE;
- }
- } else {
- purple_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n",
- friendsfilename);
- return FALSE;
- }
- } else {
- purple_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n",
- friendsfilename, g_strerror(errno));
- return FALSE;
- }
- }
-
- /*
- * Check Public and Private keys
- */
- g_snprintf(pkd, sizeof(pkd), "%s" G_DIR_SEPARATOR_S "public_key.pub", silcpurple_silcdir());
- g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcpurple_silcdir());
- g_snprintf(file_public_key, sizeof(file_public_key) - 1, "%s",
- purple_account_get_string(gc->account, "public-key", pkd));
- g_snprintf(file_private_key, sizeof(file_public_key) - 1, "%s",
- purple_account_get_string(gc->account, "private-key", prd));
-
- if ((g_stat(file_public_key, &st)) == -1) {
- /* If file doesn't exist */
- if (errno == ENOENT) {
- purple_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5);
- if (!silc_create_key_pair(SILCPURPLE_DEF_PKCS,
- SILCPURPLE_DEF_PKCS_LEN,
- file_public_key, file_private_key, NULL,
- (gc->password == NULL) ? "" : gc->password,
- NULL, NULL, NULL, FALSE)) {
- purple_debug_error("silc", "Couldn't create key pair\n");
- return FALSE;
- }
-
- if ((g_stat(file_public_key, &st)) == -1) {
- purple_debug_error("silc", "Couldn't stat '%s' public key, error: %s\n",
- file_public_key, g_strerror(errno));
- return FALSE;
- }
- } else {
- purple_debug_error("silc", "Couldn't stat '%s' public key, error: %s\n",
- file_public_key, g_strerror(errno));
- return FALSE;
- }
- }
-
-#ifndef _WIN32
- /* Check the owner of the public key */
- if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
- purple_debug_error("silc", "You don't seem to own your public key!?\n");
- return FALSE;
- }
-#endif
-
- if ((fd = g_open(file_private_key, O_RDONLY, 0)) != -1) {
- if ((fstat(fd, &st)) == -1) {
- purple_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n",
- file_private_key, g_strerror(errno));
- close(fd);
- return FALSE;
- }
- } else if ((g_stat(file_private_key, &st)) == -1) {
- /* If file doesn't exist */
- if (errno == ENOENT) {
- purple_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5);
- if (!silc_create_key_pair(SILCPURPLE_DEF_PKCS,
- SILCPURPLE_DEF_PKCS_LEN,
- file_public_key, file_private_key, NULL,
- (gc->password == NULL) ? "" : gc->password,
- NULL, NULL, NULL, FALSE)) {
- purple_debug_error("silc", "Couldn't create key pair\n");
- return FALSE;
- }
-
- if ((fd = g_open(file_private_key, O_RDONLY, 0)) != -1) {
- if ((fstat(fd, &st)) == -1) {
- purple_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n",
- file_private_key, g_strerror(errno));
- close(fd);
- return FALSE;
- }
- }
- /* This shouldn't really happen because silc_create_key_pair()
- * will set the permissions */
- else if ((g_stat(file_private_key, &st)) == -1) {
- purple_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n",
- file_private_key, g_strerror(errno));
- return FALSE;
- }
- } else {
- purple_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n",
- file_private_key, g_strerror(errno));
- return FALSE;
- }
- }
-
-#ifndef _WIN32
- /* Check the owner of the private key */
- if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
- purple_debug_error("silc", "You don't seem to own your private key!?\n");
- if (fd != -1)
- close(fd);
- return FALSE;
- }
-
- /* Check the permissions for the private key */
- if ((st.st_mode & 0777) != 0600) {
- purple_debug_warning("silc", "Wrong permissions in your private key file `%s'!\n"
- "Trying to change them ...\n", file_private_key);
- if ((fd == -1) || (fchmod(fd, S_IRUSR | S_IWUSR)) == -1) {
- purple_debug_error("silc",
- "Failed to change permissions for private key file!\n"
- "Permissions for your private key file must be 0600.\n");
- if (fd != -1)
- close(fd);
- return FALSE;
- }
- purple_debug_warning("silc", "Done.\n\n");
- }
-#endif
-
- if (fd != -1)
- close(fd);
-
- return TRUE;
-}
-
-#ifdef _WIN32
-struct passwd *getpwuid(uid_t uid) {
- struct passwd *pwd = calloc(1, sizeof(struct passwd));
- return pwd;
-}
-
-uid_t getuid() {
- return 0;
-}
-
-uid_t geteuid() {
- return 0;
-}
-#endif
-
-void silcpurple_show_public_key(SilcPurple sg,
- const char *name, SilcPublicKey public_key,
- GCallback callback, void *context)
-{
- SilcPublicKeyIdentifier ident;
- SilcPKCS pkcs;
- char *fingerprint, *babbleprint;
- unsigned char *pk;
- SilcUInt32 pk_len, key_len = 0;
- GString *s;
- char *buf;
-
- ident = silc_pkcs_decode_identifier(public_key->identifier);
- if (!ident)
- return;
-
- pk = silc_pkcs_public_key_encode(public_key, &pk_len);
- fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
-
- if (silc_pkcs_alloc((unsigned char *)public_key->name, &pkcs)) {
- key_len = silc_pkcs_public_key_set(pkcs, public_key);
- silc_pkcs_free(pkcs);
- }
-
- s = g_string_new("");
- if (ident->realname)
- /* Hint for translators: Please check the tabulator width here and in
- the next strings (short strings: 2 tabs, longer strings 1 tab,
- sum: 3 tabs or 24 characters) */
- g_string_append_printf(s, _("Real Name: \t%s\n"), ident->realname);
- if (ident->username)
- g_string_append_printf(s, _("User Name: \t%s\n"), ident->username);
- if (ident->email)
- g_string_append_printf(s, _("Email: \t\t%s\n"), ident->email);
- if (ident->host)
- g_string_append_printf(s, _("Host Name: \t%s\n"), ident->host);
- if (ident->org)
- g_string_append_printf(s, _("Organization: \t%s\n"), ident->org);
- if (ident->country)
- g_string_append_printf(s, _("Country: \t%s\n"), ident->country);
- g_string_append_printf(s, _("Algorithm: \t%s\n"), public_key->name);
- g_string_append_printf(s, _("Key Length: \t%d bits\n"), (int)key_len);
- g_string_append_printf(s, "\n");
- g_string_append_printf(s, _("Public Key Fingerprint:\n%s\n\n"), fingerprint);
- g_string_append_printf(s, _("Public Key Babbleprint:\n%s"), babbleprint);
-
- buf = g_string_free(s, FALSE);
-
- purple_request_action(sg->gc, _("Public Key Information"),
- _("Public Key Information"),
- buf, 0, purple_connection_get_account(sg->gc),
- NULL, NULL, context, 1, _("Close"), callback);
-
- g_free(buf);
- silc_free(fingerprint);
- silc_free(babbleprint);
- silc_free(pk);
- silc_pkcs_free_identifier(ident);
-}
-
-SilcAttributePayload
-silcpurple_get_attr(SilcDList attrs, SilcAttribute attribute)
-{
- SilcAttributePayload attr = NULL;
-
- if (!attrs)
- return NULL;
-
- silc_dlist_start(attrs);
- while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END)
- if (attribute == silc_attribute_get_attribute(attr))
- break;
-
- return attr;
-}
-
-void silcpurple_get_umode_string(SilcUInt32 mode, char *buf,
- SilcUInt32 buf_size)
-{
- memset(buf, 0, buf_size);
- if ((mode & SILC_UMODE_SERVER_OPERATOR) ||
- (mode & SILC_UMODE_ROUTER_OPERATOR)) {
- strcat(buf, (mode & SILC_UMODE_SERVER_OPERATOR) ?
- "[server operator] " :
- (mode & SILC_UMODE_ROUTER_OPERATOR) ?
- "[SILC operator] " : "[unknown mode] ");
- }
- if (mode & SILC_UMODE_GONE)
- strcat(buf, "[away] ");
- if (mode & SILC_UMODE_INDISPOSED)
- strcat(buf, "[indisposed] ");
- if (mode & SILC_UMODE_BUSY)
- strcat(buf, "[busy] ");
- if (mode & SILC_UMODE_PAGE)
- strcat(buf, "[wake me up] ");
- if (mode & SILC_UMODE_HYPER)
- strcat(buf, "[hyperactive] ");
- if (mode & SILC_UMODE_ROBOT)
- strcat(buf, "[robot] ");
- if (mode & SILC_UMODE_ANONYMOUS)
- strcat(buf, "[anonymous] ");
- if (mode & SILC_UMODE_BLOCK_PRIVMSG)
- strcat(buf, "[blocks private messages] ");
- if (mode & SILC_UMODE_DETACHED)
- strcat(buf, "[detached] ");
- if (mode & SILC_UMODE_REJECT_WATCHING)
- strcat(buf, "[rejects watching] ");
- if (mode & SILC_UMODE_BLOCK_INVITE)
- strcat(buf, "[blocks invites] ");
- g_strchomp(buf);
-}
-
-void silcpurple_get_chmode_string(SilcUInt32 mode, char *buf,
- SilcUInt32 buf_size)
-{
- memset(buf, 0, buf_size);
- if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
- strcat(buf, "[permanent] ");
- if (mode & SILC_CHANNEL_MODE_PRIVATE)
- strcat(buf, "[private] ");
- if (mode & SILC_CHANNEL_MODE_SECRET)
- strcat(buf, "[secret] ");
- if (mode & SILC_CHANNEL_MODE_PRIVKEY)
- strcat(buf, "[private key] ");
- if (mode & SILC_CHANNEL_MODE_INVITE)
- strcat(buf, "[invite only] ");
- if (mode & SILC_CHANNEL_MODE_TOPIC)
- strcat(buf, "[topic restricted] ");
- if (mode & SILC_CHANNEL_MODE_ULIMIT)
- strcat(buf, "[user count limit] ");
- if (mode & SILC_CHANNEL_MODE_PASSPHRASE)
- strcat(buf, "[passphrase auth] ");
- if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
- strcat(buf, "[public key auth] ");
- if (mode & SILC_CHANNEL_MODE_SILENCE_USERS)
- strcat(buf, "[users silenced] ");
- if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS)
- strcat(buf, "[operators silenced] ");
- g_strchomp(buf);
-}
-
-void silcpurple_get_chumode_string(SilcUInt32 mode, char *buf,
- SilcUInt32 buf_size)
-{
- memset(buf, 0, buf_size);
- if (mode & SILC_CHANNEL_UMODE_CHANFO)
- strcat(buf, "[founder] ");
- if (mode & SILC_CHANNEL_UMODE_CHANOP)
- strcat(buf, "[operator] ");
- if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
- strcat(buf, "[blocks messages] ");
- if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)
- strcat(buf, "[blocks user messages] ");
- if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)
- strcat(buf, "[blocks robot messages] ");
- if (mode & SILC_CHANNEL_UMODE_QUIET)
- strcat(buf, "[quieted] ");
- g_strchomp(buf);
-}
-
-void
-silcpurple_parse_attrs(SilcDList attrs, char **moodstr, char **statusstr,
- char **contactstr, char **langstr, char **devicestr,
- char **tzstr, char **geostr)
-{
- SilcAttributePayload attr;
- SilcAttributeMood mood = 0;
- SilcAttributeContact contact;
- SilcAttributeObjDevice device;
- SilcAttributeObjGeo geo;
-
- char tmp[1024];
- GString *s;
-
- *moodstr = NULL;
- *statusstr = NULL;
- *contactstr = NULL;
- *langstr = NULL;
- *devicestr = NULL;
- *tzstr = NULL;
- *geostr = NULL;
-
- if (!attrs)
- return;
-
- s = g_string_new("");
- attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_STATUS_MOOD);
- if (attr && silc_attribute_get_object(attr, &mood, sizeof(mood))) {
- if (mood & SILC_ATTRIBUTE_MOOD_HAPPY)
- g_string_append_printf(s, "[%s] ", _("Happy"));
- if (mood & SILC_ATTRIBUTE_MOOD_SAD)
- g_string_append_printf(s, "[%s] ", _("Sad"));
- if (mood & SILC_ATTRIBUTE_MOOD_ANGRY)
- g_string_append_printf(s, "[%s] ", _("Angry"));
- if (mood & SILC_ATTRIBUTE_MOOD_JEALOUS)
- g_string_append_printf(s, "[%s] ", _("Jealous"));
- if (mood & SILC_ATTRIBUTE_MOOD_ASHAMED)
- g_string_append_printf(s, "[%s] ", _("Ashamed"));
- if (mood & SILC_ATTRIBUTE_MOOD_INVINCIBLE)
- g_string_append_printf(s, "[%s] ", _("Invincible"));
- if (mood & SILC_ATTRIBUTE_MOOD_INLOVE)
- g_string_append_printf(s, "[%s] ", _("In Love"));
- if (mood & SILC_ATTRIBUTE_MOOD_SLEEPY)
- g_string_append_printf(s, "[%s] ", _("Sleepy"));
- if (mood & SILC_ATTRIBUTE_MOOD_BORED)
- g_string_append_printf(s, "[%s] ", _("Bored"));
- if (mood & SILC_ATTRIBUTE_MOOD_EXCITED)
- g_string_append_printf(s, "[%s] ", _("Excited"));
- if (mood & SILC_ATTRIBUTE_MOOD_ANXIOUS)
- g_string_append_printf(s, "[%s] ", _("Anxious"));
- }
- if (strlen(s->str)) {
- *moodstr = s->str;
- g_string_free(s, FALSE);
- g_strchomp(*moodstr);
- } else
- g_string_free(s, TRUE);
-
- attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_STATUS_FREETEXT);
- memset(tmp, 0, sizeof(tmp));
- if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp)))
- *statusstr = g_strdup(tmp);
-
- s = g_string_new("");
- attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_PREFERRED_CONTACT);
- if (attr && silc_attribute_get_object(attr, &contact, sizeof(contact))) {
- if (contact & SILC_ATTRIBUTE_CONTACT_CHAT)
- g_string_append_printf(s, "[%s] ", _("Chat"));
- if (contact & SILC_ATTRIBUTE_CONTACT_EMAIL)
- g_string_append_printf(s, "[%s] ", _("Email"));
- if (contact & SILC_ATTRIBUTE_CONTACT_CALL)
- g_string_append_printf(s, "[%s] ", _("Phone"));
- if (contact & SILC_ATTRIBUTE_CONTACT_PAGE)
- g_string_append_printf(s, "[%s] ", _("Paging"));
- if (contact & SILC_ATTRIBUTE_CONTACT_SMS)
- g_string_append_printf(s, "[%s] ", _("SMS"));
- if (contact & SILC_ATTRIBUTE_CONTACT_MMS)
- g_string_append_printf(s, "[%s] ", _("MMS"));
- if (contact & SILC_ATTRIBUTE_CONTACT_VIDEO)
- g_string_append_printf(s, "[%s] ", _("Video Conferencing"));
- }
- if (strlen(s->str)) {
- *contactstr = s->str;
- g_string_free(s, FALSE);
- g_strchomp(*contactstr);
- } else
- g_string_free(s, TRUE);
-
- attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_PREFERRED_LANGUAGE);
- memset(tmp, 0, sizeof(tmp));
- if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp)))
- *langstr = g_strdup(tmp);
-
- s = g_string_new("");
- attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_DEVICE_INFO);
- memset(&device, 0, sizeof(device));
- if (attr && silc_attribute_get_object(attr, &device, sizeof(device))) {
- if (device.type == SILC_ATTRIBUTE_DEVICE_COMPUTER)
- g_string_append_printf(s, "%s: ", _("Computer"));
- if (device.type == SILC_ATTRIBUTE_DEVICE_MOBILE_PHONE)
- g_string_append_printf(s, "%s: ", _("Mobile Phone"));
- if (device.type == SILC_ATTRIBUTE_DEVICE_PDA)
- g_string_append_printf(s, "%s: ", _("PDA"));
- if (device.type == SILC_ATTRIBUTE_DEVICE_TERMINAL)
- g_string_append_printf(s, "%s: ", _("Terminal"));
- g_string_append_printf(s, "%s %s %s %s",
- device.manufacturer ? device.manufacturer : "",
- device.version ? device.version : "",
- device.model ? device.model : "",
- device.language ? device.language : "");
- }
- if (strlen(s->str)) {
- *devicestr = s->str;
- g_string_free(s, FALSE);
- } else
- g_string_free(s, TRUE);
-
- attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_TIMEZONE);
- memset(tmp, 0, sizeof(tmp));
- if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp)))
- *tzstr = g_strdup(tmp);
-
- attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_GEOLOCATION);
- memset(&geo, 0, sizeof(geo));
- if (attr && silc_attribute_get_object(attr, &geo, sizeof(geo)))
- *geostr = g_strdup_printf("%s %s %s (%s)",
- geo.longitude ? geo.longitude : "",
- geo.latitude ? geo.latitude : "",
- geo.altitude ? geo.altitude : "",
- geo.accuracy ? geo.accuracy : "");
-}
-
-#ifdef HAVE_SILCMIME_H
-/* Returns MIME type of filetype */
-
-char *silcpurple_file2mime(const char *filename)
-{
- const char *ct;
-
- ct = strrchr(filename, '.');
- if (!ct)
- return NULL;
- else if (!g_ascii_strcasecmp(".png", ct))
- return strdup("image/png");
- else if (!g_ascii_strcasecmp(".jpg", ct))
- return strdup("image/jpeg");
- else if (!g_ascii_strcasecmp(".jpeg", ct))
- return strdup("image/jpeg");
- else if (!g_ascii_strcasecmp(".gif", ct))
- return strdup("image/gif");
- else if (!g_ascii_strcasecmp(".tiff", ct))
- return strdup("image/tiff");
-
- return NULL;
-}
-
-/* Checks if message has images, and assembles MIME message if it has.
- If only one image is present, creates simple MIME image message. If
- there are multiple images and/or text with images multipart MIME
- message is created. */
-
-SilcDList silcpurple_image_message(const char *msg, SilcUInt32 *mflags)
-{
- SilcMime mime = NULL, p;
- SilcDList list, parts = NULL;
- const char *start, *end, *last;
- GData *attribs;
- char *type;
- gboolean images = FALSE;
-
- last = msg;
- while (last && *last && purple_markup_find_tag("img", last, &start,
- &end, &attribs)) {
- PurpleStoredImage *image = NULL;
- const char *id;
-
- /* Check if there is text before image */
- if (start - last) {
- char *text, *tmp;
- p = silc_mime_alloc();
-
- /* Add content type */
- silc_mime_add_field(p, "Content-Type",
- "text/plain; charset=utf-8");
-
- tmp = g_strndup(last, start - last);
- text = purple_unescape_html(tmp);
- g_free(tmp);
- /* Add text */
- silc_mime_add_data(p, (unsigned char *)text, strlen(text));
- g_free(text);
-
- if (!parts)
- parts = silc_dlist_init();
- silc_dlist_add(parts, p);
- }
-
- id = g_datalist_get_data(&attribs, "id");
- if (id && (image = purple_imgstore_find_by_id(atoi(id)))) {
- unsigned long imglen = purple_imgstore_get_size(image);
- gconstpointer img = purple_imgstore_get_data(image);
-
- p = silc_mime_alloc();
-
- /* Add content type */
- type = silcpurple_file2mime(purple_imgstore_get_filename(image));
- if (!type) {
- g_datalist_clear(&attribs);
- last = end + 1;
- continue;
- }
- silc_mime_add_field(p, "Content-Type", type);
- silc_free(type);
-
- /* Add content transfer encoding */
- silc_mime_add_field(p, "Content-Transfer-Encoding", "binary");
-
- /* Add image data */
- silc_mime_add_data(p, img, imglen);
-
- if (!parts)
- parts = silc_dlist_init();
- silc_dlist_add(parts, p);
- images = TRUE;
- }
-
- g_datalist_clear(&attribs);
-
- /* Continue after tag */
- last = end + 1;
- }
-
- /* Check for text after the image(s) */
- if (images && last && *last) {
- char *tmp = purple_unescape_html(last);
- p = silc_mime_alloc();
-
- /* Add content type */
- silc_mime_add_field(p, "Content-Type",
- "text/plain; charset=utf-8");
-
- /* Add text */
- silc_mime_add_data(p, (unsigned char *)tmp, strlen(tmp));
- g_free(tmp);
-
- if (!parts)
- parts = silc_dlist_init();
- silc_dlist_add(parts, p);
- }
-
- /* If there weren't any images, don't return anything. */
- if (!images) {
- if (parts)
- silc_dlist_uninit(parts);
- return NULL;
- }
-
- if (silc_dlist_count(parts) > 1) {
- /* Multipart MIME message */
- char b[32];
- mime = silc_mime_alloc();
- silc_mime_add_field(mime, "MIME-Version", "1.0");
- g_snprintf(b, sizeof(b), "b%4X%4X",
- (unsigned int)time(NULL),
- silc_dlist_count(parts));
- silc_mime_set_multipart(mime, "mixed", b);
- silc_dlist_start(parts);
- while ((p = silc_dlist_get(parts)) != SILC_LIST_END)
- silc_mime_add_multipart(mime, p);
- } else {
- /* Simple MIME message */
- silc_dlist_start(parts);
- mime = silc_dlist_get(parts);
- silc_mime_add_field(mime, "MIME-Version", "1.0");
- }
-
- *mflags &= ~SILC_MESSAGE_FLAG_UTF8;
- *mflags |= SILC_MESSAGE_FLAG_DATA;
-
- /* Encode message. Fragment if it is too large */
- list = silc_mime_encode_partial(mime, 0xfc00);
-
- silc_dlist_uninit(parts);
-
- /* Added multiparts gets freed here */
- silc_mime_free(mime);
-
- return list;
-}
-
-#endif /* HAVE_SILCMIME_H */
diff --git a/libpurple/protocols/silc10/wb.c b/libpurple/protocols/silc10/wb.c
deleted file mode 100644
index 5e917b8cce..0000000000
--- a/libpurple/protocols/silc10/wb.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
-
- wb.c
-
- Author: Pekka Riikonen <priikone@silcnet.org>
-
- Copyright (C) 2005 Pekka Riikonen
-
- 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; version 2 of the License.
-
- 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.
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-#include "silcpurple.h"
-#include "wb.h"
-
-/*
- SILC Whiteboard packet:
-
- 1 byte command
- 2 bytes width
- 2 bytes height
- 4 bytes brush color
- 2 bytes brush size
- n bytes data
-
- Data:
-
- 4 bytes x
- 4 bytes y
-
- Commands:
-
- 0x01 draw
- 0x02 clear
-
- MIME:
-
- MIME-Version: 1.0
- Content-Type: application/x-wb
- Content-Transfer-Encoding: binary
-
-*/
-
-#define SILCPURPLE_WB_MIME "MIME-Version: 1.0\r\nContent-Type: application/x-wb\r\nContent-Transfer-Encoding: binary\r\n\r\n"
-#define SILCPURPLE_WB_HEADER strlen(SILCPURPLE_WB_MIME) + 11
-
-#define SILCPURPLE_WB_WIDTH 500
-#define SILCPURPLE_WB_HEIGHT 400
-#define SILCPURPLE_WB_WIDTH_MAX 1024
-#define SILCPURPLE_WB_HEIGHT_MAX 1024
-
-/* Commands */
-typedef enum {
- SILCPURPLE_WB_DRAW = 0x01,
- SILCPURPLE_WB_CLEAR = 0x02
-} SilcPurpleWbCommand;
-
-/* Brush size */
-typedef enum {
- SILCPURPLE_WB_BRUSH_SMALL = 2,
- SILCPURPLE_WB_BRUSH_MEDIUM = 5,
- SILCPURPLE_WB_BRUSH_LARGE = 10
-} SilcPurpleWbBrushSize;
-
-/* Brush color (XXX Purple should provide default colors) */
-typedef enum {
- SILCPURPLE_WB_COLOR_BLACK = 0,
- SILCPURPLE_WB_COLOR_RED = 13369344,
- SILCPURPLE_WB_COLOR_GREEN = 52224,
- SILCPURPLE_WB_COLOR_BLUE = 204,
- SILCPURPLE_WB_COLOR_YELLOW = 15658496,
- SILCPURPLE_WB_COLOR_ORANGE = 16737792,
- SILCPURPLE_WB_COLOR_CYAN = 52428,
- SILCPURPLE_WB_COLOR_VIOLET = 5381277,
- SILCPURPLE_WB_COLOR_PURPLE = 13369548,
- SILCPURPLE_WB_COLOR_TAN = 12093547,
- SILCPURPLE_WB_COLOR_BROWN = 5256485,
- SILCPURPLE_WB_COLOR_GREY = 11184810,
- SILCPURPLE_WB_COLOR_WHITE = 16777215
-} SilcPurpleWbColor;
-
-typedef struct {
- int type; /* 0 = buddy, 1 = channel */
- union {
- SilcClientEntry client;
- SilcChannelEntry channel;
- } u;
- int width;
- int height;
- int brush_size;
- int brush_color;
-} *SilcPurpleWb;
-
-/* Initialize whiteboard */
-
-PurpleWhiteboard *silcpurple_wb_init(SilcPurple sg, SilcClientEntry client_entry)
-{
- SilcClientConnection conn;
- PurpleWhiteboard *wb;
- SilcPurpleWb wbs;
-
- conn = sg->conn;
- wb = purple_whiteboard_get_session(sg->account, client_entry->nickname);
- if (!wb)
- wb = purple_whiteboard_create(sg->account, client_entry->nickname, 0);
- if (!wb)
- return NULL;
-
- if (!wb->proto_data) {
- wbs = silc_calloc(1, sizeof(*wbs));
- if (!wbs)
- return NULL;
- wbs->type = 0;
- wbs->u.client = client_entry;
- wbs->width = SILCPURPLE_WB_WIDTH;
- wbs->height = SILCPURPLE_WB_HEIGHT;
- wbs->brush_size = SILCPURPLE_WB_BRUSH_SMALL;
- wbs->brush_color = SILCPURPLE_WB_COLOR_BLACK;
- wb->proto_data = wbs;
-
- /* Start the whiteboard */
- purple_whiteboard_start(wb);
- purple_whiteboard_clear(wb);
- }
-
- return wb;
-}
-
-PurpleWhiteboard *silcpurple_wb_init_ch(SilcPurple sg, SilcChannelEntry channel)
-{
- PurpleWhiteboard *wb;
- SilcPurpleWb wbs;
-
- wb = purple_whiteboard_get_session(sg->account, channel->channel_name);
- if (!wb)
- wb = purple_whiteboard_create(sg->account, channel->channel_name, 0);
- if (!wb)
- return NULL;
-
- if (!wb->proto_data) {
- wbs = silc_calloc(1, sizeof(*wbs));
- if (!wbs)
- return NULL;
- wbs->type = 1;
- wbs->u.channel = channel;
- wbs->width = SILCPURPLE_WB_WIDTH;
- wbs->height = SILCPURPLE_WB_HEIGHT;
- wbs->brush_size = SILCPURPLE_WB_BRUSH_SMALL;
- wbs->brush_color = SILCPURPLE_WB_COLOR_BLACK;
- wb->proto_data = wbs;
-
- /* Start the whiteboard */
- purple_whiteboard_start(wb);
- purple_whiteboard_clear(wb);
- }
-
- return wb;
-}
-
-static void
-silcpurple_wb_parse(SilcPurpleWb wbs, PurpleWhiteboard *wb,
- unsigned char *message, SilcUInt32 message_len)
-{
- SilcUInt8 command;
- SilcUInt16 width, height, brush_size;
- SilcUInt32 brush_color, x, y, dx, dy;
- SilcBufferStruct buf;
- int ret;
-
- /* Parse the packet */
- silc_buffer_set(&buf, message, message_len);
- ret = silc_buffer_unformat(&buf,
- SILC_STR_UI_CHAR(&command),
- SILC_STR_UI_SHORT(&width),
- SILC_STR_UI_SHORT(&height),
- SILC_STR_UI_INT(&brush_color),
- SILC_STR_UI_SHORT(&brush_size),
- SILC_STR_END);
- if (ret < 0)
- return;
- silc_buffer_pull(&buf, ret);
-
- /* Update whiteboard if its dimensions changed */
- if (width != wbs->width || height != wbs->height)
- silcpurple_wb_set_dimensions(wb, height, width);
-
- if (command == SILCPURPLE_WB_DRAW) {
- /* Parse data and draw it */
- ret = silc_buffer_unformat(&buf,
- SILC_STR_UI_INT(&dx),
- SILC_STR_UI_INT(&dy),
- SILC_STR_END);
- if (ret < 0)
- return;
- silc_buffer_pull(&buf, 8);
- x = dx;
- y = dy;
- while (buf.len > 0) {
- ret = silc_buffer_unformat(&buf,
- SILC_STR_UI_INT(&dx),
- SILC_STR_UI_INT(&dy),
- SILC_STR_END);
- if (ret < 0)
- return;
- silc_buffer_pull(&buf, 8);
-
- purple_whiteboard_draw_line(wb, x, y, x + dx, y + dy,
- brush_color, brush_size);
- x += dx;
- y += dy;
- }
- }
-
- if (command == SILCPURPLE_WB_CLEAR)
- purple_whiteboard_clear(wb);
-}
-
-typedef struct {
- unsigned char *message;
- SilcUInt32 message_len;
- SilcPurple sg;
- SilcClientEntry sender;
- SilcChannelEntry channel;
-} *SilcPurpleWbRequest;
-
-static void
-silcpurple_wb_request_cb(SilcPurpleWbRequest req, gint id)
-{
- PurpleWhiteboard *wb;
-
- if (id != 1)
- goto out;
-
- if (!req->channel)
- wb = silcpurple_wb_init(req->sg, req->sender);
- else
- wb = silcpurple_wb_init_ch(req->sg, req->channel);
-
- silcpurple_wb_parse(wb->proto_data, wb, req->message, req->message_len);
-
- out:
- silc_free(req->message);
- silc_free(req);
-}
-
-static void
-silcpurple_wb_request(SilcClient client, const unsigned char *message,
- SilcUInt32 message_len, SilcClientEntry sender,
- SilcChannelEntry channel)
-{
- char tmp[128];
- SilcPurpleWbRequest req;
- PurpleConnection *gc;
- SilcPurple sg;
-
- gc = client->application;
- sg = gc->proto_data;
-
- /* Open whiteboard automatically if requested */
- if (purple_account_get_bool(sg->account, "open-wb", FALSE)) {
- PurpleWhiteboard *wb;
-
- if (!channel)
- wb = silcpurple_wb_init(sg, sender);
- else
- wb = silcpurple_wb_init_ch(sg, channel);
-
- silcpurple_wb_parse(wb->proto_data, wb, (unsigned char *)message,
- message_len);
- return;
- }
-
- /* Close any previous unaccepted requests */
- purple_request_close_with_handle(sender);
-
- if (!channel) {
- g_snprintf(tmp, sizeof(tmp),
- _("%s sent message to whiteboard. Would you like "
- "to open the whiteboard?"), sender->nickname);
- } else {
- g_snprintf(tmp, sizeof(tmp),
- _("%s sent message to whiteboard on %s channel. "
- "Would you like to open the whiteboard?"),
- sender->nickname, channel->channel_name);
- }
-
- req = silc_calloc(1, sizeof(*req));
- if (!req)
- return;
- req->message = silc_memdup(message, message_len);
- req->message_len = message_len;
- req->sender = sender;
- req->channel = channel;
- req->sg = sg;
-
- purple_request_action(sender, _("Whiteboard"), tmp, NULL, 1,
- sg->account, sender->nickname, NULL, req, 2,
- _("Yes"), G_CALLBACK(silcpurple_wb_request_cb),
- _("No"), G_CALLBACK(silcpurple_wb_request_cb));
-}
-
-/* Process incoming whiteboard message */
-
-void silcpurple_wb_receive(SilcClient client, SilcClientConnection conn,
- SilcClientEntry sender, SilcMessagePayload payload,
- SilcMessageFlags flags, const unsigned char *message,
- SilcUInt32 message_len)
-{
- SilcPurple sg;
- PurpleConnection *gc;
- PurpleWhiteboard *wb;
- SilcPurpleWb wbs;
-
- gc = client->application;
- sg = gc->proto_data;
-
- wb = purple_whiteboard_get_session(sg->account, sender->nickname);
- if (!wb) {
- /* Ask user if they want to open the whiteboard */
- silcpurple_wb_request(client, message, message_len,
- sender, NULL);
- return;
- }
-
- wbs = wb->proto_data;
- silcpurple_wb_parse(wbs, wb, (unsigned char *)message, message_len);
-}
-
-/* Process incoming whiteboard message on channel */
-
-void silcpurple_wb_receive_ch(SilcClient client, SilcClientConnection conn,
- SilcClientEntry sender, SilcChannelEntry channel,
- SilcMessagePayload payload,
- SilcMessageFlags flags,
- const unsigned char *message,
- SilcUInt32 message_len)
-{
- SilcPurple sg;
- PurpleConnection *gc;
- PurpleWhiteboard *wb;
- SilcPurpleWb wbs;
-
- gc = client->application;
- sg = gc->proto_data;
-
- wb = purple_whiteboard_get_session(sg->account, channel->channel_name);
- if (!wb) {
- /* Ask user if they want to open the whiteboard */
- silcpurple_wb_request(client, message, message_len,
- sender, channel);
- return;
- }
-
- wbs = wb->proto_data;
- silcpurple_wb_parse(wbs, wb, (unsigned char *)message, message_len);
-}
-
-/* Send whiteboard message */
-
-void silcpurple_wb_send(PurpleWhiteboard *wb, GList *draw_list)
-{
- SilcPurpleWb wbs = wb->proto_data;
- SilcBuffer packet;
- GList *list;
- int len;
- PurpleConnection *gc;
- SilcPurple sg;
-
- g_return_if_fail(draw_list);
- gc = purple_account_get_connection(wb->account);
- g_return_if_fail(gc);
- sg = gc->proto_data;
- g_return_if_fail(sg);
-
- len = SILCPURPLE_WB_HEADER;
- for (list = draw_list; list; list = list->next)
- len += 4;
-
- packet = silc_buffer_alloc_size(len);
- if (!packet)
- return;
-
- /* Assmeble packet */
- silc_buffer_format(packet,
- SILC_STR_UI32_STRING(SILCPURPLE_WB_MIME),
- SILC_STR_UI_CHAR(SILCPURPLE_WB_DRAW),
- SILC_STR_UI_SHORT(wbs->width),
- SILC_STR_UI_SHORT(wbs->height),
- SILC_STR_UI_INT(wbs->brush_color),
- SILC_STR_UI_SHORT(wbs->brush_size),
- SILC_STR_END);
- silc_buffer_pull(packet, SILCPURPLE_WB_HEADER);
- for (list = draw_list; list; list = list->next) {
- silc_buffer_format(packet,
- SILC_STR_UI_INT(GPOINTER_TO_INT(list->data)),
- SILC_STR_END);
- silc_buffer_pull(packet, 4);
- }
-
- /* Send the message */
- if (wbs->type == 0) {
- /* Private message */
- silc_client_send_private_message(sg->client, sg->conn,
- wbs->u.client,
- SILC_MESSAGE_FLAG_DATA,
- packet->head, len, TRUE);
- } else if (wbs->type == 1) {
- /* Channel message. Channel private keys are not supported. */
- silc_client_send_channel_message(sg->client, sg->conn,
- wbs->u.channel, NULL,
- SILC_MESSAGE_FLAG_DATA,
- packet->head, len, TRUE);
- }
-
- silc_buffer_free(packet);
-}
-
-/* Purple Whiteboard operations */
-
-void silcpurple_wb_start(PurpleWhiteboard *wb)
-{
- /* Nothing here. Everything is in initialization */
-}
-
-void silcpurple_wb_end(PurpleWhiteboard *wb)
-{
- silc_free(wb->proto_data);
- wb->proto_data = NULL;
-}
-
-void silcpurple_wb_get_dimensions(const PurpleWhiteboard *wb, int *width, int *height)
-{
- SilcPurpleWb wbs = wb->proto_data;
- *width = wbs->width;
- *height = wbs->height;
-}
-
-void silcpurple_wb_set_dimensions(PurpleWhiteboard *wb, int width, int height)
-{
- SilcPurpleWb wbs = wb->proto_data;
- wbs->width = width > SILCPURPLE_WB_WIDTH_MAX ? SILCPURPLE_WB_WIDTH_MAX :
- width;
- wbs->height = height > SILCPURPLE_WB_HEIGHT_MAX ? SILCPURPLE_WB_HEIGHT_MAX :
- height;
-
- /* Update whiteboard */
- purple_whiteboard_set_dimensions(wb, wbs->width, wbs->height);
-}
-
-void silcpurple_wb_get_brush(const PurpleWhiteboard *wb, int *size, int *color)
-{
- SilcPurpleWb wbs = wb->proto_data;
- *size = wbs->brush_size;
- *color = wbs->brush_color;
-}
-
-void silcpurple_wb_set_brush(PurpleWhiteboard *wb, int size, int color)
-{
- SilcPurpleWb wbs = wb->proto_data;
- wbs->brush_size = size;
- wbs->brush_color = color;
-
- /* Update whiteboard */
- purple_whiteboard_set_brush(wb, size, color);
-}
-
-void silcpurple_wb_clear(PurpleWhiteboard *wb)
-{
- SilcPurpleWb wbs = wb->proto_data;
- SilcBuffer packet;
- int len;
- PurpleConnection *gc;
- SilcPurple sg;
-
- gc = purple_account_get_connection(wb->account);
- g_return_if_fail(gc);
- sg = gc->proto_data;
- g_return_if_fail(sg);
-
- len = SILCPURPLE_WB_HEADER;
- packet = silc_buffer_alloc_size(len);
- if (!packet)
- return;
-
- /* Assmeble packet */
- silc_buffer_format(packet,
- SILC_STR_UI32_STRING(SILCPURPLE_WB_MIME),
- SILC_STR_UI_CHAR(SILCPURPLE_WB_CLEAR),
- SILC_STR_UI_SHORT(wbs->width),
- SILC_STR_UI_SHORT(wbs->height),
- SILC_STR_UI_INT(wbs->brush_color),
- SILC_STR_UI_SHORT(wbs->brush_size),
- SILC_STR_END);
-
- /* Send the message */
- if (wbs->type == 0) {
- /* Private message */
- silc_client_send_private_message(sg->client, sg->conn,
- wbs->u.client,
- SILC_MESSAGE_FLAG_DATA,
- packet->head, len, TRUE);
- } else if (wbs->type == 1) {
- /* Channel message */
- silc_client_send_channel_message(sg->client, sg->conn,
- wbs->u.channel, NULL,
- SILC_MESSAGE_FLAG_DATA,
- packet->head, len, TRUE);
- }
-
- silc_buffer_free(packet);
-}
diff --git a/libpurple/protocols/silc10/wb.h b/libpurple/protocols/silc10/wb.h
deleted file mode 100644
index 5ad0bf6fdd..0000000000
--- a/libpurple/protocols/silc10/wb.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-
- silcpurple.h
-
- Author: Pekka Riikonen <priikone@silcnet.org>
-
- Copyright (C) 2005 Pekka Riikonen
-
- 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; version 2 of the License.
-
- 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.
-
-*/
-
-#ifndef SILCPURPLE_WB_H
-#define SILCPURPLE_WB_H
-
-#include "silcpurple.h"
-#include "whiteboard.h"
-
-PurpleWhiteboard *
-silcpurple_wb_init(SilcPurple sg, SilcClientEntry client_entry);
-PurpleWhiteboard *
-silcpurple_wb_init_ch(SilcPurple sg, SilcChannelEntry channel);
-void silcpurple_wb_receive(SilcClient client, SilcClientConnection conn,
- SilcClientEntry sender, SilcMessagePayload payload,
- SilcMessageFlags flags, const unsigned char *message,
- SilcUInt32 message_len);
-void silcpurple_wb_receive_ch(SilcClient client, SilcClientConnection conn,
- SilcClientEntry sender, SilcChannelEntry channel,
- SilcMessagePayload payload,
- SilcMessageFlags flags,
- const unsigned char *message,
- SilcUInt32 message_len);
-void silcpurple_wb_start(PurpleWhiteboard *wb);
-void silcpurple_wb_end(PurpleWhiteboard *wb);
-void silcpurple_wb_get_dimensions(const PurpleWhiteboard *wb, int *width, int *height);
-void silcpurple_wb_set_dimensions(PurpleWhiteboard *wb, int width, int height);
-void silcpurple_wb_get_brush(const PurpleWhiteboard *wb, int *size, int *color);
-void silcpurple_wb_set_brush(PurpleWhiteboard *wb, int size, int color);
-void silcpurple_wb_send(PurpleWhiteboard *wb, GList *draw_list);
-void silcpurple_wb_clear(PurpleWhiteboard *wb);
-
-#endif /* SILCPURPLE_WB_H */
diff --git a/libpurple/protocols/simple/simple.c b/libpurple/protocols/simple/simple.c
index b7509118e1..706aa646a7 100644
--- a/libpurple/protocols/simple/simple.c
+++ b/libpurple/protocols/simple/simple.c
@@ -67,7 +67,7 @@ static const char *simple_list_icon(PurpleAccount *a, PurpleBuddy *b) {
}
static void simple_keep_alive(PurpleConnection *gc) {
- struct simple_account_data *sip = gc->proto_data;
+ struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
if(sip->udp) { /* in case of UDP send a packet only with a 0 byte to
remain in the NAT table */
gchar buf[2] = {0, 0};
@@ -100,14 +100,15 @@ static void do_notifies(struct simple_account_data *sip) {
}
static void simple_set_status(PurpleAccount *account, PurpleStatus *status) {
+ PurpleConnection *gc = purple_account_get_connection(account);
PurpleStatusPrimitive primitive = purple_status_type_get_primitive(purple_status_get_type(status));
struct simple_account_data *sip = NULL;
if (!purple_status_is_active(status))
return;
- if (account->gc)
- sip = account->gc->proto_data;
+ if (gc)
+ sip = purple_connection_get_protocol_data(gc);
if (sip)
{
@@ -192,9 +193,9 @@ static void connection_free_all(struct simple_account_data *sip) {
}
}
-static void simple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
+static void simple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, const char *message)
{
- struct simple_account_data *sip = (struct simple_account_data *)gc->proto_data;
+ struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
struct simple_buddy *b;
const char *name = purple_buddy_get_name(buddy);
if(strncmp(name, "sip:", 4)) {
@@ -222,7 +223,7 @@ static void simple_get_buddies(PurpleConnection *gc) {
buddies = purple_find_buddies(account, NULL);
while (buddies) {
PurpleBuddy *buddy = buddies->data;
- simple_add_buddy(gc, buddy, purple_buddy_get_group(buddy));
+ simple_add_buddy(gc, buddy, purple_buddy_get_group(buddy), NULL);
buddies = g_slist_delete_link(buddies, buddies);
}
@@ -231,7 +232,7 @@ static void simple_get_buddies(PurpleConnection *gc) {
static void simple_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
{
const char *name = purple_buddy_get_name(buddy);
- struct simple_account_data *sip = (struct simple_account_data *)gc->proto_data;
+ struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
struct simple_buddy *b = g_hash_table_lookup(sip->buddies, name);
g_hash_table_remove(sip->buddies, name);
g_free(b->name);
@@ -412,7 +413,7 @@ static void fill_auth(struct simple_account_data *sip, const gchar *hdr, struct
static void simple_canwrite_cb(gpointer data, gint source, PurpleInputCondition cond) {
PurpleConnection *gc = data;
- struct simple_account_data *sip = gc->proto_data;
+ struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
gsize max_write;
gssize written;
@@ -432,7 +433,7 @@ static void simple_canwrite_cb(gpointer data, gint source, PurpleInputCondition
/*TODO: do we really want to disconnect on a failure to write?*/
gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
g_strerror(errno));
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
@@ -451,13 +452,13 @@ static void send_later_cb(gpointer data, gint source, const gchar *error_message
if(source < 0) {
gchar *tmp = g_strdup_printf(_("Unable to connect: %s"),
error_message);
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
}
- sip = gc->proto_data;
+ sip = purple_connection_get_protocol_data(gc);
sip->fd = source;
sip->connecting = FALSE;
@@ -474,12 +475,12 @@ static void send_later_cb(gpointer data, gint source, const gchar *error_message
static void sendlater(PurpleConnection *gc, const char *buf) {
- struct simple_account_data *sip = gc->proto_data;
+ struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
if(!sip->connecting) {
purple_debug_info("simple", "connecting to %s port %d\n", sip->realhostname ? sip->realhostname : "{NULL}", sip->realport);
if (purple_proxy_connect(gc, sip->account, sip->realhostname, sip->realport, send_later_cb, gc) == NULL) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect"));
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect"));
}
sip->connecting = TRUE;
}
@@ -491,7 +492,7 @@ static void sendlater(PurpleConnection *gc, const char *buf) {
}
static void sendout_pkt(PurpleConnection *gc, const char *buf) {
- struct simple_account_data *sip = gc->proto_data;
+ struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
time_t currtime = time(NULL);
int writelen = strlen(buf);
@@ -629,7 +630,7 @@ static struct transaction *transactions_find(struct simple_account_data *sip, st
static void send_sip_request(PurpleConnection *gc, const gchar *method,
const gchar *url, const gchar *to, const gchar *addheaders,
const gchar *body, struct sip_dialog *dialog, TransCallback tc) {
- struct simple_account_data *sip = gc->proto_data;
+ struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
char *callid = dialog ? g_strdup(dialog->callid) : gencallid();
char *auth = NULL;
const char *addh = "";
@@ -1026,7 +1027,7 @@ static void simple_send_message(struct simple_account_data *sip, const char *to,
}
static int simple_im_send(PurpleConnection *gc, const char *who, const char *what, PurpleMessageFlags flags) {
- struct simple_account_data *sip = gc->proto_data;
+ struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
char *to = g_strdup(who);
char *text = purple_unescape_html(what);
simple_send_message(sip, to, text, NULL);
@@ -1120,9 +1121,9 @@ gboolean process_register_response(struct simple_account_data *sip, struct sipms
if(sip->registerstatus != SIMPLE_REGISTER_RETRY) {
purple_debug_info("simple", "REGISTER retries %d\n", sip->registrar.retries);
if(sip->registrar.retries > SIMPLE_REGISTER_RETRY_MAX) {
- if (!purple_account_get_remember_password(sip->gc->account))
- purple_account_set_password(sip->gc->account, NULL);
- purple_connection_error_reason(sip->gc,
+ if (!purple_account_get_remember_password(purple_connection_get_account(sip->gc)))
+ purple_account_set_password(purple_connection_get_account(sip->gc), NULL);
+ purple_connection_error(sip->gc,
PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
_("Incorrect password"));
return TRUE;
@@ -1137,7 +1138,7 @@ gboolean process_register_response(struct simple_account_data *sip, struct sipms
if (sip->registerstatus != SIMPLE_REGISTER_RETRY) {
purple_debug_info("simple", "Unrecognized return code for REGISTER.\n");
if (sip->registrar.retries > SIMPLE_REGISTER_RETRY_MAX) {
- purple_connection_error_reason(sip->gc,
+ purple_connection_error(sip->gc,
PURPLE_CONNECTION_ERROR_OTHER_ERROR,
_("Unknown server response"));
return TRUE;
@@ -1285,7 +1286,7 @@ static void process_incoming_notify(struct simple_account_data *sip, struct sipm
}
static unsigned int simple_typing(PurpleConnection *gc, const char *name, PurpleTypingState state) {
- struct simple_account_data *sip = gc->proto_data;
+ struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
gchar *xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<isComposing xmlns=\"urn:ietf:params:xml:ns:im-iscomposing\"\n"
@@ -1661,7 +1662,7 @@ static void process_input(struct simple_account_data *sip, struct sip_connection
static void simple_udp_process(gpointer data, gint source, PurpleInputCondition con) {
PurpleConnection *gc = data;
- struct simple_account_data *sip = gc->proto_data;
+ struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
struct sipmsg *msg;
int len;
time_t currtime = time(NULL);
@@ -1681,7 +1682,7 @@ static void simple_udp_process(gpointer data, gint source, PurpleInputCondition
static void simple_input_cb(gpointer data, gint source, PurpleInputCondition cond)
{
PurpleConnection *gc = data;
- struct simple_account_data *sip = gc->proto_data;
+ struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
int len;
struct sip_connection *conn = connection_find(sip, source);
if(!conn) {
@@ -1704,7 +1705,7 @@ static void simple_input_cb(gpointer data, gint source, PurpleInputCondition con
if(sip->fd == source) sip->fd = -1;
return;
}
- gc->last_received = time(NULL);
+ purple_connection_update_last_received(gc);
conn->inbufused += len;
conn->inbuf[conn->inbufused] = '\0';
@@ -1714,7 +1715,7 @@ static void simple_input_cb(gpointer data, gint source, PurpleInputCondition con
/* Callback for new connections on incoming TCP port */
static void simple_newconn_cb(gpointer data, gint source, PurpleInputCondition cond) {
PurpleConnection *gc = data;
- struct simple_account_data *sip = gc->proto_data;
+ struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
struct sip_connection *conn;
int newfd, flags;
@@ -1739,13 +1740,13 @@ static void login_cb(gpointer data, gint source, const gchar *error_message) {
if(source < 0) {
gchar *tmp = g_strdup_printf(_("Unable to connect: %s"),
error_message);
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
}
- sip = gc->proto_data;
+ sip = purple_connection_get_protocol_data(gc);
sip->fd = source;
conn = connection_create(sip, source);
@@ -1775,7 +1776,7 @@ static void simple_udp_host_resolved_listen_cb(int listenfd, gpointer data) {
sip->listen_data = NULL;
if(listenfd == -1) {
- purple_connection_error_reason(sip->gc,
+ purple_connection_error(sip->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to create listen socket"));
return;
@@ -1804,7 +1805,7 @@ static void simple_udp_host_resolved(GSList *hosts, gpointer data, const char *e
sip->query_data = NULL;
if (!hosts || !hosts->data) {
- purple_connection_error_reason(sip->gc,
+ purple_connection_error(sip->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to resolve hostname"));
return;
@@ -1822,10 +1823,10 @@ static void simple_udp_host_resolved(GSList *hosts, gpointer data, const char *e
}
/* create socket for incoming connections */
- sip->listen_data = purple_network_listen_range(5060, 5160, SOCK_DGRAM,
+ sip->listen_data = purple_network_listen_range(5060, 5160, AF_UNSPEC, SOCK_DGRAM, TRUE,
simple_udp_host_resolved_listen_cb, sip);
if (sip->listen_data == NULL) {
- purple_connection_error_reason(sip->gc,
+ purple_connection_error(sip->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to create listen socket"));
return;
@@ -1840,7 +1841,7 @@ simple_tcp_connect_listen_cb(int listenfd, gpointer data) {
sip->listenfd = listenfd;
if(sip->listenfd == -1) {
- purple_connection_error_reason(sip->gc,
+ purple_connection_error(sip->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to create listen socket"));
return;
@@ -1855,7 +1856,7 @@ simple_tcp_connect_listen_cb(int listenfd, gpointer data) {
/* open tcp connection to the server */
if (purple_proxy_connect(sip->gc, sip->account, sip->realhostname,
sip->realport, login_cb, sip->gc) == NULL) {
- purple_connection_error_reason(sip->gc,
+ purple_connection_error(sip->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect"));
}
@@ -1892,10 +1893,10 @@ static void srvresolved(PurpleSrvResponse *resp, int results, gpointer data) {
/* TCP case */
if(!sip->udp) {
/* create socket for incoming connections */
- sip->listen_data = purple_network_listen_range(5060, 5160, SOCK_STREAM,
+ sip->listen_data = purple_network_listen_range(5060, 5160, AF_UNSPEC, SOCK_STREAM, TRUE,
simple_tcp_connect_listen_cb, sip);
if (sip->listen_data == NULL) {
- purple_connection_error_reason(sip->gc,
+ purple_connection_error(sip->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to create listen socket"));
return;
@@ -1903,10 +1904,10 @@ static void srvresolved(PurpleSrvResponse *resp, int results, gpointer data) {
} else { /* UDP */
purple_debug_info("simple", "using udp with server %s and port %d\n", hostname, port);
- sip->query_data = purple_dnsquery_a_account(sip->account, hostname,
+ sip->query_data = purple_dnsquery_a(sip->account, hostname,
port, simple_udp_host_resolved, sip);
if (sip->query_data == NULL) {
- purple_connection_error_reason(sip->gc,
+ purple_connection_error(sip->gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to resolve hostname"));
}
@@ -1924,13 +1925,14 @@ static void simple_login(PurpleAccount *account)
gc = purple_account_get_connection(account);
if (strpbrk(username, " \t\v\r\n") != NULL) {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
_("SIP usernames may not contain whitespaces or @ symbols"));
return;
}
- gc->proto_data = sip = g_new0(struct simple_account_data, 1);
+ sip = g_new0(struct simple_account_data, 1);
+ purple_connection_set_protocol_data(gc, sip);
sip->gc = gc;
sip->fd = -1;
sip->listenfd = -1;
@@ -1943,7 +1945,7 @@ static void simple_login(PurpleAccount *account)
userserver = g_strsplit(username, "@", 2);
if (userserver[1] == NULL || userserver[1][0] == '\0') {
- purple_connection_error_reason(gc,
+ purple_connection_error(gc,
PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
_("SIP connect server not specified"));
return;
@@ -1968,13 +1970,13 @@ static void simple_login(PurpleAccount *account)
hosttoconnect = purple_account_get_string(account, "proxy", sip->servername);
}
- sip->srv_query_data = purple_srv_resolve_account(account, "sip",
+ sip->srv_query_data = purple_srv_resolve(account, "sip",
sip->udp ? "udp" : "tcp", hosttoconnect, srvresolved, sip);
}
static void simple_close(PurpleConnection *gc)
{
- struct simple_account_data *sip = gc->proto_data;
+ struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
if (!sip)
return;
@@ -2005,7 +2007,7 @@ static void simple_close(PurpleConnection *gc)
purple_dnsquery_destroy(sip->query_data);
if (sip->srv_query_data != NULL)
- purple_srv_cancel(sip->srv_query_data);
+ purple_srv_txt_query_destroy(sip->srv_query_data);
if (sip->listen_data != NULL)
purple_network_listen_cancel(sip->listen_data);
@@ -2039,11 +2041,12 @@ static void simple_close(PurpleConnection *gc)
g_free(sip->realhostname);
g_free(sip);
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
}
static PurplePluginProtocolInfo prpl_info =
{
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
0,
NULL, /* user_splits */
NULL, /* protocol_options */
@@ -2084,7 +2087,6 @@ static PurplePluginProtocolInfo prpl_info =
simple_keep_alive, /* keepalive */
NULL, /* register_user */
NULL, /* get_cb_info */
- NULL, /* get_cb_away */
NULL, /* alias_buddy */
NULL, /* group_buddy */
NULL, /* rename_group */
@@ -2109,15 +2111,12 @@ static PurplePluginProtocolInfo prpl_info =
NULL, /* unregister_user */
NULL, /* send_attention */
NULL, /* get_attention_types */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
NULL, /* get_account_text_table */
NULL, /* initiate_media */
NULL, /* get_media_caps */
NULL, /* get_moods */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */
};
diff --git a/libpurple/protocols/yahoo/libyahoo.c b/libpurple/protocols/yahoo/libyahoo.c
index 4e3d5ce263..0233bfe98c 100644
--- a/libpurple/protocols/yahoo/libyahoo.c
+++ b/libpurple/protocols/yahoo/libyahoo.c
@@ -194,6 +194,7 @@ static PurpleWhiteboardPrplOps yahoo_whiteboard_prpl_ops =
static PurplePluginProtocolInfo prpl_info =
{
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
OPT_PROTO_MAIL_CHECK | OPT_PROTO_CHAT_TOPIC,
NULL, /* user_splits */
NULL, /* protocol_options */
@@ -234,7 +235,6 @@ static PurplePluginProtocolInfo prpl_info =
yahoo_keepalive,
NULL, /* register_user */
NULL, /* get_cb_info */
- NULL, /* get_cb_away */
yahoo_update_alias, /* alias_buddy */
yahoo_change_buddys_group,
yahoo_rename_group,
@@ -257,19 +257,14 @@ static PurplePluginProtocolInfo prpl_info =
NULL, /* send_raw */
NULL, /* roomlist_room_serialize */
NULL, /* unregister_user */
-
yahoo_send_attention,
yahoo_attention_types,
-
- sizeof(PurplePluginProtocolInfo), /* struct_size */
yahoo_get_account_text_table, /* get_account_text_table */
NULL, /* initiate_media */
NULL, /* get_media_caps */
NULL, /* get_moods */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */
};
static PurplePluginInfo info =
diff --git a/libpurple/protocols/yahoo/libyahoojp.c b/libpurple/protocols/yahoo/libyahoojp.c
index 219603c1fa..c06fd81f28 100644
--- a/libpurple/protocols/yahoo/libyahoojp.c
+++ b/libpurple/protocols/yahoo/libyahoojp.c
@@ -90,6 +90,7 @@ static PurpleWhiteboardPrplOps yahoo_whiteboard_prpl_ops =
static PurplePluginProtocolInfo prpl_info =
{
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
OPT_PROTO_MAIL_CHECK | OPT_PROTO_CHAT_TOPIC,
NULL, /* user_splits */
NULL, /* protocol_options */
@@ -130,7 +131,6 @@ static PurplePluginProtocolInfo prpl_info =
yahoo_keepalive,
NULL, /* register_user */
NULL, /* get_cb_info */
- NULL, /* get_cb_away */
yahoo_update_alias, /* alias_buddy */
yahoo_change_buddys_group,
yahoo_rename_group,
@@ -157,15 +157,12 @@ static PurplePluginProtocolInfo prpl_info =
yahoo_send_attention,
yahoo_attention_types,
- sizeof(PurplePluginProtocolInfo), /* struct_size */
yahoojp_get_account_text_table, /* get_account_text_table */
NULL, /* initiate_media */
NULL, /* get_media_caps */
NULL, /* get_moods */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */
};
static PurplePluginInfo info =
diff --git a/libpurple/protocols/yahoo/libymsg.c b/libpurple/protocols/yahoo/libymsg.c
index 75092f8305..61736b9b6b 100644
--- a/libpurple/protocols/yahoo/libymsg.c
+++ b/libpurple/protocols/yahoo/libymsg.c
@@ -159,7 +159,7 @@ static void yahoo_process_status(PurpleConnection *gc, struct yahoo_packet *pkt)
if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) {
if (!purple_account_get_remember_password(account))
purple_account_set_password(account, NULL);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NAME_IN_USE,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NAME_IN_USE,
_("You have signed on from another location"));
return;
}
@@ -337,12 +337,12 @@ static void yahoo_process_status(PurpleConnection *gc, struct yahoo_packet *pkt)
if (!name)
break;
- b = purple_find_buddy(gc->account, name);
+ b = purple_find_buddy(purple_connection_get_account(gc), name);
if (!cksum || (cksum == -1)) {
if (f)
yahoo_friend_set_buddy_icon_need_request(f, TRUE);
- purple_buddy_icons_set_for_user(gc->account, name, NULL, 0, NULL);
+ purple_buddy_icons_set_for_user(purple_connection_get_account(gc), name, NULL, 0, NULL);
break;
}
@@ -496,7 +496,7 @@ static void yahoo_process_list_15(PurpleConnection *gc, struct yahoo_packet *pkt
GSList *l = pkt->hash;
PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
GHashTable *ht;
char *norm_bud = NULL;
char *temp = NULL;
@@ -573,7 +573,7 @@ static void yahoo_process_list_15(PurpleConnection *gc, struct yahoo_packet *pkt
yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_DO_NOT_CONNECT);
} else {
/* This buddy is on the ignore list (and therefore in no group) */
- purple_debug_info("yahoo", "%s adding %s to the deny list because of the ignore list / no group was found\n",account->username, norm_bud);
+ purple_debug_info("yahoo", "%s adding %s to the deny list because of the ignore list / no group was found\n", purple_account_get_username(account), norm_bud);
purple_privacy_deny_add(account, norm_bud, 1);
}
@@ -634,11 +634,10 @@ static void yahoo_process_list_15(PurpleConnection *gc, struct yahoo_packet *pkt
static void yahoo_process_list(PurpleConnection *gc, struct yahoo_packet *pkt)
{
GSList *l = pkt->hash;
- gboolean export = FALSE;
gboolean got_serv_list = FALSE;
YahooFriend *f = NULL;
PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
GHashTable *ht;
char **lines;
@@ -712,7 +711,6 @@ static void yahoo_process_list(PurpleConnection *gc, struct yahoo_packet *pkt)
}
b = purple_buddy_new(account, norm_bud, NULL);
purple_blist_add_buddy(b, NULL, g, NULL);
- export = TRUE;
}
yahoo_do_group_check(account, ht, norm_bud, grp);
@@ -748,13 +746,13 @@ static void yahoo_process_list(PurpleConnection *gc, struct yahoo_packet *pkt)
}
if (got_serv_list &&
- ((account->perm_deny != PURPLE_PRIVACY_ALLOW_BUDDYLIST) &&
- (account->perm_deny != PURPLE_PRIVACY_DENY_ALL) &&
- (account->perm_deny != PURPLE_PRIVACY_ALLOW_USERS)))
+ ((purple_account_get_privacy_type(account) != PURPLE_PRIVACY_ALLOW_BUDDYLIST) &&
+ (purple_account_get_privacy_type(account) != PURPLE_PRIVACY_DENY_ALL) &&
+ (purple_account_get_privacy_type(account) != PURPLE_PRIVACY_ALLOW_USERS)))
{
- account->perm_deny = PURPLE_PRIVACY_DENY_USERS;
+ purple_account_set_privacy_type(account, PURPLE_PRIVACY_DENY_USERS);
purple_debug_info("yahoo", "%s privacy defaulting to PURPLE_PRIVACY_DENY_USERS.\n",
- account->username);
+ purple_account_get_username(account));
}
if (yd->tmp_serv_plist) {
@@ -763,7 +761,7 @@ static void yahoo_process_list(PurpleConnection *gc, struct yahoo_packet *pkt)
f = yahoo_friend_find(gc, *bud);
if (f) {
purple_debug_info("yahoo", "%s setting presence for %s to PERM_OFFLINE\n",
- account->username, *bud);
+ purple_account_get_username(account), *bud);
f->presence = YAHOO_PRESENCE_PERM_OFFLINE;
}
}
@@ -787,7 +785,7 @@ static void yahoo_process_notify(PurpleConnection *gc, struct yahoo_packet *pkt,
YahooFriend *f = NULL;
GSList *l = pkt->hash;
gint val_11 = 0;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
YahooFederation fed = YAHOO_FEDERATION_NONE;
account = purple_connection_get_account(gc);
@@ -899,7 +897,7 @@ static void yahoo_process_sms_message(PurpleConnection *gc, struct yahoo_packet
char *server_msg = NULL;
char *m;
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
account = purple_connection_get_account(gc);
while (l != NULL) {
@@ -960,7 +958,7 @@ static void yahoo_process_sms_message(PurpleConnection *gc, struct yahoo_packet
static void yahoo_process_message(PurpleConnection *gc, struct yahoo_packet *pkt, yahoo_pkt_type pkt_type)
{
PurpleAccount *account;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
GSList *l = pkt->hash;
GSList *list = NULL;
struct _yahoo_im *im = NULL;
@@ -1061,7 +1059,7 @@ static void yahoo_process_message(PurpleConnection *gc, struct yahoo_packet *pkt
doodle_session *ds;
wb = purple_whiteboard_create(account, im->from,
DOODLE_STATE_REQUESTED);
- ds = wb->proto_data;
+ ds = purple_whiteboard_get_protocol_data(wb);
ds->imv_key = g_strdup(pair->value);
yahoo_doodle_command_send_request(gc, im->from, pair->value);
@@ -1202,7 +1200,7 @@ yahoo_buddy_add_authorize_cb(gpointer data)
{
struct yahoo_add_request *add_req = data;
struct yahoo_packet *pkt;
- YahooData *yd = add_req->gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(add_req->gc);
const char *who = add_req->who;
pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH_REQ_15, YAHOO_STATUS_AVAILABLE, yd->session_id);
@@ -1233,7 +1231,7 @@ yahoo_buddy_add_authorize_cb(gpointer data)
static void
yahoo_buddy_add_deny_cb(struct yahoo_add_request *add_req, const char *msg)
{
- YahooData *yd = add_req->gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(add_req->gc);
struct yahoo_packet *pkt;
char *encoded_msg = NULL;
const char *who = add_req->who;
@@ -1295,7 +1293,7 @@ yahoo_buddy_add_deny_reason_cb(gpointer data) {
static void yahoo_buddy_denied_our_add(PurpleConnection *gc, const char *who, const char *reason)
{
char *notify_msg;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
if (who == NULL)
return;
@@ -1625,7 +1623,7 @@ static char *yahoo_decode(const char *text)
static void yahoo_process_mail(PurpleConnection *gc, struct yahoo_packet *pkt)
{
PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
const char *who = NULL;
const char *email = NULL;
const char *subj = NULL;
@@ -1709,7 +1707,7 @@ static void to_y64(char *out, const unsigned char *in, gsize inlen)
static void yahoo_auth16_stage3(PurpleConnection *gc, const char *crypt)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
PurpleAccount *account = purple_connection_get_account(gc);
const char *name = purple_normalize(account, purple_account_get_username(account));
PurpleCipher *md5_cipher;
@@ -1803,7 +1801,7 @@ static void yahoo_auth16_stage2(PurpleUtilFetchUrlData *url_data, gpointer user_
if (error_message != NULL) {
purple_debug_error("yahoo", "Login Failed, unable to retrieve stage 2 url: %s\n", error_message);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message);
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message);
g_free(auth_data->seed);
g_free(auth_data);
return;
@@ -1890,7 +1888,7 @@ static void yahoo_auth16_stage2(PurpleUtilFetchUrlData *url_data, gpointer user_
if(error_reason) {
purple_debug_error("yahoo", "Authentication error: %s. "
"Code %d\n", error_reason, response_no);
- purple_connection_error_reason(gc, error, error_reason);
+ purple_connection_error(gc, error, error_reason);
g_free(error_reason);
g_free(auth_data->seed);
g_free(auth_data);
@@ -1919,7 +1917,7 @@ static void yahoo_auth16_stage1_cb(PurpleUtilFetchUrlData *url_data, gpointer us
if (error_message != NULL) {
purple_debug_error("yahoo", "Login Failed, unable to retrieve login url: %s\n", error_message);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message);
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message);
g_free(auth_data->seed);
g_free(auth_data);
return;
@@ -2000,7 +1998,7 @@ static void yahoo_auth16_stage1_cb(PurpleUtilFetchUrlData *url_data, gpointer us
}
purple_debug_error("yahoo", "Authentication error: %s. Code %d\n",
error_reason, response_no);
- purple_connection_error_reason(gc, error, error_reason);
+ purple_connection_error(gc, error, error_reason);
g_free(error_reason);
g_free(auth_data->seed);
g_free(auth_data);
@@ -2014,7 +2012,7 @@ static void yahoo_auth16_stage1_cb(PurpleUtilFetchUrlData *url_data, gpointer us
gboolean proxy_ssl = purple_account_get_bool(account, "proxy_ssl", FALSE);
url = g_strdup_printf(yahoojp ? YAHOOJP_LOGIN_URL : YAHOO_LOGIN_URL, token);
- url_data = purple_util_fetch_url_request_len_with_account(
+ url_data = purple_util_fetch_url_request(
proxy_ssl ? account : NULL, url, TRUE, YAHOO_CLIENT_USERAGENT,
TRUE, NULL, TRUE, -1, yahoo_auth16_stage2, auth_data);
if (url_data)
@@ -2040,7 +2038,7 @@ static void yahoo_auth16_stage1(PurpleConnection *gc, const char *seed)
purple_debug_info("yahoo", "Authentication: In yahoo_auth16_stage1\n");
if(!purple_ssl_is_supported()) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("SSL support unavailable"));
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("SSL support unavailable"));
return;
}
@@ -2055,7 +2053,7 @@ static void yahoo_auth16_stage1(PurpleConnection *gc, const char *seed)
g_free(encoded_password);
g_free(encoded_username);
- url_data = purple_util_fetch_url_request_len_with_account(
+ url_data = purple_util_fetch_url_request(
proxy_ssl ? account : NULL, url, TRUE,
YAHOO_CLIENT_USERAGENT, TRUE, NULL, FALSE, -1,
yahoo_auth16_stage1_cb, auth_data);
@@ -2180,12 +2178,12 @@ static void yahoo_process_ignore(PurpleConnection *gc, struct yahoo_packet *pkt)
who, (ignore ? "ignoring" : "unignoring"));
if (ignore) {
- b = purple_find_buddy(gc->account, who);
+ b = purple_find_buddy(purple_connection_get_account(gc), who);
g_snprintf(buf, sizeof(buf), _("You have tried to ignore %s, but the "
"user is on your buddy list. Clicking \"Yes\" "
"will remove and ignore the buddy."), who);
purple_request_yes_no(gc, NULL, _("Ignore buddy?"), buf, 0,
- gc->account, who, NULL,
+ purple_connection_get_account(gc), who, NULL,
b,
G_CALLBACK(ignore_buddy),
G_CALLBACK(keep_buddy));
@@ -2207,14 +2205,14 @@ static void yahoo_process_ignore(PurpleConnection *gc, struct yahoo_packet *pkt)
static void yahoo_process_authresp(PurpleConnection *gc, struct yahoo_packet *pkt)
{
#ifdef TRY_WEBMESSENGER_LOGIN
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
#endif /* TRY_WEBMESSENGER_LOGIN */
GSList *l = pkt->hash;
int err = 0;
char *msg;
char *url = NULL;
char *fullmsg;
- PurpleAccount *account = gc->account;
+ PurpleAccount *account = purple_connection_get_account(gc);
PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
while (l) {
@@ -2244,10 +2242,12 @@ static void yahoo_process_authresp(PurpleConnection *gc, struct yahoo_packet *pk
yd->wm = TRUE;
if (yd->fd >= 0)
close(yd->fd);
- if (gc->inpa)
- purple_input_remove(gc->inpa);
+ if (yd->inpa) {
+ purple_input_remove(yd->inpa);
+ yd->inpa = 0;
+ }
url_data = purple_util_fetch_url(WEBMESSENGER_URL, TRUE,
- "Purple/" VERSION, FALSE, yahoo_login_page_cb, gc);
+ "Purple/" VERSION, FALSE, -1, yahoo_login_page_cb, gc);
if (url_data != NULL)
yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
return;
@@ -2285,7 +2285,7 @@ static void yahoo_process_authresp(PurpleConnection *gc, struct yahoo_packet *pk
else
fullmsg = g_strdup(msg);
- purple_connection_error_reason(gc, reason, fullmsg);
+ purple_connection_error(gc, reason, fullmsg);
g_free(msg);
g_free(fullmsg);
}
@@ -2300,7 +2300,7 @@ static void yahoo_process_addbuddy(PurpleConnection *gc, struct yahoo_packet *pk
char *buf;
YahooFriend *f;
GSList *l = pkt->hash;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
YahooFederation fed = YAHOO_FEDERATION_NONE;
while (l) {
@@ -2394,7 +2394,7 @@ static void yahoo_p2p_keepalive_cb(gpointer key, gpointer value, gpointer user_d
PurpleConnection *gc = user_data;
struct yahoo_packet *pkt_to_send;
PurpleAccount *account;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
account = purple_connection_get_account(gc);
@@ -2413,7 +2413,7 @@ static void yahoo_p2p_keepalive_cb(gpointer key, gpointer value, gpointer user_d
static gboolean yahoo_p2p_keepalive(gpointer data)
{
PurpleConnection *gc = data;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
g_hash_table_foreach(yd->peers, yahoo_p2p_keepalive_cb, gc);
@@ -2460,7 +2460,7 @@ static void yahoo_p2p_process_p2pfilexfer(gpointer data, gint source, struct yah
if(!(p2p_data = data))
return ;
- yd = p2p_data->gc->proto_data;
+ yd = purple_connection_get_protocol_data(p2p_data->gc);
/* lets see whats in the packet */
while (l) {
@@ -2545,7 +2545,7 @@ static void yahoo_p2p_read_pkt_cb(gpointer data, gint source, PurpleInputConditi
if(!(p2p_data = data))
return ;
- yd = p2p_data->gc->proto_data;
+ yd = purple_connection_get_protocol_data(p2p_data->gc);
len = read(source, buf, sizeof(buf));
if ((len < 0) && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))
@@ -2617,7 +2617,7 @@ static void yahoo_p2p_server_send_connected_cb(gpointer data, gint source, Purpl
if(!(p2p_data = data))
return ;
- yd = p2p_data->gc->proto_data;
+ yd = purple_connection_get_protocol_data(p2p_data->gc);
acceptfd = accept(source, NULL, 0);
if(acceptfd == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
@@ -2657,7 +2657,7 @@ static gboolean yahoo_cancel_p2p_server_listen_cb(gpointer data)
if(!(p2p_data = data))
return FALSE;
- yd = p2p_data->gc->proto_data;
+ yd = purple_connection_get_protocol_data(p2p_data->gc);
purple_debug_warning("yahoo","yahoo p2p server timeout, peer failed to connect\n");
yahoo_p2p_disconnect_destroy_data(data);
@@ -2678,7 +2678,7 @@ static void yahoo_p2p_server_listen_cb(int listenfd, gpointer data)
if(!(p2p_data = data))
return ;
- yd = p2p_data->gc->proto_data;
+ yd = purple_connection_get_protocol_data(p2p_data->gc);
yd->listen_data = NULL;
if(listenfd == -1) {
@@ -2706,7 +2706,7 @@ void yahoo_send_p2p_pkt(PurpleConnection *gc, const char *who, int val_13)
YahooFriend *f;
struct yahoo_packet *pkt;
PurpleAccount *account;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_p2p_data *p2p_data;
const char *norm_username;
@@ -2770,7 +2770,7 @@ void yahoo_send_p2p_pkt(PurpleConnection *gc, const char *who, int val_13)
if (yd->listen_data)
purple_debug_warning("yahoo","p2p: Failed to create p2p server - server already exists\n");
else {
- yd->listen_data = purple_network_listen(YAHOO_PAGER_PORT_P2P, SOCK_STREAM, yahoo_p2p_server_listen_cb, p2p_data);
+ yd->listen_data = purple_network_listen(YAHOO_PAGER_PORT_P2P, AF_UNSPEC, SOCK_STREAM, TRUE, yahoo_p2p_server_listen_cb, p2p_data);
if (yd->listen_data == NULL)
purple_debug_warning("yahoo","p2p: Failed to created p2p server\n");
}
@@ -2787,7 +2787,7 @@ static void yahoo_p2p_init_cb(gpointer data, gint source, const gchar *error_mes
YahooData *yd;
p2p_data = data;
- yd = p2p_data->gc->proto_data;
+ yd = purple_connection_get_protocol_data(p2p_data->gc);
if(error_message != NULL) {
purple_debug_warning("yahoo","p2p: %s\n",error_message);
@@ -3132,7 +3132,7 @@ static void yahoo_packet_process(PurpleConnection *gc, struct yahoo_packet *pkt)
static void yahoo_pending(gpointer data, gint source, PurpleInputCondition cond)
{
PurpleConnection *gc = data;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
char buf[1024];
int len;
@@ -3147,15 +3147,15 @@ static void yahoo_pending(gpointer data, gint source, PurpleInputCondition cond)
tmp = g_strdup_printf(_("Lost connection with server: %s"),
g_strerror(errno));
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
} else if (len == 0) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Server closed the connection"));
return;
}
- gc->last_received = time(NULL);
+ purple_connection_update_last_received(gc);
yd->rxqueue = g_realloc(yd->rxqueue, len + yd->rxlen);
memcpy(yd->rxqueue + yd->rxlen, buf, len);
yd->rxlen += len;
@@ -3235,20 +3235,20 @@ static void yahoo_got_connected(gpointer data, gint source, const gchar *error_m
if (source < 0) {
gchar *tmp;
tmp = g_strdup_printf(_("Unable to connect: %s"), error_message);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
}
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
yd->fd = source;
pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, yd->current_status, yd->session_id);
- yahoo_packet_hash_str(pkt, 1, purple_normalize(gc->account, purple_account_get_username(purple_connection_get_account(gc))));
+ yahoo_packet_hash_str(pkt, 1, purple_normalize(purple_connection_get_account(gc), purple_account_get_username(purple_connection_get_account(gc))));
yahoo_packet_send_and_free(pkt, yd);
- gc->inpa = purple_input_add(yd->fd, PURPLE_INPUT_READ, yahoo_pending, gc);
+ yd->inpa = purple_input_add(yd->fd, PURPLE_INPUT_READ, yahoo_pending, gc);
}
#ifdef TRY_WEBMESSENGER_LOGIN
@@ -3261,31 +3261,31 @@ static void yahoo_got_web_connected(gpointer data, gint source, const gchar *err
if (source < 0) {
gchar *tmp;
tmp = g_strdup_printf(_("Unable to connect: %s"), error_message);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
}
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
yd->fd = source;
pkt = yahoo_packet_new(YAHOO_SERVICE_WEBLOGIN, YAHOO_STATUS_WEBLOGIN, yd->session_id);
yahoo_packet_hash(pkt, "sss", 0,
- purple_normalize(gc->account, purple_account_get_username(purple_connection_get_account(gc))),
- 1, purple_normalize(gc->account, purple_account_get_username(purple_connection_get_account(gc))),
+ purple_normalize(purple_connection_get_account(gc), purple_account_get_username(purple_connection_get_account(gc))),
+ 1, purple_normalize(purple_connection_get_account(gc), purple_account_get_username(purple_connection_get_account(gc))),
6, yd->auth);
yahoo_packet_send_and_free(pkt, yd);
g_free(yd->auth);
- gc->inpa = purple_input_add(yd->fd, PURPLE_INPUT_READ, yahoo_pending, gc);
+ yd->inpa = purple_input_add(yd->fd, PURPLE_INPUT_READ, yahoo_pending, gc);
}
static void yahoo_web_pending(gpointer data, gint source, PurpleInputCondition cond)
{
PurpleConnection *gc = data;
PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
char bufread[2048], *i = bufread, *buf = bufread;
int len;
GString *s;
@@ -3301,11 +3301,11 @@ static void yahoo_web_pending(gpointer data, gint source, PurpleInputCondition c
tmp = g_strdup_printf(_("Lost connection with server: %s"),
g_strerror(errno));
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
} else if (len == 0) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Server closed the connection"));
return;
}
@@ -3321,7 +3321,7 @@ static void yahoo_web_pending(gpointer data, gint source, PurpleInputCondition c
if ((strncmp(buf, "HTTP/1.0 302", strlen("HTTP/1.0 302")) &&
strncmp(buf, "HTTP/1.1 302", strlen("HTTP/1.1 302")))) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Received unexpected HTTP response from server"));
purple_debug_misc("yahoo", "Unexpected HTTP response: %s\n", buf);
return;
@@ -3342,7 +3342,8 @@ static void yahoo_web_pending(gpointer data, gint source, PurpleInputCondition c
}
yd->auth = g_string_free(s, FALSE);
- purple_input_remove(gc->inpa);
+ purple_input_remove(yd->inpa);
+ yd->inpa = 0;
close(source);
g_free(yd->rxqueue);
yd->rxqueue = NULL;
@@ -3351,7 +3352,7 @@ static void yahoo_web_pending(gpointer data, gint source, PurpleInputCondition c
if (purple_proxy_connect(gc, account, "wcs2.msg.dcn.yahoo.com",
purple_account_get_int(account, "port", YAHOO_PAGER_PORT),
yahoo_got_web_connected, gc) == NULL) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect"));
return;
}
@@ -3359,13 +3360,10 @@ static void yahoo_web_pending(gpointer data, gint source, PurpleInputCondition c
static void yahoo_got_cookies_send_cb(gpointer data, gint source, PurpleInputCondition cond)
{
- PurpleConnection *gc;
- YahooData *yd;
+ PurpleConnection *gc = data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
int written, remaining;
- gc = data;
- yd = gc->proto_data;
-
remaining = strlen(yd->auth) - yd->auth_written;
written = write(source, yd->auth + yd->auth_written, remaining);
@@ -3375,12 +3373,13 @@ static void yahoo_got_cookies_send_cb(gpointer data, gint source, PurpleInputCon
gchar *tmp;
g_free(yd->auth);
yd->auth = NULL;
- if (gc->inpa)
- purple_input_remove(gc->inpa);
- gc->inpa = 0;
+ if (yd->inpa) {
+ purple_input_remove(yd->inpa);
+ yd->inpa = 0;
+ }
tmp = g_strdup_printf(_("Lost connection with %s: %s"),
"login.yahoo.com:80", g_strerror(errno));
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
}
@@ -3393,26 +3392,27 @@ static void yahoo_got_cookies_send_cb(gpointer data, gint source, PurpleInputCon
g_free(yd->auth);
yd->auth = NULL;
yd->auth_written = 0;
- purple_input_remove(gc->inpa);
- gc->inpa = purple_input_add(source, PURPLE_INPUT_READ, yahoo_web_pending, gc);
+ purple_input_remove(yd->inpa);
+ yd->inpa = purple_input_add(source, PURPLE_INPUT_READ, yahoo_web_pending, gc);
}
static void yahoo_got_cookies(gpointer data, gint source, const gchar *error_message)
{
PurpleConnection *gc = data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
if (source < 0) {
gchar *tmp;
tmp = g_strdup_printf(_("Unable to establish a connection with %s: %s"),
"login.yahoo.com:80", error_message);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
return;
}
- if (gc->inpa == 0)
+ if (yd->inpa == 0)
{
- gc->inpa = purple_input_add(source, PURPLE_INPUT_WRITE,
+ yd->inpa = purple_input_add(source, PURPLE_INPUT_WRITE,
yahoo_got_cookies_send_cb, gc);
yahoo_got_cookies_send_cb(gc, source, PURPLE_INPUT_WRITE);
}
@@ -3474,7 +3474,7 @@ yahoo_login_page_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data,
{
PurpleConnection *gc = (PurpleConnection *)user_data;
PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
const char *sn = purple_account_get_username(account);
const char *pass = purple_connection_get_password(gc);
GHashTable *hash = yahoo_login_page_hash(url_text, len);
@@ -3489,7 +3489,7 @@ yahoo_login_page_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data,
if (error_message != NULL)
{
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
error_message);
return;
}
@@ -3539,7 +3539,7 @@ yahoo_login_page_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data,
g_hash_table_destroy(hash);
yd->auth = g_string_free(url, FALSE);
if (purple_proxy_connect(gc, account, "login.yahoo.com", 80, yahoo_got_cookies, gc) == NULL) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect"));
return;
}
@@ -3619,12 +3619,12 @@ static void yahoo_got_pager_server(PurpleUtilFetchUrlData *url_data,
error_message ? error_message : "(null)");
if(yahoo_is_japan(a)) { /* We don't know fallback hosts for Yahoo Japan :( */
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect: The server returned an empty response."));
} else {
if(purple_proxy_connect(gc, a, YAHOO_PAGER_HOST_FALLBACK, port,
yahoo_got_connected, gc) == NULL) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect"));
}
}
@@ -3646,20 +3646,20 @@ static void yahoo_got_pager_server(PurpleUtilFetchUrlData *url_data,
if(cs_server) { /* got an address; get on with connecting */
if(purple_proxy_connect(gc, a, cs_server, port, yahoo_got_connected, gc) == NULL)
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect"));
} else {
purple_debug_error("yahoo", "No CS address retrieved! Server "
"response:\n%s\n", url_text ? url_text : "(null)");
if(yahoo_is_japan(a)) { /* We don't know fallback hosts for Yahoo Japan :( */
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect: The server's response did not contain "
"the necessary information"));
} else
if(purple_proxy_connect(gc, a, YAHOO_PAGER_HOST_FALLBACK, port,
yahoo_got_connected, gc) == NULL) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to connect"));
}
}
@@ -3671,13 +3671,14 @@ static void yahoo_got_pager_server(PurpleUtilFetchUrlData *url_data,
void yahoo_login(PurpleAccount *account) {
PurpleConnection *gc = purple_account_get_connection(account);
- YahooData *yd = gc->proto_data = g_new0(YahooData, 1);
+ YahooData *yd = g_new0(YahooData, 1);
PurpleStatus *status = purple_account_get_active_status(account);
gboolean use_whole_url = yahoo_account_use_http_proxy(gc);
gboolean proxy_ssl = purple_account_get_bool(account, "proxy_ssl", FALSE);
PurpleUtilFetchUrlData *url_data;
- gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC;
+ purple_connection_set_protocol_data(gc, yd);
+ purple_connection_set_flags(gc, PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC);
purple_connection_update_progress(gc, _("Connecting"), 1, 2);
@@ -3708,7 +3709,7 @@ void yahoo_login(PurpleAccount *account) {
/* Get the pager server. Actually start connecting in the callback since we
* must have the contents of the HTTP response to proceed. */
- url_data = purple_util_fetch_url_request_len_with_account(
+ url_data = purple_util_fetch_url_request(
proxy_ssl ? purple_connection_get_account(gc) : NULL,
yd->jp ? YAHOOJP_PAGER_HOST_REQ_URL : YAHOO_PAGER_HOST_REQ_URL,
use_whole_url ? TRUE : FALSE,
@@ -3721,11 +3722,13 @@ void yahoo_login(PurpleAccount *account) {
}
void yahoo_close(PurpleConnection *gc) {
- YahooData *yd = (YahooData *)gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
GSList *l;
- if (gc->inpa)
- purple_input_remove(gc->inpa);
+ if (yd->inpa) {
+ purple_input_remove(yd->inpa);
+ yd->inpa = 0;
+ }
while (yd->url_datas) {
purple_util_fetch_url_cancel(yd->url_datas->data);
@@ -3810,7 +3813,7 @@ void yahoo_close(PurpleConnection *gc) {
g_free(yd->current_list15_grp);
g_free(yd);
- gc->proto_data = NULL;
+ purple_connection_set_protocol_data(gc, NULL);
}
const char *yahoo_list_icon(PurpleAccount *a, PurpleBuddy *b)
@@ -3827,7 +3830,7 @@ const char *yahoo_list_emblem(PurpleBuddy *b)
if (!b || !(account = purple_buddy_get_account(b)) ||
!(gc = purple_account_get_connection(account)) ||
- !gc->proto_data)
+ !purple_connection_get_protocol_data(gc))
return NULL;
f = yahoo_friend_find(gc, purple_buddy_get_name(b));
@@ -3892,7 +3895,7 @@ static void yahoo_initiate_conference(PurpleBlistNode *node, gpointer data) {
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
id = yd->conf_id;
components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
@@ -4036,22 +4039,12 @@ void yahoo_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolea
if (f && full) {
YahooPersonalDetails *ypd = &f->ypd;
- int i;
- struct {
- char *id;
- char *text;
- char *value;
- } yfields[] = {
- {"hp", N_("Home Phone Number"), ypd->phone.home},
- {"wp", N_("Work Phone Number"), ypd->phone.work},
- {"mo", N_("Mobile Phone Number"), ypd->phone.mobile},
- {NULL, NULL, NULL}
- };
- for (i = 0; yfields[i].id; i++) {
- if (!yfields[i].value || !*yfields[i].value)
- continue;
- purple_notify_user_info_add_pair(user_info, _(yfields[i].text), yfields[i].value);
- }
+ if (ypd->phone.home && *ypd->phone.home)
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Home Phone Number"), ypd->phone.home);
+ if (ypd->phone.work && *ypd->phone.work)
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Work Phone Number"), ypd->phone.work);
+ if (ypd->phone.mobile && *ypd->phone.mobile)
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Mobile Phone Number"), ypd->phone.mobile);
}
}
@@ -4065,7 +4058,7 @@ static void yahoo_addbuddyfrommenu_cb(PurpleBlistNode *node, gpointer data)
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- yahoo_add_buddy(gc, buddy, NULL);
+ yahoo_add_buddy(gc, buddy, NULL, NULL);
}
@@ -4085,7 +4078,7 @@ static void yahoo_chat_goto_menu(PurpleBlistNode *node, gpointer data)
static GList *build_presence_submenu(YahooFriend *f, PurpleConnection *gc) {
GList *m = NULL;
PurpleMenuAction *act;
- YahooData *yd = (YahooData *) gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
if (yd->current_status == YAHOO_STATUS_INVISIBLE) {
if (f->presence != YAHOO_PRESENCE_ONLINE) {
@@ -4145,7 +4138,7 @@ static GList *yahoo_buddy_menu(PurpleBuddy *buddy)
PurpleMenuAction *act;
PurpleConnection *gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
static char buf2[1024];
YahooFriend *f;
@@ -4228,7 +4221,7 @@ GList *yahoo_blist_node_menu(PurpleBlistNode *node)
static void yahoo_act_id(PurpleConnection *gc, PurpleRequestFields *fields)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
const char *name = yd->profiles[purple_request_fields_get_choice(fields, "id")];
struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_IDACT, YAHOO_STATUS_AVAILABLE, yd->session_id);
@@ -4245,7 +4238,7 @@ yahoo_get_inbox_token_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data,
PurpleConnection *gc = user_data;
gboolean set_cookie = FALSE;
gchar *url;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc));
@@ -4281,7 +4274,7 @@ static void yahoo_show_inbox(PurplePluginAction *action)
/* XXX I have no idea how this will work with Yahoo! Japan. */
PurpleConnection *gc = action->context;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
PurpleUtilFetchUrlData *url_data;
const char* base_url = "http://login.yahoo.com";
@@ -4296,7 +4289,7 @@ static void yahoo_show_inbox(PurplePluginAction *action)
use_whole_url ? base_url : "",
yd->cookie_t, yd->cookie_y);
- url_data = purple_util_fetch_url_request_len_with_account(
+ url_data = purple_util_fetch_url_request(
purple_connection_get_account(gc), base_url, use_whole_url,
YAHOO_CLIENT_USERAGENT, TRUE, request, FALSE, -1,
yahoo_get_inbox_token_cb, gc);
@@ -4395,7 +4388,7 @@ static void yahoo_get_sms_carrier_cb(PurpleUtilFetchUrlData *url_data, gpointer
{
struct yahoo_sms_carrier_cb_data *sms_cb_data = user_data;
PurpleConnection *gc = sms_cb_data->gc;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
char *status = NULL;
char *carrier = NULL;
PurpleAccount *account = purple_connection_get_account(gc);
@@ -4450,7 +4443,7 @@ static void yahoo_get_sms_carrier_cb(PurpleUtilFetchUrlData *url_data, gpointer
static void yahoo_get_sms_carrier(PurpleConnection *gc, gpointer data)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
PurpleUtilFetchUrlData *url_data;
struct yahoo_sms_carrier_cb_data *sms_cb_data;
char *validate_request_str = NULL;
@@ -4485,10 +4478,10 @@ static void yahoo_get_sms_carrier(PurpleConnection *gc, gpointer data)
YAHOO_CLIENT_VERSION, yd->cookie_t, yd->cookie_y, strlen(validate_request_str), validate_request_str);
/* use whole URL if using HTTP Proxy */
- if ((gc->account->proxy_info) && (gc->account->proxy_info->type == PURPLE_PROXY_HTTP))
+ if ((purple_account_get_proxy_info(purple_connection_get_account(gc))) && (purple_proxy_info_get_type(purple_account_get_proxy_info(purple_connection_get_account(gc))) == PURPLE_PROXY_HTTP))
use_whole_url = TRUE;
- url_data = purple_util_fetch_url_request_len_with_account(
+ url_data = purple_util_fetch_url_request(
purple_connection_get_account(gc), YAHOO_SMS_CARRIER_URL, use_whole_url,
YAHOO_CLIENT_USERAGENT, TRUE, request, FALSE, -1,
yahoo_get_sms_carrier_cb, data);
@@ -4510,7 +4503,7 @@ static void yahoo_get_sms_carrier(PurpleConnection *gc, gpointer data)
int yahoo_send_im(PurpleConnection *gc, const char *who, const char *what, PurpleMessageFlags flags)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt = NULL;
char *msg = yahoo_html_to_codes(what);
char *msg2;
@@ -4621,7 +4614,7 @@ int yahoo_send_im(PurpleConnection *gc, const char *who, const char *what, Purpl
*
* If they have not set an IMVironment, then use the default.
*/
- wb = purple_whiteboard_get_session(gc->account, who);
+ wb = purple_whiteboard_get_session(purple_connection_get_account(gc), who);
if (wb)
yahoo_packet_hash_str(pkt, 63, DOODLE_IMV_KEY);
else
@@ -4667,7 +4660,7 @@ int yahoo_send_im(PurpleConnection *gc, const char *who, const char *what, Purpl
unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_p2p_data *p2p_data;
YahooFederation fed = YAHOO_FEDERATION_NONE;
struct yahoo_packet *pkt = NULL;
@@ -4738,7 +4731,7 @@ void yahoo_set_status(PurpleAccount *account, PurpleStatus *status)
gc = purple_account_get_connection(account);
presence = purple_status_get_presence(status);
- yd = (YahooData *)gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
old_status = yd->current_status;
yd->current_status = get_yahoo_status_from_purple_status(status);
@@ -4804,7 +4797,7 @@ void yahoo_set_status(PurpleAccount *account, PurpleStatus *status)
void yahoo_set_idle(PurpleConnection *gc, int idle)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt = NULL;
char *msg = NULL, *msg2 = NULL;
PurpleStatus *status = NULL;
@@ -4923,7 +4916,7 @@ GList *yahoo_status_types(PurpleAccount *account)
void yahoo_keepalive(PurpleConnection *gc)
{
struct yahoo_packet *pkt;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
time_t now = time(NULL);
/* We're only allowed to send a ping once an hour or the servers will boot us */
@@ -4954,9 +4947,9 @@ void yahoo_keepalive(PurpleConnection *gc)
}
-void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g)
+void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g, const char *message)
{
- YahooData *yd = (YahooData *)gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
const char *group = NULL;
char *group2;
@@ -5019,7 +5012,7 @@ void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g)
void yahoo_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
{
- YahooData *yd = (YahooData *)gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
GSList *buddies, *l;
PurpleGroup *g;
@@ -5075,7 +5068,7 @@ void yahoo_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g
}
void yahoo_add_deny(PurpleConnection *gc, const char *who) {
- YahooData *yd = (YahooData *)gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
YahooFederation fed = YAHOO_FEDERATION_NONE;
@@ -5098,7 +5091,7 @@ void yahoo_add_deny(PurpleConnection *gc, const char *who) {
}
void yahoo_rem_deny(PurpleConnection *gc, const char *who) {
- YahooData *yd = (YahooData *)gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
YahooFederation fed = YAHOO_FEDERATION_NONE;
@@ -5126,7 +5119,7 @@ void yahoo_set_permit_deny(PurpleConnection *gc)
account = purple_connection_get_account(gc);
- switch (account->perm_deny)
+ switch (purple_account_get_privacy_type(account))
{
case PURPLE_PRIVACY_ALLOW_ALL:
for (deny = account->deny; deny; deny = deny->next)
@@ -5146,7 +5139,7 @@ void yahoo_set_permit_deny(PurpleConnection *gc)
void yahoo_change_buddys_group(PurpleConnection *gc, const char *who,
const char *old_group, const char *new_group)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
char *gpn, *gpo;
YahooFriend *f = yahoo_friend_find(gc, who);
@@ -5193,7 +5186,7 @@ void yahoo_change_buddys_group(PurpleConnection *gc, const char *who,
void yahoo_rename_group(PurpleConnection *gc, const char *old_name,
PurpleGroup *group, GList *moved_buddies)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
char *gpn, *gpo;
@@ -5222,7 +5215,7 @@ yahoopurple_cmd_buzz(PurpleConversation *c, const gchar *cmd, gchar **args, gcha
if (*args && args[0])
return PURPLE_CMD_RET_FAILED;
- purple_prpl_send_attention(account->gc, c->name, YAHOO_BUZZ);
+ purple_prpl_send_attention(purple_account_get_connection(account), purple_conversation_get_name(c), YAHOO_BUZZ);
return PURPLE_CMD_RET_OK;
}
@@ -5237,7 +5230,7 @@ yahoopurple_cmd_chat_join(PurpleConversation *conv, const char *cmd,
if (!args || !args[0])
return PURPLE_CMD_RET_FAILED;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
purple_debug_info("yahoo", "Trying to join %s \n", args[0]);
comp = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
@@ -5271,12 +5264,12 @@ gboolean yahoo_send_attention(PurpleConnection *gc, const char *username, guint
PurpleConversation *c;
c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- username, gc->account);
+ username, purple_connection_get_account(gc));
g_return_val_if_fail(c != NULL, FALSE);
purple_debug_info("yahoo", "Sending <ding> on account %s to buddy %s.\n",
- username, c->name);
+ username, purple_conversation_get_name(c));
purple_conv_im_send_with_flags(PURPLE_CONV_IM(c), "<ding>", PURPLE_MESSAGE_INVISIBLE);
return TRUE;
diff --git a/libpurple/protocols/yahoo/libymsg.h b/libpurple/protocols/yahoo/libymsg.h
index 3dea10bfee..31bfade8d0 100644
--- a/libpurple/protocols/yahoo/libymsg.h
+++ b/libpurple/protocols/yahoo/libymsg.h
@@ -188,6 +188,7 @@ typedef struct _YahooPersonalDetails {
typedef struct {
PurpleConnection *gc;
int fd;
+ guint inpa;
guchar *rxqueue;
int rxlen;
PurpleCircBuffer *txbuf;
@@ -371,7 +372,7 @@ int yahoo_send_im(PurpleConnection *gc, const char *who, const char *what, Purpl
unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state);
void yahoo_set_status(PurpleAccount *account, PurpleStatus *status);
void yahoo_set_idle(PurpleConnection *gc, int idle);
-void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g);
+void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g, const char *message);
void yahoo_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group);
void yahoo_add_deny(PurpleConnection *gc, const char *who);
void yahoo_rem_deny(PurpleConnection *gc, const char *who);
diff --git a/libpurple/protocols/yahoo/util.c b/libpurple/protocols/yahoo/util.c
index bcfede658e..ab382af554 100644
--- a/libpurple/protocols/yahoo/util.c
+++ b/libpurple/protocols/yahoo/util.c
@@ -63,8 +63,9 @@ gchar* yahoo_get_cookies(PurpleConnection *gc)
char firstflag = 1;
gchar *t1,*t2,*t3;
GSList *tmp;
- GSList *cookies;
- cookies = ((YahooData*)(gc->proto_data))->cookies;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
+ GSList *cookies = yd->cookies;
+
tmp = cookies;
while(tmp)
{
@@ -129,7 +130,7 @@ gchar* yahoo_get_cookies(PurpleConnection *gc)
*/
char *yahoo_string_encode(PurpleConnection *gc, const char *str, gboolean *utf8)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
char *ret;
const char *to_codeset;
@@ -158,7 +159,7 @@ char *yahoo_string_encode(PurpleConnection *gc, const char *str, gboolean *utf8)
*/
char *yahoo_string_decode(PurpleConnection *gc, const char *str, gboolean utf8)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
char *ret;
const char *from_codeset;
diff --git a/libpurple/protocols/yahoo/yahoo_aliases.c b/libpurple/protocols/yahoo/yahoo_aliases.c
index dcbf55254b..c790f156a9 100644
--- a/libpurple/protocols/yahoo/yahoo_aliases.c
+++ b/libpurple/protocols/yahoo/yahoo_aliases.c
@@ -74,7 +74,7 @@ static void
yahoo_fetch_aliases_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, size_t len, const gchar *error_message)
{
PurpleConnection *gc = user_data;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
yd->url_datas = g_slist_remove(yd->url_datas, url_data);
@@ -186,7 +186,7 @@ yahoo_fetch_aliases_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, con
void
yahoo_fetch_aliases(PurpleConnection *gc)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
const char *url;
gchar *request, *webpage, *webaddress;
PurpleUtilFetchUrlData *url_data;
@@ -207,7 +207,7 @@ yahoo_fetch_aliases(PurpleConnection *gc)
webaddress);
/* We have a URL and some header information, let's connect and get some aliases */
- url_data = purple_util_fetch_url_request_len_with_account(purple_connection_get_account(gc),
+ url_data = purple_util_fetch_url_request(purple_connection_get_account(gc),
url, use_whole_url, NULL, TRUE, request, FALSE, -1,
yahoo_fetch_aliases_cb, gc);
if (url_data != NULL)
@@ -230,7 +230,7 @@ yahoo_update_alias_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, cons
PurpleConnection *gc = cb->gc;
YahooData *yd;
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
yd->url_datas = g_slist_remove(yd->url_datas, url_data);
if (len == 0 || error_message != NULL) {
@@ -310,7 +310,7 @@ yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias)
return;
}
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
/* Using callback_data so I have access to gc in the callback function */
cb = g_new0(struct callback_data, 1);
@@ -331,7 +331,7 @@ yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias)
gchar *converted_alias_jp = yahoo_convert_to_numeric(alias_jp);
content = g_strdup_printf("<ab k=\"%s\" cc=\"9\">\n"
"<ct a=\"1\" yi='%s' nn='%s' />\n</ab>\r\n",
- purple_account_get_username(gc->account),
+ purple_account_get_username(purple_connection_get_account(gc)),
who, converted_alias_jp);
g_free(converted_alias_jp);
g_free(alias_jp);
@@ -339,7 +339,7 @@ yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias)
gchar *escaped_alias = g_markup_escape_text(alias, -1);
content = g_strdup_printf("<?xml version=\"1.0\" encoding=\"utf-8\"?><ab k=\"%s\" cc=\"9\">\n"
"<ct a=\"1\" yi='%s' nn='%s' />\n</ab>\r\n",
- purple_account_get_username(gc->account),
+ purple_account_get_username(purple_connection_get_account(gc)),
who, escaped_alias);
g_free(escaped_alias);
}
@@ -351,7 +351,7 @@ yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias)
gchar *converted_alias_jp = yahoo_convert_to_numeric(alias_jp);
content = g_strdup_printf("<ab k=\"%s\" cc=\"1\">\n"
"<ct e=\"1\" yi='%s' id='%s' nn='%s' pr='0' />\n</ab>\r\n",
- purple_account_get_username(gc->account),
+ purple_account_get_username(purple_connection_get_account(gc)),
who, cb->id, converted_alias_jp);
g_free(converted_alias_jp);
g_free(alias_jp);
@@ -359,7 +359,7 @@ yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias)
gchar *escaped_alias = g_markup_escape_text(alias, -1);
content = g_strdup_printf("<?xml version=\"1.0\" encoding=\"utf-8\"?><ab k=\"%s\" cc=\"1\">\n"
"<ct e=\"1\" yi='%s' id='%s' nn='%s' pr='0' />\n</ab>\r\n",
- purple_account_get_username(gc->account),
+ purple_account_get_username(purple_connection_get_account(gc)),
who, cb->id, escaped_alias);
g_free(escaped_alias);
}
@@ -379,7 +379,7 @@ yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias)
content);
/* We have a URL and some header information, let's connect and update the alias */
- url_data = purple_util_fetch_url_request_len_with_account(
+ url_data = purple_util_fetch_url_request(
purple_connection_get_account(gc), url, use_whole_url, NULL, TRUE,
request, FALSE, -1, yahoo_update_alias_cb, cb);
if (url_data != NULL)
@@ -517,7 +517,7 @@ yahoo_set_userinfo_cb(PurpleConnection *gc, PurpleRequestFields *fields)
}
#endif
- url_data = purple_util_fetch_url_request_len_with_account(account, webaddress, FALSE,
+ url_data = purple_util_fetch_url_request(account, webaddress, FALSE,
YAHOO_CLIENT_USERAGENT, TRUE, request, FALSE, -1,
yahoo_fetch_aliases_cb, gc);
if (url_data != NULL)
diff --git a/libpurple/protocols/yahoo/yahoo_doodle.c b/libpurple/protocols/yahoo/yahoo_doodle.c
index f3f44a2631..972b8f4c5b 100644
--- a/libpurple/protocols/yahoo/yahoo_doodle.c
+++ b/libpurple/protocols/yahoo/yahoo_doodle.c
@@ -161,7 +161,7 @@ static void yahoo_doodle_command_got_request(PurpleConnection *gc, const char *f
*/
wb = purple_whiteboard_create(account, from, DOODLE_STATE_REQUESTED);
- ds = wb->proto_data;
+ ds = purple_whiteboard_get_protocol_data(wb);
ds->imv_key = g_strdup(imv_key);
yahoo_doodle_command_send_ready(gc, from, imv_key);
@@ -189,19 +189,19 @@ static void yahoo_doodle_command_got_ready(PurpleConnection *gc, const char *fro
if(wb == NULL)
return;
- if(wb->state == DOODLE_STATE_REQUESTING)
+ if(purple_whiteboard_get_state(wb) == DOODLE_STATE_REQUESTING)
{
- doodle_session *ds = wb->proto_data;
+ doodle_session *ds = purple_whiteboard_get_protocol_data(wb);
purple_whiteboard_start(wb);
- wb->state = DOODLE_STATE_ESTABLISHED;
+ purple_whiteboard_set_state(wb, DOODLE_STATE_ESTABLISHED);
yahoo_doodle_command_send_confirm(gc, from, imv_key);
/* Let's steal the imv_key and reuse it */
g_free(ds->imv_key);
ds->imv_key = g_strdup(imv_key);
}
- else if(wb->state == DOODLE_STATE_ESTABLISHED)
+ else if(purple_whiteboard_get_state(wb) == DOODLE_STATE_ESTABLISHED)
{
/* TODO Ask whether to save picture too */
purple_whiteboard_clear(wb);
@@ -211,7 +211,7 @@ static void yahoo_doodle_command_got_ready(PurpleConnection *gc, const char *fro
* already thinks we're in a session with them (when their chat message
* contains the doodle imv key)
*/
- else if(wb->state == DOODLE_STATE_REQUESTED)
+ else if(purple_whiteboard_get_state(wb) == DOODLE_STATE_REQUESTED)
{
/* purple_whiteboard_start(wb); */
yahoo_doodle_command_send_ready(gc, from, imv_key);
@@ -292,7 +292,7 @@ static void yahoo_doodle_command_got_clear(PurpleConnection *gc, const char *fro
if(wb == NULL)
return;
- if(wb->state == DOODLE_STATE_ESTABLISHED)
+ if(purple_whiteboard_get_state(wb) == DOODLE_STATE_ESTABLISHED)
{
/* TODO Ask user whether to save the image before clearing it */
@@ -333,9 +333,9 @@ static void yahoo_doodle_command_got_confirm(PurpleConnection *gc, const char *f
/* TODO Combine the following IF's? */
/* Check if we requested a doodle session */
- /*if(wb->state == DOODLE_STATE_REQUESTING)
+ /*if(purple_whiteboard_get_state(wb) == DOODLE_STATE_REQUESTING)
{
- wb->state = DOODLE_STATE_ESTABLISHED;
+ purple_whiteboard_set_state(wb, DOODLE_STATE_ESTABLISHED);
purple_whiteboard_start(wb);
@@ -343,9 +343,9 @@ static void yahoo_doodle_command_got_confirm(PurpleConnection *gc, const char *f
}*/
/* Check if we accepted a request for a doodle session */
- if(wb->state == DOODLE_STATE_REQUESTED)
+ if(purple_whiteboard_get_state(wb) == DOODLE_STATE_REQUESTED)
{
- wb->state = DOODLE_STATE_ESTABLISHED;
+ purple_whiteboard_set_state(wb, DOODLE_STATE_ESTABLISHED);
purple_whiteboard_start(wb);
}
@@ -372,7 +372,7 @@ void yahoo_doodle_command_got_shutdown(PurpleConnection *gc, const char *from)
/* TODO Ask if user wants to save picture before the session is closed */
- wb->state = DOODLE_STATE_CANCELLED;
+ purple_whiteboard_set_state(wb, DOODLE_STATE_CANCELLED);
purple_whiteboard_destroy(wb);
}
@@ -389,12 +389,12 @@ static void yahoo_doodle_command_send_generic(const char *type,
purple_debug_info("yahoo", "doodle: Sent %s (%s)\n", type, to);
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
/* Make and send an acknowledge (ready) Doodle packet */
pkt = yahoo_packet_new(YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, yd->session_id);
yahoo_packet_hash_str(pkt, 49, "IMVIRONMENT");
- yahoo_packet_hash_str(pkt, 1, purple_account_get_username(gc->account));
+ yahoo_packet_hash_str(pkt, 1, purple_account_get_username(purple_connection_get_account(gc)));
yahoo_packet_hash_str(pkt, 14, message);
yahoo_packet_hash_int(pkt, 13, command);
yahoo_packet_hash_str(pkt, 5, to);
@@ -450,21 +450,23 @@ void yahoo_doodle_start(PurpleWhiteboard *wb)
ds->brush_size = DOODLE_BRUSH_SMALL;
ds->brush_color = DOODLE_COLOR_RED;
- wb->proto_data = ds;
+ purple_whiteboard_set_protocol_data(wb, ds);
}
void yahoo_doodle_end(PurpleWhiteboard *wb)
{
- PurpleConnection *gc = purple_account_get_connection(wb->account);
- doodle_session *ds = wb->proto_data;
+ PurpleAccount *account = purple_whiteboard_get_account(wb);
+ PurpleConnection *gc = purple_account_get_connection(account);
+ doodle_session *ds = purple_whiteboard_get_protocol_data(wb);
/* g_debug_debug("yahoo", "doodle: yahoo_doodle_end()\n"); */
- if (gc && wb->state != DOODLE_STATE_CANCELLED)
- yahoo_doodle_command_send_shutdown(gc, wb->who);
+ if (gc && (purple_whiteboard_get_state(wb) != DOODLE_STATE_CANCELLED))
+ yahoo_doodle_command_send_shutdown(gc, purple_whiteboard_get_who(wb));
g_free(ds->imv_key);
- g_free(wb->proto_data);
+ g_free(ds);
+ purple_whiteboard_set_protocol_data(wb, NULL);
}
void yahoo_doodle_get_dimensions(const PurpleWhiteboard *wb, int *width, int *height)
@@ -494,20 +496,25 @@ static char *yahoo_doodle_build_draw_string(doodle_session *ds, GList *draw_list
void yahoo_doodle_send_draw_list(PurpleWhiteboard *wb, GList *draw_list)
{
- doodle_session *ds = wb->proto_data;
+ PurpleAccount *account = purple_whiteboard_get_account(wb);
+ PurpleConnection *gc = purple_account_get_connection(account);
+ doodle_session *ds = purple_whiteboard_get_protocol_data(wb);
char *message;
g_return_if_fail(draw_list != NULL);
message = yahoo_doodle_build_draw_string(ds, draw_list);
- yahoo_doodle_command_send_draw(wb->account->gc, wb->who, message, ds->imv_key);
+ yahoo_doodle_command_send_draw(gc, purple_whiteboard_get_who(wb), message, ds->imv_key);
g_free(message);
}
void yahoo_doodle_clear(PurpleWhiteboard *wb)
{
- doodle_session *ds = wb->proto_data;
- yahoo_doodle_command_send_clear(wb->account->gc, wb->who, ds->imv_key);
+ PurpleAccount *account = purple_whiteboard_get_account(wb);
+ PurpleConnection *gc = purple_account_get_connection(account);
+ doodle_session *ds = purple_whiteboard_get_protocol_data(wb);
+
+ yahoo_doodle_command_send_clear(gc, purple_whiteboard_get_who(wb), ds->imv_key);
}
@@ -560,14 +567,14 @@ void yahoo_doodle_draw_stroke(PurpleWhiteboard *wb, GList *draw_list)
void yahoo_doodle_get_brush(const PurpleWhiteboard *wb, int *size, int *color)
{
- doodle_session *ds = wb->proto_data;
+ doodle_session *ds = purple_whiteboard_get_protocol_data(wb);
*size = ds->brush_size;
*color = ds->brush_color;
}
void yahoo_doodle_set_brush(PurpleWhiteboard *wb, int size, int color)
{
- doodle_session *ds = wb->proto_data;
+ doodle_session *ds = purple_whiteboard_get_protocol_data(wb);
ds->brush_size = size;
ds->brush_color = color;
diff --git a/libpurple/protocols/yahoo/yahoo_filexfer.c b/libpurple/protocols/yahoo/yahoo_filexfer.c
index bf87dbe2ab..1b0ff85187 100644
--- a/libpurple/protocols/yahoo/yahoo_filexfer.c
+++ b/libpurple/protocols/yahoo/yahoo_filexfer.c
@@ -43,7 +43,7 @@ struct yahoo_xfer_data {
PurpleConnection *gc;
long expires;
gboolean started;
- gchar *txbuf;
+ guchar *txbuf;
gsize txbuflen;
gsize txbuf_written;
guint tx_handler;
@@ -85,7 +85,7 @@ static void yahoo_xfer_data_free(struct yahoo_xfer_data *xd)
GSList *l;
gc = xd->gc;
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
/* remove entry from map */
if(xd->xfer_peer_idstring) {
@@ -120,13 +120,13 @@ static void yahoo_receivefile_send_cb(gpointer data, gint source, PurpleInputCon
{
PurpleXfer *xfer;
struct yahoo_xfer_data *xd;
- int remaining, written;
+ gssize remaining, written;
xfer = data;
- xd = xfer->data;
+ xd = purple_xfer_get_protocol_data(xfer);
remaining = xd->txbuflen - xd->txbuf_written;
- written = write(xfer->fd, xd->txbuf + xd->txbuf_written, remaining);
+ written = purple_xfer_write(xfer, xd->txbuf + xd->txbuf_written, remaining);
if (written < 0 && errno == EAGAIN)
written = 0;
@@ -160,22 +160,23 @@ static void yahoo_receivefile_connected(gpointer data, gint source, const gchar
if (!(xfer = data))
return;
- if (!(xd = xfer->data))
+ if (!(xd = purple_xfer_get_protocol_data(xfer)))
return;
if ((source < 0) || (xd->path == NULL) || (xd->host == NULL)) {
purple_xfer_error(PURPLE_XFER_RECEIVE, purple_xfer_get_account(xfer),
- xfer->who, _("Unable to connect."));
+ purple_xfer_get_remote_user(xfer), _("Unable to connect."));
purple_xfer_cancel_remote(xfer);
return;
}
- xfer->fd = source;
+ purple_xfer_set_fd(xfer, source);
/* The first time we get here, assemble the tx buffer */
if (xd->txbuflen == 0) {
- xd->txbuf = g_strdup_printf("GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n",
+ gchar *header = g_strdup_printf("GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n",
xd->path, xd->host);
- xd->txbuflen = strlen(xd->txbuf);
+ xd->txbuf = (guchar*) header;
+ xd->txbuflen = strlen(header);
xd->txbuf_written = 0;
}
@@ -191,13 +192,13 @@ static void yahoo_sendfile_send_cb(gpointer data, gint source, PurpleInputCondit
{
PurpleXfer *xfer;
struct yahoo_xfer_data *xd;
- int written, remaining;
+ gssize written, remaining;
xfer = data;
- xd = xfer->data;
+ xd = purple_xfer_get_protocol_data(xfer);
remaining = xd->txbuflen - xd->txbuf_written;
- written = write(xfer->fd, xd->txbuf + xd->txbuf_written, remaining);
+ written = purple_xfer_write(xfer, xd->txbuf + xd->txbuf_written, remaining);
if (written < 0 && errno == EAGAIN)
written = 0;
@@ -239,32 +240,32 @@ static void yahoo_sendfile_connected(gpointer data, gint source, const gchar *er
if (!(xfer = data))
return;
- if (!(xd = xfer->data))
+ if (!(xd = purple_xfer_get_protocol_data(xfer)))
return;
if (source < 0) {
purple_xfer_error(PURPLE_XFER_RECEIVE, purple_xfer_get_account(xfer),
- xfer->who, _("Unable to connect."));
+ purple_xfer_get_remote_user(xfer), _("Unable to connect."));
purple_xfer_cancel_remote(xfer);
return;
}
- xfer->fd = source;
+ purple_xfer_set_fd(xfer, source);
/* Assemble the tx buffer */
gc = xd->gc;
account = purple_connection_get_account(gc);
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANSFER,
YAHOO_STATUS_AVAILABLE, yd->session_id);
- size = g_strdup_printf("%" G_GSIZE_FORMAT, purple_xfer_get_size(xfer));
+ size = g_strdup_printf("%" G_GOFFSET_FORMAT, purple_xfer_get_size(xfer));
filename = g_path_get_basename(purple_xfer_get_local_filename(xfer));
encoded_filename = yahoo_string_encode(gc, filename, NULL);
yahoo_packet_hash(pkt, "sssss", 0, purple_connection_get_display_name(gc),
- 5, xfer->who, 14, "", 27, encoded_filename, 28, size);
+ 5, purple_xfer_get_remote_user(xfer), 14, "", 27, encoded_filename, 28, size);
g_free(size);
g_free(encoded_filename);
g_free(filename);
@@ -278,7 +279,7 @@ static void yahoo_sendfile_connected(gpointer data, gint source, const gchar *er
port = purple_account_get_int(account, "xfer_port", YAHOO_XFER_PORT);
header = g_strdup_printf(
"POST http://%s:%d/notifyft HTTP/1.0\r\n"
- "Content-length: %" G_GSIZE_FORMAT "\r\n"
+ "Content-length: %" G_GOFFSET_FORMAT "\r\n"
"Host: %s:%d\r\n"
"Cookie: Y=%s; T=%s\r\n"
"\r\n",
@@ -313,9 +314,9 @@ static void yahoo_xfer_init(PurpleXfer *xfer)
PurpleAccount *account;
YahooData *yd;
- xfer_data = xfer->data;
+ xfer_data = purple_xfer_get_protocol_data(xfer);
gc = xfer_data->gc;
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
account = purple_connection_get_account(gc);
if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
@@ -339,7 +340,7 @@ static void yahoo_xfer_init(PurpleXfer *xfer)
}
}
} else {
- xfer->fd = -1;
+ purple_xfer_set_fd(xfer, -1);
if (purple_proxy_connect(gc, account, xfer_data->host, xfer_data->port,
yahoo_receivefile_connected, xfer) == NULL) {
purple_notify_error(gc, NULL, _("File Transfer Failed"),
@@ -357,9 +358,9 @@ static void yahoo_xfer_init_15(PurpleXfer *xfer)
YahooData *yd;
struct yahoo_packet *pkt;
- xfer_data = xfer->data;
+ xfer_data = purple_xfer_get_protocol_data(xfer);
gc = xfer_data->gc;
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
account = purple_connection_get_account(gc);
if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
@@ -370,14 +371,14 @@ static void yahoo_xfer_init_15(PurpleXfer *xfer)
yd->session_id);
yahoo_packet_hash(pkt, "sssiiiisiii",
1, purple_normalize(account, purple_account_get_username(account)),
- 5, xfer->who,
+ 5, purple_xfer_get_remote_user(xfer),
265, xfer_data->xfer_peer_idstring,
222, 1,
266, 1,
302, 268,
300, 268,
27, filename,
- 28, xfer->size,
+ 28, (int)purple_xfer_get_size(xfer),
301, 268,
303, 268);
g_free(filename);
@@ -388,7 +389,7 @@ static void yahoo_xfer_init_15(PurpleXfer *xfer)
yahoo_packet_hash(pkt, "sssi",
1, purple_normalize(account, purple_account_get_username(account)),
- 5, xfer->who,
+ 5, purple_xfer_get_remote_user(xfer),
265, xfer_data->xfer_peer_idstring,
222, 3);
} else {
@@ -397,7 +398,7 @@ static void yahoo_xfer_init_15(PurpleXfer *xfer)
yahoo_packet_hash(pkt, "sssi",
1, purple_normalize(account, purple_account_get_username(account)),
- 5, xfer->who,
+ 5, purple_xfer_get_remote_user(xfer),
265, xfer_data->xfer_peer_idstring,
271, 1);
}
@@ -410,14 +411,14 @@ static void yahoo_xfer_start(PurpleXfer *xfer)
/* We don't need to do anything here, do we? */
}
-static guint calculate_length(const gchar *l, size_t len)
+static goffset calculate_length(const gchar *l, size_t len)
{
int i;
for (i = 0; i < len; i++) {
if (!g_ascii_isdigit(l[i]))
continue;
- return strtol(l + i, NULL, 10);
+ return g_ascii_strtoll(l + i, NULL, 10);
}
return 0;
}
@@ -429,14 +430,14 @@ static gssize yahoo_xfer_read(guchar **buffer, PurpleXfer *xfer)
gchar *start = NULL;
gchar *length;
gchar *end;
- int filelen;
- struct yahoo_xfer_data *xd = xfer->data;
+ goffset filelen;
+ struct yahoo_xfer_data *xd = purple_xfer_get_protocol_data(xfer);
if (purple_xfer_get_type(xfer) != PURPLE_XFER_RECEIVE) {
return 0;
}
- len = read(xfer->fd, buf, sizeof(buf));
+ len = read(purple_xfer_get_fd(xfer), buf, sizeof(buf));
if (len <= 0) {
if ((purple_xfer_get_size(xfer) > 0) &&
@@ -490,7 +491,7 @@ static gssize yahoo_xfer_read(guchar **buffer, PurpleXfer *xfer)
static gssize yahoo_xfer_write(const guchar *buffer, size_t size, PurpleXfer *xfer)
{
gssize len;
- struct yahoo_xfer_data *xd = xfer->data;
+ struct yahoo_xfer_data *xd = purple_xfer_get_protocol_data(xfer);
if (!xd)
return -1;
@@ -499,7 +500,7 @@ static gssize yahoo_xfer_write(const guchar *buffer, size_t size, PurpleXfer *xf
return -1;
}
- len = write(xfer->fd, buffer, size);
+ len = write(purple_xfer_get_fd(xfer), buffer, size);
if (len == -1) {
if (purple_xfer_get_bytes_sent(xfer) >= purple_xfer_get_size(xfer))
@@ -516,7 +517,7 @@ static void yahoo_xfer_cancel_send(PurpleXfer *xfer)
{
struct yahoo_xfer_data *xfer_data;
- xfer_data = xfer->data;
+ xfer_data = purple_xfer_get_protocol_data(xfer);
if(purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL && xfer_data->version == 15)
{
@@ -526,7 +527,7 @@ static void yahoo_xfer_cancel_send(PurpleXfer *xfer)
struct yahoo_packet *pkt;
gc = xfer_data->gc;
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
account = purple_connection_get_account(gc);
if(xfer_data->xfer_idstring_for_relay) /* hack to see if file trans acc/info packet has been received */
{
@@ -535,7 +536,7 @@ static void yahoo_xfer_cancel_send(PurpleXfer *xfer)
yd->session_id);
yahoo_packet_hash(pkt, "sssi",
1, purple_normalize(account, purple_account_get_username(account)),
- 5, xfer->who,
+ 5, purple_xfer_get_remote_user(xfer),
265, xfer_data->xfer_peer_idstring,
66, -1);
}
@@ -546,7 +547,7 @@ static void yahoo_xfer_cancel_send(PurpleXfer *xfer)
yd->session_id);
yahoo_packet_hash(pkt, "sssi",
1, purple_normalize(account, purple_account_get_username(account)),
- 5, xfer->who,
+ 5, purple_xfer_get_remote_user(xfer),
265, xfer_data->xfer_peer_idstring,
222, 2);
}
@@ -556,14 +557,14 @@ static void yahoo_xfer_cancel_send(PurpleXfer *xfer)
if (xfer_data)
yahoo_xfer_data_free(xfer_data);
- xfer->data = NULL;
+ purple_xfer_set_protocol_data(xfer, NULL);
}
static void yahoo_xfer_cancel_recv(PurpleXfer *xfer)
{
struct yahoo_xfer_data *xfer_data;
- xfer_data = xfer->data;
+ xfer_data = purple_xfer_get_protocol_data(xfer);
if(purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL && xfer_data->version == 15)
{
@@ -574,7 +575,7 @@ static void yahoo_xfer_cancel_recv(PurpleXfer *xfer)
struct yahoo_packet *pkt;
gc = xfer_data->gc;
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
account = purple_connection_get_account(gc);
if(!xfer_data->xfer_idstring_for_relay) /* hack to see if file trans acc/info packet has been received */
{
@@ -583,7 +584,7 @@ static void yahoo_xfer_cancel_recv(PurpleXfer *xfer)
yd->session_id);
yahoo_packet_hash(pkt, "sssi",
1, purple_normalize(account, purple_account_get_username(account)),
- 5, xfer->who,
+ 5, purple_xfer_get_remote_user(xfer),
265, xfer_data->xfer_peer_idstring,
222, 4);
}
@@ -594,7 +595,7 @@ static void yahoo_xfer_cancel_recv(PurpleXfer *xfer)
yd->session_id);
yahoo_packet_hash(pkt, "sssi",
1, purple_normalize(account, purple_account_get_username(account)),
- 5, xfer->who,
+ 5, purple_xfer_get_remote_user(xfer),
265, xfer_data->xfer_peer_idstring,
66, -1);
}
@@ -603,7 +604,7 @@ static void yahoo_xfer_cancel_recv(PurpleXfer *xfer)
if (xfer_data)
yahoo_xfer_data_free(xfer_data);
- xfer->data = NULL;
+ purple_xfer_set_protocol_data(xfer, NULL);
}
/* Send HTTP OK after receiving file */
@@ -611,9 +612,10 @@ static void yahoo_p2p_ft_server_send_OK(PurpleXfer *xfer)
{
char *tx = NULL;
int written;
+ int fd = purple_xfer_get_fd(xfer);
- tx = g_strdup_printf("HTTP/1.1 200 OK\r\nContent-Length: 0\r\nContent-Type: application/octet-stream\r\nConnection: close\r\n\r\n");
- written = write(xfer->fd, tx, strlen(tx));
+ tx = "HTTP/1.1 200 OK\r\nContent-Length: 0\r\nContent-Type: application/octet-stream\r\nConnection: close\r\n\r\n";
+ written = write(fd, tx, strlen(tx));
if (written < 0 && errno == EAGAIN)
written = 0;
@@ -621,9 +623,8 @@ static void yahoo_p2p_ft_server_send_OK(PurpleXfer *xfer)
purple_debug_info("yahoo", "p2p filetransfer: Unable to write HTTP OK");
/* close connection */
- close(xfer->fd);
- xfer->fd = -1;
- g_free(tx);
+ close(fd);
+ purple_xfer_set_fd(xfer, -1);
}
static void yahoo_xfer_end(PurpleXfer *xfer_old)
@@ -633,13 +634,13 @@ static void yahoo_xfer_end(PurpleXfer *xfer_old)
PurpleConnection *gc;
YahooData *yd;
- xfer_data = xfer_old->data;
+ xfer_data = purple_xfer_get_protocol_data(xfer_old);
if(xfer_data && xfer_data->version == 15
&& purple_xfer_get_type(xfer_old) == PURPLE_XFER_RECEIVE
&& xfer_data->filename_list) {
/* Send HTTP OK in case of p2p transfer, when we act as server */
- if((xfer_data->xfer_url != NULL) && (xfer_old->fd >=0) && (purple_xfer_get_status(xfer_old) == PURPLE_XFER_STATUS_DONE))
+ if((xfer_data->xfer_url != NULL) && (purple_xfer_get_fd(xfer_old) >=0) && (purple_xfer_get_status(xfer_old) == PURPLE_XFER_STATUS_DONE))
yahoo_p2p_ft_server_send_OK(xfer_old);
/* removing top of filename & size list completely */
@@ -656,13 +657,13 @@ static void yahoo_xfer_end(PurpleXfer *xfer_old)
if(xfer_data->filename_list)
{
gchar* filename;
- long filesize;
+ goffset filesize;
filename = xfer_data->filename_list->data;
- filesize = atol( xfer_data->size_list->data );
+ filesize = g_ascii_strtoll( xfer_data->size_list->data, NULL, 10 );
gc = xfer_data->gc;
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
/* setting up xfer_data for next file's tranfer */
g_free(xfer_data->host);
@@ -689,10 +690,10 @@ static void yahoo_xfer_end(PurpleXfer *xfer_old)
xfer_data->firstoflist = FALSE;
/* Dereference xfer_data from old xfer */
- xfer_old->data = NULL;
+ purple_xfer_set_protocol_data(xfer_old, NULL);
/* Build the file transfer handle. */
- xfer = purple_xfer_new(gc->account, PURPLE_XFER_RECEIVE, xfer_old->who);
+ xfer = purple_xfer_new(purple_connection_get_account(gc), PURPLE_XFER_RECEIVE, purple_xfer_get_remote_user(xfer_old));
if (xfer) {
@@ -702,7 +703,7 @@ static void yahoo_xfer_end(PurpleXfer *xfer_old)
g_free(utf8_filename);
purple_xfer_set_size(xfer, filesize);
- xfer->data = xfer_data;
+ purple_xfer_set_protocol_data(xfer, xfer_data);
/* Setup our I/O op functions */
purple_xfer_set_init_fnc(xfer, yahoo_xfer_init_15);
@@ -726,8 +727,7 @@ static void yahoo_xfer_end(PurpleXfer *xfer_old)
}
if (xfer_data)
yahoo_xfer_data_free(xfer_data);
- xfer_old->data = NULL;
-
+ purple_xfer_set_protocol_data(xfer_old, NULL);
}
void yahoo_process_p2pfilexfer(PurpleConnection *gc, struct yahoo_packet *pkt)
@@ -803,10 +803,10 @@ void yahoo_process_filetransfer(PurpleConnection *gc, struct yahoo_packet *pkt)
struct yahoo_xfer_data *xfer_data;
char *service = NULL;
char *filename = NULL;
- unsigned long filesize = 0L;
+ goffset filesize = G_GOFFSET_CONSTANT(0);
GSList *l;
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
for (l = pkt->hash; l; l = l->next) {
struct yahoo_pair *pair = l->data;
@@ -831,7 +831,7 @@ void yahoo_process_filetransfer(PurpleConnection *gc, struct yahoo_packet *pkt)
filename = pair->value;
break;
case 28:
- filesize = atol(pair->value);
+ filesize = g_ascii_strtoll(pair->value, NULL, 10);
break;
case 49:
service = pair->value;
@@ -880,13 +880,13 @@ void yahoo_process_filetransfer(PurpleConnection *gc, struct yahoo_packet *pkt)
xfer_data->host, xfer_data->port, xfer_data->path, url);
/* Build the file transfer handle. */
- xfer = purple_xfer_new(gc->account, PURPLE_XFER_RECEIVE, from);
+ xfer = purple_xfer_new(purple_connection_get_account(gc), PURPLE_XFER_RECEIVE, from);
if (xfer == NULL) {
g_free(xfer_data);
g_return_if_reached();
}
- xfer->data = xfer_data;
+ purple_xfer_set_protocol_data(xfer, xfer_data);
/* Set the info about the incoming file. */
if (filename) {
@@ -936,14 +936,14 @@ PurpleXfer *yahoo_new_xfer(PurpleConnection *gc, const char *who)
xfer_data->gc = gc;
/* Build the file transfer handle. */
- xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who);
+ xfer = purple_xfer_new(purple_connection_get_account(gc), PURPLE_XFER_SEND, who);
if (xfer == NULL)
{
g_free(xfer_data);
g_return_val_if_reached(NULL);
}
- xfer->data = xfer_data;
+ purple_xfer_set_protocol_data(xfer, xfer_data);
/* Setup our I/O op functions */
purple_xfer_set_init_fnc(xfer, yahoo_xfer_init);
@@ -993,11 +993,11 @@ static void yahoo_xfer_dns_connected_15(GSList *hosts, gpointer data, const char
if (!(xfer = data))
return;
- if (!(xd = xfer->data))
+ if (!(xd = purple_xfer_get_protocol_data(xfer)))
return;
gc = xd->gc;
account = purple_connection_get_account(gc);
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
if(!hosts)
{
@@ -1057,7 +1057,7 @@ static void yahoo_xfer_dns_connected_15(GSList *hosts, gpointer data, const char
yahoo_packet_hash(pkt, "ssssis",
1, purple_normalize(account, purple_account_get_username(account)),
- 5, xfer->who,
+ 5, purple_xfer_get_remote_user(xfer),
265, xd->xfer_peer_idstring,
27, filename,
249, 3,
@@ -1077,7 +1077,7 @@ gboolean yahoo_can_receive_file(PurpleConnection *gc, const char *who)
void yahoo_send_file(PurpleConnection *gc, const char *who, const char *file)
{
struct yahoo_xfer_data *xfer_data;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
PurpleXfer *xfer = yahoo_new_xfer(gc, who);
g_return_if_fail(xfer != NULL);
@@ -1086,7 +1086,7 @@ void yahoo_send_file(PurpleConnection *gc, const char *who, const char *file)
if( !g_hash_table_lookup(yd->peers, who) )
yahoo_send_p2p_pkt(gc, who, 0);
- xfer_data = xfer->data;
+ xfer_data = purple_xfer_get_protocol_data(xfer);
xfer_data->status_15 = STARTED;
purple_xfer_set_init_fnc(xfer, yahoo_xfer_init_15);
xfer_data->version = 15;
@@ -1108,26 +1108,22 @@ static void yahoo_xfer_recv_cb_15(gpointer data, gint source, PurpleInputConditi
PurpleXfer *xfer;
struct yahoo_xfer_data *xd;
int did;
- gchar* buf;
- gchar* t;
+ guchar buf[1000];
PurpleAccount *account;
PurpleConnection *gc;
xfer = data;
- xd = xfer->data;
+ xd = purple_xfer_get_protocol_data(xfer);
account = purple_connection_get_account(xd->gc);
gc = xd->gc;
- buf=g_strnfill(1000, 0);
- while((did = read(source, buf, 998)) > 0)
+ while((did = read(source, buf, sizeof(buf))) > 0)
{
+ /* TODO: Convert to circ buffer, this all is pretty horrible */
+ xd->txbuf = g_realloc(xd->txbuf, xd->txbuflen + did);
+ g_memmove(xd->txbuf + xd->txbuflen, buf, did);
xd->txbuflen += did;
- buf[did] = '\0';
- t = xd->txbuf;
- xd->txbuf = g_strconcat(t,buf,NULL);
- g_free(t);
}
- g_free(buf);
if (did < 0 && errno == EAGAIN)
return;
@@ -1167,7 +1163,7 @@ static void yahoo_xfer_send_cb_15(gpointer data, gint source, PurpleInputConditi
int remaining, written;
xfer = data;
- xd = xfer->data;
+ xd = purple_xfer_get_protocol_data(xfer);
remaining = xd->txbuflen - xd->txbuf_written;
written = write(source, xd->txbuf + xd->txbuf_written, remaining);
@@ -1200,13 +1196,13 @@ static void yahoo_xfer_send_cb_15(gpointer data, gint source, PurpleInputConditi
else if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE && xd->status_15 == HEAD_REPLY_RECEIVED)
{
xd->status_15 = TRANSFER_PHASE;
- xfer->fd = source;
+ purple_xfer_set_fd(xfer, source);
purple_xfer_start(xfer, source, NULL, 0);
}
else if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND && (xd->status_15 == ACCEPTED || xd->status_15 == P2P_GET_REQUESTED) )
{
xd->status_15 = TRANSFER_PHASE;
- xfer->fd = source;
+ purple_xfer_set_fd(xfer, source);
/* Remove Read event */
purple_input_remove(xd->input_event);
xd->input_event = 0;
@@ -1219,9 +1215,9 @@ static void yahoo_xfer_send_cb_15(gpointer data, gint source, PurpleInputConditi
purple_input_remove(xd->input_event);
xd->input_event = 0;
close(source);
- xfer->fd = -1;
+ purple_xfer_set_fd(xfer, -1);
/* start local server, listen for connections */
- purple_network_listen(xd->yahoo_local_p2p_ft_server_port, SOCK_STREAM, yahoo_p2p_ft_server_listen_cb, xfer);
+ purple_network_listen(xd->yahoo_local_p2p_ft_server_port, AF_UNSPEC, SOCK_STREAM, TRUE, yahoo_p2p_ft_server_listen_cb, xfer);
}
else
{
@@ -1239,13 +1235,13 @@ static void yahoo_xfer_connected_15(gpointer data, gint source, const gchar *err
if (!(xfer = data))
return;
- if (!(xd = xfer->data))
+ if (!(xd = purple_xfer_get_protocol_data(xfer)))
return;
gc = xd->gc;
account = purple_connection_get_account(gc);
if ((source < 0) || (xd->path == NULL) || (xd->host == NULL)) {
purple_xfer_error(PURPLE_XFER_RECEIVE, purple_xfer_get_account(xfer),
- xfer->who, _("Unable to connect."));
+ purple_xfer_get_remote_user(xfer), _("Unable to connect."));
purple_xfer_cancel_remote(xfer);
return;
}
@@ -1253,7 +1249,8 @@ static void yahoo_xfer_connected_15(gpointer data, gint source, const gchar *err
if (xd->txbuflen == 0)
{
gchar* cookies;
- YahooData *yd = gc->proto_data;
+ gchar* initial_buffer;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
/* cookies = yahoo_get_cookies(gc);
* This doesn't seem to be working. The function is returning NULL, which yahoo servers don't like
@@ -1266,30 +1263,30 @@ static void yahoo_xfer_connected_15(gpointer data, gint source, const gchar *err
if(xd->info_val_249 == 2)
{
/* sending file via p2p, we are connected as client */
- xd->txbuf = g_strdup_printf("POST /%s HTTP/1.1\r\n"
+ initial_buffer = g_strdup_printf("POST /%s HTTP/1.1\r\n"
"User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
"Host: %s\r\n"
- "Content-Length: %ld\r\n"
+ "Content-Length: %" G_GOFFSET_FORMAT "\r\n"
"Cache-Control: no-cache\r\n\r\n",
xd->path,
xd->host,
- (long int)xfer->size); /* to do, add Referer */
+ purple_xfer_get_size(xfer)); /* to do, add Referer */
}
else
{
/* sending file via relaying */
- xd->txbuf = g_strdup_printf("POST /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
+ initial_buffer = g_strdup_printf("POST /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
"Cookie:%s\r\n"
"User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
"Host: %s\r\n"
- "Content-Length: %ld\r\n"
+ "Content-Length: %" G_GOFFSET_FORMAT "\r\n"
"Cache-Control: no-cache\r\n\r\n",
purple_url_encode(xd->xfer_idstring_for_relay),
purple_normalize(account, purple_account_get_username(account)),
- xfer->who,
+ purple_xfer_get_remote_user(xfer),
cookies,
xd->host,
- (long int)xfer->size);
+ purple_xfer_get_size(xfer)); /* to do, add Referer */
}
}
else if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE && xd->status_15 == STARTED)
@@ -1297,7 +1294,7 @@ static void yahoo_xfer_connected_15(gpointer data, gint source, const gchar *err
if(xd->info_val_249 == 1)
{
/* receiving file via p2p, connected as client */
- xd->txbuf = g_strdup_printf("HEAD /%s HTTP/1.1\r\n"
+ initial_buffer = g_strdup_printf("HEAD /%s HTTP/1.1\r\n"
"Accept: */*\r\n"
"User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
"Host: %s\r\n"
@@ -1308,7 +1305,7 @@ static void yahoo_xfer_connected_15(gpointer data, gint source, const gchar *err
else
{
/* receiving file via relaying */
- xd->txbuf = g_strdup_printf("HEAD /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
+ initial_buffer = g_strdup_printf("HEAD /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
"Accept: */*\r\n"
"Cookie: %s\r\n"
"User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
@@ -1317,7 +1314,7 @@ static void yahoo_xfer_connected_15(gpointer data, gint source, const gchar *err
"Cache-Control: no-cache\r\n\r\n",
purple_url_encode(xd->xfer_idstring_for_relay),
purple_normalize(account, purple_account_get_username(account)),
- xfer->who,
+ purple_xfer_get_remote_user(xfer),
cookies,
xd->host);
}
@@ -1327,7 +1324,7 @@ static void yahoo_xfer_connected_15(gpointer data, gint source, const gchar *err
if(xd->info_val_249 == 1)
{
/* receiving file via p2p, connected as client */
- xd->txbuf = g_strdup_printf("GET /%s HTTP/1.1\r\n"
+ initial_buffer = g_strdup_printf("GET /%s HTTP/1.1\r\n"
"User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
"Host: %s\r\n"
"Connection: Keep-Alive\r\n\r\n",
@@ -1336,14 +1333,14 @@ static void yahoo_xfer_connected_15(gpointer data, gint source, const gchar *err
else
{
/* receiving file via relaying */
- xd->txbuf = g_strdup_printf("GET /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
+ initial_buffer = g_strdup_printf("GET /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
"Cookie: %s\r\n"
"User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
"Host: %s\r\n"
"Connection: Keep-Alive\r\n\r\n",
purple_url_encode(xd->xfer_idstring_for_relay),
purple_normalize(account, purple_account_get_username(account)),
- xfer->who,
+ purple_xfer_get_remote_user(xfer),
cookies,
xd->host);
}
@@ -1354,7 +1351,8 @@ static void yahoo_xfer_connected_15(gpointer data, gint source, const gchar *err
g_free(cookies);
return;
}
- xd->txbuflen = strlen(xd->txbuf);
+ xd->txbuf = (guchar*) initial_buffer;
+ xd->txbuflen = strlen(initial_buffer);
xd->txbuf_written = 0;
g_free(cookies);
}
@@ -1373,14 +1371,14 @@ static void yahoo_p2p_ft_POST_cb(gpointer data, gint source, PurpleInputConditio
struct yahoo_xfer_data *xd;
xfer = data;
- if (!(xd = xfer->data)) {
+ if (!(xd = purple_xfer_get_protocol_data(xfer))) {
purple_xfer_cancel_remote(xfer);
return;
}
purple_input_remove(xd->input_event);
xd->status_15 = TRANSFER_PHASE;
- xfer->fd = source;
+ purple_xfer_set_fd(xfer, source);
purple_xfer_start(xfer, source, NULL, 0);
}
@@ -1396,7 +1394,7 @@ static void yahoo_p2p_ft_HEAD_GET_cb(gpointer data, gint source, PurpleInputCond
char *time_str;
xfer = data;
- if (!(xd = xfer->data)) {
+ if (!(xd = purple_xfer_get_protocol_data(xfer))) {
purple_xfer_cancel_remote(xfer);
return;
}
@@ -1431,14 +1429,15 @@ static void yahoo_p2p_ft_HEAD_GET_cb(gpointer data, gint source, PurpleInputCond
time_str[strlen(time_str) - 1] = '\0';
if (xd->txbuflen == 0) {
- xd->txbuf = g_strdup_printf("HTTP/1.0 200 OK\r\n"
+ gchar *initial_buffer = g_strdup_printf("HTTP/1.0 200 OK\r\n"
"Date: %s GMT\r\n"
"Server: Y!/1.0\r\n"
"MIME-version: 1.0\r\n"
"Last-modified: %s GMT\r\n"
- "Content-length: %" G_GSIZE_FORMAT "\r\n\r\n",
- time_str, time_str, xfer->size);
- xd->txbuflen = strlen(xd->txbuf);
+ "Content-length: %" G_GOFFSET_FORMAT "\r\n\r\n",
+ time_str, time_str, purple_xfer_get_size(xfer));
+ xd->txbuf = (guchar *)initial_buffer;
+ xd->txbuflen = strlen(initial_buffer);
xd->txbuf_written = 0;
}
@@ -1458,7 +1457,7 @@ static void yahoo_p2p_ft_server_send_connected_cb(gpointer data, gint source, Pu
struct yahoo_xfer_data *xd;
xfer = data;
- if (!(xd = xfer->data)) {
+ if (!(xd = purple_xfer_get_protocol_data(xfer))) {
purple_xfer_cancel_remote(xfer);
return;
}
@@ -1480,8 +1479,8 @@ static void yahoo_p2p_ft_server_send_connected_cb(gpointer data, gint source, Pu
close(xd->yahoo_local_p2p_ft_server_fd);
/* Add an Input Read event to the file descriptor */
- xfer->fd = acceptfd;
- if(xfer->type == PURPLE_XFER_RECEIVE)
+ purple_xfer_set_fd(xfer, acceptfd);
+ if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE)
xd->input_event = purple_input_add(acceptfd, PURPLE_INPUT_READ, yahoo_p2p_ft_POST_cb, data);
else
xd->input_event = purple_input_add(acceptfd, PURPLE_INPUT_READ, yahoo_p2p_ft_HEAD_GET_cb, data);
@@ -1500,14 +1499,14 @@ static void yahoo_p2p_ft_server_listen_cb(int listenfd, gpointer data)
char *filename_without_spaces = NULL;
xfer = data;
- if (!(xd = xfer->data) || (listenfd == -1)) {
+ if (!(xd = purple_xfer_get_protocol_data(xfer)) || (listenfd == -1)) {
purple_debug_warning("yahoo","p2p: error starting server for p2p file transfer\n");
purple_xfer_cancel_remote(xfer);
return;
}
- if( (xfer->type == PURPLE_XFER_RECEIVE) || (xd->status_15 != P2P_HEAD_REPLIED) ) {
- yd = xd->gc->proto_data;
+ if( (purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) || (xd->status_15 != P2P_HEAD_REPLIED) ) {
+ yd = purple_connection_get_protocol_data(xd->gc);
account = purple_connection_get_account(xd->gc);
local_ip = purple_network_get_my_ip(listenfd);
xd->yahoo_local_p2p_ft_server_port = purple_network_get_port_from_fd(listenfd);
@@ -1515,18 +1514,18 @@ static void yahoo_p2p_ft_server_listen_cb(int listenfd, gpointer data)
filename = g_path_get_basename(purple_xfer_get_local_filename(xfer));
filename_without_spaces = g_strdup(filename);
purple_util_chrreplace(filename_without_spaces, ' ', '+');
- xd->xfer_url = g_strdup_printf("/Messenger.%s.%d000%s?AppID=Messenger&UserID=%s&K=lc9lu2u89gz1llmplwksajkjx", xfer->who, (int)time(NULL), filename_without_spaces, xfer->who);
+ xd->xfer_url = g_strdup_printf("/Messenger.%s.%d000%s?AppID=Messenger&UserID=%s&K=lc9lu2u89gz1llmplwksajkjx", purple_xfer_get_remote_user(xfer), (int)time(NULL), filename_without_spaces, purple_xfer_get_remote_user(xfer));
url_to_send = g_strdup_printf("http://%s:%d%s", local_ip, xd->yahoo_local_p2p_ft_server_port, xd->xfer_url);
- if(xfer->type == PURPLE_XFER_RECEIVE) {
+ if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) {
xd->info_val_249 = 2; /* 249=2: we are p2p server, and receiving file */
pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_ACC_15,
YAHOO_STATUS_AVAILABLE, yd->session_id);
yahoo_packet_hash(pkt, "ssssis",
1, purple_normalize(account, purple_account_get_username(account)),
- 5, xfer->who,
+ 5, purple_xfer_get_remote_user(xfer),
265, xd->xfer_peer_idstring,
- 27, xfer->filename,
+ 27, purple_xfer_get_filename(xfer),
249, 2,
250, url_to_send);
}
@@ -1535,7 +1534,7 @@ static void yahoo_p2p_ft_server_listen_cb(int listenfd, gpointer data)
pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_INFO_15, YAHOO_STATUS_AVAILABLE, yd->session_id);
yahoo_packet_hash(pkt, "ssssis",
1, purple_normalize(account, purple_account_get_username(account)),
- 5, xfer->who,
+ 5, purple_xfer_get_remote_user(xfer),
265, xd->xfer_peer_idstring,
27, filename,
249, 1,
@@ -1564,15 +1563,15 @@ static void yahoo_p2p_client_send_ft_info(PurpleConnection *gc, PurpleXfer *xfer
gchar *filename;
struct yahoo_p2p_data *p2p_data;
- if (!(xd = xfer->data))
+ if (!(xd = purple_xfer_get_protocol_data(xfer)))
return;
account = purple_connection_get_account(gc);
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
- p2p_data = g_hash_table_lookup(yd->peers, xfer->who);
+ p2p_data = g_hash_table_lookup(yd->peers, purple_xfer_get_remote_user(xfer));
if( p2p_data->connection_type == YAHOO_P2P_WE_ARE_SERVER )
- if(purple_network_listen_range(0, 0, SOCK_STREAM, yahoo_p2p_ft_server_listen_cb, xfer))
+ if(purple_network_listen_range(0, 0, AF_UNSPEC, SOCK_STREAM, TRUE, yahoo_p2p_ft_server_listen_cb, xfer))
return;
pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_INFO_15, YAHOO_STATUS_AVAILABLE, yd->session_id);
@@ -1580,7 +1579,7 @@ static void yahoo_p2p_client_send_ft_info(PurpleConnection *gc, PurpleXfer *xfer
yahoo_packet_hash(pkt, "ssssi",
1, purple_normalize(account, purple_account_get_username(account)),
- 5, xfer->who,
+ 5, purple_xfer_get_remote_user(xfer),
265, xd->xfer_peer_idstring,
27, filename,
249, 2); /* 249=2: we are p2p client */
@@ -1603,13 +1602,13 @@ void yahoo_process_filetrans_15(PurpleConnection *gc, struct yahoo_packet *pkt)
char *filename = NULL;
char *xfer_peer_idstring = NULL;
char *utf8_filename;
- unsigned long filesize = 0L;
+ goffset filesize = G_GOFFSET_CONSTANT(0);
GSList *l;
GSList *filename_list = NULL;
GSList *size_list = NULL;
int nooffiles = 0;
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
for (l = pkt->hash; l; l = l->next) {
struct yahoo_pair *pair = l->data;
@@ -1683,13 +1682,13 @@ void yahoo_process_filetrans_15(PurpleConnection *gc, struct yahoo_packet *pkt)
account = purple_connection_get_account(gc);
if (yd->jp)
{
- purple_dnsquery_a_account(account, YAHOOJP_XFER_RELAY_HOST,
+ purple_dnsquery_a(account, YAHOOJP_XFER_RELAY_HOST,
YAHOOJP_XFER_RELAY_PORT,
yahoo_xfer_dns_connected_15, xfer);
}
else
{
- purple_dnsquery_a_account(account, YAHOO_XFER_RELAY_HOST,
+ purple_dnsquery_a(account, YAHOO_XFER_RELAY_HOST,
YAHOO_XFER_RELAY_PORT,
yahoo_xfer_dns_connected_15, xfer);
}
@@ -1720,7 +1719,7 @@ void yahoo_process_filetrans_15(PurpleConnection *gc, struct yahoo_packet *pkt)
filename_list = g_slist_reverse(filename_list);
size_list = g_slist_reverse(size_list);
filename = filename_list->data;
- filesize = atol(size_list->data);
+ filesize = g_ascii_strtoll(size_list->data, NULL, 10);
if(!from) return;
xfer_data = g_new0(struct yahoo_xfer_data, 1);
@@ -1732,22 +1731,20 @@ void yahoo_process_filetrans_15(PurpleConnection *gc, struct yahoo_packet *pkt)
xfer_data->size_list = size_list;
/* Build the file transfer handle. */
- xfer = purple_xfer_new(gc->account, PURPLE_XFER_RECEIVE, from);
+ xfer = purple_xfer_new(purple_connection_get_account(gc), PURPLE_XFER_RECEIVE, from);
if (xfer == NULL)
{
g_free(xfer_data);
g_return_if_reached();
}
- xfer->message = NULL;
-
/* Set the info about the incoming file. */
utf8_filename = yahoo_string_decode(gc, filename, TRUE);
purple_xfer_set_filename(xfer, utf8_filename);
g_free(utf8_filename);
purple_xfer_set_size(xfer, filesize);
- xfer->data = xfer_data;
+ purple_xfer_set_protocol_data(xfer, xfer_data);
/* Setup our I/O op functions */
purple_xfer_set_init_fnc(xfer, yahoo_xfer_init_15);
@@ -1765,7 +1762,7 @@ void yahoo_process_filetrans_15(PurpleConnection *gc, struct yahoo_packet *pkt)
if(nooffiles > 1) {
gchar* message;
- message = g_strdup_printf(_("%s is trying to send you a group of %d files.\n"), xfer->who, nooffiles);
+ message = g_strdup_printf(_("%s is trying to send you a group of %d files.\n"), purple_xfer_get_remote_user(xfer), nooffiles);
purple_xfer_conversation_write(xfer, message, FALSE);
g_free(message);
}
@@ -1790,7 +1787,7 @@ void yahoo_process_filetrans_info_15(PurpleConnection *gc, struct yahoo_packet *
struct yahoo_packet *pkt_to_send;
struct yahoo_p2p_data *p2p_data;
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
for (l = pkt->hash; l; l = l->next) {
struct yahoo_pair *pair = l->data;
@@ -1837,7 +1834,7 @@ void yahoo_process_filetrans_info_15(PurpleConnection *gc, struct yahoo_packet *
return;
}
- xfer_data = xfer->data;
+ xfer_data = purple_xfer_get_protocol_data(xfer);
xfer_data->info_val_249 = val_249;
xfer_data->xfer_idstring_for_relay = g_strdup(xfer_idstring_for_relay);
@@ -1854,9 +1851,9 @@ void yahoo_process_filetrans_info_15(PurpleConnection *gc, struct yahoo_packet *
YAHOO_STATUS_AVAILABLE, yd->session_id);
yahoo_packet_hash(pkt_to_send, "ssssis",
1, purple_normalize(account, purple_account_get_username(account)),
- 5, xfer->who,
+ 5, purple_xfer_get_remote_user(xfer),
265, xfer_data->xfer_peer_idstring,
- 27, xfer->filename,
+ 27, purple_xfer_get_filename(xfer),
249, xfer_data->info_val_249,
251, xfer_data->xfer_idstring_for_relay);
@@ -1870,12 +1867,12 @@ void yahoo_process_filetrans_info_15(PurpleConnection *gc, struct yahoo_packet *
}
}
else if(val_249 == 2) {
- p2p_data = g_hash_table_lookup(yd->peers, xfer->who);
+ p2p_data = g_hash_table_lookup(yd->peers, purple_xfer_get_remote_user(xfer));
if( !( p2p_data && (p2p_data->connection_type == YAHOO_P2P_WE_ARE_SERVER) ) ) {
purple_xfer_cancel_remote(xfer);
return;
}
- if(!purple_network_listen_range(0, 0, SOCK_STREAM, yahoo_p2p_ft_server_listen_cb, xfer)) {
+ if(!purple_network_listen_range(0, 0, AF_UNSPEC, SOCK_STREAM, TRUE, yahoo_p2p_ft_server_listen_cb, xfer)) {
purple_xfer_cancel_remote(xfer);
return;
}
@@ -1896,7 +1893,7 @@ void yahoo_process_filetrans_acc_15(PurpleConnection *gc, struct yahoo_packet *p
gchar *url = NULL;
int val_249 = 0;
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
for (l = pkt->hash; l; l = l->next) {
struct yahoo_pair *pair = l->data;
@@ -1934,7 +1931,7 @@ void yahoo_process_filetrans_acc_15(PurpleConnection *gc, struct yahoo_packet *p
return;
}
- xfer_data = xfer->data;
+ xfer_data = purple_xfer_get_protocol_data(xfer);
if(url)
purple_url_parse(url, &(xfer_data->host), &(xfer_data->port), &(xfer_data->path), NULL, NULL);
diff --git a/libpurple/protocols/yahoo/yahoo_friend.c b/libpurple/protocols/yahoo/yahoo_friend.c
index 1acced0d8a..8c5e3a45ef 100644
--- a/libpurple/protocols/yahoo/yahoo_friend.c
+++ b/libpurple/protocols/yahoo/yahoo_friend.c
@@ -46,9 +46,10 @@ YahooFriend *yahoo_friend_find(PurpleConnection *gc, const char *name)
const char *norm;
g_return_val_if_fail(gc != NULL, NULL);
- g_return_val_if_fail(gc->proto_data != NULL, NULL);
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
+ g_return_val_if_fail(yd != NULL, NULL);
+
norm = purple_normalize(purple_connection_get_account(gc), name);
return g_hash_table_lookup(yd->friends, norm);
@@ -61,9 +62,10 @@ YahooFriend *yahoo_friend_find_or_new(PurpleConnection *gc, const char *name)
const char *norm;
g_return_val_if_fail(gc != NULL, NULL);
- g_return_val_if_fail(gc->proto_data != NULL, NULL);
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
+ g_return_val_if_fail(yd != NULL, NULL);
+
norm = purple_normalize(purple_connection_get_account(gc), name);
f = g_hash_table_lookup(yd->friends, norm);
@@ -225,7 +227,7 @@ void yahoo_process_presence(PurpleConnection *gc, struct yahoo_packet *pkt)
void yahoo_friend_update_presence(PurpleConnection *gc, const char *name,
YahooPresenceVisibility presence)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt = NULL;
YahooFriend *f;
const char *thirtyone, *thirteen;
diff --git a/libpurple/protocols/yahoo/yahoo_packet.c b/libpurple/protocols/yahoo/yahoo_packet.c
index f029575782..a2a4fa0803 100644
--- a/libpurple/protocols/yahoo/yahoo_packet.c
+++ b/libpurple/protocols/yahoo/yahoo_packet.c
@@ -302,7 +302,7 @@ yahoo_packet_send_can_write(gpointer data, gint source, PurpleInputCondition con
return;
else if (ret < 0) {
/* TODO: what to do here - do we really have to disconnect? */
- purple_connection_error_reason(yd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error(yd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Write Error"));
return;
}
diff --git a/libpurple/protocols/yahoo/yahoo_picture.c b/libpurple/protocols/yahoo/yahoo_picture.c
index f04b8fc51e..f9cfde63e3 100644
--- a/libpurple/protocols/yahoo/yahoo_picture.c
+++ b/libpurple/protocols/yahoo/yahoo_picture.c
@@ -52,7 +52,7 @@ yahoo_fetch_picture_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data,
YahooData *yd;
d = user_data;
- yd = d->gc->proto_data;
+ yd = purple_connection_get_protocol_data(d->gc);
yd->url_datas = g_slist_remove(yd->url_datas, url_data);
if (error_message != NULL) {
@@ -132,10 +132,10 @@ void yahoo_process_picture(PurpleConnection *gc, struct yahoo_packet *pkt)
data->checksum = checksum;
/* TODO: Does this need to be MSIE 5.0? */
url_data = purple_util_fetch_url(url, use_whole_url,
- "Mozilla/4.0 (compatible; MSIE 5.5)", FALSE,
+ "Mozilla/4.0 (compatible; MSIE 5.5)", FALSE, -1,
yahoo_fetch_picture_cb, data);
if (url_data != NULL) {
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
}
} else if (who && send_icon_info) {
@@ -167,7 +167,7 @@ void yahoo_process_picture_checksum(PurpleConnection *gc, struct yahoo_packet *p
}
if (who) {
- PurpleBuddy *b = purple_find_buddy(gc->account, who);
+ PurpleBuddy *b = purple_find_buddy(purple_connection_get_account(gc), who);
const char *locksum = NULL;
/* FIXME: Cleanup this strtol() stuff if possible. */
@@ -182,7 +182,7 @@ void yahoo_process_picture_checksum(PurpleConnection *gc, struct yahoo_packet *p
void yahoo_process_picture_upload(PurpleConnection *gc, struct yahoo_packet *pkt)
{
PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
GSList *l = pkt->hash;
char *url = NULL;
@@ -248,7 +248,7 @@ void yahoo_process_avatar_update(PurpleConnection *gc, struct yahoo_packet *pkt)
yahoo_send_picture_request(gc, who);
else if ((avatar == 0) || (avatar == 1)) {
YahooFriend *f;
- purple_buddy_icons_set_for_user(gc->account, who, NULL, 0, NULL);
+ purple_buddy_icons_set_for_user(purple_connection_get_account(gc), who, NULL, 0, NULL);
if ((f = yahoo_friend_find(gc, who)))
yahoo_friend_set_buddy_icon_need_request(f, TRUE);
purple_debug_misc("yahoo", "Setting user %s's icon to NULL.\n", who);
@@ -258,7 +258,7 @@ void yahoo_process_avatar_update(PurpleConnection *gc, struct yahoo_packet *pkt)
void yahoo_send_picture_info(PurpleConnection *gc, const char *who)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
if (!yd->picture_url) {
@@ -275,7 +275,7 @@ void yahoo_send_picture_info(PurpleConnection *gc, const char *who)
void yahoo_send_picture_request(PurpleConnection *gc, const char *who)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, yd->session_id);
@@ -287,7 +287,7 @@ void yahoo_send_picture_request(PurpleConnection *gc, const char *who)
void yahoo_send_picture_checksum(PurpleConnection *gc)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_CHECKSUM, YAHOO_STATUS_AVAILABLE, yd->session_id);
@@ -298,7 +298,7 @@ void yahoo_send_picture_checksum(PurpleConnection *gc)
void yahoo_send_picture_update_to_user(PurpleConnection *gc, const char *who, int type)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
pkt = yahoo_packet_new(YAHOO_SERVICE_AVATAR_UPDATE, YAHOO_STATUS_AVAILABLE, yd->session_id);
@@ -323,7 +323,7 @@ static void yahoo_send_picture_update_foreach(gpointer key, gpointer value, gpoi
void yahoo_send_picture_update(PurpleConnection *gc, int type)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yspufe data;
data.gc = gc;
@@ -422,7 +422,7 @@ static void yahoo_buddy_icon_upload_connected(gpointer data, gint source, const
gboolean use_whole_url = yahoo_account_use_http_proxy(gc);
account = purple_connection_get_account(gc);
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
/* Buddy icon connect is now complete; clear the PurpleProxyConnectData */
yd->buddy_icon_connect_data = NULL;
@@ -487,7 +487,7 @@ static void yahoo_buddy_icon_upload_connected(gpointer data, gint source, const
void yahoo_buddy_icon_upload(PurpleConnection *gc, struct yahoo_buddy_icon_upload_data *d)
{
PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
if (yd->buddy_icon_connect_data != NULL) {
/* Cancel any in-progress buddy icon upload */
@@ -532,8 +532,8 @@ static int yahoo_buddy_icon_calculate_checksum(const guchar *data, gsize len)
void yahoo_set_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img)
{
- YahooData *yd = gc->proto_data;
- PurpleAccount *account = gc->account;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
+ PurpleAccount *account = purple_connection_get_account(gc);
if (img == NULL) {
g_free(yd->picture_url);
diff --git a/libpurple/protocols/yahoo/yahoo_profile.c b/libpurple/protocols/yahoo/yahoo_profile.c
index 4938d73f6c..8203d96b81 100644
--- a/libpurple/protocols/yahoo/yahoo_profile.c
+++ b/libpurple/protocols/yahoo/yahoo_profile.c
@@ -789,7 +789,7 @@ static void yahoo_got_info(PurpleUtilFetchUrlData *url_data, gpointer user_data,
purple_debug_info("yahoo", "In yahoo_got_info\n");
- yd = info_data->gc->proto_data;
+ yd = purple_connection_get_protocol_data(info_data->gc);
yd->url_datas = g_slist_remove(yd->url_datas, url_data);
user_info = purple_notify_user_info_new();
@@ -805,7 +805,7 @@ static void yahoo_got_info(PurpleUtilFetchUrlData *url_data, gpointer user_data,
* to send back HTML, with a 200 status code.
*/
if (error_message != NULL || url_text == NULL || strcmp(url_text, "") == 0) {
- purple_notify_user_info_add_pair(user_info, _("Error retrieving profile"), NULL);
+ purple_notify_user_info_add_pair_html(user_info, _("Error retrieving profile"), NULL);
purple_notify_userinfo(info_data->gc, info_data->name,
user_info, NULL, NULL);
purple_notify_user_info_destroy(user_info);
@@ -840,7 +840,7 @@ static void yahoo_got_info(PurpleUtilFetchUrlData *url_data, gpointer user_data,
_("If you wish to view this profile, "
"you will need to visit this link in your web browser:"),
profile_url_text, profile_url_text);
- purple_notify_user_info_add_pair(user_info, NULL, tmp);
+ purple_notify_user_info_add_pair_html(user_info, NULL, tmp);
g_free(tmp);
purple_notify_userinfo(info_data->gc, info_data->name,
@@ -940,7 +940,7 @@ static void yahoo_got_info(PurpleUtilFetchUrlData *url_data, gpointer user_data,
* we specify HTTP 1.1. So we have to specify 1.0 & fix purple_util_fetch_url
*/
url_data = purple_util_fetch_url(photo_url_text, use_whole_url, NULL,
- FALSE, yahoo_got_photo, info2_data);
+ FALSE, -1, yahoo_got_photo, info2_data);
if (url_data != NULL)
yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
} else {
@@ -983,7 +983,7 @@ yahoo_got_photo(PurpleUtilFetchUrlData *url_data, gpointer data,
/* in to purple_markup_strip_html*/
char *fudged_buffer;
- yd = info_data->gc->proto_data;
+ yd = purple_connection_get_protocol_data(info_data->gc);
yd->url_datas = g_slist_remove(yd->url_datas, url_data);
fudged_buffer = purple_strcasereplace(url_buffer, "</dd>", "</dd><br>");
@@ -1047,8 +1047,9 @@ yahoo_got_photo(PurpleUtilFetchUrlData *url_data, gpointer data,
" bytes\n", photo_url_text, len);
id = purple_imgstore_add_with_id(g_memdup(url_text, len), len, NULL);
- tmp = g_strdup_printf("<img id=\"%d\"><br>", id);
- purple_notify_user_info_add_pair(user_info, NULL, tmp);
+ tmp = g_strdup_printf("<img id=\"" PURPLE_STORED_IMAGE_PROTOCOL "%d\"><br>",
+ id);
+ purple_notify_user_info_add_pair_html(user_info, NULL, tmp);
g_free(tmp);
}
}
@@ -1195,7 +1196,7 @@ yahoo_got_photo(PurpleUtilFetchUrlData *url_data, gpointer data,
const gchar *str;
purple_notify_user_info_add_section_break(user_info);
- purple_notify_user_info_add_pair(user_info,
+ purple_notify_user_info_add_pair_html(user_info,
_("Error retrieving profile"), NULL);
if (profile_state == PROFILE_STATE_UNKNOWN_LANGUAGE) {
@@ -1228,14 +1229,14 @@ yahoo_got_photo(PurpleUtilFetchUrlData *url_data, gpointer data,
str = _("The user's profile is empty.");
}
- purple_notify_user_info_add_pair(user_info, NULL, str);
+ purple_notify_user_info_add_pair_plaintext(user_info, NULL, str);
}
/* put a link to the actual profile URL */
purple_notify_user_info_add_section_break(user_info);
tmp = g_strdup_printf("<a href=\"%s\">%s</a>",
profile_url_text, _("View web profile"));
- purple_notify_user_info_add_pair(user_info, NULL, tmp);
+ purple_notify_user_info_add_pair_html(user_info, NULL, tmp);
g_free(tmp);
g_free(stripped);
@@ -1262,7 +1263,7 @@ yahoo_got_photo(PurpleUtilFetchUrlData *url_data, gpointer data,
void yahoo_get_info(PurpleConnection *gc, const char *name)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
YahooGetInfoData *data;
char *url;
PurpleUtilFetchUrlData *url_data;
@@ -1274,7 +1275,7 @@ void yahoo_get_info(PurpleConnection *gc, const char *name)
url = g_strdup_printf("%s%s",
(yd->jp ? YAHOOJP_PROFILE_URL : YAHOO_PROFILE_URL), name);
- url_data = purple_util_fetch_url(url, TRUE, NULL, FALSE, yahoo_got_info, data);
+ url_data = purple_util_fetch_url(url, TRUE, NULL, FALSE, -1, yahoo_got_info, data);
if (url_data != NULL)
yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
diff --git a/libpurple/protocols/yahoo/yahoochat.c b/libpurple/protocols/yahoo/yahoochat.c
index 10635908a5..c384dcf859 100644
--- a/libpurple/protocols/yahoo/yahoochat.c
+++ b/libpurple/protocols/yahoo/yahoochat.c
@@ -53,7 +53,7 @@ static void yahoo_chat_leave(PurpleConnection *gc, const char *room, const char
/* special function to log us on to the yahoo chat service */
static void yahoo_chat_online(PurpleConnection *gc)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
const char *rll;
@@ -101,7 +101,7 @@ static PurpleConversation *yahoo_find_conference(PurpleConnection *gc, const cha
YahooData *yd;
GSList *l;
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
for (l = yd->confs; l; l = l->next) {
PurpleConversation *c = l->data;
@@ -372,7 +372,7 @@ void yahoo_process_conference_message(PurpleConnection *gc, struct yahoo_packet
static void yahoo_chat_join(PurpleConnection *gc, const char *dn, const char *room, const char *topic, const char *id)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
char *room2;
gboolean utf8 = TRUE;
@@ -400,7 +400,7 @@ static void yahoo_chat_join(PurpleConnection *gc, const char *dn, const char *ro
/* this is a confirmation of yahoo_chat_online(); */
void yahoo_process_chat_online(PurpleConnection *gc, struct yahoo_packet *pkt)
{
- YahooData *yd = (YahooData *) gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
if (pkt->status == 1) {
yd->chat_online = TRUE;
@@ -432,7 +432,7 @@ void yahoo_process_chat_online(PurpleConnection *gc, struct yahoo_packet *pkt)
/* this is basicly the opposite of chat_online */
void yahoo_process_chat_logout(PurpleConnection *gc, struct yahoo_packet *pkt)
{
- YahooData *yd = (YahooData *) gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
GSList *l;
for (l = pkt->hash; l; l = l->next) {
@@ -462,7 +462,7 @@ void yahoo_process_chat_logout(PurpleConnection *gc, struct yahoo_packet *pkt)
void yahoo_process_chat_join(PurpleConnection *gc, struct yahoo_packet *pkt)
{
PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = (YahooData *) gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
PurpleConversation *c = NULL;
GSList *l;
GList *members = NULL;
@@ -786,7 +786,7 @@ void yahoo_conf_leave(YahooData *yd, const char *room, const char *dn, GList *wh
static int yahoo_conf_send(PurpleConnection *gc, const char *dn, const char *room,
GList *members, const char *what)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
GList *who;
char *msg, *msg2;
@@ -843,7 +843,7 @@ static void yahoo_conf_join(YahooData *yd, PurpleConversation *c, const char *dn
static void yahoo_conf_invite(PurpleConnection *gc, PurpleConversation *c,
const char *dn, const char *buddy, const char *room, const char *msg)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
GList *members;
char *msg2 = NULL;
@@ -873,7 +873,7 @@ static void yahoo_conf_invite(PurpleConnection *gc, PurpleConversation *c,
static void yahoo_chat_leave(PurpleConnection *gc, const char *room, const char *dn, gboolean logout)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
char *eroom;
@@ -924,7 +924,7 @@ static void yahoo_chat_leave(PurpleConnection *gc, const char *room, const char
static int yahoo_chat_send(PurpleConnection *gc, const char *dn, const char *room, const char *what, PurpleMessageFlags flags)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
int me = 0;
char *msg1, *msg2, *room2;
@@ -969,7 +969,7 @@ static int yahoo_chat_send(PurpleConnection *gc, const char *dn, const char *roo
static void yahoo_chat_invite(PurpleConnection *gc, const char *dn, const char *buddy,
const char *room, const char *msg)
{
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_packet *pkt;
char *room2, *msg2 = NULL;
gboolean utf8 = TRUE;
@@ -997,7 +997,7 @@ void yahoo_chat_goto(PurpleConnection *gc, const char *name)
YahooData *yd;
struct yahoo_packet *pkt;
- yd = gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
if (yd->wm) {
g_return_if_fail(yd->ycht != NULL);
@@ -1029,7 +1029,7 @@ void yahoo_chat_goto(PurpleConnection *gc, const char *name)
void yahoo_c_leave(PurpleConnection *gc, int id)
{
- YahooData *yd = (YahooData *) gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
PurpleConversation *c;
if (!yd)
@@ -1056,7 +1056,7 @@ int yahoo_c_send(PurpleConnection *gc, int id, const char *what, PurpleMessageFl
int ret;
YahooData *yd;
- yd = (YahooData *) gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
if (!yd)
return -1;
@@ -1114,7 +1114,7 @@ void yahoo_c_join(PurpleConnection *gc, GHashTable *data)
char *room, *topic, *type;
PurpleConversation *c;
- yd = (YahooData *) gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc);
if (!yd)
return;
@@ -1166,7 +1166,7 @@ void yahoo_c_invite(PurpleConnection *gc, int id, const char *msg, const char *n
PurpleConversation *c;
c = purple_find_chat(gc, id);
- if (!c || !c->name)
+ if (!c || !purple_conversation_get_name(c))
return;
if (id != YAHOO_CHAT_ID) {
@@ -1375,7 +1375,9 @@ static void yahoo_roomlist_cleanup(PurpleRoomlist *list, struct yahoo_roomlist *
purple_roomlist_set_in_progress(list, FALSE);
if (yrl) {
- list->proto_data = g_list_remove(list->proto_data, yrl);
+ GList *proto_data = purple_roomlist_get_proto_data(list);
+ proto_data = g_list_remove(proto_data, yrl);
+ purple_roomlist_set_proto_data(list, proto_data);
yahoo_roomlist_destroy(yrl);
}
@@ -1451,7 +1453,7 @@ static void yahoo_roomlist_send_cb(gpointer data, gint source, PurpleInputCondit
yrl->inpa = 0;
g_free(yrl->txbuf);
yrl->txbuf = NULL;
- purple_notify_error(purple_account_get_connection(list->account), NULL, _("Unable to connect"), _("Fetching the room list failed."));
+ purple_notify_error(purple_account_get_connection(purple_roomlist_get_account(list)), NULL, _("Unable to connect"), _("Fetching the room list failed."));
yahoo_roomlist_cleanup(list, yrl);
return;
}
@@ -1474,10 +1476,12 @@ static void yahoo_roomlist_got_connected(gpointer data, gint source, const gchar
{
struct yahoo_roomlist *yrl = data;
PurpleRoomlist *list = yrl->list;
- YahooData *yd = purple_account_get_connection(list->account)->proto_data;
+ PurpleAccount *account = purple_roomlist_get_account(list);
+ PurpleConnection *pc = purple_account_get_connection(account);
+ YahooData *yd = purple_connection_get_protocol_data(pc);
if (source < 0) {
- purple_notify_error(purple_account_get_connection(list->account), NULL, _("Unable to connect"), _("Fetching the room list failed."));
+ purple_notify_error(pc, NULL, _("Unable to connect"), _("Fetching the room list failed."));
yahoo_roomlist_cleanup(list, yrl);
return;
}
@@ -1506,6 +1510,7 @@ PurpleRoomlist *yahoo_roomlist_get_list(PurpleConnection *gc)
struct yahoo_roomlist *yrl;
const char *rll, *rlurl;
char *url;
+ GList *proto_data;
account = purple_connection_get_account(gc);
@@ -1556,7 +1561,9 @@ PurpleRoomlist *yahoo_roomlist_get_list(PurpleConnection *gc)
return NULL;
}
- rl->proto_data = g_list_append(rl->proto_data, yrl);
+ proto_data = purple_roomlist_get_proto_data(rl);
+ proto_data = g_list_append(proto_data, yrl);
+ purple_roomlist_set_proto_data(rl, proto_data);
purple_roomlist_set_in_progress(rl, TRUE);
return rl;
@@ -1566,8 +1573,8 @@ void yahoo_roomlist_cancel(PurpleRoomlist *list)
{
GList *l, *k;
- k = l = list->proto_data;
- list->proto_data = NULL;
+ k = l = purple_roomlist_get_proto_data(list);
+ purple_roomlist_set_proto_data(list, NULL);
purple_roomlist_set_in_progress(list, FALSE);
@@ -1580,36 +1587,42 @@ void yahoo_roomlist_cancel(PurpleRoomlist *list)
void yahoo_roomlist_expand_category(PurpleRoomlist *list, PurpleRoomlistRoom *category)
{
+ PurpleAccount *account;
struct yahoo_roomlist *yrl;
char *url;
char *id;
const char *rll;
+ GList *proto_data;
- if (category->type != PURPLE_ROOMLIST_ROOMTYPE_CATEGORY)
+ if (purple_roomlist_room_get_type(category) != PURPLE_ROOMLIST_ROOMTYPE_CATEGORY)
return;
- if (!(id = g_list_nth_data(category->fields, 1))) {
+ if (!(id = g_list_nth_data(purple_roomlist_room_get_fields(category), 1))) {
purple_roomlist_set_in_progress(list, FALSE);
return;
}
- rll = purple_account_get_string(list->account, "room_list_locale",
+ account = purple_roomlist_get_account(list);
+ rll = purple_account_get_string(account, "room_list_locale",
YAHOO_ROOMLIST_LOCALE);
if (rll != NULL && *rll != '\0') {
url = g_strdup_printf("%s?chatroom_%s=0&intl=%s",
- purple_account_get_string(list->account,"room_list",
+ purple_account_get_string(account,"room_list",
YAHOO_ROOMLIST_URL), id, rll);
} else {
url = g_strdup_printf("%s?chatroom_%s=0",
- purple_account_get_string(list->account,"room_list",
+ purple_account_get_string(account,"room_list",
YAHOO_ROOMLIST_URL), id);
}
yrl = g_new0(struct yahoo_roomlist, 1);
yrl->list = list;
yrl->cat = category;
- list->proto_data = g_list_append(list->proto_data, yrl);
+
+ proto_data = purple_roomlist_get_proto_data(list);
+ proto_data = g_list_append(proto_data, yrl);
+ purple_roomlist_set_proto_data(list, proto_data);
purple_url_parse(url, &(yrl->host), NULL, &(yrl->path), NULL, NULL);
g_free(url);
@@ -1617,11 +1630,11 @@ void yahoo_roomlist_expand_category(PurpleRoomlist *list, PurpleRoomlistRoom *ca
yrl->ucat = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_CATEGORY, _("User Rooms"), yrl->cat);
purple_roomlist_room_add(list, yrl->ucat);
- if (purple_proxy_connect(purple_account_get_connection(list->account),
- list->account, yrl->host, 80,
+ if (purple_proxy_connect(purple_account_get_connection(account),
+ account, yrl->host, 80,
yahoo_roomlist_got_connected, yrl) == NULL)
{
- purple_notify_error(purple_account_get_connection(list->account),
+ purple_notify_error(purple_account_get_connection(account),
NULL, _("Connection problem"), _("Unable to fetch room list."));
purple_roomlist_ref(list);
yahoo_roomlist_cleanup(list, yrl);
diff --git a/libpurple/protocols/yahoo/ycht.c b/libpurple/protocols/yahoo/ycht.c
index 5a05e1869d..22f3142116 100644
--- a/libpurple/protocols/yahoo/ycht.c
+++ b/libpurple/protocols/yahoo/ycht.c
@@ -53,7 +53,7 @@
static void ycht_process_login(YchtConn *ycht, YchtPkt *pkt)
{
PurpleConnection *gc = ycht->gc;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
if (ycht->logged_in)
return;
@@ -68,7 +68,7 @@ static void ycht_process_login(YchtConn *ycht, YchtPkt *pkt)
static void ycht_process_logout(YchtConn *ycht, YchtPkt *pkt)
{
PurpleConnection *gc = ycht->gc;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
yd->chat_online = FALSE;
ycht->logged_in = FALSE;
@@ -173,7 +173,7 @@ static void ycht_progress_online_friends(YchtConn *ycht, YchtPkt *pkt)
{
#if 0
PurpleConnection *gc = ycht->gc;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
if (ycht->logged_in)
return;
@@ -285,7 +285,7 @@ static void ycht_packet_send_write_cb(gpointer data, gint source, PurpleInputCon
/*
gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
g_strerror(errno));
- purple_connection_error_reason(purple_account_get_connection(irc->account),
+ purple_connection_error(purple_account_get_connection(irc->account),
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
*/
@@ -429,7 +429,7 @@ static void ycht_packet_free(YchtPkt *pkt)
void ycht_connection_close(YchtConn *ycht)
{
- YahooData *yd = ycht->gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(ycht->gc);
if (yd) {
yd->ycht = NULL;
@@ -541,7 +541,7 @@ static void ycht_got_connected(gpointer data, gint source, const gchar *error_me
{
YchtConn *ycht = data;
PurpleConnection *gc = ycht->gc;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
YchtPkt *pkt;
char *buf;
@@ -568,7 +568,7 @@ static void ycht_got_connected(gpointer data, gint source, const gchar *error_me
void ycht_connection_open(PurpleConnection *gc)
{
YchtConn *ycht;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
PurpleAccount *account = purple_connection_get_account(gc);
ycht = g_new0(YchtConn, 1);
diff --git a/libpurple/protocols/zephyr/ZRetSubs.c b/libpurple/protocols/zephyr/ZRetSubs.c
index 35ade9c2f4..376b218a3a 100644
--- a/libpurple/protocols/zephyr/ZRetSubs.c
+++ b/libpurple/protocols/zephyr/ZRetSubs.c
@@ -132,6 +132,11 @@ static Code_t Z_RetSubs(notice, nsubs, auth_routine)
__subscriptions_num = __subscriptions_num / 3;
+ if (!__subscriptions_num) {
+ ZFreeNotice(&retnotice);
+ continue;
+ }
+
__subscriptions_list = (ZSubscription_t *)
malloc((unsigned)(__subscriptions_num*
sizeof(ZSubscription_t)));
diff --git a/libpurple/protocols/zephyr/zephyr.c b/libpurple/protocols/zephyr/zephyr.c
index 69c71137cf..c02d5d2226 100644
--- a/libpurple/protocols/zephyr/zephyr.c
+++ b/libpurple/protocols/zephyr/zephyr.c
@@ -146,7 +146,7 @@ struct _zephyr_triple {
return TRUE;
#define z_call_s(func, err) if (func != ZERR_NONE) {\
- purple_connection_error(gc, err);\
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, err);\
return;\
}
@@ -347,7 +347,7 @@ static gchar *zephyr_recv_convert(PurpleConnection *gc, gchar *string)
{
gchar *utf8;
GError *err = NULL;
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
if (g_utf8_validate(string, -1, NULL)) {
return g_strdup(string);
} else {
@@ -762,7 +762,7 @@ static void message_failed(PurpleConnection *gc, ZNotice_t notice, struct sockad
static void handle_message(PurpleConnection *gc,ZNotice_t notice)
{
- zephyr_account* zephyr = gc->proto_data;
+ zephyr_account* zephyr = purple_connection_get_protocol_data(gc);
if (!g_ascii_strcasecmp(notice.z_class, LOGIN_CLASS)) {
/* well, we'll be updating in 20 seconds anyway, might as well ignore this. */
@@ -777,9 +777,9 @@ static void handle_message(PurpleConnection *gc,ZNotice_t notice)
if (ZParseLocations(&notice, NULL, &nlocs, &user) != ZERR_NONE)
return;
- if ((b = purple_find_buddy(gc->account, user)) == NULL) {
+ if ((b = purple_find_buddy(purple_connection_get_account(gc), user)) == NULL) {
char* stripped_user = zephyr_strip_local_realm(zephyr,user);
- b = purple_find_buddy(gc->account,stripped_user);
+ b = purple_find_buddy(purple_connection_get_account(gc),stripped_user);
g_free(stripped_user);
}
@@ -791,20 +791,23 @@ static void handle_message(PurpleConnection *gc,ZNotice_t notice)
char *tmp;
const char *balias;
- purple_notify_user_info_add_pair(user_info, _("User"), (b ? bname : user));
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("User"), (b ? bname : user));
balias = purple_buddy_get_local_buddy_alias(b);
if (b && balias)
- purple_notify_user_info_add_pair(user_info, _("Alias"), balias);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), balias);
if (!nlocs) {
- purple_notify_user_info_add_pair(user_info, NULL, _("Hidden or not logged-in"));
+ purple_notify_user_info_add_pair_plaintext(user_info, NULL, _("Hidden or not logged-in"));
}
for (; nlocs > 0; nlocs--) {
/* XXX add real error reporting */
ZGetLocations(&locs, &one);
+ /* TODO: Need to escape locs.host and locs.time? */
tmp = g_strdup_printf(_("<br>At %s since %s"), locs.host, locs.time);
- purple_notify_user_info_add_pair(user_info, _("Location"), tmp);
+ purple_notify_user_info_add_pair_html(user_info, _("Location"), tmp);
g_free(tmp);
}
purple_notify_userinfo(gc, (b ? bname : user),
@@ -812,9 +815,9 @@ static void handle_message(PurpleConnection *gc,ZNotice_t notice)
purple_notify_user_info_destroy(user_info);
} else {
if (nlocs>0)
- purple_prpl_got_user_status(gc->account, b ? bname : user, "available", NULL);
+ purple_prpl_got_user_status(purple_connection_get_account(gc), b ? bname : user, "available", NULL);
else
- purple_prpl_got_user_status(gc->account, b ? bname : user, "offline", NULL);
+ purple_prpl_got_user_status(purple_connection_get_account(gc), b ? bname : user, "offline", NULL);
}
g_free(user);
@@ -869,7 +872,7 @@ static void handle_message(PurpleConnection *gc,ZNotice_t notice)
} else {
zephyr_triple *zt1, *zt2;
gchar *send_inst_utf8;
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
zt1 = new_triple(zephyr,notice.z_class, notice.z_class_inst, notice.z_recipient);
zt2 = find_sub_by_triple(zephyr,zt1);
if (!zt2) {
@@ -897,7 +900,7 @@ static void handle_message(PurpleConnection *gc,ZNotice_t notice)
}
gconv1 = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- zt2->name, gc->account);
+ zt2->name, purple_connection_get_account(gc));
gcc = purple_conversation_get_chat_data(gconv1);
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
@@ -1106,7 +1109,7 @@ static parse_tree *read_from_tzc(zephyr_account* zephyr){
static gint check_notify_tzc(gpointer data)
{
PurpleConnection *gc = (PurpleConnection *)data;
- zephyr_account* zephyr = gc->proto_data;
+ zephyr_account* zephyr = purple_connection_get_protocol_data(gc);
parse_tree *newparsetree = read_from_tzc(zephyr);
if (newparsetree != NULL) {
gchar *spewtype;
@@ -1153,15 +1156,15 @@ static gint check_notify_tzc(gpointer data)
gchar *locval;
user = tree_child(find_node(newparsetree,"user"),2)->contents;
- if ((b = purple_find_buddy(gc->account, user)) == NULL) {
+ if ((b = purple_find_buddy(purple_connection_get_account(gc), user)) == NULL) {
gchar *stripped_user = zephyr_strip_local_realm(zephyr,user);
- b = purple_find_buddy(gc->account, stripped_user);
+ b = purple_find_buddy(purple_connection_get_account(gc), stripped_user);
g_free(stripped_user);
}
locations = find_node(newparsetree,"locations");
locval = tree_child(tree_child(tree_child(tree_child(locations,2),0),0),2)->contents;
- if (!locval || !g_ascii_strcasecmp(locval," ") || (strlen(locval) == 0)) {
+ if (!locval || !g_ascii_strcasecmp(locval," ") || !*locval) {
nlocs = 0;
} else {
nlocs = 1;
@@ -1173,19 +1176,22 @@ static gint check_notify_tzc(gpointer data)
char *tmp;
const char *balias;
- purple_notify_user_info_add_pair(user_info, _("User"), (b ? bname : user));
+ /* TODO: Check whether it's correct to call add_pair_html,
+ or if we should be using add_pair_plaintext */
+ purple_notify_user_info_add_pair_html(user_info, _("User"), (b ? bname : user));
balias = b ? purple_buddy_get_local_buddy_alias(b) : NULL;
if (balias)
- purple_notify_user_info_add_pair(user_info, _("Alias"), balias);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), balias);
if (!nlocs) {
- purple_notify_user_info_add_pair(user_info, NULL, _("Hidden or not logged-in"));
+ purple_notify_user_info_add_pair_plaintext(user_info, NULL, _("Hidden or not logged-in"));
} else {
+ /* TODO: Need to escape the two strings that make up tmp? */
tmp = g_strdup_printf(_("<br>At %s since %s"),
tree_child(tree_child(tree_child(tree_child(locations,2),0),0),2)->contents,
tree_child(tree_child(tree_child(tree_child(locations,2),0),2),2)->contents);
- purple_notify_user_info_add_pair(user_info, _("Location"), tmp);
+ purple_notify_user_info_add_pair_html(user_info, _("Location"), tmp);
g_free(tmp);
}
@@ -1194,9 +1200,9 @@ static gint check_notify_tzc(gpointer data)
purple_notify_user_info_destroy(user_info);
} else {
if (nlocs>0)
- purple_prpl_got_user_status(gc->account, b ? bname : user, "available", NULL);
+ purple_prpl_got_user_status(purple_connection_get_account(gc), b ? bname : user, "available", NULL);
else
- purple_prpl_got_user_status(gc->account, b ? bname : user, "offline", NULL);
+ purple_prpl_got_user_status(purple_connection_get_account(gc), b ? bname : user, "offline", NULL);
}
}
else if (!g_ascii_strncasecmp(spewtype,"subscribed",10)) {
@@ -1259,7 +1265,7 @@ static gint check_loc(gpointer data)
GSList *buddies;
ZLocations_t locations;
PurpleConnection *gc = data;
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
PurpleAccount *account = purple_connection_get_account(gc);
int numlocs;
int one = 1;
@@ -1290,7 +1296,7 @@ static gint check_loc(gpointer data)
GSList *buddies;
ZAsyncLocateData_t ald;
PurpleConnection *gc = (PurpleConnection *)data;
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
PurpleAccount *account = purple_connection_get_account(gc);
if (use_zeph02(zephyr)) {
@@ -1515,11 +1521,11 @@ static void process_anyone(PurpleConnection *gc)
while (fgets(buff, BUFSIZ, fd)) {
strip_comments(buff);
if (buff[0]) {
- if (!(b = purple_find_buddy(gc->account, buff))) {
+ if (!(b = purple_find_buddy(purple_connection_get_account(gc), buff))) {
char *stripped_user = zephyr_strip_local_realm(zephyr,buff);
purple_debug_info("zephyr","stripped_user %s\n",stripped_user);
- if (!(b = purple_find_buddy(gc->account,stripped_user))){
- b = purple_buddy_new(gc->account, stripped_user, NULL);
+ if (!(b = purple_find_buddy(purple_connection_get_account(gc),stripped_user))){
+ b = purple_buddy_new(purple_connection_get_account(gc), stripped_user, NULL);
purple_blist_add_buddy(b, NULL, g, NULL);
}
g_free(stripped_user);
@@ -1558,34 +1564,35 @@ static void zephyr_login(PurpleAccount * account)
gchar *exposure;
gc = purple_account_get_connection(account);
- read_anyone = purple_account_get_bool(gc->account,"read_anyone",TRUE);
- read_zsubs = purple_account_get_bool(gc->account,"read_zsubs",TRUE);
- exposure = (gchar *)purple_account_get_string(gc->account, "exposure_level", EXPOSE_REALMVIS);
+ read_anyone = purple_account_get_bool(purple_connection_get_account(gc),"read_anyone",TRUE);
+ read_zsubs = purple_account_get_bool(purple_connection_get_account(gc),"read_zsubs",TRUE);
+ exposure = (gchar *)purple_account_get_string(purple_connection_get_account(gc), "exposure_level", EXPOSE_REALMVIS);
#ifdef WIN32
username = purple_account_get_username(account);
#endif
- gc->flags |= PURPLE_CONNECTION_AUTO_RESP | PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC;
- gc->proto_data = zephyr=g_new0(zephyr_account,1);
+ purple_connection_set_flags(gc, PURPLE_CONNECTION_AUTO_RESP | PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC);
+ zephyr = g_new0(zephyr_account, 1);
+ purple_connection_set_protocol_data(gc, zephyr);
zephyr->account = account;
/* Make sure that the exposure (visibility) is set to a sane value */
zephyr->exposure=g_strdup(normalize_zephyr_exposure(exposure));
- if (purple_account_get_bool(gc->account,"use_tzc",0)) {
+ if (purple_account_get_bool(purple_connection_get_account(gc),"use_tzc",0)) {
zephyr->connection_type = PURPLE_ZEPHYR_TZC;
} else {
zephyr->connection_type = PURPLE_ZEPHYR_KRB4;
}
- zephyr->encoding = (char *)purple_account_get_string(gc->account, "encoding", ZEPHYR_FALLBACK_CHARSET);
+ zephyr->encoding = (char *)purple_account_get_string(purple_connection_get_account(gc), "encoding", ZEPHYR_FALLBACK_CHARSET);
purple_connection_update_progress(gc, _("Connecting"), 0, 8);
/* XXX z_call_s should actually try to report the com_err determined error */
if (use_tzc(zephyr)) {
pid_t pid;
- /* purple_connection_error(gc,"tzc not supported yet"); */
+ /* purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, "tzc not supported yet"); */
if ((pipe(zephyr->totzc) != 0) || (pipe(zephyr->fromtzc) != 0)) {
purple_debug_error("zephyr", "pipe creation failed. killing\n");
exit(-1);
@@ -1600,7 +1607,7 @@ static void zephyr_login(PurpleAccount * account)
if (pid == 0) {
unsigned int i=0;
gboolean found_ps = FALSE;
- gchar ** tzc_cmd_array = g_strsplit(purple_account_get_string(gc->account,"tzc_command","/usr/bin/tzc -e %s")," ",0);
+ gchar ** tzc_cmd_array = g_strsplit(purple_account_get_string(purple_connection_get_account(gc),"tzc_command","/usr/bin/tzc -e %s")," ",0);
if (close(1) == -1) {
exit(-1);
}
@@ -1706,7 +1713,7 @@ static void zephyr_login(PurpleAccount * account)
ptr++;
}
if (ptr >=bufcur) {
- purple_connection_error(gc,"invalid output by tzc (or bad parsing code)");
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, "invalid output by tzc (or bad parsing code)");
free(buf);
return;
}
@@ -1772,7 +1779,7 @@ static void zephyr_login(PurpleAccount * account)
if ((realm = strchr(username,'@')))
zephyr->realm = g_strdup_printf("%s",realm+1);
else {
- realm = (gchar *)purple_account_get_string(gc->account,"realm","");
+ realm = (gchar *)purple_account_get_string(purple_connection_get_account(gc),"realm","");
if (!*realm) {
realm = "local-realm";
}
@@ -1809,7 +1816,7 @@ static void zephyr_login(PurpleAccount * account)
z_call_s(ZOpenPort(&(zephyr->port)), "Couldn't open port");
z_call_s(ZSetLocation((char *)zephyr->exposure), "Couldn't set location");
- realm = (gchar *)purple_account_get_string(gc->account,"realm","");
+ realm = (gchar *)purple_account_get_string(purple_connection_get_account(gc),"realm","");
if (!*realm) {
realm = ZGetRealm();
}
@@ -1821,7 +1828,7 @@ static void zephyr_login(PurpleAccount * account)
purple_debug_info("zephyr","realm: %s\n",zephyr->realm);
}
else {
- purple_connection_error(gc,"Only ZEPH0.2 supported currently");
+ purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, "Only ZEPH0.2 supported currently");
return;
}
purple_debug_info("zephyr","does it get here\n");
@@ -1835,7 +1842,7 @@ static void zephyr_login(PurpleAccount * account)
if (zephyr_subscribe_to(zephyr,"MESSAGE","PERSONAL",zephyr->username,NULL) != ZERR_NONE) {
/* XXX don't translate this yet. It could be written better */
/* XXX error messages could be handled with more detail */
- purple_notify_error(account->gc, NULL,
+ purple_notify_error(purple_account_get_connection(account), NULL,
"Unable to subscribe to messages", "Unable to subscribe to initial messages");
return;
}
@@ -1955,7 +1962,7 @@ static void zephyr_close(PurpleConnection * gc)
{
GList *l;
GSList *s;
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
pid_t tzc_pid = zephyr->tzc_pid;
l = zephyr->pending_zloc_names;
@@ -1965,10 +1972,10 @@ static void zephyr_close(PurpleConnection * gc)
}
g_list_free(zephyr->pending_zloc_names);
- if (purple_account_get_bool(gc->account, "write_anyone", FALSE))
+ if (purple_account_get_bool(purple_connection_get_account(gc), "write_anyone", FALSE))
write_anyone(zephyr);
- if (purple_account_get_bool(gc->account, "write_zsubs", FALSE))
+ if (purple_account_get_bool(purple_connection_get_account(gc), "write_zsubs", FALSE))
write_zsubs(zephyr);
s = zephyr->subscrips;
@@ -2030,7 +2037,7 @@ static int zephyr_chat_send(PurpleConnection * gc, int id, const char *im, Purpl
PurpleConvChat *gcc;
char *inst;
char *recipient;
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
zt = find_sub_by_id(zephyr,id);
if (!zt)
@@ -2040,7 +2047,7 @@ static int zephyr_chat_send(PurpleConnection * gc, int id, const char *im, Purpl
sig = zephyr_get_signature();
gconv1 = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, zt->name,
- gc->account);
+ purple_connection_get_account(gc));
gcc = purple_conversation_get_chat_data(gconv1);
if (!(inst = (char *)purple_conv_chat_get_topic(gcc)))
@@ -2059,7 +2066,7 @@ static int zephyr_chat_send(PurpleConnection * gc, int id, const char *im, Purpl
static int zephyr_send_im(PurpleConnection * gc, const char *who, const char *im, PurpleMessageFlags flags)
{
const char *sig;
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
if (flags & PURPLE_MESSAGE_AUTO_RESP)
sig = "Automated reply:";
else {
@@ -2079,7 +2086,7 @@ static char* zephyr_tzc_escape_msg(const char *message)
int pos2 = 0;
char *newmsg;
- if (message && (strlen(message) > 0)) {
+ if (message && *message) {
newmsg = g_new0(char,1+strlen(message)*2);
while(pos < strlen(message)) {
if (message[pos]=='\\') {
@@ -2111,7 +2118,7 @@ char* zephyr_tzc_deescape_str(const char *message)
int pos2 = 0;
char *newmsg;
- if (message && (strlen(message) > 0)) {
+ if (message && *message) {
newmsg = g_new0(char,strlen(message)+1);
while(pos < strlen(message)) {
if (message[pos]=='\\') {
@@ -2228,7 +2235,7 @@ static const char *zephyr_normalize(const PurpleAccount *account, const char *wh
if (gc == NULL)
return NULL;
- tmp = local_zephyr_normalize(gc->proto_data, who);
+ tmp = local_zephyr_normalize(purple_connection_get_protocol_data(gc), who);
if (strlen(tmp) >= sizeof(buf)) {
g_free(tmp);
@@ -2244,7 +2251,7 @@ static const char *zephyr_normalize(const PurpleAccount *account, const char *wh
static void zephyr_zloc(PurpleConnection *gc, const char *who)
{
ZAsyncLocateData_t ald;
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
gchar* normalized_who = local_zephyr_normalize(zephyr,who);
if (use_zeph02(zephyr)) {
@@ -2271,7 +2278,8 @@ static void zephyr_zloc(PurpleConnection *gc, const char *who)
static void zephyr_set_status(PurpleAccount *account, PurpleStatus *status) {
size_t len;
size_t result;
- zephyr_account *zephyr = purple_account_get_connection(account)->proto_data;
+ PurpleConnection *gc = purple_account_get_connection(account);
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
PurpleStatusPrimitive primitive = purple_status_type_get_primitive(purple_status_get_type(status));
if (zephyr->away) {
@@ -2405,7 +2413,7 @@ static void zephyr_join_chat(PurpleConnection * gc, GHashTable * data)
const char *classname;
const char *instname;
const char *recip;
- zephyr_account *zephyr=gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
classname = g_hash_table_lookup(data, "class");
instname = g_hash_table_lookup(data, "instance");
recip = g_hash_table_lookup(data, "recipient");
@@ -2468,7 +2476,7 @@ static void zephyr_join_chat(PurpleConnection * gc, GHashTable * data)
static void zephyr_chat_leave(PurpleConnection * gc, int id)
{
zephyr_triple *zt;
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
zt = find_sub_by_id(zephyr,id);
if (zt) {
@@ -2518,7 +2526,7 @@ static const char *zephyr_list_icon(PurpleAccount * a, PurpleBuddy * b)
static unsigned int zephyr_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state) {
gchar *recipient;
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
if (use_tzc(zephyr))
return 0;
@@ -2560,7 +2568,7 @@ static void zephyr_chat_set_topic(PurpleConnection * gc, int id, const char *top
PurpleConversation *gconv;
PurpleConvChat *gcc;
gchar *topic_utf8;
- zephyr_account* zephyr = gc->proto_data;
+ zephyr_account* zephyr = purple_connection_get_protocol_data(gc);
char *sender = (char *)zephyr->username;
zt = find_sub_by_id(zephyr,id);
@@ -2568,7 +2576,7 @@ static void zephyr_chat_set_topic(PurpleConnection * gc, int id, const char *top
if (!zt)
return;
gconv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, zt->name,
- gc->account);
+ purple_connection_get_account(gc));
gcc = purple_conversation_get_chat_data(gconv);
topic_utf8 = zephyr_recv_convert(gc,(gchar *)topic);
@@ -2583,7 +2591,8 @@ static PurpleCmdRet zephyr_purple_cmd_msg(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
char *recipient;
- zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+ PurpleConnection *gc = purple_conversation_get_connection(conv);
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);;
if (!g_ascii_strcasecmp(args[0],"*"))
return PURPLE_CMD_RET_FAILED; /* "*" is not a valid argument */
else
@@ -2601,7 +2610,7 @@ static PurpleCmdRet zephyr_purple_cmd_msg(PurpleConversation *conv,
static PurpleCmdRet zephyr_purple_cmd_zlocate(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- zephyr_zloc(purple_conversation_get_gc(conv),args[0]);
+ zephyr_zloc(purple_conversation_get_connection(conv),args[0]);
return PURPLE_CMD_RET_OK;
}
@@ -2613,9 +2622,8 @@ static PurpleCmdRet zephyr_purple_cmd_instance(PurpleConversation *conv,
* one word isn't ideal either. */
PurpleConvChat *gcc = purple_conversation_get_chat_data(conv);
- int id = gcc->id;
const char* instance = args[0];
- zephyr_chat_set_topic(purple_conversation_get_gc(conv),id,instance);
+ zephyr_chat_set_topic(purple_conversation_get_connection(conv),purple_conv_chat_get_id(gcc),instance);
return PURPLE_CMD_RET_OK;
}
@@ -2627,7 +2635,7 @@ static PurpleCmdRet zephyr_purple_cmd_joinchat_cir(PurpleConversation *conv,
g_hash_table_insert(triple,"class",args[0]);
g_hash_table_insert(triple,"instance",args[1]);
g_hash_table_insert(triple,"recipient",args[2]);
- zephyr_join_chat(purple_conversation_get_gc(conv),triple);
+ zephyr_join_chat(purple_conversation_get_connection(conv),triple);
return PURPLE_CMD_RET_OK;
}
@@ -2635,7 +2643,8 @@ static PurpleCmdRet zephyr_purple_cmd_zi(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
/* args = instance, message */
- zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+ PurpleConnection *gc = purple_conversation_get_connection(conv);
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
if ( zephyr_send_message(zephyr,"message",args[0],"",args[1],zephyr_get_signature(),""))
return PURPLE_CMD_RET_OK;
else
@@ -2646,7 +2655,8 @@ static PurpleCmdRet zephyr_purple_cmd_zci(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
/* args = class, instance, message */
- zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+ PurpleConnection *gc = purple_conversation_get_connection(conv);
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
if ( zephyr_send_message(zephyr,args[0],args[1],"",args[2],zephyr_get_signature(),""))
return PURPLE_CMD_RET_OK;
else
@@ -2657,7 +2667,8 @@ static PurpleCmdRet zephyr_purple_cmd_zcir(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
/* args = class, instance, recipient, message */
- zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+ PurpleConnection *gc = purple_conversation_get_connection(conv);
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
if ( zephyr_send_message(zephyr,args[0],args[1],args[2],args[3],zephyr_get_signature(),""))
return PURPLE_CMD_RET_OK;
else
@@ -2668,7 +2679,8 @@ static PurpleCmdRet zephyr_purple_cmd_zir(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
/* args = instance, recipient, message */
- zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+ PurpleConnection *gc = purple_conversation_get_connection(conv);
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
if ( zephyr_send_message(zephyr,"message",args[0],args[1],args[2],zephyr_get_signature(),""))
return PURPLE_CMD_RET_OK;
else
@@ -2679,7 +2691,8 @@ static PurpleCmdRet zephyr_purple_cmd_zc(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
/* args = class, message */
- zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+ PurpleConnection *gc = purple_conversation_get_connection(conv);
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
if ( zephyr_send_message(zephyr,args[0],"PERSONAL","",args[1],zephyr_get_signature(),""))
return PURPLE_CMD_RET_OK;
else
@@ -2760,7 +2773,7 @@ static int zephyr_resubscribe(PurpleConnection *gc)
{
/* Resubscribe to the in-memory list of subscriptions and also
unsubscriptions*/
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
GSList *s = zephyr->subscrips;
zephyr_triple *zt;
while (s) {
@@ -2785,7 +2798,7 @@ static void zephyr_action_resubscribe(PurplePluginAction *action)
static void zephyr_action_get_subs_from_server(PurplePluginAction *action)
{
PurpleConnection *gc = (PurpleConnection *) action->context;
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
gchar *title;
int retval, nsubs, one,i;
ZSubscription_t subs;
@@ -2839,6 +2852,7 @@ static GList *zephyr_actions(PurplePlugin *plugin, gpointer context)
static PurplePlugin *my_protocol = NULL;
static PurplePluginProtocolInfo prpl_info = {
+ sizeof(PurplePluginProtocolInfo), /* struct_size */
OPT_PROTO_CHAT_TOPIC | OPT_PROTO_NO_PASSWORD,
NULL, /* ??? user_splits */
NULL, /* ??? protocol_options */
@@ -2879,7 +2893,6 @@ static PurplePluginProtocolInfo prpl_info = {
NULL, /* keepalive -- Not necessary*/
NULL, /* register_user -- Not supported*/
NULL, /* XXX get_cb_info */
- NULL, /* get_cb_away */
NULL, /* alias_buddy */
NULL, /* group_buddy */
NULL, /* rename_group */
@@ -2905,15 +2918,12 @@ static PurplePluginProtocolInfo prpl_info = {
NULL,
NULL,
NULL,
- sizeof(PurplePluginProtocolInfo), /* struct_size */
NULL, /* get_account_text_table */
NULL, /* initate_media */
NULL, /* get_media_caps */
NULL, /* get_moods */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */
};
static PurplePluginInfo info = {
diff --git a/libpurple/proxy.c b/libpurple/proxy.c
index 0d5de83f64..a5c3a55381 100644
--- a/libpurple/proxy.c
+++ b/libpurple/proxy.c
@@ -41,6 +41,16 @@
#include "proxy.h"
#include "util.h"
+struct _PurpleProxyInfo
+{
+ PurpleProxyType type; /**< The proxy type. */
+
+ char *host; /**< The host. */
+ int port; /**< The port number. */
+ char *username; /**< The username. */
+ char *password; /**< The password. */
+};
+
struct _PurpleProxyConnectData {
void *handle;
PurpleProxyConnectFunction connect_cb;
@@ -1422,7 +1432,7 @@ s4_canwrite(gpointer data, gint source, PurpleInputCondition cond)
proxy_do_write(connect_data, connect_data->fd, PURPLE_INPUT_WRITE);
} else {
- connect_data->query_data = purple_dnsquery_a_account(
+ connect_data->query_data = purple_dnsquery_a(
connect_data->account, connect_data->host,
connect_data->port, s4_host_resolved, connect_data);
@@ -2067,7 +2077,6 @@ s5_canwrite(gpointer data, gint source, PurpleInputCondition cond)
return;
}
- i = 0;
buf[0] = 0x05; /* SOCKS version 5 */
if (purple_proxy_info_get_username(connect_data->gpi) != NULL) {
@@ -2141,7 +2150,7 @@ proxy_connect_socks5(PurpleProxyConnectData *connect_data, struct sockaddr *addr
/**
* This function attempts to connect to the next IP address in the list
- * of IP addresses returned to us by purple_dnsquery_a() and attemps
+ * of IP addresses returned to us by purple_dnsquery_a() and attempts
* to connect to each one. This is called after the hostname is
* resolved, and each time a connection attempt fails (assuming there
* is another IP address to try).
@@ -2370,7 +2379,7 @@ purple_proxy_connect(void *handle, PurpleAccount *account,
return NULL;
}
- connect_data->query_data = purple_dnsquery_a_account(account, connecthost,
+ connect_data->query_data = purple_dnsquery_a(account, connecthost,
connectport, connection_host_resolved, connect_data);
if (connect_data->query_data == NULL)
{
@@ -2438,7 +2447,7 @@ purple_proxy_connect_udp(void *handle, PurpleAccount *account,
return NULL;
}
- connect_data->query_data = purple_dnsquery_a_account(account, connecthost,
+ connect_data->query_data = purple_dnsquery_a(account, connecthost,
connectport, connection_host_resolved, connect_data);
if (connect_data->query_data == NULL)
{
@@ -2451,17 +2460,6 @@ purple_proxy_connect_udp(void *handle, PurpleAccount *account,
return connect_data;
}
-PurpleProxyConnectData *
-purple_proxy_connect_socks5(void *handle, PurpleProxyInfo *gpi,
- const char *host, int port,
- PurpleProxyConnectFunction connect_cb,
- gpointer data)
-{
- return purple_proxy_connect_socks5_account(handle, NULL, gpi,
- host, port, connect_cb, data);
-}
-
-
/* This is called when we connect to the SOCKS5 proxy server (through any
* relevant account proxy)
*/
diff --git a/libpurple/proxy.h b/libpurple/proxy.h
index cf91ee8c71..fad49f3c50 100644
--- a/libpurple/proxy.h
+++ b/libpurple/proxy.h
@@ -47,16 +47,7 @@ typedef enum
/**
* Information on proxy settings.
*/
-typedef struct
-{
- PurpleProxyType type; /**< The proxy type. */
-
- char *host; /**< The host. */
- int port; /**< The port number. */
- char *username; /**< The username. */
- char *password; /**< The password. */
-
-} PurpleProxyInfo;
+typedef struct _PurpleProxyInfo PurpleProxyInfo;
typedef struct _PurpleProxyConnectData PurpleProxyConnectData;
@@ -65,9 +56,7 @@ typedef void (*PurpleProxyConnectFunction)(gpointer data, gint source, const gch
#include "account.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Proxy structure API */
@@ -191,7 +180,6 @@ PurpleProxyInfo *purple_global_proxy_get_info(void);
* Set purple's global proxy information.
*
* @param info The proxy information.
- * @since 2.6.0
*/
void purple_global_proxy_set_info(PurpleProxyInfo *info);
@@ -316,35 +304,6 @@ PurpleProxyConnectData *purple_proxy_connect_socks5_account(void *handle,
const char *host, int port,
PurpleProxyConnectFunction connect_cb, gpointer data);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_PROXY_C_)
-/**
- * Makes a connection through a SOCKS5 proxy.
- *
- * @param handle A handle that should be associated with this
- * connection attempt. The handle can be used
- * to cancel the connection attempt using the
- * purple_proxy_connect_cancel_with_handle()
- * function.
- * @param gpi The PurpleProxyInfo specifying the proxy settings
- * @param host The destination host.
- * @param port The destination port.
- * @param connect_cb The function to call when the connection is
- * established. If the connection failed then
- * fd will be -1 and error message will be set
- * to something descriptive (hopefully).
- * @param data User-defined data.
- *
- * @return NULL if there was an error, or a reference to an
- * opaque data structure that can be used to cancel
- * the pending connection, if needed.
- * @deprecated Use purple_proxy_connect_socks5_account instead
- */
-PurpleProxyConnectData *purple_proxy_connect_socks5(void *handle,
- PurpleProxyInfo *gpi,
- const char *host, int port,
- PurpleProxyConnectFunction connect_cb, gpointer data);
-#endif
-
/**
* Cancel an in-progress connection attempt. This should be called
* by the PRPL if the user disables an account while it is still
@@ -365,8 +324,6 @@ void purple_proxy_connect_cancel_with_handle(void *handle);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_PROXY_H_ */
diff --git a/libpurple/prpl.c b/libpurple/prpl.c
index 7849189d77..b366079d47 100644
--- a/libpurple/prpl.c
+++ b/libpurple/prpl.c
@@ -32,6 +32,17 @@
/**************************************************************************/
/** @name Attention Type API */
/**************************************************************************/
+
+struct _PurpleAttentionType
+{
+ const char *name; /**< Shown in GUI elements */
+ const char *incoming_description; /**< Shown when sent */
+ const char *outgoing_description; /**< Shown when receied */
+ const char *icon_name; /**< Icon to display (optional) */
+ const char *unlocalized_name; /**< Unlocalized name for UIs needing it */
+};
+
+
PurpleAttentionType *
purple_attention_type_new(const char *ulname, const char *name,
const char *inc_desc, const char *out_desc)
@@ -435,13 +446,13 @@ purple_prpl_send_attention(PurpleConnection *gc, const char *who, guint type_cod
g_return_if_fail(gc != NULL);
g_return_if_fail(who != NULL);
- prpl = purple_find_prpl(purple_account_get_protocol_id(gc->account));
+ prpl = purple_find_prpl(purple_account_get_protocol_id(purple_connection_get_account(gc)));
send_attention = PURPLE_PLUGIN_PROTOCOL_INFO(prpl)->send_attention;
g_return_if_fail(send_attention != NULL);
mtime = time(NULL);
- attn = purple_get_attention_type_from_code(gc->account, type_code);
+ attn = purple_get_attention_type_from_code(purple_connection_get_account(gc), type_code);
if ((buddy = purple_find_buddy(purple_connection_get_account(gc), who)) != NULL)
alias = purple_buddy_get_contact_alias(buddy);
@@ -462,7 +473,7 @@ purple_prpl_send_attention(PurpleConnection *gc, const char *who, guint type_cod
if (!send_attention(gc, who, type_code))
return;
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, gc->account, who);
+ conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, purple_connection_get_account(gc), who);
purple_conv_im_write(PURPLE_CONV_IM(conv), NULL, description, flags, mtime);
purple_prpl_attention(conv, who, type_code, PURPLE_MESSAGE_SEND, time(NULL));
@@ -481,7 +492,7 @@ got_attention(PurpleConnection *gc, int id, const char *who, guint type_code)
mtime = time(NULL);
- attn = purple_get_attention_type_from_code(gc->account, type_code);
+ attn = purple_get_attention_type_from_code(purple_connection_get_account(gc), type_code);
/* PURPLE_MESSAGE_NOTIFY is for attention messages. */
flags = PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NOTIFY | PURPLE_MESSAGE_RECV;
diff --git a/libpurple/prpl.h b/libpurple/prpl.h
index 51e8575d3e..0d39d87a33 100644
--- a/libpurple/prpl.h
+++ b/libpurple/prpl.h
@@ -31,7 +31,10 @@
#define _PURPLE_PRPL_H_
typedef struct _PurplePluginProtocolInfo PurplePluginProtocolInfo;
-/** @copydoc _PurpleAttentionType */
+
+/** Represents "nudges" and "buzzes" that you may send to a buddy to attract
+ * their attention (or vice-versa).
+ */
typedef struct _PurpleAttentionType PurpleAttentionType;
/**************************************************************************/
@@ -111,23 +114,6 @@ struct proto_chat_entry {
gboolean secret; /**< True if the entry is secret (password) */
};
-/** Represents "nudges" and "buzzes" that you may send to a buddy to attract
- * their attention (or vice-versa).
- */
-struct _PurpleAttentionType
-{
- const char *name; /**< Shown in GUI elements */
- const char *incoming_description; /**< Shown when sent */
- const char *outgoing_description; /**< Shown when receied */
- const char *icon_name; /**< Icon to display (optional) */
- const char *unlocalized_name; /**< Unlocalized name for UIs needing it */
-
- /* Reserved fields for future purposes */
- gpointer _reserved2;
- gpointer _reserved3;
- gpointer _reserved4;
-};
-
/**
* Protocol options
*
@@ -200,14 +186,12 @@ typedef enum
/**
* Indicates that slash commands are native to this protocol.
* Used as a hint that unknown commands should not be sent as messages.
- * @since 2.1.0
*/
OPT_PROTO_SLASH_COMMANDS_NATIVE = 0x00000400,
/**
* Indicates that this protocol supports sending a user-supplied message
* along with an invitation.
- * @since 2.8.0
*/
OPT_PROTO_INVITE_MESSAGE = 0x00000800
@@ -222,6 +206,27 @@ typedef enum
*/
struct _PurplePluginProtocolInfo
{
+ /**
+ * The size of the PurplePluginProtocolInfo. This should always be sizeof(PurplePluginProtocolInfo).
+ * This allows adding more functions to this struct without requiring a major version bump.
+ */
+ unsigned long struct_size;
+
+ /* NOTE:
+ * If more functions are added, they should accessed using the following syntax:
+ *
+ * if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl, new_function))
+ * prpl->new_function(...);
+ *
+ * instead of
+ *
+ * if (prpl->new_function != NULL)
+ * prpl->new_function(...);
+ *
+ * The PURPLE_PROTOCOL_PLUGIN_HAS_FUNC macro can be used for the older member
+ * functions (e.g. login, send_im etc.) too.
+ */
+
PurpleProtocolOptions options; /**< Protocol options. */
GList *user_splits; /**< A GList of PurpleAccountUserSplit */
@@ -333,6 +338,7 @@ struct _PurplePluginProtocolInfo
void (*set_idle)(PurpleConnection *, int idletime);
void (*change_passwd)(PurpleConnection *, const char *old_pass,
const char *new_pass);
+
/**
* Add a buddy to a group on the server.
*
@@ -341,11 +347,10 @@ struct _PurplePluginProtocolInfo
* authorization and the user is not already authorized to see the
* status of \a buddy, \a add_buddy should request authorization.
*
- * @deprecated Since 2.8.0, add_buddy_with_invite is preferred.
- * @see add_buddy_with_invite
+ * If authorization is required, then use the supplied invite message.
*/
- void (*add_buddy)(PurpleConnection *, PurpleBuddy *buddy, PurpleGroup *group);
- void (*add_buddies)(PurpleConnection *, GList *buddies, GList *groups);
+ void (*add_buddy)(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group, const char *message);
+ void (*add_buddies)(PurpleConnection *pc, GList *buddies, GList *groups, const char *message);
void (*remove_buddy)(PurpleConnection *, PurpleBuddy *buddy, PurpleGroup *group);
void (*remove_buddies)(PurpleConnection *, GList *buddies, GList *groups);
void (*add_permit)(PurpleConnection *, const char *name);
@@ -444,11 +449,6 @@ struct _PurplePluginProtocolInfo
* @deprecated Use #PurplePluginProtocolInfo.get_info instead.
*/
void (*get_cb_info)(PurpleConnection *, int, const char *who);
- /**
- * @deprecated Use #PurplePluginProtocolInfo.get_cb_real_name and
- * #PurplePluginProtocolInfo.status_text instead.
- */
- void (*get_cb_away)(PurpleConnection *, int, const char *who);
/** save/store buddy's alias on server list/roster */
void (*alias_buddy)(PurpleConnection *, const char *who,
@@ -467,11 +467,20 @@ struct _PurplePluginProtocolInfo
void (*convo_closed)(PurpleConnection *, const char *who);
/**
- * Convert the username @a who to its canonical form. (For example,
- * AIM treats "fOo BaR" and "foobar" as the same user; this function
- * should return the same normalized string for both of those.)
+ * Convert the username @a who to its canonical form. Also checks for
+ * validity.
+ *
+ * For example, AIM treats "fOo BaR" and "foobar" as the same user; this
+ * function should return the same normalized string for both of those.
+ * On the other hand, both of these are invalid for protocols with
+ * number-based usernames, so function should return NULL in such case.
+ *
+ * @param account The account, that username is related with. Can
+ * be NULL.
+ * @param who The username to convert.
+ * @return Normalized username, or NULL, if it's invalid.
*/
- const char *(*normalize)(const PurpleAccount *, const char *who);
+ const char *(*normalize)(const PurpleAccount *account, const char *who);
/**
* Set the buddy icon for the given connection to @a img. The prpl
@@ -534,27 +543,6 @@ struct _PurplePluginProtocolInfo
gboolean (*send_attention)(PurpleConnection *gc, const char *username, guint type);
GList *(*get_attention_types)(PurpleAccount *acct);
- /**
- * The size of the PurplePluginProtocolInfo. This should always be sizeof(PurplePluginProtocolInfo).
- * This allows adding more functions to this struct without requiring a major version bump.
- */
- unsigned long struct_size;
-
- /* NOTE:
- * If more functions are added, they should accessed using the following syntax:
- *
- * if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl, new_function))
- * prpl->new_function(...);
- *
- * instead of
- *
- * if (prpl->new_function != NULL)
- * prpl->new_function(...);
- *
- * The PURPLE_PROTOCOL_PLUGIN_HAS_FUNC macro can be used for the older member
- * functions (e.g. login, send_im etc.) too.
- */
-
/** This allows protocols to specify additional strings to be used for
* various purposes. The idea is to stuff a bunch of strings in this hash
* table instead of expanding the struct for every addition. This hash
@@ -590,7 +578,6 @@ struct _PurplePluginProtocolInfo
/**
* Returns an array of "PurpleMood"s, with the last one having
* "mood" set to @c NULL.
- * @since 2.7.0
*/
PurpleMood *(*get_moods)(PurpleAccount *account);
@@ -610,7 +597,6 @@ struct _PurplePluginProtocolInfo
* @param failure_cb Callback to be called if setting the public alias
* fails
* @see purple_account_set_public_alias
- * @since 2.7.0
*/
void (*set_public_alias)(PurpleConnection *gc, const char *alias,
PurpleSetPublicAliasSuccessCallback success_cb,
@@ -627,31 +613,14 @@ struct _PurplePluginProtocolInfo
* @param failure_cb Callback to be called if the prpl is unable to
* retrieve the alias
* @see purple_account_get_public_alias
- * @since 2.7.0
*/
void (*get_public_alias)(PurpleConnection *gc,
PurpleGetPublicAliasSuccessCallback success_cb,
PurpleGetPublicAliasFailureCallback failure_cb);
-
- /**
- * Add a buddy to a group on the server.
- *
- * This PRPL function may be called in situations in which the buddy is
- * already in the specified group. If the protocol supports
- * authorization and the user is not already authorized to see the
- * status of \a buddy, \a add_buddy should request authorization.
- *
- * If authorization is required, then use the supplied invite message.
- *
- * @since 2.8.0
- */
- void (*add_buddy_with_invite)(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group, const char *message);
- void (*add_buddies_with_invite)(PurpleConnection *pc, GList *buddies, GList *groups, const char *message);
};
#define PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl, member) \
- (((G_STRUCT_OFFSET(PurplePluginProtocolInfo, member) < G_STRUCT_OFFSET(PurplePluginProtocolInfo, struct_size)) \
- || (G_STRUCT_OFFSET(PurplePluginProtocolInfo, member) < prpl->struct_size)) && \
+ (G_STRUCT_OFFSET(PurplePluginProtocolInfo, member) < prpl->struct_size && \
prpl->member != NULL)
@@ -661,9 +630,7 @@ struct _PurplePluginProtocolInfo
#define PURPLE_PLUGIN_PROTOCOL_INFO(plugin) \
((PurplePluginProtocolInfo *)(plugin)->info->extra_info)
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Attention Type API */
@@ -680,8 +647,8 @@ extern "C" {
* should be the same string as @a ulname, with localization.
* @param inc_desc A localized description shown when the event is received.
* @param out_desc A localized description shown when the event is sent.
+ *
* @return A pointer to the new object.
- * @since 2.4.0
*/
PurpleAttentionType *purple_attention_type_new(const char *ulname, const char *name,
const char *inc_desc, const char *out_desc);
@@ -693,7 +660,6 @@ PurpleAttentionType *purple_attention_type_new(const char *ulname, const char *n
* @param name The localized name that will be displayed by UIs. This should be
* the same string given as the unlocalized name, but with
* localization.
- * @since 2.4.0
*/
void purple_attention_type_set_name(PurpleAttentionType *type, const char *name);
@@ -703,7 +669,6 @@ void purple_attention_type_set_name(PurpleAttentionType *type, const char *name)
*
* @param type The attention type.
* @param desc The localized description for incoming events.
- * @since 2.4.0
*/
void purple_attention_type_set_incoming_desc(PurpleAttentionType *type, const char *desc);
@@ -713,7 +678,6 @@ void purple_attention_type_set_incoming_desc(PurpleAttentionType *type, const ch
*
* @param type The attention type.
* @param desc The localized description for outgoing events.
- * @since 2.4.0
*/
void purple_attention_type_set_outgoing_desc(PurpleAttentionType *type, const char *desc);
@@ -723,7 +687,6 @@ void purple_attention_type_set_outgoing_desc(PurpleAttentionType *type, const ch
* @param type The attention type.
* @param name The icon's name.
* @note Icons are optional for attention events.
- * @since 2.4.0
*/
void purple_attention_type_set_icon_name(PurpleAttentionType *type, const char *name);
@@ -734,7 +697,6 @@ void purple_attention_type_set_icon_name(PurpleAttentionType *type, const char *
* @param type The attention type.
* @param ulname The unlocalized name. This should be the same string given as
* the localized name, but without localization.
- * @since 2.4.0
*/
void purple_attention_type_set_unlocalized_name(PurpleAttentionType *type, const char *ulname);
@@ -742,8 +704,8 @@ void purple_attention_type_set_unlocalized_name(PurpleAttentionType *type, const
* Get the attention type's name as displayed by the UI.
*
* @param type The attention type.
+ *
* @return The name.
- * @since 2.4.0
*/
const char *purple_attention_type_get_name(const PurpleAttentionType *type);
@@ -752,7 +714,6 @@ const char *purple_attention_type_get_name(const PurpleAttentionType *type);
*
* @param type The attention type.
* @return The description.
- * @since 2.4.0
*/
const char *purple_attention_type_get_incoming_desc(const PurpleAttentionType *type);
@@ -761,7 +722,6 @@ const char *purple_attention_type_get_incoming_desc(const PurpleAttentionType *t
*
* @param type The attention type.
* @return The description.
- * @since 2.4.0
*/
const char *purple_attention_type_get_outgoing_desc(const PurpleAttentionType *type);
@@ -771,7 +731,6 @@ const char *purple_attention_type_get_outgoing_desc(const PurpleAttentionType *t
* @param type The attention type.
* @return The icon name or @c NULL if unset/empty.
* @note Icons are optional for attention events.
- * @since 2.4.0
*/
const char *purple_attention_type_get_icon_name(const PurpleAttentionType *type);
@@ -780,7 +739,6 @@ const char *purple_attention_type_get_icon_name(const PurpleAttentionType *type)
*
* @param type The attention type
* @return The unlocalized name.
- * @since 2.4.0
*/
const char *purple_attention_type_get_unlocalized_name(const PurpleAttentionType *type);
@@ -836,7 +794,6 @@ void purple_prpl_got_account_status(PurpleAccount *account,
* @param account The account.
*
* @see account-actions-changed
- * @since 2.6.0
*/
void purple_prpl_got_account_actions(PurpleAccount *account);
@@ -927,8 +884,6 @@ GList *purple_prpl_get_statuses(PurpleAccount *account, PurplePresence *presence
*
* Note that you can't send arbitrary PurpleAttentionType's, because there is
* only a fixed set of attention commands.
- *
- * @since 2.5.0
*/
void purple_prpl_send_attention(PurpleConnection *gc, const char *who, guint type_code);
@@ -939,8 +894,6 @@ void purple_prpl_send_attention(PurpleConnection *gc, const char *who, guint typ
* @param who Who requested your attention.
* @param type_code An index into the prpl's attention_types list determining the type
* of the attention request command to send.
- *
- * @since 2.5.0
*/
void purple_prpl_got_attention(PurpleConnection *gc, const char *who, guint type_code);
@@ -952,8 +905,6 @@ void purple_prpl_got_attention(PurpleConnection *gc, const char *who, guint type
* @param who Who requested your attention.
* @param type_code An index into the prpl's attention_types list determining the type
* of the attention request command to send.
- *
- * @since 2.5.0
*/
void purple_prpl_got_attention_in_chat(PurpleConnection *gc, int id, const char *who, guint type_code);
@@ -988,7 +939,6 @@ gboolean purple_prpl_initiate_media(PurpleAccount *account,
*
* @param account The account the user is on.
* @param who The name of the contact for which capabilities have been received.
- * @since 2.7.0
*/
void purple_prpl_got_media_caps(PurpleAccount *account, const char *who);
@@ -1008,8 +958,6 @@ PurplePlugin *purple_find_prpl(const char *id);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PRPL_H_ */
diff --git a/libpurple/purple-2-uninstalled.pc.in b/libpurple/purple-3-uninstalled.pc.in
index 90e0275cee..90e0275cee 100644
--- a/libpurple/purple-2-uninstalled.pc.in
+++ b/libpurple/purple-3-uninstalled.pc.in
diff --git a/libpurple/purple-2.pc.in b/libpurple/purple-3.pc.in
index 9506b6f5be..281a522a96 100644
--- a/libpurple/purple-2.pc.in
+++ b/libpurple/purple-3.pc.in
@@ -1,7 +1,7 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
-includedir=@includedir@
+includedir=@includedir@/libpurple
datarootdir=@datarootdir@
datadir=@datadir@
sysconfdir=@sysconfdir@
diff --git a/libpurple/purple-uninstalled.pc.in b/libpurple/purple-uninstalled.pc.in
deleted file mode 100644
index 11d4da8a0c..0000000000
--- a/libpurple/purple-uninstalled.pc.in
+++ /dev/null
@@ -1,19 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-
-abs_srcdir=@abs_srcdir@
-abs_builddir=@abs_builddir@
-
-plugindir=${libdir}/purple-@PURPLE_MAJOR_VERSION@
-
-Name: libpurple
-Description: libpurple is a GLib-based instant messenger library.
-Version: @VERSION@
-Requires: glib-2.0
-Cflags: -I${abs_srcdir} -I${abs_builddir}
-Libs: ${abs_builddir}/libpurple.la
diff --git a/libpurple/purple.h.in b/libpurple/purple.h.in
index a96b2537ec..327bea0f9c 100644
--- a/libpurple/purple.h.in
+++ b/libpurple/purple.h.in
@@ -6,7 +6,6 @@
* include any other libpurple files.
*
* @ingroup core libpurple
- * @since 2.3.0
*/
/* purple
diff --git a/libpurple/purple.pc.in b/libpurple/purple.pc.in
deleted file mode 100644
index c776f6f26f..0000000000
--- a/libpurple/purple.pc.in
+++ /dev/null
@@ -1,16 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-
-plugindir=${libdir}/purple-@PURPLE_MAJOR_VERSION@
-
-Name: libpurple
-Description: libpurple is a GLib-based instant messenger library.
-Version: @VERSION@
-Requires: glib-2.0
-Cflags: -I${includedir}/libpurple
-Libs: -L${libdir} -lpurple
diff --git a/libpurple/request.c b/libpurple/request.c
index d61d24182e..c872e06020 100644
--- a/libpurple/request.c
+++ b/libpurple/request.c
@@ -42,6 +42,113 @@ typedef struct
} PurpleRequestInfo;
+struct _PurpleRequestField
+{
+ PurpleRequestFieldType type;
+ PurpleRequestFieldGroup *group;
+
+ char *id;
+ char *label;
+ char *type_hint;
+
+ gboolean visible;
+ gboolean required;
+
+ union
+ {
+ struct
+ {
+ gboolean multiline;
+ gboolean masked;
+ gboolean editable;
+ char *default_value;
+ char *value;
+
+ } string;
+
+ struct
+ {
+ int default_value;
+ int value;
+
+ } integer;
+
+ struct
+ {
+ gboolean default_value;
+ gboolean value;
+
+ } boolean;
+
+ struct
+ {
+ int default_value;
+ int value;
+
+ GList *labels;
+
+ } choice;
+
+ struct
+ {
+ GList *items;
+ GList *icons;
+ GHashTable *item_data;
+ GList *selected;
+ GHashTable *selected_table;
+
+ gboolean multiple_selection;
+
+ } list;
+
+ struct
+ {
+ PurpleAccount *default_account;
+ PurpleAccount *account;
+ gboolean show_all;
+
+ PurpleFilterAccountFunc filter_func;
+
+ } account;
+
+ struct
+ {
+ unsigned int scale_x;
+ unsigned int scale_y;
+ const char *buffer;
+ gsize size;
+ } image;
+
+ struct
+ {
+ PurpleCertificate *cert;
+ } certificate;
+
+ } u;
+
+ void *ui_data;
+ char *tooltip;
+};
+
+struct _PurpleRequestFields
+{
+ GList *groups;
+
+ GHashTable *fields;
+
+ GList *required_fields;
+
+ void *ui_data;
+};
+
+struct _PurpleRequestFieldGroup
+{
+ PurpleRequestFields *fields_list;
+
+ char *title;
+
+ GList *fields;
+};
PurpleRequestFields *
purple_request_fields_new(void)
@@ -271,6 +378,20 @@ purple_request_fields_get_account(const PurpleRequestFields *fields,
return purple_request_field_account_get_value(field);
}
+gpointer purple_request_fields_get_ui_data(const PurpleRequestFields *fields)
+{
+ g_return_val_if_fail(fields != NULL, NULL);
+
+ return fields->ui_data;
+}
+
+void purple_request_fields_set_ui_data(PurpleRequestFields *fields, gpointer ui_data)
+{
+ g_return_if_fail(fields != NULL);
+
+ fields->ui_data = ui_data;
+}
+
PurpleRequestFieldGroup *
purple_request_field_group_new(const char *title)
{
@@ -337,6 +458,14 @@ purple_request_field_group_get_fields(const PurpleRequestFieldGroup *group)
return group->fields;
}
+PurpleRequestFields *
+purple_request_field_group_get_fields_list(const PurpleRequestFieldGroup *group)
+{
+ g_return_val_if_fail(group != NULL, NULL);
+
+ return group->fields_list;
+}
+
PurpleRequestField *
purple_request_field_new(const char *id, const char *text,
PurpleRequestFieldType type)
@@ -365,6 +494,7 @@ purple_request_field_destroy(PurpleRequestField *field)
g_free(field->id);
g_free(field->label);
g_free(field->type_hint);
+ g_free(field->tooltip);
if (field->type == PURPLE_REQUEST_FIELD_STRING)
{
@@ -428,6 +558,15 @@ purple_request_field_set_type_hint(PurpleRequestField *field,
}
void
+purple_request_field_set_tooltip(PurpleRequestField *field, const char *tooltip)
+{
+ g_return_if_fail(field != NULL);
+
+ g_free(field->tooltip);
+ field->tooltip = g_strdup(tooltip);
+}
+
+void
purple_request_field_set_required(PurpleRequestField *field, gboolean required)
{
g_return_if_fail(field != NULL);
@@ -502,6 +641,14 @@ purple_request_field_get_type_hint(const PurpleRequestField *field)
return field->type_hint;
}
+const char *
+purple_request_field_get_tooltip(const PurpleRequestField *field)
+{
+ g_return_val_if_fail(field != NULL, NULL);
+
+ return field->tooltip;
+}
+
gboolean
purple_request_field_is_required(const PurpleRequestField *field)
{
@@ -847,13 +994,6 @@ purple_request_field_list_get_data(const PurpleRequestField *field,
}
void
-purple_request_field_list_add(PurpleRequestField *field, const char *item,
- void *data)
-{
- purple_request_field_list_add_icon(field, item, NULL, data);
-}
-
-void
purple_request_field_list_add_icon(PurpleRequestField *field, const char *item, const char* icon_path,
void *data)
{
@@ -1194,6 +1334,31 @@ purple_request_field_account_get_filter(const PurpleRequestField *field)
return field->u.account.filter_func;
}
+PurpleRequestField *
+purple_request_field_certificate_new(const char *id, const char *text, PurpleCertificate *cert)
+{
+ PurpleRequestField *field;
+
+ g_return_val_if_fail(id != NULL, NULL);
+ g_return_val_if_fail(text != NULL, NULL);
+ g_return_val_if_fail(cert != NULL, NULL);
+
+ field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_CERTIFICATE);
+
+ field->u.certificate.cert = cert;
+
+ return field;
+}
+
+PurpleCertificate *
+purple_request_field_certificate_get_value(const PurpleRequestField *field)
+{
+ g_return_val_if_fail(field != NULL, NULL);
+ g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_CERTIFICATE, NULL);
+
+ return field->u.certificate.cert;
+}
+
/* -- */
void *
@@ -1501,6 +1666,29 @@ purple_request_folder(void *handle, const char *title, const char *dirname,
return NULL;
}
+void *
+purple_request_certificate(void *handle, const char *title,
+ const char *primary, const char *secondary,
+ PurpleCertificate *cert,
+ const char *ok_text, GCallback ok_cb,
+ const char *cancel_text, GCallback cancel_cb,
+ void *user_data)
+{
+ PurpleRequestFields *fields;
+ PurpleRequestFieldGroup *group;
+ PurpleRequestField *field;
+
+ fields = purple_request_fields_new();
+ group = purple_request_field_group_new(NULL);
+ purple_request_fields_add_group(fields, group);
+ field = purple_request_field_certificate_new("certificate", "Certificate", cert);
+ purple_request_field_group_add_field(group, field);
+
+ return purple_request_fields(handle, title, primary, secondary, fields,
+ ok_text, ok_cb, cancel_text, cancel_cb,
+ NULL, NULL, NULL, user_data);
+}
+
static void
purple_request_close_info(PurpleRequestInfo *info)
{
diff --git a/libpurple/request.h b/libpurple/request.h
index 8035ef806b..0920df7bd0 100644
--- a/libpurple/request.h
+++ b/libpurple/request.h
@@ -30,9 +30,21 @@
#include <glib-object.h>
#include <glib.h>
-/** @copydoc _PurpleRequestField */
+/**
+ * A request field.
+ */
typedef struct _PurpleRequestField PurpleRequestField;
+/**
+ * Multiple fields request data.
+ */
+typedef struct _PurpleRequestFields PurpleRequestFields;
+
+/**
+ * A group of fields with a title.
+ */
+typedef struct _PurpleRequestFieldGroup PurpleRequestFieldGroup;
+
#include "account.h"
#define PURPLE_DEFAULT_ACTION_NONE -1
@@ -64,127 +76,12 @@ typedef enum
PURPLE_REQUEST_FIELD_LIST,
PURPLE_REQUEST_FIELD_LABEL,
PURPLE_REQUEST_FIELD_IMAGE,
- PURPLE_REQUEST_FIELD_ACCOUNT
+ PURPLE_REQUEST_FIELD_ACCOUNT,
+ PURPLE_REQUEST_FIELD_CERTIFICATE
} PurpleRequestFieldType;
/**
- * Multiple fields request data.
- */
-typedef struct
-{
- GList *groups;
-
- GHashTable *fields;
-
- GList *required_fields;
-
- void *ui_data;
-
-} PurpleRequestFields;
-
-/**
- * A group of fields with a title.
- */
-typedef struct
-{
- PurpleRequestFields *fields_list;
-
- char *title;
-
- GList *fields;
-
-} PurpleRequestFieldGroup;
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_REQUEST_C_)
-/**
- * A request field.
- */
-struct _PurpleRequestField
-{
- PurpleRequestFieldType type;
- PurpleRequestFieldGroup *group;
-
- char *id;
- char *label;
- char *type_hint;
-
- gboolean visible;
- gboolean required;
-
- union
- {
- struct
- {
- gboolean multiline;
- gboolean masked;
- gboolean editable;
- char *default_value;
- char *value;
-
- } string;
-
- struct
- {
- int default_value;
- int value;
-
- } integer;
-
- struct
- {
- gboolean default_value;
- gboolean value;
-
- } boolean;
-
- struct
- {
- int default_value;
- int value;
-
- GList *labels;
-
- } choice;
-
- struct
- {
- GList *items;
- GList *icons;
- GHashTable *item_data;
- GList *selected;
- GHashTable *selected_table;
-
- gboolean multiple_selection;
-
- } list;
-
- struct
- {
- PurpleAccount *default_account;
- PurpleAccount *account;
- gboolean show_all;
-
- PurpleFilterAccountFunc filter_func;
-
- } account;
-
- struct
- {
- unsigned int scale_x;
- unsigned int scale_y;
- const char *buffer;
- gsize size;
- } image;
-
- } u;
-
- void *ui_data;
-
-};
-#endif
-
-/**
* Request UI operations.
*/
typedef struct
@@ -262,9 +159,7 @@ typedef void (*PurpleRequestChoiceCb)(void *, int);
typedef void (*PurpleRequestFieldsCb)(void *, PurpleRequestFields *fields);
typedef void (*PurpleRequestFileCb)(void *, const char *filename);
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Field List API */
@@ -410,6 +305,25 @@ int purple_request_fields_get_choice(const PurpleRequestFields *fields,
PurpleAccount *purple_request_fields_get_account(const PurpleRequestFields *fields,
const char *id);
+/**
+ * Returns the UI data associated with this object.
+ *
+ * @param fields The fields list.
+ *
+ * @return The UI data associated with this object. This is a
+ * convenience field provided to the UIs--it is not
+ * used by the libuprple core.
+ */
+gpointer purple_request_fields_get_ui_data(const PurpleRequestFields *fields);
+
+/**
+ * Set the UI data associated with this object.
+ *
+ * @param fields The fields list.
+ * @param ui_data A pointer to associate with this object.
+ */
+void purple_request_fields_set_ui_data(PurpleRequestFields *fields, gpointer ui_data);
+
/*@}*/
/**************************************************************************/
@@ -462,6 +376,16 @@ const char *purple_request_field_group_get_title(
GList *purple_request_field_group_get_fields(
const PurpleRequestFieldGroup *group);
+/**
+ * Returns a list of all fields in a group.
+ *
+ * @param group The group.
+ *
+ * @constreturn The list of fields in the group.
+ */
+PurpleRequestFields *purple_request_field_group_get_fields_list(
+ const PurpleRequestFieldGroup *group);
+
/*@}*/
/**************************************************************************/
@@ -517,6 +441,18 @@ void purple_request_field_set_type_hint(PurpleRequestField *field,
const char *type_hint);
/**
+ * Sets the tooltip for the field.
+ *
+ * This is optionally used by the UIs to provide a tooltip for
+ * the field.
+ *
+ * @param field The field.
+ * @param tooltip The tooltip text.
+ */
+void purple_request_field_set_tooltip(PurpleRequestField *field,
+ const char *tooltip);
+
+/**
* Sets whether or not a field is required.
*
* @param field The field.
@@ -540,8 +476,6 @@ PurpleRequestFieldType purple_request_field_get_type(const PurpleRequestField *f
* @param field The field.
*
* @return The UI data.
- *
- * @since 2.6.0
*/
PurpleRequestFieldGroup *purple_request_field_get_group(const PurpleRequestField *field);
@@ -582,6 +516,15 @@ gboolean purple_request_field_is_visible(const PurpleRequestField *field);
const char *purple_request_field_get_type_hint(const PurpleRequestField *field);
/**
+ * Returns the field's tooltip.
+ *
+ * @param field The field.
+ *
+ * @return The field's tooltip.
+ */
+const char *purple_request_field_get_tooltip(const PurpleRequestField *field);
+
+/**
* Returns whether or not a field is required.
*
* @param field The field.
@@ -596,8 +539,6 @@ gboolean purple_request_field_is_required(const PurpleRequestField *field);
* @param field The field.
*
* @return The UI data.
- *
- * @since 2.6.0
*/
gpointer purple_request_field_get_ui_data(const PurpleRequestField *field);
@@ -608,8 +549,6 @@ gpointer purple_request_field_get_ui_data(const PurpleRequestField *field);
* @param ui_data The UI data.
*
* @return The UI data.
- *
- * @since 2.6.0
*/
void purple_request_field_set_ui_data(PurpleRequestField *field,
gpointer ui_data);
@@ -961,18 +900,6 @@ void *purple_request_field_list_get_data(const PurpleRequestField *field,
*
* @param field The list field.
* @param item The list item.
- * @param data The associated data.
- *
- * @deprecated Use purple_request_field_list_add_icon() instead.
- */
-void purple_request_field_list_add(PurpleRequestField *field,
- const char *item, void *data);
-
-/**
- * Adds an item to a list field.
- *
- * @param field The list field.
- * @param item The list item.
* @param icon_path The path to icon file, or @c NULL for no icon.
* @param data The associated data.
*/
@@ -1244,6 +1171,36 @@ PurpleFilterAccountFunc purple_request_field_account_get_filter(
/*@}*/
/**************************************************************************/
+/** @name Certificate Field API */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Creates a certificate field.
+ *
+ * @param id The field ID.
+ * @param text The label of the field.
+ * @param cert The certificate of the field.
+ *
+ * @return The new field.
+ */
+PurpleRequestField *purple_request_field_certificate_new(const char *id,
+ const char *text,
+ PurpleCertificate *cert);
+
+/**
+ * Returns the certificate in a certificate field.
+ *
+ * @param field The field.
+ *
+ * @return The certificate.
+ */
+PurpleCertificate *purple_request_field_certificate_get_value(
+ const PurpleRequestField *field);
+
+/*@}*/
+
+/**************************************************************************/
/** @name Request API */
/**************************************************************************/
/*@{*/
@@ -1402,8 +1359,7 @@ void *purple_request_action_varg(void *handle, const char *title,
/**
* Version of purple_request_action() supplying an image for the UI to
- * optionally display as an icon in the dialog; see its documentation
- * @since 2.7.0
+ * optionally display as an icon in the dialog; see its documentation.
*/
void *purple_request_action_with_icon(void *handle, const char *title,
const char *primary, const char *secondary, int default_action,
@@ -1414,7 +1370,6 @@ void *purple_request_action_with_icon(void *handle, const char *title,
/**
* <tt>va_list</tt> version of purple_request_action_with_icon();
* see its documentation.
- * @since 2.7.0
*/
void *purple_request_action_with_icon_varg(void *handle, const char *title,
const char *primary, const char *secondary, int default_action,
@@ -1576,6 +1531,37 @@ void *purple_request_folder(void *handle, const char *title, const char *dirname
PurpleAccount *account, const char *who, PurpleConversation *conv,
void *user_data);
+/**
+ * Prompts the user for action over a certificate.
+ *
+ * This is often represented as a dialog with a button for each action.
+ *
+ * @param handle The plugin or connection handle. For some things this
+ * is <em>extremely</em> important. See the comments on
+ * purple_request_input().
+ * @param title The title of the message, or @c NULL if it should have
+ * no title.
+ * @param primary The main point of the message, or @c NULL if you're
+ * feeling enigmatic.
+ * @param secondary Secondary information, or @c NULL if there is none.
+ * @param cert The #PurpleCertificate associated with this request.
+ * @param ok_text The text for the @c OK button, which may not be @c NULL.
+ * @param ok_cb The callback for the @c OK button, which may not be
+ * @c NULL.
+ * @param cancel_text The text for the @c Cancel button, which may not be
+ * @c NULL.
+ * @param cancel_cb The callback for the @c Cancel button, which may be
+ * @c NULL.
+ * @param user_data The data to pass to the callback.
+ *
+ * @return A UI-specific handle.
+ */
+void *purple_request_certificate(void *handle, const char *title,
+ const char *primary, const char *secondary, PurpleCertificate *cert,
+ const char *ok_text, GCallback ok_cb,
+ const char *cancel_text, GCallback cancel_cb,
+ void *user_data);
+
/*@}*/
/**************************************************************************/
@@ -1601,8 +1587,6 @@ PurpleRequestUiOps *purple_request_get_ui_ops(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_REQUEST_H_ */
diff --git a/libpurple/roomlist.c b/libpurple/roomlist.c
index 8a415ebe00..ad32d6d30b 100644
--- a/libpurple/roomlist.c
+++ b/libpurple/roomlist.c
@@ -32,6 +32,39 @@
#include "roomlist.h"
#include "server.h"
+/**
+ * Represents a list of rooms for a given connection on a given protocol.
+ */
+struct _PurpleRoomlist {
+ PurpleAccount *account; /**< The account this list belongs to. */
+ GList *fields; /**< The fields. */
+ GList *rooms; /**< The list of rooms. */
+ gboolean in_progress; /**< The listing is in progress. */
+ gpointer ui_data; /**< UI private data. */
+ gpointer proto_data; /** Prpl private data. */
+ guint ref; /**< The reference count. */
+};
+
+/**
+ * Represents a room.
+ */
+struct _PurpleRoomlistRoom {
+ PurpleRoomlistRoomType type; /**< The type of room. */
+ gchar *name; /**< The name of the room. */
+ GList *fields; /**< Other fields. */
+ PurpleRoomlistRoom *parent; /**< The parent room, or NULL. */
+ gboolean expanded_once; /**< A flag the UI uses to avoid multiple expand prpl cbs. */
+};
+
+/**
+ * A field a room might have.
+ */
+struct _PurpleRoomlistField {
+ PurpleRoomlistFieldType type; /**< The type of field. */
+ gchar *label; /**< The i18n user displayed name of the field. */
+ gchar *name; /**< The internal name of the field. */
+ gboolean hidden; /**< Hidden? */
+};
static PurpleRoomlistUiOps *ops = NULL;
@@ -127,6 +160,13 @@ void purple_roomlist_unref(PurpleRoomlist *list)
purple_roomlist_destroy(list);
}
+PurpleAccount *purple_roomlist_get_account(PurpleRoomlist *list)
+{
+ g_return_val_if_fail(list != NULL, NULL);
+
+ return list->account;
+}
+
void purple_roomlist_set_fields(PurpleRoomlist *list, GList *fields)
{
g_return_if_fail(list != NULL);
@@ -234,6 +274,34 @@ GList * purple_roomlist_get_fields(PurpleRoomlist *list)
return list->fields;
}
+gpointer purple_roomlist_get_proto_data(PurpleRoomlist *list)
+{
+ g_return_val_if_fail(list != NULL, NULL);
+
+ return list->proto_data;
+}
+
+void purple_roomlist_set_proto_data(PurpleRoomlist *list, gpointer proto_data)
+{
+ g_return_if_fail(list != NULL);
+
+ list->proto_data = proto_data;
+}
+
+gpointer purple_roomlist_get_ui_data(PurpleRoomlist *list)
+{
+ g_return_val_if_fail(list != NULL, NULL);
+
+ return list->ui_data;
+}
+
+void purple_roomlist_set_ui_data(PurpleRoomlist *list, gpointer ui_data)
+{
+ g_return_if_fail(list != NULL);
+
+ list->ui_data = ui_data;
+}
+
/*@}*/
/**************************************************************************/
@@ -329,7 +397,21 @@ PurpleRoomlistRoom * purple_roomlist_room_get_parent(PurpleRoomlistRoom *room)
return room->parent;
}
-GList * purple_roomlist_room_get_fields(PurpleRoomlistRoom *room)
+gboolean purple_roomlist_room_get_expanded_once(PurpleRoomlistRoom *room)
+{
+ g_return_val_if_fail(room != NULL, FALSE);
+
+ return room->expanded_once;
+}
+
+void purple_roomlist_room_set_expanded_once(PurpleRoomlistRoom *room, gboolean expanded_once)
+{
+ g_return_if_fail(room != NULL);
+
+ room->expanded_once = expanded_once;
+}
+
+GList *purple_roomlist_room_get_fields(PurpleRoomlistRoom *room)
{
return room->fields;
}
diff --git a/libpurple/roomlist.h b/libpurple/roomlist.h
index de9270f002..83161b8360 100644
--- a/libpurple/roomlist.h
+++ b/libpurple/roomlist.h
@@ -64,40 +64,6 @@ typedef enum
/**************************************************************************/
/**
- * Represents a list of rooms for a given connection on a given protocol.
- */
-struct _PurpleRoomlist {
- PurpleAccount *account; /**< The account this list belongs to. */
- GList *fields; /**< The fields. */
- GList *rooms; /**< The list of rooms. */
- gboolean in_progress; /**< The listing is in progress. */
- gpointer ui_data; /**< UI private data. */
- gpointer proto_data; /** Prpl private data. */
- guint ref; /**< The reference count. */
-};
-
-/**
- * Represents a room.
- */
-struct _PurpleRoomlistRoom {
- PurpleRoomlistRoomType type; /**< The type of room. */
- gchar *name; /**< The name of the room. */
- GList *fields; /**< Other fields. */
- PurpleRoomlistRoom *parent; /**< The parent room, or NULL. */
- gboolean expanded_once; /**< A flag the UI uses to avoid multiple expand prpl cbs. */
-};
-
-/**
- * A field a room might have.
- */
-struct _PurpleRoomlistField {
- PurpleRoomlistFieldType type; /**< The type of field. */
- gchar *label; /**< The i18n user displayed name of the field. */
- gchar *name; /**< The internal name of the field. */
- gboolean hidden; /**< Hidden? */
-};
-
-/**
* The room list ops to be filled out by the UI.
*/
struct _PurpleRoomlistUiOps {
@@ -115,9 +81,7 @@ struct _PurpleRoomlistUiOps {
};
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Room List API */
@@ -163,6 +127,14 @@ void purple_roomlist_ref(PurpleRoomlist *list);
void purple_roomlist_unref(PurpleRoomlist *list);
/**
+ * Retrieve the PurpleAccount that was given when the room list was
+ * created.
+ *
+ * @return The PurpleAccount tied to this room list.
+ */
+PurpleAccount *purple_roomlist_get_account(PurpleRoomlist *list);
+
+/**
* Set the different field types and their names for this protocol.
*
* This must be called before purple_roomlist_room_add().
@@ -241,11 +213,48 @@ void purple_roomlist_expand_category(PurpleRoomlist *list, PurpleRoomlistRoom *c
/**
* Get the list of fields for a roomlist.
*
- * @param roomlist The roomlist, which must not be @c NULL.
+ * @param roomlist The roomlist, which must not be @c NULL.
* @constreturn A list of fields
- * @since 2.4.0
*/
-GList * purple_roomlist_get_fields(PurpleRoomlist *roomlist);
+GList *purple_roomlist_get_fields(PurpleRoomlist *roomlist);
+
+/**
+ * Get the protocol data associated with this room list.
+ *
+ * @param list The roomlist, which must not be @c NULL.
+ *
+ * @return The protocol data associated with this room list. This is a
+ * convenience field provided to the protocol plugin--it is not
+ * used the libpurple core.
+ */
+gpointer purple_roomlist_get_proto_data(PurpleRoomlist *list);
+
+/**
+ * Set the protocol data associated with this room list.
+ *
+ * @param list The roomlist, which must not be @c NULL.
+ * @param proto_data A pointer to associate with this room list.
+ */
+void purple_roomlist_set_proto_data(PurpleRoomlist *list, gpointer proto_data);
+
+/**
+ * Get the UI data associated with this room list.
+ *
+ * @param list The roomlist, which must not be @c NULL.
+ *
+ * @return The UI data associated with this room list. This is a
+ * convenience field provided to the UIs--it is not
+ * used by the libpurple core.
+ */
+gpointer purple_roomlist_get_ui_data(PurpleRoomlist *list);
+
+/**
+ * Set the UI data associated with this room list.
+ *
+ * @param list The roomlist, which must not be @c NULL.
+ * @param ui_data A pointer to associate with this room list.
+ */
+void purple_roomlist_set_ui_data(PurpleRoomlist *list, gpointer ui_data);
/*@}*/
@@ -287,7 +296,6 @@ void purple_roomlist_room_join(PurpleRoomlist *list, PurpleRoomlistRoom *room);
* Get the type of a room.
* @param room The room, which must not be @c NULL.
* @return The type of the room.
- * @since 2.4.0
*/
PurpleRoomlistRoomType purple_roomlist_room_get_type(PurpleRoomlistRoom *room);
@@ -295,7 +303,6 @@ PurpleRoomlistRoomType purple_roomlist_room_get_type(PurpleRoomlistRoom *room);
* Get the name of a room.
* @param room The room, which must not be @c NULL.
* @return The name of the room.
- * @since 2.4.0
*/
const char * purple_roomlist_room_get_name(PurpleRoomlistRoom *room);
@@ -303,16 +310,31 @@ const char * purple_roomlist_room_get_name(PurpleRoomlistRoom *room);
* Get the parent of a room.
* @param room The room, which must not be @c NULL.
* @return The parent of the room, which can be @c NULL.
- * @since 2.4.0
*/
PurpleRoomlistRoom * purple_roomlist_room_get_parent(PurpleRoomlistRoom *room);
/**
+ * Get the value of the expanded_once flag.
+ *
+ * @param room The room, which must not be @c NULL.
+ *
+ * @return The value of the expanded_once flag.
+ */
+gboolean purple_roomlist_room_get_expanded_once(PurpleRoomlistRoom *room);
+
+/**
+ * Set the expanded_once flag.
+ *
+ * @param room The room, which must not be @c NULL.
+ * @param expanded_once The new value of the expanded_once flag.
+ */
+void purple_roomlist_room_set_expanded_once(PurpleRoomlistRoom *room, gboolean expanded_once);
+
+/**
* Get the list of fields for a room.
*
* @param room The room, which must not be @c NULL.
* @constreturn A list of fields
- * @since 2.4.0
*/
GList * purple_roomlist_room_get_fields(PurpleRoomlistRoom *room);
@@ -344,7 +366,6 @@ PurpleRoomlistField *purple_roomlist_field_new(PurpleRoomlistFieldType type,
* @param field A PurpleRoomlistField, which must not be @c NULL.
*
* @return The type of the field.
- * @since 2.4.0
*/
PurpleRoomlistFieldType purple_roomlist_field_get_type(PurpleRoomlistField *field);
@@ -354,7 +375,6 @@ PurpleRoomlistFieldType purple_roomlist_field_get_type(PurpleRoomlistField *fiel
* @param field A PurpleRoomlistField, which must not be @c NULL.
*
* @return The label of the field.
- * @since 2.4.0
*/
const char * purple_roomlist_field_get_label(PurpleRoomlistField *field);
@@ -363,7 +383,6 @@ const char * purple_roomlist_field_get_label(PurpleRoomlistField *field);
* @param field A PurpleRoomlistField, which must not be @c NULL.
*
* @return @c TRUE if the field is hidden, @c FALSE otherwise.
- * @since 2.4.0
*/
gboolean purple_roomlist_field_get_hidden(PurpleRoomlistField *field);
@@ -391,8 +410,6 @@ PurpleRoomlistUiOps *purple_roomlist_get_ui_ops(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_ROOMLIST_H_ */
diff --git a/libpurple/savedstatuses.c b/libpurple/savedstatuses.c
index 70f4190b2a..eaee07ee68 100644
--- a/libpurple/savedstatuses.c
+++ b/libpurple/savedstatuses.c
@@ -387,7 +387,6 @@ parse_substatus(xmlnode *substatus)
const char *protocol;
acct_name = xmlnode_get_data(node);
protocol = xmlnode_get_attrib(node, "protocol");
- protocol = _purple_oscar_convert(acct_name, protocol); /* XXX: Remove */
if ((acct_name != NULL) && (protocol != NULL))
ret->account = purple_accounts_find(acct_name, protocol);
g_free(acct_name);
@@ -404,7 +403,7 @@ parse_substatus(xmlnode *substatus)
if ((node != NULL) && ((data = xmlnode_get_data(node)) != NULL))
{
ret->type = purple_status_type_find_with_id(
- ret->account->status_types, data);
+ purple_account_get_status_types(ret->account), data);
g_free(data);
}
diff --git a/libpurple/savedstatuses.h b/libpurple/savedstatuses.h
index bd5b091343..53be07cd55 100644
--- a/libpurple/savedstatuses.h
+++ b/libpurple/savedstatuses.h
@@ -60,9 +60,7 @@ typedef struct _PurpleSavedStatusSub PurpleSavedStatusSub;
#include "status.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Saved status subsystem */
@@ -418,8 +416,7 @@ void purple_savedstatuses_uninit(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_SAVEDSTATUSES_H_ */
+
diff --git a/libpurple/server.c b/libpurple/server.c
index 73739720a7..ded5f084ae 100644
--- a/libpurple/server.c
+++ b/libpurple/server.c
@@ -149,7 +149,7 @@ int serv_send_im(PurpleConnection *gc, const char *name, const char *message,
* this only reset lar->sent if we're away AND idle?
*/
auto_reply_pref = purple_prefs_get_string("/purple/away/auto_reply");
- if((gc->flags & PURPLE_CONNECTION_AUTO_RESP) &&
+ if((purple_connection_get_flags(gc) & PURPLE_CONNECTION_AUTO_RESP) &&
!purple_presence_is_available(presence) &&
!purple_strequal(auto_reply_pref, "never")) {
@@ -325,18 +325,6 @@ PurpleAttentionType *purple_get_attention_type_from_code(PurpleAccount *account,
return attn;
}
-void
-serv_send_attention(PurpleConnection *gc, const char *who, guint type_code)
-{
- purple_prpl_send_attention(gc, who, type_code);
-}
-
-void
-serv_got_attention(PurpleConnection *gc, const char *who, guint type_code)
-{
- purple_prpl_got_attention(gc, who, type_code);
-}
-
/*
* Move a buddy from one group to another on server.
@@ -582,7 +570,7 @@ void serv_got_im(PurpleConnection *gc, const char *who, const char *msg,
* We should update the conversation window buttons and menu,
* if it exists.
*/
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, gc->account);
+ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, purple_connection_get_account(gc));
/*
* Make copies of the message and the sender in case plugins want
@@ -593,7 +581,7 @@ void serv_got_im(PurpleConnection *gc, const char *who, const char *msg,
plugin_return = GPOINTER_TO_INT(
purple_signal_emit_return_1(purple_conversations_get_handle(),
- "receiving-im-msg", gc->account,
+ "receiving-im-msg", purple_connection_get_account(gc),
&angel, &buffy, conv, &flags));
if (!buffy || !angel || plugin_return) {
@@ -605,12 +593,12 @@ void serv_got_im(PurpleConnection *gc, const char *who, const char *msg,
name = angel;
message = buffy;
- purple_signal_emit(purple_conversations_get_handle(), "received-im-msg", gc->account,
+ purple_signal_emit(purple_conversations_get_handle(), "received-im-msg", purple_connection_get_account(gc),
name, message, conv, flags);
/* search for conversation again in case it was created by received-im-msg handler */
if (conv == NULL)
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, name, gc->account);
+ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, name, purple_connection_get_account(gc));
if (conv == NULL)
conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, name);
@@ -627,7 +615,7 @@ void serv_got_im(PurpleConnection *gc, const char *who, const char *msg,
* - or we're not idle and the 'only auto respond if idle' pref
* is set
*/
- if (gc->flags & PURPLE_CONNECTION_AUTO_RESP)
+ if (purple_connection_get_flags(gc) & PURPLE_CONNECTION_AUTO_RESP)
{
PurplePresence *presence;
PurpleStatus *status;
@@ -700,7 +688,7 @@ void serv_got_typing(PurpleConnection *gc, const char *name, int timeout,
PurpleConversation *conv;
PurpleConvIm *im = NULL;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, name, gc->account);
+ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, name, purple_connection_get_account(gc));
if (conv != NULL) {
im = PURPLE_CONV_IM(conv);
@@ -710,15 +698,15 @@ void serv_got_typing(PurpleConnection *gc, const char *name, int timeout,
{
case PURPLE_TYPING:
purple_signal_emit(purple_conversations_get_handle(),
- "buddy-typing", gc->account, name);
+ "buddy-typing", purple_connection_get_account(gc), name);
break;
case PURPLE_TYPED:
purple_signal_emit(purple_conversations_get_handle(),
- "buddy-typed", gc->account, name);
+ "buddy-typed", purple_connection_get_account(gc), name);
break;
case PURPLE_NOT_TYPING:
purple_signal_emit(purple_conversations_get_handle(),
- "buddy-typing-stopped", gc->account, name);
+ "buddy-typing-stopped", purple_connection_get_account(gc), name);
break;
}
}
@@ -732,12 +720,12 @@ void serv_got_typing_stopped(PurpleConnection *gc, const char *name) {
PurpleConversation *conv;
PurpleConvIm *im;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, name, gc->account);
+ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, name, purple_connection_get_account(gc));
if (conv != NULL)
{
im = PURPLE_CONV_IM(conv);
- if (im->typing_state == PURPLE_NOT_TYPING)
+ if (purple_conv_im_get_typing_state(im) == PURPLE_NOT_TYPING)
return;
purple_conv_im_stop_typing_timeout(im);
@@ -746,7 +734,7 @@ void serv_got_typing_stopped(PurpleConnection *gc, const char *name) {
else
{
purple_signal_emit(purple_conversations_get_handle(),
- "buddy-typing-stopped", gc->account, name);
+ "buddy-typing-stopped", purple_connection_get_account(gc), name);
}
}
@@ -937,7 +925,7 @@ void serv_got_chat_in(PurpleConnection *g, int id, const char *who,
plugin_return = GPOINTER_TO_INT(
purple_signal_emit_return_1(purple_conversations_get_handle(),
- "receiving-chat-msg", g->account,
+ "receiving-chat-msg", purple_connection_get_account(g),
&angel, &buffy, conv, &flags));
if (!buffy || !angel || plugin_return) {
@@ -949,7 +937,7 @@ void serv_got_chat_in(PurpleConnection *g, int id, const char *who,
who = angel;
message = buffy;
- purple_signal_emit(purple_conversations_get_handle(), "received-chat-msg", g->account,
+ purple_signal_emit(purple_conversations_get_handle(), "received-chat-msg", purple_connection_get_account(g),
who, message, conv, flags);
purple_conv_chat_write(chat, who, message, flags, mtime);
diff --git a/libpurple/server.h b/libpurple/server.h
index 504011561b..d80b05d224 100644
--- a/libpurple/server.h
+++ b/libpurple/server.h
@@ -30,9 +30,7 @@
#include "conversation.h"
#include "prpl.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**
* Send a typing message to a given user over a given connection.
@@ -61,32 +59,6 @@ int serv_send_im(PurpleConnection *, const char *, const char *, PurpleMessageF
*/
PurpleAttentionType *purple_get_attention_type_from_code(PurpleAccount *account, guint type_code);
-/** Send an attention request message.
- *
- * @deprecated Use purple_prpl_send_attention() instead.
- *
- * @param gc The connection to send the message on.
- * @param who Whose attention to request.
- * @param type_code An index into the prpl's attention_types list determining the type
- * of the attention request command to send. 0 if prpl only defines one
- * (for example, Yahoo and MSN), but some protocols define more (MySpaceIM).
- *
- * Note that you can't send arbitrary PurpleAttentionType's, because there is
- * only a fixed set of attention commands.
- */
-void serv_send_attention(PurpleConnection *gc, const char *who, guint type_code);
-
-/** Process an incoming attention message.
- *
- * @deprecated Use purple_prpl_got_attention() instead.
- *
- * @param gc The connection that received the attention message.
- * @param who Who requested your attention.
- * @param type_code An index into the prpl's attention_types list determining the type
- * of the attention request command to send.
- */
-void serv_got_attention(PurpleConnection *gc, const char *who, guint type_code);
-
void serv_get_info(PurpleConnection *, const char *);
void serv_set_info(PurpleConnection *, const char *);
@@ -211,8 +183,7 @@ void serv_got_chat_in(PurpleConnection *g, int id, const char *who,
PurpleMessageFlags flags, const char *message, time_t mtime);
void serv_send_file(PurpleConnection *gc, const char *who, const char *file);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_SERVER_H_ */
+
diff --git a/libpurple/signals.h b/libpurple/signals.h
index 8499cebe5f..aa732050ef 100644
--- a/libpurple/signals.h
+++ b/libpurple/signals.h
@@ -35,9 +35,7 @@ typedef void (*PurpleCallback)(void);
typedef void (*PurpleSignalMarshalFunc)(PurpleCallback cb, va_list args,
void *data, void **return_val);
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Signal API */
@@ -373,8 +371,7 @@ void purple_marshal_POINTER__POINTER_POINTER(
PurpleCallback cb, va_list args, void *data, void **return_val);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_SIGNALS_H_ */
+
diff --git a/libpurple/smiley.h b/libpurple/smiley.h
index 73202bda47..c297d1daf0 100644
--- a/libpurple/smiley.h
+++ b/libpurple/smiley.h
@@ -1,7 +1,6 @@
/**
* @file smiley.h Smiley API
* @ingroup core
- * @since 2.5.0
*/
/* purple
@@ -51,9 +50,7 @@ typedef struct _PurpleSmileyClass PurpleSmileyClass;
#define PURPLE_IS_SMILEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PURPLE_TYPE_SMILEY))
#define PURPLE_SMILEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PURPLE_TYPE_SMILEY, PurpleSmileyClass))
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Custom Smiley API */
@@ -254,9 +251,7 @@ void purple_smileys_uninit(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_SMILEY_H_ */
diff --git a/libpurple/sound-theme-loader.c b/libpurple/sound-theme-loader.c
index ea85881053..2f2203bffc 100644
--- a/libpurple/sound-theme-loader.c
+++ b/libpurple/sound-theme-loader.c
@@ -32,23 +32,26 @@
*****************************************************************************/
static PurpleTheme *
-purple_sound_loader_build(const gchar *dir)
+purple_sound_loader_build(const gchar *theme_dir)
{
xmlnode *root_node = NULL, *sub_node;
- gchar *filename_full, *data = NULL;
+ gchar *dir, *filename_full, *data = NULL;
PurpleSoundTheme *theme = NULL;
const gchar *name;
/* Find the theme file */
- g_return_val_if_fail(dir != NULL, NULL);
+ g_return_val_if_fail(theme_dir != NULL, NULL);
+ dir = g_build_filename(theme_dir, "purple", "sound", NULL);
filename_full = g_build_filename(dir, "theme.xml", NULL);
if (g_file_test(filename_full, G_FILE_TEST_IS_REGULAR))
root_node = xmlnode_from_file(dir, "theme.xml", "sound themes", "sound-theme-loader");
g_free(filename_full);
- if (root_node == NULL)
+ if (root_node == NULL) {
+ g_free(dir);
return NULL;
+ }
name = xmlnode_get_attrib(root_node, "name");
@@ -79,6 +82,7 @@ purple_sound_loader_build(const gchar *dir)
xmlnode_free(root_node);
g_free(data);
+ g_free(dir);
return PURPLE_THEME(theme);
}
diff --git a/libpurple/sound-theme.c b/libpurple/sound-theme.c
index 4918f40758..1f471a3e5c 100644
--- a/libpurple/sound-theme.c
+++ b/libpurple/sound-theme.c
@@ -24,7 +24,7 @@
#include "sound-theme.h"
#define PURPLE_SOUND_THEME_GET_PRIVATE(Gobject) \
- ((PurpleSoundThemePrivate *) ((PURPLE_SOUND_THEME(Gobject))->priv))
+ (G_TYPE_INSTANCE_GET_PRIVATE((Gobject), PURPLE_TYPE_SOUND_THEME, PurpleSoundThemePrivate))
/******************************************************************************
* Structs
@@ -55,8 +55,6 @@ purple_sound_theme_init(GTypeInstance *instance,
{
PurpleSoundThemePrivate *priv;
- (PURPLE_SOUND_THEME(instance))->priv = g_new0(PurpleSoundThemePrivate, 1);
-
priv = PURPLE_SOUND_THEME_GET_PRIVATE(instance);
priv->sound_files = g_hash_table_new_full(g_str_hash,
@@ -82,6 +80,8 @@ purple_sound_theme_class_init(PurpleSoundThemeClass *klass)
parent_class = g_type_class_peek_parent(klass);
+ g_type_class_add_private(klass, sizeof(PurpleSoundThemePrivate));
+
obj_class->finalize = purple_sound_theme_finalize;
}
diff --git a/libpurple/sound-theme.h b/libpurple/sound-theme.h
index 3814e4527f..adde4fddea 100644
--- a/libpurple/sound-theme.h
+++ b/libpurple/sound-theme.h
@@ -51,7 +51,6 @@ typedef struct _PurpleSoundThemeClass PurpleSoundThemeClass;
struct _PurpleSoundTheme
{
PurpleTheme parent;
- gpointer priv;
};
struct _PurpleSoundThemeClass
diff --git a/libpurple/sound.h b/libpurple/sound.h
index 1879725818..cd46ed137c 100644
--- a/libpurple/sound.h
+++ b/libpurple/sound.h
@@ -38,7 +38,7 @@
* A type of sound.
*/
-typedef enum _PurpleSoundEventID
+typedef enum
{
PURPLE_SOUND_BUDDY_ARRIVE = 0, /**< Buddy signs on. */
PURPLE_SOUND_BUDDY_LEAVE, /**< Buddy signs off. */
@@ -72,9 +72,7 @@ typedef struct _PurpleSoundUiOps
void (*_purple_reserved4)(void);
} PurpleSoundUiOps;
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name Sound API */
@@ -136,8 +134,6 @@ void *purple_sounds_get_handle(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_SOUND_H_ */
diff --git a/libpurple/sslconn.c b/libpurple/sslconn.c
index e6365d390e..34e4a102f3 100644
--- a/libpurple/sslconn.c
+++ b/libpurple/sslconn.c
@@ -185,15 +185,6 @@ purple_ssl_strerror(PurpleSslErrorType error)
}
PurpleSslConnection *
-purple_ssl_connect_fd(PurpleAccount *account, int fd,
- PurpleSslInputFunction func,
- PurpleSslErrorFunction error_func,
- void *data)
-{
- return purple_ssl_connect_with_host_fd(account, fd, func, error_func, NULL, data);
-}
-
-PurpleSslConnection *
purple_ssl_connect_with_host_fd(PurpleAccount *account, int fd,
PurpleSslInputFunction func,
PurpleSslErrorFunction error_func,
diff --git a/libpurple/sslconn.h b/libpurple/sslconn.h
index 0bceccd57a..6987fb0e91 100644
--- a/libpurple/sslconn.h
+++ b/libpurple/sslconn.h
@@ -140,9 +140,7 @@ typedef struct
void (*_purple_reserved4)(void);
} PurpleSslOps;
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name SSL API */
@@ -203,7 +201,6 @@ PurpleSslConnection *purple_ssl_connect(PurpleAccount *account, const char *host
* @param data User-defined data.
*
* @return The SSL connection handle.
- * @since 2.6.0
*/
PurpleSslConnection *purple_ssl_connect_with_ssl_cn(PurpleAccount *account, const char *host,
int port, PurpleSslInputFunction func,
@@ -211,26 +208,6 @@ PurpleSslConnection *purple_ssl_connect_with_ssl_cn(PurpleAccount *account, cons
const char *ssl_host,
void *data);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_SSLCONN_C_)
-/**
- * Makes a SSL connection using an already open file descriptor.
- *
- * @deprecated Use purple_ssl_connect_with_host_fd() instead.
- *
- * @param account The account making the connection.
- * @param fd The file descriptor.
- * @param func The SSL input handler function.
- * @param error_func The SSL error handler function.
- * @param data User-defined data.
- *
- * @return The SSL connection handle.
- */
-PurpleSslConnection *purple_ssl_connect_fd(PurpleAccount *account, int fd,
- PurpleSslInputFunction func,
- PurpleSslErrorFunction error_func,
- void *data);
-#endif
-
/**
* Makes a SSL connection using an already open file descriptor.
*
@@ -242,8 +219,6 @@ PurpleSslConnection *purple_ssl_connect_fd(PurpleAccount *account, int fd,
* @param data User-defined data.
*
* @return The SSL connection handle.
- *
- * @since 2.2.0
*/
PurpleSslConnection *purple_ssl_connect_with_host_fd(PurpleAccount *account, int fd,
PurpleSslInputFunction func,
@@ -298,8 +273,6 @@ size_t purple_ssl_write(PurpleSslConnection *gsc, const void *buffer, size_t len
*
* @return The peer certificate chain, in the order of certificate, issuer,
* issuer's issuer, etc. @a NULL if no certificates have been provided,
- *
- * @since 2.2.0
*/
GList * purple_ssl_get_peer_certificates(PurpleSslConnection *gsc);
@@ -336,8 +309,6 @@ void purple_ssl_uninit(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_SSLCONN_H_ */
diff --git a/libpurple/status.c b/libpurple/status.c
index 9f7f80f151..9d43446efb 100644
--- a/libpurple/status.c
+++ b/libpurple/status.c
@@ -44,7 +44,6 @@ struct _PurpleStatusType
char *id;
char *name;
- char *primary_attr_id;
gboolean saveable;
gboolean user_settable;
@@ -258,6 +257,42 @@ purple_status_type_new(PurpleStatusPrimitive primitive, const char *id,
user_settable, FALSE);
}
+static void
+status_type_add_attr(PurpleStatusType *status_type, const char *id,
+ const char *name, PurpleValue *value)
+{
+ PurpleStatusAttr *attr;
+
+ g_return_if_fail(status_type != NULL);
+ g_return_if_fail(id != NULL);
+ g_return_if_fail(name != NULL);
+ g_return_if_fail(value != NULL);
+
+ attr = purple_status_attr_new(id, name, value);
+
+ status_type->attrs = g_list_append(status_type->attrs, attr);
+}
+
+static void
+status_type_add_attrs_vargs(PurpleStatusType *status_type, va_list args)
+{
+ const char *id, *name;
+ PurpleValue *value;
+
+ g_return_if_fail(status_type != NULL);
+
+ while ((id = va_arg(args, const char *)) != NULL)
+ {
+ name = va_arg(args, const char *);
+ g_return_if_fail(name != NULL);
+
+ value = va_arg(args, PurpleValue *);
+ g_return_if_fail(value != NULL);
+
+ status_type_add_attr(status_type, id, name, value);
+ }
+}
+
PurpleStatusType *
purple_status_type_new_with_attrs(PurpleStatusPrimitive primitive,
const char *id, const char *name,
@@ -278,10 +313,10 @@ purple_status_type_new_with_attrs(PurpleStatusPrimitive primitive,
user_settable, independent);
/* Add the first attribute */
- purple_status_type_add_attr(status_type, attr_id, attr_name, attr_value);
+ status_type_add_attr(status_type, attr_id, attr_name, attr_value);
va_start(args, attr_value);
- purple_status_type_add_attrs_vargs(status_type, args);
+ status_type_add_attrs_vargs(status_type, args);
va_end(args);
return status_type;
@@ -294,7 +329,6 @@ purple_status_type_destroy(PurpleStatusType *status_type)
g_free(status_type->id);
g_free(status_type->name);
- g_free(status_type->primary_attr_id);
g_list_foreach(status_type->attrs, (GFunc)purple_status_attr_destroy, NULL);
g_list_free(status_type->attrs);
@@ -303,70 +337,6 @@ purple_status_type_destroy(PurpleStatusType *status_type)
g_free(status_type);
}
-void
-purple_status_type_set_primary_attr(PurpleStatusType *status_type, const char *id)
-{
- g_return_if_fail(status_type != NULL);
-
- g_free(status_type->primary_attr_id);
- status_type->primary_attr_id = g_strdup(id);
-}
-
-void
-purple_status_type_add_attr(PurpleStatusType *status_type, const char *id,
- const char *name, PurpleValue *value)
-{
- PurpleStatusAttr *attr;
-
- g_return_if_fail(status_type != NULL);
- g_return_if_fail(id != NULL);
- g_return_if_fail(name != NULL);
- g_return_if_fail(value != NULL);
-
- attr = purple_status_attr_new(id, name, value);
-
- status_type->attrs = g_list_append(status_type->attrs, attr);
-}
-
-void
-purple_status_type_add_attrs_vargs(PurpleStatusType *status_type, va_list args)
-{
- const char *id, *name;
- PurpleValue *value;
-
- g_return_if_fail(status_type != NULL);
-
- while ((id = va_arg(args, const char *)) != NULL)
- {
- name = va_arg(args, const char *);
- g_return_if_fail(name != NULL);
-
- value = va_arg(args, PurpleValue *);
- g_return_if_fail(value != NULL);
-
- purple_status_type_add_attr(status_type, id, name, value);
- }
-}
-
-void
-purple_status_type_add_attrs(PurpleStatusType *status_type, const char *id,
- const char *name, PurpleValue *value, ...)
-{
- va_list args;
-
- g_return_if_fail(status_type != NULL);
- g_return_if_fail(id != NULL);
- g_return_if_fail(name != NULL);
- g_return_if_fail(value != NULL);
-
- /* Add the first attribute */
- purple_status_type_add_attr(status_type, id, name, value);
-
- va_start(args, value);
- purple_status_type_add_attrs_vargs(status_type, args);
- va_end(args);
-}
-
PurpleStatusPrimitive
purple_status_type_get_primitive(const PurpleStatusType *status_type)
{
@@ -435,14 +405,6 @@ purple_status_type_is_available(const PurpleStatusType *status_type)
return (primitive == PURPLE_STATUS_AVAILABLE);
}
-const char *
-purple_status_type_get_primary_attr(const PurpleStatusType *status_type)
-{
- g_return_val_if_fail(status_type != NULL, NULL);
-
- return status_type->primary_attr_id;
-}
-
PurpleStatusAttr *
purple_status_type_get_attr(const PurpleStatusType *status_type, const char *id)
{
@@ -706,6 +668,68 @@ status_has_changed(PurpleStatus *status)
notify_status_update(presence, old_status, status);
}
+static void
+status_set_attr_boolean(PurpleStatus *status, const char *id,
+ gboolean value)
+{
+ PurpleValue *attr_value;
+
+ g_return_if_fail(status != NULL);
+ g_return_if_fail(id != NULL);
+
+ /* Make sure this attribute exists and is the correct type. */
+ attr_value = purple_status_get_attr_value(status, id);
+ g_return_if_fail(attr_value != NULL);
+ g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_BOOLEAN);
+
+ purple_value_set_boolean(attr_value, value);
+}
+
+static void
+status_set_attr_int(PurpleStatus *status, const char *id, int value)
+{
+ PurpleValue *attr_value;
+
+ g_return_if_fail(status != NULL);
+ g_return_if_fail(id != NULL);
+
+ /* Make sure this attribute exists and is the correct type. */
+ attr_value = purple_status_get_attr_value(status, id);
+ g_return_if_fail(attr_value != NULL);
+ g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_INT);
+
+ purple_value_set_int(attr_value, value);
+}
+
+static void
+status_set_attr_string(PurpleStatus *status, const char *id,
+ const char *value)
+{
+ PurpleValue *attr_value;
+
+ g_return_if_fail(status != NULL);
+ g_return_if_fail(id != NULL);
+
+ /* Make sure this attribute exists and is the correct type. */
+ attr_value = purple_status_get_attr_value(status, id);
+ /* This used to be g_return_if_fail, but it's failing a LOT, so
+ * let's generate a log error for now. */
+ /* g_return_if_fail(attr_value != NULL); */
+ if (attr_value == NULL) {
+ purple_debug_error("status",
+ "Attempted to set status attribute '%s' for "
+ "status '%s', which is not legal. Fix "
+ "this!\n", id,
+ purple_status_type_get_name(purple_status_get_type(status)));
+ return;
+ }
+ g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_STRING);
+
+ /* XXX: Check if the value has actually changed. If it has, and the status
+ * is active, should this trigger 'status_has_changed'? */
+ purple_value_set_string(attr_value, value);
+}
+
void
purple_status_set_active(PurpleStatus *status, gboolean active)
{
@@ -782,31 +806,31 @@ purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active,
specified_attr_ids = g_list_prepend(specified_attr_ids, (gpointer)id);
- if (value->type == PURPLE_TYPE_STRING)
+ if (purple_value_get_type(value) == PURPLE_TYPE_STRING)
{
const gchar *string_data = l->data;
l = l->next;
- if (purple_strequal(string_data, value->data.string_data))
+ if (purple_strequal(string_data, purple_value_get_string(value)))
continue;
- purple_status_set_attr_string(status, id, string_data);
+ status_set_attr_string(status, id, string_data);
changed = TRUE;
}
- else if (value->type == PURPLE_TYPE_INT)
+ else if (purple_value_get_type(value) == PURPLE_TYPE_INT)
{
int int_data = GPOINTER_TO_INT(l->data);
l = l->next;
- if (int_data == value->data.int_data)
+ if (int_data == purple_value_get_int(value))
continue;
- purple_status_set_attr_int(status, id, int_data);
+ status_set_attr_int(status, id, int_data);
changed = TRUE;
}
- else if (value->type == PURPLE_TYPE_BOOLEAN)
+ else if (purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN)
{
gboolean boolean_data = GPOINTER_TO_INT(l->data);
l = l->next;
- if (boolean_data == value->data.boolean_data)
+ if (boolean_data == purple_value_get_boolean(value))
continue;
- purple_status_set_attr_boolean(status, id, boolean_data);
+ status_set_attr_boolean(status, id, boolean_data);
changed = TRUE;
}
else
@@ -828,7 +852,7 @@ purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active,
if (!g_list_find_custom(specified_attr_ids, attr->id, (GCompareFunc)strcmp)) {
PurpleValue *default_value;
default_value = purple_status_attr_get_value(attr);
- if (default_value->type == PURPLE_TYPE_STRING) {
+ if (purple_value_get_type(default_value) == PURPLE_TYPE_STRING) {
const char *cur = purple_status_get_attr_string(status, attr->id);
const char *def = purple_value_get_string(default_value);
if ((cur == NULL && def == NULL)
@@ -837,21 +861,21 @@ purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active,
continue;
}
- purple_status_set_attr_string(status, attr->id, def);
- } else if (default_value->type == PURPLE_TYPE_INT) {
+ status_set_attr_string(status, attr->id, def);
+ } else if (purple_value_get_type(default_value) == PURPLE_TYPE_INT) {
int cur = purple_status_get_attr_int(status, attr->id);
int def = purple_value_get_int(default_value);
if (cur == def)
continue;
- purple_status_set_attr_int(status, attr->id, def);
- } else if (default_value->type == PURPLE_TYPE_BOOLEAN) {
+ status_set_attr_int(status, attr->id, def);
+ } else if (purple_value_get_type(default_value) == PURPLE_TYPE_BOOLEAN) {
gboolean cur = purple_status_get_attr_boolean(status, attr->id);
gboolean def = purple_value_get_boolean(default_value);
if (cur == def)
continue;
- purple_status_set_attr_boolean(status, attr->id, def);
+ status_set_attr_boolean(status, attr->id, def);
}
changed = TRUE;
}
@@ -863,68 +887,6 @@ purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active,
status_has_changed(status);
}
-void
-purple_status_set_attr_boolean(PurpleStatus *status, const char *id,
- gboolean value)
-{
- PurpleValue *attr_value;
-
- g_return_if_fail(status != NULL);
- g_return_if_fail(id != NULL);
-
- /* Make sure this attribute exists and is the correct type. */
- attr_value = purple_status_get_attr_value(status, id);
- g_return_if_fail(attr_value != NULL);
- g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_BOOLEAN);
-
- purple_value_set_boolean(attr_value, value);
-}
-
-void
-purple_status_set_attr_int(PurpleStatus *status, const char *id, int value)
-{
- PurpleValue *attr_value;
-
- g_return_if_fail(status != NULL);
- g_return_if_fail(id != NULL);
-
- /* Make sure this attribute exists and is the correct type. */
- attr_value = purple_status_get_attr_value(status, id);
- g_return_if_fail(attr_value != NULL);
- g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_INT);
-
- purple_value_set_int(attr_value, value);
-}
-
-void
-purple_status_set_attr_string(PurpleStatus *status, const char *id,
- const char *value)
-{
- PurpleValue *attr_value;
-
- g_return_if_fail(status != NULL);
- g_return_if_fail(id != NULL);
-
- /* Make sure this attribute exists and is the correct type. */
- attr_value = purple_status_get_attr_value(status, id);
- /* This used to be g_return_if_fail, but it's failing a LOT, so
- * let's generate a log error for now. */
- /* g_return_if_fail(attr_value != NULL); */
- if (attr_value == NULL) {
- purple_debug_error("status",
- "Attempted to set status attribute '%s' for "
- "status '%s', which is not legal. Fix "
- "this!\n", id,
- purple_status_type_get_name(purple_status_get_type(status)));
- return;
- }
- g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_STRING);
-
- /* XXX: Check if the value has actually changed. If it has, and the status
- * is active, should this trigger 'status_has_changed'? */
- purple_value_set_string(attr_value, value);
-}
-
PurpleStatusType *
purple_status_get_type(const PurpleStatus *status)
{
@@ -1137,7 +1099,7 @@ purple_presence_new_for_conv(PurpleConversation *conv)
presence = purple_presence_new(PURPLE_PRESENCE_CONTEXT_CONV);
presence->u.chat.conv = conv;
- /* presence->statuses = purple_prpl_get_statuses(conv->account, presence); ? */
+ /* presence->statuses = purple_prpl_get_statuses(purple_conversation_get_account(conv), presence); ? */
return presence;
}
@@ -1186,30 +1148,6 @@ purple_presence_destroy(PurplePresence *presence)
}
void
-purple_presence_add_status(PurplePresence *presence, PurpleStatus *status)
-{
- g_return_if_fail(presence != NULL);
- g_return_if_fail(status != NULL);
-
- presence->statuses = g_list_append(presence->statuses, status);
-
- g_hash_table_insert(presence->status_table,
- g_strdup(purple_status_get_id(status)), status);
-}
-
-void
-purple_presence_add_list(PurplePresence *presence, GList *source_list)
-{
- GList *l;
-
- g_return_if_fail(presence != NULL);
- g_return_if_fail(source_list != NULL);
-
- for (l = source_list; l != NULL; l = l->next)
- purple_presence_add_status(presence, (PurpleStatus *)l->data);
-}
-
-void
purple_presence_set_status_active(PurplePresence *presence, const char *status_id,
gboolean active)
{
diff --git a/libpurple/status.h b/libpurple/status.h
index f47ce900bb..6c7e525776 100644
--- a/libpurple/status.h
+++ b/libpurple/status.h
@@ -148,9 +148,7 @@ typedef enum
#define PURPLE_MOOD_NAME "mood"
#define PURPLE_MOOD_COMMENT "moodtext"
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name PurpleStatusPrimitive API */
@@ -271,73 +269,6 @@ PurpleStatusType *purple_status_type_new_with_attrs(PurpleStatusPrimitive primit
*/
void purple_status_type_destroy(PurpleStatusType *status_type);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Sets a status type's primary attribute.
- *
- * The value for the primary attribute is used as the description for
- * the particular status type. An example is an away message. The message
- * would be the primary attribute.
- *
- * @param status_type The status type.
- * @param attr_id The ID of the primary attribute.
- *
- * @deprecated This function isn't used and should be removed in 3.0.0.
- */
-void purple_status_type_set_primary_attr(PurpleStatusType *status_type,
- const char *attr_id);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Adds an attribute to a status type.
- *
- * @param status_type The status type to add the attribute to.
- * @param id The ID of the attribute.
- * @param name The name presented to the user.
- * @param value The value type of this attribute.
- *
- * @deprecated This function isn't needed and should be removed in 3.0.0.
- * Status type attributes should be set when the status type
- * is created, in the call to purple_status_type_new_with_attrs.
- */
-void purple_status_type_add_attr(PurpleStatusType *status_type, const char *id,
- const char *name, PurpleValue *value);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Adds multiple attributes to a status type.
- *
- * @param status_type The status type to add the attribute to.
- * @param id The ID of the first attribute.
- * @param name The description of the first attribute.
- * @param value The value type of the first attribute attribute.
- * @param ... Additional attribute information.
- *
- * @deprecated This function isn't needed and should be removed in 3.0.0.
- * Status type attributes should be set when the status type
- * is created, in the call to purple_status_type_new_with_attrs.
- */
-void purple_status_type_add_attrs(PurpleStatusType *status_type, const char *id,
- const char *name, PurpleValue *value, ...) G_GNUC_NULL_TERMINATED;
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Adds multiple attributes to a status type using a va_list.
- *
- * @param status_type The status type to add the attribute to.
- * @param args The va_list of attributes.
- *
- * @deprecated This function isn't needed and should be removed in 3.0.0.
- * Status type attributes should be set when the status type
- * is created, in the call to purple_status_type_new_with_attrs.
- */
-void purple_status_type_add_attrs_vargs(PurpleStatusType *status_type,
- va_list args);
-#endif
-
/**
* Returns the primitive type of a status type.
*
@@ -419,19 +350,6 @@ gboolean purple_status_type_is_exclusive(const PurpleStatusType *status_type);
*/
gboolean purple_status_type_is_available(const PurpleStatusType *status_type);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Returns a status type's primary attribute ID.
- *
- * @param type The status type.
- *
- * @return The primary attribute's ID.
- *
- * @deprecated This function isn't used and should be removed in 3.0.0.
- */
-const char *purple_status_type_get_primary_attr(const PurpleStatusType *type);
-#endif
-
/**
* Returns the attribute with the specified ID.
*
@@ -582,51 +500,6 @@ void purple_status_set_active_with_attrs(PurpleStatus *status, gboolean active,
void purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active,
GList *attrs);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Sets the boolean value of an attribute in a status with the specified ID.
- *
- * @param status The status.
- * @param id The attribute ID.
- * @param value The boolean value.
- *
- * @deprecated This function is only used by status.c and should be made
- * static in 3.0.0.
- */
-void purple_status_set_attr_boolean(PurpleStatus *status, const char *id,
- gboolean value);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Sets the integer value of an attribute in a status with the specified ID.
- *
- * @param status The status.
- * @param id The attribute ID.
- * @param value The integer value.
- *
- * @deprecated This function is only used by status.c and should be made
- * static in 3.0.0.
- */
-void purple_status_set_attr_int(PurpleStatus *status, const char *id,
- int value);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Sets the string value of an attribute in a status with the specified ID.
- *
- * @param status The status.
- * @param id The attribute ID.
- * @param value The string value.
- *
- * @deprecated This function is only used by status.c and should be made
- * static in 3.0.0.
- */
-void purple_status_set_attr_string(PurpleStatus *status, const char *id,
- const char *value);
-#endif
-
/**
* Returns the status's type.
*
@@ -833,32 +706,6 @@ PurplePresence *purple_presence_new_for_buddy(PurpleBuddy *buddy);
*/
void purple_presence_destroy(PurplePresence *presence);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Adds a status to a presence.
- *
- * @param presence The presence.
- * @param status The status to add.
- *
- * @deprecated This function is only used by purple_presence_add_list,
- * and both should be removed in 3.0.0.
- */
-void purple_presence_add_status(PurplePresence *presence, PurpleStatus *status);
-#endif
-
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_)
-/**
- * Adds a list of statuses to the presence.
- *
- * @param presence The presence.
- * @param source_list The source list of statuses to add, which is not
- * modified or freed by this function.
- *
- * @deprecated This function isn't used and should be removed in 3.0.0.
- */
-void purple_presence_add_list(PurplePresence *presence, GList *source_list);
-#endif
-
/**
* Sets the active state of a status in a presence.
*
@@ -1096,8 +943,7 @@ void purple_status_uninit(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_STATUS_H_ */
+
diff --git a/libpurple/stringref.h b/libpurple/stringref.h
index cbb9eecb19..debbe1fd5c 100644
--- a/libpurple/stringref.h
+++ b/libpurple/stringref.h
@@ -29,12 +29,10 @@
#ifndef _PURPLE_STRINGREF_H_
#define _PURPLE_STRINGREF_H_
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct _PurpleStringref PurpleStringref;
+G_BEGIN_DECLS
+
/**
* Creates an immutable reference-counted string object. The newly
* created object will have a reference count of 1.
@@ -131,8 +129,6 @@ int purple_stringref_cmp(const PurpleStringref *s1, const PurpleStringref *s2);
*/
size_t purple_stringref_len(const PurpleStringref *stringref);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_STRINGREF_H_ */
diff --git a/libpurple/stun.c b/libpurple/stun.c
index 809bf6b86f..2308d80677 100644
--- a/libpurple/stun.c
+++ b/libpurple/stun.c
@@ -174,6 +174,8 @@ static void reply_cb(gpointer data, gint source, PurpleInputCondition cond) {
struct ifreq *ifr;
struct sockaddr_in *sinptr;
+ memset(&in, 0, sizeof(in));
+
len = recv(source, buffer, sizeof(buffer) - 1, 0);
if (!len) {
purple_debug_warning("stun", "unable to read stun response\n");
@@ -338,7 +340,7 @@ static void hbn_cb(GSList *hosts, gpointer data, const char *error_message) {
return;
}
- if (!purple_network_listen_range(12108, 12208, SOCK_DGRAM, hbn_listen_cb, hosts)) {
+ if (!purple_network_listen_range(12108, 12208, AF_UNSPEC, SOCK_DGRAM, TRUE, hbn_listen_cb, hosts)) {
while (hosts) {
hosts = g_slist_delete_link(hosts, hosts);
g_free(hosts->data);
@@ -365,7 +367,7 @@ static void do_test1(PurpleSrvResponse *resp, int results, gpointer sdata) {
purple_debug_info("stun", "got %d SRV responses, server: %s, port: %d\n",
results, servername, port);
- purple_dnsquery_a_account(NULL, servername, port, hbn_cb, NULL);
+ purple_dnsquery_a(NULL, servername, port, hbn_cb, NULL);
g_free(resp);
}
@@ -424,7 +426,7 @@ PurpleStunNatDiscovery *purple_stun_discover(StunCallback cb) {
nattype.servername = g_strdup(servername);
callbacks = g_slist_append(callbacks, cb);
- purple_srv_resolve_account(NULL, "stun", "udp", servername, do_test1,
+ purple_srv_resolve(NULL, "stun", "udp", servername, do_test1,
(gpointer) servername);
return &nattype;
diff --git a/libpurple/stun.h b/libpurple/stun.h
index b51a61c7e5..003f19f0cd 100644
--- a/libpurple/stun.h
+++ b/libpurple/stun.h
@@ -26,10 +26,6 @@
#ifndef _PURPLE_STUN_H_
#define _PURPLE_STUN_H_
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/**************************************************************************/
/** @name STUN API */
/**************************************************************************/
@@ -63,6 +59,8 @@ struct _PurpleStunNatDiscovery {
typedef void (*StunCallback) (PurpleStunNatDiscovery *);
+G_BEGIN_DECLS
+
/**
* Starts a NAT discovery. It returns a PurpleStunNatDiscovery if the discovery
* is already done. Otherwise the callback is called when the discovery is over
@@ -81,8 +79,6 @@ void purple_stun_init(void);
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_STUN_H_ */
diff --git a/libpurple/tests/test_xmlnode.c b/libpurple/tests/test_xmlnode.c
index 59f8d44338..264a468d92 100644
--- a/libpurple/tests/test_xmlnode.c
+++ b/libpurple/tests/test_xmlnode.c
@@ -21,6 +21,101 @@ START_TEST(test_xmlnode_billion_laughs_attack)
}
END_TEST
+#define check_doc_structure(x) { \
+ xmlnode *ping, *child1, *child2; \
+ fail_if(x == NULL, "Failed to parse document"); \
+ ping = xmlnode_get_child(x, "ping"); \
+ fail_if(ping == NULL, "Failed to find 'ping' child"); \
+ child1 = xmlnode_get_child(ping, "child1"); \
+ fail_if(child1 == NULL, "Failed to find 'child1'"); \
+ child2 = xmlnode_get_child(child1, "child2"); \
+ fail_if(child2 == NULL, "Failed to find 'child2'"); \
+ xmlnode_new_child(child2, "a"); \
+ \
+ assert_string_equal("jabber:client", xmlnode_get_namespace(x)); \
+ /* NOTE: xmlnode_get_namespace() returns the namespace of the element, not the
+ * current default namespace. See http://www.w3.org/TR/xml-names/#defaulting and
+ * http://www.w3.org/TR/xml-names/#dt-defaultNS.
+ */ \
+ assert_string_equal("urn:xmpp:ping", xmlnode_get_namespace(ping)); \
+ assert_string_equal("jabber:client", xmlnode_get_namespace(child1)); \
+ assert_string_equal("urn:xmpp:ping", xmlnode_get_namespace(child2)); \
+ /*
+ * This fails (well, actually crashes [the ns is NULL]) unless
+ * xmlnode_new_child() actually sets the element namespace.
+ assert_string_equal("jabber:client", xmlnode_get_namespace(xmlnode_get_child(child2, "a")));
+ */ \
+ \
+ assert_string_equal("jabber:client", xmlnode_get_default_namespace(x)); \
+ assert_string_equal("jabber:client", xmlnode_get_default_namespace(ping)); \
+ assert_string_equal("jabber:client", xmlnode_get_default_namespace(child1)); \
+ assert_string_equal("jabber:client", xmlnode_get_default_namespace(child2)); \
+}
+
+START_TEST(test_xmlnode_prefixes)
+{
+ const char *xml_doc =
+ "<iq type='get' xmlns='jabber:client' xmlns:ping='urn:xmpp:ping'>"
+ "<ping:ping>"
+ "<child1>"
+ "<ping:child2></ping:child2>" /* xmlns='jabber:child' */
+ "</child1>"
+ "</ping:ping>"
+ "</iq>";
+ char *str;
+ xmlnode *xml, *reparsed;
+
+ xml = xmlnode_from_str(xml_doc, -1);
+ check_doc_structure(xml);
+
+ /* Check that xmlnode_from_str(xmlnode_to_str(xml, NULL), -1) is idempotent. */
+ str = xmlnode_to_str(xml, NULL);
+ fail_if(str == NULL, "Failed to serialize XMLnode");
+ reparsed = xmlnode_from_str(str, -1);
+ fail_if(reparsed == NULL, "Failed to reparse xml document");
+ check_doc_structure(reparsed);
+
+ g_free(str);
+ xmlnode_free(xml);
+ xmlnode_free(reparsed);
+}
+END_TEST
+
+
+START_TEST(test_strip_prefixes)
+{
+ const char *xml_doc = "<message xmlns='jabber:client' from='user@gmail.com/resource' to='another_user@darkrain42.org' type='chat' id='purple'>"
+ "<cha:active xmlns:cha='http://jabber.org/protocol/chatstates'/>"
+ "<body>xvlc xvlc</body>"
+ "<im:html xmlns:im='http://jabber.org/protocol/xhtml-im'>"
+ "<xht:body xmlns:xht='http://www.w3.org/1999/xhtml'>"
+ "<xht:p>xvlc <xht:span style='font-weight: bold;'>xvlc</xht:span></xht:p>"
+ "</xht:body>"
+ "</im:html>"
+ "</message>";
+ const char *out = "<message xmlns='jabber:client' from='user@gmail.com/resource' to='another_user@darkrain42.org' type='chat' id='purple'>"
+ "<active xmlns:cha='http://jabber.org/protocol/chatstates' xmlns='http://jabber.org/protocol/chatstates'/>"
+ "<body>xvlc xvlc</body>"
+ "<html xmlns:im='http://jabber.org/protocol/xhtml-im' xmlns='http://jabber.org/protocol/xhtml-im'>"
+ "<body xmlns:xht='http://www.w3.org/1999/xhtml' xmlns='http://www.w3.org/1999/xhtml'>"
+ "<p>xvlc <span style='font-weight: bold;'>xvlc</span></p>"
+ "</body>"
+ "</html>"
+ "</message>";
+ char *str;
+ xmlnode *xml;
+
+ xml = xmlnode_from_str(xml_doc, -1);
+ fail_if(xml == NULL, "Failed to parse XML");
+
+ xmlnode_strip_prefixes(xml);
+ str = xmlnode_to_str(xml, NULL);
+ assert_string_equal_free(out, str);
+
+ xmlnode_free(xml);
+}
+END_TEST
+
Suite *
xmlnode_suite(void)
{
@@ -28,6 +123,9 @@ xmlnode_suite(void)
TCase *tc = tcase_create("xmlnode");
tcase_add_test(tc, test_xmlnode_billion_laughs_attack);
+ tcase_add_test(tc, test_xmlnode_prefixes);
+ tcase_add_test(tc, test_strip_prefixes);
+
suite_add_tcase(s, tc);
return s;
diff --git a/libpurple/theme-loader.c b/libpurple/theme-loader.c
index e9b4a3ba9a..fd8a570253 100644
--- a/libpurple/theme-loader.c
+++ b/libpurple/theme-loader.c
@@ -24,7 +24,7 @@
#include "theme-loader.h"
#define PURPLE_THEME_LOADER_GET_PRIVATE(PurpleThemeLoader) \
- ((PurpleThemeLoaderPrivate *) ((PurpleThemeLoader)->priv))
+ (G_TYPE_INSTANCE_GET_PRIVATE((PurpleThemeLoader), PURPLE_TYPE_THEME_LOADER, PurpleThemeLoaderPrivate))
void purple_theme_loader_set_type_string(PurpleThemeLoader *loader, const gchar *type);
@@ -85,12 +85,19 @@ purple_theme_loader_set_property(GObject *obj, guint param_id, const GValue *val
}
}
-static void
-purple_theme_loader_init(GTypeInstance *instance,
- gpointer klass)
+static gboolean
+purple_theme_loader_probe_directory(PurpleThemeLoader *loader, const gchar *dir)
{
- PurpleThemeLoader *loader = PURPLE_THEME_LOADER(instance);
- loader->priv = g_new0(PurpleThemeLoaderPrivate, 1);
+ const gchar *type = purple_theme_loader_get_type_string(loader);
+ char *themedir;
+ gboolean result;
+
+ /* Checks for directory as $root/purple/$type */
+ themedir = g_build_filename(dir, "purple", type, NULL);
+ result = g_file_test(themedir, G_FILE_TEST_IS_DIR);
+ g_free(themedir);
+
+ return result;
}
static void
@@ -100,7 +107,6 @@ purple_theme_loader_finalize(GObject *obj)
PurpleThemeLoaderPrivate *priv = PURPLE_THEME_LOADER_GET_PRIVATE(loader);
g_free(priv->type);
- g_free(priv);
parent_class->finalize(obj);
}
@@ -113,6 +119,8 @@ purple_theme_loader_class_init(PurpleThemeLoaderClass *klass)
parent_class = g_type_class_peek_parent(klass);
+ g_type_class_add_private(klass, sizeof(PurpleThemeLoaderPrivate));
+
obj_class->get_property = purple_theme_loader_get_property;
obj_class->set_property = purple_theme_loader_set_property;
obj_class->finalize = purple_theme_loader_finalize;
@@ -139,7 +147,7 @@ purple_theme_loader_get_type(void)
NULL, /* class_data */
sizeof(PurpleThemeLoader),
0, /* n_preallocs */
- purple_theme_loader_init, /* instance_init */
+ NULL, /* instance_init */
NULL, /* value table */
};
type = g_type_register_static(G_TYPE_OBJECT,
@@ -182,3 +190,13 @@ purple_theme_loader_build(PurpleThemeLoader *loader, const gchar *dir)
{
return PURPLE_THEME_LOADER_GET_CLASS(loader)->purple_theme_loader_build(dir);
}
+
+gboolean
+purple_theme_loader_probe(PurpleThemeLoader *loader, const gchar *dir)
+{
+ if (PURPLE_THEME_LOADER_GET_CLASS(loader)->probe_directory != NULL)
+ return PURPLE_THEME_LOADER_GET_CLASS(loader)->probe_directory(dir);
+ else
+ return purple_theme_loader_probe_directory(loader, dir);
+}
+
diff --git a/libpurple/theme-loader.h b/libpurple/theme-loader.h
index bf76b38920..dedef39d9f 100644
--- a/libpurple/theme-loader.h
+++ b/libpurple/theme-loader.h
@@ -50,13 +50,13 @@ typedef struct _PurpleThemeLoaderClass PurpleThemeLoaderClass;
struct _PurpleThemeLoader
{
GObject parent;
- gpointer priv;
};
struct _PurpleThemeLoaderClass
{
GObjectClass parent_class;
PurpleTheme *((*purple_theme_loader_build)(const gchar*));
+ gboolean (*probe_directory)(const gchar *);
};
/**************************************************************************/
@@ -89,5 +89,19 @@ const gchar *purple_theme_loader_get_type_string(PurpleThemeLoader *self);
*/
PurpleTheme *purple_theme_loader_build(PurpleThemeLoader *loader, const gchar *dir);
+/**
+ * Probes a directory to see if it might possibly contain a theme
+ *
+ * This function might only check for obvious files or directory structure.
+ * Loading of a theme may fail for other reasons.
+ * The default prober checks for $dir/purple/$type.
+ *
+ * @param loader The theme loader
+ * @param dir The directory that may contain the theme
+ *
+ * @returns TRUE if the directory appears to contain a theme, FALSE otherwise.
+ */
+gboolean purple_theme_loader_probe(PurpleThemeLoader *loader, const gchar *dir);
+
G_END_DECLS
#endif /* PURPLE_THEME_LOADER_H */
diff --git a/libpurple/theme-manager.c b/libpurple/theme-manager.c
index 7b8e3506f8..25d7c42657 100644
--- a/libpurple/theme-manager.c
+++ b/libpurple/theme-manager.c
@@ -80,11 +80,14 @@ purple_theme_manager_is_theme_type(gchar *key,
}
static gboolean
-purple_theme_manager_is_theme(gchar *key,
- gpointer value,
- gchar *user_data)
+check_if_theme_or_loader(gchar *key, gpointer value, GSList **loaders)
{
- return PURPLE_IS_THEME(value);
+ if (PURPLE_IS_THEME(value))
+ return TRUE;
+ else if (PURPLE_IS_THEME_LOADER(value))
+ *loaders = g_slist_prepend(*loaders, value);
+
+ return FALSE;
}
static void
@@ -97,11 +100,12 @@ purple_theme_manager_function_wrapper(gchar *key,
}
static void
-purple_theme_manager_build_dir(const gchar *root)
+purple_theme_manager_build_dir(GSList *loaders, const gchar *root)
{
- gchar *purple_dir, *theme_dir;
- const gchar *name = NULL, *type = NULL;
- GDir *rdir, *tdir;
+ gchar *theme_dir;
+ const gchar *name;
+ GDir *rdir;
+ GSList *tmp;
PurpleThemeLoader *loader;
rdir = g_dir_open(root, 0, NULL);
@@ -109,33 +113,20 @@ purple_theme_manager_build_dir(const gchar *root)
if (!rdir)
return;
- /* Parses directory by root/name/purple/type */
while ((name = g_dir_read_name(rdir))) {
- purple_dir = g_build_filename(root, name, "purple", NULL);
- tdir = g_dir_open(purple_dir, 0, NULL);
-
- if (!tdir) {
- g_free(purple_dir);
+ theme_dir = g_build_filename(root, name, NULL);
- continue;
- }
-
- while ((type = g_dir_read_name(tdir))) {
- if ((loader = g_hash_table_lookup(theme_table, type))) {
- PurpleTheme *theme = NULL;
-
- theme_dir = g_build_filename(purple_dir, type, NULL);
-
- theme = purple_theme_loader_build(loader, theme_dir);
- g_free(theme_dir);
+ for (tmp = loaders; tmp; tmp = g_slist_next(tmp)) {
+ loader = PURPLE_THEME_LOADER(tmp->data);
+ if (purple_theme_loader_probe(loader, theme_dir)) {
+ PurpleTheme *theme = purple_theme_loader_build(loader, theme_dir);
if (PURPLE_IS_THEME(theme))
purple_theme_manager_add_theme(theme);
}
}
- g_dir_close(tdir);
- g_free(purple_dir);
+ g_free(theme_dir);
}
g_dir_close(rdir);
@@ -155,16 +146,17 @@ purple_theme_manager_init(void)
void
purple_theme_manager_refresh(void)
{
- gchar *path = NULL;
- const gchar *xdg = NULL;
- gint i = 0;
+ gchar *path;
+ const gchar *xdg;
+ gint i;
+ GSList *loaders = NULL;
- g_hash_table_foreach_remove(theme_table,
- (GHRFunc) purple_theme_manager_is_theme, NULL);
+ g_hash_table_foreach_remove(theme_table, (GHRFunc)check_if_theme_or_loader,
+ &loaders);
/* Add themes from ~/.purple */
path = g_build_filename(purple_user_dir(), "themes", NULL);
- purple_theme_manager_build_dir(path);
+ purple_theme_manager_build_dir(loaders, path);
g_free(path);
/* look for XDG_DATA_HOME. If we don't have it use ~/.local, and add it */
@@ -173,7 +165,7 @@ purple_theme_manager_refresh(void)
else
path = g_build_filename(purple_home_dir(), ".local", "themes", NULL);
- purple_theme_manager_build_dir(path);
+ purple_theme_manager_build_dir(loaders, path);
g_free(path);
/* now dig through XDG_DATA_DIRS and add those too */
@@ -183,12 +175,14 @@ purple_theme_manager_refresh(void)
for (i = 0; xdg_dirs[i]; i++) {
path = g_build_filename(xdg_dirs[i], "themes", NULL);
- purple_theme_manager_build_dir(path);
+ purple_theme_manager_build_dir(loaders, path);
g_free(path);
}
g_strfreev(xdg_dirs);
}
+
+ g_slist_free(loaders);
}
void
diff --git a/libpurple/theme.c b/libpurple/theme.c
index c21e71a053..cf3bc36985 100644
--- a/libpurple/theme.c
+++ b/libpurple/theme.c
@@ -25,7 +25,7 @@
#include "util.h"
#define PURPLE_THEME_GET_PRIVATE(PurpleTheme) \
- ((PurpleThemePrivate *) ((PurpleTheme)->priv))
+ (G_TYPE_INSTANCE_GET_PRIVATE((PurpleTheme), PURPLE_TYPE_THEME, PurpleThemePrivate))
void purple_theme_set_type_string(PurpleTheme *theme, const gchar *type);
@@ -129,14 +129,6 @@ purple_theme_set_property(GObject *obj, guint param_id, const GValue *value,
}
static void
-purple_theme_init(GTypeInstance *instance,
- gpointer klass)
-{
- PurpleTheme *theme = PURPLE_THEME(instance);
- theme->priv = g_new0(PurpleThemePrivate, 1);
-}
-
-static void
purple_theme_finalize(GObject *obj)
{
PurpleTheme *theme = PURPLE_THEME(obj);
@@ -160,6 +152,8 @@ purple_theme_class_init(PurpleThemeClass *klass)
parent_class = g_type_class_peek_parent(klass);
+ g_type_class_add_private(klass, sizeof(PurpleThemePrivate));
+
obj_class->get_property = purple_theme_get_property;
obj_class->set_property = purple_theme_set_property;
obj_class->finalize = purple_theme_finalize;
@@ -222,7 +216,7 @@ purple_theme_get_type(void)
NULL, /* class_data */
sizeof(PurpleTheme),
0, /* n_preallocs */
- purple_theme_init, /* instance_init */
+ NULL, /* instance_init */
NULL, /* value table */
};
type = g_type_register_static (G_TYPE_OBJECT,
diff --git a/libpurple/theme.h b/libpurple/theme.h
index e6ffa130e5..9f4b0bc8f1 100644
--- a/libpurple/theme.h
+++ b/libpurple/theme.h
@@ -49,7 +49,6 @@ typedef struct _PurpleThemeClass PurpleThemeClass;
struct _PurpleTheme
{
GObject parent;
- gpointer priv;
};
struct _PurpleThemeClass
diff --git a/libpurple/upnp.c b/libpurple/upnp.c
index a0ad9af7fb..61b5ef3b84 100644
--- a/libpurple/upnp.c
+++ b/libpurple/upnp.c
@@ -464,7 +464,7 @@ purple_upnp_parse_description(const gchar* descriptionURL, UPnPDiscoveryData *dd
purple_timeout_remove(dd->tima);
dd->tima = 0;
- purple_util_fetch_url_request_len(descriptionURL, TRUE, NULL, TRUE, httpRequest,
+ purple_util_fetch_url_request(NULL, descriptionURL, TRUE, NULL, TRUE, httpRequest,
TRUE, MAX_UPNP_DOWNLOAD, upnp_parse_description_cb, dd);
g_free(httpRequest);
@@ -730,7 +730,7 @@ purple_upnp_generate_action_message_and_send(const gchar* actionName,
g_free(pathOfControl);
g_free(soapMessage);
- gfud = purple_util_fetch_url_request_len(control_info.control_url, FALSE, NULL, TRUE,
+ gfud = purple_util_fetch_url_request(NULL, control_info.control_url, FALSE, NULL, TRUE,
totalSendMessage, TRUE, MAX_UPNP_DOWNLOAD, cb, cb_data);
g_free(totalSendMessage);
@@ -744,7 +744,7 @@ purple_upnp_get_public_ip()
{
if (control_info.status == PURPLE_UPNP_STATUS_DISCOVERED
&& control_info.publicip
- && strlen(control_info.publicip) > 0)
+ && *control_info.publicip)
return control_info.publicip;
/* Trigger another UPnP discovery if 5 minutes have elapsed since the
@@ -803,7 +803,7 @@ purple_upnp_get_internal_ip(void)
{
if (control_info.status == PURPLE_UPNP_STATUS_DISCOVERED
&& control_info.internalip
- && strlen(control_info.internalip) > 0)
+ && *control_info.internalip)
return control_info.internalip;
/* Trigger another UPnP discovery if 5 minutes have elapsed since the
diff --git a/libpurple/upnp.h b/libpurple/upnp.h
index b0e4ab4e47..d47c583527 100644
--- a/libpurple/upnp.h
+++ b/libpurple/upnp.h
@@ -29,9 +29,7 @@
typedef struct _UPnPMappingAddRemove UPnPMappingAddRemove;
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************/
/** @name UPnP API */
@@ -125,8 +123,6 @@ UPnPMappingAddRemove *purple_upnp_remove_port_mapping(unsigned short portmap,
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_UPNP_H_ */
diff --git a/libpurple/util.c b/libpurple/util.c
index f7d039add5..4f17031506 100644
--- a/libpurple/util.c
+++ b/libpurple/util.c
@@ -73,6 +73,14 @@ struct _PurpleUtilFetchUrlData
PurpleAccount *account;
};
+struct _PurpleMenuAction
+{
+ char *label;
+ PurpleCallback callback;
+ gpointer data;
+ GList *children;
+};
+
static char *custom_user_dir = NULL;
static char *user_dir = NULL;
@@ -98,6 +106,62 @@ purple_menu_action_free(PurpleMenuAction *act)
g_free(act);
}
+char * purple_menu_action_get_label(const PurpleMenuAction *act)
+{
+ g_return_val_if_fail(act != NULL, NULL);
+
+ return act->label;
+}
+
+PurpleCallback purple_menu_action_get_callback(const PurpleMenuAction *act)
+{
+ g_return_val_if_fail(act != NULL, NULL);
+
+ return act->callback;
+}
+
+gpointer purple_menu_action_get_data(const PurpleMenuAction *act)
+{
+ g_return_val_if_fail(act != NULL, NULL);
+
+ return act->data;
+}
+
+GList* purple_menu_action_get_children(const PurpleMenuAction *act)
+{
+ g_return_val_if_fail(act != NULL, NULL);
+
+ return act->children;
+}
+
+void purple_menu_action_set_label(PurpleMenuAction *act, char *label)
+{
+ g_return_if_fail(act != NULL);
+
+ act-> label = label;
+}
+
+void purple_menu_action_set_callback(PurpleMenuAction *act, PurpleCallback callback)
+{
+ g_return_if_fail(act != NULL);
+
+ act->callback = callback;
+}
+
+void purple_menu_action_set_data(PurpleMenuAction *act, gpointer data)
+{
+ g_return_if_fail(act != NULL);
+
+ act->data = data;
+}
+
+void purple_menu_action_set_children(PurpleMenuAction *act, GList *children)
+{
+ g_return_if_fail(act != NULL);
+
+ act->children = children;
+}
+
void
purple_util_init(void)
{
@@ -147,7 +211,7 @@ purple_base16_decode(const char *str, gsize *ret_len)
len = strlen(str);
- g_return_val_if_fail(strlen(str) > 0, 0);
+ g_return_val_if_fail(*str, 0);
g_return_val_if_fail(len % 2 == 0, 0);
data = g_malloc(len / 2);
@@ -612,7 +676,7 @@ purple_utf8_strftime(const char *format, const struct tm *tm)
}
else
{
- purple_strlcpy(buf, utf8);
+ g_strlcpy(buf, utf8, sizeof(buf));
g_free(utf8);
}
@@ -865,6 +929,365 @@ purple_str_to_time(const char *timestamp, gboolean utc,
return retval;
}
+char *
+purple_uts35_to_str(const char *format, size_t len, struct tm *tm)
+{
+ GString *string;
+ int i, count;
+
+ if (tm == NULL) {
+ time_t now = time(NULL);
+ tm = localtime(&now);
+ }
+
+ string = g_string_sized_new(len);
+ i = 0;
+ while (i < len) {
+ count = 1;
+ while ((i + count) < len && format[i] == format[i+count])
+ count++;
+
+ switch (format[i]) {
+ /* Era Designator */
+ case 'G':
+ if (count <= 3) {
+ /* Abbreviated */
+ } else if (count == 4) {
+ /* Full */
+ } else if (count >= 5) {
+ /* Narrow */
+ count = 5;
+ }
+ break;
+
+
+ /* Year */
+ case 'y':
+ if (count == 2) {
+ /* Two-digits only */
+ g_string_append(string, purple_utf8_strftime("%y", tm));
+ } else {
+ /* Zero-padding */
+ char *tmp = g_strdup_printf("%%0%dY", count);
+ g_string_append(string, purple_utf8_strftime(tmp, tm));
+ g_free(tmp);
+ }
+ break;
+
+ /* Year (in "Week of Year" based calendars) */
+ case 'Y':
+ if (count == 2) {
+ /* Two-digits only */
+ } else {
+ /* Zero-padding */
+ }
+ break;
+
+ /* Extended Year */
+ case 'u':
+ break;
+
+ /* Cyclic Year Name */
+ case 'U':
+ if (count <= 3) {
+ /* Abbreviated */
+ } else if (count == 4) {
+ /* Full */
+ } else if (count >= 5) {
+ /* Narrow */
+ count = 5;
+ }
+ break;
+
+
+ /* Quarter */
+ case 'Q':
+ if (count <= 2) {
+ /* Numerical */
+ } else if (count == 3) {
+ /* Abbreviation */
+ } else if (count >= 4) {
+ /* Full */
+ count = 4;
+ }
+ break;
+
+ /* Stand-alone Quarter */
+ case 'q':
+ if (count <= 2) {
+ /* Numerical */
+ } else if (count == 3) {
+ /* Abbreviation */
+ } else if (count >= 4) {
+ /* Full */
+ count = 4;
+ }
+ break;
+
+ /* Month */
+ case 'M':
+ if (count <= 2) {
+ /* Numerical */
+ g_string_append(string, purple_utf8_strftime("%m", tm));
+ } else if (count == 3) {
+ /* Abbreviation */
+ g_string_append(string, purple_utf8_strftime("%b", tm));
+ } else if (count == 4) {
+ /* Full */
+ g_string_append(string, purple_utf8_strftime("%B", tm));
+ } else if (count >= 5) {
+ g_string_append_len(string, purple_utf8_strftime("%b", tm), 1);
+ count = 5;
+ }
+ break;
+
+ /* Stand-alone Month */
+ case 'L':
+ if (count <= 2) {
+ /* Numerical */
+ g_string_append(string, purple_utf8_strftime("%m", tm));
+ } else if (count == 3) {
+ /* Abbreviation */
+ g_string_append(string, purple_utf8_strftime("%b", tm));
+ } else if (count == 4) {
+ /* Full */
+ g_string_append(string, purple_utf8_strftime("%B", tm));
+ } else if (count >= 5) {
+ g_string_append_len(string, purple_utf8_strftime("%b", tm), 1);
+ count = 5;
+ }
+ break;
+
+ /* Ignored */
+ case 'l':
+ break;
+
+
+ /* Week of Year */
+ case 'w':
+ g_string_append(string, purple_utf8_strftime("%W", tm));
+ count = MIN(count, 2);
+ break;
+
+ /* Week of Month */
+ case 'W':
+ count = 1;
+ break;
+
+
+ /* Day of Month */
+ case 'd':
+ g_string_append(string, purple_utf8_strftime("%d", tm));
+ count = MIN(count, 2);
+ break;
+
+ /* Day of Year */
+ case 'D':
+ g_string_append(string, purple_utf8_strftime("%j", tm));
+ count = MIN(count, 3);
+ break;
+
+ /* Day of Year in Month */
+ case 'F':
+ count = 1;
+ break;
+
+ /* Modified Julian Day */
+ case 'g':
+ break;
+
+
+ /* Day of Week */
+ case 'E':
+ if (count <= 3) {
+ /* Short */
+ g_string_append(string, purple_utf8_strftime("%a", tm));
+ } else if (count == 4) {
+ /* Full */
+ g_string_append(string, purple_utf8_strftime("%A", tm));
+ } else if (count >= 5) {
+ /* Narrow */
+ g_string_append_len(string, purple_utf8_strftime("%a", tm), 1);
+ count = 5;
+ }
+ break;
+
+ /* Local Day of Week */
+ case 'e':
+ if (count <= 2) {
+ /* Numeric */
+ g_string_append(string, purple_utf8_strftime("%u", tm));
+ } else if (count == 3) {
+ /* Short */
+ g_string_append(string, purple_utf8_strftime("%a", tm));
+ } else if (count == 4) {
+ /* Full */
+ g_string_append(string, purple_utf8_strftime("%A", tm));
+ } else if (count >= 5) {
+ /* Narrow */
+ g_string_append_len(string, purple_utf8_strftime("%a", tm), 1);
+ count = 5;
+ }
+ break;
+
+ /* Stand-alone Local Day of Week */
+ case 'c':
+ if (count <= 2) {
+ /* Numeric */
+ g_string_append(string, purple_utf8_strftime("%u", tm));
+ count = 1;
+ } else if (count == 3) {
+ /* Short */
+ g_string_append(string, purple_utf8_strftime("%a", tm));
+ } else if (count == 4) {
+ /* Full */
+ g_string_append(string, purple_utf8_strftime("%A", tm));
+ } else if (count >= 5) {
+ /* Narrow */
+ g_string_append_len(string, purple_utf8_strftime("%a", tm), 1);
+ count = 5;
+ }
+ break;
+
+
+ /* AM/PM */
+ case 'a':
+ g_string_append(string, purple_utf8_strftime("%p", tm));
+ break;
+
+
+ /* Hour (1-12) */
+ case 'h':
+ if (count == 1) {
+ /* No padding */
+ g_string_append(string, purple_utf8_strftime("%I", tm));
+ } else if (count >= 2) {
+ /* Zero-padded */
+ g_string_append(string, purple_utf8_strftime("%I", tm));
+ count = 2;
+ }
+ break;
+
+ /* Hour (0-23) */
+ case 'H':
+ if (count == 1) {
+ /* No padding */
+ g_string_append(string, purple_utf8_strftime("%H", tm));
+ } else if (count >= 2) {
+ /* Zero-padded */
+ g_string_append(string, purple_utf8_strftime("%H", tm));
+ count = 2;
+ }
+ break;
+
+ /* Hour (0-11) */
+ case 'K':
+ if (count == 1) {
+ /* No padding */
+ } else if (count >= 2) {
+ /* Zero-padded */
+ count = 2;
+ }
+ break;
+
+ /* Hour (1-24) */
+ case 'k':
+ if (count == 1) {
+ /* No padding */
+ } else if (count >= 2) {
+ /* Zero-padded */
+ count = 2;
+ }
+ break;
+
+ /* Hour (hHkK by locale) */
+ case 'j':
+ break;
+
+
+ /* Minute */
+ case 'm':
+ g_string_append(string, purple_utf8_strftime("%M", tm));
+ count = MIN(count, 2);
+ break;
+
+
+ /* Second */
+ case 's':
+ g_string_append(string, purple_utf8_strftime("%S", tm));
+ count = MIN(count, 2);
+ break;
+
+ /* Fractional Sub-second */
+ case 'S':
+ break;
+
+ /* Millisecond */
+ case 'A':
+ break;
+
+
+ /* Time Zone (specific non-location format) */
+ case 'z':
+ if (count <= 3) {
+ /* Short */
+ } else if (count >= 4) {
+ /* Full */
+ count = 4;
+ }
+ break;
+
+ /* Time Zone */
+ case 'Z':
+ if (count <= 3) {
+ /* RFC822 */
+ g_string_append(string, purple_utf8_strftime("%z", tm));
+ } else if (count == 4) {
+ /* Localized GMT */
+ } else if (count >= 5) {
+ /* ISO8601 */
+ g_string_append(string, purple_utf8_strftime("%z", tm));
+ count = 5;
+ }
+ break;
+
+ /* Time Zone (generic non-location format) */
+ case 'v':
+ if (count <= 3) {
+ /* Short */
+ g_string_append(string, purple_utf8_strftime("%Z", tm));
+ count = 1;
+ } else if (count >= 4) {
+ /* Long */
+ g_string_append(string, purple_utf8_strftime("%Z", tm));
+ count = 4;
+ }
+ break;
+
+ /* Time Zone */
+ case 'V':
+ if (count <= 3) {
+ /* Same as z */
+ count = 1;
+ } else if (count >= 4) {
+ /* Generic Location Format) */
+ g_string_append(string, purple_utf8_strftime("%Z", tm));
+ count = 4;
+ }
+ break;
+
+
+ default:
+ g_string_append_len(string, format + i, count);
+ break;
+ }
+
+ i += count;
+ }
+
+ return g_string_free(string, FALSE);
+}
+
/**************************************************************************
* Markup Functions
**************************************************************************/
@@ -1321,7 +1744,7 @@ purple_markup_extract_info_field(const char *str, int len, PurpleNotifyUserInfo
g_string_append_len(dest, p, q - p);
}
- purple_notify_user_info_add_pair(user_info, display_name, dest->str);
+ purple_notify_user_info_add_pair_html(user_info, display_name, dest->str);
g_string_free(dest, TRUE);
return TRUE;
@@ -2267,7 +2690,7 @@ purple_markup_linkify(const char *text)
url_buf = g_string_free(gurl_buf, FALSE);
/* strip off trailing periods */
- if (strlen(url_buf) > 0) {
+ if (*url_buf) {
for (d = url_buf + strlen(url_buf) - 1; *d == '.'; d--, t--)
*d = '\0';
}
@@ -3064,6 +3487,28 @@ purple_normalize_nocase(const PurpleAccount *account, const char *str)
return buf;
}
+gboolean
+purple_validate(const PurplePlugin *prpl, const char *str)
+{
+ PurplePluginProtocolInfo *prpl_info;
+ const char *normalized;
+
+ g_return_val_if_fail(prpl != NULL, FALSE);
+ g_return_val_if_fail(str != NULL, FALSE);
+
+ if (str[0] == '\0')
+ return FALSE;
+
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
+
+ if (!prpl_info->normalize)
+ return TRUE;
+
+ normalized = prpl_info->normalize(NULL, str);
+
+ return (NULL != normalized);
+}
+
gchar *
purple_strdup_withhtml(const gchar *src)
{
@@ -3267,9 +3712,9 @@ purple_strcasestr(const char *haystack, const char *needle)
}
char *
-purple_str_size_to_units(size_t size)
+purple_str_size_to_units(goffset size)
{
- static const char * const size_str[] = { "bytes", "KiB", "MiB", "GiB" };
+ static const char * const size_str[] = { "bytes", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB" };
float size_mag;
int size_index = 0;
@@ -3282,7 +3727,7 @@ purple_str_size_to_units(size_t size)
else {
size_mag = (float)size;
- while ((size_index < 3) && (size_mag > 1024)) {
+ while ((size_index < G_N_ELEMENTS(size_str) - 1) && (size_mag > 1024)) {
size_mag /= 1024;
size_index++;
}
@@ -3473,9 +3918,9 @@ purple_url_parse(const char *url, char **ret_host, int *ret_port,
#define ADDR_CTRL "A-Za-z0-9.-"
#define PORT_CTRL "0-9"
-#define PAGE_CTRL "A-Za-z0-9.~_/:*!@&%%?=+^-"
-#define USER_CTRL "A-Za-z0-9.~_/*!&%%?=+^-"
-#define PASSWD_CTRL "A-Za-z0-9.~_/*!&%%?=+^-"
+#define PAGE_CTRL "A-Za-z0-9.,~_/:*!@&%%?=+^-"
+#define USER_CTRL "A-Za-z0-9.,~_/*!&%%?=+^-"
+#define PASSWD_CTRL "A-Za-z0-9.,~_/*!&%%?=+^-"
g_return_val_if_fail(url != NULL, FALSE);
@@ -4103,30 +4548,7 @@ static void ssl_url_fetch_error_cb(PurpleSslConnection *ssl_connection, PurpleSs
}
PurpleUtilFetchUrlData *
-purple_util_fetch_url_request(const char *url, gboolean full,
- const char *user_agent, gboolean http11,
- const char *request, gboolean include_headers,
- PurpleUtilFetchUrlCallback callback, void *user_data)
-{
- return purple_util_fetch_url_request_len_with_account(NULL, url, full,
- user_agent, http11,
- request, include_headers, -1,
- callback, user_data);
-}
-
-PurpleUtilFetchUrlData *
-purple_util_fetch_url_request_len(const char *url, gboolean full,
- const char *user_agent, gboolean http11,
- const char *request, gboolean include_headers, gssize max_len,
- PurpleUtilFetchUrlCallback callback, void *user_data)
-{
- return purple_util_fetch_url_request_len_with_account(NULL, url, full,
- user_agent, http11, request, include_headers, max_len, callback,
- user_data);
-}
-
-PurpleUtilFetchUrlData *
-purple_util_fetch_url_request_len_with_account(PurpleAccount *account,
+purple_util_fetch_url_request(PurpleAccount *account,
const char *url, gboolean full, const char *user_agent, gboolean http11,
const char *request, gboolean include_headers, gssize max_len,
PurpleUtilFetchUrlCallback callback, void *user_data)
@@ -4413,11 +4835,10 @@ purple_ipv6_address_is_valid(const gchar *ip)
return (double_colon && chunks < 8) || (!double_colon && chunks == 8);
}
-/* TODO 3.0.0: Add ipv6 check, too */
gboolean
purple_ip_address_is_valid(const char *ip)
{
- return purple_ipv4_address_is_valid(ip);
+ return (purple_ipv4_address_is_valid(ip) || purple_ipv6_address_is_valid(ip));
}
/* Stolen from gnome_uri_list_extract_uris */
@@ -4597,7 +5018,7 @@ purple_utf8_strip_unprintables(const gchar *str)
* This function is copied from g_strerror() but changed to use
* gai_strerror().
*/
-G_CONST_RETURN gchar *
+const gchar *
purple_gai_strerror(gint errnum)
{
static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
@@ -4943,18 +5364,6 @@ purple_escape_filename(const char *str)
return buf;
}
-const char *_purple_oscar_convert(const char *act, const char *protocol)
-{
- if (act && purple_strequal(protocol, "prpl-oscar")) {
- int i;
- for (i = 0; act[i] != '\0'; i++)
- if (!isdigit(act[i]))
- return "prpl-aim";
- return "prpl-icq";
- }
- return protocol;
-}
-
void purple_restore_default_signal_handlers(void)
{
#ifndef _WIN32
diff --git a/libpurple/util.h b/libpurple/util.h
index 282c4bbfcd..f5a73c45f1 100644
--- a/libpurple/util.h
+++ b/libpurple/util.h
@@ -36,37 +36,31 @@
* the request.
*/
typedef struct _PurpleUtilFetchUrlData PurpleUtilFetchUrlData;
-/** @copydoc _PurpleMenuAction */
+
+/**
+ * A generic structure that contains information about an "action." One
+ * place this is is used is by PRPLs to tell the core the list of available
+ * right-click actions for a buddy list row.
+ */
typedef struct _PurpleMenuAction PurpleMenuAction;
-/** @copydoc _PurpleKeyValuePair */
+
+/**
+ * A key-value pair.
+ *
+ * This is used by, among other things, purple_gtk_combo* functions to pass in a
+ * list of key-value pairs so it can display a user-friendly value.
+ */
typedef struct _PurpleKeyValuePair PurpleKeyValuePair;
#include "account.h"
#include "signals.h"
#include "xmlnode.h"
#include "notify.h"
+#include "plugin.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct _PurpleMenuAction
-{
- char *label;
- PurpleCallback callback;
- gpointer data;
- GList *children;
-};
-
typedef char *(*PurpleInfoFieldFormatCallback)(const char *field, size_t len);
-/**
- * A key-value pair.
- *
- * This is used by, among other things, purple_gtk_combo* functions to pass in a
- * list of key-value pairs so it can display a user-friendly value.
- */
struct _PurpleKeyValuePair
{
gchar *key;
@@ -74,6 +68,8 @@ struct _PurpleKeyValuePair
};
+G_BEGIN_DECLS
+
/**
* Creates a new PurpleMenuAction.
*
@@ -96,12 +92,79 @@ PurpleMenuAction *purple_menu_action_new(const char *label, PurpleCallback callb
void purple_menu_action_free(PurpleMenuAction *act);
/**
+ * Returns the label of the PurpleMenuAction.
+ *
+ * @param act The PurpleMenuAction.
+ *
+ * @return The label string.
+ */
+char * purple_menu_action_get_label(const PurpleMenuAction *act);
+
+/**
+ * Returns the callback of the PurpleMenuAction.
+ *
+ * @param act The PurpleMenuAction.
+ *
+ * @return The callback function.
+ */
+PurpleCallback purple_menu_action_get_callback(const PurpleMenuAction *act);
+
+/**
+ * Returns the data stored in the PurpleMenuAction.
+ *
+ * @param act The PurpleMenuAction.
+ *
+ * @return The data.
+ */
+gpointer purple_menu_action_get_data(const PurpleMenuAction *act);
+
+/**
+ * Returns the children of the PurpleMenuAction.
+ *
+ * @param act The PurpleMenuAction.
+ *
+ * @return The GList of children.
+ */
+GList* purple_menu_action_get_children(const PurpleMenuAction *act);
+
+/**
+ * Set the label to the PurpleMenuAction.
+ *
+ * @param act The menu action.
+ * @param label The label for the menu action.
+ */
+void purple_menu_action_set_label(PurpleMenuAction *act, char *label);
+
+/**
+ * Set the callback that will be used by the PurpleMenuAction.
+ *
+ * @param act The menu action.
+ * @param callback The callback.
+ */
+void purple_menu_action_set_callback(PurpleMenuAction *act, PurpleCallback callback);
+
+/**
+ * Set the label to the PurpleMenuAction.
+ *
+ * @param act The menu action.
+ * @param data The data used by this PurpleMenuAction
+ */
+void purple_menu_action_set_data(PurpleMenuAction *act, gpointer data);
+
+/**
+ * Set the children of the PurpleMenuAction.
+ *
+ * @param act The menu action.
+ * @param children The PurpleMenuAtion children
+ */
+void purple_menu_action_set_children(PurpleMenuAction *act, GList *children);
+
+/**
* Set the appropriate presence values for the currently playing song.
*
* @param title The title of the song, @c NULL to unset the value.
* @param artist The artist of the song, can be @c NULL.
* @param album The album of the song, can be @c NULL.
- * @since 2.4.0
*/
void purple_util_set_current_song(const char *title, const char *artist,
const char *album);
@@ -115,7 +178,6 @@ void purple_util_set_current_song(const char *title, const char *artist,
* @param unused Currently unused, must be @c NULL.
*
* @return The formatted string. The caller must g_free the returned string.
- * @since 2.4.0
*/
char * purple_util_format_song_info(const char *title, const char *artist,
const char *album, gpointer unused);
@@ -127,15 +189,11 @@ char * purple_util_format_song_info(const char *title, const char *artist,
/**
* Initializes the utility subsystem.
- *
- * @since 2.3.0
*/
void purple_util_init(void);
/**
* Uninitializes the util subsystem.
- *
- * @since 2.3.0
*/
void purple_util_uninit(void);
@@ -413,6 +471,19 @@ time_t purple_time_build(int year, int month, int day, int hour,
time_t purple_str_to_time(const char *timestamp, gboolean utc,
struct tm *tm, long *tz_off, const char **rest);
+/**
+ * Formats a datetime according to a UTS-35 Date Format Pattern.
+ *
+ * @param format The formatting string, according to UTS #35
+ * See http://unicode.org/reports/tr35/
+ * (NOTE: not all formats are supported)
+ * @param len The length of the formatting string
+ * @param tm The time to format, or @c NULL to use the current local time
+ *
+ * @return The time, formatted as per the user's settings.
+ */
+char *purple_uts35_to_str(const char *format, size_t len, struct tm *tm);
+
/*@}*/
@@ -429,8 +500,6 @@ time_t purple_str_to_time(const char *timestamp, gboolean utc,
* This is exactly the same as g_markup_escape_text(), except that it
* does not change ' to &apos; because &apos; is not a valid HTML 4 entity,
* and is displayed literally in IE7.
- *
- * @since 2.6.0
*/
gchar *purple_markup_escape_text(const gchar *text, gssize length);
@@ -531,7 +600,6 @@ char *purple_markup_linkify(const char *str);
* this string when finished with it.
*
* @see purple_unescape_html()
- * @since 2.7.0
*/
char *purple_unescape_text(const char *text);
@@ -624,8 +692,6 @@ char * purple_markup_get_css_property(const gchar *style, const gchar *opt);
* @param html The HTML text.
*
* @return TRUE if the text contains RTL text, FALSE otherwise.
- *
- * @since 2.6.0
*/
gboolean purple_markup_is_rtl(const char *html);
@@ -826,7 +892,6 @@ char *purple_fd_get_ip(int fd);
*
* @return The address family of the socket (AF_INET, AF_INET6, etc) or -1
* on error.
- * @since 2.7.0
*/
int purple_socket_get_family(int fd);
@@ -838,7 +903,6 @@ int purple_socket_get_family(int fd);
*
* @param fd The socket file descriptor
* @return TRUE if a socket can speak IPv4.
- * @since 2.7.0
*/
gboolean purple_socket_speaks_ipv4(int fd);
@@ -860,8 +924,6 @@ gboolean purple_socket_speaks_ipv4(int fd);
* @param right A string to compare with left
*
* @return @c TRUE if the strings are the same, else @c FALSE.
- *
- * @since 2.6.0
*/
gboolean purple_strequal(const gchar *left, const gchar *right);
@@ -899,6 +961,16 @@ const char *purple_normalize(const PurpleAccount *account, const char *str);
const char *purple_normalize_nocase(const PurpleAccount *account, const char *str);
/**
+ * Checks, if a string is valid.
+ *
+ * @param prpl The protocol plugin the string belongs to.
+ * @param str The string to validate.
+ *
+ * @return TRUE, if string is valid, otherwise FALSE.
+ */
+gboolean purple_validate(const PurplePlugin *prpl, const char *str);
+
+/**
* Compares two strings to see if the first contains the second as
* a proper prefix.
*
@@ -1041,7 +1113,7 @@ const char *purple_strcasestr(const char *haystack, const char *needle);
*
* @return The string in units form. This must be freed.
*/
-char *purple_str_size_to_units(size_t size);
+char *purple_str_size_to_units(goffset size);
/**
* Converts seconds into a human-readable form.
@@ -1117,75 +1189,17 @@ typedef void (*PurpleUtilFetchUrlCallback)(PurpleUtilFetchUrlData *url_data, gpo
* partial URL.
* @param user_agent The user agent field to use, or NULL.
* @param http11 TRUE if HTTP/1.1 should be used to download the file.
- * @param cb The callback function.
- * @param data The user data to pass to the callback function.
- */
-#define purple_util_fetch_url(url, full, user_agent, http11, cb, data) \
- purple_util_fetch_url_request(url, full, user_agent, http11, NULL, \
- FALSE, cb, data);
-
-/**
- * Fetches the data from a URL, and passes it to a callback function.
- *
- * @param url The URL.
- * @param full TRUE if this is the full URL, or FALSE if it's a
- * partial URL.
- * @param user_agent The user agent field to use, or NULL.
- * @param http11 TRUE if HTTP/1.1 should be used to download the file.
* @param max_len The maximum number of bytes to retrieve (-1 for unlimited)
* @param cb The callback function.
* @param data The user data to pass to the callback function.
- * @deprecated In 3.0.0, we'll rename this to "purple_util_fetch_url" and get rid of the old one
*/
-#define purple_util_fetch_url_len(url, full, user_agent, http11, max_len, cb, data) \
- purple_util_fetch_url_request_len(url, full, user_agent, http11, NULL, \
+#define purple_util_fetch_url(url, full, user_agent, http11, max_len, cb, data) \
+ purple_util_fetch_url_request(NULL, url, full, user_agent, http11, NULL, \
FALSE, max_len, cb, data);
/**
* Fetches the data from a URL, and passes it to a callback function.
*
- * @param url The URL.
- * @param full TRUE if this is the full URL, or FALSE if it's a
- * partial URL.
- * @param user_agent The user agent field to use, or NULL.
- * @param http11 TRUE if HTTP/1.1 should be used to download the file.
- * @param request A HTTP request to send to the server instead of the
- * standard GET
- * @param include_headers
- * If TRUE, include the HTTP headers in the response.
- * @param callback The callback function.
- * @param data The user data to pass to the callback function.
- */
-PurpleUtilFetchUrlData *purple_util_fetch_url_request(const gchar *url,
- gboolean full, const gchar *user_agent, gboolean http11,
- const gchar *request, gboolean include_headers,
- PurpleUtilFetchUrlCallback callback, gpointer data);
-
-/**
- * Fetches the data from a URL, and passes it to a callback function.
- *
- * @param url The URL.
- * @param full TRUE if this is the full URL, or FALSE if it's a
- * partial URL.
- * @param user_agent The user agent field to use, or NULL.
- * @param http11 TRUE if HTTP/1.1 should be used to download the file.
- * @param request A HTTP request to send to the server instead of the
- * standard GET
- * @param include_headers
- * If TRUE, include the HTTP headers in the response.
- * @param max_len The maximum number of bytes to retrieve (-1 for unlimited)
- * @param callback The callback function.
- * @param data The user data to pass to the callback function.
- * @deprecated In 3.0.0, this will go away.
- */
-PurpleUtilFetchUrlData *purple_util_fetch_url_request_len(const gchar *url,
- gboolean full, const gchar *user_agent, gboolean http11,
- const gchar *request, gboolean include_headers, gssize max_len,
- PurpleUtilFetchUrlCallback callback, gpointer data);
-
-/**
- * Fetches the data from a URL, and passes it to a callback function.
- *
* @param account The account for which the request is needed, or NULL.
* @param url The URL.
* @param full TRUE if this is the full URL, or FALSE if it's a
@@ -1199,9 +1213,8 @@ PurpleUtilFetchUrlData *purple_util_fetch_url_request_len(const gchar *url,
* @param max_len The maximum number of bytes to retrieve (-1 for unlimited)
* @param callback The callback function.
* @param data The user data to pass to the callback function.
- * @deprecated In 3.0.0, we'll rename this to "purple_util_fetch_url_request" and get rid of the old one
*/
-PurpleUtilFetchUrlData *purple_util_fetch_url_request_len_with_account(
+PurpleUtilFetchUrlData *purple_util_fetch_url_request(
PurpleAccount *account, const gchar *url,
gboolean full, const gchar *user_agent, gboolean http11,
const gchar *request, gboolean include_headers, gssize max_len,
@@ -1247,14 +1260,15 @@ const char *purple_url_encode(const char *str);
gboolean purple_email_is_valid(const char *address);
/**
- * Checks if the given IP address is a syntactically valid IPv4 address.
+ * Checks if the given IP address is a syntactically valid IPv4 or
+ * IPv6 address.
+ * If you specifically want to check for an IPv4 address use
+ * purple_ipv4_address_is_valid(), or for an IPv6 address use
+ * purple_ipv6_address_is_valid().
*
* @param ip The IP address to validate.
*
* @return True if the IP address is syntactically correct.
- * @deprecated This function will be replaced with one that validates
- * as either IPv4 or IPv6 in 3.0.0. If you don't want this,
- * behavior, use one of the more specific functions.
*/
gboolean purple_ip_address_is_valid(const char *ip);
@@ -1264,7 +1278,6 @@ gboolean purple_ip_address_is_valid(const char *ip);
* @param ip The IP address to validate.
*
* @return True if the IP address is syntactically correct.
- * @since 2.6.0
*/
gboolean purple_ipv4_address_is_valid(const char *ip);
@@ -1274,7 +1287,6 @@ gboolean purple_ipv4_address_is_valid(const char *ip);
* @param ip The IP address to validate.
*
* @return True if the IP address is syntactically correct.
- * @since 2.6.0
*/
gboolean purple_ipv6_address_is_valid(const char *ip);
@@ -1342,7 +1354,6 @@ gchar *purple_utf8_salvage(const char *str);
* @param str A valid UTF-8 string.
*
* @return A newly allocated UTF-8 string without the unprintable characters.
- * @since 2.6.0
*/
gchar *purple_utf8_strip_unprintables(const gchar *str);
@@ -1354,9 +1365,8 @@ gchar *purple_utf8_strip_unprintables(const gchar *str);
* @param errnum The error code.
*
* @return The UTF-8 error message.
- * @since 2.4.0
*/
-G_CONST_RETURN gchar *purple_gai_strerror(gint errnum);
+const gchar *purple_gai_strerror(gint errnum);
/**
* Compares two UTF-8 strings case-insensitively. This comparison is
@@ -1450,16 +1460,6 @@ const char *purple_unescape_filename(const char *str);
const char *purple_escape_filename(const char *str);
/**
- * This is added temporarily to assist the split of oscar into aim and icq.
- * This should not be used by plugins.
- *
- * @deprecated This function should not be used in new code and should be
- * removed in 3.0.0. The aim/icq prpl split happened a long
- * time ago, and we don't need to keep migrating old data.
- */
-const char *_purple_oscar_convert(const char *act, const char *protocol);
-
-/**
* Restore default signal handlers for signals which might reasonably have
* handlers. This should be called by a fork()'d child process, since child processes
* inherit the handlers of the parent.
@@ -1478,12 +1478,9 @@ const gchar *purple_get_host_name(void);
* Returns a type 4 (random) UUID
*
* @return A UUID, caller is responsible for freeing it
- * @since 2.7.0
*/
gchar *purple_uuid_random(void);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_UTIL_H_ */
diff --git a/libpurple/value.c b/libpurple/value.c
index c7002c60ed..34ed57baa5 100644
--- a/libpurple/value.c
+++ b/libpurple/value.c
@@ -29,6 +29,44 @@
#define OUTGOING_FLAG 0x01
+/**
+ * A wrapper for a type, subtype, and specific type of value.
+ */
+struct _PurpleValue
+{
+ PurpleType type;
+ unsigned short flags;
+
+ union
+ {
+ char char_data;
+ unsigned char uchar_data;
+ gboolean boolean_data;
+ short short_data;
+ unsigned short ushort_data;
+ int int_data;
+ unsigned int uint_data;
+ long long_data;
+ unsigned long ulong_data;
+ gint64 int64_data;
+ guint64 uint64_data;
+ char *string_data;
+ void *object_data;
+ void *pointer_data;
+ int enum_data;
+ void *boxed_data;
+
+ } data;
+
+ union
+ {
+ unsigned int subtype;
+ char *specific_type;
+
+ } u;
+
+};
+
PurpleValue *
purple_value_new(PurpleType type, ...)
{
diff --git a/libpurple/value.h b/libpurple/value.h
index 155c0146b4..5cd26afbc9 100644
--- a/libpurple/value.h
+++ b/libpurple/value.h
@@ -86,44 +86,9 @@ typedef enum
/**
* A wrapper for a type, subtype, and specific type of value.
*/
-typedef struct
-{
- PurpleType type;
- unsigned short flags;
-
- union
- {
- char char_data;
- unsigned char uchar_data;
- gboolean boolean_data;
- short short_data;
- unsigned short ushort_data;
- int int_data;
- unsigned int uint_data;
- long long_data;
- unsigned long ulong_data;
- gint64 int64_data;
- guint64 uint64_data;
- char *string_data;
- void *object_data;
- void *pointer_data;
- int enum_data;
- void *boxed_data;
-
- } data;
-
- union
- {
- unsigned int subtype;
- char *specific_type;
-
- } u;
-
-} PurpleValue;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+typedef struct _PurpleValue PurpleValue;
+
+G_BEGIN_DECLS
/**
* Creates a new PurpleValue.
@@ -497,8 +462,6 @@ int purple_value_get_enum(const PurpleValue *value);
*/
void *purple_value_get_boxed(const PurpleValue *value);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_VALUE_H_ */
diff --git a/libpurple/version.h.in b/libpurple/version.h.in
index 6e13bb3748..a77ca0f252 100644
--- a/libpurple/version.h.in
+++ b/libpurple/version.h.in
@@ -56,8 +56,6 @@ const char *purple_version_check(guint required_major, guint required_minor, gui
* The major version of the running libpurple. Contrast with
* #PURPLE_MAJOR_VERSION, which expands at compile time to the major version of
* libpurple being compiled against.
- *
- * @since 2.4.0
*/
extern const guint purple_major_version;
@@ -65,8 +63,6 @@ extern const guint purple_major_version;
* The minor version of the running libpurple. Contrast with
* #PURPLE_MINOR_VERSION, which expands at compile time to the minor version of
* libpurple being compiled against.
- *
- * @since 2.4.0
*/
extern const guint purple_minor_version;
@@ -75,8 +71,6 @@ extern const guint purple_minor_version;
* The micro version of the running libpurple. Contrast with
* #PURPLE_MICRO_VERSION, which expands at compile time to the micro version of
* libpurple being compiled against.
- *
- * @since 2.4.0
*/
extern const guint purple_micro_version;
diff --git a/libpurple/whiteboard.c b/libpurple/whiteboard.c
index 3ac4c4e010..3390819e18 100644
--- a/libpurple/whiteboard.c
+++ b/libpurple/whiteboard.c
@@ -25,6 +25,23 @@
#include "whiteboard.h"
#include "prpl.h"
+/**
+ * A PurpleWhiteboard
+ */
+struct _PurpleWhiteboard
+{
+ int state; /**< State of whiteboard session */
+
+ PurpleAccount *account; /**< Account associated with this session */
+ char *who; /**< Name of the remote user */
+
+ void *ui_data; /**< Graphical user-interface data */
+ void *proto_data; /**< Protocol specific data */
+ PurpleWhiteboardPrplOps *prpl_ops; /**< Protocol-plugin operations */
+
+ GList *draw_list; /**< List of drawing elements/deltas to send */
+};
+
/******************************************************************************
* Globals
*****************************************************************************/
@@ -90,6 +107,34 @@ void purple_whiteboard_destroy(PurpleWhiteboard *wb)
g_free(wb);
}
+PurpleAccount *purple_whiteboard_get_account(const PurpleWhiteboard *wb)
+{
+ g_return_val_if_fail(wb != NULL, NULL);
+
+ return wb->account;
+}
+
+const char *purple_whiteboard_get_who(const PurpleWhiteboard *wb)
+{
+ g_return_val_if_fail(wb != NULL, NULL);
+
+ return wb->who;
+}
+
+void purple_whiteboard_set_state(PurpleWhiteboard *wb, int state)
+{
+ g_return_if_fail(wb != NULL);
+
+ wb->state = state;
+}
+
+int purple_whiteboard_get_state(const PurpleWhiteboard *wb)
+{
+ g_return_val_if_fail(wb != NULL, -1);
+
+ return wb->state;
+}
+
void purple_whiteboard_start(PurpleWhiteboard *wb)
{
/* Create frontend for whiteboard */
@@ -206,3 +251,44 @@ void purple_whiteboard_set_brush(PurpleWhiteboard *wb, int size, int color)
whiteboard_ui_ops->set_brush(wb, size, color);
}
+GList *purple_whiteboard_get_draw_list(const PurpleWhiteboard *wb)
+{
+ g_return_val_if_fail(wb != NULL, NULL);
+
+ return wb->draw_list;
+}
+
+void purple_whiteboard_set_draw_list(PurpleWhiteboard *wb, GList* draw_list)
+{
+ g_return_if_fail(wb != NULL);
+
+ wb->draw_list = draw_list;
+}
+
+void purple_whiteboard_set_protocol_data(PurpleWhiteboard *wb, gpointer proto_data)
+{
+ g_return_if_fail(wb != NULL);
+
+ wb->proto_data = proto_data;
+}
+
+gpointer purple_whiteboard_get_protocol_data(const PurpleWhiteboard *wb)
+{
+ g_return_val_if_fail(wb != NULL, NULL);
+
+ return wb->proto_data;
+}
+
+void purple_whiteboard_set_ui_data(PurpleWhiteboard *wb, gpointer ui_data)
+{
+ g_return_if_fail(wb != NULL);
+
+ wb->ui_data = ui_data;
+}
+
+gpointer purple_whiteboard_get_ui_data(const PurpleWhiteboard *wb)
+{
+ g_return_val_if_fail(wb != NULL, NULL);
+
+ return wb->ui_data;
+}
diff --git a/libpurple/whiteboard.h b/libpurple/whiteboard.h
index 7d5700dee9..3fa491095a 100644
--- a/libpurple/whiteboard.h
+++ b/libpurple/whiteboard.h
@@ -26,6 +26,9 @@
#ifndef _PURPLE_WHITEBOARD_H_
#define _PURPLE_WHITEBOARD_H_
+/** @copydoc _PurpleWhiteboard */
+typedef struct _PurpleWhiteboard PurpleWhiteboard;
+
/**
* Whiteboard PRPL Operations
*/
@@ -33,22 +36,6 @@ typedef struct _PurpleWhiteboardPrplOps PurpleWhiteboardPrplOps;
#include "account.h"
-/**
- * A PurpleWhiteboard
- */
-typedef struct _PurpleWhiteboard
-{
- int state; /**< State of whiteboard session */
-
- PurpleAccount *account; /**< Account associated with this session */
- char *who; /**< Name of the remote user */
-
- void *ui_data; /**< Graphical user-interface data */
- void *proto_data; /**< Protocol specific data */
- PurpleWhiteboardPrplOps *prpl_ops; /**< Protocol-plugin operations */
-
- GList *draw_list; /**< List of drawing elements/deltas to send */
-} PurpleWhiteboard;
/**
* The PurpleWhiteboard UI Operations
@@ -92,9 +79,7 @@ struct _PurpleWhiteboardPrplOps
void (*_purple_reserved4)(void);
};
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
+G_BEGIN_DECLS
/******************************************************************************/
/** @name PurpleWhiteboard API */
@@ -135,6 +120,41 @@ PurpleWhiteboard *purple_whiteboard_create(PurpleAccount *account, const char *w
void purple_whiteboard_destroy(PurpleWhiteboard *wb);
/**
+ * Returns the whiteboard's account.
+ *
+ * @param wb The whiteboard.
+ *
+ * @return The whiteboard's account.
+ */
+PurpleAccount *purple_whiteboard_get_account(const PurpleWhiteboard *wb);
+
+/**
+ * Return who you're drawing with.
+ *
+ * @param wb The whiteboard
+ *
+ * @return Who you're drawing with.
+ */
+const char *purple_whiteboard_get_who(const PurpleWhiteboard *wb);
+
+/**
+ * Set the state of the whiteboard.
+ *
+ * @param wb The whiteboard.
+ * @param state The state
+ */
+void purple_whiteboard_set_state(PurpleWhiteboard *wb, int state);
+
+/**
+ * Return the state of the whiteboard.
+ *
+ * @param wb The whiteboard.
+ *
+ * @return The state of the whiteboard.
+ */
+int purple_whiteboard_get_state(const PurpleWhiteboard *wb);
+
+/**
* Starts a whiteboard
*
* @param wb The whiteboard.
@@ -253,10 +273,61 @@ gboolean purple_whiteboard_get_brush(const PurpleWhiteboard *wb, int *size, int
*/
void purple_whiteboard_set_brush(PurpleWhiteboard *wb, int size, int color);
+/**
+ * Return the drawing list.
+ *
+ * @param wb The whiteboard.
+ *
+ * @return The drawing list
+ */
+GList *purple_whiteboard_get_draw_list(const PurpleWhiteboard *wb);
+
+/**
+ * Set the drawing list.
+ *
+ * @param wb The whiteboard
+ * @param draw_list The drawing list.
+ */
+void purple_whiteboard_set_draw_list(PurpleWhiteboard *wb, GList* draw_list);
+
+/**
+ * Sets the protocol data for a whiteboard.
+ *
+ * @param wb The whiteboard.
+ * @param proto_data The protocol data to set for the whiteboard.
+ */
+void purple_whiteboard_set_protocol_data(PurpleWhiteboard *wb, gpointer proto_data);
+
+/**
+ * Gets the protocol data for a whiteboard.
+ *
+ * @param wb The whiteboard.
+ *
+ * @return The protocol data for the whiteboard.
+ */
+gpointer purple_whiteboard_get_protocol_data(const PurpleWhiteboard *wb);
+
+/**
+ * Set the UI data associated with this whiteboard.
+ *
+ * @param wb The whiteboard.
+ * @param ui_data A pointer to associate with this whiteboard.
+ */
+void purple_whiteboard_set_ui_data(PurpleWhiteboard *wb, gpointer ui_data);
+
+/**
+ * Get the UI data associated with this whiteboard.
+ *
+ * @param wb The whiteboard..
+ *
+ * @return The UI data associated with this whiteboard. This is a
+ * convenience field provided to the UIs--it is not
+ * used by the libpurple core.
+ */
+gpointer purple_whiteboard_get_ui_data(const PurpleWhiteboard *wb);
+
/*@}*/
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+G_END_DECLS
#endif /* _PURPLE_WHITEBOARD_H_ */
diff --git a/libpurple/win32/libc_interface.c b/libpurple/win32/libc_interface.c
index 493dfca53f..1e597acc62 100644
--- a/libpurple/win32/libc_interface.c
+++ b/libpurple/win32/libc_interface.c
@@ -511,12 +511,6 @@ int wpurple_gettimeofday(struct timeval *p, struct timezone *z) {
return res;
}
-/* stdio.h */
-
-int wpurple_rename (const char *oldname, const char *newname) {
- return g_rename(oldname, newname);
-}
-
/* time.h */
struct tm * wpurple_localtime_r (const time_t *time, struct tm *resultp) {
@@ -1091,15 +1085,3 @@ wpurple_get_timezone_abbreviation(const struct tm *tm)
purple_debug_warning("wpurple", "could not find a match for Windows timezone \"%s\"\n", tzname);
return "";
}
-
-int wpurple_g_access (const gchar *filename, int mode);
-/**
- * @deprecated - remove for 3.0.0
- */
-int
-wpurple_g_access (const gchar *filename, int mode)
-{
- return g_access(filename, mode);
-}
-
-
diff --git a/libpurple/win32/libc_interface.h b/libpurple/win32/libc_interface.h
index 1aacf56863..19e1284e0f 100644
--- a/libpurple/win32/libc_interface.h
+++ b/libpurple/win32/libc_interface.h
@@ -138,7 +138,7 @@ wpurple_gettimeofday( timeval, timezone )
#define vsnprintf _vsnprintf
#define rename( oldname, newname ) \
-wpurple_rename( oldname, newname )
+g_rename( oldname, newname )
/* sys/stat.h */
#define fchmod(a,b)
diff --git a/libpurple/win32/libc_internal.h b/libpurple/win32/libc_internal.h
index 565af6ea3e..10fa2483e8 100644
--- a/libpurple/win32/libc_internal.h
+++ b/libpurple/win32/libc_internal.h
@@ -142,9 +142,6 @@ int wpurple_close(int fd);
int wpurple_gethostname(char *name, size_t size);
-/* stdio.h */
-int wpurple_rename(const char *oldname, const char *newname);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/libpurple/xmlnode.c b/libpurple/xmlnode.c
index 6fc7d3dac9..e1072056a7 100644
--- a/libpurple/xmlnode.c
+++ b/libpurple/xmlnode.c
@@ -78,6 +78,19 @@ xmlnode_new_child(xmlnode *parent, const char *name)
node = new_node(name, XMLNODE_TYPE_TAG);
xmlnode_insert_child(parent, node);
+#if 0
+ /* This would give xmlnodes more appropriate namespacing
+ * when creating them. Otherwise, unless an explicit namespace
+ * is set, xmlnode_get_namespace() will return NULL, when
+ * there may be a default namespace.
+ *
+ * I'm unconvinced that it's useful, and concerned it may break things.
+ *
+ * _insert_child would need the same thing, probably (assuming
+ * xmlns->node == NULL)
+ */
+ xmlnode_set_namespace(node, xmlnode_get_default_namespace(node))
+#endif
return node;
}
@@ -191,18 +204,6 @@ xmlnode_set_attrib(xmlnode *node, const char *attr, const char *value)
}
void
-xmlnode_set_attrib_with_namespace(xmlnode *node, const char *attr, const char *xmlns, const char *value)
-{
- xmlnode_set_attrib_full(node, attr, xmlns, NULL, value);
-}
-
-void
-xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char *prefix, const char *value)
-{
- xmlnode_set_attrib_full(node, attr, NULL, prefix, value);
-}
-
-void
xmlnode_set_attrib_full(xmlnode *node, const char *attr, const char *xmlns, const char *prefix, const char *value)
{
xmlnode *attrib_node;
@@ -261,19 +262,53 @@ xmlnode_get_attrib_with_namespace(const xmlnode *node, const char *attr, const c
void xmlnode_set_namespace(xmlnode *node, const char *xmlns)
{
+ char *tmp;
g_return_if_fail(node != NULL);
- g_free(node->xmlns);
+ tmp = node->xmlns;
node->xmlns = g_strdup(xmlns);
+
+ if (node->namespace_map) {
+ g_hash_table_insert(node->namespace_map,
+ g_strdup(""), g_strdup(xmlns));
+ }
+
+ g_free(tmp);
}
-const char *xmlnode_get_namespace(xmlnode *node)
+const char *xmlnode_get_namespace(const xmlnode *node)
{
g_return_val_if_fail(node != NULL, NULL);
return node->xmlns;
}
+const char *xmlnode_get_default_namespace(const xmlnode *node)
+{
+ const xmlnode *current_node;
+ const char *ns = NULL;
+
+ g_return_val_if_fail(node != NULL, NULL);
+
+ current_node = node;
+ while (current_node) {
+ /* If this node does *not* have a prefix, node->xmlns is the default
+ * namespace. Otherwise, it's the prefix namespace.
+ */
+ if (!current_node->prefix && current_node->xmlns) {
+ return current_node->xmlns;
+ } else if (current_node->namespace_map) {
+ ns = g_hash_table_lookup(current_node->namespace_map, "");
+ if (ns && *ns)
+ return ns;
+ }
+
+ current_node = current_node->parent;
+ }
+
+ return ns;
+}
+
void xmlnode_set_prefix(xmlnode *node, const char *prefix)
{
g_return_if_fail(node != NULL);
@@ -288,6 +323,53 @@ const char *xmlnode_get_prefix(const xmlnode *node)
return node->prefix;
}
+const char *xmlnode_get_prefix_namespace(const xmlnode *node, const char *prefix)
+{
+ const xmlnode *current_node;
+
+ g_return_val_if_fail(node != NULL, NULL);
+ g_return_val_if_fail(prefix != NULL, xmlnode_get_default_namespace(node));
+
+ current_node = node;
+ while (current_node) {
+ if (current_node->prefix && g_str_equal(prefix, current_node->prefix) &&
+ current_node->xmlns) {
+ return current_node->xmlns;
+ } else if (current_node->namespace_map) {
+ const char *ns = g_hash_table_lookup(current_node->namespace_map, prefix);
+ if (ns && *ns) {
+ return ns;
+ }
+ }
+
+ current_node = current_node->parent;
+ }
+
+ return NULL;
+}
+
+void xmlnode_strip_prefixes(xmlnode *node)
+{
+ xmlnode *child;
+ const char *prefix;
+
+ g_return_if_fail(node != NULL);
+
+ for (child = node->child; child; child = child->next) {
+ if (child->type == XMLNODE_TYPE_TAG)
+ xmlnode_strip_prefixes(child);
+ }
+
+ prefix = xmlnode_get_prefix(node);
+ if (prefix) {
+ const char *ns = xmlnode_get_prefix_namespace(node, prefix);
+ xmlnode_set_namespace(node, ns);
+ xmlnode_set_prefix(node, NULL);
+ } else {
+ xmlnode_set_namespace(node, xmlnode_get_default_namespace(node));
+ }
+}
+
xmlnode *xmlnode_get_parent(const xmlnode *child)
{
g_return_val_if_fail(child != NULL, NULL);
@@ -455,12 +537,22 @@ xmlnode_to_str_helper(const xmlnode *node, int *len, gboolean formatting, int de
if (node->namespace_map) {
g_hash_table_foreach(node->namespace_map,
(GHFunc)xmlnode_to_str_foreach_append_ns, text);
- } else if (node->xmlns) {
- if(!node->parent || !purple_strequal(node->xmlns, node->parent->xmlns))
+ } else {
+ /* Figure out if this node has a different default namespace from parent */
+ const char *xmlns = NULL;
+ const char *parent_xmlns = NULL;
+ if (!prefix)
+ xmlns = node->xmlns;
+
+ if (!xmlns)
+ xmlns = xmlnode_get_default_namespace(node);
+ if (node->parent)
+ parent_xmlns = xmlnode_get_default_namespace(node->parent);
+ if (!purple_strequal(xmlns, parent_xmlns))
{
- char *xmlns = g_markup_escape_text(node->xmlns, -1);
- g_string_append_printf(text, " xmlns='%s'", xmlns);
- g_free(xmlns);
+ char *escaped_xmlns = g_markup_escape_text(xmlns, -1);
+ g_string_append_printf(text, " xmlns='%s'", escaped_xmlns);
+ g_free(escaped_xmlns);
}
}
for(c = node->child; c; c = c->next)
diff --git a/libpurple/xmlnode.h b/libpurple/xmlnode.h
index 95b330cde1..8bbf0b1a7d 100644
--- a/libpurple/xmlnode.h
+++ b/libpurple/xmlnode.h
@@ -28,14 +28,10 @@
#include <glib.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/**
* The valid types for an xmlnode
*/
-typedef enum _XMLNodeType
+typedef enum
{
XMLNODE_TYPE_TAG, /**< Just a tag */
XMLNODE_TYPE_ATTRIB, /**< Has attributes */
@@ -61,6 +57,8 @@ struct _xmlnode
GHashTable *namespace_map; /**< The namespace map. */
};
+G_BEGIN_DECLS
+
/**
* Creates a new xmlnode.
*
@@ -157,42 +155,14 @@ char *xmlnode_get_data_unescaped(const xmlnode *node);
*/
void xmlnode_set_attrib(xmlnode *node, const char *attr, const char *value);
-#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_XMLNODE_C_)
-/**
- * Sets a prefixed attribute for a node
- *
- * @param node The node to set an attribute for.
- * @param attr The name of the attribute to set
- * @param prefix The prefix of the attribute to ste
- * @param value The value of the attribute
- *
- * @deprecated Use xmlnode_set_attrib_full instead.
- */
-void xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char *prefix, const char *value);
-
-/**
- * Sets a namespaced attribute for a node
- *
- * @param node The node to set an attribute for.
- * @param attr The name of the attribute to set
- * @param xmlns The namespace of the attribute to ste
- * @param value The value of the attribute
- *
- * @deprecated Use xmlnode_set_attrib_full instead.
- */
-void xmlnode_set_attrib_with_namespace(xmlnode *node, const char *attr, const char *xmlns, const char *value);
-#endif /* PURPLE_DISABLE_DEPRECATED */
-
/**
* Sets a namespaced attribute for a node
*
* @param node The node to set an attribute for.
* @param attr The name of the attribute to set
- * @param xmlns The namespace of the attribute to ste
- * @param prefix The prefix of the attribute to ste
+ * @param xmlns The namespace of the attribute to set
+ * @param prefix The prefix of the attribute to set
* @param value The value of the attribute
- *
- * @since 2.6.0
*/
void xmlnode_set_attrib_full(xmlnode *node, const char *attr, const char *xmlns,
const char *prefix, const char *value);
@@ -249,7 +219,37 @@ void xmlnode_set_namespace(xmlnode *node, const char *xmlns);
* @param node The node to get the namepsace from
* @return The namespace of this node
*/
-const char *xmlnode_get_namespace(xmlnode *node);
+const char *xmlnode_get_namespace(const xmlnode *node);
+
+/**
+ * Returns the current default namespace. The default
+ * namespace is the current namespace which applies to child
+ * elements which are unprefixed and which do not contain their
+ * own namespace.
+ *
+ * For example, given:
+ * \verbatim
+ * <iq type='get' xmlns='jabber:client' xmlns:ns1='http://example.org/ns1'>
+ * <ns1:element><child1/></ns1:element>
+ * </iq>
+ * \endverbatim
+ *
+ * The default namespace of all nodes (including 'child1') is "jabber:client",
+ * though the namespace for 'element' is "http://example.org/ns1".
+ *
+ * @param node The node for which to return the default namespace
+ * @return The default namespace of this node
+ */
+const char *xmlnode_get_default_namespace(const xmlnode *node);
+
+/**
+ * Returns the defined namespace for a prefix.
+ *
+ * @param node The node from which to start the search.
+ * @param prefix The prefix for which to return the associated namespace.
+ * @return The namespace for this prefix.
+ */
+const char *xmlnode_get_prefix_namespace(const xmlnode *node, const char *prefix);
/**
* Sets the prefix of a node
@@ -268,13 +268,24 @@ void xmlnode_set_prefix(xmlnode *node, const char *prefix);
const char *xmlnode_get_prefix(const xmlnode *node);
/**
+ * Remove all element prefixes from an xmlnode tree. The prefix's
+ * namespace is transformed into the default namespace for an element.
+ *
+ * Note that this will not necessarily remove all prefixes in use
+ * (prefixed attributes may still exist), and that this usage may
+ * break some applications (SOAP / XPath apparently often rely on
+ * the prefixes having the same name.
+ *
+ * @param node The node from which to strip prefixes
+ */
+void xmlnode_strip_prefixes(xmlnode *node);
+
+/**
* Gets the parent node.
*
* @param child The child node.
*
* @return The parent or NULL.
- *
- * @since 2.6.0
*/
xmlnode *xmlnode_get_parent(const xmlnode *child);
@@ -343,14 +354,11 @@ void xmlnode_free(xmlnode *node);
* the category for debugging.
*
* @return The new node or NULL if an error occurred.
- *
- * @since 2.6.0
*/
xmlnode *xmlnode_from_file(const char *dir, const char *filename,
const char *description, const char *process);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PURPLE_XMLNODE_H_ */
+
diff --git a/pidgin/Makefile.am b/pidgin/Makefile.am
index b6a5bd4642..ec1706d967 100644
--- a/pidgin/Makefile.am
+++ b/pidgin/Makefile.am
@@ -3,8 +3,8 @@ EXTRA_DIST = \
getopt.h \
getopt1.c \
Makefile.mingw \
- pidgin.pc.in \
- pidgin-uninstalled.pc.in \
+ pidgin-3.pc.in \
+ pidgin-3-uninstalled.pc.in \
win32/MinimizeToTray.h \
win32/MinimizeToTray.c \
win32/pidgin_dll_rc.rc.in \
@@ -32,9 +32,9 @@ EXTRA_DIST = \
if ENABLE_GTK
pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = pidgin.pc
+pkgconfig_DATA = pidgin-3.pc
-SUBDIRS = pixmaps plugins
+SUBDIRS = pixmaps plugins themes
bin_PROGRAMS = pidgin
@@ -48,11 +48,12 @@ pidgin_SOURCES = \
gtkcertmgr.c \
gtkconn.c \
gtkconv.c \
+ gtkconv-theme.c \
+ gtkconv-theme-loader.c \
gtkdebug.c \
gtkdialogs.c \
gtkdnd-hints.c \
gtkdocklet.c \
- gtkdocklet-gtk.c \
gtkeventloop.c \
gtkft.c \
gtkicon-theme.c \
@@ -84,9 +85,12 @@ pidgin_SOURCES = \
gtkstatusbox.c \
gtkthemes.c \
gtkutils.c \
+ gtkwebview.c \
+ gtkwebviewtoolbar.c \
gtkwhiteboard.c \
minidialog.c \
- pidgintooltip.c
+ pidgintooltip.c \
+ smileyparser.c
pidgin_headers = \
gtkaccount.h \
@@ -98,6 +102,8 @@ pidgin_headers = \
gtkconn.h \
gtkconv.h \
gtkconvwin.h \
+ gtkconv-theme.h \
+ gtkconv-theme-loader.h \
gtkdebug.h \
gtkdialogs.h \
gtkdnd-hints.h \
@@ -107,7 +113,6 @@ pidgin_headers = \
gtkicon-theme.h \
gtkicon-theme-loader.h \
gtkidle.h \
- gtkgaim-compat.h \
gtkimhtml.h \
gtkimhtmltoolbar.h \
gtklog.h \
@@ -135,10 +140,13 @@ pidgin_headers = \
pidginstock.h \
gtkthemes.h \
gtkutils.h \
+ gtkwebview.h \
+ gtkwebviewtoolbar.h \
gtkwhiteboard.h \
minidialog.h \
pidgintooltip.h \
- pidgin.h
+ pidgin.h \
+ smileyparser.h
pidginincludedir=$(includedir)/pidgin
pidgininclude_HEADERS = \
@@ -150,6 +158,7 @@ pidgin_LDFLAGS = -export-dynamic
pidgin_LDADD = \
@LIBOBJS@ \
$(GLIB_LIBS) \
+ $(GCR_LIBS) \
$(DBUS_LIBS) \
$(GSTREAMER_LIBS) \
$(XSS_LIBS) \
@@ -157,6 +166,7 @@ pidgin_LDADD = \
$(INTLLIBS) \
$(GTKSPELL_LIBS) \
$(LIBXML_LIBS) \
+ $(WEBKIT_LIBS) \
$(GTK_LIBS) \
$(top_builddir)/libpurple/libpurple.la
@@ -174,11 +184,14 @@ AM_CPPFLAGS = \
-I$(top_builddir) \
-I$(top_srcdir) \
$(GLIB_CFLAGS) \
+ $(GCR_CFLAGS) \
$(GSTREAMER_CFLAGS) \
$(DEBUG_CFLAGS) \
$(GTK_CFLAGS) \
$(DBUS_CFLAGS) \
$(GTKSPELL_CFLAGS) \
$(LIBXML_CFLAGS) \
+ $(WEBKIT_CFLAGS) \
$(INTGG_CFLAGS)
endif # ENABLE_GTK
+
diff --git a/pidgin/Makefile.mingw b/pidgin/Makefile.mingw
index 145bb7f6d1..fd19ed9a5d 100644
--- a/pidgin/Makefile.mingw
+++ b/pidgin/Makefile.mingw
@@ -58,6 +58,8 @@ PIDGIN_C_SRC = \
gtkcertmgr.c \
gtkconn.c \
gtkconv.c \
+ gtkconv-theme.c \
+ gtkconv-theme-loader.c \
gtkdebug.c \
gtkdialogs.c \
gtkdnd-hints.c \
@@ -91,12 +93,13 @@ PIDGIN_C_SRC = \
gtkstatusbox.c \
gtkthemes.c \
gtkutils.c \
+ gtkwebview.c \
+ gtkwebviewtoolbar.c \
gtkwhiteboard.c \
minidialog.c \
pidginstock.c \
pidgintooltip.c \
- win32/MinimizeToTray.c \
- win32/gtkdocklet-win32.c \
+ smileyparser.c \
win32/gtkwin32dep.c \
win32/untar.c \
win32/wspell.c
diff --git a/pidgin/gtkaccount.c b/pidgin/gtkaccount.c
index 7bb0524961..c63c6b89fd 100644
--- a/pidgin/gtkaccount.c
+++ b/pidgin/gtkaccount.c
@@ -220,7 +220,7 @@ set_dialog_icon(AccountPrefsDialog *dialog, gpointer data, size_t len, gchar *ne
}
static void
-set_account_protocol_cb(GtkWidget *item, const char *id,
+set_account_protocol_cb(GtkWidget *widget, const char *id,
AccountPrefsDialog *dialog)
{
PurplePlugin *new_plugin;
@@ -247,14 +247,17 @@ set_account_protocol_cb(GtkWidget *item, const char *id,
gtk_widget_grab_focus(dialog->protocol_menu);
- if (!dialog->prpl_info || !dialog->prpl_info->register_user ||
- g_object_get_data(G_OBJECT(item), "fake")) {
+ if (!dialog->prpl_info || !dialog->prpl_info->register_user) {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
+ dialog->register_button), FALSE);
gtk_widget_hide(dialog->register_button);
} else {
if (dialog->prpl_info != NULL &&
(dialog->prpl_info->options & OPT_PROTO_REGISTER_NOSCREENNAME)) {
gtk_widget_set_sensitive(dialog->register_button, TRUE);
} else {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
+ dialog->register_button), FALSE);
gtk_widget_set_sensitive(dialog->register_button, FALSE);
}
gtk_widget_show(dialog->register_button);
@@ -267,6 +270,11 @@ username_focus_cb(GtkWidget *widget, GdkEventFocus *event, AccountPrefsDialog *d
GHashTable *table;
const char *label;
+ if (!dialog->prpl_info || ! PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(
+ dialog->prpl_info, get_account_text_table)) {
+ return FALSE;
+ }
+
table = dialog->prpl_info->get_account_text_table(NULL);
label = g_hash_table_lookup(table, "login_label");
@@ -283,15 +291,27 @@ username_focus_cb(GtkWidget *widget, GdkEventFocus *event, AccountPrefsDialog *d
static void
username_changed_cb(GtkEntry *entry, AccountPrefsDialog *dialog)
{
- if (dialog->ok_button)
- gtk_widget_set_sensitive(dialog->ok_button,
- *gtk_entry_get_text(entry) != '\0');
+ gboolean opt_noscreenname = (dialog->prpl_info != NULL &&
+ (dialog->prpl_info->options & OPT_PROTO_REGISTER_NOSCREENNAME));
+ gboolean username_valid = purple_validate(dialog->plugin,
+ gtk_entry_get_text(entry));
+
+ if (dialog->ok_button) {
+ if (opt_noscreenname && dialog->register_button &&
+ gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(dialog->register_button)))
+ gtk_widget_set_sensitive(dialog->ok_button, TRUE);
+ else
+ gtk_widget_set_sensitive(dialog->ok_button,
+ username_valid);
+ }
+
if (dialog->register_button) {
- if (dialog->prpl_info != NULL && (dialog->prpl_info->options & OPT_PROTO_REGISTER_NOSCREENNAME))
+ if (opt_noscreenname)
gtk_widget_set_sensitive(dialog->register_button, TRUE);
else
gtk_widget_set_sensitive(dialog->register_button,
- *gtk_entry_get_text(entry) != '\0');
+ username_valid);
}
}
@@ -324,6 +344,37 @@ username_nofocus_cb(GtkWidget *widget, GdkEventFocus *event, AccountPrefsDialog
}
static void
+register_button_cb(GtkWidget *checkbox, AccountPrefsDialog *dialog)
+{
+ int register_checked = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(dialog->register_button));
+ int opt_noscreenname = (dialog->prpl_info != NULL &&
+ (dialog->prpl_info->options & OPT_PROTO_REGISTER_NOSCREENNAME));
+ int register_noscreenname = (opt_noscreenname && register_checked);
+
+ /* get rid of login_label in username field */
+ username_focus_cb(dialog->username_entry, NULL, dialog);
+
+ if (register_noscreenname) {
+ gtk_entry_set_text(GTK_ENTRY(dialog->username_entry), "");
+ gtk_entry_set_text(GTK_ENTRY(dialog->password_entry), "");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->remember_pass_check), FALSE);
+ }
+ gtk_widget_set_sensitive(dialog->username_entry, !register_noscreenname);
+ gtk_widget_set_sensitive(dialog->password_entry, !register_noscreenname);
+ gtk_widget_set_sensitive(dialog->remember_pass_check, !register_noscreenname);
+
+ if (dialog->ok_button) {
+ gtk_widget_set_sensitive(dialog->ok_button,
+ (opt_noscreenname && register_checked) ||
+ *gtk_entry_get_text(GTK_ENTRY(dialog->username_entry))
+ != '\0');
+ }
+
+ username_nofocus_cb(dialog->username_entry, NULL, dialog);
+}
+
+static void
icon_filesel_choose_cb(const char *filename, gpointer data)
{
AccountPrefsDialog *dialog = data;
@@ -424,8 +475,6 @@ add_login_options(AccountPrefsDialog *dialog, GtkWidget *parent)
GtkWidget *hbox;
GtkWidget *vbox;
GtkWidget *entry;
- GtkWidget *menu;
- GtkWidget *item;
GList *user_splits;
GList *l, *l2;
char *username = NULL;
@@ -563,17 +612,6 @@ add_login_options(AccountPrefsDialog *dialog, GtkWidget *parent)
if (value == NULL)
value = purple_account_user_split_get_default_value(split);
- /* Google Talk default domain hackery! */
- menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(dialog->protocol_menu));
- item = gtk_menu_get_active(GTK_MENU(menu));
- if (value == NULL && g_object_get_data(G_OBJECT(item), "fakegoogle") &&
- !strcmp(purple_account_user_split_get_text(split), _("Domain")))
- value = "gmail.com";
-
- if (value == NULL && g_object_get_data(G_OBJECT(item), "fakefacebook") &&
- !strcmp(purple_account_user_split_get_text(split), _("Domain")))
- value = "chat.facebook.com";
-
if (value != NULL)
gtk_entry_set_text(GTK_ENTRY(entry), value);
}
@@ -769,7 +807,7 @@ add_protocol_options(AccountPrefsDialog *dialog)
{
PurpleAccountOption *option;
PurpleAccount *account;
- GtkWidget *vbox, *check, *entry, *combo, *menu, *item;
+ GtkWidget *vbox, *check, *entry, *combo;
GList *list, *node;
gint i, idx, int_value;
GtkListStore *model;
@@ -808,9 +846,6 @@ add_protocol_options(AccountPrefsDialog *dialog)
gtk_label_new_with_mnemonic(_("Ad_vanced")), 1);
gtk_widget_show(vbox);
- menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(dialog->protocol_menu));
- item = gtk_menu_get_active(GTK_MENU(menu));
-
for (l = dialog->prpl_info->protocol_options; l != NULL; l = l->next)
{
option = (PurpleAccountOption *)l->data;
@@ -925,10 +960,6 @@ add_protocol_options(AccountPrefsDialog *dialog)
model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
opt_entry->widget = combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model));
- if (g_object_get_data(G_OBJECT(item), "fakefacebook") &&
- !strcmp(opt_entry->setting, "connection_security"))
- str_value = "opportunistic_tls";
-
/* Loop through list of PurpleKeyValuePair items */
for (node = list; node != NULL; node = node->next) {
if (node->data != NULL) {
@@ -1213,8 +1244,12 @@ add_voice_options(AccountPrefsDialog *dialog)
gtk_widget_show_all(dialog->voice_frame);
}
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->suppression_check),
- purple_account_get_silence_suppression(dialog->account));
+ if (dialog->account) {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->suppression_check),
+ purple_account_get_silence_suppression(dialog->account));
+ } else {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->suppression_check), FALSE);
+ }
#endif
}
@@ -1254,6 +1289,23 @@ cancel_account_prefs_cb(GtkWidget *w, AccountPrefsDialog *dialog)
}
static void
+account_register_cb(PurpleAccount *account, gboolean succeeded, void *user_data)
+{
+ if (succeeded)
+ {
+ const PurpleSavedStatus *saved_status = purple_savedstatus_get_current();
+ purple_signal_emit(pidgin_account_get_handle(), "account-modified", account);
+
+ if (saved_status != NULL && purple_account_get_remember_password(account)) {
+ purple_savedstatus_activate_for_account(saved_status, account);
+ purple_account_set_enabled(account, PIDGIN_UI, TRUE);
+ }
+ }
+ else
+ purple_accounts_delete(account);
+}
+
+static void
ok_account_prefs_cb(GtkWidget *w, AccountPrefsDialog *dialog)
{
PurpleProxyInfo *proxy_info = NULL;
@@ -1506,6 +1558,7 @@ ok_account_prefs_cb(GtkWidget *w, AccountPrefsDialog *dialog)
/* If this is a new account, then sign on! */
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->register_button))) {
+ purple_account_set_register_callback(account, account_register_cb, NULL);
purple_account_register(account);
} else if (new_acct) {
const PurpleSavedStatus *saved_status;
@@ -1602,6 +1655,7 @@ pidgin_account_dialog_show(PidginAccountDialogType type,
gtk_box_pack_start(GTK_BOX(main_vbox), button, FALSE, FALSE, 0);
gtk_widget_show(button);
dialog->register_button = button;
+ g_signal_connect(G_OBJECT(dialog->register_button), "toggled", G_CALLBACK(register_button_cb), dialog);
if (dialog->account == NULL)
gtk_widget_set_sensitive(button, FALSE);
@@ -2726,4 +2780,3 @@ pidgin_account_uninit(void)
purple_signals_unregister_by_instance(pidgin_account_get_handle());
}
-
diff --git a/pidgin/gtkaccount.h b/pidgin/gtkaccount.h
index e9a5a5319b..8410d8817d 100644
--- a/pidgin/gtkaccount.h
+++ b/pidgin/gtkaccount.h
@@ -37,6 +37,8 @@ typedef enum
} PidginAccountDialogType;
+G_BEGIN_DECLS
+
/**
* Shows the accounts window.
*/
@@ -80,4 +82,6 @@ void pidgin_account_init(void);
*/
void pidgin_account_uninit(void);
+G_END_DECLS
+
#endif /* _PIDGINACCOUNT_H_ */
diff --git a/pidgin/gtkblist-theme-loader.c b/pidgin/gtkblist-theme-loader.c
index b5936f3916..ad395e6229 100644
--- a/pidgin/gtkblist-theme-loader.c
+++ b/pidgin/gtkblist-theme-loader.c
@@ -73,10 +73,10 @@ parse_color(xmlnode *node, const char *tag)
}
static PurpleTheme *
-pidgin_blist_loader_build(const gchar *dir)
+pidgin_blist_loader_build(const gchar *theme_dir)
{
xmlnode *root_node = NULL, *sub_node, *sub_sub_node;
- gchar *filename_full, *data = NULL;
+ gchar *dir, *filename_full, *data = NULL;
const gchar *temp, *name;
gboolean success = TRUE;
GdkColor *bgcolor, *expanded_bgcolor, *collapsed_bgcolor, *contact_color;
@@ -112,15 +112,18 @@ pidgin_blist_loader_build(const gchar *dir)
status = NULL;
/* Find the theme file */
- g_return_val_if_fail(dir != NULL, NULL);
+ g_return_val_if_fail(theme_dir != NULL, NULL);
+ dir = g_build_filename(theme_dir, "purple", "blist", NULL);
filename_full = g_build_filename(dir, "theme.xml", NULL);
if (g_file_test(filename_full, G_FILE_TEST_IS_REGULAR))
root_node = xmlnode_from_file(dir, "theme.xml", "buddy list themes", "blist-loader");
g_free(filename_full);
- if (root_node == NULL)
+ if (root_node == NULL) {
+ g_free(dir);
return NULL;
+ }
sub_node = xmlnode_get_child(root_node, "description");
data = xmlnode_get_data(sub_node);
@@ -227,6 +230,7 @@ pidgin_blist_loader_build(const gchar *dir)
xmlnode_free(root_node);
g_free(data);
+ g_free(dir);
/* malformed xml file - also frees all partial data*/
if (!success) {
diff --git a/pidgin/gtkblist-theme.c b/pidgin/gtkblist-theme.c
index 83585aa0bd..cb034bfb2e 100644
--- a/pidgin/gtkblist-theme.c
+++ b/pidgin/gtkblist-theme.c
@@ -24,7 +24,7 @@
#include "gtkblist-theme.h"
#define PIDGIN_BLIST_THEME_GET_PRIVATE(Gobject) \
- ((PidginBlistThemePrivate *) ((PIDGIN_BLIST_THEME(Gobject))->priv))
+ (G_TYPE_INSTANCE_GET_PRIVATE((Gobject), PIDGIN_TYPE_BLIST_THEME, PidginBlistThemePrivate))
/******************************************************************************
* Structs
@@ -189,13 +189,6 @@ pidgin_theme_font_get_color_describe(PidginThemeFont *font)
*****************************************************************************/
static void
-pidgin_blist_theme_init(GTypeInstance *instance,
- gpointer klass)
-{
- (PIDGIN_BLIST_THEME(instance))->priv = g_new0(PidginBlistThemePrivate, 1);
-}
-
-static void
pidgin_blist_theme_get_property(GObject *obj, guint param_id, GValue *value,
GParamSpec *psec)
{
@@ -349,8 +342,6 @@ pidgin_blist_theme_finalize(GObject *obj)
pidgin_theme_font_free(priv->message_nick_said);
pidgin_theme_font_free(priv->status);
- g_free(priv);
-
parent_class->finalize (obj);
}
@@ -362,6 +353,8 @@ pidgin_blist_theme_class_init(PidginBlistThemeClass *klass)
parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private(klass, sizeof(PidginBlistThemePrivate));
+
obj_class->get_property = pidgin_blist_theme_get_property;
obj_class->set_property = pidgin_blist_theme_set_property;
obj_class->finalize = pidgin_blist_theme_finalize;
@@ -484,7 +477,7 @@ pidgin_blist_theme_get_type (void)
NULL, /* class_data */
sizeof(PidginBlistTheme),
0, /* n_preallocs */
- pidgin_blist_theme_init, /* instance_init */
+ NULL, /* instance_init */
NULL, /* value table */
};
type = g_type_register_static (PURPLE_TYPE_THEME,
@@ -507,7 +500,7 @@ pidgin_blist_theme_get_background_color(PidginBlistTheme *theme)
g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
return priv->bgcolor;
}
@@ -519,7 +512,7 @@ pidgin_blist_theme_get_opacity(PidginBlistTheme *theme)
g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), 1.0);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
return priv->opacity;
}
@@ -531,7 +524,7 @@ pidgin_blist_theme_get_layout(PidginBlistTheme *theme)
g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
return priv->layout;
}
@@ -543,7 +536,7 @@ pidgin_blist_theme_get_expanded_background_color(PidginBlistTheme *theme)
g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
return priv->expanded_color;
}
@@ -555,7 +548,7 @@ pidgin_blist_theme_get_expanded_text_info(PidginBlistTheme *theme)
g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
return priv->expanded;
}
@@ -567,7 +560,7 @@ pidgin_blist_theme_get_collapsed_background_color(PidginBlistTheme *theme)
g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
return priv->collapsed_color;
}
@@ -579,7 +572,7 @@ pidgin_blist_theme_get_collapsed_text_info(PidginBlistTheme *theme)
g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
return priv->collapsed;
}
@@ -591,7 +584,7 @@ pidgin_blist_theme_get_contact_color(PidginBlistTheme *theme)
g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
return priv->contact_color;
}
@@ -603,7 +596,7 @@ pidgin_blist_theme_get_contact_text_info(PidginBlistTheme *theme)
g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
return priv->contact;
}
@@ -615,7 +608,7 @@ pidgin_blist_theme_get_online_text_info(PidginBlistTheme *theme)
g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
return priv->online;
}
@@ -627,7 +620,7 @@ pidgin_blist_theme_get_away_text_info(PidginBlistTheme *theme)
g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
return priv->away;
}
@@ -639,7 +632,7 @@ pidgin_blist_theme_get_offline_text_info(PidginBlistTheme *theme)
g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
return priv->offline;
}
@@ -651,7 +644,7 @@ pidgin_blist_theme_get_idle_text_info(PidginBlistTheme *theme)
g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
return priv->idle;
}
@@ -663,7 +656,7 @@ pidgin_blist_theme_get_unread_message_text_info(PidginBlistTheme *theme)
g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
return priv->message;
}
@@ -675,7 +668,7 @@ pidgin_blist_theme_get_unread_message_nick_said_text_info(PidginBlistTheme *them
g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
return priv->message_nick_said;
}
@@ -687,7 +680,7 @@ pidgin_blist_theme_get_status_text_info(PidginBlistTheme *theme)
g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
return priv->status;
}
@@ -700,7 +693,7 @@ pidgin_blist_theme_set_background_color(PidginBlistTheme *theme, const GdkColor
g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme));
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
if (priv->bgcolor)
gdk_color_free(priv->bgcolor);
@@ -714,7 +707,7 @@ pidgin_blist_theme_set_opacity(PidginBlistTheme *theme, gdouble opacity)
g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme) || opacity < 0.0 || opacity > 1.0);
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
priv->opacity = opacity;
}
@@ -726,7 +719,7 @@ pidgin_blist_theme_set_layout(PidginBlistTheme *theme, const PidginBlistLayout *
g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme));
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
g_free(priv->layout);
priv->layout = g_memdup(layout, sizeof(PidginBlistLayout));
@@ -739,7 +732,7 @@ pidgin_blist_theme_set_expanded_background_color(PidginBlistTheme *theme, const
g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme));
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
if (priv->expanded_color)
gdk_color_free(priv->expanded_color);
@@ -753,7 +746,7 @@ pidgin_blist_theme_set_expanded_text_info(PidginBlistTheme *theme, const PidginT
g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme));
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
pidgin_theme_font_free(priv->expanded);
priv->expanded = copy_font_and_color(pair);
@@ -766,7 +759,7 @@ pidgin_blist_theme_set_collapsed_background_color(PidginBlistTheme *theme, const
g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme));
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
if (priv->collapsed_color)
gdk_color_free(priv->collapsed_color);
@@ -780,7 +773,7 @@ pidgin_blist_theme_set_collapsed_text_info(PidginBlistTheme *theme, const Pidgin
g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme));
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
pidgin_theme_font_free(priv->collapsed);
priv->collapsed = copy_font_and_color(pair);
@@ -793,7 +786,7 @@ pidgin_blist_theme_set_contact_color(PidginBlistTheme *theme, const GdkColor *co
g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme));
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
if (priv->contact_color)
gdk_color_free(priv->contact_color);
@@ -807,7 +800,7 @@ pidgin_blist_theme_set_contact_text_info(PidginBlistTheme *theme, const PidginTh
g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme));
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
pidgin_theme_font_free(priv->contact);
priv->contact = copy_font_and_color(pair);
@@ -820,7 +813,7 @@ pidgin_blist_theme_set_online_text_info(PidginBlistTheme *theme, const PidginThe
g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme));
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
pidgin_theme_font_free(priv->online);
priv->online = copy_font_and_color(pair);
@@ -833,7 +826,7 @@ pidgin_blist_theme_set_away_text_info(PidginBlistTheme *theme, const PidginTheme
g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme));
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
pidgin_theme_font_free(priv->away);
priv->away = copy_font_and_color(pair);
@@ -846,7 +839,7 @@ pidgin_blist_theme_set_offline_text_info(PidginBlistTheme *theme, const PidginTh
g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme));
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
pidgin_theme_font_free(priv->offline);
priv->offline = copy_font_and_color(pair);
@@ -859,7 +852,7 @@ pidgin_blist_theme_set_idle_text_info(PidginBlistTheme *theme, const PidginTheme
g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme));
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
pidgin_theme_font_free(priv->idle);
priv->idle = copy_font_and_color(pair);
@@ -872,7 +865,7 @@ pidgin_blist_theme_set_unread_message_text_info(PidginBlistTheme *theme, const P
g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme));
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
pidgin_theme_font_free(priv->message);
priv->message = copy_font_and_color(pair);
@@ -885,7 +878,7 @@ pidgin_blist_theme_set_unread_message_nick_said_text_info(PidginBlistTheme *them
g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme));
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
pidgin_theme_font_free(priv->message_nick_said);
priv->message_nick_said = copy_font_and_color(pair);
@@ -898,7 +891,7 @@ pidgin_blist_theme_set_status_text_info(PidginBlistTheme *theme, const PidginThe
g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme));
- priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme));
+ priv = PIDGIN_BLIST_THEME_GET_PRIVATE(theme);
pidgin_theme_font_free(priv->status);
priv->status = copy_font_and_color(pair);
diff --git a/pidgin/gtkblist-theme.h b/pidgin/gtkblist-theme.h
index 2c4fb07fb0..2a29137de8 100644
--- a/pidgin/gtkblist-theme.h
+++ b/pidgin/gtkblist-theme.h
@@ -51,7 +51,6 @@ typedef struct _PidginBlistThemeClass PidginBlistThemeClass;
struct _PidginBlistTheme
{
PurpleTheme parent;
- gpointer priv;
};
struct _PidginBlistThemeClass
@@ -80,6 +79,8 @@ typedef struct
} PidginBlistLayout;
+G_BEGIN_DECLS
+
/**************************************************************************/
/** @name PidginThemeFont API */
/**************************************************************************/
@@ -147,7 +148,6 @@ const gchar * pidgin_theme_font_get_color_describe(PidginThemeFont *font);
/**************************************************************************/
/** @name Purple Buddy List Theme API */
/**************************************************************************/
-G_BEGIN_DECLS
/**
* GObject foo.
@@ -183,7 +183,7 @@ gdouble pidgin_blist_theme_get_opacity(PidginBlistTheme *theme);
*
* @returns The buddy list layout.
*/
- PidginBlistLayout *pidgin_blist_theme_get_layout(PidginBlistTheme *theme);
+PidginBlistLayout *pidgin_blist_theme_get_layout(PidginBlistTheme *theme);
/**
* Returns the background color to be used with expanded groups.
@@ -192,7 +192,7 @@ gdouble pidgin_blist_theme_get_opacity(PidginBlistTheme *theme);
*
* @returns A gdk color.
*/
- GdkColor *pidgin_blist_theme_get_expanded_background_color(PidginBlistTheme *theme);
+GdkColor *pidgin_blist_theme_get_expanded_background_color(PidginBlistTheme *theme);
/**
* Returns the text font and color to be used with expanded groups.
@@ -201,7 +201,7 @@ gdouble pidgin_blist_theme_get_opacity(PidginBlistTheme *theme);
*
* @returns A font and color pair.
*/
- PidginThemeFont *pidgin_blist_theme_get_expanded_text_info(PidginBlistTheme *theme);
+PidginThemeFont *pidgin_blist_theme_get_expanded_text_info(PidginBlistTheme *theme);
/**
* Returns the background color to be used with collapsed groups.
@@ -210,7 +210,7 @@ gdouble pidgin_blist_theme_get_opacity(PidginBlistTheme *theme);
*
* @returns A gdk color.
*/
- GdkColor *pidgin_blist_theme_get_collapsed_background_color(PidginBlistTheme *theme);
+GdkColor *pidgin_blist_theme_get_collapsed_background_color(PidginBlistTheme *theme);
/**
* Returns the text font and color to be used with collapsed groups.
@@ -219,7 +219,7 @@ gdouble pidgin_blist_theme_get_opacity(PidginBlistTheme *theme);
*
* @returns A font and color pair.
*/
- PidginThemeFont *pidgin_blist_theme_get_collapsed_text_info(PidginBlistTheme *theme);
+PidginThemeFont *pidgin_blist_theme_get_collapsed_text_info(PidginBlistTheme *theme);
/**
* Returns the colors to be used for contacts and chats.
@@ -228,7 +228,7 @@ gdouble pidgin_blist_theme_get_opacity(PidginBlistTheme *theme);
*
* @returns A gdkcolor for contacts and chats.
*/
- GdkColor *pidgin_blist_theme_get_contact_color(PidginBlistTheme *theme);
+GdkColor *pidgin_blist_theme_get_contact_color(PidginBlistTheme *theme);
/**
* Returns the text font and color to be used for expanded contacts.
@@ -237,7 +237,7 @@ gdouble pidgin_blist_theme_get_opacity(PidginBlistTheme *theme);
*
* @returns A font and color pair.
*/
- PidginThemeFont *pidgin_blist_theme_get_contact_text_info(PidginBlistTheme *theme);
+PidginThemeFont *pidgin_blist_theme_get_contact_text_info(PidginBlistTheme *theme);
/**
* Returns the text font and color to be used for online buddies.
@@ -246,7 +246,7 @@ gdouble pidgin_blist_theme_get_opacity(PidginBlistTheme *theme);
*
* @returns A font and color pair.
*/
- PidginThemeFont *pidgin_blist_theme_get_online_text_info(PidginBlistTheme *theme);
+PidginThemeFont *pidgin_blist_theme_get_online_text_info(PidginBlistTheme *theme);
/**
* Returns the text font and color to be used for away and idle buddies.
@@ -255,7 +255,7 @@ gdouble pidgin_blist_theme_get_opacity(PidginBlistTheme *theme);
*
* @returns A font and color pair.
*/
- PidginThemeFont *pidgin_blist_theme_get_away_text_info(PidginBlistTheme *theme);
+PidginThemeFont *pidgin_blist_theme_get_away_text_info(PidginBlistTheme *theme);
/**
* Returns the text font and color to be used for offline buddies.
@@ -264,7 +264,7 @@ gdouble pidgin_blist_theme_get_opacity(PidginBlistTheme *theme);
*
* @returns A font and color pair.
*/
- PidginThemeFont *pidgin_blist_theme_get_offline_text_info(PidginBlistTheme *theme);
+PidginThemeFont *pidgin_blist_theme_get_offline_text_info(PidginBlistTheme *theme);
/**
* Returns the text font and color to be used for idle buddies.
@@ -273,7 +273,7 @@ gdouble pidgin_blist_theme_get_opacity(PidginBlistTheme *theme);
*
* @returns A font and color pair.
*/
- PidginThemeFont *pidgin_blist_theme_get_idle_text_info(PidginBlistTheme *theme);
+PidginThemeFont *pidgin_blist_theme_get_idle_text_info(PidginBlistTheme *theme);
/**
* Returns the text font and color to be used for buddies with unread messages.
@@ -282,7 +282,7 @@ gdouble pidgin_blist_theme_get_opacity(PidginBlistTheme *theme);
*
* @returns A font and color pair.
*/
- PidginThemeFont *pidgin_blist_theme_get_unread_message_text_info(PidginBlistTheme *theme);
+PidginThemeFont *pidgin_blist_theme_get_unread_message_text_info(PidginBlistTheme *theme);
/**
* Returns the text font and color to be used for chats with unread messages
@@ -292,7 +292,7 @@ gdouble pidgin_blist_theme_get_opacity(PidginBlistTheme *theme);
*
* @returns A font and color pair.
*/
- PidginThemeFont *pidgin_blist_theme_get_unread_message_nick_said_text_info(PidginBlistTheme *theme);
+PidginThemeFont *pidgin_blist_theme_get_unread_message_nick_said_text_info(PidginBlistTheme *theme);
/**
* Returns the text font and color to be used for a buddy's status message.
@@ -301,7 +301,7 @@ gdouble pidgin_blist_theme_get_opacity(PidginBlistTheme *theme);
*
* @returns A font and color pair.
*/
- PidginThemeFont *pidgin_blist_theme_get_status_text_info(PidginBlistTheme *theme);
+PidginThemeFont *pidgin_blist_theme_get_status_text_info(PidginBlistTheme *theme);
/* Set Methods */
@@ -435,4 +435,5 @@ void pidgin_blist_theme_set_unread_message_nick_said_text_info(PidginBlistTheme
void pidgin_blist_theme_set_status_text_info(PidginBlistTheme *theme, const PidginThemeFont *pair);
G_END_DECLS
+
#endif /* PIDGIN_BLIST_THEME_H */
diff --git a/pidgin/gtkblist.c b/pidgin/gtkblist.c
index 6bcef4c88a..c1b204b443 100644
--- a/pidgin/gtkblist.c
+++ b/pidgin/gtkblist.c
@@ -50,6 +50,7 @@
#include "gtkdebug.h"
#include "gtkdialogs.h"
#include "gtkft.h"
+#include "gtkimhtml.h"
#include "gtklog.h"
#include "gtkmenutray.h"
#include "gtkpounce.h"
@@ -124,6 +125,11 @@ typedef struct
#define PIDGIN_BUDDY_LIST_GET_PRIVATE(list) \
((PidginBuddyListPrivate *)((list)->priv))
+#if !GTK_CHECK_VERSION(2,18,0)
+#define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x)
+#define gtk_widget_has_focus(x) GTK_WIDGET_HAS_FOCUS(x)
+#endif
+
static GtkWidget *accountmenu = NULL;
static guint visibility_manager_count = 0;
@@ -138,6 +144,9 @@ static void sort_method_none(PurpleBlistNode *node, PurpleBuddyList *blist, GtkT
static void sort_method_alphabetical(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
static void sort_method_status(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
+static guint sort_merge_id;
+static GtkActionGroup *sort_action_group = NULL;
+
static PidginBuddyList *gtkblist = NULL;
static GList *groups_tree(void);
@@ -148,7 +157,6 @@ static void pidgin_blist_update(PurpleBuddyList *list, PurpleBlistNode *node);
static void pidgin_blist_update_group(PurpleBuddyList *list, PurpleBlistNode *node);
static void pidgin_blist_update_contact(PurpleBuddyList *list, PurpleBlistNode *node);
static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full);
-static const char *item_factory_translate_func (const char *path, gpointer func_data);
static gboolean get_iter_from_node(PurpleBlistNode *node, GtkTreeIter *iter);
static gboolean buddy_is_displayable(PurpleBuddy *buddy);
static void redo_buddy_list(PurpleBuddyList *list, gboolean remove, gboolean rerender);
@@ -242,7 +250,7 @@ static gboolean gtk_blist_configure_cb(GtkWidget *w, GdkEventConfigure *event, g
/* check for visibility because when we aren't visible, this will *
* give us bogus (0,0) coordinates. - xOr */
- if (GTK_WIDGET_VISIBLE(w))
+ if (gtk_widget_get_visible(w))
gtk_window_get_position(GTK_WINDOW(w), &x, &y);
else
return FALSE; /* carry on normally */
@@ -343,13 +351,13 @@ static void gtk_blist_menu_move_to_cb(GtkWidget *w, PurpleBlistNode *node)
static void gtk_blist_menu_autojoin_cb(GtkWidget *w, PurpleChat *chat)
{
- purple_blist_node_set_bool((PurpleBlistNode*)chat, "gtk-autojoin",
+ purple_blist_node_set_bool(PURPLE_BLIST_NODE(chat), "gtk-autojoin",
gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)));
}
static void gtk_blist_menu_persistent_cb(GtkWidget *w, PurpleChat *chat)
{
- purple_blist_node_set_bool((PurpleBlistNode*)chat, "gtk-persistent",
+ purple_blist_node_set_bool(PURPLE_BLIST_NODE(chat), "gtk-persistent",
gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)));
}
@@ -890,7 +898,7 @@ do_joinchat(GtkWidget *dialog, int id, PidginChatData *info)
* strings are empty then don't allow the user to click on "OK."
*/
static void
-set_sensitive_if_input_cb(GtkWidget *entry, gpointer user_data)
+set_sensitive_if_input_chat_cb(GtkWidget *entry, gpointer user_data)
{
PurplePluginProtocolInfo *prpl_info;
PurpleConnection *gc;
@@ -916,13 +924,28 @@ set_sensitive_if_input_cb(GtkWidget *entry, gpointer user_data)
gtk_dialog_set_response_sensitive(GTK_DIALOG(data->rq_data.window), GTK_RESPONSE_OK, sensitive);
gc = purple_account_get_connection(data->rq_data.account);
- prpl_info = (gc != NULL) ? PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl) : NULL;
+ prpl_info = (gc != NULL) ? PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)) : NULL;
sensitive = (prpl_info != NULL && prpl_info->roomlist_get_list != NULL);
gtk_dialog_set_response_sensitive(GTK_DIALOG(data->rq_data.window), 1, sensitive);
}
static void
+set_sensitive_if_input_buddy_cb(GtkWidget *entry, gpointer user_data)
+{
+ PurplePlugin *prpl;
+ PidginAddBuddyData *data = user_data;
+ const char *text;
+
+ prpl = purple_find_prpl(purple_account_get_protocol_id(
+ data->rq_data.account));
+ text = gtk_entry_get_text(GTK_ENTRY(entry));
+
+ gtk_dialog_set_response_sensitive(GTK_DIALOG(data->rq_data.window),
+ GTK_RESPONSE_OK, purple_validate(prpl, text));
+}
+
+static void
pidgin_blist_update_privacy_cb(PurpleBuddy *buddy)
{
struct _pidgin_blist_node *ui_data = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy));
@@ -940,7 +963,7 @@ chat_account_filter_func(PurpleAccount *account)
if (gc == NULL)
return FALSE;
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
return (prpl_info->chat_info != NULL);
}
@@ -1030,6 +1053,7 @@ static void
rebuild_chat_entries(PidginChatData *data, const char *default_chat_name)
{
PurpleConnection *gc;
+ PurplePluginProtocolInfo *prpl_info;
GList *list = NULL, *tmp;
GHashTable *defaults = NULL;
struct proto_chat_entry *pce;
@@ -1038,17 +1062,18 @@ rebuild_chat_entries(PidginChatData *data, const char *default_chat_name)
g_return_if_fail(data->rq_data.account != NULL);
gc = purple_account_get_connection(data->rq_data.account);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
gtk_container_foreach(GTK_CONTAINER(data->rq_data.vbox), (GtkCallback)gtk_widget_destroy, NULL);
g_list_free(data->entries);
data->entries = NULL;
- if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL)
- list = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info(gc);
+ if (prpl_info->chat_info != NULL)
+ list = prpl_info->chat_info(gc);
- if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL)
- defaults = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, default_chat_name);
+ if (prpl_info->chat_info_defaults != NULL)
+ defaults = prpl_info->chat_info_defaults(gc, default_chat_name);
for (tmp = list; tmp; tmp = tmp->next)
{
@@ -1083,7 +1108,7 @@ rebuild_chat_entries(PidginChatData *data, const char *default_chat_name)
}
pidgin_add_widget_to_vbox(data->rq_data.vbox, pce->label, data->rq_data.sg, input, TRUE, NULL);
g_signal_connect(G_OBJECT(input), "changed",
- G_CALLBACK(set_sensitive_if_input_cb), data);
+ G_CALLBACK(set_sensitive_if_input_chat_cb), data);
}
/* Do the following for any type of input widget */
@@ -1104,7 +1129,7 @@ rebuild_chat_entries(PidginChatData *data, const char *default_chat_name)
g_hash_table_destroy(defaults);
/* Set whether the "OK" button should be clickable initially */
- set_sensitive_if_input_cb(NULL, data);
+ set_sensitive_if_input_chat_cb(NULL, data);
gtk_widget_show_all(GTK_WIDGET(data->rq_data.vbox));
}
@@ -1411,7 +1436,7 @@ pidgin_append_blist_node_proto_menu(GtkWidget *menu, PurpleConnection *gc,
PurpleBlistNode *node)
{
GList *l, *ll;
- PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
if(!prpl_info || !prpl_info->blist_node_menu)
return;
@@ -1519,7 +1544,7 @@ pidgin_blist_make_buddy_menu(GtkWidget *menu, PurpleBuddy *buddy, gboolean sub)
if (prpl_info && prpl_info->send_file) {
if (!prpl_info->can_receive_file ||
- prpl_info->can_receive_file(buddy->account->gc, buddy->name))
+ prpl_info->can_receive_file(purple_account_get_connection(purple_buddy_get_account(buddy)), purple_buddy_get_name(buddy)))
{
pidgin_new_item_from_stock(menu, _("_Send File..."),
PIDGIN_STOCK_TOOLBAR_SEND_FILE,
@@ -1547,11 +1572,11 @@ pidgin_blist_make_buddy_menu(GtkWidget *menu, PurpleBuddy *buddy, gboolean sub)
NULL, G_CALLBACK(gtk_blist_menu_showoffline_cb), node, 0, 0, NULL);
}
- pidgin_append_blist_node_proto_menu(menu, buddy->account->gc, node);
+ pidgin_append_blist_node_proto_menu(menu, purple_account_get_connection(purple_buddy_get_account(buddy)), node);
pidgin_append_blist_node_extended_menu(menu, node);
if (!contact_expanded && contact != NULL)
- pidgin_append_blist_node_move_to_menu(menu, (PurpleBlistNode *)contact);
+ pidgin_append_blist_node_move_to_menu(menu, PURPLE_BLIST_NODE(contact));
if (node->parent && node->parent->child->next &&
!sub && !contact_expanded) {
@@ -1600,7 +1625,7 @@ gtk_blist_key_press_cb(GtkWidget *tv, GdkEventKey *event, gpointer data)
return FALSE;
}
if(buddy)
- pidgin_retrieve_user_info(buddy->account->gc, buddy->name);
+ pidgin_retrieve_user_info(purple_account_get_connection(purple_buddy_get_account(buddy)), purple_buddy_get_name(buddy));
} else {
switch (event->keyval) {
case GDK_F2:
@@ -1753,7 +1778,7 @@ create_chat_menu(PurpleBlistNode *node, PurpleChat *c)
pidgin_new_item_from_stock(menu, _("View _Log"), NULL,
G_CALLBACK(gtk_blist_menu_showlog_cb), node, 0, 0, NULL);
- pidgin_append_blist_node_proto_menu(menu, c->account->gc, node);
+ pidgin_append_blist_node_proto_menu(menu, purple_account_get_connection(purple_chat_get_account(c)), node);
pidgin_append_blist_node_extended_menu(menu, node);
pidgin_separator(menu);
@@ -1803,7 +1828,7 @@ create_contact_menu (PurpleBlistNode *node)
static GtkWidget *
create_buddy_menu(PurpleBlistNode *node, PurpleBuddy *b)
{
- struct _pidgin_blist_node *gtknode = (struct _pidgin_blist_node *)node->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(node);
GtkWidget *menu;
GtkWidget *menuitem;
gboolean show_offline = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies");
@@ -1838,13 +1863,13 @@ create_buddy_menu(PurpleBlistNode *node, PurpleBuddy *b)
if(buddy == b)
continue;
- if(!buddy->account->gc)
+ if(!purple_account_get_connection(purple_buddy_get_account(buddy)))
continue;
if(!show_offline && !PURPLE_BUDDY_IS_ONLINE(buddy))
continue;
- menuitem = gtk_image_menu_item_new_with_label(buddy->name);
- buf = pidgin_create_prpl_icon(buddy->account,PIDGIN_PRPL_ICON_SMALL);
+ menuitem = gtk_image_menu_item_new_with_label(purple_buddy_get_name(buddy));
+ buf = pidgin_create_prpl_icon(purple_buddy_get_account(buddy), PIDGIN_PRPL_ICON_SMALL);
image = gtk_image_new_from_pixbuf(buf);
g_object_unref(G_OBJECT(buf));
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem),
@@ -1871,12 +1896,10 @@ pidgin_blist_show_context_menu(PurpleBlistNode *node,
guint button,
guint32 time)
{
- struct _pidgin_blist_node *gtknode;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(node);
GtkWidget *menu = NULL;
gboolean handled = FALSE;
- gtknode = (struct _pidgin_blist_node *)node->ui_data;
-
/* Create a menu based on the thing we right-clicked on */
if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
PurpleGroup *g = (PurpleGroup *)node;
@@ -1938,7 +1961,7 @@ gtk_blist_button_press_cb(GtkWidget *tv, GdkEventButton *event, gpointer user_da
return FALSE;
gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path);
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1);
- gtknode = (struct _pidgin_blist_node *)node->ui_data;
+ gtknode = purple_blist_node_get_ui_data(node);
/* Right click draws a context menu */
if ((event->button == 3) && (event->type == GDK_BUTTON_PRESS)) {
@@ -1962,12 +1985,12 @@ gtk_blist_button_press_cb(GtkWidget *tv, GdkEventButton *event, gpointer user_da
else
b = (PurpleBuddy *)node;
- prpl = purple_find_prpl(purple_account_get_protocol_id(b->account));
+ prpl = purple_find_prpl(purple_account_get_protocol_id(purple_buddy_get_account(b)));
if (prpl != NULL)
prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
if (prpl && prpl_info->get_info)
- pidgin_retrieve_user_info(b->account->gc, b->name);
+ pidgin_retrieve_user_info(purple_account_get_connection(purple_buddy_get_account(b)), purple_buddy_get_name(b));
handled = TRUE;
}
@@ -2012,64 +2035,70 @@ pidgin_blist_popup_menu_cb(GtkWidget *tv, void *user_data)
return handled;
}
-static void pidgin_blist_buddy_details_cb(gpointer data, guint action, GtkWidget *item)
+static void gtk_blist_show_xfer_dialog_cb(GtkAction *item, gpointer data)
+{
+ pidgin_xfer_dialog_show(NULL);
+}
+
+static void pidgin_blist_buddy_details_cb(GtkToggleAction *item, gpointer data)
{
pidgin_set_cursor(gtkblist->window, GDK_WATCH);
purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons",
- gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)));
+ gtk_toggle_action_get_active(item));
pidgin_clear_cursor(gtkblist->window);
}
-static void pidgin_blist_show_idle_time_cb(gpointer data, guint action, GtkWidget *item)
+static void pidgin_blist_show_idle_time_cb(GtkToggleAction *item, gpointer data)
{
pidgin_set_cursor(gtkblist->window, GDK_WATCH);
purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/show_idle_time",
- gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)));
+ gtk_toggle_action_get_active(item));
pidgin_clear_cursor(gtkblist->window);
}
-static void pidgin_blist_show_protocol_icons_cb(gpointer data, guint action, GtkWidget *item)
+static void pidgin_blist_show_protocol_icons_cb(GtkToggleAction *item, gpointer data)
{
purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons",
- gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)));
+ gtk_toggle_action_get_active(item));
}
-static void pidgin_blist_show_empty_groups_cb(gpointer data, guint action, GtkWidget *item)
+static void pidgin_blist_show_empty_groups_cb(GtkToggleAction *item, gpointer data)
{
pidgin_set_cursor(gtkblist->window, GDK_WATCH);
purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/show_empty_groups",
- gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)));
+ gtk_toggle_action_get_active(item));
pidgin_clear_cursor(gtkblist->window);
}
-static void pidgin_blist_edit_mode_cb(gpointer callback_data, guint callback_action,
- GtkWidget *checkitem)
+static void pidgin_blist_edit_mode_cb(GtkToggleAction *checkitem, gpointer data)
{
pidgin_set_cursor(gtkblist->window, GDK_WATCH);
purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies",
- gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(checkitem)));
+ gtk_toggle_action_get_active(checkitem));
pidgin_clear_cursor(gtkblist->window);
}
-static void pidgin_blist_mute_sounds_cb(gpointer data, guint action, GtkWidget *item)
+static void pidgin_blist_mute_sounds_cb(GtkToggleAction *item, gpointer data)
{
- purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/sound/mute", GTK_CHECK_MENU_ITEM(item)->active);
+ purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/sound/mute",
+ gtk_toggle_action_get_active(item));
}
+
static void
pidgin_blist_mute_pref_cb(const char *name, PurplePrefType type,
gconstpointer value, gpointer data)
{
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item(gtkblist->ift,
- N_("/Tools/Mute Sounds"))), (gboolean)GPOINTER_TO_INT(value));
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui,
+ "/BList/ToolsMenu/MuteSounds")), (gboolean)GPOINTER_TO_INT(value));
}
static void
@@ -2081,7 +2110,7 @@ pidgin_blist_sound_method_pref_cb(const char *name, PurplePrefType type,
if(!strcmp(value, "none"))
sensitive = FALSE;
- gtk_widget_set_sensitive(gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Mute Sounds")), sensitive);
+ gtk_action_set_sensitive(gtk_ui_manager_get_action(gtkblist->ui, "/BList/ToolsMenu/MuteSounds"), sensitive);
}
static void
@@ -2111,7 +2140,7 @@ add_buddies_from_vcard(const char *prpl_id, PurpleGroup *group, GList *list,
for (l = list; l != NULL; l = l->next)
{
purple_blist_request_add_buddy(account, l->data,
- (group ? group->name : NULL),
+ (group ? purple_group_get_name(group) : NULL),
alias);
}
}
@@ -2292,7 +2321,7 @@ static void pidgin_blist_drag_data_get_cb(GtkWidget *widget,
buddy = (PurpleBuddy *)node;
}
- gc = purple_account_get_connection(buddy->account);
+ gc = purple_account_get_connection(purple_buddy_get_account(buddy));
if (gc == NULL)
{
@@ -2301,7 +2330,7 @@ static void pidgin_blist_drag_data_get_cb(GtkWidget *widget,
}
protocol =
- PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->list_icon(buddy->account,
+ PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc))->list_icon(purple_buddy_get_account(buddy),
buddy);
str = g_string_new(NULL);
@@ -2311,13 +2340,13 @@ static void pidgin_blist_drag_data_get_cb(GtkWidget *widget,
"X-IM-Protocol: %s\r\n"
"X-IM-Username: %s\r\n",
protocol,
- buddy->name);
+ purple_buddy_get_name(buddy));
- if (buddy->alias != NULL)
+ if (purple_buddy_get_local_buddy_alias(buddy) != NULL)
{
g_string_append_printf(str,
"X-IM-Alias: %s\r\n",
- buddy->alias);
+ purple_buddy_get_local_buddy_alias(buddy));
}
g_string_append(str, "\r\n");
@@ -2356,7 +2385,7 @@ static void pidgin_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc,
&iter, path);
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel),
&iter, NODE_COLUMN, &node, -1);
- gtknode = node->ui_data;
+ gtknode = purple_blist_node_get_ui_data(node);
if (PURPLE_BLIST_NODE_IS_CONTACT(n)) {
PurpleContact *c = (PurpleContact*)n;
@@ -2533,7 +2562,7 @@ static void pidgin_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc,
else
{
purple_blist_request_add_buddy(account, username,
- (group ? group->name : NULL),
+ (group ? purple_group_get_name(group) : NULL),
alias);
}
}
@@ -2600,7 +2629,7 @@ static void pidgin_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc,
if (PURPLE_BLIST_NODE_IS_BUDDY(node) || PURPLE_BLIST_NODE_IS_CONTACT(node)) {
PurpleBuddy *b = PURPLE_BLIST_NODE_IS_BUDDY(node) ? PURPLE_BUDDY(node) : purple_contact_get_priority_buddy(PURPLE_CONTACT(node));
- pidgin_dnd_file_manage(sd, b->account, b->name);
+ pidgin_dnd_file_manage(sd, purple_buddy_get_account(b), purple_buddy_get_name(b));
gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
} else {
gtk_drag_finish(dc, FALSE, FALSE, t);
@@ -2673,8 +2702,8 @@ static GdkPixbuf *pidgin_blist_get_buddy_icon(PurpleBlistNode *node,
account = purple_buddy_get_account(buddy);
}
- if(account && account->gc) {
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl);
+ if(account && purple_account_get_connection(account)) {
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(purple_account_get_connection(account)));
}
#if 0
@@ -2687,7 +2716,7 @@ static GdkPixbuf *pidgin_blist_get_buddy_icon(PurpleBlistNode *node,
* a contact then this is a group or some other type of node and we
* want to use that directly. */
if (contact) {
- custom_img = purple_buddy_icons_node_find_custom_icon((PurpleBlistNode*)contact);
+ custom_img = purple_buddy_icons_node_find_custom_icon(PURPLE_BLIST_NODE(contact));
} else {
custom_img = purple_buddy_icons_node_find_custom_icon(node);
}
@@ -2700,7 +2729,7 @@ static GdkPixbuf *pidgin_blist_get_buddy_icon(PurpleBlistNode *node,
if (data == NULL) {
if (buddy) {
/* Not sure I like this...*/
- if (!(icon = purple_buddy_icons_find(buddy->account, buddy->name)))
+ if (!(icon = purple_buddy_icons_find(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy))))
return NULL;
data = purple_buddy_icon_get_data(icon, &len);
}
@@ -2870,9 +2899,9 @@ static struct tooltip_data * create_tip_for_node(PurpleBlistNode *node, gboolean
char *tmp = NULL, *node_name = NULL, *tooltip_text = NULL;
if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
- account = ((PurpleBuddy*)(node))->account;
+ account = purple_buddy_get_account((PurpleBuddy*)(node));
} else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
- account = ((PurpleChat*)(node))->account;
+ account = purple_chat_get_account((PurpleChat*)(node));
}
td->padding = TOOLTIP_BORDER;
@@ -2926,6 +2955,7 @@ static gboolean
pidgin_blist_paint_tip(GtkWidget *widget, gpointer null)
{
GtkStyle *style;
+ cairo_t *cr;
int current_height, max_width;
int max_text_width;
int max_avatar_width;
@@ -2959,6 +2989,7 @@ pidgin_blist_paint_tip(GtkWidget *widget, gpointer null)
else
prpl_col = TOOLTIP_BORDER + status_size + SMALL_SPACE + max_text_width - PRPL_SIZE;
+ cr = gdk_cairo_create(GDK_DRAWABLE(gtk_widget_get_window(gtkblist->tipwindow)));
current_height = 12;
for(l = gtkblist->tooltipdata; l; l = l->next)
{
@@ -2978,30 +3009,37 @@ pidgin_blist_paint_tip(GtkWidget *widget, gpointer null)
}
if (td->status_icon) {
- if (dir == GTK_TEXT_DIR_RTL)
- gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon,
- 0, 0, max_width - TOOLTIP_BORDER - status_size, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
- else
- gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon,
- 0, 0, TOOLTIP_BORDER, current_height, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0);
+ if (dir == GTK_TEXT_DIR_RTL) {
+ gdk_cairo_set_source_pixbuf(cr, td->status_icon,
+ max_width - TOOLTIP_BORDER - status_size,
+ current_height);
+ cairo_paint(cr);
+ } else {
+ gdk_cairo_set_source_pixbuf(cr, td->status_icon,
+ TOOLTIP_BORDER, current_height);
+ cairo_paint(cr);
+ }
}
if(td->avatar) {
- if (dir == GTK_TEXT_DIR_RTL)
- gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL,
- td->avatar, 0, 0, TOOLTIP_BORDER, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
- else
- gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL,
- td->avatar, 0, 0, max_width - (td->avatar_width + TOOLTIP_BORDER),
- current_height, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0);
+ if (dir == GTK_TEXT_DIR_RTL) {
+ gdk_cairo_set_source_pixbuf(cr, td->avatar,
+ TOOLTIP_BORDER, current_height);
+ cairo_paint(cr);
+ } else {
+ gdk_cairo_set_source_pixbuf(cr, td->avatar,
+ max_width - (td->avatar_width + TOOLTIP_BORDER),
+ current_height);
+ cairo_paint(cr);
+ }
}
- if (!td->avatar_is_prpl_icon && td->prpl_icon)
- gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->prpl_icon,
- 0, 0,
- prpl_col,
- current_height + ((td->name_height / 2) - (PRPL_SIZE / 2)),
- -1 , -1, GDK_RGB_DITHER_NONE, 0, 0);
+ if (!td->avatar_is_prpl_icon && td->prpl_icon) {
+ gdk_cairo_set_source_pixbuf(cr, td->prpl_icon, prpl_col,
+ current_height +
+ (td->name_height - PRPL_SIZE) / 2);
+ cairo_paint(cr);
+ }
if (td->name_layout) {
if (dir == GTK_TEXT_DIR_RTL) {
@@ -3032,6 +3070,8 @@ pidgin_blist_paint_tip(GtkWidget *widget, gpointer null)
current_height += MAX(td->name_height + td->height, td->avatar_height) + td->padding;
}
+
+ cairo_destroy(cr);
return FALSE;
}
@@ -3172,7 +3212,7 @@ static gboolean pidgin_blist_expand_timeout(GtkWidget *tv)
return FALSE;
}
- gtknode = node->ui_data;
+ gtknode = purple_blist_node_get_ui_data(node);
if (!gtknode->contact_expanded) {
GtkTreeIter i;
@@ -3201,13 +3241,13 @@ static gboolean buddy_is_displayable(PurpleBuddy *buddy)
if(!buddy)
return FALSE;
- gtknode = ((PurpleBlistNode*)buddy)->ui_data;
+ gtknode = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy));
- return (purple_account_is_connected(buddy->account) &&
- (purple_presence_is_online(buddy->presence) ||
+ return (purple_account_is_connected(purple_buddy_get_account(buddy)) &&
+ (purple_presence_is_online(purple_buddy_get_presence(buddy)) ||
(gtknode && gtknode->recent_signonoff) ||
purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies") ||
- purple_blist_node_get_bool((PurpleBlistNode*)buddy, "show_offline")));
+ purple_blist_node_get_bool(PURPLE_BLIST_NODE(buddy), "show_offline")));
}
void pidgin_blist_draw_tooltip(PurpleBlistNode *node, GtkWidget *widget)
@@ -3382,7 +3422,7 @@ edit_mood_cb(PurpleConnection *gc, PurpleRequestFields *fields)
const char *text;
PurpleAccount *account = purple_connection_get_account(gc);
- if (gc->flags & PURPLE_CONNECTION_SUPPORT_MOOD_MESSAGES) {
+ if (purple_connection_get_flags(gc) & PURPLE_CONNECTION_SUPPORT_MOOD_MESSAGES) {
PurpleRequestField *text_field;
text_field = purple_request_fields_get_field(fields, "text");
text = purple_request_field_string_get_value(text_field);
@@ -3398,7 +3438,7 @@ edit_mood_cb(PurpleConnection *gc, PurpleRequestFields *fields)
PurpleAccount *account = (PurpleAccount *) accounts->data;
PurpleConnection *gc = purple_account_get_connection(account);
- if (gc && gc->flags & PURPLE_CONNECTION_SUPPORT_MOODS) {
+ if (gc && (purple_connection_get_flags(gc) & PURPLE_CONNECTION_SUPPORT_MOODS)) {
update_status_with_mood(account, mood, NULL);
}
}
@@ -3433,9 +3473,9 @@ get_global_moods(void)
if (purple_account_is_connected(account)) {
PurpleConnection *gc = purple_account_get_connection(account);
- if (gc->flags & PURPLE_CONNECTION_SUPPORT_MOODS) {
+ if (purple_connection_get_flags(gc) & PURPLE_CONNECTION_SUPPORT_MOODS) {
PurplePluginProtocolInfo *prpl_info =
- PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
PurpleMood *mood = NULL;
/* PURPLE_CONNECTION_SUPPORT_MOODS would not be set if the prpl doesn't
@@ -3493,7 +3533,7 @@ get_global_mood_status(void)
PurpleAccount *account = (PurpleAccount *) accounts->data;
if (purple_account_is_connected(account) &&
- (purple_account_get_connection(account)->flags &
+ (purple_connection_get_flags(purple_account_get_connection(account)) &
PURPLE_CONNECTION_SUPPORT_MOODS)) {
PurplePresence *presence = purple_account_get_presence(account);
PurpleStatus *status = purple_presence_get_status(presence, "mood");
@@ -3528,8 +3568,8 @@ set_mood_cb(GtkWidget *widget, PurpleAccount *account)
PurplePresence *presence = purple_account_get_presence(account);
PurpleStatus *status = purple_presence_get_status(presence, "mood");
gc = purple_account_get_connection(account);
- g_return_if_fail(gc->prpl != NULL);
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ g_return_if_fail(purple_connection_get_prpl(gc) != NULL);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
current_mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME);
} else {
current_mood = get_global_mood_status();
@@ -3539,7 +3579,7 @@ set_mood_cb(GtkWidget *widget, PurpleAccount *account)
g = purple_request_field_group_new(NULL);
f = purple_request_field_list_new("mood", _("Please select your mood from the list"));
- purple_request_field_list_add(f, _("None"), "");
+ purple_request_field_list_add_icon(f, _("None"), NULL, "");
if (current_mood == NULL)
purple_request_field_list_add_selected(f, _("None"));
@@ -3568,7 +3608,7 @@ set_mood_cb(GtkWidget *widget, PurpleAccount *account)
purple_request_fields_add_group(fields, g);
/* if the connection allows setting a mood message */
- if (gc && (gc->flags & PURPLE_CONNECTION_SUPPORT_MOOD_MESSAGES)) {
+ if (gc && (purple_connection_get_flags(gc) & PURPLE_CONNECTION_SUPPORT_MOOD_MESSAGES)) {
g = purple_request_field_group_new(NULL);
f = purple_request_field_string_new("text",
_("Message (optional)"), NULL, FALSE);
@@ -3595,64 +3635,121 @@ set_mood_show(void)
/***************************************************
* Crap *
***************************************************/
-static GtkItemFactoryEntry blist_menu[] =
-{
+/* TODO: fill out tooltips... */
+static const GtkActionEntry blist_menu_entries[] = {
/* NOTE: Do not set any accelerator to Control+O. It is mapped by
gtk_blist_key_press_cb to "Get User Info" on the selected buddy. */
-
/* Buddies menu */
- { N_("/_Buddies"), NULL, NULL, 0, "<Branch>", NULL },
- { N_("/Buddies/New Instant _Message..."), "<CTL>M", pidgin_dialogs_im, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW },
- { N_("/Buddies/Join a _Chat..."), "<CTL>C", pidgin_blist_joinchat_show, 0, "<StockItem>", PIDGIN_STOCK_CHAT },
- { N_("/Buddies/Get User _Info..."), "<CTL>I", pidgin_dialogs_info, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_USER_INFO },
- { N_("/Buddies/View User _Log..."), "<CTL>L", pidgin_dialogs_log, 0, "<Item>", NULL },
- { "/Buddies/sep1", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Buddies/Sh_ow"), NULL, NULL, 0, "<Branch>", NULL},
- { N_("/Buddies/Show/_Offline Buddies"), NULL, pidgin_blist_edit_mode_cb, 1, "<CheckItem>", NULL },
- { N_("/Buddies/Show/_Empty Groups"), NULL, pidgin_blist_show_empty_groups_cb, 1, "<CheckItem>", NULL },
- { N_("/Buddies/Show/Buddy _Details"), NULL, pidgin_blist_buddy_details_cb, 1, "<CheckItem>", NULL },
- { N_("/Buddies/Show/Idle _Times"), NULL, pidgin_blist_show_idle_time_cb, 1, "<CheckItem>", NULL },
- { N_("/Buddies/Show/_Protocol Icons"), NULL, pidgin_blist_show_protocol_icons_cb, 1, "<CheckItem>", NULL },
- { N_("/Buddies/_Sort Buddies"), NULL, NULL, 0, "<Branch>", NULL },
- { "/Buddies/sep2", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Buddies/_Add Buddy..."), "<CTL>B", pidgin_blist_add_buddy_cb, 0, "<StockItem>", GTK_STOCK_ADD },
- { N_("/Buddies/Add C_hat..."), NULL, pidgin_blist_add_chat_cb, 0, "<StockItem>", GTK_STOCK_ADD },
- { N_("/Buddies/Add _Group..."), NULL, purple_blist_request_add_group, 0, "<StockItem>", GTK_STOCK_ADD },
- { "/Buddies/sep3", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Buddies/_Quit"), "<CTL>Q", purple_core_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
+ { "BuddiesMenu", NULL, N_("_Buddies"), NULL, NULL, NULL },
+ { "NewInstantMessage", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, N_("New Instant _Message..."), "<control>M", NULL, pidgin_dialogs_im },
+ { "JoinAChat", PIDGIN_STOCK_CHAT, N_("Join a _Chat..."), "<control>C", NULL, pidgin_blist_joinchat_show },
+ { "GetUserInfo", PIDGIN_STOCK_TOOLBAR_USER_INFO, N_("Get User _Info..."), "<control>I", NULL, pidgin_dialogs_info },
+ { "ViewUserLog", NULL, N_("View User _Log..."), "<control>L", NULL, pidgin_dialogs_log },
+ { "ShowMenu", NULL, N_("Sh_ow"), NULL, NULL, NULL },
+ { "SortMenu", NULL, N_("_Sort Buddies"), NULL, NULL, NULL },
+ { "AddBuddy", GTK_STOCK_ADD, N_("_Add Buddy..."), "<control>B", NULL, pidgin_blist_add_buddy_cb },
+ { "AddChat", GTK_STOCK_ADD, N_("Add C_hat..."), NULL, NULL, pidgin_blist_add_chat_cb },
+ { "AddGroup", GTK_STOCK_ADD, N_("Add _Group..."), NULL, NULL, purple_blist_request_add_group },
+ { "Quit", GTK_STOCK_QUIT, N_("_Quit"), "<control>Q", NULL, purple_core_quit },
/* Accounts menu */
- { N_("/_Accounts"), NULL, NULL, 0, "<Branch>", NULL },
- { N_("/Accounts/Manage Accounts"), "<CTL>A", pidgin_accounts_window_show, 0, "<Item>", NULL },
+ { "AccountsMenu", NULL, N_("_Accounts"), NULL, NULL, NULL },
+ { "ManageAccounts", NULL, N_("Manage Accounts"), "<control>A", NULL, pidgin_accounts_window_show },
/* Tools */
- { N_("/_Tools"), NULL, NULL, 0, "<Branch>", NULL },
- { N_("/Tools/Buddy _Pounces"), NULL, pidgin_pounces_manager_show, 1, "<Item>", NULL },
- { N_("/Tools/_Certificates"), NULL, pidgin_certmgr_show, 0, "<Item>", NULL },
- { N_("/Tools/Custom Smile_ys"), "<CTL>Y", pidgin_smiley_manager_show, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_SMILEY },
- { N_("/Tools/Plu_gins"), "<CTL>U", pidgin_plugin_dialog_show, 2, "<StockItem>", PIDGIN_STOCK_TOOLBAR_PLUGINS },
- { N_("/Tools/Pr_eferences"), "<CTL>P", pidgin_prefs_show, 0, "<StockItem>", GTK_STOCK_PREFERENCES },
- { N_("/Tools/Pr_ivacy"), NULL, pidgin_privacy_dialog_show, 0, "<Item>", NULL },
- { N_("/Tools/Set _Mood"), "<CTL>D", set_mood_show, 0, "<Item>", NULL },
- { "/Tools/sep2", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Tools/_File Transfers"), "<CTL>T", pidgin_xfer_dialog_show, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_TRANSFER },
- { N_("/Tools/R_oom List"), NULL, pidgin_roomlist_dialog_show, 0, "<Item>", NULL },
- { N_("/Tools/System _Log"), NULL, gtk_blist_show_systemlog_cb, 3, "<Item>", NULL },
- { "/Tools/sep3", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Tools/Mute _Sounds"), NULL, pidgin_blist_mute_sounds_cb, 0, "<CheckItem>", NULL },
+ { "ToolsMenu", NULL, N_("_Tools"), NULL, NULL, NULL },
+ { "BuddyPounces", NULL, N_("Buddy _Pounces"), NULL, NULL, pidgin_pounces_manager_show },
+ { "Certificates", NULL, N_("_Certificates"), NULL, NULL, pidgin_certmgr_show },
+ { "CustomSmileys", PIDGIN_STOCK_TOOLBAR_SMILEY, N_("Custom Smile_ys"), "<control>Y", NULL, pidgin_smiley_manager_show },
+ { "Plugins", PIDGIN_STOCK_TOOLBAR_PLUGINS, N_("Plu_gins"), "<control>U", NULL, pidgin_plugin_dialog_show },
+ { "Preferences", GTK_STOCK_PREFERENCES, N_("Pr_eferences"), "<control>P", NULL, pidgin_prefs_show },
+ { "Privacy", NULL, N_("Pr_ivacy"), NULL, NULL, pidgin_privacy_dialog_show },
+ { "SetMood", NULL, N_("Set _Mood"), "<control>D", NULL, set_mood_show },
+ { "FileTransfers", PIDGIN_STOCK_TOOLBAR_TRANSFER, N_("_File Transfers"), "<control>T", NULL, G_CALLBACK(gtk_blist_show_xfer_dialog_cb) },
+ { "RoomList", NULL, N_("R_oom List"), NULL, NULL, pidgin_roomlist_dialog_show },
+ { "SystemLog", NULL, N_("System _Log"), NULL, NULL, gtk_blist_show_systemlog_cb },
+
/* Help */
- { N_("/_Help"), NULL, NULL, 0, "<Branch>", NULL },
- { N_("/Help/Online _Help"), "F1", gtk_blist_show_onlinehelp_cb, 0, "<StockItem>", GTK_STOCK_HELP },
- { "/Help/sep1", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Help/_Build Information"), NULL, pidgin_dialogs_buildinfo, 0, "<Item>", NULL },
- { N_("/Help/_Debug Window"), NULL, toggle_debug, 0, "<Item>", NULL },
- { N_("/Help/De_veloper Information"), NULL, pidgin_dialogs_developers, 0, "<Item>", NULL },
- { N_("/Help/_Plugin Information"), NULL, pidgin_dialogs_plugins_info, 0, "<Item>", NULL },
- { N_("/Help/_Translator Information"), NULL, pidgin_dialogs_translators, 0, "<Item>", NULL },
- { "/Help/sep2", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Help/_About"), NULL, pidgin_dialogs_about, 4, "<StockItem>", GTK_STOCK_ABOUT },
+ { "HelpMenu", NULL, N_("_Help"), NULL, NULL, NULL },
+ { "OnlineHelp", GTK_STOCK_HELP, N_("Online _Help"), "F1", NULL, gtk_blist_show_onlinehelp_cb },
+ { "BuildInformation", NULL, N_("_Build Information"), NULL, NULL, pidgin_dialogs_buildinfo },
+ { "DebugWindow", NULL, N_("_Debug Window"), NULL, NULL, toggle_debug },
+ { "DeveloperInformation", NULL, N_("De_veloper Information"), NULL, NULL, pidgin_dialogs_developers },
+ { "PluginInformation", NULL, N_("_Plugin Information"), NULL, NULL, pidgin_dialogs_plugins_info },
+ { "TranslatorInformation", NULL, N_("_Translator Information"), NULL, NULL, pidgin_dialogs_translators },
+ { "About", GTK_STOCK_ABOUT, N_("_About"), NULL, NULL, pidgin_dialogs_about },
+};
+
+/* Toggle items */
+static const GtkToggleActionEntry blist_menu_toggle_entries[] = {
+ /* Buddies->Show menu */
+ { "ShowOffline", NULL, N_("_Offline Buddies"), NULL, NULL, G_CALLBACK(pidgin_blist_edit_mode_cb), FALSE },
+ { "ShowEmptyGroups", NULL, N_("_Empty Groups"), NULL, NULL, G_CALLBACK(pidgin_blist_show_empty_groups_cb), FALSE },
+ { "ShowBuddyDetails", NULL, N_("Buddy _Details"), NULL, NULL, G_CALLBACK(pidgin_blist_buddy_details_cb), FALSE },
+ { "ShowIdleTimes", NULL, N_("Idle _Times"), NULL, NULL, G_CALLBACK(pidgin_blist_show_idle_time_cb), FALSE },
+ { "ShowProtocolIcons", NULL, N_("_Protocol Icons"), NULL, NULL, G_CALLBACK(pidgin_blist_show_protocol_icons_cb), FALSE },
+
+ /* Tools menu */
+ { "MuteSounds", NULL, N_("Mute _Sounds"), NULL, NULL, G_CALLBACK(pidgin_blist_mute_sounds_cb), FALSE },
};
+static const char *blist_menu =
+"<ui>"
+ "<menubar name='BList'>"
+ "<menu action='BuddiesMenu'>"
+ "<menuitem action='NewInstantMessage'/>"
+ "<menuitem action='JoinAChat'/>"
+ "<menuitem action='GetUserInfo'/>"
+ "<menuitem action='ViewUserLog'/>"
+ "<separator/>"
+ "<menu action='ShowMenu'>"
+ "<menuitem action='ShowOffline'/>"
+ "<menuitem action='ShowEmptyGroups'/>"
+ "<menuitem action='ShowBuddyDetails'/>"
+ "<menuitem action='ShowIdleTimes'/>"
+ "<menuitem action='ShowProtocolIcons'/>"
+ "</menu>"
+ "<menu action='SortMenu'/>"
+ "<separator/>"
+ "<menuitem action='AddBuddy'/>"
+ "<menuitem action='AddChat'/>"
+ "<menuitem action='AddGroup'/>"
+ "<separator/>"
+ "<menuitem action='Quit'/>"
+ "</menu>"
+ "<menu action='AccountsMenu'>"
+ "<menuitem action='ManageAccounts'/>"
+ "</menu>"
+ "<menu action='ToolsMenu'>"
+ "<menuitem action='BuddyPounces'/>"
+ "<menuitem action='Certificates'/>"
+ "<menuitem action='CustomSmileys'/>"
+ "<menuitem action='Plugins'/>"
+ "<menuitem action='Preferences'/>"
+ "<menuitem action='Privacy'/>"
+ "<menuitem action='SetMood'/>"
+ "<separator/>"
+ "<menuitem action='FileTransfers'/>"
+ "<menuitem action='RoomList'/>"
+ "<menuitem action='SystemLog'/>"
+ "<separator/>"
+ "<menuitem action='MuteSounds'/>"
+ "<placeholder name='PluginActions'/>"
+ "</menu>"
+ "<menu action='HelpMenu'>"
+ "<menuitem action='OnlineHelp'/>"
+ "<separator/>"
+ "<menuitem action='BuildInformation'/>"
+ "<menuitem action='DebugWindow'/>"
+ "<menuitem action='DeveloperInformation'/>"
+ "<menuitem action='PluginInformation'/>"
+ "<menuitem action='TranslatorInformation'/>"
+ "<separator/>"
+ "<menuitem action='About'/>"
+ "</menu>"
+ "</menubar>"
+"</ui>";
+
/*********************************************************
* Private Utility functions *
*********************************************************/
@@ -3672,16 +3769,16 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
struct proto_chat_entry *pce;
char *name, *value;
PurpleConversation *conv;
- PidginBlistNode *bnode = node->ui_data;
+ PidginBlistNode *bnode = purple_blist_node_get_ui_data(node);
chat = (PurpleChat *)node;
- prpl = purple_find_prpl(purple_account_get_protocol_id(chat->account));
+ prpl = purple_find_prpl(purple_account_get_protocol_id(purple_chat_get_account(chat)));
prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
connections = purple_connections_get_all();
if (connections && connections->next)
{
- tmp = g_markup_escape_text(chat->account->username, -1);
+ tmp = g_markup_escape_text(purple_account_get_username(purple_chat_get_account(chat)), -1);
g_string_append_printf(str, _("<b>Account:</b> %s"), tmp);
g_free(tmp);
}
@@ -3691,12 +3788,12 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
} else {
char *chat_name;
if (prpl_info && prpl_info->get_chat_name)
- chat_name = prpl_info->get_chat_name(chat->components);
+ chat_name = prpl_info->get_chat_name(purple_chat_get_components(chat));
else
chat_name = g_strdup(purple_chat_get_name(chat));
conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, chat_name,
- chat->account);
+ purple_chat_get_account(chat));
g_free(chat_name);
}
@@ -3713,7 +3810,7 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
}
if (prpl_info && prpl_info->chat_info != NULL)
- cur = prpl_info->chat_info(chat->account->gc);
+ cur = prpl_info->chat_info(purple_account_get_connection(purple_chat_get_account(chat)));
else
cur = NULL;
@@ -3722,13 +3819,13 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
pce = cur->data;
if (!pce->secret && (!pce->required &&
- g_hash_table_lookup(chat->components, pce->identifier) == NULL))
+ g_hash_table_lookup(purple_chat_get_components(chat), pce->identifier) == NULL))
{
tmp = purple_text_strip_mnemonic(pce->label);
name = g_markup_escape_text(tmp, -1);
g_free(tmp);
value = g_markup_escape_text(g_hash_table_lookup(
- chat->components, pce->identifier), -1);
+ purple_chat_get_components(chat), pce->identifier), -1);
g_string_append_printf(str, "\n<b>%s</b> %s",
name ? name : "",
value ? value : "");
@@ -3764,7 +3861,7 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
c = purple_buddy_get_contact(b);
}
- prpl = purple_find_prpl(purple_account_get_protocol_id(b->account));
+ prpl = purple_find_prpl(purple_account_get_protocol_id(purple_buddy_get_account(b)));
prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
presence = purple_buddy_get_presence(b);
@@ -3774,22 +3871,19 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
connections = purple_connections_get_all();
if (full && connections && connections->next)
{
- tmp = g_markup_escape_text(purple_account_get_username(
- purple_buddy_get_account(b)), -1);
- purple_notify_user_info_add_pair(user_info, _("Account"), tmp);
- g_free(tmp);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Account"),
+ purple_account_get_username(purple_buddy_get_account(b)));
}
/* Alias */
/* If there's not a contact alias, the node is being displayed with
* this alias, so there's no point in showing it in the tooltip. */
- if (full && c && b->alias != NULL && b->alias[0] != '\0' &&
+ if (full && c && purple_buddy_get_local_buddy_alias(b) != NULL && purple_buddy_get_local_buddy_alias(b)[0] != '\0' &&
(c->alias != NULL && c->alias[0] != '\0') &&
- strcmp(c->alias, b->alias) != 0)
+ strcmp(c->alias, purple_buddy_get_local_buddy_alias(b)) != 0)
{
- tmp = g_markup_escape_text(b->alias, -1);
- purple_notify_user_info_add_pair(user_info, _("Buddy Alias"), tmp);
- g_free(tmp);
+ purple_notify_user_info_add_pair_plaintext(user_info,
+ _("Buddy Alias"), purple_buddy_get_local_buddy_alias(b));
}
/* Nickname/Server Alias */
@@ -3797,11 +3891,10 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
* alias, but many people on MSN set long nicknames, which
* get ellipsized, so the only way to see the whole thing is
* to look at the tooltip. */
- if (full && b->server_alias != NULL && b->server_alias[0] != '\0')
+ if (full && purple_buddy_get_server_alias(b))
{
- tmp = g_markup_escape_text(b->server_alias, -1);
- purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp);
- g_free(tmp);
+ purple_notify_user_info_add_pair_plaintext(user_info,
+ _("Nickname"), purple_buddy_get_server_alias(b));
}
/* Logged In */
@@ -3817,7 +3910,7 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
tmp = g_strdup(purple_date_format_long(localtime(&signon)));
} else
tmp = purple_str_seconds_to_string(time(NULL) - signon);
- purple_notify_user_info_add_pair(user_info, _("Logged In"), tmp);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Logged In"), tmp);
g_free(tmp);
}
@@ -3828,7 +3921,7 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
if (idle_secs > 0)
{
tmp = purple_str_seconds_to_string(time(NULL) - idle_secs);
- purple_notify_user_info_add_pair(user_info, _("Idle"), tmp);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Idle"), tmp);
g_free(tmp);
}
}
@@ -3836,7 +3929,7 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
/* Last Seen */
if (full && c && !PURPLE_BUDDY_IS_ONLINE(b))
{
- struct _pidgin_blist_node *gtknode = ((PurpleBlistNode *)c)->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(c));
PurpleBlistNode *bnode;
int lastseen = 0;
@@ -3863,7 +3956,7 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
if (lastseen > 0)
{
tmp = purple_str_seconds_to_string(time(NULL) - lastseen);
- purple_notify_user_info_add_pair(user_info, _("Last Seen"), tmp);
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Last Seen"), tmp);
g_free(tmp);
}
}
@@ -3873,10 +3966,10 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
/* FIXME: Why is this status special-cased by the core? --rlaager
* FIXME: Alternatively, why not have the core do all of them? --rlaager */
if (!PURPLE_BUDDY_IS_ONLINE(b)) {
- purple_notify_user_info_add_pair(user_info, _("Status"), _("Offline"));
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), _("Offline"));
}
- if (purple_account_is_connected(b->account) &&
+ if (purple_account_is_connected(purple_buddy_get_account(b)) &&
prpl_info && prpl_info->tooltip_text)
{
/* Additional text from the PRPL */
@@ -3884,12 +3977,12 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
}
/* These are Easter Eggs. Patches to remove them will be rejected. */
- if (!g_ascii_strcasecmp(b->name, "robflynn"))
- purple_notify_user_info_add_pair(user_info, _("Description"), _("Spooky"));
- if (!g_ascii_strcasecmp(b->name, "seanegn"))
- purple_notify_user_info_add_pair(user_info, _("Status"), _("Awesome"));
- if (!g_ascii_strcasecmp(b->name, "chipx86"))
- purple_notify_user_info_add_pair(user_info, _("Status"), _("Rockin'"));
+ if (!g_ascii_strcasecmp(purple_buddy_get_name(b), "robflynn"))
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Description"), _("Spooky"));
+ if (!g_ascii_strcasecmp(purple_buddy_get_name(b), "seanegn"))
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), _("Awesome"));
+ if (!g_ascii_strcasecmp(purple_buddy_get_name(b), "chipx86"))
+ purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), _("Rockin'"));
tmp = purple_notify_user_info_get_text_with_newline(user_info, "\n");
g_string_append(str, tmp);
@@ -3904,24 +3997,21 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
user_info = purple_notify_user_info_new();
count = purple_blist_get_group_online_count(group);
-
if (count != 0) {
/* Online buddies in group */
- tmp = g_strdup_printf("%d", count);
- purple_notify_user_info_add_pair(user_info,
- _("Online Buddies"),
- tmp);
- g_free(tmp);
+ char tmp2[12];
+ sprintf(tmp2, "%d", count);
+ purple_notify_user_info_add_pair_plaintext(user_info,
+ _("Online Buddies"), tmp2);
}
count = purple_blist_get_group_size(group, FALSE);
if (count != 0) {
/* Total buddies (from online accounts) in group */
- tmp = g_strdup_printf("%d", count);
- purple_notify_user_info_add_pair(user_info,
- _("Total Buddies"),
- tmp);
- g_free(tmp);
+ char tmp2[12];
+ sprintf(tmp2, "%d", count);
+ purple_notify_user_info_add_pair_html(user_info,
+ _("Total Buddies"), tmp2);
}
tmp = purple_notify_user_info_get_text_with_newline(user_info, "\n");
@@ -3968,7 +4058,7 @@ GdkPixbuf *
pidgin_blist_get_emblem(PurpleBlistNode *node)
{
PurpleBuddy *buddy = NULL;
- struct _pidgin_blist_node *gtknode = node->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(node);
PurplePlugin *prpl;
PurplePluginProtocolInfo *prpl_info;
const char *name = NULL;
@@ -3991,10 +4081,10 @@ pidgin_blist_get_emblem(PurpleBlistNode *node)
return _pidgin_blist_get_cached_emblem(path);
}
- if (((struct _pidgin_blist_node*)(node->parent->ui_data))->contact_expanded) {
+ if (((struct _pidgin_blist_node*)purple_blist_node_get_ui_data(node->parent))->contact_expanded) {
if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"))
return NULL;
- return pidgin_create_prpl_icon(((PurpleBuddy*)node)->account, PIDGIN_PRPL_ICON_SMALL);
+ return pidgin_create_prpl_icon(purple_buddy_get_account((PurpleBuddy*)node), PIDGIN_PRPL_ICON_SMALL);
}
} else {
return NULL;
@@ -4002,7 +4092,7 @@ pidgin_blist_get_emblem(PurpleBlistNode *node)
g_return_val_if_fail(buddy != NULL, NULL);
- if (!purple_privacy_check(buddy->account, purple_buddy_get_name(buddy))) {
+ if (!purple_privacy_check(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy))) {
path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "blocked.png", NULL);
return _pidgin_blist_get_cached_emblem(path);
}
@@ -4038,7 +4128,7 @@ pidgin_blist_get_emblem(PurpleBlistNode *node)
return _pidgin_blist_get_cached_emblem(path);
}
- prpl = purple_find_prpl(purple_account_get_protocol_id(buddy->account));
+ prpl = purple_find_prpl(purple_account_get_protocol_id(purple_buddy_get_account(buddy)));
if (!prpl)
return NULL;
@@ -4075,7 +4165,7 @@ pidgin_blist_get_status_icon(PurpleBlistNode *node, PidginStatusIconSize size)
{
GdkPixbuf *ret;
const char *icon = NULL;
- struct _pidgin_blist_node *gtknode = node->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(node);
struct _pidgin_blist_node *gtkbuddynode = NULL;
PurpleBuddy *buddy = NULL;
PurpleChat *chat = NULL;
@@ -4086,11 +4176,11 @@ pidgin_blist_get_status_icon(PurpleBlistNode *node, PidginStatusIconSize size)
if(!gtknode->contact_expanded) {
buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
if (buddy != NULL)
- gtkbuddynode = ((PurpleBlistNode*)buddy)->ui_data;
+ gtkbuddynode = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy));
}
} else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
buddy = (PurpleBuddy*)node;
- gtkbuddynode = node->ui_data;
+ gtkbuddynode = purple_blist_node_get_ui_data(node);
} else if(PURPLE_BLIST_NODE_IS_CHAT(node)) {
chat = (PurpleChat*)node;
} else {
@@ -4102,9 +4192,9 @@ pidgin_blist_get_status_icon(PurpleBlistNode *node, PidginStatusIconSize size)
PurplePlugin *prpl;
if(buddy)
- account = buddy->account;
+ account = purple_buddy_get_account(buddy);
else
- account = chat->account;
+ account = purple_chat_get_account(chat);
prpl = purple_find_prpl(purple_account_get_protocol_id(account));
if(!prpl)
@@ -4119,7 +4209,7 @@ pidgin_blist_get_status_icon(PurpleBlistNode *node, PidginStatusIconSize size)
if(conv != NULL) {
PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
if (gtkconv == NULL && size == PIDGIN_STATUS_ICON_SMALL) {
- PidginBlistNode *ui = buddy->node.ui_data;
+ PidginBlistNode *ui = purple_blist_node_get_ui_data(&(buddy->node));
if (ui == NULL || (ui->conv.flags & PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE))
return gtk_widget_render_icon (GTK_WIDGET(gtkblist->treeview),
PIDGIN_STOCK_STATUS_MESSAGE, icon_size, "GtkTreeView");
@@ -4203,7 +4293,7 @@ pidgin_blist_get_name_markup(PurpleBuddy *b, gboolean selected, gboolean aliased
PidginBlistTheme *theme;
if (conv != NULL) {
- PidginBlistNode *ui = b->node.ui_data;
+ PidginBlistNode *ui = purple_blist_node_get_ui_data(&(b->node));
if (ui) {
if (ui->conv.flags & PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE)
hidden_conv = TRUE;
@@ -4237,12 +4327,12 @@ pidgin_blist_get_name_markup(PurpleBuddy *b, gboolean selected, gboolean aliased
if (!aliased || biglist) {
/* Status Info */
- prpl = purple_find_prpl(purple_account_get_protocol_id(b->account));
+ prpl = purple_find_prpl(purple_account_get_protocol_id(purple_buddy_get_account(b)));
if (prpl != NULL)
prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
- if (prpl_info && prpl_info->status_text && b->account->gc) {
+ if (prpl_info && prpl_info->status_text && purple_account_get_connection(purple_buddy_get_account(b))) {
char *tmp = prpl_info->status_text(b);
const char *end;
@@ -4393,7 +4483,7 @@ static void pidgin_blist_restore_position(void)
/* if the window exists, is hidden, we're saving positions, and the
* position is sane... */
if (gtkblist && gtkblist->window &&
- !GTK_WIDGET_VISIBLE(gtkblist->window) && blist_width != 0) {
+ !gtk_widget_get_visible(gtkblist->window) && blist_width != 0) {
blist_x = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/x");
blist_y = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/y");
@@ -4423,7 +4513,7 @@ static gboolean pidgin_blist_refresh_timer(PurpleBuddyList *list)
PurpleBlistNode *gnode, *cnode;
if (gtk_blist_visibility == GDK_VISIBILITY_FULLY_OBSCURED
- || !GTK_WIDGET_VISIBLE(gtkblist->window))
+ || !gtk_widget_get_visible(gtkblist->window))
return TRUE;
for(gnode = list->root; gnode; gnode = gnode->next) {
@@ -4437,7 +4527,7 @@ static gboolean pidgin_blist_refresh_timer(PurpleBuddyList *list)
if (buddy &&
purple_presence_is_idle(purple_buddy_get_presence(buddy)))
- pidgin_blist_update_contact(list, (PurpleBlistNode*)buddy);
+ pidgin_blist_update_contact(list, PURPLE_BLIST_NODE(buddy));
}
}
}
@@ -4448,7 +4538,7 @@ static gboolean pidgin_blist_refresh_timer(PurpleBuddyList *list)
static void pidgin_blist_hide_node(PurpleBuddyList *list, PurpleBlistNode *node, gboolean update)
{
- struct _pidgin_blist_node *gtknode = (struct _pidgin_blist_node *)node->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(node);
GtkTreeIter iter;
if (!gtknode || !gtknode->row || !gtkblist)
@@ -4469,12 +4559,13 @@ static void pidgin_blist_hide_node(PurpleBuddyList *list, PurpleBlistNode *node,
static const char *require_connection[] =
{
- N_("/Buddies/New Instant Message..."),
- N_("/Buddies/Join a Chat..."),
- N_("/Buddies/Get User Info..."),
- N_("/Buddies/Add Buddy..."),
- N_("/Buddies/Add Chat..."),
- N_("/Buddies/Add Group..."),
+ "/BList/BuddiesMenu/NewInstantMessage",
+ "/BList/BuddiesMenu/JoinAChat",
+ "/BList/BuddiesMenu/GetUserInfo",
+ "/BList/BuddiesMenu/AddBuddy",
+ "/BList/BuddiesMenu/AddChat",
+ "/BList/BuddiesMenu/AddGroup",
+ "/BList/ToolsMenu/Privacy",
};
static const int require_connection_size = sizeof(require_connection)
@@ -4487,7 +4578,7 @@ static const int require_connection_size = sizeof(require_connection)
static void
update_menu_bar(PidginBuddyList *gtkblist)
{
- GtkWidget *widget;
+ GtkAction *action;
gboolean sensitive;
int i;
@@ -4499,21 +4590,18 @@ update_menu_bar(PidginBuddyList *gtkblist)
for (i = 0; i < require_connection_size; i++)
{
- widget = gtk_item_factory_get_widget(gtkblist->ift, require_connection[i]);
- gtk_widget_set_sensitive(widget, sensitive);
+ action = gtk_ui_manager_get_action(gtkblist->ui, require_connection[i]);
+ gtk_action_set_sensitive(action, sensitive);
}
- widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Buddies/Join a Chat..."));
- gtk_widget_set_sensitive(widget, pidgin_blist_joinchat_is_showable());
+ action = gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/JoinAChat");
+ gtk_action_set_sensitive(action, pidgin_blist_joinchat_is_showable());
- widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Buddies/Add Chat..."));
- gtk_widget_set_sensitive(widget, pidgin_blist_joinchat_is_showable());
+ action = gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/AddChat");
+ gtk_action_set_sensitive(action, pidgin_blist_joinchat_is_showable());
- widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Privacy"));
- gtk_widget_set_sensitive(widget, sensitive);
-
- widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Room List"));
- gtk_widget_set_sensitive(widget, pidgin_roomlist_is_showable());
+ action = gtk_ui_manager_get_action(gtkblist->ui, "/BList/ToolsMenu/RoomList");
+ gtk_action_set_sensitive(action, pidgin_roomlist_is_showable());
}
static void
@@ -4597,6 +4685,7 @@ static void
conversation_updated_cb(PurpleConversation *conv, PurpleConvUpdateType type,
PidginBuddyList *gtkblist)
{
+ PurpleAccount *account = purple_conversation_get_account(conv);
GList *convs = NULL;
GList *ims, *chats;
GList *l = NULL;
@@ -4604,10 +4693,10 @@ conversation_updated_cb(PurpleConversation *conv, PurpleConvUpdateType type,
if (type != PURPLE_CONV_UPDATE_UNSEEN)
return;
- if(conv->account != NULL && conv->name != NULL) {
- PurpleBuddy *buddy = purple_find_buddy(conv->account, conv->name);
+ if(account != NULL && purple_conversation_get_name(conv) != NULL) {
+ PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv));
if(buddy != NULL)
- pidgin_blist_update_buddy(NULL, (PurpleBlistNode *)buddy, TRUE);
+ pidgin_blist_update_buddy(NULL, PURPLE_BLIST_NODE(buddy), TRUE);
}
if (gtkblist->menutrayicon) {
@@ -4687,7 +4776,7 @@ static void
written_msg_update_ui_cb(PurpleAccount *account, const char *who, const char *message,
PurpleConversation *conv, PurpleMessageFlags flag, PurpleBlistNode *node)
{
- PidginBlistNode *ui = node->ui_data;
+ PidginBlistNode *ui = purple_blist_node_get_ui_data(node);
if (ui->conv.conv != conv || !pidgin_conv_is_hidden(PIDGIN_CONVERSATION(conv)) ||
!(flag & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_RECV)))
return;
@@ -4703,7 +4792,7 @@ written_msg_update_ui_cb(PurpleAccount *account, const char *who, const char *me
static void
displayed_msg_update_ui_cb(PidginConversation *gtkconv, PurpleBlistNode *node)
{
- PidginBlistNode *ui = node->ui_data;
+ PidginBlistNode *ui = purple_blist_node_get_ui_data(node);
if (ui->conv.conv != gtkconv->active_conv)
return;
ui->conv.flags &= ~(PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE |
@@ -4714,13 +4803,15 @@ displayed_msg_update_ui_cb(PidginConversation *gtkconv, PurpleBlistNode *node)
static void
conversation_created_cb(PurpleConversation *conv, PidginBuddyList *gtkblist)
{
- switch (conv->type) {
+ PurpleAccount *account = purple_conversation_get_account(conv);
+
+ switch (purple_conversation_get_type(conv)) {
case PURPLE_CONV_TYPE_IM:
{
- GSList *buddies = purple_find_buddies(conv->account, conv->name);
+ GSList *buddies = purple_find_buddies(account, purple_conversation_get_name(conv));
while (buddies) {
PurpleBlistNode *buddy = buddies->data;
- struct _pidgin_blist_node *ui = buddy->ui_data;
+ struct _pidgin_blist_node *ui = purple_blist_node_get_ui_data(buddy);
buddies = g_slist_delete_link(buddies, buddies);
if (!ui)
continue;
@@ -4738,11 +4829,11 @@ conversation_created_cb(PurpleConversation *conv, PidginBuddyList *gtkblist)
break;
case PURPLE_CONV_TYPE_CHAT:
{
- PurpleChat *chat = purple_blist_find_chat(conv->account, conv->name);
+ PurpleChat *chat = purple_blist_find_chat(account, purple_conversation_get_name(conv));
struct _pidgin_blist_node *ui;
if (!chat)
break;
- ui = chat->node.ui_data;
+ ui = purple_blist_node_get_ui_data(&(chat->node));
if (!ui)
break;
ui->conv.conv = conv;
@@ -4770,8 +4861,6 @@ static void pidgin_blist_new_list(PurpleBuddyList *blist)
PidginBuddyList *gtkblist;
gtkblist = g_new0(PidginBuddyList, 1);
- gtkblist->connection_errors = g_hash_table_new_full(g_direct_hash,
- g_direct_equal, NULL, g_free);
gtkblist->priv = g_new0(PidginBuddyListPrivate, 1);
blist->ui_data = gtkblist;
@@ -4779,7 +4868,7 @@ static void pidgin_blist_new_list(PurpleBuddyList *blist)
static void pidgin_blist_new_node(PurpleBlistNode *node)
{
- node->ui_data = g_new0(struct _pidgin_blist_node, 1);
+ purple_blist_node_set_ui_data(node, g_new0(struct _pidgin_blist_node, 1));
}
gboolean pidgin_blist_node_is_contact_expanded(PurpleBlistNode *node)
@@ -4792,7 +4881,7 @@ gboolean pidgin_blist_node_is_contact_expanded(PurpleBlistNode *node)
g_return_val_if_fail(PURPLE_BLIST_NODE_IS_CONTACT(node), FALSE);
- return ((struct _pidgin_blist_node *)node->ui_data)->contact_expanded;
+ return ((struct _pidgin_blist_node *)purple_blist_node_get_ui_data(node))->contact_expanded;
}
enum {
@@ -4804,12 +4893,6 @@ enum {
NUM_TARGETS
};
-static const char *
-item_factory_translate_func (const char *path, gpointer func_data)
-{
- return _((char *)path);
-}
-
void pidgin_blist_setup_sort_methods()
{
const char *id;
@@ -4848,7 +4931,7 @@ static void _prefs_change_redo_list(const char *name, PurplePrefType type,
struct _pidgin_blist_node *gtknode;
GtkTreePath *path;
- gtknode = node->ui_data;
+ gtknode = purple_blist_node_get_ui_data(node);
if (gtknode && gtknode->row)
{
path = gtk_tree_row_reference_get_path(gtknode->row);
@@ -5085,7 +5168,6 @@ static void
generic_error_destroy_cb(GtkObject *dialog,
PurpleAccount *account)
{
- g_hash_table_remove(gtkblist->connection_errors, account);
/* If the error dialog is being destroyed in response to the
* account-error-changed signal, we don't want to clear the current
* error.
@@ -5356,12 +5438,6 @@ update_account_error_state(PurpleAccount *account,
if (old == NULL && new == NULL)
return;
- /* For backwards compatibility: */
- if (new)
- pidgin_blist_update_account_error_state(account, new->description);
- else
- pidgin_blist_update_account_error_state(account, NULL);
-
if (new != NULL)
pidgin_blist_select_notebook_page(gtkblist);
@@ -5427,18 +5503,6 @@ show_initial_account_errors(PidginBuddyList *gtkblist)
}
}
-void
-pidgin_blist_update_account_error_state(PurpleAccount *account, const char *text)
-{
- /* connection_errors isn't actually used anywhere; it's just kept in
- * sync with reality in case a plugin uses it.
- */
- if (text == NULL)
- g_hash_table_remove(gtkblist->connection_errors, account);
- else
- g_hash_table_insert(gtkblist->connection_errors, account, g_strdup(text));
-}
-
static gboolean
paint_headline_hbox (GtkWidget *widget,
GdkEventExpose *event,
@@ -5478,8 +5542,28 @@ static void
headline_style_set (GtkWidget *widget,
GtkStyle *prev_style)
{
- GtkTooltips *tooltips;
GtkStyle *style;
+#if GTK_CHECK_VERSION(2,12,0)
+ GtkWidget *window;
+
+ if (gtkblist->changing_style)
+ return;
+
+ /* This is a hack needed to use the tooltip background colour */
+ window = gtk_window_new(GTK_WINDOW_POPUP);
+ gtk_widget_set_name(window, "gtk-tooltip");
+ gtk_widget_ensure_style(window);
+ style = gtk_widget_get_style(window);
+
+ gtkblist->changing_style = TRUE;
+ gtk_widget_set_style(gtkblist->headline_hbox, style);
+ gtkblist->changing_style = FALSE;
+
+ gtk_widget_destroy(window);
+
+ gtk_widget_queue_draw(gtkblist->headline_hbox);
+#else
+ GtkTooltips *tooltips;
if (gtkblist->changing_style)
return;
@@ -5488,9 +5572,6 @@ headline_style_set (GtkWidget *widget,
g_object_ref_sink (tooltips);
gtk_tooltips_force_window (tooltips);
-#if GTK_CHECK_VERSION(2, 12, 0)
- gtk_widget_set_name (tooltips->tip_window, "gtk-tooltips");
-#endif
gtk_widget_ensure_style (tooltips->tip_window);
style = gtk_widget_get_style (tooltips->tip_window);
@@ -5499,6 +5580,7 @@ headline_style_set (GtkWidget *widget,
gtkblist->changing_style = FALSE;
g_object_unref (tooltips);
+#endif
}
/******************************************/
@@ -5735,6 +5817,8 @@ static void pidgin_blist_show(PurpleBuddyList *list)
GtkWidget *close;
char *pretty, *tmp;
const char *theme_name;
+ GtkActionGroup *action_group;
+ GError *error;
GtkAccelGroup *accel_group;
GtkTreeSelection *selection;
GtkTargetEntry dte[] = {{"PURPLE_BLIST_NODE", GTK_TARGET_SAME_APP, DRAG_ROW},
@@ -5784,27 +5868,45 @@ static void pidgin_blist_show(PurpleBuddyList *list)
gtk_widget_add_events(gtkblist->window, GDK_VISIBILITY_NOTIFY_MASK);
/******************************* Menu bar *************************************/
- accel_group = gtk_accel_group_new();
- gtk_window_add_accel_group(GTK_WINDOW (gtkblist->window), accel_group);
- g_object_unref(accel_group);
- gtkblist->ift = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<PurpleMain>", accel_group);
- gtk_item_factory_set_translate_func(gtkblist->ift,
- (GtkTranslateFunc)item_factory_translate_func,
- NULL, NULL);
- gtk_item_factory_create_items(gtkblist->ift, sizeof(blist_menu) / sizeof(*blist_menu),
- blist_menu, NULL);
+ action_group = gtk_action_group_new("BListActions");
+ gtk_action_group_add_actions(action_group,
+ blist_menu_entries,
+ G_N_ELEMENTS(blist_menu_entries),
+ GTK_WINDOW(gtkblist->window));
+ gtk_action_group_add_toggle_actions(action_group,
+ blist_menu_toggle_entries,
+ G_N_ELEMENTS(blist_menu_toggle_entries),
+ GTK_WINDOW(gtkblist->window));
+#ifdef ENABLE_NLS
+ gtk_action_group_set_translation_domain(action_group,
+ PACKAGE);
+#endif
+
+ gtkblist->ui = gtk_ui_manager_new();
+ gtk_ui_manager_insert_action_group(gtkblist->ui, action_group, 0);
+
+ accel_group = gtk_ui_manager_get_accel_group(gtkblist->ui);
+ gtk_window_add_accel_group(GTK_WINDOW(gtkblist->window), accel_group);
pidgin_load_accels();
g_signal_connect(G_OBJECT(accel_group), "accel-changed", G_CALLBACK(pidgin_save_accels_cb), NULL);
- menu = gtk_item_factory_get_widget(gtkblist->ift, "<PurpleMain>");
+ error = NULL;
+ if (!gtk_ui_manager_add_ui_from_string(gtkblist->ui, blist_menu, -1, &error))
+ {
+ g_message("building menus failed: %s", error->message);
+ g_error_free(error);
+ exit(EXIT_FAILURE);
+ }
+
+ menu = gtk_ui_manager_get_widget(gtkblist->ui, "/BList");
gtkblist->menutray = pidgin_menu_tray_new();
gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtkblist->menutray);
gtk_widget_show(gtkblist->menutray);
gtk_widget_show(menu);
gtk_box_pack_start(GTK_BOX(gtkblist->main_vbox), menu, FALSE, FALSE, 0);
- accountmenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Accounts"));
-
+ menu = gtk_ui_manager_get_widget(gtkblist->ui, "/BList/AccountsMenu");
+ accountmenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu));
/****************************** Notebook *************************************/
gtkblist->notebook = gtk_notebook_new();
@@ -5861,8 +5963,6 @@ static void pidgin_blist_show(PurpleBuddyList *list)
NULL);
gtk_widget_set_name(gtkblist->headline_hbox, "gtk-tooltips");
- gtkblist->headline_close = gtk_widget_render_icon(ebox, GTK_STOCK_CLOSE,
- gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC), NULL);
gtkblist->hand_cursor = gdk_cursor_new (GDK_HAND2);
gtkblist->arrow_cursor = gdk_cursor_new (GDK_LEFT_PTR);
@@ -5969,19 +6069,10 @@ static void pidgin_blist_show(PurpleBuddyList *list)
gtkblist->scrollbook = pidgin_scroll_book_new();
gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->scrollbook, FALSE, FALSE, 0);
- /* Create an vbox which holds the scrollbook which is actually used to
- * display connection errors. The vbox needs to still exist for
- * backwards compatibility.
- */
- gtkblist->error_buttons = gtk_vbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->error_buttons, FALSE, FALSE, 0);
- gtk_container_set_border_width(GTK_CONTAINER(gtkblist->error_buttons), 0);
-
priv->error_scrollbook = PIDGIN_SCROLL_BOOK(pidgin_scroll_book_new());
- gtk_box_pack_start(GTK_BOX(gtkblist->error_buttons),
+ gtk_box_pack_start(GTK_BOX(gtkblist->vbox),
GTK_WIDGET(priv->error_scrollbook), FALSE, FALSE, 0);
-
/* Add the statusbox */
gtkblist->statusbox = pidgin_status_box_new();
gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->statusbox, FALSE, TRUE, 0);
@@ -5992,26 +6083,26 @@ static void pidgin_blist_show(PurpleBuddyList *list)
/* set the Show Offline Buddies option. must be done
* after the treeview or faceprint gets mad. -Robot101
*/
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Offline Buddies"))),
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/ShowMenu/ShowOffline")),
purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies"));
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Empty Groups"))),
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/ShowMenu/ShowEmptyGroups")),
purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_empty_groups"));
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Tools/Mute Sounds"))),
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/ToolsMenu/MuteSounds")),
purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/sound/mute"));
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Buddy Details"))),
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/ShowMenu/ShowBuddyDetails")),
purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"));
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Idle Times"))),
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/ShowMenu/ShowIdleTimes")),
purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_idle_time"));
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Protocol Icons"))),
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/ShowMenu/ShowProtocolIcons")),
purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"));
if(!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"), "none"))
- gtk_widget_set_sensitive(gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Mute Sounds")), FALSE);
+ gtk_action_set_sensitive(gtk_ui_manager_get_action(gtkblist->ui, "/BList/ToolsMenu/MuteSounds"), FALSE);
/* Update some dynamic things */
update_menu_bar(gtkblist);
@@ -6153,7 +6244,7 @@ pidgin_blist_update_refresh_timeout()
}
static gboolean get_iter_from_node(PurpleBlistNode *node, GtkTreeIter *iter) {
- struct _pidgin_blist_node *gtknode = (struct _pidgin_blist_node *)node->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(node);
GtkTreePath *path;
if (!gtknode) {
@@ -6182,7 +6273,7 @@ static gboolean get_iter_from_node(PurpleBlistNode *node, GtkTreeIter *iter) {
static void pidgin_blist_remove(PurpleBuddyList *list, PurpleBlistNode *node)
{
- struct _pidgin_blist_node *gtknode = node->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(node);
purple_request_close_with_handle(node);
@@ -6204,9 +6295,9 @@ static void pidgin_blist_remove(PurpleBuddyList *list, PurpleBlistNode *node)
if(gtknode->recent_signonoff_timer > 0)
purple_timeout_remove(gtknode->recent_signonoff_timer);
- purple_signals_disconnect_by_handle(node->ui_data);
- g_free(node->ui_data);
- node->ui_data = NULL;
+ purple_signals_disconnect_by_handle(gtknode);
+ g_free(gtknode);
+ purple_blist_node_set_ui_data(node, NULL);
}
}
@@ -6250,8 +6341,8 @@ static void pidgin_blist_selection_changed(GtkTreeSelection *selection, gpointer
static gboolean insert_node(PurpleBuddyList *list, PurpleBlistNode *node, GtkTreeIter *iter)
{
- GtkTreeIter parent_iter, cur, *curptr = NULL;
- struct _pidgin_blist_node *gtknode = node->ui_data;
+ GtkTreeIter parent_iter = {0, NULL, NULL, NULL}, cur, *curptr = NULL;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(node);
GtkTreePath *newpath;
if(!iter)
@@ -6273,7 +6364,7 @@ static gboolean insert_node(PurpleBuddyList *list, PurpleBlistNode *node, GtkTre
gtk_tree_row_reference_free(gtknode->row);
} else {
pidgin_blist_new_node(node);
- gtknode = (struct _pidgin_blist_node *)node->ui_data;
+ gtknode = purple_blist_node_get_ui_data(node);
}
newpath = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel),
@@ -6291,7 +6382,7 @@ static gboolean insert_node(PurpleBuddyList *list, PurpleBlistNode *node, GtkTre
if(node->parent) {
GtkTreePath *expand = NULL;
- struct _pidgin_blist_node *gtkparentnode = node->parent->ui_data;
+ struct _pidgin_blist_node *gtkparentnode = purple_blist_node_get_ui_data(node->parent);
if(PURPLE_BLIST_NODE_IS_GROUP(node->parent)) {
if(!purple_blist_node_get_bool(node->parent, "collapsed"))
@@ -6313,12 +6404,12 @@ static gboolean pidgin_blist_group_has_show_offline_buddy(PurpleGroup *group)
{
PurpleBlistNode *gnode, *cnode, *bnode;
- gnode = (PurpleBlistNode *)group;
+ gnode = PURPLE_BLIST_NODE(group);
for(cnode = gnode->child; cnode; cnode = cnode->next) {
if(PURPLE_BLIST_NODE_IS_CONTACT(cnode)) {
for(bnode = cnode->child; bnode; bnode = bnode->next) {
PurpleBuddy *buddy = (PurpleBuddy *)bnode;
- if (purple_account_is_connected(buddy->account) &&
+ if (purple_account_is_connected(purple_buddy_get_account(buddy)) &&
purple_blist_node_get_bool(bnode, "show_offline"))
return TRUE;
}
@@ -6458,7 +6549,7 @@ static char *pidgin_get_group_title(PurpleBlistNode *gnode, gboolean expanded)
text_color = selected ? NULL : theme_font_get_color_default(pair, NULL);
text_font = theme_font_get_face_default(pair, "");
- esc = g_markup_escape_text(group->name, -1);
+ esc = g_markup_escape_text(purple_group_get_name(group), -1);
if (text_color) {
mark = g_strdup_printf("<span foreground='%s' font_desc='%s'><b>%s</b>%s%s%s</span>",
text_color, text_font,
@@ -6485,7 +6576,7 @@ static void buddy_node(PurpleBuddy *buddy, GtkTreeIter *iter, PurpleBlistNode *n
GdkColor *color = NULL;
char *mark;
char *idle = NULL;
- gboolean expanded = ((struct _pidgin_blist_node *)(node->parent->ui_data))->contact_expanded;
+ gboolean expanded = ((struct _pidgin_blist_node *)purple_blist_node_get_ui_data(node->parent))->contact_expanded;
gboolean selected = (gtkblist->selected_node == node);
gboolean biglist = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons");
PidginBlistTheme *theme;
@@ -6493,12 +6584,12 @@ static void buddy_node(PurpleBuddy *buddy, GtkTreeIter *iter, PurpleBlistNode *n
if (editing_blist)
return;
- status = pidgin_blist_get_status_icon((PurpleBlistNode*)buddy,
+ status = pidgin_blist_get_status_icon(PURPLE_BLIST_NODE(buddy),
biglist ? PIDGIN_STATUS_ICON_LARGE : PIDGIN_STATUS_ICON_SMALL);
/* Speed it up if we don't want buddy icons. */
if(biglist)
- avatar = pidgin_blist_get_buddy_icon((PurpleBlistNode *)buddy, TRUE, TRUE);
+ avatar = pidgin_blist_get_buddy_icon(PURPLE_BLIST_NODE(buddy), TRUE, TRUE);
else
avatar = NULL;
@@ -6509,7 +6600,7 @@ static void buddy_node(PurpleBuddy *buddy, GtkTreeIter *iter, PurpleBlistNode *n
do_alphashift(avatar, 77);
}
- emblem = pidgin_blist_get_emblem((PurpleBlistNode*) buddy);
+ emblem = pidgin_blist_get_emblem(PURPLE_BLIST_NODE(buddy));
mark = pidgin_blist_get_name_markup(buddy, selected, TRUE);
theme = pidgin_blist_get_theme();
@@ -6550,7 +6641,7 @@ static void buddy_node(PurpleBuddy *buddy, GtkTreeIter *iter, PurpleBlistNode *n
}
}
- prpl_icon = pidgin_create_prpl_icon(buddy->account, PIDGIN_PRPL_ICON_SMALL);
+ prpl_icon = pidgin_create_prpl_icon(purple_buddy_get_account(buddy), PIDGIN_PRPL_ICON_SMALL);
if (theme != NULL)
color = pidgin_blist_theme_get_contact_color(theme);
@@ -6621,7 +6712,7 @@ static void pidgin_blist_update_contact(PurpleBuddyList *list, PurpleBlistNode *
if(!insert_node(list, cnode, &iter))
return;
- gtknode = (struct _pidgin_blist_node *)cnode->ui_data;
+ gtknode = purple_blist_node_get_ui_data(cnode);
if(gtknode->contact_expanded) {
GdkPixbuf *status;
@@ -6698,7 +6789,7 @@ static void pidgin_blist_update_buddy(PurpleBuddyList *list, PurpleBlistNode *no
/* First things first, update the contact */
pidgin_blist_update_contact(list, node);
- gtkparentnode = (struct _pidgin_blist_node *)node->parent->ui_data;
+ gtkparentnode = purple_blist_node_get_ui_data(node->parent);
if (gtkparentnode->contact_expanded && buddy_is_displayable(buddy))
{
@@ -6729,7 +6820,7 @@ static void pidgin_blist_update_chat(PurpleBuddyList *list, PurpleBlistNode *nod
chat = (PurpleChat*)node;
- if(purple_account_is_connected(chat->account)) {
+ if(purple_account_is_connected(purple_chat_get_account(chat))) {
GtkTreeIter iter;
GdkPixbuf *status, *avatar, *emblem, *prpl_icon;
const gchar *color, *font;
@@ -6748,7 +6839,7 @@ static void pidgin_blist_update_chat(PurpleBuddyList *list, PurpleBlistNode *nod
if (!insert_node(list, node, &iter))
return;
- ui = node->ui_data;
+ ui = purple_blist_node_get_ui_data(node);
conv = ui->conv.conv;
if (conv && pidgin_conv_is_hidden(PIDGIN_CONVERSATION(conv))) {
hidden = (ui->conv.flags & PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE);
@@ -6793,7 +6884,7 @@ static void pidgin_blist_update_chat(PurpleBuddyList *list, PurpleBlistNode *nod
g_free(mark);
mark = tmp;
- prpl_icon = pidgin_create_prpl_icon(chat->account, PIDGIN_PRPL_ICON_SMALL);
+ prpl_icon = pidgin_create_prpl_icon(purple_chat_get_account(chat), PIDGIN_PRPL_ICON_SMALL);
if (theme != NULL)
bgcolor = pidgin_blist_theme_get_contact_color(theme);
@@ -6834,10 +6925,10 @@ static void pidgin_blist_update(PurpleBuddyList *list, PurpleBlistNode *node)
if(!gtkblist || !gtkblist->treeview || !node)
return;
- if (node->ui_data == NULL)
+ if (purple_blist_node_get_ui_data(node) == NULL)
pidgin_blist_new_node(node);
- switch(node->type) {
+ switch (purple_blist_node_get_type(node)) {
case PURPLE_BLIST_GROUP_NODE:
pidgin_blist_update_group(list, node);
break;
@@ -6867,9 +6958,6 @@ static void pidgin_blist_destroy(PurpleBuddyList *list)
purple_signals_disconnect_by_handle(gtkblist);
- if (gtkblist->headline_close)
- gdk_pixbuf_unref(gtkblist->headline_close);
-
gtk_widget_destroy(gtkblist->window);
pidgin_blist_tooltip_destroy();
@@ -6881,14 +6969,13 @@ static void pidgin_blist_destroy(PurpleBuddyList *list)
if (gtkblist->drag_timeout)
g_source_remove(gtkblist->drag_timeout);
- g_hash_table_destroy(gtkblist->connection_errors);
gtkblist->refresh_timer = 0;
gtkblist->timeout = 0;
gtkblist->drag_timeout = 0;
gtkblist->window = gtkblist->vbox = gtkblist->treeview = NULL;
g_object_unref(G_OBJECT(gtkblist->treemodel));
gtkblist->treemodel = NULL;
- g_object_unref(G_OBJECT(gtkblist->ift));
+ g_object_unref(G_OBJECT(gtkblist->ui));
g_object_unref(G_OBJECT(gtkblist->empty_avatar));
gdk_cursor_unref(gtkblist->hand_cursor);
@@ -6913,7 +7000,7 @@ static void pidgin_blist_set_visible(PurpleBuddyList *list, gboolean show)
return;
if (show) {
- if(!PIDGIN_WINDOW_ICONIFIED(gtkblist->window) && !GTK_WIDGET_VISIBLE(gtkblist->window))
+ if(!PIDGIN_WINDOW_ICONIFIED(gtkblist->window) && !gtk_widget_get_visible(gtkblist->window))
purple_signal_emit(pidgin_blist_get_handle(), "gtkblist-unhiding", gtkblist);
pidgin_blist_restore_position();
gtk_window_present(GTK_WINDOW(gtkblist->window));
@@ -6922,7 +7009,7 @@ static void pidgin_blist_set_visible(PurpleBuddyList *list, gboolean show)
purple_signal_emit(pidgin_blist_get_handle(), "gtkblist-hiding", gtkblist);
gtk_widget_hide(gtkblist->window);
} else {
- if (!GTK_WIDGET_VISIBLE(gtkblist->window))
+ if (!gtk_widget_get_visible(gtkblist->window))
gtk_widget_show(gtkblist->window);
gtk_window_iconify(GTK_WINDOW(gtkblist->window));
}
@@ -6933,7 +7020,6 @@ static GList *
groups_tree(void)
{
static GList *list = NULL;
- char *tmp2;
PurpleGroup *g;
PurpleBlistNode *gnode;
@@ -6953,8 +7039,7 @@ groups_tree(void)
if (PURPLE_BLIST_NODE_IS_GROUP(gnode))
{
g = (PurpleGroup *)gnode;
- tmp2 = g->name;
- list = g_list_append(list, tmp2);
+ list = g_list_append(list, (char *) purple_group_get_name(g));
}
}
}
@@ -6984,6 +7069,7 @@ add_buddy_select_account_cb(GObject *w, PurpleAccount *account,
invite_enabled = FALSE;
gtk_widget_set_sensitive(data->entry_for_invite, invite_enabled);
+ set_sensitive_if_input_buddy_cb(data->entry, data);
}
static void
@@ -7037,11 +7123,11 @@ add_buddy_cb(GtkWidget *w, int resp, PidginAddBuddyData *data)
purple_blist_add_buddy(b, NULL, g, NULL);
}
- purple_account_add_buddy_with_invite(account, b, invite);
+ purple_account_add_buddy(account, b, invite);
/* Offer to merge people with the same alias. */
if (whoalias != NULL && g != NULL)
- gtk_blist_auto_personize((PurpleBlistNode *)g, whoalias);
+ gtk_blist_auto_personize(PURPLE_BLIST_NODE(g), whoalias);
/*
* XXX
@@ -7109,8 +7195,8 @@ pidgin_blist_request_add_buddy(PurpleAccount *account, const char *username,
gtk_entry_set_activates_default (GTK_ENTRY(data->entry), TRUE);
g_signal_connect(G_OBJECT(data->entry), "changed",
- G_CALLBACK(pidgin_set_sensitive_if_input),
- data->rq_data.window);
+ G_CALLBACK(set_sensitive_if_input_buddy_cb),
+ data);
data->entry_for_alias = gtk_entry_new();
pidgin_add_widget_to_vbox(data->rq_data.vbox, _("(Optional) A_lias:"),
@@ -7189,10 +7275,10 @@ add_chat_cb(GtkWidget *w, PidginAddChatData *data)
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);
+ purple_blist_node_set_bool(PURPLE_BLIST_NODE(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);
+ purple_blist_node_set_bool(PURPLE_BLIST_NODE(chat), "gtk-persistent", TRUE);
}
gtk_widget_destroy(data->chat_data.rq_data.window);
@@ -7229,11 +7315,13 @@ pidgin_blist_request_add_chat(PurpleAccount *account, PurpleGroup *group,
GList *l;
PurpleConnection *gc;
GtkBox *vbox;
+ PurplePluginProtocolInfo *prpl_info = NULL;
if (account != NULL) {
gc = purple_account_get_connection(account);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
- if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->join_chat == NULL) {
+ if (prpl_info->join_chat == NULL) {
purple_notify_error(gc, NULL, _("This protocol does not support chat rooms."), NULL);
return;
}
@@ -7241,8 +7329,9 @@ pidgin_blist_request_add_chat(PurpleAccount *account, PurpleGroup *group,
/* Find an account with chat capabilities */
for (l = purple_connections_get_all(); l != NULL; l = l->next) {
gc = (PurpleConnection *)l->data;
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
- if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->join_chat != NULL) {
+ if (prpl_info->join_chat != NULL) {
account = purple_connection_get_account(gc);
break;
}
@@ -7286,7 +7375,7 @@ pidgin_blist_request_add_chat(PurpleAccount *account, PurpleGroup *group,
if (name != NULL)
gtk_widget_grab_focus(data->alias_entry);
- data->group_combo = pidgin_text_combo_box_entry_new(group ? group->name : NULL, groups_tree());
+ data->group_combo = pidgin_text_combo_box_entry_new(group ? purple_group_get_name(group) : NULL, groups_tree());
pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Group:"),
data->chat_data.rq_data.sg, data->group_combo,
TRUE, NULL);
@@ -7327,7 +7416,7 @@ void
pidgin_blist_toggle_visibility()
{
if (gtkblist && gtkblist->window) {
- if (GTK_WIDGET_VISIBLE(gtkblist->window)) {
+ if (gtk_widget_get_visible(gtkblist->window)) {
/* make the buddy list visible if it is iconified or if it is
* obscured and not currently focused (the focus part ensures
* that we do something reasonable if the buddy list is obscured
@@ -7392,7 +7481,7 @@ pidgin_blist_set_headline(const char *text, GdkPixbuf *pixbuf, GCallback callbac
static void
set_urgent(void)
{
- if (gtkblist->window && !GTK_WIDGET_HAS_FOCUS(gtkblist->window))
+ if (gtkblist->window && !gtk_widget_has_focus(gtkblist->window))
pidgin_set_urgent(GTK_WINDOW(gtkblist->window), TRUE);
}
@@ -7443,11 +7532,11 @@ static gboolean autojoin_cb(PurpleConnection *gc, gpointer data)
chat = (PurpleChat *)cnode;
- if(chat->account != account)
+ if(purple_chat_get_account(chat) != account)
continue;
- if (purple_blist_node_get_bool((PurpleBlistNode*)chat, "gtk-autojoin"))
- serv_join_chat(gc, chat->components);
+ if (purple_blist_node_get_bool(PURPLE_BLIST_NODE(chat), "gtk-autojoin"))
+ serv_join_chat(gc, purple_chat_get_components(chat));
}
}
@@ -7464,25 +7553,25 @@ pidgin_blist_get_handle() {
static gboolean buddy_signonoff_timeout_cb(PurpleBuddy *buddy)
{
- struct _pidgin_blist_node *gtknode = ((PurpleBlistNode*)buddy)->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy));
gtknode->recent_signonoff = FALSE;
gtknode->recent_signonoff_timer = 0;
- pidgin_blist_update(NULL, (PurpleBlistNode*)buddy);
+ pidgin_blist_update(NULL, PURPLE_BLIST_NODE(buddy));
return FALSE;
}
static void buddy_signonoff_cb(PurpleBuddy *buddy)
{
- struct _pidgin_blist_node *gtknode;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy));
- if(!((PurpleBlistNode*)buddy)->ui_data) {
- pidgin_blist_new_node((PurpleBlistNode*)buddy);
+ if(!gtknode) {
+ pidgin_blist_new_node(PURPLE_BLIST_NODE(buddy));
}
- gtknode = ((PurpleBlistNode*)buddy)->ui_data;
+ gtknode = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy));
gtknode->recent_signonoff = TRUE;
@@ -7849,7 +7938,7 @@ static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *bli
PurpleBuddy *buddy;
for (n = node->child; n; n = n->next) {
buddy = (PurpleBuddy*)n;
- activity_score += purple_log_get_activity_score(PURPLE_LOG_IM, buddy->name, buddy->account);
+ activity_score += purple_log_get_activity_score(PURPLE_LOG_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy));
}
buddy_name = purple_contact_get_alias((PurpleContact*)node);
} else if(PURPLE_BLIST_NODE_IS_CHAT(node)) {
@@ -7885,7 +7974,7 @@ static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *bli
if(PURPLE_BLIST_NODE_IS_CONTACT(n)) {
for (n2 = n->child; n2; n2 = n2->next) {
buddy = (PurpleBuddy*)n2;
- this_log_activity_score += purple_log_get_activity_score(PURPLE_LOG_IM, buddy->name, buddy->account);
+ this_log_activity_score += purple_log_get_activity_score(PURPLE_LOG_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy));
}
this_buddy_name = purple_contact_get_alias((PurpleContact*)n);
} else {
@@ -7927,40 +8016,43 @@ plugin_act(GtkObject *obj, PurplePluginAction *pam)
}
static void
-build_plugin_actions(GtkWidget *menu, PurplePlugin *plugin,
- gpointer context)
+build_plugin_actions(GtkActionGroup *action_group, GString *ui, char *parent,
+ PurplePlugin *plugin, gpointer context)
{
- GtkWidget *menuitem;
+ GtkAction *menuaction;
PurplePluginAction *action = NULL;
GList *actions, *l;
+ char *name;
+ int count = 0;
actions = PURPLE_PLUGIN_ACTIONS(plugin, context);
- for (l = actions; l != NULL; l = l->next)
- {
- if (l->data)
- {
- action = (PurplePluginAction *) l->data;
+ for (l = actions; l != NULL; l = l->next) {
+ if (l->data) {
+ action = (PurplePluginAction *)l->data;
action->plugin = plugin;
action->context = context;
- menuitem = gtk_menu_item_new_with_label(action->label);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+ name = g_strdup_printf("%s-action-%d", parent, count++);
+ menuaction = gtk_action_new(name, action->label, NULL, NULL);
+ gtk_action_group_add_action(action_group, menuaction);
+ g_string_append_printf(ui, "<menuitem action='%s'/>", name);
- g_signal_connect(G_OBJECT(menuitem), "activate",
+ g_signal_connect(G_OBJECT(menuaction), "activate",
G_CALLBACK(plugin_act), action);
- g_object_set_data_full(G_OBJECT(menuitem), "plugin_action",
+ g_object_set_data_full(G_OBJECT(menuaction), "plugin_action",
action,
(GDestroyNotify)purple_plugin_action_free);
- gtk_widget_show(menuitem);
+ g_free(name);
}
else
- pidgin_separator(menu);
+ g_string_append(ui, "<separator/>");
}
g_list_free(actions);
}
+
static void
modify_account_cb(GtkWidget *widget, gpointer data)
{
@@ -7987,14 +8079,12 @@ disable_account_cb(GtkCheckMenuItem *widget, gpointer data)
purple_account_set_enabled(account, PIDGIN_UI, FALSE);
}
-
-
void
pidgin_blist_update_accounts_menu(void)
{
- GtkWidget *menuitem = NULL, *submenu = NULL;
- GtkAccelGroup *accel_group = NULL;
- GList *l = NULL, *accounts = NULL;
+ GtkWidget *menuitem, *submenu;
+ GtkAccelGroup *accel_group;
+ GList *l, *accounts;
gboolean disabled_accounts = FALSE;
gboolean enabled_accounts = FALSE;
@@ -8005,10 +8095,12 @@ pidgin_blist_update_accounts_menu(void)
for (l = gtk_container_get_children(GTK_CONTAINER(accountmenu)); l; l = g_list_delete_link(l, l)) {
menuitem = l->data;
- if (menuitem != gtk_item_factory_get_widget(gtkblist->ift, N_("/Accounts/Manage Accounts")))
+ if (menuitem != gtk_ui_manager_get_widget(gtkblist->ui, "/BList/AccountsMenu/ManageAccounts"))
gtk_widget_destroy(menuitem);
}
+ accel_group = gtk_menu_get_accel_group(GTK_MENU(accountmenu));
+
for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
char *buf = NULL;
GtkWidget *image = NULL;
@@ -8017,14 +8109,14 @@ pidgin_blist_update_accounts_menu(void)
account = accounts->data;
- if(!purple_account_get_enabled(account, PIDGIN_UI)) {
+ if (!purple_account_get_enabled(account, PIDGIN_UI)) {
if (!disabled_accounts) {
menuitem = gtk_menu_item_new_with_label(_("Enable Account"));
gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem);
submenu = gtk_menu_new();
gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
- gtk_menu_set_accel_path(GTK_MENU(submenu), N_("<PurpleMain>/Accounts/Enable Account"));
+ gtk_menu_set_accel_path(GTK_MENU(submenu), "<Actions>/BListActions/EnableAccount");
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
disabled_accounts = TRUE;
@@ -8034,9 +8126,9 @@ pidgin_blist_update_accounts_menu(void)
purple_account_get_protocol_name(account), ")", NULL);
menuitem = gtk_image_menu_item_new_with_label(buf);
g_free(buf);
+
pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
- if (pixbuf != NULL)
- {
+ if (pixbuf != NULL) {
if (!purple_account_is_connected(account))
gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE);
image = gtk_image_new_from_pixbuf(pixbuf);
@@ -8044,9 +8136,11 @@ pidgin_blist_update_accounts_menu(void)
gtk_widget_show(image);
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
}
+
g_signal_connect(G_OBJECT(menuitem), "activate",
G_CALLBACK(enable_account_cb), account);
gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
+
} else {
enabled_accounts = TRUE;
}
@@ -8058,7 +8152,6 @@ pidgin_blist_update_accounts_menu(void)
}
pidgin_separator(accountmenu);
- accel_group = gtk_menu_get_accel_group(GTK_MENU(accountmenu));
for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
char *buf = NULL;
@@ -8078,8 +8171,9 @@ pidgin_blist_update_accounts_menu(void)
buf = g_strconcat(purple_account_get_username(account), " (",
purple_account_get_protocol_name(account), ")", NULL);
menuitem = gtk_image_menu_item_new_with_label(buf);
- accel_path_buf = g_strconcat(N_("<PurpleMain>/Accounts/"), buf, NULL);
+ accel_path_buf = g_strconcat("<Actions>/AccountActions/", buf, NULL);
g_free(buf);
+
pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
if (pixbuf != NULL) {
if (!purple_account_is_connected(account))
@@ -8090,6 +8184,7 @@ pidgin_blist_update_accounts_menu(void)
gtk_widget_show(image);
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
}
+
gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem);
submenu = gtk_menu_new();
@@ -8098,7 +8193,6 @@ pidgin_blist_update_accounts_menu(void)
g_free(accel_path_buf);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
-
menuitem = gtk_menu_item_new_with_mnemonic(_("_Edit Account"));
g_signal_connect(G_OBJECT(menuitem), "activate",
G_CALLBACK(modify_account_cb), account);
@@ -8107,14 +8201,14 @@ pidgin_blist_update_accounts_menu(void)
pidgin_separator(submenu);
gc = purple_account_get_connection(account);
- plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
+ plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? purple_connection_get_prpl(gc) : NULL;
prpl_info = plugin ? PURPLE_PLUGIN_PROTOCOL_INFO(plugin) : NULL;
if (prpl_info &&
(PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_moods) ||
PURPLE_PLUGIN_HAS_ACTIONS(plugin))) {
if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_moods) &&
- gc->flags & PURPLE_CONNECTION_SUPPORT_MOODS) {
+ (purple_connection_get_flags(gc) & PURPLE_CONNECTION_SUPPORT_MOODS)) {
if (purple_account_get_status(account, "mood")) {
menuitem = gtk_menu_item_new_with_mnemonic(_("Set _Mood..."));
@@ -8123,8 +8217,37 @@ pidgin_blist_update_accounts_menu(void)
gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
}
}
+
if (PURPLE_PLUGIN_HAS_ACTIONS(plugin)) {
- build_plugin_actions(submenu, plugin, gc);
+ GtkWidget *menuitem;
+ PurplePluginAction *action = NULL;
+ GList *actions, *l;
+
+ actions = PURPLE_PLUGIN_ACTIONS(plugin, gc);
+
+ for (l = actions; l != NULL; l = l->next)
+ {
+ if (l->data)
+ {
+ action = (PurplePluginAction *) l->data;
+ action->plugin = plugin;
+ action->context = gc;
+
+ menuitem = gtk_menu_item_new_with_label(action->label);
+ gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
+
+ g_signal_connect(G_OBJECT(menuitem), "activate",
+ G_CALLBACK(plugin_act), action);
+ g_object_set_data_full(G_OBJECT(menuitem), "plugin_action",
+ action,
+ (GDestroyNotify)purple_plugin_action_free);
+ gtk_widget_show(menuitem);
+ }
+ else
+ pidgin_separator(submenu);
+ }
+
+ g_list_free(actions);
}
} else {
menuitem = gtk_menu_item_new_with_label(_("No actions available"));
@@ -8139,36 +8262,45 @@ pidgin_blist_update_accounts_menu(void)
G_CALLBACK(disable_account_cb), account);
gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
}
+
gtk_widget_show_all(accountmenu);
}
-static GList *plugin_submenus = NULL;
+static guint plugins_merge_id;
+static GtkActionGroup *plugins_action_group = NULL;
void
pidgin_blist_update_plugin_actions(void)
{
- GtkWidget *menuitem, *submenu;
PurplePlugin *plugin = NULL;
GList *l;
- GtkAccelGroup *accel_group;
- GtkWidget *pluginmenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools"));
+ GtkAction *action;
+ GString *plugins_ui;
+ gchar *ui_string;
+ int count = 0;
- g_return_if_fail(pluginmenu != NULL);
+ if ((gtkblist == NULL) || (gtkblist->ui == NULL))
+ return;
- /* Remove old plugin action submenus from the Tools menu */
- for (l = plugin_submenus; l; l = l->next)
- gtk_widget_destroy(GTK_WIDGET(l->data));
- g_list_free(plugin_submenus);
- plugin_submenus = NULL;
+ /* Clear the old menu */
+ if (plugins_action_group) {
+ gtk_ui_manager_remove_ui(gtkblist->ui, plugins_merge_id);
+ gtk_ui_manager_remove_action_group(gtkblist->ui, plugins_action_group);
+ g_object_unref(G_OBJECT(plugins_action_group));
+ }
- accel_group = gtk_menu_get_accel_group(GTK_MENU(pluginmenu));
+ plugins_action_group = gtk_action_group_new("PluginActions");
+#ifdef ENABLE_NLS
+ gtk_action_group_set_translation_domain(plugins_action_group, PACKAGE);
+#endif
+ plugins_ui = g_string_new(NULL);
/* Add a submenu for each plugin with custom actions */
for (l = purple_plugins_get_loaded(); l; l = l->next) {
- char *path;
+ char *name;
- plugin = (PurplePlugin *) l->data;
+ plugin = (PurplePlugin *)l->data;
if (PURPLE_IS_PROTOCOL_PLUGIN(plugin))
continue;
@@ -8176,28 +8308,34 @@ pidgin_blist_update_plugin_actions(void)
if (!PURPLE_PLUGIN_HAS_ACTIONS(plugin))
continue;
- menuitem = gtk_image_menu_item_new_with_label(_(plugin->info->name));
- gtk_menu_shell_append(GTK_MENU_SHELL(pluginmenu), menuitem);
+ name = g_strdup_printf("plugin%d", count);
+ action = gtk_action_new(name, plugin->info->name, NULL, NULL);
+ gtk_action_group_add_action(plugins_action_group, action);
+ g_string_append_printf(plugins_ui, "<menu action='%s'>", name);
- plugin_submenus = g_list_append(plugin_submenus, menuitem);
+ build_plugin_actions(plugins_action_group, plugins_ui, name, plugin, NULL);
- submenu = gtk_menu_new();
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
-
- gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
- path = g_strdup_printf("%s/Tools/%s", gtkblist->ift->path, plugin->info->name);
- gtk_menu_set_accel_path(GTK_MENU(submenu), path);
- g_free(path);
+ g_string_append(plugins_ui, "</menu>");
+ count++;
- build_plugin_actions(submenu, plugin, NULL);
+ g_free(name);
}
- gtk_widget_show_all(pluginmenu);
+
+ ui_string = g_strconcat("<ui><menubar action='BList'><menu action='ToolsMenu'><placeholder name='PluginActions'>",
+ plugins_ui->str,
+ "</placeholder></menu></menubar></ui>",
+ NULL);
+ gtk_ui_manager_insert_action_group(gtkblist->ui, plugins_action_group, 1);
+ plugins_merge_id = gtk_ui_manager_add_ui_from_string(gtkblist->ui, ui_string, -1, NULL);
+
+ g_string_free(plugins_ui, TRUE);
+ g_free(ui_string);
}
static void
-sortmethod_act(GtkCheckMenuItem *checkmenuitem, char *id)
+sortmethod_act(GtkRadioAction *action, GtkRadioAction *current, char *id)
{
- if (gtk_check_menu_item_get_active(checkmenuitem))
+ if (action == current)
{
pidgin_set_cursor(gtkblist->window, GDK_WATCH);
/* This is redundant. I think. */
@@ -8211,40 +8349,58 @@ sortmethod_act(GtkCheckMenuItem *checkmenuitem, char *id)
void
pidgin_blist_update_sort_methods(void)
{
- GtkWidget *menuitem = NULL, *activeitem = NULL;
PidginBlistSortMethod *method = NULL;
GList *l;
GSList *sl = NULL;
- GtkWidget *sortmenu;
const char *m = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/sort_type");
- if ((gtkblist == NULL) || (gtkblist->ift == NULL))
- return;
-
- g_return_if_fail(m != NULL);
+ GtkRadioAction *action;
+ GString *ui_string;
- sortmenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Buddies/Sort Buddies"));
-
- if (sortmenu == NULL)
+ if ((gtkblist == NULL) || (gtkblist->ui == NULL))
return;
/* Clear the old menu */
- for (l = gtk_container_get_children(GTK_CONTAINER(sortmenu)); l; l = g_list_delete_link(l, l)) {
- menuitem = l->data;
- gtk_widget_destroy(GTK_WIDGET(menuitem));
+ if (sort_action_group) {
+ gtk_ui_manager_remove_ui(gtkblist->ui, sort_merge_id);
+ gtk_ui_manager_remove_action_group(gtkblist->ui, sort_action_group);
+ g_object_unref(G_OBJECT(sort_action_group));
}
+ sort_action_group = gtk_action_group_new("SortMethods");
+#ifdef ENABLE_NLS
+ gtk_action_group_set_translation_domain(sort_action_group, PACKAGE);
+#endif
+ ui_string = g_string_new("<ui><menubar name='BList'>"
+ "<menu action='BuddiesMenu'><menu action='SortMenu'>");
+
for (l = pidgin_blist_sort_methods; l; l = l->next) {
- method = (PidginBlistSortMethod *) l->data;
- menuitem = gtk_radio_menu_item_new_with_label(sl, _(method->name));
- if (g_str_equal(m, method->id))
- activeitem = menuitem;
- sl = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem));
- gtk_menu_shell_append(GTK_MENU_SHELL(sortmenu), menuitem);
- g_signal_connect(G_OBJECT(menuitem), "toggled",
- G_CALLBACK(sortmethod_act), method->id);
- gtk_widget_show(menuitem);
- }
- if (activeitem)
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(activeitem), TRUE);
+ method = (PidginBlistSortMethod *)l->data;
+
+ g_string_append_printf(ui_string, "<menuitem action='%s'/>", method->id);
+ action = gtk_radio_action_new(method->id,
+ method->name,
+ NULL,
+ NULL,
+ 0);
+ gtk_action_group_add_action_with_accel(sort_action_group, GTK_ACTION(action), NULL);
+
+ gtk_radio_action_set_group(action, sl);
+ sl = gtk_radio_action_get_group(action);
+
+ if (!strcmp(m, method->id))
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE);
+ else
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), FALSE);
+
+ g_signal_connect(G_OBJECT(action), "changed",
+ G_CALLBACK(sortmethod_act), method->id);
+ }
+
+ g_string_append(ui_string, "</menu></menu></menubar></ui>");
+ gtk_ui_manager_insert_action_group(gtkblist->ui, sort_action_group, 1);
+ sort_merge_id = gtk_ui_manager_add_ui_from_string(gtkblist->ui, ui_string->str, -1, NULL);
+
+ g_string_free(ui_string, TRUE);
}
+
diff --git a/pidgin/gtkblist.h b/pidgin/gtkblist.h
index a3d5f26c4f..8777180b39 100644
--- a/pidgin/gtkblist.h
+++ b/pidgin/gtkblist.h
@@ -82,19 +82,10 @@ struct _PidginBuddyList {
GtkCellRenderer *text_rend;
- GtkItemFactory *ift;
+ GtkUIManager *ui;
GtkWidget *menutray; /**< The menu tray widget. */
GtkWidget *menutrayicon; /**< The menu tray icon. */
- /** Caches connection error messages; keys are #PurpleAccount and
- * values are non-@c NULL <tt>const char *</tt>s containing localised
- * error messages. (If an account does not have an error, it will not
- * appear in the table.)
- * @deprecated in favour of purple_account_get_current_error(), which also
- * gives you the #PurpleConnectionError value.
- */
- GHashTable *connection_errors;
-
guint refresh_timer; /**< The timer for refreshing every 30 seconds */
guint timeout; /**< The timeout for the tooltip. */
@@ -119,13 +110,11 @@ struct _PidginBuddyList {
GtkWidget *headline_hbox; /**< Hbox for headline notification */
GtkWidget *headline_label; /**< Label for headline notifications */
GtkWidget *headline_image; /**< Image for headline notifications */
- GdkPixbuf *headline_close; /**< @deprecated: Close image for closing the headline without triggering the callback */
GCallback headline_callback; /**< Callback for headline notifications */
gpointer headline_data; /**< User data for headline notifications */
GDestroyNotify headline_destroy; /**< Callback to use for destroying the headline-data */
gboolean changing_style; /**< True when changing GTK+ theme style */
- GtkWidget *error_buttons; /**< Box containing the connection error buttons */
GtkWidget *statusbox; /**< The status selector dropdown */
GdkPixbuf *empty_avatar; /**< A 32x32 transparent pixbuf */
@@ -136,6 +125,8 @@ struct _PidginBuddyList {
#define PIDGIN_IS_PIDGIN_BLIST(list) \
(purple_blist_get_ui_ops() == pidgin_blist_get_ui_ops())
+G_BEGIN_DECLS
+
/**************************************************************************
* @name GTK+ Buddy List API
**************************************************************************/
@@ -259,8 +250,6 @@ void pidgin_blist_add_alert(GtkWidget *widget);
* Sets the current theme for Pidgin to use
*
* @param theme the new theme to use
- *
- * @since 2.6.0
*/
void pidgin_blist_set_theme(PidginBlistTheme *theme);
@@ -268,8 +257,6 @@ void pidgin_blist_set_theme(PidginBlistTheme *theme);
* Gets Pidgin's current buddy list theme
*
* @returns the current theme
- *
- * @since 2.6.0
*/
PidginBlistTheme *pidgin_blist_get_theme(void);
@@ -370,20 +357,6 @@ void pidgin_append_blist_node_proto_menu (GtkWidget *menu, PurpleConnection *gc,
void pidgin_append_blist_node_extended_menu(GtkWidget *menu, PurpleBlistNode *node);
/**
- * Was used by the connection API to tell the blist if an account has a
- * connection error or no longer has a connection error, but the blist now does
- * this itself with the @ref account-error-changed signal.
- *
- * @param account The account that either has a connection error
- * or no longer has a connection error.
- * @param message The connection error message, or NULL if this
- * account is no longer in an error state.
- * @deprecated There was no good reason for code other than gtkconn to call
- * this.
- */
-void pidgin_blist_update_account_error_state(PurpleAccount *account, const char *message);
-
-/**
* Sets a headline notification
*
* This is currently used for mail notification, but could theoretically be used for anything.
@@ -405,8 +378,6 @@ void pidgin_blist_set_headline(const char *text, GdkPixbuf *pixbuf, GCallback ca
* @param selected Whether this buddy is selected. If TRUE, the markup will not change the color.
* @param aliased TRUE to return the appropriate alias of this buddy, FALSE to return its username and status information
* @return The markup for this buddy
- *
- * @since 2.1.0
*/
gchar *pidgin_blist_get_name_markup(PurpleBuddy *buddy, gboolean selected, gboolean aliased);
@@ -418,17 +389,14 @@ gchar *pidgin_blist_get_name_markup(PurpleBuddy *buddy, gboolean selected, gbool
*
* @param node The buddy list node to show a tooltip for
* @param widget The widget to draw the tooltip on
- *
- * @since 2.1.0
*/
void pidgin_blist_draw_tooltip(PurpleBlistNode *node, GtkWidget *widget);
/**
* Destroys the current (if any) Buddy List tooltip
- *
- * @since 2.1.0
*/
void pidgin_blist_tooltip_destroy(void);
+G_END_DECLS
#endif /* _PIDGINBLIST_H_ */
diff --git a/pidgin/gtkcellrendererexpander.c b/pidgin/gtkcellrendererexpander.c
index a5bb6c8a98..10d899e977 100644
--- a/pidgin/gtkcellrendererexpander.c
+++ b/pidgin/gtkcellrendererexpander.c
@@ -250,8 +250,13 @@ static void pidgin_cell_renderer_expander_render(GtkCellRenderer *cell,
state = GTK_STATE_INSENSITIVE;
else if (flags & GTK_CELL_RENDERER_PRELIT)
state = GTK_STATE_PRELIGHT;
+#if GTK_CHECK_VERSION(2,18,0)
+ else if (gtk_widget_has_focus (widget) && flags & GTK_CELL_RENDERER_SELECTED)
+ state = GTK_STATE_ACTIVE;
+#else
else if (GTK_WIDGET_HAS_FOCUS (widget) && flags & GTK_CELL_RENDERER_SELECTED)
state = GTK_STATE_ACTIVE;
+#endif
else
state = GTK_STATE_NORMAL;
diff --git a/pidgin/gtkcellrendererexpander.h b/pidgin/gtkcellrendererexpander.h
index 983a9bd84a..d95b9bdaee 100644
--- a/pidgin/gtkcellrendererexpander.h
+++ b/pidgin/gtkcellrendererexpander.h
@@ -23,11 +23,6 @@
#include <gtk/gtk.h>
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
#define PIDGIN_TYPE_GTK_CELL_RENDERER_EXPANDER (pidgin_cell_renderer_expander_get_type())
#define PIDGIN_CELL_RENDERER_EXPANDER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PIDGIN_TYPE_GTK_CELL_RENDERER_EXPANDER, PidginCellRendererExpander))
#define PIDGIN_CELL_RENDERER_EXPANDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PURPLE_TYPE_GTK_CELL_RENDERER_EXPANDER, PidginCellRendererExpanderClass))
@@ -48,12 +43,11 @@ struct _PidginCellRendererExpanderClass {
GtkCellRendererClass parent_class;
};
+G_BEGIN_DECLS
+
GType pidgin_cell_renderer_expander_get_type (void);
GtkCellRenderer *pidgin_cell_renderer_expander_new (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+G_END_DECLS
#endif /* _PIDGINCELLRENDEREREXPANDER_H_ */
diff --git a/pidgin/gtkcertmgr.c b/pidgin/gtkcertmgr.c
index 381ff2c72b..bfac2752d1 100644
--- a/pidgin/gtkcertmgr.c
+++ b/pidgin/gtkcertmgr.c
@@ -310,6 +310,7 @@ tls_peers_mgmt_info_cb(GtkWidget *button, gpointer data)
GtkTreeModel *model;
gchar *id;
PurpleCertificate *crt;
+ char *title;
/* See if things are selected */
if (!gtk_tree_selection_get_selected(select, &model, &iter)) {
@@ -326,10 +327,20 @@ tls_peers_mgmt_info_cb(GtkWidget *button, gpointer data)
g_return_if_fail(crt);
/* Fire the notification */
- purple_certificate_display_x509(crt);
+ title = g_strdup_printf(_("Certificate Information for %s"), id);
+ purple_request_certificate(tpm_dat, title, NULL, NULL, crt,
+ _("OK"), G_CALLBACK(purple_certificate_destroy),
+ _("Cancel"), G_CALLBACK(purple_certificate_destroy),
+ crt);
g_free(id);
- purple_certificate_destroy(crt);
+ g_free(title);
+}
+
+static void
+tls_peers_mgmt_activated_cb(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *column, gpointer data)
+{
+ tls_peers_mgmt_info_cb(NULL, NULL);
}
static void
@@ -452,6 +463,9 @@ tls_peers_mgmt_build(void)
g_signal_connect(G_OBJECT(select), "changed",
G_CALLBACK(tls_peers_mgmt_select_chg_cb), NULL);
+ g_signal_connect(G_OBJECT(listview), "row-activated",
+ G_CALLBACK(tls_peers_mgmt_activated_cb), NULL);
+
gtk_box_pack_start(GTK_BOX(mgmt_widget),
pidgin_make_scrollable(GTK_WIDGET(listview), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1),
TRUE, TRUE, /* Take up lots of space */
@@ -471,9 +485,8 @@ tls_peers_mgmt_build(void)
gtk_widget_show(bbox);
/* Import button */
- /* TODO: This is the wrong stock button */
tpm_dat->importbutton = importbutton =
- gtk_button_new_from_stock(GTK_STOCK_ADD);
+ gtk_button_new_from_stock(GTK_STOCK_OPEN);
gtk_box_pack_start(GTK_BOX(bbox), importbutton, FALSE, FALSE, 0);
gtk_widget_show(importbutton);
g_signal_connect(G_OBJECT(importbutton), "clicked",
@@ -481,9 +494,8 @@ tls_peers_mgmt_build(void)
/* Export button */
- /* TODO: This is the wrong stock button */
tpm_dat->exportbutton = exportbutton =
- gtk_button_new_from_stock(GTK_STOCK_SAVE);
+ gtk_button_new_from_stock(GTK_STOCK_SAVE_AS);
gtk_box_pack_start(GTK_BOX(bbox), exportbutton, FALSE, FALSE, 0);
gtk_widget_show(exportbutton);
g_signal_connect(G_OBJECT(exportbutton), "clicked",
diff --git a/pidgin/gtkcertmgr.h b/pidgin/gtkcertmgr.h
index 8971be41e1..f64968ce2e 100644
--- a/pidgin/gtkcertmgr.h
+++ b/pidgin/gtkcertmgr.h
@@ -43,6 +43,8 @@ struct _PidginCertificateManager {
gchar *label;
};
+G_BEGIN_DECLS
+
/**************************************************************************/
/** @name Certificate Manager API */
/**************************************************************************/
@@ -59,4 +61,6 @@ void pidgin_certmgr_hide(void);
/*@}*/
+G_END_DECLS
+
#endif /* _PIDGINCERTMGR_H_ */
diff --git a/pidgin/gtkconn.c b/pidgin/gtkconn.c
index 6fa8e3b085..70a60f0268 100644
--- a/pidgin/gtkconn.c
+++ b/pidgin/gtkconn.c
@@ -136,9 +136,9 @@ do_signon(gpointer data)
}
static void
-pidgin_connection_report_disconnect_reason (PurpleConnection *gc,
- PurpleConnectionError reason,
- const char *text)
+pidgin_connection_report_disconnect(PurpleConnection *gc,
+ PurpleConnectionError reason,
+ const char *text)
{
PurpleAccount *account = NULL;
PidginAutoRecon *info;
@@ -215,10 +215,9 @@ static PurpleConnectionUiOps conn_ui_ops =
pidgin_connection_connected,
pidgin_connection_disconnected,
pidgin_connection_notice,
- NULL, /* report_disconnect */
pidgin_connection_network_connected,
pidgin_connection_network_disconnected,
- pidgin_connection_report_disconnect_reason,
+ pidgin_connection_report_disconnect,
NULL,
NULL,
NULL
diff --git a/pidgin/gtkconn.h b/pidgin/gtkconn.h
index 9fda617259..27408b2039 100644
--- a/pidgin/gtkconn.h
+++ b/pidgin/gtkconn.h
@@ -25,6 +25,8 @@
#ifndef _PIDGINCONN_H_
#define _PIDGINCONN_H_
+G_BEGIN_DECLS
+
/**************************************************************************/
/** @name GTK+ Connection API */
/**************************************************************************/
@@ -56,4 +58,6 @@ void pidgin_connection_init(void);
*/
void pidgin_connection_uninit(void);
+G_END_DECLS
+
#endif /* _PIDGINCONN_H_ */
diff --git a/pidgin/gtkconv-theme-loader.c b/pidgin/gtkconv-theme-loader.c
new file mode 100644
index 0000000000..c2f8c02204
--- /dev/null
+++ b/pidgin/gtkconv-theme-loader.c
@@ -0,0 +1,294 @@
+/*
+ * PidginConvThemeLoader for 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.
+ *
+ * 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 "pidgin.h"
+#include "gtkconv-theme-loader.h"
+#include "gtkconv-theme.h"
+
+#include "xmlnode.h"
+#include "debug.h"
+
+/*****************************************************************************
+ * Conversation Theme Builder
+ *****************************************************************************/
+
+static GHashTable *
+read_info_plist(xmlnode *plist)
+{
+ GHashTable *info;
+ xmlnode *key, *value;
+ gboolean fail = FALSE;
+
+ info = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+
+ for (key = xmlnode_get_child(plist, "dict/key");
+ key;
+ key = xmlnode_get_next_twin(key)) {
+ char *keyname;
+ GValue *val;
+
+ ;
+ for (value = key->next; value && value->type != XMLNODE_TYPE_TAG; value = value->next)
+ ;
+ if (!value) {
+ fail = TRUE;
+ break;
+ }
+
+ val = g_new0(GValue, 1);
+ if (g_str_equal(value->name, "string")) {
+ g_value_init(val, G_TYPE_STRING);
+ g_value_take_string(val, xmlnode_get_data_unescaped(value));
+
+ } else if (g_str_equal(value->name, "true")) {
+ g_value_init(val, G_TYPE_BOOLEAN);
+ g_value_set_boolean(val, TRUE);
+
+ } else if (g_str_equal(value->name, "false")) {
+ g_value_init(val, G_TYPE_BOOLEAN);
+ g_value_set_boolean(val, FALSE);
+
+ } else if (g_str_equal(value->name, "real")) {
+ char *temp = xmlnode_get_data_unescaped(value);
+ g_value_init(val, G_TYPE_FLOAT);
+ g_value_set_float(val, atof(temp));
+ g_free(temp);
+
+ } else if (g_str_equal(value->name, "integer")) {
+ char *temp = xmlnode_get_data_unescaped(value);
+ g_value_init(val, G_TYPE_INT);
+ g_value_set_int(val, atoi(temp));
+ g_free(temp);
+
+ } else {
+ /* NOTE: We don't support array, data, date, or dict as values,
+ since they don't seem to be needed for styles. */
+ g_free(val);
+ fail = TRUE;
+ break;
+ }
+
+ keyname = xmlnode_get_data_unescaped(key);
+ g_hash_table_insert(info, keyname, val);
+ }
+
+ if (fail) {
+ g_hash_table_destroy(info);
+ info = NULL;
+ }
+
+ return info;
+}
+
+static gboolean
+pidgin_conv_loader_probe(const gchar *dir)
+{
+ gboolean result;
+ gchar *plist_file;
+
+ plist_file = g_build_filename(dir, "Contents", "Info.plist", NULL);
+ result = g_file_test(plist_file, G_FILE_TEST_IS_REGULAR);
+ g_free(plist_file);
+
+ return result;
+}
+
+static PurpleTheme *
+pidgin_conv_loader_build(const gchar *dir)
+{
+ PidginConvTheme *theme = NULL;
+ char *contents;
+ xmlnode *plist;
+ GHashTable *info;
+ GValue *val;
+ int MessageViewVersion;
+ const char *CFBundleName;
+ const char *CFBundleIdentifier;
+ GDir *variants;
+ char *variant_dir;
+
+ g_return_val_if_fail(dir != NULL, NULL);
+
+ /* Load Info.plist for theme information */
+ contents = g_build_filename(dir, "Contents", NULL);
+ plist = xmlnode_from_file(contents, "Info.plist", "Info.plist", "gtkconv-theme-loader");
+ g_free(contents);
+ if (plist == NULL) {
+ purple_debug_error("gtkconv-theme-loader",
+ "Failed to load Contents/Info.plist in %s\n", dir);
+ return NULL;
+ }
+
+ info = read_info_plist(plist);
+ xmlnode_free(plist);
+ if (info == NULL) {
+ purple_debug_error("gtkconv-theme-loader",
+ "Failed to load Contents/Info.plist in %s\n", dir);
+ return NULL;
+ }
+
+ /* Check for required keys: CFBundleName */
+ val = g_hash_table_lookup(info, "CFBundleName");
+ if (!val || !G_VALUE_HOLDS_STRING(val)) {
+ purple_debug_error("gtkconv-theme-loader",
+ "%s/Contents/Info.plist missing required string key CFBundleName.\n",
+ dir);
+ g_hash_table_destroy(info);
+ return NULL;
+ }
+ CFBundleName = g_value_get_string(val);
+
+ /* Check for required keys: CFBundleIdentifier */
+ val = g_hash_table_lookup(info, "CFBundleIdentifier");
+ if (!val || !G_VALUE_HOLDS_STRING(val)) {
+ purple_debug_error("gtkconv-theme-loader",
+ "%s/Contents/Info.plist missing required string key CFBundleIdentifier.\n",
+ dir);
+ g_hash_table_destroy(info);
+ return NULL;
+ }
+ CFBundleIdentifier = g_value_get_string(val);
+
+ /* Check for required keys: MessageViewVersion */
+ val = g_hash_table_lookup(info, "MessageViewVersion");
+ if (!val || !G_VALUE_HOLDS_INT(val)) {
+ purple_debug_error("gtkconv-theme-loader",
+ "%s/Contents/Info.plist missing required integer key MessageViewVersion.\n",
+ dir);
+ g_hash_table_destroy(info);
+ return NULL;
+ }
+
+ MessageViewVersion = g_value_get_int(val);
+ if (MessageViewVersion < 3) {
+ purple_debug_error("gtkconv-theme-loader",
+ "%s is a legacy style (version %d) and will not be loaded.\n",
+ CFBundleName, MessageViewVersion);
+ g_hash_table_destroy(info);
+ return NULL;
+ }
+
+ theme = g_object_new(PIDGIN_TYPE_CONV_THEME,
+ "type", "conversation",
+ "name", CFBundleName,
+ "directory", dir,
+ "info", info, NULL);
+
+ /* Read list of variants */
+ variant_dir = g_build_filename(dir, "Contents", "Resources", "Variants", NULL);
+ variants = g_dir_open(variant_dir, 0, NULL);
+ g_free(variant_dir);
+
+ if (variants) {
+ char *prefname;
+ const char *default_variant = NULL;
+ const char *file;
+
+ /* Make sure prefs exist */
+ prefname = g_strdup_printf(PIDGIN_PREFS_ROOT "/conversations/themes/%s",
+ CFBundleIdentifier);
+ purple_prefs_add_none(prefname);
+ g_free(prefname);
+
+ /* Try user-set variant */
+ prefname = g_strdup_printf(PIDGIN_PREFS_ROOT "/conversations/themes/%s/variant",
+ CFBundleIdentifier);
+ if (purple_prefs_exists(prefname))
+ default_variant = purple_prefs_get_string(prefname);
+ g_free(prefname);
+
+ if (default_variant && *default_variant) {
+ pidgin_conversation_theme_set_variant(theme, default_variant);
+
+ } else {
+ /* Try theme default */
+ val = g_hash_table_lookup(info, "DefaultVariant");
+ if (val && G_VALUE_HOLDS_STRING(val)) {
+ default_variant = g_value_get_string(val);
+ if (default_variant && *default_variant)
+ pidgin_conversation_theme_set_variant(theme, default_variant);
+ else
+ default_variant = NULL;
+ } else
+ default_variant = NULL;
+ }
+
+ while ((file = g_dir_read_name(variants)) != NULL) {
+ const char *end = g_strrstr(file, ".css");
+ char *name;
+
+ if ((end == NULL) || (*(end + 4) != '\0'))
+ continue;
+
+ name = g_strndup(file, end - file);
+ pidgin_conversation_theme_add_variant(theme, name);
+
+ /* Set variant with first found */
+ if (!default_variant) {
+ pidgin_conversation_theme_set_variant(theme, name);
+ default_variant = name;
+ }
+ }
+
+ g_dir_close(variants);
+ }
+
+ return PURPLE_THEME(theme);
+}
+
+/******************************************************************************
+ * GObject Stuff
+ *****************************************************************************/
+
+static void
+pidgin_conv_theme_loader_class_init(PidginConvThemeLoaderClass *klass)
+{
+ PurpleThemeLoaderClass *loader_klass = PURPLE_THEME_LOADER_CLASS(klass);
+
+ loader_klass->purple_theme_loader_build = pidgin_conv_loader_build;
+ loader_klass->probe_directory = pidgin_conv_loader_probe;
+}
+
+
+GType
+pidgin_conversation_theme_loader_get_type(void)
+{
+ static GType type = 0;
+ if (type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PidginConvThemeLoaderClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc)pidgin_conv_theme_loader_class_init, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (PidginConvThemeLoader),
+ 0, /* n_preallocs */
+ NULL, /* instance_init */
+ NULL, /* value table */
+ };
+ type = g_type_register_static(PURPLE_TYPE_THEME_LOADER,
+ "PidginConvThemeLoader", &info, 0);
+ }
+ return type;
+}
+
diff --git a/pidgin/gtkconv-theme-loader.h b/pidgin/gtkconv-theme-loader.h
new file mode 100644
index 0000000000..09bdb75134
--- /dev/null
+++ b/pidgin/gtkconv-theme-loader.h
@@ -0,0 +1,72 @@
+/**
+ * @file gtkconv-theme-loader.h Pidgin Conversation Theme Loader Class API
+ */
+
+/* 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
+ * source distribution.
+ *
+ * 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
+ */
+
+#ifndef PIDGIN_CONV_THEME_LOADER_H
+#define PIDGIN_CONV_THEME_LOADER_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include "theme-loader.h"
+
+/**
+ * A pidgin conversation theme loader. Extends PurpleThemeLoader (theme-loader.h)
+ * This is a class designed to build conversation themes
+ *
+ * PidginConvThemeLoader is a GObject.
+ */
+typedef struct _PidginConvThemeLoader PidginConvThemeLoader;
+typedef struct _PidginConvThemeLoaderClass PidginConvThemeLoaderClass;
+
+#define PIDGIN_TYPE_CONV_THEME_LOADER (pidgin_conversation_theme_loader_get_type ())
+#define PIDGIN_CONV_THEME_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PIDGIN_TYPE_CONV_THEME_LOADER, PidginConvThemeLoader))
+#define PIDGIN_CONV_THEME_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PIDGIN_TYPE_CONV_THEME_LOADER, PidginConvThemeLoaderClass))
+#define PIDGIN_IS_CONV_THEME_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PIDGIN_TYPE_CONV_THEME_LOADER))
+#define PIDGIN_IS_CONV_THEME_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIDGIN_TYPE_CONV_THEME_LOADER))
+#define PIDGIN_CONV_THEME_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PIDGIN_TYPE_CONV_THEME_LOADER, PidginConvThemeLoaderClass))
+
+struct _PidginConvThemeLoader
+{
+ PurpleThemeLoader parent;
+};
+
+struct _PidginConvThemeLoaderClass
+{
+ PurpleThemeLoaderClass parent_class;
+};
+
+/**************************************************************************/
+/** @name Pidgin Conversation Theme-Loader API */
+/**************************************************************************/
+G_BEGIN_DECLS
+
+/**
+ * GObject foo.
+ * @internal.
+ */
+GType pidgin_conversation_theme_loader_get_type(void);
+
+G_END_DECLS
+#endif /* PIDGIN_CONV_THEME_LOADER_H */
+
diff --git a/pidgin/gtkconv-theme.c b/pidgin/gtkconv-theme.c
new file mode 100644
index 0000000000..0c5d08fc94
--- /dev/null
+++ b/pidgin/gtkconv-theme.c
@@ -0,0 +1,751 @@
+/*
+ * Conversation Themes for 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.
+ *
+ * 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 "gtkconv-theme.h"
+
+#include "conversation.h"
+#include "debug.h"
+#include "prefs.h"
+#include "xmlnode.h"
+
+#include "pidgin.h"
+#include "internal.h"
+#include "gtkconv.h"
+#include "gtkwebview.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#define PIDGIN_CONV_THEME_GET_PRIVATE(Gobject) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((Gobject), PIDGIN_TYPE_CONV_THEME, PidginConvThemePrivate))
+
+/******************************************************************************
+ * Structs
+ *****************************************************************************/
+
+typedef struct {
+ /* current config options */
+ char *variant; /* allowed to be NULL if there are no variants */
+ GList *variants;
+
+ /* Info.plist keys/values */
+ GHashTable *info;
+
+ /* caches */
+ char *template_html;
+ char *header_html;
+ char *footer_html;
+ char *topic_html;
+ char *status_html;
+ char *content_html;
+ char *incoming_content_html;
+ char *outgoing_content_html;
+ char *incoming_next_content_html;
+ char *outgoing_next_content_html;
+ char *incoming_context_html;
+ char *outgoing_context_html;
+ char *incoming_next_context_html;
+ char *outgoing_next_context_html;
+ char *basestyle_css;
+} PidginConvThemePrivate;
+
+/******************************************************************************
+ * Enums
+ *****************************************************************************/
+
+enum {
+ PROP_ZERO = 0,
+ PROP_INFO,
+ PROP_VARIANT,
+ PROP_LAST
+};
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+
+static GObjectClass *parent_class = NULL;
+#if GLIB_CHECK_VERSION(2,26,0)
+static GParamSpec *properties[PROP_LAST];
+#endif
+
+/******************************************************************************
+ * Helper Functions
+ *****************************************************************************/
+
+static const GValue *
+get_key(PidginConvThemePrivate *priv, const char *key, gboolean specific)
+{
+ GValue *val = NULL;
+
+ /* Try variant-specific key */
+ if (specific && priv->variant) {
+ char *name = g_strdup_printf("%s:%s", key, priv->variant);
+ val = g_hash_table_lookup(priv->info, name);
+ g_free(name);
+ }
+
+ /* Try generic key */
+ if (!val) {
+ val = g_hash_table_lookup(priv->info, key);
+ }
+
+ return val;
+}
+
+/* The template path can either come from the theme, or can
+ * be stock Template.html that comes with Pidgin */
+static char *
+get_template_path(const char *dir)
+{
+ char *file;
+
+ file = g_build_filename(dir, "Contents", "Resources", "Template.html", NULL);
+
+ if (!g_file_test(file, G_FILE_TEST_EXISTS)) {
+ g_free(file);
+ file = g_build_filename(DATADIR, "pidgin", "theme", "Template.html", NULL);
+ }
+
+ return file;
+}
+
+static const char *
+get_template_html(PidginConvThemePrivate *priv, const char *dir)
+{
+ char *file;
+
+ if (priv->template_html)
+ return priv->template_html;
+
+ file = get_template_path(dir);
+
+ if (!g_file_get_contents(file, &priv->template_html, NULL, NULL)) {
+ purple_debug_error("webkit", "Could not locate a Template.html (%s)\n", file);
+ priv->template_html = g_strdup("");
+ }
+ g_free(file);
+
+ return priv->template_html;
+}
+
+static const char *
+get_basestyle_css(PidginConvThemePrivate *priv, const char *dir)
+{
+ char *file;
+
+ if (priv->basestyle_css)
+ return priv->basestyle_css;
+
+ file = g_build_filename(dir, "Contents", "Resources", "main.css", NULL);
+ if (!g_file_get_contents(file, &priv->basestyle_css, NULL, NULL))
+ priv->basestyle_css = g_strdup("");
+ g_free(file);
+
+ return priv->basestyle_css;
+}
+
+static const char *
+get_header_html(PidginConvThemePrivate *priv, const char *dir)
+{
+ char *file;
+
+ if (priv->header_html)
+ return priv->header_html;
+
+ file = g_build_filename(dir, "Contents", "Resources", "Header.html", NULL);
+ if (!g_file_get_contents(file, &priv->header_html, NULL, NULL))
+ priv->header_html = g_strdup("");
+ g_free(file);
+
+ return priv->header_html;
+}
+
+static const char *
+get_footer_html(PidginConvThemePrivate *priv, const char *dir)
+{
+ char *file;
+
+ if (priv->footer_html)
+ return priv->footer_html;
+
+ file = g_build_filename(dir, "Contents", "Resources", "Footer.html", NULL);
+ if (!g_file_get_contents(file, &priv->footer_html, NULL, NULL))
+ priv->footer_html = g_strdup("");
+ g_free(file);
+
+ return priv->footer_html;
+}
+
+static const char *
+get_topic_html(PidginConvThemePrivate *priv, const char *dir)
+{
+ char *file;
+
+ if (priv->topic_html)
+ return priv->topic_html;
+
+ file = g_build_filename(dir, "Contents", "Resources", "Topic.html", NULL);
+ if (!g_file_get_contents(file, &priv->topic_html, NULL, NULL)) {
+ purple_debug_info("webkit", "%s could not find Resources/Topic.html\n", dir);
+ priv->topic_html = g_strdup("");
+ }
+ g_free(file);
+
+ return priv->topic_html;
+}
+
+static const char *
+get_content_html(PidginConvThemePrivate *priv, const char *dir)
+{
+ char *file;
+
+ if (priv->content_html)
+ return priv->content_html;
+
+ file = g_build_filename(dir, "Contents", "Resources", "Content.html", NULL);
+ if (!g_file_get_contents(file, &priv->content_html, NULL, NULL)) {
+ purple_debug_info("webkit", "%s did not have a Content.html\n", dir);
+ priv->content_html = g_strdup("");
+ }
+ g_free(file);
+
+ return priv->content_html;
+}
+
+static const char *
+get_status_html(PidginConvThemePrivate *priv, const char *dir)
+{
+ char *file;
+
+ if (priv->status_html)
+ return priv->status_html;
+
+ file = g_build_filename(dir, "Contents", "Resources", "Status.html", NULL);
+ if (!g_file_get_contents(file, &priv->status_html, NULL, NULL)) {
+ purple_debug_info("webkit", "%s could not find Resources/Status.html\n", dir);
+ priv->status_html = g_strdup(get_content_html(priv, dir));
+ }
+ g_free(file);
+
+ return priv->status_html;
+}
+
+static const char *
+get_incoming_content_html(PidginConvThemePrivate *priv, const char *dir)
+{
+ char *file;
+
+ if (priv->incoming_content_html)
+ return priv->incoming_content_html;
+
+ file = g_build_filename(dir, "Contents", "Resources", "Incoming", "Content.html", NULL);
+ if (!g_file_get_contents(file, &priv->incoming_content_html, NULL, NULL)) {
+ purple_debug_info("webkit", "%s did not have a Incoming/Content.html\n", dir);
+ priv->incoming_content_html = g_strdup(get_content_html(priv, dir));
+ }
+ g_free(file);
+
+ return priv->incoming_content_html;
+}
+
+static const char *
+get_incoming_next_content_html(PidginConvThemePrivate *priv, const char *dir)
+{
+ char *file;
+
+ if (priv->incoming_next_content_html)
+ return priv->incoming_next_content_html;
+
+ file = g_build_filename(dir, "Contents", "Resources", "Incoming", "NextContent.html", NULL);
+ if (!g_file_get_contents(file, &priv->incoming_next_content_html, NULL, NULL)) {
+ priv->incoming_next_content_html = g_strdup(get_incoming_content_html(priv, dir));
+ }
+ g_free(file);
+
+ return priv->incoming_next_content_html;
+}
+
+static const char *
+get_incoming_context_html(PidginConvThemePrivate *priv, const char *dir)
+{
+ char *file;
+
+ if (priv->incoming_context_html)
+ return priv->incoming_context_html;
+
+ file = g_build_filename(dir, "Contents", "Resources", "Incoming", "Context.html", NULL);
+ if (!g_file_get_contents(file, &priv->incoming_context_html, NULL, NULL)) {
+ purple_debug_info("webkit", "%s did not have a Incoming/Context.html\n", dir);
+ priv->incoming_context_html = g_strdup(get_incoming_content_html(priv, dir));
+ }
+ g_free(file);
+
+ return priv->incoming_context_html;
+}
+
+static const char *
+get_incoming_next_context_html(PidginConvThemePrivate *priv, const char *dir)
+{
+ char *file;
+
+ if (priv->incoming_next_context_html)
+ return priv->incoming_next_context_html;
+
+ file = g_build_filename(dir, "Contents", "Resources", "Incoming", "NextContext.html", NULL);
+ if (!g_file_get_contents(file, &priv->incoming_next_context_html, NULL, NULL)) {
+ priv->incoming_next_context_html = g_strdup(get_incoming_context_html(priv, dir));
+ }
+ g_free(file);
+
+ return priv->incoming_next_context_html;
+}
+
+static const char *
+get_outgoing_content_html(PidginConvThemePrivate *priv, const char *dir)
+{
+ char *file;
+
+ if (priv->outgoing_content_html)
+ return priv->outgoing_content_html;
+
+ file = g_build_filename(dir, "Contents", "Resources", "Outgoing", "Content.html", NULL);
+ if (!g_file_get_contents(file, &priv->outgoing_content_html, NULL, NULL)) {
+ priv->outgoing_content_html = g_strdup(get_incoming_content_html(priv, dir));
+ }
+ g_free(file);
+
+ return priv->outgoing_content_html;
+}
+
+static const char *
+get_outgoing_next_content_html(PidginConvThemePrivate *priv, const char *dir)
+{
+ char *file;
+
+ if (priv->outgoing_next_content_html)
+ return priv->outgoing_next_content_html;
+
+ file = g_build_filename(dir, "Contents", "Resources", "Outgoing", "NextContent.html", NULL);
+ if (!g_file_get_contents(file, &priv->outgoing_next_content_html, NULL, NULL)) {
+ priv->outgoing_next_content_html = g_strdup(get_outgoing_content_html(priv, dir));
+ }
+
+ return priv->outgoing_next_content_html;
+}
+
+static const char *
+get_outgoing_context_html(PidginConvThemePrivate *priv, const char *dir)
+{
+ char *file;
+
+ if (priv->outgoing_context_html)
+ return priv->outgoing_context_html;
+
+ file = g_build_filename(dir, "Contents", "Resources", "Outgoing", "Context.html", NULL);
+ if (!g_file_get_contents(file, &priv->outgoing_context_html, NULL, NULL)) {
+ priv->outgoing_context_html = g_strdup(get_incoming_context_html(priv, dir));
+ }
+ g_free(file);
+
+ return priv->outgoing_context_html;
+}
+
+static const char *
+get_outgoing_next_context_html(PidginConvThemePrivate *priv, const char *dir)
+{
+ char *file;
+
+ if (priv->outgoing_next_context_html)
+ return priv->outgoing_next_context_html;
+
+ file = g_build_filename(dir, "Contents", "Resources", "Outgoing", "NextContext.html", NULL);
+ if (!g_file_get_contents(file, &priv->outgoing_next_context_html, NULL, NULL)) {
+ priv->outgoing_next_context_html = g_strdup(get_outgoing_context_html(priv, dir));
+ }
+ g_free(file);
+
+ return priv->outgoing_next_context_html;
+}
+
+static void
+_set_variant(PidginConvTheme *theme, const char *variant)
+{
+ PidginConvThemePrivate *priv;
+ const GValue *val;
+ char *prefname;
+
+ g_return_if_fail(theme != NULL);
+ g_return_if_fail(variant != NULL);
+
+ priv = PIDGIN_CONV_THEME_GET_PRIVATE(theme);
+
+ g_free(priv->variant);
+ priv->variant = g_strdup(variant);
+
+ val = get_key(priv, "CFBundleIdentifier", FALSE);
+ prefname = g_strdup_printf(PIDGIN_PREFS_ROOT "/conversations/themes/%s/variant",
+ g_value_get_string(val));
+ purple_prefs_set_string(prefname, variant);
+ g_free(prefname);
+}
+
+/******************************************************************************
+ * GObject Stuff
+ *****************************************************************************/
+
+static void
+pidgin_conv_theme_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *psec)
+{
+ PidginConvTheme *theme = PIDGIN_CONV_THEME(obj);
+
+ switch (param_id) {
+ case PROP_INFO:
+ g_value_set_boxed(value, (gpointer)pidgin_conversation_theme_get_info(theme));
+ break;
+
+ case PROP_VARIANT:
+ g_value_set_string(value, pidgin_conversation_theme_get_variant(theme));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, psec);
+ break;
+ }
+}
+
+static void
+pidgin_conv_theme_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *psec)
+{
+ PidginConvTheme *theme = PIDGIN_CONV_THEME(obj);
+
+ switch (param_id) {
+ case PROP_INFO:
+ pidgin_conversation_theme_set_info(theme, g_value_get_boxed(value));
+ break;
+
+ case PROP_VARIANT:
+ _set_variant(theme, g_value_get_string(value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, psec);
+ break;
+ }
+}
+
+static void
+pidgin_conv_theme_init(GTypeInstance *instance,
+ gpointer klass)
+{
+ PidginConvThemePrivate *priv;
+
+ priv = PIDGIN_CONV_THEME_GET_PRIVATE(instance);
+}
+
+static void
+pidgin_conv_theme_finalize(GObject *obj)
+{
+ PidginConvThemePrivate *priv;
+ GList *list;
+
+ priv = PIDGIN_CONV_THEME_GET_PRIVATE(obj);
+
+ g_free(priv->template_html);
+ g_free(priv->header_html);
+ g_free(priv->footer_html);
+ g_free(priv->topic_html);
+ g_free(priv->status_html);
+ g_free(priv->content_html);
+ g_free(priv->incoming_content_html);
+ g_free(priv->outgoing_content_html);
+ g_free(priv->incoming_next_content_html);
+ g_free(priv->outgoing_next_content_html);
+ g_free(priv->incoming_context_html);
+ g_free(priv->outgoing_context_html);
+ g_free(priv->incoming_next_context_html);
+ g_free(priv->outgoing_next_context_html);
+ g_free(priv->basestyle_css);
+
+ if (priv->info)
+ g_hash_table_destroy(priv->info);
+
+ list = priv->variants;
+ while (list) {
+ g_free(list->data);
+ list = g_list_delete_link(list, list);
+ }
+ g_free(priv->variant);
+
+ parent_class->finalize(obj);
+}
+
+static void
+pidgin_conv_theme_class_init(PidginConvThemeClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ GParamSpec *pspec;
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ g_type_class_add_private(klass, sizeof(PidginConvThemePrivate));
+
+ obj_class->get_property = pidgin_conv_theme_get_property;
+ obj_class->set_property = pidgin_conv_theme_set_property;
+ obj_class->finalize = pidgin_conv_theme_finalize;
+
+ /* INFO */
+ pspec = g_param_spec_boxed("info", "Info",
+ "The information about this theme",
+ G_TYPE_HASH_TABLE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property(obj_class, PROP_INFO, pspec);
+#if GLIB_CHECK_VERSION(2,26,0)
+ properties[PROP_INFO] = pspec;
+#endif
+
+ /* VARIANT */
+ pspec = g_param_spec_string("variant", "Variant",
+ "The current variant for this theme",
+ NULL, G_PARAM_READWRITE);
+ g_object_class_install_property(obj_class, PROP_VARIANT, pspec);
+#if GLIB_CHECK_VERSION(2,26,0)
+ properties[PROP_VARIANT] = pspec;
+#endif
+}
+
+GType
+pidgin_conversation_theme_get_type(void)
+{
+ static GType type = 0;
+ if (type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PidginConvThemeClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc)pidgin_conv_theme_class_init, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(PidginConvTheme),
+ 0, /* n_preallocs */
+ pidgin_conv_theme_init, /* instance_init */
+ NULL, /* value table */
+ };
+ type = g_type_register_static(PURPLE_TYPE_THEME,
+ "PidginConvTheme", &info, 0);
+ }
+ return type;
+}
+
+/*****************************************************************************
+ * Public API functions
+ *****************************************************************************/
+
+const GHashTable *
+pidgin_conversation_theme_get_info(const PidginConvTheme *theme)
+{
+ PidginConvThemePrivate *priv;
+
+ g_return_val_if_fail(theme != NULL, NULL);
+
+ priv = PIDGIN_CONV_THEME_GET_PRIVATE(theme);
+ return priv->info;
+}
+
+void
+pidgin_conversation_theme_set_info(PidginConvTheme *theme, GHashTable *info)
+{
+ PidginConvThemePrivate *priv;
+
+ g_return_if_fail(theme != NULL);
+
+ priv = PIDGIN_CONV_THEME_GET_PRIVATE(theme);
+
+ if (priv->info)
+ g_hash_table_destroy(priv->info);
+
+ priv->info = info;
+}
+
+const GValue *
+pidgin_conversation_theme_lookup(PidginConvTheme *theme, const char *key, gboolean specific)
+{
+ PidginConvThemePrivate *priv;
+
+ g_return_val_if_fail(theme != NULL, NULL);
+
+ priv = PIDGIN_CONV_THEME_GET_PRIVATE(theme);
+
+ return get_key(priv, key, specific);
+}
+
+const char *
+pidgin_conversation_theme_get_template(PidginConvTheme *theme, PidginConvThemeTemplateType type)
+{
+ PidginConvThemePrivate *priv;
+ const char *dir;
+ const char *html;
+
+ g_return_val_if_fail(theme != NULL, NULL);
+
+ priv = PIDGIN_CONV_THEME_GET_PRIVATE(theme);
+ dir = purple_theme_get_dir(PURPLE_THEME(theme));
+
+ switch (type) {
+ case PIDGIN_CONVERSATION_THEME_TEMPLATE_MAIN:
+ html = get_template_html(priv, dir);
+ break;
+ case PIDGIN_CONVERSATION_THEME_TEMPLATE_HEADER:
+ html = get_header_html(priv, dir);
+ break;
+ case PIDGIN_CONVERSATION_THEME_TEMPLATE_FOOTER:
+ html = get_footer_html(priv, dir);
+ break;
+ case PIDGIN_CONVERSATION_THEME_TEMPLATE_TOPIC:
+ html = get_topic_html(priv, dir);
+ break;
+ case PIDGIN_CONVERSATION_THEME_TEMPLATE_STATUS:
+ html = get_status_html(priv, dir);
+ break;
+ case PIDGIN_CONVERSATION_THEME_TEMPLATE_CONTENT:
+ html = get_content_html(priv, dir);
+ break;
+ case PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_CONTENT:
+ html = get_incoming_content_html(priv, dir);
+ break;
+ case PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_NEXT_CONTENT:
+ html = get_incoming_next_content_html(priv, dir);
+ break;
+ case PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_CONTEXT:
+ html = get_incoming_context_html(priv, dir);
+ break;
+ case PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_NEXT_CONTEXT:
+ html = get_incoming_next_context_html(priv, dir);
+ break;
+ case PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_CONTENT:
+ html = get_outgoing_content_html(priv, dir);
+ break;
+ case PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_NEXT_CONTENT:
+ html = get_outgoing_next_content_html(priv, dir);
+ break;
+ case PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_CONTEXT:
+ html = get_outgoing_context_html(priv, dir);
+ break;
+ case PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_NEXT_CONTEXT:
+ html = get_outgoing_next_context_html(priv, dir);
+ break;
+ case PIDGIN_CONVERSATION_THEME_TEMPLATE_BASESTYLE_CSS:
+ html = get_basestyle_css(priv, dir);
+ break;
+ default:
+ purple_debug_error("gtkconv-theme",
+ "Requested invalid template type (%d) for theme %s.\n",
+ type, purple_theme_get_name(PURPLE_THEME(theme)));
+ html = NULL;
+ }
+
+ return html;
+}
+
+void
+pidgin_conversation_theme_add_variant(PidginConvTheme *theme, char *variant)
+{
+ PidginConvThemePrivate *priv;
+
+ g_return_if_fail(theme != NULL);
+ g_return_if_fail(variant != NULL);
+
+ priv = PIDGIN_CONV_THEME_GET_PRIVATE(theme);
+
+ priv->variants = g_list_prepend(priv->variants, variant);
+}
+
+const char *
+pidgin_conversation_theme_get_variant(PidginConvTheme *theme)
+{
+ PidginConvThemePrivate *priv;
+
+ g_return_val_if_fail(theme != NULL, NULL);
+
+ priv = PIDGIN_CONV_THEME_GET_PRIVATE(theme);
+
+ return priv->variant;
+}
+
+void
+pidgin_conversation_theme_set_variant(PidginConvTheme *theme, const char *variant)
+{
+ _set_variant(theme, variant);
+#if GLIB_CHECK_VERSION(2,26,0)
+ g_object_notify_by_pspec(G_OBJECT(theme), properties[PROP_VARIANT]);
+#else
+ g_object_notify(G_OBJECT(theme), "variant");
+#endif
+}
+
+const GList *
+pidgin_conversation_theme_get_variants(PidginConvTheme *theme)
+{
+ PidginConvThemePrivate *priv;
+
+ g_return_val_if_fail(theme != NULL, NULL);
+
+ priv = PIDGIN_CONV_THEME_GET_PRIVATE(theme);
+
+ return priv->variants;
+}
+
+char *
+pidgin_conversation_theme_get_template_path(PidginConvTheme *theme)
+{
+ const char *dir;
+
+ g_return_val_if_fail(theme != NULL, NULL);
+
+ dir = purple_theme_get_dir(PURPLE_THEME(theme));
+
+ return get_template_path(dir);
+}
+
+char *
+pidgin_conversation_theme_get_css_path(PidginConvTheme *theme)
+{
+ PidginConvThemePrivate *priv;
+ const char *dir;
+
+ g_return_val_if_fail(theme != NULL, NULL);
+
+ priv = PIDGIN_CONV_THEME_GET_PRIVATE(theme);
+
+ dir = purple_theme_get_dir(PURPLE_THEME(theme));
+ if (!priv->variant) {
+ return g_build_filename(dir, "Contents", "Resources", "main.css", NULL);
+ } else {
+ char *file = g_strdup_printf("%s.css", priv->variant);
+ char *ret = g_build_filename(dir, "Contents", "Resources", "Variants", file, NULL);
+ g_free(file);
+ return ret;
+ }
+}
+
diff --git a/pidgin/gtkconv-theme.h b/pidgin/gtkconv-theme.h
new file mode 100644
index 0000000000..053c4c320f
--- /dev/null
+++ b/pidgin/gtkconv-theme.h
@@ -0,0 +1,196 @@
+/**
+ * @file gtkconv-theme.h Pidgin Conversation Theme Class API
+ */
+
+/* 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.
+ *
+ * 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
+ */
+
+#ifndef PIDGIN_CONV_THEME_H
+#define PIDGIN_CONV_THEME_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include "conversation.h"
+#include "theme.h"
+
+/**
+ * extends PurpleTheme (theme.h)
+ * A pidgin icon theme.
+ * This object represents a Pidgin icon theme.
+ *
+ * PidginConvTheme is a PurpleTheme Object.
+ */
+typedef struct _PidginConvTheme PidginConvTheme;
+typedef struct _PidginConvThemeClass PidginConvThemeClass;
+
+#define PIDGIN_TYPE_CONV_THEME (pidgin_conversation_theme_get_type ())
+#define PIDGIN_CONV_THEME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PIDGIN_TYPE_CONV_THEME, PidginConvTheme))
+#define PIDGIN_CONV_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PIDGIN_TYPE_CONV_THEME, PidginConvThemeClass))
+#define PIDGIN_IS_CONV_THEME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PIDGIN_TYPE_CONV_THEME))
+#define PIDGIN_IS_CONV_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIDGIN_TYPE_CONV_THEME))
+#define PIDGIN_CONV_THEME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PIDGIN_TYPE_CONV_THEME, PidginConvThemeClass))
+
+struct _PidginConvTheme
+{
+ PurpleTheme parent;
+};
+
+struct _PidginConvThemeClass
+{
+ PurpleThemeClass parent_class;
+};
+
+typedef enum {
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_MAIN,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_HEADER,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_FOOTER,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_TOPIC,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_STATUS,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_CONTENT,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_CONTENT,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_NEXT_CONTENT,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_CONTEXT,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_NEXT_CONTEXT,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_CONTENT,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_NEXT_CONTENT,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_CONTEXT,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_NEXT_CONTEXT,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_BASESTYLE_CSS
+
+} PidginConvThemeTemplateType;
+
+/**************************************************************************/
+/** @name Pidgin Conversation Theme API */
+/**************************************************************************/
+G_BEGIN_DECLS
+
+/**
+ * GObject foo.
+ * @internal.
+ */
+GType pidgin_conversation_theme_get_type(void);
+
+/**
+ * Get the Info.plist hash table from a conversation theme.
+ *
+ * @param theme The conversation theme
+ *
+ * @return The hash table. Keys are strings as outlined for message styles,
+ * values are GValue*s. This is an internal structure. Take a ref if
+ * necessary, but don't destroy it yourself.
+ */
+const GHashTable *pidgin_conversation_theme_get_info(const PidginConvTheme *theme);
+
+/**
+ * Set the Info.plist hash table for a conversation theme.
+ *
+ * @param theme The conversation theme
+ * @param info The new hash table. The theme will take ownership of this hash
+ * table. Do not use it yourself afterwards with holding a ref.
+ * For key and value specifications, @see pidgin_conversation_theme_get_info.
+ *
+ */
+void pidgin_conversation_theme_set_info(PidginConvTheme *theme, GHashTable *info);
+
+/**
+ * Lookup a key in a theme
+ *
+ * @param theme The conversation theme
+ * @param key The key to find
+ * @param specific Whether to search variant-specific keys
+ *
+ * @return The key information. If @a specific is @c TRUE, then keys are first
+ * searched by variant, then by general ones. Otherwise, only general
+ * key values are returned.
+ */
+const GValue *pidgin_conversation_theme_lookup(PidginConvTheme *theme, const char *key, gboolean specific);
+
+/**
+ * Get the template data from a conversation theme.
+ *
+ * @param theme The conversation theme
+ * @param type The type of template data
+ *
+ * @return The template data requested. Fallback is made as required by styles.
+ * Subsequent calls to this function will return cached values.
+ */
+const char *pidgin_conversation_theme_get_template(PidginConvTheme *theme, PidginConvThemeTemplateType type);
+
+/**
+ * Add an available variant name to a conversation theme.
+ *
+ * @param theme The conversation theme
+ * @param variant The name of the variant
+ *
+ * @Note The conversation theme will take ownership of the variant name string.
+ * This function should normally only be called by the theme loader.
+ */
+void pidgin_conversation_theme_add_variant(PidginConvTheme *theme, char *variant);
+
+/**
+ * Get the currently set variant name for a conversation theme.
+ *
+ * @param theme The conversation theme
+ *
+ * @return The current variant name.
+ */
+const char *pidgin_conversation_theme_get_variant(PidginConvTheme *theme);
+
+/**
+ * Set the variant name for a conversation theme.
+ *
+ * @param theme The conversation theme
+ * @param variant The name of the variant
+ *
+ */
+void pidgin_conversation_theme_set_variant(PidginConvTheme *theme, const char *variant);
+
+/**
+ * Get a list of available variants for a conversation theme.
+ *
+ * @param theme The conversation theme
+ *
+ * @return The list of variants. This GList and the string data are owned by
+ * the theme and should not be freed by the caller.
+ */
+const GList *pidgin_conversation_theme_get_variants(PidginConvTheme *theme);
+
+/**
+ * Get the path to the template HTML file.
+ *
+ * @param theme The conversation theme
+ *
+ * @return The path to the HTML file.
+ */
+char *pidgin_conversation_theme_get_template_path(PidginConvTheme *theme);
+
+/**
+ * Get the path to the current variant CSS file.
+ *
+ * @param theme The conversation theme
+ *
+ * @return The path to the CSS file.
+ */
+char *pidgin_conversation_theme_get_css_path(PidginConvTheme *theme);
+
+G_END_DECLS
+#endif /* PIDGIN_CONV_THEME_H */
+
diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c
index 4f0121d931..87d5b53c47 100644
--- a/pidgin/gtkconv.c
+++ b/pidgin/gtkconv.c
@@ -52,6 +52,8 @@
#include "notify.h"
#include "prpl.h"
#include "request.h"
+#include "theme-loader.h"
+#include "theme-manager.h"
#include "util.h"
#include "version.h"
@@ -59,6 +61,8 @@
#include "gtkblist.h"
#include "gtkconv.h"
#include "gtkconvwin.h"
+#include "gtkconv-theme.h"
+#include "gtkconv-theme-loader.h"
#include "gtkdialogs.h"
#include "gtkimhtml.h"
#include "gtkimhtmltoolbar.h"
@@ -69,11 +73,55 @@
#include "gtkprivacy.h"
#include "gtkthemes.h"
#include "gtkutils.h"
+#include "gtkwebview.h"
#include "pidginstock.h"
#include "pidgintooltip.h"
+#include "smileyparser.h"
#include "gtknickcolors.h"
+#if !GTK_CHECK_VERSION(2,20,0)
+#define gtk_widget_get_realized(x) GTK_WIDGET_REALIZED(x)
+
+#if !GTK_CHECK_VERSION(2,18,0)
+#define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x)
+#define gtk_widget_is_drawable(x) GTK_WIDGET_DRAWABLE(x)
+#endif
+#endif
+
+/**
+ * A GTK+ Instant Message pane.
+ */
+struct _PidginImPane
+{
+ GtkWidget *block;
+ GtkWidget *send_file;
+ GtkWidget *sep1;
+ GtkWidget *sep2;
+ GtkWidget *check;
+ GtkWidget *progress;
+ guint32 typing_timer;
+
+ /* Buddy icon stuff */
+ GtkWidget *icon_container;
+ GtkWidget *icon;
+ gboolean show_icon;
+ gboolean animate;
+ GdkPixbufAnimation *anim;
+ GdkPixbufAnimationIter *iter;
+ guint32 icon_timer;
+};
+
+/**
+ * GTK+ Chat panes.
+ */
+struct _PidginChatPane
+{
+ GtkWidget *count;
+ GtkWidget *list;
+ GtkWidget *topic_text;
+};
+
#define CLOSE_CONV_TIMEOUT_SECS (10 * 60)
#define AUTO_RESPONSE "&lt;AUTO-REPLY&gt; : "
@@ -144,10 +192,13 @@ static GList *xa_list = NULL;
static GList *offline_list = NULL;
static GHashTable *prpl_lists = NULL;
+static PurpleTheme *default_conv_theme = NULL;
+
static gboolean update_send_to_selection(PidginWindow *win);
static void generate_send_to_items(PidginWindow *win);
/* Prototypes. <-- because Paco-Paco hates this comment. */
+static void load_conv_theme(PidginConversation *gtkconv);
static gboolean infopane_entry_activate(PidginConversation *gtkconv);
static void got_typing_keypress(PidginConversation *gtkconv, gboolean first);
static void gray_stuff_out(PidginConversation *gtkconv);
@@ -158,7 +209,6 @@ static void conv_set_unseen(PurpleConversation *gtkconv, PidginUnseenState state
static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state);
static void update_typing_icon(PidginConversation *gtkconv);
static void update_typing_message(PidginConversation *gtkconv, const char *message);
-static const char *item_factory_translate_func (const char *path, gpointer func_data);
gboolean pidgin_conv_has_focus(PurpleConversation *conv);
static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background);
static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast);
@@ -176,7 +226,7 @@ static gboolean pidgin_conv_xy_to_right_infopane(PidginWindow *win, int x, int y
static const GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name)
{
static GdkColor col;
- GtkStyle *style = gtk_widget_get_style(gtkconv->imhtml);
+ GtkStyle *style = gtk_widget_get_style(gtkconv->webview);
float scale;
col = nick_colors[g_str_hash(name) % nbr_nick_colors];
@@ -196,15 +246,16 @@ static const GdkColor *get_nick_color(PidginConversation *gtkconv, const char *n
static PurpleBlistNode *
get_conversation_blist_node(PurpleConversation *conv)
{
+ PurpleAccount *account = purple_conversation_get_account(conv);
PurpleBlistNode *node = NULL;
switch (purple_conversation_get_type(conv)) {
case PURPLE_CONV_TYPE_IM:
- node = PURPLE_BLIST_NODE(purple_find_buddy(conv->account, conv->name));
+ node = PURPLE_BLIST_NODE(purple_find_buddy(account, purple_conversation_get_name(conv)));
node = node ? node->parent : NULL;
break;
case PURPLE_CONV_TYPE_CHAT:
- node = PURPLE_BLIST_NODE(purple_blist_find_chat(conv->account, conv->name));
+ node = PURPLE_BLIST_NODE(purple_blist_find_chat(account, purple_conversation_get_name(conv)));
break;
default:
break;
@@ -276,7 +327,7 @@ static void
default_formatize(PidginConversation *c)
{
PurpleConversation *conv = c->active_conv;
- gtk_imhtml_setup_entry(GTK_IMHTML(c->entry), conv->features);
+ gtk_imhtml_setup_entry(GTK_IMHTML(c->entry), purple_conversation_get_features(conv));
}
static void
@@ -356,8 +407,32 @@ debug_command_cb(PurpleConversation *conv,
}
tmp = g_string_free(str, FALSE);
+ } else if (!g_ascii_strcasecmp(args[0], "unsafe")) {
+ if (purple_debug_is_unsafe()) {
+ purple_debug_set_unsafe(FALSE);
+ purple_conversation_write(conv, NULL, _("Unsafe debugging is now disabled."),
+ PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL));
+ } else {
+ purple_debug_set_unsafe(TRUE);
+ purple_conversation_write(conv, NULL, _("Unsafe debugging is now enabled."),
+ PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL));
+ }
+
+ return PURPLE_CMD_RET_OK;
+ } else if (!g_ascii_strcasecmp(args[0], "verbose")) {
+ if (purple_debug_is_verbose()) {
+ purple_debug_set_verbose(FALSE);
+ purple_conversation_write(conv, NULL, _("Verbose debugging is now disabled."),
+ PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL));
+ } else {
+ purple_debug_set_verbose(TRUE);
+ purple_conversation_write(conv, NULL, _("Verbose debugging is now enabled."),
+ PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL));
+ }
+
+ return PURPLE_CMD_RET_OK;
} else {
- purple_conversation_write(conv, NULL, _("Supported debug options are: plugins version"),
+ purple_conversation_write(conv, NULL, _("Supported debug options are: plugins version unsafe verbose"),
PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_ERROR, time(NULL));
return PURPLE_CMD_RET_OK;
}
@@ -376,11 +451,12 @@ debug_command_cb(PurpleConversation *conv,
static void clear_conversation_scrollback_cb(PurpleConversation *conv,
void *data)
{
- PidginConversation *gtkconv = NULL;
+ PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
- gtkconv = PIDGIN_CONVERSATION(conv);
- if (gtkconv)
- gtk_imhtml_clear(GTK_IMHTML(gtkconv->imhtml));
+ if (PIDGIN_CONVERSATION(conv)) {
+ load_conv_theme(gtkconv);
+ gtkconv->last_flags = 0;
+ }
}
static PurpleCmdRet
@@ -420,8 +496,8 @@ help_command_cb(PurpleConversation *conv,
g_string_append(s, _("No such command (in this context)."));
}
} else {
- s = g_string_new(_("Use \"/help &lt;command&gt;\" for help on a specific command.\n"
- "The following commands are available in this context:\n"));
+ s = g_string_new(_("Use \"/help &lt;command&gt;\" for help on a specific command.<br/>"
+ "The following commands are available in this context:<br/>"));
text = purple_cmd_list(conv);
for (l = text; l; l = l->next)
@@ -498,8 +574,8 @@ check_for_and_do_command(PurpleConversation *conv)
PurplePluginProtocolInfo *prpl_info = NULL;
PurpleConnection *gc;
- if ((gc = purple_conversation_get_gc(conv)))
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ if ((gc = purple_conversation_get_connection(conv)))
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
if ((prpl_info != NULL) && (prpl_info->options & OPT_PROTO_SLASH_COMMANDS_NATIVE)) {
char *spaceslash;
@@ -578,7 +654,7 @@ send_cb(GtkWidget *widget, PidginConversation *gtkconv)
gtk_widget_grab_focus(gtkconv->entry);
- if (strlen(clean) == 0) {
+ if (!*clean) {
g_free(buf);
g_free(clean);
return;
@@ -591,7 +667,7 @@ send_cb(GtkWidget *widget, PidginConversation *gtkconv)
flags |= PURPLE_MESSAGE_IMAGES;
gc = purple_account_get_connection(account);
- if (gc && (conv->features & PURPLE_CONNECTION_NO_NEWLINES)) {
+ if (gc && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_NO_NEWLINES)) {
char **bufs;
int i;
@@ -657,7 +733,7 @@ static void chat_do_info(PidginConversation *gtkconv, const char *who)
PurpleConversation *conv = gtkconv->active_conv;
PurpleConnection *gc;
- if ((gc = purple_conversation_get_gc(conv))) {
+ if ((gc = purple_conversation_get_connection(conv))) {
pidgin_retrieve_user_info_in_chat(gc, who, purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)));
}
}
@@ -669,7 +745,7 @@ info_cb(GtkWidget *widget, PidginConversation *gtkconv)
PurpleConversation *conv = gtkconv->active_conv;
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- pidgin_retrieve_user_info(purple_conversation_get_gc(conv),
+ pidgin_retrieve_user_info(purple_conversation_get_connection(conv),
purple_conversation_get_name(conv));
gtk_widget_grab_focus(gtkconv->entry);
} else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
@@ -757,7 +833,7 @@ do_invite(GtkWidget *w, int resp, InviteBuddyInfo *info)
if (!g_ascii_strcasecmp(buddy, ""))
return;
- serv_chat_invite(purple_conversation_get_gc(conv),
+ serv_chat_invite(purple_conversation_get_connection(conv),
purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)),
message, buddy);
}
@@ -792,7 +868,7 @@ invite_dnd_recv(GtkWidget *widget, GdkDragContext *dc, gint x, gint y,
else
return;
- if (strcmp(convprotocol, purple_account_get_protocol_id(buddy->account)))
+ if (strcmp(convprotocol, purple_account_get_protocol_id(purple_buddy_get_account(buddy))))
{
purple_notify_error(PIDGIN_CONVERSATION(info->conv), NULL,
_("That buddy is not on the same protocol as this "
@@ -877,7 +953,9 @@ invite_cb(GtkWidget *widget, PidginConversation *gtkconv)
GTK_RESPONSE_OK);
gtk_container_set_border_width(GTK_CONTAINER(invite_dialog), PIDGIN_HIG_BOX_SPACE);
gtk_window_set_resizable(GTK_WINDOW(invite_dialog), FALSE);
+#if !GTK_CHECK_VERSION(2,22,0)
gtk_dialog_set_has_separator(GTK_DIALOG(invite_dialog), FALSE);
+#endif
info->window = GTK_WIDGET(invite_dialog);
@@ -974,13 +1052,13 @@ invite_cb(GtkWidget *widget, PidginConversation *gtkconv)
}
static void
-menu_new_conv_cb(gpointer data, guint action, GtkWidget *widget)
+menu_new_conv_cb(GtkAction *action, gpointer data)
{
pidgin_dialogs_im();
}
static void
-menu_join_chat_cb(gpointer data, guint action, GtkWidget *widget)
+menu_join_chat_cb(GtkAction *action, gpointer data)
{
pidgin_blist_joinchat_show();
}
@@ -989,9 +1067,9 @@ static void
savelog_writefile_cb(void *user_data, const char *filename)
{
PurpleConversation *conv = (PurpleConversation *)user_data;
+ GtkWebView *webview;
FILE *fp;
const char *name;
- char **lines;
gchar *text;
if ((fp = g_fopen(filename, "w+")) == NULL) {
@@ -999,20 +1077,26 @@ savelog_writefile_cb(void *user_data, const char *filename)
return;
}
+ webview = GTK_WEBVIEW(PIDGIN_CONVERSATION(conv)->webview);
name = purple_conversation_get_name(conv);
- fprintf(fp, "<html>\n<head>\n");
+ fprintf(fp, "<html>\n");
+
+ fprintf(fp, "<head>\n");
fprintf(fp, "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n");
- fprintf(fp, "<title>%s</title>\n</head>\n<body>\n", name);
- fprintf(fp, _("<h1>Conversation with %s</h1>\n"), name);
+ fprintf(fp, "<title>%s</title>\n", name);
+ text = gtk_webview_get_head_html(webview);
+ fprintf(fp, "%s", text);
+ g_free(text);
+ fprintf(fp, "</head>\n");
- lines = gtk_imhtml_get_markup_lines(
- GTK_IMHTML(PIDGIN_CONVERSATION(conv)->imhtml));
- text = g_strjoinv("<br>\n", lines);
+ fprintf(fp, "<body>\n");
+ fprintf(fp, _("<h1>Conversation with %s</h1>\n"), name);
+ text = gtk_webview_get_body_html(webview);
fprintf(fp, "%s", text);
g_free(text);
- g_strfreev(lines);
+ fprintf(fp, "\n</body>\n");
- fprintf(fp, "\n</body>\n</html>\n");
+ fprintf(fp, "</html>\n");
fclose(fp);
}
@@ -1021,11 +1105,12 @@ savelog_writefile_cb(void *user_data, const char *filename)
* plaintext v. HTML file.
*/
static void
-menu_save_as_cb(gpointer data, guint action, GtkWidget *widget)
+menu_save_as_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = data;
PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
- PurpleBuddy *buddy = purple_find_buddy(conv->account, conv->name);
+ PurpleAccount *account = purple_conversation_get_account(conv);
+ PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv));
const char *name;
gchar *buf;
gchar *c;
@@ -1033,7 +1118,7 @@ menu_save_as_cb(gpointer data, guint action, GtkWidget *widget)
if (buddy != NULL)
name = purple_buddy_get_contact_alias(buddy);
else
- name = purple_normalize(conv->account, conv->name);
+ name = purple_normalize(account, purple_conversation_get_name(conv));
buf = g_strdup_printf("%s.html", name);
for (c = buf ; *c ; c++)
@@ -1051,7 +1136,7 @@ menu_save_as_cb(gpointer data, guint action, GtkWidget *widget)
}
static void
-menu_view_log_cb(gpointer data, guint action, GtkWidget *widget)
+menu_view_log_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = data;
PurpleConversation *conv;
@@ -1078,7 +1163,6 @@ menu_view_log_cb(gpointer data, guint action, GtkWidget *widget)
gdk_window_set_cursor(gtkblist->window->window, cursor);
gdk_window_set_cursor(win->window->window, cursor);
gdk_cursor_unref(cursor);
- gdk_display_flush(gdk_drawable_get_display(GDK_DRAWABLE(widget->window)));
name = purple_conversation_get_name(conv);
account = purple_conversation_get_account(conv);
@@ -1105,7 +1189,7 @@ menu_view_log_cb(gpointer data, guint action, GtkWidget *widget)
}
static void
-menu_clear_cb(gpointer data, guint action, GtkWidget *widget)
+menu_clear_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = data;
PurpleConversation *conv;
@@ -1115,7 +1199,7 @@ menu_clear_cb(gpointer data, guint action, GtkWidget *widget)
}
static void
-menu_find_cb(gpointer data, guint action, GtkWidget *widget)
+menu_find_cb(GtkAction *action, gpointer data)
{
PidginWindow *gtkwin = data;
PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(gtkwin);
@@ -1125,7 +1209,7 @@ menu_find_cb(gpointer data, guint action, GtkWidget *widget)
#ifdef USE_VV
static void
-menu_initiate_media_call_cb(gpointer data, guint action, GtkWidget *widget)
+menu_initiate_media_call_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = (PidginWindow *)data;
PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
@@ -1133,39 +1217,44 @@ menu_initiate_media_call_cb(gpointer data, guint action, GtkWidget *widget)
purple_prpl_initiate_media(account,
purple_conversation_get_name(conv),
- action == 0 ? PURPLE_MEDIA_AUDIO :
- action == 1 ? PURPLE_MEDIA_VIDEO :
- action == 2 ? PURPLE_MEDIA_AUDIO |
+ action == win->menu.audio_call ? PURPLE_MEDIA_AUDIO :
+ action == win->menu.video_call ? PURPLE_MEDIA_VIDEO :
+ action == win->menu.audio_video_call ? PURPLE_MEDIA_AUDIO |
PURPLE_MEDIA_VIDEO : PURPLE_MEDIA_NONE);
}
#endif
static void
-menu_send_file_cb(gpointer data, guint action, GtkWidget *widget)
+menu_send_file_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = data;
PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- serv_send_file(purple_conversation_get_gc(conv), purple_conversation_get_name(conv), NULL);
+ serv_send_file(purple_conversation_get_connection(conv), purple_conversation_get_name(conv), NULL);
}
}
static void
-menu_get_attention_cb(gpointer data, guint action, GtkWidget *widget)
+menu_get_attention_cb(GObject *obj, gpointer data)
{
PidginWindow *win = data;
PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- purple_prpl_send_attention(purple_conversation_get_gc(conv),
- purple_conversation_get_name(conv), 0);
+ int index;
+ if ((GtkAction *)obj == win->menu.get_attention)
+ index = 0;
+ else
+ index = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(obj), "index"));
+ purple_prpl_send_attention(purple_conversation_get_connection(conv),
+ purple_conversation_get_name(conv), index);
}
}
static void
-menu_add_pounce_cb(gpointer data, guint action, GtkWidget *widget)
+menu_add_pounce_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = data;
PurpleConversation *conv;
@@ -1177,7 +1266,7 @@ menu_add_pounce_cb(gpointer data, guint action, GtkWidget *widget)
}
static void
-menu_insert_link_cb(gpointer data, guint action, GtkWidget *widget)
+menu_insert_link_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = data;
PidginConversation *gtkconv;
@@ -1191,7 +1280,7 @@ menu_insert_link_cb(gpointer data, guint action, GtkWidget *widget)
}
static void
-menu_insert_image_cb(gpointer data, guint action, GtkWidget *widget)
+menu_insert_image_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = data;
PidginConversation *gtkconv;
@@ -1206,7 +1295,7 @@ menu_insert_image_cb(gpointer data, guint action, GtkWidget *widget)
static void
-menu_alias_cb(gpointer data, guint action, GtkWidget *widget)
+menu_alias_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = data;
PurpleConversation *conv;
@@ -1233,7 +1322,7 @@ menu_alias_cb(gpointer data, guint action, GtkWidget *widget)
}
static void
-menu_get_info_cb(gpointer data, guint action, GtkWidget *widget)
+menu_get_info_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = data;
PurpleConversation *conv;
@@ -1244,7 +1333,7 @@ menu_get_info_cb(gpointer data, guint action, GtkWidget *widget)
}
static void
-menu_invite_cb(gpointer data, guint action, GtkWidget *widget)
+menu_invite_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = data;
PurpleConversation *conv;
@@ -1255,7 +1344,7 @@ menu_invite_cb(gpointer data, guint action, GtkWidget *widget)
}
static void
-menu_block_cb(gpointer data, guint action, GtkWidget *widget)
+menu_block_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = data;
PurpleConversation *conv;
@@ -1266,7 +1355,7 @@ menu_block_cb(gpointer data, guint action, GtkWidget *widget)
}
static void
-menu_unblock_cb(gpointer data, guint action, GtkWidget *widget)
+menu_unblock_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = data;
PurpleConversation *conv;
@@ -1277,7 +1366,7 @@ menu_unblock_cb(gpointer data, guint action, GtkWidget *widget)
}
static void
-menu_add_remove_cb(gpointer data, guint action, GtkWidget *widget)
+menu_add_remove_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = data;
PurpleConversation *conv;
@@ -1322,7 +1411,7 @@ hide_conv(PidginConversation *gtkconv, gboolean closetimer)
}
static void
-menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget)
+menu_close_conv_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = data;
@@ -1330,7 +1419,7 @@ menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget)
}
static void
-menu_logging_cb(gpointer data, guint action, GtkWidget *widget)
+menu_logging_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = data;
PurpleConversation *conv;
@@ -1342,7 +1431,7 @@ menu_logging_cb(gpointer data, guint action, GtkWidget *widget)
if (conv == NULL)
return;
- logging = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+ logging = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
if (logging == purple_conversation_is_logging(conv))
return;
@@ -1356,16 +1445,14 @@ menu_logging_cb(gpointer data, guint action, GtkWidget *widget)
purple_conversation_write(conv, NULL,
_("Logging started. Future messages in this conversation will be logged."),
- conv->logs ? (PURPLE_MESSAGE_SYSTEM) :
- (PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG),
+ PURPLE_MESSAGE_SYSTEM,
time(NULL));
}
else
{
purple_conversation_write(conv, NULL,
_("Logging stopped. Future messages in this conversation will not be logged."),
- conv->logs ? (PURPLE_MESSAGE_SYSTEM) :
- (PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG),
+ PURPLE_MESSAGE_SYSTEM,
time(NULL));
/* Disable the logging second, so that the above message can be logged. */
@@ -1373,7 +1460,7 @@ menu_logging_cb(gpointer data, guint action, GtkWidget *widget)
}
/* Save the setting IFF it's different than the pref. */
- switch (conv->type)
+ switch (purple_conversation_get_type(conv))
{
case PURPLE_CONV_TYPE_IM:
if (logging == purple_prefs_get_bool("/purple/logging/log_ims"))
@@ -1395,14 +1482,14 @@ menu_logging_cb(gpointer data, guint action, GtkWidget *widget)
}
static void
-menu_toolbar_cb(gpointer data, guint action, GtkWidget *widget)
+menu_toolbar_cb(GtkAction *action, gpointer data)
{
purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar",
- gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)));
+ gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)));
}
static void
-menu_sounds_cb(gpointer data, guint action, GtkWidget *widget)
+menu_sounds_cb(GtkAction *action, gpointer data)
{
PidginWindow *win = data;
PurpleConversation *conv;
@@ -1417,20 +1504,13 @@ menu_sounds_cb(gpointer data, guint action, GtkWidget *widget)
gtkconv = PIDGIN_CONVERSATION(conv);
gtkconv->make_sound =
- gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+ gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
node = get_conversation_blist_node(conv);
if (node)
purple_blist_node_set_bool(node, "gtk-mute-sound", !gtkconv->make_sound);
}
static void
-menu_timestamps_cb(gpointer data, guint action, GtkWidget *widget)
-{
- purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps",
- gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)));
-}
-
-static void
chat_do_im(PidginConversation *gtkconv, const char *who)
{
PurpleConversation *conv = gtkconv->active_conv;
@@ -1445,7 +1525,7 @@ chat_do_im(PidginConversation *gtkconv, const char *who)
gc = purple_account_get_connection(account);
g_return_if_fail(gc != NULL);
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
if (prpl_info && prpl_info->get_cb_real_name)
real_who = prpl_info->get_cb_real_name(gc,
@@ -1496,12 +1576,12 @@ menu_chat_send_file_cb(GtkWidget *w, PidginConversation *gtkconv)
PurplePluginProtocolInfo *prpl_info;
PurpleConversation *conv = gtkconv->active_conv;
const char *who = g_object_get_data(G_OBJECT(w), "user_data");
- PurpleConnection *gc = purple_conversation_get_gc(conv);
+ PurpleConnection *gc = purple_conversation_get_connection(conv);
gchar *real_who = NULL;
g_return_if_fail(gc != NULL);
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
if (prpl_info && prpl_info->get_cb_real_name)
real_who = prpl_info->get_cb_real_name(gc,
@@ -1522,32 +1602,6 @@ menu_chat_info_cb(GtkWidget *w, PidginConversation *gtkconv)
}
static void
-menu_chat_get_away_cb(GtkWidget *w, PidginConversation *gtkconv)
-{
- PurpleConversation *conv = gtkconv->active_conv;
- PurplePluginProtocolInfo *prpl_info = NULL;
- PurpleConnection *gc;
- char *who;
-
- gc = purple_conversation_get_gc(conv);
- who = g_object_get_data(G_OBJECT(w), "user_data");
-
- if (gc != NULL) {
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
-
- /*
- * May want to expand this to work similarly to menu_info_cb?
- */
-
- if (prpl_info->get_cb_away != NULL)
- {
- prpl_info->get_cb_away(gc,
- purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who);
- }
- }
-}
-
-static void
menu_chat_add_remove_cb(GtkWidget *w, PidginConversation *gtkconv)
{
PurpleConversation *conv = gtkconv->active_conv;
@@ -1570,7 +1624,7 @@ menu_chat_add_remove_cb(GtkWidget *w, PidginConversation *gtkconv)
static GtkTextMark *
get_mark_for_user(PidginConversation *gtkconv, const char *who)
{
- GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml));
+ GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->webview));
char *tmp = g_strconcat("user:", who, NULL);
GtkTextMark *mark = gtk_text_buffer_get_mark(buf, tmp);
@@ -1581,6 +1635,8 @@ get_mark_for_user(PidginConversation *gtkconv, const char *who)
static void
menu_last_said_cb(GtkWidget *w, PidginConversation *gtkconv)
{
+/* TODO WEBKIT: This doesn't work yet, of course... */
+#if 0
GtkTextMark *mark;
const char *who;
@@ -1591,6 +1647,7 @@ menu_last_said_cb(GtkWidget *w, PidginConversation *gtkconv)
gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(gtkconv->imhtml), mark, 0.1, FALSE, 0, 0);
else
g_return_if_reached();
+#endif /* if 0 */
}
static GtkWidget *
@@ -1599,12 +1656,13 @@ create_chat_menu(PurpleConversation *conv, const char *who, PurpleConnection *gc
static GtkWidget *menu = NULL;
PurplePluginProtocolInfo *prpl_info = NULL;
PurpleConvChat *chat = PURPLE_CONV_CHAT(conv);
+ PurpleAccount *account = purple_conversation_get_account(conv);
gboolean is_me = FALSE;
GtkWidget *button;
PurpleBuddy *buddy = NULL;
if (gc != NULL)
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
/*
* If a menu already exists, destroy it before creating a new one,
@@ -1613,7 +1671,7 @@ create_chat_menu(PurpleConversation *conv, const char *who, PurpleConnection *gc
if (menu)
gtk_widget_destroy(menu);
- if (!strcmp(chat->nick, purple_normalize(conv->account, who)))
+ if (!strcmp(purple_conv_chat_get_nick(chat), purple_normalize(account, who)))
is_me = TRUE;
menu = gtk_menu_new();
@@ -1678,18 +1736,8 @@ create_chat_menu(PurpleConversation *conv, const char *who, PurpleConnection *gc
g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
}
- if (prpl_info && prpl_info->get_cb_away) {
- button = pidgin_new_item_from_stock(menu, _("Get Away Message"), PIDGIN_STOCK_AWAY,
- G_CALLBACK(menu_chat_get_away_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL);
-
- if (gc == NULL)
- gtk_widget_set_sensitive(button, FALSE);
- else
- g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
- }
-
if (!is_me && prpl_info && !(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
- if ((buddy = purple_find_buddy(conv->account, who)) != NULL)
+ if ((buddy = purple_find_buddy(account, who)) != NULL)
button = pidgin_new_item_from_stock(menu, _("Remove"), GTK_STOCK_REMOVE,
G_CALLBACK(menu_chat_add_remove_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL);
else
@@ -1710,8 +1758,8 @@ create_chat_menu(PurpleConversation *conv, const char *who, PurpleConnection *gc
if (buddy != NULL)
{
- if (purple_account_is_connected(conv->account))
- pidgin_append_blist_node_proto_menu(menu, conv->account->gc,
+ if (purple_account_is_connected(account))
+ pidgin_append_blist_node_proto_menu(menu, purple_account_get_connection(account),
(PurpleBlistNode *)buddy);
pidgin_append_blist_node_extended_menu(menu, (PurpleBlistNode *)buddy);
gtk_widget_show_all(menu);
@@ -1737,7 +1785,7 @@ gtkconv_chat_popup_menu_cb(GtkWidget *widget, PidginConversation *gtkconv)
gtkconv = PIDGIN_CONVERSATION(conv);
gtkchat = gtkconv->u.chat;
account = purple_conversation_get_account(conv);
- gc = account->gc;
+ gc = purple_account_get_connection(account);
model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
@@ -1773,7 +1821,7 @@ right_click_chat_cb(GtkWidget *widget, GdkEventButton *event,
gtkchat = gtkconv->u.chat;
account = purple_conversation_get_account(conv);
- gc = account->gc;
+ gc = purple_account_get_connection(account);
model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
@@ -1805,10 +1853,13 @@ right_click_chat_cb(GtkWidget *widget, GdkEventButton *event,
chat_do_im(gtkconv, who);
} else if (event->button == 2 && event->type == GDK_BUTTON_PRESS) {
/* Move to user's anchor */
+/* TODO WEBKIT: This isn't implemented yet. */
+#if 0
GtkTextMark *mark = get_mark_for_user(gtkconv, who);
if(mark != NULL)
gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(gtkconv->imhtml), mark, 0.1, FALSE, 0, 0);
+#endif /* if 0 */
} else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) {
GtkWidget *menu = create_chat_menu (conv, who, gc);
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
@@ -1885,8 +1936,8 @@ gtkconv_cycle_focus(PidginConversation *gtkconv, GtkDirectionType dir)
GtkWidget *from;
GtkWidget *to;
} transitions[] = {
- {gtkconv->entry, gtkconv->imhtml},
- {gtkconv->imhtml, chat ? gtkconv->u.chat->list : gtkconv->entry},
+ {gtkconv->entry, gtkconv->webview},
+ {gtkconv->webview, chat ? gtkconv->u.chat->list : gtkconv->entry},
{chat ? gtkconv->u.chat->list : NULL, gtkconv->entry},
{NULL, NULL}
}, *ptr;
@@ -2142,14 +2193,14 @@ entry_key_press_cb(GtkWidget *entry, GdkEventKey *event, gpointer data)
break;
case GDK_Page_Up:
- case GDK_KP_Page_Up:
- gtk_imhtml_page_up(GTK_IMHTML(gtkconv->imhtml));
+ case GDK_KP_Page_Up:
+ gtk_webview_page_up(GTK_WEBVIEW(gtkconv->webview));
return TRUE;
break;
case GDK_Page_Down:
- case GDK_KP_Page_Down:
- gtk_imhtml_page_down(GTK_IMHTML(gtkconv->imhtml));
+ case GDK_KP_Page_Down:
+ gtk_webview_page_down(GTK_WEBVIEW(gtkconv->webview));
return TRUE;
break;
@@ -2236,6 +2287,7 @@ pidgin_conv_switch_active_conversation(PurpleConversation *conv)
PurpleConversation *old_conv;
GtkIMHtml *entry;
const char *protocol_name;
+ PurpleConnectionFlags features;
g_return_if_fail(conv != NULL);
@@ -2254,17 +2306,18 @@ pidgin_conv_switch_active_conversation(PurpleConversation *conv)
gtkconv->active_conv = conv;
purple_conversation_set_logging(conv,
- gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging)));
+ gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(gtkconv->win->menu.logging)));
entry = GTK_IMHTML(gtkconv->entry);
- protocol_name = purple_account_get_protocol_name(conv->account);
+ protocol_name = purple_account_get_protocol_name(purple_conversation_get_account(conv));
gtk_imhtml_set_protocol_name(entry, protocol_name);
- gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol_name);
+ /* TODO WEBKIT: gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol_name); */
- if (!(conv->features & PURPLE_CONNECTION_HTML))
+ features = purple_conversation_get_features(conv);
+ if (!(features & PURPLE_CONNECTION_HTML))
gtk_imhtml_clear_formatting(GTK_IMHTML(gtkconv->entry));
- else if (conv->features & PURPLE_CONNECTION_FORMATTING_WBFO &&
- !(old_conv->features & PURPLE_CONNECTION_FORMATTING_WBFO))
+ else if (features & PURPLE_CONNECTION_FORMATTING_WBFO &&
+ !(purple_conversation_get_features(old_conv) & PURPLE_CONNECTION_FORMATTING_WBFO))
{
/* The old conversation allowed formatting on parts of the
* buffer, but the new one only allows it on the whole
@@ -2304,12 +2357,12 @@ pidgin_conv_switch_active_conversation(PurpleConversation *conv)
gtk_imhtml_toggle_fontface(entry, fontface);
- if (!(conv->features & PURPLE_CONNECTION_NO_FONTSIZE))
+ if (!(features & PURPLE_CONNECTION_NO_FONTSIZE))
gtk_imhtml_font_set_size(entry, fontsize);
gtk_imhtml_toggle_forecolor(entry, forecolor);
- if (!(conv->features & PURPLE_CONNECTION_NO_BGCOLOR))
+ if (!(features & PURPLE_CONNECTION_NO_BGCOLOR))
{
gtk_imhtml_toggle_backcolor(entry, backcolor);
gtk_imhtml_toggle_background(entry, background);
@@ -2327,7 +2380,7 @@ pidgin_conv_switch_active_conversation(PurpleConversation *conv)
* here, we didn't call gtk_imhtml_clear_formatting() (because we want to
* preserve the formatting exactly as it is), so we have to do this now. */
gtk_imhtml_set_whole_buffer_formatting_only(entry,
- (conv->features & PURPLE_CONNECTION_FORMATTING_WBFO));
+ (features & PURPLE_CONNECTION_FORMATTING_WBFO));
}
purple_signal_emit(pidgin_conversations_get_handle(), "conversation-switched", conv);
@@ -2392,7 +2445,7 @@ delete_text_cb(GtkTextBuffer *textbuffer, GtkTextIter *start_pos,
/* We deleted all the text, so turn off typing. */
purple_conv_im_stop_send_typed_timeout(im);
- serv_send_typing(purple_conversation_get_gc(conv),
+ serv_send_typing(purple_conversation_get_connection(conv),
purple_conversation_get_name(conv),
PURPLE_NOT_TYPING);
}
@@ -2557,7 +2610,7 @@ update_tab_icon(PurpleConversation *conv)
status = infopane_status = pidgin_conv_get_icon_stock(conv);
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- PurpleBuddy *b = purple_find_buddy(conv->account, conv->name);
+ PurpleBuddy *b = purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv));
if (b)
emblem = pidgin_blist_get_emblem((PurpleBlistNode*)b);
}
@@ -2578,7 +2631,7 @@ update_tab_icon(PurpleConversation *conv)
g_object_unref(emblem);
if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons")) {
- emblem = pidgin_create_prpl_icon(gtkconv->active_conv->account, PIDGIN_PRPL_ICON_SMALL);
+ emblem = pidgin_create_prpl_icon(purple_conversation_get_account(gtkconv->active_conv), PIDGIN_PRPL_ICON_SMALL);
} else {
emblem = NULL;
}
@@ -2634,7 +2687,7 @@ redraw_icon(gpointer data)
gtkconv = PIDGIN_CONVERSATION(conv);
account = purple_conversation_get_account(conv);
- if (!(account && account->gc)) {
+ if (!(account && purple_account_get_connection(account))) {
gtkconv->u.im->icon_timer = 0;
return FALSE;
}
@@ -2841,11 +2894,11 @@ icon_menu_save_cb(GtkWidget *widget, PidginConversation *gtkconv)
ext = purple_buddy_icon_get_extension(purple_conv_im_get_icon(PURPLE_CONV_IM(conv)));
- buf = g_strdup_printf("%s.%s", purple_normalize(conv->account, conv->name), ext);
+ buf = g_strdup_printf("%s.%s", purple_normalize(purple_conversation_get_account(conv), purple_conversation_get_name(conv)), ext);
purple_request_file(gtkconv, _("Save Icon"), buf, TRUE,
G_CALLBACK(saveicon_writefile_cb), NULL,
- conv->account, NULL, conv,
+ purple_conversation_get_account(conv), NULL, conv,
gtkconv);
g_free(buf);
@@ -3068,91 +3121,96 @@ pidgin_conv_get_window(PidginConversation *gtkconv)
return gtkconv->win;
}
-static GtkItemFactoryEntry menu_items[] =
+static GtkActionEntry menu_entries[] =
+/* TODO: fill out tooltips... */
{
/* Conversation menu */
- { N_("/_Conversation"), NULL, NULL, 0, "<Branch>", NULL },
-
- { N_("/Conversation/New Instant _Message..."), "<CTL>M", menu_new_conv_cb,
- 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW },
- { N_("/Conversation/Join a _Chat..."), NULL, menu_join_chat_cb,
- 0, "<StockItem>", PIDGIN_STOCK_CHAT },
-
- { "/Conversation/sep0", NULL, NULL, 0, "<Separator>", NULL },
-
- { N_("/Conversation/_Find..."), NULL, menu_find_cb, 0,
- "<StockItem>", GTK_STOCK_FIND },
- { N_("/Conversation/View _Log"), NULL, menu_view_log_cb, 0, "<Item>", NULL },
- { N_("/Conversation/_Save As..."), NULL, menu_save_as_cb, 0,
- "<StockItem>", GTK_STOCK_SAVE_AS },
- { N_("/Conversation/Clea_r Scrollback"), "<CTL>L", menu_clear_cb, 0, "<StockItem>", GTK_STOCK_CLEAR },
-
- { "/Conversation/sep1", NULL, NULL, 0, "<Separator>", NULL },
+ { "ConversationMenu", NULL, N_("_Conversation"), NULL, NULL, NULL },
+ { "NewInstantMessage", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, N_("New Instant _Message..."), "<control>M", NULL, G_CALLBACK(menu_new_conv_cb) },
+ { "JoinAChat", PIDGIN_STOCK_CHAT, N_("Join a _Chat..."), NULL, NULL, G_CALLBACK(menu_join_chat_cb) },
+ { "Find", GTK_STOCK_FIND, N_("_Find..."), NULL, NULL, G_CALLBACK(menu_find_cb) },
+ { "ViewLog", NULL, N_("View _Log"), NULL, NULL, G_CALLBACK(menu_view_log_cb) },
+ { "SaveAs", GTK_STOCK_SAVE_AS, N_("_Save As..."), NULL, NULL, G_CALLBACK(menu_save_as_cb) },
+ { "ClearScrollback", GTK_STOCK_CLEAR, N_("Clea_r Scrollback"), "<control>L", NULL, G_CALLBACK(menu_clear_cb) },
#ifdef USE_VV
- { N_("/Conversation/M_edia"), NULL, NULL, 0, "<Branch>", NULL },
-
- { N_("/Conversation/Media/_Audio Call"), NULL, menu_initiate_media_call_cb, 0,
- "<StockItem>", PIDGIN_STOCK_TOOLBAR_AUDIO_CALL },
- { N_("/Conversation/Media/_Video Call"), NULL, menu_initiate_media_call_cb, 1,
- "<StockItem>", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL },
- { N_("/Conversation/Media/Audio\\/Video _Call"), NULL, menu_initiate_media_call_cb, 2,
- "<StockItem>", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL },
+ { "MediaMenu", NULL, N_("M_edia"), NULL, NULL, NULL },
+ { "AudioCall", PIDGIN_STOCK_TOOLBAR_AUDIO_CALL, N_("_Audio Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
+ { "VideoCall", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL, N_("_Video Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
+ { "AudioVideoCall", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL, N_("Audio/Video _Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
#endif
- { N_("/Conversation/Se_nd File..."), NULL, menu_send_file_cb, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_SEND_FILE },
- { N_("/Conversation/Get _Attention"), NULL, menu_get_attention_cb, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION },
- { N_("/Conversation/Add Buddy _Pounce..."), NULL, menu_add_pounce_cb,
- 0, "<Item>", NULL },
- { N_("/Conversation/_Get Info"), "<CTL>O", menu_get_info_cb, 0,
- "<StockItem>", PIDGIN_STOCK_TOOLBAR_USER_INFO },
- { N_("/Conversation/In_vite..."), NULL, menu_invite_cb, 0,
- "<Item>", NULL },
- { N_("/Conversation/M_ore"), NULL, NULL, 0, "<Branch>", NULL },
-
- { "/Conversation/sep2", NULL, NULL, 0, "<Separator>", NULL },
-
- { N_("/Conversation/Al_ias..."), NULL, menu_alias_cb, 0,
- "<Item>", NULL },
- { N_("/Conversation/_Block..."), NULL, menu_block_cb, 0,
- "<StockItem>", PIDGIN_STOCK_TOOLBAR_BLOCK },
- { N_("/Conversation/_Unblock..."), NULL, menu_unblock_cb, 0,
- "<StockItem>", PIDGIN_STOCK_TOOLBAR_UNBLOCK },
- { N_("/Conversation/_Add..."), NULL, menu_add_remove_cb, 0,
- "<StockItem>", GTK_STOCK_ADD },
- { N_("/Conversation/_Remove..."), NULL, menu_add_remove_cb, 0,
- "<StockItem>", GTK_STOCK_REMOVE },
-
- { "/Conversation/sep3", NULL, NULL, 0, "<Separator>", NULL },
-
- { N_("/Conversation/Insert Lin_k..."), NULL, menu_insert_link_cb, 0,
- "<StockItem>", PIDGIN_STOCK_TOOLBAR_INSERT_LINK },
- { N_("/Conversation/Insert Imag_e..."), NULL, menu_insert_image_cb, 0,
- "<StockItem>", PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE },
-
- { "/Conversation/sep4", NULL, NULL, 0, "<Separator>", NULL },
-
-
- { N_("/Conversation/_Close"), NULL, menu_close_conv_cb, 0,
- "<StockItem>", GTK_STOCK_CLOSE },
+ { "SendFile", PIDGIN_STOCK_TOOLBAR_SEND_FILE, N_("Se_nd File..."), NULL, NULL, G_CALLBACK(menu_send_file_cb) },
+ { "GetAttention", PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION, N_("Get _Attention"), NULL, NULL, G_CALLBACK(menu_get_attention_cb) },
+ { "AddBuddyPounce", NULL, N_("Add Buddy _Pounce..."), NULL, NULL, G_CALLBACK(menu_add_pounce_cb) },
+ { "GetInfo", PIDGIN_STOCK_TOOLBAR_USER_INFO, N_("_Get Info"), "<control>O", NULL, G_CALLBACK(menu_get_info_cb) },
+ { "Invite", NULL, N_("In_vite..."), NULL, NULL, G_CALLBACK(menu_invite_cb) },
+ { "MoreMenu", NULL, N_("M_ore"), NULL, NULL, NULL },
+ { "Alias", NULL, N_("Al_ias..."), NULL, NULL, G_CALLBACK(menu_alias_cb) },
+ { "Block", PIDGIN_STOCK_TOOLBAR_BLOCK, N_("_Block..."), NULL, NULL, G_CALLBACK(menu_block_cb) },
+ { "Unblock", PIDGIN_STOCK_TOOLBAR_UNBLOCK, N_("_Unblock..."), NULL, NULL, G_CALLBACK(menu_unblock_cb) },
+ { "Add", GTK_STOCK_ADD, N_("_Add..."), NULL, NULL, G_CALLBACK(menu_add_remove_cb) },
+ { "Remove", GTK_STOCK_REMOVE, N_("_Remove..."), NULL, NULL, G_CALLBACK(menu_add_remove_cb) },
+ { "InsertLink", PIDGIN_STOCK_TOOLBAR_INSERT_LINK, N_("Insert Lin_k..."), NULL, NULL, G_CALLBACK(menu_insert_link_cb) },
+ { "InsertImage", PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE, N_("Insert Imag_e..."), NULL, NULL, G_CALLBACK(menu_insert_image_cb) },
+ { "Close", GTK_STOCK_CLOSE, N_("_Close"), NULL, NULL, G_CALLBACK(menu_close_conv_cb) },
/* Options */
- { N_("/_Options"), NULL, NULL, 0, "<Branch>", NULL },
- { N_("/Options/Enable _Logging"), NULL, menu_logging_cb, 0, "<CheckItem>", NULL },
- { N_("/Options/Enable _Sounds"), NULL, menu_sounds_cb, 0, "<CheckItem>", NULL },
- { "/Options/sep0", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Options/Show Formatting _Toolbars"), NULL, menu_toolbar_cb, 0, "<CheckItem>", NULL },
- { N_("/Options/Show Ti_mestamps"), NULL, menu_timestamps_cb, 0, "<CheckItem>", NULL },
+ { "OptionsMenu", NULL, N_("_Options"), NULL, NULL, NULL },
};
-static const int menu_item_count =
-sizeof(menu_items) / sizeof(*menu_items);
+/* Toggle items */
+static const GtkToggleActionEntry menu_toggle_entries[] = {
+ { "EnableLogging", NULL, N_("Enable _Logging"), NULL, NULL, G_CALLBACK(menu_logging_cb), FALSE },
+ { "EnableSounds", NULL, N_("Enable _Sounds"), NULL, NULL, G_CALLBACK(menu_sounds_cb), FALSE },
+ { "ShowFormattingToolbars", NULL, N_("Show Formatting _Toolbars"), NULL, NULL, G_CALLBACK(menu_toolbar_cb), FALSE },
+};
-static const char *
-item_factory_translate_func (const char *path, gpointer func_data)
-{
- return _(path);
-}
+static const char *conversation_menu =
+"<ui>"
+ "<menubar name='Conversation'>"
+ "<menu action='ConversationMenu'>"
+ "<menuitem action='NewInstantMessage'/>"
+ "<menuitem action='JoinAChat'/>"
+ "<separator/>"
+ "<menuitem action='Find'/>"
+ "<menuitem action='ViewLog'/>"
+ "<menuitem action='SaveAs'/>"
+ "<menuitem action='ClearScrollback'/>"
+ "<separator/>"
+#ifdef USE_VV
+ "<menu action='MediaMenu'>"
+ "<menuitem action='AudioCall'/>"
+ "<menuitem action='VideoCall'/>"
+ "<menuitem action='AudioVideoCall'/>"
+ "</menu>"
+#endif
+ "<menuitem action='SendFile'/>"
+ "<menuitem action='GetAttention'/>"
+ "<menuitem action='AddBuddyPounce'/>"
+ "<menuitem action='GetInfo'/>"
+ "<menuitem action='Invite'/>"
+ "<menu action='MoreMenu'/>"
+ "<separator/>"
+ "<menuitem action='Alias'/>"
+ "<menuitem action='Block'/>"
+ "<menuitem action='Unblock'/>"
+ "<menuitem action='Add'/>"
+ "<menuitem action='Remove'/>"
+ "<separator/>"
+ "<menuitem action='InsertLink'/>"
+ "<menuitem action='InsertImage'/>"
+ "<separator/>"
+ "<menuitem action='Close'/>"
+ "</menu>"
+ "<menu action='OptionsMenu'>"
+ "<menuitem action='EnableLogging'/>"
+ "<menuitem action='EnableSounds'/>"
+ "<separator/>"
+ "<menuitem action='ShowFormattingToolbars'/>"
+ "</menu>"
+ "</menubar>"
+"</ui>";
static void
sound_method_pref_changed_cb(const char *name, PurplePrefType type,
@@ -3163,19 +3221,18 @@ sound_method_pref_changed_cb(const char *name, PurplePrefType type,
if (!strcmp(method, "none"))
{
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds),
- FALSE);
- gtk_widget_set_sensitive(win->menu.sounds, FALSE);
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
+ FALSE);
+ gtk_action_set_sensitive(win->menu.sounds, FALSE);
}
else
{
PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(win);
if (gtkconv != NULL)
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds),
- gtkconv->make_sound);
- gtk_widget_set_sensitive(win->menu.sounds, TRUE);
-
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
+ gtkconv->make_sound);
+ gtk_action_set_sensitive(win->menu.sounds, TRUE);
}
}
@@ -3185,21 +3242,23 @@ populate_menu_with_options(GtkWidget *menu, PidginConversation *gtkconv, gboolea
{
GList *list;
PurpleConversation *conv;
+ PurpleAccount *account;
PurpleBlistNode *node = NULL;
PurpleChat *chat = NULL;
PurpleBuddy *buddy = NULL;
gboolean ret;
conv = gtkconv->active_conv;
+ account = purple_conversation_get_account(conv);
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
- chat = purple_blist_find_chat(conv->account, conv->name);
+ chat = purple_blist_find_chat(account, purple_conversation_get_name(conv));
- if ((chat == NULL) && (gtkconv->imhtml != NULL)) {
- chat = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_chat");
+ if ((chat == NULL) && (gtkconv->webview != NULL)) {
+ chat = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_chat");
}
- if ((chat == NULL) && (gtkconv->imhtml != NULL)) {
+ if ((chat == NULL) && (gtkconv->webview != NULL)) {
GHashTable *components;
PurpleAccount *account = purple_conversation_get_account(conv);
PurplePlugin *prpl = purple_find_prpl(purple_account_get_protocol_id(account));
@@ -3214,30 +3273,30 @@ populate_menu_with_options(GtkWidget *menu, PidginConversation *gtkconv, gboolea
g_hash_table_replace(components, g_strdup("channel"),
g_strdup(purple_conversation_get_name(conv)));
}
- chat = purple_chat_new(conv->account, NULL, components);
+ chat = purple_chat_new(account, NULL, components);
purple_blist_node_set_flags((PurpleBlistNode *)chat,
PURPLE_BLIST_NODE_FLAG_NO_SAVE);
- g_object_set_data_full(G_OBJECT(gtkconv->imhtml), "transient_chat",
+ g_object_set_data_full(G_OBJECT(gtkconv->webview), "transient_chat",
chat, (GDestroyNotify)purple_blist_remove_chat);
}
} else {
- if (!purple_account_is_connected(conv->account))
+ if (!purple_account_is_connected(account))
return FALSE;
- buddy = purple_find_buddy(conv->account, conv->name);
+ buddy = purple_find_buddy(account, purple_conversation_get_name(conv));
/* gotta remain bug-compatible :( libpurple < 2.0.2 didn't handle
* removing "isolated" buddy nodes well */
if (purple_version_check(2, 0, 2) == NULL) {
- if ((buddy == NULL) && (gtkconv->imhtml != NULL)) {
- buddy = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_buddy");
+ if ((buddy == NULL) && (gtkconv->webview != NULL)) {
+ buddy = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_buddy");
}
- if ((buddy == NULL) && (gtkconv->imhtml != NULL)) {
- buddy = purple_buddy_new(conv->account, conv->name, NULL);
+ if ((buddy == NULL) && (gtkconv->webview != NULL)) {
+ buddy = purple_buddy_new(account, purple_conversation_get_name(conv), NULL);
purple_blist_node_set_flags((PurpleBlistNode *)buddy,
PURPLE_BLIST_NODE_FLAG_NO_SAVE);
- g_object_set_data_full(G_OBJECT(gtkconv->imhtml), "transient_buddy",
+ g_object_set_data_full(G_OBJECT(gtkconv->webview), "transient_buddy",
buddy, (GDestroyNotify)purple_buddy_destroy);
}
}
@@ -3256,8 +3315,8 @@ populate_menu_with_options(GtkWidget *menu, PidginConversation *gtkconv, gboolea
/* XXX: */
}
} else if (node) {
- if (purple_account_is_connected(conv->account))
- pidgin_append_blist_node_proto_menu(menu, conv->account->gc, node);
+ if (purple_account_is_connected(account))
+ pidgin_append_blist_node_proto_menu(menu, purple_account_get_connection(account), node);
pidgin_append_blist_node_extended_menu(menu, node);
}
@@ -3303,38 +3362,100 @@ regenerate_media_items(PidginWindow *win)
purple_prpl_get_media_caps(account,
purple_conversation_get_name(conv));
- gtk_widget_set_sensitive(win->audio_call,
+ gtk_action_set_sensitive(win->menu.audio_call,
caps & PURPLE_MEDIA_CAPS_AUDIO
? TRUE : FALSE);
- gtk_widget_set_sensitive(win->video_call,
+ gtk_action_set_sensitive(win->menu.video_call,
caps & PURPLE_MEDIA_CAPS_VIDEO
? TRUE : FALSE);
- gtk_widget_set_sensitive(win->audio_video_call,
+ gtk_action_set_sensitive(win->menu.audio_video_call,
caps & PURPLE_MEDIA_CAPS_AUDIO_VIDEO
? TRUE : FALSE);
} else if (purple_conversation_get_type(conv)
== PURPLE_CONV_TYPE_CHAT) {
/* for now, don't care about chats... */
- gtk_widget_set_sensitive(win->audio_call, FALSE);
- gtk_widget_set_sensitive(win->video_call, FALSE);
- gtk_widget_set_sensitive(win->audio_video_call, FALSE);
+ gtk_action_set_sensitive(win->menu.audio_call, FALSE);
+ gtk_action_set_sensitive(win->menu.video_call, FALSE);
+ gtk_action_set_sensitive(win->menu.audio_video_call, FALSE);
} else {
- gtk_widget_set_sensitive(win->audio_call, FALSE);
- gtk_widget_set_sensitive(win->video_call, FALSE);
- gtk_widget_set_sensitive(win->audio_video_call, FALSE);
+ gtk_action_set_sensitive(win->menu.audio_call, FALSE);
+ gtk_action_set_sensitive(win->menu.video_call, FALSE);
+ gtk_action_set_sensitive(win->menu.audio_video_call, FALSE);
}
#endif
}
static void
+regenerate_attention_items(PidginWindow *win)
+{
+ GtkWidget *attention;
+ GtkWidget *menu;
+ PurpleConversation *conv;
+ PurpleConnection *pc;
+ PurplePlugin *prpl = NULL;
+ PurplePluginProtocolInfo *prpl_info = NULL;
+ GList *list;
+
+ conv = pidgin_conv_window_get_active_conversation(win);
+ if (!conv)
+ return;
+
+ attention = gtk_ui_manager_get_widget(win->menu.ui,
+ "/Conversation/ConversationMenu/GetAttention");
+
+ /* Remove the previous entries */
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(attention), NULL);
+
+ pc = purple_conversation_get_connection(conv);
+ if (pc != NULL)
+ prpl = purple_connection_get_prpl(pc);
+ if (prpl != NULL)
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
+
+ if (prpl_info && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_attention_types)) {
+ list = prpl_info->get_attention_types(purple_connection_get_account(pc));
+
+ /* Multiple attention types */
+ if (list && list->next) {
+ int index = 0;
+
+ menu = gtk_menu_new();
+ while (list) {
+ PurpleAttentionType *type;
+ GtkWidget *menuitem;
+
+ type = list->data;
+
+ menuitem = gtk_menu_item_new_with_label(purple_attention_type_get_name(type));
+ g_object_set_data(G_OBJECT(menuitem), "index", GINT_TO_POINTER(index));
+ g_signal_connect(G_OBJECT(menuitem), "activate",
+ G_CALLBACK(menu_get_attention_cb),
+ win);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+
+ index++;
+ list = g_list_delete_link(list, list);
+ }
+
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(attention), menu);
+ gtk_widget_show_all(menu);
+ }
+ }
+}
+
+static void
regenerate_options_items(PidginWindow *win)
{
GtkWidget *menu;
PidginConversation *gtkconv;
GList *list;
+ GtkWidget *more_menu;
gtkconv = pidgin_conv_window_get_active_gtkconv(win);
- menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Conversation/More"));
+ more_menu = gtk_ui_manager_get_widget(win->menu.ui,
+ "/Conversation/ConversationMenu/MoreMenu");
+ gtk_widget_show(more_menu);
+ menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(more_menu));
/* Remove the previous entries */
for (list = gtk_container_get_children(GTK_CONTAINER(menu)); list; )
@@ -3390,7 +3511,8 @@ regenerate_plugins_items(PidginWindow *win)
action_items = g_list_delete_link(action_items, action_items);
}
- menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Options"));
+ item = gtk_ui_manager_get_widget(win->menu.ui, "/Conversation/OptionsMenu");
+ menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(item));
list = purple_conversation_get_extended_menu(conv);
if (list) {
@@ -3414,6 +3536,7 @@ static void menubar_activated(GtkWidget *item, gpointer data)
regenerate_media_items(win);
regenerate_options_items(win);
regenerate_plugins_items(win);
+ regenerate_attention_items(win);
/* The following are to make sure the 'More' submenu is not regenerated every time
* the focus shifts from 'Conversations' to some other menu and back. */
@@ -3426,7 +3549,7 @@ focus_out_from_menubar(GtkWidget *wid, PidginWindow *win)
{
/* The menubar has been deactivated. Make sure the 'More' submenu is regenerated next time
* the 'Conversation' menu pops up. */
- GtkWidget *menuitem = gtk_item_factory_get_item(win->menu.item_factory, N_("/Conversation"));
+ GtkWidget *menuitem = gtk_ui_manager_get_widget(win->menu.ui, "/Conversation/ConversationMenu");
g_signal_handlers_unblock_by_func(G_OBJECT(menuitem), G_CALLBACK(menubar_activated), win);
g_signal_handlers_disconnect_by_func(G_OBJECT(win->menu.menubar),
G_CALLBACK(focus_out_from_menubar), win);
@@ -3437,129 +3560,142 @@ setup_menubar(PidginWindow *win)
{
GtkAccelGroup *accel_group;
const char *method;
+ GtkActionGroup *action_group;
+ GError *error;
GtkWidget *menuitem;
- accel_group = gtk_accel_group_new ();
- gtk_window_add_accel_group(GTK_WINDOW(win->window), accel_group);
- g_object_unref(accel_group);
-
- win->menu.item_factory =
- gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
+ action_group = gtk_action_group_new("ConversationActions");
+ gtk_action_group_add_actions(action_group,
+ menu_entries,
+ G_N_ELEMENTS(menu_entries),
+ win);
+ gtk_action_group_add_toggle_actions(action_group,
+ menu_toggle_entries,
+ G_N_ELEMENTS(menu_toggle_entries),
+ win);
+#ifdef ENABLE_NLS
+ gtk_action_group_set_translation_domain(action_group,
+ PACKAGE);
+#endif
- gtk_item_factory_set_translate_func(win->menu.item_factory,
- (GtkTranslateFunc)item_factory_translate_func,
- NULL, NULL);
+ win->menu.ui = gtk_ui_manager_new();
+ gtk_ui_manager_insert_action_group(win->menu.ui, action_group, 0);
- gtk_item_factory_create_items(win->menu.item_factory, menu_item_count,
- menu_items, win);
+ accel_group = gtk_ui_manager_get_accel_group(win->menu.ui);
+ gtk_window_add_accel_group(GTK_WINDOW(win->window), accel_group);
g_signal_connect(G_OBJECT(accel_group), "accel-changed",
G_CALLBACK(pidgin_save_accels_cb), NULL);
+ error = NULL;
+ if (!gtk_ui_manager_add_ui_from_string(win->menu.ui, conversation_menu, -1, &error))
+ {
+ g_message("building menus failed: %s", error->message);
+ g_error_free(error);
+ exit(EXIT_FAILURE);
+ }
+
+ win->menu.menubar =
+ gtk_ui_manager_get_widget(win->menu.ui, "/Conversation");
+
/* Make sure the 'Conversation -> More' menuitems are regenerated whenever
* the 'Conversation' menu pops up because the entries can change after the
* conversation is created. */
- menuitem = gtk_item_factory_get_item(win->menu.item_factory, N_("/Conversation"));
+ menuitem = gtk_ui_manager_get_widget(win->menu.ui, "/Conversation/ConversationMenu");
g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(menubar_activated), win);
- win->menu.menubar =
- gtk_item_factory_get_widget(win->menu.item_factory, "<main>");
-
win->menu.view_log =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Conversation/View Log"));
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/ConversationMenu/ViewLog");
#ifdef USE_VV
- win->audio_call =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Conversation/Media/Audio Call"));
- win->video_call =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Conversation/Media/Video Call"));
- win->audio_video_call =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Conversation/Media/Audio\\/Video Call"));
+ win->menu.audio_call =
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/ConversationMenu/MediaMenu/AudioCall");
+ win->menu.video_call =
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/ConversationMenu/MediaMenu/VideoCall");
+ win->menu.audio_video_call =
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/ConversationMenu/MediaMenu/AudioVideoCall");
#endif
/* --- */
win->menu.send_file =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Conversation/Send File..."));
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/ConversationMenu/SendFile");
+
+ win->menu.get_attention =
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/ConversationMenu/GetAttention");
- g_object_set_data(G_OBJECT(win->window), "get_attention",
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Conversation/Get Attention")));
win->menu.add_pounce =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Conversation/Add Buddy Pounce..."));
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/ConversationMenu/AddBuddyPounce");
/* --- */
win->menu.get_info =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Conversation/Get Info"));
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/ConversationMenu/GetInfo");
win->menu.invite =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Conversation/Invite..."));
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/ConversationMenu/Invite");
/* --- */
win->menu.alias =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Conversation/Alias..."));
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/ConversationMenu/Alias");
win->menu.block =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Conversation/Block..."));
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/ConversationMenu/Block");
win->menu.unblock =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Conversation/Unblock..."));
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/ConversationMenu/Unblock");
win->menu.add =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Conversation/Add..."));
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/ConversationMenu/Add");
win->menu.remove =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Conversation/Remove..."));
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/ConversationMenu/Remove");
/* --- */
win->menu.insert_link =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Conversation/Insert Link..."));
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/ConversationMenu/InsertLink");
win->menu.insert_image =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Conversation/Insert Image..."));
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/ConversationMenu/InsertImage");
/* --- */
win->menu.logging =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Options/Enable Logging"));
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/OptionsMenu/EnableLogging");
win->menu.sounds =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Options/Enable Sounds"));
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/OptionsMenu/EnableSounds");
method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method");
if (method != NULL && !strcmp(method, "none"))
{
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds),
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
FALSE);
- gtk_widget_set_sensitive(win->menu.sounds, FALSE);
+ gtk_action_set_sensitive(win->menu.sounds, FALSE);
}
purple_prefs_connect_callback(win, PIDGIN_PREFS_ROOT "/sound/method",
sound_method_pref_changed_cb, win);
win->menu.show_formatting_toolbar =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Options/Show Formatting Toolbars"));
- win->menu.show_timestamps =
- gtk_item_factory_get_widget(win->menu.item_factory,
- N_("/Options/Show Timestamps"));
- win->menu.show_icon = NULL;
+ gtk_ui_manager_get_action(win->menu.ui,
+ "/Conversation/OptionsMenu/ShowFormattingToolbars");
win->menu.tray = pidgin_menu_tray_new();
gtk_menu_shell_append(GTK_MENU_SHELL(win->menu.menubar),
@@ -3597,7 +3733,7 @@ got_typing_keypress(PidginConversation *gtkconv, gboolean first)
time(NULL) > purple_conv_im_get_type_again(im)))
{
unsigned int timeout;
- timeout = serv_send_typing(purple_conversation_get_gc(conv),
+ timeout = serv_send_typing(purple_conversation_get_connection(conv),
purple_conversation_get_name(conv),
PURPLE_TYPING);
purple_conv_im_set_type_again(im, timeout);
@@ -3648,6 +3784,8 @@ typing_animation(gpointer data) {
static void
update_typing_message(PidginConversation *gtkconv, const char *message)
{
+ /* TODO WEBKIT: this is not handled at all */
+#if 0
GtkTextBuffer *buffer;
GtkTextMark *stmark, *enmark;
@@ -3680,6 +3818,7 @@ update_typing_message(PidginConversation *gtkconv, const char *message)
gtk_text_buffer_get_end_iter(buffer, &iter);
gtk_text_buffer_create_mark(buffer, "typing-notification-end", &iter, TRUE);
}
+#endif /* if 0 */
}
static void
@@ -3736,10 +3875,9 @@ update_send_to_selection(PidginWindow *win)
if (win->menu.send_to == NULL)
return FALSE;
- if (!(b = purple_find_buddy(account, conv->name)))
+ if (!(b = purple_find_buddy(account, purple_conversation_get_name(conv))))
return FALSE;
-
gtk_widget_show(win->menu.send_to);
menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(win->menu.send_to));
@@ -3896,8 +4034,8 @@ generate_send_to_items(PidginWindow *win)
gtk_widget_show(menu);
- if (gtkconv->active_conv->type == PURPLE_CONV_TYPE_IM) {
- buds = purple_find_buddies(gtkconv->active_conv->account, gtkconv->active_conv->name);
+ if (purple_conversation_get_type(gtkconv->active_conv) == PURPLE_CONV_TYPE_IM) {
+ buds = purple_find_buddies(purple_conversation_get_account(gtkconv->active_conv), purple_conversation_get_name(gtkconv->active_conv));
if (buds == NULL)
{
@@ -3921,7 +4059,8 @@ generate_send_to_items(PidginWindow *win)
continue;
account = purple_buddy_get_account(buddy);
- if (purple_account_is_connected(account) || account == gtkconv->active_conv->account)
+ /* TODO WEBKIT: (I'm not actually sure if this is webkit-related --Mark Doliner) */
+ if (purple_account_is_connected(account) /*|| account == purple_conversation_get_account(gtkconv->active_conv)*/)
{
/* Use the PurplePresence to get unique buddies. */
PurplePresence *presence = purple_buddy_get_presence(buddy);
@@ -3980,10 +4119,11 @@ get_chat_buddy_status_icon(PurpleConvChat *chat, const char *name, PurpleConvCha
static void
deleting_chat_buddy_cb(PurpleConvChatBuddy *cb)
{
- if (cb->ui_data) {
- GtkTreeRowReference *ref = cb->ui_data;
+ GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cb);
+
+ if (ref) {
gtk_tree_row_reference_free(ref);
- cb->ui_data = NULL;
+ purple_conv_chat_cb_set_ui_data(cb, NULL);
}
}
@@ -4002,20 +4142,21 @@ add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const c
GtkTreeIter iter;
gboolean is_me = FALSE;
gboolean is_buddy;
- gchar *tmp, *alias_key, *name, *alias;
+ const gchar *name, *alias;
+ gchar *tmp, *alias_key;
PurpleConvChatBuddyFlags flags;
GdkColor *color = NULL;
- alias = cb->alias;
- name = cb->name;
- flags = cb->flags;
+ alias = purple_conv_chat_cb_get_alias(cb);
+ name = purple_conv_chat_cb_get_name(cb);
+ flags = purple_conv_chat_cb_get_flags(cb);
chat = PURPLE_CONV_CHAT(conv);
gtkconv = PIDGIN_CONVERSATION(conv);
gtkchat = gtkconv->u.chat;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
- if (!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)))
+ if (!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc))))
return;
tm = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
@@ -4023,20 +4164,23 @@ add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const c
stock = get_chat_buddy_status_icon(chat, name, flags);
- if (!strcmp(chat->nick, purple_normalize(conv->account, old_name != NULL ? old_name : name)))
+ if (!strcmp(purple_conv_chat_get_nick(chat), purple_normalize(purple_conversation_get_account(conv), old_name != NULL ? old_name : name)))
is_me = TRUE;
- is_buddy = cb->buddy;
+ is_buddy = purple_conv_chat_cb_is_buddy(cb);
tmp = g_utf8_casefold(alias, -1);
alias_key = g_utf8_collate_key(tmp, -1);
g_free(tmp);
if (is_me) {
+#if 0
+ /* TODO WEBKIT: No tags in webkit stuff, yet. */
GtkTextTag *tag = gtk_text_tag_table_lookup(
- gtk_text_buffer_get_tag_table(GTK_IMHTML(gtkconv->imhtml)->text_buffer),
+ gtk_text_buffer_get_tag_table(GTK_IMHTML(gtkconv->webview)->text_buffer),
"send-name");
g_object_get(tag, "foreground-gdk", &color, NULL);
+#endif /* if 0 */
} else {
GtkTextTag *tag;
if ((tag = get_buddy_tag(conv, name, 0, FALSE)))
@@ -4064,13 +4208,13 @@ add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const c
CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL,
-1);
- if (cb->ui_data) {
- GtkTreeRowReference *ref = cb->ui_data;
+ if (purple_conv_chat_cb_get_ui_data(cb)) {
+ GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cb);
gtk_tree_row_reference_free(ref);
}
newpath = gtk_tree_model_get_path(tm, &iter);
- cb->ui_data = gtk_tree_row_reference_new(tm, newpath);
+ purple_conv_chat_cb_set_ui_data(cb, gtk_tree_row_reference_new(tm, newpath));
gtk_tree_path_free(newpath);
if (is_me && color)
@@ -4100,7 +4244,7 @@ add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const c
*/
static void
tab_complete_process_item(int *most_matched, const char *entered, gsize entered_bytes, char **partial, char *nick_partial,
- GList **matches, char *name)
+ GList **matches, const char *name)
{
memcpy(nick_partial, name, entered_bytes);
if (purple_utf8_strcasecmp(nick_partial, entered))
@@ -4222,7 +4366,7 @@ tab_complete(PurpleConversation *conv)
/* Users */
for (; l != NULL; l = l->next) {
tab_complete_process_item(&most_matched, entered, entered_bytes, &partial, nick_partial,
- &matches, ((PurpleConvChatBuddy *)l->data)->name);
+ &matches, purple_conv_chat_cb_get_name((PurpleConvChatBuddy *)l->data));
}
@@ -4320,9 +4464,9 @@ static void topic_callback(GtkWidget *w, PidginConversation *gtkconv)
char *new_topic;
const char *current_topic;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
- if(!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)))
+ if(!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc))))
return;
if(prpl_info->set_chat_topic == NULL)
@@ -4397,6 +4541,7 @@ update_chat_alias(PurpleBuddy *buddy, PurpleConversation *conv, PurpleConnection
{
PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
PurpleConvChat *chat = PURPLE_CONV_CHAT(conv);
+ PurpleAccount *account = purple_conversation_get_account(conv);
GtkTreeModel *model;
char *normalized_name;
GtkTreeIter iter;
@@ -4411,23 +4556,23 @@ update_chat_alias(PurpleBuddy *buddy, PurpleConversation *conv, PurpleConnection
if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter))
return;
- normalized_name = g_strdup(purple_normalize(conv->account, buddy->name));
+ normalized_name = g_strdup(purple_normalize(account, purple_buddy_get_name(buddy)));
do {
char *name;
gtk_tree_model_get(model, &iter, CHAT_USERS_NAME_COLUMN, &name, -1);
- if (!strcmp(normalized_name, purple_normalize(conv->account, name))) {
+ if (!strcmp(normalized_name, purple_normalize(account, name))) {
const char *alias = name;
char *tmp;
char *alias_key = NULL;
PurpleBuddy *buddy2;
- if (strcmp(chat->nick, purple_normalize(conv->account, name))) {
+ if (strcmp(purple_conv_chat_get_nick(chat), purple_normalize(account, name))) {
/* This user is not me, so look into updating the alias. */
- if ((buddy2 = purple_find_buddy(conv->account, name)) != NULL) {
+ if ((buddy2 = purple_find_buddy(account, name)) != NULL) {
alias = purple_buddy_get_contact_alias(buddy2);
}
@@ -4462,10 +4607,10 @@ blist_node_aliased_cb(PurpleBlistNode *node, const char *old_alias, PurpleConver
g_return_if_fail(node != NULL);
g_return_if_fail(conv != NULL);
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
g_return_if_fail(gc != NULL);
- g_return_if_fail(gc->prpl != NULL);
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ g_return_if_fail(purple_connection_get_prpl(gc) != NULL);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
if (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)
return;
@@ -4485,7 +4630,7 @@ blist_node_aliased_cb(PurpleBlistNode *node, const char *old_alias, PurpleConver
else if (PURPLE_BLIST_NODE_IS_BUDDY(node))
update_chat_alias((PurpleBuddy *)node, conv, gc, prpl_info);
else if (PURPLE_BLIST_NODE_IS_CHAT(node) &&
- purple_conversation_get_account(conv) == ((PurpleChat*)node)->account)
+ purple_conversation_get_account(conv) == purple_chat_get_account((PurpleChat*)node))
{
if (old_alias == NULL || g_utf8_collate(old_alias, purple_conversation_get_title(conv)) == 0)
pidgin_conv_update_fields(conv, PIDGIN_CONV_SET_TITLE);
@@ -4514,14 +4659,14 @@ buddy_cb_common(PurpleBuddy *buddy, PurpleConversation *conv, gboolean is_buddy)
if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter))
return;
- normalized_name = g_strdup(purple_normalize(conv->account, buddy->name));
+ normalized_name = g_strdup(purple_normalize(purple_conversation_get_account(conv), purple_buddy_get_name(buddy)));
do {
char *name;
gtk_tree_model_get(model, &iter, CHAT_USERS_NAME_COLUMN, &name, -1);
- if (!strcmp(normalized_name, purple_normalize(conv->account, name))) {
+ if (!strcmp(normalized_name, purple_normalize(purple_conversation_get_account(conv), name))) {
gtk_list_store_set(GTK_LIST_STORE(model), &iter,
CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, -1);
g_free(name);
@@ -4600,7 +4745,7 @@ static gboolean resize_imhtml_cb(PidginConversation *gtkconv)
GdkRectangle oneline;
int height, diff;
int pad_top, pad_inside, pad_bottom;
- int total_height = (gtkconv->imhtml->allocation.height + gtkconv->entry->allocation.height);
+ int total_height = (gtkconv->webview->allocation.height + gtkconv->entry->allocation.height);
int max_height = total_height / 2;
int min_lines = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines");
int min_height;
@@ -4672,8 +4817,8 @@ static void
setup_chat_topic(PidginConversation *gtkconv, GtkWidget *vbox)
{
PurpleConversation *conv = gtkconv->active_conv;
- PurpleConnection *gc = purple_conversation_get_gc(conv);
- PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ PurpleConnection *gc = purple_conversation_get_connection(conv);
+ PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
if (prpl_info->options & OPT_PROTO_CHAT_TOPIC)
{
GtkWidget *hbox, *label;
@@ -4714,7 +4859,7 @@ pidgin_conv_userlist_create_tooltip(GtkWidget *tipwindow, GtkTreePath *path,
PurpleAccount *account = purple_conversation_get_account(conv);
char *who = NULL;
- if (account->gc == NULL)
+ if (purple_account_get_connection(account) == NULL)
return FALSE;
if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path))
@@ -4722,8 +4867,8 @@ pidgin_conv_userlist_create_tooltip(GtkWidget *tipwindow, GtkTreePath *path,
gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1);
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl);
- node = (PurpleBlistNode*)(purple_find_buddy(conv->account, who));
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(purple_account_get_connection(account)));
+ node = (PurpleBlistNode*)(purple_find_buddy(purple_conversation_get_account(conv), who));
if (node && prpl_info && (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME))
pidgin_blist_draw_tooltip(node, gtkconv->infopane);
@@ -4824,7 +4969,7 @@ setup_chat_userlist(PidginConversation *gtkconv, GtkWidget *hpaned)
gtkchat->list = list;
- gtk_box_pack_start(GTK_BOX(lbox),
+ gtk_box_pack_start(GTK_BOX(lbox),
pidgin_make_scrollable(list, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1),
TRUE, TRUE, 0);
}
@@ -4838,15 +4983,15 @@ pidgin_conv_create_tooltip(GtkWidget *tipwindow, gpointer userdata, int *w, int
conv = gtkconv->active_conv;
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
- node = (PurpleBlistNode*)(purple_blist_find_chat(conv->account, conv->name));
+ node = (PurpleBlistNode*)(purple_blist_find_chat(purple_conversation_get_account(conv), purple_conversation_get_name(conv)));
if (!node)
- node = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_chat");
+ node = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_chat");
} else {
- node = (PurpleBlistNode*)(purple_find_buddy(conv->account, conv->name));
+ node = (PurpleBlistNode*)(purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv)));
#if 0
/* Using the transient blist nodes to show the tooltip doesn't quite work yet. */
if (!node)
- node = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_buddy");
+ node = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_buddy");
#endif
}
@@ -4861,7 +5006,7 @@ pidgin_conv_end_quickfind(PidginConversation *gtkconv)
{
gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL);
- gtk_imhtml_search_clear(GTK_IMHTML(gtkconv->imhtml));
+ webkit_web_view_unmark_text_matches(WEBKIT_WEB_VIEW(gtkconv->webview));
gtk_widget_hide_all(gtkconv->quickfind.container);
gtk_widget_grab_focus(gtkconv->entry);
@@ -4874,7 +5019,7 @@ quickfind_process_input(GtkWidget *entry, GdkEventKey *event, PidginConversation
switch (event->keyval) {
case GDK_Return:
case GDK_KP_Enter:
- if (gtk_imhtml_search_find(GTK_IMHTML(gtkconv->imhtml), gtk_entry_get_text(GTK_ENTRY(entry)))) {
+ if (webkit_web_view_search_text(WEBKIT_WEB_VIEW(gtkconv->webview), gtk_entry_get_text(GTK_ENTRY(entry)), FALSE, TRUE, TRUE)) {
gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL);
} else {
GdkColor col;
@@ -4903,8 +5048,12 @@ pidgin_conv_setup_quickfind(PidginConversation *gtkconv, GtkWidget *container)
close = pidgin_create_small_button(gtk_label_new("×"));
gtk_box_pack_start(GTK_BOX(widget), close, FALSE, FALSE, 0);
+#if GTK_CHECK_VERSION(2,12,0)
+ gtk_widget_set_tooltip_text(close, _("Close Find bar"));
+#else
gtk_tooltips_set_tip(gtkconv->tooltips, close,
_("Close Find bar"), NULL);
+#endif
label = gtk_label_new(_("Find:"));
gtk_box_pack_start(GTK_BOX(widget), label, FALSE, FALSE, 10);
@@ -4924,15 +5073,238 @@ pidgin_conv_setup_quickfind(PidginConversation *gtkconv, GtkWidget *container)
/* }}} */
+static char *
+replace_header_tokens(PurpleConversation *conv, const char *text)
+{
+ PurpleAccount *account = purple_conversation_get_account(conv);
+ GString *str;
+ const char *cur = text;
+ const char *prev = cur;
+ time_t mtime;
+ struct tm *tm = NULL;
+
+ if (text == NULL || *text == '\0')
+ return NULL;
+
+ str = g_string_new(NULL);
+ while ((cur = strchr(cur, '%'))) {
+ char *freeval = NULL;
+ const char *replace = NULL;
+ const char *fin = NULL;
+
+ if (g_str_has_prefix(cur, "%chatName%")) {
+ replace = purple_conversation_get_name(conv);
+
+ } else if (g_str_has_prefix(cur, "%sourceName%")) {
+ replace = purple_account_get_alias(account);
+ if (replace == NULL)
+ replace = purple_account_get_username(account);
+
+ } else if (g_str_has_prefix(cur, "%destinationName%")) {
+ PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv));
+ if (buddy) {
+ replace = purple_buddy_get_alias(buddy);
+ } else {
+ replace = purple_conversation_get_name(conv);
+ }
+
+ } else if (g_str_has_prefix(cur, "%incomingIconPath%")) {
+ PurpleBuddyIcon *icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv));
+ if (icon)
+ replace = purple_buddy_icon_get_full_path(icon);
+
+ } else if (g_str_has_prefix(cur, "%outgoingIconPath%")) {
+ replace = purple_account_get_buddy_icon_path(account);
+
+ } else if (g_str_has_prefix(cur, "%timeOpened")) {
+ const char *tmp = cur + strlen("%timeOpened");
+
+ if (*tmp == '{') {
+ const char *end;
+ tmp++;
+ end = strstr(tmp, "}%");
+ if (!end) /* Invalid string */
+ continue;
+ if (!tm) {
+ mtime = time(NULL);
+ tm = localtime(&mtime);
+ }
+ replace = freeval = purple_uts35_to_str(tmp, end - tmp, tm);
+ fin = end + 1;
+ } else {
+ if (!tm) {
+ mtime = time(NULL);
+ tm = localtime(&mtime);
+ }
+
+ replace = purple_utf8_strftime("%X", tm);
+ }
+
+ } else if (g_str_has_prefix(cur, "%dateOpened%")) {
+ if (!tm) {
+ mtime = time(NULL);
+ tm = localtime(&mtime);
+ }
+
+ replace = purple_date_format_short(tm);
+
+ } else {
+ cur++;
+ continue;
+ }
+
+ /* Here we have a replacement to make */
+ g_string_append_len(str, prev, cur - prev);
+ if (replace)
+ g_string_append(str, replace);
+
+ /* And update the pointers */
+ if (fin) {
+ prev = cur = fin + 1;
+ } else {
+ prev = cur = strchr(cur + 1, '%') + 1;
+ }
+ g_free(freeval);
+ freeval = NULL;
+ }
+
+ /* And wrap it up */
+ g_string_append(str, prev);
+ return g_string_free(str, FALSE);
+}
+
+static char *
+replace_template_tokens(PidginConvTheme *theme, const char *header, const char *footer)
+{
+ GString *str;
+ const char *text;
+ char **ms;
+ char *path;
+
+ text = pidgin_conversation_theme_get_template(theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_MAIN);
+ if (text == NULL)
+ return NULL;
+
+ ms = g_strsplit(text, "%@", 6);
+ if (ms[0] == NULL || ms[1] == NULL || ms[2] == NULL || ms[3] == NULL || ms[4] == NULL || ms[5] == NULL) {
+ g_strfreev(ms);
+ return NULL;
+ }
+
+ str = g_string_new(NULL);
+
+ g_string_append(str, ms[0]);
+ g_string_append(str, "file://");
+ path = pidgin_conversation_theme_get_template_path(theme);
+ g_string_append(str, path);
+ g_free(path);
+
+ g_string_append(str, ms[1]);
+
+ text = pidgin_conversation_theme_get_template(theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_BASESTYLE_CSS);
+ g_string_append(str, text);
+
+ g_string_append(str, ms[2]);
+
+ g_string_append(str, "file://");
+ path = pidgin_conversation_theme_get_css_path(theme);
+ g_string_append(str, path);
+ g_free(path);
+
+ g_string_append(str, ms[3]);
+ if (header)
+ g_string_append(str, header);
+ g_string_append(str, ms[4]);
+ if (footer)
+ g_string_append(str, footer);
+ g_string_append(str, ms[5]);
+
+ g_strfreev(ms);
+
+ return g_string_free(str, FALSE);
+}
+
+static void
+set_theme_webkit_settings(WebKitWebView *webview, PidginConvTheme *theme)
+{
+ WebKitWebSettings *settings;
+ const GValue *val;
+
+ g_object_get(G_OBJECT(webview), "settings", &settings, NULL);
+
+ val = pidgin_conversation_theme_lookup(theme, "DefaultFontFamily", TRUE);
+ if (val && G_VALUE_HOLDS_STRING(val))
+ g_object_set(G_OBJECT(settings), "default-font-family", g_value_get_string(val), NULL);
+
+ val = pidgin_conversation_theme_lookup(theme, "DefaultFontSize", TRUE);
+ if (val && G_VALUE_HOLDS_INT(val))
+ g_object_set(G_OBJECT(settings), "default-font-size", GINT_TO_POINTER(g_value_get_int(val)), NULL);
+
+ val = pidgin_conversation_theme_lookup(theme, "DefaultBackgroundIsTransparent", TRUE);
+ if (val && G_VALUE_HOLDS_BOOLEAN(val))
+ /* this does not work :( */
+ webkit_web_view_set_transparent(webview, g_value_get_boolean(val));
+}
+
+static void
+conv_variant_changed_cb(GObject *gobject, GParamSpec *pspec, gpointer user_data)
+{
+ PidginConversation *gtkconv = user_data;
+ char *path, *js;
+
+ path = pidgin_conversation_theme_get_css_path(PIDGIN_CONV_THEME(gobject));
+ js = g_strdup_printf("setStylesheet(\"mainStyle\", \"file://%s\");", path);
+ g_free(path);
+ gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview), js);
+ g_free(js);
+}
+
+static void
+load_conv_theme(PidginConversation *gtkconv)
+{
+ char *header, *footer;
+ char *template;
+ char *basedir, *baseuri;
+
+ header = replace_header_tokens(gtkconv->active_conv,
+ pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_HEADER));
+ footer = replace_header_tokens(gtkconv->active_conv,
+ pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_FOOTER));
+ template = replace_template_tokens(gtkconv->theme, header, footer);
+ g_free(header);
+ g_free(footer);
+
+ if (template == NULL)
+ return;
+
+ set_theme_webkit_settings(WEBKIT_WEB_VIEW(gtkconv->webview), gtkconv->theme);
+
+ basedir = pidgin_conversation_theme_get_template_path(gtkconv->theme);
+ baseuri = g_strdup_printf("file://%s", basedir);
+ webkit_web_view_load_string(WEBKIT_WEB_VIEW(gtkconv->webview), template,
+ "text/html", "UTF-8", baseuri);
+
+ if (purple_conversation_get_type(gtkconv->active_conv) == PURPLE_CONV_TYPE_CHAT)
+ gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview),
+ "document.getElementById('Chat').className = 'groupchat'");
+
+ g_signal_connect(G_OBJECT(gtkconv->theme), "notify::variant",
+ G_CALLBACK(conv_variant_changed_cb), gtkconv);
+
+ g_free(basedir);
+ g_free(baseuri);
+ g_free(template);
+}
+
static GtkWidget *
setup_common_pane(PidginConversation *gtkconv)
{
- GtkWidget *vbox, *frame, *imhtml_sw, *event_box;
+ GtkWidget *vbox, *frame, *webview_sw, *event_box;
GtkCellRenderer *rend;
GtkTreePath *path;
PurpleConversation *conv = gtkconv->active_conv;
PurpleBuddy *buddy;
- gboolean chat = (conv->type == PURPLE_CONV_TYPE_CHAT);
+ gboolean chat = (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT);
int buddyicon_size = 0;
/* Setup the top part of the pane */
@@ -5023,9 +5395,12 @@ setup_common_pane(PidginConversation *gtkconv)
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkconv->infopane), rend, "pixbuf", CONV_EMBLEM_COLUMN, NULL);
g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL);
- /* Setup the gtkimhtml widget */
- frame = pidgin_create_imhtml(FALSE, &gtkconv->imhtml, NULL, &imhtml_sw);
- gtk_widget_set_size_request(gtkconv->imhtml, -1, 0);
+ /* Setup the webkit widget */
+ frame = pidgin_create_webview(FALSE, &gtkconv->webview, NULL, &webview_sw);
+ gtk_widget_set_size_request(gtkconv->webview, -1, 0);
+
+ load_conv_theme(gtkconv);
+
if (chat) {
GtkWidget *hpaned;
@@ -5043,19 +5418,16 @@ setup_common_pane(PidginConversation *gtkconv)
} else {
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
}
- gtk_widget_show(frame);
-
- gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml");
- gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),TRUE);
- g_object_set_data(G_OBJECT(gtkconv->imhtml), "gtkconv", gtkconv);
+ gtk_widget_show_all(frame);
- g_object_set(G_OBJECT(imhtml_sw), "vscrollbar-policy", GTK_POLICY_ALWAYS, NULL);
+ gtk_widget_set_name(gtkconv->webview, "pidgin_conv_webview");
+ g_object_set_data(G_OBJECT(gtkconv->webview), "gtkconv", gtkconv);
- g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event",
+ g_signal_connect_after(G_OBJECT(gtkconv->webview), "button_press_event",
G_CALLBACK(entry_stop_rclick_cb), NULL);
- g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event",
+ g_signal_connect(G_OBJECT(gtkconv->webview), "key_press_event",
G_CALLBACK(refocus_entry_cb), gtkconv);
- g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event",
+ g_signal_connect(G_OBJECT(gtkconv->webview), "key_release_event",
G_CALLBACK(refocus_entry_cb), gtkconv);
pidgin_conv_setup_quickfind(gtkconv, vbox);
@@ -5071,7 +5443,7 @@ setup_common_pane(PidginConversation *gtkconv)
gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry");
gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry),
- purple_account_get_protocol_name(conv->account));
+ purple_account_get_protocol_name(purple_conversation_get_account(conv)));
g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup",
G_CALLBACK(entry_popup_menu_cb), gtkconv);
@@ -5118,7 +5490,7 @@ conv_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
PurpleConversation *c;
PurpleAccount *convaccount = purple_conversation_get_account(conv);
PurpleConnection *gc = purple_account_get_connection(convaccount);
- PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl) : NULL;
+ PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)) : NULL;
if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
{
@@ -5238,7 +5610,7 @@ static const GtkTargetEntry te[] =
static PidginConversation *
pidgin_conv_find_gtkconv(PurpleConversation * conv)
{
- PurpleBuddy *bud = purple_find_buddy(conv->account, conv->name);
+ PurpleBuddy *bud = purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv));
PurpleContact *c;
PurpleBlistNode *cn, *bn;
@@ -5252,9 +5624,9 @@ pidgin_conv_find_gtkconv(PurpleConversation * conv)
for (bn = purple_blist_node_get_first_child(cn); bn; bn = purple_blist_node_get_sibling_next(bn)) {
PurpleBuddy *b = PURPLE_BUDDY(bn);
PurpleConversation *conv;
- if ((conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, b->name, b->account))) {
- if (conv->ui_data)
- return conv->ui_data;
+ if ((conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(b), purple_buddy_get_account(b)))) {
+ if (PIDGIN_CONVERSATION(conv))
+ return PIDGIN_CONVERSATION(conv);
}
}
@@ -5296,6 +5668,8 @@ ignore_middle_click(GtkWidget *widget, GdkEventButton *e, gpointer null)
static void set_typing_font(GtkWidget *widget, GtkStyle *style, PidginConversation *gtkconv)
{
+/* TODO WEBKIT */
+#if 0
static PangoFontDescription *font_desc = NULL;
static GdkColor *color = NULL;
static gboolean enable = TRUE;
@@ -5326,6 +5700,7 @@ static void set_typing_font(GtkWidget *widget, GtkStyle *style, PidginConversati
}
g_signal_handlers_disconnect_by_func(G_OBJECT(widget), set_typing_font, gtkconv);
+#endif /* if 0 */
}
/**************************************************************************
@@ -5335,14 +5710,15 @@ static void
private_gtkconv_new(PurpleConversation *conv, gboolean hidden)
{
PidginConversation *gtkconv;
+ const char *theme_name;
+ PurpleTheme *theme = NULL;
PurpleConversationType conv_type = purple_conversation_get_type(conv);
GtkWidget *pane = NULL;
GtkWidget *tab_cont;
PurpleBlistNode *convnode;
- PurpleValue *value;
if (conv_type == PURPLE_CONV_TYPE_IM && (gtkconv = pidgin_conv_find_gtkconv(conv))) {
- conv->ui_data = gtkconv;
+ purple_conversation_set_ui_data(conv, gtkconv);
if (!g_list_find(gtkconv->convs, conv))
gtkconv->convs = g_list_prepend(gtkconv->convs, conv);
pidgin_conv_switch_active_conversation(conv);
@@ -5350,15 +5726,24 @@ private_gtkconv_new(PurpleConversation *conv, gboolean hidden)
}
gtkconv = g_new0(PidginConversation, 1);
- conv->ui_data = gtkconv;
+ purple_conversation_set_ui_data(conv, gtkconv);
gtkconv->active_conv = conv;
gtkconv->convs = g_list_prepend(gtkconv->convs, conv);
gtkconv->send_history = g_list_append(NULL, NULL);
/* Setup some initial variables. */
+#if !GTK_CHECK_VERSION(2,12,0)
gtkconv->tooltips = gtk_tooltips_new();
+#endif
gtkconv->unseen_state = PIDGIN_UNSEEN_NONE;
gtkconv->unseen_count = 0;
+ theme_name = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/theme");
+ if (theme_name && *theme_name)
+ theme = purple_theme_manager_find_theme(theme_name, "conversation");
+ if (!theme)
+ theme = default_conv_theme;
+ gtkconv->theme = PIDGIN_CONV_THEME(g_object_ref(theme));
+ gtkconv->last_flags = 0;
if (conv_type == PURPLE_CONV_TYPE_IM) {
gtkconv->u.im = g_malloc0(sizeof(PidginImPane));
@@ -5367,9 +5752,6 @@ private_gtkconv_new(PurpleConversation *conv, gboolean hidden)
}
pane = setup_common_pane(gtkconv);
- gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->imhtml),
- gtk_imhtml_get_format_functions(GTK_IMHTML(gtkconv->imhtml)) | GTK_IMHTML_IMAGE);
-
if (pane == NULL) {
if (conv_type == PURPLE_CONV_TYPE_CHAT)
g_free(gtkconv->u.chat);
@@ -5377,7 +5759,7 @@ private_gtkconv_new(PurpleConversation *conv, gboolean hidden)
g_free(gtkconv->u.im);
g_free(gtkconv);
- conv->ui_data = NULL;
+ purple_conversation_set_ui_data(conv, NULL);
return;
}
@@ -5392,7 +5774,7 @@ private_gtkconv_new(PurpleConversation *conv, gboolean hidden)
GTK_DEST_DEFAULT_DROP,
te, sizeof(te) / sizeof(GtkTargetEntry),
GDK_ACTION_COPY);
- gtk_drag_dest_set(gtkconv->imhtml, 0,
+ gtk_drag_dest_set(gtkconv->webview, 0,
te, sizeof(te) / sizeof(GtkTargetEntry),
GDK_ACTION_COPY);
@@ -5404,12 +5786,12 @@ private_gtkconv_new(PurpleConversation *conv, gboolean hidden)
G_CALLBACK(ignore_middle_click), NULL);
g_signal_connect(G_OBJECT(pane), "drag_data_received",
G_CALLBACK(conv_dnd_recv), gtkconv);
- g_signal_connect(G_OBJECT(gtkconv->imhtml), "drag_data_received",
+ g_signal_connect(G_OBJECT(gtkconv->webview), "drag_data_received",
G_CALLBACK(conv_dnd_recv), gtkconv);
g_signal_connect(G_OBJECT(gtkconv->entry), "drag_data_received",
G_CALLBACK(conv_dnd_recv), gtkconv);
- g_signal_connect(gtkconv->imhtml, "style-set", G_CALLBACK(set_typing_font), gtkconv);
+ g_signal_connect(gtkconv->webview, "style-set", G_CALLBACK(set_typing_font), gtkconv);
/* Setup the container for the tab. */
gtkconv->tab_cont = tab_cont = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
@@ -5422,11 +5804,9 @@ private_gtkconv_new(PurpleConversation *conv, gboolean hidden)
if (convnode == NULL || !purple_blist_node_get_bool(convnode, "gtk-mute-sound"))
gtkconv->make_sound = TRUE;
- if (convnode != NULL &&
- (value = g_hash_table_lookup(convnode->settings, "enable-logging")) &&
- purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN)
- {
- purple_conversation_set_logging(conv, purple_value_get_boolean(value));
+ if (convnode != NULL && purple_blist_node_has_setting(convnode, "enable-logging")) {
+ gboolean logging = purple_blist_node_get_bool(convnode, "enable-logging");
+ purple_conversation_set_logging(conv, logging);
}
if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar"))
@@ -5439,10 +5819,6 @@ private_gtkconv_new(PurpleConversation *conv, gboolean hidden)
else
gtk_widget_hide(gtkconv->infopane_hbox);
- gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),
- purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps"));
- gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml),
- purple_account_get_protocol_name(conv->account));
g_signal_connect_swapped(G_OBJECT(pane), "focus",
G_CALLBACK(gtk_widget_grab_focus),
@@ -5455,10 +5831,10 @@ private_gtkconv_new(PurpleConversation *conv, gboolean hidden)
if (nick_colors == NULL) {
nbr_nick_colors = NUM_NICK_COLORS;
- nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]);
+ nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->webview)->base[GTK_STATE_NORMAL]);
}
- if (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)
+ if (purple_conversation_get_features(conv) & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)
pidgin_themes_smiley_themeize_custom(gtkconv->entry);
}
@@ -5559,7 +5935,9 @@ pidgin_conv_destroy(PurpleConversation *conv)
g_free(gtkconv->u.chat);
}
+#if !GTK_CHECK_VERSION(2,12,0)
gtk_object_sink(GTK_OBJECT(gtkconv->tooltips));
+#endif
gtkconv->send_history = g_list_first(gtkconv->send_history);
g_list_foreach(gtkconv->send_history, (GFunc)g_free, NULL);
@@ -5569,6 +5947,10 @@ pidgin_conv_destroy(PurpleConversation *conv)
g_source_remove(gtkconv->attach.timer);
}
+ g_object_disconnect(G_OBJECT(gtkconv->theme), "any_signal::notify",
+ conv_variant_changed_cb, gtkconv, NULL);
+ g_object_unref(gtkconv->theme);
+
g_free(gtkconv);
}
@@ -5596,6 +5978,7 @@ pidgin_conv_write_im(PurpleConversation *conv, const char *who,
purple_conversation_write(conv, who, message, flags, mtime);
}
+#if 0
static const char *
get_text_tag_color(GtkTextTag *tag)
{
@@ -5659,7 +6042,7 @@ static gboolean buddytag_event(GtkTextTag *tag, GObject *imhtml,
&start, &end)) {
GtkWidget *menu = NULL;
PurpleConnection *gc =
- purple_conversation_get_gc(conv);
+ purple_conversation_get_connection(conv);
menu = create_chat_menu(conv, buddyname, gc);
@@ -5676,10 +6059,13 @@ static gboolean buddytag_event(GtkTextTag *tag, GObject *imhtml,
return FALSE;
}
+#endif
static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag,
gboolean create)
{
+/* TODO WEBKIT */
+#if 0
PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
GtkTextTag *buddytag;
gchar *str;
@@ -5713,8 +6099,11 @@ static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, Purp
g_free(str);
return buddytag;
+#endif /* if 0 */
+ return NULL;
}
+#if 0
static void pidgin_conv_calculate_newday(PidginConversation *gtkconv, time_t mtime)
{
struct tm *tm = localtime(&mtime);
@@ -5760,6 +6149,142 @@ str_embed_direction_chars(char **str)
*str = ret;
#endif
}
+#endif
+
+static char *
+replace_message_tokens(
+ const char *text,
+ PurpleConversation *conv,
+ const char *name,
+ const char *alias,
+ const char *message,
+ PurpleMessageFlags flags,
+ time_t mtime)
+{
+ GString *str;
+ const char *cur = text;
+ const char *prev = cur;
+ struct tm *tm = NULL;
+
+ if (text == NULL || *text == '\0')
+ return NULL;
+
+ str = g_string_new(NULL);
+ while ((cur = strchr(cur, '%'))) {
+ const char *replace = NULL;
+ const char *fin = NULL;
+ gpointer freeval = NULL;
+
+ if (g_str_has_prefix(cur, "%message%")) {
+ replace = message;
+
+ } else if (g_str_has_prefix(cur, "%messageClasses%")) {
+ GString *classes = g_string_new(NULL);
+#define ADD_CLASS(f, class) \
+ if (flags & f) \
+ g_string_append(classes, class);
+ ADD_CLASS(PURPLE_MESSAGE_SEND, "outgoing ");
+ ADD_CLASS(PURPLE_MESSAGE_RECV, "incoming ");
+ ADD_CLASS(PURPLE_MESSAGE_SYSTEM, "event ");
+ ADD_CLASS(PURPLE_MESSAGE_AUTO_RESP, "autoreply ");
+ ADD_CLASS(PURPLE_MESSAGE_DELAYED, "history ");
+ ADD_CLASS(PURPLE_MESSAGE_NICK, "mention ");
+#undef ADD_CLASS
+
+ replace = freeval = g_string_free(classes, FALSE);
+
+ } else if (g_str_has_prefix(cur, "%time")) {
+ const char *tmp = cur + strlen("%time");
+
+ if (*tmp == '{') {
+ char *end;
+ tmp++;
+ end = strstr(tmp, "}%");
+ if (!end) /* Invalid string */
+ continue;
+ if (!tm)
+ tm = localtime(&mtime);
+ replace = freeval = purple_uts35_to_str(tmp, end - tmp, tm);
+ fin = end + 1;
+ } else {
+ if (!tm)
+ tm = localtime(&mtime);
+
+ replace = purple_utf8_strftime("%X", tm);
+ }
+
+ } else if (g_str_has_prefix(cur, "%shortTime%")) {
+ if (!tm)
+ tm = localtime(&mtime);
+
+ replace = purple_utf8_strftime("%H:%M", tm);
+
+ } else if (g_str_has_prefix(cur, "%userIconPath%")) {
+ if (flags & PURPLE_MESSAGE_SEND) {
+ if (purple_account_get_bool(purple_conversation_get_account(conv), "use-global-buddyicon", TRUE)) {
+ replace = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/accounts/buddyicon");
+ } else {
+ PurpleStoredImage *img = purple_buddy_icons_find_account_icon(purple_conversation_get_account(conv));
+ replace = purple_imgstore_get_filename(img);
+ }
+ if (replace == NULL || !g_file_test(replace, G_FILE_TEST_EXISTS)) {
+ replace = freeval = g_build_filename("Outgoing", "buddy_icon.png", NULL);
+ }
+ } else if (flags & PURPLE_MESSAGE_RECV) {
+ PurpleBuddyIcon *icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv));
+ if (icon)
+ replace = purple_buddy_icon_get_full_path(icon);
+ if (replace == NULL || !g_file_test(replace, G_FILE_TEST_EXISTS)) {
+ replace = freeval = g_build_filename("Incoming", "buddy_icon.png", NULL);
+ }
+ }
+
+ } else if (g_str_has_prefix(cur, "%senderScreenName%")) {
+ replace = name;
+
+ } else if (g_str_has_prefix(cur, "%sender%")) {
+ replace = alias;
+
+ } else if (g_str_has_prefix(cur, "%service%")) {
+ replace = purple_account_get_protocol_name(purple_conversation_get_account(conv));
+
+ } else if (g_str_has_prefix(cur, "%messageDirection%")) {
+ replace = purple_markup_is_rtl(message) ? "rtl" : "ltr";
+
+ } else if (g_str_has_prefix(cur, "%status%")) {
+ GString *classes = g_string_new(NULL);
+
+ if (flags & PURPLE_MESSAGE_ERROR)
+ g_string_append(classes, "error ");
+
+ replace = freeval = g_string_free(classes, FALSE);
+
+ } else {
+ cur++;
+ continue;
+ }
+
+ /* Here we have a replacement to make */
+ g_string_append_len(str, prev, cur - prev);
+ if (replace)
+ g_string_append(str, replace);
+ g_free(freeval);
+ replace = freeval = NULL;
+
+ /* And update the pointers */
+ if (fin) {
+ prev = cur = fin + 1;
+ } else {
+ prev = cur = strchr(cur + 1, '%') + 1;
+ }
+
+ }
+
+ /* And wrap it up */
+ g_string_append(str, prev);
+
+ return g_string_free(str, FALSE);
+}
static void
pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *alias,
@@ -5769,23 +6294,31 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
PidginConversation *gtkconv;
PurpleConnection *gc;
PurpleAccount *account;
+#if 0
int gtk_font_options = 0;
int gtk_font_options_all = 0;
- int max_scrollback_lines;
- int line_count;
char buf2[BUF_LONG];
gboolean show_date;
char *mdate;
char *str;
char *with_font_tag;
char *sml_attrib = NULL;
+#endif
size_t length;
PurpleConversationType type;
char *displaying;
gboolean plugin_return;
- char *bracket;
- int tag_count = 0;
+#if 0
gboolean is_rtl_message = FALSE;
+#endif
+
+ const char *message_html;
+ char *msg;
+ char *escape;
+ char *script;
+ char *smileyed;
+ PurpleMessageFlags old_flags;
+ const char *func = "appendMessage";
g_return_if_fail(conv != NULL);
gtkconv = PIDGIN_CONVERSATION(conv);
@@ -5842,56 +6375,56 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
}
length = strlen(displaying) + 1;
- /* Awful hack to work around GtkIMHtml's inefficient rendering of messages with lots of formatting changes.
- * If a message has over 100 '<' characters, strip formatting before appending it. Hopefully nobody actually
- * needs that much formatting, anyway.
- */
- for (bracket = strchr(displaying, '<'); bracket && *(bracket + 1); bracket = strchr(bracket + 1, '<'))
- tag_count++;
-
- if (tag_count > 100) {
- char *tmp = displaying;
- displaying = purple_markup_strip_html(tmp);
- g_free(tmp);
- }
-
- line_count = gtk_text_buffer_get_line_count(
- gtk_text_view_get_buffer(GTK_TEXT_VIEW(
- gtkconv->imhtml)));
-
- max_scrollback_lines = purple_prefs_get_int(
- PIDGIN_PREFS_ROOT "/conversations/scrollback_lines");
- /* If we're sitting at more than 100 lines more than the
- max scrollback, trim down to max scrollback */
- if (max_scrollback_lines > 0
- && line_count > (max_scrollback_lines + 100)) {
- GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(
- GTK_TEXT_VIEW(gtkconv->imhtml));
- GtkTextIter start, end;
+ old_flags = gtkconv->last_flags;
+ if ((flags & PURPLE_MESSAGE_SEND) && (old_flags & PURPLE_MESSAGE_SEND)) {
+ message_html = pidgin_conversation_theme_get_template(gtkconv->theme,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_NEXT_CONTENT);
+ func = "appendNextMessage";
+
+ } else if (flags & PURPLE_MESSAGE_SEND) {
+ message_html = pidgin_conversation_theme_get_template(gtkconv->theme,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_CONTENT);
+
+ } else if ((flags & PURPLE_MESSAGE_RECV) && (old_flags & PURPLE_MESSAGE_RECV)) {
+ GList *history = purple_conversation_get_message_history(conv);
+ PurpleConvMessage *last_msg = (PurpleConvMessage *)history->data;
+
+ /* If the senders are the same, use appendNextMessage */
+ if (purple_strequal(purple_conversation_message_get_sender(last_msg), name)) {
+ message_html = pidgin_conversation_theme_get_template(gtkconv->theme,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_NEXT_CONTENT);
+ func = "appendNextMessage";
+ } else {
+ message_html = pidgin_conversation_theme_get_template(gtkconv->theme,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_CONTENT);
+ }
+ } else if (flags & PURPLE_MESSAGE_RECV) {
+ message_html = pidgin_conversation_theme_get_template(gtkconv->theme,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_CONTENT);
- gtk_text_buffer_get_start_iter(text_buffer, &start);
- gtk_text_buffer_get_iter_at_line(text_buffer, &end,
- (line_count - max_scrollback_lines));
- gtk_imhtml_delete(GTK_IMHTML(gtkconv->imhtml), &start, &end);
+ } else {
+ message_html = pidgin_conversation_theme_get_template(gtkconv->theme,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_STATUS);
}
+ gtkconv->last_flags = flags;
- if (type == PURPLE_CONV_TYPE_CHAT)
- {
- /* Create anchor for user */
- GtkTextIter iter;
- char *tmp = g_strconcat("user:", name, NULL);
+ smileyed = smiley_parse_markup(displaying, purple_account_get_protocol_id(account));
+ msg = replace_message_tokens(message_html, conv, name, alias, smileyed, flags, mtime);
+ escape = gtk_webview_quote_js_string(msg ? msg : "");
+ script = g_strdup_printf("%s(%s)", func, escape);
- gtk_text_buffer_get_end_iter(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)), &iter);
- gtk_text_buffer_create_mark(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)),
- tmp, &iter, TRUE);
- g_free(tmp);
- }
+ purple_debug_info("webkit", "JS: %s\n", script);
+ gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview), script);
- if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling"))
- gtk_font_options_all |= GTK_IMHTML_USE_SMOOTHSCROLLING;
+ g_free(script);
+ g_free(smileyed);
+ g_free(msg);
+ g_free(escape);
- if (gtk_text_buffer_get_char_count(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml))))
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR>", gtk_font_options_all | GTK_IMHTML_NO_SCROLL);
+#if 0
+ /* if the buffer is not empty add a <br> */
+ if (!gtk_webview_is_empty(GTK_WEBVIEW(gtkconv->webview)))
+ gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "<br />");
/* First message in a conversation. */
if (gtkconv->newday == 0)
@@ -5934,40 +6467,40 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
gtk_font_options |= GTK_IMHTML_NO_COLOURS | GTK_IMHTML_NO_FONTS | GTK_IMHTML_NO_SIZES | GTK_IMHTML_NO_FORMATTING;
/* this is gonna crash one day, I can feel it. */
- if (PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(conv->account)))->options &
+ if (PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(purple_conversation_get_account(conv))))->options &
OPT_PROTO_USE_POINTSIZE) {
gtk_font_options |= GTK_IMHTML_USE_POINTSIZE;
}
- if (!(flags & PURPLE_MESSAGE_RECV) && (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY))
+ if (!(flags & PURPLE_MESSAGE_RECV) && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY))
{
/* We want to see our own smileys. Need to revert it after send*/
- pidgin_themes_smiley_themeize_custom(gtkconv->imhtml);
+ pidgin_themes_smiley_themeize_custom(gtkconv->webview);
}
/* TODO: These colors should not be hardcoded so log.c can use them */
if (flags & PURPLE_MESSAGE_RAW) {
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), message, gtk_font_options_all);
+ gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), message);
} else if (flags & PURPLE_MESSAGE_SYSTEM) {
g_snprintf(buf2, sizeof(buf2),
- "<FONT %s><FONT SIZE=\"2\"><!--%s --></FONT><B>%s</B></FONT>",
+ "<font %s><font size=\"2\"><span class='timestamp'>%s</span></font><b>%s</b></font>",
sml_attrib ? sml_attrib : "", mdate, displaying);
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all);
+ gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), buf2);
} else if (flags & PURPLE_MESSAGE_ERROR) {
g_snprintf(buf2, sizeof(buf2),
- "<FONT COLOR=\"#ff0000\"><FONT %s><FONT SIZE=\"2\"><!--%s --></FONT><B>%s</B></FONT></FONT>",
+ "<font color=\"#ff0000\"><font %s><font size=\"2\"><span class='timestamp'>%s</span> </font><b>%s</b></font></font>",
sml_attrib ? sml_attrib : "", mdate, displaying);
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all);
+ gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), buf2);
} else if (flags & PURPLE_MESSAGE_NO_LOG) {
g_snprintf(buf2, BUF_LONG,
- "<B><FONT %s COLOR=\"#777777\">%s</FONT></B>",
+ "<b><font %s color=\"#777777\">%s</font></b>",
sml_attrib ? sml_attrib : "", displaying);
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all);
+ gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), buf2);
} else {
char *new_message = g_memdup(displaying, length);
char *alias_escaped = (alias ? g_markup_escape_text(alias, strlen(alias)) : g_strdup(""));
@@ -5977,11 +6510,6 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
int tag_end_offset = 0;
const char *tagname = NULL;
- GtkTextIter start, end;
- GtkTextMark *mark;
- GtkTextTag *tag;
- GtkTextBuffer *buffer = GTK_IMHTML(gtkconv->imhtml)->text_buffer;
-
/* Enforce direction on alias */
if (is_rtl_message)
str_embed_direction_chars(&alias_escaped);
@@ -6042,55 +6570,41 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
g_free(alias_escaped);
+ /* TODO WEBKIT */
+#if 0
if (tagname)
tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer), tagname);
else
tag = get_buddy_tag(conv, name, flags, TRUE);
if (GTK_IMHTML(gtkconv->imhtml)->show_comments) {
+ {
/* The color for the timestamp has to be set in the font-tags, unfortunately.
* Applying the nick-tag to timestamps would work, but that can make it
* bold. I thought applying the "comment" tag again, which has "weight" set
* to PANGO_WEIGHT_NORMAL, would remove the boldness. But it doesn't. So
* this will have to do. I don't terribly like it. -- sadrul */
- const char *color = get_text_tag_color(tag);
+ /* const char *color = get_text_tag_color(tag); */
g_snprintf(buf2, BUF_LONG, "<FONT %s%s%s SIZE=\"2\"><!--%s --></FONT>",
color ? "COLOR=\"" : "", color ? color : "", color ? "\"" : "", mdate);
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all | GTK_IMHTML_NO_SCROLL);
+ gtk_webview_append_html (GTK_WEBVIEW(gtkconv->webview), buf2);
}
-
- gtk_text_buffer_get_end_iter(buffer, &end);
- mark = gtk_text_buffer_create_mark(buffer, NULL, &end, TRUE);
-
- g_snprintf(buf2, BUF_LONG, "<FONT %s>%s</FONT> ", sml_attrib ? sml_attrib : "", str);
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all | GTK_IMHTML_NO_SCROLL);
-
- gtk_text_buffer_get_end_iter(buffer, &end);
- gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
- gtk_text_buffer_apply_tag(buffer, tag, &start, &end);
- gtk_text_buffer_delete_mark(buffer, mark);
+#endif /* if 0 */
+ g_snprintf(buf2, BUF_LONG, "<font %s>%s</font> ", sml_attrib ? sml_attrib : "", str);
+ gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), buf2);
g_free(str);
- if(gc){
+ if (gc) {
char *pre = g_strdup_printf("<font %s>", sml_attrib ? sml_attrib : "");
char *post = "</font>";
- int pre_len = strlen(pre);
- int post_len = strlen(post);
-
- with_font_tag = g_malloc(length + pre_len + post_len + 1);
-
- strcpy(with_font_tag, pre);
- memcpy(with_font_tag + pre_len, new_message, length);
- strcpy(with_font_tag + pre_len + length, post);
-
- length += pre_len + post_len;
+ with_font_tag = g_strdup_printf("%s%s%s", pre, new_message, post);
g_free(pre);
} else
with_font_tag = g_memdup(new_message, length);
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml),
- with_font_tag, gtk_font_options | gtk_font_options_all);
+ gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview),
+ with_font_tag);
g_free(with_font_tag);
g_free(new_message);
@@ -6099,6 +6613,8 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
g_free(mdate);
g_free(sml_attrib);
+#endif
+
/* Tab highlighting stuff */
if (!(flags & PURPLE_MESSAGE_SEND) && !pidgin_conv_has_focus(conv))
{
@@ -6117,11 +6633,13 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
gtkconv_set_unseen(gtkconv, unseen);
}
- if (!(flags & PURPLE_MESSAGE_RECV) && (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY))
+#if 0
+ if (!(flags & PURPLE_MESSAGE_RECV) && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY))
{
/* Restore the smiley-data */
- pidgin_themes_smiley_themeize(gtkconv->imhtml);
+ pidgin_themes_smiley_themeize(gtkconv->webview);
}
+#endif
purple_signal_emit(pidgin_conversations_get_handle(),
(type == PURPLE_CONV_TYPE_IM ? "displayed-im-msg" : "displayed-chat-msg"),
@@ -6138,7 +6656,7 @@ static gboolean get_iter_from_chatbuddy(PurpleConvChatBuddy *cb, GtkTreeIter *it
g_return_val_if_fail(cb != NULL, FALSE);
- ref = cb->ui_data;
+ ref = purple_conv_chat_cb_get_ui_data(cb);
if (!ref)
return FALSE;
@@ -6229,11 +6747,11 @@ pidgin_conv_chat_rename_user(PurpleConversation *conv, const char *old_name,
return;
if (get_iter_from_chatbuddy(old_cbuddy, &iter)) {
- GtkTreeRowReference *ref = old_cbuddy->ui_data;
+ GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(old_cbuddy);
gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
gtk_tree_row_reference_free(ref);
- old_cbuddy->ui_data = NULL;
+ purple_conv_chat_cb_set_ui_data(old_cbuddy, NULL);
}
g_return_if_fail(new_alias != NULL);
@@ -6322,10 +6840,10 @@ pidgin_conv_chat_update_user(PurpleConversation *conv, const char *user)
return;
if (get_iter_from_chatbuddy(cbuddy, &iter)) {
- GtkTreeRowReference *ref = cbuddy->ui_data;
+ GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cbuddy);
gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
gtk_tree_row_reference_free(ref);
- cbuddy->ui_data = NULL;
+ purple_conv_chat_cb_set_ui_data(cbuddy, NULL);
}
if (cbuddy)
@@ -6372,6 +6890,13 @@ add_custom_smiley_for_imhtml(GtkIMHtml *imhtml, const char *sml, const char *smi
}
static gboolean
+add_custom_smiley_for_webview(GtkWebView *webview, const char *sml, const char *smile)
+{
+ /* TODO WEBKIT: Smileys need to be added to webkit stuff */
+ return TRUE;
+}
+
+static gboolean
pidgin_conv_custom_smiley_add(PurpleConversation *conv, const char *smile, gboolean remote)
{
PidginConversation *gtkconv;
@@ -6388,7 +6913,7 @@ pidgin_conv_custom_smiley_add(PurpleConversation *conv, const char *smile, gbool
/* If possible add this smiley to the current theme.
* The addition is only temporary: custom smilies aren't saved to disk. */
- conv_sml = purple_account_get_protocol_name(conv->account);
+ conv_sml = purple_account_get_protocol_name(purple_conversation_get_account(conv));
gtkconv = PIDGIN_CONVERSATION(conv);
for (list = (struct smiley_list *)current_smiley_theme->list; list; list = list->next) {
@@ -6398,7 +6923,7 @@ pidgin_conv_custom_smiley_add(PurpleConversation *conv, const char *smile, gbool
}
}
- if (!add_custom_smiley_for_imhtml(GTK_IMHTML(gtkconv->imhtml), sml, smile))
+ if (!add_custom_smiley_for_webview(GTK_WEBVIEW(gtkconv->webview), sml, smile))
return FALSE;
if (!remote) /* If it's a local custom smiley, then add it for the entry */
@@ -6412,12 +6937,14 @@ static void
pidgin_conv_custom_smiley_write(PurpleConversation *conv, const char *smile,
const guchar *data, gsize size)
{
+/* TODO WEBKIT */
+#if 0
PidginConversation *gtkconv;
GtkIMHtmlSmiley *smiley;
const char *sml;
GError *error = NULL;
- sml = purple_account_get_protocol_name(conv->account);
+ sml = purple_account_get_protocol_name(purple_conversation_get_account(conv));
gtkconv = PIDGIN_CONVERSATION(conv);
smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile);
@@ -6433,7 +6960,7 @@ pidgin_conv_custom_smiley_write(PurpleConversation *conv, const char *smile,
if (!gdk_pixbuf_loader_write(smiley->loader, data, size, &error) || error) {
purple_debug_warning("gtkconv", "gdk_pixbuf_loader_write() "
- "failed with size=%zu: %s\n", size,
+ "failed with size=%" G_GSIZE_FORMAT ": %s\n", size,
error ? error->message : "(no error message)");
if (error)
g_error_free(error);
@@ -6446,11 +6973,14 @@ pidgin_conv_custom_smiley_write(PurpleConversation *conv, const char *smile,
g_object_unref(G_OBJECT(smiley->loader));
smiley->loader = gdk_pixbuf_loader_new();
}
+#endif /* if 0 */
}
static void
pidgin_conv_custom_smiley_close(PurpleConversation *conv, const char *smile)
{
+/* TODO WEBKIT */
+#if 0
PidginConversation *gtkconv;
GtkIMHtmlSmiley *smiley;
const char *sml;
@@ -6459,7 +6989,7 @@ pidgin_conv_custom_smiley_close(PurpleConversation *conv, const char *smile)
g_return_if_fail(conv != NULL);
g_return_if_fail(smile != NULL);
- sml = purple_account_get_protocol_name(conv->account);
+ sml = purple_account_get_protocol_name(purple_conversation_get_account(conv));
gtkconv = PIDGIN_CONVERSATION(conv);
smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile);
@@ -6487,6 +7017,7 @@ pidgin_conv_custom_smiley_close(PurpleConversation *conv, const char *smile)
g_object_unref(G_OBJECT(smiley->loader));
smiley->loader = gdk_pixbuf_loader_new();
}
+#endif /* if 0 */
}
static void
@@ -6514,11 +7045,11 @@ gray_stuff_out(PidginConversation *gtkconv)
PurpleAccount *account;
win = pidgin_conv_get_window(gtkconv);
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
account = purple_conversation_get_account(conv);
if (gc != NULL)
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
if (win->menu.send_to != NULL)
update_send_to_selection(win);
@@ -6535,57 +7066,57 @@ gray_stuff_out(PidginConversation *gtkconv)
/* Show stuff that applies to IMs, hide stuff that applies to chats */
/* Deal with menu items */
- gtk_widget_show(win->menu.view_log);
- gtk_widget_show(win->menu.send_file);
- gtk_widget_show(g_object_get_data(G_OBJECT(win->window), "get_attention"));
- gtk_widget_show(win->menu.add_pounce);
- gtk_widget_show(win->menu.get_info);
- gtk_widget_hide(win->menu.invite);
- gtk_widget_show(win->menu.alias);
+ gtk_action_set_visible(win->menu.view_log, TRUE);
+ gtk_action_set_visible(win->menu.send_file, TRUE);
+ gtk_action_set_visible(win->menu.get_attention, TRUE);
+ gtk_action_set_visible(win->menu.add_pounce, TRUE);
+ gtk_action_set_visible(win->menu.get_info, TRUE);
+ gtk_action_set_visible(win->menu.invite, FALSE);
+ gtk_action_set_visible(win->menu.alias, TRUE);
if (purple_privacy_check(account, purple_conversation_get_name(conv))) {
- gtk_widget_hide(win->menu.unblock);
- gtk_widget_show(win->menu.block);
+ gtk_action_set_visible(win->menu.unblock, FALSE);
+ gtk_action_set_visible(win->menu.block, TRUE);
} else {
- gtk_widget_hide(win->menu.block);
- gtk_widget_show(win->menu.unblock);
+ gtk_action_set_visible(win->menu.block, FALSE);
+ gtk_action_set_visible(win->menu.unblock, TRUE);
}
if ((account == NULL) || purple_find_buddy(account, purple_conversation_get_name(conv)) == NULL) {
- gtk_widget_show(win->menu.add);
- gtk_widget_hide(win->menu.remove);
+ gtk_action_set_visible(win->menu.add, TRUE);
+ gtk_action_set_visible(win->menu.remove, FALSE);
} else {
- gtk_widget_show(win->menu.remove);
- gtk_widget_hide(win->menu.add);
+ gtk_action_set_visible(win->menu.remove, TRUE);
+ gtk_action_set_visible(win->menu.add, FALSE);
}
- gtk_widget_show(win->menu.insert_link);
- gtk_widget_show(win->menu.insert_image);
+ gtk_action_set_visible(win->menu.insert_link, TRUE);
+ gtk_action_set_visible(win->menu.insert_image, TRUE);
} else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
/* Show stuff that applies to Chats, hide stuff that applies to IMs */
/* Deal with menu items */
- gtk_widget_show(win->menu.view_log);
- gtk_widget_hide(win->menu.send_file);
- gtk_widget_hide(g_object_get_data(G_OBJECT(win->window), "get_attention"));
- gtk_widget_hide(win->menu.add_pounce);
- gtk_widget_hide(win->menu.get_info);
- gtk_widget_show(win->menu.invite);
- gtk_widget_show(win->menu.alias);
- gtk_widget_hide(win->menu.block);
- gtk_widget_hide(win->menu.unblock);
+ gtk_action_set_visible(win->menu.view_log, TRUE);
+ gtk_action_set_visible(win->menu.send_file, FALSE);
+ gtk_action_set_visible(win->menu.get_attention, FALSE);
+ gtk_action_set_visible(win->menu.add_pounce, FALSE);
+ gtk_action_set_visible(win->menu.get_info, FALSE);
+ gtk_action_set_visible(win->menu.invite, TRUE);
+ gtk_action_set_visible(win->menu.alias, TRUE);
+ gtk_action_set_visible(win->menu.block, FALSE);
+ gtk_action_set_visible(win->menu.unblock, FALSE);
if ((account == NULL) || purple_blist_find_chat(account, purple_conversation_get_name(conv)) == NULL) {
/* If the chat is NOT in the buddy list */
- gtk_widget_show(win->menu.add);
- gtk_widget_hide(win->menu.remove);
+ gtk_action_set_visible(win->menu.add, TRUE);
+ gtk_action_set_visible(win->menu.remove, FALSE);
} else {
/* If the chat IS in the buddy list */
- gtk_widget_hide(win->menu.add);
- gtk_widget_show(win->menu.remove);
+ gtk_action_set_visible(win->menu.add, FALSE);
+ gtk_action_set_visible(win->menu.remove, TRUE);
}
- gtk_widget_show(win->menu.insert_link);
- gtk_widget_show(win->menu.insert_image);
+ gtk_action_set_visible(win->menu.insert_link, TRUE);
+ gtk_action_set_visible(win->menu.insert_image, TRUE);
}
/*
@@ -6596,31 +7127,35 @@ gray_stuff_out(PidginConversation *gtkconv)
((purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_CHAT) ||
!purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)) ))
{
+ PurpleConnectionFlags features = purple_conversation_get_features(conv);
/* Account is online */
/* Deal with the toolbar */
- if (conv->features & PURPLE_CONNECTION_HTML)
+ if (features & PURPLE_CONNECTION_HTML)
{
buttons = GTK_IMHTML_ALL; /* Everything on */
- if (conv->features & PURPLE_CONNECTION_NO_BGCOLOR)
+ if (features & PURPLE_CONNECTION_NO_BGCOLOR)
buttons &= ~GTK_IMHTML_BACKCOLOR;
- if (conv->features & PURPLE_CONNECTION_NO_FONTSIZE)
+ if (features & PURPLE_CONNECTION_NO_FONTSIZE)
{
buttons &= ~GTK_IMHTML_GROW;
buttons &= ~GTK_IMHTML_SHRINK;
}
- if (conv->features & PURPLE_CONNECTION_NO_URLDESC)
+ if (features & PURPLE_CONNECTION_NO_URLDESC)
buttons &= ~GTK_IMHTML_LINKDESC;
} else {
buttons = GTK_IMHTML_SMILEY | GTK_IMHTML_IMAGE;
}
- if (!(prpl_info->options & OPT_PROTO_IM_IMAGE))
- conv->features |= PURPLE_CONNECTION_NO_IMAGES;
+ if (!(prpl_info->options & OPT_PROTO_IM_IMAGE)
+ && !(features & PURPLE_CONNECTION_NO_IMAGES)) {
+ features |= PURPLE_CONNECTION_NO_IMAGES;
+ purple_conversation_set_features(conv, features);
+ }
- if(conv->features & PURPLE_CONNECTION_NO_IMAGES)
+ if (features & PURPLE_CONNECTION_NO_IMAGES)
buttons &= ~GTK_IMHTML_IMAGE;
- if (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)
+ if (features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)
buttons |= GTK_IMHTML_CUSTOM_SMILEY;
else
buttons &= ~GTK_IMHTML_CUSTOM_SMILEY;
@@ -6630,30 +7165,30 @@ gray_stuff_out(PidginConversation *gtkconv)
gtk_imhtmltoolbar_associate_smileys(GTK_IMHTMLTOOLBAR(gtkconv->toolbar), purple_account_get_protocol_id(account));
/* Deal with menu items */
- gtk_widget_set_sensitive(win->menu.view_log, TRUE);
- gtk_widget_set_sensitive(win->menu.add_pounce, TRUE);
- gtk_widget_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL));
- gtk_widget_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL));
- gtk_widget_set_sensitive(win->menu.insert_link, (conv->features & PURPLE_CONNECTION_HTML));
- gtk_widget_set_sensitive(win->menu.insert_image, !(conv->features & PURPLE_CONNECTION_NO_IMAGES));
+ gtk_action_set_sensitive(win->menu.view_log, TRUE);
+ gtk_action_set_sensitive(win->menu.add_pounce, TRUE);
+ gtk_action_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL));
+ gtk_action_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL));
+ gtk_action_set_sensitive(win->menu.insert_link, (features & PURPLE_CONNECTION_HTML));
+ gtk_action_set_sensitive(win->menu.insert_image, !(features & PURPLE_CONNECTION_NO_IMAGES));
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
{
- gtk_widget_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL) || (prpl_info->add_buddy_with_invite != NULL));
- gtk_widget_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL));
- gtk_widget_set_sensitive(win->menu.send_file,
+ gtk_action_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL));
+ gtk_action_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL));
+ gtk_action_set_sensitive(win->menu.send_file,
(prpl_info->send_file != NULL && (!prpl_info->can_receive_file ||
prpl_info->can_receive_file(gc, purple_conversation_get_name(conv)))));
- gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(win->window), "get_attention"), (prpl_info->send_attention != NULL));
- gtk_widget_set_sensitive(win->menu.alias,
+ gtk_action_set_sensitive(win->menu.get_attention, (prpl_info->send_attention != NULL));
+ gtk_action_set_sensitive(win->menu.alias,
(account != NULL) &&
(purple_find_buddy(account, purple_conversation_get_name(conv)) != NULL));
}
else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
{
- gtk_widget_set_sensitive(win->menu.add, (prpl_info->join_chat != NULL));
- gtk_widget_set_sensitive(win->menu.remove, (prpl_info->join_chat != NULL));
- gtk_widget_set_sensitive(win->menu.alias,
+ gtk_action_set_sensitive(win->menu.add, (prpl_info->join_chat != NULL));
+ gtk_action_set_sensitive(win->menu.remove, (prpl_info->join_chat != NULL));
+ gtk_action_set_sensitive(win->menu.alias,
(account != NULL) &&
(purple_blist_find_chat(account, purple_conversation_get_name(conv)) != NULL));
}
@@ -6663,18 +7198,17 @@ gray_stuff_out(PidginConversation *gtkconv)
/* Or it's a chat that we've left. */
/* Then deal with menu items */
- gtk_widget_set_sensitive(win->menu.view_log, TRUE);
- gtk_widget_set_sensitive(win->menu.send_file, FALSE);
- gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(win->window),
- "get_attention"), FALSE);
- gtk_widget_set_sensitive(win->menu.add_pounce, TRUE);
- gtk_widget_set_sensitive(win->menu.get_info, FALSE);
- gtk_widget_set_sensitive(win->menu.invite, FALSE);
- gtk_widget_set_sensitive(win->menu.alias, FALSE);
- gtk_widget_set_sensitive(win->menu.add, FALSE);
- gtk_widget_set_sensitive(win->menu.remove, FALSE);
- gtk_widget_set_sensitive(win->menu.insert_link, TRUE);
- gtk_widget_set_sensitive(win->menu.insert_image, FALSE);
+ gtk_action_set_sensitive(win->menu.view_log, TRUE);
+ gtk_action_set_sensitive(win->menu.send_file, FALSE);
+ gtk_action_set_sensitive(win->menu.get_attention, FALSE);
+ gtk_action_set_sensitive(win->menu.add_pounce, TRUE);
+ gtk_action_set_sensitive(win->menu.get_info, FALSE);
+ gtk_action_set_sensitive(win->menu.invite, FALSE);
+ gtk_action_set_sensitive(win->menu.alias, FALSE);
+ gtk_action_set_sensitive(win->menu.add, FALSE);
+ gtk_action_set_sensitive(win->menu.remove, FALSE);
+ gtk_action_set_sensitive(win->menu.insert_link, TRUE);
+ gtk_action_set_sensitive(win->menu.insert_image, FALSE);
}
/*
@@ -6686,7 +7220,7 @@ gray_stuff_out(PidginConversation *gtkconv)
if ((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) &&
(gtkconv->u.im->anim))
{
- PurpleBuddy *buddy = purple_find_buddy(conv->account, conv->name);
+ PurpleBuddy *buddy = purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv));
window_icon =
gdk_pixbuf_animation_get_static_image(gtkconv->u.im->anim);
@@ -6734,6 +7268,7 @@ pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields)
{
gray_stuff_out(PIDGIN_CONVERSATION(conv));
generate_send_to_items(win);
+ regenerate_plugins_items(win);
}
if (fields & PIDGIN_CONV_TAB_ICON)
@@ -6754,13 +7289,20 @@ pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields)
topic = purple_conv_chat_get_topic(chat);
gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), topic ? topic : "");
+#if GTK_CHECK_VERSION(2,12,0)
+ gtk_widget_set_tooltip_text(gtkchat->topic_text,
+ topic ? topic : "");
+#else
gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->topic_text,
topic ? topic : "", NULL);
+#endif
}
}
+#if 0
if (fields & PIDGIN_CONV_SMILEY_THEME)
- pidgin_themes_smiley_themeize(PIDGIN_CONVERSATION(conv)->imhtml);
+ pidgin_themes_smiley_themeize(PIDGIN_CONVERSATION(conv)->webview);
+#endif
if ((fields & PIDGIN_CONV_COLORIZE_TITLE) ||
(fields & PIDGIN_CONV_SET_TITLE) ||
@@ -6787,7 +7329,7 @@ pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields)
title = g_strdup(purple_conversation_get_title(conv));
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- buddy = purple_find_buddy(account, conv->name);
+ buddy = purple_find_buddy(account, purple_conversation_get_name(conv));
if (buddy) {
markup = pidgin_blist_get_name_markup(buddy, FALSE, FALSE);
} else {
@@ -6815,7 +7357,7 @@ pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields)
if (title != markup)
g_free(markup);
- if (!GTK_WIDGET_REALIZED(gtkconv->tab_label))
+ if (!gtk_widget_get_realized(gtkconv->tab_label))
gtk_widget_realize(gtkconv->tab_label);
accessibility_obj = gtk_widget_get_accessible(gtkconv->tab_cont);
@@ -6832,7 +7374,7 @@ pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields)
style = "tab-label-attention";
} else if (gtkconv->unseen_state == PIDGIN_UNSEEN_TEXT) {
atk_object_set_description(accessibility_obj, _("Unread Messages"));
- if (gtkconv->active_conv->type == PURPLE_CONV_TYPE_CHAT)
+ if (purple_conversation_get_type(gtkconv->active_conv) == PURPLE_CONV_TYPE_CHAT)
style = "tab-label-unreadchat";
else
style = "tab-label-attention";
@@ -7044,7 +7586,7 @@ pidgin_conv_update_buddy_icon(PurpleConversation *conv)
if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons"))
return;
- if (purple_conversation_get_gc(conv) == NULL)
+ if (purple_conversation_get_connection(conv) == NULL)
return;
buddy = purple_find_buddy(account, purple_conversation_get_name(conv));
@@ -7209,7 +7751,7 @@ pidgin_conv_get_tab_at_xy(PidginWindow *win, int x, int y, gboolean *to_right)
tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page);
/* Make sure the tab is not hidden beyond an arrow */
- if (!GTK_WIDGET_DRAWABLE(tab) && gtk_notebook_get_show_tabs(notebook))
+ if (!gtk_widget_is_drawable(tab) && gtk_notebook_get_show_tabs(notebook))
continue;
if (horiz) {
@@ -7316,34 +7858,6 @@ tab_side_pref_cb(const char *name, PurplePrefType type,
}
static void
-show_timestamps_pref_cb(const char *name, PurplePrefType type,
- gconstpointer value, gpointer data)
-{
- GList *l;
- PurpleConversation *conv;
- PidginConversation *gtkconv;
- PidginWindow *win;
-
- for (l = purple_get_conversations(); l != NULL; l = l->next)
- {
- conv = (PurpleConversation *)l->data;
-
- if (!PIDGIN_IS_PIDGIN_CONVERSATION(conv))
- continue;
-
- gtkconv = PIDGIN_CONVERSATION(conv);
- win = gtkconv->win;
-
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(win->menu.show_timestamps),
- (gboolean)GPOINTER_TO_INT(value));
-
- gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),
- (gboolean)GPOINTER_TO_INT(value));
- }
-}
-
-static void
show_formatting_toolbar_pref_cb(const char *name, PurplePrefType type,
gconstpointer value, gpointer data)
{
@@ -7362,8 +7876,8 @@ show_formatting_toolbar_pref_cb(const char *name, PurplePrefType type,
gtkconv = PIDGIN_CONVERSATION(conv);
win = gtkconv->win;
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(win->menu.show_formatting_toolbar),
+ gtk_toggle_action_set_active(
+ GTK_TOGGLE_ACTION(win->menu.show_formatting_toolbar),
(gboolean)GPOINTER_TO_INT(value));
if ((gboolean)GPOINTER_TO_INT(value))
@@ -7507,7 +8021,7 @@ hide_new_pref_cb(const char *name, PurplePrefType type,
conv = gtkconv->active_conv;
- if (conv->type == PURPLE_CONV_TYPE_CHAT ||
+ if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT ||
gtkconv->unseen_count == 0 ||
(when_away && !purple_status_is_available(
purple_account_get_active_status(
@@ -7547,7 +8061,7 @@ get_gtkconv_with_contact(PurpleContact *contact)
{
PurpleBuddy *buddy = (PurpleBuddy*)node;
PurpleConversation *conv;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy->name, buddy->account);
+ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy));
if (conv)
return PIDGIN_CONVERSATION(conv);
}
@@ -7572,16 +8086,18 @@ account_signed_off_cb(PurpleConnection *gc, gpointer event)
PIDGIN_CONV_MENU | PIDGIN_CONV_COLORIZE_TITLE);
if (PURPLE_CONNECTION_IS_CONNECTED(gc) &&
- conv->type == PURPLE_CONV_TYPE_CHAT &&
- conv->account == gc->account &&
+ purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT &&
+ purple_conversation_get_account(conv) == purple_connection_get_account(gc) &&
purple_conversation_get_data(conv, "want-to-rejoin")) {
GHashTable *comps = NULL;
- PurpleChat *chat = purple_blist_find_chat(conv->account, conv->name);
+ PurpleChat *chat = purple_blist_find_chat(purple_conversation_get_account(conv), purple_conversation_get_name(conv));
if (chat == NULL) {
- if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL)
- comps = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, conv->name);
+ PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
+
+ if (prpl_info->chat_info_defaults != NULL)
+ comps = prpl_info->chat_info_defaults(gc, purple_conversation_get_name(conv));
} else {
- comps = chat->components;
+ comps = purple_chat_get_components(chat);
}
serv_join_chat(gc, comps);
if (chat == NULL && comps != NULL)
@@ -7648,7 +8164,7 @@ update_buddy_idle_changed(PurpleBuddy *buddy, gboolean old, gboolean newidle)
{
PurpleConversation *conv;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy->name, buddy->account);
+ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy));
if (conv)
pidgin_conv_update_fields(conv, PIDGIN_CONV_TAB_ICON);
}
@@ -7658,7 +8174,7 @@ update_buddy_icon(PurpleBuddy *buddy)
{
PurpleConversation *conv;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy->name, buddy->account);
+ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy));
if (conv)
pidgin_conv_update_fields(conv, PIDGIN_CONV_BUDDY_ICON);
}
@@ -7723,7 +8239,7 @@ static int
message_compare(gconstpointer p1, gconstpointer p2)
{
const PurpleConvMessage *m1 = p1, *m2 = p2;
- return (m1->when > m2->when);
+ return (purple_conversation_message_get_timestamp(m1) > purple_conversation_message_get_timestamp(m2));
}
/* Adds some message history to the gtkconv. This happens in a idle-callback. */
@@ -7731,19 +8247,27 @@ static gboolean
add_message_history_to_gtkconv(gpointer data)
{
PidginConversation *gtkconv = data;
+ GtkWebView *webview = GTK_WEBVIEW(gtkconv->webview);
int count = 0;
int timer = gtkconv->attach.timer;
time_t when = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtkconv->entry), "attach-start-time"));
- gboolean im = (gtkconv->active_conv->type == PURPLE_CONV_TYPE_IM);
+ gboolean im = (purple_conversation_get_type(gtkconv->active_conv) == PURPLE_CONV_TYPE_IM);
gtkconv->attach.timer = 0;
while (gtkconv->attach.current && count < 100) { /* XXX: 100 is a random value here */
PurpleConvMessage *msg = gtkconv->attach.current->data;
- if (!im && when && when < msg->when) {
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR><HR>", 0);
+ if (!im && when && when < purple_conversation_message_get_timestamp(msg)) {
+ gtk_webview_append_html(webview, "<BR><HR>");
+ gtk_webview_scroll_to_end(webview, TRUE);
g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL);
}
- pidgin_conv_write_conv(msg->conv, msg->who, msg->alias, msg->what, msg->flags, msg->when);
+ pidgin_conv_write_conv(
+ purple_conversation_message_get_conv(msg),
+ purple_conversation_message_get_sender(msg),
+ purple_conversation_message_get_alias(msg),
+ purple_conversation_message_get_message(msg),
+ purple_conversation_message_get_flags(msg),
+ purple_conversation_message_get_timestamp(msg));
if (im) {
gtkconv->attach.current = g_list_delete_link(gtkconv->attach.current, gtkconv->attach.current);
} else {
@@ -7766,16 +8290,23 @@ add_message_history_to_gtkconv(gpointer data)
GList *history = purple_conversation_get_message_history(conv);
for (; history; history = history->next) {
PurpleConvMessage *msg = history->data;
- if (msg->when > when)
+ if (purple_conversation_message_get_timestamp(msg) > when)
msgs = g_list_prepend(msgs, msg);
}
}
msgs = g_list_sort(msgs, message_compare);
for (; msgs; msgs = g_list_delete_link(msgs, msgs)) {
PurpleConvMessage *msg = msgs->data;
- pidgin_conv_write_conv(msg->conv, msg->who, msg->alias, msg->what, msg->flags, msg->when);
+ pidgin_conv_write_conv(
+ purple_conversation_message_get_conv(msg),
+ purple_conversation_message_get_sender(msg),
+ purple_conversation_message_get_alias(msg),
+ purple_conversation_message_get_message(msg),
+ purple_conversation_message_get_flags(msg),
+ purple_conversation_message_get_timestamp(msg));
}
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR><HR>", 0);
+ gtk_webview_append_html(webview, "<BR><HR>");
+ gtk_webview_scroll_to_end(webview, TRUE);
g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL);
}
@@ -7851,21 +8382,27 @@ gboolean pidgin_conv_attach_to_conversation(PurpleConversation *conv)
g_return_val_if_reached(TRUE);
}
g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time",
- GINT_TO_POINTER(((PurpleConvMessage*)(list->data))->when));
+ GINT_TO_POINTER(purple_conversation_message_get_timestamp((PurpleConvMessage*)(list->data))));
gtkconv->attach.timer = g_idle_add(add_message_history_to_gtkconv, gtkconv);
} else {
purple_signal_emit(pidgin_conversations_get_handle(),
"conversation-displayed", gtkconv);
}
- if (conv->type == PURPLE_CONV_TYPE_CHAT) {
+ if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
pidgin_conv_update_fields(conv, PIDGIN_CONV_TOPIC);
- pidgin_conv_chat_add_users(conv, PURPLE_CONV_CHAT(conv)->in_room, TRUE);
+ pidgin_conv_chat_add_users(conv, purple_conv_chat_get_users(PURPLE_CONV_CHAT(conv)), TRUE);
}
return TRUE;
}
+PurpleTheme *
+pidgin_conversations_get_default_theme(void)
+{
+ return default_conv_theme;
+}
+
void *
pidgin_conversations_get_handle(void)
{
@@ -7879,21 +8416,23 @@ pidgin_conversations_init(void)
{
void *handle = pidgin_conversations_get_handle();
void *blist_handle = purple_blist_get_handle();
+ char *theme_dir;
/* Conversations */
purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations");
+ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations/themes");
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling", TRUE);
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/close_on_tabs", TRUE);
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_bold", FALSE);
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_italic", FALSE);
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_underline", FALSE);
+ purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_strike", FALSE);
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/spellcheck", TRUE);
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/show_incoming_formatting", TRUE);
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/resize_custom_smileys", TRUE);
purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/custom_smileys_size", 96);
purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines", 2);
- purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps", TRUE);
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar", TRUE);
purple_prefs_add_string(PIDGIN_PREFS_ROOT "/conversations/placement", "last");
@@ -7942,8 +8481,6 @@ pidgin_conversations_init(void)
/* Connect callbacks. */
purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/close_on_tabs",
close_on_tabs_pref_cb, NULL);
- purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/show_timestamps",
- show_timestamps_pref_cb, NULL);
purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar",
show_formatting_toolbar_pref_cb, NULL);
purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/spellcheck",
@@ -8165,6 +8702,11 @@ pidgin_conversations_init(void)
purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg", handle,
PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL);
+ purple_theme_manager_register_type(g_object_new(PIDGIN_TYPE_CONV_THEME_LOADER, "type", "conversation", NULL));
+ theme_dir = g_build_filename(DATADIR, "pidgin", "theme", NULL);
+ default_conv_theme = purple_theme_manager_load_theme(theme_dir, "conversation");
+ g_free(theme_dir);
+
{
/* Set default tab colors */
GString *str = g_string_new(NULL);
@@ -8310,8 +8852,9 @@ build_warn_close_dialog(PidginWindow *gtkwin)
gtk_container_set_border_width(GTK_CONTAINER(warn_close_dialog),
6);
gtk_window_set_resizable(GTK_WINDOW(warn_close_dialog), FALSE);
- gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog),
- FALSE);
+#if !GTK_CHECK_VERSION(2,22,0)
+ gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog), FALSE);
+#endif
/* Setup the outside spacing. */
vbox = GTK_DIALOG(warn_close_dialog)->vbox;
@@ -8613,9 +9156,9 @@ infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkc
/* Right click was pressed. Popup the context menu. */
GtkWidget *menu = gtk_menu_new(), *sub;
gboolean populated = populate_menu_with_options(menu, gtkconv, TRUE);
- sub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(gtkconv->win->menu.send_to));
- if (sub && GTK_WIDGET_IS_SENSITIVE(gtkconv->win->menu.send_to)) {
+ sub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(gtkconv->win->menu.send_to));
+ if (sub && gtk_widget_is_sensitive(gtkconv->win->menu.send_to)) {
GtkWidget *item = gtk_menu_item_new_with_mnemonic(_("S_end To"));
if (populated)
pidgin_separator(menu);
@@ -9048,18 +9591,18 @@ infopane_entry_activate(PidginConversation *gtkconv)
PurpleConversation *conv = gtkconv->active_conv;
const char *text = NULL;
- if (!GTK_WIDGET_VISIBLE(gtkconv->infopane)) {
+ if (!gtk_widget_get_visible(gtkconv->infopane)) {
/* There's already an entry for alias. Let's not create another one. */
return FALSE;
}
- if (!purple_account_is_connected(gtkconv->active_conv->account)) {
+ if (!purple_account_is_connected(purple_conversation_get_account(gtkconv->active_conv))) {
/* Do not allow aliasing someone on a disconnected account. */
return FALSE;
}
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- PurpleBuddy *buddy = purple_find_buddy(gtkconv->active_conv->account, gtkconv->active_conv->name);
+ PurpleBuddy *buddy = purple_find_buddy(purple_conversation_get_account(gtkconv->active_conv), purple_conversation_get_name(gtkconv->active_conv));
if (!buddy)
/* This buddy isn't in your buddy list, so we can't alias him */
return FALSE;
@@ -9069,9 +9612,9 @@ infopane_entry_activate(PidginConversation *gtkconv)
PurpleConnection *gc;
PurplePluginProtocolInfo *prpl_info = NULL;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv);
if (gc != NULL)
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
if (prpl_info && prpl_info->set_chat_topic == NULL)
/* This protocol doesn't support setting the chat room topic */
return FALSE;
@@ -9132,8 +9675,8 @@ switch_conv_cb(GtkNotebook *notebook, GtkWidget *page, gint page_num,
/* Update the menubar */
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging),
- purple_conversation_is_logging(conv));
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtkconv->win->menu.logging),
+ purple_conversation_is_logging(conv));
generate_send_to_items(win);
regenerate_options_items(win);
@@ -9143,14 +9686,11 @@ switch_conv_cb(GtkNotebook *notebook, GtkWidget *page, gint page_num,
sound_method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method");
if (strcmp(sound_method, "none") != 0)
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds),
- gtkconv->make_sound);
-
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_formatting_toolbar),
- purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar"));
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
+ gtkconv->make_sound);
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_timestamps),
- purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps"));
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.show_formatting_toolbar),
+ purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar"));
/*
* We pause icons when they are not visible. If this icon should
@@ -9208,7 +9748,7 @@ plugin_changed_cb(PurplePlugin *p, gpointer data)
static gboolean gtk_conv_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) {
int x, y;
- if (GTK_WIDGET_VISIBLE(w))
+ if (gtk_widget_get_visible(w))
gtk_window_get_position(GTK_WINDOW(w), &x, &y);
else
return FALSE; /* carry on normally */
@@ -9243,7 +9783,7 @@ pidgin_conv_set_position_size(PidginWindow *win, int conv_x, int conv_y,
/* if the window exists, is hidden, we're saving positions, and the
* position is sane... */
if (win && win->window &&
- !GTK_WIDGET_VISIBLE(win->window) && conv_width != 0) {
+ !gtk_widget_get_visible(win->window) && conv_width != 0) {
#ifdef _WIN32 /* only override window manager placement on Windows */
/* ...check position is on screen... */
@@ -9383,10 +9923,6 @@ pidgin_conv_window_destroy(PidginWindow *win)
purple_prefs_disconnect_by_handle(win);
window_list = g_list_remove(window_list, win);
- /* Close the "Find" dialog if it's open */
- if (win->dialogs.search)
- gtk_widget_destroy(win->dialogs.search);
-
if (win->gtkconvs) {
while (win->gtkconvs) {
gboolean last = (win->gtkconvs->next == NULL);
@@ -9398,7 +9934,7 @@ pidgin_conv_window_destroy(PidginWindow *win)
}
gtk_widget_destroy(win->window);
- g_object_unref(G_OBJECT(win->menu.item_factory));
+ g_object_unref(G_OBJECT(win->menu.ui));
purple_notify_close_with_handle(win);
purple_signals_disconnect_by_handle(win);
@@ -9476,8 +10012,12 @@ pidgin_conv_window_add_gtkconv(PidginWindow *win, PidginConversation *gtkconv)
/* Close button. */
gtkconv->close = pidgin_create_small_button(gtk_label_new("×"));
+#if GTK_CHECK_VERSION(2,12,0)
+ gtk_widget_set_tooltip_text(gtkconv->close, _("Close conversation"));
+#else
gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->close,
_("Close conversation"), NULL);
+#endif
g_signal_connect(gtkconv->close, "clicked", G_CALLBACK (close_conv_cb), gtkconv);
@@ -9613,9 +10153,9 @@ pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv)
gtk_notebook_set_tab_label(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, ebox);
}
- gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont,
- !tabs_side && !angle,
- TRUE, GTK_PACK_START);
+ gtk_container_child_set(GTK_CONTAINER(win->notebook), gtkconv->tab_cont,
+ "tab-expand", !tabs_side && !angle,
+ "tab-fill", TRUE, NULL);
if (pidgin_conv_window_get_gtkconv_count(win) == 1)
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook),
@@ -9639,8 +10179,7 @@ pidgin_conv_window_remove_gtkconv(PidginWindow *win, PidginConversation *gtkconv
index = gtk_notebook_page_num(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont);
- g_object_ref(gtkconv->tab_cont);
- gtk_object_sink(GTK_OBJECT(gtkconv->tab_cont));
+ g_object_ref_sink(G_OBJECT(gtkconv->tab_cont));
gtk_notebook_remove_page(GTK_NOTEBOOK(win->notebook), index);
@@ -9845,7 +10384,7 @@ conv_placement_last_created_win_type_configured_cb(GtkWidget *w,
PurpleConversationType type = purple_conversation_get_type(conv->active_conv);
GList *all;
- if (GTK_WIDGET_VISIBLE(w))
+ if (gtk_widget_get_visible(w))
gtk_window_get_position(GTK_WINDOW(w), &x, &y);
else
return FALSE; /* carry on normally */
diff --git a/pidgin/gtkconv.h b/pidgin/gtkconv.h
index a952e73b81..9f32af3dd3 100644
--- a/pidgin/gtkconv.h
+++ b/pidgin/gtkconv.h
@@ -51,12 +51,12 @@ enum {
CHAT_USERS_FLAGS_COLUMN,
CHAT_USERS_COLOR_COLUMN,
CHAT_USERS_WEIGHT_COLUMN,
- CHAT_USERS_ICON_STOCK_COLUMN, /** @since 2.6.0 */
+ CHAT_USERS_ICON_STOCK_COLUMN,
CHAT_USERS_COLUMNS
};
#define PIDGIN_CONVERSATION(conv) \
- ((PidginConversation *)(conv)->ui_data)
+ ((PidginConversation *)purple_conversation_get_ui_data(conv))
#define PIDGIN_IS_PIDGIN_CONVERSATION(conv) \
(purple_conversation_get_ui_ops(conv) == \
@@ -65,6 +65,7 @@ enum {
#include "pidgin.h"
#include "conversation.h"
#include "gtkconvwin.h"
+#include "gtkconv-theme.h"
/**************************************************************************
* @name Structures
@@ -77,39 +78,6 @@ enum {
*/
/**
- * A GTK+ Instant Message pane.
- */
-struct _PidginImPane
-{
- GtkWidget *block;
- GtkWidget *send_file;
- GtkWidget *sep1;
- GtkWidget *sep2;
- GtkWidget *check;
- GtkWidget *progress;
- guint32 typing_timer;
-
- /* Buddy icon stuff */
- GtkWidget *icon_container;
- GtkWidget *icon;
- gboolean show_icon;
- gboolean animate;
- GdkPixbufAnimation *anim;
- GdkPixbufAnimationIter *iter;
- guint32 icon_timer;
-};
-
-/**
- * GTK+ Chat panes.
- */
-struct _PidginChatPane
-{
- GtkWidget *count;
- GtkWidget *list;
- GtkWidget *topic_text;
-};
-
-/**
* A GTK+ conversation pane.
*/
struct _PidginConversation
@@ -122,18 +90,24 @@ struct _PidginConversation
gboolean make_sound;
+#if GTK_CHECK_VERSION(2,12,0)
+ gpointer depr2;
+#else
GtkTooltips *tooltips;
+#endif
GtkWidget *tab_cont;
GtkWidget *tabby;
GtkWidget *menu_tabby;
- GtkWidget *imhtml;
+ PidginConvTheme *theme;
+ PurpleMessageFlags last_flags;
+ GtkWidget *webview;
GtkTextBuffer *entry_buffer;
GtkWidget *entry;
gboolean auto_resize; /* this is set to TRUE if the conversation
- * is being resized by a non-user-initiated
- * event, such as the buddy icon appearing
+ * is being resized by a non-user-initiated
+ * event, such as the buddy icon appearing
*/
gboolean entry_growing; /* True if the size of the entry was set
* automatically by typing too much to fit
@@ -144,12 +118,6 @@ struct _PidginConversation
GtkWidget *tab_label;
GtkWidget *menu_icon;
GtkWidget *menu_label;
-#if !(defined PIDGIN_DISABLE_DEPRECATED) || (defined _PIDGIN_GTKCONV_C_)
- /** @deprecated */
- GtkSizeGroup *sg;
-#else
- gpointer depr1;
-#endif
GtkWidget *lower_hbox;
@@ -180,8 +148,6 @@ struct _PidginConversation
/**
* Quick Find.
- *
- * @since 2.7.0
*/
struct {
GtkWidget *entry;
@@ -191,6 +157,8 @@ struct _PidginConversation
/*@}*/
+G_BEGIN_DECLS
+
/**************************************************************************
* @name GTK+ Conversation API
**************************************************************************/
@@ -204,6 +172,13 @@ struct _PidginConversation
PurpleConversationUiOps *pidgin_conversations_get_conv_ui_ops(void);
/**
+ * Returns the default theme for GTK+ conversations.
+ *
+ * @return The default GTK+ conversation theme.
+ */
+PurpleTheme *pidgin_conversations_get_default_theme(void);
+
+/**
* Updates the buddy icon on a conversation.
*
* @param conv The conversation.
@@ -269,8 +244,6 @@ void pidgin_conv_present_conversation(PurpleConversation *conv);
* @param conv The conversation.
*
* @return Wheter Pidgin UI was successfully attached.
- *
- * @since 2.2.0
*/
gboolean pidgin_conv_attach_to_conversation(PurpleConversation *conv);
@@ -305,4 +278,6 @@ void pidgin_conversations_uninit(void);
/*@}*/
+G_END_DECLS
+
#endif /* _PIDGIN_CONVERSATION_H_ */
diff --git a/pidgin/gtkconvwin.h b/pidgin/gtkconvwin.h
index 986b1ca28f..c2a5268704 100644
--- a/pidgin/gtkconvwin.h
+++ b/pidgin/gtkconvwin.h
@@ -46,29 +46,33 @@ struct _PidginWindow
struct
{
+ GtkUIManager *ui;
GtkWidget *menubar;
- GtkWidget *view_log;
+ GtkAction *view_log;
- GtkWidget *send_file;
- GtkWidget *add_pounce;
- GtkWidget *get_info;
- GtkWidget *invite;
+ GtkAction *audio_call;
+ GtkAction *video_call;
+ GtkAction *audio_video_call;
- GtkWidget *alias;
- GtkWidget *block;
- GtkWidget *unblock;
- GtkWidget *add;
- GtkWidget *remove;
+ GtkAction *send_file;
+ GtkAction *get_attention;
+ GtkAction *add_pounce;
+ GtkAction *get_info;
+ GtkAction *invite;
- GtkWidget *insert_link;
- GtkWidget *insert_image;
+ GtkAction *alias;
+ GtkAction *block;
+ GtkAction *unblock;
+ GtkAction *add;
+ GtkAction *remove;
- GtkWidget *logging;
- GtkWidget *sounds;
- GtkWidget *show_formatting_toolbar;
- GtkWidget *show_timestamps;
- GtkWidget *show_icon;
+ GtkAction *insert_link;
+ GtkAction *insert_image;
+
+ GtkAction *logging;
+ GtkAction *sounds;
+ GtkAction *show_formatting_toolbar;
GtkWidget *send_to;
@@ -76,16 +80,8 @@ struct _PidginWindow
GtkWidget *typing_icon;
- GtkItemFactory *item_factory;
-
} menu;
- struct
- {
- GtkWidget *search;
-
- } dialogs;
-
/* Tab dragging stuff. */
gboolean in_drag;
gboolean in_predrag;
@@ -96,15 +92,12 @@ struct _PidginWindow
gint drag_motion_signal;
gint drag_leave_signal;
-
- /* Media menu options. */
- GtkWidget *audio_call;
- GtkWidget *video_call;
- GtkWidget *audio_video_call;
};
/*@}*/
+G_BEGIN_DECLS
+
/**************************************************************************
* @name GTK+ Conversation Window API
**************************************************************************/
@@ -151,4 +144,6 @@ void pidgin_conv_placement_place(PidginConversation *gtkconv);
/*@}*/
+G_END_DECLS
+
#endif /* _PIDGIN_CONVERSATION_WINDOW_H_ */
diff --git a/pidgin/gtkdebug.c b/pidgin/gtkdebug.c
index 895ba5b32d..da51277b50 100644
--- a/pidgin/gtkdebug.c
+++ b/pidgin/gtkdebug.c
@@ -33,72 +33,57 @@
#include "gtkdebug.h"
#include "gtkdialogs.h"
-#include "gtkimhtml.h"
#include "gtkutils.h"
+#include "gtkwebview.h"
#include "pidginstock.h"
-#ifdef HAVE_REGEX_H
-# include <regex.h>
-# define USE_REGEX 1
-#else
-#if GLIB_CHECK_VERSION(2,14,0)
-# define USE_REGEX 1
-#endif
-#endif /* HAVE_REGEX_H */
-
#include <gdk/gdkkeysyms.h>
typedef struct
{
GtkWidget *window;
GtkWidget *text;
-
- GtkListStore *store;
-
- gboolean paused;
-
-#ifdef USE_REGEX
GtkWidget *filter;
GtkWidget *expression;
+ GtkWidget *filterlevel;
+
+ gboolean paused;
gboolean invert;
gboolean highlight;
-
guint timer;
-# ifdef HAVE_REGEX_H
- regex_t regex;
-# else
GRegex *regex;
-# endif /* HAVE_REGEX_H */
-#else
- GtkWidget *find;
-#endif /* USE_REGEX */
- GtkWidget *filterlevel;
} DebugWindow;
-static const char debug_fg_colors[][8] = {
- "#000000", /**< All debug levels. */
- "#666666", /**< Misc. */
- "#000000", /**< Information. */
- "#660000", /**< Warnings. */
- "#FF0000", /**< Errors. */
- "#FF0000", /**< Fatal errors. */
-};
+#define EMPTY_HTML \
+ "<html><head><style>" \
+ "body{white-space:pre-wrap;}" \
+ "div.l0{color:#000000;}" /* All debug levels. */ \
+ "div.l1{color:#666666;}" /* Misc. */ \
+ "div.l2{color:#000000;}" /* Information. */ \
+ "div.l3{color:#660000;}" /* Warnings. */ \
+ "div.l4{color:#FF0000;}" /* Errors. */ \
+ "div.l5{color:#FF0000;font-weight:bold;}" /* Fatal errors. */ \
+ /* Filter levels */ \
+ "div#pause~div{display:none;}" \
+ "body.l1 div.l0{display:none;}" \
+ "body.l2 div.l0,body.l2 div.l1{display:none;}" \
+ "body.l3 div.l0,body.l3 div.l1,body.l3 div.l2{display:none;}" \
+ "body.l4 div.l0,body.l4 div.l1,body.l4 div.l2,body.l4 div.l3{display:none;}" \
+ "body.l5 div.l0,body.l5 div.l1,body.l5 div.l2,body.l5 div.l3,body.l5 div.l4{display:none;}" \
+ /* Regex */ \
+ "div.hide{display:none;}" \
+ "span.regex{background-color:#ffafaf;font-weight:bold;}" \
+ "</style></head></html>"
static DebugWindow *debug_win = NULL;
static guint debug_enabled_timer = 0;
-#ifdef USE_REGEX
-static void regex_filter_all(DebugWindow *win);
-static void regex_show_all(DebugWindow *win);
-#endif /* USE_REGEX */
-
static gint
debug_window_destroy(GtkWidget *w, GdkEvent *event, void *unused)
{
purple_prefs_disconnect_by_handle(pidgin_debug_get_handle());
-#ifdef USE_REGEX
if(debug_win->timer != 0) {
const gchar *text;
@@ -107,12 +92,7 @@ debug_window_destroy(GtkWidget *w, GdkEvent *event, void *unused)
text = gtk_entry_get_text(GTK_ENTRY(debug_win->expression));
purple_prefs_set_string(PIDGIN_PREFS_ROOT "/debug/regex", text);
}
-#ifdef HAVE_REGEX_H
- regfree(&debug_win->regex);
-#else
g_regex_unref(debug_win->regex);
-#endif /* HAVE_REGEX_H */
-#endif /* USE_REGEX */
/* If the "Save Log" dialog is open then close it */
purple_request_close_with_handle(debug_win);
@@ -128,7 +108,11 @@ debug_window_destroy(GtkWidget *w, GdkEvent *event, void *unused)
static gboolean
configure_cb(GtkWidget *w, GdkEventConfigure *event, DebugWindow *win)
{
+#if GTK_CHECK_VERSION(2,18,0)
+ if (gtk_widget_get_visible(w)) {
+#else
if (GTK_WIDGET_VISIBLE(w)) {
+#endif
purple_prefs_set_int(PIDGIN_PREFS_ROOT "/debug/width", event->width);
purple_prefs_set_int(PIDGIN_PREFS_ROOT "/debug/height", event->height);
}
@@ -136,89 +120,6 @@ configure_cb(GtkWidget *w, GdkEventConfigure *event, DebugWindow *win)
return FALSE;
}
-#ifndef USE_REGEX
-struct _find {
- DebugWindow *window;
- GtkWidget *entry;
-};
-
-static void
-do_find_cb(GtkWidget *widget, gint response, struct _find *f)
-{
- switch (response) {
- case GTK_RESPONSE_OK:
- gtk_imhtml_search_find(GTK_IMHTML(f->window->text),
- gtk_entry_get_text(GTK_ENTRY(f->entry)));
- break;
-
- case GTK_RESPONSE_DELETE_EVENT:
- case GTK_RESPONSE_CLOSE:
- gtk_imhtml_search_clear(GTK_IMHTML(f->window->text));
- gtk_widget_destroy(f->window->find);
- f->window->find = NULL;
- g_free(f);
- break;
- }
-}
-
-static void
-find_cb(GtkWidget *w, DebugWindow *win)
-{
- GtkWidget *hbox, *img, *label;
- struct _find *f;
-
- if(win->find)
- {
- gtk_window_present(GTK_WINDOW(win->find));
- return;
- }
-
- f = g_malloc(sizeof(struct _find));
- f->window = win;
- win->find = gtk_dialog_new_with_buttons(_("Find"),
- GTK_WINDOW(win->window), GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
- GTK_STOCK_FIND, GTK_RESPONSE_OK, NULL);
- gtk_dialog_set_default_response(GTK_DIALOG(win->find),
- GTK_RESPONSE_OK);
- g_signal_connect(G_OBJECT(win->find), "response",
- G_CALLBACK(do_find_cb), f);
-
- gtk_container_set_border_width(GTK_CONTAINER(win->find), PIDGIN_HIG_BOX_SPACE);
- gtk_window_set_resizable(GTK_WINDOW(win->find), FALSE);
- gtk_dialog_set_has_separator(GTK_DIALOG(win->find), FALSE);
- gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(win->find)->vbox), PIDGIN_HIG_BORDER);
- gtk_container_set_border_width(
- GTK_CONTAINER(GTK_DIALOG(win->find)->vbox), PIDGIN_HIG_BOX_SPACE);
-
- hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(win->find)->vbox),
- hbox);
- img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION,
- gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE));
- gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
-
- gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
- gtk_dialog_set_response_sensitive(GTK_DIALOG(win->find),
- GTK_RESPONSE_OK, FALSE);
-
- label = gtk_label_new(NULL);
- gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), _("_Search for:"));
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-
- f->entry = gtk_entry_new();
- gtk_entry_set_activates_default(GTK_ENTRY(f->entry), TRUE);
- gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_WIDGET(f->entry));
- g_signal_connect(G_OBJECT(f->entry), "changed",
- G_CALLBACK(pidgin_set_sensitive_if_input),
- win->find);
- gtk_box_pack_start(GTK_BOX(hbox), f->entry, FALSE, FALSE, 0);
-
- gtk_widget_show_all(win->find);
- gtk_widget_grab_focus(f->entry);
-}
-#endif /* USE_REGEX */
-
static void
save_writefile_cb(void *user_data, const char *filename)
{
@@ -231,7 +132,7 @@ save_writefile_cb(void *user_data, const char *filename)
return;
}
- tmp = gtk_imhtml_get_text(GTK_IMHTML(win->text), NULL, NULL);
+ tmp = gtk_webview_get_body_text(GTK_WEBVIEW(win->text));
fprintf(fp, "Pidgin Debug Log : %s\n", purple_date_format_full(NULL));
fprintf(fp, "%s", tmp);
g_free(tmp);
@@ -251,11 +152,7 @@ save_cb(GtkWidget *w, DebugWindow *win)
static void
clear_cb(GtkWidget *w, DebugWindow *win)
{
- gtk_imhtml_clear(GTK_IMHTML(win->text));
-
-#ifdef USE_REGEX
- gtk_list_store_clear(win->store);
-#endif /* USE_REGEX */
+ gtk_webview_load_html_string(GTK_WEBVIEW(win->text), EMPTY_HTML);
}
static void
@@ -263,20 +160,25 @@ pause_cb(GtkWidget *w, DebugWindow *win)
{
win->paused = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(w));
-#ifdef USE_REGEX
- if(!win->paused) {
- if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter)))
- regex_filter_all(win);
- else
- regex_show_all(win);
+ if (win->paused) {
+ gtk_webview_append_html(GTK_WEBVIEW(win->text), "<div id=pause></div>");
+ } else {
+ WebKitDOMDocument *dom;
+ WebKitDOMElement *pause;
+
+ dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(win->text));
+ pause = webkit_dom_document_get_element_by_id(dom, "pause");
+ if (pause) {
+ WebKitDOMNode *parent;
+ parent = webkit_dom_node_get_parent_node(WEBKIT_DOM_NODE(pause));
+ webkit_dom_node_remove_child(parent, WEBKIT_DOM_NODE(pause), NULL);
+ }
}
-#endif /* USE_REGEX */
}
/******************************************************************************
* regex stuff
*****************************************************************************/
-#ifdef USE_REGEX
static void
regex_clear_color(GtkWidget *w) {
gtk_widget_modify_base(w, GTK_STATE_NORMAL, NULL);
@@ -294,28 +196,133 @@ regex_change_color(GtkWidget *w, guint16 r, guint16 g, guint16 b) {
}
static void
-regex_highlight_clear(DebugWindow *win) {
- GtkIMHtml *imhtml = GTK_IMHTML(win->text);
- GtkTextIter s, e;
+regex_toggle_div(WebKitDOMNode *div)
+{
+ WebKitDOMDOMTokenList *classes;
+
+ if (!WEBKIT_DOM_IS_HTML_ELEMENT(div))
+ return;
- gtk_text_buffer_get_start_iter(imhtml->text_buffer, &s);
- gtk_text_buffer_get_end_iter(imhtml->text_buffer, &e);
- gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "regex", &s, &e);
+ classes = webkit_dom_html_element_get_class_list(WEBKIT_DOM_HTML_ELEMENT(div));
+ webkit_dom_dom_token_list_toggle(classes, "hide", NULL);
}
static void
-regex_match(DebugWindow *win, const gchar *text) {
- GtkIMHtml *imhtml = GTK_IMHTML(win->text);
-#ifdef HAVE_REGEX_H
- regmatch_t matches[4]; /* adjust if necessary */
- size_t n_matches = sizeof(matches) / sizeof(matches[0]);
- gint inverted;
-#else
+regex_highlight_clear(WebKitDOMDocument *dom)
+{
+ WebKitDOMNodeList *nodes;
+ gulong i;
+
+ /* Remove highlighting SPANs */
+ nodes = webkit_dom_document_get_elements_by_class_name(dom, "regex");
+ i = webkit_dom_node_list_get_length(nodes);
+ while (i--) {
+ WebKitDOMNode *span, *parent;
+ char *content;
+ WebKitDOMText *text;
+ GError *err = NULL;
+
+ span = webkit_dom_node_list_item(nodes, i);
+ parent = webkit_dom_node_get_parent_node(span);
+
+ content = webkit_dom_node_get_text_content(span);
+ text = webkit_dom_document_create_text_node(dom, content);
+ g_free(content);
+
+ webkit_dom_node_replace_child(parent, WEBKIT_DOM_NODE(text), span, &err);
+ }
+}
+
+static void
+regex_highlight_text_nodes(WebKitDOMDocument *dom, WebKitDOMNode *div,
+ gint start_pos, gint end_pos)
+{
+ GSList *data = NULL;
+ WebKitDOMNode *node;
+ WebKitDOMRange *range;
+ WebKitDOMElement *span;
+ gint ind, end_ind;
+ gint this_start, this_end;
+
+ ind = 0;
+ webkit_dom_node_normalize(div);
+ node = div;
+
+ /* First, find the container nodes and offsets to apply highlighting. */
+ do {
+ if (webkit_dom_node_get_node_type(node) == 3/*TEXT_NODE*/) {
+ /* The GObject model does not correctly reflect the type, hence the
+ regular cast. */
+ end_ind = ind + webkit_dom_character_data_get_length((WebKitDOMCharacterData*)node);
+
+ if (start_pos <= ind)
+ this_start = 0;
+ else if (start_pos < end_ind)
+ this_start = start_pos - ind;
+ else
+ this_start = -1;
+
+ if (end_pos < end_ind)
+ this_end = end_pos - ind;
+ else
+ this_end = end_ind - ind;
+
+ if (this_start != -1 && this_start < this_end) {
+ data = g_slist_prepend(data, GINT_TO_POINTER(this_end));
+ data = g_slist_prepend(data, GINT_TO_POINTER(this_start));
+ data = g_slist_prepend(data, node);
+ }
+
+ ind = end_ind;
+ }
+
+ if (webkit_dom_node_has_child_nodes(node)) {
+ node = webkit_dom_node_get_first_child(node);
+ } else {
+ while (node != div) {
+ WebKitDOMNode *next;
+
+ next = webkit_dom_node_get_next_sibling(node);
+ if (next) {
+ node = next;
+ break;
+ } else {
+ node = webkit_dom_node_get_parent_node(node);
+ }
+ }
+ }
+ } while (node != div);
+
+ /* Second, apply highlighting to saved sections. Changing the DOM is
+ automatically reflected in all WebKit API, so we have to do this after
+ finding the offsets, or things could get complicated. */
+ while (data) {
+ node = WEBKIT_DOM_NODE(data->data);
+ data = g_slist_delete_link(data, data);
+ this_start = GPOINTER_TO_INT(data->data);
+ data = g_slist_delete_link(data, data);
+ this_end = GPOINTER_TO_INT(data->data);
+ data = g_slist_delete_link(data, data);
+
+ range = webkit_dom_document_create_range(dom);
+ webkit_dom_range_set_start(range, node, this_start, NULL);
+ webkit_dom_range_set_end(range, node, this_end, NULL);
+ span = webkit_dom_document_create_element(dom, "span", NULL);
+ webkit_dom_html_element_set_class_name(WEBKIT_DOM_HTML_ELEMENT(span),
+ "regex");
+ webkit_dom_range_surround_contents(range, WEBKIT_DOM_NODE(span), NULL);
+ }
+}
+
+static void
+regex_match(DebugWindow *win, WebKitDOMDocument *dom, WebKitDOMNode *div)
+{
GMatchInfo *match_info;
-#endif /* HAVE_REGEX_H */
+ gchar *text;
gchar *plaintext;
- if(!text)
+ text = webkit_dom_node_get_text_content(div);
+ if (!text)
return;
/* I don't like having to do this, but we need it for highlighting. Plus
@@ -323,193 +330,80 @@ regex_match(DebugWindow *win, const gchar *text) {
*/
plaintext = purple_markup_strip_html(text);
- /* we do a first pass to see if it matches at all. If it does we append
- * it, and work out the offsets to highlight.
+ /* We do a first pass to see if it matches at all. If it does we work out
+ * the offsets to highlight.
*/
-#ifdef HAVE_REGEX_H
- inverted = (win->invert) ? REG_NOMATCH : 0;
- if(regexec(&win->regex, plaintext, n_matches, matches, 0) == inverted) {
-#else
- if(g_regex_match(win->regex, plaintext, 0, &match_info) != win->invert) {
-#endif /* HAVE_REGEX_H */
- gchar *p = plaintext;
- GtkTextIter ins;
- gint i, offset = 0;
-
- gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &ins,
- gtk_text_buffer_get_insert(imhtml->text_buffer));
- i = gtk_text_iter_get_offset(&ins);
-
- gtk_imhtml_append_text(imhtml, text, 0);
-
+ if (g_regex_match(win->regex, plaintext, 0, &match_info) != win->invert) {
/* If we're not highlighting or the expression is inverted, we're
* done and move on.
*/
- if(!win->highlight || win->invert) {
+ if (!win->highlight || win->invert) {
g_free(plaintext);
-#ifndef HAVE_REGEX_H
g_match_info_free(match_info);
-#endif
return;
}
- /* we use a do-while to highlight the first match, and then continue
- * if necessary...
- */
-#ifdef HAVE_REGEX_H
do {
- size_t m;
-
- for(m = 0; m < n_matches; m++) {
- GtkTextIter ms, me;
-
- if(matches[m].rm_eo == -1)
- break;
-
- i += offset;
-
- gtk_text_buffer_get_iter_at_offset(imhtml->text_buffer, &ms,
- i + matches[m].rm_so);
- gtk_text_buffer_get_iter_at_offset(imhtml->text_buffer, &me,
- i + matches[m].rm_eo);
- gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "regex",
- &ms, &me);
- offset = matches[m].rm_eo;
- }
-
- p += offset;
- } while(regexec(&win->regex, p, n_matches, matches, REG_NOTBOL) == inverted);
-#else
- do
- {
- gint m;
+ gint m, count;
gint start_pos, end_pos;
- GtkTextIter ms, me;
if (!g_match_info_matches(match_info))
break;
- for (m = 0; m < g_match_info_get_match_count(match_info); m++)
- {
- if (m == 1)
- continue;
+ count = g_match_info_get_match_count(match_info);
+ if (count == 1)
+ m = 0;
+ else
+ m = 1;
+ for (; m < count; m++)
+ {
g_match_info_fetch_pos(match_info, m, &start_pos, &end_pos);
if (end_pos == -1)
break;
- gtk_text_buffer_get_iter_at_offset(imhtml->text_buffer, &ms,
- i + start_pos);
- gtk_text_buffer_get_iter_at_offset(imhtml->text_buffer, &me,
- i + end_pos);
- gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "regex",
- &ms, &me);
- offset = end_pos;
+ regex_highlight_text_nodes(dom, div, start_pos, end_pos);
}
+ } while (g_match_info_next(match_info, NULL));
- g_match_info_free(match_info);
- p += offset;
- i += offset;
- } while (g_regex_match(win->regex, p, G_REGEX_MATCH_NOTBOL, &match_info) != win->invert);
g_match_info_free(match_info);
-#endif /* HAVE_REGEX_H */
+ } else {
+ regex_toggle_div(div);
}
g_free(plaintext);
-}
-
-static gboolean
-regex_filter_all_cb(GtkTreeModel *m, GtkTreePath *p, GtkTreeIter *iter,
- gpointer data)
-{
- DebugWindow *win = (DebugWindow *)data;
- gchar *text;
- PurpleDebugLevel level;
-
- gtk_tree_model_get(m, iter, 0, &text, 1, &level, -1);
-
- if (level >= purple_prefs_get_int(PIDGIN_PREFS_ROOT "/debug/filterlevel"))
- regex_match(win, text);
-
g_free(text);
-
- return FALSE;
}
static void
-regex_filter_all(DebugWindow *win) {
- gtk_imhtml_clear(GTK_IMHTML(win->text));
-
- if(win->highlight)
- regex_highlight_clear(win);
-
- gtk_tree_model_foreach(GTK_TREE_MODEL(win->store), regex_filter_all_cb,
- win);
-}
-
-static gboolean
-regex_show_all_cb(GtkTreeModel *m, GtkTreePath *p, GtkTreeIter *iter,
- gpointer data)
+regex_toggle_filter(DebugWindow *win, gboolean filter)
{
- DebugWindow *win = (DebugWindow *)data;
- gchar *text;
- PurpleDebugLevel level;
+ WebKitDOMDocument *dom;
+ WebKitDOMNodeList *list;
+ gulong i;
- gtk_tree_model_get(m, iter, 0, &text, 1, &level, -1);
- if (level >= purple_prefs_get_int(PIDGIN_PREFS_ROOT "/debug/filterlevel"))
- gtk_imhtml_append_text(GTK_IMHTML(win->text), text, 0);
- g_free(text);
+ dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(win->text));
- return FALSE;
-}
+ if (win->highlight)
+ regex_highlight_clear(dom);
-static void
-regex_show_all(DebugWindow *win) {
- gtk_imhtml_clear(GTK_IMHTML(win->text));
-
- if(win->highlight)
- regex_highlight_clear(win);
-
- gtk_tree_model_foreach(GTK_TREE_MODEL(win->store), regex_show_all_cb,
- win);
-}
-
-static void
-regex_compile(DebugWindow *win) {
- const gchar *text;
-
- text = gtk_entry_get_text(GTK_ENTRY(win->expression));
-
- if(text == NULL || *text == '\0') {
- regex_clear_color(win->expression);
- gtk_widget_set_sensitive(win->filter, FALSE);
- return;
+ /* Re-show debug lines that didn't match regex */
+ list = webkit_dom_document_get_elements_by_class_name(dom, "hide");
+ i = webkit_dom_node_list_get_length(list);
+ while (i--) {
+ WebKitDOMNode *div = webkit_dom_node_list_item(list, i);
+ regex_toggle_div(div);
}
-#ifdef HAVE_REGEX_H
- regfree(&win->regex);
- if(regcomp(&win->regex, text, REG_EXTENDED | REG_ICASE) != 0) {
-#else
- if (win->regex)
- g_regex_unref(win->regex);
- win->regex = g_regex_new(text, G_REGEX_EXTENDED | G_REGEX_CASELESS, 0, NULL);
- if(win->regex == NULL) {
-#endif
- /* failed to compile */
- regex_change_color(win->expression, 0xFFFF, 0xAFFF, 0xAFFF);
- gtk_widget_set_sensitive(win->filter, FALSE);
- } else {
- /* compiled successfully */
- regex_change_color(win->expression, 0xAFFF, 0xFFFF, 0xAFFF);
- gtk_widget_set_sensitive(win->filter, TRUE);
- }
+ if (filter) {
+ list = webkit_dom_document_get_elements_by_tag_name(dom, "div");
- /* we check if the filter is on in case it was only of the options that
- * got changed, and not the expression.
- */
- if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter)))
- regex_filter_all(win);
+ for (i = 0; i < webkit_dom_node_list_get_length(list); i++) {
+ WebKitDOMNode *div = webkit_dom_node_list_item(list, i);
+ regex_match(win, dom, div);
+ }
+ }
}
static void
@@ -519,11 +413,11 @@ regex_pref_filter_cb(const gchar *name, PurplePrefType type,
DebugWindow *win = (DebugWindow *)data;
gboolean active = GPOINTER_TO_INT(val), current;
- if(!win || !win->window)
+ if (!win || !win->window)
return;
current = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter));
- if(active != current)
+ if (active != current)
gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(win->filter), active);
}
@@ -546,8 +440,8 @@ regex_pref_invert_cb(const gchar *name, PurplePrefType type,
win->invert = active;
- if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter)))
- regex_filter_all(win);
+ if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter)))
+ regex_toggle_filter(win, TRUE);
}
static void
@@ -559,40 +453,8 @@ regex_pref_highlight_cb(const gchar *name, PurplePrefType type,
win->highlight = active;
- if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter)))
- regex_filter_all(win);
-}
-
-static void
-regex_row_changed_cb(GtkTreeModel *model, GtkTreePath *path,
- GtkTreeIter *iter, DebugWindow *win)
-{
- gchar *text;
- PurpleDebugLevel level;
-
- if(!win || !win->window)
- return;
-
- /* If the debug window is paused, we just return since it's in the store.
- * We don't call regex_match because it doesn't make sense to check the
- * string if it's paused. When we unpause we clear the imhtml and
- * reiterate over the store to handle matches that were outputted when
- * we were paused.
- */
- if(win->paused)
- return;
-
- gtk_tree_model_get(model, iter, 0, &text, 1, &level, -1);
-
- if (level >= purple_prefs_get_int(PIDGIN_PREFS_ROOT "/debug/filterlevel")) {
- if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter))) {
- regex_match(win, text);
- } else {
- gtk_imhtml_append_text(GTK_IMHTML(win->text), text, 0);
- }
- }
-
- g_free(text);
+ if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter)))
+ regex_toggle_filter(win, TRUE);
}
static gboolean
@@ -609,21 +471,46 @@ regex_timer_cb(DebugWindow *win) {
static void
regex_changed_cb(GtkWidget *w, DebugWindow *win) {
- if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter))) {
+ const gchar *text;
+
+ if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter))) {
gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(win->filter),
FALSE);
}
- if(win->timer == 0)
+ if (win->timer == 0)
win->timer = purple_timeout_add_seconds(5, (GSourceFunc)regex_timer_cb, win);
- regex_compile(win);
+ text = gtk_entry_get_text(GTK_ENTRY(win->expression));
+
+ if (text == NULL || *text == '\0') {
+ regex_clear_color(win->expression);
+ gtk_widget_set_sensitive(win->filter, FALSE);
+ return;
+ }
+
+ if (win->regex)
+ g_regex_unref(win->regex);
+ win->regex = g_regex_new(text, G_REGEX_CASELESS, 0, NULL);
+ if (win->regex == NULL) {
+ /* failed to compile */
+ regex_change_color(win->expression, 0xFFFF, 0xAFFF, 0xAFFF);
+ gtk_widget_set_sensitive(win->filter, FALSE);
+ } else {
+ /* compiled successfully */
+ regex_change_color(win->expression, 0xAFFF, 0xFFFF, 0xAFFF);
+ gtk_widget_set_sensitive(win->filter, TRUE);
+ }
}
static void
regex_key_release_cb(GtkWidget *w, GdkEventKey *e, DebugWindow *win) {
if(e->keyval == GDK_Return &&
+#if GTK_CHECK_VERSION(2,18,0)
+ gtk_widget_is_sensitive(win->filter) &&
+#else
GTK_WIDGET_IS_SENSITIVE(win->filter) &&
+#endif
!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter)))
{
gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(win->filter), TRUE);
@@ -651,35 +538,38 @@ regex_popup_cb(GtkEntry *entry, GtkWidget *menu, DebugWindow *win) {
}
static void
-regex_filter_toggled_cb(GtkToggleToolButton *button, DebugWindow *win) {
+regex_filter_toggled_cb(GtkToggleToolButton *button, DebugWindow *win)
+{
gboolean active;
active = gtk_toggle_tool_button_get_active(button);
purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/debug/filter", active);
- if(!GTK_IS_IMHTML(win->text))
+ if (!GTK_IS_WEBVIEW(win->text))
return;
- if(active)
- regex_filter_all(win);
- else
- regex_show_all(win);
+ regex_toggle_filter(win, active);
}
static void
filter_level_pref_changed(const char *name, PurplePrefType type, gconstpointer value, gpointer data)
{
DebugWindow *win = data;
+ WebKitDOMDocument *dom;
+ WebKitDOMHTMLElement *body;
+ int level = GPOINTER_TO_INT(value);
+ char *tmp;
- if (GPOINTER_TO_INT(value) != gtk_combo_box_get_active(GTK_COMBO_BOX(win->filterlevel)))
- gtk_combo_box_set_active(GTK_COMBO_BOX(win->filterlevel), GPOINTER_TO_INT(value));
- if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter)))
- regex_filter_all(win);
- else
- regex_show_all(win);
+ if (level != gtk_combo_box_get_active(GTK_COMBO_BOX(win->filterlevel)))
+ gtk_combo_box_set_active(GTK_COMBO_BOX(win->filterlevel), level);
+
+ dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(win->text));
+ body = webkit_dom_document_get_body(dom);
+ tmp = g_strdup_printf("l%d", level);
+ webkit_dom_html_element_set_class_name(body, tmp);
+ g_free(tmp);
}
-#endif /* USE_REGEX */
static void
filter_level_changed_cb(GtkWidget *combo, gpointer null)
@@ -765,20 +655,6 @@ debug_window_new(void)
handle = pidgin_debug_get_handle();
-#ifdef USE_REGEX
- /* the list store for all the messages */
- win->store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
-
- /* row-changed gets called when we do gtk_list_store_set, and row-inserted
- * gets called with gtk_list_store_append, which is a
- * completely empty row. So we just ignore row-inserted, and deal with row
- * changed. -Gary
- */
- g_signal_connect(G_OBJECT(win->store), "row-changed",
- G_CALLBACK(regex_row_changed_cb), win);
-
-#endif /* USE_REGEX */
-
/* Setup the vbox */
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(win->window), vbox);
@@ -804,19 +680,6 @@ debug_window_new(void)
gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
-#ifndef USE_REGEX
- /* Find button */
- item = gtk_tool_button_new_from_stock(GTK_STOCK_FIND);
- gtk_tool_item_set_is_important(item, TRUE);
-#if GTK_CHECK_VERSION(2,12,0)
- gtk_tool_item_set_tooltip_text(item, _("Find"));
-#else
- gtk_tool_item_set_tooltip(item, tooltips, _("Find"), NULL);
-#endif
- g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(find_cb), win);
- gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(item));
-#endif /* USE_REGEX */
-
/* Save */
item = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE);
gtk_tool_item_set_is_important(item, TRUE);
@@ -853,7 +716,6 @@ debug_window_new(void)
g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(pause_cb), win);
gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(item));
-#ifdef USE_REGEX
/* regex stuff */
item = gtk_separator_tool_item_new();
gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(item));
@@ -916,8 +778,6 @@ debug_window_new(void)
purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/debug/highlight",
regex_pref_highlight_cb, win);
-#endif /* USE_REGEX */
-
item = gtk_separator_tool_item_new();
gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(item));
@@ -943,28 +803,21 @@ debug_window_new(void)
gtk_combo_box_append_text(GTK_COMBO_BOX(win->filterlevel), _("Fatal Error"));
gtk_combo_box_set_active(GTK_COMBO_BOX(win->filterlevel),
purple_prefs_get_int(PIDGIN_PREFS_ROOT "/debug/filterlevel"));
-#ifdef USE_REGEX
+
purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/debug/filterlevel",
filter_level_pref_changed, win);
-#endif
g_signal_connect(G_OBJECT(win->filterlevel), "changed",
G_CALLBACK(filter_level_changed_cb), NULL);
}
- /* Add the gtkimhtml */
- frame = pidgin_create_imhtml(FALSE, &win->text, NULL, NULL);
- gtk_imhtml_set_format_functions(GTK_IMHTML(win->text),
- GTK_IMHTML_ALL ^ GTK_IMHTML_SMILEY ^ GTK_IMHTML_IMAGE);
+ /* Add the gtkwebview */
+ frame = pidgin_create_webview(FALSE, &win->text, NULL, NULL);
+ gtk_webview_set_format_functions(GTK_WEBVIEW(win->text),
+ GTK_WEBVIEW_ALL ^ GTK_WEBVIEW_SMILEY ^ GTK_WEBVIEW_IMAGE);
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
gtk_widget_show(frame);
-#ifdef USE_REGEX
- /* add the tag for regex highlighting */
- gtk_text_buffer_create_tag(GTK_IMHTML(win->text)->text_buffer, "regex",
- "background", "#FFAFAF",
- "weight", "bold",
- NULL);
-#endif /* USE_REGEX */
+ gtk_webview_load_html_string(GTK_WEBVIEW(win->text), EMPTY_HTML);
gtk_widget_show_all(win->window);
@@ -1065,13 +918,11 @@ pidgin_debug_init(void)
purple_prefs_add_int(PIDGIN_PREFS_ROOT "/debug/width", 450);
purple_prefs_add_int(PIDGIN_PREFS_ROOT "/debug/height", 250);
-#ifdef USE_REGEX
purple_prefs_add_string(PIDGIN_PREFS_ROOT "/debug/regex", "");
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/debug/filter", FALSE);
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/debug/invert", FALSE);
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/debug/case_insensitive", FALSE);
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/debug/highlight", FALSE);
-#endif /* USE_REGEX */
purple_prefs_connect_callback(NULL, PIDGIN_PREFS_ROOT "/debug/enabled",
debug_enabled_cb, NULL);
@@ -1133,9 +984,6 @@ static void
pidgin_debug_print(PurpleDebugLevel level, const char *category,
const char *arg_s)
{
-#ifdef USE_REGEX
- GtkTreeIter iter;
-#endif /* USE_REGEX */
gchar *ts_s;
gchar *esc_s, *cat_s, *tmp, *s;
const char *mdate;
@@ -1155,34 +1003,32 @@ pidgin_debug_print(PurpleDebugLevel level, const char *category,
else
cat_s = g_strdup_printf("<b>%s:</b> ", category);
- esc_s = g_markup_escape_text(arg_s, -1);
+ tmp = purple_utf8_try_convert(arg_s);
+ esc_s = g_markup_escape_text(tmp, -1);
- s = g_strdup_printf("<font color=\"%s\">%s%s%s</font>",
- debug_fg_colors[level], ts_s, cat_s, esc_s);
+ s = g_strdup_printf("<div class=\"l%d\">%s%s%s</div>",
+ level, ts_s, cat_s, esc_s);
g_free(ts_s);
g_free(cat_s);
g_free(esc_s);
+ g_free(tmp);
- tmp = purple_utf8_try_convert(s);
- g_free(s);
- s = tmp;
-
- if (level == PURPLE_DEBUG_FATAL) {
- tmp = g_strdup_printf("<b>%s</b>", s);
- g_free(s);
- s = tmp;
+ gtk_webview_append_html(GTK_WEBVIEW(debug_win->text), s);
+
+ if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(debug_win->filter))) {
+ WebKitDOMDocument *dom = NULL;
+ WebKitDOMHTMLElement *body = NULL;
+ WebKitDOMNode *div = NULL;
+ dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(debug_win->text));
+ if (dom)
+ body = webkit_dom_document_get_body(dom);
+ if (body)
+ div = webkit_dom_node_get_last_child(WEBKIT_DOM_NODE(body));
+ if (div)
+ regex_match(debug_win, dom, div);
}
-#ifdef USE_REGEX
- /* add the text to the list store */
- gtk_list_store_append(debug_win->store, &iter);
- gtk_list_store_set(debug_win->store, &iter, 0, s, 1, level, -1);
-#else /* USE_REGEX */
- if(!debug_win->paused && level >= purple_prefs_get_int(PIDGIN_PREFS_ROOT "/debug/filterlevel"))
- gtk_imhtml_append_text(GTK_IMHTML(debug_win->text), s, 0);
-#endif /* !USE_REGEX */
-
g_free(s);
}
@@ -1215,3 +1061,4 @@ pidgin_debug_get_handle() {
return &handle;
}
+
diff --git a/pidgin/gtkdebug.h b/pidgin/gtkdebug.h
index 75f0a8535e..853bec56d6 100644
--- a/pidgin/gtkdebug.h
+++ b/pidgin/gtkdebug.h
@@ -28,6 +28,8 @@
#include "debug.h"
+G_BEGIN_DECLS
+
/**
* Initializes the GTK+ debug system.
*/
@@ -62,4 +64,6 @@ void pidgin_debug_window_hide(void);
*/
PurpleDebugUiOps *pidgin_debug_get_ui_ops(void);
+G_END_DECLS
+
#endif /* _PIDGINDEBUG_H_ */
diff --git a/pidgin/gtkdialogs.c b/pidgin/gtkdialogs.c
index 5395fd8986..8d279f7fc5 100644
--- a/pidgin/gtkdialogs.c
+++ b/pidgin/gtkdialogs.c
@@ -39,10 +39,9 @@
#include "gtkblist.h"
#include "gtkdialogs.h"
-#include "gtkimhtml.h"
-#include "gtkimhtmltoolbar.h"
#include "gtklog.h"
#include "gtkutils.h"
+#include "gtkwebview.h"
#include "pidginstock.h"
static GList *dialogwindows = NULL;
@@ -79,8 +78,6 @@ static const struct developer developers[] = {
{"Hylke Bons", N_("artist"), "hylkebons@gmail.com"},
{"Sadrul Habib Chowdhury", NULL, NULL},
{"Mark 'KingAnt' Doliner", NULL, "mark@kingant.net"},
- {"Casey Harkins", NULL, NULL},
- {"Ivan Komarov", NULL, "ivan.komarov@pidgin.im"},
{"Gary 'grim' Kramlich", NULL, "grim@pidgin.im"},
{"Richard 'rlaager' Laager", NULL, "rlaager@pidgin.im"},
{"Marcus 'malu' Lundblad", NULL, NULL},
@@ -114,12 +111,14 @@ static const struct developer retired_developers[] = {
{"Herman Bloggs", N_("win32 port"), "herman@bluedigits.com"},
{"Thomas Butter", NULL, NULL},
/* feel free to not translate this */
- {N_("Ka-Hing Cheung"), NULL, NULL},
+ {N_("Ka-Hing Cheung"), NULL, NULL},
{"Jim Duchek", N_("maintainer"), "jim@linuxpimps.com"},
{"Sean Egan", NULL, "sean.egan@gmail.com"},
{"Rob Flynn", N_("maintainer"), NULL},
{"Adam Fritzler", N_("libfaim maintainer"), NULL},
{"Christian 'ChipX86' Hammond", N_("webmaster"), NULL},
+ {"Casey Harkins", NULL, NULL},
+ {"Ivan Komarov", NULL, "ivan.komarov@pidgin.im"},
/* If "lazy bum" translates literally into a serious insult, use something else or omit it. */
{"Syd Logan", N_("hacker and designated driver [lazy bum]"), NULL},
{"Christopher 'siege' O'Brien", NULL, "taliesein@users.sf.net"},
@@ -144,33 +143,34 @@ static const struct developer retired_patch_writers[] = {
{NULL, NULL, NULL}
};
-/* Order: Code, then Alphabetical by Last Name */
+/* Order: Code, then Alphabetical by Last Name
+ Use NULL language and code for secondary translators. */
static const struct translator translators[] = {
{N_("Afrikaans"), "af", "Samuel Murray", "afrikaans@gmail.com"},
- {N_("Afrikaans"), "af", "Friedel Wolff", "friedel@translate.org.za"},
+ {NULL, NULL, "Friedel Wolff", "friedel@translate.org.za"},
{N_("Arabic"), "ar", "Khaled Hosny", "khaledhosny@eglug.org"},
{N_("Assamese"), "as", "Amitakhya Phukan", "aphukan@fedoraproject.org"},
{N_("Belarusian Latin"), "be@latin", "Ihar Hrachyshka", "ihar.hrachyshka@gmail.com"},
{N_("Bulgarian"), "bg", "Vladimira Girginova", "missing@here.is"},
- {N_("Bulgarian"), "bg", "Vladimir (Kaladan) Petkov", "vpetkov@i-space.org"},
+ {NULL, NULL, "Vladimir (Kaladan) Petkov", "kaladan@gmail.com"},
{N_("Bengali"), "bn", "Jamil Ahmed", "jamil@bengalinux.org"},
- {N_("Bengali"), "bn", "Israt Jahan", "israt@ankur.org.bd"},
- {N_("Bengali"), "bn", "Samia Nimatullah", "mailsamia2001@yahoo.com"},
+ {NULL, NULL, "Israt Jahan", "israt@ankur.org.bd"},
+ {NULL, NULL, "Samia Nimatullah", "mailsamia2001@yahoo.com"},
{N_("Bengali-India"), "bn_IN", "Runa Bhattacharjee", "runab@fedoraproject.org"},
{N_("Bosnian"), "bs", "Lejla Hadzialic", "lejlah@gmail.com"},
{N_("Catalan"), "ca", "Josep Puigdemont", "josep.puigdemont@gmail.com"},
{N_("Valencian-Catalan"), "ca@valencia", "Toni Hermoso", "toniher@softcatala.org"},
- {N_("Valencian-Catalan"), "ca@valencia", "Josep Puigdemont", "tradgnome@softcatala.org"},
+ {NULL, NULL, "Josep Puigdemont", "tradgnome@softcatala.org"},
{N_("Czech"), "cs", "David Vachulka", "david@konstrukce-cad.com"},
{N_("Danish"), "da", "Peter Bach", "bach.peter@gmail.com"},
- {N_("Danish"), "da", "Morten Brix Pedersen", "morten@wtf.dk"},
- {N_("German"), "de", "Jochen Kemnade", "jochenkemnade@web.de"},
+ {NULL, NULL, "Morten Brix Pedersen", "morten@wtf.dk"},
{N_("German"), "de", "Björn Voigt", "bjoern@cs.tu-berlin.de"},
+ {NULL, NULL, "Jochen Kemnade", "jochenkemnade@web.de"},
{N_("Dzongkha"), "dz", "Norbu", "nor_den@hotmail.com"},
- {N_("Dzongkha"), "dz", "Jurmey Rabgay", "jur_gay@yahoo.com"},
- {N_("Dzongkha"), "dz", "Wangmo Sherpa", "rinwanshe@yahoo.com"},
+ {NULL, NULL, "Jurmey Rabgay", "jur_gay@yahoo.com"},
+ {NULL, NULL, "Wangmo Sherpa", "rinwanshe@yahoo.com"},
{N_("Greek"), "el", "Katsaloulis Panayotis", "panayotis@panayotis.com"},
- {N_("Greek"), "el", "Bouklis Panos", "panos@echidna-band.com"},
+ {NULL, NULL, "Bouklis Panos", "panos@echidna-band.com"},
{N_("Australian English"), "en_AU", "Peter Lawler", "trans@six-by-nine.com.au"},
{N_("British English"), "en_GB", "Phil Hannent", "phil@hannent.co.uk"},
{N_("Canadian English"), "en_CA", "Adam Weinberger", "adamw@gnome.org"},
@@ -179,18 +179,18 @@ static const struct translator translators[] = {
{N_("Estonian"), "et", "Ivar Smolin", "okul@linux.ee"},
{N_("Basque"), "eu", "Mikel Pascual Aldabaldetreku", "mikel.paskual@gmail.com"},
{N_("Persian"), "fa", "Elnaz Sarbar", "elnaz@farsiweb.info"},
- {N_("Persian"), "fa", "Roozbeh Pournader", "roozbeh@farsiweb.info"},
- {N_("Persian"), "fa", "Meelad Zakaria", "meelad@farsiweb.info"},
+ {NULL, NULL, "Roozbeh Pournader", "roozbeh@farsiweb.info"},
+ {NULL, NULL, "Meelad Zakaria", "meelad@farsiweb.info"},
{N_("Finnish"), "fi", "Timo Jyrinki", "timo.jyrinki@iki.fi"},
{N_("French"), "fr", "Éric Boumaour", "zongo_fr@users.sourceforge.net"},
{N_("Irish"), "ga", "Aaron Kearns", "ajkearns6@gmail.com"},
{N_("Galician"), "gl", "Mar Castro", "mariamarcp@gmail.com"},
- {N_("Galician"), "gl", "Frco. Javier Rial", "fjrial@cesga.es"},
+ {NULL, NULL, "Frco. Javier Rial", "fjrial@cesga.es"},
{N_("Gujarati"), "gu", "Ankit Patel", "ankit_patel@users.sf.net"},
- {N_("Gujarati"), "gu", N_("Gujarati Language Team"), "indianoss-gujarati@lists.sourceforge.net"},
+ {NULL, NULL, N_("Gujarati Language Team"), "indianoss-gujarati@lists.sourceforge.net"},
{N_("Hebrew"), "he", "Shalom Craimer", "scraimer@gmail.com"},
{N_("Hindi"), "hi", "Sangeeta Kumari", "sangeeta_0975@yahoo.com"},
- {N_("Hindi"), "hi", "Rajesh Ranjan", "rajeshkajha@yahoo.com"},
+ {NULL, NULL, "Rajesh Ranjan", "rajeshkajha@yahoo.com"},
{N_("Croatian"), "hr", "Sabina Drempetić", "bina91991@googlemail.com"},
{N_("Hungarian"), "hu", "Kelemen Gábor", "kelemeng@gnome.hu"},
{N_("Armenian"), "hy", "David Avsharyan", "avsharyan@gmail.com"},
@@ -202,15 +202,15 @@ static const struct translator translators[] = {
{N_("Kannada"), "kn", N_("Kannada Translation team"), "translation@sampada.info"},
{N_("Korean"), "ko", "Sushizang", "sushizang@empal.com"},
{N_("Kurdish"), "ku", "Amed Ç. Jiyan", "amedcj@hotmail.com"},
- {N_("Kurdish"), "ku", "Erdal Ronahi", "erdal.ronahi@gmail.com"},
- {N_("Kurdish"), "ku", "Rizoyê Xerzî", "rizoxerzi@hotmail.com"},
+ {NULL, NULL, "Erdal Ronahi", "erdal.ronahi@gmail.com"},
+ {NULL, NULL, "Rizoyê Xerzî", "rizoxerzi@hotmail.com"},
{N_("Lao"), "lo", "Anousak Souphavah", "anousak@gmail.com"},
{N_("Maithili"), "mai", "Sangeeta Kumari", "sangeeta_0975@yahoo.com"},
- {N_("Maithili"), "mai", "Rajesh Ranjan", "rajeshkajha@yahoo.com"},
+ {NULL, NULL, "Rajesh Ranjan", "rajeshkajha@yahoo.com"},
{N_("Meadow Mari"), "mhr", "David Preece", "davidpreece1@gmail.com"},
{N_("Macedonian"), "mk", "Arangel Angov ", "arangel@linux.net.mk"},
- {N_("Macedonian"), "mk", "Ivana Kirkovska", "ivana.kirkovska@gmail.com"},
- {N_("Macedonian"), "mk", "Jovan Naumovski", "jovan@lugola.net"},
+ {NULL, NULL, "Ivana Kirkovska", "ivana.kirkovska@gmail.com"},
+ {NULL, NULL, "Jovan Naumovski", "jovan@lugola.net"},
{N_("Malayalam"), "ml", "Ani Peter", "apeter@redhat.com"},
{N_("Mongolian"), "mn", "gooyo", NULL},
{N_("Marathi"), "mr", "Sandeep Shedmake", "sandeep.shedmake@gmail.com"},
@@ -224,25 +224,24 @@ static const struct translator translators[] = {
{N_("Oriya"), "or", "Manoj Kumar Giri", "giri.manojkr@gmail.com"},
{N_("Punjabi"), "pa", "Amanpreet Singh Alam", "aalam@users.sf.net"},
{N_("Polish"), "pl", "Piotr Drąg", "piotrdrag@gmail.com"},
- {N_("Polish"), "pl", "Piotr Makowski", "pmakowski@aviary.pl"},
{N_("Portuguese"), "pt", "Duarte Henriques", "duarte_henriques@myrealbox.com"},
{N_("Portuguese-Brazil"), "pt_BR", "Rodrigo Luiz Marques Flores", "rodrigomarquesflores@gmail.com"},
{N_("Pashto"), "ps", "Kashif Masood", "masudmails@yahoo.com"},
{N_("Romanian"), "ro", "Mișu Moldovan", "dumol@gnome.org"},
- {N_("Romanian"), "ro", "Andrei Popescu", "andreimpopescu@gmail.com"},
+ {NULL, NULL, "Andrei Popescu", "andreimpopescu@gmail.com"},
{N_("Russian"), "ru", "Антон Самохвалов", "samant.ua@mail.ru"},
{N_("Slovak"), "sk", "Jozef Káčer", "quickparser@gmail.com"},
- {N_("Slovak"), "sk", "loptosko", "loptosko@gmail.com"},
+ {NULL, NULL, "loptosko", "loptosko@gmail.com"},
{N_("Slovenian"), "sl", "Martin Srebotnjak", "miles@filmsi.net"},
{N_("Albanian"), "sq", "Besnik Bleta", "besnik@programeshqip.org"},
{N_("Serbian"), "sr", "Miloš Popović", "gpopac@gmail.com"},
- {N_("Serbian"), "sr@Latn", "Miloš Popović", "gpopac@gmail.com"},
+ {N_("Serbian Latin"), "sr@latin", "Miloš Popović", "gpopac@gmail.com"},
{N_("Sinhala"), "si", "Yajith Ajantha Dayarathna", "yajith@gmail.com"},
- {N_("Sinhala"), "si", "Danishka Navin", "snavin@redhat.com"},
+ {NULL, NULL, "Danishka Navin", "snavin@redhat.com"},
{N_("Swedish"), "sv", "Peter Hjalmarsson", "xake@telia.com"},
{N_("Swahili"), "sw", "Paul Msegeya", "msegeya@gmail.com"},
{N_("Tamil"), "ta", "I. Felix", "ifelix25@gmail.com"},
- {N_("Tamil"), "ta", "Viveka Nathan K", "vivekanathan@users.sourceforge.net"},
+ {NULL, NULL, "Viveka Nathan K", "vivekanathan@users.sourceforge.net"},
{N_("Telugu"), "te", "Krishnababu Krottapalli", "krottapalli@ymail.com"},
{N_("Thai"), "th", "Isriya Paireepairit", "markpeak@gmail.com"},
{N_("Turkish"), "tr", "Serdar Soytetir", "tulliana@gmail.com"},
@@ -251,10 +250,10 @@ static const struct translator translators[] = {
{N_("Vietnamese"), "vi", "Nguyễn Vũ Hưng", "vuhung16plus@gmail.com"},
{N_("Simplified Chinese"), "zh_CN", "Aron Xu", "happyaron.xu@gmail.com"},
{N_("Hong Kong Chinese"), "zh_HK", "Abel Cheung", "abelindsay@gmail.com"},
- {N_("Hong Kong Chinese"), "zh_HK", "Ambrose C. Li", "acli@ada.dhs.org"},
- {N_("Hong Kong Chinese"), "zh_HK", "Paladin R. Liu", "paladin@ms1.hinet.net"},
+ {NULL, NULL, "Ambrose C. Li", "acli@ada.dhs.org"},
+ {NULL, NULL, "Paladin R. Liu", "paladin@ms1.hinet.net"},
{N_("Traditional Chinese"), "zh_TW", "Ambrose C. Li", "acli@ada.dhs.org"},
- {N_("Traditional Chinese"), "zh_TW", "Paladin R. Liu", "paladin@ms1.hinet.net"},
+ {NULL, NULL, "Paladin R. Liu", "paladin@ms1.hinet.net"},
{NULL, NULL, NULL, NULL}
};
@@ -264,67 +263,72 @@ static const struct translator past_translators[] = {
{N_("Arabic"), "ar", "Mohamed Magdy", "alnokta@yahoo.com"},
{N_("Bulgarian"), "bg", "Hristo Todorov", NULL},
{N_("Bengali"), "bn", "Indranil Das Gupta", "indradg@l2c2.org"},
- {N_("Bengali"), "bn", "Tisa Nafisa", "tisa_nafisa@yahoo.com"},
+ {NULL, NULL, "Tisa Nafisa", "tisa_nafisa@yahoo.com"},
{N_("Catalan"), "ca", "JM Pérez Cáncer", NULL},
- {N_("Catalan"), "ca", "Robert Millan", NULL},
+ {NULL, NULL, "Robert Millan", NULL},
{N_("Czech"), "cs", "Honza Král", NULL},
- {N_("Czech"), "cs", "Miloslav Trmac", "mitr@volny.cz"},
- {N_("German"), "de", "Daniel Seifert, Karsten Weiss", NULL},
+ {NULL, NULL, "Miloslav Trmac", "mitr@volny.cz"},
+ {N_("German"), "de", "Daniel Seifert", NULL},
+ {NULL, NULL, "Karsten Weiss", NULL},
{N_("British English"), "en_GB", "Luke Ross", "luke@lukeross.name"},
{N_("Spanish"), "es", "JM Pérez Cáncer", NULL},
- {N_("Spanish"), "es", "Nicolás Lichtmaier", NULL},
- {N_("Spanish"), "es", "Amaya Rodrigo", NULL},
- {N_("Spanish"), "es", "Alejandro G Villar", NULL},
+ {NULL, NULL, "Nicolás Lichtmaier", NULL},
+ {NULL, NULL, "Amaya Rodrigo", NULL},
+ {NULL, NULL, "Alejandro G Villar", NULL},
{N_("Basque"), "eu", "Iñaki Larrañaga Murgoitio", "dooteo@zundan.com"},
- {N_("Basque"), "eu", "Hizkuntza Politikarako Sailburuordetza", "hizkpol@ej-gv.es"},
+ {NULL, NULL, "Hizkuntza Politikarako Sailburuordetza", "hizkpol@ej-gv.es"},
{N_("Finnish"), "fi", "Arto Alakulju", NULL},
- {N_("Finnish"), "fi", "Tero Kuusela", NULL},
+ {NULL, NULL, "Tero Kuusela", NULL},
{N_("French"), "fr", "Sébastien François", NULL},
- {N_("French"), "fr", "Loïc Jeannin", NULL},
- {N_("French"), "fr", "Stéphane Pontier", NULL},
- {N_("French"), "fr", "Stéphane Wirtel", NULL},
+ {NULL, NULL, "Loïc Jeannin", NULL},
+ {NULL, NULL, "Stéphane Pontier", NULL},
+ {NULL, NULL, "Stéphane Wirtel", NULL},
{N_("Galician"), "gl", "Ignacio Casal Quinteiro", NULL},
{N_("Hebrew"), "he", "Pavel Bibergal", NULL},
{N_("Hindi"), "hi", "Ravishankar Shrivastava", NULL},
{N_("Hungarian"), "hu", "Zoltan Sutto", NULL},
{N_("Italian"), "it", "Salvatore di Maggio", NULL},
{N_("Japanese"), "ja", "Takashi Aihana", NULL},
- {N_("Japanese"), "ja", "Ryosuke Kutsuna", NULL},
- {N_("Japanese"), "ja", "Junichi Uekawa", NULL},
- {N_("Japanese"), "ja", "Taku Yasui", NULL},
+ {NULL, NULL, "Ryosuke Kutsuna", NULL},
+ {NULL, NULL, "Junichi Uekawa", NULL},
+ {NULL, NULL, "Taku Yasui", NULL},
{N_("Georgian"), "ka", "Temuri Doghonadze", NULL},
- {N_("Korean"), "ko", "Sang-hyun S, A Ho-seok Lee", NULL},
- {N_("Korean"), "ko", "Kyeong-uk Son", NULL},
+ {N_("Korean"), "ko", "Sang-hyun S", NULL},
+ {NULL, NULL, "A Ho-seok Lee", NULL},
+ {NULL, NULL, "Kyeong-uk Son", NULL},
{N_("Lithuanian"), "lt", "Laurynas Biveinis", "laurynas.biveinis@gmail.com"},
- {N_("Lithuanian"), "lt", "Gediminas Čičinskas", NULL},
- {N_("Lithuanian"), "lt", "Andrius Štikonas", NULL},
+ {NULL, NULL, "Gediminas Čičinskas", NULL},
+ {NULL, NULL, "Andrius Štikonas", NULL},
{N_("Macedonian"), "mk", "Tomislav Markovski", NULL},
{N_("Bokmål Norwegian"), "nb", "Hallvard Glad", "hallvard.glad@gmail.com"},
- {N_("Bokmål Norwegian"), "nb", "Petter Johan Olsen", NULL},
- {N_("Bokmål Norwegian"), "nb", "Espen Stefansen", "espenas@gmail.com"},
+ {NULL, NULL, "Petter Johan Olsen", NULL},
+ {NULL, NULL, "Espen Stefansen", "espenas@gmail.com"},
{N_("Dutch, Flemish"), "nl", "Vincent van Adrighem", "V.vanAdrighem@dirck.mine.nu"},
{N_("Polish"), "pl", "Krzysztof Foltman", "krzysztof@foltman.com"},
- {N_("Polish"), "pl", "Paweł Godlewski", "pawel@bajk.pl"},
- {N_("Polish"), "pl", "Emil Nowak", "emil5@go2.pl"},
- {N_("Polish"), "pl", "Przemysław Sułek", NULL},
+ {NULL, NULL, "Paweł Godlewski", "pawel@bajk.pl"},
+ {NULL, NULL, "Piotr Makowski", NULL},
+ {NULL, NULL, "Emil Nowak", "emil5@go2.pl"},
+ {NULL, NULL, "Przemysław Sułek", NULL},
{N_("Portuguese-Brazil"), "pt_BR", "Maurício de Lemos Rodrigues Collares Neto", "mauricioc@gmail.com"},
{N_("Russian"), "ru", "Dmitry Beloglazov", "dmaa@users.sf.net"},
- {N_("Russian"), "ru", "Alexandre Prokoudine", NULL},
- {N_("Russian"), "ru", "Sergey Volozhanin", NULL},
+ {NULL, NULL, "Alexandre Prokoudine", NULL},
+ {NULL, NULL, "Sergey Volozhanin", NULL},
{N_("Slovak"), "sk", "Daniel Režný", NULL},
- {N_("Slovak"), "sk", "Richard Golier", NULL},
- {N_("Slovak"), "sk", "helix84", NULL},
+ {NULL, NULL, "Richard Golier", NULL},
+ {NULL, NULL, "helix84", NULL},
{N_("Slovenian"), "sl", "Matjaz Horvat", NULL},
{N_("Serbian"), "sr", "Danilo Šegan", "dsegan@gmx.net"},
- {N_("Serbian"), "sr", "Aleksandar Urosevic", "urke@users.sourceforge.net"},
+ {NULL, NULL, "Aleksandar Urosevic", "urke@users.sourceforge.net"},
{N_("Swedish"), "sv", "Tore Lundqvist", NULL},
- {N_("Swedish"), "sv", "Christian Rose", NULL},
+ {NULL, NULL, "Christian Rose", NULL},
{N_("Telugu"), "te", "Mr. Subbaramaih", "info.gist@cdac.in"},
{N_("Turkish"), "tr", "Ahmet Alp Balkan", NULL},
{N_("Vietnamese"), "vi", N_("T.M.Thanh and the Gnome-Vi Team"), "gnomevi-list@lists.sf.net"},
- {N_("Simplified Chinese"), "zh_CN", "Hashao, Rocky S. Lee", NULL},
- {N_("Simplified Chinese"), "zh_CN", "Funda Wang", "fundawang@linux.net.cn"},
- {N_("Traditional Chinese"), "zh_TW", "Hashao, Rocky S. Lee", NULL},
+ {N_("Simplified Chinese"), "zh_CN", "Hashao", NULL},
+ {NULL, NULL, "Rocky S. Lee", NULL},
+ {NULL, NULL, "Funda Wang", "fundawang@linux.net.cn"},
+ {N_("Traditional Chinese"), "zh_TW", "Hashao", NULL},
+ {NULL, NULL, "Rocky S. Lee", NULL},
{NULL, NULL, NULL, NULL}
};
@@ -333,13 +337,14 @@ add_developers(GString *str, const struct developer *list)
{
for (; list->name != NULL; list++) {
if (list->email != NULL) {
- g_string_append_printf(str, " <a href=\"mailto:%s\">%s</a>%s%s%s<br/>",
- list->email, _(list->name),
+ g_string_append_printf(str,
+ "<li><a href=\"mailto:%s\" title=\"%s\">%s</a>%s%s%s</li>",
+ list->email, list->email, _(list->name),
list->role ? " (" : "",
list->role ? _(list->role) : "",
list->role ? ")" : "");
} else {
- g_string_append_printf(str, " %s%s%s%s<br/>",
+ g_string_append_printf(str, "<li>%s%s%s%s</li>",
_(list->name),
list->role ? " (" : "",
list->role ? _(list->role) : "",
@@ -351,18 +356,18 @@ add_developers(GString *str, const struct developer *list)
static void
add_translators(GString *str, const struct translator *list)
{
- for (; list->language != NULL; list++) {
+ for (; list->name != NULL; list++) {
+ if (list->language && list->abbr) {
+ g_string_append_printf(str, "<dt>%s (%s)</dt>",
+ _(list->language), list->abbr);
+ }
if (list->email != NULL) {
- g_string_append_printf(str, " <b>%s (%s)</b> - <a href=\"mailto:%s\">%s</a><br/>",
- _(list->language),
- list->abbr,
- list->email,
+ g_string_append_printf(str,
+ "<dd><a href=\"mailto:%s\" title=\"%s\">%s</a></dd>",
+ list->email, list->email,
_(list->name));
} else {
- g_string_append_printf(str, " <b>%s (%s)</b> - %s<br/>",
- _(list->language),
- list->abbr,
- _(list->name));
+ g_string_append_printf(str, "<dd>%s</dd>", _(list->name));
}
}
}
@@ -425,9 +430,8 @@ pidgin_logo_versionize(GdkPixbuf **original, GtkWidget *widget) {
static GtkWidget *
pidgin_build_help_dialog(const char *title, const char *role, GString *string)
{
- GtkWidget *win, *vbox, *frame, *logo, *imhtml, *button;
+ GtkWidget *win, *vbox, *frame, *logo, *webview, *button;
GdkPixbuf *pixbuf;
- GtkTextIter iter;
AtkObject *obj;
char *filename, *tmp;
@@ -454,18 +458,20 @@ pidgin_build_help_dialog(const char *title, const char *role, GString *string)
g_free(tmp);
gtk_box_pack_start(GTK_BOX(vbox), logo, FALSE, FALSE, 0);
- frame = pidgin_create_imhtml(FALSE, &imhtml, NULL, NULL);
- gtk_imhtml_set_format_functions(GTK_IMHTML(imhtml), GTK_IMHTML_ALL ^ GTK_IMHTML_SMILEY);
+ frame = pidgin_create_webview(FALSE, &webview, NULL, NULL);
+ gtk_webview_set_format_functions(GTK_WEBVIEW(webview), GTK_WEBVIEW_ALL ^ GTK_WEBVIEW_SMILEY);
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
- gtk_imhtml_append_text(GTK_IMHTML(imhtml), string->str, GTK_IMHTML_NO_SCROLL);
- gtk_text_buffer_get_start_iter(gtk_text_view_get_buffer(GTK_TEXT_VIEW(imhtml)), &iter);
- gtk_text_buffer_place_cursor(gtk_text_view_get_buffer(GTK_TEXT_VIEW(imhtml)), &iter);
+ gtk_webview_append_html(GTK_WEBVIEW(webview), string->str);
button = pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_CLOSE,
G_CALLBACK(destroy_win), win);
+#if GTK_CHECK_VERSION(2,18,0)
+ gtk_widget_set_can_default(button, TRUE);
+#else
GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
+#endif
gtk_widget_grab_default(button);
gtk_widget_show_all(win);
@@ -490,37 +496,45 @@ void pidgin_dialogs_about(void)
str = g_string_sized_new(4096);
g_string_append_printf(str,
- "<CENTER><FONT SIZE=\"4\"><B>%s %s</B></FONT></CENTER> (libpurple %s)"
- "<BR>%s<BR><BR>", PIDGIN_NAME, DISPLAY_VERSION,
+ "<h2>%s %s</h2>"
+ "<strong>(libpurple %s)<br/>%s</strong>",
+ PIDGIN_NAME, DISPLAY_VERSION,
purple_core_get_version(), REVISION);
g_string_append_printf(str,
- _("%s is a messaging client based on libpurple which is capable of "
+ _("<p>%s is a messaging client based on libpurple which is capable of "
"connecting to multiple messaging services at once. %s is written "
"in C using GTK+. %s is released, and may be modified and "
"redistributed, under the terms of the GPL version 2 (or later). "
"A copy of the GPL is distributed with %s. %s is copyrighted by "
"its contributors, a list of whom is also distributed with %s. "
- "There is no warranty for %s.<BR><BR>"), PIDGIN_NAME, PIDGIN_NAME,
+ "There is no warranty for %s.</p>"), PIDGIN_NAME, PIDGIN_NAME,
PIDGIN_NAME, PIDGIN_NAME, PIDGIN_NAME, PIDGIN_NAME, PIDGIN_NAME);
g_string_append_printf(str,
- _("<FONT SIZE=\"4\"><B>Helpful Resources</B></FONT><BR>\t<A "
- "HREF=\"%s\">Website</A><BR>\t<A HREF=\"%s\">Frequently Asked "
- "Questions</A><BR>\tIRC Channel: #pidgin on irc.freenode.net<BR>"
- "\tXMPP MUC: devel@conference.pidgin.im<BR><BR>"), PURPLE_WEBSITE,
+ _("<h3>Helpful Resources</h3>"
+ "<ul>"
+ "<li><a href=\"%s\" title=\"%s\">Website</a></li>"
+ "<li><a href=\"%s\" title=\"%s\">Frequently Asked Questions</a></li>"
+ "<li>IRC Channel: #pidgin on irc.freenode.net</li>"
+ "<li>XMPP MUC: devel@conference.pidgin.im</li>"
+ "</ul>"),
+ PURPLE_WEBSITE, PURPLE_WEBSITE,
+ "http://developer.pidgin.im/wiki/FAQ",
"http://developer.pidgin.im/wiki/FAQ");
g_string_append_printf(str,
- _("<font size=\"4\"><b>Help from other Pidgin users</b></font> is "
- "available by e-mailing <a "
- "href=\"mailto:support@pidgin.im\">support@pidgin.im</a><br/>"
- "This is a <b>public</b> mailing list! "
- "(<a href=\"http://pidgin.im/pipermail/support/\">archive</a>)<br/>"
+ _("<p><strong>Help from other Pidgin users</strong> is available "
+ "by e-mailing <a href=\"mailto:%s\">%s</a>.<br/>"
+ "This is a <strong>public</strong> mailing list! "
+ "(<a href=\"%s\" title=\"%s\">archive</a>)<br/>"
"We can't help with third-party protocols or plugins!<br/>"
- "This list's primary language is <b>English</b>. You are "
- "welcome to post in another language, but the responses may "
- "be less helpful.<br/>"));
+ "This list's primary language is <strong>English</strong>. You "
+ "are welcome to post in another language, but the responses may "
+ "be less helpful.</p>"),
+ "support@pidgin.im", "support@pidgin.im",
+ "http://pidgin.im/pipermail/support/",
+ "http://pidgin.im/pipermail/support/");
tmp = g_strdup_printf(_("About %s"), PIDGIN_NAME);
about = pidgin_build_help_dialog(tmp, "about", str);
@@ -542,175 +556,179 @@ void pidgin_dialogs_buildinfo(void)
str = g_string_sized_new(4096);
g_string_append_printf(str,
- "<FONT SIZE=\"4\"><B>%s %s</B></FONT> (libpurple %s)<BR>%s<BR><BR>", PIDGIN_NAME, DISPLAY_VERSION, purple_core_get_version(), REVISION);
+ "<h2>%s %s</h2>"
+ "<strong>(libpurple %s)<br/>%s</strong>",
+ PIDGIN_NAME, DISPLAY_VERSION, purple_core_get_version(), REVISION);
- g_string_append_printf(str, "<FONT SIZE=\"4\"><B>%s</B></FONT><br/>", _("Build Information"));
+ g_string_append_printf(str, "<h3>%s</h3><dl>", _("Build Information"));
- /* The following primarly intented for user/developer interaction and thus
- ought not be translated */
+ /* The following is primarily intended for user/developer interaction and
+ thus ought not be translated */
#ifdef CONFIG_ARGS /* win32 build doesn't use configure */
- g_string_append(str, " <b>Arguments to <i>./configure</i>:</b> " CONFIG_ARGS "<br/>");
+ g_string_append(str, "<dt>Arguments to <em>./configure</em>:</dt><dd>" CONFIG_ARGS "</dd>");
#endif
#ifndef _WIN32
#ifdef DEBUG
- g_string_append(str, " <b>Print debugging messages:</b> Yes<br/>");
+ g_string_append(str, "<dt>Print debugging messages:</dt><dd>Yes</dd>");
#else
- g_string_append(str, " <b>Print debugging messages:</b> No<br/>");
+ g_string_append(str, "<dt>Print debugging messages:</dt><dd>No</dd>");
#endif
#endif
#ifdef PURPLE_PLUGINS
- g_string_append(str, " <b>Plugins:</b> Enabled<br/>");
+ g_string_append(str, "<dt>Plugins:</dt><dd>Enabled</dd>");
#else
- g_string_append(str, " <b>Plugins:</b> Disabled<br/>");
+ g_string_append(str, "<dt>Plugins:</dt><dd>Disabled</dd>");
#endif
#ifdef HAVE_SSL
- g_string_append(str, " <b>SSL:</b> SSL support is present.<br/>");
+ g_string_append(str, "<dt>SSL:</dt><dd>SSL support is present.</dd>");
#else
- g_string_append(str, " <b>SSL:</b> SSL support was <b><i>NOT</i></b> compiled!<br/>");
+ g_string_append(str, "<dt>SSL:</dt><dd>SSL support was <strong><em>NOT</em></strong> compiled!</dd>");
#endif
/* This might be useful elsewhere too, but it is particularly useful for
- * debugging stuff known to be GTK+/Glib bugs on Windows */
+ * debugging stuff known to be GTK+/GLib bugs on Windows */
#ifdef _WIN32
- g_string_append_printf(str, " <b>GTK+ Runtime:</b> %u.%u.%u<br/>"
- " <b>Glib Runtime:</b> %u.%u.%u<br/>",
+ g_string_append_printf(str, "<dt>GTK+ Runtime:</dt><dd>%u.%u.%u</dd>"
+ "<dt>GLib Runtime:</dt><dd>%u.%u.%u</dd>",
gtk_major_version, gtk_minor_version, gtk_micro_version,
glib_major_version, glib_minor_version, glib_micro_version);
#endif
-g_string_append(str, "<br/> <b>Library Support</b><br/>");
+ g_string_append(str, "</dl><h3>Library Support</h3><dl>");
#ifdef HAVE_CYRUS_SASL
- g_string_append_printf(str, " <b>Cyrus SASL:</b> Enabled<br/>");
+ g_string_append_printf(str, "<dt>Cyrus SASL:</dt><dd>Enabled</dd>");
#else
- g_string_append_printf(str, " <b>Cyrus SASL:</b> Disabled<br/>");
+ g_string_append_printf(str, "<dt>Cyrus SASL:</dt><dd>Disabled</dd>");
#endif
#ifndef _WIN32
#ifdef HAVE_DBUS
- g_string_append_printf(str, " <b>D-Bus:</b> Enabled<br/>");
+ g_string_append_printf(str, "<dt>D-Bus:</dt><dd>Enabled</dd>");
#else
- g_string_append_printf(str, " <b>D-Bus:</b> Disabled<br/>");
+ g_string_append_printf(str, "<dt>D-Bus:</dt><dd>Disabled</dd>");
#endif
#ifdef HAVE_EVOLUTION_ADDRESSBOOK
- g_string_append_printf(str, " <b>Evolution Addressbook:</b> Enabled<br/>");
+ g_string_append_printf(str, "<dt>Evolution Addressbook:</dt><dd>Enabled</dd>");
#else
- g_string_append_printf(str, " <b>Evolution Addressbook:</b> Disabled<br/>");
+ g_string_append_printf(str, "<dt>Evolution Addressbook:</dt><dd>Disabled</dd>");
#endif
#endif
#if defined(_WIN32) || defined(USE_INTERNAL_LIBGADU)
- g_string_append(str, " <b>Gadu-Gadu library (libgadu):</b> Internal<br/>");
+ g_string_append(str, "<dt>Gadu-Gadu library (libgadu):</dt><dd>Internal</dd>");
#else
#ifdef HAVE_LIBGADU
- g_string_append(str, " <b>Gadu-Gadu library (libgadu):</b> Enabled<br/>");
+ g_string_append(str, "<dt>Gadu-Gadu library (libgadu):</dt><dd>Enabled</dd>");
#else
- g_string_append(str, " <b>Gadu-Gadu library (libgadu):</b> Disabled<br/>");
+ g_string_append(str, "<dt>Gadu-Gadu library (libgadu):</dt><dd>Disabled</dd>");
#endif
#endif
#ifdef USE_GTKSPELL
- g_string_append(str, " <b>GtkSpell:</b> Enabled<br/>");
+ g_string_append(str, "<dt>GtkSpell:</dt><dd>Enabled</dd>");
#else
- g_string_append(str, " <b>GtkSpell:</b> Disabled<br/>");
+ g_string_append(str, "<dt>GtkSpell:</dt><dd>Disabled</dd>");
#endif
#ifdef HAVE_GNUTLS
- g_string_append(str, " <b>GnuTLS:</b> Enabled<br/>");
+ g_string_append(str, "<dt>GnuTLS:</dt><dd>Enabled</dd>");
#else
- g_string_append(str, " <b>GnuTLS:</b> Disabled<br/>");
+ g_string_append(str, "<dt>GnuTLS:</dt><dd>Disabled</dd>");
#endif
#ifndef _WIN32
#ifdef USE_GSTREAMER
- g_string_append(str, " <b>GStreamer:</b> Enabled<br/>");
+ g_string_append(str, "<dt>GStreamer:</dt><dd>Enabled</dd>");
#else
- g_string_append(str, " <b>GStreamer:</b> Disabled<br/>");
+ g_string_append(str, "<dt>GStreamer:</dt><dd>Disabled</dd>");
#endif
#endif
#ifndef _WIN32
#ifdef ENABLE_MONO
- g_string_append(str, " <b>Mono:</b> Enabled<br/>");
+ g_string_append(str, "<dt>Mono:</dt><dd>Enabled</dd>");
#else
- g_string_append(str, " <b>Mono:</b> Disabled<br/>");
+ g_string_append(str, "<dt>Mono:</dt><dd>Disabled</dd>");
#endif
#endif
#ifndef _WIN32
#ifdef HAVE_NETWORKMANAGER
- g_string_append(str, " <b>NetworkManager:</b> Enabled<br/>");
+ g_string_append(str, "<dt>NetworkManager:</dt><dd>Enabled</dd>");
#else
- g_string_append(str, " <b>NetworkManager:</b> Disabled<br/>");
+ g_string_append(str, "<dt>NetworkManager:</dt><dd>Disabled</dd>");
#endif
#endif
#ifdef HAVE_NSS
- g_string_append(str, " <b>Network Security Services (NSS):</b> Enabled<br/>");
+ g_string_append(str, "<dt>Network Security Services (NSS):</dt><dd>Enabled</dd>");
#else
- g_string_append(str, " <b>Network Security Services (NSS):</b> Disabled<br/>");
+ g_string_append(str, "<dt>Network Security Services (NSS):</dt><dd>Disabled</dd>");
#endif
-if (purple_plugins_find_with_id("core-perl") != NULL)
- g_string_append(str, " <b>Perl:</b> Enabled<br/>");
-else
- g_string_append(str, " <b>Perl:</b> Disabled<br/>");
+ if (purple_plugins_find_with_id("core-perl") != NULL)
+ g_string_append(str, "<dt>Perl:</dt><dd>Enabled</dd>");
+ else
+ g_string_append(str, "<dt>Perl:</dt><dd>Disabled</dd>");
-if (purple_plugins_find_with_id("core-tcl") != NULL) {
- g_string_append(str, " <b>Tcl:</b> Enabled<br/>");
+ if (purple_plugins_find_with_id("core-tcl") != NULL) {
+ g_string_append(str, "<dt>Tcl:</dt><dd>Enabled</dd>");
#ifdef HAVE_TK
- g_string_append(str, " <b>Tk:</b> Enabled<br/>");
+ g_string_append(str, "<dt>Tk:</dt><dd>Enabled</dd>");
#else
- g_string_append(str, " <b>Tk:</b> Disabled<br/>");
+ g_string_append(str, "<dt>Tk:</dt><dd>Disabled</dd>");
#endif
-} else {
- g_string_append(str, " <b>Tcl:</b> Disabled<br/>");
- g_string_append(str, " <b>Tk:</b> Disabled<br/>");
-}
+ } else {
+ g_string_append(str, "<dt>Tcl:</dt><dd>Disabled</dd>");
+ g_string_append(str, "<dt>Tk:</dt><dd>Disabled</dd>");
+ }
#ifdef USE_IDN
- g_string_append(str, " <b>UTF-8 DNS (IDN):</b> Enabled<br/>");
+ g_string_append(str, "<dt>UTF-8 DNS (IDN):</dt><dd>Enabled</dd>");
#else
- g_string_append(str, " <b>UTF-8 DNS (IDN):</b> Disabled<br/>");
+ g_string_append(str, "<dt>UTF-8 DNS (IDN):</dt><dd>Disabled</dd>");
#endif
#ifdef USE_VV
- g_string_append(str, " <b>Voice and Video:</b> Enabled<br/>");
+ g_string_append(str, "<dt>Voice and Video:</dt><dd>Enabled</dd>");
#else
- g_string_append(str, " <b>Voice and Video:</b> Disabled<br/>");
+ g_string_append(str, "<dt>Voice and Video:</dt><dd>Disabled</dd>");
#endif
#ifndef _WIN32
#ifdef USE_SM
- g_string_append(str, " <b>X Session Management:</b> Enabled<br/>");
+ g_string_append(str, "<dt>X Session Management:</dt><dd>Enabled</dd>");
#else
- g_string_append(str, " <b>X Session Management:</b> Disabled<br/>");
+ g_string_append(str, "<dt>X Session Management:</dt><dd>Disabled</dd>");
#endif
#ifdef USE_SCREENSAVER
- g_string_append(str, " <b>XScreenSaver:</b> Enabled<br/>");
+ g_string_append(str, "<dt>XScreenSaver:</dt><dd>Enabled</dd>");
#else
- g_string_append(str, " <b>XScreenSaver:</b> Disabled<br/>");
+ g_string_append(str, "<dt>XScreenSaver:</dt><dd>Disabled</dd>");
#endif
#ifdef LIBZEPHYR_EXT
- g_string_append(str, " <b>Zephyr library (libzephyr):</b> External<br/>");
+ g_string_append(str, "<dt>Zephyr library (libzephyr):</dt><dd>External</dd>");
#else
- g_string_append(str, " <b>Zephyr library (libzephyr):</b> Internal<br/>");
+ g_string_append(str, "<dt>Zephyr library (libzephyr):</dt><dd>Internal</dd>");
#endif
#ifdef ZEPHYR_USES_KERBEROS
- g_string_append(str, " <b>Zephyr uses Kerberos:</b> Yes<br/>");
+ g_string_append(str, "<dt>Zephyr uses Kerberos:</dt><dd>Yes</dd>");
#else
- g_string_append(str, " <b>Zephyr uses Kerberos:</b> No<br/>");
+ g_string_append(str, "<dt>Zephyr uses Kerberos:</dt><dd>No</dd>");
#endif
#endif
+ g_string_append(str, "</dl>");
+
/* End of not to be translated section */
tmp = g_strdup_printf(_("%s Build Information"), PIDGIN_NAME);
@@ -733,27 +751,28 @@ void pidgin_dialogs_developers(void)
str = g_string_sized_new(4096);
/* Current Developers */
- g_string_append_printf(str, "<FONT SIZE=\"4\"><B>%s:</B></FONT><BR/>",
+ g_string_append_printf(str, "<h3>%s</h3><ul>",
_("Current Developers"));
add_developers(str, developers);
- g_string_append(str, "<BR/>");
+ g_string_append(str, "</ul>");
/* Crazy Patch Writers */
- g_string_append_printf(str, "<FONT SIZE=\"4\"><B>%s:</B></FONT><BR/>",
+ g_string_append_printf(str, "<h3>%s</h3><ul>",
_("Crazy Patch Writers"));
add_developers(str, patch_writers);
- g_string_append(str, "<BR/>");
+ g_string_append(str, "</ul>");
/* Retired Developers */
- g_string_append_printf(str, "<FONT SIZE=\"4\"><B>%s:</B></FONT><BR/>",
+ g_string_append_printf(str, "<h3>%s</h3><ul>",
_("Retired Developers"));
add_developers(str, retired_developers);
- g_string_append(str, "<BR/>");
+ g_string_append(str, "</ul>");
/* Retired Crazy Patch Writers */
- g_string_append_printf(str, "<FONT SIZE=\"4\"><B>%s:</B></FONT><BR/>",
+ g_string_append_printf(str, "<h3>%s</h3><ul>",
_("Retired Crazy Patch Writers"));
add_developers(str, retired_patch_writers);
+ g_string_append(str, "</ul>");
tmp = g_strdup_printf(_("%s Developer Information"), PIDGIN_NAME);
developer_info = pidgin_build_help_dialog(tmp, "developer_info", str);
@@ -775,15 +794,16 @@ void pidgin_dialogs_translators(void)
str = g_string_sized_new(4096);
/* Current Translators */
- g_string_append_printf(str, "<FONT SIZE=\"4\">%s:</FONT><BR/>",
+ g_string_append_printf(str, "<h3>%s</h3><dl>",
_("Current Translators"));
add_translators(str, translators);
- g_string_append(str, "<BR/>");
+ g_string_append(str, "</dl>");
/* Past Translators */
- g_string_append_printf(str, "<FONT SIZE=\"4\">%s:</FONT><BR/>",
+ g_string_append_printf(str, "<h3>%s</h3><dl>",
_("Past Translators"));
add_translators(str, past_translators);
+ g_string_append(str, "</dl>");
tmp = g_strdup_printf(_("%s Translator Information"), PIDGIN_NAME);
translator_info = pidgin_build_help_dialog(tmp, "translator_info", str);
@@ -804,14 +824,14 @@ void pidgin_dialogs_plugins_info(void)
str = g_string_sized_new(4096);
- g_string_append_printf(str, "<FONT SIZE=\"4\">%s</FONT><BR/>",
- _("Plugin Information"));
+ g_string_append_printf(str, "<h2>%s</h2><dl>", _("Plugin Information"));
for(l = purple_plugins_get_all(); l; l = l->next) {
plugin = (PurplePlugin *)l->data;
pname = g_markup_escape_text(purple_plugin_get_name(plugin), -1);
- pauthor = g_markup_escape_text(purple_plugin_get_author(plugin), -1);
+ if ((pauthor = (char *)purple_plugin_get_author(plugin)) != NULL)
+ pauthor = g_markup_escape_text(pauthor, -1);
pver = purple_plugin_get_version(plugin);
pwebsite = purple_plugin_get_homepage(plugin);
pid = purple_plugin_get_id(plugin);
@@ -819,22 +839,29 @@ void pidgin_dialogs_plugins_info(void)
ploaded = purple_plugin_is_loaded(plugin);
g_string_append_printf(str,
- "<FONT SIZE=\"3\"><B>%s</B></FONT><BR/><FONT SIZE=\"2\">"
- "\t<B>Author:</B> %s<BR/>\t<B>Version:</B> %s<BR/>"
- "\t<B>Website:</B> %s<BR/>\t<B>ID String:</B> %s<BR/>"
- "\t<B>Loadable:</B> %s<BR/>\t<B>Loaded:</B> %s<BR/>"
- "<BR/></FONT>", pname, pauthor ? pauthor : "(null)",
+ "<dt>%s</dt><dd>"
+ "<b>Author:</b> %s<br/>"
+ "<b>Version:</b> %s<br/>"
+ "<b>Website:</b> %s<br/>"
+ "<b>ID String:</b> %s<br/>"
+ "<b>Loadable:</b> %s<br/>"
+ "<b>Loaded:</b> %s"
+ "</dd><br/>",
+ pname, pauthor ? pauthor : "(null)",
pver, pwebsite, pid,
- punloadable ? "<FONT COLOR=\"#FF0000\"><B>No</B></FONT>" : "Yes",
+ punloadable ? "<span style=\"color: #FF0000;\"><b>No</b></span>" : "Yes",
ploaded ? "Yes" : "No");
+
+ g_free(pname);
+ g_free(pauthor);
}
+ g_string_append(str, "</dl>");
+
plugins_info = pidgin_build_help_dialog(title, "plugins_info", str);
g_signal_connect(G_OBJECT(plugins_info), "destroy",
G_CALLBACK(gtk_widget_destroyed), &plugins_info);
g_free(title);
- g_free(pname);
- g_free(pauthor);
}
static void
@@ -950,7 +977,9 @@ pidgin_dialogs_ee(const char *ee)
gtk_container_set_border_width (GTK_CONTAINER(window), PIDGIN_HIG_BOX_SPACE);
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
+#if !GTK_CHECK_VERSION(2,22,0)
gtk_dialog_set_has_separator(GTK_DIALOG(window), FALSE);
+#endif
gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(window)->vbox), PIDGIN_HIG_BORDER);
gtk_container_set_border_width (GTK_CONTAINER(GTK_DIALOG(window)->vbox), PIDGIN_HIG_BOX_SPACE);
@@ -1117,26 +1146,6 @@ pidgin_dialogs_log(void)
}
static void
-pidgin_dialogs_alias_contact_cb(PurpleContact *contact, const char *new_alias)
-{
- purple_blist_alias_contact(contact, new_alias);
-}
-
-void
-pidgin_dialogs_alias_contact(PurpleContact *contact)
-{
- g_return_if_fail(contact != NULL);
-
- purple_request_input(NULL, _("Alias Contact"), NULL,
- _("Enter an alias for this contact."),
- contact->alias, FALSE, FALSE, NULL,
- _("Alias"), G_CALLBACK(pidgin_dialogs_alias_contact_cb),
- _("Cancel"), NULL,
- NULL, purple_contact_get_alias(contact), NULL,
- contact);
-}
-
-static void
pidgin_dialogs_alias_buddy_cb(PurpleBuddy *buddy, const char *new_alias)
{
purple_blist_alias_buddy(buddy, new_alias);
@@ -1150,10 +1159,10 @@ pidgin_dialogs_alias_buddy(PurpleBuddy *buddy)
g_return_if_fail(buddy != NULL);
- secondary = g_strdup_printf(_("Enter an alias for %s."), buddy->name);
+ secondary = g_strdup_printf(_("Enter an alias for %s."), purple_buddy_get_name(buddy));
purple_request_input(NULL, _("Alias Buddy"), NULL,
- secondary, buddy->alias, FALSE, FALSE, NULL,
+ secondary, purple_buddy_get_local_buddy_alias(buddy), FALSE, FALSE, NULL,
_("Alias"), G_CALLBACK(pidgin_dialogs_alias_buddy_cb),
_("Cancel"), NULL,
purple_buddy_get_account(buddy), purple_buddy_get_name(buddy), NULL,
@@ -1178,7 +1187,7 @@ pidgin_dialogs_alias_chat(PurpleChat *chat)
chat->alias, FALSE, FALSE, NULL,
_("Alias"), G_CALLBACK(pidgin_dialogs_alias_chat_cb),
_("Cancel"), NULL,
- chat->account, NULL, NULL,
+ purple_chat_get_account(chat), NULL, NULL,
chat);
}
@@ -1192,8 +1201,8 @@ pidgin_dialogs_remove_contact_cb(PurpleContact *contact)
group = (PurpleGroup*)cnode->parent;
for (bnode = cnode->child; bnode; bnode = bnode->next) {
PurpleBuddy *buddy = (PurpleBuddy*)bnode;
- if (purple_account_is_connected(buddy->account))
- purple_account_remove_buddy(buddy->account, buddy, group);
+ if (purple_account_is_connected(purple_buddy_get_account(buddy)))
+ purple_account_remove_buddy(purple_buddy_get_account(buddy), buddy, group);
}
purple_blist_remove_contact(contact);
}
@@ -1218,8 +1227,8 @@ pidgin_dialogs_remove_contact(PurpleContact *contact)
"want to continue?",
"You are about to remove the contact containing %s "
"and %d other buddies from your buddy list. Do you "
- "want to continue?", contact->totalsize - 1),
- buddy->name, contact->totalsize - 1);
+ "want to continue?", purple_contact_get_contact_size(contact, TRUE) - 1),
+ purple_buddy_get_name(buddy), purple_contact_get_contact_size(contact, TRUE) - 1);
purple_request_action(contact, NULL, _("Remove Contact"), text, 0,
NULL, purple_contact_get_alias(contact), NULL,
@@ -1256,7 +1265,7 @@ pidgin_dialogs_merge_groups(PurpleGroup *source, const char *new_name)
text = g_strdup_printf(
_("You are about to merge the group called %s into the group "
- "called %s. Do you want to continue?"), source->name, new_name);
+ "called %s. Do you want to continue?"), purple_group_get_name(source), new_name);
ggp = g_new(struct _PidginGroupMergeObject, 1);
ggp->parent = source;
@@ -1287,8 +1296,8 @@ pidgin_dialogs_remove_group_cb(PurpleGroup *group)
if (PURPLE_BLIST_NODE_IS_BUDDY(bnode)) {
buddy = (PurpleBuddy*)bnode;
bnode = bnode->next;
- if (purple_account_is_connected(buddy->account)) {
- purple_account_remove_buddy(buddy->account, buddy, group);
+ if (purple_account_is_connected(purple_buddy_get_account(buddy))) {
+ purple_account_remove_buddy(purple_buddy_get_account(buddy), buddy, group);
purple_blist_remove_buddy(buddy);
}
} else {
@@ -1298,7 +1307,7 @@ pidgin_dialogs_remove_group_cb(PurpleGroup *group)
} else if (PURPLE_BLIST_NODE_IS_CHAT(cnode)) {
PurpleChat *chat = (PurpleChat *)cnode;
cnode = cnode->next;
- if (purple_account_is_connected(chat->account))
+ if (purple_account_is_connected(purple_chat_get_account(chat)))
purple_blist_remove_chat(chat);
} else {
cnode = cnode->next;
@@ -1316,7 +1325,7 @@ pidgin_dialogs_remove_group(PurpleGroup *group)
g_return_if_fail(group != NULL);
text = g_strdup_printf(_("You are about to remove the group %s and all its members from your buddy list. Do you want to continue?"),
- group->name);
+ purple_group_get_name(group));
purple_request_action(group, NULL, _("Remove Group"), text, 0,
NULL, NULL, NULL,
@@ -1336,10 +1345,10 @@ pidgin_dialogs_remove_buddy_cb(PurpleBuddy *buddy)
PurpleAccount *account;
group = purple_buddy_get_group(buddy);
- name = g_strdup(buddy->name); /* b->name is a crasher after remove_buddy */
- account = buddy->account;
+ name = g_strdup(purple_buddy_get_name(buddy)); /* purple_buddy_get_name() is a crasher after remove_buddy */
+ account = purple_buddy_get_account(buddy);
- purple_debug_info("blist", "Removing '%s' from buddy list.\n", buddy->name);
+ purple_debug_info("blist", "Removing '%s' from buddy list.\n", purple_buddy_get_name(buddy));
/* TODO - Should remove from blist first... then call purple_account_remove_buddy()? */
purple_account_remove_buddy(account, buddy, group);
purple_blist_remove_buddy(buddy);
@@ -1355,7 +1364,7 @@ pidgin_dialogs_remove_buddy(PurpleBuddy *buddy)
g_return_if_fail(buddy != NULL);
text = g_strdup_printf(_("You are about to remove %s from your buddy list. Do you want to continue?"),
- buddy->name);
+ purple_buddy_get_name(buddy));
purple_request_action(buddy, NULL, _("Remove Buddy"), text, 0,
purple_buddy_get_account(buddy), purple_buddy_get_name(buddy), NULL,
@@ -1385,7 +1394,7 @@ pidgin_dialogs_remove_chat(PurpleChat *chat)
name ? name : "");
purple_request_action(chat, NULL, _("Remove Chat"), text, 0,
- chat->account, NULL, NULL,
+ purple_chat_get_account(chat), NULL, NULL,
chat, 2,
_("_Remove Chat"), G_CALLBACK(pidgin_dialogs_remove_chat_cb),
_("Cancel"), NULL);
diff --git a/pidgin/gtkdialogs.h b/pidgin/gtkdialogs.h
index 821ccb6a5a..19419d607b 100644
--- a/pidgin/gtkdialogs.h
+++ b/pidgin/gtkdialogs.h
@@ -30,6 +30,8 @@
#include "account.h"
#include "conversation.h"
+G_BEGIN_DECLS
+
/* Functions in gtkdialogs.c (these should actually stay in this file) */
void pidgin_dialogs_destroy_all(void);
void pidgin_dialogs_about(void);
@@ -42,14 +44,6 @@ void pidgin_dialogs_im_with_user(PurpleAccount *, const char *);
void pidgin_dialogs_info(void);
void pidgin_dialogs_log(void);
-#if !(defined PIDGIN_DISABLE_DEPRECATED) || (defined _PIDGIN_GTKDIALOGS_C_)
-/**
- * @deprecated This function is no longer used and will be removed in
- * Pidgin 3.0.0 unless there is sufficient demand to keep it.
- */
-void pidgin_dialogs_alias_contact(PurpleContact *);
-#endif
-
void pidgin_dialogs_alias_buddy(PurpleBuddy *);
void pidgin_dialogs_alias_chat(PurpleChat *);
void pidgin_dialogs_remove_buddy(PurpleBuddy *);
@@ -58,15 +52,9 @@ void pidgin_dialogs_remove_chat(PurpleChat *);
void pidgin_dialogs_remove_contact(PurpleContact *);
void pidgin_dialogs_merge_groups(PurpleGroup *, const char *);
-/* Everything after this should probably be moved elsewhere */
-
-#ifndef PIDGIN_DISABLE_DEPRECATED
-/* This PIDGIN_DISABLE_DEPRECATED doesn't need to be deactivated by
- * _PIDGIN_GTKDIALOGS_C_, because it shouldn't be using this macro. */
-#define PIDGIN_DIALOG(x) x = gtk_window_new(GTK_WINDOW_TOPLEVEL); \
- gtk_window_set_type_hint(GTK_WINDOW(x), GDK_WINDOW_TYPE_HINT_DIALOG)
-#endif
-
+/* This macro should probably be moved elsewhere */
#define PIDGIN_WINDOW_ICONIFIED(x) (gdk_window_get_state(GTK_WIDGET(x)->window) & GDK_WINDOW_STATE_ICONIFIED)
+G_END_DECLS
+
#endif /* _PIDGINDIALOGS_H_ */
diff --git a/pidgin/gtkdnd-hints.c b/pidgin/gtkdnd-hints.c
index faed31c511..750d6aef4b 100644
--- a/pidgin/gtkdnd-hints.c
+++ b/pidgin/gtkdnd-hints.c
@@ -62,19 +62,20 @@ dnd_hints_init_window(const gchar *fname)
GdkBitmap *bitmap;
GtkWidget *pix;
GtkWidget *win;
+ GdkColormap *colormap;
pixbuf = gdk_pixbuf_new_from_file(fname, NULL);
g_return_val_if_fail(pixbuf, NULL);
- gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap, &bitmap, 128);
+ win = gtk_window_new(GTK_WINDOW_POPUP);
+ colormap = gtk_widget_get_colormap(win);
+ gdk_pixbuf_render_pixmap_and_mask_for_colormap(pixbuf, colormap,
+ &pixmap, &bitmap, 128);
g_object_unref(G_OBJECT(pixbuf));
- gtk_widget_push_colormap(gdk_rgb_get_colormap());
- win = gtk_window_new(GTK_WINDOW_POPUP);
pix = gtk_image_new_from_pixmap(pixmap, bitmap);
gtk_container_add(GTK_CONTAINER(win), pix);
gtk_widget_shape_combine_mask(win, bitmap, 0, 0);
- gtk_widget_pop_colormap();
g_object_unref(G_OBJECT(pixmap));
g_object_unref(G_OBJECT(bitmap));
diff --git a/pidgin/gtkdnd-hints.h b/pidgin/gtkdnd-hints.h
index a53b9b5835..ed2f4c37ef 100644
--- a/pidgin/gtkdnd-hints.h
+++ b/pidgin/gtkdnd-hints.h
@@ -52,6 +52,8 @@ typedef enum {
} DndHintPosition;
+G_BEGIN_DECLS
+
/**
* Shows a drag-and-drop hint at the specified location.
*
@@ -84,4 +86,6 @@ void dnd_hints_hide_all(void);
void dnd_hints_show_relative(DndHintWindowId id, GtkWidget *widget,
DndHintPosition horiz, DndHintPosition vert);
+G_END_DECLS
+
#endif /* _PIDGIN_DND_HINTS_H_ */
diff --git a/pidgin/gtkdocklet-gtk.c b/pidgin/gtkdocklet-gtk.c
deleted file mode 100644
index f70916bb57..0000000000
--- a/pidgin/gtkdocklet-gtk.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * System tray icon (aka docklet) plugin for Purple
- *
- * Copyright (C) 2007 Anders Hasselqvist
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "internal.h"
-#include "pidgin.h"
-#include "debug.h"
-#include "prefs.h"
-#include "pidginstock.h"
-#include "gtkdocklet.h"
-
-#define SHORT_EMBED_TIMEOUT 5
-#define LONG_EMBED_TIMEOUT 15
-
-/* globals */
-static GtkStatusIcon *docklet = NULL;
-static guint embed_timeout = 0;
-
-/* protos */
-static void docklet_gtk_status_create(gboolean);
-
-static gboolean
-docklet_gtk_recreate_cb(gpointer data)
-{
- docklet_gtk_status_create(TRUE);
-
- return FALSE;
-}
-
-static gboolean
-docklet_gtk_embed_timeout_cb(gpointer data)
-{
-#if !GTK_CHECK_VERSION(2,12,0)
- if (gtk_status_icon_is_embedded(docklet)) {
- /* Older GTK+ (<2.12) don't implement the embedded signal, but the
- information is still accessable through the above function. */
- purple_debug_info("docklet", "embedded\n");
-
- pidgin_docklet_embedded();
- purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
- }
- else
-#endif
- {
- /* The docklet was not embedded within the timeout.
- * Remove it as a visibility manager, but leave the plugin
- * loaded so that it can embed automatically if/when a notification
- * area becomes available.
- */
- purple_debug_info("docklet", "failed to embed within timeout\n");
- pidgin_docklet_remove();
- purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
- }
-
-#if GTK_CHECK_VERSION(2,12,0)
- embed_timeout = 0;
- return FALSE;
-#else
- return TRUE;
-#endif
-}
-
-#if GTK_CHECK_VERSION(2,12,0)
-static gboolean
-docklet_gtk_embedded_cb(GtkWidget *widget, gpointer data)
-{
- if (embed_timeout) {
- purple_timeout_remove(embed_timeout);
- embed_timeout = 0;
- }
-
- if (gtk_status_icon_is_embedded(docklet)) {
- purple_debug_info("docklet", "embedded\n");
-
- pidgin_docklet_embedded();
- purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
- } else {
- purple_debug_info("docklet", "detached\n");
-
- pidgin_docklet_remove();
- purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
- }
-
- return TRUE;
-}
-#endif
-
-static void
-docklet_gtk_destroyed_cb(GtkWidget *widget, gpointer data)
-{
- purple_debug_info("docklet", "destroyed\n");
-
- pidgin_docklet_remove();
-
- g_object_unref(G_OBJECT(docklet));
- docklet = NULL;
-
- g_idle_add(docklet_gtk_recreate_cb, NULL);
-}
-
-static void
-docklet_gtk_status_activated_cb(GtkStatusIcon *status_icon, gpointer user_data)
-{
- pidgin_docklet_clicked(1);
-}
-
-static void
-docklet_gtk_status_clicked_cb(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data)
-{
- purple_debug_info("docklet", "The button is %u\n", button);
-#ifdef GDK_WINDOWING_QUARTZ
- /* You can only click left mouse button on MacOSX native GTK. Let that be the menu */
- pidgin_docklet_clicked(3);
-#else
- pidgin_docklet_clicked(button);
-#endif
-}
-
-static void
-docklet_gtk_status_update_icon(PurpleStatusPrimitive status, gboolean connecting, gboolean pending)
-{
- const gchar *icon_name = NULL;
-
- switch (status) {
- case PURPLE_STATUS_OFFLINE:
- icon_name = PIDGIN_STOCK_TRAY_OFFLINE;
- break;
- case PURPLE_STATUS_AWAY:
- icon_name = PIDGIN_STOCK_TRAY_AWAY;
- break;
- case PURPLE_STATUS_UNAVAILABLE:
- icon_name = PIDGIN_STOCK_TRAY_BUSY;
- break;
- case PURPLE_STATUS_EXTENDED_AWAY:
- icon_name = PIDGIN_STOCK_TRAY_XA;
- break;
- case PURPLE_STATUS_INVISIBLE:
- icon_name = PIDGIN_STOCK_TRAY_INVISIBLE;
- break;
- default:
- icon_name = PIDGIN_STOCK_TRAY_AVAILABLE;
- break;
- }
-
- if (pending)
- icon_name = PIDGIN_STOCK_TRAY_PENDING;
- if (connecting)
- icon_name = PIDGIN_STOCK_TRAY_CONNECT;
-
- if (icon_name) {
- gtk_status_icon_set_from_icon_name(docklet, icon_name);
- }
-
- if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink")) {
- gtk_status_icon_set_blinking(docklet, (pending && !connecting));
- } else if (gtk_status_icon_get_blinking(docklet)) {
- gtk_status_icon_set_blinking(docklet, FALSE);
- }
-}
-
-static void
-docklet_gtk_status_set_tooltip(gchar *tooltip)
-{
- gtk_status_icon_set_tooltip(docklet, tooltip);
-}
-
-static void
-docklet_gtk_status_position_menu(GtkMenu *menu,
- int *x, int *y, gboolean *push_in,
- gpointer user_data)
-{
- gtk_status_icon_position_menu(menu, x, y, push_in, docklet);
-}
-
-static void
-docklet_gtk_status_destroy(void)
-{
- g_return_if_fail(docklet != NULL);
-
- pidgin_docklet_remove();
-
- if (embed_timeout) {
- purple_timeout_remove(embed_timeout);
- embed_timeout = 0;
- }
-
- gtk_status_icon_set_visible(docklet, FALSE);
- g_signal_handlers_disconnect_by_func(G_OBJECT(docklet), G_CALLBACK(docklet_gtk_destroyed_cb), NULL);
- g_object_unref(G_OBJECT(docklet));
- docklet = NULL;
-
- purple_debug_info("docklet", "GTK+ destroyed\n");
-}
-
-static void
-docklet_gtk_status_create(gboolean recreate)
-{
- if (docklet) {
- /* if this is being called when a tray icon exists, it's because
- something messed up. try destroying it before we proceed,
- although docklet_refcount may be all hosed. hopefully won't happen. */
- purple_debug_warning("docklet", "trying to create icon but it already exists?\n");
- docklet_gtk_status_destroy();
- }
-
- docklet = gtk_status_icon_new();
- g_return_if_fail(docklet != NULL);
-
- g_signal_connect(G_OBJECT(docklet), "activate", G_CALLBACK(docklet_gtk_status_activated_cb), NULL);
- g_signal_connect(G_OBJECT(docklet), "popup-menu", G_CALLBACK(docklet_gtk_status_clicked_cb), NULL);
-#if GTK_CHECK_VERSION(2,12,0)
- g_signal_connect(G_OBJECT(docklet), "notify::embedded", G_CALLBACK(docklet_gtk_embedded_cb), NULL);
-#endif
- g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(docklet_gtk_destroyed_cb), NULL);
-
- gtk_status_icon_set_visible(docklet, TRUE);
-
- /* This is a hack to avoid a race condition between the docklet getting
- * embedded in the notification area and the gtkblist restoring its
- * previous visibility state. If the docklet does not get embedded within
- * the timeout, it will be removed as a visibility manager until it does
- * get embedded. Ideally, we would only call docklet_embedded() when the
- * icon was actually embedded. This only happens when the docklet is first
- * created, not when being recreated.
- *
- * The gtk docklet tracks whether it successfully embedded in a pref and
- * allows for a longer timeout period if it successfully embedded the last
- * time it was run. This should hopefully solve problems with the buddy
- * list not properly starting hidden when Pidgin is started on login.
- */
- if (!recreate) {
- pidgin_docklet_embedded();
-#if GTK_CHECK_VERSION(2,12,0)
- if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded")) {
- embed_timeout = purple_timeout_add_seconds(LONG_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
- } else {
- embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
- }
-#else
- embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
-#endif
- }
-
- purple_debug_info("docklet", "GTK+ created\n");
-}
-
-static void
-docklet_gtk_status_create_ui_op(void)
-{
- docklet_gtk_status_create(FALSE);
-}
-
-static struct docklet_ui_ops ui_ops =
-{
- docklet_gtk_status_create_ui_op,
- docklet_gtk_status_destroy,
- docklet_gtk_status_update_icon,
- NULL,
- docklet_gtk_status_set_tooltip,
- docklet_gtk_status_position_menu
-};
-
-void
-docklet_ui_init(void)
-{
- pidgin_docklet_set_ui_ops(&ui_ops);
-
- purple_prefs_add_none(PIDGIN_PREFS_ROOT "/docklet/gtk");
- if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/x11/embedded")) {
- purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
- purple_prefs_remove(PIDGIN_PREFS_ROOT "/docklet/x11/embedded");
- } else {
- purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
- }
-
- gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(),
- DATADIR G_DIR_SEPARATOR_S "pixmaps" G_DIR_SEPARATOR_S "pidgin" G_DIR_SEPARATOR_S "tray");
-}
-
diff --git a/pidgin/gtkdocklet.c b/pidgin/gtkdocklet.c
index 571222e017..88ce410d30 100644
--- a/pidgin/gtkdocklet.c
+++ b/pidgin/gtkdocklet.c
@@ -30,6 +30,7 @@
#include "prefs.h"
#include "signals.h"
#include "sound.h"
+#include "status.h"
#include "gtkaccount.h"
#include "gtkblist.h"
@@ -48,8 +49,12 @@
#define DOCKLET_TOOLTIP_LINE_LIMIT 5
#endif
+#define SHORT_EMBED_TIMEOUT 5
+#define LONG_EMBED_TIMEOUT 15
+
/* globals */
-static struct docklet_ui_ops *ui_ops = NULL;
+static GtkStatusIcon *docklet = NULL;
+static guint embed_timeout = 0;
static PurpleStatusPrimitive status = PURPLE_STATUS_OFFLINE;
static gboolean pending = FALSE;
static gboolean connecting = FALSE;
@@ -58,9 +63,55 @@ static guint docklet_blinking_timer = 0;
static gboolean visible = FALSE;
static gboolean visibility_manager = FALSE;
+/* protos */
+static void docklet_gtk_status_create(gboolean);
+static void docklet_gtk_status_destroy(void);
+
/**************************************************************************
* docklet status and utility functions
**************************************************************************/
+static void
+docklet_gtk_status_update_icon(PurpleStatusPrimitive status, gboolean connecting, gboolean pending)
+{
+ const gchar *icon_name = NULL;
+
+ switch (status) {
+ case PURPLE_STATUS_OFFLINE:
+ icon_name = PIDGIN_STOCK_TRAY_OFFLINE;
+ break;
+ case PURPLE_STATUS_AWAY:
+ icon_name = PIDGIN_STOCK_TRAY_AWAY;
+ break;
+ case PURPLE_STATUS_UNAVAILABLE:
+ icon_name = PIDGIN_STOCK_TRAY_BUSY;
+ break;
+ case PURPLE_STATUS_EXTENDED_AWAY:
+ icon_name = PIDGIN_STOCK_TRAY_XA;
+ break;
+ case PURPLE_STATUS_INVISIBLE:
+ icon_name = PIDGIN_STOCK_TRAY_INVISIBLE;
+ break;
+ default:
+ icon_name = PIDGIN_STOCK_TRAY_AVAILABLE;
+ break;
+ }
+
+ if (pending)
+ icon_name = PIDGIN_STOCK_TRAY_PENDING;
+ if (connecting)
+ icon_name = PIDGIN_STOCK_TRAY_CONNECT;
+
+ if (icon_name) {
+ gtk_status_icon_set_from_icon_name(docklet, icon_name);
+ }
+
+ if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink")) {
+ gtk_status_icon_set_blinking(docklet, (pending && !connecting));
+ } else if (gtk_status_icon_get_blinking(docklet)) {
+ gtk_status_icon_set_blinking(docklet, FALSE);
+ }
+}
+
static gboolean
docklet_blink_icon(gpointer data)
{
@@ -70,11 +121,8 @@ docklet_blink_icon(gpointer data)
blinked = !blinked;
if(pending && !connecting) {
- if (blinked) {
- if (ui_ops && ui_ops->blank_icon)
- ui_ops->blank_icon();
- } else {
- pidgin_docklet_update_icon();
+ if (!blinked) {
+ docklet_gtk_status_update_icon(status, connecting, pending);
}
ret = TRUE; /* keep blinking */
} else {
@@ -126,12 +174,12 @@ docklet_update_status(void)
convs = get_pending_list(DOCKLET_TOOLTIP_LINE_LIMIT);
if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "pending")) {
- if (convs && ui_ops->create && !visible) {
+ if (convs && !visible) {
g_list_free(convs);
- ui_ops->create();
+ docklet_gtk_status_create(FALSE);
return FALSE;
- } else if (!convs && ui_ops->destroy && visible) {
- ui_ops->destroy();
+ } else if (!convs && visible) {
+ docklet_gtk_status_destroy();
return FALSE;
}
}
@@ -142,53 +190,49 @@ docklet_update_status(void)
}
if (convs != NULL) {
+ /* set tooltip if messages are pending */
+ GString *tooltip_text = g_string_new("");
newpending = TRUE;
- /* set tooltip if messages are pending */
- if (ui_ops->set_tooltip) {
- GString *tooltip_text = g_string_new("");
- for (l = convs, count = 0 ; l != NULL ; l = l->next, count++) {
- PurpleConversation *conv = (PurpleConversation *)l->data;
- PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
-
- if (count == DOCKLET_TOOLTIP_LINE_LIMIT - 1) {
- g_string_append(tooltip_text, _("Right-click for more unread messages...\n"));
- } else if(gtkconv) {
- g_string_append_printf(tooltip_text,
- ngettext("%d unread message from %s\n", "%d unread messages from %s\n", gtkconv->unseen_count),
- gtkconv->unseen_count,
- purple_conversation_get_title(conv));
- } else {
- g_string_append_printf(tooltip_text,
- ngettext("%d unread message from %s\n", "%d unread messages from %s\n",
- GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count"))),
- GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count")),
- purple_conversation_get_title(conv));
- }
+ for (l = convs, count = 0 ; l != NULL ; l = l->next, count++) {
+ PurpleConversation *conv = (PurpleConversation *)l->data;
+ PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
+
+ if (count == DOCKLET_TOOLTIP_LINE_LIMIT - 1) {
+ g_string_append(tooltip_text, _("Right-click for more unread messages...\n"));
+ } else if(gtkconv) {
+ g_string_append_printf(tooltip_text,
+ ngettext("%d unread message from %s\n", "%d unread messages from %s\n", gtkconv->unseen_count),
+ gtkconv->unseen_count,
+ purple_conversation_get_title(conv));
+ } else {
+ g_string_append_printf(tooltip_text,
+ ngettext("%d unread message from %s\n", "%d unread messages from %s\n",
+ GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count"))),
+ GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count")),
+ purple_conversation_get_title(conv));
}
+ }
- /* get rid of the last newline */
- if (tooltip_text->len > 0)
- tooltip_text = g_string_truncate(tooltip_text, tooltip_text->len - 1);
+ /* get rid of the last newline */
+ if (tooltip_text->len > 0)
+ tooltip_text = g_string_truncate(tooltip_text, tooltip_text->len - 1);
- ui_ops->set_tooltip(tooltip_text->str);
-
- g_string_free(tooltip_text, TRUE);
- }
+ gtk_status_icon_set_tooltip(docklet, tooltip_text->str);
+ g_string_free(tooltip_text, TRUE);
g_list_free(convs);
- } else if (ui_ops->set_tooltip) {
+ } else {
char *tooltip_text = g_strconcat(PIDGIN_NAME, " - ",
purple_savedstatus_get_title(saved_status), NULL);
- ui_ops->set_tooltip(tooltip_text);
+ gtk_status_icon_set_tooltip(docklet, tooltip_text);
g_free(tooltip_text);
}
for(l = purple_accounts_get_all(); l != NULL; l = l->next) {
PurpleAccount *account = (PurpleAccount*)l->data;
- PurpleStatus *account_status;
if (!purple_account_get_enabled(account, PIDGIN_UI))
continue;
@@ -196,7 +240,6 @@ docklet_update_status(void)
if (purple_account_is_disconnected(account))
continue;
- account_status = purple_account_get_active_status(account);
if (purple_account_is_connecting(account))
newconnecting = TRUE;
}
@@ -209,7 +252,7 @@ docklet_update_status(void)
pending = newpending;
connecting = newconnecting;
- pidgin_docklet_update_icon();
+ docklet_gtk_status_update_icon(status, connecting, pending);
/* and schedule the blinker function if messages are pending */
if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink")
@@ -229,7 +272,7 @@ online_account_supports_chat(void)
while(c != NULL) {
PurpleConnection *gc = c->data;
- PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
if (prpl_info != NULL && prpl_info->chat_info != NULL)
return TRUE;
c = c->next;
@@ -266,7 +309,7 @@ static void
docklet_signed_on_cb(PurpleConnection *gc)
{
if (!enable_join_chat) {
- if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL)
+ if (PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc))->chat_info != NULL)
enable_join_chat = TRUE;
}
docklet_update_status();
@@ -276,7 +319,7 @@ static void
docklet_signed_off_cb(PurpleConnection *gc)
{
if (enable_join_chat) {
- if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL)
+ if (PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc))->chat_info != NULL)
enable_join_chat = online_account_supports_chat();
}
docklet_update_status();
@@ -288,17 +331,15 @@ docklet_show_pref_changed_cb(const char *name, PurplePrefType type,
{
const char *val = value;
if (!strcmp(val, "always")) {
- if (ui_ops->create) {
- if (!visible)
- ui_ops->create();
- else if (!visibility_manager) {
- pidgin_blist_visibility_manager_add();
- visibility_manager = TRUE;
- }
+ if (!visible)
+ docklet_gtk_status_create(FALSE);
+ else if (!visibility_manager) {
+ pidgin_blist_visibility_manager_add();
+ visibility_manager = TRUE;
}
} else if (!strcmp(val, "never")) {
- if (visible && ui_ops->destroy)
- ui_ops->destroy();
+ if (visible)
+ docklet_gtk_status_destroy();
} else {
if (visibility_manager) {
pidgin_blist_visibility_manager_remove();
@@ -523,7 +564,7 @@ add_account_statuses(GtkWidget *menu, PurpleAccount *account)
new_menu_item_with_status_icon(menu,
purple_status_type_get_name(status_type),
prim, G_CALLBACK(activate_status_account_cb),
- status_type, 0, 0, NULL);
+ GINT_TO_POINTER(status_type), 0, 0, NULL);
}
}
@@ -674,6 +715,7 @@ docklet_menu(void)
{
static GtkWidget *menu = NULL;
GtkWidget *menuitem;
+ GtkMenuPositionFunc pos_func = gtk_status_icon_position_menu;
if (menu) {
gtk_widget_destroy(menu);
@@ -749,24 +791,15 @@ docklet_menu(void)
#ifdef _WIN32
g_signal_connect(menu, "leave-notify-event", G_CALLBACK(docklet_menu_leave_enter), NULL);
g_signal_connect(menu, "enter-notify-event", G_CALLBACK(docklet_menu_leave_enter), NULL);
+ pos_func = NULL;
#endif
gtk_widget_show_all(menu);
gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
- ui_ops->position_menu,
- NULL, 0, gtk_get_current_event_time());
+ pos_func,
+ docklet, 0, gtk_get_current_event_time());
}
-/**************************************************************************
- * public api for ui_ops
- **************************************************************************/
-void
-pidgin_docklet_update_icon()
-{
- if (ui_ops && ui_ops->update_icon)
- ui_ops->update_icon(status, connecting, pending);
-}
-
-void
+static void
pidgin_docklet_clicked(int button_type)
{
switch (button_type) {
@@ -787,8 +820,8 @@ pidgin_docklet_clicked(int button_type)
}
}
-void
-pidgin_docklet_embedded()
+static void
+pidgin_docklet_embedded(void)
{
if (!visibility_manager
&& strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "pending")) {
@@ -797,11 +830,11 @@ pidgin_docklet_embedded()
}
visible = TRUE;
docklet_update_status();
- pidgin_docklet_update_icon();
+ docklet_gtk_status_update_icon(status, connecting, pending);
}
-void
-pidgin_docklet_remove()
+static void
+pidgin_docklet_remove(void)
{
if (visible) {
if (visibility_manager) {
@@ -817,12 +850,183 @@ pidgin_docklet_remove()
}
}
-void
-pidgin_docklet_set_ui_ops(struct docklet_ui_ops *ops)
+static gboolean
+docklet_gtk_recreate_cb(gpointer data)
+{
+ docklet_gtk_status_create(TRUE);
+
+ return FALSE;
+}
+
+#ifndef _WIN32
+static gboolean
+docklet_gtk_embed_timeout_cb(gpointer data)
+{
+#if !GTK_CHECK_VERSION(2,12,0)
+ if (gtk_status_icon_is_embedded(docklet)) {
+ /* Older GTK+ (<2.12) don't implement the embedded signal, but the
+ information is still accessible through the above function. */
+ purple_debug_info("docklet", "embedded\n");
+
+ pidgin_docklet_embedded();
+ purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
+ }
+ else
+#endif
+ {
+ /* The docklet was not embedded within the timeout.
+ * Remove it as a visibility manager, but leave the plugin
+ * loaded so that it can embed automatically if/when a notification
+ * area becomes available.
+ */
+ purple_debug_info("docklet", "failed to embed within timeout\n");
+ pidgin_docklet_remove();
+ purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
+ }
+
+#if GTK_CHECK_VERSION(2,12,0)
+ embed_timeout = 0;
+ return FALSE;
+#else
+ return TRUE;
+#endif
+}
+#endif
+
+#if GTK_CHECK_VERSION(2,12,0)
+static gboolean
+docklet_gtk_embedded_cb(GtkWidget *widget, gpointer data)
+{
+ if (embed_timeout) {
+ purple_timeout_remove(embed_timeout);
+ embed_timeout = 0;
+ }
+
+ if (gtk_status_icon_is_embedded(docklet)) {
+ purple_debug_info("docklet", "embedded\n");
+
+ pidgin_docklet_embedded();
+ purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
+ } else {
+ purple_debug_info("docklet", "detached\n");
+
+ pidgin_docklet_remove();
+ purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
+ }
+
+ return TRUE;
+}
+#endif
+
+static void
+docklet_gtk_destroyed_cb(GtkWidget *widget, gpointer data)
+{
+ purple_debug_info("docklet", "destroyed\n");
+
+ pidgin_docklet_remove();
+
+ g_object_unref(G_OBJECT(docklet));
+ docklet = NULL;
+
+ g_idle_add(docklet_gtk_recreate_cb, NULL);
+}
+
+static void
+docklet_gtk_status_activated_cb(GtkStatusIcon *status_icon, gpointer user_data)
+{
+ pidgin_docklet_clicked(1);
+}
+
+static void
+docklet_gtk_status_clicked_cb(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data)
+{
+ purple_debug_info("docklet", "The button is %u\n", button);
+#ifdef GDK_WINDOWING_QUARTZ
+ /* You can only click left mouse button on MacOSX native GTK. Let that be the menu */
+ pidgin_docklet_clicked(3);
+#else
+ pidgin_docklet_clicked(button);
+#endif
+}
+
+static void
+docklet_gtk_status_destroy(void)
{
- ui_ops = ops;
+ g_return_if_fail(docklet != NULL);
+
+ pidgin_docklet_remove();
+
+ if (embed_timeout) {
+ purple_timeout_remove(embed_timeout);
+ embed_timeout = 0;
+ }
+
+ gtk_status_icon_set_visible(docklet, FALSE);
+ g_signal_handlers_disconnect_by_func(G_OBJECT(docklet), G_CALLBACK(docklet_gtk_destroyed_cb), NULL);
+ g_object_unref(G_OBJECT(docklet));
+ docklet = NULL;
+
+ purple_debug_info("docklet", "GTK+ destroyed\n");
}
+static void
+docklet_gtk_status_create(gboolean recreate)
+{
+ if (docklet) {
+ /* if this is being called when a tray icon exists, it's because
+ something messed up. try destroying it before we proceed,
+ although docklet_refcount may be all hosed. hopefully won't happen. */
+ purple_debug_warning("docklet", "trying to create icon but it already exists?\n");
+ docklet_gtk_status_destroy();
+ }
+
+ docklet = gtk_status_icon_new();
+ g_return_if_fail(docklet != NULL);
+
+ g_signal_connect(G_OBJECT(docklet), "activate", G_CALLBACK(docklet_gtk_status_activated_cb), NULL);
+ g_signal_connect(G_OBJECT(docklet), "popup-menu", G_CALLBACK(docklet_gtk_status_clicked_cb), NULL);
+#if GTK_CHECK_VERSION(2,12,0)
+ g_signal_connect(G_OBJECT(docklet), "notify::embedded", G_CALLBACK(docklet_gtk_embedded_cb), NULL);
+#endif
+ g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(docklet_gtk_destroyed_cb), NULL);
+
+ gtk_status_icon_set_visible(docklet, TRUE);
+
+ /* This is a hack to avoid a race condition between the docklet getting
+ * embedded in the notification area and the gtkblist restoring its
+ * previous visibility state. If the docklet does not get embedded within
+ * the timeout, it will be removed as a visibility manager until it does
+ * get embedded. Ideally, we would only call docklet_embedded() when the
+ * icon was actually embedded. This only happens when the docklet is first
+ * created, not when being recreated.
+ *
+ * The gtk docklet tracks whether it successfully embedded in a pref and
+ * allows for a longer timeout period if it successfully embedded the last
+ * time it was run. This should hopefully solve problems with the buddy
+ * list not properly starting hidden when Pidgin is started on login.
+ */
+ if (!recreate) {
+ pidgin_docklet_embedded();
+#ifndef _WIN32
+#if GTK_CHECK_VERSION(2,12,0)
+ if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded")) {
+ embed_timeout = purple_timeout_add_seconds(LONG_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
+ } else {
+ embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
+ }
+#else
+ embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL);
+#endif
+#endif
+ }
+
+ purple_debug_info("docklet", "GTK+ created\n");
+}
+
+/**************************************************************************
+ * public api
+ **************************************************************************/
+
void*
pidgin_docklet_get_handle()
{
@@ -838,6 +1042,7 @@ pidgin_docklet_init()
void *accounts_handle = purple_accounts_get_handle();
void *status_handle = purple_savedstatuses_get_handle();
void *docklet_handle = pidgin_docklet_get_handle();
+ gchar *tmp;
purple_prefs_add_none(PIDGIN_PREFS_ROOT "/docklet");
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/blink", FALSE);
@@ -845,9 +1050,20 @@ pidgin_docklet_init()
purple_prefs_connect_callback(docklet_handle, PIDGIN_PREFS_ROOT "/docklet/show",
docklet_show_pref_changed_cb, NULL);
- docklet_ui_init();
- if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "always") && ui_ops && ui_ops->create)
- ui_ops->create();
+ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/docklet/gtk");
+ if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/x11/embedded")) {
+ purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE);
+ purple_prefs_remove(PIDGIN_PREFS_ROOT "/docklet/x11/embedded");
+ } else {
+ purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE);
+ }
+
+ tmp = g_build_path(G_DIR_SEPARATOR_S, DATADIR, "pixmaps", "pidgin", "tray", NULL);
+ gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), tmp);
+ g_free(tmp);
+
+ if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/docklet/show"), "always"))
+ docklet_gtk_status_create(FALSE);
purple_signal_connect(conn_handle, "signed-on",
docklet_handle, PURPLE_CALLBACK(docklet_signed_on_cb), NULL);
@@ -876,6 +1092,7 @@ pidgin_docklet_init()
void
pidgin_docklet_uninit()
{
- if (visible && ui_ops && ui_ops->destroy)
- ui_ops->destroy();
+ if (visible)
+ docklet_gtk_status_destroy();
}
+
diff --git a/pidgin/gtkdocklet.h b/pidgin/gtkdocklet.h
index 34f88a14f5..94e6a66b4d 100644
--- a/pidgin/gtkdocklet.h
+++ b/pidgin/gtkdocklet.h
@@ -25,31 +25,13 @@
#ifndef _GTKDOCKLET_H_
#define _GTKDOCKLET_H_
-#include "status.h"
+G_BEGIN_DECLS
-struct docklet_ui_ops
-{
- void (*create)(void);
- void (*destroy)(void);
- void (*update_icon)(PurpleStatusPrimitive, gboolean, gboolean);
- void (*blank_icon)(void);
- void (*set_tooltip)(gchar *);
- GtkMenuPositionFunc position_menu;
-};
-
-
-/* functions in gtkdocklet.c */
-void pidgin_docklet_update_icon(void);
-void pidgin_docklet_clicked(int);
-void pidgin_docklet_embedded(void);
-void pidgin_docklet_remove(void);
-void pidgin_docklet_set_ui_ops(struct docklet_ui_ops *);
-void pidgin_docklet_unload(void);
void pidgin_docklet_init(void);
void pidgin_docklet_uninit(void);
void*pidgin_docklet_get_handle(void);
-/* function in gtkdocklet-{gtk,x11,win32}.c */
-void docklet_ui_init(void);
+G_END_DECLS
#endif /* _GTKDOCKLET_H_ */
+
diff --git a/pidgin/gtkeventloop.h b/pidgin/gtkeventloop.h
index 0593a0f9e2..937f211bd2 100644
--- a/pidgin/gtkeventloop.h
+++ b/pidgin/gtkeventloop.h
@@ -28,6 +28,8 @@
#include "eventloop.h"
+G_BEGIN_DECLS
+
/**
* Returns the GTK+ event loop UI operations structure.
*
@@ -35,4 +37,6 @@
*/
PurpleEventLoopUiOps *pidgin_eventloop_get_ui_ops(void);
+G_END_DECLS
+
#endif /* _PIDGINEVENTLOOP_H_ */
diff --git a/pidgin/gtkft.c b/pidgin/gtkft.c
index 4c1bc658ea..d8cb8855c6 100644
--- a/pidgin/gtkft.c
+++ b/pidgin/gtkft.c
@@ -37,9 +37,6 @@
#include "pidginstock.h"
#include "gtkutils.h"
-#define PIDGINXFER(xfer) \
- (PidginXferUiData *)(xfer)->ui_data
-
/* the maximum size of files we will try to make a thumbnail for */
#define PIDGIN_XFER_MAX_SIZE_IMAGE_THUMBNAIL 10 * 1024 * 1024
@@ -116,14 +113,17 @@ get_xfer_info_strings(PurpleXfer *xfer, char **kbsec, char **time_elapsed,
double kbps = 0.0;
time_t elapsed, now;
- if (xfer->end_time != 0)
- now = xfer->end_time;
- else
+ now = purple_xfer_get_end_time(xfer);
+ if (now == 0)
now = time(NULL);
kb_sent = purple_xfer_get_bytes_sent(xfer) / 1024.0;
kb_rem = purple_xfer_get_bytes_remaining(xfer) / 1024.0;
- elapsed = (xfer->start_time > 0 ? now - xfer->start_time : 0);
+ elapsed = purple_xfer_get_start_time(xfer);
+ if (elapsed > 0)
+ elapsed = now - elapsed;
+ else
+ elapsed = 0;
kbps = (elapsed > 0 ? (kb_sent / elapsed) : 0);
if (kbsec != NULL) {
@@ -135,9 +135,9 @@ get_xfer_info_strings(PurpleXfer *xfer, char **kbsec, char **time_elapsed,
int h, m, s;
int secs_elapsed;
- if (xfer->start_time > 0)
+ if (purple_xfer_get_start_time(xfer) > 0)
{
- secs_elapsed = now - xfer->start_time;
+ secs_elapsed = now - purple_xfer_get_start_time(xfer);
h = secs_elapsed / 3600;
m = (secs_elapsed % 3600) / 60;
@@ -155,7 +155,7 @@ get_xfer_info_strings(PurpleXfer *xfer, char **kbsec, char **time_elapsed,
if (purple_xfer_is_completed(xfer)) {
*time_remaining = g_strdup(_("Finished"));
}
- else if (purple_xfer_is_canceled(xfer)) {
+ else if (purple_xfer_is_cancelled(xfer)) {
*time_remaining = g_strdup(_("Cancelled"));
}
else if (purple_xfer_get_size(xfer) == 0 || (kb_sent > 0 && kbps == 0)) {
@@ -243,11 +243,11 @@ update_detailed_info(PidginXferDialog *dialog, PurpleXfer *xfer)
if (dialog == NULL || xfer == NULL)
return;
- data = PIDGINXFER(xfer);
+ data = purple_xfer_get_ui_data(xfer);
get_xfer_info_strings(xfer, &kbsec, &time_elapsed, &time_remaining);
- status = g_strdup_printf("%d%% (%" G_GSIZE_FORMAT " of %" G_GSIZE_FORMAT " bytes)",
+ status = g_strdup_printf("%d%% (%" G_GOFFSET_FORMAT " of %" G_GOFFSET_FORMAT " bytes)",
(int)(purple_xfer_get_progress(xfer)*100),
purple_xfer_get_bytes_sent(xfer),
purple_xfer_get_size(xfer));
@@ -281,10 +281,10 @@ update_detailed_info(PidginXferDialog *dialog, PurpleXfer *xfer)
}
gtk_label_set_text(GTK_LABEL(dialog->local_user_label),
- purple_account_get_username(xfer->account));
- gtk_label_set_text(GTK_LABEL(dialog->remote_user_label), xfer->who);
+ purple_account_get_username(purple_xfer_get_account(xfer)));
+ gtk_label_set_text(GTK_LABEL(dialog->remote_user_label), purple_xfer_get_remote_user(xfer));
gtk_label_set_text(GTK_LABEL(dialog->protocol_label),
- purple_account_get_protocol_name(xfer->account));
+ purple_account_get_protocol_name(purple_xfer_get_account(xfer)));
if (purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) {
gtk_label_set_text(GTK_LABEL(dialog->filename_label),
@@ -357,7 +357,7 @@ update_buttons(PidginXferDialog *dialog, PurpleXfer *xfer)
#endif
gtk_widget_set_sensitive(dialog->remove_button, TRUE);
- } else if (purple_xfer_is_canceled(xfer)) {
+ } else if (purple_xfer_is_cancelled(xfer)) {
gtk_widget_hide(dialog->stop_button);
gtk_widget_show(dialog->remove_button);
@@ -732,8 +732,8 @@ pidgin_xfer_dialog_new(void)
gtk_widget_show(vbox2);
/* Setup the listbox */
- gtk_box_pack_start(GTK_BOX(vbox2),
- pidgin_make_scrollable(setup_tree(dialog), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, 140),
+ gtk_box_pack_start(GTK_BOX(vbox2),
+ pidgin_make_scrollable(setup_tree(dialog), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, 140),
TRUE, TRUE, 0);
/* "Close this window when all transfers finish" */
@@ -869,7 +869,7 @@ pidgin_xfer_dialog_add_xfer(PidginXferDialog *dialog, PurpleXfer *xfer)
purple_xfer_ref(xfer);
- data = PIDGINXFER(xfer);
+ data = purple_xfer_get_ui_data(xfer);
data->in_list = TRUE;
pidgin_xfer_dialog_show(dialog);
@@ -926,7 +926,7 @@ pidgin_xfer_dialog_remove_xfer(PidginXferDialog *dialog,
g_return_if_fail(dialog != NULL);
g_return_if_fail(xfer != NULL);
- data = PIDGINXFER(xfer);
+ data = purple_xfer_get_ui_data(xfer);
if (data == NULL)
return;
@@ -957,7 +957,7 @@ pidgin_xfer_dialog_cancel_xfer(PidginXferDialog *dialog,
g_return_if_fail(dialog != NULL);
g_return_if_fail(xfer != NULL);
- data = PIDGINXFER(xfer);
+ data = purple_xfer_get_ui_data(xfer);
if (data == NULL)
return;
@@ -970,7 +970,7 @@ pidgin_xfer_dialog_cancel_xfer(PidginXferDialog *dialog,
return;
}
- data = PIDGINXFER(xfer);
+ data = purple_xfer_get_ui_data(xfer);
update_detailed_info(dialog, xfer);
update_title_progress(dialog);
@@ -979,7 +979,7 @@ pidgin_xfer_dialog_cancel_xfer(PidginXferDialog *dialog,
PIDGIN_STOCK_FILE_CANCELED,
GTK_ICON_SIZE_MENU, NULL);
- if (purple_xfer_is_canceled(xfer))
+ if (purple_xfer_is_cancelled(xfer))
status = _("Cancelled");
else
status = _("Failed");
@@ -1007,7 +1007,7 @@ pidgin_xfer_dialog_update_xfer(PidginXferDialog *dialog,
g_return_if_fail(dialog != NULL);
g_return_if_fail(xfer != NULL);
- if ((data = PIDGINXFER(xfer)) == NULL)
+ if ((data = purple_xfer_get_ui_data(xfer)) == NULL)
return;
if (data->in_list == FALSE)
@@ -1095,9 +1095,9 @@ pidgin_xfer_new_xfer(PurpleXfer *xfer)
{
PidginXferUiData *data;
- /* This is where we're setting xfer->ui_data for the first time. */
+ /* This is where we're setting xfer's "ui_data" for the first time. */
data = g_new0(PidginXferUiData, 1);
- xfer->ui_data = data;
+ purple_xfer_set_ui_data(xfer, data);
}
static void
@@ -1105,11 +1105,11 @@ pidgin_xfer_destroy(PurpleXfer *xfer)
{
PidginXferUiData *data;
- data = PIDGINXFER(xfer);
+ data = purple_xfer_get_ui_data(xfer);
if (data) {
g_free(data->name);
g_free(data);
- xfer->ui_data = NULL;
+ purple_xfer_set_ui_data(xfer, NULL);
}
}
diff --git a/pidgin/gtkft.h b/pidgin/gtkft.h
index 12f8b380ff..3863188d02 100644
--- a/pidgin/gtkft.h
+++ b/pidgin/gtkft.h
@@ -36,6 +36,8 @@
*/
typedef struct _PidginXferDialog PidginXferDialog;
+G_BEGIN_DECLS
+
/**************************************************************************/
/** @name GTK+ File Transfer Dialog API */
/**************************************************************************/
@@ -145,4 +147,6 @@ PurpleXferUiOps *pidgin_xfers_get_ui_ops(void);
/*@}*/
+G_END_DECLS
+
#endif /* _PIDGINFT_H_ */
diff --git a/pidgin/gtkgaim-compat.h b/pidgin/gtkgaim-compat.h
deleted file mode 100644
index 778ad303bf..0000000000
--- a/pidgin/gtkgaim-compat.h
+++ /dev/null
@@ -1,412 +0,0 @@
-/**
- * @file gtkgaim-compat.h Gtk Gaim Compat macros
- */
-
-/* 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.
- *
- * 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
- *
- */
-#ifndef _GTKGAIM_COMPAT_H_
-#define _GTKGAIM_COMPAT_H_
-
-#include <pidginstock.h>
-
-#define GAIM_ALERT_TITLE PIDGIN_ALERT_TITLE
-#define GAIM_BROWSER_CURRENT PIDGIN_BROWSER_CURRENT
-#define GAIM_BROWSER_DEFAULT PIDGIN_BROWSER_DEFAULT
-#define GAIM_BROWSER_NEW_TAB PIDGIN_BROWSER_NEW_TAB
-#define GAIM_BROWSER_NEW_WINDOW PIDGIN_BROWSER_NEW_WINDOW
-#define GaimBrowserPlace PidginBrowserPlace
-#define GAIM_BUTTON_HORIZONTAL PIDGIN_BUTTON_HORIZONTAL
-#define GAIM_BUTTON_IMAGE PIDGIN_BUTTON_IMAGE
-#define GAIM_BUTTON_NONE PIDGIN_BUTTON_NONE
-#define GaimButtonOrientation PidginButtonOrientation
-#define GaimButtonStyle PidginButtonStyle
-#define GAIM_BUTTON_TEXT_IMAGE PIDGIN_BUTTON_TEXT_IMAGE
-#define GAIM_BUTTON_TEXT PIDGIN_BUTTON_TEXT
-#define GAIM_BUTTON_VERTICAL PIDGIN_BUTTON_VERTICAL
-#define GaimConvPlacementFunc PidginConvPlacementFunc
-#define GAIM_DIALOG PIDGIN_DIALOG
-#define gaim_dnd_file_manage pidgin_dnd_file_manage
-#define gaim_get_gtkxfer_dialog pidgin_get_xfer_dialog
-#define gaim_gtk_account_dialog_show pidgin_account_dialog_show
-#define GaimGtkAccountDialogType PidginAccountDialogType
-#define gaim_gtk_account_get_handle pidgin_account_get_handle
-#define gaim_gtk_account_init pidgin_account_init
-#define gaim_gtk_account_option_menu_get_selected pidgin_account_option_menu_get_selected
-#define gaim_gtk_account_option_menu_new pidgin_account_option_menu_new
-#define gaim_gtk_account_option_menu_set_selected pidgin_account_option_menu_set_selected
-#define gaim_gtk_accounts_get_ui_ops pidgin_accounts_get_ui_ops
-#define gaim_gtk_accounts_window_hide pidgin_accounts_window_hide
-#define gaim_gtk_accounts_window_show pidgin_accounts_window_show
-#define gaim_gtk_account_uninit pidgin_account_uninit
-#define GAIM_GTK_ADD_ACCOUNT_DIALOG PIDGIN_ADD_ACCOUNT_DIALOG
-#define gaim_gtk_append_blist_node_extended_menu pidgin_append_blist_node_extended_menu
-#define gaim_gtk_append_blist_node_privacy_menu pidgin_append_blist_node_privacy_menu
-#define gaim_gtk_append_blist_node_proto_menu pidgin_append_blist_node_proto_menu
-#define gaim_gtk_append_menu_action pidgin_append_menu_action
-#define gaim_gtk_blist_add_alert pidgin_blist_add_alert
-#define gaim_gtk_blist_get_default_gtk_blist pidgin_blist_get_default_gtk_blist
-#define gaim_gtk_blist_get_handle pidgin_blist_get_handle
-#define gaim_gtk_blist_get_sort_methods pidgin_blist_get_sort_methods
-#define gaim_gtk_blist_get_status_icon pidgin_blist_get_status_icon
-#define gaim_gtk_blist_get_ui_ops pidgin_blist_get_ui_ops
-#define gaim_gtk_blist_init pidgin_blist_init
-#define gaim_gtk_blist_joinchat_is_showable pidgin_blist_joinchat_is_showable
-#define gaim_gtk_blist_joinchat_show pidgin_blist_joinchat_show
-#define gaim_gtk_blist_make_buddy_menu pidgin_blist_make_buddy_menu
-#define gaim_gtk_blist_node_is_contact_expanded pidgin_blist_node_is_contact_expanded
-#define GAIM_GTK_BLIST PIDGIN_BLIST
-#define gaim_gtk_blist_refresh pidgin_blist_refresh
-#define gaim_gtk_blist_set_headline pidgin_blist_set_headline
-#define gaim_gtk_blist_setup_sort_methods pidgin_blist_setup_sort_methods
-#define gaim_gtk_blist_sort_function pidgin_blist_sort_function
-#define gaim_gtk_blist_sort_method pidgin_blist_sort_method
-#define GaimGtkBlistSortMethod PidginBlistSortMethod
-#define gaim_gtk_blist_sort_method_reg pidgin_blist_sort_method_reg
-#define gaim_gtk_blist_sort_method_set pidgin_blist_sort_method_set
-#define gaim_gtk_blist_sort_method_unreg pidgin_blist_sort_method_unreg
-#define gaim_gtk_blist_toggle_visibility pidgin_blist_toggle_visibility
-#define gaim_gtk_blist_uninit pidgin_blist_uninit
-#define gaim_gtk_blist_update_account_error_state pidgin_blist_update_account_error_state
-#define gaim_gtk_blist_update_accounts_menu pidgin_blist_update_accounts_menu
-#define gaim_gtk_blist_update_columns pidgin_blist_update_columns
-#define gaim_gtk_blist_update_plugin_actions pidgin_blist_update_plugin_actions
-#define gaim_gtk_blist_update_refresh_timeout pidgin_blist_update_refresh_timeout
-#define gaim_gtk_blist_update_sort_methods pidgin_blist_update_sort_methods
-#define gaim_gtk_blist_visibility_manager_add pidgin_blist_visibility_manager_add
-#define gaim_gtk_blist_visibility_manager_remove pidgin_blist_visibility_manager_remove
-#define gaim_gtk_buddy_icon_chooser_new pidgin_buddy_icon_chooser_new
-#define gaim_gtk_buddy_icon_get_scale_size pidgin_buddy_icon_get_scale_size
-#define GaimGtkBuddyList PidginBuddyList
-#define GaimGtkCellRendererExpanderClass PidginCellRendererExpanderClass
-#define gaim_gtk_cell_renderer_expander_get_type pidgin_cell_renderer_expander_get_type
-#define gaim_gtk_cell_renderer_expander_new pidgin_cell_renderer_expander_new
-#define GaimGtkCellRendererExpander PidginCellRendererExpander
-#define GaimGtkCellRendererProgressClass PidginCellRendererProgressClass
-#define gaim_gtk_cell_renderer_progress_get_type pidgin_cell_renderer_progress_get_type
-#define gaim_gtk_cell_renderer_progress_new pidgin_cell_renderer_progress_new
-#define GaimGtkCellRendererProgress PidginCellRendererProgress
-#define GaimGtkChatPane PidginChatPane
-#define gaim_gtk_check_if_dir pidgin_check_if_dir
-#define gaim_gtk_clear_cursor pidgin_clear_cursor
-#define gaim_gtk_connection_get_handle pidgin_connection_get_handle
-#define gaim_gtk_connection_init pidgin_connection_init
-#define gaim_gtk_connections_get_ui_ops pidgin_connections_get_ui_ops
-#define gaim_gtk_connection_uninit pidgin_connection_uninit
-#define GaimGtkConversation PidginConversation
-#define GAIM_GTK_CONVERSATION PIDGIN_CONVERSATION
-#define gaim_gtk_conversations_fill_menu pidgin_conversations_fill_menu
-#define gaim_gtk_conversations_find_unseen_list pidgin_conversations_find_unseen_list
-#define gaim_gtk_conversations_get_conv_ui_ops pidgin_conversations_get_conv_ui_ops
-#define gaim_gtk_conversations_get_handle pidgin_conversations_get_handle
-#define gaim_gtk_conversations_init pidgin_conversations_init
-#define gaim_gtk_conversations_uninit pidgin_conversations_uninit
-#define gaim_gtk_convert_buddy_icon pidgin_convert_buddy_icon
-#define gaim_gtkconv_get_tab_at_xy pidgin_conv_get_tab_at_xy
-#define gaim_gtkconv_get_tab_icon pidgin_conv_get_tab_icon
-#define gaim_gtkconv_get_window pidgin_conv_get_window
-#define gaim_gtkconv_is_hidden pidgin_conv_is_hidden
-#define gaim_gtkconv_new pidgin_conv_new
-#define gaim_gtkconv_placement_add_fnc pidgin_conv_placement_add_fnc
-#define gaim_gtkconv_placement_get_current_func pidgin_conv_placement_get_current_func
-#define gaim_gtkconv_placement_get_fnc pidgin_conv_placement_get_fnc
-#define gaim_gtkconv_placement_get_name pidgin_conv_placement_get_name
-#define gaim_gtkconv_placement_get_options pidgin_conv_placement_get_options
-#define gaim_gtkconv_placement_place pidgin_conv_placement_place
-#define gaim_gtkconv_placement_remove_fnc pidgin_conv_placement_remove_fnc
-#define gaim_gtkconv_placement_set_current_func pidgin_conv_placement_set_current_func
-#define gaim_gtkconv_present_conversation pidgin_conv_present_conversation
-#define gaim_gtkconv_switch_active_conversation pidgin_conv_switch_active_conversation
-#define gaim_gtkconv_update_buddy_icon pidgin_conv_update_buddy_icon
-#define gaim_gtkconv_update_buttons_by_protocol pidgin_conv_update_buttons_by_protocol
-#define gaim_gtk_conv_window_add_gtkconv pidgin_conv_window_add_gtkconv
-#define gaim_gtk_conv_window_destroy pidgin_conv_window_destroy
-#define gaim_gtk_conv_window_first_with_type pidgin_conv_window_first_with_type
-#define gaim_gtk_conv_window_get_active_conversation pidgin_conv_window_get_active_conversation
-#define gaim_gtk_conv_window_get_active_gtkconv pidgin_conv_window_get_active_gtkconv
-#define gaim_gtk_conv_window_get_at_xy pidgin_conv_window_get_at_xy
-#define gaim_gtk_conv_window_get_gtkconv_at_index pidgin_conv_window_get_gtkconv_at_index
-#define gaim_gtk_conv_window_get_gtkconv_count pidgin_conv_window_get_gtkconv_count
-#define gaim_gtk_conv_window_get_gtkconvs pidgin_conv_window_get_gtkconvs
-#define gaim_gtk_conv_window_has_focus pidgin_conv_window_has_focus
-#define gaim_gtk_conv_window_hide pidgin_conv_window_hide
-#define gaim_gtk_conv_window_is_active_conversation pidgin_conv_window_is_active_conversation
-#define gaim_gtk_conv_window_last_with_type pidgin_conv_window_last_with_type
-#define gaim_gtk_conv_window_new pidgin_conv_window_new
-#define gaim_gtk_conv_window_raise pidgin_conv_window_raise
-#define gaim_gtk_conv_window_remove_gtkconv pidgin_conv_window_remove_gtkconv
-#define gaim_gtk_conv_windows_get_list pidgin_conv_windows_get_list
-#define gaim_gtk_conv_window_show pidgin_conv_window_show
-#define gaim_gtk_conv_window_switch_gtkconv pidgin_conv_window_switch_gtkconv
-#define gaim_gtk_create_imhtml pidgin_create_imhtml
-#define gaim_gtk_debug_get_handle pidgin_debug_get_handle
-#define gaim_gtk_debug_get_ui_ops pidgin_debug_get_ui_ops
-#define gaim_gtk_debug_init pidgin_debug_init
-#define gaim_gtk_debug_uninit pidgin_debug_uninit
-#define gaim_gtk_debug_window_hide pidgin_debug_window_hide
-#define gaim_gtk_debug_window_show pidgin_debug_window_show
-#define gaim_gtkdialogs_about pidgin_dialogs_about
-#define gaim_gtkdialogs_alias_buddy pidgin_dialogs_alias_buddy
-#define gaim_gtkdialogs_alias_chat pidgin_dialogs_alias_chat
-#define gaim_gtkdialogs_alias_contact pidgin_dialogs_alias_contact
-#define gaim_gtkdialogs_destroy_all pidgin_dialogs_destroy_all
-#define gaim_gtkdialogs_im pidgin_dialogs_im
-#define gaim_gtkdialogs_im_with_user pidgin_dialogs_im_with_user
-#define gaim_gtkdialogs_info pidgin_dialogs_info
-#define gaim_gtkdialogs_log pidgin_dialogs_log
-#define gaim_gtkdialogs_merge_groups pidgin_dialogs_merge_groups
-#define gaim_gtkdialogs_remove_buddy pidgin_dialogs_remove_buddy
-#define gaim_gtkdialogs_remove_chat pidgin_dialogs_remove_chat
-#define gaim_gtkdialogs_remove_contact pidgin_dialogs_remove_contact
-#define gaim_gtkdialogs_remove_group pidgin_dialogs_remove_group
-#define gaim_gtk_docklet_clicked pidgin_docklet_clicked
-#define gaim_gtk_docklet_embedded pidgin_docklet_embedded
-#define gaim_gtk_docklet_get_handle pidgin_docklet_get_handle
-#define gaim_gtk_docklet_init pidgin_docklet_init
-#define gaim_gtk_docklet_remove pidgin_docklet_remove
-#define gaim_gtk_docklet_set_ui_ops pidgin_docklet_set_ui_ops
-#define gaim_gtk_docklet_uninit pidgin_docklet_uninit
-#define gaim_gtk_docklet_unload pidgin_docklet_unload
-#define gaim_gtk_eventloop_get_ui_ops pidgin_eventloop_get_ui_ops
-#define gaim_gtk_idle_get_ui_ops pidgin_idle_get_ui_ops
-#define GaimGtkImPane PidginImPane
-#define gaim_gtk_load_accels pidgin_load_accels
-#define gaim_gtk_log_get_handle pidgin_log_get_handle
-#define gaim_gtk_log_init pidgin_log_init
-#define gaim_gtk_log_show_contact pidgin_log_show_contact
-#define gaim_gtk_log_show pidgin_log_show
-#define gaim_gtk_log_uninit pidgin_log_uninit
-#define GaimGtkLogViewer PidginLogViewer
-#define gaim_gtk_make_frame pidgin_make_frame
-#define gaim_gtk_make_mini_dialog pidgin_make_mini_dialog
-#define gaim_gtk_make_pretty_arrows pidgin_make_pretty_arrows
-#define gaim_gtk_menu_tray_append pidgin_menu_tray_append
-#define GaimGtkMenuTrayClass PidginMenuTrayClass
-#define gaim_gtk_menu_tray_get_box pidgin_menu_tray_get_box
-#define gaim_gtk_menu_tray_get_gtype pidgin_menu_tray_get_gtype
-#define gaim_gtk_menu_tray_new pidgin_menu_tray_new
-#define GaimGtkMenuTray PidginMenuTray
-#define GAIM_GTK_MENU_TRAY PIDGIN_MENU_TRAY
-#define gaim_gtk_menu_tray_prepend pidgin_menu_tray_prepend
-#define gaim_gtk_menu_tray_set_tooltip pidgin_menu_tray_set_tooltip
-#define GAIM_GTK_MODIFY_ACCOUNT_DIALOG PIDGIN_MODIFY_ACCOUNT_DIALOG
-#define gaim_gtk_notify_get_ui_ops pidgin_notify_get_ui_ops
-#define gaim_gtk_parse_x_im_contact pidgin_parse_x_im_contact
-#define gaim_gtk_plugin_dialog_show pidgin_plugin_dialog_show
-#define gaim_gtk_plugin_get_config_frame pidgin_plugin_get_config_frame
-#define GAIM_GTK_PLUGIN PIDGIN_PLUGIN
-#define gaim_gtk_plugin_pref_create_frame pidgin_plugin_pref_create_frame
-#define gaim_gtk_plugins_save pidgin_plugins_save
-#define GAIM_GTK_PLUGIN_TYPE PIDGIN_PLUGIN_TYPE
-#define GaimGtkPluginUiInfo PidginPluginUiInfo
-#define GAIM_GTK_PLUGIN_UI_INFO PIDGIN_PLUGIN_UI_INFO
-#define gaim_gtk_pounce_editor_show pidgin_pounce_editor_show
-#define gaim_gtk_pounces_get_handle pidgin_pounces_get_handle
-#define gaim_gtk_pounces_init pidgin_pounces_init
-#define gaim_gtk_pounces_manager_hide pidgin_pounces_manager_hide
-#define gaim_gtk_pounces_manager_show pidgin_pounces_manager_show
-#define gaim_gtk_prefs_checkbox pidgin_prefs_checkbox
-#define gaim_gtk_prefs_dropdown_from_list pidgin_prefs_dropdown_from_list
-#define gaim_gtk_prefs_dropdown pidgin_prefs_dropdown
-#define gaim_gtk_prefs_init pidgin_prefs_init
-#define gaim_gtk_prefs_labeled_entry pidgin_prefs_labeled_entry
-#define gaim_gtk_prefs_labeled_spin_button pidgin_prefs_labeled_spin_button
-#define gaim_gtk_prefs_show pidgin_prefs_show
-#define gaim_gtk_prefs_update_old pidgin_prefs_update_old
-#define gaim_gtk_privacy_dialog_hide pidgin_privacy_dialog_hide
-#define gaim_gtk_privacy_dialog_show pidgin_privacy_dialog_show
-#define gaim_gtk_privacy_get_ui_ops pidgin_privacy_get_ui_ops
-#define gaim_gtk_privacy_init pidgin_privacy_init
-#define gaim_gtk_protocol_option_menu_new pidgin_protocol_option_menu_new
-#define gaim_gtk_request_add_block pidgin_request_add_block
-#define gaim_gtk_request_add_permit pidgin_request_add_permit
-#define gaim_gtk_request_get_ui_ops pidgin_request_get_ui_ops
-#define gaim_gtk_roomlist_dialog_show pidgin_roomlist_dialog_show
-#define gaim_gtk_roomlist_dialog_show_with_account pidgin_roomlist_dialog_show_with_account
-#define gaim_gtk_roomlist_init pidgin_roomlist_init
-#define gaim_gtk_roomlist_is_showable pidgin_roomlist_is_showable
-#define gaim_gtk_save_accels_cb pidgin_save_accels_cb
-#define gaim_gtk_save_accels pidgin_save_accels
-#define gaim_gtk_session_end pidgin_session_end
-#define gaim_gtk_session_init pidgin_session_init
-#define gaim_gtk_set_cursor pidgin_set_cursor
-#define gaim_gtk_set_custom_buddy_icon pidgin_set_custom_buddy_icon
-#define gaim_gtk_set_sensitive_if_input pidgin_set_sensitive_if_input
-#define gaim_gtk_setup_gtkspell pidgin_setup_gtkspell
-#define gaim_gtk_setup_screenname_autocomplete pidgin_setup_screenname_autocomplete
-#define gaim_gtk_set_urgent pidgin_set_urgent
-#define gaim_gtk_sound_get_event_label pidgin_sound_get_event_label
-#define gaim_gtk_sound_get_event_option pidgin_sound_get_event_option
-#define gaim_gtk_sound_get_handle pidgin_sound_get_handle
-#define gaim_gtk_sound_get_ui_ops pidgin_sound_get_ui_ops
-#define gaim_gtk_status_editor_show pidgin_status_editor_show
-#define gaim_gtk_status_get_handle pidgin_status_get_handle
-#define gaim_gtk_status_init pidgin_status_init
-#define gaim_gtk_status_menu pidgin_status_menu
-#define gaim_gtk_status_uninit pidgin_status_uninit
-#define gaim_gtk_status_window_hide pidgin_status_window_hide
-#define gaim_gtk_status_window_show pidgin_status_window_show
-#define gaim_gtk_stock_init pidgin_stock_init
-#define gaim_gtk_syslog_show pidgin_syslog_show
-#define gaim_gtkthemes_get_proto_smileys pidgin_themes_get_proto_smileys
-#define gaim_gtkthemes_init pidgin_themes_init
-#define gaim_gtkthemes_load_smiley_theme pidgin_themes_load_smiley_theme
-#define gaim_gtkthemes_smileys_disabled pidgin_themes_smileys_disabled
-#define gaim_gtkthemes_smiley_themeize pidgin_themes_smiley_themeize
-#define gaim_gtkthemes_smiley_theme_probe pidgin_themes_smiley_theme_probe
-#define gaim_gtk_toggle_sensitive_array pidgin_toggle_sensitive_array
-#define gaim_gtk_toggle_sensitive pidgin_toggle_sensitive
-#define gaim_gtk_toggle_showhide pidgin_toggle_showhide
-#define gaim_gtk_treeview_popup_menu_position_func pidgin_treeview_popup_menu_position_func
-#define gaim_gtk_tree_view_search_equal_func pidgin_tree_view_search_equal_func
-#define GAIM_GTK_TYPE_MENU_TRAY PIDGIN_TYPE_MENU_TRAY
-#define GAIM_GTK_UI PIDGIN_UI
-#define gaim_gtk_whiteboard_get_ui_ops pidgin_whiteboard_get_ui_ops
-#define GaimGtkWhiteboard PidginWhiteboard
-#define GaimGtkWindow PidginWindow
-#define gaim_gtkxfer_dialog_add_xfer pidgin_xfer_dialog_add_xfer
-#define gaim_gtkxfer_dialog_cancel_xfer pidgin_xfer_dialog_cancel_xfer
-#define gaim_gtkxfer_dialog_destroy pidgin_xfer_dialog_destroy
-#define gaim_gtkxfer_dialog_hide pidgin_xfer_dialog_hide
-#define gaim_gtkxfer_dialog_new pidgin_xfer_dialog_new
-#define GaimGtkXferDialog PidginXferDialog
-#define gaim_gtkxfer_dialog_remove_xfer pidgin_xfer_dialog_remove_xfer
-#define gaim_gtkxfer_dialog_show pidgin_xfer_dialog_show
-#define gaim_gtkxfer_dialog_update_xfer pidgin_xfer_dialog_update_xfer
-#define gaim_gtk_xfers_get_ui_ops pidgin_xfers_get_ui_ops
-#define gaim_gtk_xfers_init pidgin_xfers_init
-#define gaim_gtk_xfers_uninit pidgin_xfers_uninit
-#define GAIM_HIG_BORDER PIDGIN_HIG_BORDER
-#define GAIM_HIG_BOX_SPACE PIDGIN_HIG_BOX_SPACE
-#define GAIM_HIG_CAT_SPACE PIDGIN_HIG_CAT_SPACE
-#if !GTK_CHECK_VERSION(2,16,0)
-#define GAIM_INVISIBLE_CHAR PIDGIN_INVISIBLE_CHAR
-#endif /* Less than GTK+ 2.16 */
-#define GAIM_IS_GTK_CONVERSATION PIDGIN_IS_PIDGIN_CONVERSATION
-#define GAIM_IS_GTK_PLUGIN PIDGIN_IS_PIDGIN_PLUGIN
-#define gaim_new_check_item pidgin_new_check_item
-#define gaim_new_item_from_stock pidgin_new_item_from_stock
-#define gaim_new_item pidgin_new_item
-#define gaim_pixbuf_button_from_stock pidgin_pixbuf_button_from_stock
-#define gaim_pixbuf_toolbar_button_from_stock pidgin_pixbuf_toolbar_button_from_stock
-#define GaimScrollBookClass PidginScrollBookClass
-#define gaim_scroll_book_get_type pidgin_scroll_book_get_type
-#define gaim_scroll_book_new pidgin_scroll_book_new
-#define GaimScrollBook PidginScrollBook
-#define gaim_separator pidgin_separator
-#define gaim_set_accessible_label pidgin_set_accessible_label
-#define gaim_set_gtkxfer_dialog pidgin_set_xfer_dialog
-#define gaim_setup_imhtml pidgin_setup_imhtml
-#define gaim_status_box_add pidgin_status_box_add
-#define gaim_status_box_add_separator pidgin_status_box_add_separator
-#define GaimStatusBoxClass PidginStatusBoxClass
-#define gaim_status_box_get_buddy_icon pidgin_status_box_get_buddy_icon
-#define gaim_status_box_get_message pidgin_status_box_get_message
-#define gaim_status_box_get_type pidgin_status_box_get_type
-#define GaimStatusBoxItemType PidginStatusBoxItemType
-#define gaim_status_box_new pidgin_status_box_new
-#define gaim_status_box_new_with_account pidgin_status_box_new_with_account
-#define GaimStatusBox PidginStatusBox
-#define gaim_status_box_pulse_connecting pidgin_status_box_pulse_connecting
-#define gaim_status_box_set_buddy_icon pidgin_status_box_set_buddy_icon
-#define gaim_status_box_set_connecting pidgin_status_box_set_connecting
-#define gaim_status_box_set_network_available pidgin_status_box_set_network_available
-#define GAIM_STATUS_ICON_LARGE PIDGIN_STATUS_ICON_LARGE
-#define GaimStatusIconSize PidginStatusIconSize
-#define GAIM_STATUS_ICON_SMALL PIDGIN_STATUS_ICON_SMALL
-#define GAIM_STOCK_ABOUT PIDGIN_STOCK_ABOUT
-#define GAIM_STOCK_ACTION PIDGIN_STOCK_ACTION
-#define GAIM_STOCK_ALIAS PIDGIN_STOCK_ALIAS
-#define GAIM_STOCK_AWAY PIDGIN_STOCK_AWAY
-#define GAIM_STOCK_CHAT PIDGIN_STOCK_CHAT
-#define GAIM_STOCK_CLEAR PIDGIN_STOCK_CLEAR
-#define GAIM_STOCK_CLOSE_TABS PIDGIN_STOCK_CLOSE_TABS
-#define GAIM_STOCK_DEBUG PIDGIN_STOCK_DEBUG
-#define GAIM_STOCK_DIALOG_AUTH PIDGIN_STOCK_DIALOG_AUTH
-#define GAIM_STOCK_DIALOG_COOL PIDGIN_STOCK_DIALOG_COOL
-#define GAIM_STOCK_DIALOG_ERROR PIDGIN_STOCK_DIALOG_ERROR
-#define GAIM_STOCK_DIALOG_INFO PIDGIN_STOCK_DIALOG_INFO
-#define GAIM_STOCK_DIALOG_QUESTION PIDGIN_STOCK_DIALOG_QUESTION
-#define GAIM_STOCK_DIALOG_WARNING PIDGIN_STOCK_DIALOG_WARNING
-#define GAIM_STOCK_DISCONNECT PIDGIN_STOCK_DISCONNECT
-#define GAIM_STOCK_DOWNLOAD PIDGIN_STOCK_DOWNLOAD
-#define GAIM_STOCK_EDIT PIDGIN_STOCK_EDIT
-#define GAIM_STOCK_FGCOLOR PIDGIN_STOCK_FGCOLOR
-#define GAIM_STOCK_FILE_CANCELED PIDGIN_STOCK_FILE_CANCELED
-#define GAIM_STOCK_FILE_DONE PIDGIN_STOCK_FILE_DONE
-#define GAIM_STOCK_FILE_TRANSFER PIDGIN_STOCK_FILE_TRANSFER
-#define GAIM_STOCK_IGNORE PIDGIN_STOCK_IGNORE
-#define GAIM_STOCK_IM "gaim-im" /* foo... */
-#define GAIM_STOCK_INVITE PIDGIN_STOCK_INVITE
-#define GAIM_STOCK_MODIFY PIDGIN_STOCK_MODIFY
-#define GAIM_STOCK_OPEN_MAIL PIDGIN_STOCK_OPEN_MAIL
-#define GAIM_STOCK_PAUSE PIDGIN_STOCK_PAUSE
-#define GAIM_STOCK_POUNCE PIDGIN_STOCK_POUNCE
-#define GAIM_STOCK_SIGN_OFF PIDGIN_STOCK_SIGN_OFF
-#define GAIM_STOCK_SIGN_ON PIDGIN_STOCK_SIGN_ON
-#define GAIM_STOCK_STATUS_OFFLINE PIDGIN_STOCK_STATUS_OFFLINE
-#define GAIM_STOCK_TEXT_NORMAL PIDGIN_STOCK_TEXT_NORMAL
-#define GAIM_STOCK_TYPED PIDGIN_STOCK_TYPED
-#define GAIM_STOCK_UPLOAD PIDGIN_STOCK_UPLOAD
-#define GAIM_TYPE_GTK_CELL_RENDERER_EXPANDER PIDGIN_TYPE_GTK_CELL_RENDERER_EXPANDER
-#define GAIM_TYPE_GTK_CELL_RENDERER_PROGRESS PIDGIN_TYPE_GTK_CELL_RENDERER_PROGRESS
-#define GAIM_UNSEEN_EVENT PIDGIN_UNSEEN_EVENT
-#define GAIM_UNSEEN_NICK PIDGIN_UNSEEN_NICK
-#define GAIM_UNSEEN_NO_LOG PIDGIN_UNSEEN_NO_LOG
-#define GAIM_UNSEEN_NONE PIDGIN_UNSEEN_NONE
-#define GaimUnseenState PidginUnseenState
-#define GAIM_UNSEEN_TEXT PIDGIN_UNSEEN_TEXT
-#define GAIM_WINDOW_ICONIFIED PIDGIN_WINDOW_ICONIFIED
-#define GTK_GAIM_IS_SCROLL_BOOK_CLASS PIDGIN_IS_SCROLL_BOOK_CLASS
-#define GTK_GAIM_IS_SCROLL_BOOK PIDGIN_IS_SCROLL_BOOK
-#define GTK_GAIM_IS_STATUS_BOX_CLASS PIDGIN_IS_STATUS_BOX_CLASS
-#define GTK_GAIM_IS_STATUS_BOX PIDGIN_IS_STATUS_BOX
-#define GTK_GAIM_SCROLL_BOOK_CLASS PIDGIN_SCROLL_BOOK_CLASS
-#define GTK_GAIM_SCROLL_BOOK_GET_CLASS PIDGIN_SCROLL_BOOK_GET_CLASS
-#define gtk_gaim_scroll_book_get_type pidgin_scroll_book_get_type
-#define gtk_gaim_scroll_book_new pidgin_scroll_book_new
-#define GTK_GAIM_SCROLL_BOOK PIDGIN_SCROLL_BOOK
-#define gtk_gaim_status_box_add pidgin_status_box_add
-#define gtk_gaim_status_box_add_separator pidgin_status_box_add_separator
-#define GTK_GAIM_STATUS_BOX_CLASS PIDGIN_STATUS_BOX_CLASS
-#define gtk_gaim_status_box_get_buddy_icon pidgin_status_box_get_buddy_icon
-#define GTK_GAIM_STATUS_BOX_GET_CLASS PIDGIN_STATUS_BOX_GET_CLASS
-#define gtk_gaim_status_box_get_message pidgin_status_box_get_message
-#define gtk_gaim_status_box_get_type pidgin_status_box_get_type
-#define GtkGaimStatusBoxItemType PidginStatusBoxItemType
-#define gtk_gaim_status_box_new pidgin_status_box_new
-#define gtk_gaim_status_box_new_with_account pidgin_status_box_new_with_account
-#define GTK_GAIM_STATUS_BOX_NUM_TYPES PIDGIN_STATUS_BOX_NUM_TYPES
-#define GtkGaimStatusBox PidginStatusBox
-#define GTK_GAIM_STATUS_BOX PIDGIN_STATUS_BOX
-#define gtk_gaim_status_box_pulse_connecting pidgin_status_box_pulse_connecting
-#define gtk_gaim_status_box_set_buddy_icon pidgin_status_box_set_buddy_icon
-#define gtk_gaim_status_box_set_connecting pidgin_status_box_set_connecting
-#define gtk_gaim_status_box_set_network_available pidgin_status_box_set_network_available
-#define GTK_GAIM_STATUS_BOX_TYPE_CUSTOM PIDGIN_STATUS_BOX_TYPE_CUSTOM
-#define GTK_GAIM_STATUS_BOX_TYPE_POPULAR PIDGIN_STATUS_BOX_TYPE_POPULAR
-#define GTK_GAIM_STATUS_BOX_TYPE_PRIMITIVE PIDGIN_STATUS_BOX_TYPE_PRIMITIVE
-#define GTK_GAIM_STATUS_BOX_TYPE_SAVED PIDGIN_STATUS_BOX_TYPE_SAVED
-#define GTK_GAIM_STATUS_BOX_TYPE_SEPARATOR PIDGIN_STATUS_BOX_TYPE_SEPARATOR
-#define GTK_GAIM_TYPE_SCROLL_BOOK PIDGIN_TYPE_SCROLL_BOOK
-#define GTK_GAIM_TYPE_STATUS_BOX PIDGIN_TYPE_STATUS_BOX
-
-#endif /* _GTKGAIM_COMPAT_H */
diff --git a/pidgin/gtkicon-theme-loader.c b/pidgin/gtkicon-theme-loader.c
index e5818da667..d488ade28b 100644
--- a/pidgin/gtkicon-theme-loader.c
+++ b/pidgin/gtkicon-theme-loader.c
@@ -31,23 +31,26 @@
*****************************************************************************/
static PurpleTheme *
-pidgin_icon_loader_build(const gchar *dir)
+pidgin_icon_loader_build(const gchar *theme_dir)
{
xmlnode *root_node = NULL, *sub_node;
- gchar *filename_full, *data = NULL;
+ gchar *dir, *filename_full, *data = NULL;
PidginIconTheme *theme = NULL;
const gchar *name;
/* Find the theme file */
- g_return_val_if_fail(dir != NULL, NULL);
+ g_return_val_if_fail(theme_dir != NULL, NULL);
+ dir = g_build_filename(theme_dir, "purple", "status-icon", NULL);
filename_full = g_build_filename(dir, "theme.xml", NULL);
if (g_file_test(filename_full, G_FILE_TEST_IS_REGULAR))
root_node = xmlnode_from_file(dir, "theme.xml", "icon themes", "icon-theme-loader");
g_free(filename_full);
- if (root_node == NULL)
+ if (root_node == NULL) {
+ g_free(dir);
return NULL;
+ }
name = xmlnode_get_attrib(root_node, "name");
diff --git a/pidgin/gtkicon-theme.c b/pidgin/gtkicon-theme.c
index feca1dd7ef..b669d93522 100644
--- a/pidgin/gtkicon-theme.c
+++ b/pidgin/gtkicon-theme.c
@@ -26,7 +26,7 @@
#include <gtk/gtk.h>
#define PIDGIN_ICON_THEME_GET_PRIVATE(Gobject) \
- ((PidginIconThemePrivate *) ((PIDGIN_ICON_THEME(Gobject))->priv))
+ (G_TYPE_INSTANCE_GET_PRIVATE((Gobject), PIDGIN_TYPE_ICON_THEME, PidginIconThemePrivate))
/******************************************************************************
* Structs
@@ -53,8 +53,6 @@ pidgin_icon_theme_init(GTypeInstance *instance,
{
PidginIconThemePrivate *priv;
- (PIDGIN_ICON_THEME(instance))->priv = g_new0(PidginIconThemePrivate, 1);
-
priv = PIDGIN_ICON_THEME_GET_PRIVATE(instance);
priv->icon_files = g_hash_table_new_full(g_str_hash,
@@ -69,7 +67,6 @@ pidgin_icon_theme_finalize(GObject *obj)
priv = PIDGIN_ICON_THEME_GET_PRIVATE(obj);
g_hash_table_destroy(priv->icon_files);
- g_free(priv);
parent_class->finalize(obj);
}
@@ -82,6 +79,8 @@ pidgin_icon_theme_class_init(PidginIconThemeClass *klass)
parent_class = g_type_class_peek_parent(klass);
obj_class->finalize = pidgin_icon_theme_finalize;
+
+ g_type_class_add_private(klass, sizeof(PidginIconThemePrivate));
}
GType
diff --git a/pidgin/gtkicon-theme.h b/pidgin/gtkicon-theme.h
index ce67048ba8..18d0d24497 100644
--- a/pidgin/gtkicon-theme.h
+++ b/pidgin/gtkicon-theme.h
@@ -50,7 +50,6 @@ typedef struct _PidginIconThemeClass PidginIconThemeClass;
struct _PidginIconTheme
{
PurpleTheme parent;
- gpointer priv;
};
struct _PidginIconThemeClass
diff --git a/pidgin/gtkidle.c b/pidgin/gtkidle.c
index f5cf624b97..39862ca4fb 100644
--- a/pidgin/gtkidle.c
+++ b/pidgin/gtkidle.c
@@ -107,14 +107,16 @@ pidgin_get_time_idle(void)
int event_base, error_base;
if (has_extension == -1)
- has_extension = XScreenSaverQueryExtension(GDK_DISPLAY(), &event_base, &error_base);
+ has_extension = XScreenSaverQueryExtension(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
+ &event_base, &error_base);
if (has_extension)
{
if (mit_info == NULL)
mit_info = XScreenSaverAllocInfo();
- XScreenSaverQueryInfo(GDK_DISPLAY(), GDK_ROOT_WINDOW(), mit_info);
+ XScreenSaverQueryInfo(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
+ GDK_ROOT_WINDOW(), mit_info);
return (mit_info->idle) / 1000;
}
else
diff --git a/pidgin/gtkidle.h b/pidgin/gtkidle.h
index d869584d28..aee04ccf23 100644
--- a/pidgin/gtkidle.h
+++ b/pidgin/gtkidle.h
@@ -28,6 +28,8 @@
#include "idle.h"
+G_BEGIN_DECLS
+
/**************************************************************************/
/** @name GTK+ Idle API */
/**************************************************************************/
@@ -42,4 +44,6 @@ PurpleIdleUiOps *pidgin_idle_get_ui_ops(void);
/*@}*/
+G_END_DECLS
+
#endif /* _PIDGIN_IDLE_H_ */
diff --git a/pidgin/gtkimhtml.c b/pidgin/gtkimhtml.c
index 905430fcea..579f1730ed 100644
--- a/pidgin/gtkimhtml.c
+++ b/pidgin/gtkimhtml.c
@@ -65,6 +65,16 @@
#define TOOLTIP_TIMEOUT 500
+#if !GTK_CHECK_VERSION(2,20,0)
+#define gtk_widget_get_realized(x) GTK_WIDGET_REALIZED(x)
+
+#if !GTK_CHECK_VERSION(2,18,0)
+#define gtk_widget_get_has_window(x) !GTK_WIDGET_NO_WINDOW(x)
+#define gtk_widget_get_state(x) GTK_WIDGET_STATE(x)
+#define gtk_widget_is_drawable(x) GTK_WIDGET_DRAWABLE(x)
+#endif
+#endif
+
static GtkTextViewClass *parent_class = NULL;
struct scalable_data {
@@ -83,6 +93,36 @@ struct im_image_data {
GtkTextMark *mark;
};
+struct _GtkIMHtmlScalable {
+ void (*scale)(struct _GtkIMHtmlScalable *, int, int);
+ void (*add_to)(struct _GtkIMHtmlScalable *, GtkIMHtml *, GtkTextIter *);
+ void (*free)(struct _GtkIMHtmlScalable *);
+};
+
+struct _GtkIMHtmlHr {
+ GtkIMHtmlScalable scalable;
+ GtkWidget *sep;
+};
+
+struct _GtkIMHtmlImage {
+ GtkIMHtmlScalable scalable;
+ GtkImage *image; /**< Contains the scaled version of this pixbuf. */
+ GdkPixbuf *pixbuf; /**< The original pixbuf, before any scaling. */
+ GtkTextMark *mark;
+ gchar *filename;
+ int width;
+ int height;
+ int id;
+ GtkWidget *filesel;
+};
+
+struct _GtkIMHtmlAnimation {
+ GtkIMHtmlImage imhtmlimage;
+ GdkPixbufAnimation *anim; /**< The original animation, before any scaling. */
+ GdkPixbufAnimationIter *iter;
+ guint timer;
+};
+
struct _GtkIMHtmlLink
{
GtkIMHtml *imhtml;
@@ -90,8 +130,13 @@ struct _GtkIMHtmlLink
GtkTextTag *tag;
};
-typedef struct _GtkIMHtmlProtocol
-{
+struct _GtkSmileyTree {
+ GString *values;
+ GtkSmileyTree **children;
+ GtkIMHtmlSmiley *image;
+};
+
+typedef struct {
char *name;
int length;
@@ -99,7 +144,8 @@ typedef struct _GtkIMHtmlProtocol
gboolean (*context_menu)(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu);
} GtkIMHtmlProtocol;
-typedef struct _GtkIMHtmlFontDetail {
+/* The five elements contained in a FONT tag */
+typedef struct {
gushort size;
gchar *face;
gchar *fore;
@@ -422,7 +468,7 @@ static void gtk_imhtml_size_allocate(GtkWidget *widget, GtkAllocation *alloc)
/* Don't scroll here if we're in the middle of a smooth scroll */
if (scroll && imhtml->scroll_time == NULL &&
- GTK_WIDGET_REALIZED(imhtml))
+ gtk_widget_get_realized(GTK_WIDGET(imhtml)))
gtk_imhtml_scroll_to_end(imhtml, FALSE);
}
@@ -539,7 +585,7 @@ gtk_imhtml_tip (gpointer data)
g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE);
- if (!imhtml->tip || !GTK_WIDGET_DRAWABLE (GTK_WIDGET(imhtml))) {
+ if (!imhtml->tip || !gtk_widget_is_drawable (GTK_WIDGET(imhtml))) {
imhtml->tip_timer = 0;
return FALSE;
}
@@ -592,7 +638,7 @@ gtk_imhtml_tip (gpointer data)
h = 8 + baseline_skip;
gdk_window_get_pointer (NULL, &x, &y, NULL);
- if (GTK_WIDGET_NO_WINDOW (GTK_WIDGET(imhtml)))
+ if (!gtk_widget_get_has_window (GTK_WIDGET(imhtml)))
y += GTK_WIDGET(imhtml)->allocation.y;
scr_w = gdk_screen_width();
@@ -788,7 +834,7 @@ gtk_imhtml_expose_event (GtkWidget *widget,
gdk_color_parse(GTK_IMHTML(widget)->edit.background, &gcolor);
gdk_cairo_set_source_color(cr, &gcolor);
} else {
- gdk_cairo_set_source_color(cr, &(widget->style->base[GTK_WIDGET_STATE(widget)]));
+ gdk_cairo_set_source_color(cr, &(widget->style->base[gtk_widget_get_state(widget)]));
}
cairo_rectangle(cr,
@@ -3593,125 +3639,38 @@ void gtk_imhtml_page_down (GtkIMHtml *imhtml)
gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(imhtml), &iter, 0, TRUE, 0, 0);
}
-/* GtkIMHtmlScalable, gtk_imhtml_image, gtk_imhtml_hr */
-GtkIMHtmlScalable *gtk_imhtml_image_new(GdkPixbuf *img, const gchar *filename, int id)
-{
- GtkIMHtmlImage *im_image = g_malloc(sizeof(GtkIMHtmlImage));
-
- GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale;
- GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to;
- GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_image_free;
-
- im_image->pixbuf = img;
- im_image->image = GTK_IMAGE(gtk_image_new_from_pixbuf(im_image->pixbuf));
- im_image->width = gdk_pixbuf_get_width(img);
- im_image->height = gdk_pixbuf_get_height(img);
- im_image->mark = NULL;
- im_image->filename = g_strdup(filename);
- im_image->id = id;
- im_image->filesel = NULL;
-
- g_object_ref(img);
- return GTK_IMHTML_SCALABLE(im_image);
-}
-
-static gboolean
-animate_image_cb(gpointer data)
-{
- GtkIMHtmlImage *im_image;
- int width, height;
- int delay;
-
- im_image = data;
-
- /* Update the pointer to this GdkPixbuf frame of the animation */
- if (gdk_pixbuf_animation_iter_advance(GTK_IMHTML_ANIMATION(im_image)->iter, NULL)) {
- GdkPixbuf *pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter);
- g_object_unref(G_OBJECT(im_image->pixbuf));
- im_image->pixbuf = gdk_pixbuf_copy(pb);
-
- /* Update the displayed GtkImage */
- width = gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image));
- height = gdk_pixbuf_get_height(gtk_image_get_pixbuf(im_image->image));
- if (width > 0 && height > 0)
- {
- /* Need to scale the new frame to the same size as the old frame */
- GdkPixbuf *tmp;
- tmp = gdk_pixbuf_scale_simple(im_image->pixbuf, width, height, GDK_INTERP_BILINEAR);
- gtk_image_set_from_pixbuf(im_image->image, tmp);
- g_object_unref(G_OBJECT(tmp));
- } else {
- /* Display at full-size */
- gtk_image_set_from_pixbuf(im_image->image, im_image->pixbuf);
- }
- }
-
- delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100);
- GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image);
-
- return FALSE;
-}
-
-GtkIMHtmlScalable *gtk_imhtml_animation_new(GdkPixbufAnimation *anim, const gchar *filename, int id)
+/**
+ * Destroys and frees a GTK+ IM/HTML scalable image.
+ *
+ * @param scale The GTK+ IM/HTML scalable.
+ */
+static void gtk_imhtml_image_free(GtkIMHtmlScalable *scale)
{
- GtkIMHtmlImage *im_image = (GtkIMHtmlImage *) g_new0(GtkIMHtmlAnimation, 1);
-
- GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale;
- GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to;
- GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_animation_free;
-
- GTK_IMHTML_ANIMATION(im_image)->anim = anim;
- if (gdk_pixbuf_animation_is_static_image(anim)) {
- im_image->pixbuf = gdk_pixbuf_animation_get_static_image(anim);
- g_object_ref(im_image->pixbuf);
- } else {
- int delay;
- GdkPixbuf *pb;
- GTK_IMHTML_ANIMATION(im_image)->iter = gdk_pixbuf_animation_get_iter(anim, NULL);
- pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter);
- im_image->pixbuf = gdk_pixbuf_copy(pb);
- delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100);
- GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image);
- }
- im_image->image = GTK_IMAGE(gtk_image_new_from_pixbuf(im_image->pixbuf));
- im_image->width = gdk_pixbuf_animation_get_width(anim);
- im_image->height = gdk_pixbuf_animation_get_height(anim);
- im_image->filename = g_strdup(filename);
- im_image->id = id;
-
- g_object_ref(anim);
+ GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale;
- return GTK_IMHTML_SCALABLE(im_image);
+ g_object_unref(image->pixbuf);
+ g_free(image->filename);
+ if (image->filesel)
+ gtk_widget_destroy(image->filesel);
+ g_free(scale);
}
-void gtk_imhtml_image_scale(GtkIMHtmlScalable *scale, int width, int height)
+/**
+ * Destroys and frees a GTK+ IM/HTML scalable animation.
+ *
+ * @param scale The GTK+ IM/HTML scalable.
+ */
+static void gtk_imhtml_animation_free(GtkIMHtmlScalable *scale)
{
- GtkIMHtmlImage *im_image = (GtkIMHtmlImage *)scale;
-
- if (im_image->width > width || im_image->height > height) {
- double ratio_w, ratio_h, ratio;
- int new_h, new_w;
- GdkPixbuf *new_image = NULL;
-
- ratio_w = ((double)width - 2) / im_image->width;
- ratio_h = ((double)height - 2) / im_image->height;
-
- ratio = (ratio_w < ratio_h) ? ratio_w : ratio_h;
-
- new_w = (int)(im_image->width * ratio);
- new_h = (int)(im_image->height * ratio);
+ GtkIMHtmlAnimation *animation = (GtkIMHtmlAnimation *)scale;
- new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, new_w, new_h, GDK_INTERP_BILINEAR);
- gtk_image_set_from_pixbuf(im_image->image, new_image);
- g_object_unref(G_OBJECT(new_image));
- } else if (gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image)) != im_image->width) {
- /* Enough space to show the full-size of the image. */
- GdkPixbuf *new_image;
+ if (animation->timer > 0)
+ g_source_remove(animation->timer);
+ if (animation->iter != NULL)
+ g_object_unref(animation->iter);
+ g_object_unref(animation->anim);
- new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, im_image->width, im_image->height, GDK_INTERP_BILINEAR);
- gtk_image_set_from_pixbuf(im_image->image, new_image);
- g_object_unref(G_OBJECT(new_image));
- }
+ gtk_imhtml_image_free(scale);
}
static void
@@ -3918,55 +3877,51 @@ static gboolean gtk_imhtml_image_clicked(GtkWidget *w, GdkEvent *event, GtkIMHtm
}
-static gboolean gtk_imhtml_smiley_clicked(GtkWidget *w, GdkEvent *event, GtkIMHtmlSmiley *smiley)
+/**
+ * Rescales a GTK+ IM/HTML scalable image to a given size.
+ *
+ * @param scale The GTK+ IM/HTML scalable.
+ * @param width The new width.
+ * @param height The new height.
+ */
+static void gtk_imhtml_image_scale(GtkIMHtmlScalable *scale, int width, int height)
{
- GdkPixbufAnimation *anim = NULL;
- GtkIMHtmlImageSave *save = NULL;
- gboolean ret;
-
- if (event->type != GDK_BUTTON_RELEASE || ((GdkEventButton*)event)->button != 3)
- return FALSE;
-
- anim = gtk_smiley_get_image(smiley);
- if (!anim)
- return FALSE;
+ GtkIMHtmlImage *im_image = (GtkIMHtmlImage *)scale;
- save = g_new0(GtkIMHtmlImageSave, 1);
- save->image = (GtkIMHtmlScalable *)gtk_imhtml_animation_new(anim, smiley->smile, 0);
- save->data = smiley->data; /* Do not need to memdup here, since the smiley is not
- destroyed before this GtkIMHtmlImageSave */
- save->datasize = smiley->datasize;
- ret = gtk_imhtml_image_clicked(w, event, save);
- g_object_set_data_full(G_OBJECT(w), "image-data", save->image, (GDestroyNotify)gtk_imhtml_animation_free);
- g_object_set_data_full(G_OBJECT(w), "image-save-data", save, (GDestroyNotify)g_free);
- return ret;
-}
+ if (im_image->width > width || im_image->height > height) {
+ double ratio_w, ratio_h, ratio;
+ int new_h, new_w;
+ GdkPixbuf *new_image = NULL;
-void gtk_imhtml_image_free(GtkIMHtmlScalable *scale)
-{
- GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale;
+ ratio_w = ((double)width - 2) / im_image->width;
+ ratio_h = ((double)height - 2) / im_image->height;
- g_object_unref(image->pixbuf);
- g_free(image->filename);
- if (image->filesel)
- gtk_widget_destroy(image->filesel);
- g_free(scale);
-}
+ ratio = (ratio_w < ratio_h) ? ratio_w : ratio_h;
-void gtk_imhtml_animation_free(GtkIMHtmlScalable *scale)
-{
- GtkIMHtmlAnimation *animation = (GtkIMHtmlAnimation *)scale;
+ new_w = (int)(im_image->width * ratio);
+ new_h = (int)(im_image->height * ratio);
- if (animation->timer > 0)
- g_source_remove(animation->timer);
- if (animation->iter != NULL)
- g_object_unref(animation->iter);
- g_object_unref(animation->anim);
+ new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, new_w, new_h, GDK_INTERP_BILINEAR);
+ gtk_image_set_from_pixbuf(im_image->image, new_image);
+ g_object_unref(G_OBJECT(new_image));
+ } else if (gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image)) != im_image->width) {
+ /* Enough space to show the full-size of the image. */
+ GdkPixbuf *new_image;
- gtk_imhtml_image_free(scale);
+ new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, im_image->width, im_image->height, GDK_INTERP_BILINEAR);
+ gtk_image_set_from_pixbuf(im_image->image, new_image);
+ g_object_unref(G_OBJECT(new_image));
+ }
}
-void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter)
+/**
+ * Adds a GTK+ IM/HTML scalable image to a given GTK+ IM/HTML at a given iter.
+ *
+ * @param scale The GTK+ IM/HTML scalable.
+ * @param imhtml The GTK+ IM/HTML.
+ * @param iter The GtkTextIter at which to add the scalable.
+ */
+static void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter)
{
GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale;
GtkWidget *box = gtk_event_box_new();
@@ -3994,6 +3949,121 @@ void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTex
g_object_set_data_full(G_OBJECT(box), "image-save-data", save, (GDestroyNotify)g_free);
}
+/**
+ * Creates and returns a new GTK+ IM/HTML scalable object with an image.
+ *
+ * @param img A GdkPixbuf of the image to add.
+ * @param filename The filename to associate with the image.
+ * @param id The id to associate with the image.
+ *
+ * @return A new IM/HTML Scalable object with an image.
+ */
+static GtkIMHtmlScalable *gtk_imhtml_image_new(GdkPixbuf *img, const gchar *filename, int id)
+{
+ GtkIMHtmlImage *im_image = g_malloc(sizeof(GtkIMHtmlImage));
+
+ GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale;
+ GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to;
+ GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_image_free;
+
+ im_image->pixbuf = img;
+ im_image->image = GTK_IMAGE(gtk_image_new_from_pixbuf(im_image->pixbuf));
+ im_image->width = gdk_pixbuf_get_width(img);
+ im_image->height = gdk_pixbuf_get_height(img);
+ im_image->mark = NULL;
+ im_image->filename = g_strdup(filename);
+ im_image->id = id;
+ im_image->filesel = NULL;
+
+ g_object_ref(img);
+ return GTK_IMHTML_SCALABLE(im_image);
+}
+
+static gboolean
+animate_image_cb(gpointer data)
+{
+ GtkIMHtmlImage *im_image;
+ int width, height;
+ int delay;
+
+ im_image = data;
+
+ /* Update the pointer to this GdkPixbuf frame of the animation */
+ if (gdk_pixbuf_animation_iter_advance(GTK_IMHTML_ANIMATION(im_image)->iter, NULL)) {
+ GdkPixbuf *pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter);
+ g_object_unref(G_OBJECT(im_image->pixbuf));
+ im_image->pixbuf = gdk_pixbuf_copy(pb);
+
+ /* Update the displayed GtkImage */
+ width = gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image));
+ height = gdk_pixbuf_get_height(gtk_image_get_pixbuf(im_image->image));
+ if (width > 0 && height > 0)
+ {
+ /* Need to scale the new frame to the same size as the old frame */
+ GdkPixbuf *tmp;
+ tmp = gdk_pixbuf_scale_simple(im_image->pixbuf, width, height, GDK_INTERP_BILINEAR);
+ gtk_image_set_from_pixbuf(im_image->image, tmp);
+ g_object_unref(G_OBJECT(tmp));
+ } else {
+ /* Display at full-size */
+ gtk_image_set_from_pixbuf(im_image->image, im_image->pixbuf);
+ }
+ }
+
+ delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100);
+ GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image);
+
+ return FALSE;
+}
+
+/**
+ * Creates and returns a new GTK+ IM/HTML scalable object with an
+ * animated image.
+ *
+ * @param img A GdkPixbufAnimation of the image to add.
+ * @param filename The filename to associate with the image.
+ * @param id The id to associate with the image.
+ *
+ * @return A new IM/HTML Scalable object with an image.
+ */
+/*
+ * TODO: All this animation code could be combined much better with
+ * the image code. It couldn't be done when it was written
+ * because it requires breaking backward compatibility. It
+ * would be good to do it for 3.0.0.
+ */
+static GtkIMHtmlScalable *gtk_imhtml_animation_new(GdkPixbufAnimation *anim, const gchar *filename, int id)
+{
+ GtkIMHtmlImage *im_image = (GtkIMHtmlImage *) g_new0(GtkIMHtmlAnimation, 1);
+
+ GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale;
+ GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to;
+ GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_animation_free;
+
+ GTK_IMHTML_ANIMATION(im_image)->anim = anim;
+ if (gdk_pixbuf_animation_is_static_image(anim)) {
+ im_image->pixbuf = gdk_pixbuf_animation_get_static_image(anim);
+ g_object_ref(im_image->pixbuf);
+ } else {
+ int delay;
+ GdkPixbuf *pb;
+ GTK_IMHTML_ANIMATION(im_image)->iter = gdk_pixbuf_animation_get_iter(anim, NULL);
+ pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter);
+ im_image->pixbuf = gdk_pixbuf_copy(pb);
+ delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100);
+ GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image);
+ }
+ im_image->image = GTK_IMAGE(gtk_image_new_from_pixbuf(im_image->pixbuf));
+ im_image->width = gdk_pixbuf_animation_get_width(anim);
+ im_image->height = gdk_pixbuf_animation_get_height(anim);
+ im_image->filename = g_strdup(filename);
+ im_image->id = id;
+
+ g_object_ref(anim);
+
+ return GTK_IMHTML_SCALABLE(im_image);
+}
+
GtkIMHtmlScalable *gtk_imhtml_hr_new()
{
GtkIMHtmlHr *hr = g_malloc(sizeof(GtkIMHtmlHr));
@@ -4918,6 +4988,30 @@ static void animated_smiley_destroy_cb(GtkObject *widget, GtkIMHtml *imhtml)
}
}
+static gboolean gtk_imhtml_smiley_clicked(GtkWidget *w, GdkEvent *event, GtkIMHtmlSmiley *smiley)
+{
+ GdkPixbufAnimation *anim = NULL;
+ GtkIMHtmlImageSave *save = NULL;
+ gboolean ret;
+
+ if (event->type != GDK_BUTTON_RELEASE || ((GdkEventButton*)event)->button != 3)
+ return FALSE;
+
+ anim = gtk_smiley_get_image(smiley);
+ if (!anim)
+ return FALSE;
+
+ save = g_new0(GtkIMHtmlImageSave, 1);
+ save->image = (GtkIMHtmlScalable *)gtk_imhtml_animation_new(anim, smiley->smile, 0);
+ save->data = smiley->data; /* Do not need to memdup here, since the smiley is not
+ destroyed before this GtkIMHtmlImageSave */
+ save->datasize = smiley->datasize;
+ ret = gtk_imhtml_image_clicked(w, event, save);
+ g_object_set_data_full(G_OBJECT(w), "image-data", save->image, (GDestroyNotify)gtk_imhtml_animation_free);
+ g_object_set_data_full(G_OBJECT(w), "image-save-data", save, (GDestroyNotify)g_free);
+ return ret;
+}
+
void gtk_imhtml_insert_smiley_at_iter(GtkIMHtml *imhtml, const char *sml, char *smiley, GtkTextIter *iter)
{
GdkPixbuf *pixbuf = NULL;
@@ -5367,9 +5461,9 @@ char *gtk_imhtml_get_markup_range(GtkIMHtml *imhtml, GtkTextIter *start, GtkText
tag = sl->data;
/** don't worry about non-printing tags ending */
if (tag_ends_here(tag, &iter, &next_iter) &&
- strlen(tag_to_html_end(tag)) > 0 &&
- strlen(tag_to_html_start(tag)) > 0) {
-
+ *tag_to_html_end(tag) &&
+ *tag_to_html_start(tag))
+ {
PidginTextTagData *tmp;
GQueue *r = g_queue_new();
diff --git a/pidgin/gtkimhtml.h b/pidgin/gtkimhtml.h
index d26dcc0d2d..3ba49731c2 100644
--- a/pidgin/gtkimhtml.h
+++ b/pidgin/gtkimhtml.h
@@ -31,9 +31,7 @@
#include "connection.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**************************************************************************
* @name Structures
@@ -50,9 +48,6 @@ extern "C" {
typedef struct _GtkIMHtml GtkIMHtml;
typedef struct _GtkIMHtmlClass GtkIMHtmlClass;
-#if !(defined PIDGIN_DISABLE_DEPRECATED) && !(defined _PIDGIN_GTKIMHTML_C_)
-typedef struct _GtkIMHtmlFontDetail GtkIMHtmlFontDetail; /* The five elements contained in a FONT tag */
-#endif
typedef struct _GtkSmileyTree GtkSmileyTree;
typedef struct _GtkIMHtmlSmiley GtkIMHtmlSmiley;
typedef struct _GtkIMHtmlScalable GtkIMHtmlScalable;
@@ -61,9 +56,6 @@ typedef struct _GtkIMHtmlAnimation GtkIMHtmlAnimation;
typedef struct _GtkIMHtmlHr GtkIMHtmlHr;
typedef struct _GtkIMHtmlFuncs GtkIMHtmlFuncs;
-/**
- * @since 2.6.0
- */
typedef struct _GtkIMHtmlLink GtkIMHtmlLink;
typedef enum {
@@ -81,7 +73,7 @@ typedef enum {
GTK_IMHTML_SMILEY = 1 << 11,
GTK_IMHTML_LINKDESC = 1 << 12,
GTK_IMHTML_STRIKE = 1 << 13,
- /** Show custom smileys when appropriate. @since 2.5.0 */
+ /** Show custom smileys when appropriate. */
GTK_IMHTML_CUSTOM_SMILEY = 1 << 14,
GTK_IMHTML_ALL = -1
} GtkIMHtmlButtons;
@@ -135,16 +127,6 @@ struct _GtkIMHtml {
GtkTextTag *link;
} edit;
-#if !(defined PIDGIN_DISABLE_DEPRECATED) || (defined _PIDGIN_GTKIMHTML_C_)
- /** @deprecated */
- char *clipboard_text_string;
- /** @deprecated */
- char *clipboard_html_string;
-#else
- char *depr1;
- char *depr2;
-#endif
-
GSList *im_images;
GtkIMHtmlFuncs *funcs;
GtkSourceUndoManager *undo_manager;
@@ -164,26 +146,6 @@ struct _GtkIMHtmlClass {
GList *protocols; /* List of GtkIMHtmlProtocol's */
};
-#if !(defined PIDGIN_DISABLE_DEPRECATED) && !(defined _PIDGIN_GTKIMHTML_C_)
-/** @deprecated as of 2.7.10 */
-struct _GtkIMHtmlFontDetail {
- gushort size;
- gchar *face;
- gchar *fore;
- gchar *back;
- gchar *bg;
- gchar *sml;
- gboolean underline;
- gshort bold;
-};
-#endif
-
-struct _GtkSmileyTree {
- GString *values;
- GtkSmileyTree **children;
- GtkIMHtmlSmiley *image;
-};
-
struct _GtkIMHtmlSmiley {
gchar *smile;
gchar *file;
@@ -193,38 +155,8 @@ struct _GtkIMHtmlSmiley {
GSList *anchors;
GtkIMHtmlSmileyFlags flags;
GtkIMHtml *imhtml;
- gpointer data; /** @since 2.6.0 */
- gsize datasize; /** @since 2.6.0 */
-};
-
-struct _GtkIMHtmlScalable {
- void (*scale)(struct _GtkIMHtmlScalable *, int, int);
- void (*add_to)(struct _GtkIMHtmlScalable *, GtkIMHtml *, GtkTextIter *);
- void (*free)(struct _GtkIMHtmlScalable *);
-};
-
-struct _GtkIMHtmlImage {
- GtkIMHtmlScalable scalable;
- GtkImage *image; /**< Contains the scaled version of this pixbuf. */
- GdkPixbuf *pixbuf; /**< The original pixbuf, before any scaling. */
- GtkTextMark *mark;
- gchar *filename;
- int width;
- int height;
- int id;
- GtkWidget *filesel;
-};
-
-struct _GtkIMHtmlAnimation {
- GtkIMHtmlImage imhtmlimage;
- GdkPixbufAnimation *anim; /**< The original animation, before any scaling. */
- GdkPixbufAnimationIter *iter;
- guint timer;
-};
-
-struct _GtkIMHtmlHr {
- GtkIMHtmlScalable scalable;
- GtkWidget *sep;
+ gpointer data;
+ gsize datasize;
};
typedef enum {
@@ -443,73 +375,6 @@ void gtk_imhtml_page_down(GtkIMHtml *imhtml);
GtkIMHtmlScalable *gtk_imhtml_scalable_new(void);
/**
- * Creates and returns a new GTK+ IM/HTML scalable object with an image.
- *
- * @param img A GdkPixbuf of the image to add.
- * @param filename The filename to associate with the image.
- * @param id The id to associate with the image.
- *
- * @return A new IM/HTML Scalable object with an image.
- */
-GtkIMHtmlScalable *gtk_imhtml_image_new(GdkPixbuf *img, const gchar *filename, int id);
-
-/**
- * Creates and returns a new GTK+ IM/HTML scalable object with an
- * animated image.
- *
- * @param img A GdkPixbufAnimation of the image to add.
- * @param filename The filename to associate with the image.
- * @param id The id to associate with the image.
- *
- * @return A new IM/HTML Scalable object with an image.
- *
- * @since 2.1.0
- */
-/*
- * TODO: All this animation code could be combined much better with
- * the image code. It couldn't be done when it was written
- * because it requires breaking backward compatibility. It
- * would be good to do it for 3.0.0.
- */
-GtkIMHtmlScalable *gtk_imhtml_animation_new(GdkPixbufAnimation *img, const gchar *filename, int id);
-
-/**
- * Destroys and frees a GTK+ IM/HTML scalable image.
- *
- * @param scale The GTK+ IM/HTML scalable.
- */
-/* TODO: Is there any reason this isn't private? */
-void gtk_imhtml_image_free(GtkIMHtmlScalable *scale);
-
-/**
- * Destroys and frees a GTK+ IM/HTML scalable animation.
- *
- * @param scale The GTK+ IM/HTML scalable.
- */
-/* TODO: Is there any reason this isn't private? */
-void gtk_imhtml_animation_free(GtkIMHtmlScalable *scale);
-
-/**
- * Rescales a GTK+ IM/HTML scalable image to a given size.
- *
- * @param scale The GTK+ IM/HTML scalable.
- * @param width The new width.
- * @param height The new height.
- */
-/* TODO: Is there any reason this isn't private? */
-void gtk_imhtml_image_scale(GtkIMHtmlScalable *scale, int width, int height);
-
-/**
- * Adds a GTK+ IM/HTML scalable image to a given GTK+ IM/HTML at a given iter.
- *
- * @param scale The GTK+ IM/HTML scalable.
- * @param imhtml The GTK+ IM/HTML.
- * @param iter The GtkTextIter at which to add the scalable.
- */
-/* TODO: Is there any reason this isn't private? */
-void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter);
-
-/**
* Creates and returns an new GTK+ IM/HTML scalable with a horizontal rule.
*
* @return A new IM/HTML Scalable object with an image.
@@ -860,8 +725,6 @@ char *gtk_imhtml_get_text(GtkIMHtml *imhtml, GtkTextIter *start, GtkTextIter *st
*
* @param imhtml The GTK+ IM/HTML.
* @param flags The connection flag which describes the allowed types of formatting.
- *
- * @since 2.1.0
*/
void gtk_imhtml_setup_entry(GtkIMHtml *imhtml, PurpleConnectionFlags flags);
@@ -874,7 +737,6 @@ void gtk_imhtml_setup_entry(GtkIMHtml *imhtml, PurpleConnectionFlags flags);
* @param flags The smiley flags
*
* @return The newly created smiley
- * @since 2.5.0
*/
GtkIMHtmlSmiley *gtk_imhtml_smiley_create(const char *file, const char *shortcut, gboolean hide,
GtkIMHtmlSmileyFlags flags);
@@ -883,8 +745,6 @@ GtkIMHtmlSmiley *gtk_imhtml_smiley_create(const char *file, const char *shortcut
* Reload the image data for the smiley.
*
* @param smiley The smiley to reload
- *
- * @since 2.5.0
*/
void gtk_imhtml_smiley_reload(GtkIMHtmlSmiley *smiley);
@@ -892,8 +752,6 @@ void gtk_imhtml_smiley_reload(GtkIMHtmlSmiley *smiley);
* Destroy a GtkIMHtmlSmiley.
*
* @param smiley The smiley to destroy
- *
- * @since 2.5.0
*/
void gtk_imhtml_smiley_destroy(GtkIMHtmlSmiley *smiley);
@@ -912,8 +770,6 @@ void gtk_imhtml_smiley_destroy(GtkIMHtmlSmiley *smiley);
* successfully, @c FALSE otherwise.
*
* @return @c TRUE if the protocol was successfully registered (or unregistered, when \a activate is @c NULL)
- *
- * @since 2.6.0
*/
gboolean gtk_imhtml_class_register_protocol(const char *name,
gboolean (*activate)(GtkIMHtml *imhtml, GtkIMHtmlLink *link),
@@ -925,8 +781,6 @@ gboolean gtk_imhtml_class_register_protocol(const char *name,
* @param link The GtkIMHtmlLink object sent to the callback functions
*
* @return The URL
- *
- * @since 2.6.0
*/
const char *gtk_imhtml_link_get_url(GtkIMHtmlLink *link);
@@ -936,8 +790,6 @@ const char *gtk_imhtml_link_get_url(GtkIMHtmlLink *link);
* @param link The GtkIMHtmlLink object sent to the callback functions
*
* @return The GtkTextTag object, or @c NULL
- *
- * @since 2.6.0
*/
const GtkTextTag *gtk_imhtml_link_get_text_tag(GtkIMHtmlLink *link);
@@ -948,8 +800,6 @@ const GtkTextTag *gtk_imhtml_link_get_text_tag(GtkIMHtmlLink *link);
* @param link The GtkIMHtmlLink object sent to the callback functions
*
* @return @c TRUE if 'url-clicked' signal was emitted, @c FALSE otherwise.
- *
- * @since 2.6.0
*/
gboolean gtk_imhtml_link_activate(GtkIMHtmlLink *link);
@@ -976,8 +826,6 @@ void gtk_imhtml_set_populate_primary_clipboard(GtkIMHtml *imhtml, gboolean popul
/*@}*/
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PIDGINIMHTML_H_ */
diff --git a/pidgin/gtkimhtmltoolbar.c b/pidgin/gtkimhtmltoolbar.c
index e6d6f7652b..7cde74c931 100644
--- a/pidgin/gtkimhtmltoolbar.c
+++ b/pidgin/gtkimhtmltoolbar.c
@@ -43,6 +43,11 @@
#include <gdk/gdkkeysyms.h>
+#if !GTK_CHECK_VERSION(2,18,0)
+#define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x)
+#define gtk_widget_is_sensitive(x) GTK_WIDGET_IS_SENSITIVE(x)
+#endif
+
static GtkHBoxClass *parent_class = NULL;
static void toggle_button_set_active_block(GtkToggleButton *button,
@@ -658,7 +663,11 @@ sort_smileys(struct smiley_button_list *ls, GtkIMHtmlToolbar *toolbar,
g_object_set_data(G_OBJECT(button), "smiley_text", face);
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(insert_smiley_text), toolbar);
+#if GTK_CHECK_VERSION(2,12,0)
+ gtk_widget_set_tooltip_text(button, face);
+#else
gtk_tooltips_set_tip(toolbar->tooltips, button, face, NULL);
+#endif
/* these look really weird with borders */
gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
@@ -672,7 +681,11 @@ sort_smileys(struct smiley_button_list *ls, GtkIMHtmlToolbar *toolbar,
g_snprintf(tip, sizeof(tip),
_("This smiley is disabled because a custom smiley exists for this shortcut:\n %s"),
face);
+#if GTK_CHECK_VERSION(2,12,0)
+ gtk_widget_set_tooltip_text(button, tip);
+#else
gtk_tooltips_set_tip(toolbar->tooltips, button, tip, NULL);
+#endif
gtk_widget_set_sensitive(button, FALSE);
} else if (psmiley) {
/* Remove the button if the smiley is destroyed */
@@ -904,7 +917,7 @@ static void send_attention_cb(GtkWidget *attention, GtkIMHtmlToolbar *toolbar)
PurpleConversation *conv =
g_object_get_data(G_OBJECT(toolbar), "active_conv");
const gchar *who = purple_conversation_get_name(conv);
- PurpleConnection *gc = purple_conversation_get_gc(conv);
+ PurpleConnection *gc = purple_conversation_get_connection(conv);
toggle_button_set_active_block(GTK_TOGGLE_BUTTON(attention), FALSE, toolbar);
purple_prpl_send_attention(gc, who, 0);
@@ -1155,7 +1168,9 @@ gtk_imhtmltoolbar_finalize (GObject *object)
}
g_free(toolbar->sml);
+#if !GTK_CHECK_VERSION(2,12,0)
gtk_object_sink(GTK_OBJECT(toolbar->tooltips));
+#endif
menu = g_object_get_data(object, "font_menu");
if (menu)
@@ -1186,7 +1201,7 @@ gtk_imhtmltoolbar_popup_menu(GtkWidget *widget, GdkEventButton *event, GtkIMHtml
if (event->button != 3)
return FALSE;
- wide = GTK_WIDGET_VISIBLE(toolbar->bold);
+ wide = gtk_widget_get_visible(toolbar->bold);
menu = gtk_menu_new();
item = gtk_menu_item_new_with_mnemonic(wide ? _("Group Items") : _("Ungroup Items"));
@@ -1239,6 +1254,7 @@ static void gtk_imhtmltoolbar_create_old_buttons(GtkIMHtmlToolbar *toolbar)
{PIDGIN_STOCK_TOOLBAR_INSERT_LINK, insert_link_cb, &toolbar->link, _("Insert Link")},
{"", NULL, NULL, NULL},
{PIDGIN_STOCK_TOOLBAR_SMILEY, insert_smiley_cb, &toolbar->smiley, _("Insert Smiley")},
+ {PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION, send_attention_cb, &toolbar->attention, _("Send Attention")},
{NULL, NULL, NULL, NULL}
};
int iter;
@@ -1252,19 +1268,15 @@ static void gtk_imhtmltoolbar_create_old_buttons(GtkIMHtmlToolbar *toolbar)
g_signal_connect(G_OBJECT(button), "clicked",
G_CALLBACK(buttons[iter].callback), toolbar);
*(buttons[iter].button) = button;
+#if GTK_CHECK_VERSION(2,12,0)
+ gtk_widget_set_tooltip_text(button, buttons[iter].tooltip);
+#else
gtk_tooltips_set_tip(toolbar->tooltips, button, buttons[iter].tooltip, NULL);
+#endif
} else
button = gtk_vseparator_new();
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
}
- /* create the attention button (this is a bit hacky to not break ABI) */
- button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION);
- g_signal_connect(G_OBJECT(button), "button-press-event", G_CALLBACK(gtk_imhtmltoolbar_popup_menu), toolbar);
- g_signal_connect(G_OBJECT(button), "clicked",
- G_CALLBACK(send_attention_cb), toolbar);
- g_object_set_data(G_OBJECT(toolbar), "attention", button);
- gtk_tooltips_set_tip(toolbar->tooltips, button, _("Send Attention"), NULL);
- gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(toolbar), hbox, FALSE, FALSE, 0);
g_object_set_data(G_OBJECT(toolbar), "wide-view", hbox);
@@ -1273,7 +1285,7 @@ static void gtk_imhtmltoolbar_create_old_buttons(GtkIMHtmlToolbar *toolbar)
static void
button_visibility_changed(GtkWidget *button, gpointer dontcare, GtkWidget *item)
{
- if (GTK_WIDGET_VISIBLE(button))
+ if (gtk_widget_get_visible(button))
gtk_widget_hide(item);
else
gtk_widget_show(item);
@@ -1282,7 +1294,7 @@ button_visibility_changed(GtkWidget *button, gpointer dontcare, GtkWidget *item)
static void
button_sensitiveness_changed(GtkWidget *button, gpointer dontcare, GtkWidget *item)
{
- gtk_widget_set_sensitive(item, GTK_WIDGET_IS_SENSITIVE(button));
+ gtk_widget_set_sensitive(item, gtk_widget_is_sensitive(button));
}
static void
@@ -1327,7 +1339,6 @@ static void gtk_imhtmltoolbar_init (GtkIMHtmlToolbar *toolbar)
GtkWidget *insert_menu;
GtkWidget *menuitem;
GtkWidget *sep;
- GObject *wide_attention_button;
int i;
struct {
const char *label;
@@ -1361,7 +1372,9 @@ static void gtk_imhtmltoolbar_init (GtkIMHtmlToolbar *toolbar)
toolbar->smiley_dialog = NULL;
toolbar->image_dialog = NULL;
+#if !GTK_CHECK_VERSION(2,12,0)
toolbar->tooltips = gtk_tooltips_new();
+#endif
gtk_box_set_spacing(GTK_BOX(toolbar), 3);
@@ -1478,8 +1491,6 @@ static void gtk_imhtmltoolbar_init (GtkIMHtmlToolbar *toolbar)
gtk_widget_show_all(sep);
/* Attention */
- wide_attention_button = g_object_get_data(G_OBJECT(toolbar), "attention");
-
attention_button = gtk_button_new();
gtk_button_set_relief(GTK_BUTTON(attention_button), GTK_RELIEF_NONE);
bbox = gtk_hbox_new(FALSE, 3);
@@ -1491,16 +1502,16 @@ static void gtk_imhtmltoolbar_init (GtkIMHtmlToolbar *toolbar)
gtk_box_pack_start(GTK_BOX(bbox), label, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(box), attention_button, FALSE, FALSE, 0);
g_signal_connect_swapped(G_OBJECT(attention_button), "clicked",
- G_CALLBACK(gtk_button_clicked), wide_attention_button);
+ G_CALLBACK(gtk_button_clicked), toolbar->attention);
gtk_widget_show_all(attention_button);
- g_signal_connect(wide_attention_button, "notify::sensitive",
+ g_signal_connect(G_OBJECT(toolbar->attention), "notify::sensitive",
G_CALLBACK(button_sensitiveness_changed), attention_button);
- g_signal_connect(wide_attention_button, "notify::visible",
+ g_signal_connect(G_OBJECT(toolbar->attention), "notify::visible",
G_CALLBACK(button_visibility_changed), attention_button);
/* set attention button to be greyed out until we get a conversation */
- gtk_widget_set_sensitive(GTK_WIDGET(wide_attention_button), FALSE);
+ gtk_widget_set_sensitive(toolbar->attention, FALSE);
gtk_box_pack_start(GTK_BOX(hbox), box, FALSE, FALSE, 0);
g_object_set_data(G_OBJECT(hbox), "lean-view", box);
@@ -1581,16 +1592,14 @@ void gtk_imhtmltoolbar_associate_smileys(GtkIMHtmlToolbar *toolbar, const char *
void gtk_imhtmltoolbar_switch_active_conversation(GtkIMHtmlToolbar *toolbar,
PurpleConversation *conv)
{
- PurpleConnection *gc = purple_conversation_get_gc(conv);
+ PurpleConnection *gc = purple_conversation_get_connection(conv);
PurplePlugin *prpl = purple_connection_get_prpl(gc);
- GtkWidget *attention =
- g_object_get_data(G_OBJECT(toolbar), "attention");
g_object_set_data(G_OBJECT(toolbar), "active_conv", conv);
/* gray out attention button on protocols that don't support it
for the time being it is always disabled for chats */
- gtk_widget_set_sensitive(attention,
+ gtk_widget_set_sensitive(toolbar->attention,
conv && prpl && purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM &&
PURPLE_PLUGIN_PROTOCOL_INFO(prpl)->send_attention != NULL);
}
diff --git a/pidgin/gtkimhtmltoolbar.h b/pidgin/gtkimhtmltoolbar.h
index d31f46c22a..13efbb47a8 100644
--- a/pidgin/gtkimhtmltoolbar.h
+++ b/pidgin/gtkimhtmltoolbar.h
@@ -26,9 +26,7 @@
#include <gtk/gtk.h>
#include "gtkimhtml.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
#define DEFAULT_FONT_FACE "Helvetica 12"
@@ -46,7 +44,11 @@ struct _GtkIMHtmlToolbar {
GtkWidget *imhtml;
+#if GTK_CHECK_VERSION(2,12,0)
+ gpointer depr1;
+#else
GtkTooltips *tooltips;
+#endif
GtkWidget *bold;
GtkWidget *italic;
@@ -65,6 +67,7 @@ struct _GtkIMHtmlToolbar {
GtkWidget *image;
GtkWidget *link;
GtkWidget *smiley;
+ GtkWidget *attention;
GtkWidget *font_dialog;
GtkWidget *fgcolor_dialog;
@@ -90,14 +93,9 @@ GtkWidget* gtk_imhtmltoolbar_new (void);
void gtk_imhtmltoolbar_attach (GtkIMHtmlToolbar *toolbar, GtkWidget *imhtml);
void gtk_imhtmltoolbar_associate_smileys (GtkIMHtmlToolbar *toolbar, const char *proto_id);
-/**
- * @since 2.7.0
- */
void gtk_imhtmltoolbar_switch_active_conversation(GtkIMHtmlToolbar *toolbar,
PurpleConversation *conv);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PIDGINIMHTMLTOOLBAR_H_ */
diff --git a/pidgin/gtklog.c b/pidgin/gtklog.c
index 831effa5c5..d4f18cf07b 100644
--- a/pidgin/gtklog.c
+++ b/pidgin/gtklog.c
@@ -35,9 +35,9 @@
#include "pidginstock.h"
#include "gtkblist.h"
-#include "gtkimhtml.h"
#include "gtklog.h"
#include "gtkutils.h"
+#include "gtkwebview.h"
static GHashTable *log_viewers = NULL;
static void populate_log_tree(PidginLogViewer *lv);
@@ -130,7 +130,7 @@ static void search_cb(GtkWidget *button, PidginLogViewer *lv)
populate_log_tree(lv);
g_free(lv->search);
lv->search = NULL;
- gtk_imhtml_search_clear(GTK_IMHTML(lv->imhtml));
+ webkit_web_view_unmark_text_matches(WEBKIT_WEB_VIEW(lv->web_view));
select_first_log(lv);
return;
}
@@ -138,7 +138,7 @@ static void search_cb(GtkWidget *button, PidginLogViewer *lv)
if (lv->search != NULL && !strcmp(lv->search, search_term))
{
/* Searching for the same term acts as "Find Next" */
- gtk_imhtml_search_find(GTK_IMHTML(lv->imhtml), lv->search);
+ webkit_web_view_search_text(WEBKIT_WEB_VIEW(lv->web_view), lv->search, FALSE, TRUE, TRUE);
return;
}
@@ -148,7 +148,7 @@ static void search_cb(GtkWidget *button, PidginLogViewer *lv)
lv->search = g_strdup(search_term);
gtk_tree_store_clear(lv->treestore);
- gtk_imhtml_clear(GTK_IMHTML(lv->imhtml));
+ webkit_web_view_open(WEBKIT_WEB_VIEW(lv->web_view), "about:blank"); /* clear the view */
for (logs = lv->logs; logs != NULL; logs = logs->next) {
char *read = purple_log_read((PurpleLog*)logs->data, NULL);
@@ -419,8 +419,9 @@ static gboolean log_popup_menu_cb(GtkWidget *treeview, PidginLogViewer *lv)
static gboolean search_find_cb(gpointer data)
{
PidginLogViewer *viewer = data;
- gtk_imhtml_search_find(GTK_IMHTML(viewer->imhtml), viewer->search);
- g_object_steal_data(G_OBJECT(viewer->entry), "search-find-cb");
+ webkit_web_view_mark_text_matches(WEBKIT_WEB_VIEW(viewer->web_view), viewer->search, FALSE, 0);
+ webkit_web_view_set_highlight_text_matches(WEBKIT_WEB_VIEW(viewer->web_view), TRUE);
+ webkit_web_view_search_text(WEBKIT_WEB_VIEW(viewer->web_view), viewer->search, FALSE, TRUE, TRUE);
return FALSE;
}
@@ -461,23 +462,24 @@ static void log_select_cb(GtkTreeSelection *sel, PidginLogViewer *viewer) {
read = purple_log_read(log, &flags);
viewer->flags = flags;
- gtk_imhtml_clear(GTK_IMHTML(viewer->imhtml));
- gtk_imhtml_set_protocol_name(GTK_IMHTML(viewer->imhtml),
- purple_account_get_protocol_name(log->account));
+ webkit_web_view_open(WEBKIT_WEB_VIEW(viewer->web_view), "about:blank");
purple_signal_emit(pidgin_log_get_handle(), "log-displaying", viewer, log);
+
+ /* plaintext log (html one starts with <html> tag) */
+ if (read[0] != '<')
+ {
+ char *newRead = purple_strreplace(read, "\n", "<br>");
+ g_free(read);
+ read = newRead;
+ }
- gtk_imhtml_append_text(GTK_IMHTML(viewer->imhtml), read,
- GTK_IMHTML_NO_COMMENTS | GTK_IMHTML_NO_TITLE | GTK_IMHTML_NO_SCROLL |
- ((flags & PURPLE_LOG_READ_NO_NEWLINE) ? GTK_IMHTML_NO_NEWLINE : 0));
+ webkit_web_view_load_html_string(WEBKIT_WEB_VIEW(viewer->web_view), read, "");
g_free(read);
if (viewer->search != NULL) {
- guint source;
- gtk_imhtml_search_clear(GTK_IMHTML(viewer->imhtml));
- source = g_idle_add(search_find_cb, viewer);
- g_object_set_data_full(G_OBJECT(viewer->entry), "search-find-cb",
- GINT_TO_POINTER(source), (GDestroyNotify)g_source_remove);
+ webkit_web_view_unmark_text_matches(WEBKIT_WEB_VIEW(viewer->web_view));
+ g_idle_add(search_find_cb, viewer);
}
pidgin_clear_cursor(viewer->window);
@@ -581,7 +583,9 @@ static PidginLogViewer *display_log_viewer(struct log_viewer_hash_t *ht, GList *
gtk_dialog_add_button(GTK_DIALOG(lv->window), _("_Browse logs folder"), GTK_RESPONSE_HELP);
#endif
gtk_container_set_border_width (GTK_CONTAINER(lv->window), PIDGIN_HIG_BOX_SPACE);
+#if !GTK_CHECK_VERSION(2,22,0)
gtk_dialog_set_has_separator(GTK_DIALOG(lv->window), FALSE);
+#endif
gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(lv->window)->vbox), 0);
g_signal_connect(G_OBJECT(lv->window), "response",
G_CALLBACK(destroy_cb), ht);
@@ -620,7 +624,7 @@ static PidginLogViewer *display_log_viewer(struct log_viewer_hash_t *ht, GList *
col = gtk_tree_view_column_new_with_attributes ("time", rend, "markup", 0, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(lv->treeview), col);
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (lv->treeview), FALSE);
- gtk_paned_add1(GTK_PANED(pane),
+ gtk_paned_add1(GTK_PANED(pane),
pidgin_make_scrollable(lv->treeview, GTK_POLICY_NEVER, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1));
populate_log_tree(lv);
@@ -655,9 +659,9 @@ static PidginLogViewer *display_log_viewer(struct log_viewer_hash_t *ht, GList *
gtk_paned_add2(GTK_PANED(pane), vbox);
/* Viewer ************/
- frame = pidgin_create_imhtml(FALSE, &lv->imhtml, NULL, NULL);
- gtk_widget_set_name(lv->imhtml, "pidgin_log_imhtml");
- gtk_widget_set_size_request(lv->imhtml, 320, 200);
+ frame = pidgin_create_webview(FALSE, &lv->web_view, NULL, NULL);
+ gtk_widget_set_name(lv->web_view, "pidgin_log_web_view");
+ gtk_widget_set_size_request(lv->web_view, 320, 200);
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
gtk_widget_show(frame);
diff --git a/pidgin/gtklog.h b/pidgin/gtklog.h
index 77917a8a15..0797a76bf9 100644
--- a/pidgin/gtklog.h
+++ b/pidgin/gtklog.h
@@ -43,7 +43,7 @@ struct _PidginLogViewer {
GtkWidget *window; /**< The viewer's window */
GtkTreeStore *treestore; /**< The treestore containing said logs */
GtkWidget *treeview; /**< The treeview representing said treestore */
- GtkWidget *imhtml; /**< The imhtml to display said logs */
+ GtkWidget *web_view; /**< The webkit web view to display said logs */
GtkWidget *entry; /**< The search entry, in which search terms
* are entered */
PurpleLogReadFlags flags; /**< The most recently used log flags */
@@ -52,6 +52,7 @@ struct _PidginLogViewer {
};
+G_BEGIN_DECLS
void pidgin_log_show(PurpleLogType type, const char *buddyname, PurpleAccount *account);
void pidgin_log_show_contact(PurpleContact *contact);
@@ -82,4 +83,6 @@ void pidgin_log_uninit(void);
/*@}*/
+G_END_DECLS
+
#endif
diff --git a/pidgin/gtkmain.c b/pidgin/gtkmain.c
index 0fb2a7a393..feaabb6819 100644
--- a/pidgin/gtkmain.c
+++ b/pidgin/gtkmain.c
@@ -498,7 +498,6 @@ int main(int argc, char *argv[])
int opt;
gboolean gui_check;
gboolean debug_enabled;
- gboolean migration_failed = FALSE;
GList *active_accounts;
struct stat st;
@@ -720,7 +719,16 @@ int main(int argc, char *argv[])
/* set a user-specified config directory */
if (opt_config_dir_arg != NULL) {
- purple_util_set_user_dir(opt_config_dir_arg);
+ if (g_path_is_absolute(opt_config_dir_arg)) {
+ purple_util_set_user_dir(opt_config_dir_arg);
+ } else {
+ /* Make an absolute (if not canonical) path */
+ char *cwd = g_get_current_dir();
+ char *path = g_build_path(G_DIR_SEPARATOR_S, cwd, opt_config_dir_arg, NULL);
+ purple_util_set_user_dir(path);
+ g_free(path);
+ g_free(cwd);
+ }
}
/*
@@ -730,16 +738,6 @@ int main(int argc, char *argv[])
purple_debug_set_enabled(debug_enabled);
- /* If we're using a custom configuration directory, we
- * do NOT want to migrate, or weird things will happen. */
- if (opt_config_dir_arg == NULL)
- {
- if (!purple_core_migrate())
- {
- migration_failed = TRUE;
- }
- }
-
search_path = g_build_filename(purple_user_dir(), "gtkrc-2.0", NULL);
gtk_rc_add_default_file(search_path);
g_free(search_path);
@@ -765,37 +763,6 @@ int main(int argc, char *argv[])
winpidgin_init(hint);
#endif
- if (migration_failed)
- {
- char *old = g_strconcat(purple_home_dir(),
- G_DIR_SEPARATOR_S ".gaim", NULL);
- const char *text = _(
- "%s encountered errors migrating your settings "
- "from %s to %s. Please investigate and complete the "
- "migration by hand. Please report this error at http://developer.pidgin.im");
- GtkWidget *dialog;
-
- dialog = gtk_message_dialog_new(NULL,
- 0,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- text, PIDGIN_NAME,
- old, purple_user_dir());
- g_free(old);
-
- g_signal_connect_swapped(dialog, "response",
- G_CALLBACK(gtk_main_quit), NULL);
-
- gtk_widget_show_all(dialog);
-
- gtk_main();
-
-#ifdef HAVE_SIGNAL_H
- g_free(segfault_message);
-#endif
- return 0;
- }
-
purple_core_set_ui_ops(pidgin_core_get_ui_ops());
purple_eventloop_set_ui_ops(pidgin_eventloop_get_ui_ops());
diff --git a/pidgin/gtkmedia.c b/pidgin/gtkmedia.c
index d91a951061..f928290658 100644
--- a/pidgin/gtkmedia.c
+++ b/pidgin/gtkmedia.c
@@ -40,6 +40,8 @@
#ifdef _WIN32
#include <gdk/gdkwin32.h>
+#elif defined(GDK_WINDOWING_QUARTZ)
+#include <gdk/gdkquartz.h>
#endif
#include <gst/interfaces/xoverlay.h>
@@ -455,7 +457,7 @@ level_message_cb(PurpleMedia *media, gchar *session_id, gchar *participant,
progress = pidgin_media_get_widget(gtkmedia, session_id, participant);
if (progress)
- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), level * 5);
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), level);
}
@@ -560,6 +562,8 @@ realize_cb_cb(PidginMediaRealizeData *data)
window_id = GDK_WINDOW_HWND(window);
#elif defined(HAVE_X11)
window_id = GDK_WINDOW_XWINDOW(window);
+#elif defined(GDK_WINDOWING_QUARTZ)
+ window_id = (gulong) gdk_quartz_window_get_nsview(window);
#else
# error "Unsupported windowing system"
#endif
@@ -969,7 +973,7 @@ pidgin_media_stream_info_cb(PurpleMedia *media, PurpleMediaInfoType type,
pidgin_media_set_state(gtkmedia, PIDGIN_MEDIA_ACCEPTED);
pidgin_media_emit_message(gtkmedia, _("Call in progress."));
gtk_statusbar_push(GTK_STATUSBAR(gtkmedia->priv->statusbar),
- 0, _("Call in progress."));
+ 0, _("Call in progress"));
gtk_widget_show(GTK_WIDGET(gtkmedia));
}
}
@@ -1082,6 +1086,10 @@ create_default_video_src(PurpleMedia *media,
src = gst_element_factory_make("dshowvideosrc", NULL);
if (src == NULL)
src = gst_element_factory_make("autovideosrc", NULL);
+#elif defined(__APPLE__)
+ src = gst_element_factory_make("osxvideosrc", NULL);
+ if (src == NULL)
+ src = gst_element_factory_make("autovideosrc", NULL);
#else
src = gst_element_factory_make("gconfvideosrc", NULL);
if (src == NULL)
@@ -1136,6 +1144,8 @@ create_default_audio_src(PurpleMedia *media,
src = gst_element_factory_make("osssrc", NULL);
if (src == NULL)
src = gst_element_factory_make("dshowaudiosrc", NULL);
+ if (src == NULL)
+ src = gst_element_factory_make("osxaudiosrc", NULL);
if (src == NULL) {
purple_debug_error("gtkmedia", "Unable to find a suitable "
"element for the default audio source.\n");
diff --git a/pidgin/gtkmenutray.c b/pidgin/gtkmenutray.c
index 31a9f6f4b9..f78661ad2d 100644
--- a/pidgin/gtkmenutray.c
+++ b/pidgin/gtkmenutray.c
@@ -40,6 +40,10 @@ static GObjectClass *parent_class = NULL;
* Internal Stuff
*****************************************************************************/
+#if !GTK_CHECK_VERSION(2,18,0)
+#define gtk_widget_get_has_window(x) !GTK_WIDGET_NO_WINDOW(x)
+#endif
+
/******************************************************************************
* Item Stuff
*****************************************************************************/
@@ -92,7 +96,9 @@ pidgin_menu_tray_map(GtkWidget *widget)
static void
pidgin_menu_tray_finalize(GObject *obj)
{
+#if !GTK_CHECK_VERSION(2,12,0)
PidginMenuTray *tray = PIDGIN_MENU_TRAY(obj);
+#endif
#if 0
/* This _might_ be leaking, but I have a sneaking suspicion that the widget is
* getting destroyed in GtkContainer's finalize function. But if were are
@@ -104,9 +110,11 @@ pidgin_menu_tray_finalize(GObject *obj)
gtk_widget_destroy(GTK_WIDGET(tray->tray));
#endif
+#if !GTK_CHECK_VERSION(2,12,0)
if (tray->tooltips) {
gtk_object_sink(GTK_OBJECT(tray->tooltips));
}
+#endif
G_OBJECT_CLASS(parent_class)->finalize(obj);
}
@@ -205,7 +213,7 @@ pidgin_menu_tray_add(PidginMenuTray *menu_tray, GtkWidget *widget,
g_return_if_fail(PIDGIN_IS_MENU_TRAY(menu_tray));
g_return_if_fail(GTK_IS_WIDGET(widget));
- if (GTK_WIDGET_NO_WINDOW(widget))
+ if (!gtk_widget_get_has_window(widget))
{
GtkWidget *event;
@@ -238,21 +246,27 @@ pidgin_menu_tray_prepend(PidginMenuTray *menu_tray, GtkWidget *widget, const cha
void
pidgin_menu_tray_set_tooltip(PidginMenuTray *menu_tray, GtkWidget *widget, const char *tooltip)
{
+#if !GTK_CHECK_VERSION(2,12,0)
if (!menu_tray->tooltips)
menu_tray->tooltips = gtk_tooltips_new();
+#endif
/* Should we check whether widget is a child of menu_tray? */
/*
- * If the widget does not have it's own window, then it
+ * If the widget does not have its own window, then it
* must have automatically been added to an event box
* when it was added to the menu tray. If this is the
* case, we want to set the tooltip on the widget's parent,
* not on the widget itself.
*/
- if (GTK_WIDGET_NO_WINDOW(widget))
+ if (!gtk_widget_get_has_window(widget))
widget = widget->parent;
+#if GTK_CHECK_VERSION(2,12,0)
+ gtk_widget_set_tooltip_text(widget, tooltip);
+#else
gtk_tooltips_set_tip(menu_tray->tooltips, widget, tooltip, NULL);
+#endif
}
diff --git a/pidgin/gtkmenutray.h b/pidgin/gtkmenutray.h
index 0661ef8425..158530a7bb 100644
--- a/pidgin/gtkmenutray.h
+++ b/pidgin/gtkmenutray.h
@@ -40,7 +40,9 @@ typedef struct _PidginMenuTrayClass PidginMenuTrayClass;
struct _PidginMenuTray {
GtkMenuItem gparent; /**< The parent instance */
GtkWidget *tray; /**< The tray */
+#if !GTK_CHECK_VERSION(2,12,0)
GtkTooltips *tooltips; /**< Tooltips */
+#endif
};
/** A PidginMenuTrayClass */
diff --git a/pidgin/gtknotify.c b/pidgin/gtknotify.c
index 8d15e036fc..02ed54e04a 100644
--- a/pidgin/gtknotify.c
+++ b/pidgin/gtknotify.c
@@ -36,10 +36,10 @@
#include "util.h"
#include "gtkblist.h"
-#include "gtkimhtml.h"
#include "gtknotify.h"
#include "gtkpounce.h"
#include "gtkutils.h"
+#include "gtkwebview.h"
typedef struct
{
@@ -534,7 +534,9 @@ pidgin_notify_message(PurpleNotifyMsgType type, const char *title,
gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BORDER);
gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
+#if !GTK_CHECK_VERSION(2,22,0)
gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+#endif
gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BOX_SPACE);
@@ -689,6 +691,8 @@ pidgin_notify_emails(PurpleConnection *gc, size_t count, gboolean detailed,
PurpleAccount *account;
PidginNotifyMailData *data = NULL, *data2;
gboolean new_data = FALSE;
+ GtkTreeSelection *sel;
+ GtkTreeIter iter;
/* Don't bother updating if there aren't new emails and we don't have any displayed currently */
if (count == 0 && mail_dialog == NULL)
@@ -775,7 +779,18 @@ pidgin_notify_emails(PurpleConnection *gc, size_t count, gboolean detailed,
}
}
+ /* Select first item if nothing selected */
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(mail_dialog->treeview));
+ if ((gtk_tree_selection_count_selected_rows(sel) < 1)
+ && gtk_tree_model_get_iter_first(GTK_TREE_MODEL(mail_dialog->treemodel), &iter)) {
+ gtk_tree_selection_select_iter(sel, &iter);
+ }
+
+#if GTK_CHECK_VERSION(2,18,0)
+ if (!gtk_widget_get_visible(mail_dialog->dialog)) {
+#else
if (!GTK_WIDGET_VISIBLE(mail_dialog->dialog)) {
+#endif
GdkPixbuf *pixbuf = gtk_widget_render_icon(mail_dialog->dialog, PIDGIN_STOCK_DIALOG_MAIL,
gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL), NULL);
char *label_text = g_strdup_printf(ngettext("<b>%d new email.</b>",
@@ -791,7 +806,11 @@ pidgin_notify_emails(PurpleConnection *gc, size_t count, gboolean detailed,
g_free(label_text);
if (pixbuf)
g_object_unref(pixbuf);
+#if GTK_CHECK_VERSION(2,18,0)
+ } else if (!gtk_widget_has_focus(mail_dialog->dialog))
+#else
} else if (!GTK_WIDGET_HAS_FOCUS(mail_dialog->dialog))
+#endif
pidgin_set_urgent(GTK_WINDOW(mail_dialog->dialog), TRUE);
return data;
@@ -810,21 +829,6 @@ formatted_input_cb(GtkWidget *win, GdkEventKey *event, gpointer data)
return FALSE;
}
-static GtkIMHtmlOptions
-notify_imhtml_options(void)
-{
- GtkIMHtmlOptions options = 0;
-
- if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_incoming_formatting"))
- options |= GTK_IMHTML_NO_COLOURS | GTK_IMHTML_NO_FONTS | GTK_IMHTML_NO_SIZES;
-
- options |= GTK_IMHTML_NO_COMMENTS;
- options |= GTK_IMHTML_NO_TITLE;
- options |= GTK_IMHTML_NO_NEWLINE;
- options |= GTK_IMHTML_NO_SCROLL;
- return options;
-}
-
static void *
pidgin_notify_formatted(const char *title, const char *primary,
const char *secondary, const char *text)
@@ -833,7 +837,7 @@ pidgin_notify_formatted(const char *title, const char *primary,
GtkWidget *vbox;
GtkWidget *label;
GtkWidget *button;
- GtkWidget *imhtml;
+ GtkWidget *web_view;
GtkWidget *frame;
char label_text[2048];
char *linked_text, *primary_esc, *secondary_esc;
@@ -869,12 +873,10 @@ pidgin_notify_formatted(const char *title, const char *primary,
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
gtk_widget_show(label);
- /* Add the imhtml */
- frame = pidgin_create_imhtml(FALSE, &imhtml, NULL, NULL);
- gtk_widget_set_name(imhtml, "pidgin_notify_imhtml");
- gtk_imhtml_set_format_functions(GTK_IMHTML(imhtml),
- gtk_imhtml_get_format_functions(GTK_IMHTML(imhtml)) | GTK_IMHTML_IMAGE);
- gtk_widget_set_size_request(imhtml, 300, 250);
+ /* Add the webview */
+ frame = pidgin_create_webview(FALSE, &web_view, NULL, NULL);
+ gtk_widget_set_name(web_view, "pidgin_notify_webview");
+ gtk_widget_set_size_request(web_view, 300, 250);
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
gtk_widget_show(frame);
@@ -889,10 +891,10 @@ pidgin_notify_formatted(const char *title, const char *primary,
/* Make sure URLs are clickable */
linked_text = purple_markup_linkify(text);
- gtk_imhtml_append_text(GTK_IMHTML(imhtml), linked_text, notify_imhtml_options());
+ gtk_webview_load_html_string(GTK_WEBVIEW(web_view), linked_text);
g_free(linked_text);
- g_object_set_data(G_OBJECT(window), "info-widget", imhtml);
+ g_object_set_data(G_OBJECT(window), "webview-widget", web_view);
/* Show the window */
pidgin_auto_parent_window(window);
@@ -1034,7 +1036,11 @@ pidgin_notify_searchresults(PurpleConnection *gc, const char *title,
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1,
- column->title, renderer, "text", i, NULL);
+ purple_notify_searchresult_column_get_title(column), renderer, "text", i, NULL);
+
+ if (!purple_notify_searchresult_column_is_visible(column))
+ gtk_tree_view_column_set_visible(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), i), FALSE);
+
i++;
}
@@ -1044,7 +1050,7 @@ pidgin_notify_searchresults(PurpleConnection *gc, const char *title,
switch (b->type) {
case PURPLE_NOTIFY_BUTTON_LABELED:
if(b->label) {
- button = gtk_button_new_with_label(b->label);
+ button = gtk_dialog_add_button(GTK_DIALOG(window), b->label, GTK_RESPONSE_NONE);
} else {
purple_debug_warning("gtknotify", "Missing button label\n");
}
@@ -1089,7 +1095,7 @@ pidgin_notify_searchresults(PurpleConnection *gc, const char *title,
g_signal_connect_swapped(G_OBJECT(close_button), "clicked",
G_CALLBACK(searchresults_close_cb), data);
- data->account = gc->account;
+ data->account = purple_connection_get_account(gc);
data->model = model;
data->treeview = treeview;
data->window = window;
@@ -1143,10 +1149,9 @@ pidgin_notify_userinfo(PurpleConnection *gc, const char *who,
info = purple_notify_user_info_get_text_with_newline(user_info, "<br />");
pinfo = g_hash_table_lookup(userinfo, key);
if (pinfo != NULL) {
- GtkIMHtml *imhtml = g_object_get_data(G_OBJECT(pinfo->window), "info-widget");
+ GtkWidget *webview = g_object_get_data(G_OBJECT(pinfo->window), "webview-widget");
char *linked_text = purple_markup_linkify(info);
- gtk_imhtml_clear(imhtml);
- gtk_imhtml_append_text(imhtml, linked_text, notify_imhtml_options());
+ gtk_webview_load_html_string(GTK_WEBVIEW(webview), linked_text);
g_free(linked_text);
g_free(key);
ui_handle = pinfo->window;
@@ -1508,7 +1513,9 @@ pidgin_create_notification_dialog(PidginNotifyType type)
/* Setup the dialog */
gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BOX_SPACE);
gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BOX_SPACE);
+#if !GTK_CHECK_VERSION(2,22,0)
gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+#endif
gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
/* Vertical box */
@@ -1544,11 +1551,13 @@ pidgin_create_notification_dialog(PidginNotifyType type)
gtk_tree_view_set_search_column(GTK_TREE_VIEW(spec_dialog->treeview), PIDGIN_MAIL_TEXT);
gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(spec_dialog->treeview),
pidgin_tree_view_search_equal_func, NULL, NULL);
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(spec_dialog->treeview));
+ gtk_tree_selection_set_mode(sel, GTK_SELECTION_BROWSE);
g_signal_connect(G_OBJECT(dialog), "response",
G_CALLBACK(email_response_cb), spec_dialog);
- g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(spec_dialog->treeview))),
- "changed", G_CALLBACK(selection_changed_cb), spec_dialog);
+ g_signal_connect(G_OBJECT(sel), "changed",
+ G_CALLBACK(selection_changed_cb), spec_dialog);
g_signal_connect(G_OBJECT(spec_dialog->treeview), "row-activated", G_CALLBACK(email_row_activated_cb), NULL);
column = gtk_tree_view_column_new();
@@ -1646,7 +1655,7 @@ pidgin_create_notification_dialog(PidginNotifyType type)
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox),
+ gtk_box_pack_start(GTK_BOX(vbox),
pidgin_make_scrollable(spec_dialog->treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1),
TRUE, TRUE, 2);
diff --git a/pidgin/gtknotify.h b/pidgin/gtknotify.h
index b5973a4995..d1e6561645 100644
--- a/pidgin/gtknotify.h
+++ b/pidgin/gtknotify.h
@@ -29,6 +29,8 @@
#include "notify.h"
#include "pounce.h"
+G_BEGIN_DECLS
+
/**
* Adds a buddy pounce to the buddy pounce dialog
*
@@ -59,4 +61,6 @@ void pidgin_notify_init(void);
*/
void pidgin_notify_uninit(void);
+G_END_DECLS
+
#endif /* _PIDGINNOTIFY_H_ */
diff --git a/pidgin/gtkplugin.h b/pidgin/gtkplugin.h
index 8b07be4f12..817c03592e 100644
--- a/pidgin/gtkplugin.h
+++ b/pidgin/gtkplugin.h
@@ -56,6 +56,8 @@ struct _PidginPluginUiInfo
#define PIDGIN_PLUGIN_UI_INFO(plugin) \
((PidginPluginUiInfo *)(plugin)->info->ui_info)
+G_BEGIN_DECLS
+
/**
* Returns the configuration frame widget for a GTK+ plugin, if one
* exists.
@@ -77,4 +79,6 @@ void pidgin_plugins_save(void);
*/
void pidgin_plugin_dialog_show(void);
+G_END_DECLS
+
#endif /* _PIDGINPLUGIN_H_ */
diff --git a/pidgin/gtkpluginpref.h b/pidgin/gtkpluginpref.h
index d0f9add1c4..1a433d2178 100644
--- a/pidgin/gtkpluginpref.h
+++ b/pidgin/gtkpluginpref.h
@@ -31,9 +31,7 @@
#include "pidgin.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
/**
* Creates a Gtk Preference frame for a PurplePluginPrefFrame
@@ -43,8 +41,6 @@ extern "C" {
*/
GtkWidget *pidgin_plugin_pref_create_frame(PurplePluginPrefFrame *frame);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _PIDGINPLUGINPREF_H_ */
diff --git a/pidgin/gtkpounce.c b/pidgin/gtkpounce.c
index bb440939f0..62becb487c 100644
--- a/pidgin/gtkpounce.c
+++ b/pidgin/gtkpounce.c
@@ -427,9 +427,9 @@ pounce_dnd_recv(GtkWidget *widget, GdkDragContext *dc, gint x, gint y,
dialog = (PidginPounceDialog *)data;
- gtk_entry_set_text(GTK_ENTRY(dialog->buddy_entry), buddy->name);
- dialog->account = buddy->account;
- pidgin_account_option_menu_set_selected(dialog->account_menu, buddy->account);
+ gtk_entry_set_text(GTK_ENTRY(dialog->buddy_entry), purple_buddy_get_name(buddy));
+ dialog->account = purple_buddy_get_account(buddy);
+ pidgin_account_option_menu_set_selected(dialog->account_menu, purple_buddy_get_account(buddy));
gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
}
@@ -476,7 +476,7 @@ reset_send_msg_entry(PidginPounceDialog *dialog, GtkWidget *dontcare)
{
PurpleAccount *account = pidgin_account_option_menu_get_selected(dialog->account_menu);
gtk_imhtml_setup_entry(GTK_IMHTML(dialog->send_msg_entry),
- (account && account->gc) ? account->gc->flags : PURPLE_CONNECTION_HTML);
+ (account && purple_account_get_connection(account)) ? purple_connection_get_flags(purple_account_get_connection(account)) : PURPLE_CONNECTION_HTML);
}
void
@@ -1018,7 +1018,11 @@ pidgin_pounce_editor_show(PurpleAccount *account, const char *name,
static gboolean
pounces_manager_configure_cb(GtkWidget *widget, GdkEventConfigure *event, PouncesManager *dialog)
{
+#if GTK_CHECK_VERSION(2,18,0)
+ if (gtk_widget_get_visible(widget)) {
+#else
if (GTK_WIDGET_VISIBLE(widget)) {
+#endif
purple_prefs_set_int(PIDGIN_PREFS_ROOT "/pounces/dialog/width", event->width);
purple_prefs_set_int(PIDGIN_PREFS_ROOT "/pounces/dialog/height", event->height);
}
@@ -1419,7 +1423,6 @@ pounce_cb(PurplePounce *pounce, PurplePounceEvent events, void *data)
if (purple_pounce_action_is_enabled(pounce, "popup-notify"))
{
char *tmp;
- const char *name_shown;
const char *reason;
reason = purple_pounce_action_get_attribute(pounce, "popup-notify",
"reason");
@@ -1452,14 +1455,6 @@ pounce_cb(PurplePounce *pounce, PurplePounceEvent events, void *data)
_("Unknown.... Please report this!")
);
- /*
- * Ok here is where I change the second argument, title, from
- * NULL to the account alias if we have it or the account
- * name if that's all we have
- */
- if ((name_shown = purple_account_get_alias(account)) == NULL)
- name_shown = purple_account_get_username(account);
-
pidgin_notify_pounce_add(account, pounce, alias, tmp, reason,
purple_date_format_full(NULL));
@@ -1483,7 +1478,7 @@ pounce_cb(PurplePounce *pounce, PurplePounceEvent events, void *data)
purple_conversation_write(conv, NULL, message,
PURPLE_MESSAGE_SEND, time(NULL));
- serv_send_im(account->gc, (char *)pouncee, (char *)message, 0);
+ serv_send_im(purple_account_get_connection(account), (char *)pouncee, (char *)message, 0);
}
}
diff --git a/pidgin/gtkpounce.h b/pidgin/gtkpounce.h
index ce5bbc6505..224d319d16 100644
--- a/pidgin/gtkpounce.h
+++ b/pidgin/gtkpounce.h
@@ -28,6 +28,8 @@
#include "pounce.h"
+G_BEGIN_DECLS
+
/**
* Displays a New Buddy Pounce or Edit Buddy Pounce dialog.
*
@@ -60,4 +62,6 @@ void *pidgin_pounces_get_handle(void);
*/
void pidgin_pounces_init(void);
+G_END_DECLS
+
#endif /* _PIDGINPOUNCE_H_ */
diff --git a/pidgin/gtkprefs.c b/pidgin/gtkprefs.c
index 54381f6152..7f05851992 100644
--- a/pidgin/gtkprefs.c
+++ b/pidgin/gtkprefs.c
@@ -45,16 +45,17 @@
#include "gtkblist.h"
#include "gtkconv.h"
+#include "gtkconv-theme.h"
#include "gtkdebug.h"
#include "gtkdialogs.h"
-#include "gtkimhtml.h"
-#include "gtkimhtmltoolbar.h"
#include "gtkprefs.h"
#include "gtksavedstatuses.h"
#include "gtksound.h"
#include "gtkstatus-icon-theme.h"
#include "gtkthemes.h"
#include "gtkutils.h"
+#include "gtkwebview.h"
+#include "gtkwebviewtoolbar.h"
#include "pidginstock.h"
#define PROXYHOST 0
@@ -78,11 +79,13 @@ static GtkWidget *prefsnotebook = NULL;
static int notebook_page = 0;
/* Conversations page */
-static GtkWidget *sample_imhtml = NULL;
+static GtkWidget *sample_webview = NULL;
/* Themes page */
static GtkWidget *prefs_sound_themes_combo_box;
static GtkWidget *prefs_blist_themes_combo_box;
+static GtkWidget *prefs_conv_themes_combo_box;
+static GtkWidget *prefs_conv_variants_combo_box;
static GtkWidget *prefs_status_themes_combo_box;
static GtkWidget *prefs_smiley_themes_combo_box;
@@ -94,6 +97,8 @@ static gboolean prefs_sound_themes_loading;
/* These exist outside the lifetime of the prefs dialog */
static GtkListStore *prefs_sound_themes;
static GtkListStore *prefs_blist_themes;
+static GtkListStore *prefs_conv_themes;
+static GtkListStore *prefs_conv_variants;
static GtkListStore *prefs_status_icon_themes;
static GtkListStore *prefs_smiley_themes;
@@ -182,29 +187,49 @@ pidgin_prefs_labeled_password(GtkWidget *page, const gchar *title,
return pidgin_add_widget_to_vbox(GTK_BOX(page), title, sg, entry, TRUE, NULL);
}
+/* TODO: Maybe move this up somewheres... */
+enum {
+ PREF_DROPDOWN_TEXT,
+ PREF_DROPDOWN_VALUE,
+ PREF_DROPDOWN_COUNT
+};
static void
dropdown_set(GObject *w, const char *key)
{
const char *str_value;
int int_value;
+ gboolean bool_value;
PurplePrefType type;
+ GtkTreeIter iter;
+ GtkTreeModel *tree_model;
+
+ tree_model = gtk_combo_box_get_model(GTK_COMBO_BOX(w));
+ if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(w), &iter))
+ return;
type = GPOINTER_TO_INT(g_object_get_data(w, "type"));
if (type == PURPLE_PREF_INT) {
- int_value = GPOINTER_TO_INT(g_object_get_data(w, "value"));
+ gtk_tree_model_get(tree_model, &iter,
+ PREF_DROPDOWN_VALUE, &int_value,
+ -1);
purple_prefs_set_int(key, int_value);
}
else if (type == PURPLE_PREF_STRING) {
- str_value = (const char *)g_object_get_data(w, "value");
+ gtk_tree_model_get(tree_model, &iter,
+ PREF_DROPDOWN_VALUE, &str_value,
+ -1);
purple_prefs_set_string(key, str_value);
}
else if (type == PURPLE_PREF_BOOLEAN) {
- purple_prefs_set_bool(key,
- GPOINTER_TO_INT(g_object_get_data(w, "value")));
+ gtk_tree_model_get(tree_model, &iter,
+ PREF_DROPDOWN_VALUE, &bool_value,
+ -1);
+
+ purple_prefs_set_bool(key, bool_value);
}
}
@@ -212,69 +237,89 @@ GtkWidget *
pidgin_prefs_dropdown_from_list(GtkWidget *box, const gchar *title,
PurplePrefType type, const char *key, GList *menuitems)
{
- GtkWidget *dropdown, *opt, *menu;
+ GtkWidget *dropdown;
GtkWidget *label = NULL;
gchar *text;
const char *stored_str = NULL;
int stored_int = 0;
+ gboolean stored_bool = FALSE;
int int_value = 0;
const char *str_value = NULL;
- int o = 0;
+ gboolean bool_value = FALSE;
+ GtkListStore *store = NULL;
+ GtkTreeIter iter;
+ GtkTreeIter active;
+ GtkCellRenderer *renderer;
g_return_val_if_fail(menuitems != NULL, NULL);
- dropdown = gtk_option_menu_new();
- menu = gtk_menu_new();
-
- if (type == PURPLE_PREF_INT)
+ if (type == PURPLE_PREF_INT) {
+ store = gtk_list_store_new(PREF_DROPDOWN_COUNT, G_TYPE_STRING, G_TYPE_INT);
stored_int = purple_prefs_get_int(key);
- else if (type == PURPLE_PREF_STRING)
+ } else if (type == PURPLE_PREF_STRING) {
+ store = gtk_list_store_new(PREF_DROPDOWN_COUNT, G_TYPE_STRING, G_TYPE_STRING);
stored_str = purple_prefs_get_string(key);
+ } else if (type == PURPLE_PREF_BOOLEAN) {
+ store = gtk_list_store_new(PREF_DROPDOWN_COUNT, G_TYPE_STRING, G_TYPE_BOOLEAN);
+ stored_bool = purple_prefs_get_bool(key);
+ } else {
+ g_warn_if_reached();
+ return NULL;
+ }
+
+ dropdown = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
+ g_object_set_data(G_OBJECT(dropdown), "type", GINT_TO_POINTER(type));
- while (menuitems != NULL && (text = (char *) menuitems->data) != NULL) {
+ while (menuitems != NULL && (text = (char *)menuitems->data) != NULL) {
menuitems = g_list_next(menuitems);
g_return_val_if_fail(menuitems != NULL, NULL);
- opt = gtk_menu_item_new_with_label(text);
-
- g_object_set_data(G_OBJECT(opt), "type", GINT_TO_POINTER(type));
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ PREF_DROPDOWN_TEXT, text,
+ -1);
if (type == PURPLE_PREF_INT) {
int_value = GPOINTER_TO_INT(menuitems->data);
- g_object_set_data(G_OBJECT(opt), "value",
- GINT_TO_POINTER(int_value));
+ gtk_list_store_set(store, &iter,
+ PREF_DROPDOWN_VALUE, int_value,
+ -1);
}
else if (type == PURPLE_PREF_STRING) {
str_value = (const char *)menuitems->data;
-
- g_object_set_data(G_OBJECT(opt), "value", (char *)str_value);
+ gtk_list_store_set(store, &iter,
+ PREF_DROPDOWN_VALUE, str_value,
+ -1);
}
else if (type == PURPLE_PREF_BOOLEAN) {
- g_object_set_data(G_OBJECT(opt), "value",
- menuitems->data);
+ bool_value = (gboolean)GPOINTER_TO_INT(menuitems->data);
+ gtk_list_store_set(store, &iter,
+ PREF_DROPDOWN_VALUE, bool_value,
+ -1);
}
- g_signal_connect(G_OBJECT(opt), "activate",
- G_CALLBACK(dropdown_set), (char *)key);
-
- gtk_widget_show(opt);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), opt);
-
if ((type == PURPLE_PREF_INT && stored_int == int_value) ||
(type == PURPLE_PREF_STRING && stored_str != NULL &&
!strcmp(stored_str, str_value)) ||
(type == PURPLE_PREF_BOOLEAN &&
- (purple_prefs_get_bool(key) == GPOINTER_TO_INT(menuitems->data)))) {
+ (stored_bool == bool_value))) {
- gtk_menu_set_active(GTK_MENU(menu), o);
+ active = iter;
}
menuitems = g_list_next(menuitems);
-
- o++;
}
- gtk_option_menu_set_menu(GTK_OPTION_MENU(dropdown), menu);
+ renderer = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(dropdown), renderer, TRUE);
+ gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(dropdown), renderer,
+ "text", 0,
+ NULL);
+
+ gtk_combo_box_set_active_iter(GTK_COMBO_BOX(dropdown), &active);
+
+ g_signal_connect(G_OBJECT(dropdown), "changed",
+ G_CALLBACK(dropdown_set), (char *)key);
pidgin_add_widget_to_vbox(GTK_BOX(box), title, NULL, dropdown, FALSE, &label);
@@ -339,10 +384,12 @@ delete_prefs(GtkWidget *asdf, void *gdsa)
prefs_sound_themes_combo_box = NULL;
prefs_blist_themes_combo_box = NULL;
+ prefs_conv_themes_combo_box = NULL;
+ prefs_conv_variants_combo_box = NULL;
prefs_status_themes_combo_box = NULL;
prefs_smiley_themes_combo_box = NULL;
- sample_imhtml = NULL;
+ sample_webview = NULL;
notebook_page = 0;
prefsnotebook = NULL;
@@ -490,6 +537,18 @@ prefs_themes_sort(PurpleTheme *theme)
g_free(markup);
if (pixbuf != NULL)
g_object_unref(G_OBJECT(pixbuf));
+
+ } else if (PIDGIN_IS_CONV_THEME(theme)) {
+ /* No image available? */
+
+ name = purple_theme_get_name(theme);
+ /* No author available */
+ /* No description available */
+
+ markup = get_theme_markup(name, FALSE, NULL, NULL);
+
+ gtk_list_store_append(prefs_conv_themes, &iter);
+ gtk_list_store_set(prefs_conv_themes, &iter, 1, markup, 2, name, -1);
}
}
@@ -545,6 +604,17 @@ prefs_themes_refresh(void)
gtk_list_store_set(prefs_blist_themes, &iter, 0, pixbuf, 1, tmp, 2, "", -1);
g_free(tmp);
+ /* conversation themes */
+ gtk_list_store_clear(prefs_conv_themes);
+ gtk_list_store_append(prefs_conv_themes, &iter);
+ tmp = get_theme_markup(_("Default"), FALSE, _("Penguin Pimps"),
+ _("The default Pidgin conversation theme"));
+ gtk_list_store_set(prefs_conv_themes, &iter, 0, pixbuf, 1, tmp, 2, "", -1);
+ g_free(tmp);
+
+ /* conversation theme variants */
+ gtk_list_store_clear(prefs_conv_variants);
+
/* status icon themes */
gtk_list_store_clear(prefs_status_icon_themes);
gtk_list_store_append(prefs_status_icon_themes, &iter);
@@ -565,6 +635,7 @@ prefs_themes_refresh(void)
/* set active */
prefs_set_active_theme_combo(prefs_sound_themes_combo_box, prefs_sound_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme"));
prefs_set_active_theme_combo(prefs_blist_themes_combo_box, prefs_blist_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/theme"));
+ prefs_set_active_theme_combo(prefs_conv_themes_combo_box, prefs_conv_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/theme"));
prefs_set_active_theme_combo(prefs_status_themes_combo_box, prefs_status_icon_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/status/icon-theme"));
prefs_set_active_theme_combo(prefs_smiley_themes_combo_box, prefs_smiley_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/smileys/theme"));
prefs_sound_themes_loading = FALSE;
@@ -578,6 +649,10 @@ prefs_themes_init(void)
prefs_blist_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
+ prefs_conv_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
+
+ prefs_conv_variants = gtk_list_store_new(1, G_TYPE_STRING);
+
prefs_status_icon_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
prefs_smiley_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
@@ -856,7 +931,7 @@ theme_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
} else if (!g_ascii_strncasecmp(name, "http://", 7)) {
/* Oo, a web drag and drop. This is where things
* will start to get interesting */
- purple_util_fetch_url(name, TRUE, NULL, FALSE, theme_got_url, info);
+ purple_util_fetch_url(name, TRUE, NULL, FALSE, -1, theme_got_url, info);
} else if (!g_ascii_strncasecmp(name, "https://", 8)) {
/* purple_util_fetch_url() doesn't support HTTPS, but we want users
* to be able to drag and drop links from the SF trackers, so
@@ -867,7 +942,7 @@ theme_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
tmp[2] = 't';
tmp[3] = 'p';
- purple_util_fetch_url(tmp, TRUE, NULL, FALSE, theme_got_url, info);
+ purple_util_fetch_url(tmp, TRUE, NULL, FALSE, -1, theme_got_url, info);
g_free(tmp);
} else
free_theme_info(info);
@@ -956,7 +1031,10 @@ prefs_set_smiley_theme_cb(GtkComboBox *combo_box, gpointer user_data)
gtk_tree_model_get(GTK_TREE_MODEL(prefs_smiley_themes), &new_iter, 2, &new_theme, -1);
purple_prefs_set_string(PIDGIN_PREFS_ROOT "/smileys/theme", new_theme);
- pidgin_themes_smiley_themeize(sample_imhtml);
+#if 0
+/* TODO: WebKit-ify smileys */
+ pidgin_themes_smiley_themeize(sample_webview);
+#endif
g_free(new_theme);
}
@@ -1019,6 +1097,80 @@ prefs_set_blist_theme_cb(GtkComboBox *combo_box, gpointer user_data)
}
}
+/* sets the current conversation theme variant */
+static void
+prefs_set_conv_variant_cb(GtkComboBox *combo_box, gpointer user_data)
+{
+ PidginConvTheme *theme = NULL;
+ GtkTreeIter iter;
+ gchar *name = NULL;
+
+ if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(prefs_conv_themes_combo_box), &iter)) {
+ gtk_tree_model_get(GTK_TREE_MODEL(prefs_conv_themes), &iter, 2, &name, -1);
+ if (name && *name)
+ theme = PIDGIN_CONV_THEME(purple_theme_manager_find_theme(name, "conversation"));
+ else
+ theme = PIDGIN_CONV_THEME(pidgin_conversations_get_default_theme());
+ g_free(name);
+
+ if (gtk_combo_box_get_active_iter(combo_box, &iter)) {
+ gtk_tree_model_get(GTK_TREE_MODEL(prefs_conv_variants), &iter, 0, &name, -1);
+ pidgin_conversation_theme_set_variant(theme, name);
+ g_free(name);
+ }
+ }
+}
+
+/* sets the current conversation theme */
+static void
+prefs_set_conv_theme_cb(GtkComboBox *combo_box, gpointer user_data)
+{
+ GtkTreeIter iter;
+
+ if (gtk_combo_box_get_active_iter(combo_box, &iter)) {
+ gchar *name = NULL;
+ PidginConvTheme *theme;
+ const char *current_variant;
+ const GList *variants;
+ gboolean unset = TRUE;
+
+ gtk_tree_model_get(GTK_TREE_MODEL(prefs_conv_themes), &iter, 2, &name, -1);
+
+ purple_prefs_set_string(PIDGIN_PREFS_ROOT "/conversations/theme", name);
+
+ g_signal_handlers_block_by_func(prefs_conv_variants_combo_box,
+ prefs_set_conv_variant_cb, NULL);
+
+ /* Update list of variants */
+ gtk_list_store_clear(prefs_conv_variants);
+
+ if (name && *name)
+ theme = PIDGIN_CONV_THEME(purple_theme_manager_find_theme(name, "conversation"));
+ else
+ theme = PIDGIN_CONV_THEME(pidgin_conversations_get_default_theme());
+
+ current_variant = pidgin_conversation_theme_get_variant(theme);
+
+ variants = pidgin_conversation_theme_get_variants(theme);
+ for (; variants && current_variant; variants = g_list_next(variants)) {
+ gtk_list_store_append(prefs_conv_variants, &iter);
+ gtk_list_store_set(prefs_conv_variants, &iter, 0, variants->data, -1);
+
+ if (g_str_equal(variants->data, current_variant)) {
+ gtk_combo_box_set_active_iter(GTK_COMBO_BOX(prefs_conv_variants_combo_box), &iter);
+ unset = FALSE;
+ }
+ }
+
+ if (unset)
+ gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_conv_variants_combo_box), 0);
+
+ g_signal_handlers_unblock_by_func(prefs_conv_variants_combo_box,
+ prefs_set_conv_variant_cb, NULL);
+ g_free(name);
+ }
+}
+
/* sets the current icon theme */
static void
prefs_set_status_icon_theme_cb(GtkComboBox *combo_box, gpointer user_data)
@@ -1072,6 +1224,40 @@ add_theme_prefs_combo(GtkWidget *vbox,
}
static GtkWidget *
+add_child_theme_prefs_combo(GtkWidget *vbox, GtkSizeGroup *combo_sg,
+ GtkSizeGroup *label_sg, GtkListStore *theme_store,
+ GCallback combo_box_cb, gpointer combo_box_cb_user_data,
+ const char *label_str)
+{
+ GtkWidget *label;
+ GtkWidget *combo_box;
+ GtkWidget *themesel_hbox;
+ GtkCellRenderer *cell_rend;
+
+ themesel_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
+ gtk_box_pack_start(GTK_BOX(vbox), themesel_hbox, FALSE, FALSE, 0);
+
+ label = gtk_label_new(label_str);
+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
+ gtk_size_group_add_widget(label_sg, label);
+ gtk_box_pack_start(GTK_BOX(themesel_hbox), label, FALSE, FALSE, 0);
+
+ combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(theme_store));
+
+ cell_rend = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), cell_rend, TRUE);
+ gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_rend, "text", 0, NULL);
+ g_object_set(cell_rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+
+ g_signal_connect(G_OBJECT(combo_box), "changed",
+ (GCallback)combo_box_cb, combo_box_cb_user_data);
+ gtk_size_group_add_widget(combo_sg, combo_box);
+ gtk_box_pack_start(GTK_BOX(themesel_hbox), combo_box, TRUE, TRUE, 0);
+
+ return combo_box;
+}
+
+static GtkWidget *
theme_page(void)
{
GtkWidget *label;
@@ -1101,6 +1287,20 @@ theme_page(void)
(GCallback)prefs_set_blist_theme_cb, NULL,
_("Buddy List Theme:"), PIDGIN_PREFS_ROOT "/blist/theme", "blist");
+ /* Conversation Themes */
+ prefs_conv_themes_combo_box = add_theme_prefs_combo(
+ vbox, combo_sg, label_sg, prefs_conv_themes,
+ (GCallback)prefs_set_conv_theme_cb, NULL,
+ _("Conversation Theme:"), PIDGIN_PREFS_ROOT "/conversations/theme", "conversation");
+
+ /* Conversation Theme Variants */
+ prefs_conv_variants_combo_box = add_child_theme_prefs_combo(
+ vbox, combo_sg, label_sg, prefs_conv_variants,
+ (GCallback)prefs_set_conv_variant_cb, NULL, _("\tVariant:"));
+
+ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(prefs_conv_variants),
+ 0, GTK_SORT_ASCENDING);
+
/* Status Icon Themes */
prefs_status_themes_combo_box = add_theme_prefs_combo(
vbox, combo_sg, label_sg, prefs_status_icon_themes,
@@ -1131,82 +1331,69 @@ theme_page(void)
}
static void
-formatting_toggle_cb(GtkIMHtml *imhtml, GtkIMHtmlButtons buttons, void *toolbar)
-{
- gboolean bold, italic, uline;
-
- gtk_imhtml_get_current_format(GTK_IMHTML(imhtml),
- &bold, &italic, &uline);
-
- if (buttons & GTK_IMHTML_BOLD)
- purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/send_bold", bold);
- if (buttons & GTK_IMHTML_ITALIC)
- purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/send_italic", italic);
- if (buttons & GTK_IMHTML_UNDERLINE)
- purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/send_underline", uline);
-
- if (buttons & GTK_IMHTML_GROW || buttons & GTK_IMHTML_SHRINK)
+formatting_toggle_cb(GtkWebView *webview, GtkWebViewButtons buttons, void *toolbar)
+{
+ gboolean bold, italic, uline, strike;
+
+ gtk_webview_get_current_format(webview, &bold, &italic, &uline, &strike);
+
+ if (buttons & GTK_WEBVIEW_BOLD)
+ purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/send_bold",
+ bold);
+ if (buttons & GTK_WEBVIEW_ITALIC)
+ purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/send_italic",
+ italic);
+ if (buttons & GTK_WEBVIEW_UNDERLINE)
+ purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/send_underline",
+ uline);
+ if (buttons & GTK_WEBVIEW_STRIKE)
+ purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/send_strike",
+ strike);
+
+ if (buttons & GTK_WEBVIEW_GROW || buttons & GTK_WEBVIEW_SHRINK)
purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/font_size",
- gtk_imhtml_get_current_fontsize(GTK_IMHTML(imhtml)));
- if (buttons & GTK_IMHTML_FACE) {
- char *face = gtk_imhtml_get_current_fontface(GTK_IMHTML(imhtml));
- if (!face)
- face = g_strdup("");
+ gtk_webview_get_current_fontsize(webview));
+ if (buttons & GTK_WEBVIEW_FACE) {
+ char *face = gtk_webview_get_current_fontface(webview);
- purple_prefs_set_string(PIDGIN_PREFS_ROOT "/conversations/font_face", face);
- g_free(face);
- }
-
- if (buttons & GTK_IMHTML_FORECOLOR) {
- char *color = gtk_imhtml_get_current_forecolor(GTK_IMHTML(imhtml));
- if (!color)
- color = g_strdup("");
+ if (face)
+ purple_prefs_set_string(PIDGIN_PREFS_ROOT "/conversations/font_face", face);
+ else
+ purple_prefs_set_string(PIDGIN_PREFS_ROOT "/conversations/font_face", "");
- purple_prefs_set_string(PIDGIN_PREFS_ROOT "/conversations/fgcolor", color);
- g_free(color);
+ g_free(face);
}
- if (buttons & GTK_IMHTML_BACKCOLOR) {
- char *color;
- GObject *object;
-
- color = gtk_imhtml_get_current_backcolor(GTK_IMHTML(imhtml));
- if (!color)
- color = g_strdup("");
-
- /* Block the signal to prevent a loop. */
- object = g_object_ref(G_OBJECT(imhtml));
- g_signal_handlers_block_matched(object, G_SIGNAL_MATCH_DATA, 0, 0, NULL,
- NULL, toolbar);
- /* Clear the backcolor. */
- gtk_imhtml_toggle_backcolor(GTK_IMHTML(imhtml), "");
- /* Unblock the signal. */
- g_signal_handlers_unblock_matched(object, G_SIGNAL_MATCH_DATA, 0, 0, NULL,
- NULL, toolbar);
- g_object_unref(object);
+ if (buttons & GTK_WEBVIEW_FORECOLOR) {
+ char *color = gtk_webview_get_current_forecolor(webview);
- /* This will fire a toggle signal and get saved below. */
- gtk_imhtml_toggle_background(GTK_IMHTML(imhtml), color);
+ if (color)
+ purple_prefs_set_string(PIDGIN_PREFS_ROOT "/conversations/fgcolor", color);
+ else
+ purple_prefs_set_string(PIDGIN_PREFS_ROOT "/conversations/fgcolor", "");
g_free(color);
}
- if (buttons & GTK_IMHTML_BACKGROUND) {
- char *color = gtk_imhtml_get_current_background(GTK_IMHTML(imhtml));
- if (!color)
- color = g_strdup("");
+ if (buttons & GTK_WEBVIEW_BACKCOLOR) {
+ char *color = gtk_webview_get_current_backcolor(webview);
+
+ if (color)
+ purple_prefs_set_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor", color);
+ else
+ purple_prefs_set_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor", "");
- purple_prefs_set_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor", color);
g_free(color);
}
}
static void
-formatting_clear_cb(GtkIMHtml *imhtml, void *data)
+formatting_clear_cb(GtkWebView *webview, void *data)
{
purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/send_bold", FALSE);
purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/send_italic", FALSE);
purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/send_underline", FALSE);
+ purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/send_strike", FALSE);
purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/font_size", 3);
@@ -1422,7 +1609,7 @@ apply_custom_font(void)
desc = pango_font_description_from_string(font);
}
- gtk_widget_modify_font(sample_imhtml, desc);
+ gtk_widget_modify_font(sample_webview, desc);
if (desc)
pango_font_description_free(desc);
@@ -1446,7 +1633,7 @@ conv_page(void)
GtkWidget *toolbar;
GtkWidget *iconpref1;
GtkWidget *iconpref2;
- GtkWidget *imhtml;
+ GtkWidget *webview;
GtkWidget *frame;
GtkWidget *hbox;
GtkWidget *checkbox;
@@ -1536,33 +1723,38 @@ conv_page(void)
vbox = pidgin_make_frame(ret, _("Default Formatting"));
- frame = pidgin_create_imhtml(TRUE, &imhtml, &toolbar, NULL);
+ frame = pidgin_create_webview(TRUE, &webview, &toolbar, NULL);
gtk_widget_show(frame);
- gtk_widget_set_name(imhtml, "pidgin_prefs_font_imhtml");
+ gtk_widget_set_name(webview, "pidgin_prefs_font_webview");
gtk_widget_set_size_request(frame, 450, -1);
- gtk_imhtml_set_whole_buffer_formatting_only(GTK_IMHTML(imhtml), TRUE);
- gtk_imhtml_set_format_functions(GTK_IMHTML(imhtml),
- GTK_IMHTML_BOLD |
- GTK_IMHTML_ITALIC |
- GTK_IMHTML_UNDERLINE |
- GTK_IMHTML_GROW |
- GTK_IMHTML_SHRINK |
- GTK_IMHTML_FACE |
- GTK_IMHTML_FORECOLOR |
- GTK_IMHTML_BACKCOLOR |
- GTK_IMHTML_BACKGROUND);
-
- gtk_imhtml_append_text(GTK_IMHTML(imhtml), _("This is how your outgoing message text will appear when you use protocols that support formatting."), 0);
+ gtk_webview_set_whole_buffer_formatting_only(GTK_WEBVIEW(webview), TRUE);
+ gtk_webview_set_format_functions(GTK_WEBVIEW(webview),
+ GTK_WEBVIEW_BOLD |
+ GTK_WEBVIEW_ITALIC |
+ GTK_WEBVIEW_UNDERLINE |
+ GTK_WEBVIEW_STRIKE |
+ GTK_WEBVIEW_GROW |
+ GTK_WEBVIEW_SHRINK |
+ GTK_WEBVIEW_FACE |
+ GTK_WEBVIEW_FORECOLOR |
+ GTK_WEBVIEW_BACKCOLOR);
+
+ gtk_webview_append_html(GTK_WEBVIEW(webview),
+ _("This is how your outgoing message text will "
+ "appear when you use protocols that support "
+ "formatting."));
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
- gtk_imhtml_setup_entry(GTK_IMHTML(imhtml), PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_FORMATTING_WBFO);
+ gtk_webview_setup_entry(GTK_WEBVIEW(webview),
+ PURPLE_CONNECTION_HTML |
+ PURPLE_CONNECTION_FORMATTING_WBFO);
- g_signal_connect_after(G_OBJECT(imhtml), "format_function_toggle",
- G_CALLBACK(formatting_toggle_cb), toolbar);
- g_signal_connect_after(G_OBJECT(imhtml), "format_function_clear",
- G_CALLBACK(formatting_clear_cb), NULL);
- sample_imhtml = imhtml;
+ g_signal_connect_after(G_OBJECT(webview), "format-toggled",
+ G_CALLBACK(formatting_toggle_cb), toolbar);
+ g_signal_connect_after(G_OBJECT(webview), "format-cleared",
+ G_CALLBACK(formatting_clear_cb), NULL);
+ sample_webview = webview;
gtk_widget_show(ret);
@@ -2883,6 +3075,10 @@ pidgin_prefs_init(void)
/* Themes */
prefs_themes_init();
+ /* Conversation Themes */
+ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations");
+ purple_prefs_add_string(PIDGIN_PREFS_ROOT "/conversations/theme", "Default");
+
/* Smiley Themes */
purple_prefs_add_none(PIDGIN_PREFS_ROOT "/smileys");
purple_prefs_add_string(PIDGIN_PREFS_ROOT "/smileys/theme", "Default");
@@ -2899,15 +3095,12 @@ pidgin_prefs_update_old(void)
{
const char *str = NULL;
- purple_prefs_rename("/gaim/gtk", PIDGIN_PREFS_ROOT);
-
/* Rename some old prefs */
purple_prefs_rename(PIDGIN_PREFS_ROOT "/logging/log_ims", "/purple/logging/log_ims");
purple_prefs_rename(PIDGIN_PREFS_ROOT "/logging/log_chats", "/purple/logging/log_chats");
purple_prefs_rename("/purple/conversations/placement",
PIDGIN_PREFS_ROOT "/conversations/placement");
- purple_prefs_rename(PIDGIN_PREFS_ROOT "/debug/timestamps", "/purple/debug/timestamps");
purple_prefs_rename(PIDGIN_PREFS_ROOT "/conversations/im/raise_on_events", "/plugins/gtk/X11/notify/method_raise");
purple_prefs_rename_boolean_toggle(PIDGIN_PREFS_ROOT "/conversations/ignore_colors",
@@ -2924,12 +3117,6 @@ pidgin_prefs_update_old(void)
purple_prefs_remove(PIDGIN_PREFS_ROOT "/browsers/command");
}
- /* this string pref moved into the core, try to be friendly */
- purple_prefs_rename(PIDGIN_PREFS_ROOT "/idle/reporting_method", "/purple/away/idle_reporting");
- if ((str = purple_prefs_get_string("/purple/away/idle_reporting")) &&
- strcmp(str, "gaim") == 0)
- purple_prefs_set_string("/purple/away/idle_reporting", "purple");
-
/* Remove some no-longer-used prefs */
purple_prefs_remove(PIDGIN_PREFS_ROOT "/blist/auto_expand_contacts");
purple_prefs_remove(PIDGIN_PREFS_ROOT "/blist/button_style");
@@ -2959,6 +3146,7 @@ pidgin_prefs_update_old(void)
purple_prefs_remove(PIDGIN_PREFS_ROOT "/conversations/ignore_fonts");
purple_prefs_remove(PIDGIN_PREFS_ROOT "/conversations/ignore_font_sizes");
purple_prefs_remove(PIDGIN_PREFS_ROOT "/conversations/passthrough_unknown_commands");
+ purple_prefs_remove(PIDGIN_PREFS_ROOT "/debug/timestamps");
purple_prefs_remove(PIDGIN_PREFS_ROOT "/idle");
purple_prefs_remove(PIDGIN_PREFS_ROOT "/logging/individual_logs");
purple_prefs_remove(PIDGIN_PREFS_ROOT "/sound/signon");
diff --git a/pidgin/gtkprefs.h b/pidgin/gtkprefs.h
index d07c968b8a..bc19210ab7 100644
--- a/pidgin/gtkprefs.h
+++ b/pidgin/gtkprefs.h
@@ -29,6 +29,8 @@
#include "prefs.h"
+G_BEGIN_DECLS
+
/**
* Initializes all UI-specific preferences.
*/
@@ -92,8 +94,6 @@ GtkWidget *pidgin_prefs_labeled_entry(GtkWidget *page, const gchar *title,
* @return An hbox containing both the label and the entry. Can be used to set
* the widgets to sensitive or insensitive based on the value of a
* checkbox.
- *
- * @since 2.6.0
*/
GtkWidget *pidgin_prefs_labeled_password(GtkWidget *page, const gchar *title,
const char *key, GtkSizeGroup *sg);
@@ -130,4 +130,6 @@ GtkWidget *pidgin_prefs_dropdown_from_list(GtkWidget *page,
*/
void pidgin_prefs_update_old(void);
+G_END_DECLS
+
#endif /* _PIDGINPREFS_H_ */
diff --git a/pidgin/gtkprivacy.c b/pidgin/gtkprivacy.c
index 78f7278f13..3ed3debbc2 100644
--- a/pidgin/gtkprivacy.c
+++ b/pidgin/gtkprivacy.c
@@ -211,7 +211,7 @@ select_account_cb(GtkWidget *dropdown, PurpleAccount *account,
dialog->account = account;
for (i = 0; i < menu_entry_count; i++) {
- if (menu_entries[i].num == account->perm_deny) {
+ if (menu_entries[i].num == purple_account_get_privacy_type(account)) {
gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->type_menu), i);
break;
}
@@ -230,7 +230,7 @@ type_changed_cb(GtkComboBox *combo, PidginPrivacyDialog *dialog)
{
int new_type = menu_entries[gtk_combo_box_get_active(combo)].num;
- dialog->account->perm_deny = new_type;
+ purple_account_set_privacy_type(dialog->account, new_type);
serv_set_permit_deny(purple_account_get_connection(dialog->account));
gtk_widget_hide(dialog->allow_widget);
@@ -371,7 +371,7 @@ privacy_dialog_new(void)
gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->type_menu),
_(menu_entries[i].text));
- if (menu_entries[i].num == dialog->account->perm_deny)
+ if (menu_entries[i].num == purple_account_get_privacy_type(dialog->account))
selected = i;
}
@@ -411,12 +411,12 @@ privacy_dialog_new(void)
type_changed_cb(GTK_COMBO_BOX(dialog->type_menu), dialog);
#if 0
- if (dialog->account->perm_deny == PURPLE_PRIVACY_ALLOW_USERS) {
+ if (purple_account_get_privacy_type(dialog->account) == PURPLE_PRIVACY_ALLOW_USERS) {
gtk_widget_show(dialog->allow_widget);
gtk_widget_show(dialog->button_box);
dialog->in_allow_list = TRUE;
}
- else if (dialog->account->perm_deny == PURPLE_PRIVACY_DENY_USERS) {
+ else if (purple_account_get_privacy_type(dialog->account) == PURPLE_PRIVACY_DENY_USERS) {
gtk_widget_show(dialog->block_widget);
gtk_widget_show(dialog->button_box);
dialog->in_allow_list = FALSE;
diff --git a/pidgin/gtkprivacy.h b/pidgin/gtkprivacy.h
index 0be6a05483..6ee81a4745 100644
--- a/pidgin/gtkprivacy.h
+++ b/pidgin/gtkprivacy.h
@@ -28,6 +28,8 @@
#include "privacy.h"
+G_BEGIN_DECLS
+
/**
* Initializes the GTK+ privacy subsystem.
*/
@@ -72,4 +74,6 @@ void pidgin_request_add_block(PurpleAccount *account, const char *name);
*/
PurplePrivacyUiOps *pidgin_privacy_get_ui_ops(void);
+G_END_DECLS
+
#endif /* _PIDGINPRIVACY_H_ */
diff --git a/pidgin/gtkrequest.c b/pidgin/gtkrequest.c
index 0ab41c80ad..ecd5870123 100644
--- a/pidgin/gtkrequest.c
+++ b/pidgin/gtkrequest.c
@@ -39,6 +39,27 @@
#include <gdk/gdkkeysyms.h>
+#ifdef ENABLE_GCR
+#define GCR_API_SUBJECT_TO_CHANGE
+#include <gcr/gcr.h>
+#include <gcr/gcr-simple-certificate.h>
+#endif
+
+#if !GTK_CHECK_VERSION(2,18,0)
+#define gtk_widget_set_can_default(x,y) do {\
+ if (y) \
+ GTK_WIDGET_SET_FLAGS(x, GTK_CAN_DEFAULT); \
+ else \
+ GTK_WIDGET_UNSET_FLAGS(x, GTK_CAN_DEFAULT); \
+} while(0)
+#define gtk_widget_set_can_focus(x,y) do {\
+ if (y) \
+ GTK_WIDGET_SET_FLAGS(x, GTK_CAN_FOCUS); \
+ else \
+ GTK_WIDGET_UNSET_FLAGS(x, GTK_CAN_FOCUS); \
+} while(0)
+#endif
+
static GtkWidget * create_account_field(PurpleRequestField *field);
typedef struct
@@ -86,7 +107,9 @@ pidgin_widget_decorate_account(GtkWidget *cont, PurpleAccount *account)
{
GtkWidget *image;
GdkPixbuf *pixbuf;
+#if !GTK_CHECK_VERSION(2,12,0)
GtkTooltips *tips;
+#endif
if (!account)
return;
@@ -95,8 +118,12 @@ pidgin_widget_decorate_account(GtkWidget *cont, PurpleAccount *account)
image = gtk_image_new_from_pixbuf(pixbuf);
g_object_unref(G_OBJECT(pixbuf));
+#if GTK_CHECK_VERSION(2,12,0)
+ gtk_widget_set_tooltip_text(image, purple_account_get_username(account));
+#else
tips = gtk_tooltips_new();
gtk_tooltips_set_tip(tips, image, purple_account_get_username(account), NULL);
+#endif
if (GTK_IS_DIALOG(cont)) {
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(cont)->action_area), image, FALSE, TRUE, 0);
@@ -257,7 +284,11 @@ multifield_ok_cb(GtkWidget *button, PidginRequestData *data)
{
generic_response_start(data);
+#if GTK_CHECK_VERSION(2,18,0)
+ if (!gtk_widget_has_focus(button))
+#else
if (!GTK_WIDGET_HAS_FOCUS(button))
+#endif
gtk_widget_grab_focus(button);
if (data->cbs[0] != NULL)
@@ -356,7 +387,9 @@ pidgin_request_input(const char *title, const char *primary,
gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER/2);
if (!multiline)
gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
+#if !GTK_CHECK_VERSION(2,22,0)
gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+#endif
gtk_dialog_set_default_response(GTK_DIALOG(dialog), 0);
gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
@@ -522,7 +555,9 @@ pidgin_request_choice(const char *title, const char *primary,
gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BORDER/2);
gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER/2);
gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
+#if !GTK_CHECK_VERSION(2,22,0)
gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+#endif
gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
/* Setup the main horizontal box */
@@ -644,7 +679,9 @@ pidgin_request_action_with_icon(const char *title, const char *primary,
gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BORDER/2);
gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER/2);
gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
+#if !GTK_CHECK_VERSION(2,22,0)
gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+#endif
gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
/* Setup the main horizontal box */
@@ -715,8 +752,8 @@ pidgin_request_action_with_icon(const char *title, const char *primary,
if (default_action == PURPLE_DEFAULT_ACTION_NONE) {
- GTK_WIDGET_SET_FLAGS(img, GTK_CAN_DEFAULT);
- GTK_WIDGET_SET_FLAGS(img, GTK_CAN_FOCUS);
+ gtk_widget_set_can_default(img, TRUE);
+ gtk_widget_set_can_focus(img, TRUE);
gtk_widget_grab_focus(img);
gtk_widget_grab_default(img);
} else
@@ -749,6 +786,7 @@ static void
req_entry_field_changed_cb(GtkWidget *entry, PurpleRequestField *field)
{
PurpleRequestFieldGroup *group;
+ PurpleRequestFields *fields;
PidginRequestData *req_data;
if (purple_request_field_string_is_multiline(field))
@@ -771,10 +809,11 @@ req_entry_field_changed_cb(GtkWidget *entry, PurpleRequestField *field)
}
group = purple_request_field_get_group(field);
- req_data = (PidginRequestData *)group->fields_list->ui_data;
+ fields = purple_request_field_group_get_fields_list(group);
+ req_data = purple_request_fields_get_ui_data(fields);
gtk_widget_set_sensitive(req_data->ok_button,
- purple_request_fields_all_required_filled(group->fields_list));
+ purple_request_fields_all_required_filled(fields));
}
static void
@@ -796,7 +835,7 @@ setup_entry_field(GtkWidget *entry, PurpleRequestField *field)
{
GtkWidget *optmenu = NULL;
PurpleRequestFieldGroup *group = purple_request_field_get_group(field);
- GList *fields = group->fields;
+ GList *fields = purple_request_field_group_get_fields(group);
/* Ensure the account option menu is created (if the widget hasn't
* been initialized already) for username auto-completion. */
@@ -857,6 +896,10 @@ create_string_field(PurpleRequestField *field)
gtk_text_buffer_set_text(buffer, value, -1);
}
+#if GTK_CHECK_VERSION(2,12,0)
+ gtk_widget_set_tooltip_text(textview, purple_request_field_get_tooltip(field));
+#endif
+
gtk_text_view_set_editable(GTK_TEXT_VIEW(textview),
purple_request_field_string_is_editable(field));
@@ -881,6 +924,10 @@ create_string_field(PurpleRequestField *field)
if (value != NULL)
gtk_entry_set_text(GTK_ENTRY(widget), value);
+#if GTK_CHECK_VERSION(2,12,0)
+ gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
+#endif
+
if (purple_request_field_string_is_masked(field))
{
gtk_entry_set_visibility(GTK_ENTRY(widget), FALSE);
@@ -921,6 +968,10 @@ create_int_field(PurpleRequestField *field)
gtk_entry_set_text(GTK_ENTRY(widget), buf);
}
+#if GTK_CHECK_VERSION(2,12,0)
+ gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
+#endif
+
g_signal_connect(G_OBJECT(widget), "focus-out-event",
G_CALLBACK(field_int_focus_out_cb), field);
@@ -935,6 +986,10 @@ create_bool_field(PurpleRequestField *field)
widget = gtk_check_button_new_with_label(
purple_request_field_get_label(field));
+#if GTK_CHECK_VERSION(2,12,0)
+ gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
+#endif
+
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
purple_request_field_bool_get_default_value(field));
@@ -965,6 +1020,10 @@ create_choice_field(PurpleRequestField *field)
gtk_combo_box_set_active(GTK_COMBO_BOX(widget),
purple_request_field_choice_get_default_value(field));
+#if GTK_CHECK_VERSION(2,12,0)
+ gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
+#endif
+
g_signal_connect(G_OBJECT(widget), "changed",
G_CALLBACK(field_choice_menu_cb), field);
}
@@ -982,6 +1041,10 @@ create_choice_field(PurpleRequestField *field)
widget = box;
+#if GTK_CHECK_VERSION(2,12,0)
+ gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
+#endif
+
for (l = labels, i = 0; l != NULL; l = l->next, i++)
{
const char *text = l->data;
@@ -1024,6 +1087,10 @@ create_image_field(PurpleRequestField *field)
g_object_unref(G_OBJECT(buf));
g_object_unref(G_OBJECT(scale));
+#if GTK_CHECK_VERSION(2,12,0)
+ gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
+#endif
+
return widget;
}
@@ -1039,6 +1106,10 @@ create_account_field(PurpleRequestField *field)
purple_request_field_account_get_filter(field),
field);
+#if GTK_CHECK_VERSION(2,12,0)
+ gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
+#endif
+
return widget;
}
@@ -1157,6 +1228,51 @@ create_list_field(PurpleRequestField *field)
return pidgin_make_scrollable(treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1);
}
+static GtkWidget *
+create_certificate_field(PurpleRequestField *field)
+{
+ PurpleCertificate *cert;
+#ifdef ENABLE_GCR
+ GcrCertificateBasicsWidget *cert_widget;
+ GByteArray *der;
+ GcrCertificate *gcrt;
+#else
+ GtkWidget *cert_label;
+ char *str;
+ char *escaped;
+#endif
+
+ cert = purple_request_field_certificate_get_value(field);
+
+#ifdef ENABLE_GCR
+ der = purple_certificate_get_der_data(cert);
+ g_return_val_if_fail(der, NULL);
+
+ gcrt = gcr_simple_certificate_new(der->data, der->len);
+ g_return_val_if_fail(gcrt, NULL);
+
+ cert_widget = gcr_certificate_basics_widget_new(gcrt);
+
+ g_byte_array_free(der, TRUE);
+ g_object_unref(G_OBJECT(gcrt));
+
+ return GTK_WIDGET(cert_widget);
+#else
+ str = purple_certificate_get_display_string(cert);
+ escaped = g_markup_escape_text(str, -1);
+
+ cert_label = gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(cert_label), escaped);
+ gtk_label_set_line_wrap(GTK_LABEL(cert_label), TRUE);
+ gtk_misc_set_alignment(GTK_MISC(cert_label), 0, 0);
+
+ g_free(str);
+ g_free(escaped);
+
+ return cert_label;
+#endif
+}
+
static void *
pidgin_request_fields(const char *title, const char *primary,
const char *secondary, PurpleRequestFields *fields,
@@ -1188,7 +1304,7 @@ pidgin_request_fields(const char *title, const char *primary,
data->user_data = user_data;
data->u.multifield.fields = fields;
- fields->ui_data = data;
+ purple_request_fields_set_ui_data(fields, data);
data->cb_count = 2;
data->cbs = g_new0(GCallback, 2);
@@ -1220,12 +1336,12 @@ pidgin_request_fields(const char *title, const char *primary,
/* Cancel button */
button = pidgin_dialog_add_button(GTK_DIALOG(win), text_to_stock(cancel_text), G_CALLBACK(multifield_cancel_cb), data);
- GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
+ gtk_widget_set_can_default(button, TRUE);
/* OK button */
button = pidgin_dialog_add_button(GTK_DIALOG(win), text_to_stock(ok_text), G_CALLBACK(multifield_ok_cb), data);
data->ok_button = button;
- GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
+ gtk_widget_set_can_default(button, TRUE);
gtk_window_set_default(GTK_WINDOW(win), button);
pidgin_widget_decorate_account(hbox, account);
@@ -1444,6 +1560,8 @@ pidgin_request_fields(const char *title, const char *primary,
widget = create_image_field(field);
else if (type == PURPLE_REQUEST_FIELD_ACCOUNT)
widget = create_account_field(field);
+ else if (type == PURPLE_REQUEST_FIELD_CERTIFICATE)
+ widget = create_certificate_field(field);
else
continue;
}
diff --git a/pidgin/gtkrequest.h b/pidgin/gtkrequest.h
index 83e466f6aa..77aca7c830 100644
--- a/pidgin/gtkrequest.h
+++ b/pidgin/gtkrequest.h
@@ -28,6 +28,8 @@
#include "request.h"
+G_BEGIN_DECLS
+
/**
* Returns the UI operations structure for GTK+ request functions.
*
@@ -35,4 +37,6 @@
*/
PurpleRequestUiOps *pidgin_request_get_ui_ops(void);
+G_END_DECLS
+
#endif /* _PIDGINREQUEST_H_ */
diff --git a/pidgin/gtkroomlist.c b/pidgin/gtkroomlist.c
index 63630b1766..21a3864483 100644
--- a/pidgin/gtkroomlist.c
+++ b/pidgin/gtkroomlist.c
@@ -91,7 +91,7 @@ static gint delete_win_cb(GtkWidget *w, GdkEventAny *e, gpointer d)
purple_timeout_remove(dialog->pg_update_to);
if (dialog->roomlist) {
- PidginRoomlist *rl = dialog->roomlist->ui_data;
+ PidginRoomlist *rl = purple_roomlist_get_ui_data(dialog->roomlist);
if (dialog->pg_update_to > 0)
/* yes, that's right, unref it twice. */
@@ -115,7 +115,7 @@ static void dialog_select_account_cb(GObject *w, PurpleAccount *account,
dialog->account = account;
if (change && dialog->roomlist) {
- PidginRoomlist *rl = dialog->roomlist->ui_data;
+ PidginRoomlist *rl = purple_roomlist_get_ui_data(dialog->roomlist);
if (rl->tree) {
gtk_widget_destroy(rl->tree);
rl->tree = NULL;
@@ -135,7 +135,7 @@ static void list_button_cb(GtkButton *button, PidginRoomlistDialog *dialog)
return;
if (dialog->roomlist != NULL) {
- rl = dialog->roomlist->ui_data;
+ rl = purple_roomlist_get_ui_data(dialog->roomlist);
gtk_widget_destroy(rl->tree);
purple_roomlist_unref(dialog->roomlist);
}
@@ -144,7 +144,7 @@ static void list_button_cb(GtkButton *button, PidginRoomlistDialog *dialog)
if (!dialog->roomlist)
return;
purple_roomlist_ref(dialog->roomlist);
- rl = dialog->roomlist->ui_data;
+ rl = purple_roomlist_get_ui_data(dialog->roomlist);
rl->dialog = dialog;
if (dialog->account_widget)
@@ -203,7 +203,7 @@ selection_changed_cb(GtkTreeSelection *selection, PidginRoomlist *grl) {
val.g_type = 0;
gtk_tree_model_get_value(GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &val);
room = g_value_get_pointer(&val);
- if (!room || !(room->type & PURPLE_ROOMLIST_ROOMTYPE_ROOM)) {
+ if (!room || !(purple_roomlist_room_get_type(room) & PURPLE_ROOMLIST_ROOMTYPE_ROOM)) {
gtk_widget_set_sensitive(dialog->join_button, FALSE);
gtk_widget_set_sensitive(dialog->add_button, FALSE);
return;
@@ -228,18 +228,19 @@ selection_changed_cb(GtkTreeSelection *selection, PidginRoomlist *grl) {
static void do_add_room_cb(GtkWidget *w, struct _menu_cb_info *info)
{
char *name;
- PurpleConnection *gc = purple_account_get_connection(info->list->account);
+ PurpleAccount *account = purple_roomlist_get_account(info->list);
+ PurpleConnection *gc = purple_account_get_connection(account);
PurplePluginProtocolInfo *prpl_info = NULL;
if(gc != NULL)
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
if(prpl_info != NULL && prpl_info->roomlist_room_serialize)
name = prpl_info->roomlist_room_serialize(info->room);
else
- name = g_strdup(info->room->name);
+ name = g_strdup(purple_roomlist_room_get_name(info->room));
- purple_blist_request_add_chat(info->list->account, NULL, NULL, name);
+ purple_blist_request_add_chat(account, NULL, NULL, name);
g_free(name);
}
@@ -247,7 +248,7 @@ static void do_add_room_cb(GtkWidget *w, struct _menu_cb_info *info)
static void add_room_to_blist_cb(GtkButton *button, PidginRoomlistDialog *dialog)
{
PurpleRoomlist *rl = dialog->roomlist;
- PidginRoomlist *grl = rl->ui_data;
+ PidginRoomlist *grl = purple_roomlist_get_ui_data(rl);
struct _menu_cb_info *info = g_object_get_data(G_OBJECT(button), "room-info");
if(info != NULL)
@@ -262,7 +263,7 @@ static void do_join_cb(GtkWidget *w, struct _menu_cb_info *info)
static void join_button_cb(GtkButton *button, PidginRoomlistDialog *dialog)
{
PurpleRoomlist *rl = dialog->roomlist;
- PidginRoomlist *grl = rl->ui_data;
+ PidginRoomlist *grl = purple_roomlist_get_ui_data(rl);
struct _menu_cb_info *info = g_object_get_data(G_OBJECT(button), "room-info");
if(info != NULL)
@@ -272,7 +273,7 @@ static void join_button_cb(GtkButton *button, PidginRoomlistDialog *dialog)
static void row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *arg2,
PurpleRoomlist *list)
{
- PidginRoomlist *grl = list->ui_data;
+ PidginRoomlist *grl = purple_roomlist_get_ui_data(list);
GtkTreeIter iter;
PurpleRoomlistRoom *room;
GValue val;
@@ -282,7 +283,7 @@ static void row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColu
val.g_type = 0;
gtk_tree_model_get_value(GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &val);
room = g_value_get_pointer(&val);
- if (!room || !(room->type & PURPLE_ROOMLIST_ROOMTYPE_ROOM))
+ if (!room || !(purple_roomlist_room_get_type(room) & PURPLE_ROOMLIST_ROOMTYPE_ROOM))
return;
info.list = list;
@@ -294,7 +295,7 @@ static void row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColu
static gboolean room_click_cb(GtkWidget *tv, GdkEventButton *event, PurpleRoomlist *list)
{
GtkTreePath *path;
- PidginRoomlist *grl = list->ui_data;
+ PidginRoomlist *grl = purple_roomlist_get_ui_data(list);
GValue val;
PurpleRoomlistRoom *room;
GtkTreeIter iter;
@@ -313,7 +314,7 @@ static gboolean room_click_cb(GtkWidget *tv, GdkEventButton *event, PurpleRoomli
gtk_tree_model_get_value (GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &val);
room = g_value_get_pointer(&val);
- if (!room || !(room->type & PURPLE_ROOMLIST_ROOMTYPE_ROOM))
+ if (!room || !(purple_roomlist_room_get_type(room) & PURPLE_ROOMLIST_ROOMTYPE_ROOM))
return FALSE;
info.list = list;
@@ -341,9 +342,9 @@ static void row_expanded_cb(GtkTreeView *treeview, GtkTreeIter *arg1, GtkTreePat
gtk_tree_model_get_value(gtk_tree_view_get_model(treeview), arg1, ROOM_COLUMN, &val);
category = g_value_get_pointer(&val);
- if (!category->expanded_once) {
+ if (!purple_roomlist_room_get_expanded_once(category)) {
purple_roomlist_expand_category(list, category);
- category->expanded_once = TRUE;
+ purple_roomlist_room_set_expanded_once(category, TRUE);
}
}
@@ -354,7 +355,7 @@ static gboolean
pidgin_roomlist_paint_tooltip(GtkWidget *widget, gpointer user_data)
{
PurpleRoomlist *list = user_data;
- PidginRoomlist *grl = list->ui_data;
+ PidginRoomlist *grl = purple_roomlist_get_ui_data(list);
GtkStyle *style;
int current_height, max_width;
int max_text_width;
@@ -393,7 +394,7 @@ pidgin_roomlist_paint_tooltip(GtkWidget *widget, gpointer user_data)
static gboolean pidgin_roomlist_create_tip(PurpleRoomlist *list, GtkTreePath *path)
{
- PidginRoomlist *grl = list->ui_data;
+ PidginRoomlist *grl = purple_roomlist_get_ui_data(list);
PurpleRoomlistRoom *room;
GtkTreeIter iter;
GValue val;
@@ -414,19 +415,23 @@ static gboolean pidgin_roomlist_create_tip(PurpleRoomlist *list, GtkTreePath *pa
gtk_tree_model_get_value(GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &val);
room = g_value_get_pointer(&val);
- if (!room || !(room->type & PURPLE_ROOMLIST_ROOMTYPE_ROOM))
+ if (!room || !(purple_roomlist_room_get_type(room) & PURPLE_ROOMLIST_ROOMTYPE_ROOM))
return FALSE;
tooltip_text = g_string_new("");
gtk_tree_model_get(GTK_TREE_MODEL(grl->model), &iter, NAME_COLUMN, &name, -1);
- for (j = NUM_OF_COLUMNS, l = room->fields, k = list->fields; l && k; j++, l = l->next, k = k->next) {
+ for (j = NUM_OF_COLUMNS,
+ l = purple_roomlist_room_get_fields(room),
+ k = purple_roomlist_get_fields(list);
+ l && k; j++, l = l->next, k = k->next)
+ {
PurpleRoomlistField *f = k->data;
gchar *label;
- if (f->hidden)
+ if (purple_roomlist_field_get_hidden(f))
continue;
- label = g_markup_escape_text(f->label, -1);
- switch (f->type) {
+ label = g_markup_escape_text(purple_roomlist_field_get_label(f), -1);
+ switch (purple_roomlist_field_get_type(f)) {
case PURPLE_ROOMLIST_FIELD_BOOL:
g_string_append_printf(tooltip_text, "%s<b>%s:</b> %s", first ? "" : "\n", label, l->data ? "True" : "False");
break;
@@ -478,7 +483,7 @@ pidgin_roomlist_create_tooltip(GtkWidget *widget, GtkTreePath *path,
gpointer data, int *w, int *h)
{
PurpleRoomlist *list = data;
- PidginRoomlist *grl = list->ui_data;
+ PidginRoomlist *grl = purple_roomlist_get_ui_data(list);
grl->tipwindow = widget;
if (!pidgin_roomlist_create_tip(data, path))
return FALSE;
@@ -497,7 +502,7 @@ static gboolean account_filter_func(PurpleAccount *account)
PurplePluginProtocolInfo *prpl_info = NULL;
if (conn && PURPLE_CONNECTION_IS_CONNECTED(conn))
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(conn->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(conn));
return (prpl_info && prpl_info->roomlist_get_list != NULL);
}
@@ -622,7 +627,7 @@ static void pidgin_roomlist_new(PurpleRoomlist *list)
{
PidginRoomlist *rl = g_new0(PidginRoomlist, 1);
- list->ui_data = rl;
+ purple_roomlist_set_ui_data(list, rl);
rl->cats = g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify)gtk_tree_row_reference_free);
@@ -685,7 +690,7 @@ _search_func(GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *it
static void pidgin_roomlist_set_fields(PurpleRoomlist *list, GList *fields)
{
- PidginRoomlist *grl = list->ui_data;
+ PidginRoomlist *grl = purple_roomlist_get_ui_data(list);
gint columns = NUM_OF_COLUMNS;
int j;
GtkTreeStore *model;
@@ -707,7 +712,7 @@ static void pidgin_roomlist_set_fields(PurpleRoomlist *list, GList *fields)
for (j = NUM_OF_COLUMNS, l = fields; l; l = l->next, j++) {
PurpleRoomlistField *f = l->data;
- switch (f->type) {
+ switch (purple_roomlist_field_get_type(f)) {
case PURPLE_ROOMLIST_FIELD_BOOL:
types[j] = G_TYPE_BOOLEAN;
break;
@@ -749,18 +754,19 @@ static void pidgin_roomlist_set_fields(PurpleRoomlist *list, GList *fields)
for (j = NUM_OF_COLUMNS, l = fields; l; l = l->next, j++) {
PurpleRoomlistField *f = l->data;
- if (f->hidden)
+ if (purple_roomlist_field_get_hidden(f))
continue;
renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(f->label, renderer,
- "text", j, NULL);
+ column = gtk_tree_view_column_new_with_attributes(
+ purple_roomlist_field_get_label(f), renderer,
+ "text", j, NULL);
gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column),
GTK_TREE_VIEW_COLUMN_GROW_ONLY);
gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column), j);
gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
- if (f->type == PURPLE_ROOMLIST_FIELD_INT) {
+ if (purple_roomlist_field_get_type(f) == PURPLE_ROOMLIST_FIELD_INT) {
gtk_tree_view_column_set_cell_data_func(column, renderer, int_cell_data_func,
GINT_TO_POINTER(j), NULL);
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model), j, int_sort_func,
@@ -789,7 +795,7 @@ static void pidgin_roomlist_set_fields(PurpleRoomlist *list, GList *fields)
static gboolean pidgin_progress_bar_pulse(gpointer data)
{
PurpleRoomlist *list = data;
- PidginRoomlist *rl = list->ui_data;
+ PidginRoomlist *rl = purple_roomlist_get_ui_data(list);
if (!rl || !rl->dialog || !rl->dialog->pg_needs_pulse) {
if (rl && rl->dialog)
@@ -805,7 +811,7 @@ static gboolean pidgin_progress_bar_pulse(gpointer data)
static void pidgin_roomlist_add_room(PurpleRoomlist *list, PurpleRoomlistRoom *room)
{
- PidginRoomlist *rl = list->ui_data;
+ PidginRoomlist *rl = purple_roomlist_get_ui_data(list);
GtkTreeRowReference *rr, *parentrr = NULL;
GtkTreePath *path;
GtkTreeIter iter, parent, child;
@@ -814,7 +820,7 @@ static void pidgin_roomlist_add_room(PurpleRoomlist *list, PurpleRoomlistRoom *r
gboolean append = TRUE;
rl->total_rooms++;
- if (room->type == PURPLE_ROOMLIST_ROOMTYPE_ROOM)
+ if (purple_roomlist_room_get_type(room) == PURPLE_ROOMLIST_ROOMTYPE_ROOM)
rl->num_rooms++;
if (rl->dialog) {
@@ -826,8 +832,8 @@ static void pidgin_roomlist_add_room(PurpleRoomlist *list, PurpleRoomlistRoom *r
rl->dialog->pg_needs_pulse = TRUE;
}
- if (room->parent) {
- parentrr = g_hash_table_lookup(rl->cats, room->parent);
+ if (purple_roomlist_room_get_parent(room)) {
+ parentrr = g_hash_table_lookup(rl->cats, purple_roomlist_room_get_parent(room));
path = gtk_tree_row_reference_get_path(parentrr);
if (path) {
PurpleRoomlistRoom *tmproom = NULL;
@@ -848,24 +854,28 @@ static void pidgin_roomlist_add_room(PurpleRoomlist *list, PurpleRoomlistRoom *r
else
iter = child;
- if (room->type & PURPLE_ROOMLIST_ROOMTYPE_CATEGORY)
+ if (purple_roomlist_room_get_type(room) & PURPLE_ROOMLIST_ROOMTYPE_CATEGORY)
gtk_tree_store_append(rl->model, &child, &iter);
path = gtk_tree_model_get_path(GTK_TREE_MODEL(rl->model), &iter);
- if (room->type & PURPLE_ROOMLIST_ROOMTYPE_CATEGORY) {
+ if (purple_roomlist_room_get_type(room) & PURPLE_ROOMLIST_ROOMTYPE_CATEGORY) {
rr = gtk_tree_row_reference_new(GTK_TREE_MODEL(rl->model), path);
g_hash_table_insert(rl->cats, room, rr);
}
gtk_tree_path_free(path);
- gtk_tree_store_set(rl->model, &iter, NAME_COLUMN, room->name, -1);
+ gtk_tree_store_set(rl->model, &iter, NAME_COLUMN, purple_roomlist_room_get_name(room), -1);
gtk_tree_store_set(rl->model, &iter, ROOM_COLUMN, room, -1);
- for (j = NUM_OF_COLUMNS, l = room->fields, k = list->fields; l && k; j++, l = l->next, k = k->next) {
+ for (j = NUM_OF_COLUMNS,
+ l = purple_roomlist_room_get_fields(room),
+ k = purple_roomlist_get_fields(list);
+ l && k; j++, l = l->next, k = k->next)
+ {
PurpleRoomlistField *f = k->data;
- if (f->hidden)
+ if (purple_roomlist_field_get_hidden(f))
continue;
gtk_tree_store_set(rl->model, &iter, j, l->data, -1);
}
@@ -873,7 +883,7 @@ static void pidgin_roomlist_add_room(PurpleRoomlist *list, PurpleRoomlistRoom *r
static void pidgin_roomlist_in_progress(PurpleRoomlist *list, gboolean in_progress)
{
- PidginRoomlist *rl = list->ui_data;
+ PidginRoomlist *rl = purple_roomlist_get_ui_data(list);
if (!rl || !rl->dialog)
return;
@@ -895,7 +905,7 @@ static void pidgin_roomlist_in_progress(PurpleRoomlist *list, gboolean in_progre
static void pidgin_roomlist_destroy(PurpleRoomlist *list)
{
- PidginRoomlist *rl = list->ui_data;
+ PidginRoomlist *rl = purple_roomlist_get_ui_data(list);
roomlists = g_list_remove(roomlists, list);
@@ -903,7 +913,7 @@ static void pidgin_roomlist_destroy(PurpleRoomlist *list)
g_hash_table_destroy(rl->cats);
g_free(rl);
- list->ui_data = NULL;
+ purple_roomlist_set_ui_data(list, NULL);
}
static PurpleRoomlistUiOps ops = {
diff --git a/pidgin/gtkroomlist.h b/pidgin/gtkroomlist.h
index ed905e5c6b..1851132d18 100644
--- a/pidgin/gtkroomlist.h
+++ b/pidgin/gtkroomlist.h
@@ -28,6 +28,8 @@
#include "roomlist.h"
+G_BEGIN_DECLS
+
/**
* Initializes the room list subsystem.
*/
@@ -53,4 +55,6 @@ void pidgin_roomlist_dialog_show(void);
*/
void pidgin_roomlist_dialog_show_with_account(PurpleAccount *account);
+G_END_DECLS
+
#endif /* _PIDGINROOMLIST_H_ */
diff --git a/pidgin/gtksavedstatuses.c b/pidgin/gtksavedstatuses.c
index c82c8317f3..bf8d1394c1 100644
--- a/pidgin/gtksavedstatuses.c
+++ b/pidgin/gtksavedstatuses.c
@@ -524,7 +524,11 @@ create_saved_status_list(StatusWindow *dialog)
static gboolean
configure_cb(GtkWidget *widget, GdkEventConfigure *event, StatusWindow *dialog)
{
+#if GTK_CHECK_VERSION(2,18,0)
+ if (gtk_widget_get_visible(widget))
+#else
if (GTK_WIDGET_VISIBLE(widget))
+#endif
{
purple_prefs_set_int(PIDGIN_PREFS_ROOT "/status/dialog/width", event->width);
purple_prefs_set_int(PIDGIN_PREFS_ROOT "/status/dialog/height", event->height);
diff --git a/pidgin/gtksavedstatuses.h b/pidgin/gtksavedstatuses.h
index 144fd052c7..e582de8eb2 100644
--- a/pidgin/gtksavedstatuses.h
+++ b/pidgin/gtksavedstatuses.h
@@ -29,6 +29,8 @@
#include "savedstatuses.h"
#include "status.h"
+G_BEGIN_DECLS
+
/**
* Shows the status window.
*/
@@ -85,4 +87,6 @@ void pidgin_status_init(void);
*/
void pidgin_status_uninit(void);
+G_END_DECLS
+
#endif /* _PIDGINSAVEDSTATUSES_H_ */
diff --git a/pidgin/gtkscrollbook.c b/pidgin/gtkscrollbook.c
index aa499932ed..50f5748dca 100644
--- a/pidgin/gtkscrollbook.c
+++ b/pidgin/gtkscrollbook.c
@@ -147,7 +147,7 @@ scroll_close_cb(PidginScrollBook *scroll_book, GdkEventButton *event)
}
static void
-switch_page_cb(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, PidginScrollBook *scroll_book)
+switch_page_cb(GtkNotebook *notebook, GtkWidget *page, guint page_num, PidginScrollBook *scroll_book)
{
int count;
count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book->notebook));
diff --git a/pidgin/gtksession.h b/pidgin/gtksession.h
index fb7711329e..ad0909453b 100644
--- a/pidgin/gtksession.h
+++ b/pidgin/gtksession.h
@@ -26,6 +26,8 @@
#ifndef _PIDGINSESSION_H_
#define _PIDGINSESSION_H_
+G_BEGIN_DECLS
+
/**************************************************************************/
/** @name X Windows session subsystem */
/**************************************************************************/
@@ -51,4 +53,6 @@ void pidgin_session_end(void);
/*@}*/
+G_END_DECLS
+
#endif /* _PIDGINSESSION_H_ */
diff --git a/pidgin/gtksmiley.c b/pidgin/gtksmiley.c
index 2ea41edc14..a8819db89b 100644
--- a/pidgin/gtksmiley.c
+++ b/pidgin/gtksmiley.c
@@ -47,9 +47,9 @@ struct _PidginSmiley
GtkWidget *smiley_image;
gchar *filename;
GdkPixbuf *custom_pixbuf;
- gpointer data; /** @since 2.6.0 */
- gsize datasize; /** @since 2.6.0 */
- gint entry_len; /** @since 2.6.0 */
+ gpointer data;
+ gsize datasize;
+ gint entry_len;
};
typedef struct
@@ -750,7 +750,7 @@ smiley_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
} else if (!g_ascii_strncasecmp(name, "http://", 7)) {
/* Oo, a web drag and drop. This is where things
* will start to get interesting */
- purple_util_fetch_url(name, TRUE, NULL, FALSE, smiley_got_url, dialog);
+ purple_util_fetch_url(name, TRUE, NULL, FALSE, -1, smiley_got_url, dialog);
} else if (!g_ascii_strncasecmp(name, "https://", 8)) {
/* purple_util_fetch_url() doesn't support HTTPS */
char *tmp = g_strdup(name + 1);
@@ -759,7 +759,7 @@ smiley_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
tmp[2] = 't';
tmp[3] = 'p';
- purple_util_fetch_url(tmp, TRUE, NULL, FALSE, smiley_got_url, dialog);
+ purple_util_fetch_url(tmp, TRUE, NULL, FALSE, -1, smiley_got_url, dialog);
g_free(tmp);
}
diff --git a/pidgin/gtksmiley.h b/pidgin/gtksmiley.h
index 8cf62a8add..2d7b5e381d 100644
--- a/pidgin/gtksmiley.h
+++ b/pidgin/gtksmiley.h
@@ -1,7 +1,6 @@
/**
* @file gtksmiley.h GTK+ Custom Smiley API
* @ingroup pidgin
- * @since 2.5.0
*/
/* pidgin
@@ -32,6 +31,8 @@
typedef struct _PidginSmiley PidginSmiley;
+G_BEGIN_DECLS
+
/**
* Add a PurpleSmiley to the GtkIMHtmlSmiley's list to be able to use it
* in pidgin
@@ -106,9 +107,9 @@ void pidgin_smiley_editor_set_image(PidginSmiley *editor, GdkPixbuf *image);
* @param editor A smiley editor dialog
* @param data A pointer to smiley's data
* @param datasize The size of smiley's data
- *
- * @since 2.6.0
*/
void pidgin_smiley_editor_set_data(PidginSmiley *editor, gpointer data, gsize datasize);
+G_END_DECLS
+
#endif /* PIDGIN_GTKSMILEY_H */
diff --git a/pidgin/gtksound.c b/pidgin/gtksound.c
index e8e96d5de9..814b926c1e 100644
--- a/pidgin/gtksound.c
+++ b/pidgin/gtksound.c
@@ -96,8 +96,8 @@ chat_nick_matches_name(PurpleConversation *conv, const char *aname)
if (chat==NULL)
return ret;
- nick = g_strdup(purple_normalize(conv->account, chat->nick));
- name = g_strdup(purple_normalize(conv->account, aname));
+ nick = g_strdup(purple_normalize(purple_conversation_get_account(conv), purple_conv_chat_get_nick(chat)));
+ name = g_strdup(purple_normalize(purple_conversation_get_account(conv), aname));
if (g_utf8_collate(nick, name) == 0)
ret = TRUE;
@@ -212,7 +212,7 @@ chat_msg_received_cb(PurpleAccount *account, char *sender,
if (chat_nick_matches_name(conv, sender))
return;
- if (flags & PURPLE_MESSAGE_NICK || purple_utf8_has_word(message, chat->nick))
+ if (flags & PURPLE_MESSAGE_NICK || purple_utf8_has_word(message, purple_conv_chat_get_nick(chat)))
/* This isn't quite right; if you have the PURPLE_SOUND_CHAT_NICK event disabled
* and the PURPLE_SOUND_CHAT_SAY event enabled, you won't get a sound at all */
play_conv_event(conv, PURPLE_SOUND_CHAT_NICK);
diff --git a/pidgin/gtksound.h b/pidgin/gtksound.h
index f55713907e..147cd9409d 100644
--- a/pidgin/gtksound.h
+++ b/pidgin/gtksound.h
@@ -28,6 +28,8 @@
#include "sound.h"
+G_BEGIN_DECLS
+
/**************************************************************************/
/** @name GTK+ Sound API */
/**************************************************************************/
@@ -67,11 +69,11 @@ void *pidgin_sound_get_handle(void);
* Returns true Pidgin is using customized sounds
*
* @return TRUE if non default sounds are used.
- *
- * @since 2.6.0
*/
gboolean pidgin_sound_is_customized(void);
/*@}*/
+G_END_DECLS
+
#endif /* _PIDGINSOUND_H_ */
diff --git a/pidgin/gtksourceundomanager.h b/pidgin/gtksourceundomanager.h
index 0148455476..931486512d 100644
--- a/pidgin/gtksourceundomanager.h
+++ b/pidgin/gtksourceundomanager.h
@@ -57,6 +57,8 @@ struct _GtkSourceUndoManagerClass
void (*can_redo) (GtkSourceUndoManager *um, gboolean can_redo);
};
+G_BEGIN_DECLS
+
GType gtk_source_undo_manager_get_type (void) G_GNUC_CONST;
GtkSourceUndoManager* gtk_source_undo_manager_new (GtkTextBuffer *buffer);
@@ -78,6 +80,8 @@ void gtk_source_undo_manager_set_max_undo_levels
(GtkSourceUndoManager *um,
gint undo_levels);
+G_END_DECLS
+
#endif /* __GTK_SOURCE_UNDO_MANAGER_H__ */
diff --git a/pidgin/gtkstatusbox.c b/pidgin/gtkstatusbox.c
index ff75b29c19..f1d5c422ff 100644
--- a/pidgin/gtkstatusbox.c
+++ b/pidgin/gtkstatusbox.c
@@ -70,6 +70,16 @@
/* Timeout for typing notifications in seconds */
#define TYPING_TIMEOUT 4
+#if !GTK_CHECK_VERSION(2,18,0)
+#define gtk_widget_is_sensitive(x) GTK_WIDGET_IS_SENSITIVE(x)
+#define gtk_widget_set_has_window(x, y) do { \
+ if (y) \
+ GTK_WIDGET_UNSET_FLAGS(x, GTK_WIDGET_NO_WINDOW); \
+ else \
+ GTK_WIDGET_SET_FLAGS(x, GTK_WIDGET_NO_WINDOW); \
+} while (0)
+#endif
+
static void imhtml_changed_cb(GtkTextBuffer *buffer, void *data);
static void imhtml_format_changed_cb(GtkIMHtml *imhtml, GtkIMHtmlButtons buttons, void *data);
static void remove_typing_cb(PidginStatusBox *box);
@@ -412,7 +422,7 @@ statusbox_uri_handler(const char *proto, const char *cmd, GHashTable *params, vo
if (src == NULL)
return FALSE;
- purple_util_fetch_url(src, TRUE, NULL, FALSE, statusbox_got_url, data);
+ purple_util_fetch_url(src, TRUE, NULL, FALSE, -1, statusbox_got_url, data);
return TRUE;
}
@@ -1749,7 +1759,7 @@ pidgin_status_box_init (PidginStatusBox *status_box)
GtkWidget *toplevel;
GtkTreeSelection *sel;
- GTK_WIDGET_SET_FLAGS (status_box, GTK_NO_WINDOW);
+ gtk_widget_set_has_window(GTK_WIDGET(status_box), FALSE);
status_box->imhtml_visible = FALSE;
status_box->network_available = purple_network_is_available();
status_box->connecting = FALSE;
@@ -2625,7 +2635,7 @@ static void pidgin_status_box_changed(PidginStatusBox *status_box)
purple_timeout_remove(status_box->typing);
status_box->typing = 0;
- if (GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(status_box)))
+ if (gtk_widget_is_sensitive(GTK_WIDGET(status_box)))
{
if (type == PIDGIN_STATUS_BOX_TYPE_POPULAR || type == PIDGIN_STATUS_BOX_TYPE_SAVED_POPULAR)
{
@@ -2687,7 +2697,7 @@ static void pidgin_status_box_changed(PidginStatusBox *status_box)
}
g_list_free(accounts);
- if (GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(status_box)))
+ if (gtk_widget_is_sensitive(GTK_WIDGET(status_box)))
{
if (status_box->imhtml_visible)
{
@@ -2743,7 +2753,7 @@ get_statusbox_index(PidginStatusBox *box, PurpleSavedStatus *saved_status)
static void imhtml_changed_cb(GtkTextBuffer *buffer, void *data)
{
PidginStatusBox *status_box = (PidginStatusBox*)data;
- if (GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(status_box)))
+ if (gtk_widget_is_sensitive(GTK_WIDGET(status_box)))
{
if (status_box->typing != 0) {
pidgin_status_box_pulse_typing(status_box);
diff --git a/pidgin/gtkstatusbox.h b/pidgin/gtkstatusbox.h
index 37b536788f..b2daea34f8 100644
--- a/pidgin/gtkstatusbox.h
+++ b/pidgin/gtkstatusbox.h
@@ -98,8 +98,8 @@ struct _PidginStatusBox
GtkWidget *icon_box_menu;
GdkCursor *hand_cursor;
GdkCursor *arrow_cursor;
- int icon_size;
- gboolean icon_opaque;
+ int icon_size;
+ gboolean icon_opaque;
gboolean imhtml_visible;
diff --git a/pidgin/gtkthemes.c b/pidgin/gtkthemes.c
index e92df94a38..d4fb77d5ba 100644
--- a/pidgin/gtkthemes.c
+++ b/pidgin/gtkthemes.c
@@ -122,6 +122,8 @@ void pidgin_themes_remove_smiley_theme(const char *file)
static void _pidgin_themes_smiley_themeize(GtkWidget *imhtml, gboolean custom)
{
+ /* TODO WEBKIT: move imhtml dependency to use webview. */
+#if 0
struct smiley_list *list;
if (!current_smiley_theme)
return;
@@ -147,6 +149,7 @@ static void _pidgin_themes_smiley_themeize(GtkWidget *imhtml, gboolean custom)
list = list->next;
}
+#endif /* if 0 */
}
void pidgin_themes_smiley_themeize(GtkWidget *imhtml)
@@ -278,6 +281,8 @@ void pidgin_themes_load_smiley_theme(const char *file, gboolean load)
if (*i == '[' && strchr(i, ']') && load) {
struct smiley_list *child = g_new0(struct smiley_list, 1);
child->sml = g_strndup(i+1, strchr(i, ']') - i - 1);
+ child->files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
if (theme->list)
list->next = child;
else
@@ -320,6 +325,7 @@ void pidgin_themes_load_smiley_theme(const char *file, gboolean load)
} else {
GtkIMHtmlSmiley *smiley = gtk_imhtml_smiley_create(sfile, l, hidden, 0);
list->smileys = g_slist_prepend(list->smileys, smiley);
+ g_hash_table_insert (list->files, g_strdup(l), g_strdup(sfile));
}
while (isspace(*i))
i++;
@@ -358,7 +364,6 @@ void pidgin_themes_load_smiley_theme(const char *file, gboolean load)
if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) {
/* We want to see our custom smileys on our entry if we write the shortcut */
- pidgin_themes_smiley_themeize(PIDGIN_CONVERSATION(conv)->imhtml);
pidgin_themes_smiley_themeize_custom(PIDGIN_CONVERSATION(conv)->entry);
}
}
diff --git a/pidgin/gtkthemes.h b/pidgin/gtkthemes.h
index 138edbbeb0..8343a99d63 100644
--- a/pidgin/gtkthemes.h
+++ b/pidgin/gtkthemes.h
@@ -29,6 +29,7 @@
struct smiley_list {
char *sml;
GSList *smileys;
+ GHashTable *files; /**< map from smiley shortcut to filename */
struct smiley_list *next;
};
@@ -45,26 +46,24 @@ struct smiley_theme {
extern struct smiley_theme *current_smiley_theme;
extern GSList *smiley_themes;
+G_BEGIN_DECLS
+
void pidgin_themes_init(void);
gboolean pidgin_themes_smileys_disabled(void);
void pidgin_themes_smiley_themeize(GtkWidget *);
-/**
- * @since 2.5.0
- */
void pidgin_themes_smiley_themeize_custom(GtkWidget *);
void pidgin_themes_smiley_theme_probe(void);
void pidgin_themes_load_smiley_theme(const char *file, gboolean load);
-/**
- * @since 2.1.0
- */
void pidgin_themes_remove_smiley_theme(const char *file);
GSList *pidgin_themes_get_proto_smileys(const char *id);
+G_END_DECLS
+
#endif /* _PIDGINTHEMES_H_ */
diff --git a/pidgin/gtkutils.c b/pidgin/gtkutils.c
index beda2b64b6..5c8ac3b975 100644
--- a/pidgin/gtkutils.c
+++ b/pidgin/gtkutils.c
@@ -67,10 +67,24 @@
#include "pidginstock.h"
#include "gtkthemes.h"
#include "gtkutils.h"
+#include "gtkwebview.h"
+#include "gtkwebviewtoolbar.h"
#include "pidgin/minidialog.h"
+#if !GTK_CHECK_VERSION(2,18,0)
+#define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x)
+#define gtk_widget_is_sensitive(x) GTK_WIDGET_IS_SENSITIVE(x)
+#endif
+
+enum {
+ AOP_ICON_COLUMN,
+ AOP_NAME_COLUMN,
+ AOP_DATA_COLUMN,
+ AOP_COLUMN_COUNT
+};
+
typedef struct {
- GtkWidget *menu;
+ GtkTreeModel *model;
gint default_item;
} AopMenu;
@@ -126,6 +140,32 @@ pidgin_setup_imhtml(GtkWidget *imhtml)
}
+void
+pidgin_setup_webview(GtkWidget *webview)
+{
+ g_return_if_fail(webview != NULL);
+ g_return_if_fail(GTK_IS_WEBVIEW(webview));
+
+#if 0
+/* TODO: WebKit this stuff... */
+ pidgin_themes_smiley_themeize(webview);
+#endif
+
+#ifdef _WIN32
+ if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/use_theme_font")) {
+ WebKitWebSettings *settings = webkit_web_settings_new();
+ g_object_set(G_OBJECT(settings), "default-font-size",
+ purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/font_size"),
+ NULL);
+ g_object_set(G_OBJECT(settings), "default-font-family",
+ purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/custom_font"),
+ NULL);
+
+ webkit_web_view_set_settings(WEBKIT_WEB_VIEW(webview), settings);
+ }
+#endif
+}
+
static
void pidgin_window_init(GtkWindow *wnd, const char *title, guint border_width, const char *role, gboolean resizable)
{
@@ -276,6 +316,65 @@ pidgin_create_imhtml(gboolean editable, GtkWidget **imhtml_ret, GtkWidget **tool
return frame;
}
+GtkWidget *
+pidgin_create_webview(gboolean editable, GtkWidget **webview_ret, GtkWidget **toolbar_ret, GtkWidget **sw_ret)
+{
+ GtkWidget *frame;
+ GtkWidget *webview;
+ GtkWidget *sep;
+ GtkWidget *sw;
+ GtkWidget *toolbar = NULL;
+ GtkWidget *vbox;
+
+ frame = gtk_frame_new(NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
+
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(frame), vbox);
+ gtk_widget_show(vbox);
+
+ if (editable) {
+ toolbar = gtk_webviewtoolbar_new();
+ gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
+ gtk_widget_show(toolbar);
+
+ sep = gtk_hseparator_new();
+ gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0);
+ g_signal_connect_swapped(G_OBJECT(toolbar), "show", G_CALLBACK(gtk_widget_show), sep);
+ g_signal_connect_swapped(G_OBJECT(toolbar), "hide", G_CALLBACK(gtk_widget_hide), sep);
+ gtk_widget_show(sep);
+ }
+
+ webview = gtk_webview_new();
+ gtk_webview_set_editable(GTK_WEBVIEW(webview), editable);
+ if (editable && purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/spellcheck"))
+ pidgin_webview_set_spellcheck(GTK_WEBVIEW(webview), TRUE);
+ gtk_widget_show(webview);
+
+ if (editable) {
+ gtk_webviewtoolbar_attach(GTK_WEBVIEWTOOLBAR(toolbar), webview);
+ gtk_webviewtoolbar_associate_smileys(GTK_WEBVIEWTOOLBAR(toolbar), "default");
+ }
+ pidgin_setup_webview(webview);
+
+ sw = pidgin_make_scrollable(webview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_NONE, -1, -1);
+ gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
+
+ gtk_webview_set_vadjustment(GTK_WEBVIEW(webview),
+ gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(sw)));
+
+ if (webview_ret != NULL)
+ *webview_ret = webview;
+
+ if (editable && (toolbar_ret != NULL))
+ *toolbar_ret = toolbar;
+
+ if (sw_ret != NULL)
+ *sw_ret = sw;
+
+ return frame;
+}
+
void
pidgin_set_sensitive_if_input(GtkWidget *entry, GtkWidget *dialog)
{
@@ -292,7 +391,7 @@ pidgin_toggle_sensitive(GtkWidget *widget, GtkWidget *to_toggle)
if (to_toggle == NULL)
return;
- sensitivity = GTK_WIDGET_IS_SENSITIVE(to_toggle);
+ sensitivity = gtk_widget_is_sensitive(to_toggle);
gtk_widget_set_sensitive(to_toggle, !sensitivity);
}
@@ -309,7 +408,7 @@ pidgin_toggle_sensitive_array(GtkWidget *w, GPtrArray *data)
if (element == NULL)
continue;
- sensitivity = GTK_WIDGET_IS_SENSITIVE(element);
+ sensitivity = gtk_widget_is_sensitive(element);
gtk_widget_set_sensitive(element, !sensitivity);
}
@@ -321,7 +420,7 @@ pidgin_toggle_showhide(GtkWidget *widget, GtkWidget *to_toggle)
if (to_toggle == NULL)
return;
- if (GTK_WIDGET_VISIBLE(to_toggle))
+ if (gtk_widget_get_visible(to_toggle))
gtk_widget_hide(to_toggle);
else
gtk_widget_show(to_toggle);
@@ -522,68 +621,36 @@ pidgin_make_frame(GtkWidget *parent, const char *title)
}
static gpointer
-aop_option_menu_get_selected(GtkWidget *optmenu, GtkWidget **p_item)
+aop_option_menu_get_selected(GtkWidget *optmenu)
{
- GtkWidget *menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu));
- GtkWidget *item = gtk_menu_get_active(GTK_MENU(menu));
- if (p_item)
- (*p_item) = item;
- return item ? g_object_get_data(G_OBJECT(item), "aop_per_item_data") : NULL;
+ gpointer data = NULL;
+ GtkTreeIter iter;
+
+ g_return_val_if_fail(optmenu != NULL, NULL);
+
+ if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(optmenu), &iter))
+ gtk_tree_model_get(gtk_combo_box_get_model(GTK_COMBO_BOX(optmenu)),
+ &iter, AOP_DATA_COLUMN, &data, -1);
+
+ return data;
}
static void
aop_menu_cb(GtkWidget *optmenu, GCallback cb)
{
- GtkWidget *item;
- gpointer per_item_data;
-
- per_item_data = aop_option_menu_get_selected(optmenu, &item);
-
if (cb != NULL) {
- ((void (*)(GtkWidget *, gpointer, gpointer))cb)(item, per_item_data, g_object_get_data(G_OBJECT(optmenu), "user_data"));
+ ((void (*)(GtkWidget *, gpointer, gpointer))cb)(optmenu,
+ aop_option_menu_get_selected(optmenu),
+ g_object_get_data(G_OBJECT(optmenu), "user_data"));
}
}
-static GtkWidget *
-aop_menu_item_new(GtkSizeGroup *sg, GdkPixbuf *pixbuf, const char *lbl, gpointer per_item_data, const char *data)
+static void
+aop_option_menu_replace_menu(GtkWidget *optmenu, AopMenu *new_aop_menu)
{
- GtkWidget *item;
- GtkWidget *hbox;
- GtkWidget *image;
- GtkWidget *label;
-
- item = gtk_menu_item_new();
- gtk_widget_show(item);
-
- hbox = gtk_hbox_new(FALSE, 4);
- gtk_widget_show(hbox);
-
- /* Create the image */
- if (pixbuf == NULL)
- image = gtk_image_new();
- else
- image = gtk_image_new_from_pixbuf(pixbuf);
- gtk_widget_show(image);
-
- if (sg)
- gtk_size_group_add_widget(sg, image);
-
- /* Create the label */
- label = gtk_label_new (lbl);
- gtk_widget_show (label);
- gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
- gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
-
- gtk_container_add(GTK_CONTAINER(item), hbox);
- gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
-
- g_object_set_data(G_OBJECT (item), data, per_item_data);
- g_object_set_data(G_OBJECT (item), "aop_per_item_data", per_item_data);
-
- pidgin_set_accessible_label(item, label);
-
- return item;
+ gtk_combo_box_set_model(GTK_COMBO_BOX(optmenu), new_aop_menu->model);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(optmenu), new_aop_menu->default_item);
+ g_free(new_aop_menu);
}
static GdkPixbuf *
@@ -624,16 +691,17 @@ pidgin_create_prpl_icon_from_prpl(PurplePlugin *prpl, PidginPrplIconSize size, P
static GtkWidget *
aop_option_menu_new(AopMenu *aop_menu, GCallback cb, gpointer user_data)
{
- GtkWidget *optmenu;
+ GtkWidget *optmenu = NULL;
+ GtkCellRenderer *cr = NULL;
- optmenu = gtk_option_menu_new();
+ optmenu = gtk_combo_box_new();
gtk_widget_show(optmenu);
- gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), aop_menu->menu);
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(optmenu), cr = gtk_cell_renderer_pixbuf_new(), FALSE);
+ gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(optmenu), cr, "pixbuf", AOP_ICON_COLUMN);
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(optmenu), cr = gtk_cell_renderer_text_new(), TRUE);
+ gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(optmenu), cr, "text", AOP_NAME_COLUMN);
- if (aop_menu->default_item != -1)
- gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), aop_menu->default_item);
-
- g_object_set_data_full(G_OBJECT(optmenu), "aop_menu", aop_menu, (GDestroyNotify)g_free);
+ aop_option_menu_replace_menu(optmenu, aop_menu);
g_object_set_data(G_OBJECT(optmenu), "user_data", user_data);
g_signal_connect(G_OBJECT(optmenu), "changed", G_CALLBACK(aop_menu_cb), cb);
@@ -642,32 +710,20 @@ aop_option_menu_new(AopMenu *aop_menu, GCallback cb, gpointer user_data)
}
static void
-aop_option_menu_replace_menu(GtkWidget *optmenu, AopMenu *new_aop_menu)
-{
- if (gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)))
- gtk_option_menu_remove_menu(GTK_OPTION_MENU(optmenu));
-
- gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), new_aop_menu->menu);
-
- if (new_aop_menu->default_item != -1)
- gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), new_aop_menu->default_item);
-
- g_object_set_data_full(G_OBJECT(optmenu), "aop_menu", new_aop_menu, (GDestroyNotify)g_free);
-}
-
-static void
aop_option_menu_select_by_data(GtkWidget *optmenu, gpointer data)
{
- guint idx;
- GList *llItr = NULL;
-
- for (idx = 0, llItr = GTK_MENU_SHELL(gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)))->children;
- llItr != NULL;
- llItr = llItr->next, idx++) {
- if (data == g_object_get_data(G_OBJECT(llItr->data), "aop_per_item_data")) {
- gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), idx);
- break;
- }
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gpointer iter_data;
+ model = gtk_combo_box_get_model(GTK_COMBO_BOX(optmenu));
+ if (gtk_tree_model_get_iter_first(model, &iter)) {
+ do {
+ gtk_tree_model_get(model, &iter, AOP_DATA_COLUMN, &iter_data, -1);
+ if (iter_data == data) {
+ gtk_combo_box_set_active_iter(GTK_COMBO_BOX(optmenu), &iter);
+ return;
+ }
+ } while (gtk_tree_model_iter_next(model, &iter));
}
}
@@ -677,21 +733,16 @@ create_protocols_menu(const char *default_proto_id)
AopMenu *aop_menu = NULL;
PurplePlugin *plugin;
GdkPixbuf *pixbuf = NULL;
- GtkSizeGroup *sg;
+ GtkTreeIter iter;
+ GtkListStore *ls;
GList *p;
- const char *gtalk_name = NULL, *facebook_name = NULL;
int i;
- aop_menu = g_malloc0(sizeof(AopMenu));
- aop_menu->default_item = -1;
- aop_menu->menu = gtk_menu_new();
- gtk_widget_show(aop_menu->menu);
- sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+ ls = gtk_list_store_new(AOP_COLUMN_COUNT, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER);
- if (purple_find_prpl("prpl-jabber")) {
- gtalk_name = _("Google Talk");
- facebook_name = _("Facebook (XMPP)");
- }
+ aop_menu = g_malloc0(sizeof(AopMenu));
+ aop_menu->default_item = 0;
+ aop_menu->model = GTK_TREE_MODEL(ls);
for (p = purple_plugins_get_protocols(), i = 0;
p != NULL;
@@ -699,48 +750,14 @@ create_protocols_menu(const char *default_proto_id)
plugin = (PurplePlugin *)p->data;
- if (gtalk_name && strcmp(gtalk_name, plugin->info->name) < 0) {
- char *filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols",
- "16", "google-talk.png", NULL);
- GtkWidget *item;
-
- pixbuf = pidgin_pixbuf_new_from_file(filename);
- g_free(filename);
-
- gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu),
- item = aop_menu_item_new(sg, pixbuf, gtalk_name, "prpl-jabber", "protocol"));
- g_object_set_data(G_OBJECT(item), "fakegoogle", GINT_TO_POINTER(1));
-
- if (pixbuf)
- g_object_unref(pixbuf);
-
- gtalk_name = NULL;
- i++;
- }
-
- if (facebook_name && strcmp(facebook_name, plugin->info->name) < 0) {
- char *filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols",
- "16", "facebook.png", NULL);
- GtkWidget *item;
-
- pixbuf = pidgin_pixbuf_new_from_file(filename);
- g_free(filename);
-
- gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu),
- item = aop_menu_item_new(sg, pixbuf, facebook_name, "prpl-jabber", "protocol"));
- g_object_set_data(G_OBJECT(item), "fakefacebook", GINT_TO_POINTER(1));
-
- if (pixbuf)
- g_object_unref(pixbuf);
-
- facebook_name = NULL;
- i++;
- }
-
pixbuf = pidgin_create_prpl_icon_from_prpl(plugin, PIDGIN_PRPL_ICON_SMALL, NULL);
- gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu),
- aop_menu_item_new(sg, pixbuf, plugin->info->name, plugin->info->id, "protocol"));
+ gtk_list_store_append(ls, &iter);
+ gtk_list_store_set(ls, &iter,
+ AOP_ICON_COLUMN, pixbuf,
+ AOP_NAME_COLUMN, plugin->info->name,
+ AOP_DATA_COLUMN, plugin->info->id,
+ -1);
if (pixbuf)
g_object_unref(pixbuf);
@@ -749,8 +766,6 @@ create_protocols_menu(const char *default_proto_id)
aop_menu->default_item = i;
}
- g_object_unref(sg);
-
return aop_menu;
}
@@ -764,13 +779,13 @@ pidgin_protocol_option_menu_new(const char *id, GCallback cb,
const char *
pidgin_protocol_option_menu_get_selected(GtkWidget *optmenu)
{
- return (const char *)aop_option_menu_get_selected(optmenu, NULL);
+ return (const char *)aop_option_menu_get_selected(optmenu);
}
PurpleAccount *
pidgin_account_option_menu_get_selected(GtkWidget *optmenu)
{
- return (PurpleAccount *)aop_option_menu_get_selected(optmenu, NULL);
+ return (PurpleAccount *)aop_option_menu_get_selected(optmenu);
}
static AopMenu *
@@ -782,7 +797,8 @@ create_account_menu(PurpleAccount *default_account,
GdkPixbuf *pixbuf = NULL;
GList *list;
GList *p;
- GtkSizeGroup *sg;
+ GtkListStore *ls;
+ GtkTreeIter iter;
int i;
char buf[256];
@@ -791,11 +807,11 @@ create_account_menu(PurpleAccount *default_account,
else
list = purple_connections_get_all();
+ ls = gtk_list_store_new(AOP_COLUMN_COUNT, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER);
+
aop_menu = g_malloc0(sizeof(AopMenu));
- aop_menu->default_item = -1;
- aop_menu->menu = gtk_menu_new();
- gtk_widget_show(aop_menu->menu);
- sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+ aop_menu->default_item = 0;
+ aop_menu->model = GTK_TREE_MODEL(ls);
for (p = list, i = 0; p != NULL; p = p->next, i++) {
if (show_all)
@@ -830,8 +846,12 @@ create_account_menu(PurpleAccount *default_account,
purple_account_get_protocol_name(account));
}
- gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu),
- aop_menu_item_new(sg, pixbuf, buf, account, "account"));
+ gtk_list_store_append(ls, &iter);
+ gtk_list_store_set(ls, &iter,
+ AOP_ICON_COLUMN, pixbuf,
+ AOP_NAME_COLUMN, buf,
+ AOP_DATA_COLUMN, account,
+ -1);
if (pixbuf)
g_object_unref(pixbuf);
@@ -840,8 +860,6 @@ create_account_menu(PurpleAccount *default_account,
aop_menu->default_item = i;
}
- g_object_unref(sg);
-
return aop_menu;
}
@@ -852,7 +870,7 @@ regenerate_account_menu(GtkWidget *optmenu)
PurpleAccount *account;
PurpleFilterAccountFunc filter_func;
- account = (PurpleAccount *)aop_option_menu_get_selected(optmenu, NULL);
+ account = (PurpleAccount *)aop_option_menu_get_selected(optmenu);
show_all = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(optmenu), "show_all"));
filter_func = g_object_get_data(G_OBJECT(optmenu), "filter_func");
@@ -922,24 +940,6 @@ pidgin_account_option_menu_new(PurpleAccount *default_account,
return optmenu;
}
-gboolean
-pidgin_check_if_dir(const char *path, GtkFileSelection *filesel)
-{
- char *dirname = NULL;
-
- if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
- /* append a / if needed */
- if (path[strlen(path) - 1] != G_DIR_SEPARATOR) {
- dirname = g_strconcat(path, G_DIR_SEPARATOR_S, NULL);
- }
- gtk_file_selection_set_filename(filesel, (dirname != NULL) ? dirname : path);
- g_free(dirname);
- return TRUE;
- }
-
- return FALSE;
-}
-
void
pidgin_setup_gtkspell(GtkTextView *textview)
{
@@ -1002,7 +1002,7 @@ static void
show_retrieveing_info(PurpleConnection *conn, const char *name)
{
PurpleNotifyUserInfo *info = purple_notify_user_info_new();
- purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving..."));
+ purple_notify_user_info_add_pair_plaintext(info, _("Information"), _("Retrieving..."));
purple_notify_userinfo(conn, name, info, NULL, NULL);
purple_notify_user_info_destroy(info);
}
@@ -1023,7 +1023,7 @@ void pidgin_retrieve_user_info_in_chat(PurpleConnection *conn, const char *name,
return;
}
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(conn->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(conn));
if (prpl_info != NULL && prpl_info->get_cb_real_name)
who = prpl_info->get_cb_real_name(conn, chat, name);
if (prpl_info == NULL || prpl_info->get_cb_info == NULL) {
@@ -1149,7 +1149,7 @@ pidgin_parse_x_im_contact(const char *msg, gboolean all_accounts,
gc = (PurpleConnection *)l->data;
account = purple_connection_get_account(gc);
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
}
protoname = prpl_info->list_icon(account, NULL);
@@ -1191,7 +1191,7 @@ pidgin_parse_x_im_contact(const char *msg, gboolean all_accounts,
gc = (PurpleConnection *)l->data;
account = purple_connection_get_account(gc);
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
}
protoname = prpl_info->list_icon(account, NULL);
@@ -1308,7 +1308,7 @@ pidgin_menu_position_func_helper(GtkMenu *menu,
monitor_num = gdk_screen_get_monitor_at_point (screen, *x, *y);
- push_in = FALSE;
+ *push_in = FALSE;
/*
* The placement of popup menus horizontally works like this (with
@@ -1603,7 +1603,7 @@ pidgin_dnd_file_manage(GtkSelectionData *sd, PurpleAccount *account, const char
data->account = account;
if (gc)
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
if (prpl_info && prpl_info->options & OPT_PROTO_IM_IMAGE)
im = TRUE;
@@ -1834,21 +1834,27 @@ pidgin_append_menu_action(GtkWidget *menu, PurpleMenuAction *act,
gpointer object)
{
GtkWidget *menuitem;
+ GList *list;
if (act == NULL) {
return pidgin_separator(menu);
}
- if (act->children == NULL) {
- menuitem = gtk_menu_item_new_with_mnemonic(act->label);
+ list = purple_menu_action_get_children(act);
+ menuitem = gtk_menu_item_new_with_mnemonic(purple_menu_action_get_label(act));
+
+ if (list == NULL) {
+ PurpleCallback callback;
+
+ callback = purple_menu_action_get_callback(act);
- if (act->callback != NULL) {
+ if (callback != NULL) {
g_object_set_data(G_OBJECT(menuitem),
"purplecallback",
- act->callback);
+ callback);
g_object_set_data(G_OBJECT(menuitem),
"purplecallbackdata",
- act->data);
+ purple_menu_action_get_data(act));
g_signal_connect(G_OBJECT(menuitem), "activate",
G_CALLBACK(menu_action_cb),
object);
@@ -1862,7 +1868,6 @@ pidgin_append_menu_action(GtkWidget *menu, PurpleMenuAction *act,
GtkWidget *submenu = NULL;
GtkAccelGroup *group;
- menuitem = gtk_menu_item_new_with_mnemonic(act->label);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
submenu = gtk_menu_new();
@@ -1870,24 +1875,34 @@ pidgin_append_menu_action(GtkWidget *menu, PurpleMenuAction *act,
group = gtk_menu_get_accel_group(GTK_MENU(menu));
if (group) {
- char *path = g_strdup_printf("%s/%s", GTK_MENU_ITEM(menuitem)->accel_path, act->label);
+ char *path = g_strdup_printf("%s/%s", GTK_MENU_ITEM(menuitem)->accel_path,
+ purple_menu_action_get_label(act));
gtk_menu_set_accel_path(GTK_MENU(submenu), path);
g_free(path);
gtk_menu_set_accel_group(GTK_MENU(submenu), group);
}
- for (l = act->children; l; l = l->next) {
+ for (l = list; l; l = l->next) {
PurpleMenuAction *act = (PurpleMenuAction *)l->data;
pidgin_append_menu_action(submenu, act, object);
}
- g_list_free(act->children);
- act->children = NULL;
+ g_list_free(list);
+ purple_menu_action_set_children(act, NULL);
}
purple_menu_action_free(act);
return menuitem;
}
+enum {
+ COMPLETION_DISPLAYED_COLUMN, /* displayed completion value */
+ COMPLETION_BUDDY_COLUMN, /* buddy name */
+ COMPLETION_NORMALIZED_COLUMN, /* UTF-8 normalized & casefolded buddy name */
+ COMPLETION_COMPARISON_COLUMN, /* UTF-8 normalized & casefolded value for comparison */
+ COMPLETION_ACCOUNT_COLUMN, /* account */
+ COMPLETION_COLUMN_COUNT
+};
+
typedef struct
{
GtkWidget *entry;
@@ -1907,10 +1922,10 @@ static gboolean buddyname_completion_match_func(GtkEntryCompletion *completion,
GValue val2;
const char *tmp;
- model = gtk_entry_completion_get_model (completion);
+ model = gtk_entry_completion_get_model(completion);
val1.g_type = 0;
- gtk_tree_model_get_value(model, iter, 2, &val1);
+ gtk_tree_model_get_value(model, iter, COMPLETION_NORMALIZED_COLUMN, &val1);
tmp = g_value_get_string(&val1);
if (tmp != NULL && purple_str_has_prefix(tmp, key))
{
@@ -1920,7 +1935,7 @@ static gboolean buddyname_completion_match_func(GtkEntryCompletion *completion,
g_value_unset(&val1);
val2.g_type = 0;
- gtk_tree_model_get_value(model, iter, 3, &val2);
+ gtk_tree_model_get_value(model, iter, COMPLETION_COMPARISON_COLUMN, &val2);
tmp = g_value_get_string(&val2);
if (tmp != NULL && purple_str_has_prefix(tmp, key))
{
@@ -1940,11 +1955,11 @@ static gboolean buddyname_completion_match_selected_cb(GtkEntryCompletion *compl
PurpleAccount *account;
val.g_type = 0;
- gtk_tree_model_get_value(model, iter, 1, &val);
+ gtk_tree_model_get_value(model, iter, COMPLETION_BUDDY_COLUMN, &val);
gtk_entry_set_text(GTK_ENTRY(data->entry), g_value_get_string(&val));
g_value_unset(&val);
- gtk_tree_model_get_value(model, iter, 4, &val);
+ gtk_tree_model_get_value(model, iter, COMPLETION_ACCOUNT_COLUMN, &val);
account = g_value_get_pointer(&val);
g_value_unset(&val);
@@ -1981,11 +1996,11 @@ add_buddyname_autocomplete_entry(GtkListStore *store, const char *buddy_alias, c
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
- 0, completion_entry,
- 1, buddyname,
- 2, normalized_buddyname,
- 3, tmp,
- 4, account,
+ COMPLETION_DISPLAYED_COLUMN, completion_entry,
+ COMPLETION_BUDDY_COLUMN, buddyname,
+ COMPLETION_NORMALIZED_COLUMN, normalized_buddyname,
+ COMPLETION_COMPARISON_COLUMN, tmp,
+ COMPLETION_ACCOUNT_COLUMN, account,
-1);
g_free(completion_entry);
g_free(tmp);
@@ -2006,11 +2021,11 @@ add_buddyname_autocomplete_entry(GtkListStore *store, const char *buddy_alias, c
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
- 0, completion_entry,
- 1, buddyname,
- 2, normalized_buddyname,
- 3, tmp,
- 4, account,
+ COMPLETION_DISPLAYED_COLUMN, completion_entry,
+ COMPLETION_BUDDY_COLUMN, buddyname,
+ COMPLETION_NORMALIZED_COLUMN, normalized_buddyname,
+ COMPLETION_COMPARISON_COLUMN, tmp,
+ COMPLETION_ACCOUNT_COLUMN, account,
-1);
g_free(completion_entry);
g_free(tmp);
@@ -2022,11 +2037,11 @@ add_buddyname_autocomplete_entry(GtkListStore *store, const char *buddy_alias, c
/* Add the buddy's name. */
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
- 0, buddyname,
- 1, buddyname,
- 2, normalized_buddyname,
- 3, NULL,
- 4, account,
+ COMPLETION_DISPLAYED_COLUMN, buddyname,
+ COMPLETION_BUDDY_COLUMN, buddyname,
+ COMPLETION_NORMALIZED_COLUMN, normalized_buddyname,
+ COMPLETION_COMPARISON_COLUMN, NULL,
+ COMPLETION_ACCOUNT_COLUMN, account,
-1);
}
@@ -2082,8 +2097,8 @@ add_completion_list(PidginCompletionData *data)
add_buddyname_autocomplete_entry(data->store,
((PurpleContact *)cnode)->alias,
purple_buddy_get_contact_alias(entry.entry.buddy),
- entry.entry.buddy->account,
- entry.entry.buddy->name
+ purple_buddy_get_account(entry.entry.buddy),
+ purple_buddy_get_name(entry.entry.buddy)
);
}
}
@@ -2124,7 +2139,9 @@ pidgin_setup_screenname_autocomplete_with_filter(GtkWidget *entry, GtkWidget *ac
GtkEntryCompletion *completion;
data = g_new0(PidginCompletionData, 1);
- store = gtk_list_store_new(5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
+ store = gtk_list_store_new(COMPLETION_COLUMN_COUNT, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_POINTER);
data->entry = entry;
data->accountopt = accountopt;
@@ -2141,7 +2158,8 @@ pidgin_setup_screenname_autocomplete_with_filter(GtkWidget *entry, GtkWidget *ac
/* Sort the completion list by buddy name */
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store),
- 1, GTK_SORT_ASCENDING);
+ COMPLETION_BUDDY_COLUMN,
+ GTK_SORT_ASCENDING);
completion = gtk_entry_completion_new();
gtk_entry_completion_set_match_func(completion, buddyname_completion_match_func, NULL, NULL);
@@ -2155,7 +2173,7 @@ pidgin_setup_screenname_autocomplete_with_filter(GtkWidget *entry, GtkWidget *ac
gtk_entry_completion_set_model(completion, GTK_TREE_MODEL(store));
g_object_unref(store);
- gtk_entry_completion_set_text_column(completion, 0);
+ gtk_entry_completion_set_text_column(completion, COMPLETION_DISPLAYED_COLUMN);
purple_signal_connect(purple_connections_get_handle(), "signed-on", entry,
PURPLE_CALLBACK(repopulate_autocomplete), data);
@@ -2175,19 +2193,12 @@ pidgin_screenname_autocomplete_default_filter(const PidginBuddyCompletionEntry *
gboolean all = GPOINTER_TO_INT(all_accounts);
if (completion_entry->is_buddy) {
- return all || purple_account_is_connected(completion_entry->entry.buddy->account);
+ return all || purple_account_is_connected(purple_buddy_get_account(completion_entry->entry.buddy));
} else {
return all || (completion_entry->entry.logged_buddy->account != NULL && purple_account_is_connected(completion_entry->entry.logged_buddy->account));
}
}
-void
-pidgin_setup_screenname_autocomplete(GtkWidget *entry, GtkWidget *accountopt, gboolean all) {
- pidgin_setup_screenname_autocomplete_with_filter(entry, accountopt, pidgin_screenname_autocomplete_default_filter, GINT_TO_POINTER(all));
-}
-
-
-
void pidgin_set_cursor(GtkWidget *widget, GdkCursorType cursor_type)
{
GdkCursor *cursor;
@@ -2488,9 +2499,9 @@ pidgin_convert_buddy_icon(PurplePlugin *plugin, const char *path, size_t *len)
the image. */
purple_debug_info("buddyicon", "Converted image from "
"%dx%d to %dx%d, format=%s, quality=%u, "
- "filesize=%zu\n", orig_width, orig_height,
- new_width, new_height, prpl_formats[i], quality,
- length);
+ "filesize=%" G_GSIZE_FORMAT "\n",
+ orig_width, orig_height, new_width, new_height,
+ prpl_formats[i], quality, length);
if (len)
*len = length;
g_strfreev(prpl_formats);
@@ -2533,21 +2544,6 @@ pidgin_convert_buddy_icon(PurplePlugin *plugin, const char *path, size_t *len)
return NULL;
}
-void pidgin_set_custom_buddy_icon(PurpleAccount *account, const char *who, const char *filename)
-{
- PurpleBuddy *buddy;
- PurpleContact *contact;
-
- buddy = purple_find_buddy(account, who);
- if (!buddy) {
- purple_debug_info("custom-icon", "You can only set custom icon for someone in your buddylist.\n");
- return;
- }
-
- contact = purple_buddy_get_contact(buddy);
- purple_buddy_icons_node_set_custom_icon_from_file((PurpleBlistNode*)contact, filename);
-}
-
char *pidgin_make_pretty_arrows(const char *str)
{
char *ret;
@@ -3012,7 +3008,7 @@ gboolean pidgin_auto_parent_window(GtkWidget *widget)
windows = g_list_delete_link(windows, windows);
if (window == widget ||
- !GTK_WIDGET_VISIBLE(window))
+ !gtk_widget_get_visible(window))
continue;
if (!gdk_property_get(window->window, _WindowTime, _Cardinal, 0, sizeof(time_t), FALSE,
@@ -3066,7 +3062,7 @@ gboolean pidgin_auto_parent_window(GtkWidget *widget)
windows = g_list_delete_link(windows, windows);
if (window == widget ||
- !GTK_WIDGET_VISIBLE(window)) {
+ !gtk_widget_get_visible(window)) {
continue;
}
@@ -3096,7 +3092,7 @@ static GObject *pidgin_pixbuf_from_data_helper(const guchar *buf, gsize count, g
if (!gdk_pixbuf_loader_write(loader, buf, count, &error) || error) {
purple_debug_warning("gtkutils", "gdk_pixbuf_loader_write() "
- "failed with size=%zu: %s\n", count,
+ "failed with size=%" G_GSIZE_FORMAT ": %s\n", count,
error ? error->message : "(no error message)");
if (error)
g_error_free(error);
@@ -3106,7 +3102,7 @@ static GObject *pidgin_pixbuf_from_data_helper(const guchar *buf, gsize count, g
if (!gdk_pixbuf_loader_close(loader, &error) || error) {
purple_debug_warning("gtkutils", "gdk_pixbuf_loader_close() "
- "failed for image of size %zu: %s\n", count,
+ "failed for image of size %" G_GSIZE_FORMAT ": %s\n", count,
error ? error->message : "(no error message)");
if (error)
g_error_free(error);
@@ -3120,7 +3116,7 @@ static GObject *pidgin_pixbuf_from_data_helper(const guchar *buf, gsize count, g
pixbuf = G_OBJECT(gdk_pixbuf_loader_get_pixbuf(loader));
if (!pixbuf) {
purple_debug_warning("gtkutils", "%s() returned NULL for image "
- "of size %zu\n",
+ "of size %" G_GSIZE_FORMAT "\n",
animated ? "gdk_pixbuf_loader_get_animation"
: "gdk_pixbuf_loader_get_pixbuf", count);
g_object_unref(G_OBJECT(loader));
@@ -3450,7 +3446,7 @@ save_file_cb(GtkWidget *item, const char *url)
return TRUE;
purple_request_file(conv->active_conv, _("Save File"), NULL, TRUE,
G_CALLBACK(savefile_write_cb), NULL,
- conv->active_conv->account, NULL, conv->active_conv,
+ purple_conversation_get_account(conv->active_conv), NULL, conv->active_conv,
(void *)url);
return TRUE;
}
@@ -3707,4 +3703,3 @@ void pidgin_utils_uninit(void)
gtk_imhtml_class_register_protocol("mailto:", NULL, NULL);
gtk_imhtml_class_register_protocol("gopher://", NULL, NULL);
}
-
diff --git a/pidgin/gtkutils.h b/pidgin/gtkutils.h
index 716ec6de81..946d5f595a 100644
--- a/pidgin/gtkutils.h
+++ b/pidgin/gtkutils.h
@@ -31,10 +31,6 @@
#include "prpl.h"
#include "util.h"
-
-
-
-
typedef enum
{
PIDGIN_BUTTON_HORIZONTAL,
@@ -80,6 +76,8 @@ typedef struct {
typedef gboolean (*PidginFilterBuddyCompletionEntryFunc) (const PidginBuddyCompletionEntry *completion_entry, gpointer user_data);
+G_BEGIN_DECLS
+
/**
* Sets up a gtkimhtml widget, loads it with smileys, and sets the
* default signal handlers.
@@ -109,12 +107,42 @@ void pidgin_setup_imhtml(GtkWidget *imhtml);
GtkWidget *pidgin_create_imhtml(gboolean editable, GtkWidget **imhtml_ret, GtkWidget **toolbar_ret, GtkWidget **sw_ret);
/**
+ * Sets up a gtkwebview widget, loads it with smileys, and sets the
+ * default signal handlers.
+ *
+ * @param webview The gtkwebview widget to setup.
+ */
+void pidgin_setup_webview(GtkWidget *webview);
+
+/**
+ * Create an GtkWebView widget and associated GtkIMHtmlToolbar widget. This
+ * function puts both widgets in a nice GtkFrame. They're separated by an
+ * attractive GtkSeparator.
+ * TODO WEBKIT: editable isn't supported yet
+ *
+ * @param editable @c TRUE if this webview should be editable. If this is
+ * @c FALSE, then the toolbar will NOT be created. If this webview
+ * should be read-only at first, but may become editable later, then
+ * pass in @c TRUE here and then manually call gtk_webview_set_editable()
+ * later.
+ * @param webview_ret A pointer to a pointer to a GtkWidget. This pointer
+ * will be set to the webview when this function exits.
+ * @param toolbar_ret A pointer to a pointer to a GtkWidget. If editable is
+ * TRUE then this will be set to the toolbar when this function exits.
+ * Otherwise this will be set to @c NULL.
+ * @param sw_ret This will be filled with a pointer to the scrolled window
+ * widget which contains the webview.
+ *
+ * @return The GtkFrame containing the toolbar and webview.
+ */
+GtkWidget *pidgin_create_webview(gboolean editable, GtkWidget **webview_ret, GtkWidget **toolbar_ret, GtkWidget **sw_ret);
+
+/**
* Creates a small button
*
* @param image A button image.
*
* @return A GtkButton created from the image.
- * @since 2.7.0
*/
GtkWidget *pidgin_create_small_button(GtkWidget *image);
@@ -125,8 +153,6 @@ GtkWidget *pidgin_create_small_button(GtkWidget *image);
* @param border_width The window's desired border width
* @param role A string indicating what the window is responsible for doing, or @c NULL
* @param resizable Whether the window should be resizable (@c TRUE) or not (@c FALSE)
- *
- * @since 2.1.0
*/
GtkWidget *pidgin_create_window(const char *title, guint border_width, const char *role, gboolean resizable);
@@ -137,8 +163,6 @@ GtkWidget *pidgin_create_window(const char *title, guint border_width, const cha
* @param border_width The window's desired border width
* @param role A string indicating what the window is responsible for doing, or @c NULL
* @param resizable Whether the window should be resizable (@c TRUE) or not (@c FALSE)
- *
- * @since 2.4.0
*/
GtkWidget *pidgin_create_dialog(const char *title, guint border_width, const char *role, gboolean resizable);
@@ -148,8 +172,6 @@ GtkWidget *pidgin_create_dialog(const char *title, guint border_width, const cha
* @param dialog The dialog window
* @param homogeneous TRUE if all children are to be given equal space allotments.
* @param spacing the number of pixels to place by default between children
- *
- * @since 2.4.0
*/
GtkWidget *pidgin_dialog_get_vbox_with_properties(GtkDialog *dialog, gboolean homogeneous, gint spacing);
@@ -157,8 +179,6 @@ GtkWidget *pidgin_dialog_get_vbox_with_properties(GtkDialog *dialog, gboolean ho
* Retrieves the main content box (vbox) from a pidgin dialog window
*
* @param dialog The dialog window
- *
- * @since 2.4.0
*/
GtkWidget *pidgin_dialog_get_vbox(GtkDialog *dialog);
@@ -171,7 +191,6 @@ GtkWidget *pidgin_dialog_get_vbox(GtkDialog *dialog);
* @param callbackdata The user data for the callback function
*
* @return The created button.
- * @since 2.4.0
*/
GtkWidget *pidgin_dialog_add_button(GtkDialog *dialog, const char *label,
GCallback callback, gpointer callbackdata);
@@ -180,8 +199,6 @@ GtkWidget *pidgin_dialog_add_button(GtkDialog *dialog, const char *label,
* Retrieves the action area (button box) from a pidgin dialog window
*
* @param dialog The dialog window
- *
- * @since 2.4.0
*/
GtkWidget *pidgin_dialog_get_action_area(GtkDialog *dialog);
@@ -384,39 +401,6 @@ void pidgin_setup_screenname_autocomplete_with_filter(GtkWidget *entry, GtkWidge
gboolean pidgin_screenname_autocomplete_default_filter(const PidginBuddyCompletionEntry *completion_entry, gpointer all_accounts);
/**
- * Add autocompletion of screenames to an entry.
- *
- * @deprecated
- * For new code, use the equivalent:
- * #pidgin_setup_screenname_autocomplete_with_filter(@a entry, @a optmenu,
- * #pidgin_screenname_autocomplete_default_filter, <tt>GINT_TO_POINTER(@a
- * all)</tt>)
- *
- * @param entry The GtkEntry on which to setup autocomplete.
- * @param optmenu A menu for accounts, returned by
- * pidgin_account_option_menu_new(). If @a optmenu is not @c
- * NULL, it'll be updated when a username is chosen from the
- * autocomplete list.
- * @param all Whether to include usernames from disconnected accounts.
- */
-void pidgin_setup_screenname_autocomplete(GtkWidget *entry, GtkWidget *optmenu, gboolean all);
-
-/**
- * Check if the given path is a directory or not. If it is, then modify
- * the given GtkFileSelection dialog so that it displays the given path.
- * If the given path is not a directory, then do nothing.
- *
- * @param path The path entered in the file selection window by the user.
- * @param filesel The file selection window.
- *
- * @return TRUE if given path is a directory, FALSE otherwise.
- * @deprecated Pidgin no longer uses GtkFileSelection internally. It has also
- * been deprecated by GTK+. Use GtkFileChooser instead and ignore
- * this function.
- */
-gboolean pidgin_check_if_dir(const char *path, GtkFileSelection *filesel);
-
-/**
* Sets up GtkSpell for the given GtkTextView, reporting errors
* if encountered.
*
@@ -448,8 +432,6 @@ void pidgin_load_accels(void);
*
* @param conn The connection to get information from.
* @param name The user to get information about.
- *
- * @since 2.1.0
*/
void pidgin_retrieve_user_info(PurpleConnection *conn, const char *name);
@@ -459,8 +441,6 @@ void pidgin_retrieve_user_info(PurpleConnection *conn, const char *name);
* @param conn The connection to get information from.
* @param name The user to get information about.
* @param chatid The chat id.
- *
- * @since 2.1.0
*/
void pidgin_retrieve_user_info_in_chat(PurpleConnection *conn, const char *name, int chatid);
@@ -499,8 +479,6 @@ void pidgin_set_accessible_label(GtkWidget *w, GtkWidget *l);
*
* @param w The widget that we want to label.
* @param l A GtkLabel that we want to use as the label for the widget.
- *
- * @since 2.2.0
*/
void pidgin_set_accessible_relations(GtkWidget *w, GtkWidget *l);
@@ -515,8 +493,6 @@ void pidgin_set_accessible_relations(GtkWidget *w, GtkWidget *l);
* where the menu shall be drawn. This is an output parameter.
* @param push_in This is an output parameter?
* @param data Not used by this particular position function.
- *
- * @since 2.1.0
*/
void pidgin_menu_position_func_helper(GtkMenu *menu, gint *x, gint *y,
gboolean *push_in, gpointer data);
@@ -588,8 +564,6 @@ GdkPixbuf * pidgin_create_status_icon(PurpleStatusPrimitive primitive, GtkWidget
* @param prim The status primitive
*
* @return The stock-id
- *
- * @since 2.6.0
*/
const char *pidgin_stock_id_from_status_primitive(PurpleStatusPrimitive prim);
@@ -599,8 +573,6 @@ const char *pidgin_stock_id_from_status_primitive(PurpleStatusPrimitive prim);
* @param presence The presence.
*
* @return The stock-id
- *
- * @since 2.6.0
*/
const char *pidgin_stock_id_from_presence(PurplePresence *presence);
@@ -661,19 +633,6 @@ GtkWidget *pidgin_buddy_icon_chooser_new(GtkWindow *parent, void(*callback)(cons
*/
gpointer pidgin_convert_buddy_icon(PurplePlugin *plugin, const char *path, size_t *len);
-#if !(defined PIDGIN_DISABLE_DEPRECATED) || (defined _PIDGIN_GTKUTILS_C_)
-/**
- * Set or unset a custom buddyicon for a user.
- *
- * @param account The account the user belongs to.
- * @param who The name of the user.
- * @param filename The path of the custom icon. If this is @c NULL, then any
- * previously set custom buddy icon for the user is removed.
- * @deprecated See purple_buddy_icons_node_set_custom_icon_from_file()
- */
-void pidgin_set_custom_buddy_icon(PurpleAccount *account, const char *who, const char *filename);
-#endif
-
/**
* Converts "->" and "<-" in strings to Unicode arrow characters, for use in referencing
* menu items.
@@ -781,8 +740,6 @@ const char *pidgin_get_dim_grey_string(GtkWidget *widget);
*
* @return A newly created text GtkComboBox containing a GtkEntry
* child.
- *
- * @since 2.2.0
*/
GtkWidget *pidgin_text_combo_box_entry_new(const char *default_item, GList *items);
@@ -792,8 +749,6 @@ GtkWidget *pidgin_text_combo_box_entry_new(const char *default_item, GList *item
* @param widget The simple text GtkComboBoxEntry equivalent widget
*
* @return The text in the widget's entry. It must not be freed
- *
- * @since 2.2.0
*/
const char *pidgin_text_combo_box_entry_get_text(GtkWidget *widget);
@@ -802,8 +757,6 @@ const char *pidgin_text_combo_box_entry_get_text(GtkWidget *widget);
*
* @param widget The simple text GtkComboBoxEntry equivalent widget
* @param text The text to set
- *
- * @since 2.2.0
*/
void pidgin_text_combo_box_entry_set_text(GtkWidget *widget, const char *text);
@@ -813,8 +766,6 @@ void pidgin_text_combo_box_entry_set_text(GtkWidget *widget, const char *text);
* @param window The window to make transient.
*
* @return Whether the window was made transient or not.
- *
- * @since 2.4.0
*/
gboolean pidgin_auto_parent_window(GtkWidget *window);
@@ -829,7 +780,6 @@ gboolean pidgin_auto_parent_window(GtkWidget *window);
* @param p_label Place to store a pointer to the GtkLabel, or @c NULL if you don't care.
*
* @return A GtkHBox already added to the GtkVBox containing the GtkLabel and the GtkWidget.
- * @since 2.4.0
*/
GtkWidget *pidgin_add_widget_to_vbox(GtkBox *vbox, const char *widget_label, GtkSizeGroup *sg, GtkWidget *widget, gboolean expand, GtkWidget **p_label);
@@ -841,8 +791,6 @@ GtkWidget *pidgin_add_widget_to_vbox(GtkBox *vbox, const char *widget_label, Gtk
*
* @return A GdkPixbuf created from the image data, or NULL if
* there was an error parsing the data.
- *
- * @since 2.9.0
*/
GdkPixbuf *pidgin_pixbuf_from_data(const guchar *buf, gsize count);
@@ -854,8 +802,6 @@ GdkPixbuf *pidgin_pixbuf_from_data(const guchar *buf, gsize count);
*
* @return A GdkPixbufAnimation created from the image data, or NULL if
* there was an error parsing the data.
- *
- * @since 2.9.0
*/
GdkPixbufAnimation *pidgin_pixbuf_anim_from_data(const guchar *buf, gsize count);
@@ -865,8 +811,6 @@ GdkPixbufAnimation *pidgin_pixbuf_anim_from_data(const guchar *buf, gsize count)
* @param image A PurpleStoredImage.
*
* @return A GdkPixbuf created from the stored image.
- *
- * @since 2.5.0
*/
GdkPixbuf *pidgin_pixbuf_from_imgstore(PurpleStoredImage *image);
@@ -890,8 +834,6 @@ GdkPixbuf *pidgin_pixbuf_from_imgstore(PurpleStoredImage *image);
*
* @return The GdkPixbuf if successful. Otherwise NULL is returned and
* a warning is logged.
- *
- * @since 2.9.0
*/
GdkPixbuf *pidgin_pixbuf_new_from_file(const char *filename);
@@ -917,8 +859,6 @@ GdkPixbuf *pidgin_pixbuf_new_from_file(const char *filename);
*
* @return The GdkPixbuf if successful. Otherwise NULL is returned and
* a warning is logged.
- *
- * @since 2.9.0
*/
GdkPixbuf *pidgin_pixbuf_new_from_file_at_size(const char *filename, int width, int height);
@@ -945,37 +885,31 @@ GdkPixbuf *pidgin_pixbuf_new_from_file_at_size(const char *filename, int width,
*
* @return The GdkPixbuf if successful. Otherwise NULL is returned and
* a warning is logged.
- *
- * @since 2.9.0
*/
GdkPixbuf *pidgin_pixbuf_new_from_file_at_scale(const char *filename, int width, int height, gboolean preserve_aspect_ratio);
/**
* Add scrollbars to a widget
- * @param widget The child widget
- * @hscrollbar_policy Horizontal scrolling policy
- * @vscrollbar_policy Vertical scrolling policy
- * @shadow Shadow type
- * @width Desired widget width, or -1 for default
- * @height Desired widget height, or -1 for default
- *
- * @since 2.8.0
+ * @param child The child widget
+ * @param hscrollbar_policy Horizontal scrolling policy
+ * @param vscrollbar_policy Vertical scrolling policy
+ * @param shadow_type Shadow type
+ * @param width Desired widget width, or -1 for default
+ * @param height Desired widget height, or -1 for default
*/
GtkWidget *pidgin_make_scrollable(GtkWidget *child, GtkPolicyType hscrollbar_policy, GtkPolicyType vscrollbar_policy, GtkShadowType shadow_type, int width, int height);
/**
* Initialize some utility functions.
- *
- * @since 2.6.0
*/
void pidgin_utils_init(void);
/**
* Uninitialize some utility functions.
- *
- * @since 2.6.0
*/
void pidgin_utils_uninit(void);
+G_END_DECLS
+
#endif /* _PIDGINUTILS_H_ */
diff --git a/pidgin/gtkwebview.c b/pidgin/gtkwebview.c
new file mode 100644
index 0000000000..7b26a11d21
--- /dev/null
+++ b/pidgin/gtkwebview.c
@@ -0,0 +1,1131 @@
+/*
+ * @file gtkwebview.c GTK+ WebKitWebView wrapper class.
+ * @ingroup 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.
+ *
+ * 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 "internal.h"
+#include "pidgin.h"
+
+#include <gdk/gdkkeysyms.h>
+#include "gtkwebview.h"
+
+#define MAX_FONT_SIZE 7
+#define MAX_SCROLL_TIME 0.4 /* seconds */
+#define SCROLL_DELAY 33 /* milliseconds */
+
+#define GTK_WEBVIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), GTK_TYPE_WEBVIEW, GtkWebViewPriv))
+
+enum {
+ BUTTONS_UPDATE,
+ TOGGLE_FORMAT,
+ CLEAR_FORMAT,
+ UPDATE_FORMAT,
+ CHANGED,
+ LAST_SIGNAL
+};
+static guint signals[LAST_SIGNAL] = { 0 };
+
+/******************************************************************************
+ * Structs
+ *****************************************************************************/
+
+typedef struct _GtkWebViewPriv {
+ gboolean empty; /**< whether anything has been appended **/
+
+ /* JS execute queue */
+ GQueue *js_queue;
+ gboolean is_loading;
+
+ /* Scroll adjustments */
+ GtkAdjustment *vadj;
+ guint scroll_src;
+ GTimer *scroll_time;
+
+ /* Format options */
+ GtkWebViewButtons format_functions;
+ struct {
+ gboolean wbfo:1; /* Whole buffer formatting only. */
+ gboolean block_changed:1;
+ } edit;
+
+} GtkWebViewPriv;
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+
+static WebKitWebViewClass *parent_class = NULL;
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+
+static void
+webview_resource_loading(WebKitWebView *webview,
+ WebKitWebFrame *frame,
+ WebKitWebResource *resource,
+ WebKitNetworkRequest *request,
+ WebKitNetworkResponse *response,
+ gpointer user_data)
+{
+ const gchar *uri;
+
+ uri = webkit_network_request_get_uri(request);
+ if (purple_str_has_prefix(uri, PURPLE_STORED_IMAGE_PROTOCOL)) {
+ int id;
+ PurpleStoredImage *img;
+ const char *filename;
+
+ uri += sizeof(PURPLE_STORED_IMAGE_PROTOCOL) - 1;
+ id = strtoul(uri, NULL, 10);
+
+ img = purple_imgstore_find_by_id(id);
+ if (!img)
+ return;
+
+ filename = purple_imgstore_get_filename(img);
+ if (filename && g_path_is_absolute(filename)) {
+ char *tmp = g_strdup_printf("file://%s", filename);
+ webkit_network_request_set_uri(request, tmp);
+ g_free(tmp);
+ } else {
+ char *b64 = purple_base64_encode(purple_imgstore_get_data(img),
+ purple_imgstore_get_size(img));
+ const char *type = purple_imgstore_get_extension(img);
+ char *tmp = g_strdup_printf("data:image/%s;base64,%s", type, b64);
+ webkit_network_request_set_uri(request, tmp);
+ g_free(b64);
+ g_free(tmp);
+ }
+ }
+}
+
+static gboolean
+process_js_script_queue(GtkWebView *webview)
+{
+ GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ char *script;
+
+ if (priv->is_loading)
+ return FALSE; /* we will be called when loaded */
+ if (!priv->js_queue || g_queue_is_empty(priv->js_queue))
+ return FALSE; /* nothing to do! */
+
+ script = g_queue_pop_head(priv->js_queue);
+ webkit_web_view_execute_script(WEBKIT_WEB_VIEW(webview), script);
+ g_free(script);
+
+ return TRUE; /* there may be more for now */
+}
+
+static void
+webview_load_started(WebKitWebView *webview, WebKitWebFrame *frame,
+ gpointer userdata)
+{
+ GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+
+ /* is there a better way to test for is_loading? */
+ priv->is_loading = TRUE;
+}
+
+static void
+webview_load_finished(WebKitWebView *webview, WebKitWebFrame *frame,
+ gpointer userdata)
+{
+ GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+
+ priv->is_loading = FALSE;
+ g_idle_add((GSourceFunc)process_js_script_queue, webview);
+}
+
+static gboolean
+webview_link_clicked(WebKitWebView *webview,
+ WebKitWebFrame *frame,
+ WebKitNetworkRequest *request,
+ WebKitWebNavigationAction *navigation_action,
+ WebKitWebPolicyDecision *policy_decision,
+ gpointer userdata)
+{
+ const gchar *uri;
+ WebKitWebNavigationReason reason;
+
+ uri = webkit_network_request_get_uri(request);
+ reason = webkit_web_navigation_action_get_reason(navigation_action);
+
+ if (reason == WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED) {
+ /* the gtk imhtml way was to create an idle cb, not sure
+ * why, so right now just using purple_notify_uri directly */
+ purple_notify_uri(NULL, uri);
+ webkit_web_policy_decision_ignore(policy_decision);
+ } else if (reason == WEBKIT_WEB_NAVIGATION_REASON_OTHER)
+ webkit_web_policy_decision_use(policy_decision);
+ else
+ webkit_web_policy_decision_ignore(policy_decision);
+
+ return TRUE;
+}
+
+/*
+ * Smoothly scroll a WebView.
+ *
+ * @return TRUE if the window needs to be scrolled further, FALSE if we're at the bottom.
+ */
+static gboolean
+smooth_scroll_cb(gpointer data)
+{
+ GtkWebViewPriv *priv = data;
+ GtkAdjustment *adj;
+ gdouble max_val;
+ gdouble scroll_val;
+
+ g_return_val_if_fail(priv->scroll_time != NULL, FALSE);
+
+ adj = priv->vadj;
+#if GTK_CHECK_VERSION(2,14,0)
+ max_val = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj);
+#else
+ max_val = adj->upper - adj->page_size;
+#endif
+ scroll_val = gtk_adjustment_get_value(adj) +
+ ((max_val - gtk_adjustment_get_value(adj)) / 3);
+
+ if (g_timer_elapsed(priv->scroll_time, NULL) > MAX_SCROLL_TIME
+ || scroll_val >= max_val) {
+ /* time's up. jump to the end and kill the timer */
+ gtk_adjustment_set_value(adj, max_val);
+ g_timer_destroy(priv->scroll_time);
+ priv->scroll_time = NULL;
+ g_source_remove(priv->scroll_src);
+ priv->scroll_src = 0;
+ return FALSE;
+ }
+
+ /* scroll by 1/3rd the remaining distance */
+ gtk_adjustment_set_value(adj, scroll_val);
+ return TRUE;
+}
+
+static gboolean
+scroll_idle_cb(gpointer data)
+{
+ GtkWebViewPriv *priv = data;
+ GtkAdjustment *adj = priv->vadj;
+ gdouble max_val;
+
+ if (adj) {
+#if GTK_CHECK_VERSION(2,14,0)
+ max_val = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj);
+#else
+ max_val = adj->upper - adj->page_size;
+#endif
+ gtk_adjustment_set_value(adj, max_val);
+ }
+
+ priv->scroll_src = 0;
+ return FALSE;
+}
+
+static void
+emit_format_signal(GtkWebView *webview, GtkWebViewButtons buttons)
+{
+ g_object_ref(webview);
+ g_signal_emit(webview, signals[TOGGLE_FORMAT], 0, buttons);
+ g_object_unref(webview);
+}
+
+static void
+do_formatting(GtkWebView *webview, const char *name, const char *value)
+{
+ GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ WebKitDOMDocument *dom;
+ WebKitDOMDOMWindow *win;
+ WebKitDOMDOMSelection *sel = NULL;
+ WebKitDOMRange *range = NULL;
+
+ dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
+
+ if (priv->edit.wbfo) {
+ win = webkit_dom_document_get_default_view(dom);
+ sel = webkit_dom_dom_window_get_selection(win);
+ if (webkit_dom_dom_selection_get_range_count(sel) > 0)
+ range = webkit_dom_dom_selection_get_range_at(sel, 0, NULL);
+ webkit_web_view_select_all(WEBKIT_WEB_VIEW(webview));
+ }
+
+ priv->edit.block_changed = TRUE;
+ webkit_dom_document_exec_command(dom, name, FALSE, value);
+ priv->edit.block_changed = FALSE;
+
+ if (priv->edit.wbfo) {
+ if (range) {
+ webkit_dom_dom_selection_remove_all_ranges(sel);
+ webkit_dom_dom_selection_add_range(sel, range);
+ } else {
+ webkit_dom_dom_selection_collapse_to_end(sel, NULL);
+ }
+ }
+}
+
+static void
+webview_font_shrink(GtkWebView *webview)
+{
+ gint fontsize;
+ char *tmp;
+
+ fontsize = gtk_webview_get_current_fontsize(webview);
+ fontsize = MAX(fontsize - 1, 1);
+
+ tmp = g_strdup_printf("%d", fontsize);
+ do_formatting(webview, "fontSize", tmp);
+ g_free(tmp);
+}
+
+static void
+webview_font_grow(GtkWebView *webview)
+{
+ gint fontsize;
+ char *tmp;
+
+ fontsize = gtk_webview_get_current_fontsize(webview);
+ fontsize = MIN(fontsize + 1, MAX_FONT_SIZE);
+
+ tmp = g_strdup_printf("%d", fontsize);
+ do_formatting(webview, "fontSize", tmp);
+ g_free(tmp);
+}
+
+static void
+webview_clear_formatting(GtkWebView *webview)
+{
+ if (!webkit_web_view_get_editable(WEBKIT_WEB_VIEW(webview)))
+ return;
+
+ do_formatting(webview, "removeFormat", "");
+ do_formatting(webview, "unlink", "");
+ do_formatting(webview, "backColor", "inherit");
+}
+
+static void
+webview_toggle_format(GtkWebView *webview, GtkWebViewButtons buttons)
+{
+ /* since this function is the handler for the formatting keystrokes,
+ we need to check here that the formatting attempted is permitted */
+ buttons &= gtk_webview_get_format_functions(webview);
+
+ switch (buttons) {
+ case GTK_WEBVIEW_BOLD:
+ do_formatting(webview, "bold", "");
+ break;
+ case GTK_WEBVIEW_ITALIC:
+ do_formatting(webview, "italic", "");
+ break;
+ case GTK_WEBVIEW_UNDERLINE:
+ do_formatting(webview, "underline", "");
+ break;
+ case GTK_WEBVIEW_STRIKE:
+ do_formatting(webview, "strikethrough", "");
+ break;
+ case GTK_WEBVIEW_SHRINK:
+ webview_font_shrink(webview);
+ break;
+ case GTK_WEBVIEW_GROW:
+ webview_font_grow(webview);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+editable_input_cb(GtkWebView *webview, gpointer data)
+{
+ GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ if (!priv->edit.block_changed && gtk_widget_is_sensitive(GTK_WIDGET(webview)))
+ g_signal_emit(webview, signals[CHANGED], 0);
+}
+
+/******************************************************************************
+ * GObject Stuff
+ *****************************************************************************/
+
+GtkWidget *
+gtk_webview_new(void)
+{
+ return GTK_WIDGET(g_object_new(gtk_webview_get_type(), NULL));
+}
+
+static void
+gtk_webview_finalize(GObject *webview)
+{
+ GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ gpointer temp;
+
+ while ((temp = g_queue_pop_head(priv->js_queue)))
+ g_free(temp);
+ g_queue_free(priv->js_queue);
+
+ G_OBJECT_CLASS(parent_class)->finalize(G_OBJECT(webview));
+}
+
+static void
+gtk_webview_class_init(GtkWebViewClass *klass, gpointer userdata)
+{
+ GObjectClass *gobject_class;
+ GtkBindingSet *binding_set;
+
+ parent_class = g_type_class_ref(webkit_web_view_get_type());
+ gobject_class = G_OBJECT_CLASS(klass);
+
+ g_type_class_add_private(klass, sizeof(GtkWebViewPriv));
+
+ signals[BUTTONS_UPDATE] = g_signal_new("allowed-formats-updated",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(GtkWebViewClass, buttons_update),
+ NULL, 0, g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[TOGGLE_FORMAT] = g_signal_new("format-toggled",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET(GtkWebViewClass, toggle_format),
+ NULL, 0, g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[CLEAR_FORMAT] = g_signal_new("format-cleared",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET(GtkWebViewClass, clear_format),
+ NULL, 0, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals[UPDATE_FORMAT] = g_signal_new("format-updated",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(GtkWebViewClass, update_format),
+ NULL, 0, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals[CHANGED] = g_signal_new("changed",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(GtkWebViewClass, changed),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ klass->toggle_format = webview_toggle_format;
+ klass->clear_format = webview_clear_formatting;
+
+ gobject_class->finalize = gtk_webview_finalize;
+
+ binding_set = gtk_binding_set_by_class(parent_class);
+ gtk_binding_entry_add_signal(binding_set, GDK_KEY_b, GDK_CONTROL_MASK,
+ "format-toggled", 1, G_TYPE_INT,
+ GTK_WEBVIEW_BOLD);
+ gtk_binding_entry_add_signal(binding_set, GDK_KEY_i, GDK_CONTROL_MASK,
+ "format-toggled", 1, G_TYPE_INT,
+ GTK_WEBVIEW_ITALIC);
+ gtk_binding_entry_add_signal(binding_set, GDK_KEY_u, GDK_CONTROL_MASK,
+ "format-toggled", 1, G_TYPE_INT,
+ GTK_WEBVIEW_UNDERLINE);
+ gtk_binding_entry_add_signal(binding_set, GDK_KEY_plus, GDK_CONTROL_MASK,
+ "format-toggled", 1, G_TYPE_INT,
+ GTK_WEBVIEW_GROW);
+ gtk_binding_entry_add_signal(binding_set, GDK_KEY_equal, GDK_CONTROL_MASK,
+ "format-toggled", 1, G_TYPE_INT,
+ GTK_WEBVIEW_GROW);
+ gtk_binding_entry_add_signal(binding_set, GDK_KEY_minus, GDK_CONTROL_MASK,
+ "format-toggled", 1, G_TYPE_INT,
+ GTK_WEBVIEW_SHRINK);
+
+ binding_set = gtk_binding_set_by_class(klass);
+ gtk_binding_entry_add_signal(binding_set, GDK_KEY_r, GDK_CONTROL_MASK,
+ "format-cleared", 0);
+}
+
+static void
+gtk_webview_init(GtkWebView *webview, gpointer userdata)
+{
+ GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+
+ priv->empty = TRUE;
+ priv->js_queue = g_queue_new();
+
+ g_signal_connect(webview, "navigation-policy-decision-requested",
+ G_CALLBACK(webview_link_clicked), NULL);
+
+ g_signal_connect(webview, "load-started",
+ G_CALLBACK(webview_load_started), NULL);
+
+ g_signal_connect(webview, "load-finished",
+ G_CALLBACK(webview_load_finished), NULL);
+
+ g_signal_connect(G_OBJECT(webview), "resource-request-starting",
+ G_CALLBACK(webview_resource_loading), NULL);
+}
+
+GType
+gtk_webview_get_type(void)
+{
+ static GType mview_type = 0;
+ if (G_UNLIKELY(mview_type == 0)) {
+ static const GTypeInfo mview_info = {
+ sizeof(GtkWebViewClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)gtk_webview_class_init,
+ NULL,
+ NULL,
+ sizeof(GtkWebView),
+ 0,
+ (GInstanceInitFunc)gtk_webview_init,
+ NULL
+ };
+ mview_type = g_type_register_static(webkit_web_view_get_type(),
+ "GtkWebView", &mview_info, 0);
+ }
+ return mview_type;
+}
+
+/*****************************************************************************
+ * Public API functions
+ *****************************************************************************/
+
+gboolean
+gtk_webview_is_empty(GtkWebView *webview)
+{
+ GtkWebViewPriv *priv;
+
+ g_return_val_if_fail(webview != NULL, TRUE);
+
+ priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ return priv->empty;
+}
+
+char *
+gtk_webview_quote_js_string(const char *text)
+{
+ GString *str = g_string_new("\"");
+ const char *cur = text;
+
+ while (cur && *cur) {
+ switch (*cur) {
+ case '\\':
+ g_string_append(str, "\\\\");
+ break;
+ case '\"':
+ g_string_append(str, "\\\"");
+ break;
+ case '\r':
+ g_string_append(str, "<br/>");
+ break;
+ case '\n':
+ break;
+ default:
+ g_string_append_c(str, *cur);
+ }
+ cur++;
+ }
+
+ g_string_append_c(str, '"');
+
+ return g_string_free(str, FALSE);
+}
+
+void
+gtk_webview_safe_execute_script(GtkWebView *webview, const char *script)
+{
+ GtkWebViewPriv *priv;
+
+ g_return_if_fail(webview != NULL);
+
+ priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ g_queue_push_tail(priv->js_queue, g_strdup(script));
+ g_idle_add((GSourceFunc)process_js_script_queue, webview);
+}
+
+void
+gtk_webview_load_html_string(GtkWebView *webview, const char *html)
+{
+ g_return_if_fail(webview != NULL);
+
+ webkit_web_view_load_string(WEBKIT_WEB_VIEW(webview), html, NULL, NULL,
+ "file:///");
+}
+
+void
+gtk_webview_load_html_string_with_selection(GtkWebView *webview, const char *html)
+{
+ g_return_if_fail(webview != NULL);
+
+ gtk_webview_load_html_string(webview, html);
+ gtk_webview_safe_execute_script(webview,
+ "var s = window.getSelection();"
+ "var r = document.createRange();"
+ "var n = document.getElementById('caret');"
+ "r.selectNodeContents(n);"
+ "var f = r.extractContents();"
+ "r.selectNode(n);"
+ "r.insertNode(f);"
+ "n.parentNode.removeChild(n);"
+ "s.removeAllRanges();"
+ "s.addRange(r);");
+}
+
+void
+gtk_webview_append_html(GtkWebView *webview, const char *html)
+{
+ GtkWebViewPriv *priv;
+ WebKitDOMDocument *doc;
+ WebKitDOMHTMLElement *body;
+
+ g_return_if_fail(webview != NULL);
+
+ priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
+ body = webkit_dom_document_get_body(doc);
+ webkit_dom_html_element_insert_adjacent_html(body, "beforeend", html, NULL);
+ priv->empty = FALSE;
+}
+
+void
+gtk_webview_set_vadjustment(GtkWebView *webview, GtkAdjustment *vadj)
+{
+ GtkWebViewPriv *priv;
+
+ g_return_if_fail(webview != NULL);
+
+ priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ priv->vadj = vadj;
+}
+
+void
+gtk_webview_scroll_to_end(GtkWebView *webview, gboolean smooth)
+{
+ GtkWebViewPriv *priv;
+
+ g_return_if_fail(webview != NULL);
+
+ priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ if (priv->scroll_time)
+ g_timer_destroy(priv->scroll_time);
+ if (priv->scroll_src)
+ g_source_remove(priv->scroll_src);
+ if (smooth) {
+ priv->scroll_time = g_timer_new();
+ priv->scroll_src = g_timeout_add_full(G_PRIORITY_LOW, SCROLL_DELAY, smooth_scroll_cb, priv, NULL);
+ } else {
+ priv->scroll_time = NULL;
+ priv->scroll_src = g_idle_add_full(G_PRIORITY_LOW, scroll_idle_cb, priv, NULL);
+ }
+}
+
+void
+gtk_webview_page_up(GtkWebView *webview)
+{
+ GtkWebViewPriv *priv;
+ GtkAdjustment *vadj;
+ gdouble scroll_val;
+
+ g_return_if_fail(webview != NULL);
+
+ priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ vadj = priv->vadj;
+#if GTK_CHECK_VERSION(2,14,0)
+ scroll_val = gtk_adjustment_get_value(vadj) - gtk_adjustment_get_page_size(vadj);
+ scroll_val = MAX(scroll_val, gtk_adjustment_get_lower(vadj));
+#else
+ scroll_val = gtk_adjustment_get_value(vadj) - vadj->page_size;
+ scroll_val = MAX(scroll_val, vadj->lower);
+#endif
+
+ gtk_adjustment_set_value(vadj, scroll_val);
+}
+
+void
+gtk_webview_page_down(GtkWebView *webview)
+{
+ GtkWebViewPriv *priv;
+ GtkAdjustment *vadj;
+ gdouble scroll_val;
+ gdouble page_size;
+
+ g_return_if_fail(webview != NULL);
+
+ priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ vadj = priv->vadj;
+#if GTK_CHECK_VERSION(2,14,0)
+ page_size = gtk_adjustment_get_page_size(vadj);
+ scroll_val = gtk_adjustment_get_value(vadj) + page_size;
+ scroll_val = MIN(scroll_val, gtk_adjustment_get_upper(vadj) - page_size);
+#else
+ page_size = vadj->page_size;
+ scroll_val = gtk_adjustment_get_value(vadj) + page_size;
+ scroll_val = MIN(scroll_val, vadj->upper - page_size);
+#endif
+
+ gtk_adjustment_set_value(vadj, scroll_val);
+}
+
+void
+gtk_webview_set_editable(GtkWebView *webview, gboolean editable)
+{
+ g_return_if_fail(webview != NULL);
+
+ webkit_web_view_set_editable(WEBKIT_WEB_VIEW(webview), editable);
+
+ if (editable) {
+ g_signal_connect(G_OBJECT(webview), "user-changed-contents",
+ G_CALLBACK(editable_input_cb), NULL);
+ } else {
+ g_signal_handlers_disconnect_by_func(G_OBJECT(webview),
+ G_CALLBACK(editable_input_cb),
+ NULL);
+ }
+}
+
+void
+gtk_webview_setup_entry(GtkWebView *webview, PurpleConnectionFlags flags)
+{
+ GtkWebViewButtons buttons;
+
+ g_return_if_fail(webview != NULL);
+
+ if (flags & PURPLE_CONNECTION_HTML) {
+ gboolean bold, italic, underline, strike;
+
+ buttons = GTK_WEBVIEW_ALL;
+
+ if (flags & PURPLE_CONNECTION_NO_BGCOLOR)
+ buttons &= ~GTK_WEBVIEW_BACKCOLOR;
+ if (flags & PURPLE_CONNECTION_NO_FONTSIZE)
+ {
+ buttons &= ~GTK_WEBVIEW_GROW;
+ buttons &= ~GTK_WEBVIEW_SHRINK;
+ }
+ if (flags & PURPLE_CONNECTION_NO_URLDESC)
+ buttons &= ~GTK_WEBVIEW_LINKDESC;
+
+ gtk_webview_get_current_format(webview, &bold, &italic, &underline, &strike);
+
+ gtk_webview_set_format_functions(webview, GTK_WEBVIEW_ALL);
+ if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/send_bold") != bold)
+ gtk_webview_toggle_bold(webview);
+
+ if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/send_italic") != italic)
+ gtk_webview_toggle_italic(webview);
+
+ if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/send_underline") != underline)
+ gtk_webview_toggle_underline(webview);
+
+ if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/send_strike") != strike)
+ gtk_webview_toggle_strike(webview);
+
+ gtk_webview_toggle_fontface(webview,
+ purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/font_face"));
+
+ if (!(flags & PURPLE_CONNECTION_NO_FONTSIZE))
+ {
+ int size = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/font_size");
+
+ /* 3 is the default. */
+ if (size != 3)
+ gtk_webview_font_set_size(webview, size);
+ }
+
+ gtk_webview_toggle_forecolor(webview,
+ purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/fgcolor"));
+
+ if (!(flags & PURPLE_CONNECTION_NO_BGCOLOR)) {
+ gtk_webview_toggle_backcolor(webview,
+ purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor"));
+ } else {
+ gtk_webview_toggle_backcolor(webview, "");
+ }
+
+ if (flags & PURPLE_CONNECTION_FORMATTING_WBFO)
+ gtk_webview_set_whole_buffer_formatting_only(webview, TRUE);
+ else
+ gtk_webview_set_whole_buffer_formatting_only(webview, FALSE);
+ } else {
+ buttons = GTK_WEBVIEW_SMILEY | GTK_WEBVIEW_IMAGE;
+ webview_clear_formatting(webview);
+ }
+
+ if (flags & PURPLE_CONNECTION_NO_IMAGES)
+ buttons &= ~GTK_WEBVIEW_IMAGE;
+
+ if (flags & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)
+ buttons |= GTK_WEBVIEW_CUSTOM_SMILEY;
+ else
+ buttons &= ~GTK_WEBVIEW_CUSTOM_SMILEY;
+
+ gtk_webview_set_format_functions(webview, buttons);
+}
+
+void
+pidgin_webview_set_spellcheck(GtkWebView *webview, gboolean enable)
+{
+ WebKitWebSettings *settings;
+
+ g_return_if_fail(webview != NULL);
+
+ settings = webkit_web_view_get_settings(WEBKIT_WEB_VIEW(webview));
+ g_object_set(G_OBJECT(settings), "enable-spell-checking", enable, NULL);
+ webkit_web_view_set_settings(WEBKIT_WEB_VIEW(webview), settings);
+}
+
+void
+gtk_webview_set_whole_buffer_formatting_only(GtkWebView *webview, gboolean wbfo)
+{
+ GtkWebViewPriv *priv;
+
+ g_return_if_fail(webview != NULL);
+
+ priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ priv->edit.wbfo = wbfo;
+}
+
+void
+gtk_webview_set_format_functions(GtkWebView *webview, GtkWebViewButtons buttons)
+{
+ GtkWebViewPriv *priv;
+ GObject *object;
+
+ g_return_if_fail(webview != NULL);
+
+ priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ object = g_object_ref(G_OBJECT(webview));
+ priv->format_functions = buttons;
+ g_signal_emit(object, signals[BUTTONS_UPDATE], 0, buttons);
+ g_object_unref(object);
+}
+
+gchar *
+gtk_webview_get_head_html(GtkWebView *webview)
+{
+ WebKitDOMDocument *doc;
+ WebKitDOMHTMLHeadElement *head;
+ gchar *html;
+
+ g_return_val_if_fail(webview != NULL, NULL);
+
+ doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
+ head = webkit_dom_document_get_head(doc);
+ html = webkit_dom_html_element_get_inner_html(WEBKIT_DOM_HTML_ELEMENT(head));
+
+ return html;
+}
+
+gchar *
+gtk_webview_get_body_html(GtkWebView *webview)
+{
+ WebKitDOMDocument *doc;
+ WebKitDOMHTMLElement *body;
+ gchar *html;
+
+ g_return_val_if_fail(webview != NULL, NULL);
+
+ doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
+ body = webkit_dom_document_get_body(doc);
+ html = webkit_dom_html_element_get_inner_html(body);
+
+ return html;
+}
+
+gchar *
+gtk_webview_get_body_text(GtkWebView *webview)
+{
+ WebKitDOMDocument *doc;
+ WebKitDOMHTMLElement *body;
+ gchar *text;
+
+ g_return_val_if_fail(webview != NULL, NULL);
+
+ doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
+ body = webkit_dom_document_get_body(doc);
+ text = webkit_dom_html_element_get_inner_text(body);
+
+ return text;
+}
+
+gchar *
+gtk_webview_get_selected_text(GtkWebView *webview)
+{
+ WebKitDOMDocument *dom;
+ WebKitDOMDOMWindow *win;
+ WebKitDOMDOMSelection *sel;
+ WebKitDOMRange *range;
+
+ g_return_val_if_fail(webview != NULL, NULL);
+
+ dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
+ win = webkit_dom_document_get_default_view(dom);
+ sel = webkit_dom_dom_window_get_selection(win);
+ range = webkit_dom_dom_selection_get_range_at(sel, 0, NULL);
+
+ return webkit_dom_range_get_text(range);
+}
+
+GtkWebViewButtons
+gtk_webview_get_format_functions(GtkWebView *webview)
+{
+ GtkWebViewPriv *priv;
+
+ g_return_val_if_fail(webview != NULL, 0);
+
+ priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ return priv->format_functions;
+}
+
+void
+gtk_webview_get_current_format(GtkWebView *webview, gboolean *bold,
+ gboolean *italic, gboolean *underline,
+ gboolean *strike)
+{
+ WebKitDOMDocument *dom;
+
+ g_return_if_fail(webview != NULL);
+
+ dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
+
+ if (bold)
+ *bold = webkit_dom_document_query_command_state(dom, "bold");
+ if (italic)
+ *italic = webkit_dom_document_query_command_state(dom, "italic");
+ if (underline)
+ *underline = webkit_dom_document_query_command_state(dom, "underline");
+ if (strike)
+ *strike = webkit_dom_document_query_command_state(dom, "strikethrough");
+}
+
+char *
+gtk_webview_get_current_fontface(GtkWebView *webview)
+{
+ WebKitDOMDocument *dom;
+
+ g_return_val_if_fail(webview != NULL, NULL);
+
+ dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
+ return webkit_dom_document_query_command_value(dom, "fontName");
+}
+
+char *
+gtk_webview_get_current_forecolor(GtkWebView *webview)
+{
+ WebKitDOMDocument *dom;
+
+ g_return_val_if_fail(webview != NULL, NULL);
+
+ dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
+ return webkit_dom_document_query_command_value(dom, "foreColor");
+}
+
+char *
+gtk_webview_get_current_backcolor(GtkWebView *webview)
+{
+ WebKitDOMDocument *dom;
+
+ g_return_val_if_fail(webview != NULL, NULL);
+
+ dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
+ return webkit_dom_document_query_command_value(dom, "backColor");
+}
+
+gint
+gtk_webview_get_current_fontsize(GtkWebView *webview)
+{
+ WebKitDOMDocument *dom;
+ gchar *text;
+ gint size;
+
+ g_return_val_if_fail(webview != NULL, 0);
+
+ dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
+ text = webkit_dom_document_query_command_value(dom, "fontSize");
+ size = atoi(text);
+ g_free(text);
+
+ return size;
+}
+
+gboolean
+gtk_webview_get_editable(GtkWebView *webview)
+{
+ return webkit_web_view_get_editable(WEBKIT_WEB_VIEW(webview));
+}
+
+void
+gtk_webview_clear_formatting(GtkWebView *webview)
+{
+ GObject *object;
+
+ g_return_if_fail(webview != NULL);
+
+ object = g_object_ref(G_OBJECT(webview));
+ g_signal_emit(object, signals[CLEAR_FORMAT], 0);
+ g_object_unref(object);
+}
+
+void
+gtk_webview_toggle_bold(GtkWebView *webview)
+{
+ g_return_if_fail(webview != NULL);
+ emit_format_signal(webview, GTK_WEBVIEW_BOLD);
+}
+
+void
+gtk_webview_toggle_italic(GtkWebView *webview)
+{
+ g_return_if_fail(webview != NULL);
+ emit_format_signal(webview, GTK_WEBVIEW_ITALIC);
+}
+
+void
+gtk_webview_toggle_underline(GtkWebView *webview)
+{
+ g_return_if_fail(webview != NULL);
+ emit_format_signal(webview, GTK_WEBVIEW_UNDERLINE);
+}
+
+void
+gtk_webview_toggle_strike(GtkWebView *webview)
+{
+ g_return_if_fail(webview != NULL);
+ emit_format_signal(webview, GTK_WEBVIEW_STRIKE);
+}
+
+gboolean
+gtk_webview_toggle_forecolor(GtkWebView *webview, const char *color)
+{
+ g_return_val_if_fail(webview != NULL, FALSE);
+
+ do_formatting(webview, "foreColor", color);
+ emit_format_signal(webview, GTK_WEBVIEW_FORECOLOR);
+
+ return FALSE;
+}
+
+gboolean
+gtk_webview_toggle_backcolor(GtkWebView *webview, const char *color)
+{
+ g_return_val_if_fail(webview != NULL, FALSE);
+
+ do_formatting(webview, "backColor", color);
+ emit_format_signal(webview, GTK_WEBVIEW_BACKCOLOR);
+
+ return FALSE;
+}
+
+gboolean
+gtk_webview_toggle_fontface(GtkWebView *webview, const char *face)
+{
+ g_return_val_if_fail(webview != NULL, FALSE);
+
+ do_formatting(webview, "fontName", face);
+ emit_format_signal(webview, GTK_WEBVIEW_FACE);
+
+ return FALSE;
+}
+
+void
+gtk_webview_font_set_size(GtkWebView *webview, gint size)
+{
+ char *tmp;
+
+ g_return_if_fail(webview != NULL);
+
+ tmp = g_strdup_printf("%d", size);
+ do_formatting(webview, "fontSize", tmp);
+ emit_format_signal(webview, GTK_WEBVIEW_SHRINK|GTK_WEBVIEW_GROW);
+ g_free(tmp);
+}
+
+void
+gtk_webview_font_shrink(GtkWebView *webview)
+{
+ g_return_if_fail(webview != NULL);
+ emit_format_signal(webview, GTK_WEBVIEW_SHRINK);
+}
+
+void
+gtk_webview_font_grow(GtkWebView *webview)
+{
+ g_return_if_fail(webview != NULL);
+ emit_format_signal(webview, GTK_WEBVIEW_GROW);
+}
+
+void
+gtk_webview_insert_hr(GtkWebView *webview)
+{
+ GtkWebViewPriv *priv;
+ WebKitDOMDocument *dom;
+
+ g_return_if_fail(webview != NULL);
+
+ priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
+
+ priv->edit.block_changed = TRUE;
+ webkit_dom_document_exec_command(dom, "insertHorizontalRule", FALSE, "");
+ priv->edit.block_changed = FALSE;
+}
+
+void
+gtk_webview_insert_link(GtkWebView *webview, const char *url, const char *desc)
+{
+ GtkWebViewPriv *priv;
+ WebKitDOMDocument *dom;
+ char *link;
+
+ g_return_if_fail(webview != NULL);
+
+ priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
+ link = g_strdup_printf("<a href='%s'>%s</a>", url, desc ? desc : url);
+
+ priv->edit.block_changed = TRUE;
+ webkit_dom_document_exec_command(dom, "insertHTML", FALSE, link);
+ priv->edit.block_changed = FALSE;
+ g_free(link);
+}
+
+void
+gtk_webview_insert_image(GtkWebView *webview, int id)
+{
+ GtkWebViewPriv *priv;
+ WebKitDOMDocument *dom;
+ char *img;
+
+ g_return_if_fail(webview != NULL);
+
+ priv = GTK_WEBVIEW_GET_PRIVATE(webview);
+ dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
+ img = g_strdup_printf("<img src='" PURPLE_STORED_IMAGE_PROTOCOL "%d'/>",
+ id);
+
+ priv->edit.block_changed = TRUE;
+ webkit_dom_document_exec_command(dom, "insertHTML", FALSE, img);
+ priv->edit.block_changed = FALSE;
+ g_free(img);
+}
+
diff --git a/pidgin/gtkwebview.h b/pidgin/gtkwebview.h
new file mode 100644
index 0000000000..a3d472363b
--- /dev/null
+++ b/pidgin/gtkwebview.h
@@ -0,0 +1,460 @@
+/**
+ * @file gtkwebview.h Wrapper over the Gtk WebKitWebView component
+ * @ingroup 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.
+ *
+ * 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
+ *
+ */
+
+#ifndef _PIDGIN_WEBVIEW_H_
+#define _PIDGIN_WEBVIEW_H_
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#define GTK_TYPE_WEBVIEW (gtk_webview_get_type())
+#define GTK_WEBVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_WEBVIEW, GtkWebView))
+#define GTK_WEBVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_WEBVIEW, GtkWebViewClass))
+#define GTK_IS_WEBVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_WEBVIEW))
+#define GTK_IS_WEBVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_WEBVIEW))
+#define GTK_WEBVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_WEBVIEW, GtkWebViewClass))
+
+typedef enum {
+ GTK_WEBVIEW_BOLD = 1 << 0,
+ GTK_WEBVIEW_ITALIC = 1 << 1,
+ GTK_WEBVIEW_UNDERLINE = 1 << 2,
+ GTK_WEBVIEW_GROW = 1 << 3,
+ GTK_WEBVIEW_SHRINK = 1 << 4,
+ GTK_WEBVIEW_FACE = 1 << 5,
+ GTK_WEBVIEW_FORECOLOR = 1 << 6,
+ GTK_WEBVIEW_BACKCOLOR = 1 << 7,
+ GTK_WEBVIEW_LINK = 1 << 8,
+ GTK_WEBVIEW_IMAGE = 1 << 9,
+ GTK_WEBVIEW_SMILEY = 1 << 10,
+ GTK_WEBVIEW_LINKDESC = 1 << 11,
+ GTK_WEBVIEW_STRIKE = 1 << 12,
+ /** Show custom smileys when appropriate. */
+ GTK_WEBVIEW_CUSTOM_SMILEY = 1 << 13,
+ GTK_WEBVIEW_ALL = -1
+} GtkWebViewButtons;
+
+typedef struct _GtkWebView GtkWebView;
+typedef struct _GtkWebViewClass GtkWebViewClass;
+
+struct _GtkWebView
+{
+ WebKitWebView parent;
+};
+
+struct _GtkWebViewClass
+{
+ WebKitWebViewClass parent;
+
+ void (*buttons_update)(GtkWebView *, GtkWebViewButtons);
+ void (*toggle_format)(GtkWebView *, GtkWebViewButtons);
+ void (*clear_format)(GtkWebView *);
+ void (*update_format)(GtkWebView *);
+ void (*changed)(GtkWebView *);
+};
+
+G_BEGIN_DECLS
+
+/**
+ * Returns the GType for a GtkWebView widget
+ *
+ * @return The GType for GtkWebView widget
+ */
+GType gtk_webview_get_type(void);
+
+/**
+ * Create a new GtkWebView object
+ *
+ * @return A GtkWidget corresponding to the GtkWebView object
+ */
+GtkWidget *gtk_webview_new(void);
+
+/**
+ * TODO WEBKIT: Right now this just tests whether an append has been called
+ * since the last clear or since the Widget was created. So it does not
+ * test for load_string's called in between.
+ *
+ * @param webview The GtkWebView object
+ *
+ * @return gboolean indicating whether the webview is empty
+ */
+gboolean gtk_webview_is_empty(GtkWebView *webview);
+
+/**
+ * A very basic routine to append html, which can be considered
+ * equivalent to a "document.write" using JavaScript.
+ *
+ * @param webview The GtkWebView object
+ * @param markup The html markup to append
+ */
+void gtk_webview_append_html(GtkWebView *webview, const char *markup);
+
+/**
+ * Requests loading of the given content.
+ *
+ * @param webview The GtkWebView object
+ * @param html The HTML content to load
+ */
+void gtk_webview_load_html_string(GtkWebView *webview, const char *html);
+
+/**
+ * Requests loading of the given content and sets the selection. You must
+ * include an anchor tag with id='caret' in the HTML string, which will be
+ * used to set the selection. This tag is then removed so that querying the
+ * WebView's HTML contents will no longer return it.
+ *
+ * @param webview The GtkWebView object
+ * @param html The HTML content to load
+ */
+void gtk_webview_load_html_string_with_selection(GtkWebView *webview, const char *html);
+
+/**
+ * Execute the JavaScript only after the webkit_webview_load_string
+ * loads completely. We also guarantee that the scripts are executed
+ * in the order they are called here. This is useful to avoid race
+ * conditions when calling JS functions immediately after opening the
+ * page.
+ *
+ * @param webview The GtkWebView object
+ * @param script The script to execute
+ */
+void gtk_webview_safe_execute_script(GtkWebView *webview, const char *script);
+
+/**
+ * A convenience routine to quote a string for use as a JavaScript
+ * string. For instance, "hello 'world'" becomes "'hello \\'world\\''"
+ *
+ * @param str The string to escape and quote
+ *
+ * @return The quoted string
+ */
+char *gtk_webview_quote_js_string(const char *str);
+
+/**
+ * Set the vertical adjustment for the GtkWebView.
+ *
+ * @param webview The GtkWebView object
+ * @param vadj The GtkAdjustment that control the webview
+ */
+void gtk_webview_set_vadjustment(GtkWebView *webview, GtkAdjustment *vadj);
+
+/**
+ * Scrolls the Webview to the end of its contents.
+ *
+ * @param webview The GtkWebView object
+ * @param smooth A boolean indicating if smooth scrolling should be used
+ */
+void gtk_webview_scroll_to_end(GtkWebView *webview, gboolean smooth);
+
+/**
+ * Scrolls a GtkWebView up by one page.
+ *
+ * @param webview The GtkWebView.
+ */
+void gtk_webview_page_up(GtkWebView *webview);
+
+/**
+ * Scrolls a GtkWebView down by one page.
+ *
+ * @param webview The GtkWebView.
+ */
+void gtk_webview_page_down(GtkWebView *webview);
+
+/**
+ * Enables or disables editing in a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ * @param editable @c TRUE to make the widget editable, or @c FALSE otherwise.
+ */
+void gtk_webview_set_editable(GtkWebView *webview, gboolean editable);
+
+/**
+ * Setup formatting for a GtkWebView depending on the flags specified.
+ *
+ * @param webview The GtkWebView.
+ * @param flags The connection flags describing the allowed formatting.
+ */
+void gtk_webview_setup_entry(GtkWebView *webview, PurpleConnectionFlags flags);
+
+/**
+ * Setup spell-checking on a GtkWebView.
+ *
+ * @param webview The GtkWebView.
+ * @param enable Whether to enable or disable spell-checking.
+ */
+void pidgin_webview_set_spellcheck(GtkWebView *webview, gboolean enable);
+
+/**
+ * Enables or disables whole buffer formatting only (wbfo) in a GtkWebView.
+ * In this mode formatting options to the buffer take effect for the entire
+ * buffer instead of specific text.
+ *
+ * @param webview The GtkWebView
+ * @param wbfo @c TRUE to enable the mode, or @c FALSE otherwise.
+ */
+void gtk_webview_set_whole_buffer_formatting_only(GtkWebView *webview,
+ gboolean wbfo);
+
+/**
+ * Indicates which formatting functions to enable and disable in a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ * @param buttons A GtkWebViewButtons bitmask indicating which functions to use
+ */
+void gtk_webview_set_format_functions(GtkWebView *webview,
+ GtkWebViewButtons buttons);
+
+/**
+ * Returns which formatting functions are enabled in a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ *
+ * @return A GtkWebViewButtons bitmask indicating which functions to are enabled
+ */
+GtkWebViewButtons gtk_webview_get_format_functions(GtkWebView *webview);
+
+/**
+ * Sets each boolean to @c TRUE or @c FALSE to indicate if that formatting
+ * option is enabled at the current position in a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ * @param bold The boolean to set for bold or @c NULL.
+ * @param italic The boolean to set for italic or @c NULL.
+ * @param underline The boolean to set for underline or @c NULL.
+ * @param strikethrough The boolean to set for strikethrough or @c NULL.
+ */
+void gtk_webview_get_current_format(GtkWebView *webview, gboolean *bold,
+ gboolean *italic, gboolean *underline,
+ gboolean *strike);
+
+/**
+ * Returns a string containing the selected font face at the current position
+ * in a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ *
+ * @return A string containing the font face or @c NULL if none is set.
+ */
+char *gtk_webview_get_current_fontface(GtkWebView *webview);
+
+/**
+ * Returns a string containing the selected foreground color at the current
+ * position in a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ *
+ * @return A string containing the foreground color or @c NULL if none is set.
+ */
+char *gtk_webview_get_current_forecolor(GtkWebView *webview);
+
+/**
+ * Returns a string containing the selected font background color at the current
+ * position in a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ *
+ * @return A string containing the background color or @c NULL if none is set.
+ */
+char *gtk_webview_get_current_backcolor(GtkWebView *webview);
+
+/**
+ * Returns a integer containing the selected HTML font size at the current
+ * position in a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ *
+ * @return The HTML font size.
+ */
+gint gtk_webview_get_current_fontsize(GtkWebView *webview);
+
+/**
+ * Checks whether a GtkWebView is marked as editable.
+ *
+ * @param webview The GtkWebView
+ *
+ * @return @c TRUE if the IM/HTML is editable, or @c FALSE otherwise.
+ */
+gboolean gtk_webview_get_editable(GtkWebView *webview);
+
+/**
+ * Gets the content of the head element of a GtkWebView as HTML.
+ *
+ * @param webview The GtkWebView
+ *
+ * @return The HTML from the head element.
+ */
+gchar *gtk_webview_get_head_html(GtkWebView *webview);
+
+/**
+ * Gets the HTML content of a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ *
+ * @return The HTML that is currently displayed.
+ */
+gchar *gtk_webview_get_body_html(GtkWebView *webview);
+
+/**
+ * Gets the text content of a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ *
+ * @return The HTML-free text that is currently displayed.
+ */
+gchar *gtk_webview_get_body_text(GtkWebView *webview);
+
+/**
+ * Gets the selected text of a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ *
+ * @return The HTML-free text that is currently selected, or NULL if nothing is
+ * currently selected.
+ */
+gchar *gtk_webview_get_selected_text(GtkWebView *webview);
+
+/**
+ * Clear all the formatting on a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ */
+void gtk_webview_clear_formatting(GtkWebView *webview);
+
+/**
+ * Toggles bold at the cursor location or selection in a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ */
+void gtk_webview_toggle_bold(GtkWebView *webview);
+
+/**
+ * Toggles italic at the cursor location or selection in a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ */
+void gtk_webview_toggle_italic(GtkWebView *webview);
+
+/**
+ * Toggles underline at the cursor location or selection in a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ */
+void gtk_webview_toggle_underline(GtkWebView *webview);
+
+/**
+ * Toggles strikethrough at the cursor location or selection in a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ */
+void gtk_webview_toggle_strike(GtkWebView *webview);
+
+/**
+ * Toggles a foreground color at the current location or selection in a
+ * GtkWebView.
+ *
+ * @param webview The GtkWebView
+ * @param color The HTML-style color, or @c NULL or "" to clear the color.
+ *
+ * @return @c TRUE if a color was set, or @c FALSE if it was cleared.
+ */
+gboolean gtk_webview_toggle_forecolor(GtkWebView *webview, const char *color);
+
+/**
+ * Toggles a background color at the current location or selection in a
+ * GtkWebView.
+ *
+ * @param webview The GtkWebView
+ * @param color The HTML-style color, or @c NULL or "" to clear the color.
+ *
+ * @return @c TRUE if a color was set, or @c FALSE if it was cleared.
+ */
+gboolean gtk_webview_toggle_backcolor(GtkWebView *webview, const char *color);
+
+/**
+ * Toggles a font face at the current location or selection in a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ * @param face The font face name, or @c NULL or "" to clear the font.
+ *
+ * @return @c TRUE if a font name was set, or @c FALSE if it was cleared.
+ */
+gboolean gtk_webview_toggle_fontface(GtkWebView *webview, const char *face);
+
+/**
+ * Sets the font size at the current location or selection in a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ * @param size The HTML font size to use.
+ */
+void gtk_webview_font_set_size(GtkWebView *webview, gint size);
+
+/**
+ * Decreases the font size by 1 at the current location or selection in a
+ * GtkWebView.
+ *
+ * @param webview The GtkWebView
+ */
+void gtk_webview_font_shrink(GtkWebView *webview);
+
+/**
+ * Increases the font size by 1 at the current location or selection in a
+ * GtkWebView.
+ *
+ * @param webview The GtkWebView
+ */
+void gtk_webview_font_grow(GtkWebView *webview);
+
+/**
+ * Inserts a horizontal rule at the current location or selection in a
+ * GtkWebView.
+ *
+ * @param webview The GtkWebView
+ */
+void gtk_webview_insert_hr(GtkWebView *webview);
+
+/**
+ * Inserts a link at the current location or selection in a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ * @param url The URL of the link
+ * @param desc The text description of the link. If not supplied, the URL is
+ * used instead.
+ */
+void gtk_webview_insert_link(GtkWebView *webview, const char *url, const char *desc);
+
+/**
+ * Inserts an image at the current location or selection in a GtkWebView.
+ *
+ * @param webview The GtkWebView
+ * @param id The PurpleStoredImage id
+ */
+void gtk_webview_insert_image(GtkWebView *webview, int id);
+
+G_END_DECLS
+
+#endif /* _PIDGIN_WEBVIEW_H_ */
+
diff --git a/pidgin/gtkwebviewtoolbar.c b/pidgin/gtkwebviewtoolbar.c
new file mode 100644
index 0000000000..12f648bddf
--- /dev/null
+++ b/pidgin/gtkwebviewtoolbar.c
@@ -0,0 +1,1617 @@
+/*
+ * @file gtkwebviewtoolbar.c GTK+ WebView Toolbar
+ * @ingroup 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.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * 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 "internal.h"
+#include "pidgin.h"
+
+#include "imgstore.h"
+#include "notify.h"
+#include "prefs.h"
+#include "request.h"
+#include "pidginstock.h"
+#include "util.h"
+#include "debug.h"
+
+#include "gtkdialogs.h"
+#include "gtkwebviewtoolbar.h"
+#include "gtksmiley.h"
+#include "gtkthemes.h"
+#include "gtkutils.h"
+
+#include <gdk/gdkkeysyms.h>
+
+#define GTK_WEBVIEWTOOLBAR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), GTK_TYPE_WEBVIEWTOOLBAR, GtkWebViewToolbarPriv))
+
+/******************************************************************************
+ * Structs
+ *****************************************************************************/
+
+typedef struct _GtkWebViewToolbarPriv {
+ PurpleConversation *active_conv;
+
+ GtkWidget *wide_view;
+ GtkWidget *lean_view;
+
+ GtkWidget *font_label;
+ GtkWidget *font_menu;
+
+ GtkAction *bold;
+ GtkAction *italic;
+ GtkAction *underline;
+ GtkAction *strike;
+
+ GtkAction *larger_size;
+#if 0
+ GtkAction *normal_size;
+#endif
+ GtkAction *smaller_size;
+
+ GtkAction *font;
+ GtkAction *fgcolor;
+ GtkAction *bgcolor;
+
+ GtkAction *clear;
+
+ GtkWidget *insert_menu;
+ GtkAction *image;
+ GtkAction *link;
+ GtkAction *hr;
+
+ GtkAction *smiley;
+ GtkAction *attention;
+
+ GtkWidget *font_dialog;
+ GtkWidget *fgcolor_dialog;
+ GtkWidget *bgcolor_dialog;
+ GtkWidget *link_dialog;
+ GtkWidget *smiley_dialog;
+ GtkWidget *image_dialog;
+
+ char *sml;
+} GtkWebViewToolbarPriv;
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+
+static GtkHBoxClass *parent_class = NULL;
+
+/******************************************************************************
+ * Prototypes
+ *****************************************************************************/
+
+static void
+toggle_action_set_active_block(GtkToggleAction *action, gboolean is_active,
+ GtkWebViewToolbar *toolbar);
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+
+static void
+do_bold(GtkAction *bold, GtkWebViewToolbar *toolbar)
+{
+ g_return_if_fail(toolbar != NULL);
+ gtk_webview_toggle_bold(GTK_WEBVIEW(toolbar->webview));
+ gtk_widget_grab_focus(toolbar->webview);
+}
+
+static void
+do_italic(GtkAction *italic, GtkWebViewToolbar *toolbar)
+{
+ g_return_if_fail(toolbar != NULL);
+ gtk_webview_toggle_italic(GTK_WEBVIEW(toolbar->webview));
+ gtk_widget_grab_focus(toolbar->webview);
+}
+
+static void
+do_underline(GtkAction *underline, GtkWebViewToolbar *toolbar)
+{
+ g_return_if_fail(toolbar != NULL);
+ gtk_webview_toggle_underline(GTK_WEBVIEW(toolbar->webview));
+ gtk_widget_grab_focus(toolbar->webview);
+}
+
+static void
+do_strikethrough(GtkAction *strikethrough, GtkWebViewToolbar *toolbar)
+{
+ g_return_if_fail(toolbar != NULL);
+ gtk_webview_toggle_strike(GTK_WEBVIEW(toolbar->webview));
+ gtk_widget_grab_focus(toolbar->webview);
+}
+
+static void
+do_small(GtkAction *small, GtkWebViewToolbar *toolbar)
+{
+ g_return_if_fail(toolbar != NULL);
+ gtk_webview_font_shrink(GTK_WEBVIEW(toolbar->webview));
+ gtk_widget_grab_focus(toolbar->webview);
+}
+
+static void
+do_big(GtkAction *large, GtkWebViewToolbar *toolbar)
+{
+ g_return_if_fail(toolbar);
+ gtk_webview_font_grow(GTK_WEBVIEW(toolbar->webview));
+ gtk_widget_grab_focus(toolbar->webview);
+}
+
+static gboolean
+destroy_toolbar_font(GtkWidget *widget, GdkEvent *event,
+ GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+
+ if (widget != NULL)
+ gtk_webview_toggle_fontface(GTK_WEBVIEW(toolbar->webview), "");
+
+ if (priv->font_dialog != NULL)
+ {
+ gtk_widget_destroy(priv->font_dialog);
+ priv->font_dialog = NULL;
+ }
+
+ return FALSE;
+}
+
+static void
+realize_toolbar_font(GtkWidget *widget, GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ GtkFontSelection *sel;
+
+ sel = GTK_FONT_SELECTION(GTK_FONT_SELECTION_DIALOG(priv->font_dialog)->fontsel);
+ gtk_widget_hide_all(gtk_widget_get_parent(sel->size_entry));
+ gtk_widget_show_all(sel->family_list);
+ gtk_widget_show(gtk_widget_get_parent(sel->family_list));
+ gtk_widget_show(gtk_widget_get_parent(gtk_widget_get_parent(sel->family_list)));
+}
+
+static void
+cancel_toolbar_font(GtkWidget *widget, GtkWebViewToolbar *toolbar)
+{
+ destroy_toolbar_font(widget, NULL, toolbar);
+}
+
+static void
+apply_font(GtkWidget *widget, GtkWebViewToolbar *toolbar)
+{
+ /* this could be expanded to include font size, weight, etc.
+ but for now only works with font face */
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ GtkFontSelectionDialog *fontsel = GTK_FONT_SELECTION_DIALOG(priv->font_dialog);
+ gchar *fontname = gtk_font_selection_dialog_get_font_name(fontsel);
+
+ if (fontname) {
+ const gchar *family_name = NULL;
+ PangoFontDescription *desc = NULL;
+
+ desc = pango_font_description_from_string(fontname);
+ family_name = pango_font_description_get_family(desc);
+
+ if (family_name) {
+ gtk_webview_toggle_fontface(GTK_WEBVIEW(toolbar->webview),
+ family_name);
+ }
+
+ pango_font_description_free(desc);
+ g_free(fontname);
+ }
+
+ cancel_toolbar_font(NULL, toolbar);
+}
+
+static void
+toggle_font(GtkAction *font, GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+
+ if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(font))) {
+ char *fontname = gtk_webview_get_current_fontface(GTK_WEBVIEW(toolbar->webview));
+
+ if (!priv->font_dialog) {
+ priv->font_dialog = gtk_font_selection_dialog_new(_("Select Font"));
+
+ if (fontname) {
+ char *fonttif = g_strdup_printf("%s 12", fontname);
+ gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(priv->font_dialog),
+ fonttif);
+ g_free(fonttif);
+ } else {
+ gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(priv->font_dialog),
+ DEFAULT_FONT_FACE);
+ }
+
+ g_signal_connect(G_OBJECT(priv->font_dialog), "delete_event",
+ G_CALLBACK(destroy_toolbar_font), toolbar);
+ g_signal_connect(G_OBJECT(GTK_FONT_SELECTION_DIALOG(priv->font_dialog)->ok_button), "clicked",
+ G_CALLBACK(apply_font), toolbar);
+ g_signal_connect(G_OBJECT(GTK_FONT_SELECTION_DIALOG(priv->font_dialog)->cancel_button), "clicked",
+ G_CALLBACK(cancel_toolbar_font), toolbar);
+ g_signal_connect_after(G_OBJECT(priv->font_dialog), "realize",
+ G_CALLBACK(realize_toolbar_font), toolbar);
+ }
+
+ gtk_window_present(GTK_WINDOW(priv->font_dialog));
+
+ g_free(fontname);
+ } else {
+ cancel_toolbar_font(GTK_WIDGET(toolbar), toolbar);
+ }
+
+ gtk_widget_grab_focus(toolbar->webview);
+}
+
+static gboolean
+destroy_toolbar_fgcolor(GtkWidget *widget, GdkEvent *event,
+ GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+
+ if (widget != NULL)
+ gtk_webview_toggle_forecolor(GTK_WEBVIEW(toolbar->webview), "");
+
+ if (priv->fgcolor_dialog != NULL)
+ {
+ gtk_widget_destroy(priv->fgcolor_dialog);
+ priv->fgcolor_dialog = NULL;
+ }
+
+ return FALSE;
+}
+
+static void
+cancel_toolbar_fgcolor(GtkWidget *widget, GtkWebViewToolbar *toolbar)
+{
+ destroy_toolbar_fgcolor(widget, NULL, toolbar);
+}
+
+static void
+do_fgcolor(GtkWidget *widget, GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ GtkColorSelectionDialog *dialog;
+ GtkColorSelection *colorsel;
+ GdkColor text_color;
+ char *open_tag;
+
+ dialog = GTK_COLOR_SELECTION_DIALOG(priv->fgcolor_dialog);
+ colorsel = GTK_COLOR_SELECTION(dialog->colorsel);
+
+ open_tag = g_malloc(30);
+ gtk_color_selection_get_current_color(colorsel, &text_color);
+ g_snprintf(open_tag, 23, "#%02X%02X%02X",
+ text_color.red / 256,
+ text_color.green / 256,
+ text_color.blue / 256);
+ gtk_webview_toggle_forecolor(GTK_WEBVIEW(toolbar->webview), open_tag);
+ g_free(open_tag);
+
+ cancel_toolbar_fgcolor(NULL, toolbar);
+}
+
+static void
+toggle_fg_color(GtkAction *color, GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+
+ if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(color))) {
+ GtkWidget *colorsel;
+ GdkColor fgcolor;
+ char *color = gtk_webview_get_current_forecolor(GTK_WEBVIEW(toolbar->webview));
+
+ if (!priv->fgcolor_dialog) {
+ priv->fgcolor_dialog = gtk_color_selection_dialog_new(_("Select Text Color"));
+ colorsel = GTK_COLOR_SELECTION_DIALOG(priv->fgcolor_dialog)->colorsel;
+ if (color) {
+ gdk_color_parse(color, &fgcolor);
+ gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(colorsel), &fgcolor);
+ }
+
+ g_signal_connect(G_OBJECT(priv->fgcolor_dialog), "delete_event",
+ G_CALLBACK(destroy_toolbar_fgcolor), toolbar);
+ g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(priv->fgcolor_dialog)->ok_button), "clicked",
+ G_CALLBACK(do_fgcolor), toolbar);
+ g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(priv->fgcolor_dialog)->cancel_button), "clicked",
+ G_CALLBACK(cancel_toolbar_fgcolor), toolbar);
+ }
+
+ gtk_window_present(GTK_WINDOW(priv->fgcolor_dialog));
+
+ g_free(color);
+ } else {
+ cancel_toolbar_fgcolor(GTK_WIDGET(toolbar), toolbar);
+ }
+
+ gtk_widget_grab_focus(toolbar->webview);
+}
+
+static gboolean
+destroy_toolbar_bgcolor(GtkWidget *widget, GdkEvent *event,
+ GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ if (widget != NULL) {
+ gtk_webview_toggle_backcolor(GTK_WEBVIEW(toolbar->webview), "");
+ }
+
+ if (priv->bgcolor_dialog != NULL)
+ {
+ gtk_widget_destroy(priv->bgcolor_dialog);
+ priv->bgcolor_dialog = NULL;
+ }
+
+ return FALSE;
+}
+
+static void
+cancel_toolbar_bgcolor(GtkWidget *widget, GtkWebViewToolbar *toolbar)
+{
+ destroy_toolbar_bgcolor(widget, NULL, toolbar);
+}
+
+static void
+do_bgcolor(GtkWidget *widget, GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ GtkColorSelectionDialog *dialog;
+ GtkColorSelection *colorsel;
+ GdkColor text_color;
+ char *open_tag;
+
+ dialog = GTK_COLOR_SELECTION_DIALOG(priv->bgcolor_dialog);
+ colorsel = GTK_COLOR_SELECTION(dialog->colorsel);
+
+ open_tag = g_malloc(30);
+ gtk_color_selection_get_current_color(colorsel, &text_color);
+ g_snprintf(open_tag, 23, "#%02X%02X%02X",
+ text_color.red / 256,
+ text_color.green / 256,
+ text_color.blue / 256);
+ gtk_webview_toggle_backcolor(GTK_WEBVIEW(toolbar->webview), open_tag);
+ g_free(open_tag);
+
+ cancel_toolbar_bgcolor(NULL, toolbar);
+}
+
+static void
+toggle_bg_color(GtkAction *color, GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+
+ if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(color))) {
+ GtkWidget *colorsel;
+ GdkColor bgcolor;
+ char *color = gtk_webview_get_current_backcolor(GTK_WEBVIEW(toolbar->webview));
+
+ if (!priv->bgcolor_dialog) {
+ priv->bgcolor_dialog = gtk_color_selection_dialog_new(_("Select Background Color"));
+ colorsel = GTK_COLOR_SELECTION_DIALOG(priv->bgcolor_dialog)->colorsel;
+ if (color) {
+ gdk_color_parse(color, &bgcolor);
+ gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(colorsel), &bgcolor);
+ }
+
+ g_signal_connect(G_OBJECT(priv->bgcolor_dialog), "delete_event",
+ G_CALLBACK(destroy_toolbar_bgcolor), toolbar);
+ g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(priv->bgcolor_dialog)->ok_button), "clicked",
+ G_CALLBACK(do_bgcolor), toolbar);
+ g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(priv->bgcolor_dialog)->cancel_button), "clicked",
+ G_CALLBACK(cancel_toolbar_bgcolor), toolbar);
+ }
+
+ gtk_window_present(GTK_WINDOW(priv->bgcolor_dialog));
+
+ g_free(color);
+ } else {
+ cancel_toolbar_bgcolor(GTK_WIDGET(toolbar), toolbar);
+ }
+
+ gtk_widget_grab_focus(toolbar->webview);
+}
+
+static void
+clear_formatting_cb(GtkAction *clear, GtkWebViewToolbar *toolbar)
+{
+ gtk_webview_clear_formatting(GTK_WEBVIEW(toolbar->webview));
+ gtk_widget_grab_focus(toolbar->webview);
+}
+
+static void
+cancel_link_cb(GtkWebViewToolbar *toolbar, PurpleRequestFields *fields)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(priv->link), FALSE);
+
+ priv->link_dialog = NULL;
+}
+
+static void
+close_link_dialog(GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ if (priv->link_dialog != NULL)
+ {
+ purple_request_close(PURPLE_REQUEST_FIELDS, priv->link_dialog);
+ priv->link_dialog = NULL;
+ }
+}
+
+static void
+do_insert_link_cb(GtkWebViewToolbar *toolbar, PurpleRequestFields *fields)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ const char *url, *description;
+
+ url = purple_request_fields_get_string(fields, "url");
+ if (gtk_webview_get_format_functions(GTK_WEBVIEW(toolbar->webview)) & GTK_WEBVIEW_LINKDESC)
+ description = purple_request_fields_get_string(fields, "description");
+ else
+ description = NULL;
+
+ gtk_webview_insert_link(GTK_WEBVIEW(toolbar->webview), url, description);
+
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(priv->link), FALSE);
+
+ priv->link_dialog = NULL;
+}
+
+static void
+insert_link_cb(GtkAction *action, GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+
+ if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(priv->link))) {
+ PurpleRequestFields *fields;
+ PurpleRequestFieldGroup *group;
+ PurpleRequestField *field;
+ char *msg;
+ char *desc = NULL;
+
+ fields = purple_request_fields_new();
+
+ group = purple_request_field_group_new(NULL);
+ purple_request_fields_add_group(fields, group);
+
+ field = purple_request_field_string_new("url", _("_URL"), NULL, FALSE);
+ purple_request_field_set_required(field, TRUE);
+ purple_request_field_group_add_field(group, field);
+
+ if (gtk_webview_get_format_functions(GTK_WEBVIEW(toolbar->webview)) & GTK_WEBVIEW_LINKDESC) {
+ desc = gtk_webview_get_selected_text(GTK_WEBVIEW(toolbar->webview));
+ field = purple_request_field_string_new("description", _("_Description"),
+ desc, FALSE);
+ purple_request_field_group_add_field(group, field);
+ msg = g_strdup(_("Please enter the URL and description of the "
+ "link that you want to insert. The description "
+ "is optional."));
+ } else {
+ msg = g_strdup(_("Please enter the URL of the "
+ "link that you want to insert."));
+ }
+
+ priv->link_dialog =
+ purple_request_fields(toolbar, _("Insert Link"),
+ NULL,
+ msg,
+ fields,
+ _("_Insert"), G_CALLBACK(do_insert_link_cb),
+ _("Cancel"), G_CALLBACK(cancel_link_cb),
+ NULL, NULL, NULL,
+ toolbar);
+ g_free(msg);
+ g_free(desc);
+ } else {
+ close_link_dialog(toolbar);
+ }
+
+ gtk_widget_grab_focus(toolbar->webview);
+}
+
+static void
+insert_hr_cb(GtkAction *action, GtkWebViewToolbar *toolbar)
+{
+ gtk_webview_insert_hr(GTK_WEBVIEW(toolbar->webview));
+}
+
+static void
+do_insert_image_cb(GtkWidget *widget, int response, GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ gchar *filename = NULL, *name, *buf;
+ char *filedata;
+ size_t size;
+ GError *error = NULL;
+ int id;
+
+ if (response == GTK_RESPONSE_ACCEPT)
+ filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget));
+
+ /* The following triggers a callback that closes the widget */
+ gtk_action_activate(priv->image);
+
+ if (filename == NULL)
+ return;
+
+ if (!g_file_get_contents(filename, &filedata, &size, &error)) {
+ purple_notify_error(NULL, NULL, error->message, NULL);
+
+ g_error_free(error);
+ g_free(filename);
+
+ return;
+ }
+
+ name = strrchr(filename, G_DIR_SEPARATOR) + 1;
+
+ id = purple_imgstore_add_with_id(filedata, size, name);
+
+ if (id == 0) {
+ buf = g_strdup_printf(_("Failed to store image: %s\n"), filename);
+ purple_notify_error(NULL, NULL, buf, NULL);
+
+ g_free(buf);
+ g_free(filename);
+
+ return;
+ }
+
+ g_free(filename);
+
+ gtk_webview_insert_image(GTK_WEBVIEW(toolbar->webview), id);
+ purple_imgstore_unref_by_id(id);
+}
+
+static void
+insert_image_cb(GtkAction *action, GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ GtkWidget *window;
+
+ if (!priv->image_dialog) {
+ window = gtk_file_chooser_dialog_new(_("Insert Image"), NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_dialog_set_default_response(GTK_DIALOG(window), GTK_RESPONSE_ACCEPT);
+ g_signal_connect(G_OBJECT(window), "response",
+ G_CALLBACK(do_insert_image_cb), toolbar);
+
+ gtk_widget_show(window);
+ priv->image_dialog = window;
+ } else {
+ gtk_widget_destroy(priv->image_dialog);
+ priv->image_dialog = NULL;
+ }
+
+ gtk_widget_grab_focus(toolbar->webview);
+}
+
+#if 0
+static void
+destroy_smiley_dialog(GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ if (priv->smiley_dialog != NULL)
+ {
+ gtk_widget_destroy(priv->smiley_dialog);
+ priv->smiley_dialog = NULL;
+ }
+}
+
+static gboolean
+close_smiley_dialog(GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->smiley), FALSE);
+ return FALSE;
+}
+
+
+static void
+insert_smiley_text(GtkWidget *widget, GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ char *smiley_text, *escaped_smiley;
+
+ smiley_text = g_object_get_data(G_OBJECT(widget), "smiley_text");
+ escaped_smiley = g_markup_escape_text(smiley_text, -1);
+
+ gtk_webview_insert_smiley(GTK_WEBVIEW(toolbar->webview),
+ GTK_WEBVIEW(toolbar->webview)->protocol_name,
+ escaped_smiley);
+
+ g_free(escaped_smiley);
+
+ close_smiley_dialog(toolbar);
+}
+
+/* smiley buttons list */
+struct smiley_button_list {
+ int width, height;
+ GtkWidget *button;
+ const GtkIMHtmlSmiley *smiley;
+ struct smiley_button_list *next;
+};
+
+static struct smiley_button_list *
+sort_smileys(struct smiley_button_list *ls, GtkWebViewToolbar *toolbar,
+ int *width, const GtkIMHtmlSmiley *smiley)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ GtkWidget *image;
+ GtkWidget *button;
+ GtkRequisition size;
+ struct smiley_button_list *cur;
+ struct smiley_button_list *it, *it_last;
+ const gchar *filename = smiley->file;
+ gchar *face = smiley->smile;
+ PurpleSmiley *psmiley = NULL;
+ gboolean supports_custom = (gtk_webview_get_format_functions(GTK_WEBVIEW(toolbar->webview)) & GTK_WEBVIEW_CUSTOM_SMILEY);
+
+ cur = g_new0(struct smiley_button_list, 1);
+ it = ls;
+ it_last = ls; /* list iterators*/
+ image = gtk_image_new_from_file(filename);
+
+ gtk_widget_size_request(image, &size);
+
+ if (size.width > 24 &&
+ smiley->flags & GTK_WEBVIEW_SMILEY_CUSTOM) { /* This is a custom smiley, let's scale it */
+ GdkPixbuf *pixbuf = NULL;
+ GtkImageType type;
+
+ type = gtk_image_get_storage_type(GTK_IMAGE(image));
+
+ if (type == GTK_IMAGE_PIXBUF) {
+ pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(image));
+ } else if (type == GTK_IMAGE_ANIMATION) {
+ GdkPixbufAnimation *animation;
+
+ animation = gtk_image_get_animation(GTK_IMAGE(image));
+
+ pixbuf = gdk_pixbuf_animation_get_static_image(animation);
+ }
+
+ if (pixbuf != NULL) {
+ GdkPixbuf *resized;
+ resized = gdk_pixbuf_scale_simple(pixbuf, 24, 24,
+ GDK_INTERP_HYPER);
+
+ gtk_image_set_from_pixbuf(GTK_IMAGE(image), resized); /* This unrefs pixbuf */
+ gtk_widget_size_request(image, &size);
+ g_object_unref(G_OBJECT(resized));
+ }
+ }
+
+ (*width) += size.width;
+
+ button = gtk_button_new();
+ gtk_container_add(GTK_CONTAINER(button), image);
+
+ g_object_set_data(G_OBJECT(button), "smiley_text", face);
+ g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(insert_smiley_text), toolbar);
+
+ gtk_widget_set_tooltip_text(button, face);
+
+ /* these look really weird with borders */
+ gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
+
+ psmiley = purple_smileys_find_by_shortcut(smiley->smile);
+ /* If this is a "non-custom" smiley, check to see if its shortcut is
+ "shadowed" by any custom smiley. This can only happen if the connection
+ is custom smiley-enabled */
+ if (supports_custom && psmiley && !(smiley->flags & GTK_WEBVIEW_SMILEY_CUSTOM)) {
+ gchar tip[128];
+ g_snprintf(tip, sizeof(tip),
+ _("This smiley is disabled because a custom smiley exists for this shortcut:\n %s"),
+ face);
+ gtk_widget_set_tooltip_text(button, tip);
+ gtk_widget_set_sensitive(button, FALSE);
+ } else if (psmiley) {
+ /* Remove the button if the smiley is destroyed */
+ g_signal_connect_object(G_OBJECT(psmiley), "destroy", G_CALLBACK(gtk_widget_destroy),
+ button, G_CONNECT_SWAPPED);
+ }
+
+ /* set current element to add */
+ cur->height = size.height;
+ cur->width = size.width;
+ cur->button = button;
+ cur->smiley = smiley;
+ cur->next = ls;
+
+ /* check where to insert by height */
+ if (ls == NULL)
+ return cur;
+ while (it != NULL) {
+ it_last = it;
+ it = it->next;
+ }
+ cur->next = it;
+ it_last->next = cur;
+ return ls;
+}
+
+static gboolean
+smiley_is_unique(GSList *list, GtkIMHtmlSmiley *smiley)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ while (list) {
+ GtkIMHtmlSmiley *cur = (GtkIMHtmlSmiley *) list->data;
+ if (!strcmp(cur->file, smiley->file))
+ return FALSE;
+ list = list->next;
+ }
+ return TRUE;
+}
+
+static gboolean
+smiley_dialog_input_cb(GtkWidget *dialog, GdkEvent *event,
+ GtkWebViewToolbar *toolbar)
+{
+ if ((event->type == GDK_KEY_PRESS && event->key.keyval == GDK_Escape) ||
+ (event->type == GDK_BUTTON_PRESS && event->button.button == 1))
+ {
+ close_smiley_dialog(toolbar);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+add_smiley_list(GtkWidget *container, struct smiley_button_list *list,
+ int max_width, gboolean custom)
+{
+ GtkWidget *line;
+ int line_width = 0;
+
+ if (!list)
+ return;
+
+ line = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(container), line, FALSE, FALSE, 0);
+ for (; list; list = list->next) {
+ if (custom != !!(list->smiley->flags & GTK_WEBVIEW_SMILEY_CUSTOM))
+ continue;
+ gtk_box_pack_start(GTK_BOX(line), list->button, FALSE, FALSE, 0);
+ gtk_widget_show(list->button);
+ line_width += list->width;
+ if (line_width >= max_width) {
+ if (list->next) {
+ line = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(container), line, FALSE, FALSE, 0);
+ }
+ line_width = 0;
+ }
+ }
+}
+#endif
+
+static void
+insert_smiley_cb(GtkAction *smiley, GtkWebViewToolbar *toolbar)
+{
+#if 0
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ GtkWidget *dialog, *vbox;
+ GtkWidget *smiley_table = NULL;
+ GSList *smileys, *unique_smileys = NULL;
+ const GSList *custom_smileys = NULL;
+ gboolean supports_custom = FALSE;
+ GtkRequisition req;
+ GtkWidget *scrolled, *viewport;
+
+ if (!gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(smiley))) {
+ destroy_smiley_dialog(toolbar);
+ gtk_widget_grab_focus(toolbar->webview);
+ return;
+ }
+
+ if (priv->sml)
+ smileys = pidgin_themes_get_proto_smileys(priv->sml);
+ else
+ smileys = pidgin_themes_get_proto_smileys(NULL);
+
+ /* Note: prepend smileys to list to avoid O(n^2) overhead when there is
+ a large number of smileys... need to revers the list after for the dialog
+ work... */
+ while(smileys) {
+ GtkIMHtmlSmiley *smiley = (GtkIMHtmlSmiley *) smileys->data;
+ if(!smiley->hidden) {
+ if(smiley_is_unique(unique_smileys, smiley)) {
+ unique_smileys = g_slist_prepend(unique_smileys, smiley);
+ }
+ }
+ smileys = smileys->next;
+ }
+ supports_custom = (gtk_webview_get_format_functions(GTK_WEBVIEW(toolbar->webview)) & GTK_WEBVIEW_CUSTOM_SMILEY);
+ if (toolbar->webview && supports_custom) {
+ const GSList *iterator = NULL;
+ custom_smileys = pidgin_smileys_get_all();
+
+ for (iterator = custom_smileys ; iterator ;
+ iterator = g_slist_next(iterator)) {
+ GtkIMHtmlSmiley *smiley = (GtkIMHtmlSmiley *) iterator->data;
+ unique_smileys = g_slist_prepend(unique_smileys, smiley);
+ }
+ }
+
+ /* we need to reverse the list to get the smileys in the correct order */
+ unique_smileys = g_slist_reverse(unique_smileys);
+
+ dialog = pidgin_create_dialog(_("Smile!"), 0, "smiley_dialog", FALSE);
+ gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
+ vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(dialog), FALSE, 0);
+
+ if (unique_smileys != NULL) {
+ struct smiley_button_list *ls;
+ int max_line_width, num_lines, button_width = 0;
+
+ /* We use hboxes packed in a vbox */
+ ls = NULL;
+ max_line_width = 0;
+ num_lines = floor(sqrt(g_slist_length(unique_smileys)));
+ smiley_table = gtk_vbox_new(FALSE, 0);
+
+ if (supports_custom) {
+ GtkWidget *manage = gtk_button_new_with_mnemonic(_("_Manage custom smileys"));
+ GtkRequisition req;
+ g_signal_connect(G_OBJECT(manage), "clicked",
+ G_CALLBACK(pidgin_smiley_manager_show), NULL);
+ g_signal_connect_swapped(G_OBJECT(manage), "clicked",
+ G_CALLBACK(gtk_widget_destroy), dialog);
+ gtk_box_pack_end(GTK_BOX(vbox), manage, FALSE, TRUE, 0);
+ gtk_widget_size_request(manage, &req);
+ button_width = req.width;
+ }
+
+ /* create list of smileys sorted by height */
+ while (unique_smileys) {
+ GtkIMHtmlSmiley *smiley = (GtkIMHtmlSmiley *) unique_smileys->data;
+ if (!smiley->hidden) {
+ ls = sort_smileys(ls, toolbar, &max_line_width, smiley);
+ }
+ unique_smileys = g_slist_delete_link(unique_smileys, unique_smileys);
+ }
+ /* The window will be at least as wide as the 'Manage ..' button */
+ max_line_width = MAX(button_width, max_line_width / num_lines);
+
+ /* pack buttons of the list */
+ add_smiley_list(smiley_table, ls, max_line_width, FALSE);
+ if (supports_custom) {
+ gtk_box_pack_start(GTK_BOX(smiley_table), gtk_hseparator_new(), TRUE, FALSE, 0);
+ add_smiley_list(smiley_table, ls, max_line_width, TRUE);
+ }
+ while (ls) {
+ struct smiley_button_list *tmp = ls->next;
+ g_free(ls);
+ ls = tmp;
+ }
+
+ gtk_widget_add_events(dialog, GDK_KEY_PRESS_MASK);
+ }
+ else {
+ smiley_table = gtk_label_new(_("This theme has no available smileys."));
+ gtk_widget_add_events(dialog, GDK_KEY_PRESS_MASK | GDK_BUTTON_PRESS_MASK);
+ g_signal_connect(G_OBJECT(dialog), "button-press-event", (GCallback)smiley_dialog_input_cb, toolbar);
+ }
+
+
+ scrolled = pidgin_make_scrollable(smiley_table, GTK_POLICY_NEVER, GTK_POLICY_NEVER, GTK_SHADOW_NONE, -1, -1);
+ gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0);
+ gtk_widget_show(smiley_table);
+
+ viewport = gtk_widget_get_parent(smiley_table);
+ gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
+
+ /* connect signals */
+ g_signal_connect_swapped(G_OBJECT(dialog), "destroy", G_CALLBACK(close_smiley_dialog), toolbar);
+ g_signal_connect(G_OBJECT(dialog), "key-press-event", G_CALLBACK(smiley_dialog_input_cb), toolbar);
+
+ gtk_window_set_transient_for(GTK_WINDOW(dialog),
+ GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(toolbar))));
+
+ /* show everything */
+ gtk_widget_show_all(dialog);
+
+ gtk_widget_size_request(viewport, &req);
+ gtk_widget_set_size_request(scrolled, MIN(300, req.width), MIN(290, req.height));
+
+ /* The window has to be made resizable, and the scrollbars in the scrolled window
+ * enabled only after setting the desired size of the window. If we do either of
+ * these tasks before now, GTK+ miscalculates the required size, and erronously
+ * makes one or both scrollbars visible (sometimes).
+ * I too think this hack is gross. But I couldn't find a better way -- sadrul */
+ gtk_window_set_resizable(GTK_WINDOW(dialog), TRUE);
+ g_object_set(G_OBJECT(scrolled),
+ "hscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ NULL);
+
+#ifdef _WIN32
+ winpidgin_ensure_onscreen(dialog);
+#endif
+
+ priv->smiley_dialog = dialog;
+
+ gtk_widget_grab_focus(toolbar->webview);
+#endif
+}
+
+static void
+send_attention_cb(GtkAction *attention, GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ PurpleConversation *conv = priv->active_conv;
+ const gchar *who = purple_conversation_get_name(conv);
+ PurpleConnection *gc = purple_conversation_get_connection(conv);
+
+ purple_prpl_send_attention(gc, who, 0);
+ gtk_widget_grab_focus(toolbar->webview);
+}
+
+static void
+update_buttons_cb(GtkWebView *webview, GtkWebViewButtons buttons,
+ GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+
+ gtk_action_set_sensitive(priv->bold, buttons & GTK_WEBVIEW_BOLD);
+ gtk_action_set_sensitive(priv->italic, buttons & GTK_WEBVIEW_ITALIC);
+ gtk_action_set_sensitive(priv->underline, buttons & GTK_WEBVIEW_UNDERLINE);
+ gtk_action_set_sensitive(priv->strike, buttons & GTK_WEBVIEW_STRIKE);
+
+ gtk_action_set_sensitive(priv->larger_size, buttons & GTK_WEBVIEW_GROW);
+ gtk_action_set_sensitive(priv->smaller_size, buttons & GTK_WEBVIEW_SHRINK);
+
+ gtk_action_set_sensitive(priv->font, buttons & GTK_WEBVIEW_FACE);
+ gtk_action_set_sensitive(priv->fgcolor, buttons & GTK_WEBVIEW_FORECOLOR);
+ gtk_action_set_sensitive(priv->bgcolor, buttons & GTK_WEBVIEW_BACKCOLOR);
+
+ gtk_action_set_sensitive(priv->clear,
+ (buttons & GTK_WEBVIEW_BOLD ||
+ buttons & GTK_WEBVIEW_ITALIC ||
+ buttons & GTK_WEBVIEW_UNDERLINE ||
+ buttons & GTK_WEBVIEW_STRIKE ||
+ buttons & GTK_WEBVIEW_GROW ||
+ buttons & GTK_WEBVIEW_SHRINK ||
+ buttons & GTK_WEBVIEW_FACE ||
+ buttons & GTK_WEBVIEW_FORECOLOR ||
+ buttons & GTK_WEBVIEW_BACKCOLOR));
+
+ gtk_action_set_sensitive(priv->image, buttons & GTK_WEBVIEW_IMAGE);
+ gtk_action_set_sensitive(priv->link, buttons & GTK_WEBVIEW_LINK);
+ gtk_action_set_sensitive(priv->smiley, buttons & GTK_WEBVIEW_SMILEY);
+}
+
+/* we call this when we want to _set_active the toggle button, it'll
+ * block the callback that's connected to the button so we don't have to
+ * do the double toggling hack
+ */
+static void
+toggle_action_set_active_block(GtkToggleAction *action, gboolean is_active,
+ GtkWebViewToolbar *toolbar)
+{
+ GObject *object;
+ g_return_if_fail(toolbar);
+
+ object = g_object_ref(action);
+ g_signal_handlers_block_matched(object, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, toolbar);
+ gtk_toggle_action_set_active(action, is_active);
+ g_signal_handlers_unblock_matched(object, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, toolbar);
+ g_object_unref(object);
+}
+
+static void
+update_buttons(GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ gboolean bold, italic, underline, strike;
+ char *tmp;
+ char *label;
+
+ label = g_strdup(_("_Font"));
+
+ gtk_webview_get_current_format(GTK_WEBVIEW(toolbar->webview),
+ &bold, &italic, &underline, &strike);
+
+ if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(priv->bold)) != bold)
+ toggle_action_set_active_block(GTK_TOGGLE_ACTION(priv->bold), bold,
+ toolbar);
+ if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(priv->italic)) != italic)
+ toggle_action_set_active_block(GTK_TOGGLE_ACTION(priv->italic), italic,
+ toolbar);
+ if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(priv->underline)) != underline)
+ toggle_action_set_active_block(GTK_TOGGLE_ACTION(priv->underline),
+ underline, toolbar);
+ if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(priv->strike)) != strike)
+ toggle_action_set_active_block(GTK_TOGGLE_ACTION(priv->strike), strike,
+ toolbar);
+
+ if (bold) {
+ gchar *markup = g_strdup_printf("<b>%s</b>", label);
+ g_free(label);
+ label = markup;
+ }
+ if (italic) {
+ gchar *markup = g_strdup_printf("<i>%s</i>", label);
+ g_free(label);
+ label = markup;
+ }
+ if (underline) {
+ gchar *markup = g_strdup_printf("<u>%s</u>", label);
+ g_free(label);
+ label = markup;
+ }
+ if (strike) {
+ gchar *markup = g_strdup_printf("<s>%s</s>", label);
+ g_free(label);
+ label = markup;
+ }
+
+ tmp = gtk_webview_get_current_fontface(GTK_WEBVIEW(toolbar->webview));
+ toggle_action_set_active_block(GTK_TOGGLE_ACTION(priv->font),
+ (tmp && *tmp), toolbar);
+ if (tmp && *tmp) {
+ gchar *markup = g_strdup_printf("<span font_desc=\"%s\">%s</span>",
+ tmp, label);
+ g_free(label);
+ label = markup;
+ }
+ g_free(tmp);
+
+ tmp = gtk_webview_get_current_forecolor(GTK_WEBVIEW(toolbar->webview));
+ toggle_action_set_active_block(GTK_TOGGLE_ACTION(priv->fgcolor),
+ (tmp && *tmp), toolbar);
+ if (tmp && *tmp) {
+ gchar *markup = g_strdup_printf("<span foreground=\"%s\">%s</span>",
+ tmp, label);
+ g_free(label);
+ label = markup;
+ }
+ g_free(tmp);
+
+ tmp = gtk_webview_get_current_backcolor(GTK_WEBVIEW(toolbar->webview));
+ toggle_action_set_active_block(GTK_TOGGLE_ACTION(priv->bgcolor),
+ (tmp && *tmp), toolbar);
+ if (tmp && *tmp) {
+ gchar *markup = g_strdup_printf("<span background=\"%s\">%s</span>",
+ tmp, label);
+ g_free(label);
+ label = markup;
+ }
+ g_free(tmp);
+
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(priv->font_label), label);
+}
+
+static void
+toggle_button_cb(GtkWebView *webview, GtkWebViewButtons buttons,
+ GtkWebViewToolbar *toolbar)
+{
+ update_buttons(toolbar);
+}
+
+static void
+update_format_cb(GtkWebView *webview, GtkWebViewToolbar *toolbar)
+{
+ update_buttons(toolbar);
+}
+
+static void
+mark_set_cb(GtkWebView *webview, GtkWebViewToolbar *toolbar)
+{
+ update_buttons(toolbar);
+}
+
+/* This comes from gtkmenutoolbutton.c from gtk+
+ * Copyright (C) 2003 Ricardo Fernandez Pascual
+ * Copyright (C) 2004 Paolo Borelli
+ */
+static void
+menu_position_func(GtkMenu *menu,
+ int *x,
+ int *y,
+ gboolean *push_in,
+ gpointer data)
+{
+ GtkWidget *widget = GTK_WIDGET(data);
+ GtkRequisition menu_req;
+ gint ythickness = widget->style->ythickness;
+ int savy;
+
+ gtk_widget_size_request(GTK_WIDGET(menu), &menu_req);
+ gdk_window_get_origin(widget->window, x, y);
+ *x += widget->allocation.x;
+ *y += widget->allocation.y + widget->allocation.height;
+ savy = *y;
+
+ pidgin_menu_position_func_helper(menu, x, y, push_in, data);
+
+ if (savy > *y + ythickness + 1)
+ *y -= widget->allocation.height;
+}
+
+static void
+pidgin_menu_clicked(GtkWidget *button, GtkMenu *menu)
+{
+ if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(button))) {
+ gtk_widget_show_all(GTK_WIDGET(menu));
+ gtk_menu_popup(menu, NULL, NULL, menu_position_func, button, 0, gtk_get_current_event_time());
+ }
+}
+
+static void
+pidgin_menu_deactivate(GtkWidget *menu, GtkToggleButton *button)
+{
+ gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(button), FALSE);
+}
+
+static void
+switch_toolbar_view(GtkWidget *item, GtkWebViewToolbar *toolbar)
+{
+ purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/toolbar/wide",
+ !purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/toolbar/wide"));
+}
+
+static gboolean
+gtk_webviewtoolbar_popup_menu(GtkWidget *widget, GdkEventButton *event,
+ GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ GtkWidget *menu;
+ GtkWidget *item;
+ gboolean wide;
+
+ if (event->button != 3)
+ return FALSE;
+
+ wide = gtk_widget_get_visible(priv->wide_view);
+
+ menu = gtk_menu_new();
+ item = gtk_menu_item_new_with_mnemonic(wide ? _("Group Items") : _("Ungroup Items"));
+ g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(switch_toolbar_view), toolbar);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ gtk_widget_show(item);
+
+ gtk_menu_popup(GTK_MENU(menu), NULL, NULL, pidgin_menu_position_func_helper,
+ widget, event->button, event->time);
+
+ return TRUE;
+}
+
+static void
+enable_markup(GtkWidget *widget, gpointer null)
+{
+ GtkWidget *label;
+ label = gtk_bin_get_child(GTK_BIN(widget));
+ if (GTK_IS_LABEL(label))
+ g_object_set(G_OBJECT(label), "use-markup", TRUE, NULL);
+}
+
+static void
+webviewtoolbar_view_pref_changed(const char *name, PurplePrefType type,
+ gconstpointer value, gpointer toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ if (value) {
+ gtk_widget_hide_all(priv->lean_view);
+ gtk_widget_show_all(priv->wide_view);
+ } else {
+ gtk_widget_hide_all(priv->wide_view);
+ gtk_widget_show_all(priv->lean_view);
+ }
+}
+
+/******************************************************************************
+ * GObject stuff
+ *****************************************************************************/
+
+static void
+gtk_webviewtoolbar_finalize(GObject *object)
+{
+ GtkWebViewToolbar *toolbar = GTK_WEBVIEWTOOLBAR(object);
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+
+ if (priv->image_dialog != NULL)
+ {
+ gtk_widget_destroy(priv->image_dialog);
+ priv->image_dialog = NULL;
+ }
+
+ destroy_toolbar_font(NULL, NULL, toolbar);
+ if (priv->smiley_dialog != NULL) {
+#if 0
+ g_signal_handlers_disconnect_by_func(G_OBJECT(priv->smiley_dialog), close_smiley_dialog, toolbar);
+ destroy_smiley_dialog(toolbar);
+#endif
+ }
+ destroy_toolbar_bgcolor(NULL, NULL, toolbar);
+ destroy_toolbar_fgcolor(NULL, NULL, toolbar);
+ close_link_dialog(toolbar);
+ if (toolbar->webview) {
+ g_signal_handlers_disconnect_matched(toolbar->webview,
+ G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL,
+ toolbar);
+#if 0
+ g_signal_handlers_disconnect_matched(GTK_WEBVIEW(toolbar->webview)->text_buffer,
+ G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL,
+ toolbar);
+#endif
+ }
+
+ g_free(priv->sml);
+
+ if (priv->font_menu)
+ gtk_widget_destroy(priv->font_menu);
+ if (priv->insert_menu)
+ gtk_widget_destroy(priv->insert_menu);
+
+ purple_prefs_disconnect_by_handle(object);
+
+ G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+static void
+gtk_webviewtoolbar_class_init(GtkWebViewToolbarClass *class)
+{
+ GObjectClass *gobject_class;
+ gobject_class = (GObjectClass *)class;
+ parent_class = g_type_class_ref(GTK_TYPE_HBOX);
+ gobject_class->finalize = gtk_webviewtoolbar_finalize;
+
+ g_type_class_add_private(class, sizeof(GtkWebViewToolbarPriv));
+
+ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations/toolbar");
+ purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/toolbar/wide", FALSE);
+}
+
+static void
+gtk_webviewtoolbar_create_actions(GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ GtkActionGroup *action_group;
+ int i;
+ struct {
+ GtkAction **action;
+ char *name;
+ char *stock;
+ char *label;
+ char *tooltip;
+ void (*cb)();
+ gboolean toggle;
+ } actions[] = {
+ {&priv->bold, "ToggleBold", GTK_STOCK_BOLD, N_("<b>_Bold</b>"), N_("Bold"), do_bold, TRUE},
+ {&priv->italic, "ToggleItalic", GTK_STOCK_ITALIC, N_("<i>_Italic</i>"), N_("Italic"), do_italic, TRUE},
+ {&priv->underline, "ToggleUnderline", GTK_STOCK_UNDERLINE, N_("<u>_Underline</u>"), N_("Underline"), do_underline, TRUE},
+ {&priv->strike, "ToggleStrike", GTK_STOCK_STRIKETHROUGH, N_("<span strikethrough='true'>Strikethrough</span>"), N_("Strikethrough"), do_strikethrough, TRUE},
+ {&priv->larger_size, "ToggleLarger", PIDGIN_STOCK_TOOLBAR_TEXT_LARGER, N_("<span size='larger'>Larger</span>"), N_("Increase Font Size"), do_big, FALSE},
+#if 0
+ {&priv->normal_size, "ToggleNormal", NULL, N_("Normal"), N_("Normal Font Size"), NULL, FALSE},
+#endif
+ {&priv->smaller_size, "ToggleSmaller", PIDGIN_STOCK_TOOLBAR_TEXT_SMALLER, N_("<span size='smaller'>Smaller</span>"), N_("Decrease Font Size"), do_small, FALSE},
+ {&priv->font, "ToggleFontFace", PIDGIN_STOCK_TOOLBAR_FONT_FACE, N_("_Font face"), N_("Font Face"), toggle_font, TRUE},
+ {&priv->fgcolor, "ToggleFG", PIDGIN_STOCK_TOOLBAR_FGCOLOR, N_("Foreground _color"), N_("Foreground Color"), toggle_fg_color, TRUE},
+ {&priv->bgcolor, "ToggleBG", PIDGIN_STOCK_TOOLBAR_BGCOLOR, N_("Bac_kground color"), N_("Background Color"), toggle_bg_color, TRUE},
+ {&priv->clear, "ResetFormat", PIDGIN_STOCK_CLEAR, N_("_Reset formatting"), N_("Reset Formatting"), clear_formatting_cb, FALSE},
+ {&priv->image, "InsertImage", PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE, N_("_Image"), N_("Insert IM Image"), insert_image_cb, FALSE},
+ {&priv->link, "InsertLink", PIDGIN_STOCK_TOOLBAR_INSERT_LINK, N_("_Link"), N_("Insert Link"), insert_link_cb, TRUE},
+ {&priv->hr, "InsertHR", NULL, N_("_Horizontal rule"), N_("Insert Horizontal rule"), insert_hr_cb, FALSE},
+ {&priv->smiley, "InsertSmiley", PIDGIN_STOCK_TOOLBAR_SMILEY, N_("_Smile!"), N_("Insert Smiley"), insert_smiley_cb, FALSE},
+ {&priv->attention, "SendAttention", PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION, N_("_Attention!"), N_("Send Attention"), send_attention_cb, FALSE},
+ };
+
+ action_group = gtk_action_group_new("GtkWebViewToolbar");
+#ifdef ENABLE_NLS
+ gtk_action_group_set_translation_domain(action_group, PACKAGE);
+#endif
+
+ for (i = 0; i < G_N_ELEMENTS(actions); i++) {
+ GtkAction *action;
+ if (actions[i].toggle)
+ action = GTK_ACTION(gtk_toggle_action_new(actions[i].name,
+ actions[i].label,
+ actions[i].tooltip,
+ actions[i].stock));
+ else
+ action = gtk_action_new(actions[i].name, actions[i].label,
+ actions[i].tooltip, actions[i].stock);
+ gtk_action_set_is_important(action, TRUE);
+ gtk_action_group_add_action(action_group, action);
+ g_signal_connect(G_OBJECT(action), "activate", actions[i].cb, toolbar);
+ *(actions[i].action) = action;
+ }
+}
+
+static void
+gtk_webviewtoolbar_create_wide_view(GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ GtkAction *layout[] = {
+ priv->bold,
+ priv->italic,
+ priv->underline,
+ priv->strike,
+ NULL,
+ priv->larger_size,
+#if 0
+ priv->normal_size,
+#endif
+ priv->smaller_size,
+ NULL,
+ priv->font,
+ priv->fgcolor,
+ priv->bgcolor,
+ NULL,
+ priv->clear,
+ NULL,
+ priv->image,
+ priv->link,
+ NULL,
+ priv->smiley,
+ priv->attention
+ };
+ int i;
+ GtkToolItem *item;
+
+ priv->wide_view = gtk_toolbar_new();
+ gtk_toolbar_set_icon_size(GTK_TOOLBAR(priv->wide_view),
+ gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL));
+ gtk_toolbar_set_style(GTK_TOOLBAR(priv->wide_view), GTK_TOOLBAR_ICONS);
+
+ for (i = 0; i < G_N_ELEMENTS(layout); i++) {
+ if (layout[i])
+ item = GTK_TOOL_ITEM(gtk_action_create_tool_item(layout[i]));
+ else
+ item = gtk_separator_tool_item_new();
+ gtk_toolbar_insert(GTK_TOOLBAR(priv->wide_view), item, -1);
+ }
+}
+
+static void
+gtk_webviewtoolbar_create_lean_view(GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ GtkWidget *label;
+ GtkWidget *menuitem;
+ GtkToolItem *sep;
+ GtkToolItem *font_button;
+ GtkWidget *font_menu;
+ GtkToolItem *insert_button;
+ GtkWidget *insert_menu;
+ GtkWidget *smiley_button;
+ GtkWidget *attention_button;
+
+ priv->lean_view = gtk_toolbar_new();
+ gtk_toolbar_set_icon_size(GTK_TOOLBAR(priv->lean_view),
+ gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL));
+ gtk_toolbar_set_style(GTK_TOOLBAR(priv->lean_view), GTK_TOOLBAR_BOTH_HORIZ);
+
+#define ADD_MENU_ITEM(menu, item) \
+ menuitem = gtk_action_create_menu_item((item)); \
+ gtk_menu_shell_append(GTK_MENU_SHELL((menu)), menuitem);
+
+ /* Fonts */
+ font_button = gtk_toggle_tool_button_new();
+ gtk_toolbar_insert(GTK_TOOLBAR(priv->lean_view), font_button, -1);
+ gtk_tool_item_set_is_important(font_button, TRUE);
+ gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(font_button), GTK_STOCK_BOLD);
+ priv->font_label = label = gtk_label_new_with_mnemonic(_("_Font"));
+ gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
+ gtk_tool_button_set_label_widget(GTK_TOOL_BUTTON(font_button), label);
+
+ priv->font_menu = font_menu = gtk_menu_new();
+
+ ADD_MENU_ITEM(font_menu, priv->bold);
+ ADD_MENU_ITEM(font_menu, priv->italic);
+ ADD_MENU_ITEM(font_menu, priv->underline);
+ ADD_MENU_ITEM(font_menu, priv->strike);
+ ADD_MENU_ITEM(font_menu, priv->larger_size);
+#if 0
+ ADD_MENU_ITEM(font_menu, priv->normal_size);
+#endif
+ ADD_MENU_ITEM(font_menu, priv->smaller_size);
+ ADD_MENU_ITEM(font_menu, priv->font);
+ ADD_MENU_ITEM(font_menu, priv->fgcolor);
+ ADD_MENU_ITEM(font_menu, priv->bgcolor);
+ ADD_MENU_ITEM(font_menu, priv->clear);
+
+ g_signal_connect(G_OBJECT(font_button), "toggled",
+ G_CALLBACK(pidgin_menu_clicked), font_menu);
+ g_signal_connect(G_OBJECT(font_menu), "deactivate",
+ G_CALLBACK(pidgin_menu_deactivate), font_button);
+
+ gtk_container_foreach(GTK_CONTAINER(font_menu), enable_markup, NULL);
+
+ /* Sep */
+ sep = gtk_separator_tool_item_new();
+ gtk_toolbar_insert(GTK_TOOLBAR(priv->lean_view), sep, -1);
+
+ /* Insert */
+ insert_button = gtk_toggle_tool_button_new();
+ gtk_toolbar_insert(GTK_TOOLBAR(priv->lean_view), insert_button, -1);
+ gtk_tool_item_set_is_important(insert_button, TRUE);
+ gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(insert_button),
+ PIDGIN_STOCK_TOOLBAR_INSERT);
+ label = gtk_label_new_with_mnemonic(_("_Insert"));
+ gtk_tool_button_set_label_widget(GTK_TOOL_BUTTON(insert_button), label);
+
+ priv->insert_menu = insert_menu = gtk_menu_new();
+
+ ADD_MENU_ITEM(insert_menu, priv->image);
+ ADD_MENU_ITEM(insert_menu, priv->link);
+ ADD_MENU_ITEM(insert_menu, priv->hr);
+
+ g_signal_connect(G_OBJECT(insert_button), "toggled",
+ G_CALLBACK(pidgin_menu_clicked), insert_menu);
+ g_signal_connect(G_OBJECT(insert_menu), "deactivate",
+ G_CALLBACK(pidgin_menu_deactivate), insert_button);
+
+ /* Sep */
+ sep = gtk_separator_tool_item_new();
+ gtk_toolbar_insert(GTK_TOOLBAR(priv->lean_view), sep, -1);
+
+ /* Smiley */
+ smiley_button = gtk_action_create_tool_item(priv->smiley);
+ gtk_toolbar_insert(GTK_TOOLBAR(priv->lean_view),
+ GTK_TOOL_ITEM(smiley_button), -1);
+
+ /* Sep */
+ sep = gtk_separator_tool_item_new();
+ gtk_toolbar_insert(GTK_TOOLBAR(priv->lean_view), sep, -1);
+
+ /* Attention */
+ attention_button = gtk_action_create_tool_item(priv->attention);
+ gtk_toolbar_insert(GTK_TOOLBAR(priv->lean_view),
+ GTK_TOOL_ITEM(attention_button), -1);
+
+#undef ADD_MENU_ITEM
+}
+
+static void
+gtk_webviewtoolbar_init(GtkWebViewToolbar *toolbar)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ GtkWidget *hbox = GTK_WIDGET(toolbar);
+
+ gtk_webviewtoolbar_create_actions(toolbar);
+ gtk_webviewtoolbar_create_wide_view(toolbar);
+ gtk_webviewtoolbar_create_lean_view(toolbar);
+
+ gtk_box_pack_start(GTK_BOX(hbox), priv->wide_view, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), priv->lean_view, TRUE, TRUE, 0);
+
+ priv->sml = NULL;
+
+ /* set attention button to be greyed out until we get a conversation */
+ gtk_action_set_sensitive(priv->attention, FALSE);
+
+ purple_prefs_connect_callback(toolbar,
+ PIDGIN_PREFS_ROOT "/conversations/toolbar/wide",
+ webviewtoolbar_view_pref_changed, toolbar);
+ g_signal_connect_data(G_OBJECT(toolbar), "realize",
+ G_CALLBACK(purple_prefs_trigger_callback),
+ PIDGIN_PREFS_ROOT "/conversations/toolbar/wide",
+ NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
+
+ g_signal_connect(G_OBJECT(hbox), "button-press-event",
+ G_CALLBACK(gtk_webviewtoolbar_popup_menu), toolbar);
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+
+GtkWidget *
+gtk_webviewtoolbar_new(void)
+{
+ return GTK_WIDGET(g_object_new(gtk_webviewtoolbar_get_type(), NULL));
+}
+
+GType
+gtk_webviewtoolbar_get_type(void)
+{
+ static GType webviewtoolbar_type = 0;
+
+ if (!webviewtoolbar_type) {
+ static const GTypeInfo webviewtoolbar_info = {
+ sizeof(GtkWebViewToolbarClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)gtk_webviewtoolbar_class_init,
+ NULL,
+ NULL,
+ sizeof(GtkWebViewToolbar),
+ 0,
+ (GInstanceInitFunc)gtk_webviewtoolbar_init,
+ NULL
+ };
+
+ webviewtoolbar_type = g_type_register_static(GTK_TYPE_HBOX,
+ "GtkWebViewToolbar", &webviewtoolbar_info, 0);
+ }
+
+ return webviewtoolbar_type;
+}
+
+void
+gtk_webviewtoolbar_attach(GtkWebViewToolbar *toolbar, GtkWidget *webview)
+{
+ GtkWebViewButtons buttons;
+
+ g_return_if_fail(toolbar != NULL);
+ g_return_if_fail(GTK_IS_WEBVIEWTOOLBAR(toolbar));
+ g_return_if_fail(webview != NULL);
+ g_return_if_fail(GTK_IS_WEBVIEW(webview));
+
+ toolbar->webview = webview;
+ g_signal_connect(G_OBJECT(webview), "allowed-formats-updated",
+ G_CALLBACK(update_buttons_cb), toolbar);
+ g_signal_connect_after(G_OBJECT(webview), "format-toggled",
+ G_CALLBACK(toggle_button_cb), toolbar);
+ g_signal_connect_after(G_OBJECT(webview), "format-cleared",
+ G_CALLBACK(update_format_cb), toolbar);
+ g_signal_connect(G_OBJECT(webview), "format-updated",
+ G_CALLBACK(update_format_cb), toolbar);
+ g_signal_connect_after(G_OBJECT(webview), "selection-changed",
+ G_CALLBACK(mark_set_cb), toolbar);
+
+ buttons = gtk_webview_get_format_functions(GTK_WEBVIEW(webview));
+ update_buttons_cb(GTK_WEBVIEW(webview), buttons, toolbar);
+ update_buttons(toolbar);
+}
+
+void
+gtk_webviewtoolbar_associate_smileys(GtkWebViewToolbar *toolbar,
+ const char *proto_id)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ g_free(priv->sml);
+ priv->sml = g_strdup(proto_id);
+}
+
+void
+gtk_webviewtoolbar_switch_active_conversation(GtkWebViewToolbar *toolbar,
+ PurpleConversation *conv)
+{
+ GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
+ PurpleConnection *gc = purple_conversation_get_connection(conv);
+ PurplePlugin *prpl = purple_connection_get_prpl(gc);
+
+ priv->active_conv = conv;
+
+ /* gray out attention button on protocols that don't support it
+ for the time being it is always disabled for chats */
+ gtk_action_set_sensitive(priv->attention,
+ conv && prpl && purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM &&
+ PURPLE_PLUGIN_PROTOCOL_INFO(prpl)->send_attention != NULL);
+}
+
diff --git a/pidgin/gtkwebviewtoolbar.h b/pidgin/gtkwebviewtoolbar.h
new file mode 100644
index 0000000000..fc4df9a951
--- /dev/null
+++ b/pidgin/gtkwebviewtoolbar.h
@@ -0,0 +1,96 @@
+/*
+ * GtkWebViewToolbar
+ *
+ * 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.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * 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
+ *
+ */
+#ifndef _PIDGINWEBVIEWTOOLBAR_H_
+#define _PIDGINWEBVIEWTOOLBAR_H_
+
+#include <gtk/gtk.h>
+#include "gtkwebview.h"
+
+#define DEFAULT_FONT_FACE "Helvetica 12"
+
+#define GTK_TYPE_WEBVIEWTOOLBAR (gtk_webviewtoolbar_get_type())
+#define GTK_WEBVIEWTOOLBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_WEBVIEWTOOLBAR, GtkWebViewToolbar))
+#define GTK_WEBVIEWTOOLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_WEBVIEWTOOLBAR, GtkWebViewToolbarClass))
+#define GTK_IS_WEBVIEWTOOLBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_WEBVIEWTOOLBAR))
+#define GTK_IS_WEBVIEWTOOLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_WEBVIEWTOOLBAR))
+#define GTK_WEBVIEWTOOLBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_WEBVIEWTOOLBAR, GtkWebViewToolbarClass))
+
+typedef struct _GtkWebViewToolbar GtkWebViewToolbar;
+typedef struct _GtkWebViewToolbarClass GtkWebViewToolbarClass;
+
+struct _GtkWebViewToolbar {
+ GtkHBox box;
+
+ GtkWidget *webview;
+};
+
+struct _GtkWebViewToolbarClass {
+ GtkHBoxClass parent_class;
+};
+
+G_BEGIN_DECLS
+
+/**
+ * Returns the GType for a GtkWebViewToolbar widget
+ *
+ * @return The GType for GtkWebViewToolbar widget
+ */
+GType gtk_webviewtoolbar_get_type(void);
+
+/**
+ * Create a new GtkWebViewToolbar object
+ *
+ * @return A GtkWidget corresponding to the GtkWebViewToolbar object
+ */
+GtkWidget *gtk_webviewtoolbar_new(void);
+
+/**
+ * Attach a GtkWebViewToolbar object to a GtkWebView
+ *
+ * @param toolbar The GtkWebViewToolbar object
+ * @param webview The GtkWebView object
+ */
+void gtk_webviewtoolbar_attach(GtkWebViewToolbar *toolbar, GtkWidget *webview);
+
+/**
+ * Associate the smileys from a protocol to a GtkWebViewToolbar object
+ *
+ * @param toolbar The GtkWebViewToolbar object
+ * @param proto_id The ID of the protocol from which smileys are associated
+ */
+void gtk_webviewtoolbar_associate_smileys(GtkWebViewToolbar *toolbar,
+ const char *proto_id);
+
+/**
+ * Switch the active conversation for a GtkWebViewToolbar object
+ *
+ * @param toolbar The GtkWebViewToolbar object
+ * @param conv The new conversation
+ */
+void gtk_webviewtoolbar_switch_active_conversation(GtkWebViewToolbar *toolbar,
+ PurpleConversation *conv);
+
+G_END_DECLS
+
+#endif /* _PIDGINWEBVIEWTOOLBAR_H_ */
+
diff --git a/pidgin/gtkwhiteboard.c b/pidgin/gtkwhiteboard.c
index 8471d9e304..0975481202 100644
--- a/pidgin/gtkwhiteboard.c
+++ b/pidgin/gtkwhiteboard.c
@@ -125,7 +125,7 @@ static void pidgin_whiteboard_create(PurpleWhiteboard *wb)
PidginWhiteboard *gtkwb = g_new0(PidginWhiteboard, 1);
gtkwb->wb = wb;
- wb->ui_data = gtkwb;
+ purple_whiteboard_set_ui_data(wb, gtkwb);
/* Get dimensions (default?) for the whiteboard canvas */
if (!purple_whiteboard_get_dimensions(wb, &gtkwb->width, &gtkwb->height))
@@ -145,11 +145,11 @@ static void pidgin_whiteboard_create(PurpleWhiteboard *wb)
/* Try and set window title as the name of the buddy, else just use their
* username
*/
- buddy = purple_find_buddy(wb->account, wb->who);
+ buddy = purple_find_buddy(purple_whiteboard_get_account(wb), purple_whiteboard_get_who(wb));
- window = pidgin_create_window(buddy != NULL ? purple_buddy_get_contact_alias(buddy) : wb->who, 0, NULL, FALSE);
+ window = pidgin_create_window(buddy != NULL ? purple_buddy_get_contact_alias(buddy) : purple_whiteboard_get_who(wb), 0, NULL, FALSE);
gtkwb->window = window;
- gtk_widget_set_name(window, wb->who);
+ gtk_widget_set_name(window, purple_whiteboard_get_who(wb));
g_signal_connect(G_OBJECT(window), "delete_event",
G_CALLBACK(whiteboard_close_cb), gtkwb);
@@ -274,7 +274,7 @@ static void pidgin_whiteboard_destroy(PurpleWhiteboard *wb)
GtkWidget *colour_dialog;
g_return_if_fail(wb != NULL);
- gtkwb = wb->ui_data;
+ gtkwb = purple_whiteboard_get_ui_data(wb);
g_return_if_fail(gtkwb != NULL);
/* TODO Ask if user wants to save picture before the session is closed */
@@ -301,7 +301,7 @@ static void pidgin_whiteboard_destroy(PurpleWhiteboard *wb)
gtkwb->window = NULL;
}
g_free(gtkwb);
- wb->ui_data = NULL;
+ purple_whiteboard_set_ui_data(wb, NULL);
}
static gboolean whiteboard_close_cb(GtkWidget *widget, GdkEvent *event, PidginWhiteboard *gtkwb)
@@ -406,7 +406,7 @@ static gboolean pidgin_whiteboard_brush_down(GtkWidget *widget, GdkEventButton *
GdkPixmap *pixmap = gtkwb->pixmap;
PurpleWhiteboard *wb = gtkwb->wb;
- GList *draw_list = wb->draw_list;
+ GList *draw_list = purple_whiteboard_get_draw_list(wb);
if(BrushState != BRUSH_STATE_UP)
{
@@ -441,7 +441,7 @@ static gboolean pidgin_whiteboard_brush_down(GtkWidget *widget, GdkEventButton *
gtkwb->brush_color, gtkwb->brush_size);
}
- wb->draw_list = draw_list;
+ purple_whiteboard_set_draw_list(wb, draw_list);
return TRUE;
}
@@ -459,7 +459,7 @@ static gboolean pidgin_whiteboard_brush_motion(GtkWidget *widget, GdkEventMotion
GdkPixmap *pixmap = gtkwb->pixmap;
PurpleWhiteboard *wb = gtkwb->wb;
- GList *draw_list = wb->draw_list;
+ GList *draw_list = purple_whiteboard_get_draw_list(wb);
if(event->is_hint)
gdk_window_get_pointer(event->window, &x, &y, &state);
@@ -528,7 +528,7 @@ static gboolean pidgin_whiteboard_brush_motion(GtkWidget *widget, GdkEventMotion
LastY = y;
}
- wb->draw_list = draw_list;
+ purple_whiteboard_set_draw_list(wb, draw_list);
return TRUE;
}
@@ -539,7 +539,7 @@ static gboolean pidgin_whiteboard_brush_up(GtkWidget *widget, GdkEventButton *ev
GdkPixmap *pixmap = gtkwb->pixmap;
PurpleWhiteboard *wb = gtkwb->wb;
- GList *draw_list = wb->draw_list;
+ GList *draw_list = purple_whiteboard_get_draw_list(wb);
if((BrushState != BRUSH_STATE_DOWN) && (BrushState != BRUSH_STATE_MOTION))
{
@@ -583,7 +583,7 @@ static gboolean pidgin_whiteboard_brush_up(GtkWidget *widget, GdkEventButton *ev
if(draw_list)
purple_whiteboard_draw_list_destroy(draw_list);
- wb->draw_list = NULL;
+ purple_whiteboard_set_draw_list(wb, NULL);
}
return TRUE;
@@ -591,7 +591,7 @@ static gboolean pidgin_whiteboard_brush_up(GtkWidget *widget, GdkEventButton *ev
static void pidgin_whiteboard_draw_brush_point(PurpleWhiteboard *wb, int x, int y, int color, int size)
{
- PidginWhiteboard *gtkwb = wb->ui_data;
+ PidginWhiteboard *gtkwb = purple_whiteboard_get_ui_data(wb);
GtkWidget *widget = gtkwb->drawing_area;
GdkPixmap *pixmap = gtkwb->pixmap;
@@ -684,7 +684,7 @@ static void pidgin_whiteboard_draw_brush_line(PurpleWhiteboard *wb, int x0, int
static void pidgin_whiteboard_set_dimensions(PurpleWhiteboard *wb, int width, int height)
{
- PidginWhiteboard *gtkwb = wb->ui_data;
+ PidginWhiteboard *gtkwb = purple_whiteboard_get_ui_data(wb);
gtkwb->width = width;
gtkwb->height = height;
@@ -692,7 +692,7 @@ static void pidgin_whiteboard_set_dimensions(PurpleWhiteboard *wb, int width, in
static void pidgin_whiteboard_set_brush(PurpleWhiteboard *wb, int size, int color)
{
- PidginWhiteboard *gtkwb = wb->ui_data;
+ PidginWhiteboard *gtkwb = purple_whiteboard_get_ui_data(wb);
gtkwb->brush_size = size;
gtkwb->brush_color = color;
@@ -700,7 +700,7 @@ static void pidgin_whiteboard_set_brush(PurpleWhiteboard *wb, int size, int colo
static void pidgin_whiteboard_clear(PurpleWhiteboard *wb)
{
- PidginWhiteboard *gtkwb = wb->ui_data;
+ PidginWhiteboard *gtkwb = purple_whiteboard_get_ui_data(wb);
GdkPixmap *pixmap = gtkwb->pixmap;
GtkWidget *drawing_area = gtkwb->drawing_area;
cairo_t *cr = g_object_get_data(G_OBJECT(pixmap), "cairo-context");
diff --git a/pidgin/gtkwhiteboard.h b/pidgin/gtkwhiteboard.h
index d5bad34a36..e6469adef0 100644
--- a/pidgin/gtkwhiteboard.h
+++ b/pidgin/gtkwhiteboard.h
@@ -59,9 +59,7 @@ typedef struct _PidginWhiteboard
int brush_size; /**< Brush size */
} PidginWhiteboard;
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
+G_BEGIN_DECLS
/*****************************************************************************/
/** @name PidginWhiteboard API */
@@ -77,8 +75,6 @@ PurpleWhiteboardUiOps *pidgin_whiteboard_get_ui_ops( void );
/*@}*/
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+G_END_DECLS
#endif /* _PIDGINWHITEBOARD_H_ */
diff --git a/pidgin/pidgin-2-uninstalled.pc.in b/pidgin/pidgin-3-uninstalled.pc.in
index a2e4fd9da3..558ad54703 100644
--- a/pidgin/pidgin-2-uninstalled.pc.in
+++ b/pidgin/pidgin-3-uninstalled.pc.in
@@ -17,5 +17,5 @@ plugindir=${libdir}/pidgin
Name: Pidgin
Description: Pidgin is a GTK2-based instant messenger application.
Version: @VERSION@
-Requires: gtk+-2.0 purple
+Requires: gtk+-2.0 purple-3
Cflags: -I${abs_top_srcdir}
diff --git a/pidgin/pidgin-2.pc.in b/pidgin/pidgin-3.pc.in
index 30c930ae22..9464d8a6c3 100644
--- a/pidgin/pidgin-2.pc.in
+++ b/pidgin/pidgin-3.pc.in
@@ -1,7 +1,7 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
-includedir=@includedir@
+includedir=@includedir@/pidgin
datarootdir=@datarootdir@
datadir=@datadir@
sysconfdir=@sysconfdir@
@@ -11,5 +11,5 @@ plugindir=${libdir}/pidgin
Name: Pidgin
Description: Pidgin is a GTK2-based instant messenger application.
Version: @VERSION@
-Requires: gtk+-2.0 purple
+Requires: gtk+-2.0 purple-3
Cflags: -I${includedir}
diff --git a/pidgin/pidgin-uninstalled.pc.in b/pidgin/pidgin-uninstalled.pc.in
deleted file mode 100644
index ba2205ad3f..0000000000
--- a/pidgin/pidgin-uninstalled.pc.in
+++ /dev/null
@@ -1,18 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-
-abs_srcdir=@abs_srcdir@
-abs_builddir=@abs_builddir@
-
-plugindir=${libdir}/pidgin
-
-Name: Pidgin
-Description: Pidgin is a GTK2-based instant messenger application.
-Version: @VERSION@
-Requires: gtk+-2.0 purple
-Cflags: -I${abs_srcdir}
diff --git a/pidgin/pidgin.pc.in b/pidgin/pidgin.pc.in
deleted file mode 100644
index 53e1b88702..0000000000
--- a/pidgin/pidgin.pc.in
+++ /dev/null
@@ -1,16 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-
-plugindir=${libdir}/pidgin
-
-Name: Pidgin
-Description: Pidgin is a GTK2-based instant messenger application.
-Version: @VERSION@
-Requires: gtk+-2.0 purple
-Cflags: -I${includedir}/pidgin
-
diff --git a/pidgin/pidgintooltip.h b/pidgin/pidgintooltip.h
index 889232341e..22b97173f5 100644
--- a/pidgin/pidgintooltip.h
+++ b/pidgin/pidgintooltip.h
@@ -36,7 +36,6 @@
* @param h The value of this should be set to the desired height of the tooltip window.
*
* @return @c TRUE if the tooltip was created correctly, @c FALSE otherwise.
- * @since 2.4.0
*/
typedef gboolean (*PidginTooltipCreateForTree)(GtkWidget *tipwindow,
GtkTreePath *path, gpointer userdata, int *w, int *h);
@@ -48,7 +47,6 @@ typedef gboolean (*PidginTooltipCreateForTree)(GtkWidget *tipwindow,
* @param h The value of this should be set to the desired height of the tooltip window.
*
* @return @c TRUE if the tooltip was created correctly, @c FALSE otherwise.
- * @since 2.4.0
*/
typedef gboolean (*PidginTooltipCreate)(GtkWidget *tipwindow,
gpointer userdata, int *w, int *h);
@@ -58,10 +56,11 @@ typedef gboolean (*PidginTooltipCreate)(GtkWidget *tipwindow,
* @param userdata The userdata set during pidgin_tooltip_setup_for_treeview or pidgin_tooltip_show.
*
* @return @c TRUE if the tooltip was painted correctly, @c FALSE otherwise.
- * @since 2.4.0
*/
typedef gboolean (*PidginTooltipPaint)(GtkWidget *tipwindow, gpointer userdata);
+G_BEGIN_DECLS
+
/**
* Setup tooltip drawing functions for a treeview.
*
@@ -71,7 +70,6 @@ typedef gboolean (*PidginTooltipPaint)(GtkWidget *tipwindow, gpointer userdata);
* @param paint_cb Callback function to paint the tooltip
*
* @return @c TRUE if the tooltip callbacks were setup correctly.
- * @since 2.4.0
*/
gboolean pidgin_tooltip_setup_for_treeview(GtkWidget *tree, gpointer userdata,
PidginTooltipCreateForTree create_cb, PidginTooltipPaint paint_cb);
@@ -85,14 +83,12 @@ gboolean pidgin_tooltip_setup_for_treeview(GtkWidget *tree, gpointer userdata,
* @param paint_cb Callback function to paint the tooltip
*
* @return @c TRUE if the tooltip callbacks were setup correctly.
- * @since 2.4.0
*/
gboolean pidgin_tooltip_setup_for_widget(GtkWidget *widget, gpointer userdata,
PidginTooltipCreate create_cb, PidginTooltipPaint paint_cb);
/**
* Destroy the tooltip.
- * @since 2.4.0
*/
void pidgin_tooltip_destroy(void);
@@ -103,10 +99,10 @@ void pidgin_tooltip_destroy(void);
* @param userdata The userdata to send to the callback functions
* @param create_cb Callback function to create the tooltip from the GtkTreePath
* @param paint_cb Callback function to paint the tooltip
- *
- * @since 2.4.0
*/
void pidgin_tooltip_show(GtkWidget *widget, gpointer userdata,
PidginTooltipCreate create_cb, PidginTooltipPaint paint_cb);
+G_END_DECLS
+
#endif
diff --git a/pidgin/plugins/Makefile.am b/pidgin/plugins/Makefile.am
index 583dad0d32..1741d15670 100644
--- a/pidgin/plugins/Makefile.am
+++ b/pidgin/plugins/Makefile.am
@@ -45,9 +45,8 @@ relnot_la_LDFLAGS = -module -avoid-version
sendbutton_la_LDFLAGS = -module -avoid-version
spellchk_la_LDFLAGS = -module -avoid-version
themeedit_la_LDFLAGS = -module -avoid-version
-timestamp_la_LDFLAGS = -module -avoid-version
-timestamp_format_la_LDFLAGS = -module -avoid-version
vvconfig_la_LDFLAGS = -module -avoid-version
+webkit_la_LDFLAGS = -module -avoid-version
xmppconsole_la_LDFLAGS = -module -avoid-version
if PLUGINS
@@ -64,9 +63,8 @@ plugin_LTLIBRARIES = \
relnot.la \
sendbutton.la \
spellchk.la \
- themeedit.la \
- timestamp.la \
- timestamp_format.la \
+ themeedit.la \
+ webkit.la \
xmppconsole.la
if USE_VV
@@ -91,9 +89,7 @@ relnot_la_SOURCES = relnot.c
sendbutton_la_SOURCES = sendbutton.c
spellchk_la_SOURCES = spellchk.c
themeedit_la_SOURCES = themeedit.c themeedit-icon.c themeedit-icon.h
-timestamp_la_SOURCES = timestamp.c
-timestamp_format_la_SOURCES = timestamp_format.c
-vvconfig_la_SOURCES = vvconfig.c
+webkit_la_SOURCES = webkit.c
xmppconsole_la_SOURCES = xmppconsole.c
convcolors_la_LIBADD = $(GTK_LIBS)
@@ -103,16 +99,14 @@ gtk_signals_test_la_LIBADD = $(GTK_LIBS)
gtkbuddynote_la_LIBADD = $(GTK_LIBS)
history_la_LIBADD = $(GTK_LIBS)
iconaway_la_LIBADD = $(GTK_LIBS)
-markerline_la_LIBADD = $(GTK_LIBS)
+markerline_la_LIBADD = $(GTK_LIBS) $(WEBKIT_LIBS)
notify_la_LIBADD = $(GTK_LIBS)
pidginrc_la_LIBADD = $(GTK_LIBS)
relnot_la_LIBADD = $(GLIB_LIBS)
sendbutton_la_LIBADD = $(GTK_LIBS)
spellchk_la_LIBADD = $(GTK_LIBS)
themeedit_la_LIBADD = $(GTK_LIBS)
-timestamp_la_LIBADD = $(GTK_LIBS)
-timestamp_format_la_LIBADD = $(GTK_LIBS)
-vvconfig_la_LIBADD = $(GTK_LIBS) $(GSTREAMER_LIBS)
+webkit_la_LIBADD = $(GTK_LIBS) $(WEBKIT_LIBS)
xmppconsole_la_LIBADD = $(GTK_LIBS)
endif # PLUGINS
@@ -136,6 +130,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/pidgin \
$(DEBUG_CFLAGS) \
$(GTK_CFLAGS) \
+ $(WEBKIT_CFLAGS) \
$(GSTREAMER_CFLAGS) \
$(PLUGIN_CFLAGS)
diff --git a/pidgin/plugins/contact_priority.c b/pidgin/plugins/contact_priority.c
index e59566b481..5ec79d973d 100644
--- a/pidgin/plugins/contact_priority.c
+++ b/pidgin/plugins/contact_priority.c
@@ -35,11 +35,11 @@ select_account(GtkWidget *widget, PurpleAccount *account, gpointer data)
}
static void
-account_update(GtkWidget *widget, GtkOptionMenu *optmenu)
+account_update(GtkWidget *widget, GtkWidget *optmenu)
{
PurpleAccount *account = NULL;
- account = g_object_get_data(G_OBJECT(gtk_menu_get_active(GTK_MENU(gtk_option_menu_get_menu(optmenu)))), "account");
+ account = pidgin_account_option_menu_get_selected(optmenu);
purple_account_set_int(account, "score", gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)));
}
@@ -147,8 +147,7 @@ get_config_frame(PurplePlugin *plugin)
gtk_box_pack_start(GTK_BOX(hbox), optmenu, FALSE, FALSE, 0);
/* this is where we set up the spin button we made above */
- account = g_object_get_data(G_OBJECT(gtk_menu_get_active(GTK_MENU(gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu))))),
- "account");
+ account = pidgin_account_option_menu_get_selected(optmenu);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin),
(gdouble)purple_account_get_int(account, "score", 0));
gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(spin), GTK_ADJUSTMENT(adj));
diff --git a/pidgin/plugins/gestures/gestures.c b/pidgin/plugins/gestures/gestures.c
index 4848a844b1..51c13f011e 100644
--- a/pidgin/plugins/gestures/gestures.c
+++ b/pidgin/plugins/gestures/gestures.c
@@ -48,7 +48,7 @@ stroke_close(GtkWidget *widget, void *data)
gtkconv = PIDGIN_CONVERSATION(conv);
- gstroke_cleanup(gtkconv->imhtml);
+ gstroke_cleanup(gtkconv->webview);
purple_conversation_destroy(conv);
}
@@ -126,15 +126,15 @@ attach_signals(PurpleConversation *conv)
gtkconv = PIDGIN_CONVERSATION(conv);
- gstroke_enable(gtkconv->imhtml);
- gstroke_signal_connect(gtkconv->imhtml, "14789", stroke_close, conv);
- gstroke_signal_connect(gtkconv->imhtml, "1456", stroke_close, conv);
- gstroke_signal_connect(gtkconv->imhtml, "1489", stroke_close, conv);
- gstroke_signal_connect(gtkconv->imhtml, "74123", stroke_next_tab, conv);
- gstroke_signal_connect(gtkconv->imhtml, "7456", stroke_next_tab, conv);
- gstroke_signal_connect(gtkconv->imhtml, "96321", stroke_prev_tab, conv);
- gstroke_signal_connect(gtkconv->imhtml, "9654", stroke_prev_tab, conv);
- gstroke_signal_connect(gtkconv->imhtml, "25852", stroke_new_win, conv);
+ gstroke_enable(gtkconv->webview);
+ gstroke_signal_connect(gtkconv->webview, "14789", stroke_close, conv);
+ gstroke_signal_connect(gtkconv->webview, "1456", stroke_close, conv);
+ gstroke_signal_connect(gtkconv->webview, "1489", stroke_close, conv);
+ gstroke_signal_connect(gtkconv->webview, "74123", stroke_next_tab, conv);
+ gstroke_signal_connect(gtkconv->webview, "7456", stroke_next_tab, conv);
+ gstroke_signal_connect(gtkconv->webview, "96321", stroke_prev_tab, conv);
+ gstroke_signal_connect(gtkconv->webview, "9654", stroke_prev_tab, conv);
+ gstroke_signal_connect(gtkconv->webview, "25852", stroke_new_win, conv);
}
static void
@@ -145,7 +145,6 @@ new_conv_cb(PurpleConversation *conv)
}
#if 0
-#if GTK_CHECK_VERSION(2,4,0)
static void
mouse_button_menu_cb(GtkComboBox *opt, gpointer data)
{
@@ -153,15 +152,6 @@ mouse_button_menu_cb(GtkComboBox *opt, gpointer data)
gstroke_set_mouse_button(button + 2);
}
-#else
-static void
-mouse_button_menu_cb(GtkMenuItem *item, gpointer data)
-{
- int button = (int)data;
-
- gstroke_set_mouse_button(button + 2);
-}
-#endif
#endif
static void
@@ -215,8 +205,8 @@ plugin_unload(PurplePlugin *plugin)
gtkconv = PIDGIN_CONVERSATION(conv);
- gstroke_cleanup(gtkconv->imhtml);
- gstroke_disable(gtkconv->imhtml);
+ gstroke_cleanup(gtkconv->webview);
+ gstroke_disable(gtkconv->webview);
}
return TRUE;
@@ -230,9 +220,6 @@ get_config_frame(PurplePlugin *plugin)
GtkWidget *toggle;
#if 0
GtkWidget *opt;
-#if GTK_CHECK_VERSION(2,4,0)
- GtkWidget *menu, *item;
-#endif
#endif
/* Outside container */
@@ -243,7 +230,6 @@ get_config_frame(PurplePlugin *plugin)
vbox = pidgin_make_frame(ret, _("Mouse Gestures Configuration"));
#if 0
-#if GTK_CHECK_VERSION(2,4,0)
/* Mouse button drop-down menu */
opt = gtk_combo_box_new_text();
@@ -255,26 +241,6 @@ get_config_frame(PurplePlugin *plugin)
gtk_box_pack_start(GTK_BOX(vbox), opt, FALSE, FALSE, 0);
gtk_combo_box_set_active(GTK_COMBO_BOX(opt),
gstroke_get_mouse_button() - 2);
-#else
- /* Mouse button drop-down menu */
- menu = gtk_menu_new();
- opt = gtk_option_menu_new();
-
- item = gtk_menu_item_new_with_label(_("Middle mouse button"));
- g_signal_connect(G_OBJECT(item), "activate",
- G_CALLBACK(mouse_button_menu_cb), opt);
- gtk_menu_append(menu, item);
-
- item = gtk_menu_item_new_with_label(_("Right mouse button"));
- g_signal_connect(G_OBJECT(item), "activate",
- G_CALLBACK(mouse_button_menu_cb), opt);
- gtk_menu_append(menu, item);
-
- gtk_box_pack_start(GTK_BOX(vbox), opt, FALSE, FALSE, 0);
- gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu);
- gtk_option_menu_set_history(GTK_OPTION_MENU(opt),
- gstroke_get_mouse_button() - 2);
-#endif
#endif
/* "Visual gesture display" checkbox */
diff --git a/pidgin/plugins/gevolution/gevo-util.c b/pidgin/plugins/gevolution/gevo-util.c
index 8f97a7df8f..77d31a4ffe 100644
--- a/pidgin/plugins/gevolution/gevo-util.c
+++ b/pidgin/plugins/gevolution/gevo-util.c
@@ -49,7 +49,7 @@ gevo_add_buddy(PurpleAccount *account, const char *group_name,
purple_blist_add_buddy(buddy, NULL, group, NULL);
}
- purple_account_add_buddy(account, buddy);
+ purple_account_add_buddy(account, buddy, NULL);
if (conv != NULL)
{
diff --git a/pidgin/plugins/history.c b/pidgin/plugins/history.c
index 3d2507343b..6e53097c93 100644
--- a/pidgin/plugins/history.c
+++ b/pidgin/plugins/history.c
@@ -16,16 +16,17 @@
#include "gtkconv.h"
#include "gtkimhtml.h"
#include "gtkplugin.h"
+#include "gtkwebview.h"
#define HISTORY_PLUGIN_ID "gtk-history"
#define HISTORY_SIZE (4 * 1024)
-static gboolean _scroll_imhtml_to_end(gpointer data)
+static gboolean _scroll_webview_to_end(gpointer data)
{
- GtkIMHtml *imhtml = data;
- gtk_imhtml_scroll_to_end(GTK_IMHTML(imhtml), FALSE);
- g_object_unref(G_OBJECT(imhtml));
+ GtkWebView *webview = data;
+ gtk_webview_scroll_to_end(GTK_WEBVIEW(webview), FALSE);
+ g_object_unref(G_OBJECT(webview));
return FALSE;
}
@@ -39,9 +40,15 @@ static void historize(PurpleConversation *c)
guint flags;
char *history;
PidginConversation *gtkconv;
+#if 0
+ /* FIXME: WebView has no options */
GtkIMHtmlOptions options = GTK_IMHTML_NO_COLOURS;
+#endif
char *header;
+#if 0
+ /* FIXME: WebView has no protocol setting */
char *protocol;
+#endif
char *escaped_alias;
const char *header_date;
@@ -116,15 +123,21 @@ static void historize(PurpleConversation *c)
history = purple_log_read((PurpleLog*)logs->data, &flags);
gtkconv = PIDGIN_CONVERSATION(c);
+#if 0
+ /* FIXME: WebView has no options */
if (flags & PURPLE_LOG_READ_NO_NEWLINE)
options |= GTK_IMHTML_NO_NEWLINE;
+#endif
+#if 0
+ /* FIXME: WebView has no protocol setting */
protocol = g_strdup(gtk_imhtml_get_protocol_name(GTK_IMHTML(gtkconv->imhtml)));
gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml),
purple_account_get_protocol_name(((PurpleLog*)logs->data)->account));
+#endif
- if (gtk_text_buffer_get_char_count(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml))))
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR>", options);
+ if (!gtk_webview_is_empty(GTK_WEBVIEW(gtkconv->webview)))
+ gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "<BR>");
escaped_alias = g_markup_escape_text(alias, -1);
@@ -134,21 +147,24 @@ static void historize(PurpleConversation *c)
header_date = purple_date_format_full(localtime(&((PurpleLog *)logs->data)->time));
header = g_strdup_printf(_("<b>Conversation with %s on %s:</b><br>"), escaped_alias, header_date);
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), header, options);
+ gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), header);
g_free(header);
g_free(escaped_alias);
g_strchomp(history);
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), history, options);
+ gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), history);
g_free(history);
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<hr>", options);
+ gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "<hr>");
+#if 0
+ /* FIXME: WebView has no protocol setting */
gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol);
g_free(protocol);
+#endif
- g_object_ref(G_OBJECT(gtkconv->imhtml));
- g_idle_add(_scroll_imhtml_to_end, gtkconv->imhtml);
+ g_object_ref(G_OBJECT(gtkconv->webview));
+ g_idle_add(_scroll_webview_to_end, gtkconv->webview);
g_list_foreach(logs, (GFunc)purple_log_free, NULL);
g_list_free(logs);
diff --git a/pidgin/plugins/markerline.c b/pidgin/plugins/markerline.c
index 7db983f3f2..461da4fd61 100644
--- a/pidgin/plugins/markerline.c
+++ b/pidgin/plugins/markerline.c
@@ -33,81 +33,38 @@
/* Purple headers */
#include <gtkconv.h>
-#include <gtkimhtml.h>
#include <gtkplugin.h>
+#include <gtkwebview.h>
#include <version.h>
#define PREF_PREFIX "/plugins/gtk/" PLUGIN_ID
#define PREF_IMS PREF_PREFIX "/ims"
#define PREF_CHATS PREF_PREFIX "/chats"
-static int
-imhtml_expose_cb(GtkWidget *widget, GdkEventExpose *event, PidginConversation *gtkconv)
-{
- int y, last_y, offset;
- GdkRectangle visible_rect;
- GtkTextIter iter;
- GdkRectangle buf;
- int pad;
- PurpleConversation *conv = gtkconv->active_conv;
- PurpleConversationType type = purple_conversation_get_type(conv);
-
- if ((type == PURPLE_CONV_TYPE_CHAT && !purple_prefs_get_bool(PREF_CHATS)) ||
- (type == PURPLE_CONV_TYPE_IM && !purple_prefs_get_bool(PREF_IMS)))
- return FALSE;
-
- gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(widget), &visible_rect);
-
- offset = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "markerline"));
- if (offset)
- {
- gtk_text_buffer_get_iter_at_offset(gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget)),
- &iter, offset);
-
- gtk_text_view_get_iter_location(GTK_TEXT_VIEW(widget), &iter, &buf);
- last_y = buf.y + buf.height;
- pad = (gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(widget)) +
- gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(widget))) / 2;
- last_y += pad;
- }
- else
- last_y = 0;
-
- gtk_text_view_buffer_to_window_coords(GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_TEXT,
- 0, last_y, 0, &y);
-
- if (y >= event->area.y)
- {
- GdkColor red = {0, 0xffff, 0, 0};
- cairo_t *cr = gdk_cairo_create(GDK_DRAWABLE(event->window));
-
- gdk_cairo_set_source_color(cr, &red);
- cairo_move_to(cr, 0.0, y + 0.5);
- cairo_rel_line_to(cr, visible_rect.width, 0.0);
- cairo_set_line_width(cr, 1.0);
- cairo_stroke(cr);
- cairo_destroy(cr);
- }
- return FALSE;
-}
-
static void
update_marker_for_gtkconv(PidginConversation *gtkconv)
{
- GtkTextIter iter;
- GtkTextBuffer *buffer;
+ PurpleConversation *conv;
+ PurpleConversationType type;
+
g_return_if_fail(gtkconv != NULL);
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml));
+ conv = gtkconv->active_conv;
+ type = purple_conversation_get_type(conv);
- if (!gtk_text_buffer_get_char_count(buffer))
+ if ((type == PURPLE_CONV_TYPE_CHAT && !purple_prefs_get_bool(PREF_CHATS)) ||
+ (type == PURPLE_CONV_TYPE_IM && !purple_prefs_get_bool(PREF_IMS)))
return;
- gtk_text_buffer_get_end_iter(buffer, &iter);
-
- g_object_set_data(G_OBJECT(gtkconv->imhtml), "markerline",
- GINT_TO_POINTER(gtk_text_iter_get_offset(&iter)));
- gtk_widget_queue_draw(gtkconv->imhtml);
+ gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview),
+ "var mhr = document.getElementById(\"markerhr\");"
+ "if (!mhr) {"
+ "mhr = document.createElement(\"hr\");"
+ "mhr.setAttribute(\"id\", \"markerhr\");"
+ "mhr.setAttribute(\"color\", \"#ff0000\");"
+ "mhr.setAttribute(\"size\", \"1\");"
+ "}"
+ "document.getElementById(\"Chat\").appendChild(mhr);");
}
static gboolean
@@ -125,28 +82,6 @@ focus_removed(GtkWidget *widget, GdkEventVisibility *event, PidginWindow *win)
return FALSE;
}
-#if 0
-static gboolean
-window_resized(GtkWidget *w, GdkEventConfigure *event, PidginWindow *win)
-{
- GList *list;
-
- list = pidgin_conv_window_get_gtkconvs(win);
-
- for (; list; list = list->next)
- update_marker_for_gtkconv(list->data);
-
- return FALSE;
-}
-
-static gboolean
-imhtml_resize_cb(GtkWidget *w, GtkAllocation *allocation, PidginConversation *gtkconv)
-{
- gtk_widget_queue_draw(w);
- return FALSE;
-}
-#endif
-
static void
page_switched(GtkWidget *widget, GtkWidget *page, gint num, PidginWindow *win)
{
@@ -156,7 +91,9 @@ page_switched(GtkWidget *widget, GtkWidget *page, gint num, PidginWindow *win)
static void
detach_from_gtkconv(PidginConversation *gtkconv, gpointer null)
{
- g_signal_handlers_disconnect_by_func(G_OBJECT(gtkconv->imhtml), imhtml_expose_cb, gtkconv);
+ gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview),
+ "var mhr = document.getElementById(\"markerhr\");"
+ "if (mhr) mhr.parentNode.removeChild(mhr);");
}
static void
@@ -165,16 +102,13 @@ detach_from_pidgin_window(PidginWindow *win, gpointer null)
g_list_foreach(pidgin_conv_window_get_gtkconvs(win), (GFunc)detach_from_gtkconv, NULL);
g_signal_handlers_disconnect_by_func(G_OBJECT(win->notebook), page_switched, win);
g_signal_handlers_disconnect_by_func(G_OBJECT(win->window), focus_removed, win);
-
- gtk_widget_queue_draw(win->window);
}
static void
attach_to_gtkconv(PidginConversation *gtkconv, gpointer null)
{
detach_from_gtkconv(gtkconv, NULL);
- g_signal_connect(G_OBJECT(gtkconv->imhtml), "expose_event",
- G_CALLBACK(imhtml_expose_cb), gtkconv);
+ update_marker_for_gtkconv(gtkconv);
}
static void
@@ -187,8 +121,6 @@ attach_to_pidgin_window(PidginWindow *win, gpointer null)
g_signal_connect(G_OBJECT(win->notebook), "switch_page",
G_CALLBACK(page_switched), win);
-
- gtk_widget_queue_draw(win->window);
}
static void
@@ -220,15 +152,15 @@ static void
jump_to_markerline(PurpleConversation *conv, gpointer null)
{
PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
- int offset;
- GtkTextIter iter;
if (!gtkconv)
return;
- offset = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtkconv->imhtml), "markerline"));
- gtk_text_buffer_get_iter_at_offset(GTK_IMHTML(gtkconv->imhtml)->text_buffer, &iter, offset);
- gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(gtkconv->imhtml), &iter, 0, TRUE, 0, 0);
+ gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview),
+ "var mhr = document.getElementById(\"markerhr\");"
+ "if (mhr) {"
+ "window.scroll(0, mhr.offsetTop);"
+ "}");
}
static void
diff --git a/pidgin/plugins/musicmessaging/musicmessaging.c b/pidgin/plugins/musicmessaging/musicmessaging.c
index 1a735d7c9a..4399f19ed6 100644
--- a/pidgin/plugins/musicmessaging/musicmessaging.c
+++ b/pidgin/plugins/musicmessaging/musicmessaging.c
@@ -104,7 +104,7 @@ void music_messaging_change_request(const int session, const char *command, cons
{
if (mmconv->originator)
{
- char *name = (mmconv->conv)->name;
+ const char *name = purple_conversation_get_name(mmconv->conv);
send_change_request (session, name, command, parameters);
} else
{
@@ -376,7 +376,7 @@ intercept_received(PurpleAccount *account, char **sender, char **message, Purple
if (mmconv->originator)
{
int session = mmconv_from_conv_loc(conv);
- char *id = (mmconv->conv)->name;
+ const char *id = purple_conversation_get_name(mmconv->conv);
char *command;
char *parameters;
@@ -424,7 +424,8 @@ intercept_received(PurpleAccount *account, char **sender, char **message, Purple
command = strtok(NULL, " ");
/* char *parameters = strtok(NULL, "#"); DONT NEED PARAMETERS */
- if ((mmconv->conv)->name == id)
+ // TODO: Shouldn't this be strcmp() ?
+ if (purple_conversation_get_name(mmconv->conv) == id)
{
purple_notify_message(plugin_pointer, PURPLE_NOTIFY_MSG_ERROR,
_("Music Messaging"),
@@ -465,14 +466,14 @@ intercept_received(PurpleAccount *account, char **sender, char **message, Purple
static void send_request(MMConversation *mmconv)
{
- PurpleConnection *connection = purple_conversation_get_gc(mmconv->conv);
+ PurpleConnection *connection = purple_conversation_get_connection(mmconv->conv);
const char *convName = purple_conversation_get_name(mmconv->conv);
serv_send_im(connection, convName, MUSICMESSAGING_START_MSG, PURPLE_MESSAGE_SEND);
}
static void send_request_confirmed(MMConversation *mmconv)
{
- PurpleConnection *connection = purple_conversation_get_gc(mmconv->conv);
+ PurpleConnection *connection = purple_conversation_get_connection(mmconv->conv);
const char *convName = purple_conversation_get_name(mmconv->conv);
serv_send_im(connection, convName, MUSICMESSAGING_CONFIRM_MSG, PURPLE_MESSAGE_SEND);
}
diff --git a/pidgin/plugins/notify.c b/pidgin/plugins/notify.c
index 1e0a38aa8d..fd223d06dd 100644
--- a/pidgin/plugins/notify.c
+++ b/pidgin/plugins/notify.c
@@ -303,7 +303,7 @@ static int
attach_signals(PurpleConversation *conv)
{
PidginConversation *gtkconv = NULL;
- GSList *imhtml_ids = NULL, *entry_ids = NULL;
+ GSList *webview_ids = NULL, *entry_ids = NULL;
guint id;
gtkconv = PIDGIN_CONVERSATION(conv);
@@ -322,9 +322,9 @@ attach_signals(PurpleConversation *conv)
G_CALLBACK(unnotify_cb), conv);
entry_ids = g_slist_append(entry_ids, GUINT_TO_POINTER(id));
- id = g_signal_connect(G_OBJECT(gtkconv->imhtml), "focus-in-event",
+ id = g_signal_connect(G_OBJECT(gtkconv->webview), "focus-in-event",
G_CALLBACK(unnotify_cb), conv);
- imhtml_ids = g_slist_append(imhtml_ids, GUINT_TO_POINTER(id));
+ webview_ids = g_slist_append(webview_ids, GUINT_TO_POINTER(id));
}
if (purple_prefs_get_bool("/plugins/gtk/X11/notify/notify_click")) {
@@ -334,9 +334,9 @@ attach_signals(PurpleConversation *conv)
G_CALLBACK(unnotify_cb), conv);
entry_ids = g_slist_append(entry_ids, GUINT_TO_POINTER(id));
- id = g_signal_connect(G_OBJECT(gtkconv->imhtml), "button-press-event",
+ id = g_signal_connect(G_OBJECT(gtkconv->webview), "button-press-event",
G_CALLBACK(unnotify_cb), conv);
- imhtml_ids = g_slist_append(imhtml_ids, GUINT_TO_POINTER(id));
+ webview_ids = g_slist_append(webview_ids, GUINT_TO_POINTER(id));
}
if (purple_prefs_get_bool("/plugins/gtk/X11/notify/notify_type")) {
@@ -345,7 +345,7 @@ attach_signals(PurpleConversation *conv)
entry_ids = g_slist_append(entry_ids, GUINT_TO_POINTER(id));
}
- purple_conversation_set_data(conv, "notify-imhtml-signals", imhtml_ids);
+ purple_conversation_set_data(conv, "notify-webview-signals", webview_ids);
purple_conversation_set_data(conv, "notify-entry-signals", entry_ids);
return 0;
@@ -361,9 +361,9 @@ detach_signals(PurpleConversation *conv)
if (!gtkconv)
return;
- ids = purple_conversation_get_data(conv, "notify-imhtml-signals");
+ ids = purple_conversation_get_data(conv, "notify-webview-signals");
for (l = ids; l != NULL; l = l->next)
- g_signal_handler_disconnect(gtkconv->imhtml, GPOINTER_TO_INT(l->data));
+ g_signal_handler_disconnect(gtkconv->webview, GPOINTER_TO_INT(l->data));
g_slist_free(ids);
ids = purple_conversation_get_data(conv, "notify-entry-signals");
@@ -373,7 +373,7 @@ detach_signals(PurpleConversation *conv)
purple_conversation_set_data(conv, "notify-message-count", GINT_TO_POINTER(0));
- purple_conversation_set_data(conv, "notify-imhtml-signals", NULL);
+ purple_conversation_set_data(conv, "notify-webview-signals", NULL);
purple_conversation_set_data(conv, "notify-entry-signals", NULL);
}
diff --git a/pidgin/plugins/perl/common/GtkBlist.xs b/pidgin/plugins/perl/common/GtkBlist.xs
index 8dd74fe3d7..453868cd86 100644
--- a/pidgin/plugins/perl/common/GtkBlist.xs
+++ b/pidgin/plugins/perl/common/GtkBlist.xs
@@ -69,8 +69,3 @@ pidgin_blist_joinchat_is_showable()
void
pidgin_blist_joinchat_show()
-
-void
-pidgin_blist_update_account_error_state(account, message)
- Purple::Account account
- const char * message
diff --git a/pidgin/plugins/perl/common/GtkDialogs.xs b/pidgin/plugins/perl/common/GtkDialogs.xs
index 01767b9cb1..0e30194f1c 100644
--- a/pidgin/plugins/perl/common/GtkDialogs.xs
+++ b/pidgin/plugins/perl/common/GtkDialogs.xs
@@ -24,10 +24,6 @@ void
pidgin_dialogs_log()
void
-pidgin_dialogs_alias_contact(contact)
- Purple::BuddyList::Contact contact
-
-void
pidgin_dialogs_alias_buddy(buddy)
Purple::BuddyList::Buddy buddy
diff --git a/pidgin/plugins/perl/common/GtkIMHtml.xs b/pidgin/plugins/perl/common/GtkIMHtml.xs
index 992cb6b7f2..8a76f05576 100644
--- a/pidgin/plugins/perl/common/GtkIMHtml.xs
+++ b/pidgin/plugins/perl/common/GtkIMHtml.xs
@@ -77,26 +77,6 @@ gtk_imhtml_get_text(imhtml, start, end)
Gtk::TextIter end
*/
-/* This can't work at the moment since I don't have a typemap for Gdk::Pixbuf.
- * I thought about using the one from libgtk2-perl but wasn't sure how to go
- * about doing that.
-Pidgin::IMHtml::Scalable
-gtk_imhtml_image_new(img, filename, id)
- Gdk::Pixbuf img
- const gchar * filename
- int id
-*/
-
-/* This can't work at the moment since I don't have a typemap for Gtk::Widget.
- * I thought about using the one from libgtk2-perl but wasn't sure how to go
- * about doing that.
-void
-gtk_imhtml_image_add_to(scale, imhtml, iter)
- Pidgin::IMHtml::Scalable scale
- Pidgin::IMHtml imhtml
- Gtk::TextIter iter
-*/
-
/* This can't work at the moment since I don't have a typemap for Gtk::Widget.
* I thought about using the one from libgtk2-perl but wasn't sure how to go
* about doing that.
@@ -323,19 +303,6 @@ PPCODE:
}
XPUSHs(sv_2mortal(newRV_noinc((SV *)lines)));
-MODULE = Pidgin::IMHtml PACKAGE = Pidgin::IMHtml::Scalable PREFIX = gtk_imhtml_image_
-PROTOTYPES: ENABLE
-
-void
-gtk_imhtml_image_free(scale)
- Pidgin::IMHtml::Scalable scale
-
-void
-gtk_imhtml_image_scale(scale, width, height)
- Pidgin::IMHtml::Scalable scale
- int width
- int height
-
MODULE = Pidgin::IMHtml PACKAGE = Pidgin::IMHtml::Hr PREFIX = gtk_imhtml_hr_
PROTOTYPES: ENABLE
diff --git a/pidgin/plugins/relnot.c b/pidgin/plugins/relnot.c
index 3e2aa85504..2c381fe354 100644
--- a/pidgin/plugins/relnot.c
+++ b/pidgin/plugins/relnot.c
@@ -152,7 +152,7 @@ do_check(void)
url,
host);
- purple_util_fetch_url_request_len(url, TRUE, NULL, FALSE,
+ purple_util_fetch_url_request(NULL, url, TRUE, NULL, FALSE,
request, TRUE, -1, version_fetch_cb, NULL);
g_free(request);
diff --git a/pidgin/plugins/themeedit.c b/pidgin/plugins/themeedit.c
index 0290d36075..de4a2abf90 100644
--- a/pidgin/plugins/themeedit.c
+++ b/pidgin/plugins/themeedit.c
@@ -306,7 +306,9 @@ pidgin_blist_theme_edit(PurplePluginAction *unused)
}
}
+#if !GTK_CHECK_VERSION(2,22,0)
gtk_dialog_set_has_separator(GTK_DIALOG(dialog), TRUE);
+#endif
#ifdef NOT_SADRUL
pidgin_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_SAVE, G_CALLBACK(save_blist_theme), dialog);
#endif
diff --git a/pidgin/plugins/ticker/gtkticker.c b/pidgin/plugins/ticker/gtkticker.c
index 38ce49ed6e..56bc388187 100644
--- a/pidgin/plugins/ticker/gtkticker.c
+++ b/pidgin/plugins/ticker/gtkticker.c
@@ -21,28 +21,24 @@
* GtkTicker Copyright 2000 Syd Logan
*/
-/* FIXME: GTK+ deprecated GTK_WIDGET_MAPPED/REALIZED, but don't provide
- accessor functions yet. */
-#undef GSEAL_ENABLE
-
#include "gtkticker.h"
#include <gtk/gtk.h>
-/* These don't seem to be in a release yet. See BZ #69872 */
-#define gtk_widget_is_mapped(x) GTK_WIDGET_MAPPED(x)
-#define gtk_widget_is_realized(x) GTK_WIDGET_REALIZED(x)
-#define gtk_widget_set_realized(x,y) do {\
- if (y) \
- GTK_WIDGET_SET_FLAGS(x, GTK_REALIZED); \
- else \
- GTK_WIDGET_UNSET_FLAGS(x, GTK_REALIZED); \
-} while(0)
+#if !GTK_CHECK_VERSION(2,20,0)
+#define gtk_widget_get_mapped(x) GTK_WIDGET_MAPPED(x)
#define gtk_widget_set_mapped(x,y) do {\
if (y) \
GTK_WIDGET_SET_FLAGS(x, GTK_MAPPED); \
else \
GTK_WIDGET_UNSET_FLAGS(x, GTK_MAPPED); \
} while(0)
+#define gtk_widget_get_realized(x) GTK_WIDGET_REALIZED(x)
+#define gtk_widget_set_realized(x,y) do {\
+ if (y) \
+ GTK_WIDGET_SET_FLAGS(x, GTK_REALIZED); \
+ else \
+ GTK_WIDGET_UNSET_FLAGS(x, GTK_REALIZED); \
+} while(0)
#if !GTK_CHECK_VERSION(2,18,0)
#define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x)
@@ -51,6 +47,7 @@
#define gtk_widget_get_window(x) x->window
#endif
#endif
+#endif
static void gtk_ticker_compute_offsets (GtkTicker *ticker);
static void gtk_ticker_class_init (GtkTickerClass *klass);
@@ -181,13 +178,13 @@ static void gtk_ticker_put (GtkTicker *ticker, GtkWidget *widget)
ticker->children = g_list_append (ticker->children, child_info);
- if (gtk_widget_is_realized (ticker))
+ if (gtk_widget_get_realized (GTK_WIDGET (ticker)))
gtk_widget_realize (widget);
if (gtk_widget_get_visible (GTK_WIDGET (ticker)) &&
gtk_widget_get_visible (widget))
{
- if (gtk_widget_is_mapped (GTK_WIDGET (ticker)))
+ if (gtk_widget_get_mapped (GTK_WIDGET (ticker)))
gtk_widget_map (widget);
gtk_widget_queue_resize (GTK_WIDGET (ticker));
@@ -298,7 +295,7 @@ static void gtk_ticker_map (GtkWidget *widget)
children = children->next;
if (gtk_widget_get_visible (child->widget) &&
- !gtk_widget_is_mapped (child->widget))
+ !gtk_widget_get_mapped (child->widget))
gtk_widget_map (child->widget);
}
@@ -474,7 +471,7 @@ static void gtk_ticker_size_allocate (GtkWidget *widget,
#else
widget->allocation = *allocation;
#endif
- if (gtk_widget_is_realized (widget))
+ if (gtk_widget_get_realized (widget))
gdk_window_move_resize (gtk_widget_get_window (widget),
allocation->x,
allocation->y,
diff --git a/pidgin/plugins/vvconfig.c b/pidgin/plugins/vvconfig.c
index 93d85be586..cafdb2a823 100644
--- a/pidgin/plugins/vvconfig.c
+++ b/pidgin/plugins/vvconfig.c
@@ -39,6 +39,7 @@ static const gchar *AUDIO_SRC_PLUGINS[] = {
/* "esdmon", "ESD", ? */
"osssrc", "OSS",
"pulsesrc", "PulseAudio",
+ "libsndiosrc", "sndio",
/* "audiotestsrc wave=silence", "Silence", */
"audiotestsrc", "Test Sound",
NULL
@@ -50,6 +51,7 @@ static const gchar *AUDIO_SINK_PLUGINS[] = {
"esdsink", "ESD",
"osssink", "OSS",
"pulsesink", "PulseAudio",
+ "libsndiosink", "sndio",
NULL
};
@@ -610,7 +612,7 @@ gst_bus_cb(GstBus *bus, GstMessage *msg, BusCbCtx *ctx)
GstElement *valve;
percent = gst_msg_db_to_percent(msg, "rms");
- gtk_progress_bar_set_fraction(ctx->level, percent * 5);
+ gtk_progress_bar_set_fraction(ctx->level, percent);
percent = gst_msg_db_to_percent(msg, "decay");
threshold = gtk_range_get_value(ctx->threshold) / 100.0;
@@ -627,7 +629,7 @@ gst_bus_cb(GstBus *bus, GstMessage *msg, BusCbCtx *ctx)
}
static void
-voice_test_frame_destroy_cb(GtkObject *w, GstElement *pipeline)
+voice_test_frame_destroy_cb(GtkWidget *w, GstElement *pipeline)
{
g_return_if_fail(GST_IS_ELEMENT(pipeline));
@@ -702,7 +704,7 @@ get_voice_test_frame(PurplePlugin *plugin)
gtk_range_set_value(GTK_RANGE(volume),
purple_prefs_get_int("/purple/media/audio/volume/input"));
- gtk_widget_set(volume, "draw-value", FALSE, NULL);
+ gtk_scale_set_draw_value(GTK_SCALE(volume), FALSE);
gtk_range_set_value(GTK_RANGE(threshold),
purple_prefs_get_int("/purple/media/audio/silence_threshold"));
diff --git a/pidgin/plugins/webkit.c b/pidgin/plugins/webkit.c
new file mode 100644
index 0000000000..d80c481732
--- /dev/null
+++ b/pidgin/plugins/webkit.c
@@ -0,0 +1,197 @@
+/*
+ * WebKit - Open the inspector on any WebKit views.
+ * Copyright (C) 2011 Elliott Sales de Andrade <qulogic@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 "internal.h"
+
+#include "version.h"
+
+#include "pidgin.h"
+
+#include "gtkconv.h"
+#include "gtkplugin.h"
+#include "gtkwebview.h"
+
+static WebKitWebView *
+create_gtk_window_around_it(WebKitWebInspector *inspector,
+ WebKitWebView *webview,
+ PidginConversation *gtkconv)
+{
+ GtkWidget *win;
+ GtkWidget *view;
+ char *title;
+
+ win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ title = g_strdup_printf(_("%s - Inspector"),
+ gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)));
+ gtk_window_set_title(GTK_WINDOW(win), title);
+ g_free(title);
+ gtk_window_set_default_size(GTK_WINDOW(win), 600, 400);
+ g_signal_connect_swapped(G_OBJECT(gtkconv->tab_cont), "destroy", G_CALLBACK(gtk_widget_destroy), win);
+
+ view = webkit_web_view_new();
+ gtk_container_add(GTK_CONTAINER(win), view);
+ g_object_set_data(G_OBJECT(webview), "inspector-window", win);
+
+ return WEBKIT_WEB_VIEW(view);
+}
+
+static gboolean
+show_inspector_window(WebKitWebInspector *inspector,
+ GtkWidget *webview)
+{
+ GtkWidget *win;
+
+ win = g_object_get_data(G_OBJECT(webview), "inspector-window");
+
+ gtk_widget_show_all(win);
+
+ return TRUE;
+}
+
+static void
+setup_inspector(PidginConversation *gtkconv)
+{
+ GtkWidget *webview = gtkconv->webview;
+ WebKitWebSettings *settings;
+ WebKitWebInspector *inspector;
+
+ settings = webkit_web_view_get_settings(WEBKIT_WEB_VIEW(webview));
+ inspector = webkit_web_view_get_inspector(WEBKIT_WEB_VIEW(webview));
+
+ g_object_set(G_OBJECT(settings), "enable-developer-extras", TRUE, NULL);
+
+ g_signal_connect(G_OBJECT(inspector), "inspect-web-view",
+ G_CALLBACK(create_gtk_window_around_it), gtkconv);
+ g_signal_connect(G_OBJECT(inspector), "show-window",
+ G_CALLBACK(show_inspector_window), webview);
+}
+
+static void
+remove_inspector(PidginConversation *gtkconv)
+{
+ GtkWidget *webview = gtkconv->webview;
+ GtkWidget *win;
+ WebKitWebSettings *settings;
+
+ win = g_object_get_data(G_OBJECT(webview), "inspector-window");
+ gtk_widget_destroy(win);
+ g_object_set_data(G_OBJECT(webview), "inspector-window", NULL);
+
+ settings = webkit_web_view_get_settings(WEBKIT_WEB_VIEW(webview));
+
+ g_object_set(G_OBJECT(settings), "enable-developer-extras", FALSE, NULL);
+}
+
+static void
+conversation_displayed_cb(PidginConversation *gtkconv)
+{
+ GtkWidget *inspect = NULL;
+
+ inspect = g_object_get_data(G_OBJECT(gtkconv->webview),
+ "inspector-window");
+ if (inspect == NULL) {
+ setup_inspector(gtkconv);
+ }
+}
+
+static gboolean
+plugin_load(PurplePlugin *plugin)
+{
+ GList *convs = purple_get_conversations();
+ void *gtk_conv_handle = pidgin_conversations_get_handle();
+
+ purple_signal_connect(gtk_conv_handle, "conversation-displayed", plugin,
+ PURPLE_CALLBACK(conversation_displayed_cb), NULL);
+
+ while (convs) {
+ PurpleConversation *conv = (PurpleConversation *)convs->data;
+
+ /* Setup WebKit Inspector */
+ if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) {
+ setup_inspector(PIDGIN_CONVERSATION(conv));
+ }
+
+ convs = convs->next;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+plugin_unload(PurplePlugin *plugin)
+{
+ GList *convs = purple_get_conversations();
+
+ while (convs) {
+ PurpleConversation *conv = (PurpleConversation *)convs->data;
+
+ /* Remove WebKit Inspector */
+ if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) {
+ remove_inspector(PIDGIN_CONVERSATION(conv));
+ }
+
+ convs = convs->next;
+ }
+
+ return TRUE;
+}
+
+static PurplePluginInfo info =
+{
+ PURPLE_PLUGIN_MAGIC,
+ PURPLE_MAJOR_VERSION, /**< major version */
+ PURPLE_MINOR_VERSION, /**< minor version */
+ PURPLE_PLUGIN_STANDARD, /**< type */
+ PIDGIN_PLUGIN_TYPE, /**< ui_requirement */
+ 0, /**< flags */
+ NULL, /**< dependencies */
+ PURPLE_PRIORITY_DEFAULT, /**< priority */
+
+ "gtkwebkit-inspect", /**< id */
+ N_("WebKit Development"), /**< name */
+ DISPLAY_VERSION, /**< version */
+ N_("Enables WebKit Inspector."), /**< summary */
+ N_("Enables WebKit's built-in inspector in a "
+ "conversation window. This may be viewed "
+ "by right-clicking a WebKit widget and "
+ "selecting 'Inspect Element'."), /**< description */
+ "Elliott Sales de Andrade <qulogic@pidgin.im>", /**< author */
+ PURPLE_WEBSITE, /**< homepage */
+ plugin_load, /**< load */
+ plugin_unload, /**< unload */
+ NULL, /**< destroy */
+ NULL, /**< ui_info */
+ NULL, /**< extra_info */
+ NULL, /**< prefs_info */
+ NULL, /**< actions */
+
+ /* padding */
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static void
+init_plugin(PurplePlugin *plugin)
+{
+}
+
+PURPLE_INIT_PLUGIN(webkit-devel, init_plugin, info)
+
diff --git a/pidgin/plugins/xmppconsole.c b/pidgin/plugins/xmppconsole.c
index 6fcd66ac91..78da0e135e 100644
--- a/pidgin/plugins/xmppconsole.c
+++ b/pidgin/plugins/xmppconsole.c
@@ -26,14 +26,17 @@
#include "xmlnode.h"
#include "gtkimhtml.h"
+#include "gtkwebview.h"
#include "gtkutils.h"
+#include <gdk/gdkkeysyms.h>
+
typedef struct {
PurpleConnection *gc;
GtkWidget *window;
GtkWidget *hbox;
GtkWidget *dropdown;
- GtkWidget *imhtml;
+ GtkWidget *webview;
GtkWidget *entry;
GtkWidget *sw;
int count;
@@ -43,31 +46,34 @@ typedef struct {
XmppConsole *console = NULL;
static void *xmpp_console_handle = NULL;
-#define BRACKET_COLOR "#940f8c"
-#define TAG_COLOR "#8b1dab"
-#define ATTR_NAME_COLOR "#a02961"
-#define ATTR_VALUE_COLOR "#324aa4"
-#define XMLNS_COLOR "#2cb12f"
+#define EMPTY_HTML \
+"<html><head><style type='text/css'>" \
+ "body { word-wrap: break-word; margin: 0; }" \
+ "div.tab { padding-left: 1em; }" \
+ "div.info { color: #777777; }" \
+ "div.incoming { background-color: #ffcece; }" \
+ "div.outgoing { background-color: #dcecc4; }" \
+ "span.bracket { color: #940f8c; }" \
+ "span.tag { color: #8b1dab; font-weight: bold; }" \
+ "span.attr { color: #a02961; font-weight: bold; }" \
+ "span.value { color: #324aa4; }" \
+ "span.xmlns { color: #2cb12f; font-weight: bold;}" \
+"</style></head></html>"
static char *
-xmlnode_to_pretty_str(xmlnode *node, int *len, int depth)
+xmlnode_to_pretty_str(xmlnode *node, int *len)
{
GString *text = g_string_new("");
xmlnode *c;
- char *node_name, *esc, *esc2, *tab = NULL;
+ char *node_name, *esc, *esc2;
gboolean need_end = FALSE, pretty = TRUE;
g_return_val_if_fail(node != NULL, NULL);
- if (pretty && depth) {
- tab = g_strnfill(depth, '\t');
- text = g_string_append(text, tab);
- }
-
node_name = g_markup_escape_text(node->name, -1);
g_string_append_printf(text,
- "<font color='" BRACKET_COLOR "'>&lt;</font>"
- "<font color='" TAG_COLOR "'><b>%s</b></font>",
+ "<span class=bracket>&lt;</span>"
+ "<span class=tag>%s</span>",
node_name);
if (node->xmlns) {
@@ -78,8 +84,8 @@ xmlnode_to_pretty_str(xmlnode *node, int *len, int depth)
{
char *xmlns = g_markup_escape_text(node->xmlns, -1);
g_string_append_printf(text,
- " <font color='" ATTR_NAME_COLOR "'><b>xmlns</b></font>="
- "'<font color='" XMLNS_COLOR "'><b>%s</b></font>'",
+ " <span class=attr>xmlns</span>="
+ "'<span class=xmlns>%s</span>'",
xmlns);
g_free(xmlns);
}
@@ -90,8 +96,8 @@ xmlnode_to_pretty_str(xmlnode *node, int *len, int depth)
esc = g_markup_escape_text(c->name, -1);
esc2 = g_markup_escape_text(c->data, -1);
g_string_append_printf(text,
- " <font color='" ATTR_NAME_COLOR "'><b>%s</b></font>="
- "'<font color='" ATTR_VALUE_COLOR "'>%s</font>'",
+ " <span class=attr>%s</span>="
+ "'<span class=value>%s</span>'",
esc, esc2);
g_free(esc);
g_free(esc2);
@@ -104,14 +110,19 @@ xmlnode_to_pretty_str(xmlnode *node, int *len, int depth)
if (need_end) {
g_string_append_printf(text,
- "<font color='"BRACKET_COLOR"'>&gt;</font>%s",
+ "<span class=bracket>&gt;</span>%s",
pretty ? "<br>" : "");
+ need_end = FALSE;
for (c = node->child; c; c = c->next)
{
if (c->type == XMLNODE_TYPE_TAG) {
int esc_len;
- esc = xmlnode_to_pretty_str(c, &esc_len, depth+1);
+ esc = xmlnode_to_pretty_str(c, &esc_len);
+ if (!need_end) {
+ g_string_append(text, "<div class=tab>");
+ need_end = TRUE;
+ }
text = g_string_append_len(text, esc, esc_len);
g_free(esc);
} else if (c->type == XMLNODE_TYPE_DATA && c->data_sz > 0) {
@@ -121,23 +132,22 @@ xmlnode_to_pretty_str(xmlnode *node, int *len, int depth)
}
}
- if(tab && pretty)
- text = g_string_append(text, tab);
+ if (need_end)
+ g_string_append(text, "</div>");
+
g_string_append_printf(text,
- "<font color='" BRACKET_COLOR "'>&lt;</font>/"
- "<font color='" TAG_COLOR "'><b>%s</b></font>"
- "<font color='" BRACKET_COLOR "'>&gt;</font><br>",
+ "<span class=bracket>&lt;</span>/"
+ "<span class=tag>%s</span>"
+ "<span class=bracket>&gt;</span><br>",
node_name);
} else {
g_string_append_printf(text,
- "/<font color='" BRACKET_COLOR "'>&gt;</font><br>");
+ "/<span class=bracket>&gt;</span><br>");
}
g_free(node_name);
- g_free(tab);
-
- if(len)
+ if (len)
*len = text->len;
return g_string_free(text, FALSE);
@@ -150,9 +160,9 @@ xmlnode_received_cb(PurpleConnection *gc, xmlnode **packet, gpointer null)
if (!console || console->gc != gc)
return;
- str = xmlnode_to_pretty_str(*packet, NULL, 0);
- formatted = g_strdup_printf("<body bgcolor='#ffcece'><pre>%s</pre></body>", str);
- gtk_imhtml_append_text(GTK_IMHTML(console->imhtml), formatted, 0);
+ str = xmlnode_to_pretty_str(*packet, NULL);
+ formatted = g_strdup_printf("<div class=incoming>%s</div>", str);
+ gtk_webview_append_html(GTK_WEBVIEW(console->webview), formatted);
g_free(formatted);
g_free(str);
}
@@ -171,52 +181,55 @@ xmlnode_sent_cb(PurpleConnection *gc, char **packet, gpointer null)
if (!node)
return;
- str = xmlnode_to_pretty_str(node, NULL, 0);
- formatted = g_strdup_printf("<body bgcolor='#dcecc4'><pre>%s</pre></body>", str);
- gtk_imhtml_append_text(GTK_IMHTML(console->imhtml), formatted, 0);
+ str = xmlnode_to_pretty_str(node, NULL);
+ formatted = g_strdup_printf("<div class=outgoing>%s</div>", str);
+ gtk_webview_append_html(GTK_WEBVIEW(console->webview), formatted);
g_free(formatted);
g_free(str);
xmlnode_free(node);
}
-static void message_send_cb(GtkWidget *widget, gpointer p)
+static gboolean
+message_send_cb(GtkWidget *widget, GdkEventKey *event, gpointer p)
{
- GtkTextIter start, end;
PurplePluginProtocolInfo *prpl_info = NULL;
PurpleConnection *gc;
- GtkTextBuffer *buffer;
- char *text;
+ gchar *text;
+
+ if (event->keyval != GDK_KEY_KP_Enter && event->keyval != GDK_KEY_Return)
+ return FALSE;
gc = console->gc;
if (gc)
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
-
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(console->entry));
- gtk_text_buffer_get_start_iter(buffer, &start);
- gtk_text_buffer_get_end_iter(buffer, &end);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
- text = gtk_imhtml_get_text(GTK_IMHTML(console->entry), &start, &end);
+ text = gtk_webview_get_body_text(GTK_WEBVIEW(widget));
if (prpl_info && prpl_info->send_raw != NULL)
prpl_info->send_raw(gc, text, strlen(text));
g_free(text);
- gtk_imhtml_clear(GTK_IMHTML(console->entry));
+ gtk_webview_load_html_string(GTK_WEBVIEW(console->entry), "");
+
+ return TRUE;
}
-static void entry_changed_cb(GtkTextBuffer *buffer, void *data)
+static void
+entry_changed_cb(GtkWidget *webview, void *data)
{
char *xmlstr, *str;
- GtkTextIter iter;
+#if 0
int wrapped_lines;
int lines;
GdkRectangle oneline;
int height;
int pad_top, pad_inside, pad_bottom;
- GtkTextIter start, end;
+#endif
xmlnode *node;
+#if 0
+ /* TODO WebKit: Do entry auto-sizing... */
wrapped_lines = 1;
gtk_text_buffer_get_start_iter(buffer, &iter);
gtk_text_view_get_iter_location(GTK_TEXT_VIEW(console->entry), &iter, &oneline);
@@ -237,18 +250,17 @@ static void entry_changed_cb(GtkTextBuffer *buffer, void *data)
height += (oneline.height + pad_inside) * (wrapped_lines - lines);
gtk_widget_set_size_request(console->sw, -1, height + 6);
+#endif
- gtk_text_buffer_get_start_iter(buffer, &start);
- gtk_text_buffer_get_end_iter(buffer, &end);
- str = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
+ str = gtk_webview_get_body_text(GTK_WEBVIEW(webview));
if (!str)
return;
xmlstr = g_strdup_printf("<xml>%s</xml>", str);
node = xmlnode_from_str(xmlstr, -1);
if (node) {
- gtk_imhtml_clear_formatting(GTK_IMHTML(console->entry));
+ gtk_webview_clear_formatting(GTK_WEBVIEW(console->entry));
} else {
- gtk_imhtml_toggle_background(GTK_IMHTML(console->entry), "#ffcece");
+ gtk_webview_toggle_backcolor(GTK_WEBVIEW(console->entry), "#ffcece");
}
g_free(str);
g_free(xmlstr);
@@ -260,9 +272,7 @@ static void iq_clicked_cb(GtkWidget *w, gpointer nul)
{
GtkWidget *vbox, *hbox, *to_entry, *label, *type_combo;
GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
- GtkTextIter iter;
- GtkTextBuffer *buffer;
- const char *to;
+ char *to;
int result;
char *stanza;
@@ -274,7 +284,9 @@ static void iq_clicked_cb(GtkWidget *w, gpointer nul)
GTK_STOCK_OK,
GTK_RESPONSE_ACCEPT,
NULL);
+#if !GTK_CHECK_VERSION(2,22,0)
gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+#endif
gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);
#if GTK_CHECK_VERSION(2,14,0)
@@ -318,19 +330,20 @@ static void iq_clicked_cb(GtkWidget *w, gpointer nul)
return;
}
- to = gtk_entry_get_text(GTK_ENTRY(to_entry));
+ to = g_markup_escape_text(gtk_entry_get_text(GTK_ENTRY(to_entry)), -1);
- stanza = g_strdup_printf("<iq %s%s%s id='console%x' type='%s'></iq>",
+ stanza = g_strdup_printf("&lt;iq %s%s%s id='console%x' type='%s'&gt;"
+ "<a id=caret></a>"
+ "&lt;/iq&gt;",
to && *to ? "to='" : "",
to && *to ? to : "",
to && *to ? "'" : "",
g_random_int(),
gtk_combo_box_get_active_text(GTK_COMBO_BOX(type_combo)));
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(console->entry));
- gtk_text_buffer_set_text(buffer, stanza, -1);
- gtk_text_buffer_get_iter_at_offset(buffer, &iter, strstr(stanza, "</iq>") - stanza);
- gtk_text_buffer_place_cursor(buffer, &iter);
+ gtk_webview_load_html_string_with_selection(GTK_WEBVIEW(console->entry), stanza);
+ gtk_widget_grab_focus(console->entry);
+ g_free(to);
g_free(stanza);
gtk_widget_destroy(dialog);
@@ -348,9 +361,8 @@ static void presence_clicked_cb(GtkWidget *w, gpointer nul)
GtkWidget *show_combo;
GtkWidget *type_combo;
GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
- GtkTextIter iter;
- GtkTextBuffer *buffer;
- const char *to, *type, *status, *show, *priority;
+ char *to, *status, *priority;
+ const char *type, *show;
int result;
char *stanza;
@@ -362,7 +374,9 @@ static void presence_clicked_cb(GtkWidget *w, gpointer nul)
GTK_STOCK_OK,
GTK_RESPONSE_ACCEPT,
NULL);
+#if !GTK_CHECK_VERSION(2,22,0)
gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+#endif
gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);
#if GTK_CHECK_VERSION(2,14,0)
@@ -449,21 +463,22 @@ static void presence_clicked_cb(GtkWidget *w, gpointer nul)
return;
}
- to = gtk_entry_get_text(GTK_ENTRY(to_entry));
+ to = g_markup_escape_text(gtk_entry_get_text(GTK_ENTRY(to_entry)), -1);
type = gtk_combo_box_get_active_text(GTK_COMBO_BOX(type_combo));
if (!strcmp(type, "default"))
type = "";
show = gtk_combo_box_get_active_text(GTK_COMBO_BOX(show_combo));
if (!strcmp(show, "default"))
show = "";
- status = gtk_entry_get_text(GTK_ENTRY(status_entry));
- priority = gtk_entry_get_text(GTK_ENTRY(priority_entry));
+ status = g_markup_escape_text(gtk_entry_get_text(GTK_ENTRY(status_entry)), -1);
+ priority = g_markup_escape_text(gtk_entry_get_text(GTK_ENTRY(priority_entry)), -1);
if (!strcmp(priority, "0"))
- priority = "";
+ *priority = '\0';
- stanza = g_strdup_printf("<presence %s%s%s id='console%x' %s%s%s>"
+ stanza = g_strdup_printf("&lt;presence %s%s%s id='console%x' %s%s%s&gt;"
"%s%s%s%s%s%s%s%s%s"
- "</presence>",
+ "<a id=caret></a>"
+ "&lt;/presence&gt;",
*to ? "to='" : "",
*to ? to : "",
*to ? "'" : "",
@@ -473,23 +488,24 @@ static void presence_clicked_cb(GtkWidget *w, gpointer nul)
*type ? type : "",
*type ? "'" : "",
- *show ? "<show>" : "",
+ *show ? "&lt;show&gt;" : "",
*show ? show : "",
- *show ? "</show>" : "",
+ *show ? "&lt;/show&gt;" : "",
- *status ? "<status>" : "",
+ *status ? "&lt;status&gt;" : "",
*status ? status : "",
- *status ? "</status>" : "",
+ *status ? "&lt;/status&gt;" : "",
- *priority ? "<priority>" : "",
+ *priority ? "&lt;priority&gt;" : "",
*priority ? priority : "",
- *priority ? "</priority>" : "");
+ *priority ? "&lt;/priority&gt;" : "");
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(console->entry));
- gtk_text_buffer_set_text(buffer, stanza, -1);
- gtk_text_buffer_get_iter_at_offset(buffer, &iter, strstr(stanza, "</presence>") - stanza);
- gtk_text_buffer_place_cursor(buffer, &iter);
+ gtk_webview_load_html_string_with_selection(GTK_WEBVIEW(console->entry), stanza);
+ gtk_widget_grab_focus(console->entry);
g_free(stanza);
+ g_free(to);
+ g_free(status);
+ g_free(priority);
gtk_widget_destroy(dialog);
g_object_unref(sg);
@@ -506,9 +522,7 @@ static void message_clicked_cb(GtkWidget *w, gpointer nul)
GtkWidget *label;
GtkWidget *type_combo;
GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
- GtkTextIter iter;
- GtkTextBuffer *buffer;
- const char *to, *body, *thread, *subject;
+ char *to, *body, *thread, *subject;
char *stanza;
int result;
@@ -520,7 +534,9 @@ static void message_clicked_cb(GtkWidget *w, gpointer nul)
GTK_STOCK_OK,
GTK_RESPONSE_ACCEPT,
NULL);
+#if !GTK_CHECK_VERSION(2,22,0)
gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+#endif
gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);
#if GTK_CHECK_VERSION(2,14,0)
@@ -600,14 +616,15 @@ static void message_clicked_cb(GtkWidget *w, gpointer nul)
return;
}
- to = gtk_entry_get_text(GTK_ENTRY(to_entry));
- body = gtk_entry_get_text(GTK_ENTRY(body_entry));
- thread = gtk_entry_get_text(GTK_ENTRY(thread_entry));
- subject = gtk_entry_get_text(GTK_ENTRY(subject_entry));
+ to = g_markup_escape_text(gtk_entry_get_text(GTK_ENTRY(to_entry)), -1);
+ body = g_markup_escape_text(gtk_entry_get_text(GTK_ENTRY(body_entry)), -1);
+ thread = g_markup_escape_text(gtk_entry_get_text(GTK_ENTRY(thread_entry)), -1);
+ subject = g_markup_escape_text(gtk_entry_get_text(GTK_ENTRY(subject_entry)), -1);
- stanza = g_strdup_printf("<message %s%s%s id='console%x' type='%s'>"
+ stanza = g_strdup_printf("&lt;message %s%s%s id='console%x' type='%s'&gt;"
"%s%s%s%s%s%s%s%s%s"
- "</message>",
+ "<a id=caret></a>"
+ "&lt;/message&gt;",
*to ? "to='" : "",
*to ? to : "",
@@ -615,23 +632,25 @@ static void message_clicked_cb(GtkWidget *w, gpointer nul)
g_random_int(),
gtk_combo_box_get_active_text(GTK_COMBO_BOX(type_combo)),
- *body ? "<body>" : "",
+ *body ? "&lt;body&gt;" : "",
*body ? body : "",
- *body ? "</body>" : "",
+ *body ? "&lt;/body&gt;" : "",
- *subject ? "<subject>" : "",
+ *subject ? "&lt;subject&gt;" : "",
*subject ? subject : "",
- *subject ? "</subject>" : "",
+ *subject ? "&lt;/subject&gt;" : "",
- *thread ? "<thread>" : "",
+ *thread ? "&lt;thread&gt;" : "",
*thread ? thread : "",
- *thread ? "</thread>" : "");
+ *thread ? "&lt;/thread&gt;" : "");
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(console->entry));
- gtk_text_buffer_set_text(buffer, stanza, -1);
- gtk_text_buffer_get_iter_at_offset(buffer, &iter, strstr(stanza, "</message>") - stanza);
- gtk_text_buffer_place_cursor(buffer, &iter);
+ gtk_webview_load_html_string_with_selection(GTK_WEBVIEW(console->entry), stanza);
+ gtk_widget_grab_focus(console->entry);
g_free(stanza);
+ g_free(to);
+ g_free(body);
+ g_free(thread);
+ g_free(subject);
gtk_widget_destroy(dialog);
g_object_unref(sg);
@@ -640,16 +659,24 @@ static void message_clicked_cb(GtkWidget *w, gpointer nul)
static void
signing_on_cb(PurpleConnection *gc)
{
+ PurpleAccount *account;
+
if (!console)
return;
- gtk_combo_box_append_text(GTK_COMBO_BOX(console->dropdown), purple_account_get_username(gc->account));
+ account = purple_connection_get_account(gc);
+ if (strcmp(purple_account_get_protocol_id(account), "prpl-jabber"))
+ return;
+
+ gtk_combo_box_append_text(GTK_COMBO_BOX(console->dropdown), purple_account_get_username(account));
console->accounts = g_list_append(console->accounts, gc);
console->count++;
- if (console->count == 1)
+ if (console->count == 1) {
console->gc = gc;
- else
+ gtk_webview_load_html_string(GTK_WEBVIEW(console->webview), EMPTY_HTML);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(console->dropdown), 0);
+ } else
gtk_widget_show_all(console->hbox);
}
@@ -679,9 +706,11 @@ signed_off_cb(PurpleConnection *gc)
console->count--;
if (gc == console->gc) {
+ char *tmp = g_strdup_printf("<div class=info>%s</div>",
+ _("Logged out."));
+ gtk_webview_append_html(GTK_WEBVIEW(console->webview), tmp);
+ g_free(tmp);
console->gc = NULL;
- gtk_imhtml_append_text(GTK_IMHTML(console->imhtml),
- _("<font color='#777777'>Logged out.</font>"), 0);
}
}
@@ -726,18 +755,11 @@ console_destroy(GtkObject *window, gpointer nul)
static void
dropdown_changed_cb(GtkComboBox *widget, gpointer nul)
{
- PurpleAccount *account;
-
if (!console)
return;
- account = purple_accounts_find(gtk_combo_box_get_active_text(GTK_COMBO_BOX(console->dropdown)),
- "prpl-jabber");
- if (!account || !account->gc)
- return;
-
- console->gc = account->gc;
- gtk_imhtml_clear(GTK_IMHTML(console->imhtml));
+ console->gc = g_list_nth_data(console->accounts, gtk_combo_box_get_active(GTK_COMBO_BOX(console->dropdown)));
+ gtk_webview_load_html_string(GTK_WEBVIEW(console->webview), EMPTY_HTML);
}
static void
@@ -745,7 +767,6 @@ create_console(PurplePluginAction *action)
{
GtkWidget *vbox = gtk_vbox_new(FALSE, 6);
GtkWidget *label;
- GtkTextBuffer *buffer;
GtkWidget *toolbar;
GList *connections;
GtkToolItem *button;
@@ -779,44 +800,50 @@ create_console(PurplePluginAction *action)
console->gc = gc;
}
}
- gtk_combo_box_set_active(GTK_COMBO_BOX(console->dropdown),0);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(console->dropdown), 0);
gtk_box_pack_start(GTK_BOX(console->hbox), console->dropdown, TRUE, TRUE, 0);
g_signal_connect(G_OBJECT(console->dropdown), "changed", G_CALLBACK(dropdown_changed_cb), NULL);
- console->imhtml = gtk_imhtml_new(NULL, NULL);
- if (console->count == 0)
- gtk_imhtml_append_text(GTK_IMHTML(console->imhtml),
- _("<font color='#777777'>Not connected to XMPP</font>"), 0);
+ console->webview = gtk_webview_new();
+ gtk_webview_load_html_string(GTK_WEBVIEW(console->webview), EMPTY_HTML);
+ if (console->count == 0) {
+ char *tmp = g_strdup_printf("<div class=info>%s</div>",
+ _("Not connected to XMPP"));
+ gtk_webview_append_html(GTK_WEBVIEW(console->webview), tmp);
+ g_free(tmp);
+ }
gtk_box_pack_start(GTK_BOX(vbox),
- pidgin_make_scrollable(console->imhtml, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_ETCHED_IN, -1, -1),
+ pidgin_make_scrollable(console->webview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_ETCHED_IN, -1, -1),
TRUE, TRUE, 0);
toolbar = gtk_toolbar_new();
button = gtk_tool_button_new(NULL, "<iq/>");
+ gtk_tool_item_set_is_important(button, TRUE);
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(iq_clicked_cb), NULL);
gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(button));
button = gtk_tool_button_new(NULL, "<presence/>");
+ gtk_tool_item_set_is_important(button, TRUE);
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(presence_clicked_cb), NULL);
gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(button));
button = gtk_tool_button_new(NULL, "<message/>");
+ gtk_tool_item_set_is_important(button, TRUE);
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(message_clicked_cb), NULL);
gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(button));
gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
- console->entry = gtk_imhtml_new(NULL, NULL);
- gtk_imhtml_set_whole_buffer_formatting_only(GTK_IMHTML(console->entry), TRUE);
- g_signal_connect(G_OBJECT(console->entry),"message_send", G_CALLBACK(message_send_cb), console);
+ console->entry = gtk_webview_new();
+ gtk_webview_set_whole_buffer_formatting_only(GTK_WEBVIEW(console->entry), TRUE);
+ g_signal_connect(G_OBJECT(console->entry),"key-press-event", G_CALLBACK(message_send_cb), console);
console->sw = pidgin_make_scrollable(console->entry, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_ETCHED_IN, -1, -1);
gtk_box_pack_start(GTK_BOX(vbox), console->sw, FALSE, FALSE, 0);
- gtk_imhtml_set_editable(GTK_IMHTML(console->entry), TRUE);
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(console->entry));
- g_signal_connect(G_OBJECT(buffer), "changed", G_CALLBACK(entry_changed_cb), NULL);
+ gtk_webview_set_editable(GTK_WEBVIEW(console->entry), TRUE);
+ g_signal_connect(G_OBJECT(console->entry), "changed", G_CALLBACK(entry_changed_cb), NULL);
- entry_changed_cb(buffer, NULL);
+ entry_changed_cb(console->entry, NULL);
gtk_widget_show_all(console->window);
if (console->count < 2)
diff --git a/pidgin/smileyparser.c b/pidgin/smileyparser.c
new file mode 100644
index 0000000000..0c6e2d1470
--- /dev/null
+++ b/pidgin/smileyparser.c
@@ -0,0 +1,169 @@
+/* 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.
+ *
+ * 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 <gtk/gtk.h>
+#include <debug.h>
+#include "smileyparser.h"
+#include <smiley.h>
+#include <string.h>
+#include "gtkthemes.h"
+
+static char *
+get_fullpath(const char *filename)
+{
+ if (g_path_is_absolute(filename))
+ return g_strdup(filename);
+ else
+ return g_build_path(g_get_current_dir(), filename, NULL);
+}
+
+static void
+parse_for_shortcut_plaintext(const char *text, const char *shortcut, const char *file, GString *ret)
+{
+ const char *tmp = text;
+
+ for (;*tmp;) {
+ const char *end = strstr(tmp, shortcut);
+ char *path;
+ char *escaped_path;
+
+ if (end == NULL) {
+ g_string_append(ret, tmp);
+ break;
+ }
+ path = get_fullpath(file);
+ escaped_path = g_markup_escape_text(path, -1);
+
+ g_string_append_len(ret, tmp, end-tmp);
+ g_string_append_printf(ret,"<img alt='%s' src='%s' />",
+ shortcut, escaped_path);
+ g_free(path);
+ g_free(escaped_path);
+ g_assert(strlen(tmp) >= strlen(shortcut));
+ tmp = end + strlen(shortcut);
+ }
+}
+
+static char *
+parse_for_shortcut(const char *markup, const char *shortcut, const char *file)
+{
+ GString* ret = g_string_new("");
+ char *local_markup = g_strdup(markup);
+ char *escaped_shortcut = g_markup_escape_text(shortcut, -1);
+
+ char *temp = local_markup;
+
+ for (;*temp;) {
+ char *end = strchr(temp, '<');
+ char *end_of_tag;
+
+ if (!end) {
+ parse_for_shortcut_plaintext(temp, escaped_shortcut, file, ret);
+ break;
+ }
+
+ *end = 0;
+ parse_for_shortcut_plaintext(temp, escaped_shortcut, file, ret);
+ *end = '<';
+
+ /* if this is well-formed, then there should be no '>' within
+ * the tag. TODO: handle a comment tag better :( */
+ end_of_tag = strchr(end, '>');
+ if (!end_of_tag) {
+ g_string_append(ret, end);
+ break;
+ }
+
+ g_string_append_len(ret, end, end_of_tag - end + 1);
+
+ temp = end_of_tag + 1;
+ }
+ g_free(local_markup);
+ g_free(escaped_shortcut);
+ return g_string_free(ret, FALSE);
+}
+
+static char *
+parse_for_purple_smiley(const char *markup, PurpleSmiley *smiley)
+{
+ char *file = purple_smiley_get_full_path(smiley);
+ char *ret = parse_for_shortcut(markup, purple_smiley_get_shortcut(smiley), file);
+ g_free(file);
+ return ret;
+}
+
+static char *
+parse_for_smiley_list(const char *markup, GHashTable *smileys)
+{
+ GHashTableIter iter;
+ char *key, *value;
+ char *ret = g_strdup(markup);
+
+ g_hash_table_iter_init(&iter, smileys);
+ while (g_hash_table_iter_next(&iter, (gpointer *)&key, (gpointer *)&value))
+ {
+ char *temp = parse_for_shortcut(ret, key, value);
+ g_free(ret);
+ ret = temp;
+ }
+
+ return ret;
+}
+
+char *
+smiley_parse_markup(const char *markup, const char *proto_id)
+{
+ GList *smileys = purple_smileys_get_all();
+ char *temp = g_strdup(markup), *temp2;
+ struct smiley_list *list;
+ const char *proto_name = "default";
+
+ if (proto_id != NULL) {
+ PurplePlugin *proto;
+ proto = purple_find_prpl(proto_id);
+ proto_name = proto->info->name;
+ }
+
+ /* unnecessarily slow, but lets manage for now. */
+ for (; smileys; smileys = g_list_next(smileys)) {
+ temp2 = parse_for_purple_smiley(temp, PURPLE_SMILEY(smileys->data));
+ g_free(temp);
+ temp = temp2;
+ }
+
+ /* now for each theme smiley, observe that this does look nasty */
+ if (!current_smiley_theme || !(current_smiley_theme->list)) {
+ purple_debug_warning("smiley", "theme does not exist\n");
+ return temp;
+ }
+
+ for (list = current_smiley_theme->list; list; list = list->next) {
+ if (g_str_equal(list->sml, proto_name)) {
+ temp2 = parse_for_smiley_list(temp, list->files);
+ g_free(temp);
+ temp = temp2;
+ }
+ }
+
+ return temp;
+}
+
diff --git a/pidgin/smileyparser.h b/pidgin/smileyparser.h
new file mode 100644
index 0000000000..a1c1e550b7
--- /dev/null
+++ b/pidgin/smileyparser.h
@@ -0,0 +1,29 @@
+/* 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.
+ *
+ * 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
+ *
+ */
+
+G_BEGIN_DECLS
+
+char *
+smiley_parse_markup(const char *markup, const char *sml);
+
+G_END_DECLS
+
diff --git a/pidgin/themes/Contents/Info.plist b/pidgin/themes/Contents/Info.plist
new file mode 100644
index 0000000000..f2891d3d11
--- /dev/null
+++ b/pidgin/themes/Contents/Info.plist
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>MessageViewVersion</key>
+ <integer>4</integer>
+ <key>CFBundleName</key>
+ <string>Default</string>
+ <key>CFBundleIdentifier</key>
+ <string>im.pidgin.Default.style</string>
+ <key>DefaultFontFamily</key>
+ <string>sans-serif</string>
+ <key>DefaultFontSize</key>
+ <integer>11</integer>
+</dict>
+</plist>
diff --git a/pidgin/themes/Contents/Resources/Content.html b/pidgin/themes/Contents/Resources/Content.html
new file mode 100644
index 0000000000..37eddcd7e3
--- /dev/null
+++ b/pidgin/themes/Contents/Resources/Content.html
@@ -0,0 +1,6 @@
+<div class="x-container %messageClasses% %messageDirection%">
+ <abbr class="x-time" title="%time{yyyy-MM-ddTHH:mm:ssZZ}%">(%time%)</abbr>
+ <div class="x-sender">%sender%:</div>
+ <div class="x-message">%message%</div>
+</div>
+<div id="insert"></div>
diff --git a/pidgin/themes/Contents/Resources/Status.html b/pidgin/themes/Contents/Resources/Status.html
new file mode 100644
index 0000000000..b8447eb765
--- /dev/null
+++ b/pidgin/themes/Contents/Resources/Status.html
@@ -0,0 +1,5 @@
+<div class="x-status_container %messageClasses% %messageDirection% %status%">
+ <abbr class="x-time" title="%time{yyyy-MM-ddTHH:mm:ssZZ}%">%time%</abbr>
+ <div class="x-message">%message%</div>
+</div>
+<div id="insert"></div>
diff --git a/pidgin/themes/Contents/Resources/Variants/Default.css b/pidgin/themes/Contents/Resources/Variants/Default.css
new file mode 100644
index 0000000000..d1c6352610
--- /dev/null
+++ b/pidgin/themes/Contents/Resources/Variants/Default.css
@@ -0,0 +1,2 @@
+@import ../main.css;
+
diff --git a/pidgin/themes/Contents/Resources/Variants/No-Timestamps.css b/pidgin/themes/Contents/Resources/Variants/No-Timestamps.css
new file mode 100644
index 0000000000..155fe8aa15
--- /dev/null
+++ b/pidgin/themes/Contents/Resources/Variants/No-Timestamps.css
@@ -0,0 +1,8 @@
+@import ../main.css;
+
+.x-container .x-time,
+.x-status_container .x-time
+{
+ display: none;
+}
+
diff --git a/pidgin/themes/Contents/Resources/main.css b/pidgin/themes/Contents/Resources/main.css
new file mode 100644
index 0000000000..06f8bf7e06
--- /dev/null
+++ b/pidgin/themes/Contents/Resources/main.css
@@ -0,0 +1,66 @@
+body {
+ word-wrap: break-word;
+ word-break: break-word;
+
+ font-size: 13px;
+ margin: 2px;
+ overflow-y: scroll;
+}
+
+.x-container,
+.x-status_container
+{
+ line-height: 1.3em;
+ margin-bottom: 4px;
+}
+
+.x-container .x-time,
+.x-status_container .x-time
+{
+ display: inline;
+ font-size: 12px;
+}
+
+.x-container .x-sender
+{
+ display: inline;
+ font-weight: bold;
+}
+
+.x-container .x-message,
+.x-status_container .x-message
+{
+ display: inline;
+}
+
+/* Colour-ify things */
+
+.x-container.incoming .x-time,
+.x-container.incoming .x-sender
+{
+ color: #cc0000;
+}
+
+.x-container.outgoing .x-time,
+.x-container.outgoing .x-sender
+{
+ color: #204a87;
+}
+
+.x-container.mention .x-time,
+.x-container.mention .x-sender
+{
+ color: #AF7F00;
+}
+
+.x-status_container
+{
+ color: #777777;
+}
+
+.x-status_container.error
+{
+ color: #ff0000;
+ font-weight: bold;
+}
+
diff --git a/pidgin/themes/Makefile.am b/pidgin/themes/Makefile.am
new file mode 100644
index 0000000000..e06e723663
--- /dev/null
+++ b/pidgin/themes/Makefile.am
@@ -0,0 +1,19 @@
+
+themetemplatedir = $(datadir)/pidgin/theme
+themetemplate_DATA = Template.html
+themecontentsdir = $(themetemplatedir)/Contents
+themecontents_DATA = Contents/Info.plist
+themeresourcesdir = $(themecontentsdir)/Resources
+themeresources_DATA = Contents/Resources/Content.html \
+ Contents/Resources/Status.html \
+ Contents/Resources/main.css
+themevariantsdir = $(themeresourcesdir)/Variants
+themevariants_DATA = Contents/Resources/Variants/Default.css \
+ Contents/Resources/Variants/No-Timestamps.css
+
+EXTRA_DIST = \
+ $(themetemplate_DATA) \
+ $(themecontents_DATA) \
+ $(themeresources_DATA) \
+ $(themevariants_DATA)
+
diff --git a/pidgin/themes/Template.html b/pidgin/themes/Template.html
new file mode 100644
index 0000000000..aca283da2a
--- /dev/null
+++ b/pidgin/themes/Template.html
@@ -0,0 +1,331 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+ <base href="%@">
+ <script type="text/javascript" defer="defer">
+ // NOTE:
+ // Any percent signs in this file must be escaped!
+ // Use two escape signs (%%) to display it, this is passed through a format call!
+
+ function appendHTML(html) {
+ var node = document.getElementById("Chat");
+ var range = document.createRange();
+ range.selectNode(node);
+ var documentFragment = range.createContextualFragment(html);
+ node.appendChild(documentFragment);
+ }
+
+ // a coalesced HTML object buffers and outputs DOM objects en masse.
+ // saves A LOT of CSS recalculation time when loading many messages.
+ // (ex. a long twitter timeline)
+ function CoalescedHTML() {
+ var self = this;
+ this.fragment = document.createDocumentFragment();
+ this.timeoutID = 0;
+ this.coalesceRounds = 0;
+ this.isCoalescing = false;
+ this.isConsecutive = undefined;
+ this.shouldScroll = undefined;
+
+ var appendElement = function (elem) {
+ document.getElementById("Chat").appendChild(elem);
+ };
+
+ function outputHTML() {
+ var insert = document.getElementById("insert");
+ if(!!insert && self.isConsecutive) {
+ insert.parentNode.replaceChild(self.fragment, insert);
+ } else {
+ if(insert)
+ insert.parentNode.removeChild(insert);
+ // insert the documentFragment into the live DOM
+ appendElement(self.fragment);
+ }
+ alignChat(self.shouldScroll);
+
+ // reset state to empty/non-coalescing
+ self.shouldScroll = undefined;
+ self.isConsecutive = undefined;
+ self.isCoalescing = false;
+ self.coalesceRounds = 0;
+ }
+
+ // creates and returns a new documentFragment, containing all content nodes
+ // which can be inserted as a single node.
+ function createHTMLNode(html) {
+ var range = document.createRange();
+ range.selectNode(document.getElementById("Chat"));
+ return range.createContextualFragment(html);
+ }
+
+ // removes first insert node from the internal fragment.
+ function rmInsertNode() {
+ var insert = self.fragment.querySelector("#insert");
+ if(insert)
+ insert.parentNode.removeChild(insert);
+ }
+
+ function setShouldScroll(flag) {
+ if(flag && undefined === self.shouldScroll)
+ self.shouldScroll = flag;
+ }
+
+ // hook in a custom method to append new data
+ // to the chat.
+ this.setAppendElementMethod = function (func) {
+ if(typeof func === 'function')
+ appendElement = func;
+ }
+
+ // (re)start the coalescing timer.
+ // we wait 25ms for a new message to come in.
+ // If we get one, restart the timer and wait another 10ms.
+ // If not, run outputHTML()
+ // We do this a maximum of 400 times, for 10s max that can be spent
+ // coalescing input, since this will block display.
+ this.coalesce = function() {
+ window.clearTimeout(self.timeoutID);
+ self.timeoutID = window.setTimeout(outputHTML, 25);
+ self.isCoalescing = true;
+ self.coalesceRounds += 1;
+ if(400 < self.coalesceRounds)
+ self.cancel();
+ }
+
+ // if we need to append content into an insertion div,
+ // we need to clear the buffer and cancel the timeout.
+ this.cancel = function() {
+ if(self.isCoalescing) {
+ window.clearTimeout(self.timeoutID);
+ outputHTML();
+ }
+ }
+
+
+ // coalased analogs to the global functions
+
+ this.append = function(html, shouldScroll) {
+ // if we started this fragment with a consecuative message,
+ // cancel and output before we continue
+ if(self.isConsecutive) {
+ self.cancel();
+ }
+ self.isConsecutive = false;
+ rmInsertNode();
+ var node = createHTMLNode(html);
+ self.fragment.appendChild(node);
+
+ node = null;
+
+ setShouldScroll(shouldScroll);
+ self.coalesce();
+ }
+
+ this.appendNext = function(html, shouldScroll) {
+ if(undefined === self.isConsecutive)
+ self.isConsecutive = true;
+ var node = createHTMLNode(html);
+ var insert = self.fragment.querySelector("#insert");
+ if(insert) {
+ insert.parentNode.replaceChild(node, insert);
+ } else {
+ self.fragment.appendChild(node);
+ }
+ node = null;
+ setShouldScroll(shouldScroll);
+ self.coalesce();
+ }
+
+ this.replaceLast = function (html, shouldScroll) {
+ rmInsertNode();
+ var node = createHTMLNode(html);
+ var lastMessage = self.fragment.lastChild;
+ lastMessage.parentNode.replaceChild(node, lastMessage);
+ node = null;
+ setShouldScroll(shouldScroll);
+ }
+ }
+ var coalescedHTML;
+
+ //Appending new content to the message view
+ function appendMessage(html) {
+ var shouldScroll;
+
+ // Only call nearBottom() if should scroll is undefined.
+ if(undefined === coalescedHTML.shouldScroll) {
+ shouldScroll = nearBottom();
+ } else {
+ shouldScroll = coalescedHTML.shouldScroll;
+ }
+ appendMessageNoScroll(html, shouldScroll);
+ }
+
+ function appendMessageNoScroll(html, shouldScroll) {
+ shouldScroll = shouldScroll || false;
+ // always try to coalesce new, non-griuped, messages
+ coalescedHTML.append(html, shouldScroll)
+ }
+
+ function appendNextMessage(html){
+ var shouldScroll;
+ if(undefined === coalescedHTML.shouldScroll) {
+ shouldScroll = nearBottom();
+ } else {
+ shouldScroll = coalescedHTML.shouldScroll;
+ }
+ appendNextMessageNoScroll(html, shouldScroll);
+ }
+
+ function appendNextMessageNoScroll(html, shouldScroll){
+ shouldScroll = shouldScroll || false;
+ // only group next messages if we're already coalescing input
+ coalescedHTML.appendNext(html, shouldScroll);
+ }
+
+ function replaceLastMessage(html){
+ var shouldScroll;
+ // only replace messages if we're already coalescing
+ if(coalescedHTML.isCoalescing){
+ if(undefined === coalescedHTML.shouldScroll) {
+ shouldScroll = nearBottom();
+ } else {
+ shouldScroll = coalescedHTML.shouldScroll;
+ }
+ coalescedHTML.replaceLast(html, shouldScroll);
+ } else {
+ shouldScroll = nearBottom();
+ //Retrieve the current insertion point, then remove it
+ //This requires that there have been an insertion point... is there a better way to retrieve the last element? -evands
+ var insert = document.getElementById("insert");
+ if(insert){
+ var parentNode = insert.parentNode;
+ parentNode.removeChild(insert);
+ var lastMessage = document.getElementById("Chat").lastChild;
+ document.getElementById("Chat").removeChild(lastMessage);
+ }
+
+ //Now append the message itself
+ appendHTML(html);
+
+ alignChat(shouldScroll);
+ }
+ }
+
+ //Auto-scroll to bottom. Use nearBottom to determine if a scrollToBottom is desired.
+ function nearBottom() {
+ return ( document.body.scrollTop >= ( document.body.offsetHeight - ( window.innerHeight * 1.2 ) ) );
+ }
+ function scrollToBottom() {
+ document.body.scrollTop = document.body.offsetHeight;
+ }
+
+ //Dynamically exchange the active stylesheet
+ function setStylesheet( id, url ) {
+ var code = "<style id=\"" + id + "\" type=\"text/css\" media=\"screen,print\">";
+ if( url.length )
+ code += "@import url( \"" + url + "\" );";
+ code += "</style>";
+ var range = document.createRange();
+ var head = document.getElementsByTagName( "head" ).item(0);
+ range.selectNode( head );
+ var documentFragment = range.createContextualFragment( code );
+ head.removeChild( document.getElementById( id ) );
+ head.appendChild( documentFragment );
+ }
+
+ /* Converts emoticon images to textual emoticons; all emoticons in message if alt is held */
+ document.onclick = function imageCheck() {
+ var node = event.target;
+ if (node.tagName.toLowerCase() != 'img')
+ return;
+
+ imageSwap(node, false);
+ }
+
+ /* Converts textual emoticons to images if textToImagesFlag is true, otherwise vice versa */
+ function imageSwap(node, textToImagesFlag) {
+ var shouldScroll = nearBottom();
+
+ var images = [node];
+ if (event.altKey) {
+ while (node.id != "Chat" && node.parentNode.id != "Chat")
+ node = node.parentNode;
+ images = node.querySelectorAll(textToImagesFlag ? "a" : "img");
+ }
+
+ for (var i = 0; i < images.length; i++) {
+ textToImagesFlag ? textToImage(images[i]) : imageToText(images[i]);
+ }
+
+ alignChat(shouldScroll);
+ }
+
+ function textToImage(node) {
+ if (!node.getAttribute("isEmoticon"))
+ return;
+ //Swap the image/text
+ var img = document.createElement('img');
+ img.setAttribute('src', node.getAttribute('src'));
+ img.setAttribute('alt', node.firstChild.nodeValue);
+ img.className = node.className;
+ node.parentNode.replaceChild(img, node);
+ }
+
+ function imageToText(node)
+ {
+ if (client.zoomImage(node) || !node.alt)
+ return;
+ var a = document.createElement('a');
+ a.setAttribute('onclick', 'imageSwap(this, true)');
+ a.setAttribute('src', node.getAttribute('src'));
+ a.setAttribute('isEmoticon', true);
+ a.className = node.className;
+ var text = document.createTextNode(node.alt);
+ a.appendChild(text);
+ node.parentNode.replaceChild(a, node);
+ }
+
+ //If true is passed, view will be scrolled down
+ function alignChat(shouldScroll) {
+ if (shouldScroll)
+ scrollToBottom();
+ }
+
+ window.onresize = function windowDidResize(){
+ alignChat(true/*nearBottom()*/); //nearBottom buggy with inactive tabs
+ }
+
+ function initStyle() {
+ alignChat(true);
+ if(!coalescedHTML)
+ coalescedHTML = new CoalescedHTML();
+ }
+ </script>
+
+ <style type="text/css">
+ .actionMessageUserName { display:none; }
+ .actionMessageBody:before { content:"*"; }
+ .actionMessageBody:after { content:"*"; }
+ * { word-wrap:break-word }
+ img.scaledToFitImage { height: auto; max-width: 100%%; }
+ </style>
+
+ <!-- This style is shared by all variants. !-->
+ <style id="baseStyle" type="text/css" media="screen,print">
+ %@
+ </style>
+
+ <!-- Although we call this mainStyle for legacy reasons, it's actually the variant style !-->
+ <style id="mainStyle" type="text/css" media="screen,print">
+ @import url( "%@" );
+ </style>
+
+</head>
+<body onload="initStyle();" style="==bodyBackground==">
+%@
+<div id="Chat">
+</div>
+%@
+</body>
+</html>
diff --git a/pidgin/win32/untar.h b/pidgin/win32/untar.h
index 10e88976f1..54ad9ca007 100644
--- a/pidgin/win32/untar.h
+++ b/pidgin/win32/untar.h
@@ -12,7 +12,7 @@
extern "C" {
#endif /* __cplusplus */
-typedef enum _untar_opt {
+typedef enum {
UNTAR_LISTING = (1 << 0),
UNTAR_QUIET = (1 << 1),
UNTAR_VERBOSE = (1 << 2),
diff --git a/po/POTFILES.in b/po/POTFILES.in
index fcbc3b4809..aba6b9c232 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -160,14 +160,6 @@ libpurple/protocols/silc/pk.c
libpurple/protocols/silc/silc.c
libpurple/protocols/silc/util.c
libpurple/protocols/silc/wb.c
-libpurple/protocols/silc10/buddy.c
-libpurple/protocols/silc10/chat.c
-libpurple/protocols/silc10/ft.c
-libpurple/protocols/silc10/ops.c
-libpurple/protocols/silc10/pk.c
-libpurple/protocols/silc10/silc.c
-libpurple/protocols/silc10/util.c
-libpurple/protocols/silc10/wb.c
libpurple/protocols/simple/simple.c
libpurple/protocols/yahoo/libyahoo.c
libpurple/protocols/yahoo/libyahoojp.c
diff --git a/po/de.po b/po/de.po
index cf491c9ec8..9eb865ee9d 100644
--- a/po/de.po
+++ b/po/de.po
@@ -50,17 +50,6 @@ msgstr ""
" -n, --nologin nicht automatisch anmelden\n"
" -v, --version zeigt aktuelle Version und beendet das Programm\n"
-#, c-format
-msgid ""
-"%s encountered errors migrating your settings from %s to %s. Please "
-"investigate and complete the migration by hand. Please report this error at "
-"http://developer.pidgin.im"
-msgstr ""
-"%s ist beim Übertragen Ihrer Einstellungen von %s nach %s auf Fehler "
-"gestoßen. Bitte untersuchen Sie das Problem und vervollständigen Sie die "
-"Migration per Hand. Bitte melden Sie diesen Fehler auf http://developer."
-"pidgin.im"
-
#. the user did not fill in the captcha
msgid "Error"
msgstr "Fehler"
@@ -213,6 +202,8 @@ msgstr "Das gewählte Konto ist nicht online."
msgid "Error adding buddy"
msgstr "Fehler beim Hinzufügen des Buddys"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Username"
msgstr "Benutzer"
@@ -346,7 +337,11 @@ msgstr "Markierung umkehren"
msgid "View Log"
msgstr "Mitschnitt anzeigen"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
#. General
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Nickname"
msgstr "Spitzname"
@@ -800,7 +795,11 @@ msgid "Remaining"
msgstr "Verbleibend"
#. XXX: Use of ggp_str_to_uin() is an ugly hack!
+#. TODO: Check whether it's correct to call prepend_pair_html,
+#. or if we should be using prepend_pair_plaintext
#. presence
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Status"
msgstr "Status"
@@ -906,7 +905,6 @@ msgstr "Anrufen..."
msgid "Hangup"
msgstr "Auflegen"
-#. Number of actions
msgid "Accept"
msgstr "Akzeptieren"
@@ -1389,6 +1387,8 @@ msgstr "Titel"
msgid "Type"
msgstr "Typ"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
#. Statuses are almost all the same. Define a macro to reduce code repetition.
#. PurpleStatusPrimitive
#. id - use default
@@ -1397,6 +1397,8 @@ msgstr "Typ"
#. user_settable
#. not independent
#. Attributes - each status can have a message.
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Message"
msgstr "Nachricht"
@@ -1741,22 +1743,25 @@ msgstr "Das Zertifikat wurde widerrufen."
msgid "An unknown certificate error occurred."
msgstr "Es ist ein unbekannter Zertifikatfehler aufgetreten."
+#, fuzzy
+msgid "(MATCH)"
+msgstr "Beobachten"
+
msgid "(DOES NOT MATCH)"
msgstr "(stimmt nicht überein)"
-#. Make messages
#, c-format
msgid "%s has presented the following certificate for just-this-once use:"
msgstr ""
"%s hat das folgende Zertifikat für den einmaligen Gebrauch präsentiert:"
-#, c-format
-msgid ""
-"Common name: %s %s\n"
-"Fingerprint (SHA1): %s"
+#, fuzzy, c-format
+msgid "Common name: %s %s"
msgstr ""
-"Allgemeiner Name (Common name:) %s %s\n"
-"Fingerabdruck (SHA1): %s"
+"Allgemeiner Name (Common name): %s\n"
+"\n"
+"Fingerabdruck (SHA1):\n"
+"%s"
#. TODO: Find what the handle ought to be
msgid "Single-use Certificate Verification"
@@ -1772,7 +1777,6 @@ msgstr "Zertifizierungsstelle"
msgid "SSL Peers Cache"
msgstr "SSL-Peers-Zwischenspeicher"
-#. Make messages
#, c-format
msgid "Accept certificate for %s?"
msgstr "Akzeptieren Sie das Zertifikat für %s?"
@@ -1781,9 +1785,6 @@ msgstr "Akzeptieren Sie das Zertifikat für %s?"
msgid "SSL Certificate Verification"
msgstr "SSL-Zertifikatsüberprüfung"
-msgid "_View Certificate..."
-msgstr "Ze_rtifikat ansehen..."
-
#, c-format
msgid "The certificate for %s could not be validated."
msgstr "Das Zertifikat für %s konnte nicht validiert werden."
@@ -1804,27 +1805,6 @@ msgstr ""
"dass Sie tatsächlich nicht mit dem Dienst verbunden sind, mit dem Sie "
"glauben verbunden zu sein."
-#. Make messages
-#, c-format
-msgid ""
-"Common name: %s\n"
-"\n"
-"Fingerprint (SHA1): %s\n"
-"\n"
-"Activation date: %s\n"
-"Expiration date: %s\n"
-msgstr ""
-"Allgemeiner Name (Common name): %s\n"
-"\n"
-"Fingerabdruck (SHA1): %s\n"
-"\n"
-"Aktivierungsdatum: %s\n"
-"Ablaufdatum: %s\n"
-
-#. TODO: Find what the handle ought to be
-msgid "Certificate Information"
-msgstr "Zertifikat-Information"
-
#. show error to user
msgid "Registration Error"
msgstr "Registrierungsfehler"
@@ -2759,6 +2739,10 @@ msgstr "Offline-Nachrichten-Emulation"
msgid "Save messages sent to an offline user as pounce."
msgstr "Sichert Nachrichten an einen Offline-Benutzer als Alarm."
+#, fuzzy
+msgid "Offline message"
+msgstr "Offline-Nachrichten"
+
msgid ""
"The rest of the messages will be saved as pounces. You can edit/delete the "
"pounce from the `Buddy Pounce' dialog."
@@ -2896,6 +2880,23 @@ msgstr "Einfaches Plugin"
msgid "Tests to see that most things are working."
msgstr "Tests, um zu sehen, ob das meiste funktioniert."
+#. Make messages
+#, c-format
+msgid ""
+"Common name: %s\n"
+"\n"
+"Fingerprint (SHA1): %s\n"
+"\n"
+"Activation date: %s\n"
+"Expiration date: %s\n"
+msgstr ""
+"Allgemeiner Name (Common name): %s\n"
+"\n"
+"Fingerabdruck (SHA1): %s\n"
+"\n"
+"Aktivierungsdatum: %s\n"
+"Ablaufdatum: %s\n"
+
#. Scheme name
msgid "X.509 Certificates"
msgstr "X.509-Zertifikate"
@@ -3028,19 +3029,29 @@ msgid ""
msgstr "Keine Verbindung zum lokalen mDNS-Server. Ist er aktiviert?"
# old strings
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "First name"
msgstr "Vorname"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Last name"
msgstr "Nachname"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
#. email
msgid "Email"
msgstr "E-Mail"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "AIM Account"
msgstr "AIM-Konto"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "XMPP Account"
msgstr "XMPP-Konto"
@@ -3155,6 +3166,8 @@ msgstr "Registrierung eines neuen Gadu-Gadu-Kontos"
msgid "Please, fill in the following fields"
msgstr "Bitte füllen Sie die folgenden Felder aus"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "City"
msgstr "Stadt"
@@ -3162,6 +3175,8 @@ msgid "Year of birth"
msgstr "Geburtsjahr"
#. gender
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Gender"
msgstr "Geschlecht"
@@ -3184,20 +3199,26 @@ msgstr "Suche Buddys"
msgid "Please, enter your search criteria below"
msgstr "Bitte geben Sie Ihre Suchkriterien unten ein"
-msgid "Fill in the fields."
-msgstr "Füllen Sie die Felder aus."
+msgid "Change password for the Gadu-Gadu account"
+msgstr "Ändern des Passworts für dieses Gadu-Gadu-Konto"
-msgid "Your current password is different from the one that you specified."
-msgstr "Ihr aktuelles Passwort ist anders als das angegebene."
+msgid "Password was changed successfully!"
+msgstr "Das Passwort wurde erfolgreich geändert!"
msgid "Unable to change password. Error occurred.\n"
msgstr "Konnte das Passwort nicht ändern. Es trat ein Fehler auf.\n"
-msgid "Change password for the Gadu-Gadu account"
-msgstr "Ändern des Passworts für dieses Gadu-Gadu-Konto"
+msgid "Fill in the fields."
+msgstr "Füllen Sie die Felder aus."
-msgid "Password was changed successfully!"
-msgstr "Das Passwort wurde erfolgreich geändert!"
+msgid "New password should be at most 15 characters long."
+msgstr ""
+
+msgid "Your current password is different from the one that you specified."
+msgstr "Ihr aktuelles Passwort ist anders als das angegebene."
+
+msgid "Invalid email address"
+msgstr "Ungültige E-Mail-Adresse"
msgid "Current password"
msgstr "Aktuelles Passwort"
@@ -3205,6 +3226,9 @@ msgstr "Aktuelles Passwort"
msgid "Password (retype)"
msgstr "Passwort (nochmal)"
+msgid "Email Address"
+msgstr "E-Mail-Adresse"
+
msgid "Enter current token"
msgstr "Geben Sie das aktuelle Token ein"
@@ -3260,14 +3284,20 @@ msgstr "Nicht stören"
msgid "Away"
msgstr "Abwesend"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "UIN"
msgstr "UIN"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
#. first name
#. optional information
msgid "First Name"
msgstr "Vorname"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Birth Year"
msgstr "Geburtsjahr"
@@ -3307,6 +3337,30 @@ msgstr "Ihre Buddy-Liste wurde auf dem Server gespeichert."
msgid "Connected"
msgstr "Verbunden"
+msgid "Unable to resolve hostname"
+msgstr "Hostname konnte nicht aufgelöst werden"
+
+msgid "Incorrect password"
+msgstr "Falsches Passwort"
+
+msgid "SSL Connection Failed"
+msgstr "SSL-Verbindung gescheitert"
+
+msgid ""
+"Your account has been disabled because too many incorrect passwords were "
+"entered"
+msgstr ""
+"Ihr Konto wurde wegen zu vielen falsch eingegebenen Passworten gesperrt"
+
+msgid "Service temporarily unavailable"
+msgstr "Dienst momentan nicht verfügbar"
+
+msgid "Error connecting to proxy server"
+msgstr "Fehler beim Verbinden mit dem Proxy-Server"
+
+msgid "Error connecting to master server"
+msgstr "Fehler beim Verbinden mit dem Master-Server"
+
msgid "Connection failed"
msgstr "Verbindung fehlgeschlagen"
@@ -3316,6 +3370,12 @@ msgstr "Zum Chat hinzufügen"
msgid "Chat _name:"
msgstr "Chat_name:"
+msgid "The username specified is invalid."
+msgstr "Der angegebene Benutzername ist ungültig."
+
+msgid "SSL support unavailable"
+msgstr "SSL-Unterstützung nicht verfügbar"
+
#, c-format
msgid "Unable to resolve hostname '%s': %s"
msgstr "Hostname '%s' kann nicht aufgelöst werden: %s"
@@ -3334,12 +3394,12 @@ msgstr "Dieser Chatname existiert bereits"
msgid "Not connected to the server"
msgstr "Nicht mit dem Server verbunden"
-msgid "Find buddies..."
-msgstr "Finde Buddys..."
-
msgid "Change password..."
msgstr "Passwort ändern..."
+msgid "Find buddies..."
+msgstr "Finde Buddys..."
+
msgid "Upload buddylist to Server"
msgstr "Buddy-Liste zum Server hochladen"
@@ -3370,25 +3430,24 @@ msgstr "Gadu-Gadu-Protokoll-Plugin"
msgid "Polish popular IM"
msgstr "Beliebter polnischer IM-Dienst"
-msgid "Gadu-Gadu User"
-msgstr "Gadu-Gadu-Benutzer"
-
msgid "GG server"
msgstr "GG-Server"
-msgid "Don't use encryption"
-msgstr "Keine Verschlüsselung benutzen"
-
msgid "Use encryption if available"
msgstr "Verschlüsselung benutzen, wenn verfügbar"
-#. TODO
msgid "Require encryption"
msgstr "Verschlüsselung fordern"
+msgid "Don't use encryption"
+msgstr "Keine Verschlüsselung benutzen"
+
msgid "Connection security"
msgstr "Verbindungssicherheit"
+msgid "Show links from strangers"
+msgstr ""
+
#, c-format
msgid "Unknown command: %s"
msgstr "Unbekanntes Kommando: %s"
@@ -3441,9 +3500,6 @@ msgstr "_Passwort:"
msgid "IRC nick and server may not contain whitespace"
msgstr "IRC-Server und -Spitzname dürfen keinen Leerraum enthalten"
-msgid "SSL support unavailable"
-msgstr "SSL-Unterstützung nicht verfügbar"
-
msgid "Unable to connect"
msgstr "Verbindung nicht möglich"
@@ -3478,6 +3534,8 @@ msgid "The IRC Protocol Plugin that Sucks Less"
msgstr "Das IRC-Protokoll-Plugin mit weniger Problemen"
#. set up account ID as user:server
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Server"
msgstr "Server"
@@ -4016,6 +4074,8 @@ msgstr "Die Verbindung mit dem Server konnte nicht hergestellt werden: %s"
msgid "Unable to establish SSL connection"
msgstr "Kann SSL-Verbindung nicht erstellen"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Full Name"
msgstr "Vollständiger Name"
@@ -4086,9 +4146,13 @@ msgstr ""
"Die folgenden Punkte sind optional. Geben Sie nur die Informationen an, die "
"Sie angeben möchten."
+#. TODO: Check whether it's correct to call prepend_pair_html,
+#. or if we should be using prepend_pair_plaintext
msgid "Client"
msgstr "Client"
+#. TODO: Check whether it's correct to call prepend_pair_html,
+#. or if we should be using prepend_pair_plaintext
msgid "Operating System"
msgstr "Betriebssystem"
@@ -4098,6 +4162,8 @@ msgstr "Lokale Zeit"
msgid "Priority"
msgstr "Priorität"
+#. TODO: Check whether it's correct to call prepend_pair_html,
+#. or if we should be using prepend_pair_plaintext
msgid "Resource"
msgstr "Ressource"
@@ -4194,9 +4260,6 @@ msgstr ""
"Füllen Sie ein oder mehrere Felder aus, um nach entsprechenden XMPP-"
"Benutzern zu suchen."
-msgid "Email Address"
-msgstr "E-Mail-Adresse"
-
msgid "Search for XMPP users"
msgstr "Suche nach XMPP-Benutzern"
@@ -4407,6 +4470,8 @@ msgstr "Server unterstützt kein Blockieren"
msgid "Not Authorized"
msgstr "Nicht autorisiert"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Mood"
msgstr "Stimmung"
@@ -4740,6 +4805,10 @@ msgstr "Wählen Sie eine Ressource"
msgid "Initiate Media"
msgstr "Initiiere Medien"
+#, fuzzy
+msgid "Failed to specify mood"
+msgstr "Setzen der cmodes für %s gescheitert"
+
msgid "Account does not support PEP, can't set mood"
msgstr "Konto unterstützt kein PEP, kann die Stimmung nicht setzen"
@@ -4799,7 +4868,8 @@ msgstr "ping &lt;jid&gt;:\tBenutzer/Komponente/Server anpingen."
msgid "buzz: Buzz a user to get their attention"
msgstr "buzz: Einen Kontakt anrufen, um seine Aufmerksamkeit zu erhalten"
-msgid "mood: Set current user mood"
+#, fuzzy
+msgid "mood &lt;mood&gt; [text]: Set current user mood"
msgstr "mood: Setze die aktuelle Benutzerstimmung"
msgid "Extended Away"
@@ -5256,9 +5326,6 @@ msgstr "Kann die Nachricht nicht parsen"
msgid "Syntax Error (probably a client bug)"
msgstr "Syntaxfehler (wahrscheinlich ein Client-Bug)"
-msgid "Invalid email address"
-msgstr "Ungültige E-Mail-Adresse"
-
msgid "User does not exist"
msgstr "Benutzer existiert nicht"
@@ -5326,9 +5393,6 @@ msgstr "Zu viele Treffer zu einem FND"
msgid "Not logged in"
msgstr "Nicht angemeldet"
-msgid "Service temporarily unavailable"
-msgstr "Dienst momentan nicht verfügbar"
-
msgid "Database server error"
msgstr "Fehler des Datenbank-Servers"
@@ -5676,6 +5740,8 @@ msgstr "Alter"
msgid "Occupation"
msgstr "Beruf"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Location"
msgstr "Ort"
@@ -6083,9 +6149,6 @@ msgstr "Buddy aus dem Adressbuch löschen?"
msgid "Do you want to delete this buddy from your address book as well?"
msgstr "Möchten Sie diesen Buddy außerdem aus Ihrem Adressbuch löschen?"
-msgid "The username specified is invalid."
-msgstr "Der angegebene Benutzername ist ungültig."
-
msgid "The Display Name you entered is invalid."
msgstr "Der eingegebene Anzeigename ist ungültig."
@@ -6101,6 +6164,8 @@ msgstr "Profil-Aktualisierungsfehler"
#. no profile information yet, so we cannot update
#. (reference: "libpurple/request.h")
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Profile"
msgstr "Profil"
@@ -6214,6 +6279,8 @@ msgstr "Startbildschirm anzeigen..."
msgid "About..."
msgstr "Über..."
+#. we are trying to send a file to MXit
+#. need to reserve some space for packet headers
#. the file is too big
msgid "The file you are trying to send is too large!"
msgstr "Die Datei, die Sie senden möchten ist zu groß!"
@@ -6334,16 +6401,14 @@ msgstr "Sie haben eingeladen"
msgid "Loading menu..."
msgstr "Lade das Menü..."
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Status Message"
msgstr "Status-Nachricht"
msgid "Rejection Message"
msgstr "Ablehnungsnachricht"
-#. hidden number
-msgid "Hidden Number"
-msgstr "Versteckte Nummer"
-
msgid "No profile available"
msgstr "Kein Profil verfügbar"
@@ -6427,6 +6492,10 @@ msgstr ""
msgid "Message Error"
msgstr "Nachrichtenfehler"
+#. could not be decrypted
+msgid "An encrypted message was received which could not be decrypted."
+msgstr ""
+
msgid "Cannot perform redirect using the specified protocol"
msgstr "Kann die Umleitung nicht mit dem angegebenen Protokoll durchführen"
@@ -6691,18 +6760,26 @@ msgstr "Bildschirmauflösung (dpi)"
msgid "Base font size (points)"
msgstr "Basis-Schriftgröße (Punkt)"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "User"
msgstr "Benutzer"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Headline"
msgstr "Überschrift"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Song"
msgstr "Lied"
msgid "Total Friends"
msgstr "Freunde insgesamt"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Client Version"
msgstr "Client-Version"
@@ -6906,9 +6983,6 @@ msgstr "Nicht unterstützt"
msgid "Password has expired"
msgstr "Passwort ist abgelaufen"
-msgid "Incorrect password"
-msgstr "Falsches Passwort"
-
msgid "Account has been disabled"
msgstr "Konto wurde deaktiviert"
@@ -6935,12 +7009,6 @@ msgstr ""
"Konnte den Rechnernamen des Benutzers, den Sie eingegeben haben, nicht "
"erkennen"
-msgid ""
-"Your account has been disabled because too many incorrect passwords were "
-"entered"
-msgstr ""
-"Ihr Konto wurde wegen zu vielen falsch eingegebenen Passworten gesperrt"
-
msgid "You cannot add the same person twice to a conversation"
msgstr "Sie können die selbe Person nicht zweimal zu einem Gespräch hinzufügen"
@@ -7066,12 +7134,9 @@ msgstr "Hauspostcode"
msgid "User ID"
msgstr "Benutzer-ID"
-#. tag = _("DN");
-#. value = nm_user_record_get_dn(user_record);
-#. if (value) {
-#. purple_notify_user_info_add_pair(user_info, tag, value);
-#. }
-#.
+msgid "DN"
+msgstr ""
+
msgid "Full name"
msgstr "Vollständiger Name"
@@ -7566,9 +7631,6 @@ msgstr "SecurID-Eingabe"
msgid "Enter the 6 digit number from the digital display."
msgstr "Geben Sie die 6-stellige Nummer vom Digital-Display ein."
-msgid "Password sent"
-msgstr "Passwort gesendet"
-
msgid "Unable to initialize connection"
msgstr "Kann Verbindung nicht erstellen"
@@ -7868,9 +7930,6 @@ msgstr ""
"senden. Ihre Buddy-Liste ist nicht verloren und wird wahrscheinlich in ein "
"paar Minuten wieder verfügbar sein."
-msgid "Orphans"
-msgstr "Waisen"
-
#, c-format
msgid ""
"Unable to add the buddy %s because you have too many buddies in your buddy "
@@ -8174,6 +8233,7 @@ msgstr "Benutzerinformation nicht verfügbar: %s"
msgid "Mobile Phone"
msgstr "Handynummer"
+#. TODO: Is it correct to pass info->email here...?
msgid "Personal Web Page"
msgstr "Persönliche Webseite"
@@ -8194,6 +8254,7 @@ msgstr "Abteilung"
msgid "Position"
msgstr "Position"
+#. TODO: Is it correct to pass info->email here...?
msgid "Web Page"
msgstr "Webseite"
@@ -8463,13 +8524,13 @@ msgstr "Thema:"
msgid "A server is required to connect this account"
msgstr "Es wird ein Server benötigt um dieses Konto zu verbinden"
+msgid "Last Known Client"
+msgstr "Letzter bekannter Client"
+
#, c-format
msgid "Unknown (0x%04x)<br>"
msgstr "Unbekannt (0x%04x)<br>"
-msgid "Last Known Client"
-msgstr "Letzter bekannter Client"
-
msgid "User Name"
msgstr "Benutzername"
@@ -8792,21 +8853,33 @@ msgstr "Hyperaktiv"
msgid "Robot"
msgstr "Robot"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "User Modes"
msgstr "Benutzermodi"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Preferred Contact"
msgstr "Bevorzugter Kontakt"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Preferred Language"
msgstr "Bevorzugte Sprache"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Device"
msgstr "Gerät"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Timezone"
msgstr "Zeitzone"
+#. TODO: Check whether it's correct to call add_pair_html,
+#. or if we should be using add_pair_plaintext
msgid "Geolocation"
msgstr "Geographische Koordinaten"
@@ -9676,78 +9749,12 @@ msgstr ""
msgid "Whiteboard"
msgstr "Whiteboard"
-msgid "No server statistics available"
-msgstr "Keine Serverstatistik verfügbar"
-
-msgid "Error during connecting to SILC Server"
-msgstr "Fehler beim Verbinden mit dem SILC-Server"
-
-#, c-format
-msgid "Failure: Version mismatch, upgrade your client"
-msgstr "Fehler: Unterschiedliche Version, aktualisieren Sie Ihren Client"
-
-#, c-format
-msgid "Failure: Remote does not trust/support your public key"
-msgstr ""
-"Fehler: Die entfernte Seite vertraut Ihrem öffentlichen Schlüssel nicht"
-
-#, c-format
-msgid "Failure: Remote does not support proposed KE group"
-msgstr ""
-"Fehler: Entferntes Programm unterstützt nicht die vorgeschlagen KE-Gruppe"
-
-#, c-format
-msgid "Failure: Remote does not support proposed cipher"
-msgstr ""
-"Fehler: Entferntes Programm unterstützt die vorgeschlagene Chiffre nicht"
-
-#, c-format
-msgid "Failure: Remote does not support proposed PKCS"
-msgstr "Fehler: Entferntes Programm unterstützt die vorgeschlagene PKCS nicht"
-
-#, c-format
-msgid "Failure: Remote does not support proposed hash function"
-msgstr ""
-"Fehler: Entferntes Programm unterstützt die vorgeschlagen Hashfunktion nicht"
-
-#, c-format
-msgid "Failure: Remote does not support proposed HMAC"
-msgstr "Fehler: Entferntes Programm unterstützt das vorgeschlagene HMAC nicht"
-
-#, c-format
-msgid "Failure: Incorrect signature"
-msgstr "Fehler: Falsche Signatur"
-
-#, c-format
-msgid "Failure: Invalid cookie"
-msgstr "Fehler: Ungültiger Cookie"
-
-#, c-format
-msgid "Failure: Authentication failed"
-msgstr "Fehler: Authentifizierung fehlgeschlagen"
-
-msgid "Unable to initialize SILC Client connection"
-msgstr "SILC-Client-Verbindung konnte nicht hergestellt werden"
-
-msgid "John Noname"
-msgstr "Max Mustermann"
-
-#, c-format
-msgid "Unable to load SILC key pair: %s"
-msgstr "SILC-Schlüsselpaar konnte nicht geladen werden: %s"
-
-msgid "Unable to create connection"
-msgstr "Kann Verbindung nicht erstellen"
-
msgid "Unknown server response"
msgstr "Unbekannte Serverantwort"
msgid "Unable to create listen socket"
msgstr "Lauschender Socket konnte nicht erstellt werden"
-msgid "Unable to resolve hostname"
-msgstr "Hostname konnte nicht aufgelöst werden"
-
msgid "SIP usernames may not contain whitespaces or @ symbols"
msgstr "SIP-Benutzernamen dürfen keine Leerzeichen oder @-Symbole enthalten"
@@ -10228,6 +10235,8 @@ msgstr "Kann nicht an den Chat %s,%s,%s senden"
msgid "Hidden or not logged-in"
msgstr "Versteckt oder nicht angemeldet"
+#. TODO: Need to escape locs.host and locs.time?
+#. TODO: Need to escape the two strings that make up tmp?
#, c-format
msgid "<br>At %s since %s"
msgstr "<br>Bei %s seit %s"
@@ -10436,9 +10445,6 @@ msgstr "Gespeichertes Bild"
msgid "Stored Image. (that'll have to do for now)"
msgstr "Gespeichertes Bild. (Das muss erstmal reichen)"
-msgid "SSL Connection Failed"
-msgstr "SSL-Verbindung gescheitert"
-
msgid "SSL Handshake Failed"
msgstr "SSL-Verhandlung gescheitert"
@@ -11009,9 +11015,6 @@ msgstr "_Zusammenklappen"
msgid "_Expand"
msgstr "A_usklappen"
-msgid "/Tools/Mute Sounds"
-msgstr "/Werkzeuge/Stummschalten"
-
msgid ""
"You are not currently signed on with an account that can add that buddy."
msgstr ""
@@ -11036,122 +11039,123 @@ msgstr "Benutzerstimmung ändern"
#. NOTE: Do not set any accelerator to Control+O. It is mapped by
#. gtk_blist_key_press_cb to "Get User Info" on the selected buddy.
#. Buddies menu
-msgid "/_Buddies"
-msgstr "/_Buddys"
+msgid "_Buddies"
+msgstr "_Buddys"
-msgid "/Buddies/New Instant _Message..."
-msgstr "/Buddys/_Neue Sofortnachricht..."
+msgid "New Instant _Message..."
+msgstr "_Neue Sofortnachricht..."
-msgid "/Buddies/Join a _Chat..."
-msgstr "/Buddys/Einen _Chat betreten..."
+msgid "Join a _Chat..."
+msgstr "_Chat betreten..."
-msgid "/Buddies/Get User _Info..."
-msgstr "/Buddys/Benu_tzer-Info abrufen..."
+msgid "Get User _Info..."
+msgstr "Benutzer-_Info abrufen..."
-msgid "/Buddies/View User _Log..."
-msgstr "/Buddys/Benutzer-_Mitschnitt ansehen..."
+msgid "View User _Log..."
+msgstr "Benutzer-_Mitschnitt anzeigen..."
-msgid "/Buddies/Sh_ow"
-msgstr "/Buddys/_Anzeigen"
+msgid "Sh_ow"
+msgstr "_Anzeigen"
-msgid "/Buddies/Show/_Offline Buddies"
-msgstr "/Buddys/Anzeigen/_Offline-Buddys"
+msgid "_Sort Buddies"
+msgstr "Buddys _sortieren"
-msgid "/Buddies/Show/_Empty Groups"
-msgstr "/Buddys/Anzeigen/_Leere Gruppen"
+msgid "_Add Buddy..."
+msgstr "_Buddy hinzufügen..."
-msgid "/Buddies/Show/Buddy _Details"
-msgstr "/Buddys/Anzeigen/Buddy-_Details"
+msgid "Add _Group..."
+msgstr "_Gruppe hinzufügen..."
-msgid "/Buddies/Show/Idle _Times"
-msgstr "/Buddys/Anzeigen/Untätigkeitszei_ten"
+msgid "_Quit"
+msgstr "_Beenden"
-msgid "/Buddies/Show/_Protocol Icons"
-msgstr "/Buddys/Anzeigen/_Protokoll-Icons"
+#. Accounts menu
+msgid "_Accounts"
+msgstr "_Konten"
-msgid "/Buddies/_Sort Buddies"
-msgstr "/Buddys/Buddys _sortieren"
+msgid "Manage Accounts"
+msgstr "Konten verwalten"
-msgid "/Buddies/_Add Buddy..."
-msgstr "/Buddys/B_uddy hinzufügen..."
+#. Tools
+msgid "_Tools"
+msgstr "_Werkzeuge"
-msgid "/Buddies/Add C_hat..."
-msgstr "/Buddys/C_hat hinzufügen..."
+msgid "Buddy _Pounces"
+msgstr "Buddy-_Alarm"
-msgid "/Buddies/Add _Group..."
-msgstr "/Buddys/_Gruppe hinzufügen..."
+msgid "_Certificates"
+msgstr "_Zertifikate"
-msgid "/Buddies/_Quit"
-msgstr "/Buddys/_Beenden"
+msgid "Custom Smile_ys"
+msgstr "Benutzerdefinierte Smile_ys"
-#. Accounts menu
-msgid "/_Accounts"
-msgstr "/_Konten"
-
-msgid "/Accounts/Manage Accounts"
-msgstr "/Konten/Konten verwalten"
+msgid "Plu_gins"
+msgstr "_Plugins"
-#. Tools
-msgid "/_Tools"
-msgstr "/_Werkzeuge"
+msgid "Pr_eferences"
+msgstr "_Einstellungen"
-msgid "/Tools/Buddy _Pounces"
-msgstr "/Werkzeuge/Buddy-_Alarm"
+msgid "Pr_ivacy"
+msgstr "Pri_vatsphäre"
-msgid "/Tools/_Certificates"
-msgstr "/Werkzeuge/_Zertifikate"
+msgid "Set _Mood"
+msgstr "Setze Sti_mmung"
-msgid "/Tools/Custom Smile_ys"
-msgstr "/Werkzeuge/Benutzerdefinierte Smile_ys"
+msgid "_File Transfers"
+msgstr "_Dateiübertragungen"
-msgid "/Tools/Plu_gins"
-msgstr "/Werkzeuge/Plu_gins"
+#, fuzzy
+msgid "R_oom List"
+msgstr "Raumliste"
-msgid "/Tools/Pr_eferences"
-msgstr "/Werkzeuge/_Einstellungen"
+#, fuzzy
+msgid "System _Log"
+msgstr "Systemmitschnitt"
-msgid "/Tools/Pr_ivacy"
-msgstr "/Werkzeuge/Pri_vatsphäre"
+#. Help
+msgid "_Help"
+msgstr "_Hilfe"
-msgid "/Tools/Set _Mood"
-msgstr "/Werkzeuge/Setze Sti_mmung"
+msgid "Online _Help"
+msgstr "Online-_Hilfe"
-msgid "/Tools/_File Transfers"
-msgstr "/Werkzeuge/_Dateiübertragungen"
+msgid "_Build Information"
+msgstr "_Build-Informationen"
-msgid "/Tools/R_oom List"
-msgstr "/Werkzeuge/Chat_räume"
+msgid "_Debug Window"
+msgstr "_Debug-Fenster"
-msgid "/Tools/System _Log"
-msgstr "/Werkzeuge/_Systemmitschnitt"
+msgid "De_veloper Information"
+msgstr "_Entwickler-Informationen"
-msgid "/Tools/Mute _Sounds"
-msgstr "/Werkzeuge/S_tummschalten"
+msgid "_Plugin Information"
+msgstr "_Plugin-Informationen"
-#. Help
-msgid "/_Help"
-msgstr "/_Hilfe"
+msgid "_Translator Information"
+msgstr "Ü_bersetzer-Informationen"
-msgid "/Help/Online _Help"
-msgstr "/Hilfe/Online-_Hilfe"
+msgid "_About"
+msgstr "Übe_r"
-msgid "/Help/_Build Information"
-msgstr "/Hilfe/_Build-Informationen"
+#. Buddies->Show menu
+msgid "_Offline Buddies"
+msgstr "_Offline-Buddys"
-msgid "/Help/_Debug Window"
-msgstr "/Hilfe/_Debug-Fenster"
+msgid "_Empty Groups"
+msgstr "_Leere Gruppen"
-msgid "/Help/De_veloper Information"
-msgstr "/Hilfe/_Entwickler-Informationen"
+msgid "Buddy _Details"
+msgstr "Buddy-_Details"
-msgid "/Help/_Plugin Information"
-msgstr "/Hilfe/_Plugin-Informationen"
+msgid "Idle _Times"
+msgstr "Un_tätigkeitszeiten"
-msgid "/Help/_Translator Information"
-msgstr "/Hilfe/Über_setzer-Informationen"
+msgid "_Protocol Icons"
+msgstr "_Protokoll-Icons"
-msgid "/Help/_About"
-msgstr "/Hilfe/Übe_r"
+#. Tools menu
+msgid "Mute _Sounds"
+msgstr "Stu_mmschalten"
#, c-format
msgid "<b>Account:</b> %s"
@@ -11209,30 +11213,6 @@ msgstr "Untätig %dh %02dm"
msgid "Idle %dm"
msgstr "Untätig seit %dm"
-msgid "/Buddies/New Instant Message..."
-msgstr "/Buddys/Neue Sofortnachricht..."
-
-msgid "/Buddies/Join a Chat..."
-msgstr "/Buddys/Chat betreten..."
-
-msgid "/Buddies/Get User Info..."
-msgstr "/Buddys/Benutzer-Info abrufen..."
-
-msgid "/Buddies/Add Buddy..."
-msgstr "/Buddys/Buddy hinzufügen..."
-
-msgid "/Buddies/Add Chat..."
-msgstr "/Buddys/Chat hinzufügen..."
-
-msgid "/Buddies/Add Group..."
-msgstr "/Buddys/Gruppe hinzufügen..."
-
-msgid "/Tools/Privacy"
-msgstr "/Werkzeuge/Privatsphäre"
-
-msgid "/Tools/Room List"
-msgstr "/Werkzeuge/Chaträume"
-
#, c-format
msgid "%d unread message from %s\n"
msgid_plural "%d unread messages from %s\n"
@@ -11288,9 +11268,6 @@ msgstr "<b>Passwort:</b>"
msgid "_Login"
msgstr "_Anmelden"
-msgid "/Accounts"
-msgstr "/Konten"
-
#. Translators: Please maintain the use of -> and <- to refer to menu heirarchy
#, c-format
msgid ""
@@ -11307,24 +11284,6 @@ msgstr ""
"aktiviert haben, können Sie sich anmelden, Ihren Status setzen und mit Ihren "
"Freunden reden."
-#. set the Show Offline Buddies option. must be done
-#. * after the treeview or faceprint gets mad. -Robot101
-#.
-msgid "/Buddies/Show/Offline Buddies"
-msgstr "/Buddys/Anzeigen/Offline-Buddys"
-
-msgid "/Buddies/Show/Empty Groups"
-msgstr "/Buddys/Anzeigen/Leere Gruppen"
-
-msgid "/Buddies/Show/Buddy Details"
-msgstr "/Buddys/Anzeigen/Buddy-Details"
-
-msgid "/Buddies/Show/Idle Times"
-msgstr "/Buddys/Anzeigen/Untätigkeitszeiten"
-
-msgid "/Buddies/Show/Protocol Icons"
-msgstr "/Buddys/Anzeigen/Protokoll-Icons"
-
msgid "Add a buddy.\n"
msgstr "Einen Buddy hinzufügen.\n"
@@ -11373,12 +11332,6 @@ msgstr "Bitte geben Sie den Namen der Gruppe ein, die hinzugefügt werden soll."
msgid "Enable Account"
msgstr "Konten aktivieren"
-msgid "<PurpleMain>/Accounts/Enable Account"
-msgstr "<PurpleMain>/Konten/Konto aktivieren"
-
-msgid "<PurpleMain>/Accounts/"
-msgstr "<PurpleMain>/Konten/"
-
msgid "_Edit Account"
msgstr "Konto _bearbeiten"
@@ -11391,19 +11344,41 @@ msgstr "Keine Aktionen verfügbar"
msgid "_Disable"
msgstr "_Deaktivieren"
-msgid "/Tools"
-msgstr "/Werkzeuge"
-
-msgid "/Buddies/Sort Buddies"
-msgstr "/Buddys/Buddys sortieren"
-
msgid "Type the host name for this certificate."
msgstr "Geben Sie einen Hostnamen für dieses Zertifikat an."
+#. Fire the notification
+#, c-format
+msgid "Certificate Information for %s"
+msgstr "Zertifikat-Informationen für %s"
+
#. Widget creation function
msgid "SSL Servers"
msgstr "SSL-Server"
+msgid "Unsafe debugging is now disabled."
+msgstr ""
+
+msgid "Unsafe debugging is now enabled."
+msgstr ""
+
+msgid "Verbose debugging is now disabled."
+msgstr ""
+
+msgid "Verbose debugging is now enabled."
+msgstr ""
+
+msgid "Supported debug options are: plugins version unsafe verbose"
+msgstr "Unterstützte Debug-Optionen sind: plugins version unsafe verbose"
+
+msgid ""
+"Use \"/help &lt;command&gt;\" for help on a specific command.<br/>The "
+"following commands are available in this context:<br/>"
+msgstr ""
+"Benutzen Sie „/help &lt;kommando&gt;“, um Hilfe für ein bestimmtes Kommando "
+"zu erhalten.<br/>Die folgenden Kommandos sind in diesem Kontext verfügbar:"
+"<br/>"
+
msgid "Unknown command."
msgstr "Unbekanntes Kommando."
@@ -11438,9 +11413,6 @@ msgstr "Nicht Ignorieren"
msgid "Ignore"
msgstr "Ignorieren"
-msgid "Get Away Message"
-msgstr "Neue Abwesenheitsnachricht abholen"
-
msgid "Last Said"
msgstr "Zuletzt gesagt"
@@ -11469,171 +11441,93 @@ msgid "Show All"
msgstr "Alle anzeigen"
#. Conversation menu
-msgid "/_Conversation"
-msgstr "/_Unterhaltung"
-
-msgid "/Conversation/New Instant _Message..."
-msgstr "/Unterhaltung/_Neue Sofortnachricht..."
-
-msgid "/Conversation/Join a _Chat..."
-msgstr "/Unterhaltung/Einen Cha_t betreten..."
-
-msgid "/Conversation/_Find..."
-msgstr "/Unterhaltung/_Finden..."
-
-msgid "/Conversation/View _Log"
-msgstr "/Unterhaltung/_Mitschnitt anzeigen"
-
-msgid "/Conversation/_Save As..."
-msgstr "/Unterhaltung/S_peichern als..."
+msgid "_Conversation"
+msgstr "_Unterhaltung"
-msgid "/Conversation/Clea_r Scrollback"
-msgstr "/Unterhaltung/_Leeren"
-
-msgid "/Conversation/M_edia"
-msgstr "/Unterhaltung/M_edien"
+#, fuzzy
+msgid "_Find..."
+msgstr "Suchen"
-msgid "/Conversation/Media/_Audio Call"
-msgstr "/Unterhaltung/Medien/_Audio-Anruf"
+msgid "_Save As..."
+msgstr "S_peichern unter..."
-msgid "/Conversation/Media/_Video Call"
-msgstr "/Unterhaltung/Medien/_Video-Anruf"
+#, fuzzy
+msgid "Clea_r Scrollback"
+msgstr "Gesprächsfenster leeren"
-msgid "/Conversation/Media/Audio\\/Video _Call"
-msgstr "/Unterhaltung/Medien/A_udio-\\/Video-Anruf"
+#, fuzzy
+msgid "M_edia"
+msgstr "_Medien"
-msgid "/Conversation/Se_nd File..."
-msgstr "/Unterhaltung/Datei _senden..."
+#, fuzzy
+msgid "Audio/Video _Call"
+msgstr "Audio/_Video-Anruf"
-msgid "/Conversation/Get _Attention"
-msgstr "/Unterhaltung/_Aufmerksamkeit erregen"
+#, fuzzy
+msgid "Se_nd File..."
+msgstr "_Datei versenden..."
-msgid "/Conversation/Add Buddy _Pounce..."
-msgstr "/Unterhaltung/_Buddy-Alarm hinzufügen..."
+msgid "Get _Attention"
+msgstr "_Aufmerksamkeit erregen"
-msgid "/Conversation/_Get Info"
-msgstr "/Unterhaltung/_Info abrufen"
+msgid "_Get Info"
+msgstr "_Info abrufen"
-msgid "/Conversation/In_vite..."
-msgstr "/Unterhaltung/_Einladen..."
+#, fuzzy
+msgid "In_vite..."
+msgstr "Einladen..."
-msgid "/Conversation/M_ore"
-msgstr "/Unterhaltung/Me_hr"
+msgid "M_ore"
+msgstr ""
-msgid "/Conversation/Al_ias..."
-msgstr "/Unterhaltung/Al_ias..."
+#, fuzzy
+msgid "Al_ias..."
+msgstr "_Alias..."
-msgid "/Conversation/_Block..."
-msgstr "/Unterhaltung/_Blockieren..."
+#, fuzzy
+msgid "_Block..."
+msgstr "_Sperren"
-msgid "/Conversation/_Unblock..."
-msgstr "/Unterhaltung/_Entsperren..."
+#, fuzzy
+msgid "_Unblock..."
+msgstr "Sperrung aufheben"
-msgid "/Conversation/_Add..."
-msgstr "/Unterhaltung/_Hinzufügen..."
+msgid "_Add..."
+msgstr "_Hinzufügen..."
-msgid "/Conversation/_Remove..."
-msgstr "/Unterhaltung/_Entfernen..."
+#, fuzzy
+msgid "_Remove..."
+msgstr "E_ntfernen"
-msgid "/Conversation/Insert Lin_k..."
-msgstr "/Unterhaltung/Lin_k einfügen..."
+#, fuzzy
+msgid "Insert Lin_k..."
+msgstr "Link einfügen"
-msgid "/Conversation/Insert Imag_e..."
-msgstr "/Unterhaltung/Bil_d einfügen..."
+#, fuzzy
+msgid "Insert Imag_e..."
+msgstr "Bild einfügen"
-msgid "/Conversation/_Close"
-msgstr "/Unterhaltung/S_chließen"
+#, fuzzy
+msgid "_Close"
+msgstr "Schließen"
#. Options
-msgid "/_Options"
+#, fuzzy
+msgid "_Options"
msgstr "/_Optionen"
-msgid "/Options/Enable _Logging"
-msgstr "/Optionen/Schalte _Mitschnitt ein"
+#, fuzzy
+msgid "Enable _Logging"
+msgstr "Mitschnitt aktivieren"
-msgid "/Options/Enable _Sounds"
-msgstr "/Optionen/Schalte _Klänge ein"
+#, fuzzy
+msgid "Enable _Sounds"
+msgstr "Klänge aktivieren"
-msgid "/Options/Show Formatting _Toolbars"
+#, fuzzy
+msgid "Show Formatting _Toolbars"
msgstr "/Optionen/Zeige _Werkzeugleisten für Formatierung"
-msgid "/Options/Show Ti_mestamps"
-msgstr "/Optionen/Zeige _Zeitstempel"
-
-msgid "/Conversation/More"
-msgstr "/Unterhaltung/Mehr"
-
-msgid "/Options"
-msgstr "/Optionen"
-
-#. The menubar has been deactivated. Make sure the 'More' submenu is regenerated next time
-#. * the 'Conversation' menu pops up.
-#. Make sure the 'Conversation -> More' menuitems are regenerated whenever
-#. * the 'Conversation' menu pops up because the entries can change after the
-#. * conversation is created.
-msgid "/Conversation"
-msgstr "/Unterhaltung"
-
-msgid "/Conversation/View Log"
-msgstr "/Unterhaltung/Mitschnitt anzeigen"
-
-msgid "/Conversation/Media/Audio Call"
-msgstr "/Unterhaltung/Medien/Audio-Anruf"
-
-msgid "/Conversation/Media/Video Call"
-msgstr "/Unterhaltung/Medien/Video-Anruf"
-
-msgid "/Conversation/Media/Audio\\/Video Call"
-msgstr "/Unterhaltung/Medien/Audio-\\/Video-Anruf"
-
-msgid "/Conversation/Send File..."
-msgstr "/Unterhaltung/Datei senden ..."
-
-msgid "/Conversation/Get Attention"
-msgstr "/Unterhaltung/Aufmerksamkeit erregen"
-
-msgid "/Conversation/Add Buddy Pounce..."
-msgstr "/Unterhaltung/Buddy-Alarm hinzufügen..."
-
-msgid "/Conversation/Get Info"
-msgstr "/Unterhaltung/Info abrufen"
-
-msgid "/Conversation/Invite..."
-msgstr "/Unterhaltung/Einladen ..."
-
-msgid "/Conversation/Alias..."
-msgstr "/Unterhaltung/Alias..."
-
-msgid "/Conversation/Block..."
-msgstr "/Unterhaltung/Blockieren..."
-
-msgid "/Conversation/Unblock..."
-msgstr "/Unterhaltung/Entsperren..."
-
-msgid "/Conversation/Add..."
-msgstr "/Unterhaltung/Hinzufügen..."
-
-msgid "/Conversation/Remove..."
-msgstr "/Unterhaltung/Entfernen..."
-
-msgid "/Conversation/Insert Link..."
-msgstr "/Unterhaltung/Link einfügen..."
-
-msgid "/Conversation/Insert Image..."
-msgstr "/Unterhaltung/Bild einfügen..."
-
-msgid "/Options/Enable Logging"
-msgstr "/Optionen/Schalte Mitschnitt ein"
-
-msgid "/Options/Enable Sounds"
-msgstr "/Optionen/Schalte Klänge ein"
-
-msgid "/Options/Show Formatting Toolbars"
-msgstr "/Optionen/Zeige Werkzeugleisten für Formatierung"
-
-msgid "/Options/Show Timestamps"
-msgstr "/Optionen/Zeige Zeitstempel"
-
msgid "User is typing..."
msgstr "Benutzer tippt gerade..."
@@ -12032,6 +11926,10 @@ msgstr "Albanisch"
msgid "Serbian"
msgstr "Serbisch"
+#, fuzzy
+msgid "Serbian Latin"
+msgstr "Weißrussisch (Latin)"
+
msgid "Sinhala"
msgstr "Singhalesisch"
@@ -12080,14 +11978,14 @@ msgstr "Litauisch"
msgid "T.M.Thanh and the Gnome-Vi Team"
msgstr "T.M.Thanh und das Gnome-Vi Team"
-#, c-format
+#, fuzzy, c-format
msgid ""
-"%s is a messaging client based on libpurple which is capable of connecting "
-"to multiple messaging services at once. %s is written in C using GTK+. %s "
-"is released, and may be modified and redistributed, under the terms of the "
-"GPL version 2 (or later). A copy of the GPL is distributed with %s. %s is "
-"copyrighted by its contributors, a list of whom is also distributed with "
-"%s. There is no warranty for %s.<BR><BR>"
+"<p>%s is a messaging client based on libpurple which is capable of "
+"connecting to multiple messaging services at once. %s is written in C using "
+"GTK+. %s is released, and may be modified and redistributed, under the "
+"terms of the GPL version 2 (or later). A copy of the GPL is distributed "
+"with %s. %s is copyrighted by its contributors, a list of whom is also "
+"distributed with %s. There is no warranty for %s.</p>"
msgstr ""
"%s ist ein Nachrichtendienst, basierend auf libpurple, der die Verbindung zu "
"mehreren Nachrichtendiensten gleichzeitig unterstützt. %s wird in C "
@@ -12098,27 +11996,26 @@ msgstr ""
"der Mitwirkenden wird mit %s ausgeliefert. Wir übernehmen keine Haftung für "
"%s.<BR><BR>"
-#, c-format
+#, fuzzy, c-format
msgid ""
-"<FONT SIZE=\"4\"><B>Helpful Resources</B></FONT><BR>\t<A HREF=\"%s"
-"\">Website</A><BR>\t<A HREF=\"%s\">Frequently Asked Questions</A><BR>\tIRC "
-"Channel: #pidgin on irc.freenode.net<BR>\tXMPP MUC: devel@conference.pidgin."
-"im<BR><BR>"
+"<h3>Helpful Resources</h3><ul><li><a href=\"%s\" title=\"%s\">Website</a></"
+"li><li><a href=\"%s\" title=\"%s\">Frequently Asked Questions</a></"
+"li><li>IRC Channel: #pidgin on irc.freenode.net</li><li>XMPP MUC: "
+"devel@conference.pidgin.im</li></ul>"
msgstr ""
"<FONT SIZE=\"4\"><B>Hilfreiche Quellen</B></FONT><BR>\t<A HREF=\"%s"
"\">Webseite</A><BR>\t<A HREF=\"%s\">Häufig gestellte Fragen (FAQ)</A><BR>"
"\tIRC-Channel: #pidgin auf irc.freenode.net<BR>\tXMPP-MUC: devel@conference."
"pidgin.im<BR><BR>"
-#, c-format
+#, fuzzy, c-format
msgid ""
-"<font size=\"4\"><b>Help from other Pidgin users</b></font> is available by "
-"e-mailing <a href=\"mailto:support@pidgin.im\">support@pidgin.im</a><br/"
-">This is a <b>public</b> mailing list! (<a href=\"http://pidgin.im/pipermail/"
-"support/\">archive</a>)<br/>We can't help with third-party protocols or "
-"plugins!<br/>This list's primary language is <b>English</b>. You are "
-"welcome to post in another language, but the responses may be less helpful."
-"<br/>"
+"<p><strong>Help from other Pidgin users</strong> is available by e-mailing "
+"<a href=\"mailto:%s\">%s</a>.<br/>This is a <strong>public</strong> mailing "
+"list! (<a href=\"%s\" title=\"%s\">archive</a>)<br/>We can't help with third-"
+"party protocols or plugins!<br/>This list's primary language is "
+"<strong>English</strong>. You are welcome to post in another language, but "
+"the responses may be less helpful.</p>"
msgstr ""
"<font size=\"4\"><b>Hilfe von anderen Pidgin-Benutzern</b></font> erhält man "
"per E-Mail an <a href=\"mailto:support@pidgin.im\">support@pidgin.im</a><br/"
@@ -12198,12 +12095,6 @@ msgstr ""
msgid "View User Log"
msgstr "Benutzer-Mitschnitt anzeigen"
-msgid "Alias Contact"
-msgstr "Kontakt-Alias"
-
-msgid "Enter an alias for this contact."
-msgstr "Geben Sie einen Alias für diesen Kontakt ein."
-
#, c-format
msgid "Enter an alias for %s."
msgstr "Geben Sie einen Alias %s ein."
@@ -12307,24 +12198,9 @@ msgstr "_Ungelesene Nachrichten"
msgid "New _Message..."
msgstr "_Neue Nachricht..."
-msgid "_Accounts"
-msgstr "_Konten"
-
-msgid "Plu_gins"
-msgstr "_Plugins"
-
-msgid "Pr_eferences"
-msgstr "_Einstellungen"
-
-msgid "Mute _Sounds"
-msgstr "Stu_mmschalten"
-
msgid "_Blink on New Message"
msgstr "Be_i neuen Nachrichten blinken"
-msgid "_Quit"
-msgstr "_Beenden"
-
msgid "Not started"
msgstr "Nicht gestartet"
@@ -12808,6 +12684,10 @@ msgstr "_Pause"
msgid "_Mute"
msgstr "Stu_mmschalten"
+#, fuzzy
+msgid "Call in progress"
+msgstr "Verbindungsaufbau."
+
#, c-format
msgid "%s has %d new message."
msgid_plural "%s has %d new messages."
@@ -13030,6 +12910,10 @@ msgstr "Das Standard-Klangthema für Pidgin"
msgid "The default Pidgin buddy list theme"
msgstr "Das Standard-Buddy-Listen-Thema für Pidgin"
+#, fuzzy
+msgid "The default Pidgin conversation theme"
+msgstr "Das Standard-Status-Icon-Thema für Pidgin"
+
msgid "The default Pidgin status icon theme"
msgstr "Das Standard-Status-Icon-Thema für Pidgin"
@@ -13057,6 +12941,13 @@ msgstr ""
msgid "Buddy List Theme:"
msgstr "Buddy-Listen-Thema:"
+#, fuzzy
+msgid "Conversation Theme:"
+msgstr "Platzierung der Gespräche"
+
+msgid "\tVariant:"
+msgstr ""
+
msgid "Status Icon Theme:"
msgstr "Status-Icon-Thema:"
@@ -13653,12 +13544,6 @@ msgstr "Gespeicherter Status..."
msgid "Status Selector"
msgstr "Statusauswahl"
-msgid "Google Talk"
-msgstr "Google Talk"
-
-msgid "Facebook (XMPP)"
-msgstr "Facebook (XMPP)"
-
#, c-format
msgid "The following error has occurred loading %s: %s"
msgstr "Beim Laden von %s ist folgender Fehler aufgetreten: %s"
@@ -13793,18 +13678,12 @@ msgstr "Alia_s"
msgid "Close _tabs"
msgstr "_Reiter schließen"
-msgid "_Get Info"
-msgstr "_Info abrufen"
-
msgid "_Invite"
msgstr "_Einladen"
msgid "_Modify..."
msgstr "_Bearbeiten..."
-msgid "_Add..."
-msgstr "_Hinzufügen..."
-
msgid "_Open Mail"
msgstr "Mail ö_ffnen"
@@ -14984,8 +14863,9 @@ msgid ""
msgstr ""
"Bietet spezielle Optionen für Windows-Pidgin, wie Buddy-Listen-Docking."
-msgid "<font color='#777777'>Logged out.</font>"
-msgstr "<font color='#777777'>Abgemeldet.</font>"
+#, fuzzy
+msgid "Logged out."
+msgstr "Angemeldet"
#. *< type
#. *< ui_requirement
@@ -14999,8 +14879,9 @@ msgstr "XMPP-Konsole"
msgid "Account: "
msgstr "Konto: "
-msgid "<font color='#777777'>Not connected to XMPP</font>"
-msgstr "<font color='#777777'>Nicht mit XMPP verbunden</font>"
+#, fuzzy
+msgid "Not connected to XMPP"
+msgstr "Nicht mit dem Server verbunden"
#. *< name
#. *< version
@@ -15162,6 +15043,420 @@ msgstr ""
msgid "You do not have permission to uninstall this application."
msgstr "Sie haben keine Berechtigung, diese Anwendung zu deinstallieren."
+#~ msgid ""
+#~ "%s encountered errors migrating your settings from %s to %s. Please "
+#~ "investigate and complete the migration by hand. Please report this error "
+#~ "at http://developer.pidgin.im"
+#~ msgstr ""
+#~ "%s ist beim Übertragen Ihrer Einstellungen von %s nach %s auf Fehler "
+#~ "gestoßen. Bitte untersuchen Sie das Problem und vervollständigen Sie die "
+#~ "Migration per Hand. Bitte melden Sie diesen Fehler auf http://developer."
+#~ "pidgin.im"
+
+#~ msgid ""
+#~ "Common name: %s %s\n"
+#~ "Fingerprint (SHA1): %s"
+#~ msgstr ""
+#~ "Allgemeiner Name (Common name:) %s %s\n"
+#~ "Fingerabdruck (SHA1): %s"
+
+#~ msgid "_View Certificate..."
+#~ msgstr "Ze_rtifikat ansehen..."
+
+#~ msgid "Gadu-Gadu User"
+#~ msgstr "Gadu-Gadu-Benutzer"
+
+#~ msgid "Hidden Number"
+#~ msgstr "Versteckte Nummer"
+
+#~ msgid "Password sent"
+#~ msgstr "Passwort gesendet"
+
+#~ msgid "Orphans"
+#~ msgstr "Waisen"
+
+#~ msgid "No server statistics available"
+#~ msgstr "Keine Serverstatistik verfügbar"
+
+#~ msgid "Error during connecting to SILC Server"
+#~ msgstr "Fehler beim Verbinden mit dem SILC-Server"
+
+#~ msgid "Failure: Version mismatch, upgrade your client"
+#~ msgstr "Fehler: Unterschiedliche Version, aktualisieren Sie Ihren Client"
+
+#~ msgid "Failure: Remote does not trust/support your public key"
+#~ msgstr ""
+#~ "Fehler: Die entfernte Seite vertraut Ihrem öffentlichen Schlüssel nicht"
+
+#~ msgid "Failure: Remote does not support proposed KE group"
+#~ msgstr ""
+#~ "Fehler: Entferntes Programm unterstützt nicht die vorgeschlagen KE-Gruppe"
+
+#~ msgid "Failure: Remote does not support proposed cipher"
+#~ msgstr ""
+#~ "Fehler: Entferntes Programm unterstützt die vorgeschlagene Chiffre nicht"
+
+#~ msgid "Failure: Remote does not support proposed PKCS"
+#~ msgstr ""
+#~ "Fehler: Entferntes Programm unterstützt die vorgeschlagene PKCS nicht"
+
+#~ msgid "Failure: Remote does not support proposed hash function"
+#~ msgstr ""
+#~ "Fehler: Entferntes Programm unterstützt die vorgeschlagen Hashfunktion "
+#~ "nicht"
+
+#~ msgid "Failure: Remote does not support proposed HMAC"
+#~ msgstr ""
+#~ "Fehler: Entferntes Programm unterstützt das vorgeschlagene HMAC nicht"
+
+#~ msgid "Failure: Incorrect signature"
+#~ msgstr "Fehler: Falsche Signatur"
+
+#~ msgid "Failure: Invalid cookie"
+#~ msgstr "Fehler: Ungültiger Cookie"
+
+#~ msgid "Failure: Authentication failed"
+#~ msgstr "Fehler: Authentifizierung fehlgeschlagen"
+
+#~ msgid "Unable to initialize SILC Client connection"
+#~ msgstr "SILC-Client-Verbindung konnte nicht hergestellt werden"
+
+#~ msgid "John Noname"
+#~ msgstr "Max Mustermann"
+
+#~ msgid "Unable to load SILC key pair: %s"
+#~ msgstr "SILC-Schlüsselpaar konnte nicht geladen werden: %s"
+
+#~ msgid "Unable to create connection"
+#~ msgstr "Kann Verbindung nicht erstellen"
+
+#~ msgid "/Tools/Mute Sounds"
+#~ msgstr "/Werkzeuge/Stummschalten"
+
+#~ msgid "/Buddies/New Instant _Message..."
+#~ msgstr "/Buddys/_Neue Sofortnachricht..."
+
+#~ msgid "/Buddies/Join a _Chat..."
+#~ msgstr "/Buddys/Einen _Chat betreten..."
+
+#~ msgid "/Buddies/Get User _Info..."
+#~ msgstr "/Buddys/Benu_tzer-Info abrufen..."
+
+#~ msgid "/Buddies/View User _Log..."
+#~ msgstr "/Buddys/Benutzer-_Mitschnitt ansehen..."
+
+#~ msgid "/Buddies/Sh_ow"
+#~ msgstr "/Buddys/_Anzeigen"
+
+#~ msgid "/Buddies/Show/_Offline Buddies"
+#~ msgstr "/Buddys/Anzeigen/_Offline-Buddys"
+
+#~ msgid "/Buddies/Show/_Empty Groups"
+#~ msgstr "/Buddys/Anzeigen/_Leere Gruppen"
+
+#~ msgid "/Buddies/Show/Idle _Times"
+#~ msgstr "/Buddys/Anzeigen/Untätigkeitszei_ten"
+
+#~ msgid "/Buddies/Show/_Protocol Icons"
+#~ msgstr "/Buddys/Anzeigen/_Protokoll-Icons"
+
+#~ msgid "/Buddies/_Sort Buddies"
+#~ msgstr "/Buddys/Buddys _sortieren"
+
+#~ msgid "/Buddies/_Add Buddy..."
+#~ msgstr "/Buddys/B_uddy hinzufügen..."
+
+#~ msgid "/Buddies/Add C_hat..."
+#~ msgstr "/Buddys/C_hat hinzufügen..."
+
+#~ msgid "/Buddies/Add _Group..."
+#~ msgstr "/Buddys/_Gruppe hinzufügen..."
+
+#~ msgid "/Buddies/_Quit"
+#~ msgstr "/Buddys/_Beenden"
+
+#~ msgid "/_Accounts"
+#~ msgstr "/_Konten"
+
+#~ msgid "/Accounts/Manage Accounts"
+#~ msgstr "/Konten/Konten verwalten"
+
+#~ msgid "/Tools/Buddy _Pounces"
+#~ msgstr "/Werkzeuge/Buddy-_Alarm"
+
+#~ msgid "/Tools/_Certificates"
+#~ msgstr "/Werkzeuge/_Zertifikate"
+
+#~ msgid "/Tools/Custom Smile_ys"
+#~ msgstr "/Werkzeuge/Benutzerdefinierte Smile_ys"
+
+#~ msgid "/Tools/Plu_gins"
+#~ msgstr "/Werkzeuge/Plu_gins"
+
+#~ msgid "/Tools/Pr_eferences"
+#~ msgstr "/Werkzeuge/_Einstellungen"
+
+#~ msgid "/Tools/Pr_ivacy"
+#~ msgstr "/Werkzeuge/Pri_vatsphäre"
+
+#~ msgid "/Tools/Set _Mood"
+#~ msgstr "/Werkzeuge/Setze Sti_mmung"
+
+#~ msgid "/Tools/_File Transfers"
+#~ msgstr "/Werkzeuge/_Dateiübertragungen"
+
+#~ msgid "/Tools/R_oom List"
+#~ msgstr "/Werkzeuge/Chat_räume"
+
+#~ msgid "/Tools/System _Log"
+#~ msgstr "/Werkzeuge/_Systemmitschnitt"
+
+#~ msgid "/Tools/Mute _Sounds"
+#~ msgstr "/Werkzeuge/S_tummschalten"
+
+#~ msgid "/Help/_Build Information"
+#~ msgstr "/Hilfe/_Build-Informationen"
+
+#~ msgid "/Help/_Debug Window"
+#~ msgstr "/Hilfe/_Debug-Fenster"
+
+#~ msgid "/Help/De_veloper Information"
+#~ msgstr "/Hilfe/_Entwickler-Informationen"
+
+#~ msgid "/Help/_Plugin Information"
+#~ msgstr "/Hilfe/_Plugin-Informationen"
+
+#~ msgid "/Help/_Translator Information"
+#~ msgstr "/Hilfe/Über_setzer-Informationen"
+
+#~ msgid "/Help/_About"
+#~ msgstr "/Hilfe/Übe_r"
+
+#~ msgid "/Buddies/New Instant Message..."
+#~ msgstr "/Buddys/Neue Sofortnachricht..."
+
+#~ msgid "/Buddies/Join a Chat..."
+#~ msgstr "/Buddys/Chat betreten..."
+
+#~ msgid "/Buddies/Get User Info..."
+#~ msgstr "/Buddys/Benutzer-Info abrufen..."
+
+#~ msgid "/Buddies/Add Buddy..."
+#~ msgstr "/Buddys/Buddy hinzufügen..."
+
+#~ msgid "/Buddies/Add Chat..."
+#~ msgstr "/Buddys/Chat hinzufügen..."
+
+#~ msgid "/Buddies/Add Group..."
+#~ msgstr "/Buddys/Gruppe hinzufügen..."
+
+#~ msgid "/Tools/Privacy"
+#~ msgstr "/Werkzeuge/Privatsphäre"
+
+#~ msgid "/Tools/Room List"
+#~ msgstr "/Werkzeuge/Chaträume"
+
+#~ msgid "/Accounts"
+#~ msgstr "/Konten"
+
+#~ msgid "/Buddies/Show/Offline Buddies"
+#~ msgstr "/Buddys/Anzeigen/Offline-Buddys"
+
+#~ msgid "/Buddies/Show/Empty Groups"
+#~ msgstr "/Buddys/Anzeigen/Leere Gruppen"
+
+#~ msgid "/Buddies/Show/Buddy Details"
+#~ msgstr "/Buddys/Anzeigen/Buddy-Details"
+
+#~ msgid "/Buddies/Show/Idle Times"
+#~ msgstr "/Buddys/Anzeigen/Untätigkeitszeiten"
+
+#~ msgid "/Buddies/Show/Protocol Icons"
+#~ msgstr "/Buddys/Anzeigen/Protokoll-Icons"
+
+#~ msgid "<PurpleMain>/Accounts/Enable Account"
+#~ msgstr "<PurpleMain>/Konten/Konto aktivieren"
+
+#~ msgid "<PurpleMain>/Accounts/"
+#~ msgstr "<PurpleMain>/Konten/"
+
+#~ msgid "/Tools"
+#~ msgstr "/Werkzeuge"
+
+#~ msgid "/Buddies/Sort Buddies"
+#~ msgstr "/Buddys/Buddys sortieren"
+
+#~ msgid "Get Away Message"
+#~ msgstr "Neue Abwesenheitsnachricht abholen"
+
+#~ msgid "/Conversation/New Instant _Message..."
+#~ msgstr "/Unterhaltung/_Neue Sofortnachricht..."
+
+#~ msgid "/Conversation/Join a _Chat..."
+#~ msgstr "/Unterhaltung/Einen Cha_t betreten..."
+
+#~ msgid "/Conversation/_Find..."
+#~ msgstr "/Unterhaltung/_Finden..."
+
+#~ msgid "/Conversation/View _Log"
+#~ msgstr "/Unterhaltung/_Mitschnitt anzeigen"
+
+#~ msgid "/Conversation/_Save As..."
+#~ msgstr "/Unterhaltung/S_peichern als..."
+
+#~ msgid "/Conversation/Clea_r Scrollback"
+#~ msgstr "/Unterhaltung/_Leeren"
+
+#~ msgid "/Conversation/M_edia"
+#~ msgstr "/Unterhaltung/M_edien"
+
+#~ msgid "/Conversation/Media/_Audio Call"
+#~ msgstr "/Unterhaltung/Medien/_Audio-Anruf"
+
+#~ msgid "/Conversation/Media/_Video Call"
+#~ msgstr "/Unterhaltung/Medien/_Video-Anruf"
+
+#~ msgid "/Conversation/Media/Audio\\/Video _Call"
+#~ msgstr "/Unterhaltung/Medien/A_udio-\\/Video-Anruf"
+
+#~ msgid "/Conversation/Se_nd File..."
+#~ msgstr "/Unterhaltung/Datei _senden..."
+
+#~ msgid "/Conversation/Get _Attention"
+#~ msgstr "/Unterhaltung/_Aufmerksamkeit erregen"
+
+#~ msgid "/Conversation/Add Buddy _Pounce..."
+#~ msgstr "/Unterhaltung/_Buddy-Alarm hinzufügen..."
+
+#~ msgid "/Conversation/_Get Info"
+#~ msgstr "/Unterhaltung/_Info abrufen"
+
+#~ msgid "/Conversation/In_vite..."
+#~ msgstr "/Unterhaltung/_Einladen..."
+
+#~ msgid "/Conversation/M_ore"
+#~ msgstr "/Unterhaltung/Me_hr"
+
+#~ msgid "/Conversation/Al_ias..."
+#~ msgstr "/Unterhaltung/Al_ias..."
+
+#~ msgid "/Conversation/_Block..."
+#~ msgstr "/Unterhaltung/_Blockieren..."
+
+#~ msgid "/Conversation/_Unblock..."
+#~ msgstr "/Unterhaltung/_Entsperren..."
+
+#~ msgid "/Conversation/_Add..."
+#~ msgstr "/Unterhaltung/_Hinzufügen..."
+
+#~ msgid "/Conversation/_Remove..."
+#~ msgstr "/Unterhaltung/_Entfernen..."
+
+#~ msgid "/Conversation/Insert Lin_k..."
+#~ msgstr "/Unterhaltung/Lin_k einfügen..."
+
+#~ msgid "/Conversation/Insert Imag_e..."
+#~ msgstr "/Unterhaltung/Bil_d einfügen..."
+
+#~ msgid "/Conversation/_Close"
+#~ msgstr "/Unterhaltung/S_chließen"
+
+#~ msgid "/Options/Enable _Logging"
+#~ msgstr "/Optionen/Schalte _Mitschnitt ein"
+
+#~ msgid "/Options/Enable _Sounds"
+#~ msgstr "/Optionen/Schalte _Klänge ein"
+
+#~ msgid "/Options/Show Ti_mestamps"
+#~ msgstr "/Optionen/Zeige _Zeitstempel"
+
+#~ msgid "/Conversation/More"
+#~ msgstr "/Unterhaltung/Mehr"
+
+#~ msgid "/Options"
+#~ msgstr "/Optionen"
+
+#~ msgid "/Conversation"
+#~ msgstr "/Unterhaltung"
+
+#~ msgid "/Conversation/View Log"
+#~ msgstr "/Unterhaltung/Mitschnitt anzeigen"
+
+#~ msgid "/Conversation/Media/Audio Call"
+#~ msgstr "/Unterhaltung/Medien/Audio-Anruf"
+
+#~ msgid "/Conversation/Media/Video Call"
+#~ msgstr "/Unterhaltung/Medien/Video-Anruf"
+
+#~ msgid "/Conversation/Media/Audio\\/Video Call"
+#~ msgstr "/Unterhaltung/Medien/Audio-\\/Video-Anruf"
+
+#~ msgid "/Conversation/Send File..."
+#~ msgstr "/Unterhaltung/Datei senden ..."
+
+#~ msgid "/Conversation/Get Attention"
+#~ msgstr "/Unterhaltung/Aufmerksamkeit erregen"
+
+#~ msgid "/Conversation/Add Buddy Pounce..."
+#~ msgstr "/Unterhaltung/Buddy-Alarm hinzufügen..."
+
+#~ msgid "/Conversation/Get Info"
+#~ msgstr "/Unterhaltung/Info abrufen"
+
+#~ msgid "/Conversation/Invite..."
+#~ msgstr "/Unterhaltung/Einladen ..."
+
+#~ msgid "/Conversation/Alias..."
+#~ msgstr "/Unterhaltung/Alias..."
+
+#~ msgid "/Conversation/Block..."
+#~ msgstr "/Unterhaltung/Blockieren..."
+
+#~ msgid "/Conversation/Unblock..."
+#~ msgstr "/Unterhaltung/Entsperren..."
+
+#~ msgid "/Conversation/Add..."
+#~ msgstr "/Unterhaltung/Hinzufügen..."
+
+#~ msgid "/Conversation/Remove..."
+#~ msgstr "/Unterhaltung/Entfernen..."
+
+#~ msgid "/Conversation/Insert Link..."
+#~ msgstr "/Unterhaltung/Link einfügen..."
+
+#~ msgid "/Conversation/Insert Image..."
+#~ msgstr "/Unterhaltung/Bild einfügen..."
+
+#~ msgid "/Options/Enable Logging"
+#~ msgstr "/Optionen/Schalte Mitschnitt ein"
+
+#~ msgid "/Options/Enable Sounds"
+#~ msgstr "/Optionen/Schalte Klänge ein"
+
+#~ msgid "/Options/Show Formatting Toolbars"
+#~ msgstr "/Optionen/Zeige Werkzeugleisten für Formatierung"
+
+#~ msgid "/Options/Show Timestamps"
+#~ msgstr "/Optionen/Zeige Zeitstempel"
+
+#~ msgid "Alias Contact"
+#~ msgstr "Kontakt-Alias"
+
+#~ msgid "Enter an alias for this contact."
+#~ msgstr "Geben Sie einen Alias für diesen Kontakt ein."
+
+#~ msgid "Google Talk"
+#~ msgstr "Google Talk"
+
+#~ msgid "Facebook (XMPP)"
+#~ msgstr "Facebook (XMPP)"
+
+#~ msgid "<font color='#777777'>Logged out.</font>"
+#~ msgstr "<font color='#777777'>Abgemeldet.</font>"
+
+#~ msgid "<font color='#777777'>Not connected to XMPP</font>"
+#~ msgstr "<font color='#777777'>Nicht mit XMPP verbunden</font>"
+
#~ msgid "No Sametime Community Server specified"
#~ msgstr "Kein Sametime-Community Server angegeben"