summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnkit Vani <a@nevitus.org>2013-08-22 01:35:32 +0530
committerAnkit Vani <a@nevitus.org>2013-08-22 01:35:32 +0530
commitf30f5667daa327c86ae481816fc516d6833f86e7 (patch)
treec95a3d4675c8ebe44fdd2ef71bc7cdd8eaade097
parent836575deafeb881a6c984146be7ccb62e40561c0 (diff)
parent24eb25e1d7eeba87abf49e997674459b43c994e6 (diff)
downloadpidgin-f30f5667daa327c86ae481816fc516d6833f86e7.tar.gz
Merged default branch
-rw-r--r--.hgignore1
-rw-r--r--configure.ac3
-rw-r--r--doc/SIGNAL-HOWTO.dox2
-rw-r--r--doc/conversation-signals.dox25
-rw-r--r--finch/gntaccount.c7
-rw-r--r--finch/gntblist.c410
-rw-r--r--finch/gntblist.h2
-rw-r--r--finch/gntconv.c259
-rw-r--r--finch/gntlog.c14
-rw-r--r--finch/gntmedia.c8
-rw-r--r--finch/gntpounce.c22
-rw-r--r--finch/gntrequest.c6
-rw-r--r--finch/gntsound.c57
-rw-r--r--finch/libgnt/wms/s.c2
-rw-r--r--finch/plugins/gntgf.c11
-rw-r--r--finch/plugins/gnthistory.c16
-rw-r--r--finch/plugins/gnttinyurl.c14
-rw-r--r--finch/plugins/grouping.c164
-rw-r--r--libpurple/Makefile.am58
-rw-r--r--libpurple/Makefile.mingw22
-rw-r--r--libpurple/account.c2963
-rw-r--r--libpurple/account.h428
-rw-r--r--libpurple/accounts.c1022
-rw-r--r--libpurple/accounts.h225
-rw-r--r--libpurple/blist.c3251
-rw-r--r--libpurple/blist.h1204
-rw-r--r--libpurple/blistnode.c662
-rw-r--r--libpurple/blistnode.h423
-rw-r--r--libpurple/blistnodetypes.c1722
-rw-r--r--libpurple/blistnodetypes.h611
-rw-r--r--libpurple/buddyicon.c77
-rw-r--r--libpurple/buddyicon.h9
-rw-r--r--libpurple/buddylist.c2108
-rw-r--r--libpurple/buddylist.h481
-rw-r--r--libpurple/certificate.c53
-rw-r--r--libpurple/certificate.h18
-rw-r--r--libpurple/cipher.c989
-rw-r--r--libpurple/cipher.h423
-rw-r--r--libpurple/ciphers/Makefile.am23
-rw-r--r--libpurple/ciphers/aes.c564
-rw-r--r--libpurple/ciphers/aescipher.c657
-rw-r--r--libpurple/ciphers/aescipher.h64
-rw-r--r--libpurple/ciphers/ciphers.h66
-rw-r--r--libpurple/ciphers/des.c903
-rw-r--r--libpurple/ciphers/des3cipher.c529
-rw-r--r--libpurple/ciphers/des3cipher.h65
-rw-r--r--libpurple/ciphers/descipher.c585
-rw-r--r--libpurple/ciphers/descipher.h66
-rw-r--r--libpurple/ciphers/gchecksum.c144
-rw-r--r--libpurple/ciphers/hmac.c247
-rw-r--r--libpurple/ciphers/hmaccipher.c345
-rw-r--r--libpurple/ciphers/hmaccipher.h67
-rw-r--r--libpurple/ciphers/md4.c306
-rw-r--r--libpurple/ciphers/md4hash.c317
-rw-r--r--libpurple/ciphers/md4hash.h63
-rw-r--r--libpurple/ciphers/md5hash.c195
-rw-r--r--libpurple/ciphers/md5hash.h64
-rw-r--r--libpurple/ciphers/pbkdf2.c323
-rw-r--r--libpurple/ciphers/pbkdf2cipher.c418
-rw-r--r--libpurple/ciphers/pbkdf2cipher.h68
-rw-r--r--libpurple/ciphers/rc4.c159
-rw-r--r--libpurple/ciphers/rc4cipher.c266
-rw-r--r--libpurple/ciphers/rc4cipher.h69
-rw-r--r--libpurple/ciphers/sha1hash.c195
-rw-r--r--libpurple/ciphers/sha1hash.h64
-rw-r--r--libpurple/ciphers/sha256hash.c195
-rw-r--r--libpurple/ciphers/sha256hash.h64
-rw-r--r--libpurple/circbuffer.c153
-rw-r--r--libpurple/circularbuffer.c444
-rw-r--r--libpurple/circularbuffer.h (renamed from libpurple/circbuffer.h)88
-rw-r--r--libpurple/cmds.c26
-rw-r--r--libpurple/connection.c902
-rw-r--r--libpurple/connection.h114
-rw-r--r--libpurple/conversation.c2668
-rw-r--r--libpurple/conversation.h1121
-rw-r--r--libpurple/conversations.c478
-rw-r--r--libpurple/conversations.h167
-rw-r--r--libpurple/conversationtypes.c1999
-rw-r--r--libpurple/conversationtypes.h707
-rw-r--r--libpurple/core.c22
-rw-r--r--libpurple/dbus-analyze-functions.py18
-rw-r--r--libpurple/dbus-define-api.h13
-rw-r--r--libpurple/dbus-server.c70
-rw-r--r--libpurple/dbus-server.h6
-rw-r--r--libpurple/dbus-useful.c1
-rw-r--r--libpurple/enums.c.template64
-rw-r--r--libpurple/enums.h.template45
-rw-r--r--libpurple/ft.c106
-rw-r--r--libpurple/ft.h9
-rw-r--r--libpurple/hash.c268
-rw-r--r--libpurple/hash.h181
-rw-r--r--libpurple/imgstore.c33
-rw-r--r--libpurple/imgstore.h9
-rw-r--r--libpurple/internal.h36
-rw-r--r--libpurple/keyring.c55
-rw-r--r--libpurple/keyring.h7
-rw-r--r--libpurple/log.c44
-rw-r--r--libpurple/log.h8
-rw-r--r--libpurple/media.c26
-rw-r--r--libpurple/media.h29
-rw-r--r--libpurple/network.c2
-rw-r--r--libpurple/notify.c66
-rw-r--r--libpurple/notify.h22
-rw-r--r--libpurple/ntlm.c27
-rw-r--r--libpurple/plugin.c74
-rw-r--r--libpurple/plugin.h31
-rw-r--r--libpurple/plugins/autoaccept.c24
-rw-r--r--libpurple/plugins/buddynote.c2
-rw-r--r--libpurple/plugins/ciphertest.c114
-rw-r--r--libpurple/plugins/dbus-example.c2
-rw-r--r--libpurple/plugins/idle.c1
-rw-r--r--libpurple/plugins/joinpart.c24
-rw-r--r--libpurple/plugins/keyrings/internalkeyring.c66
-rw-r--r--libpurple/plugins/log_reader.c22
-rw-r--r--libpurple/plugins/mono/loader/blist-glue.c4
-rw-r--r--libpurple/plugins/mono/loader/mono-helper.c1
-rw-r--r--libpurple/plugins/mono/loader/mono-helper.h1
-rw-r--r--libpurple/plugins/mono/loader/signal-glue.c3
-rw-r--r--libpurple/plugins/newline.c4
-rw-r--r--libpurple/plugins/offlinemsg.c19
-rw-r--r--libpurple/plugins/perl/common/Account.xs128
-rw-r--r--libpurple/plugins/perl/common/BuddyList.xs224
-rw-r--r--libpurple/plugins/perl/common/Cipher.xs234
-rw-r--r--libpurple/plugins/perl/common/Connection.xs12
-rw-r--r--libpurple/plugins/perl/common/Conversation.xs348
-rw-r--r--libpurple/plugins/perl/common/Hash.xs110
-rw-r--r--libpurple/plugins/perl/common/MANIFEST3
-rw-r--r--libpurple/plugins/perl/common/Makefile.mingw3
-rw-r--r--libpurple/plugins/perl/common/Presence.xs102
-rw-r--r--libpurple/plugins/perl/common/Privacy.xs33
-rw-r--r--libpurple/plugins/perl/common/Prpl.xs2
-rw-r--r--libpurple/plugins/perl/common/Server.xs6
-rw-r--r--libpurple/plugins/perl/common/Status.xs156
-rw-r--r--libpurple/plugins/perl/common/module.h62
-rw-r--r--libpurple/plugins/perl/common/typemap33
-rw-r--r--libpurple/plugins/perl/perl-common.c231
-rw-r--r--libpurple/plugins/perl/perl-common.h6
-rw-r--r--libpurple/plugins/perl/perl-handlers.c14
-rw-r--r--libpurple/plugins/psychic.c21
-rw-r--r--libpurple/plugins/signals-test.c127
-rw-r--r--libpurple/plugins/statenotify.c16
-rw-r--r--libpurple/plugins/tcl/tcl_cmds.c151
-rw-r--r--libpurple/plugins/tcl/tcl_purple.h5
-rw-r--r--libpurple/plugins/tcl/tcl_signals.c183
-rw-r--r--libpurple/pounce.c14
-rw-r--r--libpurple/presence.c996
-rw-r--r--libpurple/presence.h387
-rw-r--r--libpurple/privacy.c411
-rw-r--r--libpurple/privacy.h190
-rw-r--r--libpurple/protocols/bonjour/bonjour.c32
-rw-r--r--libpurple/protocols/bonjour/bonjour_ft.c13
-rw-r--r--libpurple/protocols/bonjour/buddy.c16
-rw-r--r--libpurple/protocols/bonjour/jabber.c48
-rw-r--r--libpurple/protocols/bonjour/jabber.h4
-rw-r--r--libpurple/protocols/bonjour/mdns_avahi.c4
-rw-r--r--libpurple/protocols/bonjour/mdns_win32.c8
-rw-r--r--libpurple/protocols/gg/Makefile.am4
-rw-r--r--libpurple/protocols/gg/avatar.c4
-rw-r--r--libpurple/protocols/gg/blist.c (renamed from libpurple/protocols/gg/buddylist.c)14
-rw-r--r--libpurple/protocols/gg/blist.h (renamed from libpurple/protocols/gg/buddylist.h)2
-rw-r--r--libpurple/protocols/gg/confer.c17
-rw-r--r--libpurple/protocols/gg/confer.h2
-rw-r--r--libpurple/protocols/gg/gg.c58
-rw-r--r--libpurple/protocols/gg/image.c5
-rw-r--r--libpurple/protocols/gg/oauth/oauth.c23
-rw-r--r--libpurple/protocols/gg/pubdir-prpl.c6
-rw-r--r--libpurple/protocols/gg/purplew.c8
-rw-r--r--libpurple/protocols/gg/roster.c24
-rw-r--r--libpurple/protocols/gg/status.c14
-rw-r--r--libpurple/protocols/irc/cmds.c41
-rw-r--r--libpurple/protocols/irc/irc.c42
-rw-r--r--libpurple/protocols/irc/irc.h4
-rw-r--r--libpurple/protocols/irc/msgs.c299
-rw-r--r--libpurple/protocols/jabber/adhoccommands.c2
-rw-r--r--libpurple/protocols/jabber/auth.c20
-rw-r--r--libpurple/protocols/jabber/auth_digest_md5.c32
-rw-r--r--libpurple/protocols/jabber/auth_scram.c57
-rw-r--r--libpurple/protocols/jabber/auth_scram.h4
-rw-r--r--libpurple/protocols/jabber/buddy.c18
-rw-r--r--libpurple/protocols/jabber/caps.c49
-rw-r--r--libpurple/protocols/jabber/caps.h3
-rw-r--r--libpurple/protocols/jabber/chat.c18
-rw-r--r--libpurple/protocols/jabber/chat.h8
-rw-r--r--libpurple/protocols/jabber/disco.c4
-rw-r--r--libpurple/protocols/jabber/google/google.c2
-rw-r--r--libpurple/protocols/jabber/google/google_roster.c20
-rw-r--r--libpurple/protocols/jabber/jabber.c292
-rw-r--r--libpurple/protocols/jabber/jabber.h4
-rw-r--r--libpurple/protocols/jabber/jutil.c23
-rw-r--r--libpurple/protocols/jabber/libfacebook.c10
-rw-r--r--libpurple/protocols/jabber/libgtalk.c10
-rw-r--r--libpurple/protocols/jabber/libxmpp.c10
-rw-r--r--libpurple/protocols/jabber/message.c103
-rw-r--r--libpurple/protocols/jabber/message.h2
-rw-r--r--libpurple/protocols/jabber/parser.c3
-rw-r--r--libpurple/protocols/jabber/presence.c41
-rw-r--r--libpurple/protocols/jabber/roster.c28
-rw-r--r--libpurple/protocols/jabber/si.c22
-rw-r--r--libpurple/protocols/jabber/useravatar.c2
-rw-r--r--libpurple/protocols/msn/contact.c18
-rw-r--r--libpurple/protocols/msn/directconn.c11
-rw-r--r--libpurple/protocols/msn/directconn.h2
-rw-r--r--libpurple/protocols/msn/error.c6
-rw-r--r--libpurple/protocols/msn/msg.c46
-rw-r--r--libpurple/protocols/msn/msn.c83
-rw-r--r--libpurple/protocols/msn/msnutils.c16
-rw-r--r--libpurple/protocols/msn/nexus.c113
-rw-r--r--libpurple/protocols/msn/notification.c15
-rw-r--r--libpurple/protocols/msn/object.c18
-rw-r--r--libpurple/protocols/msn/servconn.c14
-rw-r--r--libpurple/protocols/msn/servconn.h4
-rw-r--r--libpurple/protocols/msn/session.c25
-rw-r--r--libpurple/protocols/msn/slpcall.c22
-rw-r--r--libpurple/protocols/msn/switchboard.c35
-rw-r--r--libpurple/protocols/msn/user.c8
-rw-r--r--libpurple/protocols/msn/userlist.c20
-rw-r--r--libpurple/protocols/mxit/formcmds.c8
-rw-r--r--libpurple/protocols/mxit/login.c8
-rw-r--r--libpurple/protocols/mxit/multimx.c52
-rw-r--r--libpurple/protocols/mxit/mxit.c24
-rw-r--r--libpurple/protocols/mxit/profile.c2
-rw-r--r--libpurple/protocols/mxit/protocol.c8
-rw-r--r--libpurple/protocols/mxit/roster.c32
-rw-r--r--libpurple/protocols/mxit/voicevideo.c4
-rw-r--r--libpurple/protocols/myspace/myspace.c111
-rw-r--r--libpurple/protocols/myspace/myspace.h5
-rw-r--r--libpurple/protocols/myspace/user.c2
-rw-r--r--libpurple/protocols/myspace/zap.c8
-rw-r--r--libpurple/protocols/novell/novell.c210
-rw-r--r--libpurple/protocols/null/nullprpl.c207
-rw-r--r--libpurple/protocols/oscar/authorization.c6
-rw-r--r--libpurple/protocols/oscar/clientlogin.c21
-rw-r--r--libpurple/protocols/oscar/family_auth.c40
-rw-r--r--libpurple/protocols/oscar/family_buddy.c2
-rw-r--r--libpurple/protocols/oscar/family_icbm.c4
-rw-r--r--libpurple/protocols/oscar/family_icq.c4
-rw-r--r--libpurple/protocols/oscar/family_oservice.c2
-rw-r--r--libpurple/protocols/oscar/flap_connection.c17
-rw-r--r--libpurple/protocols/oscar/odc.c29
-rw-r--r--libpurple/protocols/oscar/oft.c4
-rw-r--r--libpurple/protocols/oscar/oscar.c228
-rw-r--r--libpurple/protocols/oscar/oscar.h6
-rw-r--r--libpurple/protocols/oscar/oscarcommon.h2
-rw-r--r--libpurple/protocols/oscar/peer.c50
-rw-r--r--libpurple/protocols/oscar/peer.h4
-rw-r--r--libpurple/protocols/oscar/userinfo.c8
-rw-r--r--libpurple/protocols/oscar/visibility.c2
-rw-r--r--libpurple/protocols/sametime/sametime.c277
-rw-r--r--libpurple/protocols/silc/buddy.c20
-rw-r--r--libpurple/protocols/silc/chat.c22
-rw-r--r--libpurple/protocols/silc/ops.c120
-rw-r--r--libpurple/protocols/silc/silc.c28
-rw-r--r--libpurple/protocols/simple/simple.c66
-rw-r--r--libpurple/protocols/simple/simple.h4
-rw-r--r--libpurple/protocols/simple/sipmsg.c2
-rw-r--r--libpurple/protocols/yahoo/libyahoo.c12
-rw-r--r--libpurple/protocols/yahoo/libymsg.c190
-rw-r--r--libpurple/protocols/yahoo/libymsg.h6
-rw-r--r--libpurple/protocols/yahoo/yahoo_aliases.c4
-rw-r--r--libpurple/protocols/yahoo/yahoo_aliases.h2
-rw-r--r--libpurple/protocols/yahoo/yahoo_doodle.c5
-rw-r--r--libpurple/protocols/yahoo/yahoo_packet.c11
-rw-r--r--libpurple/protocols/yahoo/yahoo_picture.c7
-rw-r--r--libpurple/protocols/yahoo/yahoo_profile.c6
-rw-r--r--libpurple/protocols/yahoo/yahoochat.c151
-rw-r--r--libpurple/protocols/yahoo/yahoochat.h4
-rw-r--r--libpurple/protocols/yahoo/ycht.c33
-rw-r--r--libpurple/protocols/yahoo/ycht.h2
-rw-r--r--libpurple/protocols/zephyr/zephyr.c73
-rw-r--r--libpurple/proxy.c30
-rw-r--r--libpurple/prpl.c28
-rw-r--r--libpurple/prpl.h8
-rw-r--r--libpurple/purple-client.h1
-rw-r--r--libpurple/purple.h.in11
-rw-r--r--libpurple/savedstatuses.c49
-rw-r--r--libpurple/savedstatuses.h8
-rw-r--r--libpurple/server.c187
-rw-r--r--libpurple/server.h22
-rw-r--r--libpurple/signals.c63
-rw-r--r--libpurple/signals.h26
-rw-r--r--libpurple/smiley.c139
-rw-r--r--libpurple/smiley.h17
-rw-r--r--libpurple/sound-theme-loader.h7
-rw-r--r--libpurple/sound-theme.h7
-rw-r--r--libpurple/sound.c7
-rw-r--r--libpurple/status.c998
-rw-r--r--libpurple/status.h417
-rw-r--r--libpurple/tests/test_cipher.c145
-rw-r--r--libpurple/tests/test_jabber_caps.c14
-rw-r--r--libpurple/tests/test_jabber_scram.c3
-rw-r--r--libpurple/theme-loader.h8
-rw-r--r--libpurple/theme-manager.h7
-rw-r--r--libpurple/theme.h7
-rw-r--r--libpurple/util.c196
-rw-r--r--libpurple/util.h67
-rw-r--r--libpurple/value.c526
-rw-r--r--libpurple/value.h467
-rw-r--r--libpurple/xmlnode.c14
-rw-r--r--libpurple/xmlnode.h8
-rw-r--r--pidgin/gtkaccount.c56
-rw-r--r--pidgin/gtkaccount.h8
-rw-r--r--pidgin/gtkblist.c722
-rw-r--r--pidgin/gtkblist.h2
-rw-r--r--pidgin/gtkconv.c1208
-rw-r--r--pidgin/gtkconv.h48
-rw-r--r--pidgin/gtkconvwin.h6
-rw-r--r--pidgin/gtkdialogs.c45
-rw-r--r--pidgin/gtkdocklet.c14
-rw-r--r--pidgin/gtkimhtml.c18
-rw-r--r--pidgin/gtkimhtmltoolbar.c2
-rw-r--r--pidgin/gtklog.c25
-rw-r--r--pidgin/gtkmain.c5
-rw-r--r--pidgin/gtkmedia.c12
-rw-r--r--pidgin/gtknotify.c7
-rw-r--r--pidgin/gtkpounce.c24
-rw-r--r--pidgin/gtkprefs.c6
-rw-r--r--pidgin/gtkprivacy.c66
-rw-r--r--pidgin/gtkprivacy.h9
-rw-r--r--pidgin/gtksession.c2
-rw-r--r--pidgin/gtksound.c52
-rw-r--r--pidgin/gtkstatusbox.c4
-rw-r--r--pidgin/gtkthemes.c2
-rw-r--r--pidgin/gtkutils.c25
-rw-r--r--pidgin/gtkwebview.c18
-rw-r--r--pidgin/gtkwebviewtoolbar.c2
-rw-r--r--pidgin/gtkwhiteboard.c6
-rw-r--r--pidgin/plugins/cap/cap.c6
-rw-r--r--pidgin/plugins/cap/cap.h2
-rw-r--r--pidgin/plugins/cap/cap_statistics.h2
-rw-r--r--pidgin/plugins/convcolors.c6
-rw-r--r--pidgin/plugins/crazychat/cc_network.c24
-rw-r--r--pidgin/plugins/crazychat/cc_pidgin_plugin.c6
-rw-r--r--pidgin/plugins/extplacement.c5
-rw-r--r--pidgin/plugins/gestures/gestures.c6
-rw-r--r--pidgin/plugins/gevolution/add_buddy_dialog.c2
-rw-r--r--pidgin/plugins/gevolution/gevo-util.c18
-rw-r--r--pidgin/plugins/gevolution/gevolution.c10
-rw-r--r--pidgin/plugins/gtk-signals-test.c2
-rw-r--r--pidgin/plugins/history.c16
-rw-r--r--pidgin/plugins/mailchk.c8
-rw-r--r--pidgin/plugins/markerline.c11
-rw-r--r--pidgin/plugins/musicmessaging/musicmessaging.c10
-rw-r--r--pidgin/plugins/notify.c58
-rw-r--r--pidgin/plugins/perl/common/GtkAccount.xs2
-rw-r--r--pidgin/plugins/perl/common/GtkConv.xs19
-rw-r--r--pidgin/plugins/perl/common/GtkConvWin.xs12
-rw-r--r--pidgin/plugins/pidgininc.c4
-rw-r--r--pidgin/plugins/sendbutton.c4
-rw-r--r--pidgin/plugins/spellchk.c4
-rw-r--r--pidgin/plugins/themeedit-icon.c2
-rw-r--r--pidgin/plugins/themeedit.c2
-rw-r--r--pidgin/plugins/ticker/ticker.c17
-rw-r--r--pidgin/plugins/win32/transparency/win2ktrans.c10
-rw-r--r--pidgin/plugins/win32/winprefs/winprefs.c8
354 files changed, 27664 insertions, 22080 deletions
diff --git a/.hgignore b/.hgignore
index 7ea7d288cd..87c5a27860 100644
--- a/.hgignore
+++ b/.hgignore
@@ -59,6 +59,7 @@ libpurple/dbus-bindings.c
libpurple/dbus-signals.c
libpurple/dbus-types.c
libpurple/dbus-types.h
+libpurple/enums.[ch]
libpurple/example/nullclient
libpurple/gconf/purple.schemas$
libpurple/marshallers.[ch]
diff --git a/configure.ac b/configure.ac
index 01ace1d191..ee3ea2850f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -353,6 +353,9 @@ AC_SUBST(GLIB_LIBS)
GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0`
AC_SUBST(GLIB_GENMARSHAL)
+GLIB_MKENUMS=`pkg-config --variable=glib_mkenums glib-2.0`
+AC_SUBST(GLIB_MKENUMS)
+
AC_ARG_WITH([extraversion],
AS_HELP_STRING([--with-extraversion=STRING],
[extra version number to be displayed in Help->About and --help (for packagers)]),
diff --git a/doc/SIGNAL-HOWTO.dox b/doc/SIGNAL-HOWTO.dox
index 3007415ca2..a123cbc0a8 100644
--- a/doc/SIGNAL-HOWTO.dox
+++ b/doc/SIGNAL-HOWTO.dox
@@ -78,8 +78,6 @@
@todo Describe this more.
- @see value.h
-
@section connect Connecting to the signal
Once the signal is registered, you can connect callbacks to it. First, you
must define a callback function, such as this one from gtkplugin.c :
diff --git a/doc/conversation-signals.dox b/doc/conversation-signals.dox
index b9746990ac..6ac019bc2e 100644
--- a/doc/conversation-signals.dox
+++ b/doc/conversation-signals.dox
@@ -19,11 +19,11 @@
@signal deleting-conversation
@signal buddy-typing
@signal buddy-typing-stopped
- @signal chat-buddy-joining
- @signal chat-buddy-joined
- @signal chat-buddy-flags
- @signal chat-buddy-leaving
- @signal chat-buddy-left
+ @signal chat-user-joining
+ @signal chat-user-joined
+ @signal chat-user-flags
+ @signal chat-user-leaving
+ @signal chat-user-left
@signal chat-inviting-user
@signal chat-invited-user
@signal chat-invited
@@ -294,7 +294,7 @@ void (*buddy_typing_stopped)(PurpleAccount *account, const char *name);
@param name The name of the user which stopped typing.
@endsignaldef
- @signaldef chat-buddy-joining
+ @signaldef chat-user-joining
@signalproto
gboolean (*chat_buddy_joining)(PurpleConversation *conv, const char *name,
PurpleConvChatBuddyFlags flags);
@@ -308,7 +308,7 @@ gboolean (*chat_buddy_joining)(PurpleConversation *conv, const char *name,
@param flags The flags of the user that is joining the conversation.
@endsignaldef
- @signaldef chat-buddy-joined
+ @signaldef chat-user-joined
@signalproto
void (*chat_buddy_joined)(PurpleConversation *conv, const char *name,
PurpleConvChatBuddyFlags flags,
@@ -334,21 +334,20 @@ void (*chat_join_failed)(PurpleConnection *gc, GHashTable *components);
function should be g_str_equal().
@endsignaldef
- @signaldef chat-buddy-flags
+ @signaldef chat-user-flags
@signalproto
-void (*chat_buddy_flags)(PurpleConversation *conv, const char *name,
+void (*chat_buddy_flags)(PurpleChatUser *chatuser,
PurpleConvChatBuddyFlags oldflags,
PurpleConvChatBuddyFlags newflags);
@endsignalproto
@signaldesc
Emitted when a user in a chat changes flags.
- @param conv The chat conversation.
- @param name The name of the user.
+ @param chatuser The chat user whose flags changed.
@param oldflags The old flags.
@param newflags The new flags.
@endsignaldef
- @signaldef chat-buddy-leaving
+ @signaldef chat-user-leaving
@signalproto
gboolean (*chat_buddy_leaving)(PurpleConversation *conv, const char *name,
const char *reason);
@@ -362,7 +361,7 @@ gboolean (*chat_buddy_leaving)(PurpleConversation *conv, const char *name,
@param reason The optional reason why the user is leaving.
@endsignaldef
- @signaldef chat-buddy-left
+ @signaldef chat-user-left
@signalproto
void (*chat_buddy_left)(PurpleConversation *conv, const char *name,
const char *reason);
diff --git a/finch/gntaccount.c b/finch/gntaccount.c
index a08f7ffffb..5f612b8aab 100644
--- a/finch/gntaccount.c
+++ b/finch/gntaccount.c
@@ -188,7 +188,7 @@ save_account_cb(AccountEditDialog *dialog)
/* Alias */
value = gnt_entry_get_text(GNT_ENTRY(dialog->alias));
- purple_account_set_alias(account, value);
+ purple_account_set_private_alias(account, value);
/* Remember password and password */
purple_account_set_remember_password(account,
@@ -628,7 +628,7 @@ edit_account_continue(PurpleAccount *account,
gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Alias:")));
gnt_box_add_widget(GNT_BOX(hbox), entry);
if (account)
- gnt_entry_set_text(GNT_ENTRY(entry), purple_account_get_alias(account));
+ gnt_entry_set_text(GNT_ENTRY(entry), purple_account_get_private_alias(account));
/* User options */
update_user_options(dialog);
@@ -1158,7 +1158,8 @@ static PurpleAccountUiOps ui_ops =
NULL,
NULL,
NULL,
- NULL
+ NULL,
+ NULL, NULL, NULL, NULL
};
PurpleAccountUiOps *finch_accounts_get_ui_ops()
diff --git a/finch/gntblist.c b/finch/gntblist.c
index 4bf1148c38..8d68a55f0c 100644
--- a/finch/gntblist.c
+++ b/finch/gntblist.c
@@ -27,10 +27,9 @@
#include "finch.h"
#include <account.h>
-#include <blist.h>
+#include <buddylist.h>
#include <log.h>
#include <notify.h>
-#include <privacy.h>
#include <request.h>
#include <savedstatuses.h>
#include <server.h>
@@ -73,15 +72,15 @@ typedef struct
GntWidget *tree;
GntWidget *tooltip;
- PurpleBlistNode *tnode; /* Who is the tooltip being displayed for? */
- GList *tagged; /* A list of tagged blistnodes */
+ PurpleBlistNode *tnode; /* Who is the tooltip being displayed for? */
+ GList *tagged; /* A list of tagged blistnodes */
GntWidget *context;
PurpleBlistNode *cnode;
/* XXX: I am KISSing */
- GntWidget *status; /* Dropdown with the statuses */
- GntWidget *statustext; /* Status message */
+ GntWidget *status; /* Dropdown with the statuses */
+ GntWidget *statustext; /* Status message */
int typing;
GntWidget *menu;
@@ -102,8 +101,8 @@ typedef struct
typedef struct
{
- gpointer row; /* the row in the GntTree */
- guint signed_timer; /* used when 'recently' signed on/off */
+ gpointer row; /* the row in the GntTree */
+ guint signed_timer; /* used when 'recently' signed on/off */
} FinchBlistNode;
typedef enum
@@ -168,7 +167,7 @@ static gboolean default_can_add_node(PurpleBlistNode *node)
{
gboolean offline = purple_prefs_get_bool(PREF_ROOT "/showoffline");
- if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if (PURPLE_IS_BUDDY(node)) {
PurpleBuddy *buddy = (PurpleBuddy*)node;
FinchBlistNode *fnode = purple_blist_node_get_ui_data(node);
if (!purple_buddy_get_contact(buddy))
@@ -183,18 +182,18 @@ static gboolean default_can_add_node(PurpleBlistNode *node)
return TRUE; /* Show if the buddy just signed off */
if (purple_blist_node_get_bool(node, "show_offline"))
return TRUE;
- } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ } else if (PURPLE_IS_CONTACT(node)) {
PurpleBlistNode *nd;
for (nd = purple_blist_node_get_first_child(node);
nd; nd = purple_blist_node_get_sibling_next(nd)) {
if (default_can_add_node(nd))
return TRUE;
}
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
PurpleChat *chat = (PurpleChat*)node;
if (purple_account_is_connected(purple_chat_get_account(chat)))
return TRUE; /* Show whenever the account is online */
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
PurpleBlistNode *nd;
gboolean empty = purple_prefs_get_bool(PREF_ROOT "/emptygroups");
if (empty)
@@ -216,17 +215,13 @@ static gboolean default_can_add_node(PurpleBlistNode *node)
static gpointer default_find_parent(PurpleBlistNode *node)
{
gpointer ret = NULL;
- switch (purple_blist_node_get_type(node)) {
- case PURPLE_BLIST_BUDDY_NODE:
- case PURPLE_BLIST_CONTACT_NODE:
- case PURPLE_BLIST_CHAT_NODE:
- ret = purple_blist_node_get_parent(node);
- break;
- default:
- break;
- }
+
+ if (PURPLE_IS_BUDDY(node) || PURPLE_IS_CONTACT(node) || PURPLE_IS_CHAT(node))
+ ret = purple_blist_node_get_parent(node);
+
if (ret)
add_node(ret, ggblist);
+
return ret;
}
@@ -237,13 +232,13 @@ static gboolean default_create_tooltip(gpointer selected_row, GString **body, ch
int lastseen = 0;
char *title;
- if (!node ||
- purple_blist_node_get_type(node) == PURPLE_BLIST_OTHER_NODE)
+ if (!node || !(PURPLE_IS_BUDDY(node) || PURPLE_IS_CONTACT(node) ||
+ PURPLE_IS_GROUP(node) || PURPLE_IS_CHAT(node)))
return FALSE;
str = g_string_new("");
- if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if (PURPLE_IS_CONTACT(node)) {
PurpleBuddy *pr = purple_contact_get_priority_buddy((PurpleContact*)node);
gboolean offline = !PURPLE_BUDDY_IS_ONLINE(pr);
gboolean showoffline = purple_prefs_get_bool(PREF_ROOT "/showoffline");
@@ -267,21 +262,21 @@ static gboolean default_create_tooltip(gpointer selected_row, GString **body, ch
str = g_string_append(str, "\n----------\n");
tooltip_for_buddy(buddy, str, FALSE);
}
- } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ } else if (PURPLE_IS_BUDDY(node)) {
PurpleBuddy *buddy = (PurpleBuddy *)node;
tooltip_for_buddy(buddy, str, TRUE);
title = g_strdup(purple_buddy_get_name(buddy));
if (!PURPLE_BUDDY_IS_ONLINE((PurpleBuddy*)node))
lastseen = purple_blist_node_get_int(node, "last_seen");
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
PurpleGroup *group = (PurpleGroup *)node;
g_string_append_printf(str, _("Online: %d\nTotal: %d"),
- purple_blist_get_group_online_count(group),
- purple_blist_get_group_size(group, FALSE));
+ purple_counting_node_get_online_count(PURPLE_COUNTING_NODE(group)),
+ purple_counting_node_get_current_size(PURPLE_COUNTING_NODE(group)));
title = g_strdup(purple_group_get_name(group));
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
PurpleChat *chat = (PurpleChat *)node;
PurpleAccount *account = purple_chat_get_account(chat);
@@ -358,9 +353,9 @@ get_display_color(PurpleBlistNode *node)
PurpleBuddy *buddy;
int color = 0;
- if (PURPLE_BLIST_NODE_IS_CONTACT(node))
+ if (PURPLE_IS_CONTACT(node))
node = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node)));
- if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (!PURPLE_IS_BUDDY(node))
return 0;
buddy = (PurpleBuddy*)node;
@@ -389,12 +384,12 @@ get_blist_node_flag(PurpleBlistNode *node)
if (fnode && fnode->signed_timer)
flag |= GNT_TEXT_FLAG_BLINK;
- else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ else if (PURPLE_IS_CONTACT(node)) {
node = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(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)) {
+ } else if (PURPLE_IS_GROUP(node)) {
/* If the node is collapsed, then check to see if any of the priority buddies of
* any of the contacts within this group recently signed on/off, and set the blink
* flag appropriately. */
@@ -448,7 +443,7 @@ is_group_online(PurpleGroup *group)
PurpleBlistNode *node;
for (node = purple_blist_node_get_first_child(((PurpleBlistNode*)group)); node;
node = purple_blist_node_get_sibling_next(node)) {
- if (PURPLE_BLIST_NODE_IS_CHAT(node) &&
+ if (PURPLE_IS_CHAT(node) &&
purple_account_is_connected(((PurpleChat *)node)->account))
return TRUE;
else if (is_contact_online((PurpleContact*)node))
@@ -472,13 +467,13 @@ add_node(PurpleBlistNode *node, FinchBlist *ggblist)
if (!ggblist->manager->can_add_node(node))
return;
- if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (PURPLE_IS_BUDDY(node))
add_buddy((PurpleBuddy*)node, ggblist);
- else if (PURPLE_BLIST_NODE_IS_CONTACT(node))
+ else if (PURPLE_IS_CONTACT(node))
add_contact((PurpleContact*)node, ggblist);
- else if (PURPLE_BLIST_NODE_IS_GROUP(node))
+ else if (PURPLE_IS_GROUP(node))
add_group((PurpleGroup*)node, ggblist);
- else if (PURPLE_BLIST_NODE_IS_CHAT(node))
+ else if (PURPLE_IS_CHAT(node))
add_chat((PurpleChat *)node, ggblist);
draw_tooltip(ggblist);
@@ -506,7 +501,7 @@ node_remove(PurpleBuddyList *list, PurpleBlistNode *node)
if (ggblist == NULL || purple_blist_node_get_ui_data(node) == NULL)
return;
- if (PURPLE_BLIST_NODE_IS_GROUP(node) && ggblist->new_group) {
+ if (PURPLE_IS_GROUP(node) && ggblist->new_group) {
ggblist->new_group = g_list_remove(ggblist->new_group, node);
}
@@ -554,19 +549,19 @@ node_update(PurpleBuddyList *list, PurpleBlistNode *node)
node_remove(list, node);
}
- if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if (PURPLE_IS_BUDDY(node)) {
PurpleBuddy *buddy = (PurpleBuddy*)node;
add_node((PurpleBlistNode*)buddy, FINCH_GET_DATA(list));
node_update(list, purple_blist_node_get_parent(node));
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
add_node(node, FINCH_GET_DATA(list));
- } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ } else if (PURPLE_IS_CONTACT(node)) {
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));
}
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
if (!ggblist->manager->can_add_node(node))
node_remove(list, node);
else
@@ -608,7 +603,7 @@ remove_new_empty_group(gpointer data)
if (!ggblist)
return FALSE;
- list = purple_get_blist();
+ list = purple_blist_get_buddy_list();
g_return_val_if_fail(list, FALSE);
ggblist->new_group_timeout = 0;
@@ -649,7 +644,7 @@ add_buddy_cb(void *data, PurpleRequestFields *allfields)
return;
}
- grp = purple_find_group(group);
+ grp = purple_blist_find_group(group);
if (!grp)
{
grp = purple_group_new(group);
@@ -658,7 +653,7 @@ add_buddy_cb(void *data, PurpleRequestFields *allfields)
/* XXX: Ask to merge if there's already a buddy with the same alias in the same group (#4553) */
- if ((buddy = purple_find_buddy_in_group(account, username, grp)) == NULL)
+ if ((buddy = purple_blist_find_buddy_in_group(account, username, grp)) == NULL)
{
buddy = purple_buddy_new(account, username, alias);
purple_blist_add_buddy(buddy, NULL, grp, NULL);
@@ -708,24 +703,16 @@ join_chat(PurpleChat *chat)
{
PurpleAccount *account = purple_chat_get_account(chat);
const char *name;
- PurpleConversation *conv;
- const char *alias;
-
- /* This hack here is to work around the fact that there's no good way of
- * getting the actual name of a chat. I don't understand why we return
- * the alias for a chat when all we want is the name. */
- alias = chat->alias;
- chat->alias = NULL;
- name = purple_chat_get_name(chat);
- conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_CHAT, name, account);
- chat->alias = (char *)alias;
-
- if (!conv || purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv))) {
+ PurpleChatConversation *conv;
+
+ name = purple_chat_get_name_only(chat);
+ conv = purple_conversations_find_chat_with_account(name, account);
+
+ if (!conv || purple_chat_conversation_has_left(conv)) {
serv_join_chat(purple_account_get_connection(account),
purple_chat_get_components(chat));
} else if (conv) {
- purple_conversation_present(conv);
+ purple_conversation_present(PURPLE_CONVERSATION(conv));
}
}
@@ -761,12 +748,12 @@ add_chat_cb(void *data, PurpleRequestFields *allfields)
chat = purple_chat_new(account, name, hash);
if (chat != NULL) {
- if ((grp = purple_find_group(group)) == NULL) {
+ if ((grp = purple_blist_find_group(group)) == NULL) {
grp = purple_group_new(group);
purple_blist_add_group(grp, NULL);
}
purple_blist_add_chat(chat, grp, NULL);
- purple_blist_alias_chat(chat, alias);
+ purple_chat_set_alias(chat, alias);
purple_blist_node_set_bool((PurpleBlistNode*)chat, "gnt-autojoin", autojoin);
if (autojoin) {
join_chat(chat);
@@ -820,7 +807,7 @@ add_group_cb(gpointer null, const char *group)
return;
}
- grp = purple_find_group(group);
+ grp = purple_blist_find_group(group);
if (!grp) {
grp = purple_group_new(group);
purple_blist_add_group(grp, NULL);
@@ -905,13 +892,13 @@ get_display_name(PurpleBlistNode *node)
char status[8] = " ";
const char *name = NULL;
- if (PURPLE_BLIST_NODE_IS_CONTACT(node))
+ if (PURPLE_IS_CONTACT(node))
node = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node))); /* XXX: this can return NULL?! */
if (node == NULL)
return NULL;
- if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (PURPLE_IS_BUDDY(node))
{
PurpleBuddy *buddy = (PurpleBuddy *)node;
PurpleStatusPrimitive prim;
@@ -925,7 +912,7 @@ get_display_name(PurpleBlistNode *node)
else {
now = purple_presence_get_active_status(presence);
- prim = purple_status_type_get_primitive(purple_status_get_type(now));
+ prim = purple_status_type_get_primitive(purple_status_get_status_type(now));
switch(prim) {
case PURPLE_STATUS_OFFLINE:
@@ -941,14 +928,14 @@ get_display_name(PurpleBlistNode *node)
}
name = purple_buddy_get_alias(buddy);
}
- else if (PURPLE_BLIST_NODE_IS_CHAT(node))
+ else if (PURPLE_IS_CHAT(node))
{
PurpleChat *chat = (PurpleChat*)node;
name = purple_chat_get_name(chat);
strncpy(status, "~", sizeof(status) - 1);
}
- else if (PURPLE_BLIST_NODE_IS_GROUP(node))
+ else if (PURPLE_IS_GROUP(node))
return purple_group_get_name((PurpleGroup*)node);
g_snprintf(text, sizeof(text) - 1, "%s %s", status, name);
@@ -1028,7 +1015,7 @@ buddy_signed_on(PurpleBuddy *buddy, FinchBlist *ggblist)
static void
buddy_signed_off(PurpleBuddy *buddy, FinchBlist *ggblist)
{
- node_remove(purple_get_blist(), (PurpleBlistNode*)buddy);
+ node_remove(purple_blist_get_buddy_list(), (PurpleBlistNode*)buddy);
}
#endif
@@ -1046,27 +1033,25 @@ selection_activate(GntWidget *widget, FinchBlist *ggblist)
if (!node)
return;
- if (PURPLE_BLIST_NODE_IS_CONTACT(node))
+ if (PURPLE_IS_CONTACT(node))
node = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node)));
- if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (PURPLE_IS_BUDDY(node))
{
PurpleBuddy *buddy = (PurpleBuddy *)node;
- PurpleConversation *conv;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- purple_buddy_get_name(buddy),
+ PurpleIMConversation *im;
+ im = purple_conversations_find_im_with_account(purple_buddy_get_name(buddy),
purple_buddy_get_account(buddy));
- if (!conv) {
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM,
- purple_buddy_get_account(buddy),
+ if (!im) {
+ im = purple_im_conversation_new(purple_buddy_get_account(buddy),
purple_buddy_get_name(buddy));
} else {
- FinchConv *ggconv = FINCH_CONV(conv);
+ FinchConv *ggconv = FINCH_CONV(PURPLE_CONVERSATION(im));
gnt_window_present(ggconv->window);
}
- finch_conversation_set_active(conv);
+ finch_conversation_set_active(PURPLE_CONVERSATION(im));
}
- else if (PURPLE_BLIST_NODE_IS_CHAT(node))
+ else if (PURPLE_IS_CHAT(node))
{
join_chat((PurpleChat*)node);
}
@@ -1253,7 +1238,7 @@ static void
finch_blist_pounce_node_cb(PurpleBlistNode *selected, PurpleBlistNode *node)
{
PurpleBuddy *b;
- if (PURPLE_BLIST_NODE_IS_CONTACT(node))
+ if (PURPLE_IS_CONTACT(node))
b = purple_contact_get_priority_buddy((PurpleContact *)node);
else
b = (PurpleBuddy *)node;
@@ -1267,8 +1252,8 @@ toggle_block_buddy(GntMenuItem *item, gpointer buddy)
PurpleAccount *account = purple_buddy_get_account(buddy);
const char *name = purple_buddy_get_name(buddy);
- block ? purple_privacy_deny(account, name, FALSE, FALSE) :
- purple_privacy_allow(account, name, FALSE, FALSE);
+ block ? purple_account_privacy_deny(account, name) :
+ purple_account_privacy_allow(account, name);
}
static void
@@ -1277,9 +1262,9 @@ toggle_show_offline(GntMenuItem *item, gpointer buddy)
purple_blist_node_set_bool(buddy, "show_offline",
!purple_blist_node_get_bool(buddy, "show_offline"));
if (!ggblist->manager->can_add_node(buddy))
- node_remove(purple_get_blist(), buddy);
+ node_remove(purple_blist_get_buddy_list(), buddy);
else
- node_update(purple_get_blist(), buddy);
+ node_update(purple_blist_get_buddy_list(), buddy);
}
static void
@@ -1310,7 +1295,7 @@ create_buddy_menu(GntMenu *menu, PurpleBuddy *buddy)
}
account = purple_buddy_get_account(buddy);
- permitted = purple_privacy_check(account, purple_buddy_get_name(buddy));
+ permitted = purple_account_privacy_check(account, purple_buddy_get_name(buddy));
item = gnt_menuitem_check_new(_("Blocked"));
gnt_menuitem_check_set_checked(GNT_MENU_ITEM_CHECK(item), !permitted);
@@ -1365,19 +1350,19 @@ rename_blist_node(PurpleBlistNode *node, const char *newname)
if (name && !*name)
name = NULL;
- if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if (PURPLE_IS_CONTACT(node)) {
PurpleContact *contact = (PurpleContact*)node;
PurpleBuddy *buddy = purple_contact_get_priority_buddy(contact);
- purple_blist_alias_contact(contact, name);
- purple_blist_alias_buddy(buddy, name);
+ purple_contact_set_alias(contact, name);
+ purple_buddy_set_local_alias(buddy, name);
serv_alias_buddy(buddy);
- } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
- purple_blist_alias_buddy((PurpleBuddy*)node, name);
+ } else if (PURPLE_IS_BUDDY(node)) {
+ purple_buddy_set_local_alias((PurpleBuddy*)node, name);
serv_alias_buddy((PurpleBuddy*)node);
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node))
- purple_blist_alias_chat((PurpleChat*)node, name);
- else if (PURPLE_BLIST_NODE_IS_GROUP(node) && (name != NULL))
- purple_blist_rename_group((PurpleGroup*)node, name);
+ } else if (PURPLE_IS_CHAT(node))
+ purple_chat_set_alias((PurpleChat*)node, name);
+ else if (PURPLE_IS_GROUP(node) && (name != NULL))
+ purple_group_set_name((PurpleGroup*)node, name);
else
g_return_if_reached();
}
@@ -1389,20 +1374,20 @@ finch_blist_rename_node_cb(PurpleBlistNode *selected, PurpleBlistNode *node)
char *prompt;
const char *text;
- if (PURPLE_BLIST_NODE_IS_CONTACT(node))
+ if (PURPLE_IS_CONTACT(node))
name = purple_contact_get_alias((PurpleContact*)node);
- else if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ else if (PURPLE_IS_BUDDY(node))
name = purple_buddy_get_contact_alias((PurpleBuddy*)node);
- else if (PURPLE_BLIST_NODE_IS_CHAT(node))
+ else if (PURPLE_IS_CHAT(node))
name = purple_chat_get_name((PurpleChat*)node);
- else if (PURPLE_BLIST_NODE_IS_GROUP(node))
+ else if (PURPLE_IS_GROUP(node))
name = purple_group_get_name((PurpleGroup*)node);
else
g_return_if_reached();
prompt = g_strdup_printf(_("Please enter the new name for %s"), name);
- text = PURPLE_BLIST_NODE_IS_GROUP(node) ? _("Rename") : _("Set Alias");
+ text = PURPLE_IS_GROUP(node) ? _("Rename") : _("Set Alias");
purple_request_input(node, text, prompt, _("Enter empty string to reset the name."),
name, FALSE, FALSE, NULL, text, G_CALLBACK(rename_blist_node),
_("Cancel"), NULL,
@@ -1419,12 +1404,12 @@ static void showlog_cb(PurpleBlistNode *sel, PurpleBlistNode *node)
PurpleAccount *account;
char *name = NULL;
- if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if (PURPLE_IS_BUDDY(node)) {
PurpleBuddy *b = (PurpleBuddy*) node;
type = PURPLE_LOG_IM;
name = g_strdup(purple_buddy_get_name(b));
account = purple_buddy_get_account(b);
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
PurpleChat *c = (PurpleChat*) node;
PurplePluginProtocolInfo *prpl_info = NULL;
type = PURPLE_LOG_CHAT;
@@ -1433,7 +1418,7 @@ static void showlog_cb(PurpleBlistNode *sel, PurpleBlistNode *node)
if (prpl_info && prpl_info->get_chat_name) {
name = prpl_info->get_chat_name(purple_chat_get_components(c));
}
- } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ } else if (PURPLE_IS_CONTACT(node)) {
finch_log_show_contact((PurpleContact *)node);
return;
} else {
@@ -1458,12 +1443,12 @@ remove_group(PurpleGroup *group)
cnode = purple_blist_node_get_first_child(((PurpleBlistNode*)group));
while (cnode) {
- if (PURPLE_BLIST_NODE_IS_CONTACT(cnode)) {
+ if (PURPLE_IS_CONTACT(cnode)) {
bnode = purple_blist_node_get_first_child(cnode);
cnode = purple_blist_node_get_sibling_next(cnode);
while (bnode) {
PurpleBuddy *buddy;
- if (PURPLE_BLIST_NODE_IS_BUDDY(bnode)) {
+ if (PURPLE_IS_BUDDY(bnode)) {
PurpleAccount *account;
buddy = (PurpleBuddy*)bnode;
bnode = purple_blist_node_get_sibling_next(bnode);
@@ -1476,7 +1461,7 @@ remove_group(PurpleGroup *group)
bnode = purple_blist_node_get_sibling_next(bnode);
}
}
- } else if (PURPLE_BLIST_NODE_IS_CHAT(cnode)) {
+ } else if (PURPLE_IS_CHAT(cnode)) {
PurpleChat *chat = (PurpleChat *)cnode;
cnode = purple_blist_node_get_sibling_next(cnode);
if (purple_account_is_connected(purple_chat_get_account(chat)))
@@ -1492,16 +1477,16 @@ remove_group(PurpleGroup *group)
static void
finch_blist_remove_node(PurpleBlistNode *node)
{
- if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if (PURPLE_IS_CONTACT(node)) {
remove_contact((PurpleContact*)node);
- } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ } else if (PURPLE_IS_BUDDY(node)) {
PurpleBuddy *buddy = (PurpleBuddy*)node;
PurpleGroup *group = purple_buddy_get_group(buddy);
purple_account_remove_buddy(purple_buddy_get_account(buddy), buddy, group);
purple_blist_remove_buddy(buddy);
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
purple_blist_remove_chat((PurpleChat*)node);
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
remove_group((PurpleGroup*)node);
}
}
@@ -1513,17 +1498,17 @@ finch_blist_remove_node_cb(PurpleBlistNode *selected, PurpleBlistNode *node)
char *primary;
const char *name, *sec = NULL;
- if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if (PURPLE_IS_CONTACT(node)) {
PurpleContact *c = (PurpleContact*)node;
name = purple_contact_get_alias(c);
- if (purple_contact_get_contact_size(c, TRUE) > 1)
+ if (purple_counting_node_get_total_size(PURPLE_COUNTING_NODE(c)) > 1)
sec = _("Removing this contact will also remove all the buddies in the contact");
- } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ } else if (PURPLE_IS_BUDDY(node)) {
name = purple_buddy_get_name((PurpleBuddy*)node);
account = purple_buddy_get_account((PurpleBuddy*)node);
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
name = purple_chat_get_name((PurpleChat*)node);
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
name = purple_group_get_name((PurpleGroup*)node);
sec = _("Removing this group will also remove all the buddies in the group");
}
@@ -1554,9 +1539,9 @@ finch_blist_toggle_tag_buddy(PurpleBlistNode *node)
} else {
ggblist->tagged = g_list_prepend(ggblist->tagged, node);
}
- if (PURPLE_BLIST_NODE_IS_CONTACT(node))
+ if (PURPLE_IS_CONTACT(node))
update_buddy_display(purple_contact_get_priority_buddy(PURPLE_CONTACT(node)), ggblist);
- else if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ else if (PURPLE_IS_BUDDY(node))
update_buddy_display((PurpleBuddy*)node, ggblist);
else
update_node_display(node, ggblist);
@@ -1568,17 +1553,17 @@ finch_blist_place_tagged(PurpleBlistNode *target)
PurpleGroup *tg = NULL;
PurpleContact *tc = NULL;
- if (target == NULL ||
- purple_blist_node_get_type(target) == PURPLE_BLIST_OTHER_NODE)
+ if (target == NULL || !(PURPLE_IS_BUDDY(target) || PURPLE_IS_CONTACT(target) ||
+ PURPLE_IS_GROUP(target) || PURPLE_IS_CHAT(target)))
return;
- if (PURPLE_BLIST_NODE_IS_GROUP(target))
+ if (PURPLE_IS_GROUP(target))
tg = (PurpleGroup*)target;
- else if (PURPLE_BLIST_NODE_IS_BUDDY(target)) {
+ else if (PURPLE_IS_BUDDY(target)) {
tc = (PurpleContact*)purple_blist_node_get_parent(target);
tg = (PurpleGroup*)purple_blist_node_get_parent((PurpleBlistNode*)tc);
} else {
- if (PURPLE_BLIST_NODE_IS_CONTACT(target))
+ if (PURPLE_IS_CONTACT(target))
tc = (PurpleContact*)target;
tg = (PurpleGroup*)purple_blist_node_get_parent(target);
}
@@ -1590,38 +1575,38 @@ finch_blist_place_tagged(PurpleBlistNode *target)
PurpleBlistNode *node = list->data;
list = g_list_delete_link(list, list);
- if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ if (PURPLE_IS_GROUP(node)) {
update_node_display(node, ggblist);
/* Add the group after the current group */
purple_blist_add_group((PurpleGroup*)node, (PurpleBlistNode*)tg);
- } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ } else if (PURPLE_IS_CONTACT(node)) {
update_buddy_display(purple_contact_get_priority_buddy((PurpleContact*)node), ggblist);
if (PURPLE_BLIST_NODE(tg) == target) {
/* The target is a group, just add the contact to the group. */
purple_blist_add_contact((PurpleContact*)node, tg, NULL);
} else if (tc) {
/* The target is either a buddy, or a contact. Merge with that contact. */
- purple_blist_merge_contact((PurpleContact*)node, (PurpleBlistNode*)tc);
+ purple_contact_merge((PurpleContact*)node, (PurpleBlistNode*)tc);
} else {
/* The target is a chat. Add the contact to the group after this chat. */
purple_blist_add_contact((PurpleContact*)node, NULL, target);
}
- } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ } else if (PURPLE_IS_BUDDY(node)) {
update_buddy_display((PurpleBuddy*)node, ggblist);
if (PURPLE_BLIST_NODE(tg) == target) {
/* The target is a group. Add this buddy in a new contact under this group. */
purple_blist_add_buddy((PurpleBuddy*)node, NULL, tg, NULL);
- } else if (PURPLE_BLIST_NODE_IS_CONTACT(target)) {
+ } else if (PURPLE_IS_CONTACT(target)) {
/* Add to the contact. */
purple_blist_add_buddy((PurpleBuddy*)node, tc, NULL, NULL);
- } else if (PURPLE_BLIST_NODE_IS_BUDDY(target)) {
+ } else if (PURPLE_IS_BUDDY(target)) {
/* Add to the contact after the selected buddy. */
purple_blist_add_buddy((PurpleBuddy*)node, NULL, NULL, target);
- } else if (PURPLE_BLIST_NODE_IS_CHAT(target)) {
+ } else if (PURPLE_IS_CHAT(target)) {
/* Add to the selected chat's group. */
purple_blist_add_buddy((PurpleBuddy*)node, NULL, tg, NULL);
}
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
update_node_display(node, ggblist);
if (PURPLE_BLIST_NODE(tg) == target)
purple_blist_add_chat((PurpleChat*)node, tg, NULL);
@@ -1653,7 +1638,8 @@ draw_context_menu(FinchBlist *ggblist)
tree = GNT_TREE(ggblist->tree);
node = gnt_tree_get_selection_data(tree);
- if (node && purple_blist_node_get_type(node) == PURPLE_BLIST_OTHER_NODE)
+ if (node && !(PURPLE_IS_BUDDY(node) || PURPLE_IS_CONTACT(node) ||
+ PURPLE_IS_GROUP(node) || PURPLE_IS_CHAT(node)))
return;
if (ggblist->tooltip)
@@ -1668,19 +1654,19 @@ draw_context_menu(FinchBlist *ggblist)
if (!node) {
create_group_menu(GNT_MENU(context), NULL);
title = g_strdup(_("Buddy List"));
- } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ } else if (PURPLE_IS_CONTACT(node)) {
ggblist->cnode = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node)));
create_buddy_menu(GNT_MENU(context), (PurpleBuddy*)ggblist->cnode);
title = g_strdup(purple_contact_get_alias((PurpleContact*)node));
- } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ } else if (PURPLE_IS_BUDDY(node)) {
PurpleBuddy *buddy = (PurpleBuddy *)node;
create_buddy_menu(GNT_MENU(context), buddy);
title = g_strdup(purple_buddy_get_name(buddy));
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
PurpleChat *chat = (PurpleChat*)node;
create_chat_menu(GNT_MENU(context), chat);
title = g_strdup(purple_chat_get_name(chat));
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
PurpleGroup *group = (PurpleGroup *)node;
create_group_menu(GNT_MENU(context), group);
title = g_strdup(purple_group_get_name(group));
@@ -1691,22 +1677,22 @@ draw_context_menu(FinchBlist *ggblist)
/* These are common for everything */
if (node) {
add_custom_action(GNT_MENU(context),
- PURPLE_BLIST_NODE_IS_GROUP(node) ? _("Rename") : _("Alias"),
+ PURPLE_IS_GROUP(node) ? _("Rename") : _("Alias"),
PURPLE_CALLBACK(finch_blist_rename_node_cb), node);
add_custom_action(GNT_MENU(context), _("Remove"),
PURPLE_CALLBACK(finch_blist_remove_node_cb), node);
- if (ggblist->tagged && (PURPLE_BLIST_NODE_IS_CONTACT(node)
- || PURPLE_BLIST_NODE_IS_GROUP(node))) {
+ if (ggblist->tagged && (PURPLE_IS_CONTACT(node)
+ || PURPLE_IS_GROUP(node))) {
add_custom_action(GNT_MENU(context), _("Place tagged"),
PURPLE_CALLBACK(finch_blist_place_tagged), node);
}
- if (PURPLE_BLIST_NODE_IS_BUDDY(node) || PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if (PURPLE_IS_BUDDY(node) || PURPLE_IS_CONTACT(node)) {
add_custom_action(GNT_MENU(context), _("Toggle Tag"),
PURPLE_CALLBACK(finch_blist_toggle_tag_buddy), node);
}
- if (!PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ if (!PURPLE_IS_GROUP(node)) {
add_custom_action(GNT_MENU(context), _("View Log"),
PURPLE_CALLBACK(showlog_cb), node);
}
@@ -1902,7 +1888,7 @@ key_pressed(GntWidget *widget, const char *text, FinchBlist *ggblist)
} else if (strcmp(text, GNT_KEY_INS) == 0) {
PurpleBlistNode *node = gnt_tree_get_selection_data(GNT_TREE(ggblist->tree));
purple_blist_request_add_buddy(NULL, NULL,
- node && PURPLE_BLIST_NODE_IS_GROUP(node) ? purple_group_get_name(PURPLE_GROUP(node)) : NULL,
+ node && PURPLE_IS_GROUP(node) ? purple_group_get_name(PURPLE_GROUP(node)) : NULL,
NULL);
} else if (!gnt_tree_is_searching(GNT_TREE(ggblist->tree))) {
if (strcmp(text, "t") == 0) {
@@ -1985,7 +1971,7 @@ reset_blist_window(GntWidget *window, gpointer null)
{
PurpleBlistNode *node;
purple_signals_disconnect_by_handle(finch_blist_get_handle());
- FINCH_SET_DATA(purple_get_blist(), NULL);
+ FINCH_SET_DATA(purple_blist_get_buddy_list(), NULL);
node = purple_blist_get_root();
while (node) {
@@ -2028,7 +2014,7 @@ populate_buddylist(void)
(GCompareFunc)blist_node_compare_log);
}
- list = purple_get_blist();
+ list = purple_blist_get_buddy_list();
node = purple_blist_get_root();
while (node)
{
@@ -2359,25 +2345,21 @@ blist_node_compare_text(PurpleBlistNode *n1, PurpleBlistNode *n2)
char *us1, *us2;
int ret;
- if (purple_blist_node_get_type(n1) != purple_blist_node_get_type(n2))
+ if (G_OBJECT_TYPE(n1) != G_OBJECT_TYPE(n2))
return blist_node_compare_position(n1, n2);
- switch (purple_blist_node_get_type(n1))
- {
- case PURPLE_BLIST_CHAT_NODE:
- s1 = purple_chat_get_name((PurpleChat*)n1);
- s2 = purple_chat_get_name((PurpleChat*)n2);
- break;
- case PURPLE_BLIST_BUDDY_NODE:
- return purple_presence_compare(purple_buddy_get_presence((PurpleBuddy*)n1),
- purple_buddy_get_presence((PurpleBuddy*)n2));
- break;
- case PURPLE_BLIST_CONTACT_NODE:
- s1 = purple_contact_get_alias((PurpleContact*)n1);
- s2 = purple_contact_get_alias((PurpleContact*)n2);
- break;
- default:
- return blist_node_compare_position(n1, n2);
+ if (PURPLE_IS_CHAT(n1)) {
+ s1 = purple_chat_get_name((PurpleChat*)n1);
+ s2 = purple_chat_get_name((PurpleChat*)n2);
+ } else if (PURPLE_IS_BUDDY(n1)) {
+ return purple_buddy_presence_compare(
+ PURPLE_BUDDY_PRESENCE(purple_buddy_get_presence(PURPLE_BUDDY(n1))),
+ PURPLE_BUDDY_PRESENCE(purple_buddy_get_presence(PURPLE_BUDDY(n2))));
+ } else if (PURPLE_IS_CONTACT(n1)) {
+ s1 = purple_contact_get_alias((PurpleContact*)n1);
+ s2 = purple_contact_get_alias((PurpleContact*)n2);
+ } else {
+ return blist_node_compare_position(n1, n2);
}
us1 = g_utf8_strup(s1, -1);
@@ -2394,23 +2376,22 @@ blist_node_compare_status(PurpleBlistNode *n1, PurpleBlistNode *n2)
{
int ret;
- if (purple_blist_node_get_type(n1) != purple_blist_node_get_type(n2))
+ if (G_OBJECT_TYPE(n1) != G_OBJECT_TYPE(n2))
return blist_node_compare_position(n1, n2);
- switch (purple_blist_node_get_type(n1)) {
- case PURPLE_BLIST_CONTACT_NODE:
- n1 = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(n1)));
- n2 = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(n2)));
- /* now compare the presence of the priority buddies */
- case PURPLE_BLIST_BUDDY_NODE:
- ret = purple_presence_compare(purple_buddy_get_presence((PurpleBuddy*)n1),
- purple_buddy_get_presence((PurpleBuddy*)n2));
- if (ret != 0)
- return ret;
- break;
- default:
- return blist_node_compare_position(n1, n2);
- break;
+ if (PURPLE_IS_CONTACT(n1) || PURPLE_IS_BUDDY(n1)) {
+ n1 = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(n1)));
+ n2 = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(n2)));
+ }
+
+ if (PURPLE_IS_BUDDY(n1)) {
+ ret = purple_buddy_presence_compare(
+ PURPLE_BUDDY_PRESENCE(purple_buddy_get_presence(PURPLE_BUDDY(n1))),
+ PURPLE_BUDDY_PRESENCE(purple_buddy_get_presence(PURPLE_BUDDY(n2))));
+ if (ret != 0)
+ return ret;
+ } else {
+ return blist_node_compare_position(n1, n2);
}
/* Sort alphabetically if presence is not comparable */
@@ -2440,26 +2421,24 @@ blist_node_compare_log(PurpleBlistNode *n1, PurpleBlistNode *n2)
int ret;
PurpleBuddy *b1, *b2;
- if (purple_blist_node_get_type(n1) != purple_blist_node_get_type(n2))
+ if (G_OBJECT_TYPE(n1) != G_OBJECT_TYPE(n2))
return blist_node_compare_position(n1, n2);
- switch (purple_blist_node_get_type(n1)) {
- case PURPLE_BLIST_BUDDY_NODE:
- b1 = (PurpleBuddy*)n1;
- b2 = (PurpleBuddy*)n2;
- ret = purple_log_get_total_size(PURPLE_LOG_IM, purple_buddy_get_name(b2), purple_buddy_get_account(b2)) -
- purple_log_get_total_size(PURPLE_LOG_IM, purple_buddy_get_name(b1), purple_buddy_get_account(b1));
- if (ret != 0)
- return ret;
- break;
- case PURPLE_BLIST_CONTACT_NODE:
- ret = get_contact_log_size(n2) - get_contact_log_size(n1);
- if (ret != 0)
- return ret;
- break;
- default:
- return blist_node_compare_position(n1, n2);
+ if (PURPLE_IS_BUDDY(n1)) {
+ b1 = (PurpleBuddy*)n1;
+ b2 = (PurpleBuddy*)n2;
+ ret = purple_log_get_total_size(PURPLE_LOG_IM, purple_buddy_get_name(b2), purple_buddy_get_account(b2)) -
+ purple_log_get_total_size(PURPLE_LOG_IM, purple_buddy_get_name(b1), purple_buddy_get_account(b1));
+ if (ret != 0)
+ return ret;
+ } else if (PURPLE_IS_CONTACT(n1)) {
+ ret = get_contact_log_size(n2) - get_contact_log_size(n1);
+ if (ret != 0)
+ return ret;
+ } else {
+ return blist_node_compare_position(n1, n2);
}
+
ret = blist_node_compare_text(n1, n2);
return ret;
}
@@ -2506,13 +2485,14 @@ buddy_recent_signed_on_off(gpointer data)
fnode->signed_timer = 0;
if (!ggblist->manager->can_add_node(node)) {
- node_remove(purple_get_blist(), node);
+ node_remove(purple_blist_get_buddy_list(), node);
} else {
update_node_display(node, ggblist);
- if (purple_blist_node_get_parent(node) && PURPLE_BLIST_NODE_IS_CONTACT(purple_blist_node_get_parent(node)))
+ if (purple_blist_node_get_parent(node) && PURPLE_IS_CONTACT(purple_blist_node_get_parent(node)))
update_node_display(purple_blist_node_get_parent(node), ggblist);
}
+ g_object_unref(node);
return FALSE;
}
@@ -2526,9 +2506,11 @@ buddy_signed_on_off_cb(gpointer data)
if (fnode->signed_timer)
purple_timeout_remove(fnode->signed_timer);
+
+ g_object_ref(node);
fnode->signed_timer = purple_timeout_add_seconds(6, (GSourceFunc)buddy_recent_signed_on_off, data);
update_node_display(node, ggblist);
- if (purple_blist_node_get_parent(node) && PURPLE_BLIST_NODE_IS_CONTACT(purple_blist_node_get_parent(node)))
+ if (purple_blist_node_get_parent(node) && PURPLE_IS_CONTACT(purple_blist_node_get_parent(node)))
update_node_display(purple_blist_node_get_parent(node), ggblist);
return FALSE;
}
@@ -2639,7 +2621,7 @@ auto_join_chats(gpointer data)
for (node = purple_blist_get_root(); node;
node = purple_blist_node_next(node, FALSE)) {
- if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ if (PURPLE_IS_CHAT(node)) {
PurpleChat *chat = (PurpleChat*)node;
if (purple_chat_get_account(chat) == account &&
purple_blist_node_get_bool(node, "gnt-autojoin"))
@@ -2673,9 +2655,9 @@ block_select_cb(gpointer data, PurpleRequestFields *fields)
const char *name = purple_request_fields_get_string(fields, "screenname");
if (account && name && *name != '\0') {
if (purple_request_fields_get_choice(fields, "block") == 1) {
- purple_privacy_deny(account, name, FALSE, FALSE);
+ purple_account_privacy_deny(account, name);
} else {
- purple_privacy_allow(account, name, FALSE, FALSE);
+ purple_account_privacy_allow(account, name);
}
}
}
@@ -2710,7 +2692,7 @@ block_select(GntMenuItem *item, gpointer n)
purple_request_field_choice_add(field, _("Unblock"));
purple_request_field_group_add_field(group, field);
- purple_request_fields(purple_get_blist(), _("Block/Unblock"),
+ purple_request_fields(purple_blist_get_buddy_list(), _("Block/Unblock"),
NULL,
_("Please enter the username or alias of the person "
"you would like to Block/Unblock."),
@@ -2727,13 +2709,13 @@ send_im_select_cb(gpointer data, PurpleRequestFields *fields)
{
PurpleAccount *account;
const char *username;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
account = purple_request_fields_get_account(fields, "account");
username = purple_request_fields_get_string(fields, "screenname");
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, username);
- purple_conversation_present(conv);
+ im = purple_im_conversation_new(account, username);
+ purple_conversation_present(PURPLE_CONVERSATION(im));
}
static void
@@ -2761,7 +2743,7 @@ send_im_select(GntMenuItem *item, gpointer n)
purple_request_field_set_required(field, TRUE);
purple_request_field_group_add_field(group, field);
- purple_request_fields(purple_get_blist(), _("New Instant Message"),
+ purple_request_fields(purple_blist_get_buddy_list(), _("New Instant Message"),
NULL,
_("Please enter the username or alias of the person "
"you would like to IM."),
@@ -2780,7 +2762,7 @@ join_chat_select_cb(gpointer data, PurpleRequestFields *fields)
PurpleConnection *gc;
PurpleChat *chat;
GHashTable *hash = NULL;
- PurpleConversation *conv;
+ PurpleChatConversation *conv;
account = purple_request_fields_get_account(fields, "account");
name = purple_request_fields_get_string(fields, "chat");
@@ -2792,11 +2774,11 @@ join_chat_select_cb(gpointer data, PurpleRequestFields *fields)
/* Create a new conversation now. This will give focus to the new window.
* But it's necessary to pretend that we left the chat, because otherwise
* a new conversation window will pop up when we finally join the chat. */
- if (!(conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, name, account))) {
- conv = purple_conversation_new(PURPLE_CONV_TYPE_CHAT, account, name);
- purple_conv_chat_left(PURPLE_CONV_CHAT(conv));
+ if (!(conv = purple_conversations_find_chat_with_account(name, account))) {
+ conv = purple_chat_conversation_new(account, name);
+ purple_chat_conversation_leave(conv);
} else {
- purple_conversation_present(conv);
+ purple_conversation_present(PURPLE_CONVERSATION(conv));
}
chat = purple_blist_find_chat(account, name);
@@ -2836,7 +2818,7 @@ join_chat_select(GntMenuItem *item, gpointer n)
purple_request_field_set_required(field, TRUE);
purple_request_field_group_add_field(group, field);
- purple_request_fields(purple_get_blist(), _("Join a Chat"),
+ purple_request_fields(purple_blist_get_buddy_list(), _("Join a Chat"),
NULL,
_("Please enter the name of the chat you want to join."),
fields,
@@ -2857,7 +2839,7 @@ view_log_select_cb(gpointer data, PurpleRequestFields *fields)
account = purple_request_fields_get_account(fields, "account");
name = purple_request_fields_get_string(fields, "screenname");
- buddy = purple_find_buddy(account, name);
+ buddy = purple_blist_find_buddy(account, name);
if (buddy) {
contact = purple_buddy_get_contact(buddy);
} else {
@@ -2897,7 +2879,7 @@ view_log_cb(GntMenuItem *item, gpointer n)
purple_request_field_group_add_field(group, field);
purple_request_field_account_set_show_all(field, TRUE);
- purple_request_fields(purple_get_blist(), _("View Log"),
+ purple_request_fields(purple_blist_get_buddy_list(), _("View Log"),
NULL,
_("Please enter the username or alias of the person "
"whose log you would like to view."),
@@ -3057,13 +3039,13 @@ create_menu(void)
void finch_blist_show()
{
- blist_show(purple_get_blist());
+ blist_show(purple_blist_get_buddy_list());
}
static void
group_collapsed(GntWidget *widget, PurpleBlistNode *node, gboolean collapsed, gpointer null)
{
- if (PURPLE_BLIST_NODE_IS_GROUP(node))
+ if (PURPLE_IS_GROUP(node))
purple_blist_node_set_bool(node, "collapsed", collapsed);
}
diff --git a/finch/gntblist.h b/finch/gntblist.h
index 5b67691970..5c3dadfcc3 100644
--- a/finch/gntblist.h
+++ b/finch/gntblist.h
@@ -26,7 +26,7 @@
#ifndef _GNT_BLIST_H
#define _GNT_BLIST_H
-#include "blist.h"
+#include "buddylist.h"
#include "gnttree.h"
/**********************************************************************
diff --git a/finch/gntconv.c b/finch/gntconv.c
index ca8d826a6a..1f189387e6 100644
--- a/finch/gntconv.c
+++ b/finch/gntconv.c
@@ -78,7 +78,7 @@ static int color_timestamp;
static PurpleBuddy *
find_buddy_for_conversation(PurpleConversation *conv)
{
- return purple_find_buddy(purple_conversation_get_account(conv),
+ return purple_blist_find_buddy(purple_conversation_get_account(conv),
purple_conversation_get_name(conv));
}
@@ -94,17 +94,13 @@ get_conversation_blist_node(PurpleConversation *conv)
{
PurpleBlistNode *node = NULL;
- switch (purple_conversation_get_type(conv)) {
- case PURPLE_CONV_TYPE_IM:
- node = (PurpleBlistNode*)find_buddy_for_conversation(conv);
- node = node ? purple_blist_node_get_parent(node) : NULL;
- break;
- case PURPLE_CONV_TYPE_CHAT:
- node = (PurpleBlistNode*)find_chat_for_conversation(conv);
- break;
- default:
- break;
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ node = (PurpleBlistNode*)find_buddy_for_conversation(conv);
+ node = node ? purple_blist_node_get_parent(node) : NULL;
+ } else {
+ node = (PurpleBlistNode*)find_chat_for_conversation(conv);
}
+
return node;
}
@@ -115,26 +111,26 @@ send_typing_notification(GntWidget *w, FinchConv *ggconv)
gboolean empty = (!text || !*text || (*text == '/'));
if (purple_prefs_get_bool("/finch/conversations/notify_typing")) {
PurpleConversation *conv = ggconv->active_conv;
- PurpleConvIm *im = PURPLE_CONV_IM(conv);
+ PurpleIMConversation *im = PURPLE_IM_CONVERSATION(conv);
if (!empty) {
- gboolean send = (purple_conv_im_get_send_typed_timeout(im) == 0);
+ gboolean send = (purple_im_conversation_get_send_typed_timeout(im) == 0);
- purple_conv_im_stop_send_typed_timeout(im);
- purple_conv_im_start_send_typed_timeout(im);
- if (send || (purple_conv_im_get_type_again(im) != 0 &&
- time(NULL) > purple_conv_im_get_type_again(im))) {
+ purple_im_conversation_stop_send_typed_timeout(im);
+ purple_im_conversation_start_send_typed_timeout(im);
+ if (send || (purple_im_conversation_get_type_again(im) != 0 &&
+ time(NULL) > purple_im_conversation_get_type_again(im))) {
unsigned int timeout;
timeout = serv_send_typing(purple_conversation_get_connection(conv),
purple_conversation_get_name(conv),
- PURPLE_TYPING);
- purple_conv_im_set_type_again(im, timeout);
+ PURPLE_IM_TYPING);
+ purple_im_conversation_set_type_again(im, timeout);
}
} else {
- purple_conv_im_stop_send_typed_timeout(im);
+ purple_im_conversation_stop_send_typed_timeout(im);
serv_send_typing(purple_conversation_get_connection(conv),
purple_conversation_get_name(conv),
- PURPLE_NOT_TYPING);
+ PURPLE_IM_NOT_TYPING);
}
}
}
@@ -172,7 +168,7 @@ entry_key_pressed(GntWidget *w, FinchConv *ggconv)
PURPLE_MESSAGE_NO_LOG, time(NULL));
break;
case PURPLE_CMD_STATUS_WRONG_TYPE:
- if(purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
+ if(PURPLE_IS_IM_CONVERSATION(conv))
purple_conversation_write(conv, "", _("That command only works in chats, not IMs."),
PURPLE_MESSAGE_NO_LOG, time(NULL));
else
@@ -194,18 +190,7 @@ entry_key_pressed(GntWidget *w, FinchConv *ggconv)
else
{
char *escape = purple_markup_escape_text((*text == '/' ? text + 1 : text), -1);
- switch (purple_conversation_get_type(ggconv->active_conv))
- {
- case PURPLE_CONV_TYPE_IM:
- purple_conv_im_send_with_flags(PURPLE_CONV_IM(ggconv->active_conv), escape, PURPLE_MESSAGE_SEND);
- break;
- case PURPLE_CONV_TYPE_CHAT:
- purple_conv_chat_send(PURPLE_CONV_CHAT(ggconv->active_conv), escape);
- break;
- default:
- g_free(escape);
- g_return_if_reached();
- }
+ purple_conversation_send(ggconv->active_conv, escape);
g_free(escape);
purple_idle_touch();
}
@@ -221,7 +206,7 @@ closing_window(GntWidget *window, FinchConv *ggconv)
while (list) {
PurpleConversation *conv = list->data;
list = list->next;
- purple_conversation_destroy(conv);
+ g_object_unref(conv);
}
}
@@ -241,12 +226,12 @@ save_position_cb(GntWidget *w, int x, int y)
purple_prefs_set_int(PREF_ROOT "/position/y", y);
}
-static PurpleConversation *
-find_conv_with_contact(PurpleAccount *account, const char *name)
+static PurpleIMConversation *
+find_im_with_contact(PurpleAccount *account, const char *name)
{
PurpleBlistNode *node;
- PurpleBuddy *buddy = purple_find_buddy(account, name);
- PurpleConversation *ret = NULL;
+ PurpleBuddy *buddy = purple_blist_find_buddy(account, name);
+ PurpleIMConversation *im = NULL;
if (!buddy)
return NULL;
@@ -255,11 +240,11 @@ find_conv_with_contact(PurpleAccount *account, const char *name)
node; node = purple_blist_node_get_sibling_next(node)) {
if (node == (PurpleBlistNode*)buddy)
continue;
- if ((ret = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
+ if ((im = purple_conversations_find_im_with_account(
purple_buddy_get_name((PurpleBuddy*)node), purple_buddy_get_account((PurpleBuddy*)node))) != NULL)
break;
}
- return ret;
+ return im;
}
static char *
@@ -272,20 +257,20 @@ get_conversation_title(PurpleConversation *conv, PurpleAccount *account)
static void
update_buddy_typing(PurpleAccount *account, const char *who, gpointer null)
{
- PurpleConversation *conv;
FinchConv *ggc;
- PurpleConvIm *im = NULL;
+ PurpleIMConversation *im;
+ PurpleConversation *conv;
char *title, *str;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, account);
+ im = purple_conversations_find_im_with_account(who, account);
- if (!conv)
+ if (!im)
return;
- im = PURPLE_CONV_IM(conv);
+ conv = PURPLE_CONVERSATION(im);
ggc = FINCH_CONV(conv);
- if (purple_conv_im_get_typing_state(im) == PURPLE_TYPING) {
+ if (purple_im_conversation_get_typing_state(im) == PURPLE_IM_TYPING) {
int scroll;
str = get_conversation_title(conv, account);
title = g_strdup_printf(_("%s [%s]"), str,
@@ -319,29 +304,29 @@ chat_left_cb(PurpleConversation *conv, gpointer null)
static void
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)
+ PurpleIMConversation *im = find_im_with_contact(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy));
+ if (im == NULL)
return;
- generate_send_to_menu(FINCH_CONV(conv));
+ generate_send_to_menu(FINCH_CONV(PURPLE_CONVERSATION(im)));
}
static void
account_signed_on_off(PurpleConnection *gc, gpointer null)
{
- GList *list = purple_get_ims();
+ GList *list = purple_conversations_get_ims();
while (list) {
PurpleConversation *conv = list->data;
- PurpleConversation *cc = find_conv_with_contact(
+ PurpleIMConversation *cc = find_im_with_contact(
purple_conversation_get_account(conv), purple_conversation_get_name(conv));
if (cc)
- generate_send_to_menu(FINCH_CONV(cc));
+ generate_send_to_menu(FINCH_CONV(PURPLE_CONVERSATION(cc)));
list = list->next;
}
if (PURPLE_CONNECTION_IS_CONNECTED(gc)) {
/* We just signed on. Let's see if there's any chat that we have open,
* and hadn't left before the disconnect. */
- list = purple_get_chats();
+ list = purple_conversations_get_chats();
while (list) {
PurpleConversation *conv = list->data;
PurpleChat *chat;
@@ -349,7 +334,7 @@ account_signed_on_off(PurpleConnection *gc, gpointer null)
list = list->next;
if (purple_conversation_get_account(conv) != purple_connection_get_account(gc) ||
- !purple_conversation_get_data(conv, "want-to-rejoin"))
+ !g_object_get_data(G_OBJECT(conv), "want-to-rejoin"))
continue;
chat = find_chat_for_conversation(conv);
@@ -370,16 +355,16 @@ account_signed_on_off(PurpleConnection *gc, gpointer null)
static void
account_signing_off(PurpleConnection *gc)
{
- GList *list = purple_get_chats();
+ GList *list = purple_conversations_get_chats();
PurpleAccount *account = purple_connection_get_account(gc);
/* We are about to sign off. See which chats we are currently in, and mark
* them for rejoin on reconnect. */
while (list) {
PurpleConversation *conv = list->data;
- if (!purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)) &&
+ if (!purple_chat_conversation_has_left(PURPLE_CHAT_CONVERSATION(conv)) &&
purple_conversation_get_account(conv) == account) {
- purple_conversation_set_data(conv, "want-to-rejoin", GINT_TO_POINTER(TRUE));
+ g_object_set_data(G_OBJECT(conv), "want-to-rejoin", GINT_TO_POINTER(TRUE));
purple_conversation_write(conv, NULL, _("The account has disconnected and you are no "
"longer in this chat. You will be automatically rejoined in the chat when "
"the account reconnects."),
@@ -421,9 +406,9 @@ gg_extended_menu(FinchConv *ggc)
}
static void
-conv_updated(PurpleConversation *conv, PurpleConvUpdateType type)
+conv_updated(PurpleConversation *conv, PurpleConversationUpdateType type)
{
- if (type == PURPLE_CONV_UPDATE_FEATURES) {
+ if (type == PURPLE_CONVERSATION_UPDATE_FEATURES) {
gg_extended_menu(purple_conversation_get_ui_data(conv));
}
}
@@ -518,8 +503,8 @@ send_to_cb(GntMenuItem *m, gpointer n)
{
PurpleAccount *account = g_object_get_data(G_OBJECT(m), "purple_account");
gchar *buddy = g_object_get_data(G_OBJECT(m), "purple_buddy_name");
- PurpleConversation *conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, buddy);
- finch_conversation_set_active(conv);
+ PurpleIMConversation *im = purple_im_conversation_new(account, buddy);
+ finch_conversation_set_active(PURPLE_CONVERSATION(im));
}
static void
@@ -536,17 +521,15 @@ view_log_cb(GntMenuItem *n, gpointer ggc)
fc = ggc;
conv = fc->active_conv;
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
+ if (PURPLE_IS_IM_CONVERSATION(conv))
type = PURPLE_LOG_IM;
- else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
- type = PURPLE_LOG_CHAT;
else
- return;
+ type = PURPLE_LOG_CHAT;
name = purple_conversation_get_name(conv);
account = purple_conversation_get_account(conv);
- buddies = purple_find_buddies(account, name);
+ buddies = purple_blist_find_buddies(account, name);
for (cur = buddies; cur != NULL; cur = cur->next) {
PurpleBlistNode *node = cur->data;
if ((node != NULL) &&
@@ -569,7 +552,7 @@ generate_send_to_menu(FinchConv *ggc)
GSList *buds;
GList *list = NULL;
- buds = purple_find_buddies(purple_conversation_get_account(ggc->active_conv),
+ buds = purple_blist_find_buddies(purple_conversation_get_account(ggc->active_conv),
purple_conversation_get_name(ggc->active_conv));
if (!buds)
return;
@@ -598,7 +581,7 @@ generate_send_to_menu(FinchConv *ggc)
}
for (list = g_list_reverse(list); list != NULL; list = g_list_delete_link(list, list)) {
PurplePresence *pre = list->data;
- PurpleBuddy *buddy = purple_presence_get_buddy(pre);
+ PurpleBuddy *buddy = purple_buddy_presence_get_buddy(PURPLE_BUDDY_PRESENCE(pre));
PurpleAccount *account = purple_buddy_get_account(buddy);
gchar *name = g_strdup(purple_buddy_get_name(buddy));
gchar *text = g_strdup_printf("%s (%s)", purple_buddy_get_name(buddy), purple_account_get_username(account));
@@ -615,8 +598,8 @@ static void
invite_cb(GntMenuItem *item, gpointer ggconv)
{
FinchConv *fc = ggconv;
- PurpleConversation *conv = fc->active_conv;
- purple_conv_chat_invite_user(PURPLE_CONV_CHAT(conv), NULL, NULL, TRUE);
+ PurpleChatConversation *chat = PURPLE_CHAT_CONVERSATION(fc->active_conv);
+ purple_chat_conversation_invite_user(chat, NULL, NULL, TRUE);
}
static void
@@ -650,7 +633,7 @@ gg_create_menu(FinchConv *ggc)
gnt_menu_add_item(GNT_MENU(sub), item);
gnt_menuitem_set_callback(item, toggle_timestamps_cb, ggc);
- if (purple_conversation_get_type(ggc->active_conv) == PURPLE_CONV_TYPE_IM) {
+ if (PURPLE_IS_IM_CONVERSATION(ggc->active_conv)) {
PurpleAccount *account = purple_conversation_get_account(ggc->active_conv);
PurpleConnection *gc = purple_account_get_connection(account);
PurplePluginProtocolInfo *pinfo =
@@ -675,7 +658,7 @@ gg_create_menu(FinchConv *ggc)
}
generate_send_to_menu(ggc);
- } else if (purple_conversation_get_type(ggc->active_conv) == PURPLE_CONV_TYPE_CHAT) {
+ } else {
item = gnt_menuitem_new(_("Invite..."));
gnt_menu_add_item(GNT_MENU(sub), item);
gnt_menuitem_set_callback(item, invite_cb, ggc);
@@ -722,10 +705,11 @@ create_conv_from_userlist(GntWidget *widget, FinchConv *fc)
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);
+ realname = prpl_info->get_cb_real_name(gc, purple_chat_conversation_get_id(
+ PURPLE_CHAT_CONVERSATION(fc->active_conv)), name);
else
realname = NULL;
- purple_conversation_new(PURPLE_CONV_TYPE_IM, account, realname ? realname : name);
+ purple_im_conversation_new(account, realname ? realname : name);
g_free(realname);
}
@@ -734,8 +718,8 @@ gained_focus_cb(GntWindow *window, FinchConv *fc)
{
GList *iter;
for (iter = fc->list; iter; iter = iter->next) {
- purple_conversation_set_data(iter->data, "unseen-count", 0);
- purple_conversation_update(iter->data, PURPLE_CONV_UPDATE_UNSEEN);
+ g_object_set_data(G_OBJECT(iter->data), "unseen-count", 0);
+ purple_conversation_update(iter->data, PURPLE_CONVERSATION_UPDATE_UNSEEN);
}
}
@@ -788,7 +772,6 @@ finch_create_conversation(PurpleConversation *conv)
{
FinchConv *ggc = FINCH_CONV(conv);
char *title;
- PurpleConversationType type;
PurpleConversation *cc;
PurpleAccount *account;
PurpleBlistNode *convnode = NULL;
@@ -799,7 +782,7 @@ finch_create_conversation(PurpleConversation *conv)
}
account = purple_conversation_get_account(conv);
- cc = find_conv_with_contact(account, purple_conversation_get_name(conv));
+ cc = PURPLE_CONVERSATION(find_im_with_contact(account, purple_conversation_get_name(conv)));
if (cc && FINCH_CONV(cc))
ggc = FINCH_CONV(cc);
else
@@ -820,7 +803,6 @@ finch_create_conversation(PurpleConversation *conv)
return;
}
- type = purple_conversation_get_type(conv);
title = get_conversation_title(conv, account);
ggc->window = gnt_vwindow_new(FALSE);
@@ -828,30 +810,15 @@ finch_create_conversation(PurpleConversation *conv)
gnt_box_set_toplevel(GNT_BOX(ggc->window), TRUE);
gnt_box_set_pad(GNT_BOX(ggc->window), 0);
- switch (purple_conversation_get_type(conv)) {
- case PURPLE_CONV_TYPE_UNKNOWN:
- gnt_widget_set_name(ggc->window, "conversation-window-unknown" );
- break;
- case PURPLE_CONV_TYPE_IM:
- gnt_widget_set_name(ggc->window, "conversation-window-im" );
- break;
- case PURPLE_CONV_TYPE_CHAT:
- gnt_widget_set_name(ggc->window, "conversation-window-chat" );
- break;
- case PURPLE_CONV_TYPE_MISC:
- gnt_widget_set_name(ggc->window, "conversation-window-misc" );
- break;
- case PURPLE_CONV_TYPE_ANY:
- gnt_widget_set_name(ggc->window, "conversation-window-any" );
- break;
- }
+ gnt_widget_set_name(ggc->window,
+ PURPLE_IS_IM_CONVERSATION(conv) ? "conversation-window-im" : "conversation-window-chat");
ggc->tv = gnt_text_view_new();
gnt_widget_set_name(ggc->tv, "conversation-window-textview");
gnt_widget_set_size(ggc->tv, purple_prefs_get_int(PREF_ROOT "/size/width"),
purple_prefs_get_int(PREF_ROOT "/size/height"));
- if (type == PURPLE_CONV_TYPE_CHAT) {
+ if (PURPLE_IS_CHAT_CONVERSATION(conv)) {
GntWidget *hbox, *tree;
FinchConvChat *fc = ggc->u.chat = g_new0(FinchConvChat, 1);
hbox = gnt_hbox_new(FALSE);
@@ -896,9 +863,8 @@ finch_create_conversation(PurpleConversation *conv)
g_signal_connect(G_OBJECT(ggc->tv), "size_changed", G_CALLBACK(size_changed_cb), NULL);
g_signal_connect(G_OBJECT(ggc->window), "position_set", G_CALLBACK(save_position_cb), NULL);
- if (type == PURPLE_CONV_TYPE_IM) {
+ if (PURPLE_IS_IM_CONVERSATION(conv))
g_signal_connect(G_OBJECT(ggc->entry), "text_changed", G_CALLBACK(send_typing_notification), ggc);
- }
convnode = get_conversation_blist_node(conv);
if ((convnode && purple_blist_node_get_bool(convnode, "gnt-mute-sound")) ||
@@ -1027,8 +993,8 @@ finch_write_common(PurpleConversation *conv, const char *who, const char *messag
g_free(newline);
g_free(strip);
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM &&
- purple_conv_im_get_typing_state(PURPLE_CONV_IM(conv)) == PURPLE_TYPING) {
+ if (PURPLE_IS_IM_CONVERSATION(conv) && purple_im_conversation_get_typing_state(
+ PURPLE_IM_CONVERSATION(conv)) == PURPLE_IM_TYPING) {
strip = g_strdup_printf(_("\n%s is typing..."), purple_conversation_get_title(conv));
gnt_text_view_append_text_with_tag(GNT_TEXT_VIEW(ggconv->tv),
strip, GNT_TEXT_FLAG_DIM, "typing");
@@ -1041,29 +1007,30 @@ finch_write_common(PurpleConversation *conv, const char *who, const char *messag
if (flags & (PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_NICK | PURPLE_MESSAGE_ERROR))
gnt_widget_set_urgent(ggconv->tv);
if (flags & PURPLE_MESSAGE_RECV && !gnt_widget_has_focus(ggconv->window)) {
- int count = GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count"));
- purple_conversation_set_data(conv, "unseen-count", GINT_TO_POINTER(count + 1));
- purple_conversation_update(conv, PURPLE_CONV_UPDATE_UNSEEN);
+ int count = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(conv), "unseen-count"));
+ g_object_set_data(G_OBJECT(conv), "unseen-count", GINT_TO_POINTER(count + 1));
+ purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_UNSEEN);
}
}
static void
-finch_write_chat(PurpleConversation *conv, const char *who, const char *message,
+finch_write_chat(PurpleChatConversation *chat, const char *who, const char *message,
PurpleMessageFlags flags, time_t mtime)
{
- purple_conversation_write(conv, who, message, flags, mtime);
+ purple_conversation_write(PURPLE_CONVERSATION(chat), who, message, flags, mtime);
}
static void
-finch_write_im(PurpleConversation *conv, const char *who, const char *message,
+finch_write_im(PurpleIMConversation *im, const char *who, const char *message,
PurpleMessageFlags flags, time_t mtime)
{
+ PurpleConversation *conv = PURPLE_CONVERSATION(im);
PurpleAccount *account = purple_conversation_get_account(conv);
if (flags & PURPLE_MESSAGE_SEND)
{
who = purple_connection_get_display_name(purple_account_get_connection(account));
if (!who)
- who = purple_account_get_alias(account);
+ who = purple_account_get_private_alias(account);
if (!who)
who = purple_account_get_username(account);
}
@@ -1071,7 +1038,7 @@ finch_write_im(PurpleConversation *conv, const char *who, const char *message,
{
PurpleBuddy *buddy;
who = purple_conversation_get_name(conv);
- buddy = purple_find_buddy(account, who);
+ buddy = purple_blist_find_buddy(account, who);
if (buddy)
who = purple_buddy_get_contact_alias(buddy);
}
@@ -1095,22 +1062,23 @@ finch_write_conv(PurpleConversation *conv, const char *who, const char *alias,
}
static const char *
-chat_flag_text(PurpleConvChatBuddyFlags flags)
+chat_flag_text(PurpleChatUserFlags flags)
{
- if (flags & PURPLE_CBFLAGS_FOUNDER)
+ if (flags & PURPLE_CHAT_USER_FOUNDER)
return "~";
- if (flags & PURPLE_CBFLAGS_OP)
+ if (flags & PURPLE_CHAT_USER_OP)
return "@";
- if (flags & PURPLE_CBFLAGS_HALFOP)
+ if (flags & PURPLE_CHAT_USER_HALFOP)
return "%";
- if (flags & PURPLE_CBFLAGS_VOICE)
+ if (flags & PURPLE_CHAT_USER_VOICE)
return "+";
return " ";
}
static void
-finch_chat_add_users(PurpleConversation *conv, GList *users, gboolean new_arrivals)
+finch_chat_add_users(PurpleChatConversation *chat, GList *users, gboolean new_arrivals)
{
+ PurpleConversation *conv = PURPLE_CONVERSATION(chat);
FinchConv *ggc = FINCH_CONV(conv);
GntEntry *entry = GNT_ENTRY(ggc->entry);
@@ -1125,11 +1093,11 @@ finch_chat_add_users(PurpleConversation *conv, GList *users, gboolean new_arriva
ngettext("List of %d user:\n", "List of %d users:\n", count), count);
for (iter = users; iter; iter = iter->next)
{
- PurpleConvChatBuddy *cbuddy = iter->data;
+ PurpleChatUser *chatuser = iter->data;
const char *str;
- if ((str = purple_conv_chat_cb_get_alias(cbuddy)) == NULL)
- str = purple_conv_chat_cb_get_name(cbuddy);
+ if ((str = purple_chat_user_get_alias(chatuser)) == NULL)
+ str = purple_chat_user_get_name(chatuser);
g_string_append_printf(string, "[ %s ]", str);
}
@@ -1140,23 +1108,23 @@ finch_chat_add_users(PurpleConversation *conv, GList *users, gboolean new_arriva
for (; users; users = users->next)
{
- PurpleConvChatBuddy *cbuddy = users->data;
+ PurpleChatUser *chatuser = users->data;
GntTree *tree = GNT_TREE(ggc->u.chat->userlist);
- 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);
+ gnt_entry_add_suggest(entry, purple_chat_user_get_name(chatuser));
+ gnt_entry_add_suggest(entry, purple_chat_user_get_alias(chatuser));
+ gnt_tree_add_row_after(tree, g_strdup(purple_chat_user_get_name(chatuser)),
+ gnt_tree_create_row(tree, chat_flag_text(purple_chat_user_get_flags(chatuser)), purple_chat_user_get_alias(chatuser)), NULL, NULL);
}
}
static void
-finch_chat_rename_user(PurpleConversation *conv, const char *old, const char *new_n, const char *new_a)
+finch_chat_rename_user(PurpleChatConversation *chat, const char *old, const char *new_n, const char *new_a)
{
/* Update the name for string completion */
- FinchConv *ggc = FINCH_CONV(conv);
+ FinchConv *ggc = FINCH_CONV(PURPLE_CONVERSATION(chat));
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);
+ PurpleChatUser *cb = purple_chat_conversation_find_user(chat, new_n);
gnt_entry_remove_suggest(entry, old);
gnt_tree_remove(tree, (gpointer)old);
@@ -1164,14 +1132,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(purple_conv_chat_cb_get_flags(cb)), new_a), NULL, NULL);
+ gnt_tree_create_row(tree, chat_flag_text(purple_chat_user_get_flags(cb)), new_a), NULL, NULL);
}
static void
-finch_chat_remove_users(PurpleConversation *conv, GList *list)
+finch_chat_remove_users(PurpleChatConversation *chat, GList *list)
{
/* Remove the name from string completion */
- FinchConv *ggc = FINCH_CONV(conv);
+ FinchConv *ggc = FINCH_CONV(PURPLE_CONVERSATION(chat));
GntEntry *entry = GNT_ENTRY(ggc->entry);
for (; list; list = list->next) {
GntTree *tree = GNT_TREE(ggc->u.chat->userlist);
@@ -1181,11 +1149,18 @@ finch_chat_remove_users(PurpleConversation *conv, GList *list)
}
static void
-finch_chat_update_user(PurpleConversation *conv, const char *user)
+finch_chat_update_user(PurpleChatUser *cb)
{
- PurpleConvChatBuddy *cb = purple_conv_chat_cb_find(PURPLE_CONV_CHAT(conv), user);
- 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)));
+ PurpleChatConversation *chat;
+ FinchConv *ggc;
+ if (!cb)
+ return;
+
+ chat = purple_chat_user_get_chat(cb);
+ ggc = FINCH_CONV(PURPLE_CONVERSATION(chat));
+ gnt_tree_change_text(GNT_TREE(ggc->u.chat->userlist),
+ (gpointer)purple_chat_user_get_name(cb), 0,
+ chat_flag_text(purple_chat_user_get_flags(cb)));
}
static void
@@ -1238,10 +1213,7 @@ static PurpleCmdRet
say_command_cb(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
- purple_conv_im_send(PURPLE_CONV_IM(conv), args[0]);
- else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
- purple_conv_chat_send(PURPLE_CONV_CHAT(conv), args[0]);
+ purple_conversation_send(conv, args[0]);
return PURPLE_CMD_RET_OK;
}
@@ -1254,11 +1226,7 @@ me_command_cb(PurpleConversation *conv,
char *tmp;
tmp = g_strdup_printf("/me %s", args[0]);
-
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
- purple_conv_im_send(PURPLE_CONV_IM(conv), tmp);
- else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
- purple_conv_chat_send(PURPLE_CONV_CHAT(conv), tmp);
+ purple_conversation_send(conv, tmp);
g_free(tmp);
return PURPLE_CMD_RET_OK;
@@ -1299,10 +1267,7 @@ debug_command_cb(PurpleConversation *conv,
}
markup = g_markup_escape_text(tmp, -1);
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
- purple_conv_im_send(PURPLE_CONV_IM(conv), markup);
- else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
- purple_conv_chat_send(PURPLE_CONV_CHAT(conv), markup);
+ purple_conversation_send(conv, markup);
g_free(tmp);
g_free(markup);
diff --git a/finch/gntlog.c b/finch/gntlog.c
index c946c285c6..6d5a924299 100644
--- a/finch/gntlog.c
+++ b/finch/gntlog.c
@@ -407,7 +407,7 @@ void finch_log_show(PurpleLogType type, const char *username, PurpleAccount *acc
PurpleBuddy *buddy;
if (username) {
- buddy = purple_find_buddy(account, username);
+ buddy = purple_blist_find_buddy(account, username);
if (buddy != NULL)
name = purple_buddy_get_contact_alias(buddy);
title = g_strdup_printf(_("Conversations with %s"), name);
@@ -461,7 +461,7 @@ void finch_log_show_contact(PurpleContact *contact)
child = purple_blist_node_get_sibling_next(child)) {
const char *name;
PurpleAccount *account;
- if (!PURPLE_BLIST_NODE_IS_BUDDY(child))
+ if (!PURPLE_IS_BUDDY(child))
continue;
name = purple_buddy_get_name((PurpleBuddy *)child);
@@ -481,7 +481,7 @@ void finch_log_show_contact(PurpleContact *contact)
* There is probably a better way to deal with this. */
if (name == NULL) {
child = purple_blist_node_get_first_child((PurpleBlistNode*)contact);
- if (child != NULL && PURPLE_BLIST_NODE_IS_BUDDY(child))
+ if (child != NULL && PURPLE_IS_BUDDY(child))
name = purple_buddy_get_contact_alias((PurpleBuddy *)child);
if (name == NULL)
name = "";
@@ -533,11 +533,9 @@ void finch_log_init(void)
purple_signal_register(handle, "log-displaying",
purple_marshal_VOID__POINTER_POINTER,
- NULL, 2,
- purple_value_new(PURPLE_TYPE_BOXED,
- "FinchLogViewer *"),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_LOG));
+ G_TYPE_NONE, 2,
+ G_TYPE_POINTER, /* (FinchLogViewer *) */
+ PURPLE_TYPE_LOG);
}
void
diff --git a/finch/gntmedia.c b/finch/gntmedia.c
index 9c524d7eff..b88169fec2 100644
--- a/finch/gntmedia.c
+++ b/finch/gntmedia.c
@@ -262,7 +262,7 @@ finch_media_state_changed_cb(PurpleMedia *media, PurpleMediaState state,
gchar *message = NULL;
account = purple_media_get_account(gntmedia->priv->media);
- buddy = purple_find_buddy(account, name);
+ buddy = purple_blist_find_buddy(account, name);
alias = buddy ? purple_buddy_get_contact_alias(buddy) : name;
if (type & PURPLE_MEDIA_AUDIO) {
@@ -378,8 +378,8 @@ finch_media_new(PurpleMedia *media)
static void
gntmedia_message_cb(FinchMedia *gntmedia, const char *msg, PurpleConversation *conv)
{
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- purple_conv_im_write(PURPLE_CONV_IM(conv), NULL, msg, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ purple_conversation_write_message(conv, NULL, msg, PURPLE_MESSAGE_SYSTEM, time(NULL));
}
}
@@ -390,7 +390,7 @@ finch_new_media(PurpleMediaManager *manager, PurpleMedia *media,
GntWidget *gntmedia;
PurpleConversation *conv;
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, name);
+ conv = PURPLE_CONVERSATION(purple_im_conversation_new(account, name));
gntmedia = finch_media_new(media);
g_signal_connect(G_OBJECT(gntmedia), "message", G_CALLBACK(gntmedia_message_cb), conv);
diff --git a/finch/gntpounce.c b/finch/gntpounce.c
index c5fc691a54..66c5adb6ef 100644
--- a/finch/gntpounce.c
+++ b/finch/gntpounce.c
@@ -173,7 +173,7 @@ setup_buddy_list_suggestion(GntEntry *entry, gboolean offline)
{
PurpleBlistNode *node = purple_blist_get_root();
for (; node; node = purple_blist_node_next(node, offline)) {
- if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (!PURPLE_IS_BUDDY(node))
continue;
gnt_entry_add_suggest(entry, purple_buddy_get_name((PurpleBuddy*)node));
}
@@ -558,7 +558,7 @@ finch_pounce_editor_show(PurpleAccount *account, const char *name,
PurpleBuddy *buddy = NULL;
if (name != NULL)
- buddy = purple_find_buddy(account, name);
+ buddy = purple_blist_find_buddy(account, name);
/* Set some defaults */
if (buddy == NULL) {
@@ -780,7 +780,7 @@ finch_pounces_manager_hide(void)
static void
pounce_cb(PurplePounce *pounce, PurplePounceEvent events, void *data)
{
- PurpleConversation *conv;
+ PurpleIMConversation *im;
PurpleAccount *account;
PurpleBuddy *buddy;
const char *pouncee;
@@ -789,7 +789,7 @@ pounce_cb(PurplePounce *pounce, PurplePounceEvent events, void *data)
pouncee = purple_pounce_get_pouncee(pounce);
account = purple_pounce_get_pouncer(pounce);
- buddy = purple_find_buddy(account, pouncee);
+ buddy = purple_blist_find_buddy(account, pouncee);
if (buddy != NULL)
{
alias = purple_buddy_get_alias(buddy);
@@ -801,8 +801,8 @@ pounce_cb(PurplePounce *pounce, PurplePounceEvent events, void *data)
if (purple_pounce_action_is_enabled(pounce, "open-window"))
{
- if (!purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, pouncee, account))
- purple_conversation_new(PURPLE_CONV_TYPE_IM, account, pouncee);
+ if (!purple_conversations_find_im_with_account(pouncee, account))
+ purple_im_conversation_new(account, pouncee);
}
if (purple_pounce_action_is_enabled(pounce, "popup-notify"))
@@ -849,7 +849,7 @@ pounce_cb(PurplePounce *pounce, PurplePounceEvent events, void *data)
* 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)
+ if ((name_shown = purple_account_get_private_alias(account)) == NULL)
name_shown = purple_account_get_username(account);
if (reason == NULL)
@@ -874,12 +874,12 @@ pounce_cb(PurplePounce *pounce, PurplePounceEvent events, void *data)
if (message != NULL)
{
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, pouncee, account);
+ im = purple_conversations_find_im_with_account(pouncee, account);
- if (conv == NULL)
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, pouncee);
+ if (im == NULL)
+ im = purple_im_conversation_new(account, pouncee);
- purple_conversation_write(conv, NULL, message,
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, message,
PURPLE_MESSAGE_SEND, time(NULL));
serv_send_im(purple_account_get_connection(account), (char *)pouncee, (char *)message, 0);
diff --git a/finch/gntrequest.c b/finch/gntrequest.c
index 3f4413504e..838c339b3e 100644
--- a/finch/gntrequest.c
+++ b/finch/gntrequest.c
@@ -412,7 +412,7 @@ update_selected_account(GntEntry *username, const char *start, const char *end,
GList *accounts = gnt_tree_get_rows(GNT_TREE(accountlist->dropdown));
const char *name = gnt_entry_get_text(username);
while (accounts) {
- if (purple_find_buddy(accounts->data, name)) {
+ if (purple_blist_find_buddy(accounts->data, name)) {
gnt_combo_box_set_selected(accountlist, accounts->data);
gnt_widget_draw(GNT_WIDGET(accountlist));
break;
@@ -443,7 +443,7 @@ create_string_field(PurpleRequestField *field, GntWidget **username)
PurpleBlistNode *node = purple_blist_get_root();
gboolean offline = purple_str_has_suffix(hint, "all");
for (; node; node = purple_blist_node_next(node, offline)) {
- if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (!PURPLE_IS_BUDDY(node))
continue;
gnt_entry_add_suggest(GNT_ENTRY(entry), purple_buddy_get_name((PurpleBuddy*)node));
}
@@ -454,7 +454,7 @@ create_string_field(PurpleRequestField *field, GntWidget **username)
PurpleBlistNode *node;
for (node = purple_blist_get_root(); node;
node = purple_blist_node_get_sibling_next(node)) {
- if (PURPLE_BLIST_NODE_IS_GROUP(node))
+ if (PURPLE_IS_GROUP(node))
gnt_entry_add_suggest(GNT_ENTRY(entry), purple_group_get_name((PurpleGroup *)node));
}
}
diff --git a/finch/gntsound.c b/finch/gntsound.c
index fee724b0e7..4eace710d5 100644
--- a/finch/gntsound.c
+++ b/finch/gntsound.c
@@ -137,20 +137,18 @@ unmute_login_sounds_cb(gpointer data)
}
static gboolean
-chat_nick_matches_name(PurpleConversation *conv, const char *aname)
+chat_nick_matches_name(PurpleChatConversation *chat, const char *aname)
{
- PurpleConvChat *chat = NULL;
char *nick = NULL;
char *name = NULL;
gboolean ret = FALSE;
PurpleAccount *account;
- chat = purple_conversation_get_chat_data(conv);
if (chat == NULL)
return ret;
- account = purple_conversation_get_account(conv);
- nick = g_strdup(purple_normalize(account, purple_conv_chat_get_nick(chat)));
+ account = purple_conversation_get_account(PURPLE_CONVERSATION(chat));
+ nick = g_strdup(purple_normalize(account, purple_chat_conversation_get_nick(chat)));
name = g_strdup(purple_normalize(account, aname));
if (g_utf8_collate(nick, name) == 0)
@@ -214,26 +212,26 @@ static void
im_msg_sent_cb(PurpleAccount *account, const char *receiver,
const char *message, PurpleSoundEventID event)
{
- PurpleConversation *conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_IM, receiver, account);
- play_conv_event(conv, event);
+ PurpleIMConversation *im = purple_conversations_find_im_with_account(
+ receiver, account);
+ play_conv_event(PURPLE_CONVERSATION(im), event);
}
static void
-chat_buddy_join_cb(PurpleConversation *conv, const char *name,
- PurpleConvChatBuddyFlags flags, gboolean new_arrival,
+chat_user_join_cb(PurpleChatConversation *chat, const char *name,
+ PurpleChatUserFlags flags, gboolean new_arrival,
PurpleSoundEventID event)
{
- if (new_arrival && !chat_nick_matches_name(conv, name))
- play_conv_event(conv, event);
+ if (new_arrival && !chat_nick_matches_name(chat, name))
+ play_conv_event(PURPLE_CONVERSATION(chat), event);
}
static void
-chat_buddy_left_cb(PurpleConversation *conv, const char *name,
+chat_user_left_cb(PurpleChatConversation *chat, const char *name,
const char *reason, PurpleSoundEventID event)
{
- if (!chat_nick_matches_name(conv, name))
- play_conv_event(conv, event);
+ if (!chat_nick_matches_name(chat, name))
+ play_conv_event(PURPLE_CONVERSATION(chat), event);
}
static void
@@ -241,37 +239,34 @@ chat_msg_sent_cb(PurpleAccount *account, const char *message,
int id, PurpleSoundEventID event)
{
PurpleConnection *conn = purple_account_get_connection(account);
- PurpleConversation *conv = NULL;
+ PurpleChatConversation *chat = NULL;
if (conn!=NULL)
- conv = purple_find_chat(conn, id);
+ chat = purple_conversations_find_chat(conn, id);
- play_conv_event(conv, event);
+ play_conv_event(PURPLE_CONVERSATION(chat), event);
}
static void
chat_msg_received_cb(PurpleAccount *account, char *sender,
- char *message, PurpleConversation *conv,
+ char *message, PurpleChatConversation *chat,
PurpleMessageFlags flags, PurpleSoundEventID event)
{
- PurpleConvChat *chat;
-
if (flags & PURPLE_MESSAGE_DELAYED)
return;
- chat = purple_conversation_get_chat_data(conv);
g_return_if_fail(chat != NULL);
- if (purple_conv_chat_is_user_ignored(chat, sender))
+ if (purple_chat_conversation_is_ignored_user(chat, sender))
return;
- if (chat_nick_matches_name(conv, sender))
+ if (chat_nick_matches_name(chat, sender))
return;
- if (flags & PURPLE_MESSAGE_NICK || purple_utf8_has_word(message, purple_conv_chat_get_nick(chat)))
- play_conv_event(conv, PURPLE_SOUND_CHAT_NICK);
+ if (flags & PURPLE_MESSAGE_NICK || purple_utf8_has_word(message, purple_chat_conversation_get_nick(chat)))
+ play_conv_event(PURPLE_CONVERSATION(chat), PURPLE_SOUND_CHAT_NICK);
else
- play_conv_event(conv, event);
+ play_conv_event(PURPLE_CONVERSATION(chat), event);
}
static void
@@ -403,11 +398,11 @@ finch_sound_init(void)
purple_signal_connect(conv_handle, "sent-im-msg",
gnt_sound_handle, PURPLE_CALLBACK(im_msg_sent_cb),
GINT_TO_POINTER(PURPLE_SOUND_SEND));
- purple_signal_connect(conv_handle, "chat-buddy-joined",
- gnt_sound_handle, PURPLE_CALLBACK(chat_buddy_join_cb),
+ purple_signal_connect(conv_handle, "chat-user-joined",
+ gnt_sound_handle, PURPLE_CALLBACK(chat_user_join_cb),
GINT_TO_POINTER(PURPLE_SOUND_CHAT_JOIN));
- purple_signal_connect(conv_handle, "chat-buddy-left",
- gnt_sound_handle, PURPLE_CALLBACK(chat_buddy_left_cb),
+ purple_signal_connect(conv_handle, "chat-user-left",
+ gnt_sound_handle, PURPLE_CALLBACK(chat_user_left_cb),
GINT_TO_POINTER(PURPLE_SOUND_CHAT_LEAVE));
purple_signal_connect(conv_handle, "sent-chat-msg",
gnt_sound_handle, PURPLE_CALLBACK(chat_msg_sent_cb),
diff --git a/finch/libgnt/wms/s.c b/finch/libgnt/wms/s.c
index a326815bab..e7d5343788 100644
--- a/finch/libgnt/wms/s.c
+++ b/finch/libgnt/wms/s.c
@@ -11,7 +11,7 @@
#include "gntwindow.h"
#include "gntlabel.h"
-#include "blist.h"
+#include "buddylist.h"
#define TYPE_S (s_get_gtype())
diff --git a/finch/plugins/gntgf.c b/finch/plugins/gntgf.c
index 925c24834d..cfb47884ca 100644
--- a/finch/plugins/gntgf.c
+++ b/finch/plugins/gntgf.c
@@ -44,7 +44,7 @@
#include <plugin.h>
#include <version.h>
-#include <blist.h>
+#include <buddylist.h>
#include <conversation.h>
#include <debug.h>
#include <eventloop.h>
@@ -241,22 +241,23 @@ buddy_signed_off(PurpleBuddy *buddy, gpointer null)
static void
received_im_msg(PurpleAccount *account, const char *sender, const char *msg,
- PurpleConversation *conv, PurpleMessageFlags flags, gpointer null)
+ PurpleIMConversation *im, PurpleMessageFlags flags, gpointer null)
{
if (purple_prefs_get_bool(PREFS_EVENT_IM_MSG))
- notify(conv, _("%s sent you a message"), sender);
+ notify(PURPLE_CONVERSATION(im), _("%s sent you a message"), sender);
}
static void
received_chat_msg(PurpleAccount *account, const char *sender, const char *msg,
- PurpleConversation *conv, PurpleMessageFlags flags, gpointer null)
+ PurpleChatConversation *chat, PurpleMessageFlags flags, gpointer null)
{
const char *nick;
+ PurpleConversation *conv = PURPLE_CONVERSATION(chat);
if (flags & PURPLE_MESSAGE_WHISPER)
return;
- nick = purple_conv_chat_get_nick(PURPLE_CONV_CHAT(conv));
+ nick = purple_chat_conversation_get_nick(chat);
if (g_utf8_collate(sender, nick) == 0)
return;
diff --git a/finch/plugins/gnthistory.c b/finch/plugins/gnthistory.c
index b5514f0b26..9706bd7197 100644
--- a/finch/plugins/gnthistory.c
+++ b/finch/plugins/gnthistory.c
@@ -43,7 +43,6 @@ static void historize(PurpleConversation *c)
{
PurpleAccount *account = purple_conversation_get_account(c);
const char *name = purple_conversation_get_name(c);
- PurpleConversationType convtype;
GList *logs = NULL;
const char *alias = name;
PurpleLogReadFlags flags;
@@ -51,8 +50,7 @@ static void historize(PurpleConversation *c)
char *header;
PurpleMessageFlags mflag;
- convtype = purple_conversation_get_type(c);
- if (convtype == PURPLE_CONV_TYPE_IM) {
+ if (PURPLE_IS_IM_CONVERSATION(c)) {
GSList *buddies;
GSList *cur;
FinchConv *fc = FINCH_CONV(c);
@@ -65,11 +63,11 @@ static void historize(PurpleConversation *c)
return;
/* Find buddies for this conversation. */
- buddies = purple_find_buddies(account, name);
+ buddies = purple_blist_find_buddies(account, name);
/* If we found at least one buddy, save the first buddy's alias. */
if (buddies != NULL)
- alias = purple_buddy_get_contact_alias((PurpleBuddy *)buddies->data);
+ alias = purple_buddy_get_contact_alias(PURPLE_BUDDY(buddies->data));
for (cur = buddies; cur != NULL; cur = cur->next) {
PurpleBlistNode *node = cur->data;
@@ -78,7 +76,7 @@ static void historize(PurpleConversation *c)
(purple_blist_node_get_sibling_next(node) != NULL))) {
PurpleBlistNode *node2;
- alias = purple_buddy_get_contact_alias((PurpleBuddy *)node);
+ alias = purple_buddy_get_contact_alias(PURPLE_BUDDY(node));
/* We've found a buddy that matches this conversation. It's part of a
* PurpleContact with more than one PurpleBuddy. Loop through the PurpleBuddies
@@ -87,8 +85,8 @@ static void historize(PurpleConversation *c)
node2 != NULL ; node2 = purple_blist_node_get_sibling_next(node2)) {
logs = g_list_concat(
purple_log_get_logs(PURPLE_LOG_IM,
- purple_buddy_get_name((PurpleBuddy *)node2),
- purple_buddy_get_account((PurpleBuddy *)node2)),
+ purple_buddy_get_name(PURPLE_BUDDY(node2)),
+ purple_buddy_get_account(PURPLE_BUDDY(node2))),
logs);
}
break;
@@ -100,7 +98,7 @@ static void historize(PurpleConversation *c)
logs = purple_log_get_logs(PURPLE_LOG_IM, name, account);
else
logs = g_list_sort(logs, purple_log_compare);
- } else if (convtype == PURPLE_CONV_TYPE_CHAT) {
+ } else if (PURPLE_IS_CHAT_CONVERSATION(c)) {
/* If we're not logging, don't show anything.
* Otherwise, we might show a very old log. */
if (!purple_prefs_get_bool("/purple/logging/log_chats"))
diff --git a/finch/plugins/gnttinyurl.c b/finch/plugins/gnttinyurl.c
index 6428279337..2c817bf71a 100644
--- a/finch/plugins/gnttinyurl.c
+++ b/finch/plugins/gnttinyurl.c
@@ -210,7 +210,7 @@ static void url_fetched(PurpleHttpConnection *http_conn,
{
CbInfo *data = (CbInfo *)_data;
PurpleConversation *conv = data->conv;
- GList *convs = purple_get_conversations();
+ GList *convs = purple_conversations_get_all();
const gchar *url;
if (purple_http_response_is_successful(response))
@@ -251,7 +251,7 @@ static gboolean writing_msg(PurpleAccount *account, char *sender, char **message
if ((flags & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_INVISIBLE)))
return FALSE;
- urls = purple_conversation_get_data(conv, "TinyURLs");
+ urls = g_object_get_data(G_OBJECT(conv), "TinyURLs");
if (urls != NULL) /* message was cancelled somewhere? Reset. */
g_list_foreach(urls, free_urls, NULL);
g_list_free(urls);
@@ -287,8 +287,8 @@ static gboolean writing_msg(PurpleAccount *account, char *sender, char **message
*message = t->str;
g_string_free(t, FALSE);
if (conv == NULL)
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender);
- purple_conversation_set_data(conv, "TinyURLs", urls);
+ conv = PURPLE_CONVERSATION(purple_im_conversation_new(account, sender));
+ g_object_set_data(G_OBJECT(conv), "TinyURLs", urls);
return FALSE;
}
@@ -297,12 +297,12 @@ static void wrote_msg(PurpleAccount *account, char *sender, char *message,
{
GList *urls;
- urls = purple_conversation_get_data(conv, "TinyURLs");
+ urls = g_object_get_data(G_OBJECT(conv), "TinyURLs");
if ((flags & PURPLE_MESSAGE_SEND) || urls == NULL)
return;
process_urls(conv, urls);
- purple_conversation_set_data(conv, "TinyURLs", NULL);
+ g_object_set_data(G_OBJECT(conv), "TinyURLs", NULL);
}
/* Frees 'urls' */
@@ -345,7 +345,7 @@ process_urls(PurpleConversation *conv, GList *urls)
static void
free_conv_urls(PurpleConversation *conv)
{
- GList *urls = purple_conversation_get_data(conv, "TinyURLs");
+ GList *urls = g_object_get_data(G_OBJECT(conv), "TinyURLs");
if (urls)
g_list_foreach(urls, free_urls, NULL);
g_list_free(urls);
diff --git a/finch/plugins/grouping.c b/finch/plugins/grouping.c
index 18ebd4cbe0..b54584eea4 100644
--- a/finch/plugins/grouping.c
+++ b/finch/plugins/grouping.c
@@ -28,78 +28,104 @@
#include "gnttree.h"
+#define FINCH_TYPE_GROUPING_NODE (finch_grouping_node_get_type())
+#define FINCH_GROUPING_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), FINCH_TYPE_GROUPING_NODE, FinchGroupingNode))
+#define FINCH_IS_GROUPING_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), FINCH_TYPE_GROUPING_NODE))
+
+typedef struct {
+ PurpleBlistNode node;
+} FinchGroupingNode;
+
+typedef struct {
+ PurpleBlistNodeClass node_class;
+} FinchGroupingNodeClass;
+
static FinchBlistManager *default_manager;
/**
+ * GObject code
+ */
+static GType
+finch_grouping_node_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(FinchGroupingNodeClass),
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ sizeof(FinchGroupingNode),
+ 0,
+ NULL,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_BLIST_NODE,
+ "FinchGroupingNode",
+ &info, 0);
+ }
+
+ return type;
+}
+
+/**
* Online/Offline
*/
-static PurpleBlistNode online = {.type = PURPLE_BLIST_OTHER_NODE},
- offline = {.type = PURPLE_BLIST_OTHER_NODE};
+static FinchGroupingNode *online, *offline;
static gboolean on_offline_init()
{
GntTree *tree = finch_blist_get_tree();
- gnt_tree_add_row_after(tree, &online,
+ gnt_tree_add_row_after(tree, online,
gnt_tree_create_row(tree, _("Online")), NULL, NULL);
- gnt_tree_add_row_after(tree, &offline,
- gnt_tree_create_row(tree, _("Offline")), NULL, &online);
+ gnt_tree_add_row_after(tree, offline,
+ gnt_tree_create_row(tree, _("Offline")), NULL, online);
return TRUE;
}
static gboolean on_offline_can_add_node(PurpleBlistNode *node)
{
- switch (purple_blist_node_get_type(node)) {
- case PURPLE_BLIST_CONTACT_NODE:
- {
- PurpleContact *contact = (PurpleContact*)node;
- if (purple_contact_get_contact_size(contact, FALSE) > 0)
- return TRUE;
- return FALSE;
- }
- break;
- case PURPLE_BLIST_BUDDY_NODE:
- {
- PurpleBuddy *buddy = (PurpleBuddy*)node;
- if (PURPLE_BUDDY_IS_ONLINE(buddy))
- return TRUE;
- if (purple_prefs_get_bool("/finch/blist/showoffline") &&
- purple_account_is_connected(purple_buddy_get_account(buddy)))
- return TRUE;
- return FALSE;
- }
- break;
- case PURPLE_BLIST_CHAT_NODE:
- {
- PurpleChat *chat = (PurpleChat*)node;
- return purple_account_is_connected(purple_chat_get_account(chat));
- }
- break;
- default:
- return FALSE;
+ if (PURPLE_IS_CONTACT(node)) {
+ PurpleContact *contact = PURPLE_CONTACT(node);
+ if (purple_counting_node_get_current_size(PURPLE_COUNTING_NODE(contact)) > 0)
+ return TRUE;
+ return FALSE;
+ } else if (PURPLE_IS_BUDDY(node)) {
+ PurpleBuddy *buddy = PURPLE_BUDDY(node);
+ if (PURPLE_BUDDY_IS_ONLINE(buddy))
+ return TRUE;
+ if (purple_prefs_get_bool("/finch/blist/showoffline") &&
+ purple_account_is_connected(purple_buddy_get_account(buddy)))
+ return TRUE;
+ return FALSE;
+ } else if (PURPLE_IS_CHAT(node)) {
+ PurpleChat *chat = PURPLE_CHAT(node);
+ return purple_account_is_connected(purple_chat_get_account(chat));
}
+
+ return FALSE;
}
static gpointer on_offline_find_parent(PurpleBlistNode *node)
{
gpointer ret = NULL;
- switch (purple_blist_node_get_type(node)) {
- case PURPLE_BLIST_CONTACT_NODE:
- node = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node)));
- ret = PURPLE_BUDDY_IS_ONLINE((PurpleBuddy*)node) ? &online : &offline;
- break;
- case PURPLE_BLIST_BUDDY_NODE:
- ret = purple_blist_node_get_parent(node);
- finch_blist_manager_add_node(ret);
- break;
- case PURPLE_BLIST_CHAT_NODE:
- ret = &online;
- break;
- default:
- break;
+ if (PURPLE_IS_CONTACT(node)) {
+ node = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node)));
+ ret = PURPLE_BUDDY_IS_ONLINE(PURPLE_BUDDY(node)) ? online : offline;
+ } else if (PURPLE_IS_BUDDY(node)) {
+ ret = purple_blist_node_get_parent(node);
+ finch_blist_manager_add_node(ret);
+ } else if (PURPLE_IS_CHAT(node)) {
+ ret = online;
}
+
return ret;
}
@@ -107,12 +133,13 @@ static gboolean on_offline_create_tooltip(gpointer selected_row, GString **body,
{
PurpleBlistNode *node = selected_row;
- if (purple_blist_node_get_type(node) == PURPLE_BLIST_OTHER_NODE) {
+ if (FINCH_IS_GROUPING_NODE(node)) {
/* There should be some easy way of getting the total online count,
* or total number of chats. Doing a loop here will probably be pretty
* expensive. */
if (body)
- *body = g_string_new(node == &online ? _("Online Buddies") : _("Offline Buddies"));
+ *body = g_string_new(FINCH_GROUPING_NODE(node) == online ?
+ _("Online Buddies") : _("Offline Buddies"));
return TRUE;
} else {
return default_manager ? default_manager->create_tooltip(selected_row, body, tool_title) : FALSE;
@@ -134,7 +161,7 @@ static FinchBlistManager on_offline =
/**
* Meebo-like Grouping.
*/
-static PurpleBlistNode meebo = {.type = PURPLE_BLIST_OTHER_NODE};
+static FinchGroupingNode meebo;
static gboolean meebo_init()
{
GntTree *tree = finch_blist_get_tree();
@@ -147,8 +174,8 @@ static gboolean meebo_init()
static gpointer meebo_find_parent(PurpleBlistNode *node)
{
- if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
- PurpleBuddy *buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
+ if (PURPLE_IS_CONTACT(node)) {
+ PurpleBuddy *buddy = purple_contact_get_priority_buddy(PURPLE_CONTACT(node));
if (buddy && !PURPLE_BUDDY_IS_ONLINE(buddy)) {
return &meebo;
}
@@ -194,14 +221,11 @@ static gpointer no_group_find_parent(PurpleBlistNode *node)
{
gpointer ret = NULL;
- switch (purple_blist_node_get_type(node)) {
- case PURPLE_BLIST_BUDDY_NODE:
- ret = purple_blist_node_get_parent(node);
- finch_blist_manager_add_node(ret);
- break;
- default:
- break;
+ if (PURPLE_IS_BUDDY(node)) {
+ ret = purple_blist_node_get_parent(node);
+ finch_blist_manager_add_node(ret);
}
+
return ret;
}
@@ -247,10 +271,10 @@ nested_group_find_parent(PurpleBlistNode *node)
PurpleBlistNode *ret, *parent;
GntTree *tree;
- if (!PURPLE_BLIST_NODE_IS_GROUP(node))
+ if (!PURPLE_IS_GROUP(node))
return default_manager->find_parent(node);
- group = (PurpleGroup *)node;
+ group = PURPLE_GROUP(node);
name = g_strdup(purple_group_get_name(group));
if (!(sep = strchr(name, '/'))) {
g_free(name);
@@ -262,13 +286,12 @@ nested_group_find_parent(PurpleBlistNode *node)
while (sep) {
*sep = 0;
- if (*(sep + 1) && (ret = (PurpleBlistNode *)purple_find_group(name))) {
+ if (*(sep + 1) && (ret = PURPLE_BLIST_NODE(purple_blist_find_group(name)))) {
finch_blist_manager_add_node(ret);
parent = ret;
} else if (!(ret = g_hash_table_lookup(groups, name))) {
- ret = g_new0(PurpleBlistNode, 1);
+ ret = g_object_new(FINCH_TYPE_GROUPING_NODE, NULL);
g_hash_table_insert(groups, g_strdup(name), ret);
- ret->type = PURPLE_BLIST_OTHER_NODE;
gnt_tree_add_row_last(tree, ret,
gnt_tree_create_row(tree, name), parent);
parent = ret;
@@ -285,8 +308,7 @@ static gboolean
nested_group_create_tooltip(gpointer selected_row, GString **body, char **title)
{
PurpleBlistNode *node = selected_row;
- if (!node ||
- purple_blist_node_get_type(node) != PURPLE_BLIST_OTHER_NODE)
+ if (!node || !FINCH_IS_GROUPING_NODE(node))
return default_manager->create_tooltip(selected_row, body, title);
if (body)
*body = g_string_new(_("Nested Subgroup")); /* Perhaps list the child groups/subgroups? */
@@ -299,19 +321,19 @@ nested_group_can_add_node(PurpleBlistNode *node)
PurpleBlistNode *group;
int len;
- if (!PURPLE_BLIST_NODE_IS_GROUP(node))
+ if (!PURPLE_IS_GROUP(node))
return default_manager->can_add_node(node);
if (default_manager->can_add_node(node))
return TRUE;
- len = strlen(purple_group_get_name((PurpleGroup*)node));
+ len = strlen(purple_group_get_name(PURPLE_GROUP(node)));
group = purple_blist_get_root();
for (; group; group = purple_blist_node_get_sibling_next(group)) {
if (group == node)
continue;
- if (strncmp(purple_group_get_name((PurpleGroup *)node),
- purple_group_get_name((PurpleGroup *)group), len) == 0 &&
+ if (strncmp(purple_group_get_name(PURPLE_GROUP(node)),
+ purple_group_get_name(PURPLE_GROUP(group)), len) == 0 &&
default_manager->can_add_node(group))
return TRUE;
}
@@ -381,6 +403,8 @@ static PurplePluginInfo info =
static void
init_plugin(PurplePlugin *plugin)
{
+ online = g_object_new(FINCH_TYPE_GROUPING_NODE, NULL);
+ offline = g_object_new(FINCH_TYPE_GROUPING_NODE, NULL);
}
PURPLE_INIT_PLUGIN(grouping, init_plugin, info)
diff --git a/libpurple/Makefile.am b/libpurple/Makefile.am
index 433aa088cd..37842f6ec5 100644
--- a/libpurple/Makefile.am
+++ b/libpurple/Makefile.am
@@ -38,20 +38,26 @@ SUBDIRS = $(GCONF_DIR) plugins protocols ciphers . tests example
purple_coresources = \
account.c \
+ accounts.c \
accountopt.c \
- blist.c \
+ blistnode.c \
+ blistnodetypes.c \
+ buddylist.c \
buddyicon.c \
certificate.c \
cipher.c \
- circbuffer.c \
+ circularbuffer.c \
cmds.c \
connection.c \
conversation.c \
+ conversationtypes.c \
+ conversations.c \
core.c \
debug.c \
desktopitem.c \
eventloop.c \
ft.c \
+ hash.c \
http.c \
idle.c \
imgstore.c \
@@ -73,7 +79,7 @@ purple_coresources = \
pluginpref.c \
pounce.c \
prefs.c \
- privacy.c \
+ presence.c \
proxy.c \
prpl.c \
request.c \
@@ -96,31 +102,37 @@ purple_coresources = \
theme-manager.c \
upnp.c \
util.c \
- value.c \
version.c \
xmlnode.c \
whiteboard.c
purple_builtsources = \
+ enums.c \
marshallers.c
purple_coreheaders = \
account.h \
+ accounts.h \
accountopt.h \
- blist.h \
+ blistnode.h \
+ blistnodetypes.h \
+ buddylist.h \
buddyicon.h \
certificate.h \
cipher.h \
- circbuffer.h \
+ circularbuffer.h \
cmds.h \
connection.h \
conversation.h \
+ conversationtypes.h \
+ conversations.h \
core.h \
dbus-maybe.h \
debug.h \
desktopitem.h \
eventloop.h \
ft.h \
+ hash.h \
http.h \
idle.h \
imgstore.h \
@@ -138,7 +150,7 @@ purple_coreheaders = \
pluginpref.h \
pounce.h \
prefs.h \
- privacy.h \
+ presence.h \
proxy.h \
prpl.h \
request.h \
@@ -161,7 +173,6 @@ purple_coreheaders = \
theme-manager.h \
upnp.h \
util.h \
- value.h \
xmlnode.h \
whiteboard.h
@@ -171,7 +182,15 @@ purple_mediaheaders = \
codec.h \
enum-types.h
-purple_builtheaders = purple.h version.h marshallers.h
+purple_builtheaders = purple.h version.h enums.h marshallers.h
+
+purple_enumheaders = \
+ account.h \
+ cipher.h \
+ connection.h \
+ conversation.h \
+ conversationtypes.h \
+ status.h
marshallers.h: marshallers.list
$(AM_V_GEN)$(GLIB_GENMARSHAL) --prefix=purple_smarshal $(srcdir)/marshallers.list --header > marshallers.h
@@ -180,6 +199,12 @@ marshallers.c: marshallers.list marshallers.h
$(AM_V_GEN)echo "#include \"marshallers.h\"" > marshallers.c
$(AM_V_at)$(GLIB_GENMARSHAL) --prefix=purple_smarshal $(srcdir)/marshallers.list --body >> marshallers.c
+enums.h: enums.h.template $(purple_enumheaders)
+ $(AM_V_GEN)$(GLIB_MKENUMS) --template enums.h.template $(purple_enumheaders) > $@
+
+enums.c: enums.c.template $(purple_enumheaders)
+ $(AM_V_GEN)$(GLIB_MKENUMS) --template enums.c.template $(purple_enumheaders) > $@
+
if ENABLE_DBUS
CLEANFILES = \
@@ -189,6 +214,8 @@ CLEANFILES = \
dbus-signals.c \
dbus-types.c \
dbus-types.h \
+ enums.c \
+ enums.h \
marshallers.c \
marshallers.h \
purple-client-bindings.c \
@@ -200,9 +227,11 @@ CLEANFILES = \
dbus_sources = dbus-server.c dbus-useful.c
dbus_headers = dbus-bindings.h dbus-purple.h dbus-server.h dbus-useful.h dbus-define-api.h dbus-types.h
-dbus_exported = dbus-useful.h dbus-define-api.h account.h blist.h buddyicon.h \
- connection.h conversation.h core.h ft.h log.h notify.h prefs.h roomlist.h \
- savedstatuses.h smiley.h status.h server.h util.h xmlnode.h prpl.h
+dbus_exported = dbus-useful.h dbus-define-api.h account.h accounts.h blistnode.h \
+ blistnodetypes.h buddylist.h buddyicon.h connection.h conversation.h \
+ conversationtypes.h conversations.h core.h ft.h log.h notify.h \
+ prefs.h presence.h roomlist.h savedstatuses.h smiley.h status.h \
+ server.h util.h xmlnode.h prpl.h
purple_build_coreheaders = $(addprefix $(srcdir)/, $(purple_coreheaders)) \
$(addprefix $(srcdir)/media/, $(purple_mediaheaders)) \
@@ -302,7 +331,10 @@ mediaincludedir=$(includedir)/libpurple/media
mediainclude_HEADERS = \
$(addprefix $(srcdir)/media/, $(purple_mediaheaders))
-libpurple_la_DEPENDENCIES = $(STATIC_LINK_LIBS)
+libpurple_la_DEPENDENCIES = \
+ $(STATIC_LINK_LIBS) \
+ ciphers/libpurple-ciphers.la
+
libpurple_la_LDFLAGS = -export-dynamic -version-info $(PURPLE_LT_VERSION_INFO) -no-undefined
libpurple_la_LIBADD = \
$(STATIC_LINK_LIBS) \
diff --git a/libpurple/Makefile.mingw b/libpurple/Makefile.mingw
index 88164b8f31..d1eb3bbfc6 100644
--- a/libpurple/Makefile.mingw
+++ b/libpurple/Makefile.mingw
@@ -61,22 +61,27 @@ endif
C_SRC = \
account.c \
+ accounts.c \
accountopt.c \
blist.c \
buddyicon.c \
certificate.c \
cipher.c \
- ciphers/aes.c \
- ciphers/des.c \
- ciphers/gchecksum.c \
- ciphers/hmac.c \
- ciphers/md4.c \
- ciphers/pbkdf2.c \
- ciphers/rc4.c \
- circbuffer.c \
+ ciphers/aescipher.c \
+ ciphers/des3cipher.c \
+ ciphers/descipher.c \
+ ciphers/hmaccipher.c \
+ ciphers/md4hash.c \
+ ciphers/md5hash.c \
+ ciphers/pbkdf2cipher.c \
+ ciphers/rc4cipher.c \
+ ciphers/sha1hash.c \
+ ciphers/sha256hash.c \
+ circularbuffer.c \
cmds.c \
connection.c \
conversation.c \
+ conversations.c \
core.c \
debug.c \
dnsquery.c \
@@ -122,7 +127,6 @@ C_SRC = \
theme.c \
upnp.c \
util.c \
- value.c \
version.c \
whiteboard.c \
xmlnode.c \
diff --git a/libpurple/account.c b/libpurple/account.c
index 526cd7bb34..2e2d537c20 100644
--- a/libpurple/account.c
+++ b/libpurple/account.c
@@ -24,38 +24,77 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include "internal.h"
-#include "account.h"
+#include "accounts.h"
#include "core.h"
#include "dbus-maybe.h"
#include "debug.h"
-#include "keyring.h"
#include "network.h"
#include "notify.h"
#include "pounce.h"
#include "prefs.h"
-#include "privacy.h"
-#include "prpl.h"
#include "request.h"
#include "server.h"
#include "signals.h"
-#include "status.h"
#include "util.h"
-#include "xmlnode.h"
-/* TODO: Should use PurpleValue instead of this? What about "ui"? */
+#define PURPLE_ACCOUNT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_ACCOUNT, PurpleAccountPrivate))
+
typedef struct
{
- PurplePrefType type;
+ char *username; /**< The username. */
+ char *alias; /**< How you appear to yourself. */
+ char *password; /**< The account password. */
+ char *user_info; /**< User information. */
- char *ui;
+ char *buddy_icon_path; /**< The buddy icon's non-cached path. */
- union
- {
- int integer;
- char *string;
- gboolean boolean;
+ gboolean remember_pass; /**< Remember the password. */
+
+ /*
+ * TODO: After a GObject representing a protocol is ready, use it
+ * here instead of the protocol ID.
+ */
+ char *protocol_id; /**< The ID of the protocol. */
+
+ PurpleConnection *gc; /**< The connection handle. */
+ gboolean disconnecting; /**< The account is currently disconnecting */
+
+ GHashTable *settings; /**< Protocol-specific settings. */
+ GHashTable *ui_settings; /**< UI-specific settings. */
+
+ PurpleProxyInfo *proxy_info; /**< Proxy information. This will be set */
+ /* to NULL when the account inherits */
+ /* proxy settings from global prefs. */
+
+ /*
+ * TODO: Supplementing the next two linked lists with hash tables
+ * should help performance a lot when these lists are long. This
+ * matters quite a bit for protocols like MSN, where all your
+ * buddies are added to your permit list. Currently we have to
+ * iterate through the entire list if we want to check if someone
+ * is permitted or denied. We should do this for 3.0.0.
+ * Or maybe use a GTree.
+ */
+ GSList *permit; /**< Permit list. */
+ GSList *deny; /**< Deny list. */
+ PurpleAccountPrivacyType privacy_type; /**< The permit/deny setting. */
+
+ GList *status_types; /**< Status types. */
+
+ PurplePresence *presence; /**< Presence. */
+ PurpleLog *system_log; /**< The system log */
+
+ PurpleAccountRegistrationCb registration_cb;
+ void *registration_cb_user_data;
- } value;
+ PurpleConnectionErrorInfo *current_error; /**< Errors */
+} PurpleAccountPrivate;
+
+typedef struct
+{
+ char *ui;
+ GValue value;
} PurpleAccountSetting;
@@ -77,1073 +116,42 @@ typedef struct
gpointer data;
} PurpleCallbackBundle;
-static PurpleAccountUiOps *account_ui_ops = NULL;
-
-static GList *accounts = NULL;
-static guint save_timer = 0;
-static gboolean accounts_loaded = FALSE;
-
-static GList *handles = NULL;
-
-static void set_current_error(PurpleAccount *account,
- PurpleConnectionErrorInfo *new_err);
-
-/*********************************************************************
- * Writing to disk *
- *********************************************************************/
-
-static void
-setting_to_xmlnode(gpointer key, gpointer value, gpointer user_data)
-{
- const char *name;
- PurpleAccountSetting *setting;
- xmlnode *node, *child;
- char buf[21];
-
- name = (const char *)key;
- setting = (PurpleAccountSetting *)value;
- node = (xmlnode *)user_data;
-
- child = xmlnode_new_child(node, "setting");
- xmlnode_set_attrib(child, "name", name);
-
- if (setting->type == PURPLE_PREF_INT) {
- xmlnode_set_attrib(child, "type", "int");
- g_snprintf(buf, sizeof(buf), "%d", setting->value.integer);
- xmlnode_insert_data(child, buf, -1);
- }
- else if (setting->type == PURPLE_PREF_STRING && setting->value.string != NULL) {
- xmlnode_set_attrib(child, "type", "string");
- xmlnode_insert_data(child, setting->value.string, -1);
- }
- else if (setting->type == PURPLE_PREF_BOOLEAN) {
- xmlnode_set_attrib(child, "type", "bool");
- g_snprintf(buf, sizeof(buf), "%d", setting->value.boolean);
- xmlnode_insert_data(child, buf, -1);
- }
-}
-
-static void
-ui_setting_to_xmlnode(gpointer key, gpointer value, gpointer user_data)
-{
- const char *ui;
- GHashTable *table;
- xmlnode *node, *child;
-
- ui = (const char *)key;
- table = (GHashTable *)value;
- node = (xmlnode *)user_data;
-
- if (g_hash_table_size(table) > 0)
- {
- child = xmlnode_new_child(node, "settings");
- xmlnode_set_attrib(child, "ui", ui);
- g_hash_table_foreach(table, setting_to_xmlnode, child);
- }
-}
-
-static xmlnode *
-status_attr_to_xmlnode(const PurpleStatus *status, const PurpleStatusType *type, const PurpleStatusAttr *attr)
-{
- xmlnode *node;
- const char *id;
- char *value = NULL;
- PurpleStatusAttr *default_attr;
- PurpleValue *default_value;
- PurpleType attr_type;
- PurpleValue *attr_value;
-
- id = purple_status_attr_get_id(attr);
- g_return_val_if_fail(id, NULL);
-
- attr_value = purple_status_get_attr_value(status, id);
- g_return_val_if_fail(attr_value, NULL);
- attr_type = purple_value_get_type(attr_value);
-
- /*
- * If attr_value is a different type than it should be
- * then don't write it to the file.
- */
- default_attr = purple_status_type_get_attr(type, id);
- default_value = purple_status_attr_get_value(default_attr);
- if (attr_type != purple_value_get_type(default_value))
- return NULL;
-
- /*
- * If attr_value is the same as the default for this status
- * then there is no need to write it to the file.
- */
- if (attr_type == PURPLE_TYPE_STRING)
- {
- const char *string_value = purple_value_get_string(attr_value);
- const char *default_string_value = purple_value_get_string(default_value);
- if (purple_strequal(string_value, default_string_value))
- return NULL;
- value = g_strdup(purple_value_get_string(attr_value));
- }
- else if (attr_type == PURPLE_TYPE_INT)
- {
- int int_value = purple_value_get_int(attr_value);
- if (int_value == purple_value_get_int(default_value))
- return NULL;
- value = g_strdup_printf("%d", int_value);
- }
- else if (attr_type == PURPLE_TYPE_BOOLEAN)
- {
- gboolean boolean_value = purple_value_get_boolean(attr_value);
- if (boolean_value == purple_value_get_boolean(default_value))
- return NULL;
- value = g_strdup(boolean_value ?
- "true" : "false");
- }
- else
- {
- return NULL;
- }
-
- g_return_val_if_fail(value, NULL);
-
- node = xmlnode_new("attribute");
-
- xmlnode_set_attrib(node, "id", id);
- xmlnode_set_attrib(node, "value", value);
-
- g_free(value);
-
- return node;
-}
-
-static xmlnode *
-status_attrs_to_xmlnode(const PurpleStatus *status)
-{
- PurpleStatusType *type = purple_status_get_type(status);
- xmlnode *node, *child;
- GList *attrs, *attr;
-
- node = xmlnode_new("attributes");
-
- attrs = purple_status_type_get_attrs(type);
- for (attr = attrs; attr != NULL; attr = attr->next)
- {
- child = status_attr_to_xmlnode(status, type, (const PurpleStatusAttr *)attr->data);
- if (child)
- xmlnode_insert_child(node, child);
- }
-
- return node;
-}
-
-static xmlnode *
-status_to_xmlnode(const PurpleStatus *status)
-{
- xmlnode *node, *child;
-
- node = xmlnode_new("status");
- xmlnode_set_attrib(node, "type", purple_status_get_id(status));
- if (purple_status_get_name(status) != NULL)
- xmlnode_set_attrib(node, "name", purple_status_get_name(status));
- xmlnode_set_attrib(node, "active", purple_status_is_active(status) ? "true" : "false");
-
- child = status_attrs_to_xmlnode(status);
- xmlnode_insert_child(node, child);
-
- return node;
-}
-
-static xmlnode *
-statuses_to_xmlnode(const PurplePresence *presence)
-{
- xmlnode *node, *child;
- GList *statuses;
- PurpleStatus *status;
-
- node = xmlnode_new("statuses");
-
- statuses = purple_presence_get_statuses(presence);
- for (; statuses != NULL; statuses = statuses->next)
- {
- status = statuses->data;
- if (purple_status_type_is_saveable(purple_status_get_type(status)))
- {
- child = status_to_xmlnode(status);
- xmlnode_insert_child(node, child);
- }
- }
-
- return node;
-}
-
-static xmlnode *
-proxy_settings_to_xmlnode(PurpleProxyInfo *proxy_info)
-{
- xmlnode *node, *child;
- PurpleProxyType proxy_type;
- const char *value;
- int int_value;
- char buf[21];
-
- proxy_type = purple_proxy_info_get_type(proxy_info);
-
- node = xmlnode_new("proxy");
-
- child = xmlnode_new_child(node, "type");
- xmlnode_insert_data(child,
- (proxy_type == PURPLE_PROXY_USE_GLOBAL ? "global" :
- proxy_type == PURPLE_PROXY_NONE ? "none" :
- proxy_type == PURPLE_PROXY_HTTP ? "http" :
- proxy_type == PURPLE_PROXY_SOCKS4 ? "socks4" :
- proxy_type == PURPLE_PROXY_SOCKS5 ? "socks5" :
- proxy_type == PURPLE_PROXY_TOR ? "tor" :
- proxy_type == PURPLE_PROXY_USE_ENVVAR ? "envvar" : "unknown"), -1);
-
- if ((value = purple_proxy_info_get_host(proxy_info)) != NULL)
- {
- child = xmlnode_new_child(node, "host");
- xmlnode_insert_data(child, value, -1);
- }
-
- if ((int_value = purple_proxy_info_get_port(proxy_info)) != 0)
- {
- g_snprintf(buf, sizeof(buf), "%d", int_value);
- child = xmlnode_new_child(node, "port");
- xmlnode_insert_data(child, buf, -1);
- }
-
- if ((value = purple_proxy_info_get_username(proxy_info)) != NULL)
- {
- child = xmlnode_new_child(node, "username");
- xmlnode_insert_data(child, value, -1);
- }
-
- if ((value = purple_proxy_info_get_password(proxy_info)) != NULL)
- {
- child = xmlnode_new_child(node, "password");
- xmlnode_insert_data(child, value, -1);
- }
-
- return node;
-}
-
-static xmlnode *
-current_error_to_xmlnode(PurpleConnectionErrorInfo *err)
-{
- xmlnode *node, *child;
- char type_str[3];
-
- node = xmlnode_new("current_error");
-
- if(err == NULL)
- return node;
-
- /* It doesn't make sense to have transient errors persist across a
- * restart.
- */
- if(!purple_connection_error_is_fatal (err->type))
- return node;
-
- child = xmlnode_new_child(node, "type");
- g_snprintf(type_str, sizeof(type_str), "%u", err->type);
- xmlnode_insert_data(child, type_str, -1);
-
- child = xmlnode_new_child(node, "description");
- if(err->description) {
- char *utf8ized = purple_utf8_try_convert(err->description);
- if(utf8ized == NULL)
- utf8ized = purple_utf8_salvage(err->description);
- xmlnode_insert_data(child, utf8ized, -1);
- g_free(utf8ized);
- }
-
- return node;
-}
-
-static xmlnode *
-account_to_xmlnode(PurpleAccount *account)
-{
- xmlnode *node, *child;
- const char *tmp;
- PurplePresence *presence;
- PurpleProxyInfo *proxy_info;
-
- node = xmlnode_new("account");
-
- child = xmlnode_new_child(node, "protocol");
- xmlnode_insert_data(child, purple_account_get_protocol_id(account), -1);
-
- child = xmlnode_new_child(node, "name");
- xmlnode_insert_data(child, purple_account_get_username(account), -1);
-
- if (purple_account_get_remember_password(account))
- {
- const char *keyring_id = NULL;
- const char *mode = NULL;
- char *data = NULL;
- GError *error = NULL;
- GDestroyNotify destroy = NULL;
- gboolean exported = purple_keyring_export_password(account,
- &keyring_id, &mode, &data, &error, &destroy);
-
- if (error != NULL) {
- purple_debug_error("account",
- "Failed to export password for account %s: %s.\n",
- purple_account_get_username(account),
- error->message);
- } else if (exported) {
- child = xmlnode_new_child(node, "password");
- if (keyring_id != NULL)
- xmlnode_set_attrib(child, "keyring_id", keyring_id);
- if (mode != NULL)
- xmlnode_set_attrib(child, "mode", mode);
- if (data != NULL)
- xmlnode_insert_data(child, data, -1);
-
- if (destroy != NULL)
- destroy(data);
- }
- }
-
- if ((tmp = purple_account_get_alias(account)) != NULL)
- {
- child = xmlnode_new_child(node, "alias");
- xmlnode_insert_data(child, tmp, -1);
- }
-
- if ((presence = purple_account_get_presence(account)) != NULL)
- {
- child = statuses_to_xmlnode(presence);
- xmlnode_insert_child(node, child);
- }
-
- if ((tmp = purple_account_get_user_info(account)) != NULL)
- {
- /* TODO: Do we need to call purple_str_strip_char(tmp, '\r') here? */
- child = xmlnode_new_child(node, "userinfo");
- xmlnode_insert_data(child, tmp, -1);
- }
-
- if (g_hash_table_size(account->settings) > 0)
- {
- child = xmlnode_new_child(node, "settings");
- g_hash_table_foreach(account->settings, setting_to_xmlnode, child);
- }
-
- if (g_hash_table_size(account->ui_settings) > 0)
- {
- g_hash_table_foreach(account->ui_settings, ui_setting_to_xmlnode, node);
- }
-
- if ((proxy_info = purple_account_get_proxy_info(account)) != NULL)
- {
- child = proxy_settings_to_xmlnode(proxy_info);
- xmlnode_insert_child(node, child);
- }
-
- child = current_error_to_xmlnode(account->current_error);
- xmlnode_insert_child(node, child);
-
- return node;
-}
-
-static xmlnode *
-accounts_to_xmlnode(void)
-{
- xmlnode *node, *child;
- GList *cur;
-
- node = xmlnode_new("account");
- xmlnode_set_attrib(node, "version", "1.0");
-
- for (cur = purple_accounts_get_all(); cur != NULL; cur = cur->next)
- {
- child = account_to_xmlnode(cur->data);
- xmlnode_insert_child(node, child);
- }
-
- return node;
-}
-
-static void
-sync_accounts(void)
-{
- xmlnode *node;
- char *data;
-
- if (!accounts_loaded)
- {
- purple_debug_error("account", "Attempted to save accounts before "
- "they were read!\n");
- return;
- }
-
- node = accounts_to_xmlnode();
- data = xmlnode_to_formatted_str(node, NULL);
- purple_util_write_data_to_file("accounts.xml", data, -1);
- g_free(data);
- xmlnode_free(node);
-}
-
-static gboolean
-save_cb(gpointer data)
-{
- sync_accounts();
- save_timer = 0;
- return FALSE;
-}
-
-static void
-schedule_accounts_save(void)
-{
- if (save_timer == 0)
- save_timer = purple_timeout_add_seconds(5, save_cb, NULL);
-}
-
-
-/*********************************************************************
- * Reading from disk *
- *********************************************************************/
-static void
-migrate_yahoo_japan(PurpleAccount *account)
-{
- /* detect a Yahoo! JAPAN account that existed prior to 2.6.0 and convert it
- * to use the new prpl-yahoojp. Also remove the account-specific settings
- * we no longer need */
-
- if(purple_strequal(purple_account_get_protocol_id(account), "prpl-yahoo")) {
- if(purple_account_get_bool(account, "yahoojp", FALSE)) {
- const char *serverjp = purple_account_get_string(account, "serverjp", NULL);
- const char *xferjp_host = purple_account_get_string(account, "xferjp_host", NULL);
-
- g_return_if_fail(serverjp != NULL);
- g_return_if_fail(xferjp_host != NULL);
-
- purple_account_set_string(account, "server", serverjp);
- purple_account_set_string(account, "xfer_host", xferjp_host);
-
- purple_account_set_protocol_id(account, "prpl-yahoojp");
- }
-
- /* these should always be nuked */
- purple_account_remove_setting(account, "yahoojp");
- purple_account_remove_setting(account, "serverjp");
- purple_account_remove_setting(account, "xferjp_host");
-
- }
-}
-
-static void
-migrate_icq_server(PurpleAccount *account)
-{
- /* Migrate the login server setting for ICQ accounts. See
- * 'mtn log --last 1 --no-graph --from b6d7712e90b68610df3bd2d8cbaf46d94c8b3794'
- * for details on the change. */
-
- if(purple_strequal(purple_account_get_protocol_id(account), "prpl-icq")) {
- const char *tmp = purple_account_get_string(account, "server", NULL);
-
- /* Non-secure server */
- if(purple_strequal(tmp, "login.messaging.aol.com") ||
- purple_strequal(tmp, "login.oscar.aol.com"))
- purple_account_set_string(account, "server", "login.icq.com");
-
- /* Secure server */
- if(purple_strequal(tmp, "slogin.oscar.aol.com"))
- purple_account_set_string(account, "server", "slogin.icq.com");
- }
-}
-
-static void
-migrate_xmpp_encryption(PurpleAccount *account)
-{
- /* When this is removed, nuke the "old_ssl" and "require_tls" settings */
- if (g_str_equal(purple_account_get_protocol_id(account), "prpl-jabber")) {
- const char *sec = purple_account_get_string(account, "connection_security", "");
-
- if (g_str_equal("", sec)) {
- const char *val = "require_tls";
- if (purple_account_get_bool(account, "old_ssl", FALSE))
- val = "old_ssl";
- else if (!purple_account_get_bool(account, "require_tls", TRUE))
- val = "opportunistic_tls";
-
- purple_account_set_string(account, "connection_security", val);
- }
- }
-}
-
-static void
-parse_settings(xmlnode *node, PurpleAccount *account)
-{
- const char *ui;
- xmlnode *child;
-
- /* Get the UI string, if these are UI settings */
- ui = xmlnode_get_attrib(node, "ui");
-
- /* Read settings, one by one */
- for (child = xmlnode_get_child(node, "setting"); child != NULL;
- child = xmlnode_get_next_twin(child))
- {
- const char *name, *str_type;
- PurplePrefType type;
- char *data;
-
- name = xmlnode_get_attrib(child, "name");
- if (name == NULL)
- /* Ignore this setting */
- continue;
-
- str_type = xmlnode_get_attrib(child, "type");
- if (str_type == NULL)
- /* Ignore this setting */
- continue;
-
- if (purple_strequal(str_type, "string"))
- type = PURPLE_PREF_STRING;
- else if (purple_strequal(str_type, "int"))
- type = PURPLE_PREF_INT;
- else if (purple_strequal(str_type, "bool"))
- type = PURPLE_PREF_BOOLEAN;
- else
- /* Ignore this setting */
- continue;
-
- data = xmlnode_get_data(child);
- if (data == NULL)
- /* Ignore this setting */
- continue;
-
- if (ui == NULL)
- {
- if (type == PURPLE_PREF_STRING)
- purple_account_set_string(account, name, data);
- else if (type == PURPLE_PREF_INT)
- purple_account_set_int(account, name, atoi(data));
- else if (type == PURPLE_PREF_BOOLEAN)
- purple_account_set_bool(account, name,
- (*data == '0' ? FALSE : TRUE));
- } else {
- if (type == PURPLE_PREF_STRING)
- purple_account_set_ui_string(account, ui, name, data);
- else if (type == PURPLE_PREF_INT)
- purple_account_set_ui_int(account, ui, name, atoi(data));
- else if (type == PURPLE_PREF_BOOLEAN)
- purple_account_set_ui_bool(account, ui, name,
- (*data == '0' ? FALSE : TRUE));
- }
-
- g_free(data);
- }
-
- /* we do this here because we need access to account settings to determine
- * if we can/should migrate an old Yahoo! JAPAN account */
- migrate_yahoo_japan(account);
- /* we do this here because we need access to account settings to determine
- * if we can/should migrate an ICQ account's server setting */
- migrate_icq_server(account);
- /* we do this here because we need to do it before the user views the
- * Edit Account dialog. */
- migrate_xmpp_encryption(account);
-}
-
-static GList *
-parse_status_attrs(xmlnode *node, PurpleStatus *status)
-{
- GList *list = NULL;
- xmlnode *child;
- PurpleValue *attr_value;
-
- for (child = xmlnode_get_child(node, "attribute"); child != NULL;
- child = xmlnode_get_next_twin(child))
- {
- const char *id = xmlnode_get_attrib(child, "id");
- const char *value = xmlnode_get_attrib(child, "value");
-
- if (!id || !*id || !value || !*value)
- continue;
-
- attr_value = purple_status_get_attr_value(status, id);
- if (!attr_value)
- continue;
-
- list = g_list_append(list, (char *)id);
-
- switch (purple_value_get_type(attr_value))
- {
- case PURPLE_TYPE_STRING:
- list = g_list_append(list, (char *)value);
- break;
- case PURPLE_TYPE_INT:
- case PURPLE_TYPE_BOOLEAN:
- {
- int v;
- if (sscanf(value, "%d", &v) == 1)
- list = g_list_append(list, GINT_TO_POINTER(v));
- else
- list = g_list_remove(list, id);
- break;
- }
- default:
- break;
- }
- }
-
- return list;
-}
-
-static void
-parse_status(xmlnode *node, PurpleAccount *account)
-{
- gboolean active = FALSE;
- const char *data;
- const char *type;
- xmlnode *child;
- GList *attrs = NULL;
-
- /* Get the active/inactive state */
- data = xmlnode_get_attrib(node, "active");
- if (data == NULL)
- return;
- if (g_ascii_strcasecmp(data, "true") == 0)
- active = TRUE;
- else if (g_ascii_strcasecmp(data, "false") == 0)
- active = FALSE;
- else
- return;
-
- /* Get the type of the status */
- type = xmlnode_get_attrib(node, "type");
- if (type == NULL)
- return;
-
- /* Read attributes into a GList */
- child = xmlnode_get_child(node, "attributes");
- if (child != NULL)
- {
- attrs = parse_status_attrs(child,
- purple_account_get_status(account, type));
- }
-
- purple_account_set_status_list(account, type, active, attrs);
-
- g_list_free(attrs);
-}
-
-static void
-parse_statuses(xmlnode *node, PurpleAccount *account)
-{
- xmlnode *child;
-
- for (child = xmlnode_get_child(node, "status"); child != NULL;
- child = xmlnode_get_next_twin(child))
- {
- parse_status(child, account);
- }
-}
-
-static void
-parse_proxy_info(xmlnode *node, PurpleAccount *account)
-{
- PurpleProxyInfo *proxy_info;
- xmlnode *child;
- char *data;
-
- proxy_info = purple_proxy_info_new();
-
- /* Use the global proxy settings, by default */
- purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_GLOBAL);
-
- /* Read proxy type */
- child = xmlnode_get_child(node, "type");
- if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
- {
- if (purple_strequal(data, "global"))
- purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_GLOBAL);
- else if (purple_strequal(data, "none"))
- purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_NONE);
- else if (purple_strequal(data, "http"))
- purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_HTTP);
- else if (purple_strequal(data, "socks4"))
- purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_SOCKS4);
- else if (purple_strequal(data, "socks5"))
- purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_SOCKS5);
- else if (purple_strequal(data, "tor"))
- purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_TOR);
- else if (purple_strequal(data, "envvar"))
- purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_ENVVAR);
- else
- {
- purple_debug_error("account", "Invalid proxy type found when "
- "loading account information for %s\n",
- purple_account_get_username(account));
- }
- g_free(data);
- }
-
- /* Read proxy host */
- child = xmlnode_get_child(node, "host");
- if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
- {
- purple_proxy_info_set_host(proxy_info, data);
- g_free(data);
- }
-
- /* Read proxy port */
- child = xmlnode_get_child(node, "port");
- if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
- {
- purple_proxy_info_set_port(proxy_info, atoi(data));
- g_free(data);
- }
-
- /* Read proxy username */
- child = xmlnode_get_child(node, "username");
- if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
- {
- purple_proxy_info_set_username(proxy_info, data);
- g_free(data);
- }
-
- /* Read proxy password */
- child = xmlnode_get_child(node, "password");
- if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
- {
- purple_proxy_info_set_password(proxy_info, data);
- g_free(data);
- }
-
- /* If there are no values set then proxy_info NULL */
- if ((purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_GLOBAL) &&
- (purple_proxy_info_get_host(proxy_info) == NULL) &&
- (purple_proxy_info_get_port(proxy_info) == 0) &&
- (purple_proxy_info_get_username(proxy_info) == NULL) &&
- (purple_proxy_info_get_password(proxy_info) == NULL))
- {
- purple_proxy_info_destroy(proxy_info);
- return;
- }
-
- purple_account_set_proxy_info(account, proxy_info);
-}
-
-static void
-parse_current_error(xmlnode *node, PurpleAccount *account)
-{
- guint type;
- char *type_str = NULL, *description = NULL;
- xmlnode *child;
- PurpleConnectionErrorInfo *current_error = NULL;
-
- child = xmlnode_get_child(node, "type");
- if (child == NULL || (type_str = xmlnode_get_data(child)) == NULL)
- return;
- type = atoi(type_str);
- g_free(type_str);
-
- if (type > PURPLE_CONNECTION_ERROR_OTHER_ERROR)
- {
- purple_debug_error("account",
- "Invalid PurpleConnectionError value %d found when "
- "loading account information for %s\n",
- type, purple_account_get_username(account));
- type = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
- }
-
- child = xmlnode_get_child(node, "description");
- if (child)
- description = xmlnode_get_data(child);
- if (description == NULL)
- description = g_strdup("");
-
- current_error = g_new0(PurpleConnectionErrorInfo, 1);
- PURPLE_DBUS_REGISTER_POINTER(current_error, PurpleConnectionErrorInfo);
- current_error->type = type;
- current_error->description = description;
-
- set_current_error(account, current_error);
-}
-
-static PurpleAccount *
-parse_account(xmlnode *node)
-{
- PurpleAccount *ret;
- xmlnode *child;
- char *protocol_id = NULL;
- char *name = NULL;
- char *data;
-
- child = xmlnode_get_child(node, "protocol");
- if (child != NULL)
- protocol_id = xmlnode_get_data(child);
-
- child = xmlnode_get_child(node, "name");
- if (child != NULL)
- name = xmlnode_get_data(child);
- if (name == NULL)
- {
- /* Do we really need to do this? */
- child = xmlnode_get_child(node, "username");
- if (child != NULL)
- name = xmlnode_get_data(child);
- }
-
- if ((protocol_id == NULL) || (name == NULL))
- {
- g_free(protocol_id);
- g_free(name);
- return NULL;
- }
-
- ret = purple_account_new(name, protocol_id);
- g_free(name);
- g_free(protocol_id);
-
- /* Read the alias */
- child = xmlnode_get_child(node, "alias");
- if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
- {
- if (*data != '\0')
- purple_account_set_alias(ret, data);
- g_free(data);
- }
-
- /* Read the statuses */
- child = xmlnode_get_child(node, "statuses");
- if (child != NULL)
- {
- parse_statuses(child, ret);
- }
-
- /* Read the userinfo */
- child = xmlnode_get_child(node, "userinfo");
- if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
- {
- purple_account_set_user_info(ret, data);
- g_free(data);
- }
-
- /* Read an old buddyicon */
- child = xmlnode_get_child(node, "buddyicon");
- if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
- {
- const char *dirname = purple_buddy_icons_get_cache_dir();
- char *filename = g_build_filename(dirname, data, NULL);
- gchar *contents;
- gsize len;
-
- 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);
- }
-
- /* Read settings (both core and UI) */
- for (child = xmlnode_get_child(node, "settings"); child != NULL;
- child = xmlnode_get_next_twin(child))
- {
- parse_settings(child, ret);
- }
-
- /* Read proxy */
- child = xmlnode_get_child(node, "proxy");
- if (child != NULL)
- {
- parse_proxy_info(child, ret);
- }
-
- /* Read current error */
- child = xmlnode_get_child(node, "current_error");
- if (child != NULL)
- {
- parse_current_error(child, ret);
- }
-
- /* Read the password */
- child = xmlnode_get_child(node, "password");
- if (child != NULL)
- {
- const char *keyring_id = xmlnode_get_attrib(child, "keyring_id");
- const char *mode = xmlnode_get_attrib(child, "mode");
- gboolean result;
-
- data = xmlnode_get_data(child);
- result = purple_keyring_import_password(ret, keyring_id, mode, data, NULL);
-
- if (result == TRUE || purple_keyring_get_inuse() == NULL) {
- purple_account_set_remember_password(ret, TRUE);
- } else {
- purple_debug_error("account", "Failed to import password.\n");
- }
- purple_str_wipe(data);
- }
-
- return ret;
-}
-
-static void
-load_accounts(void)
-{
- xmlnode *node, *child;
-
- accounts_loaded = TRUE;
-
- node = purple_util_read_xml_from_file("accounts.xml", _("accounts"));
-
- if (node == NULL)
- return;
-
- for (child = xmlnode_get_child(node, "account"); child != NULL;
- child = xmlnode_get_next_twin(child))
- {
- PurpleAccount *new_acct;
- new_acct = parse_account(child);
- purple_accounts_add(new_acct);
- }
-
- xmlnode_free(node);
-
- _purple_buddy_icons_account_loaded_cb();
-}
-
-
-static void
-delete_setting(void *data)
-{
- PurpleAccountSetting *setting = (PurpleAccountSetting *)data;
-
- g_free(setting->ui);
-
- if (setting->type == PURPLE_PREF_STRING)
- g_free(setting->value.string);
-
- g_free(setting);
-}
-
-PurpleAccount *
-purple_account_new(const char *username, const char *protocol_id)
-{
- PurpleAccount *account = NULL;
- PurplePlugin *prpl = NULL;
- PurplePluginProtocolInfo *prpl_info = NULL;
- PurpleStatusType *status_type;
-
- g_return_val_if_fail(username != NULL, NULL);
- g_return_val_if_fail(protocol_id != NULL, NULL);
-
- account = purple_accounts_find(username, protocol_id);
-
- if (account != NULL)
- return account;
-
- account = g_new0(PurpleAccount, 1);
- PURPLE_DBUS_REGISTER_POINTER(account, PurpleAccount);
-
- purple_account_set_username(account, username);
-
- purple_account_set_protocol_id(account, protocol_id);
-
- account->settings = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, delete_setting);
- account->ui_settings = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, (GDestroyNotify)g_hash_table_destroy);
- account->system_log = NULL;
- /* 0 is not a valid privacy setting */
- account->perm_deny = PURPLE_PRIVACY_ALLOW_ALL;
-
- purple_signal_emit(purple_accounts_get_handle(), "account-created", account);
-
- prpl = purple_find_prpl(protocol_id);
-
- if (prpl == NULL)
- return account;
-
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
- if (prpl_info != NULL && prpl_info->status_types != NULL)
- purple_account_set_status_types(account, prpl_info->status_types(account));
-
- account->presence = purple_presence_new_for_account(account);
+/* GObject Property enums */
+enum
+{
+ PROP_0,
+ PROP_USERNAME,
+ PROP_PRIVATE_ALIAS,
+ PROP_ENABLED,
+ PROP_CONNECTION,
+ PROP_PROTOCOL_ID,
+ PROP_USER_INFO,
+ PROP_BUDDY_ICON_PATH,
+ PROP_REMEMBER_PASSWORD,
+ PROP_CHECK_MAIL,
+ PROP_LAST
+};
- status_type = purple_account_get_status_type_with_primitive(account, PURPLE_STATUS_AVAILABLE);
- if (status_type != NULL)
- purple_presence_set_status_active(account->presence,
- purple_status_type_get_id(status_type),
- TRUE);
- else
- purple_presence_set_status_active(account->presence,
- "offline",
- TRUE);
+static GObjectClass *parent_class = NULL;
+static GList *handles = NULL;
- return account;
-}
+void _purple_account_set_current_error(PurpleAccount *account,
+ PurpleConnectionErrorInfo *new_err);
+/***************
+ * Account API *
+ ***************/
void
-purple_account_destroy(PurpleAccount *account)
+purple_account_set_register_callback(PurpleAccount *account, PurpleAccountRegistrationCb cb, void *user_data)
{
- GList *l;
+ PurpleAccountPrivate *priv;
g_return_if_fail(account != NULL);
- purple_debug_info("account", "Destroying account %p\n", account);
- purple_signal_emit(purple_accounts_get_handle(), "account-destroying", account);
-
- for (l = purple_get_conversations(); l != NULL; l = l->next)
- {
- PurpleConversation *conv = (PurpleConversation *)l->data;
-
- if (purple_conversation_get_account(conv) == account)
- purple_conversation_set_account(conv, NULL);
- }
-
- g_free(account->username);
- g_free(account->alias);
- purple_str_wipe(account->password);
- g_free(account->user_info);
- g_free(account->buddy_icon_path);
- g_free(account->protocol_id);
-
- g_hash_table_destroy(account->settings);
- g_hash_table_destroy(account->ui_settings);
-
- if (account->proxy_info)
- purple_proxy_info_destroy(account->proxy_info);
-
- purple_account_set_status_types(account, NULL);
-
- if (account->presence)
- purple_presence_destroy(account->presence);
-
- if(account->system_log)
- purple_log_free(account->system_log);
-
- while (account->deny) {
- g_free(account->deny->data);
- account->deny = g_slist_delete_link(account->deny, account->deny);
- }
-
- while (account->permit) {
- g_free(account->permit->data);
- account->permit = g_slist_delete_link(account->permit, account->permit);
- }
-
- PURPLE_DBUS_UNREGISTER_POINTER(account->current_error);
- if (account->current_error) {
- g_free(account->current_error->description);
- g_free(account->current_error);
- }
-
- PURPLE_DBUS_UNREGISTER_POINTER(account);
- g_free(account);
-}
-
-void
-purple_account_set_register_callback(PurpleAccount *account, PurpleAccountRegistrationCb cb, void *user_data)
-{
- g_return_if_fail(account != NULL);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
- account->registration_cb = cb;
- account->registration_cb_user_data = user_data;
+ priv->registration_cb = cb;
+ priv->registration_cb_user_data = user_data;
}
static void
@@ -1183,10 +191,14 @@ purple_account_unregister_got_password_cb(PurpleAccount *account,
void
purple_account_register_completed(PurpleAccount *account, gboolean succeeded)
{
+ PurpleAccountPrivate *priv;
+
g_return_if_fail(account != NULL);
- if (account->registration_cb)
- (account->registration_cb)(account, succeeded, account->registration_cb_user_data);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ if (priv->registration_cb)
+ (priv->registration_cb)(account, succeeded, priv->registration_cb_user_data);
}
void
@@ -1299,6 +311,7 @@ purple_account_connect(PurpleAccount *account)
PurplePlugin *prpl;
const char *username;
PurplePluginProtocolInfo *prpl_info;
+ PurpleAccountPrivate *priv;
g_return_if_fail(account != NULL);
@@ -1321,12 +334,14 @@ purple_account_connect(PurpleAccount *account)
return;
}
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
purple_debug_info("account", "Connecting to account %s.\n", username);
prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
- if (account->password != NULL) {
+ if (priv->password != NULL) {
purple_account_connect_got_password_cb(account,
- account->password, NULL, prpl_info);
+ priv->password, NULL, prpl_info);
} else {
purple_keyring_get_password(account,
purple_account_connect_got_password_cb, prpl_info);
@@ -1337,30 +352,36 @@ void
purple_account_disconnect(PurpleAccount *account)
{
PurpleConnection *gc;
+ PurpleAccountPrivate *priv;
const char *username;
g_return_if_fail(account != NULL);
g_return_if_fail(!purple_account_is_disconnected(account));
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
username = purple_account_get_username(account);
purple_debug_info("account", "Disconnecting account %s (%p)\n",
username ? username : "(null)", account);
- account->disconnecting = TRUE;
+ priv->disconnecting = TRUE;
gc = purple_account_get_connection(account);
- _purple_connection_destroy(gc);
+ g_object_unref(gc);
purple_account_set_connection(account, NULL);
- account->disconnecting = FALSE;
+ priv->disconnecting = FALSE;
}
gboolean
purple_account_is_disconnecting(const PurpleAccount *account)
{
+ PurpleAccountPrivate *priv;
+
g_return_val_if_fail(account != NULL, TRUE);
-
- return account->disconnecting;
+
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ return priv->disconnecting;
}
void
@@ -1681,7 +702,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) &&
- (purple_connection_get_flags(gc) & PURPLE_CONNECTION_HTML) ? "html" : NULL),
+ (purple_connection_get_flags(gc) & PURPLE_CONNECTION_FLAG_HTML) ? "html" : NULL),
_("Save"), G_CALLBACK(set_user_info_cb),
_("Cancel"), NULL,
account, NULL, NULL,
@@ -1692,13 +713,16 @@ void
purple_account_set_username(PurpleAccount *account, const char *username)
{
PurpleBlistUiOps *blist_ops;
+ PurpleAccountPrivate *priv;
g_return_if_fail(account != NULL);
- g_free(account->username);
- account->username = g_strdup(username);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ g_free(priv->username);
+ priv->username = g_strdup(username);
- schedule_accounts_save();
+ purple_accounts_schedule_save();
/* if the name changes, we should re-write the buddy list
* to disk with the new name */
@@ -1711,12 +735,16 @@ void
purple_account_set_password(PurpleAccount *account, const gchar *password,
PurpleKeyringSaveCallback cb, gpointer data)
{
+ PurpleAccountPrivate *priv;
+
g_return_if_fail(account != NULL);
- purple_str_wipe(account->password);
- account->password = g_strdup(password);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ purple_str_wipe(priv->password);
+ priv->password = g_strdup(password);
- schedule_accounts_save();
+ purple_accounts_schedule_save();
if (!purple_account_get_remember_password(account)) {
purple_debug_info("account",
@@ -1731,80 +759,102 @@ purple_account_set_password(PurpleAccount *account, const gchar *password,
}
void
-purple_account_set_alias(PurpleAccount *account, const char *alias)
+purple_account_set_private_alias(PurpleAccount *account, const char *alias)
{
+ PurpleAccountPrivate *priv;
+
g_return_if_fail(account != NULL);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
/*
- * Do nothing if alias and account->alias are both NULL. Or if
+ * Do nothing if alias and priv->alias are both NULL. Or if
* they're the exact same string.
*/
- if (alias == account->alias)
+ if (alias == priv->alias)
return;
- if ((!alias && account->alias) || (alias && !account->alias) ||
- g_utf8_collate(account->alias, alias))
+ if ((!alias && priv->alias) || (alias && !priv->alias) ||
+ g_utf8_collate(priv->alias, alias))
{
- char *old = account->alias;
+ char *old = priv->alias;
- account->alias = g_strdup(alias);
+ priv->alias = g_strdup(alias);
purple_signal_emit(purple_accounts_get_handle(), "account-alias-changed",
account, old);
g_free(old);
- schedule_accounts_save();
+ purple_accounts_schedule_save();
}
}
void
purple_account_set_user_info(PurpleAccount *account, const char *user_info)
{
+ PurpleAccountPrivate *priv;
+
g_return_if_fail(account != NULL);
- g_free(account->user_info);
- account->user_info = g_strdup(user_info);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
- schedule_accounts_save();
+ g_free(priv->user_info);
+ priv->user_info = g_strdup(user_info);
+
+ purple_accounts_schedule_save();
}
void purple_account_set_buddy_icon_path(PurpleAccount *account, const char *path)
{
+ PurpleAccountPrivate *priv;
+
g_return_if_fail(account != NULL);
- g_free(account->buddy_icon_path);
- account->buddy_icon_path = g_strdup(path);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
- schedule_accounts_save();
+ g_free(priv->buddy_icon_path);
+ priv->buddy_icon_path = g_strdup(path);
+
+ purple_accounts_schedule_save();
}
void
purple_account_set_protocol_id(PurpleAccount *account, const char *protocol_id)
{
+ PurpleAccountPrivate *priv;
+
g_return_if_fail(account != NULL);
g_return_if_fail(protocol_id != NULL);
- g_free(account->protocol_id);
- account->protocol_id = g_strdup(protocol_id);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ g_free(priv->protocol_id);
+ priv->protocol_id = g_strdup(protocol_id);
- schedule_accounts_save();
+ purple_accounts_schedule_save();
}
void
purple_account_set_connection(PurpleAccount *account, PurpleConnection *gc)
{
+ PurpleAccountPrivate *priv;
+
g_return_if_fail(account != NULL);
- account->gc = gc;
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ priv->gc = gc;
}
void
purple_account_set_remember_password(PurpleAccount *account, gboolean value)
{
+ PurpleAccountPrivate *priv;
+
g_return_if_fail(account != NULL);
- account->remember_pass = value;
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ priv->remember_pass = value;
- schedule_accounts_save();
+ purple_accounts_schedule_save();
}
void
@@ -1820,6 +870,7 @@ purple_account_set_enabled(PurpleAccount *account, const char *ui,
gboolean value)
{
PurpleConnection *gc;
+ PurpleAccountPrivate *priv;
gboolean was_enabled = FALSE;
g_return_if_fail(account != NULL);
@@ -1835,10 +886,12 @@ purple_account_set_enabled(PurpleAccount *account, const char *ui,
else if(!was_enabled && value)
purple_signal_emit(purple_accounts_get_handle(), "account-enabled", account);
- if ((gc != NULL) && (gc->wants_to_die == TRUE))
+ if ((gc != NULL) && (_purple_connection_wants_to_die(gc)))
return;
- if (value && purple_presence_is_online(account->presence))
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ if (value && purple_presence_is_online(priv->presence))
purple_account_connect(account);
else if (!value && !purple_account_is_disconnected(account))
purple_account_disconnect(account);
@@ -1847,38 +900,49 @@ purple_account_set_enabled(PurpleAccount *account, const char *ui,
void
purple_account_set_proxy_info(PurpleAccount *account, PurpleProxyInfo *info)
{
+ PurpleAccountPrivate *priv;
+
g_return_if_fail(account != NULL);
- if (account->proxy_info != NULL)
- purple_proxy_info_destroy(account->proxy_info);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ if (priv->proxy_info != NULL)
+ purple_proxy_info_destroy(priv->proxy_info);
- account->proxy_info = info;
+ priv->proxy_info = info;
- schedule_accounts_save();
+ purple_accounts_schedule_save();
}
void
-purple_account_set_privacy_type(PurpleAccount *account, PurplePrivacyType privacy_type)
+purple_account_set_privacy_type(PurpleAccount *account, PurpleAccountPrivacyType privacy_type)
{
+ PurpleAccountPrivate *priv;
+
g_return_if_fail(account != NULL);
- account->perm_deny = privacy_type;
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ priv->privacy_type = privacy_type;
}
void
purple_account_set_status_types(PurpleAccount *account, GList *status_types)
{
+ PurpleAccountPrivate *priv;
+
g_return_if_fail(account != NULL);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
/* Out with the old... */
- if (account->status_types != NULL)
+ if (priv->status_types != NULL)
{
- g_list_foreach(account->status_types, (GFunc)purple_status_type_destroy, NULL);
- g_list_free(account->status_types);
+ g_list_foreach(priv->status_types, (GFunc)purple_status_type_destroy, NULL);
+ g_list_free(priv->status_types);
}
/* In with the new... */
- account->status_types = status_types;
+ priv->status_types = status_types;
}
void
@@ -1928,7 +992,7 @@ purple_account_set_status_list(PurpleAccount *account, const char *status_id,
* Our current statuses are saved to accounts.xml (so that when we
* reconnect, we go back to the previous status).
*/
- schedule_accounts_save();
+ purple_accounts_schedule_save();
}
struct public_alias_closure
@@ -2031,42 +1095,63 @@ purple_account_set_silence_suppression(PurpleAccount *account, gboolean value)
purple_account_set_bool(account, "silence-suppression", value);
}
+static void
+delete_setting(void *data)
+{
+ PurpleAccountSetting *setting = (PurpleAccountSetting *)data;
+
+ g_free(setting->ui);
+ g_value_unset(&setting->value);
+
+ g_free(setting);
+}
+
void
purple_account_clear_settings(PurpleAccount *account)
{
+ PurpleAccountPrivate *priv;
+
g_return_if_fail(account != NULL);
- g_hash_table_destroy(account->settings);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ g_hash_table_destroy(priv->settings);
- account->settings = g_hash_table_new_full(g_str_hash, g_str_equal,
+ priv->settings = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, delete_setting);
}
void
purple_account_remove_setting(PurpleAccount *account, const char *setting)
{
+ PurpleAccountPrivate *priv;
+
g_return_if_fail(account != NULL);
g_return_if_fail(setting != NULL);
- g_hash_table_remove(account->settings, setting);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ g_hash_table_remove(priv->settings, setting);
}
void
purple_account_set_int(PurpleAccount *account, const char *name, int value)
{
PurpleAccountSetting *setting;
+ PurpleAccountPrivate *priv;
g_return_if_fail(account != NULL);
g_return_if_fail(name != NULL);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
setting = g_new0(PurpleAccountSetting, 1);
- setting->type = PURPLE_PREF_INT;
- setting->value.integer = value;
+ g_value_init(&setting->value, G_TYPE_INT);
+ g_value_set_int(&setting->value, value);
- g_hash_table_insert(account->settings, g_strdup(name), setting);
+ g_hash_table_insert(priv->settings, g_strdup(name), setting);
- schedule_accounts_save();
+ purple_accounts_schedule_save();
}
void
@@ -2074,49 +1159,56 @@ purple_account_set_string(PurpleAccount *account, const char *name,
const char *value)
{
PurpleAccountSetting *setting;
+ PurpleAccountPrivate *priv;
g_return_if_fail(account != NULL);
g_return_if_fail(name != NULL);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
setting = g_new0(PurpleAccountSetting, 1);
- setting->type = PURPLE_PREF_STRING;
- setting->value.string = g_strdup(value);
+ g_value_init(&setting->value, G_TYPE_STRING);
+ g_value_set_string(&setting->value, value);
- g_hash_table_insert(account->settings, g_strdup(name), setting);
+ g_hash_table_insert(priv->settings, g_strdup(name), setting);
- schedule_accounts_save();
+ purple_accounts_schedule_save();
}
void
purple_account_set_bool(PurpleAccount *account, const char *name, gboolean value)
{
PurpleAccountSetting *setting;
+ PurpleAccountPrivate *priv;
g_return_if_fail(account != NULL);
g_return_if_fail(name != NULL);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
setting = g_new0(PurpleAccountSetting, 1);
- setting->type = PURPLE_PREF_BOOLEAN;
- setting->value.boolean = value;
+ g_value_init(&setting->value, G_TYPE_BOOLEAN);
+ g_value_set_boolean(&setting->value, value);
- g_hash_table_insert(account->settings, g_strdup(name), setting);
+ g_hash_table_insert(priv->settings, g_strdup(name), setting);
- schedule_accounts_save();
+ purple_accounts_schedule_save();
}
static GHashTable *
get_ui_settings_table(PurpleAccount *account, const char *ui)
{
GHashTable *table;
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
- table = g_hash_table_lookup(account->ui_settings, ui);
+ table = g_hash_table_lookup(priv->ui_settings, ui);
if (table == NULL) {
table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
delete_setting);
- g_hash_table_insert(account->ui_settings, g_strdup(ui), table);
+ g_hash_table_insert(priv->ui_settings, g_strdup(ui), table);
}
return table;
@@ -2135,15 +1227,15 @@ purple_account_set_ui_int(PurpleAccount *account, const char *ui,
setting = g_new0(PurpleAccountSetting, 1);
- setting->type = PURPLE_PREF_INT;
setting->ui = g_strdup(ui);
- setting->value.integer = value;
+ g_value_init(&setting->value, G_TYPE_INT);
+ g_value_set_int(&setting->value, value);
table = get_ui_settings_table(account, ui);
g_hash_table_insert(table, g_strdup(name), setting);
- schedule_accounts_save();
+ purple_accounts_schedule_save();
}
void
@@ -2159,15 +1251,15 @@ purple_account_set_ui_string(PurpleAccount *account, const char *ui,
setting = g_new0(PurpleAccountSetting, 1);
- setting->type = PURPLE_PREF_STRING;
setting->ui = g_strdup(ui);
- setting->value.string = g_strdup(value);
+ g_value_init(&setting->value, G_TYPE_STRING);
+ g_value_set_string(&setting->value, value);
table = get_ui_settings_table(account, ui);
g_hash_table_insert(table, g_strdup(name), setting);
- schedule_accounts_save();
+ purple_accounts_schedule_save();
}
void
@@ -2183,15 +1275,15 @@ purple_account_set_ui_bool(PurpleAccount *account, const char *ui,
setting = g_new0(PurpleAccountSetting, 1);
- setting->type = PURPLE_PREF_BOOLEAN;
setting->ui = g_strdup(ui);
- setting->value.boolean = value;
+ g_value_init(&setting->value, G_TYPE_BOOLEAN);
+ g_value_set_boolean(&setting->value, value);
table = get_ui_settings_table(account, ui);
g_hash_table_insert(table, g_strdup(name), setting);
- schedule_accounts_save();
+ purple_accounts_schedule_save();
}
static PurpleConnectionState
@@ -2199,11 +1291,11 @@ purple_account_get_state(const PurpleAccount *account)
{
PurpleConnection *gc;
- g_return_val_if_fail(account != NULL, PURPLE_DISCONNECTED);
+ g_return_val_if_fail(account != NULL, PURPLE_CONNECTION_DISCONNECTED);
gc = purple_account_get_connection(account);
if (!gc)
- return PURPLE_DISCONNECTED;
+ return PURPLE_CONNECTION_DISCONNECTED;
return purple_connection_get_state(gc);
}
@@ -2211,27 +1303,30 @@ purple_account_get_state(const PurpleAccount *account)
gboolean
purple_account_is_connected(const PurpleAccount *account)
{
- return (purple_account_get_state(account) == PURPLE_CONNECTED);
+ return (purple_account_get_state(account) == PURPLE_CONNECTION_CONNECTED);
}
gboolean
purple_account_is_connecting(const PurpleAccount *account)
{
- return (purple_account_get_state(account) == PURPLE_CONNECTING);
+ return (purple_account_get_state(account) == PURPLE_CONNECTION_CONNECTING);
}
gboolean
purple_account_is_disconnected(const PurpleAccount *account)
{
- return (purple_account_get_state(account) == PURPLE_DISCONNECTED);
+ return (purple_account_get_state(account) == PURPLE_CONNECTION_DISCONNECTED);
}
const char *
purple_account_get_username(const PurpleAccount *account)
{
+ PurpleAccountPrivate *priv;
+
g_return_val_if_fail(account != NULL, NULL);
- return account->username;
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ return priv->username;
}
static void
@@ -2240,13 +1335,14 @@ purple_account_get_password_got(PurpleAccount *account,
{
PurpleCallbackBundle *cbb = data;
PurpleKeyringReadCallback cb;
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
purple_debug_info("account",
"Read password for account %s from async keyring.\n",
purple_account_get_username(account));
- purple_str_wipe(account->password);
- account->password = g_strdup(password);
+ purple_str_wipe(priv->password);
+ priv->password = g_strdup(password);
cb = (PurpleKeyringReadCallback)cbb->cb;
if (cb != NULL)
@@ -2259,16 +1355,20 @@ void
purple_account_get_password(PurpleAccount *account,
PurpleKeyringReadCallback cb, gpointer data)
{
+ PurpleAccountPrivate *priv;
+
if (account == NULL) {
cb(NULL, NULL, NULL, data);
return;
}
- if (account->password != NULL) {
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ if (priv->password != NULL) {
purple_debug_info("account",
"Reading password for account %s from cache.\n",
purple_account_get_username(account));
- cb(account, account->password, NULL, data);
+ cb(account, priv->password, NULL, data);
} else {
PurpleCallbackBundle *cbb = g_new0(PurpleCallbackBundle, 1);
cbb->cb = PURPLE_CALLBACK(cb);
@@ -2283,34 +1383,47 @@ purple_account_get_password(PurpleAccount *account,
}
const char *
-purple_account_get_alias(const PurpleAccount *account)
+purple_account_get_private_alias(const PurpleAccount *account)
{
+ PurpleAccountPrivate *priv;
+
g_return_val_if_fail(account != NULL, NULL);
- return account->alias;
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ return priv->alias;
}
const char *
purple_account_get_user_info(const PurpleAccount *account)
{
+ PurpleAccountPrivate *priv;
+
g_return_val_if_fail(account != NULL, NULL);
- return account->user_info;
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ return priv->user_info;
}
const char *
purple_account_get_buddy_icon_path(const PurpleAccount *account)
{
+ PurpleAccountPrivate *priv;
+
g_return_val_if_fail(account != NULL, NULL);
- return account->buddy_icon_path;
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ return priv->buddy_icon_path;
}
const char *
purple_account_get_protocol_id(const PurpleAccount *account)
{
+ PurpleAccountPrivate *priv;
+
g_return_val_if_fail(account != NULL, NULL);
- return account->protocol_id;
+
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ return priv->protocol_id;
}
const char *
@@ -2328,9 +1441,12 @@ purple_account_get_protocol_name(const PurpleAccount *account)
PurpleConnection *
purple_account_get_connection(const PurpleAccount *account)
{
+ PurpleAccountPrivate *priv;
+
g_return_val_if_fail(account != NULL, NULL);
- return account->gc;
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ return priv->gc;
}
const gchar *
@@ -2340,14 +1456,14 @@ purple_account_get_name_for_display(const PurpleAccount *account)
PurpleConnection *gc = NULL;
const gchar *name = NULL, *username = NULL, *displayname = NULL;
- name = purple_account_get_alias(account);
+ name = purple_account_get_private_alias(account);
if (name) {
return name;
}
username = purple_account_get_username(account);
- self = purple_find_buddy((PurpleAccount *)account, username);
+ self = purple_blist_find_buddy((PurpleAccount *)account, username);
if (self) {
const gchar *calias= purple_buddy_get_contact_alias(self);
@@ -2372,9 +1488,12 @@ purple_account_get_name_for_display(const PurpleAccount *account)
gboolean
purple_account_get_remember_password(const PurpleAccount *account)
{
+ PurpleAccountPrivate *priv;
+
g_return_val_if_fail(account != NULL, FALSE);
- return account->remember_pass;
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ return priv->remember_pass;
}
gboolean
@@ -2397,34 +1516,434 @@ purple_account_get_enabled(const PurpleAccount *account, const char *ui)
PurpleProxyInfo *
purple_account_get_proxy_info(const PurpleAccount *account)
{
+ PurpleAccountPrivate *priv;
+
g_return_val_if_fail(account != NULL, NULL);
- return account->proxy_info;
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ return priv->proxy_info;
}
-PurplePrivacyType
+PurpleAccountPrivacyType
purple_account_get_privacy_type(const PurpleAccount *account)
{
- g_return_val_if_fail(account != NULL, PURPLE_PRIVACY_ALLOW_ALL);
+ PurpleAccountPrivate *priv;
+
+ g_return_val_if_fail(account != NULL, PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL);
+
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ return priv->privacy_type;
+}
+
+gboolean
+purple_account_privacy_permit_add(PurpleAccount *account, const char *who,
+ gboolean local_only)
+{
+ GSList *l;
+ char *name;
+ PurpleBuddy *buddy;
+ PurpleBlistUiOps *blist_ops;
+ PurpleAccountPrivate *priv;
+ PurpleAccountUiOps *ui_ops = purple_accounts_get_ui_ops();
+
+ g_return_val_if_fail(account != NULL, FALSE);
+ g_return_val_if_fail(who != NULL, FALSE);
+
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ name = g_strdup(purple_normalize(account, who));
+
+ for (l = priv->permit; l != NULL; l = l->next) {
+ if (g_str_equal(name, l->data))
+ /* This buddy already exists */
+ break;
+ }
+
+ if (l != NULL)
+ {
+ /* This buddy already exists, so bail out */
+ g_free(name);
+ return FALSE;
+ }
+
+ priv->permit = g_slist_append(priv->permit, name);
+
+ if (!local_only && purple_account_is_connected(account))
+ serv_add_permit(purple_account_get_connection(account), who);
+
+ if (ui_ops != NULL && ui_ops->permit_added != NULL)
+ ui_ops->permit_added(account, who);
+
+ blist_ops = purple_blist_get_ui_ops();
+ if (blist_ops != NULL && blist_ops->save_account != NULL)
+ blist_ops->save_account(account);
+
+ /* This lets the UI know a buddy has had its privacy setting changed */
+ buddy = purple_blist_find_buddy(account, name);
+ if (buddy != NULL) {
+ purple_signal_emit(purple_blist_get_handle(),
+ "buddy-privacy-changed", buddy);
+ }
+ return TRUE;
+}
+
+gboolean
+purple_account_privacy_permit_remove(PurpleAccount *account, const char *who,
+ gboolean local_only)
+{
+ GSList *l;
+ const char *name;
+ PurpleBuddy *buddy;
+ char *del;
+ PurpleBlistUiOps *blist_ops;
+ PurpleAccountPrivate *priv;
+ PurpleAccountUiOps *ui_ops = purple_accounts_get_ui_ops();
+
+ g_return_val_if_fail(account != NULL, FALSE);
+ g_return_val_if_fail(who != NULL, FALSE);
+
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ name = purple_normalize(account, who);
+
+ for (l = priv->permit; l != NULL; l = l->next) {
+ if (g_str_equal(name, l->data))
+ /* We found the buddy we were looking for */
+ break;
+ }
+
+ if (l == NULL)
+ /* We didn't find the buddy we were looking for, so bail out */
+ return FALSE;
+
+ /* We should not free l->data just yet. There can be occasions where
+ * l->data == who. In such cases, freeing l->data here can cause crashes
+ * later when who is used. */
+ del = l->data;
+ priv->permit = g_slist_delete_link(priv->permit, l);
+
+ if (!local_only && purple_account_is_connected(account))
+ serv_rem_permit(purple_account_get_connection(account), who);
+
+ if (ui_ops != NULL && ui_ops->permit_removed != NULL)
+ ui_ops->permit_removed(account, who);
+
+ blist_ops = purple_blist_get_ui_ops();
+ if (blist_ops != NULL && blist_ops->save_account != NULL)
+ blist_ops->save_account(account);
+
+ buddy = purple_blist_find_buddy(account, name);
+ if (buddy != NULL) {
+ purple_signal_emit(purple_blist_get_handle(),
+ "buddy-privacy-changed", buddy);
+ }
+ g_free(del);
+ return TRUE;
+}
+
+gboolean
+purple_account_privacy_deny_add(PurpleAccount *account, const char *who,
+ gboolean local_only)
+{
+ GSList *l;
+ char *name;
+ PurpleBuddy *buddy;
+ PurpleBlistUiOps *blist_ops;
+ PurpleAccountPrivate *priv;
+ PurpleAccountUiOps *ui_ops = purple_accounts_get_ui_ops();
+
+ g_return_val_if_fail(account != NULL, FALSE);
+ g_return_val_if_fail(who != NULL, FALSE);
+
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ name = g_strdup(purple_normalize(account, who));
+
+ for (l = priv->deny; l != NULL; l = l->next) {
+ if (g_str_equal(name, l->data))
+ /* This buddy already exists */
+ break;
+ }
+
+ if (l != NULL)
+ {
+ /* This buddy already exists, so bail out */
+ g_free(name);
+ return FALSE;
+ }
+
+ priv->deny = g_slist_append(priv->deny, name);
+
+ if (!local_only && purple_account_is_connected(account))
+ serv_add_deny(purple_account_get_connection(account), who);
+
+ if (ui_ops != NULL && ui_ops->deny_added != NULL)
+ ui_ops->deny_added(account, who);
+
+ blist_ops = purple_blist_get_ui_ops();
+ if (blist_ops != NULL && blist_ops->save_account != NULL)
+ blist_ops->save_account(account);
+
+ buddy = purple_blist_find_buddy(account, name);
+ if (buddy != NULL) {
+ purple_signal_emit(purple_blist_get_handle(),
+ "buddy-privacy-changed", buddy);
+ }
+ return TRUE;
+}
+
+gboolean
+purple_account_privacy_deny_remove(PurpleAccount *account, const char *who,
+ gboolean local_only)
+{
+ GSList *l;
+ const char *normalized;
+ char *name;
+ PurpleBuddy *buddy;
+ PurpleBlistUiOps *blist_ops;
+ PurpleAccountPrivate *priv;
+ PurpleAccountUiOps *ui_ops = purple_accounts_get_ui_ops();
+
+ g_return_val_if_fail(account != NULL, FALSE);
+ g_return_val_if_fail(who != NULL, FALSE);
+
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ normalized = purple_normalize(account, who);
+
+ for (l = priv->deny; l != NULL; l = l->next) {
+ if (g_str_equal(normalized, l->data))
+ /* We found the buddy we were looking for */
+ break;
+ }
+
+ if (l == NULL)
+ /* We didn't find the buddy we were looking for, so bail out */
+ return FALSE;
+
+ buddy = purple_blist_find_buddy(account, normalized);
+
+ name = l->data;
+ priv->deny = g_slist_delete_link(priv->deny, l);
+
+ if (!local_only && purple_account_is_connected(account))
+ serv_rem_deny(purple_account_get_connection(account), name);
+
+ if (ui_ops != NULL && ui_ops->deny_removed != NULL)
+ ui_ops->deny_removed(account, who);
+
+ if (buddy != NULL) {
+ purple_signal_emit(purple_blist_get_handle(),
+ "buddy-privacy-changed", buddy);
+ }
+
+ g_free(name);
+
+ blist_ops = purple_blist_get_ui_ops();
+ if (blist_ops != NULL && blist_ops->save_account != NULL)
+ blist_ops->save_account(account);
+
+ return TRUE;
+}
+
+/**
+ * This makes sure your permit list contains all buddies from your
+ * buddy list and ONLY buddies from your buddy list.
+ */
+static void
+add_all_buddies_to_permit_list(PurpleAccount *account, gboolean local)
+{
+ GSList *list;
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ /* Remove anyone in the permit list who is not in the buddylist */
+ for (list = priv->permit; list != NULL; ) {
+ char *person = list->data;
+ list = list->next;
+ if (!purple_blist_find_buddy(account, person))
+ purple_account_privacy_permit_remove(account, person, local);
+ }
+
+ /* Now make sure everyone in the buddylist is in the permit list */
+ list = purple_blist_find_buddies(account, NULL);
+ while (list != NULL)
+ {
+ PurpleBuddy *buddy = list->data;
+ const gchar *name = purple_buddy_get_name(buddy);
+
+ if (!g_slist_find_custom(priv->permit, name, (GCompareFunc)g_utf8_collate))
+ purple_account_privacy_permit_add(account, name, local);
+ list = g_slist_delete_link(list, list);
+ }
+}
+
+void
+purple_account_privacy_allow(PurpleAccount *account, const char *who)
+{
+ GSList *list;
+ PurpleAccountPrivacyType type = purple_account_get_privacy_type(account);
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ switch (type) {
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL:
+ return;
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS:
+ purple_account_privacy_permit_add(account, who, FALSE);
+ break;
+ case PURPLE_ACCOUNT_PRIVACY_DENY_USERS:
+ purple_account_privacy_deny_remove(account, who, FALSE);
+ break;
+ case PURPLE_ACCOUNT_PRIVACY_DENY_ALL:
+ {
+ /* Empty the allow-list. */
+ const char *norm = purple_normalize(account, who);
+ for (list = priv->permit; list != NULL;) {
+ char *person = list->data;
+ list = list->next;
+ if (!purple_strequal(norm, person))
+ purple_account_privacy_permit_remove(account, person, FALSE);
+ }
+ purple_account_privacy_permit_add(account, who, FALSE);
+ purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS);
+ }
+ break;
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST:
+ if (!purple_blist_find_buddy(account, who)) {
+ add_all_buddies_to_permit_list(account, FALSE);
+ purple_account_privacy_permit_add(account, who, FALSE);
+ purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS);
+ }
+ break;
+ default:
+ g_return_if_reached();
+ }
+
+ /* Notify the server if the privacy setting was changed */
+ if (type != purple_account_get_privacy_type(account) && purple_account_is_connected(account))
+ serv_set_permit_deny(purple_account_get_connection(account));
+}
+
+void
+purple_account_privacy_deny(PurpleAccount *account, const char *who)
+{
+ GSList *list;
+ PurpleAccountPrivacyType type = purple_account_get_privacy_type(account);
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ switch (type) {
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL:
+ {
+ /* Empty the deny-list. */
+ const char *norm = purple_normalize(account, who);
+ for (list = priv->deny; list != NULL; ) {
+ char *person = list->data;
+ list = list->next;
+ if (!purple_strequal(norm, person))
+ purple_account_privacy_deny_remove(account, person, FALSE);
+ }
+ purple_account_privacy_deny_add(account, who, FALSE);
+ purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_DENY_USERS);
+ }
+ break;
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS:
+ purple_account_privacy_permit_remove(account, who, FALSE);
+ break;
+ case PURPLE_ACCOUNT_PRIVACY_DENY_USERS:
+ purple_account_privacy_deny_add(account, who, FALSE);
+ break;
+ case PURPLE_ACCOUNT_PRIVACY_DENY_ALL:
+ break;
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST:
+ if (purple_blist_find_buddy(account, who)) {
+ add_all_buddies_to_permit_list(account, FALSE);
+ purple_account_privacy_permit_remove(account, who, FALSE);
+ purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS);
+ }
+ break;
+ default:
+ g_return_if_reached();
+ }
+
+ /* Notify the server if the privacy setting was changed */
+ if (type != purple_account_get_privacy_type(account) && purple_account_is_connected(account))
+ serv_set_permit_deny(purple_account_get_connection(account));
+}
+
+GSList *
+purple_account_privacy_get_permitted(PurpleAccount *account)
+{
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
- return account->perm_deny;
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->permit;
+}
+
+GSList *
+purple_account_privacy_get_denied(PurpleAccount *account)
+{
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->deny;
+}
+
+gboolean
+purple_account_privacy_check(PurpleAccount *account, const char *who)
+{
+ GSList *list;
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ switch (purple_account_get_privacy_type(account)) {
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL:
+ return TRUE;
+
+ case PURPLE_ACCOUNT_PRIVACY_DENY_ALL:
+ return FALSE;
+
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS:
+ who = purple_normalize(account, who);
+ for (list=priv->permit; list!=NULL; list=list->next) {
+ if (g_str_equal(who, list->data))
+ return TRUE;
+ }
+ return FALSE;
+
+ case PURPLE_ACCOUNT_PRIVACY_DENY_USERS:
+ who = purple_normalize(account, who);
+ for (list=priv->deny; list!=NULL; list=list->next) {
+ if (g_str_equal(who, list->data))
+ return FALSE;
+ }
+ return TRUE;
+
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST:
+ return (purple_blist_find_buddy(account, who) != NULL);
+
+ default:
+ g_return_val_if_reached(TRUE);
+ }
}
PurpleStatus *
purple_account_get_active_status(const PurpleAccount *account)
{
+ PurpleAccountPrivate *priv;
+
g_return_val_if_fail(account != NULL, NULL);
- return purple_presence_get_active_status(account->presence);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ return purple_presence_get_active_status(priv->presence);
}
PurpleStatus *
purple_account_get_status(const PurpleAccount *account, const char *status_id)
{
+ PurpleAccountPrivate *priv;
+
g_return_val_if_fail(account != NULL, NULL);
g_return_val_if_fail(status_id != NULL, NULL);
- return purple_presence_get_status(account->presence, status_id);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ return purple_presence_get_status(priv->presence, status_id);
}
PurpleStatusType *
@@ -2467,27 +1986,37 @@ purple_account_get_status_type_with_primitive(const PurpleAccount *account, Purp
PurplePresence *
purple_account_get_presence(const PurpleAccount *account)
{
+ PurpleAccountPrivate *priv;
+
g_return_val_if_fail(account != NULL, NULL);
- return account->presence;
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ return priv->presence;
}
gboolean
purple_account_is_status_active(const PurpleAccount *account,
const char *status_id)
{
+ PurpleAccountPrivate *priv;
+
g_return_val_if_fail(account != NULL, FALSE);
g_return_val_if_fail(status_id != NULL, FALSE);
- return purple_presence_is_status_active(account->presence, status_id);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ return purple_presence_is_status_active(priv->presence, status_id);
}
GList *
purple_account_get_status_types(const PurpleAccount *account)
{
+ PurpleAccountPrivate *priv;
+
g_return_val_if_fail(account != NULL, NULL);
- return account->status_types;
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ return priv->status_types;
}
int
@@ -2495,18 +2024,21 @@ purple_account_get_int(const PurpleAccount *account, const char *name,
int default_value)
{
PurpleAccountSetting *setting;
+ PurpleAccountPrivate *priv;
g_return_val_if_fail(account != NULL, default_value);
g_return_val_if_fail(name != NULL, default_value);
- setting = g_hash_table_lookup(account->settings, name);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ setting = g_hash_table_lookup(priv->settings, name);
if (setting == NULL)
return default_value;
- g_return_val_if_fail(setting->type == PURPLE_PREF_INT, default_value);
+ g_return_val_if_fail(G_VALUE_HOLDS_INT(&setting->value), default_value);
- return setting->value.integer;
+ return g_value_get_int(&setting->value);
}
const char *
@@ -2514,18 +2046,21 @@ purple_account_get_string(const PurpleAccount *account, const char *name,
const char *default_value)
{
PurpleAccountSetting *setting;
+ PurpleAccountPrivate *priv;
g_return_val_if_fail(account != NULL, default_value);
g_return_val_if_fail(name != NULL, default_value);
- setting = g_hash_table_lookup(account->settings, name);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ setting = g_hash_table_lookup(priv->settings, name);
if (setting == NULL)
return default_value;
- g_return_val_if_fail(setting->type == PURPLE_PREF_STRING, default_value);
+ g_return_val_if_fail(G_VALUE_HOLDS_STRING(&setting->value), default_value);
- return setting->value.string;
+ return g_value_get_string(&setting->value);
}
gboolean
@@ -2533,18 +2068,21 @@ purple_account_get_bool(const PurpleAccount *account, const char *name,
gboolean default_value)
{
PurpleAccountSetting *setting;
+ PurpleAccountPrivate *priv;
g_return_val_if_fail(account != NULL, default_value);
g_return_val_if_fail(name != NULL, default_value);
- setting = g_hash_table_lookup(account->settings, name);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ setting = g_hash_table_lookup(priv->settings, name);
if (setting == NULL)
return default_value;
- g_return_val_if_fail(setting->type == PURPLE_PREF_BOOLEAN, default_value);
+ g_return_val_if_fail(G_VALUE_HOLDS_BOOLEAN(&setting->value), default_value);
- return setting->value.boolean;
+ return g_value_get_boolean(&setting->value);
}
int
@@ -2552,21 +2090,24 @@ purple_account_get_ui_int(const PurpleAccount *account, const char *ui,
const char *name, int default_value)
{
PurpleAccountSetting *setting;
+ PurpleAccountPrivate *priv;
GHashTable *table;
g_return_val_if_fail(account != NULL, default_value);
g_return_val_if_fail(ui != NULL, default_value);
g_return_val_if_fail(name != NULL, default_value);
- if ((table = g_hash_table_lookup(account->ui_settings, ui)) == NULL)
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ if ((table = g_hash_table_lookup(priv->ui_settings, ui)) == NULL)
return default_value;
if ((setting = g_hash_table_lookup(table, name)) == NULL)
return default_value;
- g_return_val_if_fail(setting->type == PURPLE_PREF_INT, default_value);
+ g_return_val_if_fail(G_VALUE_HOLDS_INT(&setting->value), default_value);
- return setting->value.integer;
+ return g_value_get_int(&setting->value);
}
const char *
@@ -2574,21 +2115,24 @@ purple_account_get_ui_string(const PurpleAccount *account, const char *ui,
const char *name, const char *default_value)
{
PurpleAccountSetting *setting;
+ PurpleAccountPrivate *priv;
GHashTable *table;
g_return_val_if_fail(account != NULL, default_value);
g_return_val_if_fail(ui != NULL, default_value);
g_return_val_if_fail(name != NULL, default_value);
- if ((table = g_hash_table_lookup(account->ui_settings, ui)) == NULL)
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ if ((table = g_hash_table_lookup(priv->ui_settings, ui)) == NULL)
return default_value;
if ((setting = g_hash_table_lookup(table, name)) == NULL)
return default_value;
- g_return_val_if_fail(setting->type == PURPLE_PREF_STRING, default_value);
+ g_return_val_if_fail(G_VALUE_HOLDS_STRING(&setting->value), default_value);
- return setting->value.string;
+ return g_value_get_string(&setting->value);
}
gboolean
@@ -2596,69 +2140,78 @@ purple_account_get_ui_bool(const PurpleAccount *account, const char *ui,
const char *name, gboolean default_value)
{
PurpleAccountSetting *setting;
+ PurpleAccountPrivate *priv;
GHashTable *table;
g_return_val_if_fail(account != NULL, default_value);
g_return_val_if_fail(ui != NULL, default_value);
g_return_val_if_fail(name != NULL, default_value);
- if ((table = g_hash_table_lookup(account->ui_settings, ui)) == NULL)
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ if ((table = g_hash_table_lookup(priv->ui_settings, ui)) == NULL)
return default_value;
if ((setting = g_hash_table_lookup(table, name)) == NULL)
return default_value;
- g_return_val_if_fail(setting->type == PURPLE_PREF_BOOLEAN, default_value);
+ g_return_val_if_fail(G_VALUE_HOLDS_BOOLEAN(&setting->value), default_value);
- return setting->value.boolean;
+ return g_value_get_boolean(&setting->value);
}
gpointer
purple_account_get_ui_data(const PurpleAccount *account)
{
- g_return_val_if_fail(account != NULL, NULL);
+ g_return_val_if_fail(account != NULL, NULL);
- return account->ui_data;
+ return account->ui_data;
}
void
-purple_account_set_ui_data(PurpleAccount *account,
- gpointer ui_data)
+purple_account_set_ui_data(PurpleAccount *account, gpointer ui_data)
{
- g_return_if_fail(account != NULL);
+ g_return_if_fail(account != NULL);
- account->ui_data = ui_data;
+ account->ui_data = ui_data;
}
-
PurpleLog *
purple_account_get_log(PurpleAccount *account, gboolean create)
{
+ PurpleAccountPrivate *priv;
+
g_return_val_if_fail(account != NULL, NULL);
- if(!account->system_log && create){
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ if(!priv->system_log && create){
PurplePresence *presence;
int login_time;
presence = purple_account_get_presence(account);
login_time = purple_presence_get_login_time(presence);
- account->system_log = purple_log_new(PURPLE_LOG_SYSTEM,
+ priv->system_log = purple_log_new(PURPLE_LOG_SYSTEM,
purple_account_get_username(account), account, NULL,
(login_time != 0) ? login_time : time(NULL), NULL);
}
- return account->system_log;
+ return priv->system_log;
}
void
purple_account_destroy_log(PurpleAccount *account)
{
+ PurpleAccountPrivate *priv;
+
g_return_if_fail(account != NULL);
- if(account->system_log){
- purple_log_free(account->system_log);
- account->system_log = NULL;
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ if(priv->system_log){
+ purple_log_free(priv->system_log);
+ priv->system_log = NULL;
}
}
@@ -2829,45 +2382,27 @@ gboolean purple_account_supports_offline_message(PurpleAccount *account, PurpleB
return prpl_info->offline_message(buddy);
}
-static void
-signed_on_cb(PurpleConnection *gc,
- gpointer unused)
-{
- PurpleAccount *account = purple_connection_get_account(gc);
- purple_account_clear_current_error(account);
-
- purple_signal_emit(purple_accounts_get_handle(), "account-signed-on",
- account);
-}
-
-static void
-signed_off_cb(PurpleConnection *gc,
- gpointer unused)
-{
- PurpleAccount *account = purple_connection_get_account(gc);
-
- purple_signal_emit(purple_accounts_get_handle(), "account-signed-off",
- account);
-}
-
-static void
-set_current_error(PurpleAccount *account, PurpleConnectionErrorInfo *new_err)
+void
+_purple_account_set_current_error(PurpleAccount *account,
+ PurpleConnectionErrorInfo *new_err)
{
PurpleConnectionErrorInfo *old_err;
+ PurpleAccountPrivate *priv;
g_return_if_fail(account != NULL);
+ priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
- old_err = account->current_error;
+ old_err = priv->current_error;
if(new_err == old_err)
return;
- account->current_error = new_err;
+ priv->current_error = new_err;
purple_signal_emit(purple_accounts_get_handle(),
"account-error-changed",
account, old_err, new_err);
- schedule_accounts_save();
+ purple_accounts_schedule_save();
if(old_err)
g_free(old_err->description);
@@ -2876,435 +2411,733 @@ set_current_error(PurpleAccount *account, PurpleConnectionErrorInfo *new_err)
g_free(old_err);
}
-static void
-connection_error_cb(PurpleConnection *gc,
- PurpleConnectionError type,
- const gchar *description,
- gpointer unused)
+const PurpleConnectionErrorInfo *
+purple_account_get_current_error(PurpleAccount *account)
{
- PurpleAccount *account;
- PurpleConnectionErrorInfo *err;
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
- account = purple_connection_get_account(gc);
+ return priv->current_error;
+}
- g_return_if_fail(account != NULL);
+void
+purple_account_clear_current_error(PurpleAccount *account)
+{
+ _purple_account_set_current_error(account, NULL);
+}
+
+static xmlnode *
+status_attribute_to_xmlnode(const PurpleStatus *status, const PurpleStatusType *type,
+ const PurpleStatusAttribute *attr)
+{
+ xmlnode *node;
+ const char *id;
+ char *value = NULL;
+ PurpleStatusAttribute *default_attr;
+ GValue *default_value;
+ GType attr_type;
+ GValue *attr_value;
+
+ id = purple_status_attribute_get_id(attr);
+ g_return_val_if_fail(id, NULL);
+
+ attr_value = purple_status_get_attr_value(status, id);
+ g_return_val_if_fail(attr_value, NULL);
+ attr_type = G_VALUE_TYPE(attr_value);
+
+ /*
+ * If attr_value is a different type than it should be
+ * then don't write it to the file.
+ */
+ default_attr = purple_status_type_get_attr(type, id);
+ default_value = purple_status_attribute_get_value(default_attr);
+ if (attr_type != G_VALUE_TYPE(default_value))
+ return NULL;
+
+ /*
+ * If attr_value is the same as the default for this status
+ * then there is no need to write it to the file.
+ */
+ if (attr_type == G_TYPE_STRING)
+ {
+ const char *string_value = g_value_get_string(attr_value);
+ const char *default_string_value = g_value_get_string(default_value);
+ if (purple_strequal(string_value, default_string_value))
+ return NULL;
+ value = g_strdup(g_value_get_string(attr_value));
+ }
+ else if (attr_type == G_TYPE_INT)
+ {
+ int int_value = g_value_get_int(attr_value);
+ if (int_value == g_value_get_int(default_value))
+ return NULL;
+ value = g_strdup_printf("%d", int_value);
+ }
+ else if (attr_type == G_TYPE_BOOLEAN)
+ {
+ gboolean boolean_value = g_value_get_boolean(attr_value);
+ if (boolean_value == g_value_get_boolean(default_value))
+ return NULL;
+ value = g_strdup(boolean_value ?
+ "true" : "false");
+ }
+ else
+ {
+ return NULL;
+ }
- err = g_new0(PurpleConnectionErrorInfo, 1);
- PURPLE_DBUS_REGISTER_POINTER(err, PurpleConnectionErrorInfo);
+ g_return_val_if_fail(value, NULL);
- err->type = type;
- err->description = g_strdup(description);
+ node = xmlnode_new("attribute");
+
+ xmlnode_set_attrib(node, "id", id);
+ xmlnode_set_attrib(node, "value", value);
- set_current_error(account, err);
+ g_free(value);
- purple_signal_emit(purple_accounts_get_handle(), "account-connection-error",
- account, type, description);
+ return node;
}
-static void
-password_migration_cb(PurpleAccount *account)
+static xmlnode *
+status_attrs_to_xmlnode(const PurpleStatus *status)
{
- /* account may be NULL (means: all) */
+ PurpleStatusType *type = purple_status_get_status_type(status);
+ xmlnode *node, *child;
+ GList *attrs, *attr;
+
+ node = xmlnode_new("attributes");
- schedule_accounts_save();
+ attrs = purple_status_type_get_attrs(type);
+ for (attr = attrs; attr != NULL; attr = attr->next)
+ {
+ child = status_attribute_to_xmlnode(status, type, (const PurpleStatusAttribute *)attr->data);
+ if (child)
+ xmlnode_insert_child(node, child);
+ }
+
+ return node;
}
-const PurpleConnectionErrorInfo *
-purple_account_get_current_error(PurpleAccount *account)
+static xmlnode *
+status_to_xmlnode(const PurpleStatus *status)
{
- return account->current_error;
+ xmlnode *node, *child;
+
+ node = xmlnode_new("status");
+ xmlnode_set_attrib(node, "type", purple_status_get_id(status));
+ if (purple_status_get_name(status) != NULL)
+ xmlnode_set_attrib(node, "name", purple_status_get_name(status));
+ xmlnode_set_attrib(node, "active", purple_status_is_active(status) ? "true" : "false");
+
+ child = status_attrs_to_xmlnode(status);
+ xmlnode_insert_child(node, child);
+
+ return node;
}
-void
-purple_account_clear_current_error(PurpleAccount *account)
+static xmlnode *
+statuses_to_xmlnode(const PurplePresence *presence)
{
- set_current_error(account, NULL);
+ xmlnode *node, *child;
+ GList *statuses;
+ PurpleStatus *status;
+
+ node = xmlnode_new("statuses");
+
+ statuses = purple_presence_get_statuses(presence);
+ for (; statuses != NULL; statuses = statuses->next)
+ {
+ status = statuses->data;
+ if (purple_status_type_is_saveable(purple_status_get_status_type(status)))
+ {
+ child = status_to_xmlnode(status);
+ xmlnode_insert_child(node, child);
+ }
+ }
+
+ return node;
}
-void
-purple_accounts_add(PurpleAccount *account)
+static xmlnode *
+proxy_settings_to_xmlnode(PurpleProxyInfo *proxy_info)
{
- g_return_if_fail(account != NULL);
+ xmlnode *node, *child;
+ PurpleProxyType proxy_type;
+ const char *value;
+ int int_value;
+ char buf[21];
- if (g_list_find(accounts, account) != NULL)
- return;
+ proxy_type = purple_proxy_info_get_type(proxy_info);
- accounts = g_list_append(accounts, account);
+ node = xmlnode_new("proxy");
- schedule_accounts_save();
+ child = xmlnode_new_child(node, "type");
+ xmlnode_insert_data(child,
+ (proxy_type == PURPLE_PROXY_USE_GLOBAL ? "global" :
+ proxy_type == PURPLE_PROXY_NONE ? "none" :
+ proxy_type == PURPLE_PROXY_HTTP ? "http" :
+ proxy_type == PURPLE_PROXY_SOCKS4 ? "socks4" :
+ proxy_type == PURPLE_PROXY_SOCKS5 ? "socks5" :
+ proxy_type == PURPLE_PROXY_TOR ? "tor" :
+ proxy_type == PURPLE_PROXY_USE_ENVVAR ? "envvar" : "unknown"), -1);
+
+ if ((value = purple_proxy_info_get_host(proxy_info)) != NULL)
+ {
+ child = xmlnode_new_child(node, "host");
+ xmlnode_insert_data(child, value, -1);
+ }
- purple_signal_emit(purple_accounts_get_handle(), "account-added", account);
+ if ((int_value = purple_proxy_info_get_port(proxy_info)) != 0)
+ {
+ g_snprintf(buf, sizeof(buf), "%d", int_value);
+ child = xmlnode_new_child(node, "port");
+ xmlnode_insert_data(child, buf, -1);
+ }
+
+ if ((value = purple_proxy_info_get_username(proxy_info)) != NULL)
+ {
+ child = xmlnode_new_child(node, "username");
+ xmlnode_insert_data(child, value, -1);
+ }
+
+ if ((value = purple_proxy_info_get_password(proxy_info)) != NULL)
+ {
+ child = xmlnode_new_child(node, "password");
+ xmlnode_insert_data(child, value, -1);
+ }
+
+ return node;
}
-void
-purple_accounts_remove(PurpleAccount *account)
+static xmlnode *
+current_error_to_xmlnode(PurpleConnectionErrorInfo *err)
{
- g_return_if_fail(account != NULL);
+ xmlnode *node, *child;
+ char type_str[3];
- accounts = g_list_remove(accounts, account);
+ node = xmlnode_new("current_error");
- schedule_accounts_save();
+ if(err == NULL)
+ return node;
- /* Clearing the error ensures that account-error-changed is emitted,
- * which is the end of the guarantee that the the error's pointer is
- * valid.
+ /* It doesn't make sense to have transient errors persist across a
+ * restart.
*/
- purple_account_clear_current_error(account);
- purple_signal_emit(purple_accounts_get_handle(), "account-removed", account);
+ if(!purple_connection_error_is_fatal (err->type))
+ return node;
+
+ child = xmlnode_new_child(node, "type");
+ g_snprintf(type_str, sizeof(type_str), "%u", err->type);
+ xmlnode_insert_data(child, type_str, -1);
+
+ child = xmlnode_new_child(node, "description");
+ if(err->description) {
+ char *utf8ized = purple_utf8_try_convert(err->description);
+ if(utf8ized == NULL)
+ utf8ized = purple_utf8_salvage(err->description);
+ xmlnode_insert_data(child, utf8ized, -1);
+ g_free(utf8ized);
+ }
+
+ return node;
}
static void
-purple_accounts_delete_set(PurpleAccount *account, GError *error, gpointer data)
+setting_to_xmlnode(gpointer key, gpointer value, gpointer user_data)
{
- purple_account_destroy(account);
+ const char *name;
+ PurpleAccountSetting *setting;
+ xmlnode *node, *child;
+ char buf[21];
+
+ name = (const char *)key;
+ setting = (PurpleAccountSetting *)value;
+ node = (xmlnode *)user_data;
+
+ child = xmlnode_new_child(node, "setting");
+ xmlnode_set_attrib(child, "name", name);
+
+ if (G_VALUE_HOLDS_INT(&setting->value)) {
+ xmlnode_set_attrib(child, "type", "int");
+ g_snprintf(buf, sizeof(buf), "%d", g_value_get_int(&setting->value));
+ xmlnode_insert_data(child, buf, -1);
+ }
+ else if (G_VALUE_HOLDS_STRING(&setting->value) && g_value_get_string(&setting->value) != NULL) {
+ xmlnode_set_attrib(child, "type", "string");
+ xmlnode_insert_data(child, g_value_get_string(&setting->value), -1);
+ }
+ else if (G_VALUE_HOLDS_BOOLEAN(&setting->value)) {
+ xmlnode_set_attrib(child, "type", "bool");
+ g_snprintf(buf, sizeof(buf), "%d", g_value_get_boolean(&setting->value));
+ xmlnode_insert_data(child, buf, -1);
+ }
}
-void
-purple_accounts_delete(PurpleAccount *account)
+static void
+ui_setting_to_xmlnode(gpointer key, gpointer value, gpointer user_data)
{
- PurpleBlistNode *gnode, *cnode, *bnode;
- GList *iter;
+ const char *ui;
+ GHashTable *table;
+ xmlnode *node, *child;
- g_return_if_fail(account != NULL);
+ ui = (const char *)key;
+ table = (GHashTable *)value;
+ node = (xmlnode *)user_data;
- /*
- * Disable the account before blowing it out of the water.
- * Conceptually it probably makes more sense to disable the
- * account for all UIs rather than the just the current UI,
- * but it doesn't really matter.
- */
- purple_account_set_enabled(account, purple_core_get_ui(), FALSE);
+ if (g_hash_table_size(table) > 0)
+ {
+ child = xmlnode_new_child(node, "settings");
+ xmlnode_set_attrib(child, "ui", ui);
+ g_hash_table_foreach(table, setting_to_xmlnode, child);
+ }
+}
- purple_notify_close_with_handle(account);
- purple_request_close_with_handle(account);
+xmlnode *
+purple_account_to_xmlnode(PurpleAccount *account)
+{
+ xmlnode *node, *child;
+ const char *tmp;
+ PurplePresence *presence;
+ PurpleProxyInfo *proxy_info;
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ node = xmlnode_new("account");
+
+ child = xmlnode_new_child(node, "protocol");
+ xmlnode_insert_data(child, purple_account_get_protocol_id(account), -1);
- purple_accounts_remove(account);
+ child = xmlnode_new_child(node, "name");
+ xmlnode_insert_data(child, purple_account_get_username(account), -1);
- /* Remove this account's buddies */
- for (gnode = purple_blist_get_root();
- gnode != NULL;
- gnode = purple_blist_node_get_sibling_next(gnode))
+ if (purple_account_get_remember_password(account))
{
- if (!PURPLE_BLIST_NODE_IS_GROUP(gnode))
- continue;
+ const char *keyring_id = NULL;
+ const char *mode = NULL;
+ char *data = NULL;
+ GError *error = NULL;
+ GDestroyNotify destroy = NULL;
+ gboolean exported = purple_keyring_export_password(account,
+ &keyring_id, &mode, &data, &error, &destroy);
+
+ if (error != NULL) {
+ purple_debug_error("account",
+ "Failed to export password for account %s: %s.\n",
+ purple_account_get_username(account),
+ error->message);
+ } else if (exported) {
+ child = xmlnode_new_child(node, "password");
+ if (keyring_id != NULL)
+ xmlnode_set_attrib(child, "keyring_id", keyring_id);
+ if (mode != NULL)
+ xmlnode_set_attrib(child, "mode", mode);
+ if (data != NULL)
+ xmlnode_insert_data(child, data, -1);
+
+ if (destroy != NULL)
+ destroy(data);
+ }
+ }
- cnode = purple_blist_node_get_first_child(gnode);
- while (cnode) {
- PurpleBlistNode *cnode_next = purple_blist_node_get_sibling_next(cnode);
+ if ((tmp = purple_account_get_private_alias(account)) != NULL)
+ {
+ child = xmlnode_new_child(node, "alias");
+ xmlnode_insert_data(child, tmp, -1);
+ }
- if(PURPLE_BLIST_NODE_IS_CONTACT(cnode)) {
- bnode = purple_blist_node_get_first_child(cnode);
- while (bnode) {
- PurpleBlistNode *bnode_next = purple_blist_node_get_sibling_next(bnode);
+ if ((presence = purple_account_get_presence(account)) != NULL)
+ {
+ child = statuses_to_xmlnode(presence);
+ xmlnode_insert_child(node, child);
+ }
- if (PURPLE_BLIST_NODE_IS_BUDDY(bnode)) {
- PurpleBuddy *b = (PurpleBuddy *)bnode;
+ if ((tmp = purple_account_get_user_info(account)) != NULL)
+ {
+ /* TODO: Do we need to call purple_str_strip_char(tmp, '\r') here? */
+ child = xmlnode_new_child(node, "userinfo");
+ xmlnode_insert_data(child, tmp, -1);
+ }
- if (purple_buddy_get_account(b) == account)
- purple_blist_remove_buddy(b);
- }
- bnode = bnode_next;
- }
- } else if (PURPLE_BLIST_NODE_IS_CHAT(cnode)) {
- PurpleChat *c = (PurpleChat *)cnode;
+ if (g_hash_table_size(priv->settings) > 0)
+ {
+ child = xmlnode_new_child(node, "settings");
+ g_hash_table_foreach(priv->settings, setting_to_xmlnode, child);
+ }
- if (purple_chat_get_account(c) == account)
- purple_blist_remove_chat(c);
- }
- cnode = cnode_next;
- }
+ if (g_hash_table_size(priv->ui_settings) > 0)
+ {
+ g_hash_table_foreach(priv->ui_settings, ui_setting_to_xmlnode, node);
}
- /* Remove any open conversation for this account */
- for (iter = purple_get_conversations(); iter; ) {
- PurpleConversation *conv = iter->data;
- iter = iter->next;
- if (purple_conversation_get_account(conv) == account)
- purple_conversation_destroy(conv);
+ if ((proxy_info = purple_account_get_proxy_info(account)) != NULL)
+ {
+ child = proxy_settings_to_xmlnode(proxy_info);
+ xmlnode_insert_child(node, child);
}
- /* Remove this account's pounces */
- purple_pounce_destroy_all_by_account(account);
+ child = current_error_to_xmlnode(priv->current_error);
+ xmlnode_insert_child(node, child);
- /* This will cause the deletion of an old buddy icon. */
- purple_buddy_icons_set_account_icon(account, NULL, 0);
+ return node;
+}
- /* This is async because we do not want the
- * account being overwritten before we are done.
- */
- purple_keyring_set_password(account, NULL,
- purple_accounts_delete_set, NULL);
+/****************
+ * GObject Code *
+ ****************/
+
+/* GObject Property names */
+#define PROP_USERNAME_S "username"
+#define PROP_PRIVATE_ALIAS_S "private-alias"
+#define PROP_ENABLED_S "enabled"
+#define PROP_CONNECTION_S "connection"
+#define PROP_PROTOCOL_ID_S "protocol-id"
+#define PROP_USER_INFO_S "userinfo"
+#define PROP_BUDDY_ICON_PATH_S "buddy-icon-path"
+#define PROP_REMEMBER_PASSWORD_S "remember-password"
+#define PROP_CHECK_MAIL_S "check-mail"
+
+/* Set method for GObject properties */
+static void
+purple_account_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleAccount *account = PURPLE_ACCOUNT(obj);
+
+ switch (param_id) {
+ case PROP_USERNAME:
+ purple_account_set_username(account, g_value_get_string(value));
+ break;
+ case PROP_PRIVATE_ALIAS:
+ purple_account_set_private_alias(account, g_value_get_string(value));
+ break;
+ case PROP_ENABLED:
+ purple_account_set_enabled(account, purple_core_get_ui(),
+ g_value_get_boolean(value));
+ break;
+ case PROP_CONNECTION:
+ purple_account_set_connection(account, g_value_get_object(value));
+ break;
+ case PROP_PROTOCOL_ID:
+ purple_account_set_protocol_id(account, g_value_get_string(value));
+ break;
+ case PROP_USER_INFO:
+ purple_account_set_user_info(account, g_value_get_string(value));
+ break;
+ case PROP_BUDDY_ICON_PATH:
+ purple_account_set_buddy_icon_path(account,
+ g_value_get_string(value));
+ break;
+ case PROP_REMEMBER_PASSWORD:
+ purple_account_set_remember_password(account,
+ g_value_get_boolean(value));
+ break;
+ case PROP_CHECK_MAIL:
+ purple_account_set_check_mail(account, g_value_get_boolean(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Get method for GObject properties */
+static void
+purple_account_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleAccount *account = PURPLE_ACCOUNT(obj);
+
+ switch (param_id) {
+ case PROP_USERNAME:
+ g_value_set_string(value, purple_account_get_username(account));
+ break;
+ case PROP_PRIVATE_ALIAS:
+ g_value_set_string(value, purple_account_get_private_alias(account));
+ break;
+ case PROP_ENABLED:
+ g_value_set_boolean(value, purple_account_get_enabled(account,
+ purple_core_get_ui()));
+ break;
+ case PROP_CONNECTION:
+ g_value_set_object(value, purple_account_get_connection(account));
+ break;
+ case PROP_PROTOCOL_ID:
+ g_value_set_string(value, purple_account_get_protocol_id(account));
+ break;
+ case PROP_USER_INFO:
+ g_value_set_string(value, purple_account_get_user_info(account));
+ break;
+ case PROP_BUDDY_ICON_PATH:
+ g_value_set_string(value,
+ purple_account_get_buddy_icon_path(account));
+ break;
+ case PROP_REMEMBER_PASSWORD:
+ g_value_set_boolean(value,
+ purple_account_get_remember_password(account));
+ break;
+ case PROP_CHECK_MAIL:
+ g_value_set_boolean(value, purple_account_get_check_mail(account));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* GObject initialization function */
+static void purple_account_init(GTypeInstance *instance, gpointer klass)
+{
+ PurpleAccount *account = PURPLE_ACCOUNT(instance);
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ priv->settings = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, delete_setting);
+ priv->ui_settings = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, (GDestroyNotify)g_hash_table_destroy);
+ priv->system_log = NULL;
+
+ priv->privacy_type = PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL;
+
+ PURPLE_DBUS_REGISTER_POINTER(account, PurpleAccount);
}
-void
-purple_accounts_reorder(PurpleAccount *account, guint new_index)
+/* Called when done constructing */
+static void
+purple_account_constructed(GObject *object)
{
- gint index;
- GList *l;
+ PurpleAccount *account = PURPLE_ACCOUNT(object);
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+ gchar *username, *protocol_id;
+ PurplePlugin *prpl = NULL;
+ PurplePluginProtocolInfo *prpl_info = NULL;
+ PurpleStatusType *status_type;
- g_return_if_fail(account != NULL);
- g_return_if_fail(new_index <= g_list_length(accounts));
+ parent_class->constructed(object);
- index = g_list_index(accounts, account);
+ g_object_get(object,
+ PROP_USERNAME_S, &username,
+ PROP_PROTOCOL_ID_S, &protocol_id,
+ NULL);
- if (index < 0) {
- purple_debug_error("account",
- "Unregistered account (%s) discovered during reorder!\n",
- purple_account_get_username(account));
+ purple_signal_emit(purple_accounts_get_handle(), "account-created",
+ account);
+
+ prpl = purple_find_prpl(protocol_id);
+ if (prpl == NULL) {
+ g_free(username);
+ g_free(protocol_id);
return;
}
- l = g_list_nth(accounts, index);
-
- if (new_index > (guint)index)
- new_index--;
-
- /* Remove the old one. */
- accounts = g_list_delete_link(accounts, l);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
+ if (prpl_info != NULL && prpl_info->status_types != NULL)
+ purple_account_set_status_types(account,
+ prpl_info->status_types(account));
- /* Insert it where it should go. */
- accounts = g_list_insert(accounts, account, new_index);
+ priv->presence = PURPLE_PRESENCE(purple_account_presence_new(account));
- schedule_accounts_save();
-}
+ status_type = purple_account_get_status_type_with_primitive(account,
+ PURPLE_STATUS_AVAILABLE);
+ if (status_type != NULL)
+ purple_presence_set_status_active(priv->presence,
+ purple_status_type_get_id(status_type),
+ TRUE);
+ else
+ purple_presence_set_status_active(priv->presence,
+ "offline",
+ TRUE);
-GList *
-purple_accounts_get_all(void)
-{
- return accounts;
+ g_free(username);
+ g_free(protocol_id);
}
-GList *
-purple_accounts_get_all_active(void)
+/* GObject dispose function */
+static void
+purple_account_dispose(GObject *object)
{
- GList *list = NULL;
- GList *all = purple_accounts_get_all();
+ GList *l;
+ PurpleAccount *account = PURPLE_ACCOUNT(object);
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
- while (all != NULL) {
- PurpleAccount *account = all->data;
+ purple_debug_info("account", "Destroying account %p\n", account);
+ purple_signal_emit(purple_accounts_get_handle(), "account-destroying",
+ account);
- if (purple_account_get_enabled(account, purple_core_get_ui()))
- list = g_list_append(list, account);
+ for (l = purple_conversations_get_all(); l != NULL; l = l->next)
+ {
+ PurpleConversation *conv = (PurpleConversation *)l->data;
- all = all->next;
+ if (purple_conversation_get_account(conv) == account)
+ purple_conversation_set_account(conv, NULL);
}
- return list;
-}
+ purple_account_set_status_types(account, NULL);
-PurpleAccount *
-purple_accounts_find(const char *name, const char *protocol_id)
-{
- PurpleAccount *account = NULL;
- GList *l;
- char *who;
+ if (priv->proxy_info)
+ purple_proxy_info_destroy(priv->proxy_info);
- g_return_val_if_fail(name != NULL, NULL);
- g_return_val_if_fail(protocol_id != NULL, NULL);
+ if (priv->presence)
+ g_object_unref(priv->presence);
- for (l = purple_accounts_get_all(); l != NULL; l = l->next) {
- account = (PurpleAccount *)l->data;
- if (!purple_strequal(account->protocol_id, protocol_id))
- continue;
+ if(priv->system_log)
+ purple_log_free(priv->system_log);
- who = g_strdup(purple_normalize(account, name));
- if (purple_strequal(purple_normalize(account, purple_account_get_username(account)), who)) {
- g_free(who);
- return account;
- }
- g_free(who);
+ if (priv->current_error) {
+ g_free(priv->current_error->description);
+ g_free(priv->current_error);
}
- return NULL;
+ PURPLE_DBUS_UNREGISTER_POINTER(priv->current_error);
+ PURPLE_DBUS_UNREGISTER_POINTER(account);
+
+ parent_class->dispose(object);
}
-void
-purple_accounts_restore_current_statuses()
+/* GObject finalize function */
+static void
+purple_account_finalize(GObject *object)
{
- GList *l;
- PurpleAccount *account;
+ PurpleAccount *account = PURPLE_ACCOUNT(object);
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
- /* If we're not connected to the Internet right now, we bail on this */
- if (!purple_network_is_available())
- {
- purple_debug_warning("account", "Network not connected; skipping reconnect\n");
- return;
+ g_free(priv->username);
+ g_free(priv->alias);
+ purple_str_wipe(priv->password);
+ g_free(priv->user_info);
+ g_free(priv->buddy_icon_path);
+ g_free(priv->protocol_id);
+
+ g_hash_table_destroy(priv->settings);
+ g_hash_table_destroy(priv->ui_settings);
+
+ while (priv->deny) {
+ g_free(priv->deny->data);
+ priv->deny = g_slist_delete_link(priv->deny, priv->deny);
}
- for (l = purple_accounts_get_all(); l != NULL; l = l->next)
- {
- account = (PurpleAccount *)l->data;
- if (purple_account_get_enabled(account, purple_core_get_ui()) &&
- (purple_presence_is_online(account->presence)))
- {
- purple_account_connect(account);
- }
+ while (priv->permit) {
+ g_free(priv->permit->data);
+ priv->permit = g_slist_delete_link(priv->permit, priv->permit);
}
-}
-void
-purple_accounts_set_ui_ops(PurpleAccountUiOps *ops)
-{
- account_ui_ops = ops;
+ parent_class->finalize(object);
}
-PurpleAccountUiOps *
-purple_accounts_get_ui_ops(void)
-{
- return account_ui_ops;
+/* Class initializer function */
+static void
+purple_account_class_init(PurpleAccountClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->dispose = purple_account_dispose;
+ obj_class->finalize = purple_account_finalize;
+ obj_class->constructed = purple_account_constructed;
+
+ /* Setup properties */
+ obj_class->get_property = purple_account_get_property;
+ obj_class->set_property = purple_account_set_property;
+
+ g_object_class_install_property(obj_class, PROP_USERNAME,
+ g_param_spec_string(PROP_USERNAME_S, _("Username"),
+ _("The username for the account."), NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
+ );
+
+ g_object_class_install_property(obj_class, PROP_PRIVATE_ALIAS,
+ g_param_spec_string(PROP_PRIVATE_ALIAS_S, _("Private Alias"),
+ _("The private alias for the account."), NULL,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, PROP_USER_INFO,
+ g_param_spec_string(PROP_USER_INFO_S, _("User information"),
+ _("Detailed user information for the account."), NULL,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, PROP_BUDDY_ICON_PATH,
+ g_param_spec_string(PROP_BUDDY_ICON_PATH_S, _("Buddy icon path"),
+ _("Path to the buddyicon for the account."), NULL,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, PROP_ENABLED,
+ g_param_spec_boolean(PROP_ENABLED_S, _("Enabled"),
+ _("Whether the account is enabled or not."), FALSE,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, PROP_REMEMBER_PASSWORD,
+ g_param_spec_boolean(PROP_REMEMBER_PASSWORD_S, _("Remember password"),
+ _("Whether to remember and store the password for this account."), FALSE,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, PROP_CHECK_MAIL,
+ g_param_spec_boolean(PROP_CHECK_MAIL_S, _("Check mail"),
+ _("Whether to check mails for this account."), FALSE,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, PROP_CONNECTION,
+ g_param_spec_object(PROP_CONNECTION_S, _("Connection"),
+ _("The connection for the account."), PURPLE_TYPE_CONNECTION,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, PROP_PROTOCOL_ID,
+ g_param_spec_string(PROP_PROTOCOL_ID_S, _("Protocol ID"),
+ _("ID of the protocol that is responsible for the account."), NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)
+ );
+
+ g_type_class_add_private(klass, sizeof(PurpleAccountPrivate));
+}
+
+GType
+purple_account_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleAccountClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_account_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleAccount),
+ 0,
+ (GInstanceInitFunc)purple_account_init,
+ NULL,
+ };
+
+ type = g_type_register_static(G_TYPE_OBJECT,
+ "PurpleAccount",
+ &info, 0);
+ }
+
+ return type;
}
-void *
-purple_accounts_get_handle(void)
+PurpleAccount *
+purple_account_new(const char *username, const char *protocol_id)
{
- static int handle;
-
- return &handle;
-}
+ PurpleAccount *account;
-void
-purple_accounts_init(void)
-{
- void *handle = purple_accounts_get_handle();
- void *conn_handle = purple_connections_get_handle();
-
- purple_signal_register(handle, "account-connecting",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT));
-
- purple_signal_register(handle, "account-disabled",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT));
-
- purple_signal_register(handle, "account-enabled",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT));
-
- purple_signal_register(handle, "account-setting-info",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "account-set-info",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "account-created",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_ACCOUNT));
-
- purple_signal_register(handle, "account-destroying",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_ACCOUNT));
-
- purple_signal_register(handle, "account-added",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_ACCOUNT));
-
- purple_signal_register(handle, "account-removed",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_ACCOUNT));
-
- purple_signal_register(handle, "account-status-changed",
- purple_marshal_VOID__POINTER_POINTER_POINTER, NULL, 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_STATUS),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_STATUS));
-
- purple_signal_register(handle, "account-actions-changed",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_ACCOUNT));
-
- purple_signal_register(handle, "account-alias-changed",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "account-authorization-requested",
- purple_marshal_INT__POINTER_POINTER_POINTER,
- purple_value_new(PURPLE_TYPE_INT), 4,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "account-authorization-denied",
- purple_marshal_VOID__POINTER_POINTER, NULL, 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "account-authorization-granted",
- purple_marshal_VOID__POINTER_POINTER, NULL, 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "account-error-changed",
- purple_marshal_VOID__POINTER_POINTER_POINTER,
- NULL, 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_POINTER),
- purple_value_new(PURPLE_TYPE_POINTER));
-
- purple_signal_register(handle, "account-signed-on",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT));
-
- purple_signal_register(handle, "account-signed-off",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT));
-
- purple_signal_register(handle, "account-connection-error",
- purple_marshal_VOID__POINTER_INT_POINTER, NULL, 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_ENUM),
- purple_value_new(PURPLE_TYPE_STRING));
-
- purple_signal_connect(conn_handle, "signed-on", handle,
- PURPLE_CALLBACK(signed_on_cb), NULL);
- purple_signal_connect(conn_handle, "signed-off", handle,
- PURPLE_CALLBACK(signed_off_cb), NULL);
- purple_signal_connect(conn_handle, "connection-error", handle,
- PURPLE_CALLBACK(connection_error_cb), NULL);
- purple_signal_connect(purple_keyring_get_handle(), "password-migration", handle,
- PURPLE_CALLBACK(password_migration_cb), NULL);
-
- load_accounts();
+ g_return_val_if_fail(username != NULL, NULL);
+ g_return_val_if_fail(protocol_id != NULL, NULL);
-}
+ account = purple_accounts_find(username, protocol_id);
-void
-purple_accounts_uninit(void)
-{
- gpointer handle = purple_accounts_get_handle();
- if (save_timer != 0)
- {
- purple_timeout_remove(save_timer);
- save_timer = 0;
- sync_accounts();
- }
+ if (account != NULL)
+ return account;
- for (; accounts; accounts = g_list_delete_link(accounts, accounts))
- purple_account_destroy(accounts->data);
+ account = g_object_new(PURPLE_TYPE_ACCOUNT,
+ PROP_USERNAME_S, username,
+ PROP_PROTOCOL_ID_S, protocol_id,
+ NULL);
- purple_signals_disconnect_by_handle(handle);
- purple_signals_unregister_by_instance(handle);
+ return account;
}
diff --git a/libpurple/account.h b/libpurple/account.h
index b1b689d4b2..4cdb7ef6a0 100644
--- a/libpurple/account.h
+++ b/libpurple/account.h
@@ -1,7 +1,6 @@
/**
* @file account.h Account API
* @ingroup core
- * @see @ref account-signals
*/
/* purple
@@ -30,10 +29,17 @@
#include <glib.h>
#include <glib-object.h>
-/** @copydoc _PurpleAccountUiOps */
-typedef struct _PurpleAccountUiOps PurpleAccountUiOps;
+#define PURPLE_TYPE_ACCOUNT (purple_account_get_type())
+#define PURPLE_ACCOUNT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_ACCOUNT, PurpleAccount))
+#define PURPLE_ACCOUNT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_ACCOUNT, PurpleAccountClass))
+#define PURPLE_IS_ACCOUNT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_ACCOUNT))
+#define PURPLE_IS_ACCOUNT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_ACCOUNT))
+#define PURPLE_ACCOUNT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_ACCOUNT, PurpleAccountClass))
+
/** @copydoc _PurpleAccount */
-typedef struct _PurpleAccount PurpleAccount;
+typedef struct _PurpleAccount PurpleAccount;
+/** @copydoc _PurpleAccountClass */
+typedef struct _PurpleAccountClass PurpleAccountClass;
typedef gboolean (*PurpleFilterAccountFunc)(PurpleAccount *account);
typedef void (*PurpleAccountRequestAuthorizationCb)(const char *, void *);
@@ -46,11 +52,11 @@ typedef void (*PurpleGetPublicAliasFailureCallback)(PurpleAccount *account, cons
#include "connection.h"
#include "log.h"
-#include "privacy.h"
#include "proxy.h"
#include "prpl.h"
#include "status.h"
#include "keyring.h"
+#include "xmlnode.h"
/**
* Account request types.
@@ -71,106 +77,45 @@ typedef enum
PURPLE_ACCOUNT_RESPONSE_ACCEPT = 1
} PurpleAccountRequestResponse;
-/** Account UI operations, used to notify the user of status changes and when
- * buddies add this account to their buddy lists.
+/**
+ * Privacy data types.
*/
-struct _PurpleAccountUiOps
+typedef enum
{
- /** A buddy who is already on this account's buddy list added this account
- * to their buddy list.
- */
- void (*notify_added)(PurpleAccount *account,
- const char *remote_user,
- const char *id,
- const char *alias,
- const char *message);
-
- /** This account's status changed. */
- void (*status_changed)(PurpleAccount *account,
- PurpleStatus *status);
-
- /** Someone we don't have on our list added us; prompt to add them. */
- void (*request_add)(PurpleAccount *account,
- const char *remote_user,
- const char *id,
- const char *alias,
- const char *message);
-
- /** Prompt for authorization when someone adds this account to their buddy
- * list. To authorize them to see this account's presence, call \a
- * authorize_cb (\a message, \a user_data); otherwise call
- * \a deny_cb (\a message, \a user_data);
- * @return a UI-specific handle, as passed to #close_account_request.
- */
- void *(*request_authorize)(PurpleAccount *account,
- const char *remote_user,
- const char *id,
- const char *alias,
- const char *message,
- gboolean on_list,
- PurpleAccountRequestAuthorizationCb authorize_cb,
- PurpleAccountRequestAuthorizationCb deny_cb,
- void *user_data);
-
- /** Close a pending request for authorization. \a ui_handle is a handle
- * as returned by #request_authorize.
- */
- void (*close_account_request)(void *ui_handle);
+ PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL = 1,
+ PURPLE_ACCOUNT_PRIVACY_DENY_ALL,
+ PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS,
+ PURPLE_ACCOUNT_PRIVACY_DENY_USERS,
+ PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST
+} PurpleAccountPrivacyType;
- void (*_purple_reserved1)(void);
- void (*_purple_reserved2)(void);
- void (*_purple_reserved3)(void);
- void (*_purple_reserved4)(void);
-};
-
-/** Structure representing an account.
+/**
+ * Structure representing an account.
*/
struct _PurpleAccount
{
- char *username; /**< The username. */
- char *alias; /**< How you appear to yourself. */
- char *password; /**< The account password. */
- char *user_info; /**< User information. */
-
- char *buddy_icon_path; /**< The buddy icon's non-cached path. */
-
- gboolean remember_pass; /**< Remember the password. */
-
- char *protocol_id; /**< The ID of the protocol. */
+ /*< private >*/
+ GObject gparent;
- PurpleConnection *gc; /**< The connection handle. */
- gboolean disconnecting; /**< The account is currently disconnecting */
-
- GHashTable *settings; /**< Protocol-specific settings. */
- GHashTable *ui_settings; /**< UI-specific settings. */
-
- PurpleProxyInfo *proxy_info; /**< Proxy information. This will be set */
- /* to NULL when the account inherits */
- /* proxy settings from global prefs. */
-
- /*
- * TODO: Supplementing the next two linked lists with hash tables
- * should help performance a lot when these lists are long. This
- * matters quite a bit for protocols like MSN, where all your
- * buddies are added to your permit list. Currently we have to
- * iterate through the entire list if we want to check if someone
- * is permitted or denied. We should do this for 3.0.0.
- * Or maybe use a GTree.
+ /** The UI data associated with this account. This is a convenience
+ * field provided to the UIs -- it is not used by the libpurple core.
*/
- GSList *permit; /**< Permit list. */
- GSList *deny; /**< Deny list. */
- PurplePrivacyType perm_deny; /**< The permit/deny setting. */
-
- GList *status_types; /**< Status types. */
-
- PurplePresence *presence; /**< Presence. */
- PurpleLog *system_log; /**< The system log */
+ gpointer ui_data;
+};
- void *ui_data; /**< The UI can put data here. */
- PurpleAccountRegistrationCb registration_cb;
- void *registration_cb_user_data;
+/**
+ * PurpleAccountClass:
+ *
+ * The base class for all #PurpleAccount's.
+ */
+struct _PurpleAccountClass {
+ /*< private >*/
+ GObjectClass parent_class;
- PurpleConnectionErrorInfo *current_error; /**< Errors */
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
};
G_BEGIN_DECLS
@@ -181,6 +126,11 @@ G_BEGIN_DECLS
/*@{*/
/**
+ * Returns the GType for the Account object.
+ */
+GType purple_account_get_type(void);
+
+/**
* Creates a new account.
*
* @param username The username.
@@ -191,13 +141,6 @@ G_BEGIN_DECLS
PurpleAccount *purple_account_new(const char *username, const char *protocol_id);
/**
- * Destroys an account.
- *
- * @param account The account to destroy.
- */
-void purple_account_destroy(PurpleAccount *account);
-
-/**
* Connects to an account.
*
* @param account The account to connect to.
@@ -379,12 +322,12 @@ void purple_account_set_password(PurpleAccount *account, const gchar *password,
PurpleKeyringSaveCallback cb, gpointer data);
/**
- * Sets the account's alias.
+ * Sets the account's private alias.
*
* @param account The account.
* @param alias The alias.
*/
-void purple_account_set_alias(PurpleAccount *account, const char *alias);
+void purple_account_set_private_alias(PurpleAccount *account, const char *alias);
/**
* Sets the account's user information
@@ -460,7 +403,7 @@ void purple_account_set_proxy_info(PurpleAccount *account, PurpleProxyInfo *info
* @param account The account.
* @param privacy_type The privacy type.
*/
-void purple_account_set_privacy_type(PurpleAccount *account, PurplePrivacyType privacy_type);
+void purple_account_set_privacy_type(PurpleAccount *account, PurpleAccountPrivacyType privacy_type);
/**
* Sets the account's status types.
@@ -629,23 +572,23 @@ void purple_account_set_ui_bool(PurpleAccount *account, const char *ui,
const char *name, gboolean value);
/**
- * Returns the UI data associated with this account.
+ * Set 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.
+ * @param ui_data A pointer to associate with this object.
*/
-gpointer purple_account_get_ui_data(const PurpleAccount *account);
+void purple_account_set_ui_data(PurpleAccount *account, gpointer ui_data);
/**
- * Set the UI data associated with this account.
+ * Returns the UI data associated with this account.
*
* @param account The account.
- * @param ui_data A pointer to associate with this object.
+ *
+ * @return The UI data associated with this account. This is a
+ * convenience field provided to the UIs--it is not
+ * used by the libuprple core.
*/
-void purple_account_set_ui_data(PurpleAccount *account, gpointer ui_data);
+gpointer purple_account_get_ui_data(const PurpleAccount *account);
/**
* Returns whether or not the account is connected.
@@ -699,13 +642,13 @@ void purple_account_get_password(PurpleAccount *account,
PurpleKeyringReadCallback cb, gpointer data);
/**
- * Returns the account's alias.
+ * Returns the account's private alias.
*
* @param account The account.
*
* @return The alias.
*/
-const char *purple_account_get_alias(const PurpleAccount *account);
+const char *purple_account_get_private_alias(const PurpleAccount *account);
/**
* Returns the account's user information.
@@ -810,7 +753,135 @@ PurpleProxyInfo *purple_account_get_proxy_info(const PurpleAccount *account);
*
* @return The privacy type.
*/
-PurplePrivacyType purple_account_get_privacy_type(const PurpleAccount *account);
+PurpleAccountPrivacyType purple_account_get_privacy_type(const PurpleAccount *account);
+
+/**
+ * Adds a user to the account's permit list.
+ *
+ * @param account The account.
+ * @param name The name of the user to add to the list.
+ * @param local_only If TRUE, only the local list is updated, and not
+ * the server.
+ *
+ * @return TRUE if the user was added successfully, or @c FALSE otherwise.
+ */
+gboolean purple_account_privacy_permit_add(PurpleAccount *account,
+ const char *name, gboolean local_only);
+
+/**
+ * Removes a user from the account's permit list.
+ *
+ * @param account The account.
+ * @param name The name of the user to add to the list.
+ * @param local_only If TRUE, only the local list is updated, and not
+ * the server.
+ *
+ * @return TRUE if the user was removed successfully, or @c FALSE otherwise.
+ */
+gboolean purple_account_privacy_permit_remove(PurpleAccount *account,
+ const char *name, gboolean local_only);
+
+/**
+ * Adds a user to the account's deny list.
+ *
+ * @param account The account.
+ * @param name The name of the user to add to the list.
+ * @param local_only If TRUE, only the local list is updated, and not
+ * the server.
+ *
+ * @return TRUE if the user was added successfully, or @c FALSE otherwise.
+ */
+gboolean purple_account_privacy_deny_add(PurpleAccount *account,
+ const char *name, gboolean local_only);
+
+/**
+ * Removes a user from the account's deny list.
+ *
+ * @param account The account.
+ * @param name The name of the user to add to the list.
+ * @param local_only If TRUE, only the local list is updated, and not
+ * the server.
+ *
+ * @return TRUE if the user was removed successfully, or @c FALSE otherwise.
+ */
+gboolean purple_account_privacy_deny_remove(PurpleAccount *account,
+ const char *name, gboolean local_only);
+
+/**
+ * Allow a user to send messages. If current privacy setting for the account is:
+ * PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS: The user is added to the allow-list.
+ * PURPLE_ACCOUNT_PRIVACY_DENY_USERS : The user is removed from the
+ * deny-list.
+ * PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL : No changes made.
+ * PURPLE_ACCOUNT_PRIVACY_DENY_ALL : The privacy setting is changed to
+ * PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS and the
+ * user is added to the allow-list.
+ * PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST: No changes made if the user is
+ * already in the buddy-list. Otherwise the
+ * setting is changed to
+ * PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS, all the buddies are added to the
+ * allow-list, and the user is also added to
+ * the allow-list.
+ *
+ * The changes are reflected on the server. The previous allow/deny list is not
+ * restored if the privacy setting is changed.
+ *
+ * @param account The account.
+ * @param who The name of the user.
+ */
+void purple_account_privacy_allow(PurpleAccount *account, const char *who);
+
+/**
+ * Block messages from a user. If current privacy setting for the account is:
+ * PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS: The user is removed from the
+ * allow-list.
+ * PURPLE_ACCOUNT_PRIVACY_DENY_USERS: The user is added to the deny-list.
+ * PURPLE_ACCOUNT_PRIVACY_DENY_ALL: No changes made.
+ * PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL: The privacy setting is changed to
+ * PURPLE_ACCOUNT_PRIVACY_DENY_USERS and the
+ * user is added to the deny-list.
+ * PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST: If the user is not in the
+ * buddy-list, then no changes made. Otherwise,
+ * the setting is changed to
+ * PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS, all
+ * the buddies are added to the allow-list, and
+ * this user is removed from the list.
+ *
+ * The changes are reflected on the server. The previous allow/deny list is not
+ * restored if the privacy setting is changed.
+ *
+ * @param account The account.
+ * @param who The name of the user.
+ */
+void purple_account_privacy_deny(PurpleAccount *account, const char *who);
+
+/**
+ * Returns the account's permit list.
+ *
+ * @param account The account.
+ * @constreturn A list of the permitted users
+ */
+GSList *purple_account_privacy_get_permitted(PurpleAccount *account);
+
+/**
+ * Returns the account's deny list.
+ *
+ * @param account The account.
+ * @constreturn A list of the denied users
+ */
+GSList *purple_account_privacy_get_denied(PurpleAccount *account);
+
+/**
+ * Check the privacy-setting for a user.
+ *
+ * @param account The account.
+ * @param who The name of the user.
+ *
+ * @return @c FALSE if the specified account's privacy settings block the user
+ * or @c TRUE otherwise. The meaning of "block" is protocol-dependent and
+ * generally relates to status and/or sending of messages.
+ */
+gboolean purple_account_privacy_check(PurpleAccount *account, const char *who);
/**
* Returns the active status for this account. This looks through
@@ -1080,128 +1151,13 @@ const PurpleConnectionErrorInfo *purple_account_get_current_error(PurpleAccount
*/
void purple_account_clear_current_error(PurpleAccount *account);
-/*@}*/
-
-/**************************************************************************/
-/** @name Accounts API */
-/**************************************************************************/
-/*@{*/
-
-/**
- * Adds an account to the list of accounts.
- *
- * @param account The account.
- */
-void purple_accounts_add(PurpleAccount *account);
-
-/**
- * Removes an account from the list of accounts.
- *
- * @param account The account.
- */
-void purple_accounts_remove(PurpleAccount *account);
-
-/**
- * Deletes an account.
- *
- * This will remove any buddies from the buddy list that belong to this
- * account, buddy pounces that belong to this account, and will also
- * destroy @a account.
- *
- * @param account The account.
- */
-void purple_accounts_delete(PurpleAccount *account);
-
-/**
- * Reorders an account.
- *
- * @param account The account to reorder.
- * @param new_index The new index for the account.
- */
-void purple_accounts_reorder(PurpleAccount *account, guint new_index);
-
-/**
- * Returns a list of all accounts.
- *
- * @constreturn A list of all accounts.
- */
-GList *purple_accounts_get_all(void);
-
-/**
- * Returns a list of all enabled accounts
- *
- * @return A list of all enabled accounts. The list is owned
- * by the caller, and must be g_list_free()d to avoid
- * leaking the nodes.
- */
-GList *purple_accounts_get_all_active(void);
-
/**
- * Finds an account with the specified name and protocol id.
- *
- * @param name The account username.
- * @param protocol The account protocol ID.
+ * Get an XML description of an account.
*
- * @return The account, if found, or @c FALSE otherwise.
- */
-PurpleAccount *purple_accounts_find(const char *name, const char *protocol);
-
-/**
- * This is called by the core after all subsystems and what
- * not have been initialized. It sets all enabled accounts
- * to their startup status by signing them on, setting them
- * away, etc.
- *
- * You probably shouldn't call this unless you really know
- * what you're doing.
- */
-void purple_accounts_restore_current_statuses(void);
-
-/*@}*/
-
-
-/**************************************************************************/
-/** @name UI Registration Functions */
-/**************************************************************************/
-/*@{*/
-/**
- * Sets the UI operations structure to be used for accounts.
- *
- * @param ops The UI operations structure.
- */
-void purple_accounts_set_ui_ops(PurpleAccountUiOps *ops);
-
-/**
- * Returns the UI operations structure used for accounts.
- *
- * @return The UI operations structure in use.
- */
-PurpleAccountUiOps *purple_accounts_get_ui_ops(void);
-
-/*@}*/
-
-
-/**************************************************************************/
-/** @name Accounts Subsystem */
-/**************************************************************************/
-/*@{*/
-
-/**
- * Returns the accounts subsystem handle.
- *
- * @return The accounts subsystem handle.
- */
-void *purple_accounts_get_handle(void);
-
-/**
- * Initializes the accounts subsystem.
- */
-void purple_accounts_init(void);
-
-/**
- * Uninitializes the accounts subsystem.
+ * @param account The account
+ * @return The XML description of the account.
*/
-void purple_accounts_uninit(void);
+xmlnode *purple_account_to_xmlnode(PurpleAccount *account);
/*@}*/
diff --git a/libpurple/accounts.c b/libpurple/accounts.c
new file mode 100644
index 0000000000..a8a852f7c7
--- /dev/null
+++ b/libpurple/accounts.c
@@ -0,0 +1,1022 @@
+/**
+ * @file accounts.c Accounts API
+ * @ingroup core
+ */
+
+/* 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
+ */
+#include "internal.h"
+#include "accounts.h"
+#include "core.h"
+#include "dbus-maybe.h"
+#include "debug.h"
+#include "enums.h"
+#include "network.h"
+#include "pounce.h"
+
+static PurpleAccountUiOps *account_ui_ops = NULL;
+
+static GList *accounts = NULL;
+static guint save_timer = 0;
+static gboolean accounts_loaded = FALSE;
+
+void _purple_account_set_current_error(PurpleAccount *account,
+ PurpleConnectionErrorInfo *new_err);
+
+/*********************************************************************
+ * Writing to disk *
+ *********************************************************************/
+static xmlnode *
+accounts_to_xmlnode(void)
+{
+ xmlnode *node, *child;
+ GList *cur;
+
+ node = xmlnode_new("account");
+ xmlnode_set_attrib(node, "version", "1.0");
+
+ for (cur = purple_accounts_get_all(); cur != NULL; cur = cur->next)
+ {
+ child = purple_account_to_xmlnode(cur->data);
+ xmlnode_insert_child(node, child);
+ }
+
+ return node;
+}
+
+static void
+sync_accounts(void)
+{
+ xmlnode *node;
+ char *data;
+
+ if (!accounts_loaded)
+ {
+ purple_debug_error("account", "Attempted to save accounts before "
+ "they were read!\n");
+ return;
+ }
+
+ node = accounts_to_xmlnode();
+ data = xmlnode_to_formatted_str(node, NULL);
+ purple_util_write_data_to_file("accounts.xml", data, -1);
+ g_free(data);
+ xmlnode_free(node);
+}
+
+static gboolean
+save_cb(gpointer data)
+{
+ sync_accounts();
+ save_timer = 0;
+ return FALSE;
+}
+
+void
+purple_accounts_schedule_save(void)
+{
+ if (save_timer == 0)
+ save_timer = purple_timeout_add_seconds(5, save_cb, NULL);
+}
+
+/*********************************************************************
+ * Reading from disk *
+ *********************************************************************/
+static void
+migrate_yahoo_japan(PurpleAccount *account)
+{
+ /* detect a Yahoo! JAPAN account that existed prior to 2.6.0 and convert it
+ * to use the new prpl-yahoojp. Also remove the account-specific settings
+ * we no longer need */
+
+ if(purple_strequal(purple_account_get_protocol_id(account), "prpl-yahoo")) {
+ if(purple_account_get_bool(account, "yahoojp", FALSE)) {
+ const char *serverjp = purple_account_get_string(account, "serverjp", NULL);
+ const char *xferjp_host = purple_account_get_string(account, "xferjp_host", NULL);
+
+ g_return_if_fail(serverjp != NULL);
+ g_return_if_fail(xferjp_host != NULL);
+
+ purple_account_set_string(account, "server", serverjp);
+ purple_account_set_string(account, "xfer_host", xferjp_host);
+
+ purple_account_set_protocol_id(account, "prpl-yahoojp");
+ }
+
+ /* these should always be nuked */
+ purple_account_remove_setting(account, "yahoojp");
+ purple_account_remove_setting(account, "serverjp");
+ purple_account_remove_setting(account, "xferjp_host");
+
+ }
+}
+
+static void
+migrate_icq_server(PurpleAccount *account)
+{
+ /* Migrate the login server setting for ICQ accounts. See
+ * 'mtn log --last 1 --no-graph --from b6d7712e90b68610df3bd2d8cbaf46d94c8b3794'
+ * for details on the change. */
+
+ if(purple_strequal(purple_account_get_protocol_id(account), "prpl-icq")) {
+ const char *tmp = purple_account_get_string(account, "server", NULL);
+
+ /* Non-secure server */
+ if(purple_strequal(tmp, "login.messaging.aol.com") ||
+ purple_strequal(tmp, "login.oscar.aol.com"))
+ purple_account_set_string(account, "server", "login.icq.com");
+
+ /* Secure server */
+ if(purple_strequal(tmp, "slogin.oscar.aol.com"))
+ purple_account_set_string(account, "server", "slogin.icq.com");
+ }
+}
+
+static void
+migrate_xmpp_encryption(PurpleAccount *account)
+{
+ /* When this is removed, nuke the "old_ssl" and "require_tls" settings */
+ if (g_str_equal(purple_account_get_protocol_id(account), "prpl-jabber")) {
+ const char *sec = purple_account_get_string(account, "connection_security", "");
+
+ if (g_str_equal("", sec)) {
+ const char *val = "require_tls";
+ if (purple_account_get_bool(account, "old_ssl", FALSE))
+ val = "old_ssl";
+ else if (!purple_account_get_bool(account, "require_tls", TRUE))
+ val = "opportunistic_tls";
+
+ purple_account_set_string(account, "connection_security", val);
+ }
+ }
+}
+
+static void
+parse_settings(xmlnode *node, PurpleAccount *account)
+{
+ const char *ui;
+ xmlnode *child;
+
+ /* Get the UI string, if these are UI settings */
+ ui = xmlnode_get_attrib(node, "ui");
+
+ /* Read settings, one by one */
+ for (child = xmlnode_get_child(node, "setting"); child != NULL;
+ child = xmlnode_get_next_twin(child))
+ {
+ const char *name, *str_type;
+ PurplePrefType type;
+ char *data;
+
+ name = xmlnode_get_attrib(child, "name");
+ if (name == NULL)
+ /* Ignore this setting */
+ continue;
+
+ str_type = xmlnode_get_attrib(child, "type");
+ if (str_type == NULL)
+ /* Ignore this setting */
+ continue;
+
+ if (purple_strequal(str_type, "string"))
+ type = PURPLE_PREF_STRING;
+ else if (purple_strequal(str_type, "int"))
+ type = PURPLE_PREF_INT;
+ else if (purple_strequal(str_type, "bool"))
+ type = PURPLE_PREF_BOOLEAN;
+ else
+ /* Ignore this setting */
+ continue;
+
+ data = xmlnode_get_data(child);
+ if (data == NULL)
+ /* Ignore this setting */
+ continue;
+
+ if (ui == NULL)
+ {
+ if (type == PURPLE_PREF_STRING)
+ purple_account_set_string(account, name, data);
+ else if (type == PURPLE_PREF_INT)
+ purple_account_set_int(account, name, atoi(data));
+ else if (type == PURPLE_PREF_BOOLEAN)
+ purple_account_set_bool(account, name,
+ (*data == '0' ? FALSE : TRUE));
+ } else {
+ if (type == PURPLE_PREF_STRING)
+ purple_account_set_ui_string(account, ui, name, data);
+ else if (type == PURPLE_PREF_INT)
+ purple_account_set_ui_int(account, ui, name, atoi(data));
+ else if (type == PURPLE_PREF_BOOLEAN)
+ purple_account_set_ui_bool(account, ui, name,
+ (*data == '0' ? FALSE : TRUE));
+ }
+
+ g_free(data);
+ }
+
+ /* we do this here because we need access to account settings to determine
+ * if we can/should migrate an old Yahoo! JAPAN account */
+ migrate_yahoo_japan(account);
+ /* we do this here because we need access to account settings to determine
+ * if we can/should migrate an ICQ account's server setting */
+ migrate_icq_server(account);
+ /* we do this here because we need to do it before the user views the
+ * Edit Account dialog. */
+ migrate_xmpp_encryption(account);
+}
+
+static GList *
+parse_status_attrs(xmlnode *node, PurpleStatus *status)
+{
+ GList *list = NULL;
+ xmlnode *child;
+ GValue *attr_value;
+
+ for (child = xmlnode_get_child(node, "attribute"); child != NULL;
+ child = xmlnode_get_next_twin(child))
+ {
+ const char *id = xmlnode_get_attrib(child, "id");
+ const char *value = xmlnode_get_attrib(child, "value");
+
+ if (!id || !*id || !value || !*value)
+ continue;
+
+ attr_value = purple_status_get_attr_value(status, id);
+ if (!attr_value)
+ continue;
+
+ list = g_list_append(list, (char *)id);
+
+ switch (G_VALUE_TYPE(attr_value))
+ {
+ case G_TYPE_STRING:
+ list = g_list_append(list, (char *)value);
+ break;
+ case G_TYPE_INT:
+ case G_TYPE_BOOLEAN:
+ {
+ int v;
+ if (sscanf(value, "%d", &v) == 1)
+ list = g_list_append(list, GINT_TO_POINTER(v));
+ else
+ list = g_list_remove(list, id);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ return list;
+}
+
+static void
+parse_status(xmlnode *node, PurpleAccount *account)
+{
+ gboolean active = FALSE;
+ const char *data;
+ const char *type;
+ xmlnode *child;
+ GList *attrs = NULL;
+
+ /* Get the active/inactive state */
+ data = xmlnode_get_attrib(node, "active");
+ if (data == NULL)
+ return;
+ if (g_ascii_strcasecmp(data, "true") == 0)
+ active = TRUE;
+ else if (g_ascii_strcasecmp(data, "false") == 0)
+ active = FALSE;
+ else
+ return;
+
+ /* Get the type of the status */
+ type = xmlnode_get_attrib(node, "type");
+ if (type == NULL)
+ return;
+
+ /* Read attributes into a GList */
+ child = xmlnode_get_child(node, "attributes");
+ if (child != NULL)
+ {
+ attrs = parse_status_attrs(child,
+ purple_account_get_status(account, type));
+ }
+
+ purple_account_set_status_list(account, type, active, attrs);
+
+ g_list_free(attrs);
+}
+
+static void
+parse_statuses(xmlnode *node, PurpleAccount *account)
+{
+ xmlnode *child;
+
+ for (child = xmlnode_get_child(node, "status"); child != NULL;
+ child = xmlnode_get_next_twin(child))
+ {
+ parse_status(child, account);
+ }
+}
+
+static void
+parse_proxy_info(xmlnode *node, PurpleAccount *account)
+{
+ PurpleProxyInfo *proxy_info;
+ xmlnode *child;
+ char *data;
+
+ proxy_info = purple_proxy_info_new();
+
+ /* Use the global proxy settings, by default */
+ purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_GLOBAL);
+
+ /* Read proxy type */
+ child = xmlnode_get_child(node, "type");
+ if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+ {
+ if (purple_strequal(data, "global"))
+ purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_GLOBAL);
+ else if (purple_strequal(data, "none"))
+ purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_NONE);
+ else if (purple_strequal(data, "http"))
+ purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_HTTP);
+ else if (purple_strequal(data, "socks4"))
+ purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_SOCKS4);
+ else if (purple_strequal(data, "socks5"))
+ purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_SOCKS5);
+ else if (purple_strequal(data, "tor"))
+ purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_TOR);
+ else if (purple_strequal(data, "envvar"))
+ purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_ENVVAR);
+ else
+ {
+ purple_debug_error("account", "Invalid proxy type found when "
+ "loading account information for %s\n",
+ purple_account_get_username(account));
+ }
+ g_free(data);
+ }
+
+ /* Read proxy host */
+ child = xmlnode_get_child(node, "host");
+ if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+ {
+ purple_proxy_info_set_host(proxy_info, data);
+ g_free(data);
+ }
+
+ /* Read proxy port */
+ child = xmlnode_get_child(node, "port");
+ if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+ {
+ purple_proxy_info_set_port(proxy_info, atoi(data));
+ g_free(data);
+ }
+
+ /* Read proxy username */
+ child = xmlnode_get_child(node, "username");
+ if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+ {
+ purple_proxy_info_set_username(proxy_info, data);
+ g_free(data);
+ }
+
+ /* Read proxy password */
+ child = xmlnode_get_child(node, "password");
+ if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+ {
+ purple_proxy_info_set_password(proxy_info, data);
+ g_free(data);
+ }
+
+ /* If there are no values set then proxy_info NULL */
+ if ((purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_GLOBAL) &&
+ (purple_proxy_info_get_host(proxy_info) == NULL) &&
+ (purple_proxy_info_get_port(proxy_info) == 0) &&
+ (purple_proxy_info_get_username(proxy_info) == NULL) &&
+ (purple_proxy_info_get_password(proxy_info) == NULL))
+ {
+ purple_proxy_info_destroy(proxy_info);
+ return;
+ }
+
+ purple_account_set_proxy_info(account, proxy_info);
+}
+
+static void
+parse_current_error(xmlnode *node, PurpleAccount *account)
+{
+ guint type;
+ char *type_str = NULL, *description = NULL;
+ xmlnode *child;
+ PurpleConnectionErrorInfo *current_error = NULL;
+
+ child = xmlnode_get_child(node, "type");
+ if (child == NULL || (type_str = xmlnode_get_data(child)) == NULL)
+ return;
+ type = atoi(type_str);
+ g_free(type_str);
+
+ if (type > PURPLE_CONNECTION_ERROR_OTHER_ERROR)
+ {
+ purple_debug_error("account",
+ "Invalid PurpleConnectionError value %d found when "
+ "loading account information for %s\n",
+ type, purple_account_get_username(account));
+ type = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
+ }
+
+ child = xmlnode_get_child(node, "description");
+ if (child)
+ description = xmlnode_get_data(child);
+ if (description == NULL)
+ description = g_strdup("");
+
+ current_error = g_new0(PurpleConnectionErrorInfo, 1);
+ PURPLE_DBUS_REGISTER_POINTER(current_error, PurpleConnectionErrorInfo);
+ current_error->type = type;
+ current_error->description = description;
+
+ _purple_account_set_current_error(account, current_error);
+}
+
+static PurpleAccount *
+parse_account(xmlnode *node)
+{
+ PurpleAccount *ret;
+ xmlnode *child;
+ char *protocol_id = NULL;
+ char *name = NULL;
+ char *data;
+
+ child = xmlnode_get_child(node, "protocol");
+ if (child != NULL)
+ protocol_id = xmlnode_get_data(child);
+
+ child = xmlnode_get_child(node, "name");
+ if (child != NULL)
+ name = xmlnode_get_data(child);
+ if (name == NULL)
+ {
+ /* Do we really need to do this? */
+ child = xmlnode_get_child(node, "username");
+ if (child != NULL)
+ name = xmlnode_get_data(child);
+ }
+
+ if ((protocol_id == NULL) || (name == NULL))
+ {
+ g_free(protocol_id);
+ g_free(name);
+ return NULL;
+ }
+
+ ret = purple_account_new(name, protocol_id);
+ g_free(name);
+ g_free(protocol_id);
+
+ /* Read the alias */
+ child = xmlnode_get_child(node, "alias");
+ if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+ {
+ if (*data != '\0')
+ purple_account_set_private_alias(ret, data);
+ g_free(data);
+ }
+
+ /* Read the statuses */
+ child = xmlnode_get_child(node, "statuses");
+ if (child != NULL)
+ {
+ parse_statuses(child, ret);
+ }
+
+ /* Read the userinfo */
+ child = xmlnode_get_child(node, "userinfo");
+ if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+ {
+ purple_account_set_user_info(ret, data);
+ g_free(data);
+ }
+
+ /* Read an old buddyicon */
+ child = xmlnode_get_child(node, "buddyicon");
+ if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+ {
+ const char *dirname = purple_buddy_icons_get_cache_dir();
+ char *filename = g_build_filename(dirname, data, NULL);
+ gchar *contents;
+ gsize len;
+
+ 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);
+ }
+
+ /* Read settings (both core and UI) */
+ for (child = xmlnode_get_child(node, "settings"); child != NULL;
+ child = xmlnode_get_next_twin(child))
+ {
+ parse_settings(child, ret);
+ }
+
+ /* Read proxy */
+ child = xmlnode_get_child(node, "proxy");
+ if (child != NULL)
+ {
+ parse_proxy_info(child, ret);
+ }
+
+ /* Read current error */
+ child = xmlnode_get_child(node, "current_error");
+ if (child != NULL)
+ {
+ parse_current_error(child, ret);
+ }
+
+ /* Read the password */
+ child = xmlnode_get_child(node, "password");
+ if (child != NULL)
+ {
+ const char *keyring_id = xmlnode_get_attrib(child, "keyring_id");
+ const char *mode = xmlnode_get_attrib(child, "mode");
+ gboolean result;
+
+ data = xmlnode_get_data(child);
+ result = purple_keyring_import_password(ret, keyring_id, mode, data, NULL);
+
+ if (result == TRUE || purple_keyring_get_inuse() == NULL) {
+ purple_account_set_remember_password(ret, TRUE);
+ } else {
+ purple_debug_error("account", "Failed to import password.\n");
+ }
+ purple_str_wipe(data);
+ }
+
+ return ret;
+}
+
+static void
+load_accounts(void)
+{
+ xmlnode *node, *child;
+
+ accounts_loaded = TRUE;
+
+ node = purple_util_read_xml_from_file("accounts.xml", _("accounts"));
+
+ if (node == NULL)
+ return;
+
+ for (child = xmlnode_get_child(node, "account"); child != NULL;
+ child = xmlnode_get_next_twin(child))
+ {
+ PurpleAccount *new_acct;
+ new_acct = parse_account(child);
+ purple_accounts_add(new_acct);
+ }
+
+ xmlnode_free(node);
+
+ _purple_buddy_icons_account_loaded_cb();
+}
+
+void
+purple_accounts_add(PurpleAccount *account)
+{
+ g_return_if_fail(account != NULL);
+
+ if (g_list_find(accounts, account) != NULL)
+ return;
+
+ accounts = g_list_append(accounts, account);
+
+ purple_accounts_schedule_save();
+
+ purple_signal_emit(purple_accounts_get_handle(), "account-added", account);
+}
+
+void
+purple_accounts_remove(PurpleAccount *account)
+{
+ g_return_if_fail(account != NULL);
+
+ accounts = g_list_remove(accounts, account);
+
+ purple_accounts_schedule_save();
+
+ /* Clearing the error ensures that account-error-changed is emitted,
+ * which is the end of the guarantee that the the error's pointer is
+ * valid.
+ */
+ purple_account_clear_current_error(account);
+ purple_signal_emit(purple_accounts_get_handle(), "account-removed", account);
+}
+
+static void
+purple_accounts_delete_set(PurpleAccount *account, GError *error, gpointer data)
+{
+ g_object_unref(G_OBJECT(account));
+}
+
+void
+purple_accounts_delete(PurpleAccount *account)
+{
+ PurpleBlistNode *gnode, *cnode, *bnode;
+ GList *iter;
+
+ g_return_if_fail(account != NULL);
+
+ /*
+ * Disable the account before blowing it out of the water.
+ * Conceptually it probably makes more sense to disable the
+ * account for all UIs rather than the just the current UI,
+ * but it doesn't really matter.
+ */
+ purple_account_set_enabled(account, purple_core_get_ui(), FALSE);
+
+ purple_notify_close_with_handle(account);
+ purple_request_close_with_handle(account);
+
+ purple_accounts_remove(account);
+
+ /* Remove this account's buddies */
+ for (gnode = purple_blist_get_root();
+ gnode != NULL;
+ gnode = purple_blist_node_get_sibling_next(gnode))
+ {
+ if (!PURPLE_IS_GROUP(gnode))
+ continue;
+
+ cnode = purple_blist_node_get_first_child(gnode);
+ while (cnode) {
+ PurpleBlistNode *cnode_next = purple_blist_node_get_sibling_next(cnode);
+
+ if(PURPLE_IS_CONTACT(cnode)) {
+ bnode = purple_blist_node_get_first_child(cnode);
+ while (bnode) {
+ PurpleBlistNode *bnode_next = purple_blist_node_get_sibling_next(bnode);
+
+ if (PURPLE_IS_BUDDY(bnode)) {
+ PurpleBuddy *b = (PurpleBuddy *)bnode;
+
+ if (purple_buddy_get_account(b) == account)
+ purple_blist_remove_buddy(b);
+ }
+ bnode = bnode_next;
+ }
+ } else if (PURPLE_IS_CHAT(cnode)) {
+ PurpleChat *c = (PurpleChat *)cnode;
+
+ if (purple_chat_get_account(c) == account)
+ purple_blist_remove_chat(c);
+ }
+ cnode = cnode_next;
+ }
+ }
+
+ /* Remove any open conversation for this account */
+ for (iter = purple_conversations_get_all(); iter; ) {
+ PurpleConversation *conv = iter->data;
+ iter = iter->next;
+ if (purple_conversation_get_account(conv) == account)
+ g_object_unref(conv);
+ }
+
+ /* Remove this account's pounces */
+ purple_pounce_destroy_all_by_account(account);
+
+ /* This will cause the deletion of an old buddy icon. */
+ purple_buddy_icons_set_account_icon(account, NULL, 0);
+
+ /* This is async because we do not want the
+ * account being overwritten before we are done.
+ */
+ purple_keyring_set_password(account, NULL,
+ purple_accounts_delete_set, NULL);
+}
+
+void
+purple_accounts_reorder(PurpleAccount *account, guint new_index)
+{
+ gint index;
+ GList *l;
+
+ g_return_if_fail(account != NULL);
+ g_return_if_fail(new_index <= g_list_length(accounts));
+
+ index = g_list_index(accounts, account);
+
+ if (index < 0) {
+ purple_debug_error("account",
+ "Unregistered account (%s) discovered during reorder!\n",
+ purple_account_get_username(account));
+ return;
+ }
+
+ l = g_list_nth(accounts, index);
+
+ if (new_index > (guint)index)
+ new_index--;
+
+ /* Remove the old one. */
+ accounts = g_list_delete_link(accounts, l);
+
+ /* Insert it where it should go. */
+ accounts = g_list_insert(accounts, account, new_index);
+
+ purple_accounts_schedule_save();
+}
+
+GList *
+purple_accounts_get_all(void)
+{
+ return accounts;
+}
+
+GList *
+purple_accounts_get_all_active(void)
+{
+ GList *list = NULL;
+ GList *all = purple_accounts_get_all();
+
+ while (all != NULL) {
+ PurpleAccount *account = all->data;
+
+ if (purple_account_get_enabled(account, purple_core_get_ui()))
+ list = g_list_append(list, account);
+
+ all = all->next;
+ }
+
+ return list;
+}
+
+PurpleAccount *
+purple_accounts_find(const char *name, const char *protocol_id)
+{
+ PurpleAccount *account = NULL;
+ GList *l;
+ char *who;
+
+ g_return_val_if_fail(name != NULL, NULL);
+ g_return_val_if_fail(protocol_id != NULL, NULL);
+
+ for (l = purple_accounts_get_all(); l != NULL; l = l->next) {
+ account = (PurpleAccount *)l->data;
+
+ if (!purple_strequal(purple_account_get_protocol_id(account), protocol_id))
+ continue;
+
+ who = g_strdup(purple_normalize(account, name));
+ if (purple_strequal(purple_normalize(account, purple_account_get_username(account)), who)) {
+ g_free(who);
+ return account;
+ }
+ g_free(who);
+ }
+
+ return NULL;
+}
+
+void
+purple_accounts_restore_current_statuses()
+{
+ GList *l;
+ PurpleAccount *account;
+
+ /* If we're not connected to the Internet right now, we bail on this */
+ if (!purple_network_is_available())
+ {
+ purple_debug_warning("account", "Network not connected; skipping reconnect\n");
+ return;
+ }
+
+ for (l = purple_accounts_get_all(); l != NULL; l = l->next)
+ {
+ account = (PurpleAccount *)l->data;
+
+ if (purple_account_get_enabled(account, purple_core_get_ui()) &&
+ (purple_presence_is_online(purple_account_get_presence(account))))
+ {
+ purple_account_connect(account);
+ }
+ }
+}
+
+void
+purple_accounts_set_ui_ops(PurpleAccountUiOps *ops)
+{
+ account_ui_ops = ops;
+}
+
+PurpleAccountUiOps *
+purple_accounts_get_ui_ops(void)
+{
+ return account_ui_ops;
+}
+
+void *
+purple_accounts_get_handle(void)
+{
+ static int handle;
+
+ return &handle;
+}
+
+static void
+signed_on_cb(PurpleConnection *gc,
+ gpointer unused)
+{
+ PurpleAccount *account = purple_connection_get_account(gc);
+ purple_account_clear_current_error(account);
+
+ purple_signal_emit(purple_accounts_get_handle(), "account-signed-on",
+ account);
+}
+
+static void
+signed_off_cb(PurpleConnection *gc,
+ gpointer unused)
+{
+ PurpleAccount *account = purple_connection_get_account(gc);
+
+ purple_signal_emit(purple_accounts_get_handle(), "account-signed-off",
+ account);
+}
+
+static void
+connection_error_cb(PurpleConnection *gc,
+ PurpleConnectionError type,
+ const gchar *description,
+ gpointer unused)
+{
+ PurpleAccount *account;
+ PurpleConnectionErrorInfo *err;
+
+ account = purple_connection_get_account(gc);
+
+ g_return_if_fail(account != NULL);
+
+ err = g_new0(PurpleConnectionErrorInfo, 1);
+ PURPLE_DBUS_REGISTER_POINTER(err, PurpleConnectionErrorInfo);
+
+ err->type = type;
+ err->description = g_strdup(description);
+
+ _purple_account_set_current_error(account, err);
+
+ purple_signal_emit(purple_accounts_get_handle(), "account-connection-error",
+ account, type, description);
+}
+
+static void
+password_migration_cb(PurpleAccount *account)
+{
+ /* account may be NULL (means: all) */
+
+ purple_accounts_schedule_save();
+}
+
+void
+purple_accounts_init(void)
+{
+ void *handle = purple_accounts_get_handle();
+ void *conn_handle = purple_connections_get_handle();
+
+ purple_signal_register(handle, "account-connecting",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_ACCOUNT);
+
+ purple_signal_register(handle, "account-disabled",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_ACCOUNT);
+
+ purple_signal_register(handle, "account-enabled",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_ACCOUNT);
+
+ purple_signal_register(handle, "account-setting-info",
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ PURPLE_TYPE_ACCOUNT, G_TYPE_STRING);
+
+ purple_signal_register(handle, "account-set-info",
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ PURPLE_TYPE_ACCOUNT, G_TYPE_STRING);
+
+ purple_signal_register(handle, "account-created",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_ACCOUNT);
+
+ purple_signal_register(handle, "account-destroying",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_ACCOUNT);
+
+ purple_signal_register(handle, "account-added",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_ACCOUNT);
+
+ purple_signal_register(handle, "account-removed",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_ACCOUNT);
+
+ purple_signal_register(handle, "account-status-changed",
+ purple_marshal_VOID__POINTER_POINTER_POINTER,
+ G_TYPE_NONE, 3, PURPLE_TYPE_ACCOUNT,
+ PURPLE_TYPE_STATUS, PURPLE_TYPE_STATUS);
+
+ purple_signal_register(handle, "account-actions-changed",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_ACCOUNT);
+
+ purple_signal_register(handle, "account-alias-changed",
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ PURPLE_TYPE_ACCOUNT, G_TYPE_STRING);
+
+ purple_signal_register(handle, "account-authorization-requested",
+ purple_marshal_INT__POINTER_POINTER_POINTER,
+ G_TYPE_INT, 4, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING);
+
+ purple_signal_register(handle, "account-authorization-denied",
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 3,
+ PURPLE_TYPE_ACCOUNT, G_TYPE_STRING, G_TYPE_STRING);
+
+ purple_signal_register(handle, "account-authorization-granted",
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 3,
+ PURPLE_TYPE_ACCOUNT, G_TYPE_STRING, G_TYPE_STRING);
+
+ purple_signal_register(handle, "account-error-changed",
+ purple_marshal_VOID__POINTER_POINTER_POINTER,
+ G_TYPE_NONE, 3, PURPLE_TYPE_ACCOUNT,
+ PURPLE_TYPE_CONNECTION_ERROR_INFO,
+ PURPLE_TYPE_CONNECTION_ERROR_INFO);
+
+ purple_signal_register(handle, "account-signed-on",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_ACCOUNT);
+
+ purple_signal_register(handle, "account-signed-off",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_ACCOUNT);
+
+ purple_signal_register(handle, "account-connection-error",
+ purple_marshal_VOID__POINTER_INT_POINTER,
+ G_TYPE_NONE, 3, PURPLE_TYPE_ACCOUNT,
+ PURPLE_TYPE_CONNECTION_ERROR, G_TYPE_STRING);
+
+ purple_signal_connect(conn_handle, "signed-on", handle,
+ PURPLE_CALLBACK(signed_on_cb), NULL);
+ purple_signal_connect(conn_handle, "signed-off", handle,
+ PURPLE_CALLBACK(signed_off_cb), NULL);
+ purple_signal_connect(conn_handle, "connection-error", handle,
+ PURPLE_CALLBACK(connection_error_cb), NULL);
+ purple_signal_connect(purple_keyring_get_handle(), "password-migration", handle,
+ PURPLE_CALLBACK(password_migration_cb), NULL);
+
+ load_accounts();
+
+}
+
+void
+purple_accounts_uninit(void)
+{
+ gpointer handle = purple_accounts_get_handle();
+ if (save_timer != 0)
+ {
+ purple_timeout_remove(save_timer);
+ save_timer = 0;
+ sync_accounts();
+ }
+
+ for (; accounts; accounts = g_list_delete_link(accounts, accounts))
+ g_object_unref(G_OBJECT(accounts->data));
+
+ purple_signals_disconnect_by_handle(handle);
+ purple_signals_unregister_by_instance(handle);
+}
diff --git a/libpurple/accounts.h b/libpurple/accounts.h
new file mode 100644
index 0000000000..82e1ced0a4
--- /dev/null
+++ b/libpurple/accounts.h
@@ -0,0 +1,225 @@
+/**
+ * @file accounts.h Accounts API
+ * @ingroup core
+ * @see @ref account-signals
+ */
+
+/* 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 _PURPLE_ACCOUNTS_H_
+#define _PURPLE_ACCOUNTS_H_
+
+#include "account.h"
+#include "status.h"
+
+/** @copydoc _PurpleAccountUiOps */
+typedef struct _PurpleAccountUiOps PurpleAccountUiOps;
+
+/** Account UI operations, used to notify the user of status changes and when
+ * buddies add this account to their buddy lists.
+ */
+struct _PurpleAccountUiOps
+{
+ /** A buddy who is already on this account's buddy list added this account
+ * to their buddy list.
+ */
+ void (*notify_added)(PurpleAccount *account,
+ const char *remote_user,
+ const char *id,
+ const char *alias,
+ const char *message);
+
+ /** This account's status changed. */
+ void (*status_changed)(PurpleAccount *account,
+ PurpleStatus *status);
+
+ /** Someone we don't have on our list added us; prompt to add them. */
+ void (*request_add)(PurpleAccount *account,
+ const char *remote_user,
+ const char *id,
+ const char *alias,
+ const char *message);
+
+ /** Prompt for authorization when someone adds this account to their buddy
+ * list. To authorize them to see this account's presence, call \a
+ * authorize_cb (\a message, \a user_data); otherwise call
+ * \a deny_cb (\a message, \a user_data);
+ * @return a UI-specific handle, as passed to #close_account_request.
+ */
+ void *(*request_authorize)(PurpleAccount *account,
+ const char *remote_user,
+ const char *id,
+ const char *alias,
+ const char *message,
+ gboolean on_list,
+ PurpleAccountRequestAuthorizationCb authorize_cb,
+ PurpleAccountRequestAuthorizationCb deny_cb,
+ void *user_data);
+
+ /** Close a pending request for authorization. \a ui_handle is a handle
+ * as returned by #request_authorize.
+ */
+ void (*close_account_request)(void *ui_handle);
+
+ void (*permit_added)(PurpleAccount *account, const char *name);
+ void (*permit_removed)(PurpleAccount *account, const char *name);
+ void (*deny_added)(PurpleAccount *account, const char *name);
+ void (*deny_removed)(PurpleAccount *account, const char *name);
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+/**************************************************************************/
+/** @name Accounts API */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Adds an account to the list of accounts.
+ *
+ * @param account The account.
+ */
+void purple_accounts_add(PurpleAccount *account);
+
+/**
+ * Removes an account from the list of accounts.
+ *
+ * @param account The account.
+ */
+void purple_accounts_remove(PurpleAccount *account);
+
+/**
+ * Deletes an account.
+ *
+ * This will remove any buddies from the buddy list that belong to this
+ * account, buddy pounces that belong to this account, and will also
+ * destroy @a account.
+ *
+ * @param account The account.
+ */
+void purple_accounts_delete(PurpleAccount *account);
+
+/**
+ * Reorders an account.
+ *
+ * @param account The account to reorder.
+ * @param new_index The new index for the account.
+ */
+void purple_accounts_reorder(PurpleAccount *account, guint new_index);
+
+/**
+ * Returns a list of all accounts.
+ *
+ * @constreturn A list of all accounts.
+ */
+GList *purple_accounts_get_all(void);
+
+/**
+ * Returns a list of all enabled accounts
+ *
+ * @return A list of all enabled accounts. The list is owned
+ * by the caller, and must be g_list_free()d to avoid
+ * leaking the nodes.
+ */
+GList *purple_accounts_get_all_active(void);
+
+/**
+ * Finds an account with the specified name and protocol id.
+ *
+ * @param name The account username.
+ * @param protocol The account protocol ID.
+ *
+ * @return The account, if found, or @c FALSE otherwise.
+ */
+PurpleAccount *purple_accounts_find(const char *name, const char *protocol);
+
+/**
+ * This is called by the core after all subsystems and what
+ * not have been initialized. It sets all enabled accounts
+ * to their startup status by signing them on, setting them
+ * away, etc.
+ *
+ * You probably shouldn't call this unless you really know
+ * what you're doing.
+ */
+void purple_accounts_restore_current_statuses(void);
+
+/*@}*/
+
+
+/**************************************************************************/
+/** @name UI Registration Functions */
+/**************************************************************************/
+/*@{*/
+/**
+ * Sets the UI operations structure to be used for accounts.
+ *
+ * @param ops The UI operations structure.
+ */
+void purple_accounts_set_ui_ops(PurpleAccountUiOps *ops);
+
+/**
+ * Returns the UI operations structure used for accounts.
+ *
+ * @return The UI operations structure in use.
+ */
+PurpleAccountUiOps *purple_accounts_get_ui_ops(void);
+
+/*@}*/
+
+
+/**************************************************************************/
+/** @name Accounts Subsystem */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the accounts subsystem handle.
+ *
+ * @return The accounts subsystem handle.
+ */
+void *purple_accounts_get_handle(void);
+
+/**
+ * Initializes the accounts subsystem.
+ */
+void purple_accounts_init(void);
+
+/**
+ * Uninitializes the accounts subsystem.
+ */
+void purple_accounts_uninit(void);
+
+/**
+ * Schedules saving of accounts
+ */
+void purple_accounts_schedule_save(void);
+
+/*@}*/
+
+G_END_DECLS
+
+#endif /* _PURPLE_ACCOUNTS_H_ */
diff --git a/libpurple/blist.c b/libpurple/blist.c
deleted file mode 100644
index d44c6c037f..0000000000
--- a/libpurple/blist.c
+++ /dev/null
@@ -1,3251 +0,0 @@
-/*
- * 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
- *
- */
-#define _PURPLE_BLIST_C_
-
-#include "internal.h"
-#include "blist.h"
-#include "conversation.h"
-#include "dbus-maybe.h"
-#include "debug.h"
-#include "notify.h"
-#include "pounce.h"
-#include "prefs.h"
-#include "privacy.h"
-#include "prpl.h"
-#include "server.h"
-#include "signals.h"
-#include "util.h"
-#include "value.h"
-#include "xmlnode.h"
-
-static PurpleBlistUiOps *blist_ui_ops = NULL;
-
-static PurpleBuddyList *purplebuddylist = NULL;
-
-/**
- * A hash table used for efficient lookups of buddies by name.
- * PurpleAccount* => GHashTable*, with the inner hash table being
- * struct _purple_hbuddy => PurpleBuddy*
- */
-static GHashTable *buddies_cache = NULL;
-
-/**
- * A hash table used for efficient lookups of groups by name.
- * UTF-8 collate-key => PurpleGroup*.
- */
-static GHashTable *groups_cache = NULL;
-
-static guint save_timer = 0;
-static gboolean blist_loaded = FALSE;
-
-/*********************************************************************
- * Private utility functions *
- *********************************************************************/
-
-static PurpleBlistNode *purple_blist_get_last_sibling(PurpleBlistNode *node)
-{
- PurpleBlistNode *n = node;
- if (!n)
- return NULL;
- while (n->next)
- n = n->next;
- return n;
-}
-
-static PurpleBlistNode *purple_blist_get_last_child(PurpleBlistNode *node)
-{
- if (!node)
- return NULL;
- return purple_blist_get_last_sibling(node->child);
-}
-
-struct _list_account_buddies {
- GSList *list;
- PurpleAccount *account;
-};
-
-struct _purple_hbuddy {
- char *name;
- PurpleAccount *account;
- PurpleBlistNode *group;
-};
-
-/* This function must not use purple_normalize */
-static guint _purple_blist_hbuddy_hash(struct _purple_hbuddy *hb)
-{
- return g_str_hash(hb->name) ^ g_direct_hash(hb->group) ^ g_direct_hash(hb->account);
-}
-
-/* This function must not use purple_normalize */
-static guint _purple_blist_hbuddy_equal(struct _purple_hbuddy *hb1, struct _purple_hbuddy *hb2)
-{
- return (hb1->group == hb2->group &&
- hb1->account == hb2->account &&
- g_str_equal(hb1->name, hb2->name));
-}
-
-static void _purple_blist_hbuddy_free_key(struct _purple_hbuddy *hb)
-{
- g_free(hb->name);
- g_free(hb);
-}
-
-static void
-purple_blist_buddies_cache_add_account(PurpleAccount *account)
-{
- GHashTable *account_buddies = g_hash_table_new_full((GHashFunc)_purple_blist_hbuddy_hash,
- (GEqualFunc)_purple_blist_hbuddy_equal,
- (GDestroyNotify)_purple_blist_hbuddy_free_key, NULL);
- g_hash_table_insert(buddies_cache, account, account_buddies);
-}
-
-static void
-purple_blist_buddies_cache_remove_account(const PurpleAccount *account)
-{
- g_hash_table_remove(buddies_cache, account);
-}
-
-
-/*********************************************************************
- * Writing to disk *
- *********************************************************************/
-
-static void
-value_to_xmlnode(gpointer key, gpointer hvalue, gpointer user_data)
-{
- const char *name;
- PurpleValue *value;
- xmlnode *node, *child;
- char buf[21];
-
- name = (const char *)key;
- value = (PurpleValue *)hvalue;
- node = (xmlnode *)user_data;
-
- g_return_if_fail(value != NULL);
-
- child = xmlnode_new_child(node, "setting");
- xmlnode_set_attrib(child, "name", name);
-
- if (purple_value_get_type(value) == PURPLE_TYPE_INT) {
- xmlnode_set_attrib(child, "type", "int");
- g_snprintf(buf, sizeof(buf), "%d", purple_value_get_int(value));
- xmlnode_insert_data(child, buf, -1);
- }
- else if (purple_value_get_type(value) == PURPLE_TYPE_STRING) {
- xmlnode_set_attrib(child, "type", "string");
- xmlnode_insert_data(child, purple_value_get_string(value), -1);
- }
- else if (purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN) {
- xmlnode_set_attrib(child, "type", "bool");
- g_snprintf(buf, sizeof(buf), "%d", purple_value_get_boolean(value));
- xmlnode_insert_data(child, buf, -1);
- }
-}
-
-static void
-chat_component_to_xmlnode(gpointer key, gpointer value, gpointer user_data)
-{
- const char *name;
- const char *data;
- xmlnode *node, *child;
-
- name = (const char *)key;
- data = (const char *)value;
- node = (xmlnode *)user_data;
-
- g_return_if_fail(data != NULL);
-
- child = xmlnode_new_child(node, "component");
- xmlnode_set_attrib(child, "name", name);
- xmlnode_insert_data(child, data, -1);
-}
-
-static xmlnode *
-buddy_to_xmlnode(PurpleBlistNode *bnode)
-{
- xmlnode *node, *child;
- PurpleBuddy *buddy;
-
- buddy = (PurpleBuddy *)bnode;
-
- node = xmlnode_new("buddy");
- xmlnode_set_attrib(node, "account", purple_account_get_username(buddy->account));
- xmlnode_set_attrib(node, "proto", purple_account_get_protocol_id(buddy->account));
-
- child = xmlnode_new_child(node, "name");
- xmlnode_insert_data(child, buddy->name, -1);
-
- if (buddy->alias != NULL)
- {
- child = xmlnode_new_child(node, "alias");
- xmlnode_insert_data(child, buddy->alias, -1);
- }
-
- /* Write buddy settings */
- g_hash_table_foreach(buddy->node.settings, value_to_xmlnode, node);
-
- return node;
-}
-
-static xmlnode *
-contact_to_xmlnode(PurpleBlistNode *cnode)
-{
- xmlnode *node, *child;
- PurpleContact *contact;
- PurpleBlistNode *bnode;
-
- contact = (PurpleContact *)cnode;
-
- node = xmlnode_new("contact");
-
- if (contact->alias != NULL)
- {
- xmlnode_set_attrib(node, "alias", contact->alias);
- }
-
- /* Write buddies */
- for (bnode = cnode->child; bnode != NULL; bnode = bnode->next)
- {
- if (!PURPLE_BLIST_NODE_SHOULD_SAVE(bnode))
- continue;
- if (PURPLE_BLIST_NODE_IS_BUDDY(bnode))
- {
- child = buddy_to_xmlnode(bnode);
- xmlnode_insert_child(node, child);
- }
- }
-
- /* Write contact settings */
- g_hash_table_foreach(cnode->settings, value_to_xmlnode, node);
-
- return node;
-}
-
-static xmlnode *
-chat_to_xmlnode(PurpleBlistNode *cnode)
-{
- xmlnode *node, *child;
- PurpleChat *chat;
-
- chat = (PurpleChat *)cnode;
-
- node = xmlnode_new("chat");
- xmlnode_set_attrib(node, "proto", purple_account_get_protocol_id(chat->account));
- xmlnode_set_attrib(node, "account", purple_account_get_username(chat->account));
-
- if (chat->alias != NULL)
- {
- child = xmlnode_new_child(node, "alias");
- xmlnode_insert_data(child, chat->alias, -1);
- }
-
- /* Write chat components */
- g_hash_table_foreach(chat->components, chat_component_to_xmlnode, node);
-
- /* Write chat settings */
- g_hash_table_foreach(chat->node.settings, value_to_xmlnode, node);
-
- return node;
-}
-
-static xmlnode *
-group_to_xmlnode(PurpleBlistNode *gnode)
-{
- xmlnode *node, *child;
- PurpleGroup *group;
- PurpleBlistNode *cnode;
-
- group = (PurpleGroup *)gnode;
-
- node = xmlnode_new("group");
- xmlnode_set_attrib(node, "name", group->name);
-
- /* Write settings */
- g_hash_table_foreach(group->node.settings, value_to_xmlnode, node);
-
- /* Write contacts and chats */
- for (cnode = gnode->child; cnode != NULL; cnode = cnode->next)
- {
- if (!PURPLE_BLIST_NODE_SHOULD_SAVE(cnode))
- continue;
- if (PURPLE_BLIST_NODE_IS_CONTACT(cnode))
- {
- child = contact_to_xmlnode(cnode);
- xmlnode_insert_child(node, child);
- }
- else if (PURPLE_BLIST_NODE_IS_CHAT(cnode))
- {
- child = chat_to_xmlnode(cnode);
- xmlnode_insert_child(node, child);
- }
- }
-
- return node;
-}
-
-static xmlnode *
-accountprivacy_to_xmlnode(PurpleAccount *account)
-{
- xmlnode *node, *child;
- GSList *cur;
- char buf[10];
-
- 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", purple_account_get_privacy_type(account));
- xmlnode_set_attrib(node, "mode", buf);
-
- for (cur = account->permit; cur; cur = cur->next)
- {
- child = xmlnode_new_child(node, "permit");
- xmlnode_insert_data(child, cur->data, -1);
- }
-
- for (cur = account->deny; cur; cur = cur->next)
- {
- child = xmlnode_new_child(node, "block");
- xmlnode_insert_data(child, cur->data, -1);
- }
-
- return node;
-}
-
-static xmlnode *
-blist_to_xmlnode(void)
-{
- xmlnode *node, *child, *grandchild;
- PurpleBlistNode *gnode;
- GList *cur;
-
- node = xmlnode_new("purple");
- xmlnode_set_attrib(node, "version", "1.0");
-
- /* Write groups */
- child = xmlnode_new_child(node, "blist");
- for (gnode = purplebuddylist->root; gnode != NULL; gnode = gnode->next)
- {
- if (!PURPLE_BLIST_NODE_SHOULD_SAVE(gnode))
- continue;
- if (PURPLE_BLIST_NODE_IS_GROUP(gnode))
- {
- grandchild = group_to_xmlnode(gnode);
- xmlnode_insert_child(child, grandchild);
- }
- }
-
- /* Write privacy settings */
- child = xmlnode_new_child(node, "privacy");
- for (cur = purple_accounts_get_all(); cur != NULL; cur = cur->next)
- {
- grandchild = accountprivacy_to_xmlnode(cur->data);
- xmlnode_insert_child(child, grandchild);
- }
-
- return node;
-}
-
-static void
-purple_blist_sync(void)
-{
- xmlnode *node;
- char *data;
-
- if (!blist_loaded)
- {
- purple_debug_error("blist", "Attempted to save buddy list before it "
- "was read!\n");
- return;
- }
-
- node = blist_to_xmlnode();
- data = xmlnode_to_formatted_str(node, NULL);
- purple_util_write_data_to_file("blist.xml", data, -1);
- g_free(data);
- xmlnode_free(node);
-}
-
-static gboolean
-save_cb(gpointer data)
-{
- purple_blist_sync();
- save_timer = 0;
- return FALSE;
-}
-
-static void
-_purple_blist_schedule_save()
-{
- if (save_timer == 0)
- save_timer = purple_timeout_add_seconds(5, save_cb, NULL);
-}
-
-static void
-purple_blist_save_account(PurpleAccount *account)
-{
-#if 1
- _purple_blist_schedule_save();
-#else
- if (account != NULL) {
- /* Save the buddies and privacy data for this account */
- } else {
- /* Save all buddies and privacy data */
- }
-#endif
-}
-
-static void
-purple_blist_save_node(PurpleBlistNode *node)
-{
- _purple_blist_schedule_save();
-}
-
-void purple_blist_schedule_save()
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
-
- /* Save everything */
- if (ops && ops->save_account)
- ops->save_account(NULL);
-}
-
-
-/*********************************************************************
- * Reading from disk *
- *********************************************************************/
-
-static void
-parse_setting(PurpleBlistNode *node, xmlnode *setting)
-{
- const char *name = xmlnode_get_attrib(setting, "name");
- const char *type = xmlnode_get_attrib(setting, "type");
- char *value = xmlnode_get_data(setting);
-
- if (!value)
- return;
-
- if (!type || purple_strequal(type, "string"))
- purple_blist_node_set_string(node, name, value);
- else if (purple_strequal(type, "bool"))
- purple_blist_node_set_bool(node, name, atoi(value));
- else if (purple_strequal(type, "int"))
- purple_blist_node_set_int(node, name, atoi(value));
-
- g_free(value);
-}
-
-static void
-parse_buddy(PurpleGroup *group, PurpleContact *contact, xmlnode *bnode)
-{
- PurpleAccount *account;
- PurpleBuddy *buddy;
- char *name = NULL, *alias = NULL;
- const char *acct_name, *proto;
- xmlnode *x;
-
- acct_name = xmlnode_get_attrib(bnode, "account");
- proto = xmlnode_get_attrib(bnode, "proto");
-
- if (!acct_name || !proto)
- return;
-
- account = purple_accounts_find(acct_name, proto);
-
- if (!account)
- return;
-
- if ((x = xmlnode_get_child(bnode, "name")))
- name = xmlnode_get_data(x);
-
- if (!name)
- return;
-
- if ((x = xmlnode_get_child(bnode, "alias")))
- alias = xmlnode_get_data(x);
-
- buddy = purple_buddy_new(account, name, alias);
- purple_blist_add_buddy(buddy, contact, group,
- purple_blist_get_last_child((PurpleBlistNode*)contact));
-
- for (x = xmlnode_get_child(bnode, "setting"); x; x = xmlnode_get_next_twin(x)) {
- parse_setting((PurpleBlistNode*)buddy, x);
- }
-
- g_free(name);
- g_free(alias);
-}
-
-static void
-parse_contact(PurpleGroup *group, xmlnode *cnode)
-{
- PurpleContact *contact = purple_contact_new();
- xmlnode *x;
- const char *alias;
-
- purple_blist_add_contact(contact, group,
- purple_blist_get_last_child((PurpleBlistNode*)group));
-
- if ((alias = xmlnode_get_attrib(cnode, "alias"))) {
- purple_blist_alias_contact(contact, alias);
- }
-
- for (x = cnode->child; x; x = x->next) {
- if (x->type != XMLNODE_TYPE_TAG)
- continue;
- if (purple_strequal(x->name, "buddy"))
- parse_buddy(group, contact, x);
- else if (purple_strequal(x->name, "setting"))
- parse_setting((PurpleBlistNode*)contact, x);
- }
-
- /* if the contact is empty, don't keep it around. it causes problems */
- if (!((PurpleBlistNode*)contact)->child)
- purple_blist_remove_contact(contact);
-}
-
-static void
-parse_chat(PurpleGroup *group, xmlnode *cnode)
-{
- PurpleChat *chat;
- PurpleAccount *account;
- const char *acct_name, *proto;
- xmlnode *x;
- char *alias = NULL;
- GHashTable *components;
-
- acct_name = xmlnode_get_attrib(cnode, "account");
- proto = xmlnode_get_attrib(cnode, "proto");
-
- if (!acct_name || !proto)
- return;
-
- account = purple_accounts_find(acct_name, proto);
-
- if (!account)
- return;
-
- if ((x = xmlnode_get_child(cnode, "alias")))
- alias = xmlnode_get_data(x);
-
- components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
-
- for (x = xmlnode_get_child(cnode, "component"); x; x = xmlnode_get_next_twin(x)) {
- const char *name;
- char *value;
-
- name = xmlnode_get_attrib(x, "name");
- value = xmlnode_get_data(x);
- g_hash_table_replace(components, g_strdup(name), value);
- }
-
- chat = purple_chat_new(account, alias, components);
- purple_blist_add_chat(chat, group,
- purple_blist_get_last_child((PurpleBlistNode*)group));
-
- for (x = xmlnode_get_child(cnode, "setting"); x; x = xmlnode_get_next_twin(x)) {
- parse_setting((PurpleBlistNode*)chat, x);
- }
-
- g_free(alias);
-}
-
-static void
-parse_group(xmlnode *groupnode)
-{
- const char *name = xmlnode_get_attrib(groupnode, "name");
- PurpleGroup *group;
- xmlnode *cnode;
-
- if (!name)
- name = _("Buddies");
-
- group = purple_group_new(name);
- purple_blist_add_group(group,
- purple_blist_get_last_sibling(purplebuddylist->root));
-
- for (cnode = groupnode->child; cnode; cnode = cnode->next) {
- if (cnode->type != XMLNODE_TYPE_TAG)
- continue;
- if (purple_strequal(cnode->name, "setting"))
- parse_setting((PurpleBlistNode*)group, cnode);
- else if (purple_strequal(cnode->name, "contact") ||
- purple_strequal(cnode->name, "person"))
- parse_contact(group, cnode);
- else if (purple_strequal(cnode->name, "chat"))
- parse_chat(group, cnode);
- }
-}
-
-static void
-load_blist(void)
-{
- xmlnode *purple, *blist, *privacy;
-
- blist_loaded = TRUE;
-
- purple = purple_util_read_xml_from_file("blist.xml", _("buddy list"));
-
- if (purple == NULL)
- return;
-
- blist = xmlnode_get_child(purple, "blist");
- if (blist) {
- xmlnode *groupnode;
- for (groupnode = xmlnode_get_child(blist, "group"); groupnode != NULL;
- groupnode = xmlnode_get_next_twin(groupnode)) {
- parse_group(groupnode);
- }
- }
-
- privacy = xmlnode_get_child(purple, "privacy");
- if (privacy) {
- xmlnode *anode;
- for (anode = privacy->child; anode; anode = anode->next) {
- xmlnode *x;
- PurpleAccount *account;
- int imode;
- const char *acct_name, *proto, *mode;
-
- acct_name = xmlnode_get_attrib(anode, "name");
- proto = xmlnode_get_attrib(anode, "proto");
- mode = xmlnode_get_attrib(anode, "mode");
-
- if (!acct_name || !proto || !mode)
- continue;
-
- account = purple_accounts_find(acct_name, proto);
-
- if (!account)
- continue;
-
- imode = atoi(mode);
- purple_account_set_privacy_type(account, (imode != 0 ? imode : PURPLE_PRIVACY_ALLOW_ALL));
-
- for (x = anode->child; x; x = x->next) {
- char *name;
- if (x->type != XMLNODE_TYPE_TAG)
- continue;
-
- if (purple_strequal(x->name, "permit")) {
- name = xmlnode_get_data(x);
- purple_privacy_permit_add(account, name, TRUE);
- g_free(name);
- } else if (purple_strequal(x->name, "block")) {
- name = xmlnode_get_data(x);
- purple_privacy_deny_add(account, name, TRUE);
- g_free(name);
- }
- }
- }
- }
-
- xmlnode_free(purple);
-
- /* This tells the buddy icon code to do its thing. */
- _purple_buddy_icons_blist_loaded_cb();
-}
-
-
-/*********************************************************************
- * Stuff *
- *********************************************************************/
-
-static void
-purple_contact_compute_priority_buddy(PurpleContact *contact)
-{
- PurpleBlistNode *bnode;
- PurpleBuddy *new_priority = NULL;
-
- g_return_if_fail(contact != NULL);
-
- contact->priority = NULL;
- for (bnode = ((PurpleBlistNode*)contact)->child;
- bnode != NULL;
- bnode = bnode->next)
- {
- PurpleBuddy *buddy;
-
- if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode))
- continue;
-
- buddy = (PurpleBuddy*)bnode;
- if (new_priority == NULL)
- {
- new_priority = buddy;
- continue;
- }
-
- if (purple_account_is_connected(buddy->account))
- {
- int cmp = 1;
- if (purple_account_is_connected(new_priority->account))
- cmp = purple_presence_compare(purple_buddy_get_presence(new_priority),
- purple_buddy_get_presence(buddy));
-
- if (cmp > 0 || (cmp == 0 &&
- purple_prefs_get_bool("/purple/contact/last_match")))
- {
- new_priority = buddy;
- }
- }
- }
-
- contact->priority = new_priority;
- contact->priority_valid = TRUE;
-}
-
-
-/*****************************************************************************
- * Public API functions *
- *****************************************************************************/
-
-void
-purple_blist_boot(void)
-{
- PurpleBlistUiOps *ui_ops;
- GList *account;
- PurpleBuddyList *gbl = g_new0(PurpleBuddyList, 1);
- PURPLE_DBUS_REGISTER_POINTER(gbl, PurpleBuddyList);
-
- ui_ops = purple_blist_get_ui_ops();
-
- gbl->buddies = g_hash_table_new_full((GHashFunc)_purple_blist_hbuddy_hash,
- (GEqualFunc)_purple_blist_hbuddy_equal,
- (GDestroyNotify)_purple_blist_hbuddy_free_key, NULL);
-
- buddies_cache = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, (GDestroyNotify)g_hash_table_destroy);
-
- groups_cache = g_hash_table_new_full((GHashFunc)g_str_hash,
- (GEqualFunc)g_str_equal,
- (GDestroyNotify)g_free, NULL);
-
- for (account = purple_accounts_get_all(); account != NULL; account = account->next)
- {
- purple_blist_buddies_cache_add_account(account->data);
- }
-
- if (ui_ops != NULL && ui_ops->new_list != NULL)
- ui_ops->new_list(gbl);
-
- purplebuddylist = gbl;
-
- load_blist();
-}
-
-PurpleBuddyList *
-purple_get_blist()
-{
- return purplebuddylist;
-}
-
-PurpleBlistNode *
-purple_blist_get_root()
-{
- return purplebuddylist ? purplebuddylist->root : NULL;
-}
-
-static void
-append_buddy(gpointer key, gpointer value, gpointer user_data)
-{
- GSList **list = user_data;
- *list = g_slist_prepend(*list, value);
-}
-
-GSList *
-purple_blist_get_buddies()
-{
- GSList *buddies = NULL;
-
- if (!purplebuddylist)
- return NULL;
-
- g_hash_table_foreach(purplebuddylist->buddies, append_buddy, &buddies);
- return buddies;
-}
-
-void *
-purple_blist_get_ui_data()
-{
- return purplebuddylist->ui_data;
-}
-
-void
-purple_blist_set_ui_data(void *ui_data)
-{
- purplebuddylist->ui_data = ui_data;
-}
-
-void purple_blist_show()
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
-
- if (ops && ops->show)
- ops->show(purplebuddylist);
-}
-
-void purple_blist_destroy()
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
-
- purple_debug(PURPLE_DEBUG_INFO, "blist", "Destroying\n");
-
- if (ops && ops->destroy)
- ops->destroy(purplebuddylist);
-}
-
-void purple_blist_set_visible(gboolean show)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
-
- if (ops && ops->set_visible)
- ops->set_visible(purplebuddylist, show);
-}
-
-static PurpleBlistNode *get_next_node(PurpleBlistNode *node, gboolean godeep)
-{
- if (node == NULL)
- return NULL;
-
- if (godeep && node->child)
- return node->child;
-
- if (node->next)
- return node->next;
-
- return get_next_node(node->parent, FALSE);
-}
-
-PurpleBlistNode *purple_blist_node_next(PurpleBlistNode *node, gboolean offline)
-{
- PurpleBlistNode *ret = node;
-
- if (offline)
- return get_next_node(ret, TRUE);
- do
- {
- ret = get_next_node(ret, TRUE);
- } while (ret && PURPLE_BLIST_NODE_IS_BUDDY(ret) &&
- !purple_account_is_connected(purple_buddy_get_account((PurpleBuddy *)ret)));
-
- return ret;
-}
-
-PurpleBlistNode *purple_blist_node_get_parent(PurpleBlistNode *node)
-{
- return node ? node->parent : NULL;
-}
-
-PurpleBlistNode *purple_blist_node_get_first_child(PurpleBlistNode *node)
-{
- return node ? node->child : NULL;
-}
-
-PurpleBlistNode *purple_blist_node_get_sibling_next(PurpleBlistNode *node)
-{
- return node? node->next : NULL;
-}
-
-PurpleBlistNode *purple_blist_node_get_sibling_prev(PurpleBlistNode *node)
-{
- return node? node->prev : NULL;
-}
-
-void *
-purple_blist_node_get_ui_data(const PurpleBlistNode *node)
-{
- g_return_val_if_fail(node, NULL);
-
- return node->ui_data;
-}
-
-void
-purple_blist_node_set_ui_data(PurpleBlistNode *node, void *ui_data) {
- g_return_if_fail(node);
-
- node->ui_data = ui_data;
-}
-
-void
-purple_blist_update_buddy_status(PurpleBuddy *buddy, PurpleStatus *old_status)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- PurplePresence *presence;
- PurpleStatus *status;
- PurpleBlistNode *cnode;
-
- g_return_if_fail(buddy != NULL);
-
- presence = purple_buddy_get_presence(buddy);
- status = purple_presence_get_active_status(presence);
-
- purple_debug_info("blist", "Updating buddy status for %s (%s)\n",
- buddy->name, purple_account_get_protocol_name(buddy->account));
-
- if (purple_status_is_online(status) &&
- !purple_status_is_online(old_status)) {
-
- purple_signal_emit(purple_blist_get_handle(), "buddy-signed-on", buddy);
-
- cnode = buddy->node.parent;
- if (++(PURPLE_CONTACT(cnode)->online) == 1)
- PURPLE_GROUP(cnode->parent)->online++;
- } else if (!purple_status_is_online(status) &&
- purple_status_is_online(old_status)) {
-
- purple_blist_node_set_int(&buddy->node, "last_seen", time(NULL));
- purple_signal_emit(purple_blist_get_handle(), "buddy-signed-off", buddy);
-
- cnode = buddy->node.parent;
- if (--(PURPLE_CONTACT(cnode)->online) == 0)
- PURPLE_GROUP(cnode->parent)->online--;
- } else {
- purple_signal_emit(purple_blist_get_handle(),
- "buddy-status-changed", buddy, old_status,
- status);
- }
-
- /*
- * This function used to only call the following two functions if one of
- * the above signals had been triggered, but that's not good, because
- * if someone's away message changes and they don't go from away to back
- * to away then no signal is triggered.
- *
- * It's a safe assumption that SOMETHING called this function. PROBABLY
- * because something, somewhere changed. Calling the stuff below
- * certainly won't hurt anything. Unless you're on a K6-2 300.
- */
- purple_contact_invalidate_priority_buddy(purple_buddy_get_contact(buddy));
- if (ops && ops->update)
- ops->update(purplebuddylist, (PurpleBlistNode *)buddy);
-}
-
-void
-purple_blist_update_node_icon(PurpleBlistNode *node)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
-
- g_return_if_fail(node != NULL);
-
- if (ops && ops->update)
- ops->update(purplebuddylist, node);
-}
-
-/*
- * TODO: Maybe remove the call to this from server.c and call it
- * from oscar.c and toc.c instead?
- */
-void purple_blist_rename_buddy(PurpleBuddy *buddy, const char *name)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- struct _purple_hbuddy *hb, *hb2;
- GHashTable *account_buddies;
-
- g_return_if_fail(buddy != NULL);
-
- hb = g_new(struct _purple_hbuddy, 1);
- hb->name = (gchar *)purple_normalize(buddy->account, buddy->name);
- hb->account = buddy->account;
- hb->group = ((PurpleBlistNode *)buddy)->parent->parent;
- g_hash_table_remove(purplebuddylist->buddies, hb);
-
- account_buddies = g_hash_table_lookup(buddies_cache, buddy->account);
- g_hash_table_remove(account_buddies, hb);
-
- hb->name = g_strdup(purple_normalize(buddy->account, name));
- g_hash_table_replace(purplebuddylist->buddies, hb, buddy);
-
- hb2 = g_new(struct _purple_hbuddy, 1);
- hb2->name = g_strdup(hb->name);
- hb2->account = buddy->account;
- hb2->group = ((PurpleBlistNode *)buddy)->parent->parent;
-
- g_hash_table_replace(account_buddies, hb2, buddy);
-
- g_free(buddy->name);
- buddy->name = g_strdup(name);
-
- if (ops && ops->save_node)
- ops->save_node((PurpleBlistNode *) buddy);
-
- if (ops && ops->update)
- ops->update(purplebuddylist, (PurpleBlistNode *)buddy);
-}
-
-static gboolean
-purple_strings_are_different(const char *one, const char *two)
-{
- return !((one && two && g_utf8_collate(one, two) == 0) ||
- ((one == NULL || *one == '\0') && (two == NULL || *two == '\0')));
-}
-
-void purple_blist_alias_contact(PurpleContact *contact, const char *alias)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- PurpleConversation *conv;
- PurpleBlistNode *bnode;
- char *old_alias;
- char *new_alias = NULL;
-
- g_return_if_fail(contact != NULL);
-
- if ((alias != NULL) && (*alias != '\0'))
- new_alias = purple_utf8_strip_unprintables(alias);
-
- if (!purple_strings_are_different(contact->alias, new_alias)) {
- g_free(new_alias);
- return;
- }
-
- old_alias = contact->alias;
-
- if ((new_alias != NULL) && (*new_alias != '\0'))
- contact->alias = new_alias;
- else {
- contact->alias = NULL;
- g_free(new_alias); /* could be "\0" */
- }
-
- if (ops && ops->save_node)
- ops->save_node((PurpleBlistNode*) contact);
-
- if (ops && ops->update)
- ops->update(purplebuddylist, (PurpleBlistNode *)contact);
-
- for(bnode = ((PurpleBlistNode *)contact)->child; bnode != NULL; bnode = bnode->next)
- {
- PurpleBuddy *buddy = (PurpleBuddy *)bnode;
-
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy->name,
- buddy->account);
- if (conv)
- purple_conversation_autoset_title(conv);
- }
-
- purple_signal_emit(purple_blist_get_handle(), "blist-node-aliased",
- contact, old_alias);
- g_free(old_alias);
-}
-
-void purple_blist_alias_chat(PurpleChat *chat, const char *alias)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- char *old_alias;
- char *new_alias = NULL;
-
- g_return_if_fail(chat != NULL);
-
- if ((alias != NULL) && (*alias != '\0'))
- new_alias = purple_utf8_strip_unprintables(alias);
-
- if (!purple_strings_are_different(chat->alias, new_alias)) {
- g_free(new_alias);
- return;
- }
-
- old_alias = chat->alias;
-
- if ((new_alias != NULL) && (*new_alias != '\0'))
- chat->alias = new_alias;
- else {
- chat->alias = NULL;
- g_free(new_alias); /* could be "\0" */
- }
-
- if (ops && ops->save_node)
- ops->save_node((PurpleBlistNode*) chat);
-
- if (ops && ops->update)
- ops->update(purplebuddylist, (PurpleBlistNode *)chat);
-
- purple_signal_emit(purple_blist_get_handle(), "blist-node-aliased",
- chat, old_alias);
- g_free(old_alias);
-}
-
-void purple_blist_alias_buddy(PurpleBuddy *buddy, const char *alias)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- PurpleConversation *conv;
- char *old_alias;
- char *new_alias = NULL;
-
- g_return_if_fail(buddy != NULL);
-
- if ((alias != NULL) && (*alias != '\0'))
- new_alias = purple_utf8_strip_unprintables(alias);
-
- if (!purple_strings_are_different(buddy->alias, new_alias)) {
- g_free(new_alias);
- return;
- }
-
- old_alias = buddy->alias;
-
- if ((new_alias != NULL) && (*new_alias != '\0'))
- buddy->alias = new_alias;
- else {
- buddy->alias = NULL;
- g_free(new_alias); /* could be "\0" */
- }
-
- if (ops && ops->save_node)
- ops->save_node((PurpleBlistNode*) buddy);
-
- if (ops && ops->update)
- ops->update(purplebuddylist, (PurpleBlistNode *)buddy);
-
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy->name,
- buddy->account);
- if (conv)
- purple_conversation_autoset_title(conv);
-
- purple_signal_emit(purple_blist_get_handle(), "blist-node-aliased",
- buddy, old_alias);
- g_free(old_alias);
-}
-
-void purple_blist_server_alias_buddy(PurpleBuddy *buddy, const char *alias)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- PurpleConversation *conv;
- char *old_alias;
- char *new_alias = NULL;
-
- g_return_if_fail(buddy != NULL);
-
- if ((alias != NULL) && (*alias != '\0') && g_utf8_validate(alias, -1, NULL))
- new_alias = purple_utf8_strip_unprintables(alias);
-
- if (!purple_strings_are_different(buddy->server_alias, new_alias)) {
- g_free(new_alias);
- return;
- }
-
- old_alias = buddy->server_alias;
-
- if ((new_alias != NULL) && (*new_alias != '\0'))
- buddy->server_alias = new_alias;
- else {
- buddy->server_alias = NULL;
- g_free(new_alias); /* could be "\0"; */
- }
-
- if (ops && ops->save_node)
- ops->save_node((PurpleBlistNode*) buddy);
-
- if (ops && ops->update)
- ops->update(purplebuddylist, (PurpleBlistNode *)buddy);
-
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy->name,
- buddy->account);
- if (conv)
- purple_conversation_autoset_title(conv);
-
- purple_signal_emit(purple_blist_get_handle(), "blist-node-aliased",
- buddy, old_alias);
- g_free(old_alias);
-}
-
-/*
- * TODO: If merging, prompt the user if they want to merge.
- */
-void purple_blist_rename_group(PurpleGroup *source, const char *name)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- PurpleGroup *dest;
- gchar *old_name;
- gchar *new_name;
- GList *moved_buddies = NULL;
- GSList *accts;
-
- g_return_if_fail(source != NULL);
- g_return_if_fail(name != NULL);
-
- new_name = purple_utf8_strip_unprintables(name);
-
- if (*new_name == '\0' || purple_strequal(new_name, source->name)) {
- g_free(new_name);
- return;
- }
-
- dest = purple_find_group(new_name);
- if (dest != NULL && purple_utf8_strcasecmp(source->name, dest->name) != 0) {
- /* We're merging two groups */
- PurpleBlistNode *prev, *child, *next;
-
- prev = purple_blist_get_last_child((PurpleBlistNode*)dest);
- child = ((PurpleBlistNode*)source)->child;
-
- /*
- * TODO: This seems like a dumb way to do this... why not just
- * append all children from the old group to the end of the new
- * one? PRPLs might be expecting to receive an add_buddy() for
- * each moved buddy...
- */
- while (child)
- {
- next = child->next;
- if (PURPLE_BLIST_NODE_IS_CONTACT(child)) {
- PurpleBlistNode *bnode;
- purple_blist_add_contact((PurpleContact *)child, dest, prev);
- for (bnode = child->child; bnode != NULL; bnode = bnode->next) {
- purple_blist_add_buddy((PurpleBuddy *)bnode, (PurpleContact *)child,
- NULL, bnode->prev);
- moved_buddies = g_list_append(moved_buddies, bnode);
- }
- prev = child;
- } else if (PURPLE_BLIST_NODE_IS_CHAT(child)) {
- purple_blist_add_chat((PurpleChat *)child, dest, prev);
- prev = child;
- } else {
- purple_debug(PURPLE_DEBUG_ERROR, "blist",
- "Unknown child type in group %s\n", source->name);
- }
- child = next;
- }
-
- /* Make a copy of the old group name and then delete the old group */
- old_name = g_strdup(source->name);
- purple_blist_remove_group(source);
- source = dest;
- g_free(new_name);
- } else {
- /* A simple rename */
- PurpleBlistNode *cnode, *bnode;
- gchar* key;
-
- /* Build a GList of all buddies in this group */
- for (cnode = ((PurpleBlistNode *)source)->child; cnode != NULL; cnode = cnode->next) {
- if (PURPLE_BLIST_NODE_IS_CONTACT(cnode))
- for (bnode = cnode->child; bnode != NULL; bnode = bnode->next)
- moved_buddies = g_list_append(moved_buddies, bnode);
- }
-
- old_name = source->name;
- source->name = new_name;
-
- key = g_utf8_collate_key(old_name, -1);
- g_hash_table_remove(groups_cache, key);
- g_free(key);
-
- key = g_utf8_collate_key(new_name, -1);
- g_hash_table_insert(groups_cache, key, source);
- }
-
- /* Save our changes */
- if (ops && ops->save_node)
- ops->save_node((PurpleBlistNode*) source);
-
- /* Update the UI */
- if (ops && ops->update)
- ops->update(purplebuddylist, (PurpleBlistNode*)source);
-
- /* Notify all PRPLs */
- /* TODO: Is this condition needed? Seems like it would always be TRUE */
- if(old_name && !purple_strequal(source->name, old_name)) {
- for (accts = purple_group_get_accounts(source); accts; accts = g_slist_remove(accts, accts->data)) {
- PurpleAccount *account = accts->data;
- PurpleConnection *gc = NULL;
- PurplePlugin *prpl = NULL;
- PurplePluginProtocolInfo *prpl_info = NULL;
- GList *l = NULL, *buddies = NULL;
-
- gc = purple_account_get_connection(account);
-
- if(gc)
- prpl = purple_connection_get_prpl(gc);
-
- if(gc && prpl)
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
-
- if(!prpl_info)
- continue;
-
- for(l = moved_buddies; l; l = l->next) {
- PurpleBuddy *buddy = (PurpleBuddy *)l->data;
-
- if(buddy && buddy->account == account)
- buddies = g_list_append(buddies, (PurpleBlistNode *)buddy);
- }
-
- if(prpl_info->rename_group) {
- prpl_info->rename_group(gc, old_name, source, buddies);
- } else {
- GList *cur, *groups = NULL;
-
- /* Make a list of what the groups each buddy is in */
- for(cur = buddies; cur; cur = cur->next) {
- PurpleBlistNode *node = (PurpleBlistNode *)cur->data;
- groups = g_list_prepend(groups, node->parent->parent);
- }
-
- purple_account_remove_buddies(account, buddies, groups);
- g_list_free(groups);
- purple_account_add_buddies(account, buddies, NULL);
- }
-
- g_list_free(buddies);
- }
- }
- g_list_free(moved_buddies);
- g_free(old_name);
-}
-
-static void purple_blist_node_initialize_settings(PurpleBlistNode *node);
-
-PurpleChat *purple_chat_new(PurpleAccount *account, const char *alias, GHashTable *components)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- PurpleChat *chat;
-
- g_return_val_if_fail(account != NULL, NULL);
- g_return_val_if_fail(components != NULL, NULL);
-
- chat = g_new0(PurpleChat, 1);
- chat->account = account;
- if ((alias != NULL) && (*alias != '\0'))
- chat->alias = purple_utf8_strip_unprintables(alias);
- chat->components = components;
- purple_blist_node_initialize_settings((PurpleBlistNode *)chat);
- ((PurpleBlistNode *)chat)->type = PURPLE_BLIST_CHAT_NODE;
-
- if (ops != NULL && ops->new_node != NULL)
- ops->new_node((PurpleBlistNode *)chat);
-
- PURPLE_DBUS_REGISTER_POINTER(chat, PurpleChat);
- return chat;
-}
-
-void
-purple_chat_destroy(PurpleChat *chat)
-{
- g_hash_table_destroy(chat->components);
- g_hash_table_destroy(chat->node.settings);
- g_free(chat->alias);
- PURPLE_DBUS_UNREGISTER_POINTER(chat);
- g_free(chat);
-}
-
-PurpleBuddy *purple_buddy_new(PurpleAccount *account, const char *name, const char *alias)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- PurpleBuddy *buddy;
-
- g_return_val_if_fail(account != NULL, NULL);
- g_return_val_if_fail(name != NULL, NULL);
-
- buddy = g_new0(PurpleBuddy, 1);
- buddy->account = account;
- buddy->name = purple_utf8_strip_unprintables(name);
- buddy->alias = purple_utf8_strip_unprintables(alias);
- buddy->presence = purple_presence_new_for_buddy(buddy);
- ((PurpleBlistNode *)buddy)->type = PURPLE_BLIST_BUDDY_NODE;
-
- purple_presence_set_status_active(buddy->presence, "offline", TRUE);
-
- purple_blist_node_initialize_settings((PurpleBlistNode *)buddy);
-
- if (ops && ops->new_node)
- ops->new_node((PurpleBlistNode *)buddy);
-
- PURPLE_DBUS_REGISTER_POINTER(buddy, PurpleBuddy);
- return buddy;
-}
-
-void
-purple_buddy_destroy(PurpleBuddy *buddy)
-{
- PurplePlugin *prpl;
- PurplePluginProtocolInfo *prpl_info;
-
- /*
- * Tell the owner PRPL that we're about to free the buddy so it
- * can free proto_data
- */
- prpl = purple_find_prpl(purple_account_get_protocol_id(buddy->account));
- if (prpl) {
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
- if (prpl_info && prpl_info->buddy_free)
- prpl_info->buddy_free(buddy);
- }
-
- /* Delete the node */
- purple_buddy_icon_unref(buddy->icon);
- g_hash_table_destroy(buddy->node.settings);
- purple_presence_destroy(buddy->presence);
- g_free(buddy->name);
- g_free(buddy->alias);
- g_free(buddy->server_alias);
-
- PURPLE_DBUS_UNREGISTER_POINTER(buddy);
- g_free(buddy);
-
- /* FIXME: Once PurpleBuddy is a GObject, timeout callbacks can
- * g_object_ref() it when connecting the callback and
- * g_object_unref() it in the handler. That way, it won't
- * get freed while the timeout is pending and this line can
- * be removed. */
- while (g_source_remove_by_user_data((gpointer *)buddy));
-}
-
-void
-purple_buddy_set_icon(PurpleBuddy *buddy, PurpleBuddyIcon *icon)
-{
- g_return_if_fail(buddy != NULL);
-
- if (buddy->icon != icon)
- {
- purple_buddy_icon_unref(buddy->icon);
- buddy->icon = (icon != NULL ? purple_buddy_icon_ref(icon) : NULL);
- }
-
- purple_signal_emit(purple_blist_get_handle(), "buddy-icon-changed", buddy);
-
- purple_blist_update_node_icon((PurpleBlistNode*)buddy);
-}
-
-PurpleAccount *
-purple_buddy_get_account(const PurpleBuddy *buddy)
-{
- g_return_val_if_fail(buddy != NULL, NULL);
-
- return buddy->account;
-}
-
-const char *
-purple_buddy_get_name(const PurpleBuddy *buddy)
-{
- g_return_val_if_fail(buddy != NULL, NULL);
-
- return buddy->name;
-}
-
-PurpleBuddyIcon *
-purple_buddy_get_icon(const PurpleBuddy *buddy)
-{
- g_return_val_if_fail(buddy != NULL, NULL);
-
- return buddy->icon;
-}
-
-gpointer
-purple_buddy_get_protocol_data(const PurpleBuddy *buddy)
-{
- g_return_val_if_fail(buddy != NULL, NULL);
-
- return buddy->proto_data;
-}
-
-void
-purple_buddy_set_protocol_data(PurpleBuddy *buddy, gpointer data)
-{
- g_return_if_fail(buddy != NULL);
-
- buddy->proto_data = data;
-}
-
-
-void purple_blist_add_chat(PurpleChat *chat, PurpleGroup *group, PurpleBlistNode *node)
-{
- PurpleBlistNode *cnode = (PurpleBlistNode*)chat;
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
-
- g_return_if_fail(chat != NULL);
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT((PurpleBlistNode *)chat));
-
- if (node == NULL) {
- if (group == NULL)
- group = purple_group_new(_("Chats"));
-
- /* Add group to blist if isn't already on it. Fixes #2752. */
- if (!purple_find_group(group->name)) {
- purple_blist_add_group(group,
- purple_blist_get_last_sibling(purplebuddylist->root));
- }
- } else {
- group = (PurpleGroup*)node->parent;
- }
-
- /* if we're moving to overtop of ourselves, do nothing */
- if (cnode == node)
- return;
-
- if (cnode->parent) {
- /* This chat was already in the list and is
- * being moved.
- */
- ((PurpleGroup *)cnode->parent)->totalsize--;
- if (purple_account_is_connected(chat->account)) {
- ((PurpleGroup *)cnode->parent)->online--;
- ((PurpleGroup *)cnode->parent)->currentsize--;
- }
- if (cnode->next)
- cnode->next->prev = cnode->prev;
- if (cnode->prev)
- cnode->prev->next = cnode->next;
- if (cnode->parent->child == cnode)
- cnode->parent->child = cnode->next;
-
- if (ops && ops->remove)
- ops->remove(purplebuddylist, cnode);
- /* ops->remove() cleaned up the cnode's ui_data, so we need to
- * reinitialize it */
- if (ops && ops->new_node)
- ops->new_node(cnode);
- }
-
- if (node != NULL) {
- if (node->next)
- node->next->prev = cnode;
- cnode->next = node->next;
- cnode->prev = node;
- cnode->parent = node->parent;
- node->next = cnode;
- ((PurpleGroup *)node->parent)->totalsize++;
- if (purple_account_is_connected(chat->account)) {
- ((PurpleGroup *)node->parent)->online++;
- ((PurpleGroup *)node->parent)->currentsize++;
- }
- } else {
- if (((PurpleBlistNode *)group)->child)
- ((PurpleBlistNode *)group)->child->prev = cnode;
- cnode->next = ((PurpleBlistNode *)group)->child;
- cnode->prev = NULL;
- ((PurpleBlistNode *)group)->child = cnode;
- cnode->parent = (PurpleBlistNode *)group;
- group->totalsize++;
- if (purple_account_is_connected(chat->account)) {
- group->online++;
- group->currentsize++;
- }
- }
-
- if (ops && ops->save_node)
- ops->save_node(cnode);
-
- if (ops && ops->update)
- ops->update(purplebuddylist, (PurpleBlistNode *)cnode);
-
- purple_signal_emit(purple_blist_get_handle(), "blist-node-added",
- cnode);
-}
-
-void purple_blist_add_buddy(PurpleBuddy *buddy, PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node)
-{
- PurpleBlistNode *cnode, *bnode;
- PurpleGroup *g;
- PurpleContact *c;
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- struct _purple_hbuddy *hb, *hb2;
- GHashTable *account_buddies;
-
- g_return_if_fail(buddy != NULL);
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY((PurpleBlistNode*)buddy));
-
- bnode = (PurpleBlistNode *)buddy;
-
- /* if we're moving to overtop of ourselves, do nothing */
- if (bnode == node || (!node && bnode->parent &&
- contact && bnode->parent == (PurpleBlistNode*)contact
- && bnode == bnode->parent->child))
- return;
-
- if (node && PURPLE_BLIST_NODE_IS_BUDDY(node)) {
- c = (PurpleContact*)node->parent;
- g = (PurpleGroup*)node->parent->parent;
- } else if (contact) {
- c = contact;
- g = PURPLE_GROUP(PURPLE_BLIST_NODE(c)->parent);
- } else {
- g = group;
- if (g == NULL)
- g = purple_group_new(_("Buddies"));
- /* Add group to blist if isn't already on it. Fixes #2752. */
- if (!purple_find_group(g->name)) {
- purple_blist_add_group(g,
- purple_blist_get_last_sibling(purplebuddylist->root));
- }
- c = purple_contact_new();
- purple_blist_add_contact(c, g,
- purple_blist_get_last_child((PurpleBlistNode*)g));
- }
-
- cnode = (PurpleBlistNode *)c;
-
- if (bnode->parent) {
- if (PURPLE_BUDDY_IS_ONLINE(buddy)) {
- ((PurpleContact*)bnode->parent)->online--;
- if (((PurpleContact*)bnode->parent)->online == 0)
- ((PurpleGroup*)bnode->parent->parent)->online--;
- }
- if (purple_account_is_connected(buddy->account)) {
- ((PurpleContact*)bnode->parent)->currentsize--;
- if (((PurpleContact*)bnode->parent)->currentsize == 0)
- ((PurpleGroup*)bnode->parent->parent)->currentsize--;
- }
- ((PurpleContact*)bnode->parent)->totalsize--;
- /* the group totalsize will be taken care of by remove_contact below */
-
- if (bnode->parent->parent != (PurpleBlistNode*)g)
- serv_move_buddy(buddy, (PurpleGroup *)bnode->parent->parent, g);
-
- if (bnode->next)
- bnode->next->prev = bnode->prev;
- if (bnode->prev)
- bnode->prev->next = bnode->next;
- if (bnode->parent->child == bnode)
- bnode->parent->child = bnode->next;
-
- if (ops && ops->remove)
- ops->remove(purplebuddylist, bnode);
-
- if (bnode->parent->parent != (PurpleBlistNode*)g) {
- struct _purple_hbuddy hb;
- hb.name = (gchar *)purple_normalize(buddy->account, buddy->name);
- hb.account = buddy->account;
- hb.group = bnode->parent->parent;
- g_hash_table_remove(purplebuddylist->buddies, &hb);
-
- account_buddies = g_hash_table_lookup(buddies_cache, buddy->account);
- g_hash_table_remove(account_buddies, &hb);
- }
-
- if (!bnode->parent->child) {
- purple_blist_remove_contact((PurpleContact*)bnode->parent);
- } else {
- purple_contact_invalidate_priority_buddy((PurpleContact*)bnode->parent);
- if (ops && ops->update)
- ops->update(purplebuddylist, bnode->parent);
- }
- }
-
- if (node && PURPLE_BLIST_NODE_IS_BUDDY(node)) {
- if (node->next)
- node->next->prev = bnode;
- bnode->next = node->next;
- bnode->prev = node;
- bnode->parent = node->parent;
- node->next = bnode;
- } else {
- if (cnode->child)
- cnode->child->prev = bnode;
- bnode->prev = NULL;
- bnode->next = cnode->child;
- cnode->child = bnode;
- bnode->parent = cnode;
- }
-
- if (PURPLE_BUDDY_IS_ONLINE(buddy)) {
- if (++(PURPLE_CONTACT(bnode->parent)->online) == 1)
- PURPLE_GROUP(bnode->parent->parent)->online++;
- }
- if (purple_account_is_connected(buddy->account)) {
- if (++(PURPLE_CONTACT(bnode->parent)->currentsize) == 1)
- PURPLE_GROUP(bnode->parent->parent)->currentsize++;
- }
- PURPLE_CONTACT(bnode->parent)->totalsize++;
-
- hb = g_new(struct _purple_hbuddy, 1);
- hb->name = g_strdup(purple_normalize(buddy->account, buddy->name));
- hb->account = buddy->account;
- hb->group = ((PurpleBlistNode*)buddy)->parent->parent;
-
- g_hash_table_replace(purplebuddylist->buddies, hb, buddy);
-
- account_buddies = g_hash_table_lookup(buddies_cache, buddy->account);
-
- hb2 = g_new(struct _purple_hbuddy, 1);
- hb2->name = g_strdup(hb->name);
- hb2->account = buddy->account;
- hb2->group = ((PurpleBlistNode*)buddy)->parent->parent;
-
- g_hash_table_replace(account_buddies, hb2, buddy);
-
- purple_contact_invalidate_priority_buddy(purple_buddy_get_contact(buddy));
-
- if (ops && ops->save_node)
- ops->save_node((PurpleBlistNode*) buddy);
-
- if (ops && ops->update)
- ops->update(purplebuddylist, (PurpleBlistNode*)buddy);
-
- /* Signal that the buddy has been added */
- purple_signal_emit(purple_blist_get_handle(), "buddy-added", buddy);
-
- purple_signal_emit(purple_blist_get_handle(), "blist-node-added",
- PURPLE_BLIST_NODE(buddy));
-}
-
-PurpleContact *purple_contact_new()
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
-
- PurpleContact *contact = g_new0(PurpleContact, 1);
- contact->totalsize = 0;
- contact->currentsize = 0;
- contact->online = 0;
- purple_blist_node_initialize_settings((PurpleBlistNode *)contact);
- ((PurpleBlistNode *)contact)->type = PURPLE_BLIST_CONTACT_NODE;
-
- if (ops && ops->new_node)
- ops->new_node((PurpleBlistNode *)contact);
-
- PURPLE_DBUS_REGISTER_POINTER(contact, PurpleContact);
- return contact;
-}
-
-void
-purple_contact_destroy(PurpleContact *contact)
-{
- g_hash_table_destroy(contact->node.settings);
- g_free(contact->alias);
- PURPLE_DBUS_UNREGISTER_POINTER(contact);
- g_free(contact);
-}
-
-PurpleGroup *
-purple_contact_get_group(const PurpleContact *contact)
-{
- g_return_val_if_fail(contact, NULL);
-
- return (PurpleGroup *)(((PurpleBlistNode *)contact)->parent);
-}
-
-const char *purple_contact_get_alias(PurpleContact* contact)
-{
- g_return_val_if_fail(contact != NULL, NULL);
-
- if (contact->alias)
- return contact->alias;
-
- return purple_buddy_get_alias(purple_contact_get_priority_buddy(contact));
-}
-
-gboolean purple_contact_on_account(PurpleContact *c, PurpleAccount *account)
-{
- PurpleBlistNode *bnode, *cnode = (PurpleBlistNode *) c;
-
- g_return_val_if_fail(c != NULL, FALSE);
- g_return_val_if_fail(account != NULL, FALSE);
-
- for (bnode = cnode->child; bnode; bnode = bnode->next) {
- PurpleBuddy *buddy;
-
- if (! PURPLE_BLIST_NODE_IS_BUDDY(bnode))
- continue;
-
- buddy = (PurpleBuddy *)bnode;
- if (buddy->account == account)
- return TRUE;
- }
- return FALSE;
-}
-
-void purple_contact_invalidate_priority_buddy(PurpleContact *contact)
-{
- g_return_if_fail(contact != NULL);
-
- 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();
- PurpleGroup *group;
-
- g_return_val_if_fail(name != NULL, NULL);
- g_return_val_if_fail(*name != '\0', NULL);
-
- group = purple_find_group(name);
- if (group != NULL)
- return group;
-
- group = g_new0(PurpleGroup, 1);
- group->name = purple_utf8_strip_unprintables(name);
- group->totalsize = 0;
- group->currentsize = 0;
- group->online = 0;
- purple_blist_node_initialize_settings((PurpleBlistNode *)group);
- ((PurpleBlistNode *)group)->type = PURPLE_BLIST_GROUP_NODE;
-
- if (ops && ops->new_node)
- ops->new_node((PurpleBlistNode *)group);
-
- PURPLE_DBUS_REGISTER_POINTER(group, PurpleGroup);
- return group;
-}
-
-void
-purple_group_destroy(PurpleGroup *group)
-{
- g_hash_table_destroy(group->node.settings);
- g_free(group->name);
- PURPLE_DBUS_UNREGISTER_POINTER(group);
- g_free(group);
-}
-
-void purple_blist_add_contact(PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- PurpleGroup *g;
- PurpleBlistNode *gnode, *cnode, *bnode;
-
- g_return_if_fail(contact != NULL);
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CONTACT((PurpleBlistNode*)contact));
-
- if (PURPLE_BLIST_NODE(contact) == node)
- return;
-
- if (node && (PURPLE_BLIST_NODE_IS_CONTACT(node) ||
- PURPLE_BLIST_NODE_IS_CHAT(node)))
- g = (PurpleGroup*)node->parent;
- else if (group)
- g = group;
- else {
- g = purple_find_group(_("Buddies"));
- if (g == NULL) {
- g = purple_group_new(_("Buddies"));
- purple_blist_add_group(g,
- purple_blist_get_last_sibling(purplebuddylist->root));
- }
- }
-
- gnode = (PurpleBlistNode*)g;
- cnode = (PurpleBlistNode*)contact;
-
- if (cnode->parent) {
- if (cnode->parent->child == cnode)
- cnode->parent->child = cnode->next;
- if (cnode->prev)
- cnode->prev->next = cnode->next;
- if (cnode->next)
- cnode->next->prev = cnode->prev;
-
- if (cnode->parent != gnode) {
- bnode = cnode->child;
- while (bnode) {
- PurpleBlistNode *next_bnode = bnode->next;
- PurpleBuddy *b = (PurpleBuddy*)bnode;
- GHashTable *account_buddies;
-
- struct _purple_hbuddy *hb, *hb2;
-
- hb = g_new(struct _purple_hbuddy, 1);
- hb->name = g_strdup(purple_normalize(b->account, b->name));
- hb->account = b->account;
- hb->group = cnode->parent;
-
- g_hash_table_remove(purplebuddylist->buddies, hb);
-
- account_buddies = g_hash_table_lookup(buddies_cache, b->account);
- g_hash_table_remove(account_buddies, hb);
-
- if (!purple_find_buddy_in_group(b->account, b->name, g)) {
- hb->group = gnode;
- g_hash_table_replace(purplebuddylist->buddies, hb, b);
-
- hb2 = g_new(struct _purple_hbuddy, 1);
- hb2->name = g_strdup(hb->name);
- hb2->account = b->account;
- hb2->group = gnode;
-
- g_hash_table_replace(account_buddies, hb2, b);
-
- if (purple_account_get_connection(b->account))
- serv_move_buddy(b, (PurpleGroup *)cnode->parent, g);
- } else {
- gboolean empty_contact = FALSE;
-
- /* this buddy already exists in the group, so we're
- * gonna delete it instead */
- g_free(hb->name);
- g_free(hb);
- if (purple_account_get_connection(b->account))
- purple_account_remove_buddy(b->account, b, (PurpleGroup *)cnode->parent);
-
- if (!cnode->child->next)
- empty_contact = TRUE;
- purple_blist_remove_buddy(b);
-
- /** in purple_blist_remove_buddy(), if the last buddy in a
- * contact is removed, the contact is cleaned up and
- * g_free'd, so we mustn't try to reference bnode->next */
- if (empty_contact)
- return;
- }
- bnode = next_bnode;
- }
- }
-
- if (contact->online > 0)
- ((PurpleGroup*)cnode->parent)->online--;
- if (contact->currentsize > 0)
- ((PurpleGroup*)cnode->parent)->currentsize--;
- ((PurpleGroup*)cnode->parent)->totalsize--;
-
- if (ops && ops->remove)
- ops->remove(purplebuddylist, cnode);
-
- if (ops && ops->remove_node)
- ops->remove_node(cnode);
- }
-
- if (node && (PURPLE_BLIST_NODE_IS_CONTACT(node) ||
- PURPLE_BLIST_NODE_IS_CHAT(node))) {
- if (node->next)
- node->next->prev = cnode;
- cnode->next = node->next;
- cnode->prev = node;
- cnode->parent = node->parent;
- node->next = cnode;
- } else {
- if (gnode->child)
- gnode->child->prev = cnode;
- cnode->prev = NULL;
- cnode->next = gnode->child;
- gnode->child = cnode;
- cnode->parent = gnode;
- }
-
- if (contact->online > 0)
- g->online++;
- if (contact->currentsize > 0)
- g->currentsize++;
- g->totalsize++;
-
- if (ops && ops->save_node)
- {
- if (cnode->child)
- ops->save_node(cnode);
- for (bnode = cnode->child; bnode; bnode = bnode->next)
- ops->save_node(bnode);
- }
-
- if (ops && ops->update)
- {
- if (cnode->child)
- ops->update(purplebuddylist, cnode);
-
- for (bnode = cnode->child; bnode; bnode = bnode->next)
- ops->update(purplebuddylist, bnode);
- }
-}
-
-void purple_blist_merge_contact(PurpleContact *source, PurpleBlistNode *node)
-{
- PurpleBlistNode *sourcenode = (PurpleBlistNode*)source;
- PurpleBlistNode *prev, *cur, *next;
- PurpleContact *target;
-
- g_return_if_fail(source != NULL);
- g_return_if_fail(node != NULL);
-
- if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
- target = (PurpleContact *)node;
- prev = purple_blist_get_last_child(node);
- } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
- target = (PurpleContact *)node->parent;
- prev = node;
- } else {
- return;
- }
-
- if (source == target || !target)
- return;
-
- next = sourcenode->child;
-
- while (next) {
- cur = next;
- next = cur->next;
- if (PURPLE_BLIST_NODE_IS_BUDDY(cur)) {
- purple_blist_add_buddy((PurpleBuddy *)cur, target, NULL, prev);
- prev = cur;
- }
- }
-}
-
-void purple_blist_add_group(PurpleGroup *group, PurpleBlistNode *node)
-{
- PurpleBlistUiOps *ops;
- PurpleBlistNode *gnode = (PurpleBlistNode*)group;
- gchar* key;
-
- g_return_if_fail(group != NULL);
- g_return_if_fail(PURPLE_BLIST_NODE_IS_GROUP((PurpleBlistNode *)group));
-
- ops = purple_blist_get_ui_ops();
-
- /* if we're moving to overtop of ourselves, do nothing */
- if (gnode == node) {
- if (!purplebuddylist->root)
- node = NULL;
- else
- return;
- }
-
- if (purple_find_group(group->name)) {
- /* This is just being moved */
-
- if (ops && ops->remove)
- ops->remove(purplebuddylist, (PurpleBlistNode *)group);
-
- if (gnode == purplebuddylist->root)
- purplebuddylist->root = gnode->next;
- if (gnode->prev)
- gnode->prev->next = gnode->next;
- if (gnode->next)
- gnode->next->prev = gnode->prev;
- } else {
- key = g_utf8_collate_key(group->name, -1);
- g_hash_table_insert(groups_cache, key, group);
- }
-
- if (node && PURPLE_BLIST_NODE_IS_GROUP(node)) {
- gnode->next = node->next;
- gnode->prev = node;
- if (node->next)
- node->next->prev = gnode;
- node->next = gnode;
- } else {
- if (purplebuddylist->root)
- purplebuddylist->root->prev = gnode;
- gnode->next = purplebuddylist->root;
- gnode->prev = NULL;
- purplebuddylist->root = gnode;
- }
-
- if (ops && ops->save_node) {
- ops->save_node(gnode);
- for (node = gnode->child; node; node = node->next)
- ops->save_node(node);
- }
-
- if (ops && ops->update) {
- ops->update(purplebuddylist, gnode);
- for (node = gnode->child; node; node = node->next)
- ops->update(purplebuddylist, node);
- }
-
- purple_signal_emit(purple_blist_get_handle(), "blist-node-added",
- gnode);
-}
-
-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) {
- /*
- * If this contact has children then remove them. When the last
- * buddy is removed from the contact, the contact is automatically
- * deleted.
- */
- while (node->child->next) {
- purple_blist_remove_buddy((PurpleBuddy*)node->child);
- }
- /*
- * Remove the last buddy and trigger the deletion of the contact.
- * It would probably be cleaner if contact-deletion was done after
- * a timeout? Or if it had to be done manually, like below?
- */
- purple_blist_remove_buddy((PurpleBuddy*)node->child);
- } else {
- /* Remove the node from its parent */
- if (gnode->child == node)
- gnode->child = node->next;
- if (node->prev)
- node->prev->next = node->next;
- if (node->next)
- node->next->prev = node->prev;
- group->totalsize--;
-
- /* Update the UI */
- if (ops && ops->remove)
- ops->remove(purplebuddylist, node);
-
- if (ops && ops->remove_node)
- ops->remove_node(node);
-
- purple_signal_emit(purple_blist_get_handle(), "blist-node-removed",
- PURPLE_BLIST_NODE(contact));
-
- /* Delete the node */
- purple_contact_destroy(contact);
- }
-}
-
-void purple_blist_remove_buddy(PurpleBuddy *buddy)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- PurpleBlistNode *node, *cnode, *gnode;
- PurpleContact *contact;
- PurpleGroup *group;
- struct _purple_hbuddy hb;
- GHashTable *account_buddies;
-
- g_return_if_fail(buddy != NULL);
-
- node = (PurpleBlistNode *)buddy;
- cnode = node->parent;
- gnode = (cnode != NULL) ? cnode->parent : NULL;
- contact = (PurpleContact *)cnode;
- group = (PurpleGroup *)gnode;
-
- /* Remove the node from its parent */
- if (node->prev)
- node->prev->next = node->next;
- if (node->next)
- node->next->prev = node->prev;
- if ((cnode != NULL) && (cnode->child == node))
- cnode->child = node->next;
-
- /* Adjust size counts */
- if (contact != NULL) {
- if (PURPLE_BUDDY_IS_ONLINE(buddy)) {
- contact->online--;
- if (contact->online == 0)
- group->online--;
- }
- if (purple_account_is_connected(buddy->account)) {
- contact->currentsize--;
- if (contact->currentsize == 0)
- group->currentsize--;
- }
- contact->totalsize--;
-
- /* Re-sort the contact */
- if (cnode->child && contact->priority == buddy) {
- purple_contact_invalidate_priority_buddy(contact);
- if (ops && ops->update)
- ops->update(purplebuddylist, cnode);
- }
- }
-
- /* Remove this buddy from the buddies hash table */
- hb.name = (gchar *)purple_normalize(buddy->account, buddy->name);
- hb.account = buddy->account;
- hb.group = gnode;
- g_hash_table_remove(purplebuddylist->buddies, &hb);
-
- account_buddies = g_hash_table_lookup(buddies_cache, buddy->account);
- g_hash_table_remove(account_buddies, &hb);
-
- /* Update the UI */
- if (ops && ops->remove)
- ops->remove(purplebuddylist, node);
-
- if (ops && ops->remove_node)
- ops->remove_node(node);
-
- /* Remove this buddy's pounces */
- purple_pounce_destroy_all_by_buddy(buddy);
-
- /* Signal that the buddy has been removed before freeing the memory for it */
- purple_signal_emit(purple_blist_get_handle(), "buddy-removed", buddy);
-
- purple_signal_emit(purple_blist_get_handle(), "blist-node-removed",
- PURPLE_BLIST_NODE(buddy));
-
- purple_buddy_destroy(buddy);
-
- /* If the contact is empty then remove it */
- if ((contact != NULL) && !cnode->child)
- purple_blist_remove_contact(contact);
-}
-
-void purple_blist_remove_chat(PurpleChat *chat)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- PurpleBlistNode *node, *gnode;
- PurpleGroup *group;
-
- g_return_if_fail(chat != NULL);
-
- node = (PurpleBlistNode *)chat;
- gnode = node->parent;
- group = (PurpleGroup *)gnode;
-
- if (gnode != NULL)
- {
- /* Remove the node from its parent */
- if (gnode->child == node)
- gnode->child = node->next;
- if (node->prev)
- node->prev->next = node->next;
- if (node->next)
- node->next->prev = node->prev;
-
- /* Adjust size counts */
- if (purple_account_is_connected(chat->account)) {
- group->online--;
- group->currentsize--;
- }
- group->totalsize--;
-
- }
-
- /* Update the UI */
- if (ops && ops->remove)
- ops->remove(purplebuddylist, node);
-
- if (ops && ops->remove_node)
- ops->remove_node(node);
-
- purple_signal_emit(purple_blist_get_handle(), "blist-node-removed",
- PURPLE_BLIST_NODE(chat));
-
- /* Delete the node */
- purple_chat_destroy(chat);
-}
-
-void purple_blist_remove_group(PurpleGroup *group)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- PurpleBlistNode *node;
- GList *l;
- gchar* key;
-
- g_return_if_fail(group != NULL);
-
- node = (PurpleBlistNode *)group;
-
- /* Make sure the group is empty */
- if (node->child)
- return;
-
- /* Remove the node from its parent */
- if (purplebuddylist->root == node)
- purplebuddylist->root = node->next;
- if (node->prev)
- node->prev->next = node->next;
- if (node->next)
- node->next->prev = node->prev;
-
- key = g_utf8_collate_key(group->name, -1);
- g_hash_table_remove(groups_cache, key);
- g_free(key);
-
- /* Update the UI */
- if (ops && ops->remove)
- ops->remove(purplebuddylist, node);
-
- if (ops && ops->remove_node)
- ops->remove_node(node);
-
- purple_signal_emit(purple_blist_get_handle(), "blist-node-removed",
- PURPLE_BLIST_NODE(group));
-
- /* Remove the group from all accounts that are online */
- for (l = purple_connections_get_all(); l != NULL; l = l->next)
- {
- PurpleConnection *gc = (PurpleConnection *)l->data;
-
- if (purple_connection_get_state(gc) == PURPLE_CONNECTED)
- purple_account_remove_group(purple_connection_get_account(gc), group);
- }
-
- /* Delete the node */
- purple_group_destroy(group);
-}
-
-PurpleBuddy *purple_contact_get_priority_buddy(PurpleContact *contact)
-{
- g_return_val_if_fail(contact != NULL, NULL);
-
- if (!contact->priority_valid)
- purple_contact_compute_priority_buddy(contact);
-
- return contact->priority;
-}
-
-const char *purple_buddy_get_alias_only(PurpleBuddy *buddy)
-{
- g_return_val_if_fail(buddy != NULL, NULL);
-
- if ((buddy->alias != NULL) && (*buddy->alias != '\0')) {
- return buddy->alias;
- } else if ((buddy->server_alias != NULL) &&
- (*buddy->server_alias != '\0')) {
-
- return buddy->server_alias;
- }
-
- return NULL;
-}
-
-
-const char *purple_buddy_get_contact_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 server alias */
- if ((buddy->server_alias) && (*buddy->server_alias))
- return buddy->server_alias;
-
- /* The buddy's user name (i.e. no alias) */
- return buddy->name;
-}
-
-
-const char *purple_buddy_get_alias(PurpleBuddy *buddy)
-{
- 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 server alias */
- if ((buddy->server_alias) && (*buddy->server_alias))
- return buddy->server_alias;
-
- /* The buddy's user name (i.e. no alias) */
- return buddy->name;
-}
-
-const char *purple_buddy_get_local_buddy_alias(PurpleBuddy *buddy)
-{
- g_return_val_if_fail(buddy, NULL);
- return buddy->alias;
-}
-
-const char *purple_buddy_get_server_alias(PurpleBuddy *buddy)
-{
- g_return_val_if_fail(buddy != NULL, NULL);
-
- if ((buddy->server_alias) && (*buddy->server_alias))
- return buddy->server_alias;
-
- return NULL;
-}
-
-const char *purple_chat_get_name(PurpleChat *chat)
-{
- char *ret = NULL;
- PurplePlugin *prpl;
- PurplePluginProtocolInfo *prpl_info = NULL;
-
- g_return_val_if_fail(chat != NULL, NULL);
-
- if ((chat->alias != NULL) && (*chat->alias != '\0'))
- return chat->alias;
-
- prpl = purple_find_prpl(purple_account_get_protocol_id(chat->account));
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
-
- if (prpl_info->chat_info) {
- struct proto_chat_entry *pce;
- GList *parts = prpl_info->chat_info(purple_account_get_connection(chat->account));
- pce = parts->data;
- ret = g_hash_table_lookup(chat->components, pce->identifier);
- g_list_foreach(parts, (GFunc)g_free, NULL);
- g_list_free(parts);
- }
-
- return ret;
-}
-
-PurpleBuddy *purple_find_buddy(PurpleAccount *account, const char *name)
-{
- PurpleBuddy *buddy;
- struct _purple_hbuddy hb;
- PurpleBlistNode *group;
-
- g_return_val_if_fail(purplebuddylist != NULL, NULL);
- g_return_val_if_fail(account != NULL, NULL);
- g_return_val_if_fail((name != NULL) && (*name != '\0'), NULL);
-
- hb.account = account;
- hb.name = (gchar *)purple_normalize(account, name);
-
- for (group = purplebuddylist->root; group; group = group->next) {
- if (!group->child)
- continue;
-
- hb.group = group;
- if ((buddy = g_hash_table_lookup(purplebuddylist->buddies, &hb))) {
- return buddy;
- }
- }
-
- return NULL;
-}
-
-PurpleBuddy *purple_find_buddy_in_group(PurpleAccount *account, const char *name,
- PurpleGroup *group)
-{
- struct _purple_hbuddy hb;
-
- g_return_val_if_fail(purplebuddylist != NULL, NULL);
- g_return_val_if_fail(account != NULL, NULL);
- g_return_val_if_fail((name != NULL) && (*name != '\0'), NULL);
-
- hb.name = (gchar *)purple_normalize(account, name);
- hb.account = account;
- hb.group = (PurpleBlistNode*)group;
-
- return g_hash_table_lookup(purplebuddylist->buddies, &hb);
-}
-
-static void find_acct_buddies(gpointer key, gpointer value, gpointer data)
-{
- PurpleBuddy *buddy = value;
- GSList **list = data;
-
- *list = g_slist_prepend(*list, buddy);
-}
-
-GSList *purple_find_buddies(PurpleAccount *account, const char *name)
-{
- PurpleBuddy *buddy;
- PurpleBlistNode *node;
- GSList *ret = NULL;
-
- g_return_val_if_fail(purplebuddylist != NULL, NULL);
- g_return_val_if_fail(account != NULL, NULL);
-
- if ((name != NULL) && (*name != '\0')) {
- struct _purple_hbuddy hb;
-
- hb.name = (gchar *)purple_normalize(account, name);
- hb.account = account;
-
- for (node = purplebuddylist->root; node != NULL; node = node->next) {
- if (!node->child)
- continue;
-
- hb.group = node;
- if ((buddy = g_hash_table_lookup(purplebuddylist->buddies, &hb)) != NULL)
- ret = g_slist_prepend(ret, buddy);
- }
- } else {
- GSList *list = NULL;
- GHashTable *buddies = g_hash_table_lookup(buddies_cache, account);
- g_hash_table_foreach(buddies, find_acct_buddies, &list);
- ret = list;
- }
-
- return ret;
-}
-
-PurpleGroup *purple_find_group(const char *name)
-{
- gchar* key;
- PurpleGroup *group;
-
- g_return_val_if_fail(purplebuddylist != NULL, NULL);
- g_return_val_if_fail((name != NULL) && (*name != '\0'), NULL);
-
- key = g_utf8_collate_key(name, -1);
- group = g_hash_table_lookup(groups_cache, key);
- g_free(key);
-
- return group;
-}
-
-PurpleChat *
-purple_blist_find_chat(PurpleAccount *account, const char *name)
-{
- char *chat_name;
- PurpleChat *chat;
- PurplePlugin *prpl;
- PurplePluginProtocolInfo *prpl_info = NULL;
- struct proto_chat_entry *pce;
- PurpleBlistNode *node, *group;
- GList *parts;
- char *normname;
-
- g_return_val_if_fail(purplebuddylist != NULL, NULL);
- g_return_val_if_fail((name != NULL) && (*name != '\0'), NULL);
-
- if (!purple_account_is_connected(account))
- return NULL;
-
- prpl = purple_find_prpl(purple_account_get_protocol_id(account));
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
-
- if (prpl_info->find_blist_chat != NULL)
- return prpl_info->find_blist_chat(account, name);
-
- normname = g_strdup(purple_normalize(account, name));
- for (group = purplebuddylist->root; group != NULL; group = group->next) {
- for (node = group->child; node != NULL; node = node->next) {
- if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
-
- chat = (PurpleChat*)node;
-
- if (account != chat->account)
- continue;
-
- parts = prpl_info->chat_info(
- purple_account_get_connection(chat->account));
-
- pce = parts->data;
- chat_name = g_hash_table_lookup(chat->components,
- pce->identifier);
- g_list_foreach(parts, (GFunc)g_free, NULL);
- g_list_free(parts);
-
- if (chat->account == account && chat_name != NULL &&
- normname != NULL && !strcmp(purple_normalize(account, chat_name), normname)) {
- g_free(normname);
- return chat;
- }
- }
- }
- }
-
- g_free(normname);
- return NULL;
-}
-
-PurpleGroup *
-purple_chat_get_group(PurpleChat *chat)
-{
- g_return_val_if_fail(chat != NULL, NULL);
-
- return (PurpleGroup *)(((PurpleBlistNode *)chat)->parent);
-}
-
-PurpleAccount *
-purple_chat_get_account(PurpleChat *chat)
-{
- g_return_val_if_fail(chat != NULL, NULL);
-
- return chat->account;
-}
-
-GHashTable *
-purple_chat_get_components(PurpleChat *chat)
-{
- g_return_val_if_fail(chat != NULL, NULL);
-
- return chat->components;
-}
-
-PurpleContact *purple_buddy_get_contact(PurpleBuddy *buddy)
-{
- g_return_val_if_fail(buddy != NULL, NULL);
-
- return PURPLE_CONTACT(PURPLE_BLIST_NODE(buddy)->parent);
-}
-
-PurplePresence *purple_buddy_get_presence(const PurpleBuddy *buddy)
-{
- g_return_val_if_fail(buddy != NULL, NULL);
- return buddy->presence;
-}
-
-PurpleMediaCaps purple_buddy_get_media_caps(const PurpleBuddy *buddy)
-{
- g_return_val_if_fail(buddy != NULL, 0);
- return buddy->media_caps;
-}
-
-void purple_buddy_set_media_caps(PurpleBuddy *buddy, PurpleMediaCaps media_caps)
-{
- g_return_if_fail(buddy != NULL);
- buddy->media_caps = media_caps;
-}
-
-PurpleGroup *purple_buddy_get_group(PurpleBuddy *buddy)
-{
- g_return_val_if_fail(buddy != NULL, NULL);
-
- if (((PurpleBlistNode *)buddy)->parent == NULL)
- return NULL;
-
- return (PurpleGroup *)(((PurpleBlistNode*)buddy)->parent->parent);
-}
-
-GSList *purple_group_get_accounts(PurpleGroup *group)
-{
- GSList *l = NULL;
- PurpleBlistNode *gnode, *cnode, *bnode;
-
- gnode = (PurpleBlistNode *)group;
-
- for (cnode = gnode->child; cnode; cnode = cnode->next) {
- if (PURPLE_BLIST_NODE_IS_CHAT(cnode)) {
- if (!g_slist_find(l, ((PurpleChat *)cnode)->account))
- l = g_slist_append(l, ((PurpleChat *)cnode)->account);
- } else if (PURPLE_BLIST_NODE_IS_CONTACT(cnode)) {
- for (bnode = cnode->child; bnode; bnode = bnode->next) {
- if (PURPLE_BLIST_NODE_IS_BUDDY(bnode)) {
- if (!g_slist_find(l, ((PurpleBuddy *)bnode)->account))
- l = g_slist_append(l, ((PurpleBuddy *)bnode)->account);
- }
- }
- }
- }
-
- return l;
-}
-
-void purple_blist_add_account(PurpleAccount *account)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- PurpleBlistNode *gnode, *cnode, *bnode;
-
- g_return_if_fail(purplebuddylist != NULL);
-
- if (!ops || !ops->update)
- return;
-
- for (gnode = purplebuddylist->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)) {
- gboolean recompute = FALSE;
- for (bnode = cnode->child; bnode; bnode = bnode->next) {
- if (PURPLE_BLIST_NODE_IS_BUDDY(bnode) &&
- ((PurpleBuddy*)bnode)->account == account) {
- recompute = TRUE;
- ((PurpleContact*)cnode)->currentsize++;
- if (((PurpleContact*)cnode)->currentsize == 1)
- ((PurpleGroup*)gnode)->currentsize++;
- ops->update(purplebuddylist, bnode);
- }
- }
- if (recompute ||
- purple_blist_node_get_bool(cnode, "show_offline")) {
- purple_contact_invalidate_priority_buddy((PurpleContact*)cnode);
- ops->update(purplebuddylist, cnode);
- }
- } else if (PURPLE_BLIST_NODE_IS_CHAT(cnode) &&
- ((PurpleChat*)cnode)->account == account) {
- ((PurpleGroup *)gnode)->online++;
- ((PurpleGroup *)gnode)->currentsize++;
- ops->update(purplebuddylist, cnode);
- }
- }
- ops->update(purplebuddylist, gnode);
- }
-}
-
-void purple_blist_remove_account(PurpleAccount *account)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- PurpleBlistNode *gnode, *cnode, *bnode;
- PurpleBuddy *buddy;
- PurpleChat *chat;
- PurpleContact *contact;
- PurpleGroup *group;
- GList *list = NULL, *iter = NULL;
-
- g_return_if_fail(purplebuddylist != NULL);
-
- for (gnode = purplebuddylist->root; gnode; gnode = gnode->next) {
- if (!PURPLE_BLIST_NODE_IS_GROUP(gnode))
- continue;
-
- group = (PurpleGroup *)gnode;
-
- for (cnode = gnode->child; cnode; cnode = cnode->next) {
- if (PURPLE_BLIST_NODE_IS_CONTACT(cnode)) {
- gboolean recompute = FALSE;
- contact = (PurpleContact *)cnode;
-
- for (bnode = cnode->child; bnode; bnode = bnode->next) {
- if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode))
- continue;
-
- buddy = (PurpleBuddy *)bnode;
- if (account == buddy->account) {
- PurplePresence *presence;
-
- presence = purple_buddy_get_presence(buddy);
-
- if(purple_presence_is_online(presence)) {
- contact->online--;
- if (contact->online == 0)
- group->online--;
-
- purple_blist_node_set_int(&buddy->node,
- "last_seen", time(NULL));
- }
-
- contact->currentsize--;
- if (contact->currentsize == 0)
- group->currentsize--;
-
- if (!g_list_find(list, presence))
- list = g_list_prepend(list, presence);
-
- if (contact->priority == buddy)
- purple_contact_invalidate_priority_buddy(contact);
- else
- recompute = TRUE;
-
- if (ops && ops->remove) {
- ops->remove(purplebuddylist, bnode);
- }
- }
- }
- if (recompute) {
- purple_contact_invalidate_priority_buddy(contact);
- if (ops && ops->update)
- ops->update(purplebuddylist, cnode);
- }
- } else if (PURPLE_BLIST_NODE_IS_CHAT(cnode)) {
- chat = (PurpleChat *)cnode;
-
- if(chat->account == account) {
- group->currentsize--;
- group->online--;
-
- if (ops && ops->remove)
- ops->remove(purplebuddylist, cnode);
- }
- }
- }
- }
-
- for (iter = list; iter; iter = iter->next)
- {
- purple_presence_set_status_active(iter->data, "offline", TRUE);
- }
- g_list_free(list);
-}
-
-gboolean purple_group_on_account(PurpleGroup *g, PurpleAccount *account)
-{
- PurpleBlistNode *cnode;
- for (cnode = ((PurpleBlistNode *)g)->child; cnode; cnode = cnode->next) {
- if (PURPLE_BLIST_NODE_IS_CONTACT(cnode)) {
- if(purple_contact_on_account((PurpleContact *) cnode, account))
- return TRUE;
- } else if (PURPLE_BLIST_NODE_IS_CHAT(cnode)) {
- PurpleChat *chat = (PurpleChat *)cnode;
- if ((!account && purple_account_is_connected(chat->account))
- || chat->account == account)
- return TRUE;
- }
- }
- return FALSE;
-}
-
-const char *purple_group_get_name(PurpleGroup *group)
-{
- g_return_val_if_fail(group != NULL, NULL);
-
- return group->name;
-}
-
-void
-purple_blist_request_add_buddy(PurpleAccount *account, const char *username,
- const char *group, const char *alias)
-{
- PurpleBlistUiOps *ui_ops;
-
- ui_ops = purple_blist_get_ui_ops();
-
- if (ui_ops != NULL && ui_ops->request_add_buddy != NULL)
- ui_ops->request_add_buddy(account, username, group, alias);
-}
-
-void
-purple_blist_request_add_chat(PurpleAccount *account, PurpleGroup *group,
- const char *alias, const char *name)
-{
- PurpleBlistUiOps *ui_ops;
-
- ui_ops = purple_blist_get_ui_ops();
-
- if (ui_ops != NULL && ui_ops->request_add_chat != NULL)
- ui_ops->request_add_chat(account, group, alias, name);
-}
-
-void
-purple_blist_request_add_group(void)
-{
- PurpleBlistUiOps *ui_ops;
-
- ui_ops = purple_blist_get_ui_ops();
-
- if (ui_ops != NULL && ui_ops->request_add_group != NULL)
- ui_ops->request_add_group();
-}
-
-static void
-purple_blist_node_destroy(PurpleBlistNode *node)
-{
- PurpleBlistUiOps *ui_ops;
- PurpleBlistNode *child, *next_child;
-
- ui_ops = purple_blist_get_ui_ops();
- child = node->child;
- while (child) {
- next_child = child->next;
- purple_blist_node_destroy(child);
- child = next_child;
- }
-
- /* Allow the UI to free data */
- node->parent = NULL;
- node->child = NULL;
- node->next = NULL;
- node->prev = NULL;
- if (ui_ops && ui_ops->remove)
- ui_ops->remove(purplebuddylist, node);
-
- if (PURPLE_BLIST_NODE_IS_BUDDY(node))
- purple_buddy_destroy((PurpleBuddy*)node);
- else if (PURPLE_BLIST_NODE_IS_CHAT(node))
- purple_chat_destroy((PurpleChat*)node);
- else if (PURPLE_BLIST_NODE_IS_CONTACT(node))
- purple_contact_destroy((PurpleContact*)node);
- else if (PURPLE_BLIST_NODE_IS_GROUP(node))
- purple_group_destroy((PurpleGroup*)node);
-}
-
-static void
-purple_blist_node_setting_free(gpointer data)
-{
- PurpleValue *value;
-
- value = (PurpleValue *)data;
-
- purple_value_destroy(value);
-}
-
-static void purple_blist_node_initialize_settings(PurpleBlistNode *node)
-{
- if (node->settings)
- return;
-
- node->settings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
- (GDestroyNotify)purple_blist_node_setting_free);
-}
-
-void purple_blist_node_remove_setting(PurpleBlistNode *node, const char *key)
-{
- PurpleBlistUiOps *ops;
- g_return_if_fail(node != NULL);
- g_return_if_fail(node->settings != NULL);
- g_return_if_fail(key != NULL);
-
- g_hash_table_remove(node->settings, key);
-
- ops = purple_blist_get_ui_ops();
- if (ops && ops->save_node)
- ops->save_node(node);
-}
-
-void
-purple_blist_node_set_flags(PurpleBlistNode *node, PurpleBlistNodeFlags flags)
-{
- g_return_if_fail(node != NULL);
-
- node->flags = flags;
-}
-
-PurpleBlistNodeFlags
-purple_blist_node_get_flags(PurpleBlistNode *node)
-{
- g_return_val_if_fail(node != NULL, 0);
-
- return node->flags;
-}
-
-PurpleBlistNodeType
-purple_blist_node_get_type(PurpleBlistNode *node)
-{
- g_return_val_if_fail(node != NULL, PURPLE_BLIST_OTHER_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)
-{
- PurpleValue *value;
- PurpleBlistUiOps *ops;
-
- g_return_if_fail(node != NULL);
- g_return_if_fail(node->settings != NULL);
- g_return_if_fail(key != NULL);
-
- value = purple_value_new(PURPLE_TYPE_BOOLEAN);
- purple_value_set_boolean(value, data);
-
- g_hash_table_replace(node->settings, g_strdup(key), value);
-
- ops = purple_blist_get_ui_ops();
- if (ops && ops->save_node)
- ops->save_node(node);
-}
-
-gboolean
-purple_blist_node_get_bool(PurpleBlistNode* node, const char *key)
-{
- PurpleValue *value;
-
- 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);
-
- value = g_hash_table_lookup(node->settings, key);
-
- if (value == NULL)
- return FALSE;
-
- g_return_val_if_fail(purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN, FALSE);
-
- return purple_value_get_boolean(value);
-}
-
-void
-purple_blist_node_set_int(PurpleBlistNode* node, const char *key, int data)
-{
- PurpleValue *value;
- PurpleBlistUiOps *ops;
-
- g_return_if_fail(node != NULL);
- g_return_if_fail(node->settings != NULL);
- g_return_if_fail(key != NULL);
-
- value = purple_value_new(PURPLE_TYPE_INT);
- purple_value_set_int(value, data);
-
- g_hash_table_replace(node->settings, g_strdup(key), value);
-
- ops = purple_blist_get_ui_ops();
- if (ops && ops->save_node)
- ops->save_node(node);
-}
-
-int
-purple_blist_node_get_int(PurpleBlistNode* node, const char *key)
-{
- PurpleValue *value;
-
- g_return_val_if_fail(node != NULL, 0);
- g_return_val_if_fail(node->settings != NULL, 0);
- g_return_val_if_fail(key != NULL, 0);
-
- value = g_hash_table_lookup(node->settings, key);
-
- if (value == NULL)
- return 0;
-
- g_return_val_if_fail(purple_value_get_type(value) == PURPLE_TYPE_INT, 0);
-
- return purple_value_get_int(value);
-}
-
-void
-purple_blist_node_set_string(PurpleBlistNode* node, const char *key, const char *data)
-{
- PurpleValue *value;
- PurpleBlistUiOps *ops;
-
- g_return_if_fail(node != NULL);
- g_return_if_fail(node->settings != NULL);
- g_return_if_fail(key != NULL);
-
- value = purple_value_new(PURPLE_TYPE_STRING);
- purple_value_set_string(value, data);
-
- g_hash_table_replace(node->settings, g_strdup(key), value);
-
- ops = purple_blist_get_ui_ops();
- if (ops && ops->save_node)
- ops->save_node(node);
-}
-
-const char *
-purple_blist_node_get_string(PurpleBlistNode* node, const char *key)
-{
- PurpleValue *value;
-
- g_return_val_if_fail(node != NULL, NULL);
- g_return_val_if_fail(node->settings != NULL, NULL);
- g_return_val_if_fail(key != NULL, NULL);
-
- value = g_hash_table_lookup(node->settings, key);
-
- if (value == NULL)
- return NULL;
-
- g_return_val_if_fail(purple_value_get_type(value) == PURPLE_TYPE_STRING, NULL);
-
- return purple_value_get_string(value);
-}
-
-GList *
-purple_blist_node_get_extended_menu(PurpleBlistNode *n)
-{
- GList *menu = NULL;
-
- g_return_val_if_fail(n != NULL, NULL);
-
- purple_signal_emit(purple_blist_get_handle(),
- "blist-node-extended-menu",
- n, &menu);
- return menu;
-}
-
-int purple_blist_get_group_size(PurpleGroup *group, gboolean offline)
-{
- if (!group)
- return 0;
-
- return offline ? group->totalsize : group->currentsize;
-}
-
-int purple_blist_get_group_online_count(PurpleGroup *group)
-{
- if (!group)
- return 0;
-
- return group->online;
-}
-
-void
-purple_blist_set_ui_ops(PurpleBlistUiOps *ops)
-{
- gboolean overrode = FALSE;
- blist_ui_ops = ops;
-
- if (!ops)
- return;
-
- if (!ops->save_node) {
- ops->save_node = purple_blist_save_node;
- overrode = TRUE;
- }
- if (!ops->remove_node) {
- ops->remove_node = purple_blist_save_node;
- overrode = TRUE;
- }
- if (!ops->save_account) {
- ops->save_account = purple_blist_save_account;
- overrode = TRUE;
- }
-
- if (overrode && (ops->save_node != purple_blist_save_node ||
- ops->remove_node != purple_blist_save_node ||
- ops->save_account != purple_blist_save_account)) {
- purple_debug_warning("blist", "Only some of the blist saving UI ops "
- "were overridden. This probably is not what you want!\n");
- }
-}
-
-PurpleBlistUiOps *
-purple_blist_get_ui_ops(void)
-{
- return blist_ui_ops;
-}
-
-
-void *
-purple_blist_get_handle(void)
-{
- static int handle;
-
- return &handle;
-}
-
-void
-purple_blist_init(void)
-{
- void *handle = purple_blist_get_handle();
-
- purple_signal_register(handle, "buddy-status-changed",
- purple_marshal_VOID__POINTER_POINTER_POINTER, NULL,
- 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST_BUDDY),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_STATUS),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_STATUS));
- purple_signal_register(handle, "buddy-privacy-changed",
- purple_marshal_VOID__POINTER, NULL,
- 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST_BUDDY));
-
- purple_signal_register(handle, "buddy-idle-changed",
- purple_marshal_VOID__POINTER_INT_INT, NULL,
- 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST_BUDDY),
- purple_value_new(PURPLE_TYPE_INT),
- purple_value_new(PURPLE_TYPE_INT));
-
-
- purple_signal_register(handle, "buddy-signed-on",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST_BUDDY));
-
- purple_signal_register(handle, "buddy-signed-off",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST_BUDDY));
-
- purple_signal_register(handle, "buddy-got-login-time",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST_BUDDY));
-
- purple_signal_register(handle, "blist-node-added",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST_NODE));
-
- purple_signal_register(handle, "blist-node-removed",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST_NODE));
-
- purple_signal_register(handle, "buddy-added",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST_BUDDY));
-
- purple_signal_register(handle, "buddy-removed",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST_BUDDY));
-
- purple_signal_register(handle, "buddy-icon-changed",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST_BUDDY));
-
- purple_signal_register(handle, "update-idle", purple_marshal_VOID, NULL, 0);
-
- purple_signal_register(handle, "blist-node-extended-menu",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST_NODE),
- purple_value_new(PURPLE_TYPE_BOXED, "GList **"));
-
- purple_signal_register(handle, "blist-node-aliased",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST_NODE),
- purple_value_new(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "buddy-caps-changed",
- purple_marshal_VOID__POINTER_INT_INT, NULL,
- 3, purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST_BUDDY),
- purple_value_new(PURPLE_TYPE_INT),
- purple_value_new(PURPLE_TYPE_INT));
-
- purple_signal_connect(purple_accounts_get_handle(), "account-created",
- handle,
- PURPLE_CALLBACK(purple_blist_buddies_cache_add_account),
- NULL);
-
- purple_signal_connect(purple_accounts_get_handle(), "account-destroying",
- handle,
- PURPLE_CALLBACK(purple_blist_buddies_cache_remove_account),
- NULL);
-}
-
-void
-purple_blist_uninit(void)
-{
- PurpleBlistNode *node, *next_node;
-
- /* This happens if we quit before purple_set_blist is called. */
- if (purplebuddylist == NULL)
- return;
-
- if (save_timer != 0) {
- purple_timeout_remove(save_timer);
- save_timer = 0;
- purple_blist_sync();
- }
-
- purple_blist_destroy();
-
- node = purple_blist_get_root();
- while (node) {
- next_node = node->next;
- purple_blist_node_destroy(node);
- node = next_node;
- }
- purplebuddylist->root = NULL;
-
- g_hash_table_destroy(purplebuddylist->buddies);
- g_hash_table_destroy(buddies_cache);
- g_hash_table_destroy(groups_cache);
-
- buddies_cache = NULL;
- groups_cache = NULL;
-
- PURPLE_DBUS_UNREGISTER_POINTER(purplebuddylist);
- g_free(purplebuddylist);
- purplebuddylist = NULL;
-
- purple_signals_disconnect_by_handle(purple_blist_get_handle());
- purple_signals_unregister_by_instance(purple_blist_get_handle());
-}
diff --git a/libpurple/blist.h b/libpurple/blist.h
deleted file mode 100644
index eddbef948d..0000000000
--- a/libpurple/blist.h
+++ /dev/null
@@ -1,1204 +0,0 @@
-/**
- * @file blist.h Buddy List API
- * @ingroup core
- * @see @ref blist-signals
- */
-
-/* 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 _PURPLE_BLIST_H_
-#define _PURPLE_BLIST_H_
-
-/* I can't believe I let ChipX86 inspire me to write good code. -Sean */
-
-#include <glib.h>
-
-/** @copydoc _PurpleBuddyList */
-typedef struct _PurpleBuddyList PurpleBuddyList;
-/** @copydoc _PurpleBlistUiOps */
-typedef struct _PurpleBlistUiOps PurpleBlistUiOps;
-/** @copydoc _PurpleBlistNode */
-typedef struct _PurpleBlistNode PurpleBlistNode;
-
-/** @copydoc _PurpleChat */
-typedef struct _PurpleChat PurpleChat;
-/** @copydoc _PurpleGroup */
-typedef struct _PurpleGroup PurpleGroup;
-/** @copydoc _PurpleContact */
-typedef struct _PurpleContact PurpleContact;
-/** @copydoc _PurpleBuddy */
-typedef struct _PurpleBuddy PurpleBuddy;
-
-/**************************************************************************/
-/* Enumerations */
-/**************************************************************************/
-typedef enum
-{
- PURPLE_BLIST_GROUP_NODE,
- PURPLE_BLIST_CONTACT_NODE,
- PURPLE_BLIST_BUDDY_NODE,
- PURPLE_BLIST_CHAT_NODE,
- PURPLE_BLIST_OTHER_NODE
-
-} PurpleBlistNodeType;
-
-#define PURPLE_BLIST_NODE_IS_CHAT(n) (purple_blist_node_get_type(n) == PURPLE_BLIST_CHAT_NODE)
-#define PURPLE_BLIST_NODE_IS_BUDDY(n) (purple_blist_node_get_type(n) == PURPLE_BLIST_BUDDY_NODE)
-#define PURPLE_BLIST_NODE_IS_CONTACT(n) (purple_blist_node_get_type(n) == PURPLE_BLIST_CONTACT_NODE)
-#define PURPLE_BLIST_NODE_IS_GROUP(n) (purple_blist_node_get_type(n) == PURPLE_BLIST_GROUP_NODE)
-
-#define PURPLE_BUDDY_IS_ONLINE(b) \
- ((b) != NULL && purple_account_is_connected(purple_buddy_get_account(b)) && \
- purple_presence_is_online(purple_buddy_get_presence(b)))
-
-typedef enum
-{
- PURPLE_BLIST_NODE_FLAG_NO_SAVE = 1 << 0 /**< node should not be saved with the buddy list */
-
-} PurpleBlistNodeFlags;
-
-#define PURPLE_BLIST_NODE(obj) ((PurpleBlistNode *)(obj))
-
-#define PURPLE_BLIST_NODE_HAS_FLAG(b, f) (purple_blist_node_get_flags((PurpleBlistNode*)(b)) & (f))
-#define PURPLE_BLIST_NODE_SHOULD_SAVE(b) (! PURPLE_BLIST_NODE_HAS_FLAG(b, PURPLE_BLIST_NODE_FLAG_NO_SAVE))
-
-#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)
-
-#define PURPLE_GROUP(obj) ((PurpleGroup *)(obj))
-
-#define PURPLE_CONTACT(obj) ((PurpleContact *)(obj))
-
-#define PURPLE_BUDDY(obj) ((PurpleBuddy *)(obj))
-
-#define PURPLE_CHAT(obj) ((PurpleChat *)(obj))
-
-#include "account.h"
-#include "buddyicon.h"
-#include "media.h"
-#include "status.h"
-
-/**************************************************************************/
-/* Data Structures */
-/**************************************************************************/
-
-#if !(defined PURPLE_HIDE_STRUCTS) || (defined _PURPLE_BLIST_C_)
-
-/**
- * A Buddy list node. This can represent a group, a buddy, or anything else.
- * This is a base class for PurpleBuddy, PurpleContact, PurpleGroup, and for
- * anything else that wants to put itself in the buddy list. */
-struct _PurpleBlistNode {
- PurpleBlistNodeType type; /**< The type of node this is */
- PurpleBlistNode *prev; /**< The sibling before this buddy. */
- PurpleBlistNode *next; /**< The sibling after this buddy. */
- PurpleBlistNode *parent; /**< The parent of this node */
- PurpleBlistNode *child; /**< The child of this node */
- GHashTable *settings; /**< per-node settings */
- void *ui_data; /**< The UI can put data here. */
- PurpleBlistNodeFlags flags; /**< The buddy flags */
-};
-
-/**
- * A buddy. This contains everything Purple will ever need to know about someone on the buddy list. Everything.
- */
-struct _PurpleBuddy {
- PurpleBlistNode node; /**< The node that this buddy inherits from */
- char *name; /**< The name of the buddy. */
- char *alias; /**< The user-set alias of the buddy */
- char *server_alias; /**< The server-specified alias of the buddy. (i.e. MSN "Friendly Names") */
- void *proto_data; /**< This allows the prpl to associate whatever data it wants with a buddy */
- PurpleBuddyIcon *icon; /**< The buddy icon. */
- PurpleAccount *account; /**< the account this buddy belongs to */
- PurplePresence *presence;
- PurpleMediaCaps media_caps; /**< The media capabilities of the buddy. */
-};
-
-/**
- * A contact. This contains everything Purple will ever need to know about a contact.
- */
-struct _PurpleContact {
- PurpleBlistNode node; /**< The node that this contact inherits from. */
- char *alias; /**< The user-set alias of the contact */
- int totalsize; /**< The number of buddies in this contact */
- int currentsize; /**< The number of buddies in this contact corresponding to online accounts */
- int online; /**< The number of buddies in this contact who are currently online */
- PurpleBuddy *priority; /**< The "top" buddy for this contact */
- gboolean priority_valid; /**< Is priority valid? */
-};
-
-
-/**
- * A group. This contains everything Purple will ever need to know about a group.
- */
-struct _PurpleGroup {
- PurpleBlistNode node; /**< The node that this group inherits from */
- char *name; /**< The name of this group. */
- int totalsize; /**< The number of chats and contacts in this group */
- int currentsize; /**< The number of chats and contacts in this group corresponding to online accounts */
- int online; /**< The number of chats and contacts in this group who are currently online */
-};
-
-/**
- * A chat. This contains everything Purple needs to put a chat room in the
- * buddy list.
- */
-struct _PurpleChat {
- PurpleBlistNode node; /**< The node that this chat inherits from */
- char *alias; /**< The display name of this chat. */
- GHashTable *components; /**< the stuff the protocol needs to know to join the chat */
- PurpleAccount *account; /**< The account this chat is attached to */
-};
-
-/**
- * The Buddy List
- */
-struct _PurpleBuddyList {
- PurpleBlistNode *root; /**< The first node in the buddy list */
- GHashTable *buddies; /**< Every buddy in this list */
- void *ui_data; /**< UI-specific data. */
-};
-
-#endif /* PURPLE_HIDE_STRUCTS && PURPLE_BLIST_STRUCTS */
-
-/**
- * Buddy list UI operations.
- *
- * Any UI representing a buddy list must assign a filled-out PurpleBlistUiOps
- * structure to the buddy list core.
- */
-struct _PurpleBlistUiOps
-{
- void (*new_list)(PurpleBuddyList *list); /**< Sets UI-specific data on a buddy list. */
- void (*new_node)(PurpleBlistNode *node); /**< Sets UI-specific data on a node. */
- void (*show)(PurpleBuddyList *list); /**< The core will call this when it's finished doing its core stuff */
- void (*update)(PurpleBuddyList *list,
- PurpleBlistNode *node); /**< This will update a node in the buddy list. */
- void (*remove)(PurpleBuddyList *list,
- PurpleBlistNode *node); /**< This removes a node from the list */
- void (*destroy)(PurpleBuddyList *list); /**< When the list is destroyed, this is called to destroy the UI. */
- void (*set_visible)(PurpleBuddyList *list,
- gboolean show); /**< Hides or unhides the buddy list */
- void (*request_add_buddy)(PurpleAccount *account, const char *username,
- const char *group, const char *alias);
- void (*request_add_chat)(PurpleAccount *account, PurpleGroup *group,
- const char *alias, const char *name);
- void (*request_add_group)(void);
-
- /**
- * This is called when a node has been modified and should be saved.
- *
- * Implementation of this UI op is OPTIONAL. If not implemented, it will
- * be set to a fallback function that saves data to blist.xml like in
- * previous libpurple versions.
- *
- * @param node The node which has been modified.
- */
- void (*save_node)(PurpleBlistNode *node);
-
- /**
- * Called when a node is about to be removed from the buddy list.
- * The UI op should update the relevant data structures to remove this
- * node (for example, removing a buddy from the group this node is in).
- *
- * Implementation of this UI op is OPTIONAL. If not implemented, it will
- * be set to a fallback function that saves data to blist.xml like in
- * previous libpurple versions.
- *
- * @param node The node which has been modified.
- */
- void (*remove_node)(PurpleBlistNode *node);
-
- /**
- * Called to save all the data for an account. If the UI sets this,
- * the callback must save the privacy and buddy list data for an account.
- * If the account is NULL, save the data for all accounts.
- *
- * Implementation of this UI op is OPTIONAL. If not implemented, it will
- * be set to a fallback function that saves data to blist.xml like in
- * previous libpurple versions.
- *
- * @param account The account whose data to save. If NULL, save all data
- * for all accounts.
- */
- void (*save_account)(PurpleAccount *account);
-
- void (*_purple_reserved1)(void);
-};
-
-G_BEGIN_DECLS
-
-/**************************************************************************/
-/** @name Buddy List API */
-/**************************************************************************/
-/*@{*/
-
-/**
- * Returns the main buddy list.
- *
- * @return The main buddy list.
- */
-PurpleBuddyList *purple_get_blist(void);
-
-/**
- * Returns the root node of the main buddy list.
- *
- * @return The root node.
- */
-PurpleBlistNode *purple_blist_get_root(void);
-
-/**
- * Returns a list of every buddy in the list. Use of this function is
- * discouraged if you do not actually need every buddy in the list. Use
- * purple_find_buddies instead.
- *
- * @return A list of every buddy in the list. Caller is responsible for
- * freeing the list.
- *
- * @see purple_find_buddies
- */
-GSList *purple_blist_get_buddies(void);
-
-/**
- * Returns the UI data for the list.
- *
- * @return The UI data for the list.
- */
-gpointer purple_blist_get_ui_data(void);
-
-/**
- * Sets the UI data for the list.
- *
- * @param ui_data The UI data for the list.
- */
-void purple_blist_set_ui_data(gpointer ui_data);
-
-/**
- * Returns the next node of a given node. This function is to be used to iterate
- * over the tree returned by purple_get_blist.
- *
- * @param node A node.
- * @param offline Whether to include nodes for offline accounts
- * @return The next node
- * @see purple_blist_node_get_parent
- * @see purple_blist_node_get_first_child
- * @see purple_blist_node_get_sibling_next
- * @see purple_blist_node_get_sibling_prev
- */
-PurpleBlistNode *purple_blist_node_next(PurpleBlistNode *node, gboolean offline);
-
-/**
- * Returns the parent node of a given node.
- *
- * @param node A node.
- * @return The parent node.
- *
- * @see purple_blist_node_get_first_child
- * @see purple_blist_node_get_sibling_next
- * @see purple_blist_node_get_sibling_prev
- * @see purple_blist_node_next
- */
-PurpleBlistNode *purple_blist_node_get_parent(PurpleBlistNode *node);
-
-/**
- * Returns the the first child node of a given node.
- *
- * @param node A node.
- * @return The child node.
- *
- * @see purple_blist_node_get_parent
- * @see purple_blist_node_get_sibling_next
- * @see purple_blist_node_get_sibling_prev
- * @see purple_blist_node_next
- */
-PurpleBlistNode *purple_blist_node_get_first_child(PurpleBlistNode *node);
-
-/**
- * Returns the sibling node of a given node.
- *
- * @param node A node.
- * @return The sibling node.
- *
- * @see purple_blist_node_get_parent
- * @see purple_blist_node_get_first_child
- * @see purple_blist_node_get_sibling_prev
- * @see purple_blist_node_next
- */
-PurpleBlistNode *purple_blist_node_get_sibling_next(PurpleBlistNode *node);
-
-/**
- * Returns the previous sibling node of a given node.
- *
- * @param node A node.
- * @return The sibling node.
- *
- * @see purple_blist_node_get_parent
- * @see purple_blist_node_get_first_child
- * @see purple_blist_node_get_sibling_next
- * @see purple_blist_node_next
- */
-PurpleBlistNode *purple_blist_node_get_sibling_prev(PurpleBlistNode *node);
-
-/**
- * Returns the UI data of a given node.
- *
- * @param node The node.
- * @return The UI data.
- */
-gpointer purple_blist_node_get_ui_data(const PurpleBlistNode *node);
-
-/**
- * Sets the UI data of a given node.
- *
- * @param node The node.
- * @param ui_data The UI data.
- */
-void purple_blist_node_set_ui_data(PurpleBlistNode *node, gpointer ui_data);
-
-/**
- * Shows the buddy list, creating a new one if necessary.
- */
-void purple_blist_show(void);
-
-
-/**
- * Destroys the buddy list window.
- *
- * @deprecated The UI is responsible for cleaning up the
- * PurpleBuddyList->ui_data. purple_blist_uninit() will free the
- * PurpleBuddyList* itself.
- */
-void purple_blist_destroy(void);
-
-/**
- * Hides or unhides the buddy list.
- *
- * @param show Whether or not to show the buddy list
- */
-void purple_blist_set_visible(gboolean show);
-
-/**
- * Updates a buddy's status.
- *
- * This should only be called from within Purple.
- *
- * @param buddy The buddy whose status has changed.
- * @param old_status The status from which we are changing.
- */
-void purple_blist_update_buddy_status(PurpleBuddy *buddy, PurpleStatus *old_status);
-
-/**
- * Updates a node's custom icon.
- *
- * @param node The PurpleBlistNode whose custom icon has changed.
- */
-void purple_blist_update_node_icon(PurpleBlistNode *node);
-
-/**
- * Renames a buddy in the buddy list.
- *
- * @param buddy The buddy whose name will be changed.
- * @param name The new name of the buddy.
- */
-void purple_blist_rename_buddy(PurpleBuddy *buddy, const char *name);
-
-/**
- * Aliases a contact in the buddy list.
- *
- * @param contact The contact whose alias will be changed.
- * @param alias The contact's alias.
- */
-void purple_blist_alias_contact(PurpleContact *contact, const char *alias);
-
-/**
- * Aliases a buddy in the buddy list.
- *
- * @param buddy The buddy whose alias will be changed.
- * @param alias The buddy's alias.
- */
-void purple_blist_alias_buddy(PurpleBuddy *buddy, const char *alias);
-
-/**
- * Sets the server-sent alias of a buddy in the buddy list.
- * PRPLs should call serv_got_alias() instead of this.
- *
- * @param buddy The buddy whose alias will be changed.
- * @param alias The buddy's "official" alias.
- */
-void purple_blist_server_alias_buddy(PurpleBuddy *buddy, const char *alias);
-
-/**
- * Aliases a chat in the buddy list.
- *
- * @param chat The chat whose alias will be changed.
- * @param alias The chat's new alias.
- */
-void purple_blist_alias_chat(PurpleChat *chat, const char *alias);
-
-/**
- * Renames a group
- *
- * @param group The group to rename
- * @param name The new name
- */
-void purple_blist_rename_group(PurpleGroup *group, const char *name);
-
-/**
- * Creates a new chat for the buddy list
- *
- * @param account The account this chat will get added to
- * @param alias The alias of the new chat
- * @param components The info the prpl needs to join the chat. The
- * hash function should be g_str_hash() and the
- * equal function should be g_str_equal().
- * @return A newly allocated chat
- */
-PurpleChat *purple_chat_new(PurpleAccount *account, const char *alias, GHashTable *components);
-
-/**
- * Destroys a chat
- *
- * @param chat The chat to destroy
- */
-void purple_chat_destroy(PurpleChat *chat);
-
-/**
- * Adds a new chat to the buddy list.
- *
- * The chat will be inserted right after node or appended to the end
- * of group if node is NULL. If both are NULL, the buddy will be added to
- * the "Chats" group.
- *
- * @param chat The new chat who gets added
- * @param group The group to add the new chat to.
- * @param node The insertion point
- */
-void purple_blist_add_chat(PurpleChat *chat, PurpleGroup *group, PurpleBlistNode *node);
-
-/**
- * Creates a new buddy.
- *
- * This function only creates the PurpleBuddy. Use purple_blist_add_buddy
- * to add the buddy to the list and purple_account_add_buddy to sync up
- * with the server.
- *
- * @param account The account this buddy will get added to
- * @param name The name of the new buddy
- * @param alias The alias of the new buddy (or NULL if unaliased)
- * @return A newly allocated buddy
- *
- * @see purple_account_add_buddy
- * @see purple_blist_add_buddy
- */
-PurpleBuddy *purple_buddy_new(PurpleAccount *account, const char *name, const char *alias);
-
-/**
- * Destroys a buddy
- *
- * @param buddy The buddy to destroy
- */
-void purple_buddy_destroy(PurpleBuddy *buddy);
-
-/**
- * Sets a buddy's icon.
- *
- * This should only be called from within Purple. You probably want to
- * call purple_buddy_icon_set_data().
- *
- * @param buddy The buddy.
- * @param icon The buddy icon.
- *
- * @see purple_buddy_icon_set_data()
- */
-void purple_buddy_set_icon(PurpleBuddy *buddy, PurpleBuddyIcon *icon);
-
-/**
- * Returns a buddy's account.
- *
- * @param buddy The buddy.
- *
- * @return The account
- */
-PurpleAccount *purple_buddy_get_account(const PurpleBuddy *buddy);
-
-/**
- * Returns a buddy's name
- *
- * @param buddy The buddy.
- *
- * @return The name.
- */
-const char *purple_buddy_get_name(const PurpleBuddy *buddy);
-
-/**
- * Returns a buddy's icon.
- *
- * @param buddy The buddy.
- *
- * @return The buddy icon.
- */
-PurpleBuddyIcon *purple_buddy_get_icon(const PurpleBuddy *buddy);
-
-/**
- * Returns a buddy's protocol-specific data.
- *
- * This should only be called from the associated prpl.
- *
- * @param buddy The buddy.
- * @return The protocol data.
- *
- * @see purple_buddy_set_protocol_data()
- */
-gpointer purple_buddy_get_protocol_data(const PurpleBuddy *buddy);
-
-/**
- * Sets a buddy's protocol-specific data.
- *
- * This should only be called from the associated prpl.
- *
- * @param buddy The buddy.
- * @param data The data.
- *
- * @see purple_buddy_get_protocol_data()
- */
-void purple_buddy_set_protocol_data(PurpleBuddy *buddy, gpointer data);
-
-/**
- * Returns a buddy's contact.
- *
- * @param buddy The buddy.
- *
- * @return The buddy's contact.
- */
-PurpleContact *purple_buddy_get_contact(PurpleBuddy *buddy);
-
-/**
- * Returns a buddy's presence.
- *
- * @param buddy The buddy.
- *
- * @return The buddy's presence.
- */
-PurplePresence *purple_buddy_get_presence(const PurpleBuddy *buddy);
-
-/**
- * Gets the media caps from a buddy.
- *
- * @param buddy The buddy.
- * @return The media caps.
- */
-PurpleMediaCaps purple_buddy_get_media_caps(const PurpleBuddy *buddy);
-
-/**
- * Sets the media caps for a buddy.
- *
- * @param buddy The PurpleBuddy.
- * @param media_caps The PurpleMediaCaps.
- */
-void purple_buddy_set_media_caps(PurpleBuddy *buddy, PurpleMediaCaps media_caps);
-
-/**
- * Adds a new buddy to the buddy list.
- *
- * The buddy will be inserted right after node or prepended to the
- * group if node is NULL. If both are NULL, the buddy will be added to
- * the "Buddies" group.
- *
- * @param buddy The new buddy who gets added
- * @param contact The optional contact to place the buddy in.
- * @param group The group to add the new buddy to.
- * @param node The insertion point. Pass in NULL to add the node as
- * the first child in the given group.
- */
-void purple_blist_add_buddy(PurpleBuddy *buddy, PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node);
-
-/**
- * Creates a new group
- *
- * You can't have more than one group with the same name. Sorry. If you pass
- * this the name of a group that already exists, it will return that group.
- *
- * @param name The name of the new group
- * @return A new group struct
-*/
-PurpleGroup *purple_group_new(const char *name);
-
-/**
- * Destroys a group
- *
- * @param group The group to destroy
-*/
-void purple_group_destroy(PurpleGroup *group);
-
-/**
- * Adds a new group to the buddy list.
- *
- * The new group will be inserted after insert or prepended to the list if
- * node is NULL.
- *
- * @param group The group
- * @param node The insertion point
- */
-void purple_blist_add_group(PurpleGroup *group, PurpleBlistNode *node);
-
-/**
- * Creates a new contact
- *
- * @return A new contact struct
- */
-PurpleContact *purple_contact_new(void);
-
-/**
- * Destroys a contact
- *
- * @param contact The contact to destroy
- */
-void purple_contact_destroy(PurpleContact *contact);
-
-/**
- * Gets the PurpleGroup from a PurpleContact
- *
- * @param contact The contact
- * @return The group
- */
-PurpleGroup *purple_contact_get_group(const PurpleContact *contact);
-
-/**
- * Adds a new contact to the buddy list.
- *
- * The new contact will be inserted after insert or prepended to the list if
- * node is NULL.
- *
- * @param contact The contact
- * @param group The group to add the contact to
- * @param node The insertion point
- */
-void purple_blist_add_contact(PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node);
-
-/**
- * Merges two contacts
- *
- * All of the buddies from source will be moved to target
- *
- * @param source The contact to merge
- * @param node The place to merge to (a buddy or contact)
- */
-void purple_blist_merge_contact(PurpleContact *source, PurpleBlistNode *node);
-
-/**
- * Returns the highest priority buddy for a given contact.
- *
- * @param contact The contact
- * @return The highest priority buddy
- */
-PurpleBuddy *purple_contact_get_priority_buddy(PurpleContact *contact);
-
-/**
- * Gets the alias for a contact.
- *
- * @param contact The contact
- * @return The alias, or NULL if it is not set.
- */
-const char *purple_contact_get_alias(PurpleContact *contact);
-
-/**
- * Determines whether an account owns any buddies in a given contact
- *
- * @param contact The contact to search through.
- * @param account The account.
- *
- * @return TRUE if there are any buddies from account in the contact, or FALSE otherwise.
- */
-gboolean purple_contact_on_account(PurpleContact *contact, PurpleAccount *account);
-
-/**
- * Invalidates the priority buddy so that the next call to
- * purple_contact_get_priority_buddy recomputes it.
- *
- * @param contact The contact
- */
-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.
- *
- * @param buddy The buddy to be removed
- *
- * @see purple_account_remove_buddy
- */
-void purple_blist_remove_buddy(PurpleBuddy *buddy);
-
-/**
- * Removes a contact, and any buddies it contains, and frees the memory
- * allocated to it. This calls purple_blist_remove_buddy and therefore
- * doesn't remove the buddies from the server list.
- *
- * @param contact The contact to be removed
- *
- * @see purple_blist_remove_buddy
- */
-void purple_blist_remove_contact(PurpleContact *contact);
-
-/**
- * Removes a chat from the buddy list and frees the memory allocated to it.
- *
- * @param chat The chat to be removed
- */
-void purple_blist_remove_chat(PurpleChat *chat);
-
-/**
- * Removes a group from the buddy list and frees the memory allocated to it and to
- * its children
- *
- * @param group The group to be removed
- */
-void purple_blist_remove_group(PurpleGroup *group);
-
-/**
- * Returns the alias of a buddy.
- *
- * @param buddy The buddy whose name will be returned.
- * @return The alias (if set), server alias (if set),
- * or NULL.
- */
-const char *purple_buddy_get_alias_only(PurpleBuddy *buddy);
-
-/**
- * Gets the server alias for a buddy.
- *
- * @param buddy The buddy whose name will be returned
- * @return The server alias, or NULL if it is not set.
- */
-const char *purple_buddy_get_server_alias(PurpleBuddy *buddy);
-
-/**
- * Returns the correct name to display for a buddy, taking the contact alias
- * into account. In order of precedence: the buddy's alias; the buddy's
- * contact alias; the buddy's server alias; the buddy's user name.
- *
- * @param buddy The buddy whose name will be returned
- * @return The appropriate name or alias, or NULL.
- *
- */
-const char *purple_buddy_get_contact_alias(PurpleBuddy *buddy);
-
-/**
- * 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;
- * the buddy's user name.
- *
- * @param buddy The buddy whose name will be returned.
- * @return The appropriate name or alias, or NULL
- */
-const char *purple_buddy_get_alias(PurpleBuddy *buddy);
-
-/**
- * Returns the local alias for the buddy, or @c NULL if none exists.
- *
- * @param buddy The buddy
- * @return The local alias for the buddy
- */
-const char *purple_buddy_get_local_buddy_alias(PurpleBuddy *buddy);
-
-/**
- * Returns the correct name to display for a blist chat.
- *
- * @param chat The chat whose name will be returned.
- * @return The alias (if set), or first component value.
- */
-const char *purple_chat_get_name(PurpleChat *chat);
-
-/**
- * Finds the buddy struct given a name and an account
- *
- * @param account The account this buddy belongs to
- * @param name The buddy's name
- * @return The buddy or NULL if the buddy does not exist
- */
-PurpleBuddy *purple_find_buddy(PurpleAccount *account, const char *name);
-
-/**
- * Finds the buddy struct given a name, an account, and a group
- *
- * @param account The account this buddy belongs to
- * @param name The buddy's name
- * @param group The group to look in
- * @return The buddy or NULL if the buddy does not exist in the group
- */
-PurpleBuddy *purple_find_buddy_in_group(PurpleAccount *account, const char *name,
- PurpleGroup *group);
-
-/**
- * Finds all PurpleBuddy structs given a name and an account
- *
- * @param account The account this buddy belongs to
- * @param name The buddy's name (or NULL to return all buddies for the account)
- *
- * @return NULL if the buddy doesn't exist, or a GSList of
- * PurpleBuddy structs. You must free the GSList using
- * g_slist_free. Do not free the PurpleBuddy structs that
- * the list points to.
- */
-GSList *purple_find_buddies(PurpleAccount *account, const char *name);
-
-
-/**
- * Finds a group by name
- *
- * @param name The group's name
- * @return The group or NULL if the group does not exist
- */
-PurpleGroup *purple_find_group(const char *name);
-
-/**
- * Finds a chat by name.
- *
- * @param account The chat's account.
- * @param name The chat's name.
- *
- * @return The chat, or @c NULL if the chat does not exist.
- */
-PurpleChat *purple_blist_find_chat(PurpleAccount *account, const char *name);
-
-/**
- * Returns the group of which the chat is a member.
- *
- * @param chat The chat.
- *
- * @return The parent group, or @c NULL if the chat is not in a group.
- */
-PurpleGroup *purple_chat_get_group(PurpleChat *chat);
-
-/**
- * Returns the account the chat belongs to.
- *
- * @param chat The chat.
- *
- * @return The account the chat belongs to.
- */
-PurpleAccount *purple_chat_get_account(PurpleChat *chat);
-
-/**
- * Get a hashtable containing information about a chat.
- *
- * @param chat The chat.
- *
- * @constreturn The hashtable.
- */
-GHashTable *purple_chat_get_components(PurpleChat *chat);
-
-/**
- * Returns the group of which the buddy is a member.
- *
- * @param buddy The buddy
- * @return The group or NULL if the buddy is not in a group
- */
-PurpleGroup *purple_buddy_get_group(PurpleBuddy *buddy);
-
-
-/**
- * Returns a list of accounts that have buddies in this group
- *
- * @param g The group
- *
- * @return A GSList of accounts (which must be freed), or NULL if the group
- * has no accounts.
- */
-GSList *purple_group_get_accounts(PurpleGroup *g);
-
-/**
- * Determines whether an account owns any buddies in a given group
- *
- * @param g The group to search through.
- * @param account The account.
- *
- * @return TRUE if there are any buddies in the group, or FALSE otherwise.
- */
-gboolean purple_group_on_account(PurpleGroup *g, PurpleAccount *account);
-
-/**
- * Returns the name of a group.
- *
- * @param group The group.
- *
- * @return The name of the group.
- */
-const char *purple_group_get_name(PurpleGroup *group);
-
-/**
- * Called when an account connects. Tells the UI to update all the
- * buddies.
- *
- * @param account The account
- */
-void purple_blist_add_account(PurpleAccount *account);
-
-
-/**
- * Called when an account disconnects. Sets the presence of all the buddies to 0
- * and tells the UI to update them.
- *
- * @param account The account
- */
-void purple_blist_remove_account(PurpleAccount *account);
-
-
-/**
- * Determines the total size of a group
- *
- * @param group The group
- * @param offline Count buddies in offline accounts
- * @return The number of buddies in the group
- */
-int purple_blist_get_group_size(PurpleGroup *group, gboolean offline);
-
-/**
- * Determines the number of online buddies in a group
- *
- * @param group The group
- * @return The number of online buddies in the group, or 0 if the group is NULL
- */
-int purple_blist_get_group_online_count(PurpleGroup *group);
-
-/*@}*/
-
-/****************************************************************************************/
-/** @name Buddy list file management API */
-/****************************************************************************************/
-
-/**
- * Schedule a save of the blist.xml file. This is used by the privacy
- * API whenever the privacy settings are changed. If you make a change
- * to blist.xml using one of the functions in the buddy list API, then
- * the buddy list is saved automatically, so you should not need to
- * call this.
- */
-void purple_blist_schedule_save(void);
-
-/**
- * Requests from the user information needed to add a buddy to the
- * buddy list.
- *
- * @param account The account the buddy is added to.
- * @param username The username of the buddy.
- * @param group The name of the group to place the buddy in.
- * @param alias The optional alias for the buddy.
- */
-void purple_blist_request_add_buddy(PurpleAccount *account, const char *username,
- const char *group, const char *alias);
-
-/**
- * Requests from the user information needed to add a chat to the
- * buddy list.
- *
- * @param account The account the buddy is added to.
- * @param group The optional group to add the chat to.
- * @param alias The optional alias for the chat.
- * @param name The required chat name.
- */
-void purple_blist_request_add_chat(PurpleAccount *account, PurpleGroup *group,
- const char *alias, const char *name);
-
-/**
- * Requests from the user information needed to add a group to the
- * buddy list.
- */
-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
- * @param key The identifier for the data
- * @param value The value to set
- */
-void purple_blist_node_set_bool(PurpleBlistNode *node, const char *key, gboolean value);
-
-/**
- * Retrieves a named boolean setting from a node in the buddy list
- *
- * @param node The node to retrieve the data from
- * @param key The identifier of the data
- *
- * @return The value, or FALSE if there is no setting
- */
-gboolean purple_blist_node_get_bool(PurpleBlistNode *node, const char *key);
-
-/**
- * Associates an integer with a node in the buddy list
- *
- * @param node The node to associate the data with
- * @param key The identifier for the data
- * @param value The value to set
- */
-void purple_blist_node_set_int(PurpleBlistNode *node, const char *key, int value);
-
-/**
- * Retrieves a named integer setting from a node in the buddy list
- *
- * @param node The node to retrieve the data from
- * @param key The identifier of the data
- *
- * @return The value, or 0 if there is no setting
- */
-int purple_blist_node_get_int(PurpleBlistNode *node, const char *key);
-
-/**
- * Associates a string with a node in the buddy list
- *
- * @param node The node to associate the data with
- * @param key The identifier for the data
- * @param value The value to set
- */
-void purple_blist_node_set_string(PurpleBlistNode *node, const char *key,
- const char *value);
-
-/**
- * Retrieves a named string setting from a node in the buddy list
- *
- * @param node The node to retrieve the data from
- * @param key The identifier of the data
- *
- * @return The value, or NULL if there is no setting
- */
-const char *purple_blist_node_get_string(PurpleBlistNode *node, const char *key);
-
-/**
- * Removes a named setting from a blist node
- *
- * @param node The node from which to remove the setting
- * @param key The name of the setting
- */
-void purple_blist_node_remove_setting(PurpleBlistNode *node, const char *key);
-
-/**
- * Set the flags for the given node. Setting a node's flags will overwrite
- * the old flags, so if you want to save them, you must first call
- * purple_blist_node_get_flags and modify that appropriately.
- *
- * @param node The node on which to set the flags.
- * @param flags The flags to set. This is a bitmask.
- */
-void purple_blist_node_set_flags(PurpleBlistNode *node, PurpleBlistNodeFlags flags);
-
-/**
- * Get the current flags on a given node.
- *
- * @param node The node from which to get the flags.
- *
- * @return The flags on the node. This is a bitmask.
- */
-PurpleBlistNodeFlags purple_blist_node_get_flags(PurpleBlistNode *node);
-
-/**
- * Get the type of a given node.
- *
- * @param node The node.
- *
- * @return The type of the node.
- */
-PurpleBlistNodeType purple_blist_node_get_type(PurpleBlistNode *node);
-
-/*@}*/
-
-/**
- * Retrieves the extended menu items for a buddy list node.
- * @param n The blist node for which to obtain the extended menu items.
- * @return A list of PurpleMenuAction items, as harvested by the
- * blist-node-extended-menu signal.
- */
-GList *purple_blist_node_get_extended_menu(PurpleBlistNode *n);
-
-/**************************************************************************/
-/** @name UI Registration Functions */
-/**************************************************************************/
-/*@{*/
-
-/**
- * Sets the UI operations structure to be used for the buddy list.
- *
- * @param ops The ops struct.
- */
-void purple_blist_set_ui_ops(PurpleBlistUiOps *ops);
-
-/**
- * Returns the UI operations structure to be used for the buddy list.
- *
- * @return The UI operations structure.
- */
-PurpleBlistUiOps *purple_blist_get_ui_ops(void);
-
-/*@}*/
-
-/**************************************************************************/
-/** @name Buddy List Subsystem */
-/**************************************************************************/
-/*@{*/
-
-/**
- * Returns the handle for the buddy list subsystem.
- *
- * @return The buddy list subsystem handle.
- */
-void *purple_blist_get_handle(void);
-
-/**
- * Initializes the buddy list subsystem.
- */
-void purple_blist_init(void);
-
-/**
- * Loads the buddy list.
- *
- * You shouldn't call this. purple_core_init() will do it for you.
- */
-void purple_blist_boot(void);
-
-/**
- * Uninitializes the buddy list subsystem.
- */
-void purple_blist_uninit(void);
-
-/*@}*/
-
-G_END_DECLS
-
-#endif /* _PURPLE_BLIST_H_ */
diff --git a/libpurple/blistnode.c b/libpurple/blistnode.c
new file mode 100644
index 0000000000..b0cc8aa9ee
--- /dev/null
+++ b/libpurple/blistnode.c
@@ -0,0 +1,662 @@
+/*
+ * 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
+ *
+ */
+#include "blistnodetypes.h"
+#include "internal.h"
+
+#define PURPLE_BLIST_NODE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_BLIST_NODE, PurpleBlistNodePrivate))
+
+/** @copydoc _PurpleBlistNodePrivate */
+typedef struct _PurpleBlistNodePrivate PurpleBlistNodePrivate;
+
+#define PURPLE_COUNTING_NODE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_COUNTING_NODE, PurpleCountingNodePrivate))
+
+/** @copydoc _PurpleCountingNodePrivate */
+typedef struct _PurpleCountingNodePrivate PurpleCountingNodePrivate;
+
+/** Private data of a buddy list node */
+struct _PurpleBlistNodePrivate {
+ GHashTable *settings; /**< per-node settings */
+ gboolean transient; /**< node should not be saved with the buddy list */
+};
+
+/* Blist node property enums */
+enum
+{
+ BLNODE_PROP_0,
+ BLNODE_PROP_DONT_SAVE,
+ BLNODE_PROP_LAST
+};
+
+/** Private data of a counting node */
+struct _PurpleCountingNodePrivate {
+ int totalsize; /**< The number of children under this node */
+ int currentsize; /**< The number of children under this node
+ corresponding to online accounts */
+ int onlinecount; /**< The number of children under this contact who are
+ currently online */
+};
+
+/* Counting node property enums */
+enum
+{
+ CNODE_PROP_0,
+ CNODE_PROP_TOTAL_SIZE,
+ CNODE_PROP_CURRENT_SIZE,
+ CNODE_PROP_ONLINE_COUNT,
+ CNODE_PROP_LAST
+};
+
+static GObjectClass *parent_class;
+
+/**************************************************************************/
+/* Buddy list node API */
+/**************************************************************************/
+
+static PurpleBlistNode *get_next_node(PurpleBlistNode *node, gboolean godeep)
+{
+ if (node == NULL)
+ return NULL;
+
+ if (godeep && node->child)
+ return node->child;
+
+ if (node->next)
+ return node->next;
+
+ return get_next_node(node->parent, FALSE);
+}
+
+PurpleBlistNode *purple_blist_node_next(PurpleBlistNode *node, gboolean offline)
+{
+ PurpleBlistNode *ret = node;
+
+ if (offline)
+ return get_next_node(ret, TRUE);
+ do
+ {
+ ret = get_next_node(ret, TRUE);
+ } while (ret && PURPLE_IS_BUDDY(ret) &&
+ !purple_account_is_connected(purple_buddy_get_account((PurpleBuddy *)ret)));
+
+ return ret;
+}
+
+PurpleBlistNode *purple_blist_node_get_parent(PurpleBlistNode *node)
+{
+ return node ? node->parent : NULL;
+}
+
+PurpleBlistNode *purple_blist_node_get_first_child(PurpleBlistNode *node)
+{
+ return node ? node->child : NULL;
+}
+
+PurpleBlistNode *purple_blist_node_get_sibling_next(PurpleBlistNode *node)
+{
+ return node? node->next : NULL;
+}
+
+PurpleBlistNode *purple_blist_node_get_sibling_prev(PurpleBlistNode *node)
+{
+ return node? node->prev : NULL;
+}
+
+void *
+purple_blist_node_get_ui_data(const PurpleBlistNode *node)
+{
+ g_return_val_if_fail(node, NULL);
+
+ return node->ui_data;
+}
+
+void
+purple_blist_node_set_ui_data(PurpleBlistNode *node, void *ui_data) {
+ g_return_if_fail(node);
+
+ node->ui_data = ui_data;
+}
+
+void purple_blist_node_remove_setting(PurpleBlistNode *node, const char *key)
+{
+ PurpleBlistUiOps *ops;
+ PurpleBlistNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(priv->settings != NULL);
+ g_return_if_fail(key != NULL);
+
+ g_hash_table_remove(priv->settings, key);
+
+ ops = purple_blist_get_ui_ops();
+ if (ops && ops->save_node)
+ ops->save_node(node);
+}
+
+void
+purple_blist_node_set_transient(PurpleBlistNode *node, gboolean transient)
+{
+ PurpleBlistNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->transient = transient;
+}
+
+gboolean
+purple_blist_node_is_transient(PurpleBlistNode *node)
+{
+ PurpleBlistNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
+
+ g_return_val_if_fail(priv != NULL, 0);
+
+ return priv->transient;
+}
+
+GHashTable *
+purple_blist_node_get_settings(PurpleBlistNode *node)
+{
+ PurpleBlistNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->settings;
+}
+
+gboolean
+purple_blist_node_has_setting(PurpleBlistNode* node, const char *key)
+{
+ PurpleBlistNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
+
+ g_return_val_if_fail(priv != NULL, FALSE);
+ g_return_val_if_fail(priv->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(priv->settings, key) != NULL);
+}
+
+void
+purple_blist_node_set_bool(PurpleBlistNode* node, const char *key, gboolean data)
+{
+ GValue *value;
+ PurpleBlistUiOps *ops;
+ PurpleBlistNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(priv->settings != NULL);
+ g_return_if_fail(key != NULL);
+
+ value = purple_g_value_new(G_TYPE_BOOLEAN);
+ g_value_set_boolean(value, data);
+
+ g_hash_table_replace(priv->settings, g_strdup(key), value);
+
+ ops = purple_blist_get_ui_ops();
+ if (ops && ops->save_node)
+ ops->save_node(node);
+}
+
+gboolean
+purple_blist_node_get_bool(PurpleBlistNode* node, const char *key)
+{
+ GValue *value;
+ PurpleBlistNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
+
+ g_return_val_if_fail(priv != NULL, FALSE);
+ g_return_val_if_fail(priv->settings != NULL, FALSE);
+ g_return_val_if_fail(key != NULL, FALSE);
+
+ value = g_hash_table_lookup(priv->settings, key);
+
+ if (value == NULL)
+ return FALSE;
+
+ g_return_val_if_fail(G_VALUE_HOLDS_BOOLEAN(value), FALSE);
+
+ return g_value_get_boolean(value);
+}
+
+void
+purple_blist_node_set_int(PurpleBlistNode* node, const char *key, int data)
+{
+ GValue *value;
+ PurpleBlistUiOps *ops;
+ PurpleBlistNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(priv->settings != NULL);
+ g_return_if_fail(key != NULL);
+
+ value = purple_g_value_new(G_TYPE_INT);
+ g_value_set_int(value, data);
+
+ g_hash_table_replace(priv->settings, g_strdup(key), value);
+
+ ops = purple_blist_get_ui_ops();
+ if (ops && ops->save_node)
+ ops->save_node(node);
+}
+
+int
+purple_blist_node_get_int(PurpleBlistNode* node, const char *key)
+{
+ GValue *value;
+ PurpleBlistNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
+
+ g_return_val_if_fail(priv != NULL, 0);
+ g_return_val_if_fail(priv->settings != NULL, 0);
+ g_return_val_if_fail(key != NULL, 0);
+
+ value = g_hash_table_lookup(priv->settings, key);
+
+ if (value == NULL)
+ return 0;
+
+ g_return_val_if_fail(G_VALUE_HOLDS_INT(value), 0);
+
+ return g_value_get_int(value);
+}
+
+void
+purple_blist_node_set_string(PurpleBlistNode* node, const char *key, const char *data)
+{
+ GValue *value;
+ PurpleBlistUiOps *ops;
+ PurpleBlistNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(priv->settings != NULL);
+ g_return_if_fail(key != NULL);
+
+ value = purple_g_value_new(G_TYPE_STRING);
+ g_value_set_string(value, data);
+
+ g_hash_table_replace(priv->settings, g_strdup(key), value);
+
+ ops = purple_blist_get_ui_ops();
+ if (ops && ops->save_node)
+ ops->save_node(node);
+}
+
+const char *
+purple_blist_node_get_string(PurpleBlistNode* node, const char *key)
+{
+ GValue *value;
+ PurpleBlistNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+ g_return_val_if_fail(priv->settings != NULL, NULL);
+ g_return_val_if_fail(key != NULL, NULL);
+
+ value = g_hash_table_lookup(priv->settings, key);
+
+ if (value == NULL)
+ return NULL;
+
+ g_return_val_if_fail(G_VALUE_HOLDS_STRING(value), NULL);
+
+ return g_value_get_string(value);
+}
+
+GList *
+purple_blist_node_get_extended_menu(PurpleBlistNode *n)
+{
+ GList *menu = NULL;
+
+ g_return_val_if_fail(n != NULL, NULL);
+
+ purple_signal_emit(purple_blist_get_handle(), "blist-node-extended-menu",
+ n, &menu);
+ return menu;
+}
+
+/**************************************************************************
+ * GObject code for PurpleBlistNode
+ **************************************************************************/
+
+/* GObject Property names */
+#define BLNODE_PROP_DONT_SAVE_S "dont-save"
+
+/* Set method for GObject properties */
+static void
+purple_blist_node_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleBlistNode *node = PURPLE_BLIST_NODE(obj);
+
+ switch (param_id) {
+ case BLNODE_PROP_DONT_SAVE:
+ purple_blist_node_set_transient(node, g_value_get_boolean(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Get method for GObject properties */
+static void
+purple_blist_node_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleBlistNode *node = PURPLE_BLIST_NODE(obj);
+
+ switch (param_id) {
+ case BLNODE_PROP_DONT_SAVE:
+ g_value_set_boolean(value, purple_blist_node_is_transient(node));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* GObject initialization function */
+static void
+purple_blist_node_init(GTypeInstance *instance, gpointer klass)
+{
+ PurpleBlistNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(instance);
+
+ priv->settings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+ (GDestroyNotify)purple_g_value_free);
+}
+
+/* GObject finalize function */
+static void
+purple_blist_node_finalize(GObject *object)
+{
+ PurpleBlistNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(object);
+
+ g_hash_table_destroy(priv->settings);
+
+ parent_class->finalize(object);
+}
+
+/* Class initializer function */
+static void
+purple_blist_node_class_init(PurpleBlistNodeClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->finalize = purple_blist_node_finalize;
+
+ /* Setup properties */
+ obj_class->get_property = purple_blist_node_get_property;
+ obj_class->set_property = purple_blist_node_set_property;
+
+ g_object_class_install_property(obj_class, BLNODE_PROP_DONT_SAVE,
+ g_param_spec_boolean(BLNODE_PROP_DONT_SAVE_S, _("Do not save"),
+ _("Whether node should not be saved with the buddy list."),
+ FALSE, G_PARAM_READWRITE)
+ );
+
+ g_type_class_add_private(klass, sizeof(PurpleBlistNodePrivate));
+}
+
+GType
+purple_blist_node_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleBlistNodeClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_blist_node_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleBlistNode),
+ 0,
+ (GInstanceInitFunc)purple_blist_node_init,
+ NULL,
+ };
+
+ type = g_type_register_static(G_TYPE_OBJECT, "PurpleBlistNode",
+ &info, G_TYPE_FLAG_ABSTRACT);
+ }
+
+ return type;
+}
+
+/**************************************************************************/
+/* Counting node API */
+/**************************************************************************/
+
+int
+purple_counting_node_get_total_size(PurpleCountingNode *counter)
+{
+ PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
+
+ g_return_val_if_fail(priv != NULL, -1);
+
+ return priv->totalsize;
+}
+
+int
+purple_counting_node_get_current_size(PurpleCountingNode *counter)
+{
+ PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
+
+ g_return_val_if_fail(priv != NULL, -1);
+
+ return priv->currentsize;
+}
+
+int
+purple_counting_node_get_online_count(PurpleCountingNode *counter)
+{
+ PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
+
+ g_return_val_if_fail(priv != NULL, -1);
+
+ return priv->onlinecount;
+}
+
+void
+purple_counting_node_change_total_size(PurpleCountingNode *counter, int delta)
+{
+ PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->totalsize += delta;
+}
+
+void
+purple_counting_node_change_current_size(PurpleCountingNode *counter, int delta)
+{
+ PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->currentsize += delta;
+}
+
+void
+purple_counting_node_change_online_count(PurpleCountingNode *counter, int delta)
+{
+ PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->onlinecount += delta;
+}
+
+void
+purple_counting_node_set_total_size(PurpleCountingNode *counter, int totalsize)
+{
+ PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->totalsize = totalsize;
+}
+
+void
+purple_counting_node_set_current_size(PurpleCountingNode *counter, int currentsize)
+{
+ PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->currentsize = currentsize;
+}
+
+void
+purple_counting_node_set_online_count(PurpleCountingNode *counter, int onlinecount)
+{
+ PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->onlinecount = onlinecount;
+}
+
+/**************************************************************************
+ * GObject code for PurpleCountingNode
+ **************************************************************************/
+
+/* GObject Property names */
+#define CNODE_PROP_TOTAL_SIZE_S "total-size"
+#define CNODE_PROP_CURRENT_SIZE_S "current-size"
+#define CNODE_PROP_ONLINE_COUNT_S "online-count"
+
+/* Set method for GObject properties */
+static void
+purple_counting_node_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleCountingNode *node = PURPLE_COUNTING_NODE(obj);
+
+ switch (param_id) {
+ case CNODE_PROP_TOTAL_SIZE:
+ purple_counting_node_set_total_size(node, g_value_get_int(value));
+ break;
+ case CNODE_PROP_CURRENT_SIZE:
+ purple_counting_node_set_current_size(node, g_value_get_int(value));
+ break;
+ case CNODE_PROP_ONLINE_COUNT:
+ purple_counting_node_set_online_count(node, g_value_get_int(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Get method for GObject properties */
+static void
+purple_counting_node_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleCountingNode *node = PURPLE_COUNTING_NODE(obj);
+
+ switch (param_id) {
+ case CNODE_PROP_TOTAL_SIZE:
+ g_value_set_int(value, purple_counting_node_get_total_size(node));
+ break;
+ case CNODE_PROP_CURRENT_SIZE:
+ g_value_set_int(value, purple_counting_node_get_current_size(node));
+ break;
+ case CNODE_PROP_ONLINE_COUNT:
+ g_value_set_int(value, purple_counting_node_get_online_count(node));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* GObject initialization function */
+static void
+purple_counting_node_init(GTypeInstance *instance, gpointer klass)
+{
+ PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(instance);
+
+ priv->totalsize = 0;
+ priv->currentsize = 0;
+ priv->onlinecount = 0;
+}
+
+/* Class initializer function */
+static void
+purple_counting_node_class_init(PurpleCountingNodeClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ /* Setup properties */
+ obj_class->get_property = purple_counting_node_get_property;
+ obj_class->set_property = purple_counting_node_set_property;
+
+ g_object_class_install_property(obj_class, CNODE_PROP_TOTAL_SIZE,
+ g_param_spec_int(CNODE_PROP_TOTAL_SIZE_S, _("Total size"),
+ _("The number of children under this node."),
+ G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, CNODE_PROP_CURRENT_SIZE,
+ g_param_spec_int(CNODE_PROP_CURRENT_SIZE_S, _("Current size"),
+ _("The number of children with online accounts."),
+ G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, CNODE_PROP_ONLINE_COUNT,
+ g_param_spec_int(CNODE_PROP_ONLINE_COUNT_S, _("Online count"),
+ _("The number of children that are online."),
+ G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)
+ );
+
+ g_type_class_add_private(klass, sizeof(PurpleCountingNodePrivate));
+}
+
+GType
+purple_counting_node_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleCountingNodeClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_counting_node_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleCountingNode),
+ 0,
+ (GInstanceInitFunc)purple_counting_node_init,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_BLIST_NODE,
+ "PurpleCountingNode",
+ &info, G_TYPE_FLAG_ABSTRACT);
+ }
+
+ return type;
+}
diff --git a/libpurple/blistnode.h b/libpurple/blistnode.h
new file mode 100644
index 0000000000..80362c9ecb
--- /dev/null
+++ b/libpurple/blistnode.h
@@ -0,0 +1,423 @@
+/**
+ * @file blistnode.h Buddy list node and Counting node API
+ * @ingroup core
+ */
+/* 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 _PURPLE_BLIST_NODE_H_
+#define _PURPLE_BLIST_NODE_H_
+
+#include <glib.h>
+#include <glib-object.h>
+
+#define PURPLE_TYPE_BLIST_NODE (purple_blist_node_get_type())
+#define PURPLE_BLIST_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_BLIST_NODE, PurpleBlistNode))
+#define PURPLE_BLIST_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_BLIST_NODE, PurpleBlistNodeClass))
+#define PURPLE_IS_BLIST_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_BLIST_NODE))
+#define PURPLE_IS_BLIST_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_BLIST_NODE))
+#define PURPLE_BLIST_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_BLIST_NODE, PurpleBlistNodeClass))
+
+/** @copydoc _PurpleBlistNode */
+typedef struct _PurpleBlistNode PurpleBlistNode;
+/** @copydoc _PurpleBlistNodeClass */
+typedef struct _PurpleBlistNodeClass PurpleBlistNodeClass;
+
+#define PURPLE_TYPE_COUNTING_NODE (purple_counting_node_get_type())
+#define PURPLE_COUNTING_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_COUNTING_NODE, PurpleCountingNode))
+#define PURPLE_COUNTING_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_COUNTING_NODE, PurpleCountingNodeClass))
+#define PURPLE_IS_COUNTING_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_COUNTING_NODE))
+#define PURPLE_IS_COUNTING_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_COUNTING_NODE))
+#define PURPLE_COUNTING_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_COUNTING_NODE, PurpleCountingNodeClass))
+
+/** @copydoc _PurpleCountingNode */
+typedef struct _PurpleCountingNode PurpleCountingNode;
+/** @copydoc _PurpleCountingNodeClass */
+typedef struct _PurpleCountingNodeClass PurpleCountingNodeClass;
+
+/**************************************************************************/
+/* Data Structures */
+/**************************************************************************/
+
+/**
+ * A Buddy list node. This can represent a group, a buddy, or anything else.
+ * This is a base class for PurpleBuddy, PurpleContact, PurpleGroup, and for
+ * anything else that wants to put itself in the buddy list. */
+struct _PurpleBlistNode {
+ /*< private >*/
+ GObject gparent;
+
+ /** The UI data associated with this node. This is a convenience
+ * field provided to the UIs -- it is not used by the libpurple core.
+ */
+ gpointer ui_data;
+
+ PurpleBlistNode *prev; /**< The sibling before this buddy. */
+ PurpleBlistNode *next; /**< The sibling after this buddy. */
+ PurpleBlistNode *parent; /**< The parent of this node */
+ PurpleBlistNode *child; /**< The child of this node */
+};
+
+/** The base class for all #PurpleBlistNode's. */
+struct _PurpleBlistNodeClass {
+ /*< private >*/
+ GObjectClass gparent_class;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+/**
+ * A node that keeps count of the number of children that it has. It tracks the
+ * total number of children, the number of children corresponding to online
+ * accounts, and the number of online children.
+ *
+ * The two types of counting nodes are:
+ * 1. Contact: Keeps track of the number of buddies under it.
+ * 2. Group: Keeps track of the number of chats and contacts under it.
+ *
+ * @see PurpleContact
+ * @see PurpleGroup
+ */
+struct _PurpleCountingNode {
+ /** The blist node that this counting node inherits from */
+ PurpleBlistNode node;
+};
+
+/** The base class for all #PurpleCountingNode's. */
+struct _PurpleCountingNodeClass {
+ /*< private >*/
+ PurpleBlistNodeClass node_class;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+/**************************************************************************/
+/** @name Buddy list node API */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the GType for the PurpleBlistNode object.
+ */
+GType purple_blist_node_get_type(void);
+
+/**
+ * Returns the next node of a given node. This function is to be used to iterate
+ * over the tree returned by purple_blist_get_buddy_list.
+ *
+ * @param node A node.
+ * @param offline Whether to include nodes for offline accounts
+ * @return The next node
+ * @see purple_blist_node_get_parent
+ * @see purple_blist_node_get_first_child
+ * @see purple_blist_node_get_sibling_next
+ * @see purple_blist_node_get_sibling_prev
+ */
+PurpleBlistNode *purple_blist_node_next(PurpleBlistNode *node, gboolean offline);
+
+/**
+ * Returns the parent node of a given node.
+ *
+ * @param node A node.
+ * @return The parent node.
+ *
+ * @see purple_blist_node_get_first_child
+ * @see purple_blist_node_get_sibling_next
+ * @see purple_blist_node_get_sibling_prev
+ * @see purple_blist_node_next
+ */
+PurpleBlistNode *purple_blist_node_get_parent(PurpleBlistNode *node);
+
+/**
+ * Returns the the first child node of a given node.
+ *
+ * @param node A node.
+ * @return The child node.
+ *
+ * @see purple_blist_node_get_parent
+ * @see purple_blist_node_get_sibling_next
+ * @see purple_blist_node_get_sibling_prev
+ * @see purple_blist_node_next
+ */
+PurpleBlistNode *purple_blist_node_get_first_child(PurpleBlistNode *node);
+
+/**
+ * Returns the sibling node of a given node.
+ *
+ * @param node A node.
+ * @return The sibling node.
+ *
+ * @see purple_blist_node_get_parent
+ * @see purple_blist_node_get_first_child
+ * @see purple_blist_node_get_sibling_prev
+ * @see purple_blist_node_next
+ */
+PurpleBlistNode *purple_blist_node_get_sibling_next(PurpleBlistNode *node);
+
+/**
+ * Returns the previous sibling node of a given node.
+ *
+ * @param node A node.
+ * @return The sibling node.
+ *
+ * @see purple_blist_node_get_parent
+ * @see purple_blist_node_get_first_child
+ * @see purple_blist_node_get_sibling_next
+ * @see purple_blist_node_next
+ */
+PurpleBlistNode *purple_blist_node_get_sibling_prev(PurpleBlistNode *node);
+
+/**
+ * Returns the UI data of a given node.
+ *
+ * @param node The node.
+ * @return The UI data.
+ */
+gpointer purple_blist_node_get_ui_data(const PurpleBlistNode *node);
+
+/**
+ * Sets the UI data of a given node.
+ *
+ * @param node The node.
+ * @param ui_data The UI data.
+ */
+void purple_blist_node_set_ui_data(PurpleBlistNode *node, gpointer ui_data);
+
+/**
+ * Returns a node's settings
+ *
+ * @param node The node to from which to get settings
+ *
+ * @return The hash table with the node's settings
+ */
+GHashTable *purple_blist_node_get_settings(PurpleBlistNode *node);
+
+/**
+ * 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
+ * @param key The identifier for the data
+ * @param value The value to set
+ */
+void purple_blist_node_set_bool(PurpleBlistNode *node, const char *key, gboolean value);
+
+/**
+ * Retrieves a named boolean setting from a node in the buddy list
+ *
+ * @param node The node to retrieve the data from
+ * @param key The identifier of the data
+ *
+ * @return The value, or FALSE if there is no setting
+ */
+gboolean purple_blist_node_get_bool(PurpleBlistNode *node, const char *key);
+
+/**
+ * Associates an integer with a node in the buddy list
+ *
+ * @param node The node to associate the data with
+ * @param key The identifier for the data
+ * @param value The value to set
+ */
+void purple_blist_node_set_int(PurpleBlistNode *node, const char *key, int value);
+
+/**
+ * Retrieves a named integer setting from a node in the buddy list
+ *
+ * @param node The node to retrieve the data from
+ * @param key The identifier of the data
+ *
+ * @return The value, or 0 if there is no setting
+ */
+int purple_blist_node_get_int(PurpleBlistNode *node, const char *key);
+
+/**
+ * Associates a string with a node in the buddy list
+ *
+ * @param node The node to associate the data with
+ * @param key The identifier for the data
+ * @param value The value to set
+ */
+void purple_blist_node_set_string(PurpleBlistNode *node, const char *key,
+ const char *value);
+
+/**
+ * Retrieves a named string setting from a node in the buddy list
+ *
+ * @param node The node to retrieve the data from
+ * @param key The identifier of the data
+ *
+ * @return The value, or NULL if there is no setting
+ */
+const char *purple_blist_node_get_string(PurpleBlistNode *node, const char *key);
+
+/**
+ * Removes a named setting from a blist node
+ *
+ * @param node The node from which to remove the setting
+ * @param key The name of the setting
+ */
+void purple_blist_node_remove_setting(PurpleBlistNode *node, const char *key);
+
+/**
+ * Sets whether the node should be saved with the buddy list or not
+ *
+ * @param node The node
+ * @param transient TRUE if the node should NOT be saved, FALSE if node should
+ * be saved
+ */
+void purple_blist_node_set_transient(PurpleBlistNode *node, gboolean transient);
+
+/**
+ * Gets whether the node should be saved with the buddy list or not
+ *
+ * @param node The node
+ *
+ * @return TRUE if the node should NOT be saved, FALSE if node should be saved
+ */
+gboolean purple_blist_node_is_transient(PurpleBlistNode *node);
+
+/*@}*/
+
+/**
+ * Retrieves the extended menu items for a buddy list node.
+ * @param n The blist node for which to obtain the extended menu items.
+ * @return A list of PurpleMenuAction items, as harvested by the
+ * blist-node-extended-menu signal.
+ */
+GList *purple_blist_node_get_extended_menu(PurpleBlistNode *n);
+
+/*@}*/
+
+/**************************************************************************/
+/** @name Counting node API */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the GType for the PurpleCountingNode object.
+ */
+GType purple_counting_node_get_type(void);
+
+/**
+ * Returns the total number of children of the counting node.
+ *
+ * @param counter The node
+ *
+ * @return The total number of children of the node
+ */
+int purple_counting_node_get_total_size(PurpleCountingNode *counter);
+
+/**
+ * Returns the number of children of the counting node corresponding to online
+ * accounts.
+ *
+ * @param counter The node
+ *
+ * @return The number of children with online accounts
+ */
+int purple_counting_node_get_current_size(PurpleCountingNode *counter);
+
+/**
+ * Returns the number of children of the counting node that are online.
+ *
+ * @param counter The node
+ *
+ * @return The total number of online children
+ */
+int purple_counting_node_get_online_count(PurpleCountingNode *counter);
+
+/**
+ * Changes the total number of children of the counting node. The provided
+ * delta value is added to the count, or if it's negative, the count is
+ * decreased.
+ *
+ * @param counter The node
+ * @param delta The value to change the total size by
+ */
+void purple_counting_node_change_total_size(PurpleCountingNode *counter, int delta);
+
+/**
+ * Changes the number of children of the counting node corresponding to online
+ * accounts. The provided delta value is added to the count, or if it's
+ * negative, the count is decreased.
+ *
+ * @param counter The node
+ * @param delta The value to change the current size by
+ */
+void purple_counting_node_change_current_size(PurpleCountingNode *counter, int delta);
+
+/**
+ * Changes the number of children of the counting node that are online. The
+ * provided delta value is added to the count, or if it's negative, the count is
+ * decreased.
+ *
+ * @param counter The node
+ * @param delta The value to change the online count by
+ */
+void purple_counting_node_change_online_count(PurpleCountingNode *counter, int delta);
+
+/**
+ * Sets the total number of children of the counting node.
+ *
+ * @param counter The node
+ * @param totalsize The total number of children of the node
+ */
+void purple_counting_node_set_total_size(PurpleCountingNode *counter, int totalsize);
+
+/**
+ * Sets the number of children of the counting node corresponding to online
+ * accounts.
+ *
+ * @param counter The node
+ * @param currentsize The number of children with online accounts
+ */
+void purple_counting_node_set_current_size(PurpleCountingNode *counter, int currentsize);
+
+/**
+ * Sets the number of children of the counting node that are online.
+ *
+ * @param counter The node
+ * @param onlinecount The total number of online children
+ */
+void purple_counting_node_set_online_count(PurpleCountingNode *counter, int onlinecount);
+
+/*@}*/
+
+G_END_DECLS
+
+#endif /* _PURPLE_BLIST_NODE_H_ */
diff --git a/libpurple/blistnodetypes.c b/libpurple/blistnodetypes.c
new file mode 100644
index 0000000000..190ab04df0
--- /dev/null
+++ b/libpurple/blistnodetypes.c
@@ -0,0 +1,1722 @@
+/*
+ * 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
+ *
+ */
+#include "internal.h"
+#include "dbus-maybe.h"
+#include "debug.h"
+
+#define PURPLE_BUDDY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_BUDDY, PurpleBuddyPrivate))
+
+/** @copydoc _PurpleBuddyPrivate */
+typedef struct _PurpleBuddyPrivate PurpleBuddyPrivate;
+
+#define PURPLE_CONTACT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_CONTACT, PurpleContactPrivate))
+
+/** @copydoc _PurpleContactPrivate */
+typedef struct _PurpleContactPrivate PurpleContactPrivate;
+
+#define PURPLE_GROUP_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_GROUP, PurpleGroupPrivate))
+
+/** @copydoc _PurpleGroupPrivate */
+typedef struct _PurpleGroupPrivate PurpleGroupPrivate;
+
+#define PURPLE_CHAT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_CHAT, PurpleChatPrivate))
+
+/** @copydoc _PurpleChatPrivate */
+typedef struct _PurpleChatPrivate PurpleChatPrivate;
+
+/**************************************************************************/
+/* Private data */
+/**************************************************************************/
+/** Private data for a buddy. */
+struct _PurpleBuddyPrivate {
+ char *name; /**< The name of the buddy. */
+ char *local_alias; /**< The user-set alias of the buddy */
+ char *server_alias; /**< The server-specified alias of the buddy.
+ (i.e. MSN "Friendly Names") */
+ void *proto_data; /**< This allows the prpl to associate
+ whatever data it wants with a buddy
+ TODO Remove this field. Protocols should
+ subclass PurpleBuddy and store
+ their data as they see fit. */
+ PurpleBuddyIcon *icon; /**< The buddy icon. */
+ PurpleAccount *account; /**< the account this buddy belongs to */
+ PurplePresence *presence; /**< Presense information of the buddy */
+ PurpleMediaCaps media_caps; /**< The media capabilities of the buddy. */
+};
+
+/* Buddy property enums */
+enum
+{
+ BUDDY_PROP_0,
+ BUDDY_PROP_NAME,
+ BUDDY_PROP_LOCAL_ALIAS,
+ BUDDY_PROP_SERVER_ALIAS,
+ BUDDY_PROP_ICON,
+ BUDDY_PROP_ACCOUNT,
+ BUDDY_PROP_PRESENCE,
+ BUDDY_PROP_MEDIA_CAPS,
+ BUDDY_PROP_LAST
+};
+
+/** Private data for a contact */
+struct _PurpleContactPrivate {
+ char *alias; /**< The user-set alias of the contact */
+ PurpleBuddy *priority_buddy; /**< The "top" buddy for this contact */
+ gboolean priority_valid; /**< Is priority valid? */
+};
+
+/* Contact property enums */
+enum
+{
+ CONTACT_PROP_0,
+ CONTACT_PROP_ALIAS,
+ CONTACT_PROP_PRIORITY_BUDDY,
+ CONTACT_PROP_LAST
+};
+
+/** Private data for a group */
+struct _PurpleGroupPrivate {
+ char *name; /**< The name of this group. */
+};
+
+/* Group property enums */
+enum
+{
+ GROUP_PROP_0,
+ GROUP_PROP_NAME,
+ GROUP_PROP_LAST
+};
+
+/** Private data for a chat node */
+struct _PurpleChatPrivate {
+ char *alias; /**< The display name of this chat. */
+ PurpleAccount *account; /**< The account this chat is attached to */
+ GHashTable *components; /**< the stuff the protocol needs to know to join
+ the chat */
+};
+
+/* Chat property enums */
+enum
+{
+ CHAT_PROP_0,
+ CHAT_PROP_ALIAS,
+ CHAT_PROP_ACCOUNT,
+ CHAT_PROP_COMPONENTS,
+ CHAT_PROP_LAST
+};
+
+static PurpleBlistNode *blistnode_parent_class;
+static PurpleCountingNode *counting_parent_class;
+
+static gboolean
+purple_strings_are_different(const char *one, const char *two)
+{
+ return !((one && two && g_utf8_collate(one, two) == 0) ||
+ ((one == NULL || *one == '\0') && (two == NULL || *two == '\0')));
+}
+
+PurpleBlistNode *_purple_blist_get_last_child(PurpleBlistNode *node);
+
+/**************************************************************************/
+/* Buddy API */
+/**************************************************************************/
+
+void
+purple_buddy_set_icon(PurpleBuddy *buddy, PurpleBuddyIcon *icon)
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_if_fail(priv != NULL);
+
+ if (priv->icon != icon)
+ {
+ purple_buddy_icon_unref(priv->icon);
+ priv->icon = (icon != NULL ? purple_buddy_icon_ref(icon) : NULL);
+ }
+
+ purple_signal_emit(purple_blist_get_handle(), "buddy-icon-changed", buddy);
+
+ if (ops && ops->update)
+ ops->update(purple_blist_get_buddy_list(), PURPLE_BLIST_NODE(buddy));
+}
+
+PurpleBuddyIcon *
+purple_buddy_get_icon(const PurpleBuddy *buddy)
+{
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->icon;
+}
+
+PurpleAccount *
+purple_buddy_get_account(const PurpleBuddy *buddy)
+{
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->account;
+}
+
+void
+purple_buddy_set_name(PurpleBuddy *buddy, const char *name)
+{
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+
+ g_return_if_fail(priv != NULL);
+
+ purple_blist_update_buddies_cache(buddy, name);
+
+ g_free(priv->name);
+ priv->name = purple_utf8_strip_unprintables(name);
+
+ if (ops) {
+ if (ops->save_node)
+ ops->save_node(PURPLE_BLIST_NODE(buddy));
+ if (ops->update)
+ ops->update(purple_blist_get_buddy_list(), PURPLE_BLIST_NODE(buddy));
+ }
+}
+
+const char *
+purple_buddy_get_name(const PurpleBuddy *buddy)
+{
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->name;
+}
+
+gpointer
+purple_buddy_get_protocol_data(const PurpleBuddy *buddy)
+{
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->proto_data;
+}
+
+void
+purple_buddy_set_protocol_data(PurpleBuddy *buddy, gpointer data)
+{
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->proto_data = data;
+}
+
+const char *purple_buddy_get_alias_only(PurpleBuddy *buddy)
+{
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ if ((priv->local_alias != NULL) && (*priv->local_alias != '\0')) {
+ return priv->local_alias;
+ } else if ((priv->server_alias != NULL) &&
+ (*priv->server_alias != '\0')) {
+
+ return priv->server_alias;
+ }
+
+ return NULL;
+}
+
+const char *purple_buddy_get_contact_alias(PurpleBuddy *buddy)
+{
+ PurpleContact *c;
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ /* Search for an alias for the buddy. In order of precedence: */
+ /* The local buddy alias */
+ if (priv->local_alias != NULL)
+ return priv->local_alias;
+
+ /* The contact alias */
+ c = purple_buddy_get_contact(buddy);
+ if ((c != NULL) && (purple_contact_get_alias(c) != NULL))
+ return purple_contact_get_alias(c);
+
+ /* The server alias */
+ if ((priv->server_alias) && (*priv->server_alias))
+ return priv->server_alias;
+
+ /* The buddy's user name (i.e. no alias) */
+ return priv->name;
+}
+
+const char *purple_buddy_get_alias(PurpleBuddy *buddy)
+{
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ /* Search for an alias for the buddy. In order of precedence: */
+ /* The buddy alias */
+ if (priv->local_alias != NULL)
+ return priv->local_alias;
+
+ /* The server alias */
+ if ((priv->server_alias) && (*priv->server_alias))
+ return priv->server_alias;
+
+ /* The buddy's user name (i.e. no alias) */
+ return priv->name;
+}
+
+void
+purple_buddy_set_local_alias(PurpleBuddy *buddy, const char *alias)
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ PurpleIMConversation *im;
+ char *old_alias;
+ char *new_alias = NULL;
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_if_fail(buddy != NULL);
+
+ if ((alias != NULL) && (*alias != '\0'))
+ new_alias = purple_utf8_strip_unprintables(alias);
+
+ if (!purple_strings_are_different(priv->local_alias, new_alias)) {
+ g_free(new_alias);
+ return;
+ }
+
+ old_alias = priv->local_alias;
+
+ if ((new_alias != NULL) && (*new_alias != '\0'))
+ priv->local_alias = new_alias;
+ else {
+ priv->local_alias = NULL;
+ g_free(new_alias); /* could be "\0" */
+ }
+
+ if (ops && ops->save_node)
+ ops->save_node(PURPLE_BLIST_NODE(buddy));
+
+ if (ops && ops->update)
+ ops->update(purple_blist_get_buddy_list(), PURPLE_BLIST_NODE(buddy));
+
+ im = purple_conversations_find_im_with_account(priv->name,
+ priv->account);
+ if (im)
+ purple_conversation_autoset_title(PURPLE_CONVERSATION(im));
+
+ purple_signal_emit(purple_blist_get_handle(), "blist-node-aliased",
+ buddy, old_alias);
+ g_free(old_alias);
+}
+
+const char *purple_buddy_get_local_alias(PurpleBuddy *buddy)
+{
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->local_alias;
+}
+
+void
+purple_buddy_set_server_alias(PurpleBuddy *buddy, const char *alias)
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ PurpleIMConversation *im;
+ char *old_alias;
+ char *new_alias = NULL;
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_if_fail(priv != NULL);
+
+ if ((alias != NULL) && (*alias != '\0') && g_utf8_validate(alias, -1, NULL))
+ new_alias = purple_utf8_strip_unprintables(alias);
+
+ if (!purple_strings_are_different(priv->server_alias, new_alias)) {
+ g_free(new_alias);
+ return;
+ }
+
+ old_alias = priv->server_alias;
+
+ if ((new_alias != NULL) && (*new_alias != '\0'))
+ priv->server_alias = new_alias;
+ else {
+ priv->server_alias = NULL;
+ g_free(new_alias); /* could be "\0"; */
+ }
+
+ if (ops) {
+ if (ops->save_node)
+ ops->save_node(PURPLE_BLIST_NODE(buddy));
+ if (ops->update)
+ ops->update(purple_blist_get_buddy_list(), PURPLE_BLIST_NODE(buddy));
+ }
+
+ im = purple_conversations_find_im_with_account(priv->name,
+ priv->account);
+ if (im)
+ purple_conversation_autoset_title(PURPLE_CONVERSATION(im));
+
+ purple_signal_emit(purple_blist_get_handle(), "blist-node-aliased",
+ buddy, old_alias);
+ g_free(old_alias);
+}
+
+const char *purple_buddy_get_server_alias(PurpleBuddy *buddy)
+{
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ if ((priv->server_alias) && (*priv->server_alias))
+ return priv->server_alias;
+
+ return NULL;
+}
+
+PurpleContact *purple_buddy_get_contact(PurpleBuddy *buddy)
+{
+ g_return_val_if_fail(buddy != NULL, NULL);
+
+ return PURPLE_CONTACT(PURPLE_BLIST_NODE(buddy)->parent);
+}
+
+PurplePresence *purple_buddy_get_presence(const PurpleBuddy *buddy)
+{
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->presence;
+}
+
+void
+purple_buddy_update_status(PurpleBuddy *buddy, PurpleStatus *old_status)
+{
+ PurpleStatus *status;
+ PurpleBlistNode *cnode;
+ PurpleContact *contact;
+ PurpleCountingNode *contact_counter, *group_counter;
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_if_fail(priv != NULL);
+
+ status = purple_presence_get_active_status(priv->presence);
+
+ purple_debug_info("blist", "Updating buddy status for %s (%s)\n",
+ priv->name, purple_account_get_protocol_name(priv->account));
+
+ if (purple_status_is_online(status) &&
+ !purple_status_is_online(old_status)) {
+
+ purple_signal_emit(purple_blist_get_handle(), "buddy-signed-on", buddy);
+
+ cnode = PURPLE_BLIST_NODE(buddy)->parent;
+ contact = PURPLE_CONTACT(cnode);
+ contact_counter = PURPLE_COUNTING_NODE(contact);
+ group_counter = PURPLE_COUNTING_NODE(cnode->parent);
+
+ purple_counting_node_change_online_count(contact_counter, +1);
+ if (purple_counting_node_get_online_count(contact_counter) == 1)
+ purple_counting_node_change_online_count(group_counter, +1);
+ } else if (!purple_status_is_online(status) &&
+ purple_status_is_online(old_status)) {
+
+ purple_blist_node_set_int(PURPLE_BLIST_NODE(buddy), "last_seen", time(NULL));
+ purple_signal_emit(purple_blist_get_handle(), "buddy-signed-off", buddy);
+
+ cnode = PURPLE_BLIST_NODE(buddy)->parent;
+ contact = PURPLE_CONTACT(cnode);
+ contact_counter = PURPLE_COUNTING_NODE(contact);
+ group_counter = PURPLE_COUNTING_NODE(cnode->parent);
+
+ purple_counting_node_change_online_count(contact_counter, -1);
+ if (purple_counting_node_get_online_count(contact_counter) == 0)
+ purple_counting_node_change_online_count(group_counter, -1);
+ } else {
+ purple_signal_emit(purple_blist_get_handle(),
+ "buddy-status-changed", buddy, old_status,
+ status);
+ }
+
+ /*
+ * This function used to only call the following two functions if one of
+ * the above signals had been triggered, but that's not good, because
+ * if someone's away message changes and they don't go from away to back
+ * to away then no signal is triggered.
+ *
+ * It's a safe assumption that SOMETHING called this function. PROBABLY
+ * because something, somewhere changed. Calling the stuff below
+ * certainly won't hurt anything. Unless you're on a K6-2 300.
+ */
+ purple_contact_invalidate_priority_buddy(purple_buddy_get_contact(buddy));
+
+ if (ops && ops->update)
+ ops->update(purple_blist_get_buddy_list(), PURPLE_BLIST_NODE(buddy));
+}
+
+PurpleMediaCaps purple_buddy_get_media_caps(const PurpleBuddy *buddy)
+{
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_val_if_fail(priv != NULL, 0);
+
+ return priv->media_caps;
+}
+
+void purple_buddy_set_media_caps(PurpleBuddy *buddy, PurpleMediaCaps media_caps)
+{
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->media_caps = media_caps;
+}
+
+PurpleGroup *purple_buddy_get_group(PurpleBuddy *buddy)
+{
+ g_return_val_if_fail(buddy != NULL, NULL);
+
+ if (PURPLE_BLIST_NODE(buddy)->parent == NULL)
+ return NULL;
+
+ return PURPLE_GROUP(PURPLE_BLIST_NODE(buddy)->parent->parent);
+}
+
+/**************************************************************************
+ * GObject code for PurpleBuddy
+ **************************************************************************/
+
+/* GObject Property names */
+#define BUDDY_PROP_NAME_S "name"
+#define BUDDY_PROP_LOCAL_ALIAS_S "local-alias"
+#define BUDDY_PROP_SERVER_ALIAS_S "server-alias"
+#define BUDDY_PROP_ICON_S "icon"
+#define BUDDY_PROP_ACCOUNT_S "account"
+#define BUDDY_PROP_PRESENCE_S "presence"
+#define BUDDY_PROP_MEDIA_CAPS_S "media-caps"
+
+/* Set method for GObject properties */
+static void
+purple_buddy_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleBuddy *buddy = PURPLE_BUDDY(obj);
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+
+ switch (param_id) {
+ case BUDDY_PROP_NAME:
+ priv->name = purple_utf8_strip_unprintables(g_value_get_string(value));
+ break;
+ case BUDDY_PROP_LOCAL_ALIAS:
+ priv->local_alias = purple_utf8_strip_unprintables(g_value_get_string(value));
+ break;
+ case BUDDY_PROP_SERVER_ALIAS:
+ purple_buddy_set_server_alias(buddy, g_value_get_string(value));
+ break;
+ case BUDDY_PROP_ICON:
+ purple_buddy_set_icon(buddy, g_value_get_pointer(value));
+ break;
+ case BUDDY_PROP_ACCOUNT:
+ priv->account = g_value_get_object(value);
+ break;
+ case BUDDY_PROP_MEDIA_CAPS:
+ purple_buddy_set_media_caps(buddy, g_value_get_enum(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Get method for GObject properties */
+static void
+purple_buddy_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleBuddy *buddy = PURPLE_BUDDY(obj);
+
+ switch (param_id) {
+ case BUDDY_PROP_NAME:
+ g_value_set_string(value, purple_buddy_get_name(buddy));
+ break;
+ case BUDDY_PROP_LOCAL_ALIAS:
+ g_value_set_string(value, purple_buddy_get_local_alias(buddy));
+ break;
+ case BUDDY_PROP_SERVER_ALIAS:
+ g_value_set_string(value, purple_buddy_get_server_alias(buddy));
+ break;
+ case BUDDY_PROP_ICON:
+ g_value_set_pointer(value, purple_buddy_get_icon(buddy));
+ break;
+ case BUDDY_PROP_ACCOUNT:
+ g_value_set_object(value, purple_buddy_get_account(buddy));
+ break;
+ case BUDDY_PROP_PRESENCE:
+ g_value_set_object(value, purple_buddy_get_presence(buddy));
+ break;
+ case BUDDY_PROP_MEDIA_CAPS:
+ g_value_set_enum(value, purple_buddy_get_media_caps(buddy));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* GObject initialization function */
+static void
+purple_buddy_init(GTypeInstance *instance, gpointer klass)
+{
+ PURPLE_DBUS_REGISTER_POINTER(PURPLE_BUDDY(instance), PurpleBuddy);
+}
+
+/* Called when done constructing */
+static void
+purple_buddy_constructed(GObject *object)
+{
+ PurpleBuddy *buddy = PURPLE_BUDDY(object);
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+
+ G_OBJECT_CLASS(blistnode_parent_class)->constructed(object);
+
+ priv->presence = PURPLE_PRESENCE(purple_buddy_presence_new(buddy));
+ purple_presence_set_status_active(priv->presence, "offline", TRUE);
+
+ if (ops && ops->new_node)
+ ops->new_node((PurpleBlistNode *)buddy);
+}
+
+/* GObject dispose function */
+static void
+purple_buddy_dispose(GObject *object)
+{
+ PurpleBuddy *buddy = PURPLE_BUDDY(object);
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(buddy);
+ PurplePlugin *prpl;
+ PurplePluginProtocolInfo *prpl_info;
+
+ /*
+ * Tell the owner PRPL that we're about to free the buddy so it
+ * can free proto_data
+ */
+ prpl = purple_find_prpl(purple_account_get_protocol_id(priv->account));
+ if (prpl) {
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
+ if (prpl_info && prpl_info->buddy_free)
+ prpl_info->buddy_free(buddy);
+ }
+
+ /* Delete the node */
+ purple_buddy_icon_unref(priv->icon);
+ g_object_unref(priv->presence);
+
+ PURPLE_DBUS_UNREGISTER_POINTER(buddy);
+
+ G_OBJECT_CLASS(blistnode_parent_class)->dispose(object);
+}
+
+/* GObject finalize function */
+static void
+purple_buddy_finalize(GObject *object)
+{
+ PurpleBuddyPrivate *priv = PURPLE_BUDDY_GET_PRIVATE(object);
+
+ g_free(priv->name);
+ g_free(priv->local_alias);
+ g_free(priv->server_alias);
+
+ G_OBJECT_CLASS(blistnode_parent_class)->finalize(object);
+}
+
+/* Class initializer function */
+static void purple_buddy_class_init(PurpleBuddyClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ blistnode_parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->dispose = purple_buddy_dispose;
+ obj_class->finalize = purple_buddy_finalize;
+
+ /* Setup properties */
+ obj_class->get_property = purple_buddy_get_property;
+ obj_class->set_property = purple_buddy_set_property;
+ obj_class->constructed = purple_buddy_constructed;
+
+ g_object_class_install_property(obj_class, BUDDY_PROP_NAME,
+ g_param_spec_string(BUDDY_PROP_NAME_S, _("Name"),
+ _("The name of the buddy."), NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
+ );
+
+ g_object_class_install_property(obj_class, BUDDY_PROP_LOCAL_ALIAS,
+ g_param_spec_string(BUDDY_PROP_LOCAL_ALIAS_S, _("Local alias"),
+ _("Local alias of thee buddy."), NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
+ );
+
+ g_object_class_install_property(obj_class, BUDDY_PROP_SERVER_ALIAS,
+ g_param_spec_string(BUDDY_PROP_SERVER_ALIAS_S, _("Server alias"),
+ _("Server-side alias of the buddy."), NULL,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, BUDDY_PROP_ICON,
+ g_param_spec_pointer(BUDDY_PROP_ICON_S, _("Buddy icon"),
+ _("The icon for the buddy."),
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, BUDDY_PROP_ACCOUNT,
+ g_param_spec_object(BUDDY_PROP_ACCOUNT_S, _("Account"),
+ _("The account for the buddy."), PURPLE_TYPE_ACCOUNT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)
+ );
+
+ g_object_class_install_property(obj_class, BUDDY_PROP_PRESENCE,
+ g_param_spec_object(BUDDY_PROP_PRESENCE_S, _("Presence"),
+ _("The status information for the buddy."), PURPLE_TYPE_PRESENCE,
+ G_PARAM_READABLE)
+ );
+
+ g_object_class_install_property(obj_class, BUDDY_PROP_MEDIA_CAPS,
+ g_param_spec_enum(BUDDY_PROP_MEDIA_CAPS_S, _("Media capabilities"),
+ _("The media capabilities of the buddy."),
+ PURPLE_MEDIA_TYPE_CAPS, PURPLE_MEDIA_CAPS_NONE,
+ G_PARAM_READWRITE)
+ );
+
+ g_type_class_add_private(klass, sizeof(PurpleBuddyPrivate));
+}
+
+GType
+purple_buddy_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleBuddyClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_buddy_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleBuddy),
+ 0,
+ (GInstanceInitFunc)purple_buddy_init,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_BLIST_NODE,
+ "PurpleBuddy",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleBuddy *
+purple_buddy_new(PurpleAccount *account, const char *name, const char *alias)
+{
+ g_return_val_if_fail(account != NULL, NULL);
+ g_return_val_if_fail(name != NULL, NULL);
+
+ return g_object_new(PURPLE_TYPE_BUDDY,
+ BUDDY_PROP_ACCOUNT_S, account,
+ BUDDY_PROP_NAME_S, name,
+ BUDDY_PROP_LOCAL_ALIAS_S, alias,
+ NULL);
+}
+
+/**************************************************************************/
+/* Contact API */
+/**************************************************************************/
+
+static void
+purple_contact_compute_priority_buddy(PurpleContact *contact)
+{
+ PurpleBlistNode *bnode;
+ PurpleBuddy *new_priority = NULL;
+ PurpleContactPrivate *priv = PURPLE_CONTACT_GET_PRIVATE(contact);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->priority_buddy = NULL;
+ for (bnode = PURPLE_BLIST_NODE(contact)->child;
+ bnode != NULL;
+ bnode = bnode->next)
+ {
+ PurpleBuddy *buddy;
+
+ if (!PURPLE_IS_BUDDY(bnode))
+ continue;
+
+ buddy = PURPLE_BUDDY(bnode);
+ if (new_priority == NULL)
+ {
+ new_priority = buddy;
+ continue;
+ }
+
+ if (purple_account_is_connected(purple_buddy_get_account(buddy)))
+ {
+ int cmp = 1;
+ if (purple_account_is_connected(purple_buddy_get_account(new_priority)))
+ cmp = purple_buddy_presence_compare(
+ PURPLE_BUDDY_PRESENCE(purple_buddy_get_presence(new_priority)),
+ PURPLE_BUDDY_PRESENCE(purple_buddy_get_presence(buddy)));
+
+ if (cmp > 0 || (cmp == 0 &&
+ purple_prefs_get_bool("/purple/contact/last_match")))
+ {
+ new_priority = buddy;
+ }
+ }
+ }
+
+ priv->priority_buddy = new_priority;
+ priv->priority_valid = TRUE;
+}
+
+PurpleGroup *
+purple_contact_get_group(const PurpleContact *contact)
+{
+ g_return_val_if_fail(contact, NULL);
+
+ return PURPLE_GROUP(PURPLE_BLIST_NODE(contact)->parent);
+}
+
+void
+purple_contact_set_alias(PurpleContact *contact, const char *alias)
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ PurpleIMConversation *im;
+ PurpleBlistNode *bnode;
+ char *old_alias;
+ char *new_alias = NULL;
+ PurpleContactPrivate *priv = PURPLE_CONTACT_GET_PRIVATE(contact);
+
+ g_return_if_fail(priv != NULL);
+
+ if ((alias != NULL) && (*alias != '\0'))
+ new_alias = purple_utf8_strip_unprintables(alias);
+
+ if (!purple_strings_are_different(priv->alias, new_alias)) {
+ g_free(new_alias);
+ return;
+ }
+
+ old_alias = priv->alias;
+
+ if ((new_alias != NULL) && (*new_alias != '\0'))
+ priv->alias = new_alias;
+ else {
+ priv->alias = NULL;
+ g_free(new_alias); /* could be "\0" */
+ }
+
+ if (ops) {
+ if (ops->save_node)
+ ops->save_node(PURPLE_BLIST_NODE(contact));
+ if (ops->update)
+ ops->update(purple_blist_get_buddy_list(), PURPLE_BLIST_NODE(contact));
+ }
+
+ for(bnode = PURPLE_BLIST_NODE(contact)->child; bnode != NULL; bnode = bnode->next)
+ {
+ PurpleBuddy *buddy = PURPLE_BUDDY(bnode);
+
+ im = purple_conversations_find_im_with_account(purple_buddy_get_name(buddy),
+ purple_buddy_get_account(buddy));
+ if (im)
+ purple_conversation_autoset_title(PURPLE_CONVERSATION(im));
+ }
+
+ purple_signal_emit(purple_blist_get_handle(), "blist-node-aliased",
+ contact, old_alias);
+ g_free(old_alias);
+}
+
+const char *purple_contact_get_alias(PurpleContact* contact)
+{
+ PurpleContactPrivate *priv = PURPLE_CONTACT_GET_PRIVATE(contact);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ if (priv->alias)
+ return priv->alias;
+
+ return purple_buddy_get_alias(purple_contact_get_priority_buddy(contact));
+}
+
+gboolean purple_contact_on_account(PurpleContact *c, PurpleAccount *account)
+{
+ PurpleBlistNode *bnode, *cnode = (PurpleBlistNode *) c;
+
+ g_return_val_if_fail(c != NULL, FALSE);
+ g_return_val_if_fail(account != NULL, FALSE);
+
+ for (bnode = cnode->child; bnode; bnode = bnode->next) {
+ PurpleBuddy *buddy;
+
+ if (! PURPLE_IS_BUDDY(bnode))
+ continue;
+
+ buddy = (PurpleBuddy *)bnode;
+ if (purple_buddy_get_account(buddy) == account)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void purple_contact_invalidate_priority_buddy(PurpleContact *contact)
+{
+ PurpleContactPrivate *priv = PURPLE_CONTACT_GET_PRIVATE(contact);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->priority_valid = FALSE;
+}
+
+PurpleBuddy *purple_contact_get_priority_buddy(PurpleContact *contact)
+{
+ PurpleContactPrivate *priv = PURPLE_CONTACT_GET_PRIVATE(contact);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ if (!priv->priority_valid)
+ purple_contact_compute_priority_buddy(contact);
+
+ return priv->priority_buddy;
+}
+
+void purple_contact_merge(PurpleContact *source, PurpleBlistNode *node)
+{
+ PurpleBlistNode *sourcenode = (PurpleBlistNode*)source;
+ PurpleBlistNode *prev, *cur, *next;
+ PurpleContact *target;
+
+ g_return_if_fail(source != NULL);
+ g_return_if_fail(node != NULL);
+
+ if (PURPLE_IS_CONTACT(node)) {
+ target = (PurpleContact *)node;
+ prev = _purple_blist_get_last_child(node);
+ } else if (PURPLE_IS_BUDDY(node)) {
+ target = (PurpleContact *)node->parent;
+ prev = node;
+ } else {
+ return;
+ }
+
+ if (source == target || !target)
+ return;
+
+ next = sourcenode->child;
+
+ while (next) {
+ cur = next;
+ next = cur->next;
+ if (PURPLE_IS_BUDDY(cur)) {
+ purple_blist_add_buddy((PurpleBuddy *)cur, target, NULL, prev);
+ prev = cur;
+ }
+ }
+}
+
+/**************************************************************************
+ * GObject code for PurpleContact
+ **************************************************************************/
+
+/* GObject Property names */
+#define CONTACT_PROP_ALIAS_S "alias"
+#define CONTACT_PROP_PRIORITY_BUDDY_S "priority-buddy"
+
+/* Set method for GObject properties */
+static void
+purple_contact_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleContact *contact = PURPLE_CONTACT(obj);
+
+ switch (param_id) {
+ case CONTACT_PROP_ALIAS:
+ purple_contact_set_alias(contact, g_value_get_string(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Get method for GObject properties */
+static void
+purple_contact_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleContact *contact = PURPLE_CONTACT(obj);
+ PurpleContactPrivate *priv = PURPLE_CONTACT_GET_PRIVATE(contact);
+
+ switch (param_id) {
+ case CONTACT_PROP_ALIAS:
+ g_value_set_string(value, priv->alias);
+ break;
+ case CONTACT_PROP_PRIORITY_BUDDY:
+ g_value_set_object(value, purple_contact_get_priority_buddy(contact));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* GObject initialization function */
+static void
+purple_contact_init(GTypeInstance *instance, gpointer klass)
+{
+ PurpleContact *contact = PURPLE_CONTACT(instance);
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+
+ if (ops && ops->new_node)
+ ops->new_node(PURPLE_BLIST_NODE(contact));
+
+ PURPLE_DBUS_REGISTER_POINTER(contact, PurpleContact);
+}
+
+/* GObject dispose function */
+static void
+purple_contact_dispose(GObject *object)
+{
+ PURPLE_DBUS_UNREGISTER_POINTER(object);
+
+ G_OBJECT_CLASS(counting_parent_class)->dispose(object);
+}
+
+/* GObject finalize function */
+static void
+purple_contact_finalize(GObject *object)
+{
+ g_free(PURPLE_CONTACT_GET_PRIVATE(object)->alias);
+
+ G_OBJECT_CLASS(counting_parent_class)->finalize(object);
+}
+
+/* Class initializer function */
+static void purple_contact_class_init(PurpleContactClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ counting_parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->dispose = purple_contact_dispose;
+ obj_class->finalize = purple_contact_finalize;
+
+ /* Setup properties */
+ obj_class->get_property = purple_contact_get_property;
+ obj_class->set_property = purple_contact_set_property;
+
+ g_object_class_install_property(obj_class, CONTACT_PROP_ALIAS,
+ g_param_spec_string(CONTACT_PROP_ALIAS_S, _("Alias"),
+ _("The alias for the contact."), NULL,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, CONTACT_PROP_PRIORITY_BUDDY,
+ g_param_spec_object(CONTACT_PROP_PRIORITY_BUDDY_S,
+ _("Priority buddy"), _("The priority buddy of the contact."),
+ PURPLE_TYPE_BUDDY, G_PARAM_READABLE)
+ );
+
+ g_type_class_add_private(klass, sizeof(PurpleContactPrivate));
+}
+
+GType
+purple_contact_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleContactClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_contact_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleContact),
+ 0,
+ (GInstanceInitFunc)purple_contact_init,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_COUNTING_NODE,
+ "PurpleContact",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleContact *
+purple_contact_new(void)
+{
+ return g_object_new(PURPLE_TYPE_CONTACT, NULL);
+}
+
+/**************************************************************************/
+/* Chat API */
+/**************************************************************************/
+
+const char *purple_chat_get_name(PurpleChat *chat)
+{
+ PurpleChatPrivate *priv = PURPLE_CHAT_GET_PRIVATE(chat);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ if ((priv->alias != NULL) && (*priv->alias != '\0'))
+ return priv->alias;
+
+ return purple_chat_get_name_only(chat);
+}
+
+const char *purple_chat_get_name_only(PurpleChat *chat)
+{
+ char *ret = NULL;
+ PurplePlugin *prpl;
+ PurplePluginProtocolInfo *prpl_info = NULL;
+ PurpleChatPrivate *priv = PURPLE_CHAT_GET_PRIVATE(chat);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ prpl = purple_find_prpl(purple_account_get_protocol_id(priv->account));
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
+
+ if (prpl_info->chat_info) {
+ struct proto_chat_entry *pce;
+ GList *parts = prpl_info->chat_info(purple_account_get_connection(priv->account));
+ pce = parts->data;
+ ret = g_hash_table_lookup(priv->components, pce->identifier);
+ g_list_foreach(parts, (GFunc)g_free, NULL);
+ g_list_free(parts);
+ }
+
+ return ret;
+}
+
+void
+purple_chat_set_alias(PurpleChat *chat, const char *alias)
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ char *old_alias;
+ char *new_alias = NULL;
+ PurpleChatPrivate *priv = PURPLE_CHAT_GET_PRIVATE(chat);
+
+ g_return_if_fail(priv != NULL);
+
+ if ((alias != NULL) && (*alias != '\0'))
+ new_alias = purple_utf8_strip_unprintables(alias);
+
+ if (!purple_strings_are_different(priv->alias, new_alias)) {
+ g_free(new_alias);
+ return;
+ }
+
+ old_alias = priv->alias;
+
+ if ((new_alias != NULL) && (*new_alias != '\0'))
+ priv->alias = new_alias;
+ else {
+ priv->alias = NULL;
+ g_free(new_alias); /* could be "\0" */
+ }
+
+ if (ops) {
+ if (ops->save_node)
+ ops->save_node(PURPLE_BLIST_NODE(chat));
+ if (ops->update)
+ ops->update(purple_blist_get_buddy_list(), PURPLE_BLIST_NODE(chat));
+ }
+
+ purple_signal_emit(purple_blist_get_handle(), "blist-node-aliased",
+ chat, old_alias);
+ g_free(old_alias);
+}
+
+PurpleGroup *
+purple_chat_get_group(PurpleChat *chat)
+{
+ g_return_val_if_fail(chat != NULL, NULL);
+
+ return PURPLE_GROUP(PURPLE_BLIST_NODE(chat)->parent);
+}
+
+PurpleAccount *
+purple_chat_get_account(PurpleChat *chat)
+{
+ PurpleChatPrivate *priv = PURPLE_CHAT_GET_PRIVATE(chat);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->account;
+}
+
+GHashTable *
+purple_chat_get_components(PurpleChat *chat)
+{
+ PurpleChatPrivate *priv = PURPLE_CHAT_GET_PRIVATE(chat);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->components;
+}
+
+/**************************************************************************
+ * GObject code for PurpleChat
+ **************************************************************************/
+
+/* GObject Property names */
+#define CHAT_PROP_ALIAS_S "alias"
+#define CHAT_PROP_ACCOUNT_S "account"
+#define CHAT_PROP_COMPONENTS_S "components"
+
+/* Set method for GObject properties */
+static void
+purple_chat_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleChat *chat = PURPLE_CHAT(obj);
+ PurpleChatPrivate *priv = PURPLE_CHAT_GET_PRIVATE(chat);
+
+ switch (param_id) {
+ case CHAT_PROP_ALIAS:
+ priv->alias = purple_utf8_strip_unprintables(g_value_get_string(value));
+ break;
+ case CHAT_PROP_ACCOUNT:
+ priv->account = g_value_get_object(value);
+ break;
+ case CHAT_PROP_COMPONENTS:
+ priv->components = g_value_get_pointer(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Get method for GObject properties */
+static void
+purple_chat_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleChat *chat = PURPLE_CHAT(obj);
+ PurpleChatPrivate *priv = PURPLE_CHAT_GET_PRIVATE(chat);
+
+ switch (param_id) {
+ case CHAT_PROP_ALIAS:
+ g_value_set_string(value, priv->alias);
+ break;
+ case CHAT_PROP_ACCOUNT:
+ g_value_set_object(value, purple_chat_get_account(chat));
+ break;
+ case CHAT_PROP_COMPONENTS:
+ g_value_set_pointer(value, purple_chat_get_components(chat));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* GObject initialization function */
+static void
+purple_chat_init(GTypeInstance *instance, gpointer klass)
+{
+ PURPLE_DBUS_REGISTER_POINTER(PURPLE_CHAT(instance), PurpleChat);
+}
+
+/* Called when done constructing */
+static void
+purple_chat_constructed(GObject *object)
+{
+ PurpleChat *chat = PURPLE_CHAT(object);
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+
+ G_OBJECT_CLASS(blistnode_parent_class)->constructed(object);
+
+ if (ops != NULL && ops->new_node != NULL)
+ ops->new_node(PURPLE_BLIST_NODE(chat));
+}
+
+/* GObject dispose function */
+static void
+purple_chat_dispose(GObject *object)
+{
+ PURPLE_DBUS_UNREGISTER_POINTER(object);
+
+ G_OBJECT_CLASS(blistnode_parent_class)->dispose(object);
+}
+
+/* GObject finalize function */
+static void
+purple_chat_finalize(GObject *object)
+{
+ PurpleChatPrivate *priv = PURPLE_CHAT_GET_PRIVATE(object);
+
+ g_free(priv->alias);
+ g_hash_table_destroy(priv->components);
+
+ G_OBJECT_CLASS(blistnode_parent_class)->finalize(object);
+}
+
+/* Class initializer function */
+static void purple_chat_class_init(PurpleChatClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ blistnode_parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->dispose = purple_chat_dispose;
+ obj_class->finalize = purple_chat_finalize;
+
+ /* Setup properties */
+ obj_class->get_property = purple_chat_get_property;
+ obj_class->set_property = purple_chat_set_property;
+ obj_class->constructed = purple_chat_constructed;
+
+ g_object_class_install_property(obj_class, CHAT_PROP_ALIAS,
+ g_param_spec_string(CHAT_PROP_ALIAS_S, _("Alias"),
+ _("The alias for the chat."), NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
+ );
+
+ g_object_class_install_property(obj_class, CHAT_PROP_ACCOUNT,
+ g_param_spec_object(CHAT_PROP_ACCOUNT_S, _("Account"),
+ _("The account that the chat belongs to."), PURPLE_TYPE_ACCOUNT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)
+ );
+
+ g_object_class_install_property(obj_class, CHAT_PROP_COMPONENTS,
+ g_param_spec_pointer(CHAT_PROP_COMPONENTS_S, _("Components"),
+ _("The protocol components of the chat."),
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)
+ );
+
+ g_type_class_add_private(klass, sizeof(PurpleChatPrivate));
+}
+
+GType
+purple_chat_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleChatClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_chat_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleChat),
+ 0,
+ (GInstanceInitFunc)purple_chat_init,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_BLIST_NODE,
+ "PurpleChat",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleChat *
+purple_chat_new(PurpleAccount *account, const char *alias, GHashTable *components)
+{
+ g_return_val_if_fail(account != NULL, NULL);
+ g_return_val_if_fail(components != NULL, NULL);
+
+ return g_object_new(PURPLE_TYPE_CHAT,
+ CHAT_PROP_ACCOUNT_S, account,
+ CHAT_PROP_ALIAS_S, alias,
+ CHAT_PROP_COMPONENTS_S, components,
+ NULL);
+}
+
+/**************************************************************************/
+/* Group API */
+/**************************************************************************/
+
+GSList *purple_group_get_accounts(PurpleGroup *group)
+{
+ GSList *l = NULL;
+ PurpleBlistNode *gnode, *cnode, *bnode;
+
+ gnode = (PurpleBlistNode *)group;
+
+ for (cnode = gnode->child; cnode; cnode = cnode->next) {
+ if (PURPLE_IS_CHAT(cnode)) {
+ if (!g_slist_find(l, purple_chat_get_account(PURPLE_CHAT(cnode))))
+ l = g_slist_append(l, purple_chat_get_account(PURPLE_CHAT(cnode)));
+ } else if (PURPLE_IS_CONTACT(cnode)) {
+ for (bnode = cnode->child; bnode; bnode = bnode->next) {
+ if (PURPLE_IS_BUDDY(bnode)) {
+ if (!g_slist_find(l, purple_buddy_get_account(PURPLE_BUDDY(bnode))))
+ l = g_slist_append(l, purple_buddy_get_account(PURPLE_BUDDY(bnode)));
+ }
+ }
+ }
+ }
+
+ return l;
+}
+
+gboolean purple_group_on_account(PurpleGroup *g, PurpleAccount *account)
+{
+ PurpleBlistNode *cnode;
+ for (cnode = ((PurpleBlistNode *)g)->child; cnode; cnode = cnode->next) {
+ if (PURPLE_IS_CONTACT(cnode)) {
+ if(purple_contact_on_account((PurpleContact *) cnode, account))
+ return TRUE;
+ } else if (PURPLE_IS_CHAT(cnode)) {
+ PurpleChat *chat = (PurpleChat *)cnode;
+ if ((!account && purple_account_is_connected(purple_chat_get_account(chat)))
+ || purple_chat_get_account(chat) == account)
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * TODO: If merging, prompt the user if they want to merge.
+ */
+void purple_group_set_name(PurpleGroup *source, const char *name)
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ PurpleGroup *dest;
+ gchar *old_name;
+ gchar *new_name;
+ GList *moved_buddies = NULL;
+ GSList *accts;
+ PurpleGroupPrivate *priv = PURPLE_GROUP_GET_PRIVATE(source);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(name != NULL);
+
+ new_name = purple_utf8_strip_unprintables(name);
+
+ if (*new_name == '\0' || purple_strequal(new_name, priv->name)) {
+ g_free(new_name);
+ return;
+ }
+
+ dest = purple_blist_find_group(new_name);
+ if (dest != NULL && purple_utf8_strcasecmp(priv->name,
+ PURPLE_GROUP_GET_PRIVATE(dest)->name) != 0) {
+ /* We're merging two groups */
+ PurpleBlistNode *prev, *child, *next;
+
+ prev = _purple_blist_get_last_child((PurpleBlistNode*)dest);
+ child = PURPLE_BLIST_NODE(source)->child;
+
+ /*
+ * TODO: This seems like a dumb way to do this... why not just
+ * append all children from the old group to the end of the new
+ * one? PRPLs might be expecting to receive an add_buddy() for
+ * each moved buddy...
+ */
+ while (child)
+ {
+ next = child->next;
+ if (PURPLE_IS_CONTACT(child)) {
+ PurpleBlistNode *bnode;
+ purple_blist_add_contact((PurpleContact *)child, dest, prev);
+ for (bnode = child->child; bnode != NULL; bnode = bnode->next) {
+ purple_blist_add_buddy((PurpleBuddy *)bnode, (PurpleContact *)child,
+ NULL, bnode->prev);
+ moved_buddies = g_list_append(moved_buddies, bnode);
+ }
+ prev = child;
+ } else if (PURPLE_IS_CHAT(child)) {
+ purple_blist_add_chat((PurpleChat *)child, dest, prev);
+ prev = child;
+ } else {
+ purple_debug(PURPLE_DEBUG_ERROR, "blist",
+ "Unknown child type in group %s\n", priv->name);
+ }
+ child = next;
+ }
+
+ /* Make a copy of the old group name and then delete the old group */
+ old_name = g_strdup(priv->name);
+ purple_blist_remove_group(source);
+ source = dest;
+ g_free(new_name);
+ } else {
+ /* A simple rename */
+ PurpleBlistNode *cnode, *bnode;
+
+ /* Build a GList of all buddies in this group */
+ for (cnode = PURPLE_BLIST_NODE(source)->child; cnode != NULL; cnode = cnode->next) {
+ if (PURPLE_IS_CONTACT(cnode))
+ for (bnode = cnode->child; bnode != NULL; bnode = bnode->next)
+ moved_buddies = g_list_append(moved_buddies, bnode);
+ }
+
+ purple_blist_update_groups_cache(source, new_name);
+
+ old_name = priv->name;
+ priv->name = new_name;
+ }
+
+ /* Save our changes */
+ if (ops && ops->save_node)
+ ops->save_node(PURPLE_BLIST_NODE(source));
+
+ /* Update the UI */
+ if (ops && ops->update)
+ ops->update(purple_blist_get_buddy_list(), PURPLE_BLIST_NODE(source));
+
+ /* Notify all PRPLs */
+ /* TODO: Is this condition needed? Seems like it would always be TRUE */
+ if(old_name && !purple_strequal(priv->name, old_name)) {
+ for (accts = purple_group_get_accounts(source); accts; accts = g_slist_remove(accts, accts->data)) {
+ PurpleAccount *account = accts->data;
+ PurpleConnection *gc = NULL;
+ PurplePlugin *prpl = NULL;
+ PurplePluginProtocolInfo *prpl_info = NULL;
+ GList *l = NULL, *buddies = NULL;
+
+ gc = purple_account_get_connection(account);
+
+ if(gc)
+ prpl = purple_connection_get_prpl(gc);
+
+ if(gc && prpl)
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
+
+ if(!prpl_info)
+ continue;
+
+ for(l = moved_buddies; l; l = l->next) {
+ PurpleBuddy *buddy = PURPLE_BUDDY(l->data);
+
+ if(buddy && purple_buddy_get_account(buddy) == account)
+ buddies = g_list_append(buddies, (PurpleBlistNode *)buddy);
+ }
+
+ if(prpl_info->rename_group) {
+ prpl_info->rename_group(gc, old_name, source, buddies);
+ } else {
+ GList *cur, *groups = NULL;
+
+ /* Make a list of what the groups each buddy is in */
+ for(cur = buddies; cur; cur = cur->next) {
+ PurpleBlistNode *node = (PurpleBlistNode *)cur->data;
+ groups = g_list_prepend(groups, node->parent->parent);
+ }
+
+ purple_account_remove_buddies(account, buddies, groups);
+ g_list_free(groups);
+ purple_account_add_buddies(account, buddies, NULL);
+ }
+
+ g_list_free(buddies);
+ }
+ }
+ g_list_free(moved_buddies);
+ g_free(old_name);
+}
+
+const char *purple_group_get_name(PurpleGroup *group)
+{
+ PurpleGroupPrivate *priv = PURPLE_GROUP_GET_PRIVATE(group);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->name;
+}
+
+/**************************************************************************
+ * GObject code for PurpleGroup
+ **************************************************************************/
+
+/* GObject Property names */
+#define GROUP_PROP_NAME_S "name"
+
+/* Set method for GObject properties */
+static void
+purple_group_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleGroupPrivate *priv = PURPLE_GROUP_GET_PRIVATE(obj);
+
+ switch (param_id) {
+ case GROUP_PROP_NAME:
+ priv->name = purple_utf8_strip_unprintables(g_value_get_string(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Get method for GObject properties */
+static void
+purple_group_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleGroup *group = PURPLE_GROUP(obj);
+
+ switch (param_id) {
+ case GROUP_PROP_NAME:
+ g_value_set_string(value, purple_group_get_name(group));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* GObject initialization function */
+static void
+purple_group_init(GTypeInstance *instance, gpointer klass)
+{
+ PURPLE_DBUS_REGISTER_POINTER(PURPLE_GROUP(instance), PurpleGroup);
+}
+
+/* Called when done constructing */
+static void
+purple_group_constructed(GObject *object)
+{
+ PurpleGroup *group = PURPLE_GROUP(object);
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+
+ G_OBJECT_CLASS(counting_parent_class)->constructed(object);
+
+ if (ops && ops->new_node)
+ ops->new_node(PURPLE_BLIST_NODE(group));
+}
+
+/* GObject dispose function */
+static void
+purple_group_dispose(GObject *object)
+{
+ PURPLE_DBUS_UNREGISTER_POINTER(object);
+
+ G_OBJECT_CLASS(counting_parent_class)->dispose(object);
+}
+
+/* GObject finalize function */
+static void
+purple_group_finalize(GObject *object)
+{
+ g_free(PURPLE_GROUP_GET_PRIVATE(object)->name);
+
+ G_OBJECT_CLASS(counting_parent_class)->finalize(object);
+}
+
+/* Class initializer function */
+static void purple_group_class_init(PurpleGroupClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ counting_parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->dispose = purple_group_dispose;
+ obj_class->finalize = purple_group_finalize;
+ obj_class->constructed = purple_group_constructed;
+
+ /* Setup properties */
+ obj_class->get_property = purple_group_get_property;
+ obj_class->set_property = purple_group_set_property;
+
+ g_object_class_install_property(obj_class, GROUP_PROP_NAME,
+ g_param_spec_string(GROUP_PROP_NAME_S, _("Name"),
+ _("Name of the group."), NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
+ );
+
+ g_type_class_add_private(klass, sizeof(PurpleGroupPrivate));
+}
+
+GType
+purple_group_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleGroupClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_group_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleGroup),
+ 0,
+ (GInstanceInitFunc)purple_group_init,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_COUNTING_NODE,
+ "PurpleGroup",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleGroup *
+purple_group_new(const char *name)
+{
+ PurpleGroup *group;
+
+ g_return_val_if_fail(name != NULL, NULL);
+ g_return_val_if_fail(*name != '\0', NULL);
+
+ group = purple_blist_find_group(name);
+ if (group != NULL)
+ return group;
+
+ return g_object_new(PURPLE_TYPE_GROUP, GROUP_PROP_NAME_S, name, NULL);
+}
diff --git a/libpurple/blistnodetypes.h b/libpurple/blistnodetypes.h
new file mode 100644
index 0000000000..578955bc7f
--- /dev/null
+++ b/libpurple/blistnodetypes.h
@@ -0,0 +1,611 @@
+/**
+ * @file blistnodetypes.h Buddy, Chat, Contact and Group API
+ * @ingroup core
+ */
+/* 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 _PURPLE_BLISTNODE_TYPES_H_
+#define _PURPLE_BLISTNODE_TYPES_H_
+
+#include "blistnode.h"
+
+#define PURPLE_TYPE_BUDDY (purple_buddy_get_type())
+#define PURPLE_BUDDY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_BUDDY, PurpleBuddy))
+#define PURPLE_BUDDY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_BUDDY, PurpleBuddyClass))
+#define PURPLE_IS_BUDDY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_BUDDY))
+#define PURPLE_IS_BUDDY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_BUDDY))
+#define PURPLE_BUDDY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_BUDDY, PurpleBuddyClass))
+
+/** @copydoc _PurpleBuddy */
+typedef struct _PurpleBuddy PurpleBuddy;
+/** @copydoc _PurpleBuddyClass */
+typedef struct _PurpleBuddyClass PurpleBuddyClass;
+
+#define PURPLE_TYPE_CONTACT (purple_contact_get_type())
+#define PURPLE_CONTACT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_CONTACT, PurpleContact))
+#define PURPLE_CONTACT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_CONTACT, PurpleContactClass))
+#define PURPLE_IS_CONTACT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_CONTACT))
+#define PURPLE_IS_CONTACT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_CONTACT))
+#define PURPLE_CONTACT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_CONTACT, PurpleContactClass))
+
+/** @copydoc _PurpleContact */
+typedef struct _PurpleContact PurpleContact;
+/** @copydoc _PurpleContactClass */
+typedef struct _PurpleContactClass PurpleContactClass;
+
+#define PURPLE_TYPE_GROUP (purple_group_get_type())
+#define PURPLE_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_GROUP, PurpleGroup))
+#define PURPLE_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_GROUP, PurpleGroupClass))
+#define PURPLE_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_GROUP))
+#define PURPLE_IS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_GROUP))
+#define PURPLE_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_GROUP, PurpleGroupClass))
+
+/** @copydoc _PurpleGroup */
+typedef struct _PurpleGroup PurpleGroup;
+/** @copydoc _PurpleGroupClass */
+typedef struct _PurpleGroupClass PurpleGroupClass;
+
+#define PURPLE_TYPE_CHAT (purple_chat_get_type())
+#define PURPLE_CHAT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_CHAT, PurpleChat))
+#define PURPLE_CHAT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_CHAT, PurpleChatClass))
+#define PURPLE_IS_CHAT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_CHAT))
+#define PURPLE_IS_CHAT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_CHAT))
+#define PURPLE_CHAT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_CHAT, PurpleChatClass))
+
+/** @copydoc _PurpleChat */
+typedef struct _PurpleChat PurpleChat;
+/** @copydoc _PurpleChatClass */
+typedef struct _PurpleChatClass PurpleChatClass;
+
+#include "account.h"
+#include "buddyicon.h"
+#include "media.h"
+#include "presence.h"
+#include "status.h"
+
+#define PURPLE_BUDDY_IS_ONLINE(b) \
+ (PURPLE_IS_BUDDY(b) \
+ && purple_account_is_connected(purple_buddy_get_account(PURPLE_BUDDY(b))) \
+ && purple_presence_is_online(purple_buddy_get_presence(PURPLE_BUDDY(b))))
+
+#define PURPLE_BLIST_NODE_NAME(n) \
+ (PURPLE_IS_CHAT(n) ? purple_chat_get_name(PURPLE_CHAT(n)) : \
+ PURPLE_IS_BUDDY(n) ? purple_buddy_get_name(PURPLE_BUDDY(n)) : NULL)
+
+/**************************************************************************/
+/* Data Structures */
+/**************************************************************************/
+/**
+ * A buddy on the buddy list.
+ */
+struct _PurpleBuddy {
+ /** The node that this buddy inherits from */
+ PurpleBlistNode node;
+};
+
+/** The base class for all #PurpleBuddy's. */
+struct _PurpleBuddyClass {
+ /*< private >*/
+ PurpleBlistNodeClass node_class;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+/**
+ * A contact on the buddy list.
+ */
+struct _PurpleContact {
+ /**
+ * The counting node that this contact inherits from. This keeps track
+ * of the counts of the buddies under this contact.
+ */
+ PurpleCountingNode counting;
+};
+
+/** The base class for all #PurpleContact's. */
+struct _PurpleContactClass {
+ /*< private >*/
+ PurpleCountingNodeClass counting_class;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+/**
+ * A group on the buddy list.
+ */
+struct _PurpleGroup {
+ /**
+ * The counting node that this group inherits from. This keeps track
+ * of the counts of the chats and contacts under this group.
+ */
+ PurpleCountingNode counting;
+};
+
+/** The base class for all #PurpleGroup's. */
+struct _PurpleGroupClass {
+ /*< private >*/
+ PurpleCountingNodeClass counting_class;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+/**
+ * A chat on the buddy list.
+ */
+struct _PurpleChat {
+ /** The node that this chat inherits from */
+ PurpleBlistNode node;
+};
+
+/** The base class for all #PurpleChat's. */
+struct _PurpleChatClass {
+ /*< private >*/
+ PurpleBlistNodeClass node_class;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+/**************************************************************************/
+/** @name Buddy API */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the GType for the PurpleBuddy object.
+ */
+GType purple_buddy_get_type(void);
+
+/**
+ * Creates a new buddy.
+ *
+ * This function only creates the PurpleBuddy. Use purple_blist_add_buddy
+ * to add the buddy to the list and purple_account_add_buddy to sync up
+ * with the server.
+ *
+ * @param account The account this buddy will get added to
+ * @param name The name of the new buddy
+ * @param alias The alias of the new buddy (or NULL if unaliased)
+ * @return A newly allocated buddy
+ *
+ * @see purple_account_add_buddy
+ * @see purple_blist_add_buddy
+ */
+PurpleBuddy *purple_buddy_new(PurpleAccount *account, const char *name, const char *alias);
+
+/**
+ * Sets a buddy's icon.
+ *
+ * This should only be called from within Purple. You probably want to
+ * call purple_buddy_icon_set_data().
+ *
+ * @param buddy The buddy.
+ * @param icon The buddy icon.
+ *
+ * @see purple_buddy_icon_set_data()
+ */
+void purple_buddy_set_icon(PurpleBuddy *buddy, PurpleBuddyIcon *icon);
+
+/**
+ * Returns a buddy's icon.
+ *
+ * @param buddy The buddy.
+ *
+ * @return The buddy icon.
+ */
+PurpleBuddyIcon *purple_buddy_get_icon(const PurpleBuddy *buddy);
+
+/**
+ * Returns a buddy's account.
+ *
+ * @param buddy The buddy.
+ *
+ * @return The account
+ */
+PurpleAccount *purple_buddy_get_account(const PurpleBuddy *buddy);
+
+/**
+ * Sets a buddy's name
+ *
+ * @param buddy The buddy.
+ * @param name The name.
+ */
+void purple_buddy_set_name(PurpleBuddy *buddy, const char *name);
+
+/**
+ * Returns a buddy's name
+ *
+ * @param buddy The buddy.
+ *
+ * @return The name.
+ */
+const char *purple_buddy_get_name(const PurpleBuddy *buddy);
+
+/**
+ * Returns a buddy's protocol-specific data.
+ *
+ * This should only be called from the associated prpl.
+ *
+ * @param buddy The buddy.
+ * @return The protocol data.
+ *
+ * @see purple_buddy_set_protocol_data()
+ */
+gpointer purple_buddy_get_protocol_data(const PurpleBuddy *buddy);
+
+/**
+ * Sets a buddy's protocol-specific data.
+ *
+ * This should only be called from the associated prpl.
+ *
+ * @param buddy The buddy.
+ * @param data The data.
+ *
+ * @see purple_buddy_get_protocol_data()
+ */
+void purple_buddy_set_protocol_data(PurpleBuddy *buddy, gpointer data);
+
+/**
+ * Returns a buddy's contact.
+ *
+ * @param buddy The buddy.
+ *
+ * @return The buddy's contact.
+ */
+PurpleContact *purple_buddy_get_contact(PurpleBuddy *buddy);
+
+/**
+ * Returns a buddy's presence.
+ *
+ * @param buddy The buddy.
+ *
+ * @return The buddy's presence.
+ */
+PurplePresence *purple_buddy_get_presence(const PurpleBuddy *buddy);
+
+/**
+ * Updates a buddy's status.
+ *
+ * This should only be called from within Purple.
+ *
+ * @param buddy The buddy whose status has changed.
+ * @param old_status The status from which we are changing.
+ */
+void purple_buddy_update_status(PurpleBuddy *buddy, PurpleStatus *old_status);
+
+/**
+ * Gets the media caps from a buddy.
+ *
+ * @param buddy The buddy.
+ * @return The media caps.
+ */
+PurpleMediaCaps purple_buddy_get_media_caps(const PurpleBuddy *buddy);
+
+/**
+ * Sets the media caps for a buddy.
+ *
+ * @param buddy The PurpleBuddy.
+ * @param media_caps The PurpleMediaCaps.
+ */
+void purple_buddy_set_media_caps(PurpleBuddy *buddy, PurpleMediaCaps media_caps);
+
+/**
+ * Returns the alias of a buddy.
+ *
+ * @param buddy The buddy whose alias will be returned.
+ * @return The alias (if set), server alias (if set),
+ * or NULL.
+ */
+const char *purple_buddy_get_alias_only(PurpleBuddy *buddy);
+
+/**
+ * Sets the server alias for a buddy.
+ *
+ * @param buddy The buddy.
+ * @param alias The server alias to be set.
+ */
+void purple_buddy_set_server_alias(PurpleBuddy *buddy, const char *alias);
+
+/**
+ * Gets the server alias for a buddy.
+ *
+ * @param buddy The buddy whose server alias will be returned
+ * @return The server alias, or NULL if it is not set.
+ */
+const char *purple_buddy_get_server_alias(PurpleBuddy *buddy);
+
+/**
+ * Returns the correct name to display for a buddy, taking the contact alias
+ * into account. In order of precedence: the buddy's alias; the buddy's
+ * contact alias; the buddy's server alias; the buddy's user name.
+ *
+ * @param buddy The buddy whose alias will be returned
+ * @return The appropriate name or alias, or NULL.
+ *
+ */
+const char *purple_buddy_get_contact_alias(PurpleBuddy *buddy);
+
+/**
+ * Returns the correct name to display for a buddy. In order of precedence:
+ * the buddy's local alias; the buddy's server alias; the buddy's contact alias;
+ * the buddy's user name.
+ *
+ * @param buddy The buddy whose alias will be returned.
+ * @return The appropriate name or alias, or NULL
+ */
+const char *purple_buddy_get_alias(PurpleBuddy *buddy);
+
+/**
+ * Sets the local alias for the buddy.
+ *
+ * @param buddy The buddy
+ * @param alias The local alias for the buddy
+ */
+void purple_buddy_set_local_alias(PurpleBuddy *buddy, const char *alias);
+
+/**
+ * Returns the local alias for the buddy, or @c NULL if none exists.
+ *
+ * @param buddy The buddy
+ * @return The local alias for the buddy
+ */
+const char *purple_buddy_get_local_alias(PurpleBuddy *buddy);
+
+/**
+ * Returns the group of which the buddy is a member.
+ *
+ * @param buddy The buddy
+ * @return The group or NULL if the buddy is not in a group
+ */
+PurpleGroup *purple_buddy_get_group(PurpleBuddy *buddy);
+
+/*@}*/
+
+/**************************************************************************/
+/** @name Contact API */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the GType for the PurpleContact object.
+ */
+GType purple_contact_get_type(void);
+
+/**
+ * Creates a new contact
+ *
+ * @return A new contact struct
+ */
+PurpleContact *purple_contact_new(void);
+
+/**
+ * Gets the PurpleGroup from a PurpleContact
+ *
+ * @param contact The contact
+ * @return The group
+ */
+PurpleGroup *purple_contact_get_group(const PurpleContact *contact);
+
+/**
+ * Returns the highest priority buddy for a given contact.
+ *
+ * @param contact The contact
+ * @return The highest priority buddy
+ */
+PurpleBuddy *purple_contact_get_priority_buddy(PurpleContact *contact);
+
+/**
+ * Sets the alias for a contact.
+ *
+ * @param contact The contact
+ * @param alias The alias
+ */
+void purple_contact_set_alias(PurpleContact *contact, const char *alias);
+
+/**
+ * Gets the alias for a contact.
+ *
+ * @param contact The contact
+ * @return The alias, or NULL if it is not set.
+ */
+const char *purple_contact_get_alias(PurpleContact *contact);
+
+/**
+ * Determines whether an account owns any buddies in a given contact
+ *
+ * @param contact The contact to search through.
+ * @param account The account.
+ *
+ * @return TRUE if there are any buddies from account in the contact, or FALSE otherwise.
+ */
+gboolean purple_contact_on_account(PurpleContact *contact, PurpleAccount *account);
+
+/**
+ * Invalidates the priority buddy so that the next call to
+ * purple_contact_get_priority_buddy recomputes it.
+ *
+ * @param contact The contact
+ */
+void purple_contact_invalidate_priority_buddy(PurpleContact *contact);
+
+/**
+ * Merges two contacts
+ *
+ * All of the buddies from source will be moved to target
+ *
+ * @param source The contact to merge
+ * @param node The place to merge to (a buddy or contact)
+ */
+void purple_contact_merge(PurpleContact *source, PurpleBlistNode *node);
+
+/*@}*/
+
+/**************************************************************************/
+/** @name Chat API */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the GType for the PurpleChat object.
+ */
+GType purple_chat_get_type(void);
+
+/**
+ * Creates a new chat for the buddy list
+ *
+ * @param account The account this chat will get added to
+ * @param alias The alias of the new chat
+ * @param components The info the prpl needs to join the chat. The
+ * hash function should be g_str_hash() and the
+ * equal function should be g_str_equal().
+ * @return A newly allocated chat
+ */
+PurpleChat *purple_chat_new(PurpleAccount *account, const char *alias, GHashTable *components);
+
+/**
+ * Returns the correct name to display for a blist chat.
+ *
+ * @param chat The chat whose name will be returned.
+ * @return The alias (if set), or first component value.
+ */
+const char *purple_chat_get_name(PurpleChat *chat);
+
+/**
+ * Returns the name of the chat
+ *
+ * @param chat The chat whose name will be returned.
+ * @return The first component value.
+ */
+const char *purple_chat_get_name_only(PurpleChat *chat);
+
+/**
+ * Sets the alias for a blist chat.
+ *
+ * @param chat The chat
+ * @param alias The alias
+ */
+void purple_chat_set_alias(PurpleChat *chat, const char *alias);
+
+/**
+ * Returns the group of which the chat is a member.
+ *
+ * @param chat The chat.
+ *
+ * @return The parent group, or @c NULL if the chat is not in a group.
+ */
+PurpleGroup *purple_chat_get_group(PurpleChat *chat);
+
+/**
+ * Returns the account the chat belongs to.
+ *
+ * @param chat The chat.
+ *
+ * @return The account the chat belongs to.
+ */
+PurpleAccount *purple_chat_get_account(PurpleChat *chat);
+
+/**
+ * Get a hashtable containing information about a chat.
+ *
+ * @param chat The chat.
+ *
+ * @constreturn The hashtable.
+ */
+GHashTable *purple_chat_get_components(PurpleChat *chat);
+
+/*@}*/
+
+/**************************************************************************/
+/** @name Group API */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the GType for the PurpleGroup object.
+ */
+GType purple_group_get_type(void);
+
+/**
+ * Creates a new group
+ *
+ * You can't have more than one group with the same name. Sorry. If you pass
+ * this the name of a group that already exists, it will return that group.
+ *
+ * @param name The name of the new group
+ * @return A new group struct
+*/
+PurpleGroup *purple_group_new(const char *name);
+
+/**
+ * Returns a list of accounts that have buddies in this group
+ *
+ * @param g The group
+ *
+ * @return A GSList of accounts (which must be freed), or NULL if the group
+ * has no accounts.
+ */
+GSList *purple_group_get_accounts(PurpleGroup *g);
+
+/**
+ * Determines whether an account owns any buddies in a given group
+ *
+ * @param g The group to search through.
+ * @param account The account.
+ *
+ * @return TRUE if there are any buddies in the group, or FALSE otherwise.
+ */
+gboolean purple_group_on_account(PurpleGroup *g, PurpleAccount *account);
+
+/**
+ * Sets the name of a group.
+ *
+ * @param group The group.
+ * @param name The name of the group.
+ */
+void purple_group_set_name(PurpleGroup *group, const char *name);
+
+/**
+ * Returns the name of a group.
+ *
+ * @param group The group.
+ *
+ * @return The name of the group.
+ */
+const char *purple_group_get_name(PurpleGroup *group);
+
+/*@}*/
+
+G_END_DECLS
+
+#endif /* _PURPLE_BLISTNODE_TYPES_H_ */
diff --git a/libpurple/buddyicon.c b/libpurple/buddyicon.c
index e5ee76ee71..edb3828bfe 100644
--- a/libpurple/buddyicon.c
+++ b/libpurple/buddyicon.c
@@ -371,7 +371,7 @@ purple_buddy_icon_unref(PurpleBuddyIcon *icon)
void
purple_buddy_icon_update(PurpleBuddyIcon *icon)
{
- PurpleConversation *conv;
+ PurpleIMConversation *im;
PurpleAccount *account;
const char *username;
PurpleBuddyIcon *icon_to_set;
@@ -392,7 +392,7 @@ purple_buddy_icon_update(PurpleBuddyIcon *icon)
/* Ensure that icon remains valid throughout */
purple_buddy_icon_ref(icon);
- buddies = purple_find_buddies(account, username);
+ buddies = purple_blist_find_buddies(account, username);
while (buddies != NULL)
{
PurpleBuddy *buddy = (PurpleBuddy *)buddies->data;
@@ -432,10 +432,10 @@ purple_buddy_icon_update(PurpleBuddyIcon *icon)
buddies = g_slist_delete_link(buddies, buddies);
}
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, username, account);
+ im = purple_conversations_find_im_with_account(username, account);
- if (conv != NULL)
- purple_conv_im_set_icon(PURPLE_CONV_IM(conv), icon_to_set);
+ if (im != NULL)
+ purple_im_conversation_set_icon(im, icon_to_set);
/* icon's refcount was incremented above */
purple_buddy_icon_unref(icon);
@@ -554,7 +554,7 @@ purple_buddy_icons_set_for_user(PurpleAccount *account, const char *username,
* Since we know we're deleting the icon, we only
* need a subset of purple_buddy_icon_update(). */
- GSList *buddies = purple_find_buddies(account, username);
+ GSList *buddies = purple_blist_find_buddies(account, username);
while (buddies != NULL)
{
PurpleBuddy *buddy = (PurpleBuddy *)buddies->data;
@@ -625,7 +625,7 @@ purple_buddy_icons_find(PurpleAccount *account, const char *username)
if ((icon_cache == NULL) || ((icon = g_hash_table_lookup(icon_cache, username)) == NULL))
{
/* The icon is not currently cached in memory--try reading from disk */
- PurpleBuddy *b = purple_find_buddy(account, username);
+ PurpleBuddy *b = purple_blist_find_buddy(account, username);
const char *protocol_icon_file;
const char *dirname;
gboolean caching;
@@ -838,12 +838,13 @@ purple_buddy_icons_node_set_custom_icon(PurpleBlistNode *node,
char *old_icon;
PurpleStoredImage *old_img;
PurpleStoredImage *img = NULL;
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
g_return_val_if_fail(node != NULL, NULL);
- if (!PURPLE_BLIST_NODE_IS_CONTACT(node) &&
- !PURPLE_BLIST_NODE_IS_CHAT(node) &&
- !PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ if (!PURPLE_IS_CONTACT(node) &&
+ !PURPLE_IS_CHAT(node) &&
+ !PURPLE_IS_GROUP(node)) {
return NULL;
}
@@ -870,39 +871,41 @@ purple_buddy_icons_node_set_custom_icon(PurpleBlistNode *node,
else
g_hash_table_remove(pointer_icon_cache, node);
- if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if (PURPLE_IS_CONTACT(node)) {
PurpleBlistNode *child;
for (child = purple_blist_node_get_first_child(node);
child;
child = purple_blist_node_get_sibling_next(child))
{
PurpleBuddy *buddy;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
- if (!PURPLE_BLIST_NODE_IS_BUDDY(child))
+ if (!PURPLE_IS_BUDDY(child))
continue;
buddy = (PurpleBuddy *)child;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy));
- if (conv)
- purple_conversation_update(conv, PURPLE_CONV_UPDATE_ICON);
+ im = purple_conversations_find_im_with_account(purple_buddy_get_name(buddy), purple_buddy_get_account(buddy));
+ if (im)
+ purple_conversation_update(PURPLE_CONVERSATION(im), PURPLE_CONVERSATION_UPDATE_ICON);
/* Is this call necessary anymore? Can the buddies
* themselves need updating when the custom buddy
* icon changes? */
- purple_blist_update_node_icon((PurpleBlistNode*)buddy);
+ if (ops && ops->update)
+ ops->update(purple_blist_get_buddy_list(), PURPLE_BLIST_NODE(buddy));
}
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
- PurpleConversation *conv = NULL;
+ } else if (PURPLE_IS_CHAT(node)) {
+ PurpleChatConversation *chat = NULL;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, purple_chat_get_name((PurpleChat*)node), purple_chat_get_account((PurpleChat*)node));
- if (conv) {
- purple_conversation_update(conv, PURPLE_CONV_UPDATE_ICON);
+ chat = purple_conversations_find_chat_with_account(purple_chat_get_name((PurpleChat*)node), purple_chat_get_account((PurpleChat*)node));
+ if (chat) {
+ purple_conversation_update(PURPLE_CONVERSATION(chat), PURPLE_CONVERSATION_UPDATE_ICON);
}
}
- purple_blist_update_node_icon(node);
+ if (ops && ops->update)
+ ops->update(purple_blist_get_buddy_list(), node);
if (old_img) {
purple_imgstore_unref(old_img);
@@ -926,9 +929,9 @@ purple_buddy_icons_node_set_custom_icon_from_file(PurpleBlistNode *node,
g_return_val_if_fail(node != NULL, NULL);
- if (!PURPLE_BLIST_NODE_IS_CONTACT(node) &&
- !PURPLE_BLIST_NODE_IS_CHAT(node) &&
- !PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ if (!PURPLE_IS_CONTACT(node) &&
+ !PURPLE_IS_CHAT(node) &&
+ !PURPLE_IS_GROUP(node)) {
return NULL;
}
@@ -986,7 +989,7 @@ _purple_buddy_icons_blist_loaded_cb()
while (node != NULL)
{
- if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (PURPLE_IS_BUDDY(node))
{
const char *filename;
@@ -1006,9 +1009,9 @@ _purple_buddy_icons_blist_loaded_cb()
g_free(path);
}
}
- else if (PURPLE_BLIST_NODE_IS_CONTACT(node) ||
- PURPLE_BLIST_NODE_IS_CHAT(node) ||
- PURPLE_BLIST_NODE_IS_GROUP(node))
+ else if (PURPLE_IS_CONTACT(node) ||
+ PURPLE_IS_CHAT(node) ||
+ PURPLE_IS_GROUP(node))
{
const char *filename;
@@ -1128,3 +1131,17 @@ void purple_buddy_icon_get_scale_size(PurpleBuddyIconSpec *spec, int *width, int
*width = new_width;
*height = new_height;
}
+
+GType
+purple_buddy_icon_get_type(void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_boxed_type_register_static("PurpleBuddyIcon",
+ (GBoxedCopyFunc)purple_buddy_icon_ref,
+ (GBoxedFreeFunc)purple_buddy_icon_unref);
+ }
+
+ return type;
+}
diff --git a/libpurple/buddyicon.h b/libpurple/buddyicon.h
index 3be957594f..f395a85c55 100644
--- a/libpurple/buddyicon.h
+++ b/libpurple/buddyicon.h
@@ -26,6 +26,8 @@
#ifndef _PURPLE_BUDDYICON_H_
#define _PURPLE_BUDDYICON_H_
+#define PURPLE_TYPE_BUDDY_ICON (purple_buddy_icon_get_type())
+
/** An opaque structure representing a buddy icon for a particular user on a
* particular #PurpleAccount. Instances are reference-counted; use
* purple_buddy_icon_ref() and purple_buddy_icon_unref() to take and release
@@ -34,7 +36,7 @@
typedef struct _PurpleBuddyIcon PurpleBuddyIcon;
#include "account.h"
-#include "blist.h"
+#include "buddylist.h"
#include "imgstore.h"
#include "prpl.h"
#include "util.h"
@@ -47,6 +49,11 @@ G_BEGIN_DECLS
/*@{*/
/**
+ * Returns the GType for the PurpleBuddyIcon boxed structure.
+ */
+GType purple_buddy_icon_get_type(void);
+
+/**
* Creates a new buddy icon structure and populates it.
*
* If an icon for this account+username already exists, you'll get a reference
diff --git a/libpurple/buddylist.c b/libpurple/buddylist.c
new file mode 100644
index 0000000000..11c2092d5d
--- /dev/null
+++ b/libpurple/buddylist.c
@@ -0,0 +1,2108 @@
+/*
+ * 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
+ *
+ */
+#include "internal.h"
+#include "buddylist.h"
+#include "conversation.h"
+#include "dbus-maybe.h"
+#include "debug.h"
+#include "notify.h"
+#include "pounce.h"
+#include "prefs.h"
+#include "prpl.h"
+#include "server.h"
+#include "signals.h"
+#include "util.h"
+#include "xmlnode.h"
+
+#define PURPLE_BUDDY_LIST_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_BUDDY_LIST, PurpleBuddyListPrivate))
+
+/** Private data for a buddy list. */
+typedef struct {
+ GHashTable *buddies; /**< Every buddy in this list */
+} PurpleBuddyListPrivate;
+
+static PurpleBlistUiOps *blist_ui_ops = NULL;
+
+static PurpleBuddyList *purplebuddylist = NULL;
+
+static GObjectClass *parent_class;
+
+/**
+ * A hash table used for efficient lookups of buddies by name.
+ * PurpleAccount* => GHashTable*, with the inner hash table being
+ * struct _purple_hbuddy => PurpleBuddy*
+ */
+static GHashTable *buddies_cache = NULL;
+
+/**
+ * A hash table used for efficient lookups of groups by name.
+ * UTF-8 collate-key => PurpleGroup*.
+ */
+static GHashTable *groups_cache = NULL;
+
+static guint save_timer = 0;
+static gboolean blist_loaded = FALSE;
+
+PurpleBlistNode *_purple_blist_get_last_child(PurpleBlistNode *node);
+
+/*********************************************************************
+ * Private utility functions *
+ *********************************************************************/
+
+static PurpleBlistNode *purple_blist_get_last_sibling(PurpleBlistNode *node)
+{
+ PurpleBlistNode *n = node;
+ if (!n)
+ return NULL;
+ while (n->next)
+ n = n->next;
+ return n;
+}
+
+PurpleBlistNode *_purple_blist_get_last_child(PurpleBlistNode *node)
+{
+ if (!node)
+ return NULL;
+ return purple_blist_get_last_sibling(node->child);
+}
+
+struct _list_account_buddies {
+ GSList *list;
+ PurpleAccount *account;
+};
+
+struct _purple_hbuddy {
+ char *name;
+ PurpleAccount *account;
+ PurpleBlistNode *group;
+};
+
+/* This function must not use purple_normalize */
+static guint _purple_blist_hbuddy_hash(struct _purple_hbuddy *hb)
+{
+ return g_str_hash(hb->name) ^ g_direct_hash(hb->group) ^ g_direct_hash(hb->account);
+}
+
+/* This function must not use purple_normalize */
+static guint _purple_blist_hbuddy_equal(struct _purple_hbuddy *hb1, struct _purple_hbuddy *hb2)
+{
+ return (hb1->group == hb2->group &&
+ hb1->account == hb2->account &&
+ g_str_equal(hb1->name, hb2->name));
+}
+
+static void _purple_blist_hbuddy_free_key(struct _purple_hbuddy *hb)
+{
+ g_free(hb->name);
+ g_free(hb);
+}
+
+static void
+purple_blist_buddies_cache_add_account(PurpleAccount *account)
+{
+ GHashTable *account_buddies = g_hash_table_new_full((GHashFunc)_purple_blist_hbuddy_hash,
+ (GEqualFunc)_purple_blist_hbuddy_equal,
+ (GDestroyNotify)_purple_blist_hbuddy_free_key, NULL);
+ g_hash_table_insert(buddies_cache, account, account_buddies);
+}
+
+static void
+purple_blist_buddies_cache_remove_account(const PurpleAccount *account)
+{
+ g_hash_table_remove(buddies_cache, account);
+}
+
+/*********************************************************************
+ * Writing to disk *
+ *********************************************************************/
+
+static void
+value_to_xmlnode(gpointer key, gpointer hvalue, gpointer user_data)
+{
+ const char *name;
+ GValue *value;
+ xmlnode *node, *child;
+ char buf[21];
+
+ name = (const char *)key;
+ value = (GValue *)hvalue;
+ node = (xmlnode *)user_data;
+
+ g_return_if_fail(value != NULL);
+
+ child = xmlnode_new_child(node, "setting");
+ xmlnode_set_attrib(child, "name", name);
+
+ if (G_VALUE_HOLDS_INT(value)) {
+ xmlnode_set_attrib(child, "type", "int");
+ g_snprintf(buf, sizeof(buf), "%d", g_value_get_int(value));
+ xmlnode_insert_data(child, buf, -1);
+ }
+ else if (G_VALUE_HOLDS_STRING(value)) {
+ xmlnode_set_attrib(child, "type", "string");
+ xmlnode_insert_data(child, g_value_get_string(value), -1);
+ }
+ else if (G_VALUE_HOLDS_BOOLEAN(value)) {
+ xmlnode_set_attrib(child, "type", "bool");
+ g_snprintf(buf, sizeof(buf), "%d", g_value_get_boolean(value));
+ xmlnode_insert_data(child, buf, -1);
+ }
+}
+
+static void
+chat_component_to_xmlnode(gpointer key, gpointer value, gpointer user_data)
+{
+ const char *name;
+ const char *data;
+ xmlnode *node, *child;
+
+ name = (const char *)key;
+ data = (const char *)value;
+ node = (xmlnode *)user_data;
+
+ g_return_if_fail(data != NULL);
+
+ child = xmlnode_new_child(node, "component");
+ xmlnode_set_attrib(child, "name", name);
+ xmlnode_insert_data(child, data, -1);
+}
+
+static xmlnode *
+buddy_to_xmlnode(PurpleBuddy *buddy)
+{
+ xmlnode *node, *child;
+ PurpleAccount *account = purple_buddy_get_account(buddy);
+ const char *alias = purple_buddy_get_local_alias(buddy);
+
+ node = xmlnode_new("buddy");
+ xmlnode_set_attrib(node, "account", purple_account_get_username(account));
+ xmlnode_set_attrib(node, "proto", purple_account_get_protocol_id(account));
+
+ child = xmlnode_new_child(node, "name");
+ xmlnode_insert_data(child, purple_buddy_get_name(buddy), -1);
+
+ if (alias != NULL)
+ {
+ child = xmlnode_new_child(node, "alias");
+ xmlnode_insert_data(child, alias, -1);
+ }
+
+ /* Write buddy settings */
+ g_hash_table_foreach(purple_blist_node_get_settings(PURPLE_BLIST_NODE(buddy)),
+ value_to_xmlnode, node);
+
+ return node;
+}
+
+static xmlnode *
+contact_to_xmlnode(PurpleContact *contact)
+{
+ xmlnode *node, *child;
+ PurpleBlistNode *bnode;
+ gchar *alias;
+
+ node = xmlnode_new("contact");
+ g_object_get(contact, "alias", &alias, NULL);
+
+ if (alias != NULL)
+ {
+ xmlnode_set_attrib(node, "alias", alias);
+ }
+
+ /* Write buddies */
+ for (bnode = PURPLE_BLIST_NODE(contact)->child; bnode != NULL; bnode = bnode->next)
+ {
+ if (purple_blist_node_is_transient(bnode))
+ continue;
+ if (PURPLE_IS_BUDDY(bnode))
+ {
+ child = buddy_to_xmlnode(PURPLE_BUDDY(bnode));
+ xmlnode_insert_child(node, child);
+ }
+ }
+
+ /* Write contact settings */
+ g_hash_table_foreach(purple_blist_node_get_settings(PURPLE_BLIST_NODE(contact)),
+ value_to_xmlnode, node);
+
+ g_free(alias);
+ return node;
+}
+
+static xmlnode *
+chat_to_xmlnode(PurpleChat *chat)
+{
+ xmlnode *node, *child;
+ PurpleAccount *account = purple_chat_get_account(chat);
+ gchar *alias;
+
+ g_object_get(chat, "alias", &alias, NULL);
+
+ node = xmlnode_new("chat");
+ xmlnode_set_attrib(node, "proto", purple_account_get_protocol_id(account));
+ xmlnode_set_attrib(node, "account", purple_account_get_username(account));
+
+ if (alias != NULL)
+ {
+ child = xmlnode_new_child(node, "alias");
+ xmlnode_insert_data(child, alias, -1);
+ }
+
+ /* Write chat components */
+ g_hash_table_foreach(purple_chat_get_components(chat),
+ chat_component_to_xmlnode, node);
+
+ /* Write chat settings */
+ g_hash_table_foreach(purple_blist_node_get_settings(PURPLE_BLIST_NODE(chat)),
+ value_to_xmlnode, node);
+
+ g_free(alias);
+ return node;
+}
+
+static xmlnode *
+group_to_xmlnode(PurpleGroup *group)
+{
+ xmlnode *node, *child;
+ PurpleBlistNode *cnode;
+
+ node = xmlnode_new("group");
+ xmlnode_set_attrib(node, "name", purple_group_get_name(group));
+
+ /* Write settings */
+ g_hash_table_foreach(purple_blist_node_get_settings(PURPLE_BLIST_NODE(group)),
+ value_to_xmlnode, node);
+
+ /* Write contacts and chats */
+ for (cnode = PURPLE_BLIST_NODE(group)->child; cnode != NULL; cnode = cnode->next)
+ {
+ if (purple_blist_node_is_transient(cnode))
+ continue;
+ if (PURPLE_IS_CONTACT(cnode))
+ {
+ child = contact_to_xmlnode(PURPLE_CONTACT(cnode));
+ xmlnode_insert_child(node, child);
+ }
+ else if (PURPLE_IS_CHAT(cnode))
+ {
+ child = chat_to_xmlnode(PURPLE_CHAT(cnode));
+ xmlnode_insert_child(node, child);
+ }
+ }
+
+ return node;
+}
+
+static xmlnode *
+accountprivacy_to_xmlnode(PurpleAccount *account)
+{
+ xmlnode *node, *child;
+ GSList *cur;
+ char buf[10];
+
+ 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", purple_account_get_privacy_type(account));
+ xmlnode_set_attrib(node, "mode", buf);
+
+ for (cur = purple_account_privacy_get_permitted(account); cur; cur = cur->next)
+ {
+ child = xmlnode_new_child(node, "permit");
+ xmlnode_insert_data(child, cur->data, -1);
+ }
+
+ for (cur = purple_account_privacy_get_denied(account); cur; cur = cur->next)
+ {
+ child = xmlnode_new_child(node, "block");
+ xmlnode_insert_data(child, cur->data, -1);
+ }
+
+ return node;
+}
+
+static xmlnode *
+blist_to_xmlnode(void)
+{
+ xmlnode *node, *child, *grandchild;
+ PurpleBlistNode *gnode;
+ GList *cur;
+
+ node = xmlnode_new("purple");
+ xmlnode_set_attrib(node, "version", "1.0");
+
+ /* Write groups */
+ child = xmlnode_new_child(node, "blist");
+ for (gnode = purplebuddylist->root; gnode != NULL; gnode = gnode->next)
+ {
+ if (purple_blist_node_is_transient(gnode))
+ continue;
+ if (PURPLE_IS_GROUP(gnode))
+ {
+ grandchild = group_to_xmlnode(PURPLE_GROUP(gnode));
+ xmlnode_insert_child(child, grandchild);
+ }
+ }
+
+ /* Write privacy settings */
+ child = xmlnode_new_child(node, "privacy");
+ for (cur = purple_accounts_get_all(); cur != NULL; cur = cur->next)
+ {
+ grandchild = accountprivacy_to_xmlnode(cur->data);
+ xmlnode_insert_child(child, grandchild);
+ }
+
+ return node;
+}
+
+static void
+purple_blist_sync(void)
+{
+ xmlnode *node;
+ char *data;
+
+ if (!blist_loaded)
+ {
+ purple_debug_error("blist", "Attempted to save buddy list before it "
+ "was read!\n");
+ return;
+ }
+
+ node = blist_to_xmlnode();
+ data = xmlnode_to_formatted_str(node, NULL);
+ purple_util_write_data_to_file("blist.xml", data, -1);
+ g_free(data);
+ xmlnode_free(node);
+}
+
+static gboolean
+save_cb(gpointer data)
+{
+ purple_blist_sync();
+ save_timer = 0;
+ return FALSE;
+}
+
+static void
+_purple_blist_schedule_save()
+{
+ if (save_timer == 0)
+ save_timer = purple_timeout_add_seconds(5, save_cb, NULL);
+}
+
+static void
+purple_blist_save_account(PurpleAccount *account)
+{
+#if 1
+ _purple_blist_schedule_save();
+#else
+ if (account != NULL) {
+ /* Save the buddies and privacy data for this account */
+ } else {
+ /* Save all buddies and privacy data */
+ }
+#endif
+}
+
+static void
+purple_blist_save_node(PurpleBlistNode *node)
+{
+ _purple_blist_schedule_save();
+}
+
+void purple_blist_schedule_save()
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+
+ /* Save everything */
+ if (ops && ops->save_account)
+ ops->save_account(NULL);
+}
+
+/*********************************************************************
+ * Reading from disk *
+ *********************************************************************/
+
+static void
+parse_setting(PurpleBlistNode *node, xmlnode *setting)
+{
+ const char *name = xmlnode_get_attrib(setting, "name");
+ const char *type = xmlnode_get_attrib(setting, "type");
+ char *value = xmlnode_get_data(setting);
+
+ if (!value)
+ return;
+
+ if (!type || purple_strequal(type, "string"))
+ purple_blist_node_set_string(node, name, value);
+ else if (purple_strequal(type, "bool"))
+ purple_blist_node_set_bool(node, name, atoi(value));
+ else if (purple_strequal(type, "int"))
+ purple_blist_node_set_int(node, name, atoi(value));
+
+ g_free(value);
+}
+
+static void
+parse_buddy(PurpleGroup *group, PurpleContact *contact, xmlnode *bnode)
+{
+ PurpleAccount *account;
+ PurpleBuddy *buddy;
+ char *name = NULL, *alias = NULL;
+ const char *acct_name, *proto;
+ xmlnode *x;
+
+ acct_name = xmlnode_get_attrib(bnode, "account");
+ proto = xmlnode_get_attrib(bnode, "proto");
+
+ if (!acct_name || !proto)
+ return;
+
+ account = purple_accounts_find(acct_name, proto);
+
+ if (!account)
+ return;
+
+ if ((x = xmlnode_get_child(bnode, "name")))
+ name = xmlnode_get_data(x);
+
+ if (!name)
+ return;
+
+ if ((x = xmlnode_get_child(bnode, "alias")))
+ alias = xmlnode_get_data(x);
+
+ buddy = purple_buddy_new(account, name, alias);
+ purple_blist_add_buddy(buddy, contact, group,
+ _purple_blist_get_last_child((PurpleBlistNode*)contact));
+
+ for (x = xmlnode_get_child(bnode, "setting"); x; x = xmlnode_get_next_twin(x)) {
+ parse_setting((PurpleBlistNode*)buddy, x);
+ }
+
+ g_free(name);
+ g_free(alias);
+}
+
+static void
+parse_contact(PurpleGroup *group, xmlnode *cnode)
+{
+ PurpleContact *contact = purple_contact_new();
+ xmlnode *x;
+ const char *alias;
+
+ purple_blist_add_contact(contact, group,
+ _purple_blist_get_last_child((PurpleBlistNode*)group));
+
+ if ((alias = xmlnode_get_attrib(cnode, "alias"))) {
+ purple_contact_set_alias(contact, alias);
+ }
+
+ for (x = cnode->child; x; x = x->next) {
+ if (x->type != XMLNODE_TYPE_TAG)
+ continue;
+ if (purple_strequal(x->name, "buddy"))
+ parse_buddy(group, contact, x);
+ else if (purple_strequal(x->name, "setting"))
+ parse_setting(PURPLE_BLIST_NODE(contact), x);
+ }
+
+ /* if the contact is empty, don't keep it around. it causes problems */
+ if (!PURPLE_BLIST_NODE(contact)->child)
+ purple_blist_remove_contact(contact);
+}
+
+static void
+parse_chat(PurpleGroup *group, xmlnode *cnode)
+{
+ PurpleChat *chat;
+ PurpleAccount *account;
+ const char *acct_name, *proto;
+ xmlnode *x;
+ char *alias = NULL;
+ GHashTable *components;
+
+ acct_name = xmlnode_get_attrib(cnode, "account");
+ proto = xmlnode_get_attrib(cnode, "proto");
+
+ if (!acct_name || !proto)
+ return;
+
+ account = purple_accounts_find(acct_name, proto);
+
+ if (!account)
+ return;
+
+ if ((x = xmlnode_get_child(cnode, "alias")))
+ alias = xmlnode_get_data(x);
+
+ components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+
+ for (x = xmlnode_get_child(cnode, "component"); x; x = xmlnode_get_next_twin(x)) {
+ const char *name;
+ char *value;
+
+ name = xmlnode_get_attrib(x, "name");
+ value = xmlnode_get_data(x);
+ g_hash_table_replace(components, g_strdup(name), value);
+ }
+
+ chat = purple_chat_new(account, alias, components);
+ purple_blist_add_chat(chat, group,
+ _purple_blist_get_last_child((PurpleBlistNode*)group));
+
+ for (x = xmlnode_get_child(cnode, "setting"); x; x = xmlnode_get_next_twin(x)) {
+ parse_setting((PurpleBlistNode*)chat, x);
+ }
+
+ g_free(alias);
+}
+
+static void
+parse_group(xmlnode *groupnode)
+{
+ const char *name = xmlnode_get_attrib(groupnode, "name");
+ PurpleGroup *group;
+ xmlnode *cnode;
+
+ if (!name)
+ name = _("Buddies");
+
+ group = purple_group_new(name);
+ purple_blist_add_group(group,
+ purple_blist_get_last_sibling(purplebuddylist->root));
+
+ for (cnode = groupnode->child; cnode; cnode = cnode->next) {
+ if (cnode->type != XMLNODE_TYPE_TAG)
+ continue;
+ if (purple_strequal(cnode->name, "setting"))
+ parse_setting((PurpleBlistNode*)group, cnode);
+ else if (purple_strequal(cnode->name, "contact") ||
+ purple_strequal(cnode->name, "person"))
+ parse_contact(group, cnode);
+ else if (purple_strequal(cnode->name, "chat"))
+ parse_chat(group, cnode);
+ }
+}
+
+static void
+load_blist(void)
+{
+ xmlnode *purple, *blist, *privacy;
+
+ blist_loaded = TRUE;
+
+ purple = purple_util_read_xml_from_file("blist.xml", _("buddy list"));
+
+ if (purple == NULL)
+ return;
+
+ blist = xmlnode_get_child(purple, "blist");
+ if (blist) {
+ xmlnode *groupnode;
+ for (groupnode = xmlnode_get_child(blist, "group"); groupnode != NULL;
+ groupnode = xmlnode_get_next_twin(groupnode)) {
+ parse_group(groupnode);
+ }
+ }
+
+ privacy = xmlnode_get_child(purple, "privacy");
+ if (privacy) {
+ xmlnode *anode;
+ for (anode = privacy->child; anode; anode = anode->next) {
+ xmlnode *x;
+ PurpleAccount *account;
+ int imode;
+ const char *acct_name, *proto, *mode;
+
+ acct_name = xmlnode_get_attrib(anode, "name");
+ proto = xmlnode_get_attrib(anode, "proto");
+ mode = xmlnode_get_attrib(anode, "mode");
+
+ if (!acct_name || !proto || !mode)
+ continue;
+
+ account = purple_accounts_find(acct_name, proto);
+
+ if (!account)
+ continue;
+
+ imode = atoi(mode);
+ purple_account_set_privacy_type(account, (imode != 0 ? imode : PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL));
+
+ for (x = anode->child; x; x = x->next) {
+ char *name;
+ if (x->type != XMLNODE_TYPE_TAG)
+ continue;
+
+ if (purple_strequal(x->name, "permit")) {
+ name = xmlnode_get_data(x);
+ purple_account_privacy_permit_add(account, name, TRUE);
+ g_free(name);
+ } else if (purple_strequal(x->name, "block")) {
+ name = xmlnode_get_data(x);
+ purple_account_privacy_deny_add(account, name, TRUE);
+ g_free(name);
+ }
+ }
+ }
+ }
+
+ xmlnode_free(purple);
+
+ /* This tells the buddy icon code to do its thing. */
+ _purple_buddy_icons_blist_loaded_cb();
+}
+
+/*****************************************************************************
+ * Public API functions *
+ *****************************************************************************/
+
+void
+purple_blist_boot(void)
+{
+ PurpleBlistUiOps *ui_ops;
+ GList *account;
+ PurpleBuddyList *gbl = g_object_new(PURPLE_TYPE_BUDDY_LIST, NULL);
+
+ ui_ops = purple_blist_get_ui_ops();
+
+ buddies_cache = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, (GDestroyNotify)g_hash_table_destroy);
+
+ groups_cache = g_hash_table_new_full((GHashFunc)g_str_hash,
+ (GEqualFunc)g_str_equal,
+ (GDestroyNotify)g_free, NULL);
+
+ for (account = purple_accounts_get_all(); account != NULL; account = account->next)
+ {
+ purple_blist_buddies_cache_add_account(account->data);
+ }
+
+ if (ui_ops != NULL && ui_ops->new_list != NULL)
+ ui_ops->new_list(gbl);
+
+ purplebuddylist = gbl;
+
+ load_blist();
+}
+
+PurpleBuddyList *
+purple_blist_get_buddy_list()
+{
+ return purplebuddylist;
+}
+
+PurpleBlistNode *
+purple_blist_get_root()
+{
+ return purplebuddylist ? purplebuddylist->root : NULL;
+}
+
+static void
+append_buddy(gpointer key, gpointer value, gpointer user_data)
+{
+ GSList **list = user_data;
+ *list = g_slist_prepend(*list, value);
+}
+
+GSList *
+purple_blist_get_buddies()
+{
+ GSList *buddies = NULL;
+
+ if (!purplebuddylist)
+ return NULL;
+
+ g_hash_table_foreach(PURPLE_BUDDY_LIST_GET_PRIVATE(purplebuddylist)->buddies,
+ append_buddy, &buddies);
+ return buddies;
+}
+
+void *
+purple_blist_get_ui_data()
+{
+ return purplebuddylist->ui_data;
+}
+
+void
+purple_blist_set_ui_data(void *ui_data)
+{
+ purplebuddylist->ui_data = ui_data;
+}
+
+void purple_blist_show()
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+
+ if (ops && ops->show)
+ ops->show(purplebuddylist);
+}
+
+void purple_blist_set_visible(gboolean show)
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+
+ if (ops && ops->set_visible)
+ ops->set_visible(purplebuddylist, show);
+}
+
+void purple_blist_update_buddies_cache(PurpleBuddy *buddy, const char *new_name)
+{
+ struct _purple_hbuddy *hb, *hb2;
+ GHashTable *account_buddies;
+ PurpleAccount *account;
+ gchar *name;
+ PurpleBuddyListPrivate *priv = PURPLE_BUDDY_LIST_GET_PRIVATE(purplebuddylist);
+
+ g_return_if_fail(buddy != NULL);
+
+ account = purple_buddy_get_account(buddy);
+ name = (gchar *)purple_buddy_get_name(buddy);
+
+ hb = g_new(struct _purple_hbuddy, 1);
+ hb->name = (gchar *)purple_normalize(account, name);
+ hb->account = account;
+ hb->group = PURPLE_BLIST_NODE(buddy)->parent->parent;
+ g_hash_table_remove(priv->buddies, hb);
+
+ account_buddies = g_hash_table_lookup(buddies_cache, account);
+ g_hash_table_remove(account_buddies, hb);
+
+ hb->name = g_strdup(purple_normalize(account, new_name));
+ g_hash_table_replace(priv->buddies, hb, buddy);
+
+ hb2 = g_new(struct _purple_hbuddy, 1);
+ hb2->name = g_strdup(hb->name);
+ hb2->account = account;
+ hb2->group = PURPLE_BLIST_NODE(buddy)->parent->parent;
+
+ g_hash_table_replace(account_buddies, hb2, buddy);
+}
+
+void purple_blist_update_groups_cache(PurpleGroup *group, const char *new_name)
+{
+ gchar* key = g_utf8_collate_key(purple_group_get_name(group), -1);
+ g_hash_table_remove(groups_cache, key);
+ g_free(key);
+
+ key = g_utf8_collate_key(new_name, -1);
+ g_hash_table_insert(groups_cache, key, group);
+}
+
+void purple_blist_add_chat(PurpleChat *chat, PurpleGroup *group, PurpleBlistNode *node)
+{
+ PurpleBlistNode *cnode = PURPLE_BLIST_NODE(chat);
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ PurpleCountingNode *group_counter;
+
+ g_return_if_fail(chat != NULL);
+
+ if (node == NULL) {
+ if (group == NULL)
+ group = purple_group_new(_("Chats"));
+
+ /* Add group to blist if isn't already on it. Fixes #2752. */
+ if (!purple_blist_find_group(purple_group_get_name(group))) {
+ purple_blist_add_group(group,
+ purple_blist_get_last_sibling(purplebuddylist->root));
+ }
+ } else {
+ group = PURPLE_GROUP(node->parent);
+ }
+
+ /* if we're moving to overtop of ourselves, do nothing */
+ if (cnode == node)
+ return;
+
+ if (cnode->parent) {
+ /* This chat was already in the list and is
+ * being moved.
+ */
+ group_counter = PURPLE_COUNTING_NODE(cnode->parent);
+ purple_counting_node_change_total_size(group_counter, -1);
+ if (purple_account_is_connected(purple_chat_get_account(chat))) {
+ purple_counting_node_change_online_count(group_counter, -1);
+ purple_counting_node_change_current_size(group_counter, -1);
+ }
+ if (cnode->next)
+ cnode->next->prev = cnode->prev;
+ if (cnode->prev)
+ cnode->prev->next = cnode->next;
+ if (cnode->parent->child == cnode)
+ cnode->parent->child = cnode->next;
+
+ if (ops && ops->remove)
+ ops->remove(purplebuddylist, cnode);
+ /* ops->remove() cleaned up the cnode's ui_data, so we need to
+ * reinitialize it */
+ if (ops && ops->new_node)
+ ops->new_node(cnode);
+ }
+
+ if (node != NULL) {
+ if (node->next)
+ node->next->prev = cnode;
+ cnode->next = node->next;
+ cnode->prev = node;
+ cnode->parent = node->parent;
+ node->next = cnode;
+ group_counter = PURPLE_COUNTING_NODE(node->parent);
+ purple_counting_node_change_total_size(group_counter, +1);
+ if (purple_account_is_connected(purple_chat_get_account(chat))) {
+ purple_counting_node_change_online_count(group_counter, +1);
+ purple_counting_node_change_current_size(group_counter, +1);
+ }
+ } else {
+ if (((PurpleBlistNode *)group)->child)
+ ((PurpleBlistNode *)group)->child->prev = cnode;
+ cnode->next = ((PurpleBlistNode *)group)->child;
+ cnode->prev = NULL;
+ ((PurpleBlistNode *)group)->child = cnode;
+ cnode->parent = PURPLE_BLIST_NODE(group);
+ group_counter = PURPLE_COUNTING_NODE(group);
+ purple_counting_node_change_total_size(group_counter, +1);
+ if (purple_account_is_connected(purple_chat_get_account(chat))) {
+ purple_counting_node_change_online_count(group_counter, +1);
+ purple_counting_node_change_current_size(group_counter, +1);
+ }
+ }
+
+ if (ops) {
+ if (ops->save_node)
+ ops->save_node(cnode);
+ if (ops->update)
+ ops->update(purplebuddylist, PURPLE_BLIST_NODE(cnode));
+ }
+
+ purple_signal_emit(purple_blist_get_handle(), "blist-node-added",
+ cnode);
+}
+
+void purple_blist_add_buddy(PurpleBuddy *buddy, PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node)
+{
+ PurpleBlistNode *cnode, *bnode;
+ PurpleCountingNode *contact_counter, *group_counter;
+ PurpleGroup *g;
+ PurpleContact *c;
+ PurpleAccount *account;
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ struct _purple_hbuddy *hb, *hb2;
+ GHashTable *account_buddies;
+ PurpleBuddyListPrivate *priv = PURPLE_BUDDY_LIST_GET_PRIVATE(purplebuddylist);
+
+ g_return_if_fail(buddy != NULL);
+ g_return_if_fail(PURPLE_IS_BUDDY((PurpleBlistNode*)buddy));
+
+ bnode = PURPLE_BLIST_NODE(buddy);
+ account = purple_buddy_get_account(buddy);
+
+ /* if we're moving to overtop of ourselves, do nothing */
+ if (bnode == node || (!node && bnode->parent &&
+ contact && bnode->parent == (PurpleBlistNode*)contact
+ && bnode == bnode->parent->child))
+ return;
+
+ if (node && PURPLE_IS_BUDDY(node)) {
+ c = (PurpleContact*)node->parent;
+ g = (PurpleGroup*)node->parent->parent;
+ } else if (contact) {
+ c = contact;
+ g = PURPLE_GROUP(PURPLE_BLIST_NODE(c)->parent);
+ } else {
+ g = group;
+ if (g == NULL)
+ g = purple_group_new(_("Buddies"));
+ /* Add group to blist if isn't already on it. Fixes #2752. */
+ if (!purple_blist_find_group(purple_group_get_name(g))) {
+ purple_blist_add_group(g,
+ purple_blist_get_last_sibling(purplebuddylist->root));
+ }
+ c = purple_contact_new();
+ purple_blist_add_contact(c, g,
+ _purple_blist_get_last_child((PurpleBlistNode*)g));
+ }
+
+ cnode = PURPLE_BLIST_NODE(c);
+
+ if (bnode->parent) {
+ contact_counter = PURPLE_COUNTING_NODE(bnode->parent);
+ group_counter = PURPLE_COUNTING_NODE(bnode->parent->parent);
+
+ if (PURPLE_BUDDY_IS_ONLINE(buddy)) {
+ purple_counting_node_change_online_count(contact_counter, -1);
+ if (purple_counting_node_get_online_count(contact_counter) == 0)
+ purple_counting_node_change_online_count(group_counter, -1);
+ }
+ if (purple_account_is_connected(account)) {
+ purple_counting_node_change_current_size(contact_counter, -1);
+ if (purple_counting_node_get_current_size(contact_counter) == 0)
+ purple_counting_node_change_current_size(group_counter, -1);
+ }
+ purple_counting_node_change_total_size(contact_counter, -1);
+ /* the group totalsize will be taken care of by remove_contact below */
+
+ if (bnode->parent->parent != (PurpleBlistNode*)g)
+ serv_move_buddy(buddy, (PurpleGroup *)bnode->parent->parent, g);
+
+ if (bnode->next)
+ bnode->next->prev = bnode->prev;
+ if (bnode->prev)
+ bnode->prev->next = bnode->next;
+ if (bnode->parent->child == bnode)
+ bnode->parent->child = bnode->next;
+
+ if (ops && ops->remove)
+ ops->remove(purplebuddylist, bnode);
+
+ if (bnode->parent->parent != (PurpleBlistNode*)g) {
+ struct _purple_hbuddy hb;
+ hb.name = (gchar *)purple_normalize(account,
+ purple_buddy_get_name(buddy));
+ hb.account = account;
+ hb.group = bnode->parent->parent;
+ g_hash_table_remove(priv->buddies, &hb);
+
+ account_buddies = g_hash_table_lookup(buddies_cache, account);
+ g_hash_table_remove(account_buddies, &hb);
+ }
+
+ if (!bnode->parent->child) {
+ purple_blist_remove_contact((PurpleContact*)bnode->parent);
+ } else {
+ purple_contact_invalidate_priority_buddy((PurpleContact*)bnode->parent);
+
+ if (ops && ops->update)
+ ops->update(purplebuddylist, bnode->parent);
+ }
+ }
+
+ if (node && PURPLE_IS_BUDDY(node)) {
+ if (node->next)
+ node->next->prev = bnode;
+ bnode->next = node->next;
+ bnode->prev = node;
+ bnode->parent = node->parent;
+ node->next = bnode;
+ } else {
+ if (cnode->child)
+ cnode->child->prev = bnode;
+ bnode->prev = NULL;
+ bnode->next = cnode->child;
+ cnode->child = bnode;
+ bnode->parent = cnode;
+ }
+
+ contact_counter = PURPLE_COUNTING_NODE(bnode->parent);
+ group_counter = PURPLE_COUNTING_NODE(bnode->parent->parent);
+
+ if (PURPLE_BUDDY_IS_ONLINE(buddy)) {
+ purple_counting_node_change_online_count(contact_counter, +1);
+ if (purple_counting_node_get_online_count(contact_counter) == 1)
+ purple_counting_node_change_online_count(group_counter, +1);
+ }
+ if (purple_account_is_connected(account)) {
+ purple_counting_node_change_current_size(contact_counter, +1);
+ if (purple_counting_node_get_online_count(contact_counter) == 1)
+ purple_counting_node_change_current_size(group_counter, +1);
+ }
+ purple_counting_node_change_total_size(contact_counter, +1);
+
+ hb = g_new(struct _purple_hbuddy, 1);
+ hb->name = g_strdup(purple_normalize(account, purple_buddy_get_name(buddy)));
+ hb->account = account;
+ hb->group = PURPLE_BLIST_NODE(buddy)->parent->parent;
+
+ g_hash_table_replace(priv->buddies, hb, buddy);
+
+ account_buddies = g_hash_table_lookup(buddies_cache, account);
+
+ hb2 = g_new(struct _purple_hbuddy, 1);
+ hb2->name = g_strdup(hb->name);
+ hb2->account = account;
+ hb2->group = ((PurpleBlistNode*)buddy)->parent->parent;
+
+ g_hash_table_replace(account_buddies, hb2, buddy);
+
+ purple_contact_invalidate_priority_buddy(purple_buddy_get_contact(buddy));
+
+ if (ops) {
+ if (ops->save_node)
+ ops->save_node((PurpleBlistNode*) buddy);
+ if (ops->update)
+ ops->update(purplebuddylist, PURPLE_BLIST_NODE(buddy));
+ }
+
+ /* Signal that the buddy has been added */
+ purple_signal_emit(purple_blist_get_handle(), "buddy-added", buddy);
+
+ purple_signal_emit(purple_blist_get_handle(), "blist-node-added",
+ PURPLE_BLIST_NODE(buddy));
+}
+
+void purple_blist_add_contact(PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node)
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ PurpleGroup *g;
+ PurpleBlistNode *gnode, *cnode, *bnode;
+ PurpleCountingNode *contact_counter, *group_counter;
+ PurpleBuddyListPrivate *priv = PURPLE_BUDDY_LIST_GET_PRIVATE(purplebuddylist);
+
+ g_return_if_fail(contact != NULL);
+
+ if (PURPLE_BLIST_NODE(contact) == node)
+ return;
+
+ if (node && (PURPLE_IS_CONTACT(node) ||
+ PURPLE_IS_CHAT(node)))
+ g = PURPLE_GROUP(node->parent);
+ else if (group)
+ g = group;
+ else {
+ g = purple_blist_find_group(_("Buddies"));
+ if (g == NULL) {
+ g = purple_group_new(_("Buddies"));
+ purple_blist_add_group(g,
+ purple_blist_get_last_sibling(purplebuddylist->root));
+ }
+ }
+
+ gnode = (PurpleBlistNode*)g;
+ cnode = (PurpleBlistNode*)contact;
+
+ if (cnode->parent) {
+ if (cnode->parent->child == cnode)
+ cnode->parent->child = cnode->next;
+ if (cnode->prev)
+ cnode->prev->next = cnode->next;
+ if (cnode->next)
+ cnode->next->prev = cnode->prev;
+
+ if (cnode->parent != gnode) {
+ bnode = cnode->child;
+ while (bnode) {
+ PurpleBlistNode *next_bnode = bnode->next;
+ PurpleBuddy *b = PURPLE_BUDDY(bnode);
+ PurpleAccount *account = purple_buddy_get_account(b);
+ GHashTable *account_buddies;
+
+ struct _purple_hbuddy *hb, *hb2;
+
+ hb = g_new(struct _purple_hbuddy, 1);
+ hb->name = g_strdup(purple_normalize(account, purple_buddy_get_name(b)));
+ hb->account = account;
+ hb->group = cnode->parent;
+
+ g_hash_table_remove(priv->buddies, hb);
+
+ account_buddies = g_hash_table_lookup(buddies_cache, account);
+ g_hash_table_remove(account_buddies, hb);
+
+ if (!purple_blist_find_buddy_in_group(account, purple_buddy_get_name(b), g)) {
+ hb->group = gnode;
+ g_hash_table_replace(priv->buddies, hb, b);
+
+ hb2 = g_new(struct _purple_hbuddy, 1);
+ hb2->name = g_strdup(hb->name);
+ hb2->account = account;
+ hb2->group = gnode;
+
+ g_hash_table_replace(account_buddies, hb2, b);
+
+ if (purple_account_get_connection(account))
+ serv_move_buddy(b, (PurpleGroup *)cnode->parent, g);
+ } else {
+ gboolean empty_contact = FALSE;
+
+ /* this buddy already exists in the group, so we're
+ * gonna delete it instead */
+ g_free(hb->name);
+ g_free(hb);
+ if (purple_account_get_connection(account))
+ purple_account_remove_buddy(account, b, PURPLE_GROUP(cnode->parent));
+
+ if (!cnode->child->next)
+ empty_contact = TRUE;
+ purple_blist_remove_buddy(b);
+
+ /** in purple_blist_remove_buddy(), if the last buddy in a
+ * contact is removed, the contact is cleaned up and
+ * g_free'd, so we mustn't try to reference bnode->next */
+ if (empty_contact)
+ return;
+ }
+ bnode = next_bnode;
+ }
+ }
+
+ contact_counter = PURPLE_COUNTING_NODE(contact);
+ group_counter = PURPLE_COUNTING_NODE(cnode->parent);
+
+ if (purple_counting_node_get_online_count(contact_counter) > 0)
+ purple_counting_node_change_online_count(group_counter, -1);
+ if (purple_counting_node_get_current_size(contact_counter) > 0)
+ purple_counting_node_change_current_size(group_counter, -1);
+ purple_counting_node_change_total_size(group_counter, -1);
+
+ if (ops && ops->remove)
+ ops->remove(purplebuddylist, cnode);
+
+ if (ops && ops->remove_node)
+ ops->remove_node(cnode);
+ }
+
+ if (node && (PURPLE_IS_CONTACT(node) ||
+ PURPLE_IS_CHAT(node))) {
+ if (node->next)
+ node->next->prev = cnode;
+ cnode->next = node->next;
+ cnode->prev = node;
+ cnode->parent = node->parent;
+ node->next = cnode;
+ } else {
+ if (gnode->child)
+ gnode->child->prev = cnode;
+ cnode->prev = NULL;
+ cnode->next = gnode->child;
+ gnode->child = cnode;
+ cnode->parent = gnode;
+ }
+
+ contact_counter = PURPLE_COUNTING_NODE(contact);
+ group_counter = PURPLE_COUNTING_NODE(g);
+
+ if (purple_counting_node_get_online_count(contact_counter) > 0)
+ purple_counting_node_change_online_count(group_counter, +1);
+ if (purple_counting_node_get_current_size(contact_counter) > 0)
+ purple_counting_node_change_current_size(group_counter, +1);
+ purple_counting_node_change_total_size(group_counter, +1);
+
+ if (ops && ops->save_node)
+ {
+ if (cnode->child)
+ ops->save_node(cnode);
+ for (bnode = cnode->child; bnode; bnode = bnode->next)
+ ops->save_node(bnode);
+ }
+
+ if (ops && ops->update)
+ {
+ if (cnode->child)
+ ops->update(purplebuddylist, cnode);
+
+ for (bnode = cnode->child; bnode; bnode = bnode->next)
+ ops->update(purplebuddylist, bnode);
+ }
+}
+
+void purple_blist_add_group(PurpleGroup *group, PurpleBlistNode *node)
+{
+ PurpleBlistUiOps *ops;
+ PurpleBlistNode *gnode = (PurpleBlistNode*)group;
+ gchar* key;
+
+ g_return_if_fail(group != NULL);
+ g_return_if_fail(PURPLE_IS_GROUP((PurpleBlistNode *)group));
+
+ ops = purple_blist_get_ui_ops();
+
+ /* if we're moving to overtop of ourselves, do nothing */
+ if (gnode == node) {
+ if (!purplebuddylist->root)
+ node = NULL;
+ else
+ return;
+ }
+
+ if (purple_blist_find_group(purple_group_get_name(group))) {
+ /* This is just being moved */
+
+ if (ops && ops->remove)
+ ops->remove(purplebuddylist, (PurpleBlistNode *)group);
+
+ if (gnode == purplebuddylist->root)
+ purplebuddylist->root = gnode->next;
+ if (gnode->prev)
+ gnode->prev->next = gnode->next;
+ if (gnode->next)
+ gnode->next->prev = gnode->prev;
+ } else {
+ key = g_utf8_collate_key(purple_group_get_name(group), -1);
+ g_hash_table_insert(groups_cache, key, group);
+ }
+
+ if (node && PURPLE_IS_GROUP(node)) {
+ gnode->next = node->next;
+ gnode->prev = node;
+ if (node->next)
+ node->next->prev = gnode;
+ node->next = gnode;
+ } else {
+ if (purplebuddylist->root)
+ purplebuddylist->root->prev = gnode;
+ gnode->next = purplebuddylist->root;
+ gnode->prev = NULL;
+ purplebuddylist->root = gnode;
+ }
+
+ if (ops && ops->save_node) {
+ ops->save_node(gnode);
+ for (node = gnode->child; node; node = node->next)
+ ops->save_node(node);
+ }
+
+ if (ops && ops->update) {
+ ops->update(purplebuddylist, gnode);
+ for (node = gnode->child; node; node = node->next)
+ ops->update(purplebuddylist, node);
+ }
+
+ purple_signal_emit(purple_blist_get_handle(), "blist-node-added",
+ gnode);
+}
+
+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) {
+ /*
+ * If this contact has children then remove them. When the last
+ * buddy is removed from the contact, the contact is automatically
+ * deleted.
+ */
+ while (node->child->next) {
+ purple_blist_remove_buddy((PurpleBuddy*)node->child);
+ }
+ /*
+ * Remove the last buddy and trigger the deletion of the contact.
+ * It would probably be cleaner if contact-deletion was done after
+ * a timeout? Or if it had to be done manually, like below?
+ */
+ purple_blist_remove_buddy((PurpleBuddy*)node->child);
+ } else {
+ /* Remove the node from its parent */
+ if (gnode->child == node)
+ gnode->child = node->next;
+ if (node->prev)
+ node->prev->next = node->next;
+ if (node->next)
+ node->next->prev = node->prev;
+ purple_counting_node_change_total_size(PURPLE_COUNTING_NODE(group), -1);
+
+ /* Update the UI */
+ if (ops && ops->remove)
+ ops->remove(purplebuddylist, node);
+
+ if (ops && ops->remove_node)
+ ops->remove_node(node);
+
+ purple_signal_emit(purple_blist_get_handle(), "blist-node-removed",
+ PURPLE_BLIST_NODE(contact));
+
+ /* Delete the node */
+ g_object_unref(contact);
+ }
+}
+
+void purple_blist_remove_buddy(PurpleBuddy *buddy)
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ PurpleBlistNode *node, *cnode, *gnode;
+ PurpleCountingNode *contact_counter, *group_counter;
+ PurpleContact *contact;
+ PurpleGroup *group;
+ struct _purple_hbuddy hb;
+ GHashTable *account_buddies;
+ PurpleAccount *account;
+
+ g_return_if_fail(buddy != NULL);
+
+ account = purple_buddy_get_account(buddy);
+ node = PURPLE_BLIST_NODE(buddy);
+ cnode = node->parent;
+ gnode = (cnode != NULL) ? cnode->parent : NULL;
+ contact = (PurpleContact *)cnode;
+ group = (PurpleGroup *)gnode;
+
+ /* Remove the node from its parent */
+ if (node->prev)
+ node->prev->next = node->next;
+ if (node->next)
+ node->next->prev = node->prev;
+ if ((cnode != NULL) && (cnode->child == node))
+ cnode->child = node->next;
+
+ /* Adjust size counts */
+ if (contact != NULL) {
+ contact_counter = PURPLE_COUNTING_NODE(contact);
+ group_counter = PURPLE_COUNTING_NODE(group);
+
+ if (PURPLE_BUDDY_IS_ONLINE(buddy)) {
+ purple_counting_node_change_online_count(contact_counter, -1);
+ if (purple_counting_node_get_online_count(contact_counter) == 0)
+ purple_counting_node_set_online_count(group_counter, -1);
+ }
+ if (purple_account_is_connected(account)) {
+ purple_counting_node_change_current_size(contact_counter, -1);
+ if (purple_counting_node_get_current_size(contact_counter) == 0)
+ purple_counting_node_change_current_size(group_counter, -1);
+ }
+ purple_counting_node_change_total_size(contact_counter, -1);
+
+ /* Re-sort the contact */
+ if (cnode->child && purple_contact_get_priority_buddy(contact) == buddy) {
+ purple_contact_invalidate_priority_buddy(contact);
+
+ if (ops && ops->update)
+ ops->update(purplebuddylist, cnode);
+ }
+ }
+
+ /* Remove this buddy from the buddies hash table */
+ hb.name = (gchar *)purple_normalize(account, purple_buddy_get_name(buddy));
+ hb.account = account;
+ hb.group = gnode;
+ g_hash_table_remove(PURPLE_BUDDY_LIST_GET_PRIVATE(purplebuddylist)->buddies, &hb);
+
+ account_buddies = g_hash_table_lookup(buddies_cache, account);
+ g_hash_table_remove(account_buddies, &hb);
+
+ /* Update the UI */
+ if (ops && ops->remove)
+ ops->remove(purplebuddylist, node);
+
+ if (ops && ops->remove_node)
+ ops->remove_node(node);
+
+ /* Remove this buddy's pounces */
+ purple_pounce_destroy_all_by_buddy(buddy);
+
+ /* Signal that the buddy has been removed before freeing the memory for it */
+ purple_signal_emit(purple_blist_get_handle(), "buddy-removed", buddy);
+
+ purple_signal_emit(purple_blist_get_handle(), "blist-node-removed",
+ PURPLE_BLIST_NODE(buddy));
+
+ g_object_unref(buddy);
+
+ /* If the contact is empty then remove it */
+ if ((contact != NULL) && !cnode->child)
+ purple_blist_remove_contact(contact);
+}
+
+void purple_blist_remove_chat(PurpleChat *chat)
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ PurpleBlistNode *node, *gnode;
+ PurpleGroup *group;
+ PurpleCountingNode *group_counter;
+
+ g_return_if_fail(chat != NULL);
+
+ node = (PurpleBlistNode *)chat;
+ gnode = node->parent;
+ group = (PurpleGroup *)gnode;
+
+ if (gnode != NULL)
+ {
+ /* Remove the node from its parent */
+ if (gnode->child == node)
+ gnode->child = node->next;
+ if (node->prev)
+ node->prev->next = node->next;
+ if (node->next)
+ node->next->prev = node->prev;
+
+ /* Adjust size counts */
+ group_counter = PURPLE_COUNTING_NODE(group);
+ if (purple_account_is_connected(purple_chat_get_account(chat))) {
+ purple_counting_node_change_online_count(group_counter, -1);
+ purple_counting_node_change_current_size(group_counter, -1);
+ }
+ purple_counting_node_change_total_size(group_counter, -1);
+ }
+
+ /* Update the UI */
+ if (ops && ops->remove)
+ ops->remove(purplebuddylist, node);
+
+ if (ops && ops->remove_node)
+ ops->remove_node(node);
+
+ purple_signal_emit(purple_blist_get_handle(), "blist-node-removed",
+ PURPLE_BLIST_NODE(chat));
+
+ /* Delete the node */
+ g_object_unref(chat);
+}
+
+void purple_blist_remove_group(PurpleGroup *group)
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ PurpleBlistNode *node;
+ GList *l;
+ gchar* key;
+
+ g_return_if_fail(group != NULL);
+
+ node = (PurpleBlistNode *)group;
+
+ /* Make sure the group is empty */
+ if (node->child)
+ return;
+
+ /* Remove the node from its parent */
+ if (purplebuddylist->root == node)
+ purplebuddylist->root = node->next;
+ if (node->prev)
+ node->prev->next = node->next;
+ if (node->next)
+ node->next->prev = node->prev;
+
+ key = g_utf8_collate_key(purple_group_get_name(group), -1);
+ g_hash_table_remove(groups_cache, key);
+ g_free(key);
+
+ /* Update the UI */
+ if (ops && ops->remove)
+ ops->remove(purplebuddylist, node);
+
+ if (ops && ops->remove_node)
+ ops->remove_node(node);
+
+ purple_signal_emit(purple_blist_get_handle(), "blist-node-removed",
+ PURPLE_BLIST_NODE(group));
+
+ /* Remove the group from all accounts that are online */
+ for (l = purple_connections_get_all(); l != NULL; l = l->next)
+ {
+ PurpleConnection *gc = (PurpleConnection *)l->data;
+
+ if (purple_connection_get_state(gc) == PURPLE_CONNECTION_CONNECTED)
+ purple_account_remove_group(purple_connection_get_account(gc), group);
+ }
+
+ /* Delete the node */
+ g_object_unref(group);
+}
+
+PurpleBuddy *purple_blist_find_buddy(PurpleAccount *account, const char *name)
+{
+ PurpleBuddy *buddy;
+ struct _purple_hbuddy hb;
+ PurpleBlistNode *group;
+
+ g_return_val_if_fail(purplebuddylist != NULL, NULL);
+ g_return_val_if_fail(account != NULL, NULL);
+ g_return_val_if_fail((name != NULL) && (*name != '\0'), NULL);
+
+ hb.account = account;
+ hb.name = (gchar *)purple_normalize(account, name);
+
+ for (group = purplebuddylist->root; group; group = group->next) {
+ if (!group->child)
+ continue;
+
+ hb.group = group;
+ if ((buddy = g_hash_table_lookup(PURPLE_BUDDY_LIST_GET_PRIVATE(purplebuddylist)->buddies,
+ &hb))) {
+ return buddy;
+ }
+ }
+
+ return NULL;
+}
+
+PurpleBuddy *purple_blist_find_buddy_in_group(PurpleAccount *account, const char *name,
+ PurpleGroup *group)
+{
+ struct _purple_hbuddy hb;
+
+ g_return_val_if_fail(purplebuddylist != NULL, NULL);
+ g_return_val_if_fail(account != NULL, NULL);
+ g_return_val_if_fail((name != NULL) && (*name != '\0'), NULL);
+
+ hb.name = (gchar *)purple_normalize(account, name);
+ hb.account = account;
+ hb.group = (PurpleBlistNode*)group;
+
+ return g_hash_table_lookup(PURPLE_BUDDY_LIST_GET_PRIVATE(purplebuddylist)->buddies,
+ &hb);
+}
+
+static void find_acct_buddies(gpointer key, gpointer value, gpointer data)
+{
+ PurpleBuddy *buddy = value;
+ GSList **list = data;
+
+ *list = g_slist_prepend(*list, buddy);
+}
+
+GSList *purple_blist_find_buddies(PurpleAccount *account, const char *name)
+{
+ PurpleBuddy *buddy;
+ PurpleBlistNode *node;
+ GSList *ret = NULL;
+
+ g_return_val_if_fail(purplebuddylist != NULL, NULL);
+ g_return_val_if_fail(account != NULL, NULL);
+
+ if ((name != NULL) && (*name != '\0')) {
+ struct _purple_hbuddy hb;
+
+ hb.name = (gchar *)purple_normalize(account, name);
+ hb.account = account;
+
+ for (node = purplebuddylist->root; node != NULL; node = node->next) {
+ if (!node->child)
+ continue;
+
+ hb.group = node;
+ if ((buddy = g_hash_table_lookup(PURPLE_BUDDY_LIST_GET_PRIVATE(purplebuddylist)->buddies,
+ &hb)) != NULL)
+ ret = g_slist_prepend(ret, buddy);
+ }
+ } else {
+ GSList *list = NULL;
+ GHashTable *buddies = g_hash_table_lookup(buddies_cache, account);
+ g_hash_table_foreach(buddies, find_acct_buddies, &list);
+ ret = list;
+ }
+
+ return ret;
+}
+
+PurpleGroup *purple_blist_find_group(const char *name)
+{
+ gchar* key;
+ PurpleGroup *group;
+
+ g_return_val_if_fail(purplebuddylist != NULL, NULL);
+ g_return_val_if_fail((name != NULL) && (*name != '\0'), NULL);
+
+ key = g_utf8_collate_key(name, -1);
+ group = g_hash_table_lookup(groups_cache, key);
+ g_free(key);
+
+ return group;
+}
+
+PurpleChat *
+purple_blist_find_chat(PurpleAccount *account, const char *name)
+{
+ char *chat_name;
+ PurpleChat *chat;
+ PurplePlugin *prpl;
+ PurplePluginProtocolInfo *prpl_info = NULL;
+ struct proto_chat_entry *pce;
+ PurpleBlistNode *node, *group;
+ GList *parts;
+ char *normname;
+
+ g_return_val_if_fail(purplebuddylist != NULL, NULL);
+ g_return_val_if_fail((name != NULL) && (*name != '\0'), NULL);
+
+ if (!purple_account_is_connected(account))
+ return NULL;
+
+ prpl = purple_find_prpl(purple_account_get_protocol_id(account));
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
+
+ if (prpl_info->find_blist_chat != NULL)
+ return prpl_info->find_blist_chat(account, name);
+
+ normname = g_strdup(purple_normalize(account, name));
+ for (group = purplebuddylist->root; group != NULL; group = group->next) {
+ for (node = group->child; node != NULL; node = node->next) {
+ if (PURPLE_IS_CHAT(node)) {
+
+ chat = (PurpleChat*)node;
+
+ if (account != purple_chat_get_account(chat))
+ continue;
+
+ parts = prpl_info->chat_info(
+ purple_account_get_connection(purple_chat_get_account(chat)));
+
+ pce = parts->data;
+ chat_name = g_hash_table_lookup(purple_chat_get_components(chat),
+ pce->identifier);
+ g_list_foreach(parts, (GFunc)g_free, NULL);
+ g_list_free(parts);
+
+ if (purple_chat_get_account(chat) == account && chat_name != NULL &&
+ normname != NULL && !strcmp(purple_normalize(account, chat_name), normname)) {
+ g_free(normname);
+ return chat;
+ }
+ }
+ }
+ }
+
+ g_free(normname);
+ return NULL;
+}
+
+void purple_blist_add_account(PurpleAccount *account)
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ PurpleBlistNode *gnode, *cnode, *bnode;
+ PurpleCountingNode *contact_counter, *group_counter;
+
+ g_return_if_fail(purplebuddylist != NULL);
+
+ if (!ops || !ops->update)
+ return;
+
+ for (gnode = purplebuddylist->root; gnode; gnode = gnode->next) {
+ if (!PURPLE_IS_GROUP(gnode))
+ continue;
+ for (cnode = gnode->child; cnode; cnode = cnode->next) {
+ if (PURPLE_IS_CONTACT(cnode)) {
+ gboolean recompute = FALSE;
+ for (bnode = cnode->child; bnode; bnode = bnode->next) {
+ if (PURPLE_IS_BUDDY(bnode) &&
+ purple_buddy_get_account(PURPLE_BUDDY(bnode)) == account) {
+ recompute = TRUE;
+ contact_counter = PURPLE_COUNTING_NODE(cnode);
+ group_counter = PURPLE_COUNTING_NODE(gnode);
+ purple_counting_node_change_current_size(contact_counter, +1);
+ if (purple_counting_node_get_current_size(contact_counter) == 1)
+ purple_counting_node_change_current_size(group_counter, +1);
+ ops->update(purplebuddylist, bnode);
+ }
+ }
+ if (recompute ||
+ purple_blist_node_get_bool(cnode, "show_offline")) {
+ purple_contact_invalidate_priority_buddy((PurpleContact*)cnode);
+ ops->update(purplebuddylist, cnode);
+ }
+ } else if (PURPLE_IS_CHAT(cnode) &&
+ purple_chat_get_account(PURPLE_CHAT(cnode)) == account) {
+ group_counter = PURPLE_COUNTING_NODE(gnode);
+ purple_counting_node_change_online_count(group_counter, +1);
+ purple_counting_node_change_current_size(group_counter, +1);
+ ops->update(purplebuddylist, cnode);
+ }
+ }
+ ops->update(purplebuddylist, gnode);
+ }
+}
+
+void purple_blist_remove_account(PurpleAccount *account)
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ PurpleBlistNode *gnode, *cnode, *bnode;
+ PurpleCountingNode *contact_counter, *group_counter;
+ PurpleBuddy *buddy;
+ PurpleChat *chat;
+ PurpleContact *contact;
+ PurpleGroup *group;
+ GList *list = NULL, *iter = NULL;
+
+ g_return_if_fail(purplebuddylist != NULL);
+
+ for (gnode = purplebuddylist->root; gnode; gnode = gnode->next) {
+ if (!PURPLE_IS_GROUP(gnode))
+ continue;
+
+ group = (PurpleGroup *)gnode;
+
+ for (cnode = gnode->child; cnode; cnode = cnode->next) {
+ if (PURPLE_IS_CONTACT(cnode)) {
+ gboolean recompute = FALSE;
+ contact = (PurpleContact *)cnode;
+
+ for (bnode = cnode->child; bnode; bnode = bnode->next) {
+ if (!PURPLE_IS_BUDDY(bnode))
+ continue;
+
+ buddy = (PurpleBuddy *)bnode;
+ if (account == purple_buddy_get_account(buddy)) {
+ PurplePresence *presence;
+
+ presence = purple_buddy_get_presence(buddy);
+ contact_counter = PURPLE_COUNTING_NODE(contact);
+ group_counter = PURPLE_COUNTING_NODE(group);
+
+ if(purple_presence_is_online(presence)) {
+ purple_counting_node_change_online_count(contact_counter, -1);
+ if (purple_counting_node_get_online_count(contact_counter) == 0)
+ purple_counting_node_change_online_count(group_counter, -1);
+
+ purple_blist_node_set_int(PURPLE_BLIST_NODE(buddy),
+ "last_seen", time(NULL));
+ }
+
+ purple_counting_node_change_current_size(contact_counter, -1);
+ if (purple_counting_node_get_current_size(contact_counter) == 0)
+ purple_counting_node_change_current_size(group_counter, -1);
+
+ if (!g_list_find(list, presence))
+ list = g_list_prepend(list, presence);
+
+ if (purple_contact_get_priority_buddy(contact) == buddy)
+ purple_contact_invalidate_priority_buddy(contact);
+ else
+ recompute = TRUE;
+
+ if (ops && ops->remove) {
+ ops->remove(purplebuddylist, bnode);
+ }
+ }
+ }
+ if (recompute) {
+ purple_contact_invalidate_priority_buddy(contact);
+
+ if (ops && ops->update)
+ ops->update(purplebuddylist, cnode);
+ }
+ } else if (PURPLE_IS_CHAT(cnode)) {
+ chat = PURPLE_CHAT(cnode);
+
+ if(purple_chat_get_account(chat) == account) {
+ group_counter = PURPLE_COUNTING_NODE(group);
+ purple_counting_node_change_current_size(group_counter, -1);
+ purple_counting_node_change_online_count(group_counter, -1);
+
+ if (ops && ops->remove)
+ ops->remove(purplebuddylist, cnode);
+ }
+ }
+ }
+ }
+
+ for (iter = list; iter; iter = iter->next)
+ {
+ purple_presence_set_status_active(iter->data, "offline", TRUE);
+ }
+ g_list_free(list);
+}
+
+void
+purple_blist_request_add_buddy(PurpleAccount *account, const char *username,
+ const char *group, const char *alias)
+{
+ PurpleBlistUiOps *ui_ops;
+
+ ui_ops = purple_blist_get_ui_ops();
+
+ if (ui_ops != NULL && ui_ops->request_add_buddy != NULL)
+ ui_ops->request_add_buddy(account, username, group, alias);
+}
+
+void
+purple_blist_request_add_chat(PurpleAccount *account, PurpleGroup *group,
+ const char *alias, const char *name)
+{
+ PurpleBlistUiOps *ui_ops;
+
+ ui_ops = purple_blist_get_ui_ops();
+
+ if (ui_ops != NULL && ui_ops->request_add_chat != NULL)
+ ui_ops->request_add_chat(account, group, alias, name);
+}
+
+void
+purple_blist_request_add_group(void)
+{
+ PurpleBlistUiOps *ui_ops;
+
+ ui_ops = purple_blist_get_ui_ops();
+
+ if (ui_ops != NULL && ui_ops->request_add_group != NULL)
+ ui_ops->request_add_group();
+}
+
+void
+purple_blist_set_ui_ops(PurpleBlistUiOps *ops)
+{
+ gboolean overrode = FALSE;
+ blist_ui_ops = ops;
+
+ if (!ops)
+ return;
+
+ if (!ops->save_node) {
+ ops->save_node = purple_blist_save_node;
+ overrode = TRUE;
+ }
+ if (!ops->remove_node) {
+ ops->remove_node = purple_blist_save_node;
+ overrode = TRUE;
+ }
+ if (!ops->save_account) {
+ ops->save_account = purple_blist_save_account;
+ overrode = TRUE;
+ }
+
+ if (overrode && (ops->save_node != purple_blist_save_node ||
+ ops->remove_node != purple_blist_save_node ||
+ ops->save_account != purple_blist_save_account)) {
+ purple_debug_warning("blist", "Only some of the blist saving UI ops "
+ "were overridden. This probably is not what you want!\n");
+ }
+}
+
+PurpleBlistUiOps *
+purple_blist_get_ui_ops(void)
+{
+ return blist_ui_ops;
+}
+
+
+void *
+purple_blist_get_handle(void)
+{
+ static int handle;
+
+ return &handle;
+}
+
+void
+purple_blist_init(void)
+{
+ void *handle = purple_blist_get_handle();
+
+ purple_signal_register(handle, "buddy-status-changed",
+ purple_marshal_VOID__POINTER_POINTER_POINTER,
+ G_TYPE_NONE, 3, PURPLE_TYPE_BUDDY, PURPLE_TYPE_STATUS,
+ PURPLE_TYPE_STATUS);
+ purple_signal_register(handle, "buddy-privacy-changed",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE,
+ 1, PURPLE_TYPE_BUDDY);
+
+ purple_signal_register(handle, "buddy-idle-changed",
+ purple_marshal_VOID__POINTER_INT_INT, G_TYPE_NONE,
+ 3, PURPLE_TYPE_BUDDY, G_TYPE_INT, G_TYPE_INT);
+
+ purple_signal_register(handle, "buddy-signed-on",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_BUDDY);
+
+ purple_signal_register(handle, "buddy-signed-off",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_BUDDY);
+
+ purple_signal_register(handle, "buddy-got-login-time",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_BUDDY);
+
+ purple_signal_register(handle, "blist-node-added",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_BLIST_NODE);
+
+ purple_signal_register(handle, "blist-node-removed",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_BLIST_NODE);
+
+ purple_signal_register(handle, "buddy-added",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_BUDDY);
+
+ purple_signal_register(handle, "buddy-removed",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_BUDDY);
+
+ purple_signal_register(handle, "buddy-icon-changed",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_BUDDY);
+
+ purple_signal_register(handle, "update-idle", purple_marshal_VOID,
+ G_TYPE_NONE, 0);
+
+ purple_signal_register(handle, "blist-node-extended-menu",
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ PURPLE_TYPE_BLIST_NODE,
+ G_TYPE_POINTER); /* (GList **) */
+
+ purple_signal_register(handle, "blist-node-aliased",
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ PURPLE_TYPE_BLIST_NODE, G_TYPE_STRING);
+
+ purple_signal_register(handle, "buddy-caps-changed",
+ purple_marshal_VOID__POINTER_INT_INT, G_TYPE_NONE,
+ 3, PURPLE_TYPE_BUDDY, G_TYPE_INT, G_TYPE_INT);
+
+ purple_signal_connect(purple_accounts_get_handle(), "account-created",
+ handle,
+ PURPLE_CALLBACK(purple_blist_buddies_cache_add_account),
+ NULL);
+
+ purple_signal_connect(purple_accounts_get_handle(), "account-destroying",
+ handle,
+ PURPLE_CALLBACK(purple_blist_buddies_cache_remove_account),
+ NULL);
+}
+
+static void
+blist_node_destroy(PurpleBlistNode *node)
+{
+ PurpleBlistUiOps *ui_ops;
+ PurpleBlistNode *child, *next_child;
+
+ ui_ops = purple_blist_get_ui_ops();
+ child = node->child;
+ while (child) {
+ next_child = child->next;
+ blist_node_destroy(child);
+ child = next_child;
+ }
+
+ /* Allow the UI to free data */
+ node->parent = NULL;
+ node->child = NULL;
+ node->next = NULL;
+ node->prev = NULL;
+ if (ui_ops && ui_ops->remove)
+ ui_ops->remove(purplebuddylist, node);
+
+ g_object_unref(node);
+}
+
+void
+purple_blist_uninit(void)
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ PurpleBlistNode *node, *next_node;
+
+ /* This happens if we quit before purple_set_blist is called. */
+ if (purplebuddylist == NULL)
+ return;
+
+ if (save_timer != 0) {
+ purple_timeout_remove(save_timer);
+ save_timer = 0;
+ purple_blist_sync();
+ }
+
+ purple_debug(PURPLE_DEBUG_INFO, "blist", "Destroying\n");
+
+ if (ops && ops->destroy)
+ ops->destroy(purplebuddylist);
+
+ node = purple_blist_get_root();
+ while (node) {
+ next_node = node->next;
+ blist_node_destroy(node);
+ node = next_node;
+ }
+ purplebuddylist->root = NULL;
+
+ g_hash_table_destroy(buddies_cache);
+ g_hash_table_destroy(groups_cache);
+
+ buddies_cache = NULL;
+ groups_cache = NULL;
+
+ g_object_unref(purplebuddylist);
+ purplebuddylist = NULL;
+
+ purple_signals_disconnect_by_handle(purple_blist_get_handle());
+ purple_signals_unregister_by_instance(purple_blist_get_handle());
+}
+
+/**************************************************************************
+ * GObject code
+ **************************************************************************/
+
+/* GObject initialization function */
+static void
+purple_buddy_list_init(GTypeInstance *instance, gpointer klass)
+{
+ PurpleBuddyList *blist = PURPLE_BUDDY_LIST(instance);
+
+ PURPLE_DBUS_REGISTER_POINTER(blist, PurpleBuddyList);
+
+ PURPLE_BUDDY_LIST_GET_PRIVATE(blist)->buddies = g_hash_table_new_full(
+ (GHashFunc)_purple_blist_hbuddy_hash,
+ (GEqualFunc)_purple_blist_hbuddy_equal,
+ (GDestroyNotify)_purple_blist_hbuddy_free_key, NULL);
+}
+
+/* GObject dispose function */
+static void
+purple_buddy_list_dispose(GObject *object)
+{
+ PURPLE_DBUS_UNREGISTER_POINTER(object);
+
+ G_OBJECT_CLASS(parent_class)->dispose(object);
+}
+
+/* GObject finalize function */
+static void
+purple_buddy_list_finalize(GObject *object)
+{
+ g_hash_table_destroy(PURPLE_BUDDY_LIST_GET_PRIVATE(object)->buddies);
+
+ G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+/* Class initializer function */
+static void purple_buddy_list_class_init(PurpleBuddyListClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->dispose = purple_buddy_list_dispose;
+ obj_class->finalize = purple_buddy_list_finalize;
+
+ g_type_class_add_private(klass, sizeof(PurpleBuddyListPrivate));
+}
+
+GType
+purple_buddy_list_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleBuddyListClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_buddy_list_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleBuddyList),
+ 0,
+ (GInstanceInitFunc)purple_buddy_list_init,
+ NULL,
+ };
+
+ type = g_type_register_static(G_TYPE_OBJECT,
+ "PurpleBuddyList", &info, 0);
+ }
+
+ return type;
+}
diff --git a/libpurple/buddylist.h b/libpurple/buddylist.h
new file mode 100644
index 0000000000..e731e5eab0
--- /dev/null
+++ b/libpurple/buddylist.h
@@ -0,0 +1,481 @@
+/**
+ * @file buddylist.h Buddy List API
+ * @ingroup core
+ * @see @ref blist-signals
+ */
+
+/* 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 _PURPLE_BUDDY_LIST_H_
+#define _PURPLE_BUDDY_LIST_H_
+
+/* I can't believe I let ChipX86 inspire me to write good code. -Sean */
+
+#include "blistnodetypes.h"
+
+#define PURPLE_TYPE_BUDDY_LIST (purple_buddy_list_get_type())
+#define PURPLE_BUDDY_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_BUDDY_LIST, PurpleBuddyList))
+#define PURPLE_BUDDY_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_BUDDY_LIST, PurpleBuddyListClass))
+#define PURPLE_IS_BUDDY_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_BUDDY_LIST))
+#define PURPLE_IS_BUDDY_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_BUDDY_LIST))
+#define PURPLE_BUDDY_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_BUDDY_LIST, PurpleBuddyListClass))
+
+/** @copydoc _PurpleBuddyList */
+typedef struct _PurpleBuddyList PurpleBuddyList;
+/** @copydoc _PurpleBuddyList */
+typedef struct _PurpleBuddyListClass PurpleBuddyListClass;
+
+/** @copydoc _PurpleBlistUiOps */
+typedef struct _PurpleBlistUiOps PurpleBlistUiOps;
+
+/**************************************************************************/
+/* Data Structures */
+/**************************************************************************/
+/**
+ * The Buddy List
+ */
+struct _PurpleBuddyList {
+ /*< private >*/
+ GObject gparent;
+
+ /** The UI data associated with this buddy list. This is a convenience
+ * field provided to the UIs -- it is not used by the libpurple core.
+ */
+ gpointer ui_data;
+
+ /** The first node in the buddy list */
+ PurpleBlistNode *root;
+};
+
+/** The base class for all #PurpleBuddyList's. */
+struct _PurpleBuddyListClass {
+ /*< private >*/
+ GObjectClass gparent_class;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+/**
+ * Buddy list UI operations.
+ *
+ * Any UI representing a buddy list must assign a filled-out PurpleBlistUiOps
+ * structure to the buddy list core.
+ */
+struct _PurpleBlistUiOps
+{
+ void (*new_list)(PurpleBuddyList *list); /**< Sets UI-specific data on a buddy list. */
+ void (*new_node)(PurpleBlistNode *node); /**< Sets UI-specific data on a node. */
+ void (*show)(PurpleBuddyList *list); /**< The core will call this when it's finished doing its core stuff */
+ void (*update)(PurpleBuddyList *list,
+ PurpleBlistNode *node); /**< This will update a node in the buddy list. */
+ void (*remove)(PurpleBuddyList *list,
+ PurpleBlistNode *node); /**< This removes a node from the list */
+ void (*destroy)(PurpleBuddyList *list); /**< When the list is destroyed, this is called to destroy the UI. */
+ void (*set_visible)(PurpleBuddyList *list,
+ gboolean show); /**< Hides or unhides the buddy list */
+ void (*request_add_buddy)(PurpleAccount *account, const char *username,
+ const char *group, const char *alias);
+ void (*request_add_chat)(PurpleAccount *account, PurpleGroup *group,
+ const char *alias, const char *name);
+ void (*request_add_group)(void);
+
+ /**
+ * This is called when a node has been modified and should be saved.
+ *
+ * Implementation of this UI op is OPTIONAL. If not implemented, it will
+ * be set to a fallback function that saves data to blist.xml like in
+ * previous libpurple versions.
+ *
+ * @param node The node which has been modified.
+ */
+ void (*save_node)(PurpleBlistNode *node);
+
+ /**
+ * Called when a node is about to be removed from the buddy list.
+ * The UI op should update the relevant data structures to remove this
+ * node (for example, removing a buddy from the group this node is in).
+ *
+ * Implementation of this UI op is OPTIONAL. If not implemented, it will
+ * be set to a fallback function that saves data to blist.xml like in
+ * previous libpurple versions.
+ *
+ * @param node The node which has been modified.
+ */
+ void (*remove_node)(PurpleBlistNode *node);
+
+ /**
+ * Called to save all the data for an account. If the UI sets this,
+ * the callback must save the privacy and buddy list data for an account.
+ * If the account is NULL, save the data for all accounts.
+ *
+ * Implementation of this UI op is OPTIONAL. If not implemented, it will
+ * be set to a fallback function that saves data to blist.xml like in
+ * previous libpurple versions.
+ *
+ * @param account The account whose data to save. If NULL, save all data
+ * for all accounts.
+ */
+ void (*save_account)(PurpleAccount *account);
+
+ void (*_purple_reserved1)(void);
+};
+
+G_BEGIN_DECLS
+
+/**************************************************************************/
+/** @name Buddy List API */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the GType for the PurpleBuddyList object.
+ */
+GType purple_buddy_list_get_type(void);
+
+/**
+ * Returns the main buddy list.
+ *
+ * @return The main buddy list.
+ */
+PurpleBuddyList *purple_blist_get_buddy_list(void);
+
+/**
+ * Returns the root node of the main buddy list.
+ *
+ * @return The root node.
+ */
+PurpleBlistNode *purple_blist_get_root(void);
+
+/**
+ * Returns a list of every buddy in the list. Use of this function is
+ * discouraged if you do not actually need every buddy in the list. Use
+ * purple_blist_find_buddies instead.
+ *
+ * @return A list of every buddy in the list. Caller is responsible for
+ * freeing the list.
+ *
+ * @see purple_blist_find_buddies
+ */
+GSList *purple_blist_get_buddies(void);
+
+/**
+ * Returns the UI data for the list.
+ *
+ * @return The UI data for the list.
+ */
+gpointer purple_blist_get_ui_data(void);
+
+/**
+ * Sets the UI data for the list.
+ *
+ * @param ui_data The UI data for the list.
+ */
+void purple_blist_set_ui_data(gpointer ui_data);
+
+/**
+ * Shows the buddy list, creating a new one if necessary.
+ */
+void purple_blist_show(void);
+
+/**
+ * Hides or unhides the buddy list.
+ *
+ * @param show Whether or not to show the buddy list
+ */
+void purple_blist_set_visible(gboolean show);
+
+/**
+ * Updates the buddies hash table when a buddy has been renamed. This only
+ * updates the cache, the caller is responsible for the actual renaming of
+ * the buddy after updating the cache.
+ *
+ * @param buddy The buddy whose name will be changed.
+ * @param name The new name of the buddy.
+ */
+void purple_blist_update_buddies_cache(PurpleBuddy *buddy, const char *new_name);
+
+/**
+ * Updates the groups hash table when a group has been renamed. This only
+ * updates the cache, the caller is responsible for the actual renaming of
+ * the group after updating the cache.
+ *
+ * @param group The group whose name will be changed.
+ * @param name The new name of the group.
+ */
+void purple_blist_update_groups_cache(PurpleGroup *group, const char *new_name);
+
+/**
+ * Adds a new chat to the buddy list.
+ *
+ * The chat will be inserted right after node or appended to the end
+ * of group if node is NULL. If both are NULL, the buddy will be added to
+ * the "Chats" group.
+ *
+ * @param chat The new chat who gets added
+ * @param group The group to add the new chat to.
+ * @param node The insertion point
+ */
+void purple_blist_add_chat(PurpleChat *chat, PurpleGroup *group, PurpleBlistNode *node);
+
+/**
+ * Adds a new buddy to the buddy list.
+ *
+ * The buddy will be inserted right after node or prepended to the
+ * group if node is NULL. If both are NULL, the buddy will be added to
+ * the "Buddies" group.
+ *
+ * @param buddy The new buddy who gets added
+ * @param contact The optional contact to place the buddy in.
+ * @param group The group to add the new buddy to.
+ * @param node The insertion point. Pass in NULL to add the node as
+ * the first child in the given group.
+ */
+void purple_blist_add_buddy(PurpleBuddy *buddy, PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node);
+
+/**
+ * Adds a new group to the buddy list.
+ *
+ * The new group will be inserted after insert or prepended to the list if
+ * node is NULL.
+ *
+ * @param group The group
+ * @param node The insertion point
+ */
+void purple_blist_add_group(PurpleGroup *group, PurpleBlistNode *node);
+
+/**
+ * Adds a new contact to the buddy list.
+ *
+ * The new contact will be inserted after insert or prepended to the list if
+ * node is NULL.
+ *
+ * @param contact The contact
+ * @param group The group to add the contact to
+ * @param node The insertion point
+ */
+void purple_blist_add_contact(PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node);
+
+/**
+ * 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.
+ *
+ * @param buddy The buddy to be removed
+ *
+ * @see purple_account_remove_buddy
+ */
+void purple_blist_remove_buddy(PurpleBuddy *buddy);
+
+/**
+ * Removes a contact, and any buddies it contains, and frees the memory
+ * allocated to it. This calls purple_blist_remove_buddy and therefore
+ * doesn't remove the buddies from the server list.
+ *
+ * @param contact The contact to be removed
+ *
+ * @see purple_blist_remove_buddy
+ */
+void purple_blist_remove_contact(PurpleContact *contact);
+
+/**
+ * Removes a chat from the buddy list and frees the memory allocated to it.
+ *
+ * @param chat The chat to be removed
+ */
+void purple_blist_remove_chat(PurpleChat *chat);
+
+/**
+ * Removes a group from the buddy list and frees the memory allocated to it and to
+ * its children
+ *
+ * @param group The group to be removed
+ */
+void purple_blist_remove_group(PurpleGroup *group);
+
+/**
+ * Finds the buddy struct given a name and an account
+ *
+ * @param account The account this buddy belongs to
+ * @param name The buddy's name
+ * @return The buddy or NULL if the buddy does not exist
+ */
+PurpleBuddy *purple_blist_find_buddy(PurpleAccount *account, const char *name);
+
+/**
+ * Finds the buddy struct given a name, an account, and a group
+ *
+ * @param account The account this buddy belongs to
+ * @param name The buddy's name
+ * @param group The group to look in
+ * @return The buddy or NULL if the buddy does not exist in the group
+ */
+PurpleBuddy *purple_blist_find_buddy_in_group(PurpleAccount *account, const char *name,
+ PurpleGroup *group);
+
+/**
+ * Finds all PurpleBuddy structs given a name and an account
+ *
+ * @param account The account this buddy belongs to
+ * @param name The buddy's name (or NULL to return all buddies for the account)
+ *
+ * @return NULL if the buddy doesn't exist, or a GSList of
+ * PurpleBuddy structs. You must free the GSList using
+ * g_slist_free. Do not free the PurpleBuddy structs that
+ * the list points to.
+ */
+GSList *purple_blist_find_buddies(PurpleAccount *account, const char *name);
+
+/**
+ * Finds a group by name
+ *
+ * @param name The group's name
+ * @return The group or NULL if the group does not exist
+ */
+PurpleGroup *purple_blist_find_group(const char *name);
+
+/**
+ * Finds a chat by name.
+ *
+ * @param account The chat's account.
+ * @param name The chat's name.
+ *
+ * @return The chat, or @c NULL if the chat does not exist.
+ */
+PurpleChat *purple_blist_find_chat(PurpleAccount *account, const char *name);
+
+/**
+ * Called when an account connects. Tells the UI to update all the
+ * buddies.
+ *
+ * @param account The account
+ */
+void purple_blist_add_account(PurpleAccount *account);
+
+/**
+ * Called when an account disconnects. Sets the presence of all the buddies to 0
+ * and tells the UI to update them.
+ *
+ * @param account The account
+ */
+void purple_blist_remove_account(PurpleAccount *account);
+
+/*@}*/
+
+/****************************************************************************************/
+/** @name Buddy list file management API */
+/****************************************************************************************/
+
+/**
+ * Schedule a save of the blist.xml file. This is used by the privacy
+ * API whenever the privacy settings are changed. If you make a change
+ * to blist.xml using one of the functions in the buddy list API, then
+ * the buddy list is saved automatically, so you should not need to
+ * call this.
+ */
+void purple_blist_schedule_save(void);
+
+/**
+ * Requests from the user information needed to add a buddy to the
+ * buddy list.
+ *
+ * @param account The account the buddy is added to.
+ * @param username The username of the buddy.
+ * @param group The name of the group to place the buddy in.
+ * @param alias The optional alias for the buddy.
+ */
+void purple_blist_request_add_buddy(PurpleAccount *account, const char *username,
+ const char *group, const char *alias);
+
+/**
+ * Requests from the user information needed to add a chat to the
+ * buddy list.
+ *
+ * @param account The account the buddy is added to.
+ * @param group The optional group to add the chat to.
+ * @param alias The optional alias for the chat.
+ * @param name The required chat name.
+ */
+void purple_blist_request_add_chat(PurpleAccount *account, PurpleGroup *group,
+ const char *alias, const char *name);
+
+/**
+ * Requests from the user information needed to add a group to the
+ * buddy list.
+ */
+void purple_blist_request_add_group(void);
+
+/**************************************************************************/
+/** @name UI Registration Functions */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Sets the UI operations structure to be used for the buddy list.
+ *
+ * @param ops The ops struct.
+ */
+void purple_blist_set_ui_ops(PurpleBlistUiOps *ops);
+
+/**
+ * Returns the UI operations structure to be used for the buddy list.
+ *
+ * @return The UI operations structure.
+ */
+PurpleBlistUiOps *purple_blist_get_ui_ops(void);
+
+/*@}*/
+
+/**************************************************************************/
+/** @name Buddy List Subsystem */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the handle for the buddy list subsystem.
+ *
+ * @return The buddy list subsystem handle.
+ */
+void *purple_blist_get_handle(void);
+
+/**
+ * Initializes the buddy list subsystem.
+ */
+void purple_blist_init(void);
+
+/**
+ * Loads the buddy list.
+ *
+ * You shouldn't call this. purple_core_init() will do it for you.
+ */
+void purple_blist_boot(void);
+
+/**
+ * Uninitializes the buddy list subsystem.
+ */
+void purple_blist_uninit(void);
+
+/*@}*/
+
+G_END_DECLS
+
+#endif /* _PURPLE_BUDDY_LIST_H_ */
diff --git a/libpurple/certificate.c b/libpurple/certificate.c
index a62aa711ae..fd4d0a98d4 100644
--- a/libpurple/certificate.c
+++ b/libpurple/certificate.c
@@ -511,6 +511,20 @@ purple_certificate_get_display_string(PurpleCertificate *crt)
return str;
}
+GType
+purple_certificate_get_type(void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_boxed_type_register_static("PurpleCertificate",
+ (GBoxedCopyFunc)purple_certificate_copy,
+ (GBoxedFreeFunc)purple_certificate_destroy);
+ }
+
+ return type;
+}
+
gchar *
purple_certificate_pool_mkpath(PurpleCertificatePool *pool, const gchar *id)
{
@@ -650,6 +664,33 @@ purple_certificate_pool_destroy_idlist(GList *idlist)
g_list_free(idlist);
}
+static PurpleCertificatePool *
+purple_certificate_pool_copy(PurpleCertificatePool *certificate_pool)
+{
+ PurpleCertificatePool *certificate_pool_copy;
+
+ g_return_val_if_fail(certificate_pool != NULL, NULL);
+
+ certificate_pool_copy = g_new(PurpleCertificatePool, 1);
+ *certificate_pool_copy = *certificate_pool;
+
+ return certificate_pool_copy;
+}
+
+GType
+purple_certificate_pool_get_type(void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_boxed_type_register_static("PurpleCertificatePool",
+ (GBoxedCopyFunc)purple_certificate_pool_copy,
+ (GBoxedFreeFunc)g_free);
+ }
+
+ return type;
+}
+
/****************************************************************************/
/* Builtin Verifiers, Pools, etc. */
@@ -2034,20 +2075,16 @@ purple_certificate_register_pool(PurpleCertificatePool *pool)
purple_signal_register(pool, /* Signals emitted from pool */
"certificate-stored",
purple_marshal_VOID__POINTER_POINTER,
- NULL, /* No callback return value */
+ G_TYPE_NONE, /* No callback return value */
2, /* Two non-data arguments */
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CERTIFICATEPOOL),
- purple_value_new(PURPLE_TYPE_STRING));
+ PURPLE_TYPE_CERTIFICATE_POOL, G_TYPE_STRING);
purple_signal_register(pool, /* Signals emitted from pool */
"certificate-deleted",
purple_marshal_VOID__POINTER_POINTER,
- NULL, /* No callback return value */
+ G_TYPE_NONE, /* No callback return value */
2, /* Two non-data arguments */
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CERTIFICATEPOOL),
- purple_value_new(PURPLE_TYPE_STRING));
+ PURPLE_TYPE_CERTIFICATE_POOL, G_TYPE_STRING);
purple_debug_info("certificate",
"CertificatePool %s registered\n",
diff --git a/libpurple/certificate.h b/libpurple/certificate.h
index d34aa5e21d..8235f2e854 100644
--- a/libpurple/certificate.h
+++ b/libpurple/certificate.h
@@ -81,8 +81,12 @@ typedef enum
PURPLE_CERTIFICATE_LAST = 0x80000,
} PurpleCertificateVerificationStatus;
+#define PURPLE_TYPE_CERTIFICATE (purple_certificate_get_type())
typedef struct _PurpleCertificate PurpleCertificate;
+
+#define PURPLE_TYPE_CERTIFICATE_POOL (purple_certificate_pool_get_type())
typedef struct _PurpleCertificatePool PurpleCertificatePool;
+
typedef struct _PurpleCertificateScheme PurpleCertificateScheme;
typedef struct _PurpleCertificateVerifier PurpleCertificateVerifier;
typedef struct _PurpleCertificateVerificationRequest PurpleCertificateVerificationRequest;
@@ -456,6 +460,11 @@ purple_certificate_verify_complete(PurpleCertificateVerificationRequest *vrq,
/*@{*/
/**
+ * Returns the GType for the PurpleCertificate boxed structure.
+ */
+GType purple_certificate_get_type(void);
+
+/**
* Makes a duplicate of a certificate
*
* @param crt Instance to duplicate
@@ -643,6 +652,15 @@ purple_certificate_get_display_string(PurpleCertificate *crt);
/** @name Certificate Pool Functions */
/*****************************************************************************/
/*@{*/
+
+/**
+ * Returns the GType for the PurpleCertificatePool boxed structure.
+ * TODO Boxing of PurpleCertificatePool is a temporary solution to having a
+ * GType for certificate pools. This should rather be a GObject instead of
+ * a GBoxed.
+ */
+GType purple_certificate_pool_get_type(void);
+
/**
* Helper function for generating file paths in ~/.purple/certificates for
* CertificatePools that use them.
diff --git a/libpurple/cipher.c b/libpurple/cipher.c
index 1df779caab..14ca9aee53 100644
--- a/libpurple/cipher.c
+++ b/libpurple/cipher.c
@@ -1,24 +1,9 @@
-/*
- * purple
+/* purple
*
* Purple is the legal property of its developers, whose names are too numerous
* to list here. Please refer to the COPYRIGHT file distributed with this
* source distribution.
*
- * Original des taken from gpg
- *
- * des.c - DES and Triple-DES encryption/decryption Algorithm
- * Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * Please see below for more legal information!
- *
- * According to the definition of DES in FIPS PUB 46-2 from December 1993.
- * For a description of triple encryption, see:
- * Bruce Schneier: Applied Cryptography. Second Edition.
- * John Wiley & Sons, 1996. ISBN 0-471-12845-7. Pages 358 ff.
- *
- * This file is part of GnuPG.
- *
* 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
@@ -35,435 +20,208 @@
*/
#include "internal.h"
#include "cipher.h"
-#include "ciphers/ciphers.h"
-#include "dbus-maybe.h"
#include "debug.h"
-#include "signals.h"
-#include "value.h"
-
-/*******************************************************************************
- * Structs
- ******************************************************************************/
-struct _PurpleCipher {
- gchar *name; /**< Internal name - used for searching */
- PurpleCipherOps *ops; /**< Operations supported by this cipher */
- guint ref; /**< Reference count */
-};
-
-struct _PurpleCipherContext {
- PurpleCipher *cipher; /**< Cipher this context is under */
- gpointer data; /**< Internal cipher state data */
-};
-
-/******************************************************************************
- * Globals
- *****************************************************************************/
-static GList *ciphers = NULL;
/******************************************************************************
* PurpleCipher API
*****************************************************************************/
const gchar *
purple_cipher_get_name(PurpleCipher *cipher) {
- g_return_val_if_fail(cipher, NULL);
-
- return cipher->name;
-}
-
-guint
-purple_cipher_get_capabilities(PurpleCipher *cipher) {
- PurpleCipherOps *ops = NULL;
- guint caps = 0;
-
- g_return_val_if_fail(cipher, 0);
-
- ops = cipher->ops;
- g_return_val_if_fail(ops, 0);
-
- if(ops->set_option)
- caps |= PURPLE_CIPHER_CAPS_SET_OPT;
- if(ops->get_option)
- caps |= PURPLE_CIPHER_CAPS_GET_OPT;
- if(ops->init)
- caps |= PURPLE_CIPHER_CAPS_INIT;
- if(ops->reset)
- caps |= PURPLE_CIPHER_CAPS_RESET;
- if(ops->reset_state)
- caps |= PURPLE_CIPHER_CAPS_RESET_STATE;
- if(ops->uninit)
- caps |= PURPLE_CIPHER_CAPS_UNINIT;
- if(ops->set_iv)
- caps |= PURPLE_CIPHER_CAPS_SET_IV;
- if(ops->append)
- caps |= PURPLE_CIPHER_CAPS_APPEND;
- if(ops->digest)
- caps |= PURPLE_CIPHER_CAPS_DIGEST;
- if(ops->get_digest_size)
- caps |= PURPLE_CIPHER_CAPS_GET_DIGEST_SIZE;
- if(ops->encrypt)
- caps |= PURPLE_CIPHER_CAPS_ENCRYPT;
- if(ops->decrypt)
- caps |= PURPLE_CIPHER_CAPS_DECRYPT;
- if(ops->set_salt)
- caps |= PURPLE_CIPHER_CAPS_SET_SALT;
- if(ops->get_salt_size)
- caps |= PURPLE_CIPHER_CAPS_GET_SALT_SIZE;
- if(ops->set_key)
- caps |= PURPLE_CIPHER_CAPS_SET_KEY;
- if (ops->get_key_size)
- caps |= PURPLE_CIPHER_CAPS_GET_KEY_SIZE;
- if(ops->set_batch_mode)
- caps |= PURPLE_CIPHER_CAPS_SET_BATCH_MODE;
- if(ops->get_batch_mode)
- caps |= PURPLE_CIPHER_CAPS_GET_BATCH_MODE;
- if(ops->get_block_size)
- caps |= PURPLE_CIPHER_CAPS_GET_BLOCK_SIZE;
-
- return caps;
-}
-
-ssize_t
-purple_cipher_digest_region(const gchar *name, const guchar *data,
- size_t data_len, guchar digest[], size_t out_size)
-{
- PurpleCipher *cipher;
- PurpleCipherContext *context;
- ssize_t digest_size;
- gboolean succ;
-
- g_return_val_if_fail(name, -1);
- g_return_val_if_fail(data, -1);
-
- cipher = purple_ciphers_find_cipher(name);
-
- g_return_val_if_fail(cipher, -1);
-
- if(!cipher->ops->append || !cipher->ops->digest || !cipher->ops->get_digest_size) {
- purple_debug_warning("cipher", "purple_cipher_region failed: "
- "the %s cipher does not support appending and or "
- "digesting.", cipher->name);
- return -1;
- }
-
- context = purple_cipher_context_new(cipher, NULL);
- digest_size = purple_cipher_context_get_digest_size(context);
- if (out_size < digest_size) {
- purple_debug_error("cipher", "purple_cipher_region failed: "
- "provided output buffer too small\n");
- purple_cipher_context_destroy(context);
- return -1;
- }
- purple_cipher_context_append(context, data, data_len);
- succ = purple_cipher_context_digest(context, digest, out_size);
- purple_cipher_context_destroy(context);
-
- return succ ? digest_size : -1;
-}
+ PurpleCipherClass *klass = NULL;
-/******************************************************************************
- * PurpleCiphers API
- *****************************************************************************/
-PurpleCipher *
-purple_ciphers_find_cipher(const gchar *name) {
- PurpleCipher *cipher;
- GList *l;
-
- g_return_val_if_fail(name, NULL);
-
- for(l = ciphers; l; l = l->next) {
- cipher = PURPLE_CIPHER(l->data);
-
- if(!g_ascii_strcasecmp(cipher->name, name))
- return cipher;
- }
-
- return NULL;
-}
-
-PurpleCipher *
-purple_ciphers_register_cipher(const gchar *name, PurpleCipherOps *ops) {
- PurpleCipher *cipher = NULL;
-
- g_return_val_if_fail(name, NULL);
- g_return_val_if_fail(ops, NULL);
- g_return_val_if_fail(!purple_ciphers_find_cipher(name), NULL);
-
- cipher = g_new0(PurpleCipher, 1);
- PURPLE_DBUS_REGISTER_POINTER(cipher, PurpleCipher);
-
- cipher->name = g_strdup(name);
- cipher->ops = ops;
-
- ciphers = g_list_append(ciphers, cipher);
-
- purple_signal_emit(purple_ciphers_get_handle(), "cipher-added", cipher);
-
- return cipher;
-}
-
-gboolean
-purple_ciphers_unregister_cipher(PurpleCipher *cipher) {
- g_return_val_if_fail(cipher, FALSE);
- g_return_val_if_fail(cipher->ref == 0, FALSE);
-
- purple_signal_emit(purple_ciphers_get_handle(), "cipher-removed", cipher);
-
- ciphers = g_list_remove(ciphers, cipher);
-
- g_free(cipher->name);
-
- PURPLE_DBUS_UNREGISTER_POINTER(cipher);
- g_free(cipher);
-
- return TRUE;
-}
-
-GList *
-purple_ciphers_get_ciphers() {
- return ciphers;
-}
-
-/******************************************************************************
- * PurpleCipher Subsystem API
- *****************************************************************************/
-gpointer
-purple_ciphers_get_handle() {
- static gint handle;
-
- return &handle;
-}
-
-void
-purple_ciphers_init() {
- gpointer handle;
-
- handle = purple_ciphers_get_handle();
-
- purple_signal_register(handle, "cipher-added",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CIPHER));
- purple_signal_register(handle, "cipher-removed",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CIPHER));
-
- purple_ciphers_register_all();
-}
-
-void
-purple_ciphers_uninit() {
- PurpleCipher *cipher;
- GList *l, *ll;
-
- for(l = ciphers; l; l = ll) {
- ll = l->next;
-
- cipher = PURPLE_CIPHER(l->data);
- purple_ciphers_unregister_cipher(cipher);
- }
-
- g_list_free(ciphers);
-
- purple_signals_unregister_by_instance(purple_ciphers_get_handle());
-}
-
-/******************************************************************************
- * PurpleCipherContext API
- *****************************************************************************/
-void
-purple_cipher_context_set_option(PurpleCipherContext *context, const gchar *name,
- gpointer value)
-{
- PurpleCipher *cipher = NULL;
-
- g_return_if_fail(context);
- g_return_if_fail(name);
-
- cipher = context->cipher;
- g_return_if_fail(cipher);
-
- if(cipher->ops && cipher->ops->set_option)
- cipher->ops->set_option(context, name, value);
- else
- purple_debug_warning("cipher", "the %s cipher does not support the "
- "set_option operation\n", cipher->name);
-}
-
-gpointer
-purple_cipher_context_get_option(PurpleCipherContext *context, const gchar *name) {
- PurpleCipher *cipher = NULL;
-
- g_return_val_if_fail(context, NULL);
- g_return_val_if_fail(name, NULL);
-
- cipher = context->cipher;
g_return_val_if_fail(cipher, NULL);
-
- if(cipher->ops && cipher->ops->get_option)
- return cipher->ops->get_option(context, name);
- else {
- purple_debug_warning("cipher", "the %s cipher does not support the "
- "get_option operation\n", cipher->name);
-
- return NULL;
+ g_return_val_if_fail(PURPLE_IS_CIPHER(cipher), NULL);
+
+ klass = PURPLE_CIPHER_GET_CLASS(cipher);
+ g_return_val_if_fail(klass->get_name, NULL);
+
+ return klass->get_name(cipher);
+}
+
+GType
+purple_cipher_get_type(void) {
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleCipherClass),
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ sizeof(PurpleCipher),
+ 0,
+ NULL,
+ NULL
+ };
+
+ type = g_type_register_static(G_TYPE_OBJECT,
+ "PurpleCipher",
+ &info, G_TYPE_FLAG_ABSTRACT);
}
-}
-
-PurpleCipherContext *
-purple_cipher_context_new(PurpleCipher *cipher, void *extra) {
- PurpleCipherContext *context = NULL;
-
- g_return_val_if_fail(cipher, NULL);
-
- cipher->ref++;
-
- context = g_new0(PurpleCipherContext, 1);
- context->cipher = cipher;
- if(cipher->ops->init)
- cipher->ops->init(context, extra);
-
- return context;
-}
-
-PurpleCipherContext *
-purple_cipher_context_new_by_name(const gchar *name, void *extra) {
- PurpleCipher *cipher;
-
- g_return_val_if_fail(name, NULL);
-
- cipher = purple_ciphers_find_cipher(name);
-
- g_return_val_if_fail(cipher, NULL);
-
- return purple_cipher_context_new(cipher, extra);
-}
-
-void
-purple_cipher_context_reset(PurpleCipherContext *context, void *extra) {
- PurpleCipher *cipher = NULL;
-
- g_return_if_fail(context);
-
- cipher = context->cipher;
- g_return_if_fail(cipher);
-
- if(cipher->ops && cipher->ops->reset)
- context->cipher->ops->reset(context, extra);
+ return type;
}
+/**
+ * purple_cipher_reset:
+ * @cipher: The cipher to reset
+ *
+ * Resets a cipher to it's default value
+ *
+ * @note If you have set an IV you will have to set it after resetting
+ */
void
-purple_cipher_context_reset_state(PurpleCipherContext *context, void *extra) {
- PurpleCipher *cipher = NULL;
-
- g_return_if_fail(context);
+purple_cipher_reset(PurpleCipher *cipher) {
+ PurpleCipherClass *klass = NULL;
- cipher = context->cipher;
- g_return_if_fail(cipher);
- g_return_if_fail(cipher->ops);
+ g_return_if_fail(PURPLE_IS_CIPHER(cipher));
- if (cipher->ops->reset_state) {
- context->cipher->ops->reset_state(context, extra);
- return;
- }
+ klass = PURPLE_CIPHER_GET_CLASS(cipher);
- purple_debug_warning("cipher", "the %s cipher does not support the "
- "reset_state operation\n", cipher->name);
- purple_cipher_context_reset(context, extra);
+ if(klass && klass->reset)
+ klass->reset(cipher);
+ else
+ purple_debug_warning("cipher", "the %s cipher does not implement the "
+ "reset method\n",
+ klass->get_name ? klass->get_name(cipher) : "");
}
+/**
+ * Resets a cipher state to it's default value, but doesn't touch stateless
+ * configuration.
+ *
+ * That means, IV and digest context will be wiped out, but keys, ops or salt
+ * will remain untouched.
+ */
void
-purple_cipher_context_destroy(PurpleCipherContext *context) {
- PurpleCipher *cipher = NULL;
+purple_cipher_reset_state(PurpleCipher *cipher) {
+ PurpleCipherClass *klass = NULL;
- g_return_if_fail(context);
+ g_return_if_fail(PURPLE_IS_CIPHER(cipher));
- cipher = context->cipher;
- g_return_if_fail(cipher);
+ klass = PURPLE_CIPHER_GET_CLASS(cipher);
- cipher->ref--;
-
- if(cipher->ops && cipher->ops->uninit)
- cipher->ops->uninit(context);
-
- memset(context, 0, sizeof(*context));
- g_free(context);
- context = NULL;
+ if(klass && klass->reset_state)
+ klass->reset_state(cipher);
+ else
+ purple_debug_warning("cipher", "the %s cipher does not implement the "
+ "reset_state method\n",
+ klass->get_name ? klass->get_name(cipher) : "");
}
+/**
+ * purple_cipher_set_iv:
+ * @cipher: The cipher to set the IV to
+ * @iv: The initialization vector to set
+ * @len: The len of the IV
+ *
+ * @note This should only be called right after a cipher is created or reset
+ *
+ * Sets the initialization vector for a cipher
+ */
void
-purple_cipher_context_set_iv(PurpleCipherContext *context, guchar *iv, size_t len)
+purple_cipher_set_iv(PurpleCipher *cipher, guchar *iv, size_t len)
{
- PurpleCipher *cipher = NULL;
+ PurpleCipherClass *klass = NULL;
- g_return_if_fail(context);
+ g_return_if_fail(PURPLE_IS_CIPHER(cipher));
g_return_if_fail(iv);
- cipher = context->cipher;
- g_return_if_fail(cipher);
+ klass = PURPLE_CIPHER_GET_CLASS(cipher);
- if(cipher->ops && cipher->ops->set_iv)
- cipher->ops->set_iv(context, iv, len);
+ if(klass && klass->set_iv)
+ klass->set_iv(cipher, iv, len);
else
- purple_debug_warning("cipher", "the %s cipher does not support the set"
- "initialization vector operation\n", cipher->name);
+ purple_debug_warning("cipher", "the %s cipher does not implement the "
+ "set_iv method\n",
+ klass->get_name ? klass->get_name(cipher) : "");
}
+/**
+ * purple_cipher_append:
+ * @cipher: The cipher to append data to
+ * @data: The data to append
+ * @len: The length of the data
+ *
+ * Appends data to the cipher
+ */
void
-purple_cipher_context_append(PurpleCipherContext *context, const guchar *data,
+purple_cipher_append(PurpleCipher *cipher, const guchar *data,
size_t len)
{
- PurpleCipher *cipher = NULL;
+ PurpleCipherClass *klass = NULL;
- g_return_if_fail(context);
+ g_return_if_fail(PURPLE_IS_CIPHER(cipher));
- cipher = context->cipher;
- g_return_if_fail(cipher);
+ klass = PURPLE_CIPHER_GET_CLASS(cipher);
- if(cipher->ops && cipher->ops->append)
- cipher->ops->append(context, data, len);
+ if(klass && klass->append)
+ klass->append(cipher, data, len);
else
- purple_debug_warning("cipher", "the %s cipher does not support the append "
- "operation\n", cipher->name);
+ purple_debug_warning("cipher", "the %s cipher does not implement the "
+ "append method\n",
+ klass->get_name ? klass->get_name(cipher) : "");
}
+/**
+ * purple_cipher_digest:
+ * @cipher: The cipher to digest
+ * @in_len: The length of the buffer
+ * @digest: The return buffer for the digest
+ * @out_len: The length of the returned value
+ *
+ * Digests a cipher
+ *
+ * Return Value: TRUE if the digest was successful, FALSE otherwise.
+ */
gboolean
-purple_cipher_context_digest(PurpleCipherContext *context, guchar digest[],
- size_t len)
+purple_cipher_digest(PurpleCipher *cipher, guchar digest[], size_t len)
{
- PurpleCipher *cipher = NULL;
+ PurpleCipherClass *klass = NULL;
- g_return_val_if_fail(context, FALSE);
+ g_return_val_if_fail(PURPLE_IS_CIPHER(cipher), FALSE);
- cipher = context->cipher;
+ klass = PURPLE_CIPHER_GET_CLASS(cipher);
- if(cipher->ops && cipher->ops->digest)
- return cipher->ops->digest(context, digest, len);
- else {
- purple_debug_warning("cipher", "the %s cipher does not support the digest "
- "operation\n", cipher->name);
- return FALSE;
- }
+ if(klass && klass->digest)
+ return klass->digest(cipher, digest, len);
+ else
+ purple_debug_warning("cipher", "the %s cipher does not implement the "
+ "digest method\n",
+ klass->get_name ? klass->get_name(cipher) : "");
+
+ return FALSE;
}
+/**
+ * purple_cipher_digest_to_str:
+ * @cipher: The cipher to get a digest from
+ * @in_len: The length of the buffer
+ * @digest_s: The return buffer for the string digest
+ * @out_len: The length of the returned value
+ *
+ * Converts a guchar digest into a hex string
+ *
+ * Return Value: TRUE if the digest was successful, FALSE otherwise.
+ */
gboolean
-purple_cipher_context_digest_to_str(PurpleCipherContext *context,
- gchar digest_s[], size_t len)
+purple_cipher_digest_to_str(PurpleCipher *cipher, gchar digest_s[], size_t len)
{
/* 8k is a bit excessive, will tweak later. */
guchar digest[BUF_LEN * 4];
gint n = 0;
size_t digest_size;
- g_return_val_if_fail(context, FALSE);
+ g_return_val_if_fail(cipher, FALSE);
g_return_val_if_fail(digest_s, FALSE);
- digest_size = purple_cipher_context_get_digest_size(context);
+ digest_size = purple_cipher_get_digest_size(cipher);
g_return_val_if_fail(digest_size <= BUF_LEN * 4, FALSE);
- if(!purple_cipher_context_digest(context, digest, sizeof(digest)))
+ if(!purple_cipher_digest(cipher, digest, sizeof(digest)))
return FALSE;
/* Every digest byte occupies 2 chars + the NUL at the end. */
@@ -478,373 +236,240 @@ purple_cipher_context_digest_to_str(PurpleCipherContext *context,
}
size_t
-purple_cipher_context_get_digest_size(PurpleCipherContext *context)
+purple_cipher_get_digest_size(PurpleCipher *cipher)
{
- PurpleCipher *cipher = NULL;
+ PurpleCipherClass *klass = NULL;
- g_return_val_if_fail(context, 0);
+ g_return_val_if_fail(PURPLE_IS_CIPHER(cipher), FALSE);
- cipher = context->cipher;
- g_return_val_if_fail(cipher, 0);
+ klass = PURPLE_CIPHER_GET_CLASS(cipher);
- if(cipher->ops && cipher->ops->get_digest_size)
- return cipher->ops->get_digest_size(context);
- else {
- purple_debug_warning("cipher", "The %s cipher does not support "
- "the get_digest_size operation\n", cipher->name);
- return 0;
- }
+ if(klass && klass->get_digest_size)
+ return klass->get_digest_size(cipher);
+ else
+ purple_debug_warning("cipher", "the %s cipher does not implement the "
+ "get_digest_size method\n",
+ klass->get_name ? klass->get_name(cipher) : "");
+
+ return FALSE;
}
+/**
+ * purple_cipher_encrypt:
+ * @cipher: The cipher
+ * @data: The data to encrypt
+ * @len: The length of the data
+ * @output: The output buffer
+ * @outlen: The len of data that was outputed
+ *
+ * Encrypts data using the cipher
+ *
+ * Return Value: A cipher specific status code
+ */
ssize_t
-purple_cipher_context_encrypt(PurpleCipherContext *context,
- const guchar input[], size_t in_len, guchar output[], size_t out_size)
+purple_cipher_encrypt(PurpleCipher *cipher, const guchar input[],
+ size_t in_len, guchar output[], size_t out_size)
{
- PurpleCipher *cipher = NULL;
+ PurpleCipherClass *klass = NULL;
- g_return_val_if_fail(context != NULL, -1);
+ g_return_val_if_fail(PURPLE_IS_CIPHER(cipher), -1);
g_return_val_if_fail(input != NULL, -1);
g_return_val_if_fail(output != NULL, -1);
g_return_val_if_fail(out_size >= in_len, -1);
- cipher = context->cipher;
- g_return_val_if_fail(cipher, -1);
+ klass = PURPLE_CIPHER_GET_CLASS(cipher);
- if(cipher->ops && cipher->ops->encrypt)
- return cipher->ops->encrypt(context, input, in_len, output, out_size);
- else {
- purple_debug_warning("cipher", "the %s cipher does not support the encrypt"
- "operation\n", cipher->name);
+ if(klass && klass->encrypt)
+ return klass->encrypt(cipher, input, in_len, output, out_size);
+ else
+ purple_debug_warning("cipher", "the %s cipher does not implement the "
+ "encrypt method\n",
+ klass->get_name ? klass->get_name(cipher) : "");
- return -1;
- }
+ return -1;
}
+/**
+ * purple_cipher_decrypt:
+ * @cipher: The cipher
+ * @data: The data to encrypt
+ * @len: The length of the returned value
+ * @output: The output buffer
+ * @outlen: The len of data that was outputed
+ *
+ * Decrypts data using the cipher
+ *
+ * Return Value: A cipher specific status code
+ */
ssize_t
-purple_cipher_context_decrypt(PurpleCipherContext *context,
- const guchar input[], size_t in_len, guchar output[], size_t out_size)
+purple_cipher_decrypt(PurpleCipher *cipher, const guchar input[],
+ size_t in_len, guchar output[], size_t out_size)
{
- PurpleCipher *cipher = NULL;
+ PurpleCipherClass *klass = NULL;
- g_return_val_if_fail(context != NULL, -1);
+ g_return_val_if_fail(PURPLE_IS_CIPHER(cipher), -1);
g_return_val_if_fail(input != NULL, -1);
g_return_val_if_fail(output != NULL, -1);
- cipher = context->cipher;
- g_return_val_if_fail(cipher, -1);
+ klass = PURPLE_CIPHER_GET_CLASS(cipher);
- if(cipher->ops && cipher->ops->decrypt)
- return cipher->ops->decrypt(context, input, in_len, output, out_size);
- else {
- purple_debug_warning("cipher", "the %s cipher does not support the decrypt"
- "operation\n", cipher->name);
+ if(klass && klass->decrypt)
+ return klass->decrypt(cipher, input, in_len, output, out_size);
+ else
+ purple_debug_warning("cipher", "the %s cipher does not implement the "
+ "decrypt method\n",
+ klass->get_name ? klass->get_name(cipher) : "");
- return -1;
- }
+ return -1;
}
+/**
+ * purple_cipher_set_salt:
+ * @cipher: The cipher whose salt to set
+ * @salt: The salt
+ *
+ * Sets the salt on a cipher
+ */
void
-purple_cipher_context_set_salt(PurpleCipherContext *context, const guchar *salt, size_t len) {
- PurpleCipher *cipher = NULL;
+purple_cipher_set_salt(PurpleCipher *cipher, const guchar *salt, size_t len) {
+ PurpleCipherClass *klass = NULL;
- g_return_if_fail(context);
+ g_return_if_fail(PURPLE_IS_CIPHER(cipher));
- cipher = context->cipher;
- g_return_if_fail(cipher);
+ klass = PURPLE_CIPHER_GET_CLASS(cipher);
- if(cipher->ops && cipher->ops->set_salt)
- cipher->ops->set_salt(context, salt, len);
+ if(klass && klass->set_salt)
+ klass->set_salt(cipher, salt, len);
else
- purple_debug_warning("cipher", "the %s cipher does not support the "
- "set_salt operation\n", cipher->name);
-}
-
-size_t
-purple_cipher_context_get_salt_size(PurpleCipherContext *context) {
- PurpleCipher *cipher = NULL;
-
- g_return_val_if_fail(context, -1);
-
- cipher = context->cipher;
- g_return_val_if_fail(cipher, -1);
-
- if(cipher->ops && cipher->ops->get_salt_size)
- return cipher->ops->get_salt_size(context);
- else {
- purple_debug_warning("cipher", "the %s cipher does not support the "
- "get_salt_size operation\n", cipher->name);
-
- return -1;
- }
+ purple_debug_warning("cipher", "the %s cipher does not implement the "
+ "set_salt method\n",
+ klass->get_name ? klass->get_name(cipher) : "");
}
+/**
+ * purple_cipher_set_key:
+ * @cipher: The cipher whose key to set
+ * @key: The key
+ *
+ * Sets the key on a cipher
+ */
void
-purple_cipher_context_set_key(PurpleCipherContext *context, const guchar *key, size_t len) {
- PurpleCipher *cipher = NULL;
+purple_cipher_set_key(PurpleCipher *cipher, const guchar *key, size_t len) {
+ PurpleCipherClass *klass = NULL;
- g_return_if_fail(context);
+ g_return_if_fail(PURPLE_IS_CIPHER(cipher));
- cipher = context->cipher;
- g_return_if_fail(cipher);
+ klass = PURPLE_CIPHER_GET_CLASS(cipher);
- if(cipher->ops && cipher->ops->set_key)
- cipher->ops->set_key(context, key, len);
+ if(klass && klass->set_key)
+ klass->set_key(cipher, key, len);
else
- purple_debug_warning("cipher", "the %s cipher does not support the "
- "set_key operation\n", cipher->name);
+ purple_debug_warning("cipher", "the %s cipher does not implement the "
+ "set_key method\n",
+ klass->get_name ? klass->get_name(cipher) : "");
}
+/**
+ * purple_cipher_get_key_size:
+ * @cipher: The cipher whose key size to get
+ *
+ * Gets the key size for a cipher
+ *
+ * Return Value: The size of the key
+ */
size_t
-purple_cipher_context_get_key_size(PurpleCipherContext *context) {
- PurpleCipher *cipher = NULL;
+purple_cipher_get_key_size(PurpleCipher *cipher) {
+ PurpleCipherClass *klass = NULL;
- g_return_val_if_fail(context, 0);
+ g_return_val_if_fail(PURPLE_IS_CIPHER(cipher), -1);
- cipher = context->cipher;
- g_return_val_if_fail(cipher, 0);
+ klass = PURPLE_CIPHER_GET_CLASS(cipher);
- if (cipher->ops && cipher->ops->get_key_size)
- return cipher->ops->get_key_size(context);
- else {
- purple_debug_warning("cipher", "the %s cipher does not support "
- "the get_key_size operation\n", cipher->name);
+ if(klass && klass->get_key_size)
+ return klass->get_key_size(cipher);
+ else
+ purple_debug_warning("cipher", "the %s cipher does not implement the "
+ "get_key_size method\n",
+ klass->get_name ? klass->get_name(cipher) : "");
- return 0;
- }
+ return -1;
}
+/**
+ * purple_cipher_set_batch_mode:
+ * @cipher: The cipher whose batch mode to set
+ * @mode: The batch mode under which the cipher should operate
+ *
+ * Sets the batch mode of a cipher
+ */
void
-purple_cipher_context_set_batch_mode(PurpleCipherContext *context,
+purple_cipher_set_batch_mode(PurpleCipher *cipher,
PurpleCipherBatchMode mode)
{
- PurpleCipher *cipher = NULL;
+ PurpleCipherClass *klass = NULL;
- g_return_if_fail(context);
+ g_return_if_fail(PURPLE_IS_CIPHER(cipher));
- cipher = context->cipher;
- g_return_if_fail(cipher);
+ klass = PURPLE_CIPHER_GET_CLASS(cipher);
- if(cipher->ops && cipher->ops->set_batch_mode)
- cipher->ops->set_batch_mode(context, mode);
+ if(klass && klass->set_batch_mode)
+ klass->set_batch_mode(cipher, mode);
else
- purple_debug_warning("cipher", "The %s cipher does not support the "
- "set_batch_mode operation\n", cipher->name);
+ purple_debug_warning("cipher", "the %s cipher does not implement the "
+ "set_batch_mode method\n",
+ klass->get_name ? klass->get_name(cipher) : "");
}
+/**
+ * purple_cipher_get_batch_mode:
+ * @cipher: The cipher whose batch mode to get
+ *
+ * Gets the batch mode of a cipher
+ *
+ * Return Value: The batch mode under which the cipher is operating
+ */
PurpleCipherBatchMode
-purple_cipher_context_get_batch_mode(PurpleCipherContext *context)
+purple_cipher_get_batch_mode(PurpleCipher *cipher)
{
- PurpleCipher *cipher = NULL;
-
- g_return_val_if_fail(context, -1);
+ PurpleCipherClass *klass = NULL;
- cipher = context->cipher;
- g_return_val_if_fail(cipher, -1);
+ g_return_val_if_fail(PURPLE_IS_CIPHER(cipher), -1);
- if(cipher->ops && cipher->ops->get_batch_mode)
- return cipher->ops->get_batch_mode(context);
- else {
- purple_debug_warning("cipher", "The %s cipher does not support the "
- "get_batch_mode operation\n", cipher->name);
- return -1;
- }
-}
+ klass = PURPLE_CIPHER_GET_CLASS(cipher);
-size_t
-purple_cipher_context_get_block_size(PurpleCipherContext *context)
-{
- PurpleCipher *cipher = NULL;
-
- g_return_val_if_fail(context, -1);
-
- cipher = context->cipher;
- g_return_val_if_fail(cipher, -1);
-
- if(cipher->ops && cipher->ops->get_block_size)
- return cipher->ops->get_block_size(context);
- else {
- purple_debug_warning("cipher", "The %s cipher does not support the "
- "get_block_size operation\n", cipher->name);
- return -1;
- }
-}
-
-void
-purple_cipher_context_set_data(PurpleCipherContext *context, gpointer data) {
- g_return_if_fail(context);
-
- context->data = data;
-}
-
-gpointer
-purple_cipher_context_get_data(PurpleCipherContext *context) {
- g_return_val_if_fail(context, NULL);
+ if(klass && klass->get_batch_mode)
+ return klass->get_batch_mode(cipher);
+ else
+ purple_debug_warning("cipher", "the %s cipher does not implement the "
+ "get_batch_mode method\n",
+ klass->get_name ? klass->get_name(cipher) : "");
- return context->data;
+ return -1;
}
-gchar *purple_cipher_http_digest_calculate_session_key(
- const gchar *algorithm,
- const gchar *username,
- const gchar *realm,
- const gchar *password,
- const gchar *nonce,
- const gchar *client_nonce)
+/**
+ * purple_cipher_get_block_size:
+ * @cipher: The cipher whose block size to get
+ *
+ * Gets the block size of a cipher
+ *
+ * Return Value: The block size of the cipher
+ */
+size_t
+purple_cipher_get_block_size(PurpleCipher *cipher)
{
- PurpleCipher *cipher;
- PurpleCipherContext *context;
- gchar hash[33]; /* We only support MD5. */
-
- g_return_val_if_fail(username != NULL, NULL);
- g_return_val_if_fail(realm != NULL, NULL);
- g_return_val_if_fail(password != NULL, NULL);
- g_return_val_if_fail(nonce != NULL, NULL);
-
- /* Check for a supported algorithm. */
- g_return_val_if_fail(algorithm == NULL ||
- *algorithm == '\0' ||
- g_ascii_strcasecmp(algorithm, "MD5") ||
- g_ascii_strcasecmp(algorithm, "MD5-sess"), NULL);
-
- cipher = purple_ciphers_find_cipher("md5");
- g_return_val_if_fail(cipher != NULL, NULL);
-
- context = purple_cipher_context_new(cipher, NULL);
-
- purple_cipher_context_append(context, (guchar *)username, strlen(username));
- purple_cipher_context_append(context, (guchar *)":", 1);
- purple_cipher_context_append(context, (guchar *)realm, strlen(realm));
- purple_cipher_context_append(context, (guchar *)":", 1);
- purple_cipher_context_append(context, (guchar *)password, strlen(password));
-
- if (algorithm != NULL && !g_ascii_strcasecmp(algorithm, "MD5-sess"))
- {
- guchar digest[16];
-
- if (client_nonce == NULL)
- {
- purple_cipher_context_destroy(context);
- purple_debug_error("cipher", "Required client_nonce missing for MD5-sess digest calculation.\n");
- return NULL;
- }
-
- purple_cipher_context_digest(context, digest, sizeof(digest));
- purple_cipher_context_destroy(context);
-
- context = purple_cipher_context_new(cipher, NULL);
- purple_cipher_context_append(context, digest, sizeof(digest));
- purple_cipher_context_append(context, (guchar *)":", 1);
- purple_cipher_context_append(context, (guchar *)nonce, strlen(nonce));
- purple_cipher_context_append(context, (guchar *)":", 1);
- purple_cipher_context_append(context, (guchar *)client_nonce, strlen(client_nonce));
- }
-
- purple_cipher_context_digest_to_str(context, hash, sizeof(hash));
- purple_cipher_context_destroy(context);
+ PurpleCipherClass *klass = NULL;
- return g_strdup(hash);
-}
-
-gchar *purple_cipher_http_digest_calculate_response(
- const gchar *algorithm,
- const gchar *method,
- const gchar *digest_uri,
- const gchar *qop,
- const gchar *entity,
- const gchar *nonce,
- const gchar *nonce_count,
- const gchar *client_nonce,
- const gchar *session_key)
-{
- PurpleCipher *cipher;
- PurpleCipherContext *context;
- static gchar hash2[33]; /* We only support MD5. */
-
- g_return_val_if_fail(method != NULL, NULL);
- g_return_val_if_fail(digest_uri != NULL, NULL);
- g_return_val_if_fail(nonce != NULL, NULL);
- g_return_val_if_fail(session_key != NULL, NULL);
-
- /* Check for a supported algorithm. */
- g_return_val_if_fail(algorithm == NULL ||
- *algorithm == '\0' ||
- g_ascii_strcasecmp(algorithm, "MD5") ||
- g_ascii_strcasecmp(algorithm, "MD5-sess"), NULL);
-
- /* Check for a supported "quality of protection". */
- g_return_val_if_fail(qop == NULL ||
- *qop == '\0' ||
- g_ascii_strcasecmp(qop, "auth") ||
- g_ascii_strcasecmp(qop, "auth-int"), NULL);
-
- cipher = purple_ciphers_find_cipher("md5");
- g_return_val_if_fail(cipher != NULL, NULL);
-
- context = purple_cipher_context_new(cipher, NULL);
-
- purple_cipher_context_append(context, (guchar *)method, strlen(method));
- purple_cipher_context_append(context, (guchar *)":", 1);
- purple_cipher_context_append(context, (guchar *)digest_uri, strlen(digest_uri));
-
- if (qop != NULL && !g_ascii_strcasecmp(qop, "auth-int"))
- {
- PurpleCipherContext *context2;
- gchar entity_hash[33];
-
- if (entity == NULL)
- {
- purple_cipher_context_destroy(context);
- purple_debug_error("cipher", "Required entity missing for auth-int digest calculation.\n");
- return NULL;
- }
-
- context2 = purple_cipher_context_new(cipher, NULL);
- purple_cipher_context_append(context2, (guchar *)entity, strlen(entity));
- purple_cipher_context_digest_to_str(context2, entity_hash, sizeof(entity_hash));
- purple_cipher_context_destroy(context2);
-
- purple_cipher_context_append(context, (guchar *)":", 1);
- purple_cipher_context_append(context, (guchar *)entity_hash, strlen(entity_hash));
- }
+ g_return_val_if_fail(PURPLE_IS_CIPHER(cipher), -1);
- purple_cipher_context_digest_to_str(context, hash2, sizeof(hash2));
- purple_cipher_context_destroy(context);
-
- context = purple_cipher_context_new(cipher, NULL);
- purple_cipher_context_append(context, (guchar *)session_key, strlen(session_key));
- purple_cipher_context_append(context, (guchar *)":", 1);
- purple_cipher_context_append(context, (guchar *)nonce, strlen(nonce));
- purple_cipher_context_append(context, (guchar *)":", 1);
-
- if (qop != NULL && *qop != '\0')
- {
- if (nonce_count == NULL)
- {
- purple_cipher_context_destroy(context);
- purple_debug_error("cipher", "Required nonce_count missing for digest calculation.\n");
- return NULL;
- }
-
- if (client_nonce == NULL)
- {
- purple_cipher_context_destroy(context);
- purple_debug_error("cipher", "Required client_nonce missing for digest calculation.\n");
- return NULL;
- }
-
- purple_cipher_context_append(context, (guchar *)nonce_count, strlen(nonce_count));
- purple_cipher_context_append(context, (guchar *)":", 1);
- purple_cipher_context_append(context, (guchar *)client_nonce, strlen(client_nonce));
- purple_cipher_context_append(context, (guchar *)":", 1);
-
- purple_cipher_context_append(context, (guchar *)qop, strlen(qop));
-
- purple_cipher_context_append(context, (guchar *)":", 1);
- }
+ klass = PURPLE_CIPHER_GET_CLASS(cipher);
- purple_cipher_context_append(context, (guchar *)hash2, strlen(hash2));
- purple_cipher_context_digest_to_str(context, hash2, sizeof(hash2));
- purple_cipher_context_destroy(context);
+ if(klass && klass->get_block_size)
+ return klass->get_block_size(cipher);
+ else
+ purple_debug_warning("cipher", "the %s cipher does not implement the "
+ "get_block_size method\n",
+ klass->get_name ? klass->get_name(cipher) : "");
- return g_strdup(hash2);
+ return -1;
}
diff --git a/libpurple/cipher.h b/libpurple/cipher.h
index 249f526856..6e52734112 100644
--- a/libpurple/cipher.h
+++ b/libpurple/cipher.h
@@ -28,110 +28,96 @@
#define PURPLE_CIPHER_H
#include <glib.h>
+#include <glib-object.h>
#include <string.h>
-#define PURPLE_CIPHER(obj) ((PurpleCipher *)(obj)) /**< PurpleCipher typecast helper */
-#define PURPLE_CIPHER_OPS(obj) ((PurpleCipherOps *)(obj)) /**< PurpleCipherInfo typecase helper */
-#define PURPLE_CIPHER_CONTEXT(obj) ((PurpleCipherContext *)(obj)) /**< PurpleCipherContext typecast helper */
+#include "internal.h"
-typedef struct _PurpleCipher PurpleCipher; /**< A handle to a PurpleCipher */
-typedef struct _PurpleCipherOps PurpleCipherOps; /**< Ops for a PurpleCipher */
-typedef struct _PurpleCipherContext PurpleCipherContext; /**< A context for a PurpleCipher */
+#define PURPLE_TYPE_CIPHER (purple_cipher_get_type())
+#define PURPLE_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_CIPHER, PurpleCipher))
+#define PURPLE_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_CIPHER, PurpleCipherClass))
+#define PURPLE_IS_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_CIPHER))
+#define PURPLE_IS_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_CIPHER))
+#define PURPLE_CIPHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_CIPHER, PurpleCipherClass))
+
+typedef struct _PurpleCipher PurpleCipher;
+typedef struct _PurpleCipherClass PurpleCipherClass;
/**
+ * PurpleCipherBatchMode:
+ * @PURPLE_CIPHER_BATCH_MODE_ECB: Electronic Codebook Mode
+ * @PURPLE_CIPHER_BATCH_MODE_CBC: Cipher Block Chaining Mode
+ *
* Modes for batch encrypters
*/
-typedef enum {
- PURPLE_CIPHER_BATCH_MODE_ECB,
- PURPLE_CIPHER_BATCH_MODE_CBC
+typedef enum {
+ PURPLE_CIPHER_BATCH_MODE_ECB, /*< nick=ECB Batch Mode >*/
+ PURPLE_CIPHER_BATCH_MODE_CBC /*< nick=CBC Batch Mode >*/
} PurpleCipherBatchMode;
/**
- * The operation flags for a cipher
+ * PurpleCipher:
+ *
+ * Purple Cipher is an opaque data structure and should not be used directly.
*/
-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 */
- PURPLE_CIPHER_CAPS_RESET = 1 << 4, /**< Reset flag */
- PURPLE_CIPHER_CAPS_RESET_STATE = 1 << 5, /**< Reset state flag */
- PURPLE_CIPHER_CAPS_UNINIT = 1 << 6, /**< Uninit flag */
- PURPLE_CIPHER_CAPS_SET_IV = 1 << 7, /**< Set IV flag */
- PURPLE_CIPHER_CAPS_APPEND = 1 << 8, /**< Append flag */
- PURPLE_CIPHER_CAPS_DIGEST = 1 << 9, /**< Digest flag */
- PURPLE_CIPHER_CAPS_GET_DIGEST_SIZE = 1 << 10, /**< The get digest size flag */
- PURPLE_CIPHER_CAPS_ENCRYPT = 1 << 11, /**< Encrypt flag */
- PURPLE_CIPHER_CAPS_DECRYPT = 1 << 12, /**< Decrypt flag */
- PURPLE_CIPHER_CAPS_SET_SALT = 1 << 13, /**< Set salt flag */
- PURPLE_CIPHER_CAPS_GET_SALT_SIZE = 1 << 14, /**< Get salt size flag */
- PURPLE_CIPHER_CAPS_SET_KEY = 1 << 15, /**< Set key flag */
- PURPLE_CIPHER_CAPS_GET_KEY_SIZE = 1 << 16, /**< Get key size flag */
- PURPLE_CIPHER_CAPS_SET_BATCH_MODE = 1 << 17, /**< Set batch mode flag */
- PURPLE_CIPHER_CAPS_GET_BATCH_MODE = 1 << 18, /**< Get batch mode flag */
- PURPLE_CIPHER_CAPS_GET_BLOCK_SIZE = 1 << 19, /**< The get block size flag */
- PURPLE_CIPHER_CAPS_UNKNOWN = 1 << 20 /**< Unknown */
-} PurpleCipherCaps;
+struct _PurpleCipher {
+ /*< private >*/
+ GObject gparent;
+};
/**
- * The operations of a cipher. Every cipher must implement one of these.
+ * PurpleCipherClass:
+ *
+ * The base class for all #PurpleCipher's.
*/
-struct _PurpleCipherOps {
- /** The set option function */
- void (*set_option)(PurpleCipherContext *context, const gchar *name, void *value);
-
- /** The get option function */
- void *(*get_option)(PurpleCipherContext *context, const gchar *name);
-
- /** The init function */
- void (*init)(PurpleCipherContext *context, void *extra);
+struct _PurpleCipherClass {
+ /*< private >*/
+ GObjectClass parent_class;
/** The reset function */
- void (*reset)(PurpleCipherContext *context, void *extra);
+ void (*reset)(PurpleCipher *cipher);
/** The reset state function */
- void (*reset_state)(PurpleCipherContext *context, void *extra);
-
- /** The uninit function */
- void (*uninit)(PurpleCipherContext *context);
+ void (*reset_state)(PurpleCipher *cipher);
/** The set initialization vector function */
- void (*set_iv)(PurpleCipherContext *context, guchar *iv, size_t len);
+ void (*set_iv)(PurpleCipher *cipher, guchar *iv, size_t len);
/** The append data function */
- void (*append)(PurpleCipherContext *context, const guchar *data, size_t len);
+ void (*append)(PurpleCipher *cipher, const guchar *data, size_t len);
/** The digest function */
- gboolean (*digest)(PurpleCipherContext *context, guchar digest[], size_t len);
+ gboolean (*digest)(PurpleCipher *cipher, guchar digest[], size_t len);
/** The get digest size function */
- size_t (*get_digest_size)(PurpleCipherContext *context);
+ size_t (*get_digest_size)(PurpleCipher *cipher);
/** The encrypt function */
- ssize_t (*encrypt)(PurpleCipherContext *context, const guchar input[], size_t in_len, guchar output[], size_t out_size);
+ ssize_t (*encrypt)(PurpleCipher *cipher, const guchar input[], size_t in_len, guchar output[], size_t out_size);
/** The decrypt function */
- ssize_t (*decrypt)(PurpleCipherContext *context, const guchar input[], size_t in_len, guchar output[], size_t out_size);
+ ssize_t (*decrypt)(PurpleCipher *cipher, const guchar input[], size_t in_len, guchar output[], size_t out_size);
/** The set salt function */
- void (*set_salt)(PurpleCipherContext *context, const guchar *salt, size_t len);
-
- /** The get salt size function */
- size_t (*get_salt_size)(PurpleCipherContext *context);
+ void (*set_salt)(PurpleCipher *cipher, const guchar *salt, size_t len);
/** The set key function */
- void (*set_key)(PurpleCipherContext *context, const guchar *key, size_t len);
+ void (*set_key)(PurpleCipher *cipher, const guchar *key, size_t len);
/** The get key size function */
- size_t (*get_key_size)(PurpleCipherContext *context);
+ size_t (*get_key_size)(PurpleCipher *cipher);
/** The set batch mode function */
- void (*set_batch_mode)(PurpleCipherContext *context, PurpleCipherBatchMode mode);
+ void (*set_batch_mode)(PurpleCipher *cipher, PurpleCipherBatchMode mode);
/** The get batch mode function */
- PurpleCipherBatchMode (*get_batch_mode)(PurpleCipherContext *context);
+ PurpleCipherBatchMode (*get_batch_mode)(PurpleCipher *cipher);
/** The get block size function */
- size_t (*get_block_size)(PurpleCipherContext *context);
+ size_t (*get_block_size)(PurpleCipher *cipher);
+
+ /** The get cipher name function */
+ const gchar* (*get_name)(PurpleCipher *cipher);
void (*_purple_reserved1)(void);
void (*_purple_reserved2)(void);
@@ -147,223 +133,88 @@ G_BEGIN_DECLS
/*@{*/
/**
- * Gets a cipher's name
- *
- * @param cipher The cipher handle
- *
- * @return The cipher's name
- */
-const gchar *purple_cipher_get_name(PurpleCipher *cipher);
-
-/**
- * Gets a cipher's capabilities
- *
- * @param cipher The cipher handle
- *
- * @return The cipher's info
- */
-guint purple_cipher_get_capabilities(PurpleCipher *cipher);
-
-/**
- * Gets a digest from a cipher
- *
- * @param name The cipher's name
- * @param data The data to hash
- * @param data_len The length of the data
- * @param digest The returned digest
- * @param out_size The size of digest buffer
- *
- * @return The count of bytes written, or -1 if failed
+ * Returns the GType for the Cipher object.
*/
-ssize_t purple_cipher_digest_region(const gchar *name, const guchar *data, size_t data_len, guchar digest[], size_t out_size);
-
-/*@}*/
-/******************************************************************************/
-/** @name PurpleCiphers API */
-/******************************************************************************/
-/*@{*/
+GType purple_cipher_get_type(void);
/**
- * Finds a cipher by it's name
- *
- * @param name The name of the cipher to find
- *
- * @return The cipher handle or @c NULL
- */
-PurpleCipher *purple_ciphers_find_cipher(const gchar *name);
-
-/**
- * Registers a cipher as a usable cipher
- *
- * @param name The name of the new cipher
- * @param ops The cipher ops to register
- *
- * @return The handle to the new cipher or @c NULL if it failed
- */
-PurpleCipher *purple_ciphers_register_cipher(const gchar *name, PurpleCipherOps *ops);
-
-/**
- * Unregisters a cipher
- *
- * @param cipher The cipher handle to unregister
- *
- * @return Whether or not the cipher was successfully unloaded
- */
-gboolean purple_ciphers_unregister_cipher(PurpleCipher *cipher);
-
-/**
- * Gets the list of ciphers
- *
- * @return The list of available ciphers
- * @note This list should not be modified, it is owned by the cipher core
- */
-GList *purple_ciphers_get_ciphers(void);
-
-/*@}*/
-/******************************************************************************/
-/** @name PurpleCipher Subsystem API */
-/******************************************************************************/
-/*@{*/
-
-/**
- * Gets the handle to the cipher subsystem
- *
- * @return The handle to the cipher subsystem
- */
-gpointer purple_ciphers_get_handle(void);
-
-/**
- * Initializes the cipher core
- */
-void purple_ciphers_init(void);
-
-/**
- * Uninitializes the cipher core
- */
-void purple_ciphers_uninit(void);
-
-/*@}*/
-/******************************************************************************/
-/** @name PurpleCipherContext API */
-/******************************************************************************/
-/*@{*/
-
-/**
- * Sets the value an option on a cipher context
- *
- * @param context The cipher context
- * @param name The name of the option
- * @param value The value to set
- */
-void purple_cipher_context_set_option(PurpleCipherContext *context, const gchar *name, gpointer value);
-
-/**
- * Gets the vale of an option on a cipher context
- *
- * @param context The cipher context
- * @param name The name of the option
- * @return The value of the option
- */
-gpointer purple_cipher_context_get_option(PurpleCipherContext *context, const gchar *name);
-
-/**
- * Creates a new cipher context and initializes it
- *
- * @param cipher The cipher to use
- * @param extra Extra data for the specific cipher
- *
- * @return The new cipher context
- */
-PurpleCipherContext *purple_cipher_context_new(PurpleCipher *cipher, void *extra);
-
-/**
- * Creates a new cipher context by the cipher name and initializes it
+ * Gets a cipher's name
*
- * @param name The cipher's name
- * @param extra Extra data for the specific cipher
+ * @param cipher The cipher
*
- * @return The new cipher context
+ * @return The cipher's name
*/
-PurpleCipherContext *purple_cipher_context_new_by_name(const gchar *name, void *extra);
+const gchar *purple_cipher_get_name(PurpleCipher *cipher);
/**
- * Resets a cipher context to it's default value
+ * Resets a cipher to it's default value
* @note If you have set an IV you will have to set it after resetting
*
- * @param context The context to reset
- * @param extra Extra data for the specific cipher
+ * @param cipher The cipher
*/
-void purple_cipher_context_reset(PurpleCipherContext *context, gpointer extra);
+void purple_cipher_reset(PurpleCipher *cipher);
/**
* Resets a cipher state to it's default value, but doesn't touch stateless
* configuration.
*
- * That means, IV and digest context will be wiped out, but keys, ops or salt
+ * That means, IV and digest will be wiped out, but keys, ops or salt
* will remain untouched.
*
- * @param context The context to reset
- * @param extra Extra data for the specific cipher
- */
-void purple_cipher_context_reset_state(PurpleCipherContext *context, gpointer extra);
-
-/**
- * Destorys a cipher context and deinitializes it
- *
- * @param context The cipher context to destory
+ * @param cipher The cipher
*/
-void purple_cipher_context_destroy(PurpleCipherContext *context);
+void purple_cipher_reset_state(PurpleCipher *cipher);
/**
- * Sets the initialization vector for a context
- * @note This should only be called right after a cipher context is created or reset
+ * Sets the initialization vector for a cipher
+ * @note This should only be called right after a cipher is created or reset
*
- * @param context The context to set the IV to
+ * @param cipher The cipher
* @param iv The initialization vector to set
* @param len The len of the IV
*/
-void purple_cipher_context_set_iv(PurpleCipherContext *context, guchar *iv, size_t len);
+void purple_cipher_set_iv(PurpleCipher *cipher, guchar *iv, size_t len);
/**
- * Appends data to the context
+ * Appends data to the cipher context
*
- * @param context The context to append data to
+ * @param cipher The cipher
* @param data The data to append
* @param len The length of the data
*/
-void purple_cipher_context_append(PurpleCipherContext *context, const guchar *data, size_t len);
+void purple_cipher_append(PurpleCipher *cipher, const guchar *data, size_t len);
/**
- * Digests a context
+ * Digests a cipher context
*
- * @param context The context to digest
+ * @param cipher The cipher
* @param digest The return buffer for the digest
* @param len The length of the buffer
*/
-gboolean purple_cipher_context_digest(PurpleCipherContext *context, guchar digest[], size_t len);
+gboolean purple_cipher_digest(PurpleCipher *cipher, guchar digest[], size_t len);
/**
* Converts a guchar digest into a hex string
*
- * @param context The context to get a digest from
+ * @param cipher The cipher
* @param digest_s The return buffer for the string digest
* @param len The length of the buffer
*/
-gboolean purple_cipher_context_digest_to_str(PurpleCipherContext *context, gchar digest_s[], size_t len);
+gboolean purple_cipher_digest_to_str(PurpleCipher *cipher, gchar digest_s[], size_t len);
/**
- * Gets the digest size of a context
+ * Gets the digest size of a cipher
*
- * @param context The context whose digest size to get
+ * @param cipher The cipher whose digest size to get
*
- * @return The digest size of the context
+ * @return The digest size of the cipher
*/
-size_t purple_cipher_context_get_digest_size(PurpleCipherContext *context);
+size_t purple_cipher_get_digest_size(PurpleCipher *cipher);
/**
- * Encrypts data using the context
+ * Encrypts data using the cipher
*
- * @param context The context
+ * @param cipher The cipher
* @param input The data to encrypt
* @param in_len The length of the data
* @param output The output buffer
@@ -371,12 +222,12 @@ size_t purple_cipher_context_get_digest_size(PurpleCipherContext *context);
*
* @return A length of data that was outputed or -1, if failed
*/
-ssize_t purple_cipher_context_encrypt(PurpleCipherContext *context, const guchar input[], size_t in_len, guchar output[], size_t out_size);
+ssize_t purple_cipher_encrypt(PurpleCipher *cipher, const guchar input[], size_t in_len, guchar output[], size_t out_size);
/**
- * Decrypts data using the context
+ * Decrypts data using the cipher
*
- * @param context The context
+ * @param cipher The cipher
* @param input The data to encrypt
* @param in_len The length of the returned value
* @param output The output buffer
@@ -384,135 +235,61 @@ ssize_t purple_cipher_context_encrypt(PurpleCipherContext *context, const guchar
*
* @return A length of data that was outputed or -1, if failed
*/
-ssize_t purple_cipher_context_decrypt(PurpleCipherContext *context, const guchar input[], size_t in_len, guchar output[], size_t out_size);
+ssize_t purple_cipher_decrypt(PurpleCipher *cipher, const guchar input[], size_t in_len, guchar output[], size_t out_size);
/**
- * Sets the salt on a context
+ * Sets the salt on a cipher
*
- * @param context The context whose salt to set
+ * @param cipher The cipher whose salt to set
* @param salt The salt
* @param len The length of the salt
*/
-void purple_cipher_context_set_salt(PurpleCipherContext *context, const guchar *salt, size_t len);
+void purple_cipher_set_salt(PurpleCipher *cipher, const guchar *salt, size_t len);
/**
- * Gets the size of the salt if the cipher supports it
- *
- * @param context The context whose salt size to get
+ * Sets the key on a cipher
*
- * @return The size of the salt
- */
-size_t purple_cipher_context_get_salt_size(PurpleCipherContext *context);
-
-/**
- * Sets the key on a context
- *
- * @param context The context whose key to set
+ * @param cipher The cipher whose key to set
* @param key The key
* @param len The size of the key
*/
-void purple_cipher_context_set_key(PurpleCipherContext *context, const guchar *key, size_t len);
+void purple_cipher_set_key(PurpleCipher *cipher, const guchar *key, size_t len);
/**
* Gets the size of the key if the cipher supports it
*
- * @param context The context whose key size to get
+ * @param cipher The cipher whose key size to get
*
* @return The size of the key
*/
-size_t purple_cipher_context_get_key_size(PurpleCipherContext *context);
+size_t purple_cipher_get_key_size(PurpleCipher *cipher);
/**
- * Sets the batch mode of a context
+ * Sets the batch mode of a cipher
*
- * @param context The context whose batch mode to set
+ * @param cipher The cipher whose batch mode to set
* @param mode The batch mode under which the cipher should operate
*
*/
-void purple_cipher_context_set_batch_mode(PurpleCipherContext *context, PurpleCipherBatchMode mode);
+void purple_cipher_set_batch_mode(PurpleCipher *cipher, PurpleCipherBatchMode mode);
/**
- * Gets the batch mode of a context
+ * Gets the batch mode of a cipher
*
- * @param context The context whose batch mode to get
+ * @param cipher The cipher whose batch mode to get
*
* @return The batch mode under which the cipher is operating
*/
-PurpleCipherBatchMode purple_cipher_context_get_batch_mode(PurpleCipherContext *context);
-
-/**
- * Gets the block size of a context
- *
- * @param context The context whose block size to get
- *
- * @return The block size of the context
- */
-size_t purple_cipher_context_get_block_size(PurpleCipherContext *context);
+PurpleCipherBatchMode purple_cipher_get_batch_mode(PurpleCipher *cipher);
/**
- * Sets the cipher data for a context
+ * Gets the block size of a cipher
*
- * @param context The context whose cipher data to set
- * @param data The cipher data to set
- */
-void purple_cipher_context_set_data(PurpleCipherContext *context, gpointer data);
-
-/**
- * Gets the cipher data for a context
+ * @param cipher The cipher whose block size to get
*
- * @param context The context whose cipher data to get
- *
- * @return The cipher data
- */
-gpointer purple_cipher_context_get_data(PurpleCipherContext *context);
-
-/*@}*/
-/*****************************************************************************/
-/** @name Purple Cipher HTTP Digest Helper Functions */
-/*****************************************************************************/
-/*@{*/
-
-/**
- * Calculates a session key for HTTP Digest authentation
- *
- * See RFC 2617 for more information.
- *
- * @param algorithm The hash algorithm to use
- * @param username The username provided by the user
- * @param realm The authentication realm provided by the server
- * @param password The password provided by the user
- * @param nonce The nonce provided by the server
- * @param client_nonce The nonce provided by the client
- *
- * @return The session key, or @c NULL if an error occurred.
- */
-gchar *purple_cipher_http_digest_calculate_session_key(
- const gchar *algorithm, const gchar *username,
- const gchar *realm, const gchar *password,
- const gchar *nonce, const gchar *client_nonce);
-
-/** Calculate a response for HTTP Digest authentication
- *
- * See RFC 2617 for more information.
- *
- * @param algorithm The hash algorithm to use
- * @param method The HTTP method in use
- * @param digest_uri The URI from the initial request
- * @param qop The "quality of protection"
- * @param entity The entity body
- * @param nonce The nonce provided by the server
- * @param nonce_count The nonce count
- * @param client_nonce The nonce provided by the client
- * @param session_key The session key from purple_cipher_http_digest_calculate_session_key()
- *
- * @return The hashed response, or @c NULL if an error occurred.
+ * @return The block size of the cipher
*/
-gchar *purple_cipher_http_digest_calculate_response(
- const gchar *algorithm, const gchar *method,
- const gchar *digest_uri, const gchar *qop,
- const gchar *entity, const gchar *nonce,
- const gchar *nonce_count, const gchar *client_nonce,
- const gchar *session_key);
+size_t purple_cipher_get_block_size(PurpleCipher *cipher);
/*@}*/
diff --git a/libpurple/ciphers/Makefile.am b/libpurple/ciphers/Makefile.am
index aa27bf9450..40a6cf8c7a 100644
--- a/libpurple/ciphers/Makefile.am
+++ b/libpurple/ciphers/Makefile.am
@@ -1,24 +1,23 @@
noinst_LTLIBRARIES=libpurple-ciphers.la
-# XXX: cipher.lo won't be updated after a change in cipher files
if USE_NSS
-AES_SOURCE = aes.c
+AES_SOURCE = aescipher.c
endif
if USE_GNUTLS
-AES_SOURCE = aes.c
+AES_SOURCE = aescipher.c
endif
libpurple_ciphers_la_SOURCES=\
$(AES_SOURCE) \
- des.c \
- gchecksum.c \
- hmac.c \
- md4.c \
- pbkdf2.c \
- rc4.c
-
-noinst_HEADERS =\
- ciphers.h
+ descipher.c \
+ des3cipher.c \
+ hmaccipher.c \
+ md4hash.c \
+ md5hash.c \
+ pbkdf2cipher.c \
+ rc4cipher.c \
+ sha1hash.c \
+ sha256hash.c
AM_CPPFLAGS = \
-I$(top_srcdir)/libpurple \
diff --git a/libpurple/ciphers/aes.c b/libpurple/ciphers/aes.c
deleted file mode 100644
index f085fc5d7b..0000000000
--- a/libpurple/ciphers/aes.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * 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
- *
- * Written by Tomek Wasilczyk <tomkiewicz@cpw.pidgin.im>
- */
-
-#include "internal.h"
-#include "cipher.h"
-#include "ciphers.h"
-#include "debug.h"
-
-#if defined(HAVE_GNUTLS)
-# define PURPLE_AES_USE_GNUTLS 1
-# include <gnutls/gnutls.h>
-# include <gnutls/crypto.h>
-#elif defined(HAVE_NSS)
-# define PURPLE_AES_USE_NSS 1
-# include <nss.h>
-# include <pk11pub.h>
-# include <prerror.h>
-#else
-# error "No GnuTLS or NSS support"
-#endif
-
-/* 128bit */
-#define PURPLE_AES_BLOCK_SIZE 16
-
-typedef struct
-{
- guchar iv[PURPLE_AES_BLOCK_SIZE];
- guchar key[32];
- guint key_size;
- gboolean failure;
-} AESContext;
-
-typedef gboolean (*purple_aes_crypt_func)(
- const guchar *input, guchar *output, size_t len,
- guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size);
-
-static void
-purple_aes_init(PurpleCipherContext *context, void *extra)
-{
- AESContext *ctx_data;
-
- ctx_data = g_new0(AESContext, 1);
- purple_cipher_context_set_data(context, ctx_data);
-
- purple_cipher_context_reset(context, extra);
-}
-
-static void
-purple_aes_uninit(PurpleCipherContext *context)
-{
- AESContext *ctx_data;
-
- purple_cipher_context_reset(context, NULL);
-
- ctx_data = purple_cipher_context_get_data(context);
- g_free(ctx_data);
- purple_cipher_context_set_data(context, NULL);
-}
-
-static void
-purple_aes_reset(PurpleCipherContext *context, void *extra)
-{
- AESContext *ctx_data = purple_cipher_context_get_data(context);
-
- g_return_if_fail(ctx_data != NULL);
-
- memset(ctx_data->iv, 0, sizeof(ctx_data->iv));
- memset(ctx_data->key, 0, sizeof(ctx_data->key));
- ctx_data->key_size = 32; /* 256bit */
- ctx_data->failure = FALSE;
-}
-
-static void
-purple_aes_set_option(PurpleCipherContext *context, const gchar *name,
- void *value)
-{
- AESContext *ctx_data = purple_cipher_context_get_data(context);
-
- purple_debug_error("cipher-aes", "set_option not supported\n");
- ctx_data->failure = TRUE;
-}
-
-static void
-purple_aes_set_iv(PurpleCipherContext *context, guchar *iv, size_t len)
-{
- AESContext *ctx_data = purple_cipher_context_get_data(context);
-
- if ((len > 0 && iv == NULL) ||
- (len != 0 && len != sizeof(ctx_data->iv))) {
- purple_debug_error("cipher-aes", "invalid IV length\n");
- ctx_data->failure = TRUE;
- return;
- }
-
- if (len == 0)
- memset(ctx_data->iv, 0, sizeof(ctx_data->iv));
- else
- memcpy(ctx_data->iv, iv, len);
-}
-
-static void
-purple_aes_set_key(PurpleCipherContext *context, const guchar *key, size_t len)
-{
- AESContext *ctx_data = purple_cipher_context_get_data(context);
-
- if ((len > 0 && key == NULL) ||
- (len != 0 && len != 16 && len != 24 && len != 32)) {
- purple_debug_error("cipher-aes", "invalid key length\n");
- ctx_data->failure = TRUE;
- return;
- }
-
- ctx_data->key_size = len;
- memset(ctx_data->key, 0, sizeof(ctx_data->key));
- if (len > 0)
- memcpy(ctx_data->key, key, len);
-}
-
-static guchar *
-purple_aes_pad_pkcs7(const guchar input[], size_t in_len, size_t *out_len)
-{
- int padding_len, total_len;
- guchar *padded;
-
- g_return_val_if_fail(input != NULL, NULL);
- g_return_val_if_fail(out_len != NULL, NULL);
-
- padding_len = PURPLE_AES_BLOCK_SIZE - (in_len % PURPLE_AES_BLOCK_SIZE);
- total_len = in_len + padding_len;
- g_assert((total_len % PURPLE_AES_BLOCK_SIZE) == 0);
-
- padded = g_new(guchar, total_len);
- *out_len = total_len;
-
- memcpy(padded, input, in_len);
- memset(padded + in_len, padding_len, padding_len);
-
- return padded;
-}
-
-static ssize_t
-purple_aes_unpad_pkcs7(guchar input[], size_t in_len)
-{
- guchar padding_len, i;
- size_t out_len;
-
- g_return_val_if_fail(input != NULL, -1);
- g_return_val_if_fail(in_len > 0, -1);
-
- padding_len = input[in_len - 1];
- if (padding_len == 0 || padding_len > PURPLE_AES_BLOCK_SIZE ||
- padding_len > in_len) {
- purple_debug_warning("cipher-aes",
- "Invalid padding length: %d (total %" G_GSIZE_FORMAT ") - "
- "most probably, the key was invalid\n",
- padding_len, in_len);
- return -1;
- }
-
- out_len = in_len - padding_len;
- for (i = 0; i < padding_len; i++) {
- if (input[out_len + i] != padding_len) {
- purple_debug_warning("cipher-aes",
- "Padding doesn't match at pos %d (found %02x, "
- "expected %02x) - "
- "most probably, the key was invalid\n",
- i, input[out_len + i], padding_len);
- return -1;
- }
- }
-
- memset(input + out_len, 0, padding_len);
- return out_len;
-}
-
-#ifdef PURPLE_AES_USE_GNUTLS
-
-static gnutls_cipher_hd_t
-purple_aes_crypt_gnutls_init(guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32],
- guint key_size)
-{
- gnutls_cipher_hd_t handle;
- gnutls_cipher_algorithm_t algorithm;
- gnutls_datum_t key_info, iv_info;
- int ret;
-
- if (key_size == 16)
- algorithm = GNUTLS_CIPHER_AES_128_CBC;
- else if (key_size == 24)
- algorithm = GNUTLS_CIPHER_AES_192_CBC;
- else if (key_size == 32)
- algorithm = GNUTLS_CIPHER_AES_256_CBC;
- else
- g_return_val_if_reached(NULL);
-
- key_info.data = key;
- key_info.size = key_size;
-
- iv_info.data = iv;
- iv_info.size = PURPLE_AES_BLOCK_SIZE;
-
- ret = gnutls_cipher_init(&handle, algorithm, &key_info, &iv_info);
- if (ret != 0) {
- purple_debug_error("cipher-aes",
- "gnutls_cipher_init failed: %d\n", ret);
- return NULL;
- }
-
- return handle;
-}
-
-static gboolean
-purple_aes_encrypt_gnutls(const guchar *input, guchar *output, size_t len,
- guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size)
-{
- gnutls_cipher_hd_t handle;
- int ret;
-
- handle = purple_aes_crypt_gnutls_init(iv, key, key_size);
- if (handle == NULL)
- return FALSE;
-
- ret = gnutls_cipher_encrypt2(handle, (void *)input, len, output, len);
- gnutls_cipher_deinit(handle);
-
- if (ret != 0) {
- purple_debug_error("cipher-aes",
- "gnutls_cipher_encrypt2 failed: %d\n", ret);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-purple_aes_decrypt_gnutls(const guchar *input, guchar *output, size_t len,
- guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size)
-{
- gnutls_cipher_hd_t handle;
- int ret;
-
- handle = purple_aes_crypt_gnutls_init(iv, key, key_size);
- if (handle == NULL)
- return FALSE;
-
- ret = gnutls_cipher_decrypt2(handle, input, len, output, len);
- gnutls_cipher_deinit(handle);
-
- if (ret != 0) {
- purple_debug_error("cipher-aes",
- "gnutls_cipher_decrypt2 failed: %d\n", ret);
- return FALSE;
- }
-
- return TRUE;
-}
-
-#elif defined(PURPLE_AES_USE_NSS)
-
-typedef struct
-{
- PK11SlotInfo *slot;
- PK11SymKey *sym_key;
- SECItem *sec_param;
- PK11Context *enc_context;
-} purple_aes_encrypt_nss_context;
-
-static void
-purple_aes_encrypt_nss_context_cleanup(purple_aes_encrypt_nss_context *ctx)
-{
- g_return_if_fail(ctx != NULL);
-
- if (ctx->enc_context != NULL)
- PK11_DestroyContext(ctx->enc_context, TRUE);
- if (ctx->sec_param != NULL)
- SECITEM_FreeItem(ctx->sec_param, TRUE);
- if (ctx->sym_key != NULL)
- PK11_FreeSymKey(ctx->sym_key);
- if (ctx->slot != NULL)
- PK11_FreeSlot(ctx->slot);
-
- memset(ctx, 0, sizeof(purple_aes_encrypt_nss_context));
-}
-
-static gboolean
-purple_aes_crypt_nss(const guchar *input, guchar *output, size_t len,
- guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size,
- CK_ATTRIBUTE_TYPE operation)
-{
- purple_aes_encrypt_nss_context ctx;
- CK_MECHANISM_TYPE cipher_mech = CKM_AES_CBC;
- SECItem key_item, iv_item;
- SECStatus ret;
- int outlen = 0;
- unsigned int outlen_tmp = 0;
-
- memset(&ctx, 0, sizeof(purple_aes_encrypt_nss_context));
-
- if (NSS_NoDB_Init(NULL) != SECSuccess) {
- purple_debug_error("cipher-aes",
- "NSS_NoDB_Init failed: %d\n", PR_GetError());
- return FALSE;
- }
-
- ctx.slot = PK11_GetBestSlot(cipher_mech, NULL);
- if (ctx.slot == NULL) {
- purple_debug_error("cipher-aes",
- "PK11_GetBestSlot failed: %d\n", PR_GetError());
- return FALSE;
- }
-
- key_item.type = siBuffer;
- key_item.data = key;
- key_item.len = key_size;
- ctx.sym_key = PK11_ImportSymKey(ctx.slot, cipher_mech,
- PK11_OriginUnwrap, CKA_ENCRYPT, &key_item, NULL);
- if (ctx.sym_key == NULL) {
- purple_debug_error("cipher-aes",
- "PK11_ImportSymKey failed: %d\n", PR_GetError());
- purple_aes_encrypt_nss_context_cleanup(&ctx);
- return FALSE;
- }
-
- iv_item.type = siBuffer;
- iv_item.data = iv;
- iv_item.len = PURPLE_AES_BLOCK_SIZE;
- ctx.sec_param = PK11_ParamFromIV(cipher_mech, &iv_item);
- if (ctx.sec_param == NULL) {
- purple_debug_error("cipher-aes",
- "PK11_ParamFromIV failed: %d\n", PR_GetError());
- purple_aes_encrypt_nss_context_cleanup(&ctx);
- return FALSE;
- }
-
- ctx.enc_context = PK11_CreateContextBySymKey(cipher_mech, operation,
- ctx.sym_key, ctx.sec_param);
- if (ctx.enc_context == NULL) {
- purple_debug_error("cipher-aes",
- "PK11_CreateContextBySymKey failed: %d\n",
- PR_GetError());
- purple_aes_encrypt_nss_context_cleanup(&ctx);
- return FALSE;
- }
-
- ret = PK11_CipherOp(ctx.enc_context, output, &outlen, len, input, len);
- if (ret != SECSuccess) {
- purple_debug_error("cipher-aes",
- "PK11_CipherOp failed: %d\n", PR_GetError());
- purple_aes_encrypt_nss_context_cleanup(&ctx);
- return FALSE;
- }
-
- ret = PK11_DigestFinal(ctx.enc_context, output + outlen, &outlen_tmp,
- len - outlen);
- if (ret != SECSuccess) {
- purple_debug_error("cipher-aes",
- "PK11_DigestFinal failed: %d\n", PR_GetError());
- purple_aes_encrypt_nss_context_cleanup(&ctx);
- return FALSE;
- }
-
- purple_aes_encrypt_nss_context_cleanup(&ctx);
-
- outlen += outlen_tmp;
- if (outlen != len) {
- purple_debug_error("cipher-aes",
- "resulting length doesn't match: %d (expected: %d)\n",
- outlen, len);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-purple_aes_encrypt_nss(const guchar *input, guchar *output, size_t len,
- guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size)
-{
- return purple_aes_crypt_nss(input, output, len, iv, key, key_size,
- CKA_ENCRYPT);
-}
-
-static gboolean
-purple_aes_decrypt_nss(const guchar *input, guchar *output, size_t len,
- guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size)
-{
- return purple_aes_crypt_nss(input, output, len, iv, key, key_size,
- CKA_DECRYPT);
-}
-
-#endif /* PURPLE_AES_USE_NSS */
-
-static ssize_t
-purple_aes_encrypt(PurpleCipherContext *context, const guchar input[],
- size_t in_len, guchar output[], size_t out_size)
-{
- AESContext *ctx_data = purple_cipher_context_get_data(context);
- purple_aes_crypt_func encrypt_func;
- guchar *input_padded;
- size_t out_len = 0;
- gboolean succ;
-
- if (ctx_data->failure)
- return -1;
-
- input_padded = purple_aes_pad_pkcs7(input, in_len, &out_len);
-
- if (out_len > out_size) {
- purple_debug_error("cipher-aes", "Output buffer too small\n");
- memset(input_padded, 0, out_len);
- g_free(input_padded);
- return -1;
- }
-
-#if defined(PURPLE_AES_USE_GNUTLS)
- encrypt_func = purple_aes_encrypt_gnutls;
-#elif defined(PURPLE_AES_USE_NSS)
- encrypt_func = purple_aes_encrypt_nss;
-#else
-# error "No matching encrypt_func"
-#endif
-
- succ = encrypt_func(input_padded, output, out_len, ctx_data->iv,
- ctx_data->key, ctx_data->key_size);
-
- memset(input_padded, 0, out_len);
- g_free(input_padded);
-
- if (!succ) {
- memset(output, 0, out_len);
- return -1;
- }
-
- return out_len;
-}
-
-static ssize_t
-purple_aes_decrypt(PurpleCipherContext *context, const guchar input[],
- size_t in_len, guchar output[], size_t out_size)
-{
- AESContext *ctx_data = purple_cipher_context_get_data(context);
- purple_aes_crypt_func decrypt_func;
- gboolean succ;
- ssize_t out_len;
-
- if (ctx_data->failure)
- return -1;
-
- if (in_len > out_size) {
- purple_debug_error("cipher-aes", "Output buffer too small\n");
- return -1;
- }
-
- if ((in_len % PURPLE_AES_BLOCK_SIZE) != 0 || in_len == 0) {
- purple_debug_error("cipher-aes", "Malformed data\n");
- return -1;
- }
-
-#if defined(PURPLE_AES_USE_GNUTLS)
- decrypt_func = purple_aes_decrypt_gnutls;
-#elif defined(PURPLE_AES_USE_NSS)
- decrypt_func = purple_aes_decrypt_nss;
-#else
-# error "No matching encrypt_func"
-#endif
-
- succ = decrypt_func(input, output, in_len, ctx_data->iv, ctx_data->key,
- ctx_data->key_size);
-
- if (!succ) {
- memset(output, 0, in_len);
- return -1;
- }
-
- out_len = purple_aes_unpad_pkcs7(output, in_len);
- if (out_len < 0) {
- memset(output, 0, in_len);
- return -1;
- }
-
- return out_len;
-}
-
-static size_t
-purple_aes_get_key_size(PurpleCipherContext *context)
-{
- AESContext *ctx_data = purple_cipher_context_get_data(context);
-
- return ctx_data->key_size;
-}
-
-static void
-purple_aes_set_batch_mode(PurpleCipherContext *context,
- PurpleCipherBatchMode mode)
-{
- AESContext *ctx_data = purple_cipher_context_get_data(context);
-
- if (mode == PURPLE_CIPHER_BATCH_MODE_CBC)
- return;
-
- purple_debug_error("cipher-aes", "unsupported batch mode\n");
- ctx_data->failure = TRUE;
-}
-
-static PurpleCipherBatchMode
-purple_aes_get_batch_mode(PurpleCipherContext *context)
-{
- return PURPLE_CIPHER_BATCH_MODE_CBC;
-}
-
-static size_t
-purple_aes_get_block_size(PurpleCipherContext *context)
-{
- return PURPLE_AES_BLOCK_SIZE;
-}
-
-static PurpleCipherOps AESOps = {
- purple_aes_set_option, /* set_option */
- NULL, /* get_option */
- purple_aes_init, /* init */
- purple_aes_reset, /* reset */
- NULL, /* reset_state */
- purple_aes_uninit, /* uninit */
- purple_aes_set_iv, /* set_iv */
- NULL, /* append */
- NULL, /* digest */
- NULL, /* get_digest_size */
- purple_aes_encrypt, /* encrypt */
- purple_aes_decrypt, /* decrypt */
- NULL, /* set_salt */
- NULL, /* get_salt_size */
- purple_aes_set_key, /* set_key */
- purple_aes_get_key_size, /* get_key_size */
- purple_aes_set_batch_mode, /* set_batch_mode */
- purple_aes_get_batch_mode, /* get_batch_mode */
- purple_aes_get_block_size, /* get_block_size */
- NULL, NULL, NULL, NULL /* reserved */
-};
-
-PurpleCipherOps *
-purple_aes_cipher_get_ops(void) {
- return &AESOps;
-}
diff --git a/libpurple/ciphers/aescipher.c b/libpurple/ciphers/aescipher.c
new file mode 100644
index 0000000000..e21e3b7fb7
--- /dev/null
+++ b/libpurple/ciphers/aescipher.c
@@ -0,0 +1,657 @@
+/*
+ * 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
+ *
+ * Written by Tomek Wasilczyk <tomkiewicz@cpw.pidgin.im>
+ */
+
+#include "aescipher.h"
+#include "debug.h"
+#include "enums.h"
+
+#include <string.h>
+
+#if defined(HAVE_GNUTLS)
+# define PURPLE_AES_USE_GNUTLS 1
+# include <gnutls/gnutls.h>
+# include <gnutls/crypto.h>
+#elif defined(HAVE_NSS)
+# define PURPLE_AES_USE_NSS 1
+# include <nss.h>
+# include <pk11pub.h>
+# include <prerror.h>
+#else
+# error "No GnuTLS or NSS support"
+#endif
+
+/* 128bit */
+#define PURPLE_AES_BLOCK_SIZE 16
+
+/******************************************************************************
+ * Structs
+ *****************************************************************************/
+#define PURPLE_AES_CIPHER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_AES_CIPHER, PurpleAESCipherPrivate))
+
+typedef struct {
+ guchar iv[PURPLE_AES_BLOCK_SIZE];
+ guchar key[32];
+ guint key_size;
+ gboolean failure;
+} PurpleAESCipherPrivate;
+
+/******************************************************************************
+ * Enums
+ *****************************************************************************/
+enum {
+ PROP_NONE,
+ PROP_BATCH_MODE,
+ PROP_IV,
+ PROP_KEY,
+ PROP_LAST,
+};
+
+/******************************************************************************
+ * Cipher Stuff
+ *****************************************************************************/
+
+typedef gboolean (*purple_aes_cipher_crypt_func)(
+ const guchar *input, guchar *output, size_t len,
+ guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size);
+
+static void
+purple_aes_cipher_reset(PurpleCipher *cipher)
+{
+ PurpleAESCipherPrivate *priv = PURPLE_AES_CIPHER_GET_PRIVATE(cipher);
+
+ g_return_if_fail(priv != NULL);
+
+ memset(priv->iv, 0, sizeof(priv->iv));
+ memset(priv->key, 0, sizeof(priv->key));
+ priv->key_size = 32; /* 256bit */
+ priv->failure = FALSE;
+}
+
+static void
+purple_aes_cipher_set_iv(PurpleCipher *cipher, guchar *iv, size_t len)
+{
+ PurpleAESCipherPrivate *priv = PURPLE_AES_CIPHER_GET_PRIVATE(cipher);
+
+ if ((len > 0 && iv == NULL) ||
+ (len != 0 && len != sizeof(priv->iv))) {
+ purple_debug_error("cipher-aes", "invalid IV length\n");
+ priv->failure = TRUE;
+ return;
+ }
+
+ if (len == 0)
+ memset(priv->iv, 0, sizeof(priv->iv));
+ else
+ memcpy(priv->iv, iv, len);
+
+ g_object_notify(G_OBJECT(cipher), "iv");
+}
+
+static void
+purple_aes_cipher_set_key(PurpleCipher *cipher, const guchar *key, size_t len)
+{
+ PurpleAESCipherPrivate *priv = PURPLE_AES_CIPHER_GET_PRIVATE(cipher);
+
+ if ((len > 0 && key == NULL) ||
+ (len != 0 && len != 16 && len != 24 && len != 32)) {
+ purple_debug_error("cipher-aes", "invalid key length\n");
+ priv->failure = TRUE;
+ return;
+ }
+
+ priv->key_size = len;
+ memset(priv->key, 0, sizeof(priv->key));
+ if (len > 0)
+ memcpy(priv->key, key, len);
+
+ g_object_notify(G_OBJECT(cipher), "key");
+}
+
+static guchar *
+purple_aes_cipher_pad_pkcs7(const guchar input[], size_t in_len, size_t *out_len)
+{
+ int padding_len, total_len;
+ guchar *padded;
+
+ g_return_val_if_fail(input != NULL, NULL);
+ g_return_val_if_fail(out_len != NULL, NULL);
+
+ padding_len = PURPLE_AES_BLOCK_SIZE - (in_len % PURPLE_AES_BLOCK_SIZE);
+ total_len = in_len + padding_len;
+ g_assert((total_len % PURPLE_AES_BLOCK_SIZE) == 0);
+
+ padded = g_new(guchar, total_len);
+ *out_len = total_len;
+
+ memcpy(padded, input, in_len);
+ memset(padded + in_len, padding_len, padding_len);
+
+ return padded;
+}
+
+static ssize_t
+purple_aes_cipher_unpad_pkcs7(guchar input[], size_t in_len)
+{
+ guchar padding_len, i;
+ size_t out_len;
+
+ g_return_val_if_fail(input != NULL, -1);
+ g_return_val_if_fail(in_len > 0, -1);
+
+ padding_len = input[in_len - 1];
+ if (padding_len == 0 || padding_len > PURPLE_AES_BLOCK_SIZE ||
+ padding_len > in_len) {
+ purple_debug_warning("cipher-aes",
+ "Invalid padding length: %d (total %" G_GSIZE_FORMAT ") - "
+ "most probably, the key was invalid\n",
+ padding_len, in_len);
+ return -1;
+ }
+
+ out_len = in_len - padding_len;
+ for (i = 0; i < padding_len; i++) {
+ if (input[out_len + i] != padding_len) {
+ purple_debug_warning("cipher-aes",
+ "Padding doesn't match at pos %d (found %02x, "
+ "expected %02x) - "
+ "most probably, the key was invalid\n",
+ i, input[out_len + i], padding_len);
+ return -1;
+ }
+ }
+
+ memset(input + out_len, 0, padding_len);
+ return out_len;
+}
+
+#ifdef PURPLE_AES_USE_GNUTLS
+
+static gnutls_cipher_hd_t
+purple_aes_cipher_gnutls_crypt_init(guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32],
+ guint key_size)
+{
+ gnutls_cipher_hd_t handle;
+ gnutls_cipher_algorithm_t algorithm;
+ gnutls_datum_t key_info, iv_info;
+ int ret;
+
+ if (key_size == 16)
+ algorithm = GNUTLS_CIPHER_AES_128_CBC;
+ else if (key_size == 24)
+ algorithm = GNUTLS_CIPHER_AES_192_CBC;
+ else if (key_size == 32)
+ algorithm = GNUTLS_CIPHER_AES_256_CBC;
+ else
+ g_return_val_if_reached(NULL);
+
+ key_info.data = key;
+ key_info.size = key_size;
+
+ iv_info.data = iv;
+ iv_info.size = PURPLE_AES_BLOCK_SIZE;
+
+ ret = gnutls_cipher_init(&handle, algorithm, &key_info, &iv_info);
+ if (ret != 0) {
+ purple_debug_error("cipher-aes",
+ "gnutls_cipher_init failed: %d\n", ret);
+ return NULL;
+ }
+
+ return handle;
+}
+
+static gboolean
+purple_aes_cipher_gnutls_encrypt(const guchar *input, guchar *output, size_t len,
+ guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size)
+{
+ gnutls_cipher_hd_t handle;
+ int ret;
+
+ handle = purple_aes_cipher_gnutls_crypt_init(iv, key, key_size);
+ if (handle == NULL)
+ return FALSE;
+
+ ret = gnutls_cipher_encrypt2(handle, (guchar *)input, len, output, len);
+ gnutls_cipher_deinit(handle);
+
+ if (ret != 0) {
+ purple_debug_error("cipher-aes",
+ "gnutls_cipher_encrypt2 failed: %d\n", ret);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+purple_aes_cipher_gnutls_decrypt(const guchar *input, guchar *output, size_t len,
+ guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size)
+{
+ gnutls_cipher_hd_t handle;
+ int ret;
+
+ handle = purple_aes_cipher_gnutls_crypt_init(iv, key, key_size);
+ if (handle == NULL)
+ return FALSE;
+
+ ret = gnutls_cipher_decrypt2(handle, input, len, output, len);
+ gnutls_cipher_deinit(handle);
+
+ if (ret != 0) {
+ purple_debug_error("cipher-aes",
+ "gnutls_cipher_decrypt2 failed: %d\n", ret);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#elif defined(PURPLE_AES_USE_NSS)
+
+typedef struct {
+ PK11SlotInfo *slot;
+ PK11SymKey *sym_key;
+ SECItem *sec_param;
+ PK11Context *enc_context;
+} PurpleAESCipherNSSContext;
+
+static void
+purple_aes_cipher_nss_cleanup(PurpleAESCipherNSSContext *context)
+{
+ g_return_if_fail(context != NULL);
+
+ if (context->enc_context != NULL)
+ PK11_DestroyContext(context->enc_context, TRUE);
+ if (context->sec_param != NULL)
+ SECITEM_FreeItem(context->sec_param, TRUE);
+ if (context->sym_key != NULL)
+ PK11_FreeSymKey(context->sym_key);
+ if (context->slot != NULL)
+ PK11_FreeSlot(context->slot);
+
+ memset(context, 0, sizeof(PurpleAESCipherNSSContext));
+}
+
+static gboolean
+purple_aes_cipher_nss_crypt(const guchar *input, guchar *output, size_t len,
+ guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size,
+ CK_ATTRIBUTE_TYPE operation)
+{
+ PurpleAESCipherNSSContext context;
+ CK_MECHANISM_TYPE cipher_mech = CKM_AES_CBC;
+ SECItem key_item, iv_item;
+ SECStatus ret;
+ int outlen = 0;
+ unsigned int outlen_tmp = 0;
+
+ memset(&context, 0, sizeof(PurpleAESCipherNSSContext));
+
+ if (NSS_NoDB_Init(NULL) != SECSuccess) {
+ purple_debug_error("cipher-aes",
+ "NSS_NoDB_Init failed: %d\n", PR_GetError());
+ return FALSE;
+ }
+
+ context.slot = PK11_GetBestSlot(cipher_mech, NULL);
+ if (context.slot == NULL) {
+ purple_debug_error("cipher-aes",
+ "PK11_GetBestSlot failed: %d\n", PR_GetError());
+ return FALSE;
+ }
+
+ key_item.type = siBuffer;
+ key_item.data = key;
+ key_item.len = key_size;
+ context.sym_key = PK11_ImportSymKey(context.slot, cipher_mech,
+ PK11_OriginUnwrap, CKA_ENCRYPT, &key_item, NULL);
+ if (context.sym_key == NULL) {
+ purple_debug_error("cipher-aes",
+ "PK11_ImportSymKey failed: %d\n", PR_GetError());
+ purple_aes_cipher_nss_cleanup(&context);
+ return FALSE;
+ }
+
+ iv_item.type = siBuffer;
+ iv_item.data = iv;
+ iv_item.len = PURPLE_AES_BLOCK_SIZE;
+ context.sec_param = PK11_ParamFromIV(cipher_mech, &iv_item);
+ if (context.sec_param == NULL) {
+ purple_debug_error("cipher-aes",
+ "PK11_ParamFromIV failed: %d\n", PR_GetError());
+ purple_aes_cipher_nss_cleanup(&context);
+ return FALSE;
+ }
+
+ context.enc_context = PK11_CreateContextBySymKey(cipher_mech, operation,
+ context.sym_key, context.sec_param);
+ if (context.enc_context == NULL) {
+ purple_debug_error("cipher-aes",
+ "PK11_CreateContextBySymKey failed: %d\n",
+ PR_GetError());
+ purple_aes_cipher_nss_cleanup(&context);
+ return FALSE;
+ }
+
+ ret = PK11_CipherOp(context.enc_context, output, &outlen, len, input, len);
+ if (ret != SECSuccess) {
+ purple_debug_error("cipher-aes",
+ "PK11_CipherOp failed: %d\n", PR_GetError());
+ purple_aes_cipher_nss_cleanup(&context);
+ return FALSE;
+ }
+
+ ret = PK11_DigestFinal(context.enc_context, output + outlen, &outlen_tmp,
+ len - outlen);
+ if (ret != SECSuccess) {
+ purple_debug_error("cipher-aes",
+ "PK11_DigestFinal failed: %d\n", PR_GetError());
+ purple_aes_cipher_nss_cleanup(&context);
+ return FALSE;
+ }
+
+ purple_aes_cipher_nss_cleanup(&context);
+
+ outlen += outlen_tmp;
+ if (outlen != len) {
+ purple_debug_error("cipher-aes",
+ "resulting length doesn't match: %d (expected: %lu)\n",
+ outlen, len);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+purple_aes_cipher_nss_encrypt(const guchar *input, guchar *output, size_t len,
+ guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size)
+{
+ return purple_aes_cipher_nss_crypt(input, output, len, iv, key, key_size,
+ CKA_ENCRYPT);
+}
+
+static gboolean
+purple_aes_cipher_nss_decrypt(const guchar *input, guchar *output, size_t len,
+ guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size)
+{
+ return purple_aes_cipher_nss_crypt(input, output, len, iv, key, key_size,
+ CKA_DECRYPT);
+}
+
+#endif /* PURPLE_AES_USE_NSS */
+
+static ssize_t
+purple_aes_cipher_encrypt(PurpleCipher *cipher, const guchar input[],
+ size_t in_len, guchar output[], size_t out_size)
+{
+ PurpleAESCipherPrivate *priv = PURPLE_AES_CIPHER_GET_PRIVATE(cipher);
+ purple_aes_cipher_crypt_func encrypt_func;
+ guchar *input_padded;
+ size_t out_len = 0;
+ gboolean succ;
+
+ if (priv->failure)
+ return -1;
+
+ input_padded = purple_aes_cipher_pad_pkcs7(input, in_len, &out_len);
+
+ if (out_len > out_size) {
+ purple_debug_error("cipher-aes", "Output buffer too small\n");
+ memset(input_padded, 0, out_len);
+ g_free(input_padded);
+ return -1;
+ }
+
+#if defined(PURPLE_AES_USE_GNUTLS)
+ encrypt_func = purple_aes_cipher_gnutls_encrypt;
+#elif defined(PURPLE_AES_USE_NSS)
+ encrypt_func = purple_aes_cipher_nss_encrypt;
+#else
+# error "No matching encrypt_func"
+#endif
+
+ succ = encrypt_func(input_padded, output, out_len, priv->iv,
+ priv->key, priv->key_size);
+
+ memset(input_padded, 0, out_len);
+ g_free(input_padded);
+
+ if (!succ) {
+ memset(output, 0, out_len);
+ return -1;
+ }
+
+ return out_len;
+}
+
+static ssize_t
+purple_aes_cipher_decrypt(PurpleCipher *cipher, const guchar input[],
+ size_t in_len, guchar output[], size_t out_size)
+{
+ PurpleAESCipherPrivate *priv = PURPLE_AES_CIPHER_GET_PRIVATE(cipher);
+ purple_aes_cipher_crypt_func decrypt_func;
+ gboolean succ;
+ ssize_t out_len;
+
+ if (priv->failure)
+ return -1;
+
+ if (in_len > out_size) {
+ purple_debug_error("cipher-aes", "Output buffer too small\n");
+ return -1;
+ }
+
+ if ((in_len % PURPLE_AES_BLOCK_SIZE) != 0 || in_len == 0) {
+ purple_debug_error("cipher-aes", "Malformed data\n");
+ return -1;
+ }
+
+#if defined(PURPLE_AES_USE_GNUTLS)
+ decrypt_func = purple_aes_cipher_gnutls_decrypt;
+#elif defined(PURPLE_AES_USE_NSS)
+ decrypt_func = purple_aes_cipher_nss_decrypt;
+#else
+# error "No matching encrypt_func"
+#endif
+
+ succ = decrypt_func(input, output, in_len, priv->iv, priv->key,
+ priv->key_size);
+
+ if (!succ) {
+ memset(output, 0, in_len);
+ return -1;
+ }
+
+ out_len = purple_aes_cipher_unpad_pkcs7(output, in_len);
+ if (out_len < 0) {
+ memset(output, 0, in_len);
+ return -1;
+ }
+
+ return out_len;
+}
+
+static size_t
+purple_aes_cipher_get_key_size(PurpleCipher *cipher)
+{
+ PurpleAESCipherPrivate *priv = PURPLE_AES_CIPHER_GET_PRIVATE(cipher);
+
+ return priv->key_size;
+}
+
+static void
+purple_aes_cipher_set_batch_mode(PurpleCipher *cipher,
+ PurpleCipherBatchMode mode)
+{
+ PurpleAESCipherPrivate *priv = PURPLE_AES_CIPHER_GET_PRIVATE(cipher);
+
+ if (mode == PURPLE_CIPHER_BATCH_MODE_CBC) {
+ g_object_notify(G_OBJECT(cipher), "batch_mode");
+ return;
+ }
+
+ purple_debug_error("cipher-aes", "unsupported batch mode\n");
+ priv->failure = TRUE;
+}
+
+static PurpleCipherBatchMode
+purple_aes_cipher_get_batch_mode(PurpleCipher *cipher)
+{
+ return PURPLE_CIPHER_BATCH_MODE_CBC;
+}
+
+static size_t
+purple_aes_cipher_get_block_size(PurpleCipher *cipher)
+{
+ return PURPLE_AES_BLOCK_SIZE;
+}
+
+static const gchar*
+purple_aes_cipher_get_name(PurpleCipher *cipher)
+{
+ return "aes";
+}
+
+/******************************************************************************
+ * Object Stuff
+ *****************************************************************************/
+static void
+purple_aes_cipher_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleCipher *cipher = PURPLE_CIPHER(obj);
+
+ switch(param_id) {
+ case PROP_BATCH_MODE:
+ g_value_set_enum(value,
+ purple_cipher_get_batch_mode(cipher));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_aes_cipher_set_property(GObject *obj, guint param_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ PurpleCipher *cipher = PURPLE_CIPHER(obj);
+
+ switch(param_id) {
+ case PROP_BATCH_MODE:
+ purple_cipher_set_batch_mode(cipher,
+ g_value_get_enum(value));
+ break;
+ case PROP_IV:
+ {
+ guchar *iv = (guchar *)g_value_get_string(value);
+ purple_cipher_set_iv(cipher, iv, strlen((gchar*)iv));
+ }
+ break;
+ case PROP_KEY:
+ purple_cipher_set_key(cipher, (guchar *)g_value_get_string(value),
+ purple_aes_cipher_get_key_size(cipher));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_aes_cipher_class_init(PurpleAESCipherClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ PurpleCipherClass *cipher_class = PURPLE_CIPHER_CLASS(klass);
+ GParamSpec *pspec;
+
+ obj_class->get_property = purple_aes_cipher_get_property;
+ obj_class->set_property = purple_aes_cipher_set_property;
+
+ cipher_class->reset = purple_aes_cipher_reset;
+ cipher_class->set_iv = purple_aes_cipher_set_iv;
+ cipher_class->encrypt = purple_aes_cipher_encrypt;
+ cipher_class->decrypt = purple_aes_cipher_decrypt;
+ cipher_class->set_key = purple_aes_cipher_set_key;
+ cipher_class->get_key_size = purple_aes_cipher_get_key_size;
+ cipher_class->set_batch_mode = purple_aes_cipher_set_batch_mode;
+ cipher_class->get_batch_mode = purple_aes_cipher_get_batch_mode;
+ cipher_class->get_block_size = purple_aes_cipher_get_block_size;
+ cipher_class->get_name = purple_aes_cipher_get_name;
+
+ pspec = g_param_spec_enum("batch_mode", "batch_mode", "batch_mode",
+ PURPLE_TYPE_CIPHER_BATCH_MODE, 0,
+ G_PARAM_READWRITE);
+ g_object_class_install_property(obj_class, PROP_BATCH_MODE, pspec);
+
+ pspec = g_param_spec_string("iv", "iv", "iv", NULL,
+ G_PARAM_WRITABLE);
+ g_object_class_install_property(obj_class, PROP_IV, pspec);
+
+ pspec = g_param_spec_string("key", "key", "key", NULL,
+ G_PARAM_WRITABLE);
+ g_object_class_install_property(obj_class, PROP_KEY, pspec);
+
+ g_type_class_add_private(klass, sizeof(PurpleAESCipherPrivate));
+}
+
+static void
+purple_aes_cipher_init(PurpleCipher *cipher) {
+ purple_cipher_reset(cipher);
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GType
+purple_aes_cipher_get_gtype(void) {
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleAESCipherClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_aes_cipher_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleAESCipher),
+ 0,
+ (GInstanceInitFunc)purple_aes_cipher_init,
+ NULL
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_CIPHER,
+ "PurpleAESCipher",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleCipher *
+purple_aes_cipher_new(void) {
+ return g_object_new(PURPLE_TYPE_AES_CIPHER, NULL);
+}
diff --git a/libpurple/ciphers/aescipher.h b/libpurple/ciphers/aescipher.h
new file mode 100644
index 0000000000..99420585a8
--- /dev/null
+++ b/libpurple/ciphers/aescipher.h
@@ -0,0 +1,64 @@
+/**
+ * @file aes.h Purple AES Cipher
+ * @ingroup core
+ */
+
+/* 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 PURPLE_AES_CIPHER_H
+#define PURPLE_AES_CIPHER_H
+
+#include "cipher.h"
+
+#define PURPLE_TYPE_AES_CIPHER (purple_aes_cipher_get_gtype())
+#define PURPLE_AES_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_AES_CIPHER, PurpleAESCipher))
+#define PURPLE_AES_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_AES_CIPHER, PurpleAESCipherClass))
+#define PURPLE_IS_AES_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_AES_CIPHER))
+#define PURPLE_IS_AES_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), PURPLE_TYPE_AES_CIPHER))
+#define PURPLE_AES_CIPHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_AES_CIPHER, PurpleAESCipherClass))
+
+typedef struct _PurpleAESCipher PurpleAESCipher;
+typedef struct _PurpleAESCipherClass PurpleAESCipherClass;
+
+struct _PurpleAESCipher {
+ /*< private >*/
+ PurpleCipher gparent;
+};
+
+struct _PurpleAESCipherClass {
+ /*< private >*/
+ PurpleCipherClass gparent;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType purple_aes_cipher_get_gtype(void);
+
+PurpleCipher *purple_aes_cipher_new(void);
+
+G_END_DECLS
+
+#endif /* PURPLE_AES_CIPHER_H */
diff --git a/libpurple/ciphers/ciphers.h b/libpurple/ciphers/ciphers.h
deleted file mode 100644
index f7bb5e2edf..0000000000
--- a/libpurple/ciphers/ciphers.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* 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
- */
-
-/* aes.c */
-PurpleCipherOps * purple_aes_cipher_get_ops(void);
-
-/* des.c */
-PurpleCipherOps * purple_des_cipher_get_ops(void);
-PurpleCipherOps * purple_des3_cipher_get_ops(void);
-
-/* gchecksum.c */
-PurpleCipherOps * purple_md5_cipher_get_ops(void);
-PurpleCipherOps * purple_sha1_cipher_get_ops(void);
-PurpleCipherOps * purple_sha256_cipher_get_ops(void);
-
-/* hmac.c */
-PurpleCipherOps * purple_hmac_cipher_get_ops(void);
-
-/* md4.c */
-PurpleCipherOps * purple_md4_cipher_get_ops(void);
-
-/* pbkdf2.c */
-PurpleCipherOps * purple_pbkdf2_cipher_get_ops(void);
-
-/* rc4.c */
-PurpleCipherOps * purple_rc4_cipher_get_ops(void);
-
-static inline void purple_ciphers_register_all(void)
-{
-#if defined(HAVE_GNUTLS) || defined(HAVE_NSS)
- purple_ciphers_register_cipher("aes", purple_aes_cipher_get_ops());
-#endif
-
- purple_ciphers_register_cipher("des", purple_des_cipher_get_ops());
- purple_ciphers_register_cipher("des3", purple_des3_cipher_get_ops());
-
- purple_ciphers_register_cipher("md5", purple_md5_cipher_get_ops());
- purple_ciphers_register_cipher("sha1", purple_sha1_cipher_get_ops());
- purple_ciphers_register_cipher("sha256", purple_sha256_cipher_get_ops());
-
- purple_ciphers_register_cipher("hmac", purple_hmac_cipher_get_ops());
-
- purple_ciphers_register_cipher("md4", purple_md4_cipher_get_ops());
-
- purple_ciphers_register_cipher("pbkdf2", purple_pbkdf2_cipher_get_ops());
-
- purple_ciphers_register_cipher("rc4", purple_rc4_cipher_get_ops());
-}
diff --git a/libpurple/ciphers/des.c b/libpurple/ciphers/des.c
deleted file mode 100644
index 51e2da8192..0000000000
--- a/libpurple/ciphers/des.c
+++ /dev/null
@@ -1,903 +0,0 @@
-/*
- * 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.
- *
- * Original des taken from gpg
- *
- * des.c - DES and Triple-DES encryption/decryption Algorithm
- * Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * Please see below for more legal information!
- *
- * According to the definition of DES in FIPS PUB 46-2 from December 1993.
- * For a description of triple encryption, see:
- * Bruce Schneier: Applied Cryptography. Second Edition.
- * John Wiley & Sons, 1996. ISBN 0-471-12845-7. Pages 358 ff.
- *
- * This file is part of GnuPG.
- *
- * 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 <cipher.h>
-#include "ciphers.h"
-
-/******************************************************************************
- * DES
- *****************************************************************************/
-typedef struct _des_ctx
-{
- guint32 encrypt_subkeys[32];
- guint32 decrypt_subkeys[32];
-} des_ctx[1];
-
-/*
- * The s-box values are permuted according to the 'primitive function P'
- */
-static const guint32 sbox1[64] =
-{
- 0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000,
- 0x00000200, 0x00808200, 0x00808202, 0x00000200, 0x00800202, 0x00808002, 0x00800000, 0x00000002,
- 0x00000202, 0x00800200, 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202,
- 0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202, 0x00008202, 0x00800000,
- 0x00008000, 0x00808202, 0x00000002, 0x00808000, 0x00808200, 0x00800000, 0x00800000, 0x00000200,
- 0x00808002, 0x00008000, 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202,
- 0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202, 0x00008202, 0x00808200,
- 0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002
-};
-
-static const guint32 sbox2[64] =
-{
- 0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010,
- 0x40000010, 0x40084010, 0x40084000, 0x40000000, 0x40004000, 0x00080000, 0x00000010, 0x40080010,
- 0x00084000, 0x00080010, 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000,
- 0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000, 0x40080000, 0x00004010,
- 0x00000000, 0x00084010, 0x40080010, 0x00080000, 0x40004010, 0x40080000, 0x40084000, 0x00004000,
- 0x40080000, 0x40004000, 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000,
- 0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010, 0x40000010, 0x00080010,
- 0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000
-};
-
-static const guint32 sbox3[64] =
-{
- 0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100,
- 0x00010004, 0x04000004, 0x04000004, 0x00010000, 0x04010104, 0x00010004, 0x04010000, 0x00000104,
- 0x04000000, 0x00000004, 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104,
- 0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104, 0x00000100, 0x04000000,
- 0x04010100, 0x04000000, 0x00010004, 0x00000104, 0x00010000, 0x04010100, 0x04000100, 0x00000000,
- 0x00000100, 0x00010004, 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004,
- 0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104, 0x00010100, 0x04000004,
- 0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100
-};
-
-static const guint32 sbox4[64] =
-{
- 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000,
- 0x00000000, 0x00401000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00400040, 0x80400000,
- 0x80000000, 0x00001000, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040,
- 0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040, 0x80401040, 0x80000040,
- 0x00400040, 0x80400000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00000000, 0x00401000,
- 0x00001040, 0x00400040, 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040,
- 0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000, 0x00401040, 0x80400040,
- 0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040
-};
-
-static const guint32 sbox5[64] =
-{
- 0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000,
- 0x20040080, 0x00040000, 0x01000080, 0x20040080, 0x21000080, 0x21040000, 0x00040080, 0x20000000,
- 0x01000000, 0x20040000, 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080,
- 0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000, 0x21000000, 0x00040080,
- 0x00040000, 0x21000080, 0x00000080, 0x01000000, 0x20000000, 0x01040000, 0x21000080, 0x20040080,
- 0x01000080, 0x20000000, 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000,
- 0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000, 0x20040000, 0x21000000,
- 0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080
-};
-
-static const guint32 sbox6[64] =
-{
- 0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000,
- 0x10002000, 0x00202008, 0x00200000, 0x10000008, 0x00200008, 0x10002000, 0x10000000, 0x00002008,
- 0x00000000, 0x00200008, 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008,
- 0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000, 0x10202000, 0x10000000,
- 0x10002000, 0x00000008, 0x10200008, 0x00202000, 0x10202008, 0x00200000, 0x00002008, 0x10000008,
- 0x00200000, 0x10002000, 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000,
- 0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000, 0x10200000, 0x00202008,
- 0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008
-};
-
-static const guint32 sbox7[64] =
-{
- 0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400,
- 0x02100401, 0x00100000, 0x00000000, 0x02000001, 0x00000001, 0x02000000, 0x02100001, 0x00000401,
- 0x02000400, 0x00100401, 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001,
- 0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001, 0x02000000, 0x00100400,
- 0x02000000, 0x00100400, 0x00100000, 0x02000401, 0x02000401, 0x02100001, 0x02100001, 0x00000001,
- 0x00100001, 0x02000000, 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400,
- 0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000, 0x00000001, 0x02100401,
- 0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001
-};
-
-static const guint32 sbox8[64] =
-{
- 0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000,
- 0x00020020, 0x08020000, 0x08020820, 0x00020800, 0x08020800, 0x00020820, 0x00000800, 0x00000020,
- 0x08020000, 0x08000020, 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800,
- 0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800, 0x00020820, 0x00020000,
- 0x00020820, 0x00020000, 0x08020800, 0x00000800, 0x00000020, 0x08020020, 0x00000800, 0x00020820,
- 0x08000800, 0x00000020, 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820,
- 0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800, 0x08000820, 0x00000000,
- 0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800
-};
-
-
-/*
- * * These two tables are part of the 'permuted choice 1' function.
- * * In this implementation several speed improvements are done.
- * */
-static const guint32 leftkey_swap[16] =
-{
- 0x00000000, 0x00000001, 0x00000100, 0x00000101,
- 0x00010000, 0x00010001, 0x00010100, 0x00010101,
- 0x01000000, 0x01000001, 0x01000100, 0x01000101,
- 0x01010000, 0x01010001, 0x01010100, 0x01010101
-};
-
-static const guint32 rightkey_swap[16] =
-{
- 0x00000000, 0x01000000, 0x00010000, 0x01010000,
- 0x00000100, 0x01000100, 0x00010100, 0x01010100,
- 0x00000001, 0x01000001, 0x00010001, 0x01010001,
- 0x00000101, 0x01000101, 0x00010101, 0x01010101,
-};
-
-
-/*
- * Numbers of left shifts per round for encryption subkey schedule
- * To calculate the decryption key scheduling we just reverse the
- * ordering of the subkeys so we can omit the table for decryption
- * subkey schedule.
- */
-static const guint8 encrypt_rotate_tab[16] =
-{
- 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
-};
-
-/*
- * Macro to swap bits across two words
- **/
-#define DO_PERMUTATION(a, temp, b, offset, mask) \
- temp = ((a>>offset) ^ b) & mask; \
- b ^= temp; \
- a ^= temp<<offset;
-
-
-/*
- * This performs the 'initial permutation' for the data to be encrypted or decrypted
- **/
-#define INITIAL_PERMUTATION(left, temp, right) \
- DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f) \
- DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
- DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
- DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
- DO_PERMUTATION(left, temp, right, 1, 0x55555555)
-
-
-/*
- * The 'inverse initial permutation'
- **/
-#define FINAL_PERMUTATION(left, temp, right) \
- DO_PERMUTATION(left, temp, right, 1, 0x55555555) \
- DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
- DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
- DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
- DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f)
-
-
-/*
- * A full DES round including 'expansion function', 'sbox substitution'
- * and 'primitive function P' but without swapping the left and right word.
- **/
-#define DES_ROUND(from, to, work, subkey) \
- work = ((from<<1) | (from>>31)) ^ *subkey++; \
- to ^= sbox8[ work & 0x3f ]; \
- to ^= sbox6[ (work>>8) & 0x3f ]; \
- to ^= sbox4[ (work>>16) & 0x3f ]; \
- to ^= sbox2[ (work>>24) & 0x3f ]; \
- work = ((from>>3) | (from<<29)) ^ *subkey++; \
- to ^= sbox7[ work & 0x3f ]; \
- to ^= sbox5[ (work>>8) & 0x3f ]; \
- to ^= sbox3[ (work>>16) & 0x3f ]; \
- to ^= sbox1[ (work>>24) & 0x3f ];
-
-
-/*
- * Macros to convert 8 bytes from/to 32bit words
- **/
-#define READ_64BIT_DATA(data, left, right) \
- left = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; \
- right = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
-
-#define WRITE_64BIT_DATA(data, left, right) \
- data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff; \
- data[2] = (left >> 8) &0xff; data[3] = left &0xff; \
- data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff; \
- data[6] = (right >> 8) &0xff; data[7] = right &0xff;
-
-
-/*
- * des_key_schedule(): Calculate 16 subkeys pairs (even/odd) for
- * 16 encryption rounds.
- * To calculate subkeys for decryption the caller
- * have to reorder the generated subkeys.
- *
- * rawkey: 8 Bytes of key data
- * subkey: Array of at least 32 guint32s. Will be filled
- * with calculated subkeys.
- *
- **/
-static void
-des_key_schedule (const guint8 * rawkey, guint32 * subkey)
-{
- guint32 left, right, work;
- int round;
-
- READ_64BIT_DATA (rawkey, left, right)
-
- DO_PERMUTATION (right, work, left, 4, 0x0f0f0f0f)
- DO_PERMUTATION (right, work, left, 0, 0x10101010)
-
- left = (leftkey_swap[(left >> 0) & 0xf] << 3) | (leftkey_swap[(left >> 8) & 0xf] << 2)
- | (leftkey_swap[(left >> 16) & 0xf] << 1) | (leftkey_swap[(left >> 24) & 0xf])
- | (leftkey_swap[(left >> 5) & 0xf] << 7) | (leftkey_swap[(left >> 13) & 0xf] << 6)
- | (leftkey_swap[(left >> 21) & 0xf] << 5) | (leftkey_swap[(left >> 29) & 0xf] << 4);
-
- left &= 0x0fffffff;
-
- right = (rightkey_swap[(right >> 1) & 0xf] << 3) | (rightkey_swap[(right >> 9) & 0xf] << 2)
- | (rightkey_swap[(right >> 17) & 0xf] << 1) | (rightkey_swap[(right >> 25) & 0xf])
- | (rightkey_swap[(right >> 4) & 0xf] << 7) | (rightkey_swap[(right >> 12) & 0xf] << 6)
- | (rightkey_swap[(right >> 20) & 0xf] << 5) | (rightkey_swap[(right >> 28) & 0xf] << 4);
-
- right &= 0x0fffffff;
-
- for (round = 0; round < 16; ++round)
- {
- left = ((left << encrypt_rotate_tab[round]) | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
- right = ((right << encrypt_rotate_tab[round]) | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
-
- *subkey++ = ((left << 4) & 0x24000000)
- | ((left << 28) & 0x10000000)
- | ((left << 14) & 0x08000000)
- | ((left << 18) & 0x02080000)
- | ((left << 6) & 0x01000000)
- | ((left << 9) & 0x00200000)
- | ((left >> 1) & 0x00100000)
- | ((left << 10) & 0x00040000)
- | ((left << 2) & 0x00020000)
- | ((left >> 10) & 0x00010000)
- | ((right >> 13) & 0x00002000)
- | ((right >> 4) & 0x00001000)
- | ((right << 6) & 0x00000800)
- | ((right >> 1) & 0x00000400)
- | ((right >> 14) & 0x00000200)
- | (right & 0x00000100)
- | ((right >> 5) & 0x00000020)
- | ((right >> 10) & 0x00000010)
- | ((right >> 3) & 0x00000008)
- | ((right >> 18) & 0x00000004)
- | ((right >> 26) & 0x00000002)
- | ((right >> 24) & 0x00000001);
-
- *subkey++ = ((left << 15) & 0x20000000)
- | ((left << 17) & 0x10000000)
- | ((left << 10) & 0x08000000)
- | ((left << 22) & 0x04000000)
- | ((left >> 2) & 0x02000000)
- | ((left << 1) & 0x01000000)
- | ((left << 16) & 0x00200000)
- | ((left << 11) & 0x00100000)
- | ((left << 3) & 0x00080000)
- | ((left >> 6) & 0x00040000)
- | ((left << 15) & 0x00020000)
- | ((left >> 4) & 0x00010000)
- | ((right >> 2) & 0x00002000)
- | ((right << 8) & 0x00001000)
- | ((right >> 14) & 0x00000808)
- | ((right >> 9) & 0x00000400)
- | ((right) & 0x00000200)
- | ((right << 7) & 0x00000100)
- | ((right >> 7) & 0x00000020)
- | ((right >> 3) & 0x00000011)
- | ((right << 2) & 0x00000004)
- | ((right >> 21) & 0x00000002);
- }
-}
-
-
-/*
- * Fill a DES context with subkeys calculated from a 64bit key.
- * Does not check parity bits, but simply ignore them.
- * Does not check for weak keys.
- **/
-static void
-des_set_key (PurpleCipherContext *context, const guchar * key, size_t len)
-{
- struct _des_ctx *ctx = purple_cipher_context_get_data(context);
- int i;
-
- g_return_if_fail(len == 8);
-
- des_key_schedule (key, ctx->encrypt_subkeys);
-
- for(i=0; i<32; i+=2)
- {
- ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[30-i];
- ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[31-i];
- }
-}
-
-static size_t
-des_get_key_size(PurpleCipherContext *context)
-{
- return 8;
-}
-
-/*
- * Electronic Codebook Mode DES encryption/decryption of data according
- * to 'mode'.
- **/
-static int
-des_ecb_crypt (struct _des_ctx *ctx, const guint8 * from, guint8 * to, int mode)
-{
- guint32 left, right, work;
- guint32 *keys;
-
- keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
-
- READ_64BIT_DATA (from, left, right)
- INITIAL_PERMUTATION (left, work, right)
-
- DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
- DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
- DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
- DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
- DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
- DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
- DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
- DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-
- FINAL_PERMUTATION (right, work, left)
- WRITE_64BIT_DATA (to, right, left)
-
- return 0;
-}
-
-static ssize_t
-des_encrypt(PurpleCipherContext *context, const guchar input[], size_t in_len,
- guchar output[], size_t out_size)
-{
- gsize offset = 0;
- int i = 0;
- gsize tmp;
- guint8 buf[8] = {0,0,0,0,0,0,0,0};
- gsize out_len;
-
- g_return_val_if_fail(out_size >= in_len, -1);
-
- while(offset+8<=in_len) {
- des_ecb_crypt(purple_cipher_context_get_data(context),
- input+offset,
- output+offset,
- 0);
- offset+=8;
- }
- out_len = in_len;
- if(offset<in_len) {
- g_return_val_if_fail(in_len >= offset, -1);
- out_len += in_len - offset;
- g_return_val_if_fail(out_size >= out_len, -1);
- tmp = offset;
- while(tmp<in_len) {
- buf[i++] = input[tmp];
- tmp++;
- }
- des_ecb_crypt(purple_cipher_context_get_data(context),
- buf,
- output+offset,
- 0);
- }
- return out_len;
-}
-
-static ssize_t
-des_decrypt(PurpleCipherContext *context, const guchar input[], size_t in_len,
- guchar output[], size_t out_size)
-{
- gsize offset = 0;
- int i = 0;
- gsize tmp;
- guint8 buf[8] = {0,0,0,0,0,0,0,0};
- gsize out_len;
-
- g_return_val_if_fail(out_size >= in_len, -1);
-
- while(offset+8<=in_len) {
- des_ecb_crypt(purple_cipher_context_get_data(context),
- input+offset,
- output+offset,
- 1);
- offset+=8;
- }
- out_len = in_len;
- if(offset<in_len) {
- g_return_val_if_fail(in_len >= offset, -1);
- out_len += in_len - offset;
- g_return_val_if_fail(out_size >= out_len, -1);
- tmp = offset;
- while(tmp<in_len) {
- buf[i++] = input[tmp];
- tmp++;
- }
- des_ecb_crypt(purple_cipher_context_get_data(context),
- buf,
- output+offset,
- 1);
- }
- return out_len;
-}
-
-static void
-des_init(PurpleCipherContext *context, gpointer extra) {
- struct _des_ctx *mctx;
- mctx = g_new0(struct _des_ctx, 1);
- purple_cipher_context_set_data(context, mctx);
-}
-
-static void
-des_uninit(PurpleCipherContext *context) {
- struct _des_ctx *des_context;
-
- des_context = purple_cipher_context_get_data(context);
- memset(des_context, 0, sizeof(*des_context));
-
- g_free(des_context);
- des_context = NULL;
-}
-
-static PurpleCipherOps DESOps = {
- NULL, /* Set option */
- NULL, /* Get option */
- des_init, /* init */
- NULL, /* reset */
- NULL, /* reset state */
- des_uninit, /* uninit */
- NULL, /* set iv */
- NULL, /* append */
- NULL, /* digest */
- NULL, /* get_digest_size */
- des_encrypt, /* encrypt */
- des_decrypt, /* decrypt */
- NULL, /* set salt */
- NULL, /* get salt size */
- des_set_key, /* set key */
- des_get_key_size, /* get key size */
- NULL, /* set batch mode */
- NULL, /* get batch mode */
- NULL, /* get block size */
- NULL, NULL, NULL, NULL /* reserved */
-};
-
-/******************************************************************************
- * Triple-DES
- *****************************************************************************/
-
-typedef struct _des3_ctx
-{
- PurpleCipherBatchMode mode;
- guchar iv[8];
- /* First key for encryption */
- struct _des_ctx key1;
- /* Second key for decryption */
- struct _des_ctx key2;
- /* Third key for encryption */
- struct _des_ctx key3;
-} des3_ctx[1];
-
-/*
- * Fill a DES3 context with subkeys calculated from 3 64bit key.
- * Does not check parity bits, but simply ignore them.
- * Does not check for weak keys.
- **/
-static void
-des3_set_key(PurpleCipherContext *context, const guchar * key, size_t len)
-{
- struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
- int i;
-
- g_return_if_fail(len == 24);
-
- des_key_schedule (key + 0, ctx->key1.encrypt_subkeys);
- des_key_schedule (key + 8, ctx->key2.encrypt_subkeys);
- des_key_schedule (key + 16, ctx->key3.encrypt_subkeys);
-
- for (i = 0; i < 32; i += 2)
- {
- ctx->key1.decrypt_subkeys[i] = ctx->key1.encrypt_subkeys[30-i];
- ctx->key1.decrypt_subkeys[i+1] = ctx->key1.encrypt_subkeys[31-i];
- ctx->key2.decrypt_subkeys[i] = ctx->key2.encrypt_subkeys[30-i];
- ctx->key2.decrypt_subkeys[i+1] = ctx->key2.encrypt_subkeys[31-i];
- ctx->key3.decrypt_subkeys[i] = ctx->key3.encrypt_subkeys[30-i];
- ctx->key3.decrypt_subkeys[i+1] = ctx->key3.encrypt_subkeys[31-i];
- }
-}
-
-static size_t
-des3_get_key_size(PurpleCipherContext *context)
-{
- return 24;
-}
-
-static ssize_t
-des3_ecb_encrypt(struct _des3_ctx *ctx, const guchar input[], size_t in_len,
- guchar output[], size_t out_size)
-{
- gsize offset = 0;
- int i = 0;
- gsize tmp;
- guint8 buf[8] = {0,0,0,0,0,0,0,0};
- gsize out_len;
-
- g_return_val_if_fail(out_size >= in_len, -1);
-
- while (offset + 8 <= in_len) {
- des_ecb_crypt(&ctx->key1,
- input+offset,
- output+offset,
- 0);
- des_ecb_crypt(&ctx->key2,
- output+offset,
- buf,
- 1);
- des_ecb_crypt(&ctx->key3,
- buf,
- output+offset,
- 0);
- offset += 8;
- }
- out_len = in_len;
- if (offset < in_len) {
- g_return_val_if_fail(in_len >= offset, -1);
- out_len += in_len - offset;
- g_return_val_if_fail(out_size >= out_len, -1);
- tmp = offset;
- memset(buf, 0, 8);
- while (tmp < in_len) {
- buf[i++] = input[tmp];
- tmp++;
- }
- des_ecb_crypt(&ctx->key1,
- buf,
- output+offset,
- 0);
- des_ecb_crypt(&ctx->key2,
- output+offset,
- buf,
- 1);
- des_ecb_crypt(&ctx->key3,
- buf,
- output+offset,
- 0);
- }
- return out_len;
-}
-
-static ssize_t
-des3_cbc_encrypt(struct _des3_ctx *ctx, const guchar input[], size_t in_len,
- guchar output[], size_t out_size)
-{
- gsize offset = 0;
- int i = 0;
- gsize tmp;
- guint8 buf[8];
- gsize out_len;
- memcpy(buf, ctx->iv, 8);
-
- g_return_val_if_fail(out_size >= in_len, -1);
-
- while (offset + 8 <= in_len) {
- for (i = 0; i < 8; i++)
- buf[i] ^= input[offset + i];
-
- des_ecb_crypt(&ctx->key1,
- buf,
- output+offset,
- 0);
- des_ecb_crypt(&ctx->key2,
- output+offset,
- buf,
- 1);
- des_ecb_crypt(&ctx->key3,
- buf,
- output+offset,
- 0);
- memcpy(buf, output+offset, 8);
- offset += 8;
- }
- out_len = in_len;
- if (offset < in_len) {
- g_return_val_if_fail(in_len >= offset, -1);
- out_len += in_len - offset;
- g_return_val_if_fail(out_size >= out_len, -1);
- tmp = offset;
- i = 0;
- while (tmp < in_len) {
- buf[i++] ^= input[tmp];
- tmp++;
- }
- des_ecb_crypt(&ctx->key1,
- buf,
- output+offset,
- 0);
- des_ecb_crypt(&ctx->key2,
- output+offset,
- buf,
- 1);
- des_ecb_crypt(&ctx->key3,
- buf,
- output+offset,
- 0);
- }
- return out_len;
-}
-
-static ssize_t
-des3_encrypt(PurpleCipherContext *context, const guchar input[], size_t in_len,
- guchar output[], size_t out_size)
-{
- struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
-
- if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_ECB) {
- return des3_ecb_encrypt(ctx, input, in_len, output, out_size);
- } else if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_CBC) {
- return des3_cbc_encrypt(ctx, input, in_len, output, out_size);
- } else {
- g_return_val_if_reached(0);
- }
-
- return 0;
-}
-
-static ssize_t
-des3_ecb_decrypt(struct _des3_ctx *ctx, const guchar input[], size_t in_len,
- guchar output[], size_t out_size)
-{
- gsize offset = 0;
- int i = 0;
- gsize tmp;
- guint8 buf[8] = {0,0,0,0,0,0,0,0};
- gsize out_len;
-
- g_return_val_if_fail(out_size >= in_len, -1);
-
- while (offset + 8 <= in_len) {
- /* NOTE: Apply key in reverse */
- des_ecb_crypt(&ctx->key3,
- input+offset,
- output+offset,
- 1);
- des_ecb_crypt(&ctx->key2,
- output+offset,
- buf,
- 0);
- des_ecb_crypt(&ctx->key1,
- buf,
- output+offset,
- 1);
- offset+=8;
- }
- out_len = in_len;
- if (offset < in_len) {
- g_return_val_if_fail(in_len >= offset, -1);
- out_len += in_len - offset;
- g_return_val_if_fail(out_size >= out_len, -1);
- tmp = offset;
- memset(buf, 0, 8);
- while (tmp < in_len) {
- buf[i++] = input[tmp];
- tmp++;
- }
- des_ecb_crypt(&ctx->key3,
- buf,
- output+offset,
- 1);
- des_ecb_crypt(&ctx->key2,
- output+offset,
- buf,
- 0);
- des_ecb_crypt(&ctx->key1,
- buf,
- output+offset,
- 1);
- }
- return out_len;
-}
-
-static ssize_t
-des3_cbc_decrypt(struct _des3_ctx *ctx, const guchar input[], size_t in_len,
- guchar output[], size_t out_size)
-{
- gsize offset = 0;
- int i = 0;
- gsize tmp;
- guint8 buf[8] = {0,0,0,0,0,0,0,0};
- guint8 link[8];
- gsize out_len;
-
- g_return_val_if_fail(out_size >= in_len, -1);
-
- memcpy(link, ctx->iv, 8);
- while (offset + 8 <= in_len) {
- des_ecb_crypt(&ctx->key3,
- input+offset,
- output+offset,
- 1);
- des_ecb_crypt(&ctx->key2,
- output+offset,
- buf,
- 0);
- des_ecb_crypt(&ctx->key1,
- buf,
- output+offset,
- 1);
- for (i = 0; i < 8; i++)
- output[offset + i] ^= link[i];
- memcpy(link, input + offset, 8);
- offset+=8;
- }
- out_len = in_len;
- if(offset<in_len) {
- g_return_val_if_fail(in_len >= offset, -1);
- out_len += in_len - offset;
- g_return_val_if_fail(out_size >= out_len, -1);
- tmp = offset;
- memset(buf, 0, 8);
- i = 0;
- while(tmp<in_len) {
- buf[i++] = input[tmp];
- tmp++;
- }
- des_ecb_crypt(&ctx->key3,
- buf,
- output+offset,
- 1);
- des_ecb_crypt(&ctx->key2,
- output+offset,
- buf,
- 0);
- des_ecb_crypt(&ctx->key1,
- buf,
- output+offset,
- 1);
- for (i = 0; i < 8; i++)
- output[offset + i] ^= link[i];
- }
- return out_len;
-}
-
-static ssize_t
-des3_decrypt(PurpleCipherContext *context, const guchar input[], size_t in_len,
- guchar output[], size_t out_size)
-{
- struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
-
- if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_ECB) {
- return des3_ecb_decrypt(ctx, input, in_len, output, out_size);
- } else if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_CBC) {
- return des3_cbc_decrypt(ctx, input, in_len, output, out_size);
- } else {
- g_return_val_if_reached(0);
- }
-
- return 0;
-}
-
-static void
-des3_set_batch(PurpleCipherContext *context, PurpleCipherBatchMode mode)
-{
- struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
-
- ctx->mode = mode;
-}
-
-static PurpleCipherBatchMode
-des3_get_batch(PurpleCipherContext *context)
-{
- struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
-
- return ctx->mode;
-}
-
-static void
-des3_set_iv(PurpleCipherContext *context, guchar *iv, size_t len)
-{
- struct _des3_ctx *ctx;
-
- g_return_if_fail(len == 8);
-
- ctx = purple_cipher_context_get_data(context);
-
- memcpy(ctx->iv, iv, len);
-}
-
-static void
-des3_init(PurpleCipherContext *context, gpointer extra)
-{
- struct _des3_ctx *mctx;
- mctx = g_new0(struct _des3_ctx, 1);
- purple_cipher_context_set_data(context, mctx);
-}
-
-static void
-des3_uninit(PurpleCipherContext *context)
-{
- struct _des3_ctx *des3_context;
-
- des3_context = purple_cipher_context_get_data(context);
- memset(des3_context, 0, sizeof(*des3_context));
-
- g_free(des3_context);
- des3_context = NULL;
-}
-
-static PurpleCipherOps DES3Ops = {
- NULL, /* Set option */
- NULL, /* Get option */
- des3_init, /* init */
- NULL, /* reset */
- NULL, /* reset state */
- des3_uninit, /* uninit */
- des3_set_iv, /* set iv */
- NULL, /* append */
- NULL, /* digest */
- NULL, /* get_digest_size */
- des3_encrypt, /* encrypt */
- des3_decrypt, /* decrypt */
- NULL, /* set salt */
- NULL, /* get salt size */
- des3_set_key, /* set key */
- des3_get_key_size, /* get_key_size */
- des3_set_batch, /* set batch mode */
- des3_get_batch, /* get batch mode */
- NULL, /* get block size */
- NULL, NULL, NULL, NULL /* reserved */
-};
-
-/******************************************************************************
- * Registration
- *****************************************************************************/
-PurpleCipherOps *
-purple_des_cipher_get_ops(void) {
- return &DESOps;
-}
-
-PurpleCipherOps *
-purple_des3_cipher_get_ops(void) {
- return &DES3Ops;
-}
diff --git a/libpurple/ciphers/des3cipher.c b/libpurple/ciphers/des3cipher.c
new file mode 100644
index 0000000000..9ede05a032
--- /dev/null
+++ b/libpurple/ciphers/des3cipher.c
@@ -0,0 +1,529 @@
+/*
+ * Original des taken from gpg
+ *
+ * des.c - Triple-DES encryption/decryption Algorithm
+ * Copyright (C) 1998 Free Software Foundation, Inc.
+ *
+ * Please see below for more legal information!
+ *
+ * According to the definition of DES in FIPS PUB 46-2 from December 1993.
+ * For a description of triple encryption, see:
+ * Bruce Schneier: Applied Cryptography. Second Edition.
+ * John Wiley & Sons, 1996. ISBN 0-471-12845-7. Pages 358 ff.
+ *
+ * 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
+ */
+#include "des3cipher.h"
+#include "descipher.h"
+#include "enums.h"
+
+#include <string.h>
+
+/******************************************************************************
+ * Structs
+ *****************************************************************************/
+
+#define PURPLE_DES3_CIPHER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_DES3_CIPHER, PurpleDES3CipherPrivate))
+
+typedef struct _PurpleDES3CipherPrivate PurpleDES3CipherPrivate;
+struct _PurpleDES3CipherPrivate
+{
+ PurpleCipherBatchMode mode;
+ guchar iv[8];
+ /* First key for encryption */
+ PurpleCipher *key1;
+ /* Second key for decryption */
+ PurpleCipher *key2;
+ /* Third key for encryption */
+ PurpleCipher *key3;
+};
+
+/******************************************************************************
+ * Enums
+ *****************************************************************************/
+enum {
+ PROP_NONE,
+ PROP_BATCH_MODE,
+ PROP_IV,
+ PROP_KEY,
+ PROP_LAST,
+};
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+static GObjectClass *parent_class = NULL;
+
+/******************************************************************************
+ * Cipher Stuff
+ *****************************************************************************/
+
+static size_t
+purple_des3_cipher_get_key_size(PurpleCipher *cipher)
+{
+ return 24;
+}
+
+/*
+ * Fill a DES3 context with subkeys calculated from 3 64bit key.
+ * Does not check parity bits, but simply ignore them.
+ * Does not check for weak keys.
+ **/
+static void
+purple_des3_cipher_set_key(PurpleCipher *cipher, const guchar *key, size_t len)
+{
+ PurpleDES3Cipher *des3_cipher = PURPLE_DES3_CIPHER(cipher);
+ PurpleDES3CipherPrivate *priv = PURPLE_DES3_CIPHER_GET_PRIVATE(des3_cipher);
+
+ g_return_if_fail(len == 24);
+
+ purple_cipher_set_key(PURPLE_CIPHER(priv->key1), key + 0,
+ purple_cipher_get_key_size(PURPLE_CIPHER(priv->key1)));
+ purple_cipher_set_key(PURPLE_CIPHER(priv->key2), key + 8,
+ purple_cipher_get_key_size(PURPLE_CIPHER(priv->key2)));
+ purple_cipher_set_key(PURPLE_CIPHER(priv->key3), key + 16,
+ purple_cipher_get_key_size(PURPLE_CIPHER(priv->key3)));
+
+ g_object_notify(G_OBJECT(des3_cipher), "key");
+}
+
+static ssize_t
+purple_des3_cipher_ecb_encrypt(PurpleDES3Cipher *des3_cipher, const guchar input[],
+ size_t in_len, guchar output[], size_t out_size)
+{
+ gsize offset = 0;
+ int i = 0;
+ gsize tmp;
+ guint8 buf[8] = {0,0,0,0,0,0,0,0};
+ gsize out_len;
+ PurpleDES3CipherPrivate *priv = PURPLE_DES3_CIPHER_GET_PRIVATE(des3_cipher);
+
+ g_return_val_if_fail(out_size >= in_len, -1);
+
+ while (offset + 8 <= in_len) {
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key1),
+ input + offset, output + offset, 0);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key2),
+ output + offset, buf, 1);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key3),
+ buf, output + offset, 0);
+
+ offset += 8;
+ }
+
+ out_len = in_len;
+ if (offset < in_len) {
+ g_return_val_if_fail(in_len >= offset, -1);
+ out_len += in_len - offset;
+ g_return_val_if_fail(out_size >= out_len, -1);
+ tmp = offset;
+ memset(buf, 0, 8);
+ while (tmp < in_len) {
+ buf[i++] = input[tmp];
+ tmp++;
+ }
+
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key1),
+ buf, output + offset, 0);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key2),
+ output + offset, buf, 1);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key3),
+ buf, output + offset, 0);
+ }
+
+ return out_len;
+}
+
+static ssize_t
+purple_des3_cipher_cbc_encrypt(PurpleDES3Cipher *des3_cipher, const guchar input[],
+ size_t in_len, guchar output[], size_t out_size)
+{
+ gsize offset = 0;
+ int i = 0;
+ gsize tmp;
+ guint8 buf[8];
+ gsize out_len;
+ PurpleDES3CipherPrivate *priv = PURPLE_DES3_CIPHER_GET_PRIVATE(des3_cipher);
+
+ memcpy(buf, priv->iv, 8);
+
+ g_return_val_if_fail(out_size >= in_len, -1);
+
+ while (offset + 8 <= in_len) {
+ for (i = 0; i < 8; i++)
+ buf[i] ^= input[offset + i];
+
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key1),
+ buf, output + offset, 0);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key2),
+ output + offset, buf, 1);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key3),
+ buf, output + offset, 0);
+
+ memcpy(buf, output+offset, 8);
+ offset += 8;
+ }
+
+ out_len = in_len;
+ if (offset < in_len) {
+ g_return_val_if_fail(in_len >= offset, -1);
+ out_len += in_len - offset;
+ g_return_val_if_fail(out_size >= out_len, -1);
+ tmp = offset;
+ i = 0;
+ while (tmp < in_len) {
+ buf[i++] ^= input[tmp];
+ tmp++;
+ }
+
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key1),
+ buf, output + offset, 0);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key2),
+ output + offset, buf, 1);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key3),
+ buf, output + offset, 0);
+ }
+
+ return out_len;
+}
+
+static ssize_t
+purple_des3_cipher_encrypt(PurpleCipher *cipher, const guchar input[],
+ size_t in_len, guchar output[], size_t out_size)
+{
+ PurpleDES3Cipher *des3_cipher = PURPLE_DES3_CIPHER(cipher);
+ PurpleDES3CipherPrivate *priv = PURPLE_DES3_CIPHER_GET_PRIVATE(des3_cipher);
+
+ if (priv->mode == PURPLE_CIPHER_BATCH_MODE_ECB) {
+ return purple_des3_cipher_ecb_encrypt(des3_cipher, input, in_len, output, out_size);
+ } else if (priv->mode == PURPLE_CIPHER_BATCH_MODE_CBC) {
+ return purple_des3_cipher_cbc_encrypt(des3_cipher, input, in_len, output, out_size);
+ } else {
+ g_return_val_if_reached(0);
+ }
+
+ return 0;
+}
+
+static ssize_t
+purple_des3_cipher_ecb_decrypt(PurpleDES3Cipher *des3_cipher, const guchar input[],
+ size_t in_len, guchar output[], size_t out_size)
+{
+ gsize offset = 0;
+ int i = 0;
+ gsize tmp;
+ guint8 buf[8] = {0,0,0,0,0,0,0,0};
+ gsize out_len;
+ PurpleDES3CipherPrivate *priv = PURPLE_DES3_CIPHER_GET_PRIVATE(des3_cipher);
+
+ g_return_val_if_fail(out_size >= in_len, -1);
+
+ while (offset + 8 <= in_len) {
+ /* NOTE: Apply key in reverse */
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key3),
+ input + offset, output + offset, 1);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key2),
+ output + offset, buf, 0);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key1),
+ buf, output + offset, 1);
+
+ offset += 8;
+ }
+
+ out_len = in_len;
+ if (offset < in_len) {
+ g_return_val_if_fail(in_len >= offset, -1);
+ out_len += in_len - offset;
+ g_return_val_if_fail(out_size >= out_len, -1);
+ tmp = offset;
+ memset(buf, 0, 8);
+ while (tmp < in_len) {
+ buf[i++] = input[tmp];
+ tmp++;
+ }
+
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key3),
+ buf, output + offset, 1);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key2),
+ output + offset, buf, 0);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key1),
+ buf, output + offset, 1);
+ }
+
+ return out_len;
+}
+
+static ssize_t
+purple_des3_cipher_cbc_decrypt(PurpleDES3Cipher *des3_cipher, const guchar input[],
+ size_t in_len, guchar output[], size_t out_size)
+{
+ gsize offset = 0;
+ int i = 0;
+ gsize tmp;
+ guint8 buf[8] = {0,0,0,0,0,0,0,0};
+ guint8 link[8];
+ gsize out_len;
+ PurpleDES3CipherPrivate *priv = PURPLE_DES3_CIPHER_GET_PRIVATE(des3_cipher);
+
+ g_return_val_if_fail(out_size >= in_len, -1);
+
+ memcpy(link, priv->iv, 8);
+ while (offset + 8 <= in_len) {
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key3),
+ input + offset, output + offset, 1);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key2),
+ output + offset, buf, 0);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key1),
+ buf, output + offset, 1);
+
+ for (i = 0; i < 8; i++)
+ output[offset + i] ^= link[i];
+
+ memcpy(link, input + offset, 8);
+
+ offset+=8;
+ }
+
+ out_len = in_len;
+ if(offset<in_len) {
+ g_return_val_if_fail(in_len >= offset, -1);
+ out_len += in_len - offset;
+ g_return_val_if_fail(out_size >= out_len, -1);
+ tmp = offset;
+ memset(buf, 0, 8);
+ i = 0;
+ while(tmp<in_len) {
+ buf[i++] = input[tmp];
+ tmp++;
+ }
+
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key3),
+ buf, output + offset, 1);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key2),
+ output + offset, buf, 0);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(priv->key1),
+ buf, output + offset, 1);
+
+ for (i = 0; i < 8; i++)
+ output[offset + i] ^= link[i];
+ }
+
+ return out_len;
+}
+
+static ssize_t
+purple_des3_cipher_decrypt(PurpleCipher *cipher, const guchar input[],
+ size_t in_len, guchar output[], size_t out_size)
+{
+ PurpleDES3Cipher *des3_cipher = PURPLE_DES3_CIPHER(cipher);
+ PurpleDES3CipherPrivate *priv = PURPLE_DES3_CIPHER_GET_PRIVATE(cipher);
+
+ if (priv->mode == PURPLE_CIPHER_BATCH_MODE_ECB) {
+ return purple_des3_cipher_ecb_decrypt(des3_cipher, input, in_len, output, out_size);
+ } else if (priv->mode == PURPLE_CIPHER_BATCH_MODE_CBC) {
+ return purple_des3_cipher_cbc_decrypt(des3_cipher, input, in_len, output, out_size);
+ } else {
+ g_return_val_if_reached(0);
+ }
+
+ return 0;
+}
+
+static void
+purple_des3_cipher_set_batch_mode(PurpleCipher *cipher, PurpleCipherBatchMode mode)
+{
+ PurpleDES3Cipher *des3_cipher = PURPLE_DES3_CIPHER(cipher);
+ PurpleDES3CipherPrivate *priv = PURPLE_DES3_CIPHER_GET_PRIVATE(des3_cipher);
+
+ priv->mode = mode;
+
+ g_object_notify(G_OBJECT(des3_cipher), "batch_mode");
+}
+
+static PurpleCipherBatchMode
+purple_des3_cipher_get_batch_mode(PurpleCipher *cipher)
+{
+ PurpleDES3Cipher *des3_cipher = PURPLE_DES3_CIPHER(cipher);
+ PurpleDES3CipherPrivate *priv = PURPLE_DES3_CIPHER_GET_PRIVATE(des3_cipher);
+
+ return priv->mode;
+}
+
+static void
+purple_des3_cipher_set_iv(PurpleCipher *cipher, guchar *iv, size_t len)
+{
+ PurpleDES3Cipher *des3_cipher = PURPLE_DES3_CIPHER(cipher);
+ PurpleDES3CipherPrivate *priv = PURPLE_DES3_CIPHER_GET_PRIVATE(des3_cipher);
+
+ g_return_if_fail(len == 8);
+
+ memcpy(priv->iv, iv, len);
+
+ g_object_notify(G_OBJECT(des3_cipher), "iv");
+}
+
+static const gchar*
+purple_des3_cipher_get_name(PurpleCipher *cipher)
+{
+ return "des3";
+}
+
+/******************************************************************************
+ * Object Stuff
+ *****************************************************************************/
+static void
+purple_des3_cipher_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleCipher *cipher = PURPLE_CIPHER(obj);
+
+ switch(param_id) {
+ case PROP_BATCH_MODE:
+ g_value_set_enum(value,
+ purple_cipher_get_batch_mode(cipher));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_des3_cipher_set_property(GObject *obj, guint param_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ PurpleCipher *cipher = PURPLE_CIPHER(obj);
+
+ switch(param_id) {
+ case PROP_BATCH_MODE:
+ purple_cipher_set_batch_mode(cipher,
+ g_value_get_enum(value));
+ break;
+ case PROP_IV:
+ {
+ guchar *iv = (guchar *)g_value_get_string(value);
+ purple_cipher_set_iv(cipher, iv, strlen((gchar*)iv));
+ }
+ break;
+ case PROP_KEY:
+ purple_cipher_set_key(cipher, (guchar *)g_value_get_string(value),
+ purple_des3_cipher_get_key_size(cipher));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_des3_cipher_finalize(GObject *obj)
+{
+ PurpleDES3Cipher *des3_cipher = PURPLE_DES3_CIPHER(obj);
+ PurpleDES3CipherPrivate *priv = PURPLE_DES3_CIPHER_GET_PRIVATE(des3_cipher);
+
+ g_object_unref(G_OBJECT(priv->key1));
+ g_object_unref(G_OBJECT(priv->key2));
+ g_object_unref(G_OBJECT(priv->key3));
+
+ memset(priv->iv, 0, sizeof(priv->iv));
+
+ parent_class->finalize(obj);
+}
+
+static void
+purple_des3_cipher_class_init(PurpleDES3CipherClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ PurpleCipherClass *cipher_class = PURPLE_CIPHER_CLASS(klass);
+ GParamSpec *pspec;
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->finalize = purple_des3_cipher_finalize;
+ obj_class->get_property = purple_des3_cipher_get_property;
+ obj_class->set_property = purple_des3_cipher_set_property;
+
+ cipher_class->set_iv = purple_des3_cipher_set_iv;
+ cipher_class->encrypt = purple_des3_cipher_encrypt;
+ cipher_class->decrypt = purple_des3_cipher_decrypt;
+ cipher_class->set_key = purple_des3_cipher_set_key;
+ cipher_class->set_batch_mode = purple_des3_cipher_set_batch_mode;
+ cipher_class->get_batch_mode = purple_des3_cipher_get_batch_mode;
+ cipher_class->get_key_size = purple_des3_cipher_get_key_size;
+ cipher_class->get_name = purple_des3_cipher_get_name;
+
+ pspec = g_param_spec_enum("batch_mode", "batch_mode", "batch_mode",
+ PURPLE_TYPE_CIPHER_BATCH_MODE, 0,
+ G_PARAM_READWRITE);
+ g_object_class_install_property(obj_class, PROP_BATCH_MODE, pspec);
+
+ pspec = g_param_spec_string("iv", "iv", "iv", NULL,
+ G_PARAM_WRITABLE);
+ g_object_class_install_property(obj_class, PROP_IV, pspec);
+
+ pspec = g_param_spec_string("key", "key", "key", NULL,
+ G_PARAM_WRITABLE);
+ g_object_class_install_property(obj_class, PROP_KEY, pspec);
+
+ g_type_class_add_private(klass, sizeof(PurpleDES3CipherPrivate));
+}
+
+static void
+purple_des3_cipher_init(PurpleCipher *cipher) {
+ PurpleDES3Cipher *des3_cipher = PURPLE_DES3_CIPHER(cipher);
+ PurpleDES3CipherPrivate *priv = PURPLE_DES3_CIPHER_GET_PRIVATE(des3_cipher);
+
+ priv->key1 = purple_des_cipher_new();
+ priv->key2 = purple_des_cipher_new();
+ priv->key3 = purple_des_cipher_new();
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GType
+purple_des3_cipher_get_gtype(void) {
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleDES3CipherClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_des3_cipher_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleDES3Cipher),
+ 0,
+ (GInstanceInitFunc)purple_des3_cipher_init,
+ NULL
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_CIPHER,
+ "PurpleDES3Cipher",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleCipher *
+purple_des3_cipher_new(void) {
+ return g_object_new(PURPLE_TYPE_DES3_CIPHER, NULL);
+}
diff --git a/libpurple/ciphers/des3cipher.h b/libpurple/ciphers/des3cipher.h
new file mode 100644
index 0000000000..c981dc4b32
--- /dev/null
+++ b/libpurple/ciphers/des3cipher.h
@@ -0,0 +1,65 @@
+/**
+ * @file des3.h Purple Triple-DES Cipher
+ * @ingroup core
+ */
+
+/* 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 PURPLE_DES3_CIPHER_H
+#define PURPLE_DES3_CIPHER_H
+
+#include "cipher.h"
+
+#define PURPLE_TYPE_DES3_CIPHER (purple_des3_cipher_get_gtype())
+#define PURPLE_DES3_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_DES3_CIPHER, PurpleDES3Cipher))
+#define PURPLE_DES3_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_DES3_CIPHER, PurpleDES3CipherClass))
+#define PURPLE_IS_DES3_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_DES3_CIPHER))
+#define PURPLE_IS_DES3_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), PURPLE_TYPE_DES3_CIPHER))
+#define PURPLE_DES3_CIPHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_DES3_CIPHER, PurpleDES3CipherClass))
+
+typedef struct _PurpleDES3Cipher PurpleDES3Cipher;
+typedef struct _PurpleDES3CipherClass PurpleDES3CipherClass;
+
+struct _PurpleDES3Cipher {
+ /*< private >*/
+ PurpleCipher gparent;
+};
+
+struct _PurpleDES3CipherClass {
+ /*< private >*/
+ PurpleCipherClass gparent;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType purple_des3_cipher_get_gtype(void);
+
+PurpleCipher *purple_des3_cipher_new(void);
+
+G_END_DECLS
+
+#endif /* PURPLE_DES3_CIPHER_H */
+
diff --git a/libpurple/ciphers/descipher.c b/libpurple/ciphers/descipher.c
new file mode 100644
index 0000000000..759862f628
--- /dev/null
+++ b/libpurple/ciphers/descipher.c
@@ -0,0 +1,585 @@
+/*
+ * Original des taken from gpg
+ *
+ * des.c - DES encryption/decryption Algorithm
+ * Copyright (C) 1998 Free Software Foundation, Inc.
+ *
+ * Please see below for more legal information!
+ *
+ * According to the definition of DES in FIPS PUB 46-2 from December 1993.
+ * For a description of triple encryption, see:
+ * Bruce Schneier: Applied Cryptography. Second Edition.
+ * John Wiley & Sons, 1996. ISBN 0-471-12845-7. Pages 358 ff.
+ *
+ * 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
+ */
+#include "descipher.h"
+#include "enums.h"
+
+#include <string.h>
+
+/******************************************************************************
+ * Structs
+ *****************************************************************************/
+#define PURPLE_DES_CIPHER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_DES_CIPHER, PurpleDESCipherPrivate))
+
+typedef struct {
+ guint32 encrypt_subkeys[32];
+ guint32 decrypt_subkeys[32];
+} PurpleDESCipherPrivate;
+
+/******************************************************************************
+ * Enums
+ *****************************************************************************/
+enum {
+ PROP_NONE,
+ PROP_KEY,
+ PROP_LAST,
+};
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+static GObjectClass *parent_class = NULL;
+
+/*
+ * The s-box values are permuted according to the 'primitive function P'
+ */
+static guint32 sbox1[64] = {
+ 0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202,
+ 0x00000002, 0x00008000, 0x00000200, 0x00808200, 0x00808202, 0x00000200,
+ 0x00800202, 0x00808002, 0x00800000, 0x00000002, 0x00000202, 0x00800200,
+ 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202,
+ 0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202,
+ 0x00008202, 0x00800000, 0x00008000, 0x00808202, 0x00000002, 0x00808000,
+ 0x00808200, 0x00800000, 0x00800000, 0x00000200, 0x00808002, 0x00008000,
+ 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202,
+ 0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202,
+ 0x00008202, 0x00808200, 0x00000202, 0x00800200, 0x00800200, 0x00000000,
+ 0x00008002, 0x00008200, 0x00000000, 0x00808002
+};
+
+static guint32 sbox2[64] = {
+ 0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010,
+ 0x40080010, 0x40004010, 0x40000010, 0x40084010, 0x40084000, 0x40000000,
+ 0x40004000, 0x00080000, 0x00000010, 0x40080010, 0x00084000, 0x00080010,
+ 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000,
+ 0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000,
+ 0x40080000, 0x00004010, 0x00000000, 0x00084010, 0x40080010, 0x00080000,
+ 0x40004010, 0x40080000, 0x40084000, 0x00004000, 0x40080000, 0x40004000,
+ 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000,
+ 0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010,
+ 0x40000010, 0x00080010, 0x00084000, 0x00000000, 0x40004000, 0x00004010,
+ 0x40000000, 0x40080010, 0x40084010, 0x00084000
+};
+
+static guint32 sbox3[64] = {
+ 0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000,
+ 0x00010104, 0x04000100, 0x00010004, 0x04000004, 0x04000004, 0x00010000,
+ 0x04010104, 0x00010004, 0x04010000, 0x00000104, 0x04000000, 0x00000004,
+ 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104,
+ 0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104,
+ 0x00000100, 0x04000000, 0x04010100, 0x04000000, 0x00010004, 0x00000104,
+ 0x00010000, 0x04010100, 0x04000100, 0x00000000, 0x00000100, 0x00010004,
+ 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004,
+ 0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104,
+ 0x00010100, 0x04000004, 0x04010000, 0x04000104, 0x00000104, 0x04010000,
+ 0x00010104, 0x00000004, 0x04010004, 0x00010100
+};
+
+static guint32 sbox4[64] = {
+ 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040,
+ 0x80400000, 0x80001000, 0x00000000, 0x00401000, 0x00401000, 0x80401040,
+ 0x80000040, 0x00000000, 0x00400040, 0x80400000, 0x80000000, 0x00001000,
+ 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040,
+ 0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040,
+ 0x80401040, 0x80000040, 0x00400040, 0x80400000, 0x00401000, 0x80401040,
+ 0x80000040, 0x00000000, 0x00000000, 0x00401000, 0x00001040, 0x00400040,
+ 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040,
+ 0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000,
+ 0x00401040, 0x80400040, 0x80001000, 0x00001040, 0x00400000, 0x80401000,
+ 0x00000040, 0x00400000, 0x00001000, 0x00401040
+};
+
+static guint32 sbox5[64] = {
+ 0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080,
+ 0x20000000, 0x01040000, 0x20040080, 0x00040000, 0x01000080, 0x20040080,
+ 0x21000080, 0x21040000, 0x00040080, 0x20000000, 0x01000000, 0x20040000,
+ 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080,
+ 0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000,
+ 0x21000000, 0x00040080, 0x00040000, 0x21000080, 0x00000080, 0x01000000,
+ 0x20000000, 0x01040000, 0x21000080, 0x20040080, 0x01000080, 0x20000000,
+ 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000,
+ 0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000,
+ 0x20040000, 0x21000000, 0x00040080, 0x01000080, 0x20000080, 0x00040000,
+ 0x00000000, 0x20040000, 0x01040080, 0x20000080
+};
+
+static guint32 sbox6[64] = {
+ 0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008,
+ 0x10202008, 0x00200000, 0x10002000, 0x00202008, 0x00200000, 0x10000008,
+ 0x00200008, 0x10002000, 0x10000000, 0x00002008, 0x00000000, 0x00200008,
+ 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008,
+ 0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000,
+ 0x10202000, 0x10000000, 0x10002000, 0x00000008, 0x10200008, 0x00202000,
+ 0x10202008, 0x00200000, 0x00002008, 0x10000008, 0x00200000, 0x10002000,
+ 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000,
+ 0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000,
+ 0x10200000, 0x00202008, 0x00002000, 0x00200008, 0x10002008, 0x00000000,
+ 0x10202000, 0x10000000, 0x00200008, 0x10002008
+};
+
+static guint32 sbox7[64] = {
+ 0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401,
+ 0x00100401, 0x02100400, 0x02100401, 0x00100000, 0x00000000, 0x02000001,
+ 0x00000001, 0x02000000, 0x02100001, 0x00000401, 0x02000400, 0x00100401,
+ 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001,
+ 0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001,
+ 0x02000000, 0x00100400, 0x02000000, 0x00100400, 0x00100000, 0x02000401,
+ 0x02000401, 0x02100001, 0x02100001, 0x00000001, 0x00100001, 0x02000000,
+ 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400,
+ 0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000,
+ 0x00000001, 0x02100401, 0x00000000, 0x00100401, 0x02100000, 0x00000400,
+ 0x02000001, 0x02000400, 0x00000400, 0x00100001
+};
+
+static guint32 sbox8[64] = {
+ 0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820,
+ 0x00000020, 0x08000000, 0x00020020, 0x08020000, 0x08020820, 0x00020800,
+ 0x08020800, 0x00020820, 0x00000800, 0x00000020, 0x08020000, 0x08000020,
+ 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800,
+ 0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800,
+ 0x00020820, 0x00020000, 0x00020820, 0x00020000, 0x08020800, 0x00000800,
+ 0x00000020, 0x08020020, 0x00000800, 0x00020820, 0x08000800, 0x00000020,
+ 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820,
+ 0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800,
+ 0x08000820, 0x00000000, 0x08020820, 0x00020800, 0x00020800, 0x00000820,
+ 0x00000820, 0x00020020, 0x08000000, 0x08020800
+};
+
+/*
+ * These two tables are part of the 'permuted choice 1' function.
+ * In this implementation several speed improvements are done.
+ */
+static guint32 leftkey_swap[16] = {
+ 0x00000000, 0x00000001, 0x00000100, 0x00000101, 0x00010000, 0x00010001,
+ 0x00010100, 0x00010101, 0x01000000, 0x01000001, 0x01000100, 0x01000101,
+ 0x01010000, 0x01010001, 0x01010100, 0x01010101
+};
+
+static guint32 rightkey_swap[16] = {
+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100,
+ 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001,
+ 0x00000101, 0x01000101, 0x00010101, 0x01010101,
+};
+
+/*
+ * Numbers of left shifts per round for encryption subkey schedule
+ * To calculate the decryption key scheduling we just reverse the
+ * ordering of the subkeys so we can omit the table for decryption
+ * subkey schedule.
+ */
+static guint8 encrypt_rotate_tab[16] = {
+ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+};
+
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+/*
+ * Macro to swap bits across two words
+ */
+#define DO_PERMUTATION(a, temp, b, offset, mask) \
+ temp = ((a>>offset) ^ b) & mask; \
+ b ^= temp; \
+ a ^= temp<<offset;
+
+/*
+ * This performs the 'initial permutation' for the data to be encrypted or
+ * decrypted
+ */
+#define INITIAL_PERMUTATION(left, temp, right) \
+ DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f) \
+ DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
+ DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
+ DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
+ DO_PERMUTATION(left, temp, right, 1, 0x55555555)
+
+/*
+ * The 'inverse initial permutation'
+ */
+#define FINAL_PERMUTATION(left, temp, right) \
+ DO_PERMUTATION(left, temp, right, 1, 0x55555555) \
+ DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
+ DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
+ DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
+ DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f)
+
+/*
+ * A full DES round including 'expansion function', 'sbox substitution'
+ * and 'primitive function P' but without swapping the left and right word.
+ */
+#define DES_ROUND(from, to, work, subkey) \
+ work = ((from<<1) | (from>>31)) ^ *subkey++; \
+ to ^= sbox8[ work & 0x3f ]; \
+ to ^= sbox6[ (work>>8) & 0x3f ]; \
+ to ^= sbox4[ (work>>16) & 0x3f ]; \
+ to ^= sbox2[ (work>>24) & 0x3f ]; \
+ work = ((from>>3) | (from<<29)) ^ *subkey++; \
+ to ^= sbox7[ work & 0x3f ]; \
+ to ^= sbox5[ (work>>8) & 0x3f ]; \
+ to ^= sbox3[ (work>>16) & 0x3f ]; \
+ to ^= sbox1[ (work>>24) & 0x3f ];
+
+
+/*
+ * Macros to convert 8 bytes from/to 32bit words
+ */
+#define READ_64BIT_DATA(data, left, right) \
+ left = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; \
+ right = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
+
+#define WRITE_64BIT_DATA(data, left, right) \
+ data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff; \
+ data[2] = (left >> 8) &0xff; data[3] = left &0xff; \
+ data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff; \
+ data[6] = (right >> 8) &0xff; data[7] = right &0xff;
+
+/******************************************************************************
+ * Cipher Stuff
+ *****************************************************************************/
+/*
+ * des_key_schedule(): Calculate 16 subkeys pairs (even/odd) for
+ * 16 encryption rounds.
+ * To calculate subkeys for decryption the caller
+ * have to reorder the generated subkeys.
+ *
+ * rawkey: 8 Bytes of key data
+ * subkey: Array of at least 32 guint32s. Will be filled
+ * with calculated subkeys.
+ *
+ */
+static void
+purple_des_cipher_key_schedule(const guint8 * rawkey, guint32 * subkey) {
+ guint32 left, right, work;
+ int round;
+
+ READ_64BIT_DATA (rawkey, left, right)
+
+ DO_PERMUTATION (right, work, left, 4, 0x0f0f0f0f)
+ DO_PERMUTATION (right, work, left, 0, 0x10101010)
+
+ left = (leftkey_swap[(left >> 0) & 0xf] << 3)
+ | (leftkey_swap[(left >> 8) & 0xf] << 2)
+ | (leftkey_swap[(left >> 16) & 0xf] << 1)
+ | (leftkey_swap[(left >> 24) & 0xf] )
+ | (leftkey_swap[(left >> 5) & 0xf] << 7)
+ | (leftkey_swap[(left >> 13) & 0xf] << 6)
+ | (leftkey_swap[(left >> 21) & 0xf] << 5)
+ | (leftkey_swap[(left >> 29) & 0xf] << 4);
+
+ left &= 0x0fffffff;
+
+ right = (rightkey_swap[(right >> 1) & 0xf] << 3)
+ | (rightkey_swap[(right >> 9) & 0xf] << 2)
+ | (rightkey_swap[(right >> 17) & 0xf] << 1)
+ | (rightkey_swap[(right >> 25) & 0xf] )
+ | (rightkey_swap[(right >> 4) & 0xf] << 7)
+ | (rightkey_swap[(right >> 12) & 0xf] << 6)
+ | (rightkey_swap[(right >> 20) & 0xf] << 5)
+ | (rightkey_swap[(right >> 28) & 0xf] << 4);
+
+ right &= 0x0fffffff;
+
+ for (round = 0; round < 16; ++round) {
+ left = ((left << encrypt_rotate_tab[round]) |
+ (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
+ right = ((right << encrypt_rotate_tab[round]) |
+ (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
+
+ *subkey++ = ((left << 4) & 0x24000000)
+ | ((left << 28) & 0x10000000)
+ | ((left << 14) & 0x08000000)
+ | ((left << 18) & 0x02080000)
+ | ((left << 6) & 0x01000000)
+ | ((left << 9) & 0x00200000)
+ | ((left >> 1) & 0x00100000)
+ | ((left << 10) & 0x00040000)
+ | ((left << 2) & 0x00020000)
+ | ((left >> 10) & 0x00010000)
+ | ((right >> 13) & 0x00002000)
+ | ((right >> 4) & 0x00001000)
+ | ((right << 6) & 0x00000800)
+ | ((right >> 1) & 0x00000400)
+ | ((right >> 14) & 0x00000200)
+ | (right & 0x00000100)
+ | ((right >> 5) & 0x00000020)
+ | ((right >> 10) & 0x00000010)
+ | ((right >> 3) & 0x00000008)
+ | ((right >> 18) & 0x00000004)
+ | ((right >> 26) & 0x00000002)
+ | ((right >> 24) & 0x00000001);
+
+ *subkey++ = ((left << 15) & 0x20000000)
+ | ((left << 17) & 0x10000000)
+ | ((left << 10) & 0x08000000)
+ | ((left << 22) & 0x04000000)
+ | ((left >> 2) & 0x02000000)
+ | ((left << 1) & 0x01000000)
+ | ((left << 16) & 0x00200000)
+ | ((left << 11) & 0x00100000)
+ | ((left << 3) & 0x00080000)
+ | ((left >> 6) & 0x00040000)
+ | ((left << 15) & 0x00020000)
+ | ((left >> 4) & 0x00010000)
+ | ((right >> 2) & 0x00002000)
+ | ((right << 8) & 0x00001000)
+ | ((right >> 14) & 0x00000808)
+ | ((right >> 9) & 0x00000400)
+ | ((right) & 0x00000200)
+ | ((right << 7) & 0x00000100)
+ | ((right >> 7) & 0x00000020)
+ | ((right >> 3) & 0x00000011)
+ | ((right << 2) & 0x00000004)
+ | ((right >> 21) & 0x00000002);
+ }
+}
+
+/*
+ * Fill a DES context with subkeys calculated from a 64bit key.
+ * Does not check parity bits, but simply ignore them.
+ * Does not check for weak keys.
+ */
+static void
+purple_des_cipher_set_key(PurpleCipher *cipher, const guchar *key, size_t len) {
+ PurpleDESCipher *des_cipher = PURPLE_DES_CIPHER(cipher);
+ PurpleDESCipherPrivate *priv = PURPLE_DES_CIPHER_GET_PRIVATE(des_cipher);
+ int i;
+
+ g_return_if_fail(len == 8);
+
+ purple_des_cipher_key_schedule(key, priv->encrypt_subkeys);
+
+ for(i = 0; i < 32; i += 2) {
+ priv->decrypt_subkeys[i] = priv->encrypt_subkeys[30 - i];
+ priv->decrypt_subkeys[i + 1] = priv->encrypt_subkeys[31 - i];
+ }
+
+ g_object_notify(G_OBJECT(cipher), "key");
+}
+
+static size_t
+purple_des_cipher_get_key_size(PurpleCipher *cipher)
+{
+ return 8;
+}
+
+/*
+ * Electronic Codebook Mode DES encryption/decryption of data according to
+ * 'mode'.
+ */
+int
+purple_des_cipher_ecb_crypt(PurpleDESCipher *des_cipher, const guint8 * from, guint8 * to,
+ int mode)
+{
+ guint32 left, right, work;
+ guint32 *keys;
+ PurpleDESCipherPrivate *priv = PURPLE_DES_CIPHER_GET_PRIVATE(des_cipher);
+
+ keys = mode ? priv->decrypt_subkeys :
+ priv->encrypt_subkeys;
+
+ READ_64BIT_DATA (from, left, right)
+ INITIAL_PERMUTATION (left, work, right)
+
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+
+ FINAL_PERMUTATION (right, work, left)
+ WRITE_64BIT_DATA (to, right, left)
+
+ return 0;
+}
+
+static ssize_t
+purple_des_cipher_encrypt(PurpleCipher *cipher, const guchar input[],
+ size_t in_len, guchar output[], size_t out_size)
+{
+ PurpleDESCipher *des_cipher = PURPLE_DES_CIPHER(cipher);
+
+ gsize offset = 0;
+ int i = 0;
+ gsize tmp;
+ guint8 buf[8] = {0,0,0,0,0,0,0,0};
+ gsize out_len;
+
+ g_return_val_if_fail(out_size >= in_len, -1);
+
+ while(offset + 8 <= in_len) {
+ purple_des_cipher_ecb_crypt(des_cipher, input + offset, output + offset, 0);
+ offset += 8;
+ }
+
+ out_len = in_len;
+
+ if(offset<in_len) {
+ g_return_val_if_fail(in_len >= offset, -1);
+ out_len += in_len - offset;
+ g_return_val_if_fail(out_size >= out_len, -1);
+ tmp = offset;
+ while(tmp<in_len) {
+ buf[i++] = input[tmp];
+ tmp++;
+ }
+
+ purple_des_cipher_ecb_crypt(des_cipher, buf, output + offset, 0);
+ }
+
+ return out_len;
+}
+
+static ssize_t
+purple_des_cipher_decrypt(PurpleCipher *cipher, const guchar input[],
+ size_t in_len, guchar output[], size_t out_size)
+{
+ PurpleDESCipher *des_cipher = PURPLE_DES_CIPHER(cipher);
+
+ gsize offset = 0;
+ int i = 0;
+ gsize tmp;
+ guint8 buf[8] = {0,0,0,0,0,0,0,0};
+ gsize out_len;
+
+ g_return_val_if_fail(out_size >= in_len, -1);
+
+ while(offset + 8 <= in_len) {
+ purple_des_cipher_ecb_crypt(des_cipher, input + offset, output + offset, 1);
+ offset += 8;
+ }
+
+ out_len = in_len;
+ if(offset<in_len) {
+ g_return_val_if_fail(in_len >= offset, -1);
+ out_len += in_len - offset;
+ g_return_val_if_fail(out_size >= out_len, -1);
+ tmp = offset;
+ while(tmp<in_len) {
+ buf[i++] = input[tmp];
+ tmp++;
+ }
+
+ purple_des_cipher_ecb_crypt(des_cipher, buf, output + offset, 1);
+ }
+
+ return out_len;
+}
+
+static const gchar*
+purple_des_cipher_get_name(PurpleCipher *cipher)
+{
+ return "des";
+}
+
+/******************************************************************************
+ * Object Stuff
+ *****************************************************************************/
+static void
+purple_des_cipher_set_property(GObject *obj, guint param_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ PurpleCipher *cipher = PURPLE_CIPHER(obj);
+
+ switch(param_id) {
+ case PROP_KEY:
+ purple_cipher_set_key(cipher, (guchar *)g_value_get_string(value),
+ purple_des_cipher_get_key_size(cipher));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_des_cipher_class_init(PurpleDESCipherClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ PurpleCipherClass *cipher_class = PURPLE_CIPHER_CLASS(klass);
+ GParamSpec *pspec;
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->set_property = purple_des_cipher_set_property;
+
+ cipher_class->encrypt = purple_des_cipher_encrypt;
+ cipher_class->decrypt = purple_des_cipher_decrypt;
+ cipher_class->set_key = purple_des_cipher_set_key;
+ cipher_class->get_key_size = purple_des_cipher_get_key_size;
+ cipher_class->get_name = purple_des_cipher_get_name;
+
+ pspec = g_param_spec_string("key", "key", "key", NULL,
+ G_PARAM_WRITABLE);
+ g_object_class_install_property(obj_class, PROP_KEY, pspec);
+
+ g_type_class_add_private(klass, sizeof(PurpleDESCipherPrivate));
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GType
+purple_des_cipher_get_type(void) {
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ .class_size = sizeof(PurpleDESCipherClass),
+ .class_init = (GClassInitFunc)purple_des_cipher_class_init,
+ .instance_size = sizeof(PurpleDESCipher),
+ .instance_init = (GInstanceInitFunc)purple_cipher_reset,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_CIPHER,
+ "PurpleDESCipher",
+ &info, 0);
+ }
+
+ return type;
+}
+
+/**
+ * purple_des_cipher_new:
+ *
+ * Creates a new #PurpleCipher instance which implements the DES block cipher.
+ *
+ * Return Value: The new DES implementation of #PurpleCipher.
+ */
+PurpleCipher *
+purple_des_cipher_new(void) {
+ return g_object_new(PURPLE_TYPE_DES_CIPHER, NULL);
+}
+
diff --git a/libpurple/ciphers/descipher.h b/libpurple/ciphers/descipher.h
new file mode 100644
index 0000000000..595f0458c3
--- /dev/null
+++ b/libpurple/ciphers/descipher.h
@@ -0,0 +1,66 @@
+/**
+ * @file des.h Purple DES Cipher
+ * @ingroup core
+ */
+
+/* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef PURPLE_DES_CIPHER_H
+#define PURPLE_DES_CIPHER_H
+
+#include "cipher.h"
+
+#define PURPLE_TYPE_DES_CIPHER (purple_des_cipher_get_type())
+#define PURPLE_DES_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_DES_CIPHER, PurpleDESCipher))
+#define PURPLE_DES_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_DES_CIPHER, PurpleDESCipherClass))
+#define PURPLE_IS_DES_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_DES_CIPHER))
+#define PURPLE_IS_DES_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), PURPLE_TYPE_DES_CIPHER))
+#define PURPLE_DES_CIPHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_DES_CIPHER, PurpleDESCipherClass))
+
+typedef struct _PurpleDESCipher PurpleDESCipher;
+typedef struct _PurpleDESCipherClass PurpleDESCipherClass;
+
+struct _PurpleDESCipher {
+ /*< private >*/
+ PurpleCipher gparent;
+};
+
+struct _PurpleDESCipherClass {
+ /*< private >*/
+ PurpleCipherClass gparent;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType purple_des_cipher_get_type(void);
+
+PurpleCipher *purple_des_cipher_new(void);
+
+int purple_des_cipher_ecb_crypt(PurpleDESCipher *des_cipher, const guint8 * from, guint8 * to, int mode);
+
+G_END_DECLS
+
+#endif /* PURPLE_DES_CIPHER_H */
diff --git a/libpurple/ciphers/gchecksum.c b/libpurple/ciphers/gchecksum.c
deleted file mode 100644
index 3e09ff4b54..0000000000
--- a/libpurple/ciphers/gchecksum.c
+++ /dev/null
@@ -1,144 +0,0 @@
-#include "internal.h"
-#include <cipher.h>
-#include "ciphers.h"
-
-static void
-purple_g_checksum_init(PurpleCipherContext *context, GChecksumType type)
-{
- GChecksum *checksum;
-
- checksum = g_checksum_new(type);
- purple_cipher_context_set_data(context, checksum);
-}
-
-static void
-purple_g_checksum_reset(PurpleCipherContext *context, GChecksumType type)
-{
- GChecksum *checksum;
-
- checksum = purple_cipher_context_get_data(context);
- g_return_if_fail(checksum != NULL);
-
- g_checksum_reset(checksum);
-}
-
-static void
-purple_g_checksum_uninit(PurpleCipherContext *context)
-{
- GChecksum *checksum;
-
- checksum = purple_cipher_context_get_data(context);
- g_return_if_fail(checksum != NULL);
-
- g_checksum_free(checksum);
-}
-
-static void
-purple_g_checksum_append(PurpleCipherContext *context, const guchar *data,
- gsize len)
-{
- GChecksum *checksum;
-
- checksum = purple_cipher_context_get_data(context);
- g_return_if_fail(checksum != NULL);
-
- while (len >= G_MAXSSIZE) {
- g_checksum_update(checksum, data, G_MAXSSIZE);
- len -= G_MAXSSIZE;
- data += G_MAXSSIZE;
- }
-
- if (len)
- g_checksum_update(checksum, data, len);
-}
-
-static gboolean
-purple_g_checksum_digest(PurpleCipherContext *context, GChecksumType type,
- guchar *digest, size_t buff_len)
-{
- GChecksum *checksum;
- const gssize required_len = g_checksum_type_get_length(type);
- gsize digest_len = buff_len;
-
- checksum = purple_cipher_context_get_data(context);
-
- g_return_val_if_fail(required_len >= 0, FALSE);
- g_return_val_if_fail(buff_len >= (gsize)required_len, FALSE);
- g_return_val_if_fail(checksum != NULL, FALSE);
-
- g_checksum_get_digest(checksum, digest, &digest_len);
-
- if (digest_len != (gsize)required_len)
- return FALSE;
-
- purple_cipher_context_reset(context, NULL);
-
- return TRUE;
-}
-
-/******************************************************************************
- * Macros
- *****************************************************************************/
-#define PURPLE_G_CHECKSUM_IMPLEMENTATION(lower, camel, type, block_size) \
- static size_t \
- lower##_get_block_size(PurpleCipherContext *context) { \
- return (block_size); \
- } \
- \
- static void \
- lower##_init(PurpleCipherContext *context, gpointer extra) { \
- purple_g_checksum_init(context, (type)); \
- } \
- \
- static void \
- lower##_reset(PurpleCipherContext *context, gpointer extra) { \
- purple_g_checksum_reset(context, (type)); \
- } \
- \
- static gboolean \
- lower##_digest(PurpleCipherContext *context, guchar digest[], \
- size_t len) \
- { \
- return purple_g_checksum_digest(context, (type), digest, len); \
- } \
- \
- static size_t \
- lower##_get_digest_size(PurpleCipherContext *context) \
- { \
- return g_checksum_type_get_length((type)); \
- } \
- \
- static PurpleCipherOps camel##Ops = { \
- NULL, /* Set option */ \
- NULL, /* Get option */ \
- lower##_init, /* init */ \
- lower##_reset, /* reset */ \
- lower##_reset, /* reset state */ \
- purple_g_checksum_uninit, /* uninit */ \
- NULL, /* set iv */ \
- purple_g_checksum_append, /* append */ \
- lower##_digest, /* digest */ \
- lower##_get_digest_size, /* get digest size */ \
- NULL, /* encrypt */ \
- NULL, /* decrypt */ \
- NULL, /* set salt */ \
- NULL, /* get salt size */ \
- NULL, /* set key */ \
- NULL, /* get key size */ \
- NULL, /* set batch mode */ \
- NULL, /* get batch mode */ \
- lower##_get_block_size, /* get block size */ \
- NULL, NULL, NULL, NULL /* reserved */ \
- }; \
- \
- PurpleCipherOps * \
- purple_##lower##_cipher_get_ops(void) { \
- return &camel##Ops; \
- }
-
-/******************************************************************************
- * Macro Expansion
- *****************************************************************************/
-PURPLE_G_CHECKSUM_IMPLEMENTATION(md5, MD5, G_CHECKSUM_MD5, 64);
-PURPLE_G_CHECKSUM_IMPLEMENTATION(sha1, SHA1, G_CHECKSUM_SHA1, 64);
-PURPLE_G_CHECKSUM_IMPLEMENTATION(sha256, SHA256, G_CHECKSUM_SHA256, 64);
diff --git a/libpurple/ciphers/hmac.c b/libpurple/ciphers/hmac.c
deleted file mode 100644
index 00e6a0d99e..0000000000
--- a/libpurple/ciphers/hmac.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * 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
- */
-
-#include "internal.h"
-#include <cipher.h>
-#include "ciphers.h"
-
-#include <util.h>
-
-struct HMAC_Context {
- PurpleCipherContext *hash;
- char *name;
- int blocksize;
- guchar *opad, *ipad;
-};
-
- static void
-hmac_init(PurpleCipherContext *context, gpointer extra)
-{
- struct HMAC_Context *hctx;
- hctx = g_new0(struct HMAC_Context, 1);
- purple_cipher_context_set_data(context, hctx);
- purple_cipher_context_reset(context, extra);
-}
-
- static void
-hmac_reset(PurpleCipherContext *context, gpointer extra)
-{
- struct HMAC_Context *hctx;
-
- hctx = purple_cipher_context_get_data(context);
-
- g_free(hctx->name);
- hctx->name = NULL;
- if (hctx->hash)
- purple_cipher_context_destroy(hctx->hash);
- hctx->hash = NULL;
- hctx->blocksize = 0;
- g_free(hctx->opad);
- hctx->opad = NULL;
- g_free(hctx->ipad);
- hctx->ipad = NULL;
-}
-
- static void
-hmac_reset_state(PurpleCipherContext *context, gpointer extra)
-{
- struct HMAC_Context *hctx;
-
- hctx = purple_cipher_context_get_data(context);
-
- if (hctx->hash) {
- purple_cipher_context_reset_state(hctx->hash, NULL);
- purple_cipher_context_append(hctx->hash, hctx->ipad, hctx->blocksize);
- }
-}
-
- static void
-hmac_set_opt(PurpleCipherContext *context, const gchar *name, void *value)
-{
- struct HMAC_Context *hctx;
-
- hctx = purple_cipher_context_get_data(context);
-
- if (purple_strequal(name, "hash")) {
- g_free(hctx->name);
- if (hctx->hash)
- purple_cipher_context_destroy(hctx->hash);
- hctx->name = g_strdup((char*)value);
- hctx->hash = purple_cipher_context_new_by_name((char *)value, NULL);
- hctx->blocksize = purple_cipher_context_get_block_size(hctx->hash);
- }
-}
-
- static void *
-hmac_get_opt(PurpleCipherContext *context, const gchar *name)
-{
- struct HMAC_Context *hctx;
-
- hctx = purple_cipher_context_get_data(context);
-
- if (purple_strequal(name, "hash")) {
- return hctx->name;
- }
-
- return NULL;
-}
-
- static void
-hmac_append(PurpleCipherContext *context, const guchar *data, size_t len)
-{
- struct HMAC_Context *hctx = purple_cipher_context_get_data(context);
-
- g_return_if_fail(hctx->hash != NULL);
-
- purple_cipher_context_append(hctx->hash, data, len);
-}
-
- static gboolean
-hmac_digest(PurpleCipherContext *context, guchar *out, size_t len)
-{
- struct HMAC_Context *hctx = purple_cipher_context_get_data(context);
- PurpleCipherContext *hash = hctx->hash;
- guchar *inner_hash;
- size_t hash_len;
- gboolean result;
-
- g_return_val_if_fail(hash != NULL, FALSE);
-
- hash_len = purple_cipher_context_get_digest_size(hash);
- g_return_val_if_fail(hash_len > 0, FALSE);
-
- inner_hash = g_malloc(hash_len);
- result = purple_cipher_context_digest(hash, inner_hash, hash_len);
-
- purple_cipher_context_reset(hash, NULL);
-
- purple_cipher_context_append(hash, hctx->opad, hctx->blocksize);
- purple_cipher_context_append(hash, inner_hash, hash_len);
-
- g_free(inner_hash);
-
- result = result && purple_cipher_context_digest(hash, out, len);
-
- return result;
-}
-
- static size_t
-hmac_get_digest_size(PurpleCipherContext *context)
-{
- struct HMAC_Context *hctx = purple_cipher_context_get_data(context);
- PurpleCipherContext *hash = hctx->hash;
-
- g_return_val_if_fail(hash != NULL, 0);
-
- return purple_cipher_context_get_digest_size(hash);
-}
-
- static void
-hmac_uninit(PurpleCipherContext *context)
-{
- struct HMAC_Context *hctx;
-
- purple_cipher_context_reset(context, NULL);
-
- hctx = purple_cipher_context_get_data(context);
-
- g_free(hctx);
-}
-
- static void
-hmac_set_key(PurpleCipherContext *context, const guchar * key, size_t key_len)
-{
- struct HMAC_Context *hctx = purple_cipher_context_get_data(context);
- gsize blocksize, i;
- guchar *full_key;
-
- g_return_if_fail(hctx->hash != NULL);
-
- g_free(hctx->opad);
- g_free(hctx->ipad);
-
- blocksize = hctx->blocksize;
- hctx->ipad = g_malloc(blocksize);
- hctx->opad = g_malloc(blocksize);
-
- if (key_len > blocksize) {
- purple_cipher_context_reset(hctx->hash, NULL);
- purple_cipher_context_append(hctx->hash, key, key_len);
-
- key_len = purple_cipher_context_get_digest_size(hctx->hash);
- full_key = g_malloc(key_len);
- purple_cipher_context_digest(hctx->hash, full_key, key_len);
- } else
- full_key = g_memdup(key, key_len);
-
- if (key_len < blocksize) {
- full_key = g_realloc(full_key, blocksize);
- memset(full_key + key_len, 0, blocksize - key_len);
- }
-
- for(i = 0; i < blocksize; i++) {
- hctx->ipad[i] = 0x36 ^ full_key[i];
- hctx->opad[i] = 0x5c ^ full_key[i];
- }
-
- g_free(full_key);
-
- purple_cipher_context_reset(hctx->hash, NULL);
- purple_cipher_context_append(hctx->hash, hctx->ipad, blocksize);
-}
-
- static size_t
-hmac_get_block_size(PurpleCipherContext *context)
-{
- struct HMAC_Context *hctx = purple_cipher_context_get_data(context);
-
- return hctx->blocksize;
-}
-
-static PurpleCipherOps HMACOps = {
- hmac_set_opt, /* Set option */
- hmac_get_opt, /* Get option */
- hmac_init, /* init */
- hmac_reset, /* reset */
- hmac_reset_state, /* reset state */
- hmac_uninit, /* uninit */
- NULL, /* set iv */
- hmac_append, /* append */
- hmac_digest, /* digest */
- hmac_get_digest_size, /* get digest size */
- NULL, /* encrypt */
- NULL, /* decrypt */
- NULL, /* set salt */
- NULL, /* get salt size */
- hmac_set_key, /* set key */
- NULL, /* get key size */
- NULL, /* set batch mode */
- NULL, /* get batch mode */
- hmac_get_block_size, /* get block size */
- NULL, NULL, NULL, NULL /* reserved */
-};
-
-PurpleCipherOps *
-purple_hmac_cipher_get_ops(void) {
- return &HMACOps;
-}
-
diff --git a/libpurple/ciphers/hmaccipher.c b/libpurple/ciphers/hmaccipher.c
new file mode 100644
index 0000000000..0b27147221
--- /dev/null
+++ b/libpurple/ciphers/hmaccipher.c
@@ -0,0 +1,345 @@
+/*
+ * 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
+ */
+#include "hmaccipher.h"
+
+#include <string.h>
+
+/*******************************************************************************
+ * Structs
+ ******************************************************************************/
+#define PURPLE_HMAC_CIPHER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_HMAC_CIPHER, PurpleHMACCipherPrivate))
+
+typedef struct {
+ PurpleHash *hash;
+ guchar *ipad;
+ guchar *opad;
+} PurpleHMACCipherPrivate;
+
+/******************************************************************************
+ * Enums
+ *****************************************************************************/
+enum {
+ PROP_NONE,
+ PROP_HASH,
+ PROP_LAST,
+};
+
+/*******************************************************************************
+ * Globals
+ ******************************************************************************/
+static GObjectClass *parent_class = NULL;
+
+/*******************************************************************************
+ * Helpers
+ ******************************************************************************/
+static void
+purple_hmac_cipher_set_hash(PurpleCipher *cipher,
+ PurpleHash *hash)
+{
+ PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+
+ priv->hash = g_object_ref(G_OBJECT(hash));
+ g_object_notify(G_OBJECT(cipher), "hash");
+}
+
+/*******************************************************************************
+ * Cipher Stuff
+ ******************************************************************************/
+static void
+purple_hmac_cipher_reset(PurpleCipher *cipher) {
+ PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+
+ if(PURPLE_IS_HASH(priv->hash))
+ purple_hash_reset(priv->hash);
+
+ if(priv->ipad) {
+ g_free(priv->ipad);
+ priv->ipad = NULL;
+ }
+ if(priv->opad) {
+ g_free(priv->opad);
+ priv->opad = NULL;
+ }
+}
+
+static void
+purple_hmac_cipher_reset_state(PurpleCipher *cipher) {
+ PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+
+ if(PURPLE_IS_HASH(priv->hash)) {
+ purple_hash_reset_state(priv->hash);
+ purple_hash_append(priv->hash, priv->ipad,
+ purple_hash_get_block_size(priv->hash));
+ }
+}
+
+static void
+purple_hmac_cipher_append(PurpleCipher *cipher, const guchar *d, size_t l) {
+ PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+
+ g_return_if_fail(PURPLE_IS_HASH(priv->hash));
+
+ purple_hash_append(priv->hash, d, l);
+}
+
+static gboolean
+purple_hmac_cipher_digest(PurpleCipher *cipher, guchar *out, size_t len)
+{
+ PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+ guchar *digest = NULL;
+ size_t hash_len, block_size;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail(PURPLE_IS_HASH(priv->hash), FALSE);
+
+ hash_len = purple_hash_get_digest_size(priv->hash);
+ g_return_val_if_fail(hash_len > 0, FALSE);
+
+ block_size = purple_hash_get_block_size(priv->hash);
+ digest = g_malloc(hash_len);
+
+ /* get the digest of the data */
+ result = purple_hash_digest(priv->hash, digest, hash_len);
+ purple_hash_reset(priv->hash);
+
+ if(!result) {
+ g_free(digest);
+
+ return FALSE;
+ }
+
+ /* now append the opad and the digest from above */
+ purple_hash_append(priv->hash, priv->opad, block_size);
+ purple_hash_append(priv->hash, digest, hash_len);
+
+ /* do our last digest */
+ result = purple_hash_digest(priv->hash, out, len);
+
+ /* cleanup */
+ g_free(digest);
+
+ return result;
+}
+
+static size_t
+purple_hmac_cipher_get_digest_size(PurpleCipher *cipher)
+{
+ PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+
+ g_return_val_if_fail(priv->hash != NULL, 0);
+
+ return purple_hash_get_digest_size(priv->hash);
+}
+
+static void
+purple_hmac_cipher_set_key(PurpleCipher *cipher, const guchar *key,
+ size_t key_len)
+{
+ PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+ gsize blocksize, i;
+ guchar *full_key;
+
+ g_return_if_fail(priv->hash);
+
+ g_free(priv->ipad);
+ g_free(priv->opad);
+
+ block_size = purple_hash_get_block_size(priv->hash);
+ priv->ipad = g_malloc(block_size);
+ priv->opad = g_malloc(block_size);
+
+ if (key_len > block_size) {
+ purple_hash_reset(priv->hash);
+ purple_hash_append(priv->hash, key, key_len);
+
+ key_len = purple_hash_get_digest_size(priv->hash);
+ full_key = g_malloc(key_len);
+ purple_hash_digest(priv->hash, full_key, key_len);
+ } else {
+ full_key = g_memdup(key, key_len);
+ }
+
+ if (key_len < block_size) {
+ full_key = g_realloc(full_key, block_size);
+ memset(full_key + key_len, 0, block_size - key_len);
+ }
+
+ for(i = 0; i < block_size; i++) {
+ priv->ipad[i] = 0x36 ^ full_key[i];
+ priv->opad[i] = 0x5c ^ full_key[i];
+ }
+
+ g_free(full_key);
+
+ purple_hash_reset(priv->hash);
+ purple_hash_append(priv->hash, priv->ipad, block_size);
+}
+
+static size_t
+purple_hmac_cipher_get_block_size(PurpleCipher *cipher)
+{
+ PurpleHMACCipherPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_HMAC_CIPHER(cipher), 0);
+
+ priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+
+ return purple_hash_get_block_size(priv->hash);
+}
+
+static const gchar*
+purple_hmac_cipher_get_name(PurpleCipher *cipher)
+{
+ return "hmac";
+}
+
+/******************************************************************************
+ * Object Stuff
+ *****************************************************************************/
+static void
+purple_hmac_cipher_set_property(GObject *obj, guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleCipher *cipher = PURPLE_CIPHER(obj);
+
+ switch(param_id) {
+ case PROP_HASH:
+ purple_hmac_cipher_set_hash(cipher, g_value_get_object(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_hmac_cipher_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleHMACCipher *cipher = PURPLE_HMAC_CIPHER(obj);
+
+ switch(param_id) {
+ case PROP_HASH:
+ g_value_set_object(value,
+ purple_hmac_cipher_get_hash(cipher));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_hmac_cipher_finalize(GObject *obj) {
+ PurpleCipher *cipher = PURPLE_CIPHER(obj);
+ PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+
+ purple_hmac_cipher_reset(cipher);
+
+ if (priv->hash != NULL)
+ g_object_unref(priv->hash);
+
+ parent_class->finalize(obj);
+}
+
+static void
+purple_hmac_cipher_class_init(PurpleHMACCipherClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ PurpleCipherClass *cipher_class = PURPLE_CIPHER_CLASS(klass);
+ GParamSpec *pspec;
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ g_type_class_add_private(klass, sizeof(PurpleHMACCipherPrivate));
+
+ obj_class->finalize = purple_hmac_cipher_finalize;
+ obj_class->get_property = purple_hmac_cipher_get_property;
+ obj_class->set_property = purple_hmac_cipher_set_property;
+
+ cipher_class->reset = purple_hmac_cipher_reset;
+ cipher_class->reset_state = purple_hmac_cipher_reset_state;
+ cipher_class->append = purple_hmac_cipher_append;
+ cipher_class->digest = purple_hmac_cipher_digest;
+ cipher_class->get_digest_size = purple_hmac_cipher_get_digest_size;
+ cipher_class->set_key = purple_hmac_cipher_set_key;
+ cipher_class->get_block_size = purple_hmac_cipher_get_block_size;
+ cipher_class->get_name = purple_hmac_cipher_get_name;
+
+ pspec = g_param_spec_object("hash", "hash", "hash", PURPLE_TYPE_HASH,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property(obj_class, PROP_HASH, pspec);
+}
+
+/******************************************************************************
+ * PurpleHMACCipher API
+ *****************************************************************************/
+GType
+purple_hmac_cipher_get_gtype(void) {
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleHMACCipherClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_hmac_cipher_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleHMACCipher),
+ 0,
+ (GInstanceInitFunc)purple_cipher_reset,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_CIPHER,
+ "PurpleHMACCipher",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleCipher *
+purple_hmac_cipher_new(PurpleHash *hash) {
+ g_return_val_if_fail(PURPLE_IS_HASH(hash), NULL);
+
+ return g_object_new(PURPLE_TYPE_HMAC_CIPHER,
+ "hash", hash,
+ NULL);
+}
+
+PurpleHash *
+purple_hmac_cipher_get_hash(const PurpleHMACCipher *cipher) {
+ PurpleHMACCipherPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_HMAC_CIPHER(cipher), NULL);
+
+ priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+
+ if(priv && priv->hash)
+ return priv->hash;
+
+ return NULL;
+}
+
diff --git a/libpurple/ciphers/hmaccipher.h b/libpurple/ciphers/hmaccipher.h
new file mode 100644
index 0000000000..713ae99406
--- /dev/null
+++ b/libpurple/ciphers/hmaccipher.h
@@ -0,0 +1,67 @@
+/**
+ * @file hmac.h Purple HMAC Cipher
+ * @ingroup core
+ */
+
+/* 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 PURPLE_HMAC_CIPHER_H
+#define PURPLE_HMAC_CIPHER_H
+
+#include "cipher.h"
+#include "hash.h"
+
+#define PURPLE_TYPE_HMAC_CIPHER (purple_hmac_cipher_get_gtype())
+#define PURPLE_HMAC_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_HMAC_CIPHER, PurpleHMACCipher))
+#define PURPLE_HMAC_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_HMAC_CIPHER, PurpleHMACCipherClass))
+#define PURPLE_IS_HMAC_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_HMAC_CIPHER))
+#define PURPLE_IS_HMAC_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), PURPLE_TYPE_HMAC_CIPHER))
+#define PURPLE_HMAC_CIPHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_HMAC_CIPHER, PurpleHMACCipherClass))
+
+typedef struct _PurpleHMACCipher PurpleHMACCipher;
+typedef struct _PurpleHMACCipherClass PurpleHMACCipherClass;
+
+struct _PurpleHMACCipher {
+ /*< private >*/
+ PurpleCipher gparent;
+};
+
+struct _PurpleHMACCipherClass {
+ /*< private >*/
+ PurpleCipherClass gparent;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType purple_hmac_cipher_get_gtype(void);
+
+PurpleCipher *purple_hmac_cipher_new(PurpleHash *hash);
+
+PurpleHash *purple_hmac_cipher_get_hash(const PurpleHMACCipher *cipher);
+
+G_END_DECLS
+
+#endif /* PURPLE_HMAC_CIPHER_H */
diff --git a/libpurple/ciphers/md4.c b/libpurple/ciphers/md4.c
deleted file mode 100644
index 25583424d4..0000000000
--- a/libpurple/ciphers/md4.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * 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.
- *
- * Original md4 taken from linux kernel
- * MD4 Message Digest Algorithm (RFC1320).
- *
- * Implementation derived from Andrew Tridgell and Steve French's
- * CIFS MD4 implementation, and the cryptoapi implementation
- * originally based on the public domain implementation written
- * by Colin Plumb in 1993.
- *
- * Copyright (c) Andrew Tridgell 1997-1998.
- * Modified by Steve French (sfrench@us.ibm.com) 2002
- * Copyright (c) Cryptoapi developers.
- * Copyright (c) 2002 David S. Miller (davem@redhat.com)
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- *
- * 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 <cipher.h>
-#include "ciphers.h"
-
-#define MD4_DIGEST_SIZE 16
-#define MD4_HMAC_BLOCK_SIZE 64
-#define MD4_BLOCK_WORDS 16
-#define MD4_HASH_WORDS 4
-
-struct MD4_Context {
- guint32 hash[MD4_HASH_WORDS];
- guint32 block[MD4_BLOCK_WORDS];
- guint64 byte_count;
-};
-
-static inline guint32 lshift(guint32 x, unsigned int s)
-{
- x &= 0xFFFFFFFF;
- return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
-}
-
-static inline guint32 F(guint32 x, guint32 y, guint32 z)
-{
- return (x & y) | ((~x) & z);
-}
-
-static inline guint32 G(guint32 x, guint32 y, guint32 z)
-{
- return (x & y) | (x & z) | (y & z);
-}
-
-static inline guint32 H(guint32 x, guint32 y, guint32 z)
-{
- return x ^ y ^ z;
-}
-
-#define ROUND1(a,b,c,d,k,s) (a = lshift(a + F(b,c,d) + k, s))
-#define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (guint32)0x5A827999,s))
-#define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (guint32)0x6ED9EBA1,s))
-
-static inline void le32_to_cpu_array(guint32 *buf, unsigned int words)
-{
- while (words--) {
- *buf=GUINT_FROM_LE(*buf);
- buf++;
- }
-}
-
-static inline void cpu_to_le32_array(guint32 *buf, unsigned int words)
-{
- while (words--) {
- *buf=GUINT_TO_LE(*buf);
- buf++;
- }
-}
-
-static void md4_transform(guint32 *hash, guint32 const *in)
-{
- guint32 a, b, c, d;
-
- a = hash[0];
- b = hash[1];
- c = hash[2];
- d = hash[3];
-
- ROUND1(a, b, c, d, in[0], 3);
- ROUND1(d, a, b, c, in[1], 7);
- ROUND1(c, d, a, b, in[2], 11);
- ROUND1(b, c, d, a, in[3], 19);
- ROUND1(a, b, c, d, in[4], 3);
- ROUND1(d, a, b, c, in[5], 7);
- ROUND1(c, d, a, b, in[6], 11);
- ROUND1(b, c, d, a, in[7], 19);
- ROUND1(a, b, c, d, in[8], 3);
- ROUND1(d, a, b, c, in[9], 7);
- ROUND1(c, d, a, b, in[10], 11);
- ROUND1(b, c, d, a, in[11], 19);
- ROUND1(a, b, c, d, in[12], 3);
- ROUND1(d, a, b, c, in[13], 7);
- ROUND1(c, d, a, b, in[14], 11);
- ROUND1(b, c, d, a, in[15], 19);
-
- ROUND2(a, b, c, d,in[ 0], 3);
- ROUND2(d, a, b, c, in[4], 5);
- ROUND2(c, d, a, b, in[8], 9);
- ROUND2(b, c, d, a, in[12], 13);
- ROUND2(a, b, c, d, in[1], 3);
- ROUND2(d, a, b, c, in[5], 5);
- ROUND2(c, d, a, b, in[9], 9);
- ROUND2(b, c, d, a, in[13], 13);
- ROUND2(a, b, c, d, in[2], 3);
- ROUND2(d, a, b, c, in[6], 5);
- ROUND2(c, d, a, b, in[10], 9);
- ROUND2(b, c, d, a, in[14], 13);
- ROUND2(a, b, c, d, in[3], 3);
- ROUND2(d, a, b, c, in[7], 5);
- ROUND2(c, d, a, b, in[11], 9);
- ROUND2(b, c, d, a, in[15], 13);
-
- ROUND3(a, b, c, d,in[ 0], 3);
- ROUND3(d, a, b, c, in[8], 9);
- ROUND3(c, d, a, b, in[4], 11);
- ROUND3(b, c, d, a, in[12], 15);
- ROUND3(a, b, c, d, in[2], 3);
- ROUND3(d, a, b, c, in[10], 9);
- ROUND3(c, d, a, b, in[6], 11);
- ROUND3(b, c, d, a, in[14], 15);
- ROUND3(a, b, c, d, in[1], 3);
- ROUND3(d, a, b, c, in[9], 9);
- ROUND3(c, d, a, b, in[5], 11);
- ROUND3(b, c, d, a, in[13], 15);
- ROUND3(a, b, c, d, in[3], 3);
- ROUND3(d, a, b, c, in[11], 9);
- ROUND3(c, d, a, b, in[7], 11);
- ROUND3(b, c, d, a, in[15], 15);
-
- hash[0] += a;
- hash[1] += b;
- hash[2] += c;
- hash[3] += d;
-}
-
-static inline void md4_transform_helper(struct MD4_Context *ctx)
-{
- le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(guint32));
- md4_transform(ctx->hash, ctx->block);
-}
-
-static void
-md4_init(PurpleCipherContext *context, gpointer extra) {
- struct MD4_Context *mctx;
- mctx = g_new0(struct MD4_Context, 1);
- purple_cipher_context_set_data(context, mctx);
- purple_cipher_context_reset(context, extra);
-
- mctx->hash[0] = 0x67452301;
- mctx->hash[1] = 0xefcdab89;
- mctx->hash[2] = 0x98badcfe;
- mctx->hash[3] = 0x10325476;
- mctx->byte_count = 0;
-}
-
-static void
-md4_reset(PurpleCipherContext *context, gpointer extra) {
- struct MD4_Context *mctx;
-
- mctx = purple_cipher_context_get_data(context);
-
- mctx->hash[0] = 0x67452301;
- mctx->hash[1] = 0xefcdab89;
- mctx->hash[2] = 0x98badcfe;
- mctx->hash[3] = 0x10325476;
- mctx->byte_count = 0;
-}
-
- static void
-md4_append(PurpleCipherContext *context, const guchar *data, size_t len)
-{
- struct MD4_Context *mctx = purple_cipher_context_get_data(context);
- const guint32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
-
- mctx->byte_count += len;
-
- if (avail > len) {
- memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
- data, len);
- return;
- }
-
- memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
- data, avail);
-
- md4_transform_helper(mctx);
- data += avail;
- len -= avail;
-
- while (len >= sizeof(mctx->block)) {
- memcpy(mctx->block, data, sizeof(mctx->block));
- md4_transform_helper(mctx);
- data += sizeof(mctx->block);
- len -= sizeof(mctx->block);
- }
-
- memcpy(mctx->block, data, len);
-}
-
- static gboolean
-md4_digest(PurpleCipherContext *context, guchar *out, size_t len)
-{
- struct MD4_Context *mctx = purple_cipher_context_get_data(context);
- const unsigned int offset = mctx->byte_count & 0x3f;
- char *p = (char *)mctx->block + offset;
- int padding = 56 - (offset + 1);
-
-
- if(len<16) return FALSE;
- *p++ = 0x80;
- if (padding < 0) {
- memset(p, 0x00, padding + sizeof (guint64));
- md4_transform_helper(mctx);
- p = (char *)mctx->block;
- padding = 56;
- }
-
- memset(p, 0, padding);
- mctx->block[14] = mctx->byte_count << 3;
- mctx->block[15] = mctx->byte_count >> 29;
- le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
- sizeof(guint64)) / sizeof(guint32));
- md4_transform(mctx->hash, mctx->block);
- cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(guint32));
- memcpy(out, mctx->hash, sizeof(mctx->hash));
- memset(mctx, 0, sizeof(*mctx));
- return TRUE;
-}
-
- static size_t
-md4_get_digest_size(PurpleCipherContext *context)
-{
- return 16;
-}
-
-static void
-md4_uninit(PurpleCipherContext *context) {
- struct MD4_Context *md4_context;
-
- purple_cipher_context_reset(context, NULL);
-
- md4_context = purple_cipher_context_get_data(context);
- memset(md4_context, 0, sizeof(*md4_context));
-
- g_free(md4_context);
- md4_context = NULL;
-}
-
- static size_t
-md4_get_block_size(PurpleCipherContext *context)
-{
- /* This does not change (in this case) */
- return MD4_HMAC_BLOCK_SIZE;
-}
-
-static PurpleCipherOps MD4Ops = {
- NULL, /* Set option */
- NULL, /* Get option */
- md4_init, /* init */
- md4_reset, /* reset */
- md4_reset, /* reset state */
- md4_uninit, /* uninit */
- NULL, /* set iv */
- md4_append, /* append */
- md4_digest, /* digest */
- md4_get_digest_size, /* get digest size */
- NULL, /* encrypt */
- NULL, /* decrypt */
- NULL, /* set salt */
- NULL, /* get salt size */
- NULL, /* set key */
- NULL, /* get key size */
- NULL, /* set batch mode */
- NULL, /* get batch mode */
- md4_get_block_size, /* get block size */
- NULL, NULL, NULL, NULL /* reserved */
-};
-
-PurpleCipherOps *
-purple_md4_cipher_get_ops(void) {
- return &MD4Ops;
-}
-
diff --git a/libpurple/ciphers/md4hash.c b/libpurple/ciphers/md4hash.c
new file mode 100644
index 0000000000..b6a9a2e469
--- /dev/null
+++ b/libpurple/ciphers/md4hash.c
@@ -0,0 +1,317 @@
+/*
+ * Original md4 taken from linux kernel
+ * MD4 Message Digest Algorithm (RFC1320).
+ *
+ * Implementation derived from Andrew Tridgell and Steve French's
+ * CIFS MD4 implementation, and the cryptoapi implementation
+ * originally based on the public domain implementation written
+ * by Colin Plumb in 1993.
+ *
+ * Copyright (c) Andrew Tridgell 1997-1998.
+ * Modified by Steve French (sfrench@us.ibm.com) 2002
+ * Copyright (c) Cryptoapi developers.
+ * Copyright (c) 2002 David S. Miller (davem@redhat.com)
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ */
+#include "md4hash.h"
+
+#include <string.h>
+
+#define MD4_DIGEST_SIZE 16
+#define MD4_BLOCK_WORDS 16
+#define MD4_HASH_WORDS 4
+
+#define PURPLE_MD4_HASH_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_MD4_HASH, PurpleMD4HashPrivate))
+
+/******************************************************************************
+ * Structs
+ *****************************************************************************/
+typedef struct {
+ guint32 hash[MD4_HASH_WORDS];
+ guint32 block[MD4_BLOCK_WORDS];
+ guint64 byte_count;
+} PurpleMD4HashPrivate;
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+static GObjectClass *parent_class = NULL;
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+#define ROUND1(a,b,c,d,k,s) \
+ (a = lshift(a + F(b,c,d) + k, s))
+
+#define ROUND2(a,b,c,d,k,s) \
+ (a = lshift(a + G(b,c,d) + k + (guint32)0x5a827999,s))
+
+#define ROUND3(a,b,c,d,k,s) \
+ (a = lshift(a + H(b,c,d) + k + (guint32)0x6ed9eba1,s))
+
+static inline guint32
+lshift(guint32 x, unsigned int s) {
+ x &= 0xffffffff;
+ return (((x << s) & 0xffffffff) | (x >> (32 - s)));
+}
+
+static inline guint32
+F(guint32 x, guint32 y, guint32 z) {
+ return ((x & y) | ((~x) & z));
+}
+
+static inline guint32
+G(guint32 x, guint32 y, guint32 z) {
+ return ((x & y) | (x & z) | (y & z));
+}
+
+static inline guint32
+H(guint32 x, guint32 y, guint32 z) {
+ return (x ^ y ^ z);
+}
+
+static inline void
+le32_to_cpu_array(guint32 *buf, unsigned int words) {
+ while(words--) {
+ *buf = GUINT_FROM_LE(*buf);
+ buf++;
+ }
+}
+
+static inline void
+cpu_to_le32_array(guint32 *buf, unsigned int words) {
+ while(words--) {
+ *buf = GUINT_TO_LE(*buf);
+ buf++;
+ }
+}
+
+static void
+md4_transform(guint32 *hash, guint32 const *in) {
+ guint32 a, b, c, d;
+
+ a = hash[0];
+ b = hash[1];
+ c = hash[2];
+ d = hash[3];
+
+ ROUND1(a, b, c, d, in[0], 3);
+ ROUND1(d, a, b, c, in[1], 7);
+ ROUND1(c, d, a, b, in[2], 11);
+ ROUND1(b, c, d, a, in[3], 19);
+ ROUND1(a, b, c, d, in[4], 3);
+ ROUND1(d, a, b, c, in[5], 7);
+ ROUND1(c, d, a, b, in[6], 11);
+ ROUND1(b, c, d, a, in[7], 19);
+ ROUND1(a, b, c, d, in[8], 3);
+ ROUND1(d, a, b, c, in[9], 7);
+ ROUND1(c, d, a, b, in[10], 11);
+ ROUND1(b, c, d, a, in[11], 19);
+ ROUND1(a, b, c, d, in[12], 3);
+ ROUND1(d, a, b, c, in[13], 7);
+ ROUND1(c, d, a, b, in[14], 11);
+ ROUND1(b, c, d, a, in[15], 19);
+
+ ROUND2(a, b, c, d,in[ 0], 3);
+ ROUND2(d, a, b, c, in[4], 5);
+ ROUND2(c, d, a, b, in[8], 9);
+ ROUND2(b, c, d, a, in[12], 13);
+ ROUND2(a, b, c, d, in[1], 3);
+ ROUND2(d, a, b, c, in[5], 5);
+ ROUND2(c, d, a, b, in[9], 9);
+ ROUND2(b, c, d, a, in[13], 13);
+ ROUND2(a, b, c, d, in[2], 3);
+ ROUND2(d, a, b, c, in[6], 5);
+ ROUND2(c, d, a, b, in[10], 9);
+ ROUND2(b, c, d, a, in[14], 13);
+ ROUND2(a, b, c, d, in[3], 3);
+ ROUND2(d, a, b, c, in[7], 5);
+ ROUND2(c, d, a, b, in[11], 9);
+ ROUND2(b, c, d, a, in[15], 13);
+
+ ROUND3(a, b, c, d,in[ 0], 3);
+ ROUND3(d, a, b, c, in[8], 9);
+ ROUND3(c, d, a, b, in[4], 11);
+ ROUND3(b, c, d, a, in[12], 15);
+ ROUND3(a, b, c, d, in[2], 3);
+ ROUND3(d, a, b, c, in[10], 9);
+ ROUND3(c, d, a, b, in[6], 11);
+ ROUND3(b, c, d, a, in[14], 15);
+ ROUND3(a, b, c, d, in[1], 3);
+ ROUND3(d, a, b, c, in[9], 9);
+ ROUND3(c, d, a, b, in[5], 11);
+ ROUND3(b, c, d, a, in[13], 15);
+ ROUND3(a, b, c, d, in[3], 3);
+ ROUND3(d, a, b, c, in[11], 9);
+ ROUND3(c, d, a, b, in[7], 11);
+ ROUND3(b, c, d, a, in[15], 15);
+
+ hash[0] += a;
+ hash[1] += b;
+ hash[2] += c;
+ hash[3] += d;
+}
+
+static inline void
+md4_transform_helper(PurpleHash *hash) {
+ PurpleMD4HashPrivate *priv = PURPLE_MD4_HASH_GET_PRIVATE(hash);
+
+ le32_to_cpu_array(priv->block, sizeof(priv->block) / sizeof(guint32));
+ md4_transform(priv->hash, priv->block);
+}
+
+/******************************************************************************
+ * Hash Stuff
+ *****************************************************************************/
+static void
+purple_md4_hash_reset(PurpleHash *hash) {
+ PurpleMD4HashPrivate *priv = PURPLE_MD4_HASH_GET_PRIVATE(hash);
+
+ priv->hash[0] = 0x67452301;
+ priv->hash[1] = 0xefcdab89;
+ priv->hash[2] = 0x98badcfe;
+ priv->hash[3] = 0x10325476;
+
+ priv->byte_count = 0;
+
+ memset(priv->block, 0, sizeof(priv->block));
+}
+
+static void
+purple_md4_hash_append(PurpleHash *hash, const guchar *data, size_t len) {
+ PurpleMD4HashPrivate *priv = PURPLE_MD4_HASH_GET_PRIVATE(hash);
+ const guint32 avail = sizeof(priv->block) - (priv->byte_count & 0x3f);
+
+ priv->byte_count += len;
+
+ if(avail > len) {
+ memcpy((char *)priv->block +
+ (sizeof(priv->block) - avail),
+ data, len);
+ return;
+ }
+
+ memcpy((char *)priv->block +
+ (sizeof(priv->block) - avail),
+ data, avail);
+
+ md4_transform_helper(hash);
+ data += avail;
+ len -= avail;
+
+ while(len >= sizeof(priv->block)) {
+ memcpy(priv->block, data, sizeof(priv->block));
+ md4_transform_helper(hash);
+ data += sizeof(priv->block);
+ len -= sizeof(priv->block);
+ }
+
+ memcpy(priv->block, data, len);
+}
+
+static gboolean
+purple_md4_hash_digest(PurpleHash *hash, guchar *out, size_t len)
+{
+ PurpleMD4HashPrivate *priv = PURPLE_MD4_HASH_GET_PRIVATE(hash);
+ const unsigned int offset = priv->byte_count & 0x3f;
+ gchar *p = (gchar *)priv->block + offset;
+ gint padding = 56 - (offset + 1);
+
+ if(len < 16)
+ return FALSE;
+
+ *p++ = 0x80;
+
+ if(padding < 0) {
+ memset(p, 0x00, padding + sizeof(guint64));
+ md4_transform_helper(hash);
+ p = (gchar *)priv->block;
+ padding = 56;
+ }
+
+ memset(p, 0, padding);
+ priv->block[14] = priv->byte_count << 3;
+ priv->block[15] = priv->byte_count >> 29;
+ le32_to_cpu_array(priv->block,
+ (sizeof(priv->block) - sizeof(guint64)) /
+ sizeof(guint32));
+ md4_transform(priv->hash, priv->block);
+ cpu_to_le32_array(priv->hash, sizeof(priv->hash) / sizeof(guint32));
+ memcpy(out, priv->hash, sizeof(priv->hash));
+
+ return TRUE;
+}
+
+static size_t
+purple_md4_hash_get_digest_size(PurpleHash *hash)
+{
+ return 16;
+}
+
+static size_t
+purple_md4_hash_get_block_size(PurpleHash *hash)
+{
+ /* This does not change (in this case) */
+ return 64;
+}
+
+static const gchar*
+purple_md4_hash_get_name(PurpleHash *hash)
+{
+ return "md4";
+}
+
+/******************************************************************************
+ * Object Stuff
+ *****************************************************************************/
+static void
+purple_md4_hash_class_init(PurpleMD4HashClass *klass) {
+ PurpleHashClass *hash_class = PURPLE_HASH_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ g_type_class_add_private(klass, sizeof(PurpleMD4HashPrivate));
+
+ hash_class->reset = purple_md4_hash_reset;
+ hash_class->reset_state = purple_md4_hash_reset;
+ hash_class->append = purple_md4_hash_append;
+ hash_class->digest = purple_md4_hash_digest;
+ hash_class->get_digest_size = purple_md4_hash_get_digest_size;
+ hash_class->get_block_size = purple_md4_hash_get_block_size;
+ hash_class->get_name = purple_md4_hash_get_name;
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GType
+purple_md4_hash_get_gtype(void) {
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleMD4HashClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_md4_hash_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleMD4Hash),
+ 0,
+ (GInstanceInitFunc)purple_hash_reset,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_HASH,
+ "PurpleMD4Hash",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleHash *
+purple_md4_hash_new(void) {
+ return g_object_new(PURPLE_TYPE_MD4_HASH, NULL);
+}
diff --git a/libpurple/ciphers/md4hash.h b/libpurple/ciphers/md4hash.h
new file mode 100644
index 0000000000..6ebb3ec3b2
--- /dev/null
+++ b/libpurple/ciphers/md4hash.h
@@ -0,0 +1,63 @@
+/**
+ * @file md4.h Purple MD4 hash
+ * @ingroup core
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef PURPLE_MD4_HASH_H
+#define PURPLE_MD4_HASH_H
+
+#include "hash.h"
+
+#define PURPLE_TYPE_MD4_HASH (purple_md4_hash_get_gtype())
+#define PURPLE_MD4_HASH(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_MD4_HASH, PurpleMD4Hash))
+#define PURPLE_MD4_HASH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_MD4_HASH, PurpleMD4HashClass))
+#define PURPLE_IS_MD4_HASH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_MD4_HASH))
+#define PURPLE_IS_MD4_HASH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), PURPLE_TYPE_MD4_HASH))
+#define PURPLE_MD4_HASH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_MD4_HASH, PurpleMD4HashClass))
+
+typedef struct _PurpleMD4Hash PurpleMD4Hash;
+typedef struct _PurpleMD4HashClass PurpleMD4HashClass;
+
+struct _PurpleMD4Hash {
+ /*< private >*/
+ PurpleHash parent;
+};
+
+struct _PurpleMD4HashClass {
+ /*< private >*/
+ PurpleHashClass parent;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType purple_md4_hash_get_gtype(void);
+
+PurpleHash *purple_md4_hash_new(void);
+
+G_END_DECLS
+
+#endif /* PURPLE_MD4_HASH_H */
diff --git a/libpurple/ciphers/md5hash.c b/libpurple/ciphers/md5hash.c
new file mode 100644
index 0000000000..6100a94361
--- /dev/null
+++ b/libpurple/ciphers/md5hash.c
@@ -0,0 +1,195 @@
+/*
+ * 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
+ */
+#include "md5hash.h"
+
+/*******************************************************************************
+ * Structs
+ ******************************************************************************/
+#define PURPLE_MD5_HASH_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_MD5_HASH, PurpleMD5HashPrivate))
+
+typedef struct {
+ GChecksum *checksum;
+} PurpleMD5HashPrivate;
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+static GObjectClass *parent_class = NULL;
+
+/******************************************************************************
+ * Hash Stuff
+ *****************************************************************************/
+
+static void
+purple_md5_hash_reset(PurpleHash *hash)
+{
+ PurpleMD5Hash *md5_hash = PURPLE_MD5_HASH(hash);
+ PurpleMD5HashPrivate *priv = PURPLE_MD5_HASH_GET_PRIVATE(md5_hash);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(priv->checksum != NULL);
+
+ g_checksum_reset(priv->checksum);
+}
+
+static void
+purple_md5_hash_append(PurpleHash *hash, const guchar *data,
+ gsize len)
+{
+ PurpleMD5Hash *md5_hash = PURPLE_MD5_HASH(hash);
+ PurpleMD5HashPrivate *priv = PURPLE_MD5_HASH_GET_PRIVATE(md5_hash);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(priv->checksum != NULL);
+
+ while (len >= G_MAXSSIZE) {
+ g_checksum_update(priv->checksum, data, G_MAXSSIZE);
+ len -= G_MAXSSIZE;
+ data += G_MAXSSIZE;
+ }
+
+ if (len)
+ g_checksum_update(priv->checksum, data, len);
+}
+
+static gboolean
+purple_md5_hash_digest(PurpleHash *hash, guchar *digest, size_t buff_len)
+{
+ PurpleMD5Hash *md5_hash = PURPLE_MD5_HASH(hash);
+ PurpleMD5HashPrivate *priv = PURPLE_MD5_HASH_GET_PRIVATE(md5_hash);
+
+ const gssize required_len = g_checksum_type_get_length(G_CHECKSUM_MD5);
+ gsize digest_len = buff_len;
+
+ g_return_val_if_fail(priv != NULL, FALSE);
+ g_return_val_if_fail(priv->checksum != NULL, FALSE);
+ g_return_val_if_fail(buff_len >= required_len, FALSE);
+
+ g_checksum_get_digest(priv->checksum, digest, &digest_len);
+
+ if (digest_len != required_len)
+ return FALSE;
+
+ purple_md5_hash_reset(hash);
+
+ return TRUE;
+}
+
+static size_t
+purple_md5_hash_get_block_size(PurpleHash *hash)
+{
+ return 64;
+}
+
+static size_t
+purple_md5_hash_get_digest_size(PurpleHash *hash)
+{
+ return g_checksum_type_get_length(G_CHECKSUM_MD5);
+}
+
+static const gchar*
+purple_md5_hash_get_name(PurpleHash *hash)
+{
+ return "md5";
+}
+
+/******************************************************************************
+ * Object Stuff
+ *****************************************************************************/
+
+static void
+purple_md5_hash_finalize(GObject *obj)
+{
+ PurpleMD5Hash *md5_hash = PURPLE_MD5_HASH(obj);
+ PurpleMD5HashPrivate *priv = PURPLE_MD5_HASH_GET_PRIVATE(md5_hash);
+
+ if (priv->checksum)
+ g_checksum_free(priv->checksum);
+
+ parent_class->finalize(obj);
+}
+
+static void
+purple_md5_hash_class_init(PurpleMD5HashClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ PurpleHashClass *hash_class = PURPLE_HASH_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->finalize = purple_md5_hash_finalize;
+
+ hash_class->reset = purple_md5_hash_reset;
+ hash_class->reset_state = purple_md5_hash_reset;
+ hash_class->append = purple_md5_hash_append;
+ hash_class->digest = purple_md5_hash_digest;
+ hash_class->get_digest_size = purple_md5_hash_get_digest_size;
+ hash_class->get_block_size = purple_md5_hash_get_block_size;
+ hash_class->get_name = purple_md5_hash_get_name;
+
+ g_type_class_add_private(klass, sizeof(PurpleMD5HashPrivate));
+}
+
+static void
+purple_md5_hash_init(PurpleHash *hash)
+{
+ PurpleMD5Hash *md5_hash = PURPLE_MD5_HASH(hash);
+ PurpleMD5HashPrivate *priv = PURPLE_MD5_HASH_GET_PRIVATE(md5_hash);
+
+ priv->checksum = g_checksum_new(G_CHECKSUM_MD5);
+
+ purple_md5_hash_reset(hash);
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GType
+purple_md5_hash_get_gtype(void) {
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleMD5HashClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_md5_hash_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleMD5Hash),
+ 0,
+ (GInstanceInitFunc)purple_md5_hash_init,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_HASH,
+ "PurpleMD5Hash",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleHash *
+purple_md5_hash_new(void) {
+ return g_object_new(PURPLE_TYPE_MD5_HASH, NULL);
+}
diff --git a/libpurple/ciphers/md5hash.h b/libpurple/ciphers/md5hash.h
new file mode 100644
index 0000000000..3501bcf1c0
--- /dev/null
+++ b/libpurple/ciphers/md5hash.h
@@ -0,0 +1,64 @@
+/**
+ * @file md5.h Purple MD5 Hash
+ * @ingroup core
+ */
+
+/* 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 PURPLE_MD5_HASH_H
+#define PURPLE_MD5_HASH_H
+
+#include "hash.h"
+
+#define PURPLE_TYPE_MD5_HASH (purple_md5_hash_get_gtype())
+#define PURPLE_MD5_HASH(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_MD5_HASH, PurpleMD5Hash))
+#define PURPLE_MD5_HASH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_MD5_HASH, PurpleMD5HashClass))
+#define PURPLE_IS_MD5_HASH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_MD5_HASH))
+#define PURPLE_IS_MD5_HASH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), PURPLE_TYPE_MD5_HASH))
+#define PURPLE_MD5_HASH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_MD5_HASH, PurpleMD5HashClass))
+
+typedef struct _PurpleMD5Hash PurpleMD5Hash;
+typedef struct _PurpleMD5HashClass PurpleMD5HashClass;
+
+struct _PurpleMD5Hash {
+ /*< private >*/
+ PurpleHash gparent;
+};
+
+struct _PurpleMD5HashClass {
+ /*< private >*/
+ PurpleHashClass gparent;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType purple_md5_hash_get_gtype(void);
+
+PurpleHash *purple_md5_hash_new(void);
+
+G_END_DECLS
+
+#endif /* PURPLE_MD5_HASH_H */
diff --git a/libpurple/ciphers/pbkdf2.c b/libpurple/ciphers/pbkdf2.c
deleted file mode 100644
index 51f31d08c9..0000000000
--- a/libpurple/ciphers/pbkdf2.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * 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
- *
- * Written by Tomek Wasilczyk <tomkiewicz@cpw.pidgin.im>
- */
-
-#include "internal.h"
-#include "cipher.h"
-#include "ciphers.h"
-#include "debug.h"
-
-/* 1024bit */
-#define PBKDF2_HASH_MAX_LEN 128
-
-typedef struct
-{
- gchar *hash_func;
- guint iter_count;
- size_t out_len;
-
- guchar *salt;
- size_t salt_len;
- guchar *passphrase;
- size_t passphrase_len;
-} Pbkdf2Context;
-
-static void
-purple_pbkdf2_init(PurpleCipherContext *context, void *extra)
-{
- Pbkdf2Context *ctx_data;
-
- ctx_data = g_new0(Pbkdf2Context, 1);
- purple_cipher_context_set_data(context, ctx_data);
-
- purple_cipher_context_reset(context, extra);
-}
-
-static void
-purple_pbkdf2_uninit(PurpleCipherContext *context)
-{
- Pbkdf2Context *ctx_data;
-
- purple_cipher_context_reset(context, NULL);
-
- ctx_data = purple_cipher_context_get_data(context);
- g_free(ctx_data);
- purple_cipher_context_set_data(context, NULL);
-}
-
-static void
-purple_pbkdf2_reset(PurpleCipherContext *context, void *extra)
-{
- Pbkdf2Context *ctx_data = purple_cipher_context_get_data(context);
-
- g_return_if_fail(ctx_data != NULL);
-
- g_free(ctx_data->hash_func);
- ctx_data->hash_func = NULL;
- ctx_data->iter_count = 1;
- ctx_data->out_len = 256;
-
- purple_cipher_context_reset_state(context, extra);
-}
-
-static void
-purple_pbkdf2_reset_state(PurpleCipherContext *context, void *extra)
-{
- Pbkdf2Context *ctx_data = purple_cipher_context_get_data(context);
-
- g_return_if_fail(ctx_data != NULL);
-
- purple_cipher_context_set_salt(context, NULL, 0);
- purple_cipher_context_set_key(context, NULL, 0);
-}
-
-static void
-purple_pbkdf2_set_option(PurpleCipherContext *context, const gchar *name,
- void *value)
-{
- Pbkdf2Context *ctx_data = purple_cipher_context_get_data(context);
-
- g_return_if_fail(ctx_data != NULL);
-
- if (g_strcmp0(name, "hash") == 0) {
- g_free(ctx_data->hash_func);
- ctx_data->hash_func = g_strdup(value);
- return;
- }
-
- if (g_strcmp0(name, "iter_count") == 0) {
- ctx_data->iter_count = GPOINTER_TO_UINT(value);
- return;
- }
-
- if (g_strcmp0(name, "out_len") == 0) {
- ctx_data->out_len = GPOINTER_TO_UINT(value);
- return;
- }
-
- purple_debug_warning("pbkdf2", "Unknown option: %s\n",
- name ? name : "(null)");
-}
-
-static void *
-purple_pbkdf2_get_option(PurpleCipherContext *context, const gchar *name)
-{
- Pbkdf2Context *ctx_data = purple_cipher_context_get_data(context);
-
- g_return_val_if_fail(ctx_data != NULL, NULL);
-
- if (g_strcmp0(name, "hash") == 0)
- return ctx_data->hash_func;
-
- if (g_strcmp0(name, "iter_count") == 0)
- return GUINT_TO_POINTER(ctx_data->iter_count);
-
- if (g_strcmp0(name, "out_len") == 0)
- return GUINT_TO_POINTER(ctx_data->out_len);
-
- purple_debug_warning("pbkdf2", "Unknown option: %s\n",
- name ? name : "(null)");
- return NULL;
-}
-
-static size_t
-purple_pbkdf2_get_digest_size(PurpleCipherContext *context)
-{
- Pbkdf2Context *ctx_data = purple_cipher_context_get_data(context);
-
- g_return_val_if_fail(ctx_data != NULL, 0);
-
- return ctx_data->out_len;
-}
-
-static void
-purple_pbkdf2_set_salt(PurpleCipherContext *context, const guchar *salt, size_t len)
-{
- Pbkdf2Context *ctx_data = purple_cipher_context_get_data(context);
-
- g_return_if_fail(ctx_data != NULL);
-
- g_free(ctx_data->salt);
- ctx_data->salt = NULL;
- ctx_data->salt_len = 0;
-
- if (len == 0)
- return;
- g_return_if_fail(salt != NULL);
-
- ctx_data->salt = g_memdup(salt, len);
- ctx_data->salt_len = len;
-}
-
-static void
-purple_pbkdf2_set_key(PurpleCipherContext *context, const guchar *key,
- size_t len)
-{
- Pbkdf2Context *ctx_data = purple_cipher_context_get_data(context);
-
- g_return_if_fail(ctx_data != NULL);
-
- if (ctx_data->passphrase != NULL) {
- memset(ctx_data->passphrase, 0, ctx_data->passphrase_len);
- g_free(ctx_data->passphrase);
- ctx_data->passphrase = NULL;
- }
- ctx_data->passphrase_len = 0;
-
- if (len == 0)
- return;
- g_return_if_fail(key != NULL);
-
- ctx_data->passphrase = g_memdup(key, len);
- ctx_data->passphrase_len = len;
-}
-
-/* inspired by gnutls 3.1.10, pbkdf2-sha1.c */
-static gboolean
-purple_pbkdf2_digest(PurpleCipherContext *context, guchar digest[], size_t len)
-{
- Pbkdf2Context *ctx_data = purple_cipher_context_get_data(context);
- guchar halfkey[PBKDF2_HASH_MAX_LEN], halfkey_hash[PBKDF2_HASH_MAX_LEN];
- guint halfkey_len, halfkey_count, halfkey_pad, halfkey_no;
- guchar *salt_ext;
- size_t salt_ext_len;
- guint iter_no;
- PurpleCipherContext *hash;
-
- g_return_val_if_fail(ctx_data != NULL, FALSE);
- g_return_val_if_fail(digest != NULL, FALSE);
- g_return_val_if_fail(len >= ctx_data->out_len, FALSE);
-
- g_return_val_if_fail(ctx_data->hash_func != NULL, FALSE);
- g_return_val_if_fail(ctx_data->iter_count > 0, FALSE);
- g_return_val_if_fail(ctx_data->passphrase != NULL ||
- ctx_data->passphrase_len == 0, FALSE);
- g_return_val_if_fail(ctx_data->salt != NULL || ctx_data->salt_len == 0,
- FALSE);
- g_return_val_if_fail(ctx_data->out_len > 0, FALSE);
- g_return_val_if_fail(ctx_data->out_len < 0xFFFFFFFFU, FALSE);
-
- salt_ext_len = ctx_data->salt_len + 4;
-
- hash = purple_cipher_context_new_by_name("hmac", NULL);
- if (hash == NULL) {
- purple_debug_error("pbkdf2", "Couldn't create new hmac "
- "context\n");
- return FALSE;
- }
- purple_cipher_context_set_option(hash, "hash",
- (void*)ctx_data->hash_func);
- purple_cipher_context_set_key(hash, (const guchar*)ctx_data->passphrase,
- ctx_data->passphrase_len);
-
- halfkey_len = purple_cipher_context_get_digest_size(hash);
- if (halfkey_len <= 0 || halfkey_len > PBKDF2_HASH_MAX_LEN) {
- purple_debug_error("pbkdf2", "Unsupported hash function: %s "
- "(digest size: %d)\n",
- ctx_data->hash_func ? ctx_data->hash_func : "(null)",
- halfkey_len);
- return FALSE;
- }
-
- halfkey_count = ((ctx_data->out_len - 1) / halfkey_len) + 1;
- halfkey_pad = ctx_data->out_len - (halfkey_count - 1) * halfkey_len;
-
- salt_ext = g_new(guchar, salt_ext_len);
- memcpy(salt_ext, ctx_data->salt, ctx_data->salt_len);
-
- for (halfkey_no = 1; halfkey_no <= halfkey_count; halfkey_no++) {
- memset(halfkey, 0, halfkey_len);
-
- for (iter_no = 1; iter_no <= ctx_data->iter_count; iter_no++) {
- guint i;
-
- purple_cipher_context_reset_state(hash, NULL);
-
- if (iter_no == 1) {
- salt_ext[salt_ext_len - 4] =
- (halfkey_no & 0xff000000) >> 24;
- salt_ext[salt_ext_len - 3] =
- (halfkey_no & 0x00ff0000) >> 16;
- salt_ext[salt_ext_len - 2] =
- (halfkey_no & 0x0000ff00) >> 8;
- salt_ext[salt_ext_len - 1] =
- (halfkey_no & 0x000000ff) >> 0;
-
- purple_cipher_context_append(hash, salt_ext,
- salt_ext_len);
- }
- else
- purple_cipher_context_append(hash, halfkey_hash,
- halfkey_len);
-
- if (!purple_cipher_context_digest(hash, halfkey_hash,
- halfkey_len)) {
- purple_debug_error("pbkdf2",
- "Couldn't retrieve a digest\n");
- g_free(salt_ext);
- purple_cipher_context_destroy(hash);
- return FALSE;
- }
-
- for (i = 0; i < halfkey_len; i++)
- halfkey[i] ^= halfkey_hash[i];
- }
-
- memcpy(digest + (halfkey_no - 1) * halfkey_len, halfkey,
- (halfkey_no == halfkey_count) ? halfkey_pad :
- halfkey_len);
- }
-
- g_free(salt_ext);
- purple_cipher_context_destroy(hash);
-
- return TRUE;
-}
-
-static PurpleCipherOps PBKDF2Ops = {
- purple_pbkdf2_set_option, /* set_option */
- purple_pbkdf2_get_option, /* get_option */
- purple_pbkdf2_init, /* init */
- purple_pbkdf2_reset, /* reset */
- purple_pbkdf2_reset_state, /* reset_state */
- purple_pbkdf2_uninit, /* uninit */
- NULL, /* set_iv */
- NULL, /* append */
- purple_pbkdf2_digest, /* digest */
- purple_pbkdf2_get_digest_size, /* get_digest_size */
- NULL, /* encrypt */
- NULL, /* decrypt */
- purple_pbkdf2_set_salt, /* set_salt */
- NULL, /* get_salt_size */
- purple_pbkdf2_set_key, /* set_key */
- NULL, /* get_key_size */
- NULL, /* set_batch_mode */
- NULL, /* get_batch_mode */
- NULL, /* get_block_size */
- NULL, NULL, NULL, NULL /* reserved */
-};
-
-PurpleCipherOps *
-purple_pbkdf2_cipher_get_ops(void) {
- return &PBKDF2Ops;
-}
diff --git a/libpurple/ciphers/pbkdf2cipher.c b/libpurple/ciphers/pbkdf2cipher.c
new file mode 100644
index 0000000000..bd54c41348
--- /dev/null
+++ b/libpurple/ciphers/pbkdf2cipher.c
@@ -0,0 +1,418 @@
+/*
+ * 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
+ *
+ * Written by Tomek Wasilczyk <tomkiewicz@cpw.pidgin.im>
+ */
+
+#include "pbkdf2cipher.h"
+#include "hmaccipher.h"
+#include "debug.h"
+
+/* 1024bit */
+#define PBKDF2_HASH_MAX_LEN 128
+
+/******************************************************************************
+ * Structs
+ *****************************************************************************/
+#define PURPLE_PBKDF2_CIPHER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_PBKDF2_CIPHER, PurplePBKDF2CipherPrivate))
+
+typedef struct {
+ PurpleHash *hash;
+ guint iter_count;
+ size_t out_len;
+
+ guchar *salt;
+ size_t salt_len;
+ guchar *passphrase;
+ size_t passphrase_len;
+} PurplePBKDF2CipherPrivate;
+
+/******************************************************************************
+ * Enums
+ *****************************************************************************/
+enum {
+ PROP_NONE,
+ PROP_HASH,
+ PROP_ITER_COUNT,
+ PROP_OUT_LEN,
+ PROP_LAST,
+};
+
+/*******************************************************************************
+ * Globals
+ ******************************************************************************/
+static GObjectClass *parent_class = NULL;
+
+/*******************************************************************************
+ * Helpers
+ ******************************************************************************/
+static void
+purple_pbkdf2_cipher_set_hash(PurpleCipher *cipher,
+ PurpleHash *hash)
+{
+ PurplePBKDF2CipherPrivate *priv = PURPLE_PBKDF2_CIPHER_GET_PRIVATE(cipher);
+
+ priv->hash = g_object_ref(G_OBJECT(hash));
+ g_object_notify(G_OBJECT(cipher), "hash");
+}
+
+/******************************************************************************
+ * Cipher Stuff
+ *****************************************************************************/
+static void
+purple_pbkdf2_cipher_reset(PurpleCipher *cipher)
+{
+ PurplePBKDF2CipherPrivate *priv = PURPLE_PBKDF2_CIPHER_GET_PRIVATE(cipher);
+
+ g_return_if_fail(priv != NULL);
+
+ if(PURPLE_IS_HASH(priv->hash))
+ purple_hash_reset(priv->hash);
+ priv->iter_count = 1;
+ priv->out_len = 256;
+
+ purple_cipher_reset_state(cipher);
+}
+
+static void
+purple_pbkdf2_cipher_reset_state(PurpleCipher *cipher)
+{
+ PurplePBKDF2CipherPrivate *priv = PURPLE_PBKDF2_CIPHER_GET_PRIVATE(cipher);
+
+ g_return_if_fail(priv != NULL);
+
+ purple_cipher_set_salt(cipher, NULL, 0);
+ purple_cipher_set_key(cipher, NULL, 0);
+}
+
+static size_t
+purple_pbkdf2_cipher_get_digest_size(PurpleCipher *cipher)
+{
+ PurplePBKDF2CipherPrivate *priv = PURPLE_PBKDF2_CIPHER_GET_PRIVATE(cipher);
+
+ g_return_val_if_fail(priv != NULL, 0);
+
+ return priv->out_len;
+}
+
+static void
+purple_pbkdf2_cipher_set_salt(PurpleCipher *cipher, const guchar *salt, size_t len)
+{
+ PurplePBKDF2CipherPrivate *priv = PURPLE_PBKDF2_CIPHER_GET_PRIVATE(cipher);
+
+ g_return_if_fail(priv != NULL);
+
+ g_free(priv->salt);
+ priv->salt = NULL;
+ priv->salt_len = 0;
+
+ if (len == 0)
+ return;
+ g_return_if_fail(salt != NULL);
+
+ priv->salt = g_memdup(salt, len);
+ priv->salt_len = len;
+}
+
+static void
+purple_pbkdf2_cipher_set_key(PurpleCipher *cipher, const guchar *key,
+ size_t len)
+{
+ PurplePBKDF2CipherPrivate *priv = PURPLE_PBKDF2_CIPHER_GET_PRIVATE(cipher);
+
+ g_return_if_fail(priv != NULL);
+
+ if (priv->passphrase != NULL) {
+ memset(priv->passphrase, 0, priv->passphrase_len);
+ g_free(priv->passphrase);
+ priv->passphrase = NULL;
+ }
+ priv->passphrase_len = 0;
+
+ if (len == 0)
+ return;
+ g_return_if_fail(key != NULL);
+
+ priv->passphrase = g_memdup(key, len);
+ priv->passphrase_len = len;
+}
+
+/* inspired by gnutls 3.1.10, pbkdf2-sha1.c */
+static gboolean
+purple_pbkdf2_cipher_digest(PurpleCipher *cipher, guchar digest[], size_t len)
+{
+ PurplePBKDF2CipherPrivate *priv = PURPLE_PBKDF2_CIPHER_GET_PRIVATE(cipher);
+
+ guchar halfkey[PBKDF2_HASH_MAX_LEN], halfkey_hash[PBKDF2_HASH_MAX_LEN];
+ guint halfkey_len, halfkey_count, halfkey_pad, halfkey_no;
+ guchar *salt_ext;
+ size_t salt_ext_len;
+ guint iter_no;
+ PurpleCipher *hash;
+
+ g_return_val_if_fail(priv != NULL, FALSE);
+ g_return_val_if_fail(digest != NULL, FALSE);
+ g_return_val_if_fail(len >= priv->out_len, FALSE);
+
+ g_return_val_if_fail(priv->hash != NULL, FALSE);
+ g_return_val_if_fail(priv->iter_count > 0, FALSE);
+ g_return_val_if_fail(priv->passphrase != NULL ||
+ priv->passphrase_len == 0, FALSE);
+ g_return_val_if_fail(priv->salt != NULL || priv->salt_len == 0,
+ FALSE);
+ g_return_val_if_fail(priv->out_len > 0, FALSE);
+ g_return_val_if_fail(priv->out_len < 0xFFFFFFFFU, FALSE);
+
+ salt_ext_len = priv->salt_len + 4;
+
+ hash = purple_hmac_cipher_new(priv->hash);
+ if (hash == NULL) {
+ purple_debug_error("pbkdf2", "Couldn't create new hmac "
+ "cipher\n");
+ return FALSE;
+ }
+ purple_cipher_set_key(hash, (const guchar*)priv->passphrase,
+ priv->passphrase_len);
+
+ halfkey_len = purple_cipher_get_digest_size(hash);
+ if (halfkey_len <= 0 || halfkey_len > PBKDF2_HASH_MAX_LEN) {
+ purple_debug_error("pbkdf2", "Unsupported hash function. "
+ "(digest size: %d)\n", halfkey_len);
+ return FALSE;
+ }
+
+ halfkey_count = ((priv->out_len - 1) / halfkey_len) + 1;
+ halfkey_pad = priv->out_len - (halfkey_count - 1) * halfkey_len;
+
+ salt_ext = g_new(guchar, salt_ext_len);
+ memcpy(salt_ext, priv->salt, priv->salt_len);
+
+ for (halfkey_no = 1; halfkey_no <= halfkey_count; halfkey_no++) {
+ memset(halfkey, 0, halfkey_len);
+
+ for (iter_no = 1; iter_no <= priv->iter_count; iter_no++) {
+ guint i;
+
+ purple_cipher_reset_state(hash);
+
+ if (iter_no == 1) {
+ salt_ext[salt_ext_len - 4] =
+ (halfkey_no & 0xff000000) >> 24;
+ salt_ext[salt_ext_len - 3] =
+ (halfkey_no & 0x00ff0000) >> 16;
+ salt_ext[salt_ext_len - 2] =
+ (halfkey_no & 0x0000ff00) >> 8;
+ salt_ext[salt_ext_len - 1] =
+ (halfkey_no & 0x000000ff) >> 0;
+
+ purple_cipher_append(hash, salt_ext,
+ salt_ext_len);
+ }
+ else
+ purple_cipher_append(hash, halfkey_hash,
+ halfkey_len);
+
+ if (!purple_cipher_digest(hash, halfkey_hash,
+ halfkey_len)) {
+ purple_debug_error("pbkdf2",
+ "Couldn't retrieve a digest\n");
+ g_free(salt_ext);
+ g_object_unref(hash);
+ return FALSE;
+ }
+
+ for (i = 0; i < halfkey_len; i++)
+ halfkey[i] ^= halfkey_hash[i];
+ }
+
+ memcpy(digest + (halfkey_no - 1) * halfkey_len, halfkey,
+ (halfkey_no == halfkey_count) ? halfkey_pad :
+ halfkey_len);
+ }
+
+ g_free(salt_ext);
+ g_object_unref(hash);
+
+ return TRUE;
+}
+
+static const gchar*
+purple_pbkdf2_cipher_get_name(PurpleCipher *cipher)
+{
+ return "pbkdf2";
+}
+
+/******************************************************************************
+ * Object Stuff
+ *****************************************************************************/
+static void
+purple_pbkdf2_cipher_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurplePBKDF2Cipher *cipher = PURPLE_PBKDF2_CIPHER(obj);
+ PurplePBKDF2CipherPrivate *priv = PURPLE_PBKDF2_CIPHER_GET_PRIVATE(cipher);
+
+ switch(param_id) {
+ case PROP_HASH:
+ g_value_set_object(value, purple_pbkdf2_cipher_get_hash(cipher));
+ break;
+ case PROP_ITER_COUNT:
+ g_value_set_uint(value, priv->iter_count);
+ break;
+ case PROP_OUT_LEN:
+ g_value_set_uint(value, priv->out_len);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_pbkdf2_cipher_set_property(GObject *obj, guint param_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ PurpleCipher *cipher = PURPLE_CIPHER(obj);
+ PurplePBKDF2CipherPrivate *priv = PURPLE_PBKDF2_CIPHER_GET_PRIVATE(cipher);
+
+ switch(param_id) {
+ case PROP_HASH:
+ purple_pbkdf2_cipher_set_hash(cipher, g_value_get_object(value));
+ break;
+ case PROP_ITER_COUNT:
+ priv->iter_count = GPOINTER_TO_UINT(value);
+ break;
+ case PROP_OUT_LEN:
+ priv->out_len = GPOINTER_TO_UINT(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_pbkdf2_cipher_finalize(GObject *obj)
+{
+ PurpleCipher *cipher = PURPLE_CIPHER(obj);
+ PurplePBKDF2CipherPrivate *priv = PURPLE_PBKDF2_CIPHER_GET_PRIVATE(cipher);
+
+ purple_pbkdf2_cipher_reset(cipher);
+
+ if (priv->hash != NULL)
+ g_object_unref(priv->hash);
+
+ parent_class->finalize(obj);
+}
+
+static void
+purple_pbkdf2_cipher_class_init(PurplePBKDF2CipherClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ PurpleCipherClass *cipher_class = PURPLE_CIPHER_CLASS(klass);
+ GParamSpec *pspec;
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->finalize = purple_pbkdf2_cipher_finalize;
+ obj_class->get_property = purple_pbkdf2_cipher_get_property;
+ obj_class->set_property = purple_pbkdf2_cipher_set_property;
+
+ cipher_class->reset = purple_pbkdf2_cipher_reset;
+ cipher_class->reset_state = purple_pbkdf2_cipher_reset_state;
+ cipher_class->digest = purple_pbkdf2_cipher_digest;
+ cipher_class->get_digest_size = purple_pbkdf2_cipher_get_digest_size;
+ cipher_class->set_salt = purple_pbkdf2_cipher_set_salt;
+ cipher_class->set_key = purple_pbkdf2_cipher_set_key;
+ cipher_class->get_name = purple_pbkdf2_cipher_get_name;
+
+ pspec = g_param_spec_object("hash", "hash", "hash", PURPLE_TYPE_HASH,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property(obj_class, PROP_HASH, pspec);
+
+ pspec = g_param_spec_uint("iter_count", "iter_count", "iter_count", 0,
+ G_MAXUINT, 0, G_PARAM_READWRITE);
+ g_object_class_install_property(obj_class, PROP_ITER_COUNT, pspec);
+
+ pspec = g_param_spec_uint("out_len", "out_len", "out_len", 0,
+ G_MAXUINT, 0, G_PARAM_READWRITE);
+ g_object_class_install_property(obj_class, PROP_OUT_LEN, pspec);
+
+ g_type_class_add_private(klass, sizeof(PurplePBKDF2CipherPrivate));
+}
+
+static void
+purple_pbkdf2_cipher_init(PurpleCipher *cipher)
+{
+ purple_cipher_reset(cipher);
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GType
+purple_pbkdf2_cipher_get_gtype(void) {
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurplePBKDF2CipherClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_pbkdf2_cipher_class_init,
+ NULL,
+ NULL,
+ sizeof(PurplePBKDF2Cipher),
+ 0,
+ (GInstanceInitFunc)purple_pbkdf2_cipher_init,
+ NULL
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_CIPHER,
+ "PurplePBKDF2Cipher",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleCipher *
+purple_pbkdf2_cipher_new(PurpleHash *hash) {
+ g_return_val_if_fail(PURPLE_IS_HASH(hash), NULL);
+
+ return g_object_new(PURPLE_TYPE_PBKDF2_CIPHER,
+ "hash", hash,
+ NULL);
+}
+
+PurpleHash *
+purple_pbkdf2_cipher_get_hash(const PurplePBKDF2Cipher *cipher) {
+ PurplePBKDF2CipherPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_PBKDF2_CIPHER(cipher), NULL);
+
+ priv = PURPLE_PBKDF2_CIPHER_GET_PRIVATE(cipher);
+
+ if(priv && priv->hash)
+ return priv->hash;
+
+ return NULL;
+}
diff --git a/libpurple/ciphers/pbkdf2cipher.h b/libpurple/ciphers/pbkdf2cipher.h
new file mode 100644
index 0000000000..fc09e6236c
--- /dev/null
+++ b/libpurple/ciphers/pbkdf2cipher.h
@@ -0,0 +1,68 @@
+/**
+ * @file pbkdf2.h Purple PBKDF2 Cipher
+ * @ingroup core
+ */
+
+/* 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 PURPLE_PBKDF2_CIPHER_H
+#define PURPLE_PBKDF2_CIPHER_H
+
+#include "cipher.h"
+#include "hash.h"
+
+#define PURPLE_TYPE_PBKDF2_CIPHER (purple_pbkdf2_cipher_get_gtype())
+#define PURPLE_PBKDF2_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_PBKDF2_CIPHER, PurplePBKDF2Cipher))
+#define PURPLE_PBKDF2_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_PBKDF2_CIPHER, PurplePBKDF2CipherClass))
+#define PURPLE_IS_PBKDF2_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_PBKDF2_CIPHER))
+#define PURPLE_IS_PBKDF2_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), PURPLE_TYPE_PBKDF2_CIPHER))
+#define PURPLE_PBKDF2_CIPHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_PBKDF2_CIPHER, PurplePBKDF2CipherClass))
+
+typedef struct _PurplePBKDF2Cipher PurplePBKDF2Cipher;
+typedef struct _PurplePBKDF2CipherClass PurplePBKDF2CipherClass;
+
+struct _PurplePBKDF2Cipher {
+ /*< private >*/
+ PurpleCipher gparent;
+};
+
+struct _PurplePBKDF2CipherClass {
+ /*< private >*/
+ PurpleCipherClass gparent;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType purple_pbkdf2_cipher_get_gtype(void);
+
+PurpleCipher *purple_pbkdf2_cipher_new(PurpleHash *hash);
+
+PurpleHash *purple_pbkdf2_cipher_get_hash(const PurplePBKDF2Cipher *cipher);
+
+G_END_DECLS
+
+#endif /* PURPLE_PBKDF2_CIPHER_H */
+
diff --git a/libpurple/ciphers/rc4.c b/libpurple/ciphers/rc4.c
deleted file mode 100644
index de8101f58b..0000000000
--- a/libpurple/ciphers/rc4.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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
- */
-
-#include "internal.h"
-#include <cipher.h>
-#include "ciphers.h"
-#include <util.h>
-
-struct RC4Context {
- guchar state[256];
- guchar x;
- guchar y;
- gint key_len;
-};
-
-static void
-rc4_init(PurpleCipherContext *context, void *extra) {
- struct RC4Context *rc4_ctx;
- rc4_ctx = g_new0(struct RC4Context, 1);
- purple_cipher_context_set_data(context, rc4_ctx);
- purple_cipher_context_reset(context, extra);
-}
-
-
-static void
-rc4_reset(PurpleCipherContext *context, void *extra) {
- struct RC4Context *rc4_ctx;
- guint i;
-
- rc4_ctx = purple_cipher_context_get_data(context);
-
- g_return_if_fail(rc4_ctx);
-
- for(i = 0; i < 256; i++)
- rc4_ctx->state[i] = i;
- rc4_ctx->x = 0;
- rc4_ctx->y = 0;
-
- /* default is 5 bytes (40bit key) */
- rc4_ctx->key_len = 5;
-
-}
-
-static void
-rc4_uninit(PurpleCipherContext *context) {
- struct RC4Context *rc4_ctx;
-
- rc4_ctx = purple_cipher_context_get_data(context);
- memset(rc4_ctx, 0, sizeof(*rc4_ctx));
-
- g_free(rc4_ctx);
- rc4_ctx = NULL;
-}
-
-
-
-static void
-rc4_set_key (PurpleCipherContext *context, const guchar * key, size_t len) {
- struct RC4Context *ctx;
- guchar *state;
- guchar temp_swap;
- guchar x, y;
- guint i;
-
- ctx = purple_cipher_context_get_data(context);
-
- x = 0;
- y = 0;
- state = &ctx->state[0];
- ctx->key_len = len;
- for(i = 0; i < 256; i++)
- {
- y = (key[x] + state[i] + y) % 256;
- temp_swap = state[i];
- state[i] = state[y];
- state[y] = temp_swap;
- x = (x + 1) % len;
- }
-}
-
-
-static ssize_t
-rc4_encrypt(PurpleCipherContext *context, const guchar input[], size_t in_len,
- guchar output[], size_t out_size) {
- struct RC4Context *ctx;
- guchar temp_swap;
- guchar x, y, z;
- guchar *state;
- guint i;
-
- ctx = purple_cipher_context_get_data(context);
-
- x = ctx->x;
- y = ctx->y;
- state = &ctx->state[0];
-
- for(i = 0; i < in_len; i++)
- {
- x = (x + 1) % 256;
- y = (state[x] + y) % 256;
- temp_swap = state[x];
- state[x] = state[y];
- state[y] = temp_swap;
- z = state[x] + (state[y]) % 256;
- output[i] = input[i] ^ state[z];
- }
- ctx->x = x;
- ctx->y = y;
-
- return in_len;
-}
-
-static PurpleCipherOps RC4Ops = {
- NULL, /* Set Option */
- NULL, /* Get Option */
- rc4_init, /* init */
- rc4_reset, /* reset */
- NULL, /* reset state */
- rc4_uninit, /* uninit */
- NULL, /* set iv */
- NULL, /* append */
- NULL, /* digest */
- NULL, /* get digest size */
- rc4_encrypt, /* encrypt */
- NULL, /* decrypt */
- NULL, /* set salt */
- NULL, /* get salt size */
- rc4_set_key, /* set key */
- NULL, /* get key size */
- NULL, /* set batch mode */
- NULL, /* get batch mode */
- NULL, /* get block size */
- NULL, NULL, NULL, NULL /* reserved */
-};
-
-PurpleCipherOps *
-purple_rc4_cipher_get_ops(void) {
- return &RC4Ops;
-}
-
diff --git a/libpurple/ciphers/rc4cipher.c b/libpurple/ciphers/rc4cipher.c
new file mode 100644
index 0000000000..a4388f0d3f
--- /dev/null
+++ b/libpurple/ciphers/rc4cipher.c
@@ -0,0 +1,266 @@
+/*
+ * 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
+ */
+#include "rc4cipher.h"
+
+/*******************************************************************************
+ * Structs
+ ******************************************************************************/
+#define PURPLE_RC4_CIPHER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_RC4_CIPHER, PurpleRC4CipherPrivate))
+
+typedef struct {
+ guchar state[256];
+ guchar x;
+ guchar y;
+ gint key_len;
+} PurpleRC4CipherPrivate;
+
+/******************************************************************************
+ * Enums
+ *****************************************************************************/
+enum {
+ PROP_ZERO,
+ PROP_KEY_LEN,
+ PROP_KEY,
+ PROP_LAST,
+};
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+static GObjectClass *parent_class = NULL;
+
+/******************************************************************************
+ * Cipher Stuff
+ *****************************************************************************/
+static void
+purple_rc4_cipher_reset(PurpleCipher *cipher) {
+ PurpleRC4Cipher *rc4_cipher = PURPLE_RC4_CIPHER(cipher);
+ PurpleRC4CipherPrivate *priv = PURPLE_RC4_CIPHER_GET_PRIVATE(rc4_cipher);
+ guint i;
+
+ for(i = 0; i < 256; i++)
+ priv->state[i] = i;
+ priv->x = 0;
+ priv->y = 0;
+
+ /* default is 5 bytes (40bit key) */
+ priv->key_len = 5;
+}
+
+static void
+purple_rc4_cipher_set_key(PurpleCipher *cipher, const guchar *key, size_t len) {
+ PurpleRC4Cipher *rc4_cipher = PURPLE_RC4_CIPHER(cipher);
+ PurpleRC4CipherPrivate *priv = PURPLE_RC4_CIPHER_GET_PRIVATE(rc4_cipher);
+ guchar *state;
+ guchar temp_swap;
+ guchar x, y;
+ guint i;
+
+ x = 0;
+ y = 0;
+ state = &priv->state[0];
+ priv->key_len = len;
+ for(i = 0; i < 256; i++)
+ {
+ y = (key[x] + state[i] + y) % 256;
+ temp_swap = state[i];
+ state[i] = state[y];
+ state[y] = temp_swap;
+ x = (x + 1) % len;
+ }
+
+ g_object_notify(G_OBJECT(rc4_cipher), "key");
+}
+
+static ssize_t
+purple_rc4_cipher_encrypt(PurpleCipher *cipher, const guchar input[], size_t in_len,
+ guchar output[], size_t out_size)
+{
+ PurpleRC4Cipher *rc4_cipher = PURPLE_RC4_CIPHER(cipher);
+ guchar temp_swap;
+ guchar x, y, z;
+ guchar *state;
+ guint i;
+ PurpleRC4CipherPrivate *priv = PURPLE_RC4_CIPHER_GET_PRIVATE(rc4_cipher);
+
+ x = priv->x;
+ y = priv->y;
+ state = &priv->state[0];
+
+ for(i = 0; i < in_len; i++)
+ {
+ x = (x + 1) % 256;
+ y = (state[x] + y) % 256;
+ temp_swap = state[x];
+ state[x] = state[y];
+ state[y] = temp_swap;
+ z = state[x] + (state[y]) % 256;
+ output[i] = input[i] ^ state[z];
+ }
+ priv->x = x;
+ priv->y = y;
+
+ return in_len;
+}
+
+static const gchar*
+purple_rc4_cipher_get_name(PurpleCipher *cipher)
+{
+ return "rc4";
+}
+
+/******************************************************************************
+ * Object Stuff
+ *****************************************************************************/
+static void
+purple_rc4_cipher_set_property(GObject *obj, guint param_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ PurpleCipher *cipher = PURPLE_CIPHER(obj);
+ PurpleRC4Cipher *rc4_cipher = PURPLE_RC4_CIPHER(obj);
+
+ switch(param_id) {
+ case PROP_KEY_LEN:
+ purple_rc4_cipher_set_key_len(rc4_cipher, g_value_get_int(value));
+ break;
+ case PROP_KEY:
+ {
+ guchar *key = (guchar *)g_value_get_string(value);
+ purple_rc4_cipher_set_key(cipher, key, strlen((gchar *) key));
+ }
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_rc4_cipher_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleRC4Cipher *rc4_cipher = PURPLE_RC4_CIPHER(obj);
+
+ switch(param_id) {
+ case PROP_KEY_LEN:
+ g_value_set_int(value,
+ purple_rc4_cipher_get_key_len(rc4_cipher));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_rc4_cipher_class_init(PurpleRC4CipherClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ PurpleCipherClass *cipher_class = PURPLE_CIPHER_CLASS(klass);
+ GParamSpec *pspec = NULL;
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->set_property = purple_rc4_cipher_set_property;
+ obj_class->get_property = purple_rc4_cipher_get_property;
+
+ cipher_class->reset = purple_rc4_cipher_reset;
+ cipher_class->encrypt = purple_rc4_cipher_encrypt;
+ cipher_class->set_key = purple_rc4_cipher_set_key;
+ cipher_class->get_name = purple_rc4_cipher_get_name;
+
+ pspec = g_param_spec_int("key_len", "key_len", "key_len",
+ G_MININT, G_MAXINT, 0,
+ G_PARAM_READWRITE);
+ g_object_class_install_property(obj_class, PROP_KEY_LEN, pspec);
+
+ pspec = g_param_spec_string("key", "key", "key", NULL,
+ G_PARAM_WRITABLE);
+ g_object_class_install_property(obj_class, PROP_KEY, pspec);
+
+ g_type_class_add_private(klass, sizeof(PurpleRC4CipherPrivate));
+}
+
+static void
+purple_rc4_cipher_init(PurpleCipher *cipher) {
+ purple_rc4_cipher_reset(cipher);
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GType
+purple_rc4_cipher_get_gtype(void) {
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleRC4CipherClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_rc4_cipher_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleRC4Cipher),
+ 0,
+ (GInstanceInitFunc)purple_rc4_cipher_init,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_CIPHER,
+ "PurpleRC4Cipher",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleCipher *
+purple_rc4_cipher_new(void) {
+ return g_object_new(PURPLE_TYPE_RC4_CIPHER, NULL);
+}
+
+void
+purple_rc4_cipher_set_key_len(PurpleRC4Cipher *rc4_cipher,
+ gint key_len)
+{
+ PurpleRC4CipherPrivate *priv;
+
+ g_return_if_fail(PURPLE_IS_RC4_CIPHER(rc4_cipher));
+
+ priv = PURPLE_RC4_CIPHER_GET_PRIVATE(rc4_cipher);
+ priv->key_len = key_len;
+
+ g_object_notify(G_OBJECT(rc4_cipher), "key_len");
+}
+
+gint
+purple_rc4_cipher_get_key_len(PurpleRC4Cipher *rc4_cipher)
+{
+ PurpleRC4CipherPrivate *priv;
+
+ g_return_val_if_fail(PURPLE_IS_RC4_CIPHER(rc4_cipher), 0);
+
+ priv = PURPLE_RC4_CIPHER_GET_PRIVATE(rc4_cipher);
+
+ return priv->key_len;
+}
diff --git a/libpurple/ciphers/rc4cipher.h b/libpurple/ciphers/rc4cipher.h
new file mode 100644
index 0000000000..9565a43d12
--- /dev/null
+++ b/libpurple/ciphers/rc4cipher.h
@@ -0,0 +1,69 @@
+/**
+ * @file rc4.h Purple RC4 Cipher
+ * @ingroup core
+ */
+
+/* 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 PURPLE_RC4_CIPHER_H
+#define PURPLE_RC4_CIPHER_H
+
+#include "cipher.h"
+
+#define PURPLE_TYPE_RC4_CIPHER (purple_rc4_cipher_get_gtype())
+#define PURPLE_RC4_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_RC4_CIPHER, PurpleRC4Cipher))
+#define PURPLE_RC4_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_RC4_CIPHER, PurpleRC4CipherClass))
+#define PURPLE_IS_RC4_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_RC4_CIPHER))
+#define PURPLE_IS_RC4_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), PURPLE_TYPE_RC4_CIPHER))
+#define PURPLE_RC4_CIPHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_RC4_CIPHER, PurpleRC4CipherClass))
+
+typedef struct _PurpleRC4Cipher PurpleRC4Cipher;
+typedef struct _PurpleRC4CipherClass PurpleRC4CipherClass;
+
+struct _PurpleRC4Cipher {
+ /*< private >*/
+ PurpleCipher gparent;
+};
+
+struct _PurpleRC4CipherClass {
+ /*< private >*/
+ PurpleCipherClass gparent;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType purple_rc4_cipher_get_gtype(void);
+
+PurpleCipher *purple_rc4_cipher_new(void);
+
+gint purple_rc4_cipher_get_key_len(PurpleRC4Cipher *rc4_cipher);
+void purple_rc4_cipher_set_key_len(PurpleRC4Cipher *rc4_cipher, gint key_len);
+
+G_END_DECLS
+
+#endif /* PURPLE_RC4_CIPHER_H */
+
+
diff --git a/libpurple/ciphers/sha1hash.c b/libpurple/ciphers/sha1hash.c
new file mode 100644
index 0000000000..4ebd34fa15
--- /dev/null
+++ b/libpurple/ciphers/sha1hash.c
@@ -0,0 +1,195 @@
+/*
+ * 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
+ */
+#include "sha1hash.h"
+
+/*******************************************************************************
+ * Structs
+ ******************************************************************************/
+#define PURPLE_SHA1_HASH_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_SHA1_HASH, PurpleSHA1HashPrivate))
+
+typedef struct {
+ GChecksum *checksum;
+} PurpleSHA1HashPrivate;
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+static GObjectClass *parent_class = NULL;
+
+/******************************************************************************
+ * Hash Stuff
+ *****************************************************************************/
+
+static void
+purple_sha1_hash_reset(PurpleHash *hash)
+{
+ PurpleSHA1Hash *sha1_hash = PURPLE_SHA1_HASH(hash);
+ PurpleSHA1HashPrivate *priv = PURPLE_SHA1_HASH_GET_PRIVATE(sha1_hash);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(priv->checksum != NULL);
+
+ g_checksum_reset(priv->checksum);
+}
+
+static void
+purple_sha1_hash_append(PurpleHash *hash, const guchar *data,
+ gsize len)
+{
+ PurpleSHA1Hash *sha1_hash = PURPLE_SHA1_HASH(hash);
+ PurpleSHA1HashPrivate *priv = PURPLE_SHA1_HASH_GET_PRIVATE(sha1_hash);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(priv->checksum != NULL);
+
+ while (len >= G_MAXSSIZE) {
+ g_checksum_update(priv->checksum, data, G_MAXSSIZE);
+ len -= G_MAXSSIZE;
+ data += G_MAXSSIZE;
+ }
+
+ if (len)
+ g_checksum_update(priv->checksum, data, len);
+}
+
+static gboolean
+purple_sha1_hash_digest(PurpleHash *hash, guchar *digest, size_t buff_len)
+{
+ PurpleSHA1Hash *sha1_hash = PURPLE_SHA1_HASH(hash);
+ PurpleSHA1HashPrivate *priv = PURPLE_SHA1_HASH_GET_PRIVATE(sha1_hash);
+
+ const gssize required_len = g_checksum_type_get_length(G_CHECKSUM_SHA1);
+ gsize digest_len = buff_len;
+
+ g_return_val_if_fail(priv != NULL, FALSE);
+ g_return_val_if_fail(priv->checksum != NULL, FALSE);
+ g_return_val_if_fail(buff_len >= required_len, FALSE);
+
+ g_checksum_get_digest(priv->checksum, digest, &digest_len);
+
+ if (digest_len != required_len)
+ return FALSE;
+
+ purple_sha1_hash_reset(hash);
+
+ return TRUE;
+}
+
+static size_t
+purple_sha1_hash_get_block_size(PurpleHash *hash)
+{
+ return 64;
+}
+
+static size_t
+purple_sha1_hash_get_digest_size(PurpleHash *hash)
+{
+ return g_checksum_type_get_length(G_CHECKSUM_SHA1);
+}
+
+static const gchar*
+purple_sha1_hash_get_name(PurpleHash *hash)
+{
+ return "sha1";
+}
+
+/******************************************************************************
+ * Object Stuff
+ *****************************************************************************/
+
+static void
+purple_sha1_hash_finalize(GObject *obj)
+{
+ PurpleSHA1Hash *sha1_hash = PURPLE_SHA1_HASH(obj);
+ PurpleSHA1HashPrivate *priv = PURPLE_SHA1_HASH_GET_PRIVATE(sha1_hash);
+
+ if (priv->checksum)
+ g_checksum_free(priv->checksum);
+
+ parent_class->finalize(obj);
+}
+
+static void
+purple_sha1_hash_class_init(PurpleSHA1HashClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ PurpleHashClass *hash_class = PURPLE_HASH_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->finalize = purple_sha1_hash_finalize;
+
+ hash_class->reset = purple_sha1_hash_reset;
+ hash_class->reset_state = purple_sha1_hash_reset;
+ hash_class->append = purple_sha1_hash_append;
+ hash_class->digest = purple_sha1_hash_digest;
+ hash_class->get_digest_size = purple_sha1_hash_get_digest_size;
+ hash_class->get_block_size = purple_sha1_hash_get_block_size;
+ hash_class->get_name = purple_sha1_hash_get_name;
+
+ g_type_class_add_private(klass, sizeof(PurpleSHA1HashPrivate));
+}
+
+static void
+purple_sha1_hash_init(PurpleHash *hash)
+{
+ PurpleSHA1Hash *sha1_hash = PURPLE_SHA1_HASH(hash);
+ PurpleSHA1HashPrivate *priv = PURPLE_SHA1_HASH_GET_PRIVATE(sha1_hash);
+
+ priv->checksum = g_checksum_new(G_CHECKSUM_SHA1);
+
+ purple_sha1_hash_reset(hash);
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GType
+purple_sha1_hash_get_gtype(void) {
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleSHA1HashClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_sha1_hash_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleSHA1Hash),
+ 0,
+ (GInstanceInitFunc)purple_sha1_hash_init,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_HASH,
+ "PurpleSHA1Hash",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleHash *
+purple_sha1_hash_new(void) {
+ return g_object_new(PURPLE_TYPE_SHA1_HASH, NULL);
+}
diff --git a/libpurple/ciphers/sha1hash.h b/libpurple/ciphers/sha1hash.h
new file mode 100644
index 0000000000..bd4731374e
--- /dev/null
+++ b/libpurple/ciphers/sha1hash.h
@@ -0,0 +1,64 @@
+/**
+ * @file sha1.h Purple SHA1 Hash
+ * @ingroup core
+ */
+
+/* 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 PURPLE_SHA1_HASH_H
+#define PURPLE_SHA1_HASH_H
+
+#include "hash.h"
+
+#define PURPLE_TYPE_SHA1_HASH (purple_sha1_hash_get_gtype())
+#define PURPLE_SHA1_HASH(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_SHA1_HASH, PurpleSHA1Hash))
+#define PURPLE_SHA1_HASH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_SHA1_HASH, PurpleSHA1HashClass))
+#define PURPLE_IS_SHA1_HASH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_SHA1_HASH))
+#define PURPLE_IS_SHA1_HASH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), PURPLE_TYPE_SHA1_HASH))
+#define PURPLE_SHA1_HASH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_SHA1_HASH, PurpleSHA1HashClass))
+
+typedef struct _PurpleSHA1Hash PurpleSHA1Hash;
+typedef struct _PurpleSHA1HashClass PurpleSHA1HashClass;
+
+struct _PurpleSHA1Hash {
+ /*< private >*/
+ PurpleHash gparent;
+};
+
+struct _PurpleSHA1HashClass {
+ /*< private >*/
+ PurpleHashClass gparent;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType purple_sha1_hash_get_gtype(void);
+
+PurpleHash *purple_sha1_hash_new(void);
+
+G_END_DECLS
+
+#endif /* PURPLE_SHA1_HASH_H */
diff --git a/libpurple/ciphers/sha256hash.c b/libpurple/ciphers/sha256hash.c
new file mode 100644
index 0000000000..04b4674a86
--- /dev/null
+++ b/libpurple/ciphers/sha256hash.c
@@ -0,0 +1,195 @@
+/*
+ * 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
+ */
+#include "sha256hash.h"
+
+/*******************************************************************************
+ * Structs
+ ******************************************************************************/
+#define PURPLE_SHA256_HASH_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_SHA256_HASH, PurpleSHA256HashPrivate))
+
+typedef struct {
+ GChecksum *checksum;
+} PurpleSHA256HashPrivate;
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+static GObjectClass *parent_class = NULL;
+
+/******************************************************************************
+ * Hash Stuff
+ *****************************************************************************/
+
+static void
+purple_sha256_hash_reset(PurpleHash *hash)
+{
+ PurpleSHA256Hash *sha256_hash = PURPLE_SHA256_HASH(hash);
+ PurpleSHA256HashPrivate *priv = PURPLE_SHA256_HASH_GET_PRIVATE(sha256_hash);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(priv->checksum != NULL);
+
+ g_checksum_reset(priv->checksum);
+}
+
+static void
+purple_sha256_hash_append(PurpleHash *hash, const guchar *data,
+ gsize len)
+{
+ PurpleSHA256Hash *sha256_hash = PURPLE_SHA256_HASH(hash);
+ PurpleSHA256HashPrivate *priv = PURPLE_SHA256_HASH_GET_PRIVATE(sha256_hash);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(priv->checksum != NULL);
+
+ while (len >= G_MAXSSIZE) {
+ g_checksum_update(priv->checksum, data, G_MAXSSIZE);
+ len -= G_MAXSSIZE;
+ data += G_MAXSSIZE;
+ }
+
+ if (len)
+ g_checksum_update(priv->checksum, data, len);
+}
+
+static gboolean
+purple_sha256_hash_digest(PurpleHash *hash, guchar *digest, size_t buff_len)
+{
+ PurpleSHA256Hash *sha256_hash = PURPLE_SHA256_HASH(hash);
+ PurpleSHA256HashPrivate *priv = PURPLE_SHA256_HASH_GET_PRIVATE(sha256_hash);
+
+ const gssize required_len = g_checksum_type_get_length(G_CHECKSUM_SHA256);
+ gsize digest_len = buff_len;
+
+ g_return_val_if_fail(priv != NULL, FALSE);
+ g_return_val_if_fail(priv->checksum != NULL, FALSE);
+ g_return_val_if_fail(buff_len >= required_len, FALSE);
+
+ g_checksum_get_digest(priv->checksum, digest, &digest_len);
+
+ if (digest_len != required_len)
+ return FALSE;
+
+ purple_sha256_hash_reset(hash);
+
+ return TRUE;
+}
+
+static size_t
+purple_sha256_hash_get_block_size(PurpleHash *hash)
+{
+ return 64;
+}
+
+static size_t
+purple_sha256_hash_get_digest_size(PurpleHash *hash)
+{
+ return g_checksum_type_get_length(G_CHECKSUM_SHA256);
+}
+
+static const gchar*
+purple_sha256_hash_get_name(PurpleHash *hash)
+{
+ return "sha256";
+}
+
+/******************************************************************************
+ * Object Stuff
+ *****************************************************************************/
+
+static void
+purple_sha256_hash_finalize(GObject *obj)
+{
+ PurpleSHA256Hash *sha256_hash = PURPLE_SHA256_HASH(obj);
+ PurpleSHA256HashPrivate *priv = PURPLE_SHA256_HASH_GET_PRIVATE(sha256_hash);
+
+ if (priv->checksum)
+ g_checksum_free(priv->checksum);
+
+ parent_class->finalize(obj);
+}
+
+static void
+purple_sha256_hash_class_init(PurpleSHA256HashClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ PurpleHashClass *hash_class = PURPLE_HASH_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->finalize = purple_sha256_hash_finalize;
+
+ hash_class->reset = purple_sha256_hash_reset;
+ hash_class->reset_state = purple_sha256_hash_reset;
+ hash_class->append = purple_sha256_hash_append;
+ hash_class->digest = purple_sha256_hash_digest;
+ hash_class->get_digest_size = purple_sha256_hash_get_digest_size;
+ hash_class->get_block_size = purple_sha256_hash_get_block_size;
+ hash_class->get_name = purple_sha256_hash_get_name;
+
+ g_type_class_add_private(klass, sizeof(PurpleSHA256HashPrivate));
+}
+
+static void
+purple_sha256_hash_init(PurpleHash *hash)
+{
+ PurpleSHA256Hash *sha256_hash = PURPLE_SHA256_HASH(hash);
+ PurpleSHA256HashPrivate *priv = PURPLE_SHA256_HASH_GET_PRIVATE(sha256_hash);
+
+ priv->checksum = g_checksum_new(G_CHECKSUM_SHA256);
+
+ purple_sha256_hash_reset(hash);
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GType
+purple_sha256_hash_get_gtype(void) {
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleSHA256HashClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_sha256_hash_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleSHA256Hash),
+ 0,
+ (GInstanceInitFunc)purple_sha256_hash_init,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_HASH,
+ "PurpleSHA256Hash",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleHash *
+purple_sha256_hash_new(void) {
+ return g_object_new(PURPLE_TYPE_SHA256_HASH, NULL);
+}
diff --git a/libpurple/ciphers/sha256hash.h b/libpurple/ciphers/sha256hash.h
new file mode 100644
index 0000000000..72c778cf6f
--- /dev/null
+++ b/libpurple/ciphers/sha256hash.h
@@ -0,0 +1,64 @@
+/**
+ * @file sha256.h Purple SHA256 Hash
+ * @ingroup core
+ */
+
+/* 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 PURPLE_SHA256_HASH_H
+#define PURPLE_SHA256_HASH_H
+
+#include "hash.h"
+
+#define PURPLE_TYPE_SHA256_HASH (purple_sha256_hash_get_gtype())
+#define PURPLE_SHA256_HASH(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_SHA256_HASH, PurpleSHA256Hash))
+#define PURPLE_SHA256_HASH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_SHA256_HASH, PurpleSHA256HashClass))
+#define PURPLE_IS_SHA256_HASH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_SHA256_HASH))
+#define PURPLE_IS_SHA256_HASH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), PURPLE_TYPE_SHA256_HASH))
+#define PURPLE_SHA256_HASH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_SHA256_HASH, PurpleSHA256HashClass))
+
+typedef struct _PurpleSHA256Hash PurpleSHA256Hash;
+typedef struct _PurpleSHA256HashClass PurpleSHA256HashClass;
+
+struct _PurpleSHA256Hash {
+ /*< private >*/
+ PurpleHash gparent;
+};
+
+struct _PurpleSHA256HashClass {
+ /*< private >*/
+ PurpleHashClass gparent;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType purple_sha256_hash_get_gtype(void);
+
+PurpleHash *purple_sha256_hash_new(void);
+
+G_END_DECLS
+
+#endif /* PURPLE_SHA256_HASH_H */
diff --git a/libpurple/circbuffer.c b/libpurple/circbuffer.c
deleted file mode 100644
index 619d9c9758..0000000000
--- a/libpurple/circbuffer.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * @file circbuffer.h Buffer Utility Functions
- * @ingroup core
- */
-
-/* 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
- */
-#include "internal.h"
-
-#include "circbuffer.h"
-
-#define DEFAULT_BUF_SIZE 256
-
-PurpleCircBuffer *
-purple_circ_buffer_new(gsize growsize) {
- PurpleCircBuffer *buf = g_new0(PurpleCircBuffer, 1);
- buf->growsize = growsize ? growsize : DEFAULT_BUF_SIZE;
- return buf;
-}
-
-void purple_circ_buffer_destroy(PurpleCircBuffer *buf) {
- g_return_if_fail(buf != NULL);
-
- g_free(buf->buffer);
- g_free(buf);
-}
-
-static void grow_circ_buffer(PurpleCircBuffer *buf, gsize len) {
- int in_offset = 0, out_offset = 0;
- int start_buflen;
-
- g_return_if_fail(buf != NULL);
-
- start_buflen = buf->buflen;
-
- while ((buf->buflen - buf->bufused) < len)
- buf->buflen += buf->growsize;
-
- if (buf->inptr != NULL) {
- in_offset = buf->inptr - buf->buffer;
- out_offset = buf->outptr - buf->buffer;
- }
- buf->buffer = g_realloc(buf->buffer, buf->buflen);
-
- /* adjust the fill and remove pointer locations */
- if (buf->inptr == NULL) {
- buf->inptr = buf->outptr = buf->buffer;
- } else {
- buf->inptr = buf->buffer + in_offset;
- buf->outptr = buf->buffer + out_offset;
- }
-
- /* If the fill pointer is wrapped to before the remove
- * pointer, we need to shift the data */
- if (in_offset < out_offset
- || (in_offset == out_offset && buf->bufused > 0)) {
- int shift_n = MIN(buf->buflen - start_buflen,
- in_offset);
- memcpy(buf->buffer + start_buflen, buf->buffer,
- shift_n);
-
- /* If we couldn't fit the wrapped read buffer
- * at the end */
- if (shift_n < in_offset) {
- memmove(buf->buffer,
- buf->buffer + shift_n,
- in_offset - shift_n);
- buf->inptr = buf->buffer +
- (in_offset - shift_n);
- } else {
- buf->inptr = buf->buffer +
- start_buflen + in_offset;
- }
- }
-}
-
-void purple_circ_buffer_append(PurpleCircBuffer *buf, gconstpointer src, gsize len) {
-
- int len_stored;
-
- g_return_if_fail(buf != NULL);
-
- /* Grow the buffer, if necessary */
- if ((buf->buflen - buf->bufused) < len)
- grow_circ_buffer(buf, len);
-
- /* If there is not enough room to copy all of src before hitting
- * the end of the buffer then we will need to do two copies.
- * One copy from inptr to the end of the buffer, and the
- * second copy from the start of the buffer to the end of src. */
- if (buf->inptr >= buf->outptr)
- len_stored = MIN(len, buf->buflen
- - (buf->inptr - buf->buffer));
- else
- len_stored = len;
-
- if (len_stored > 0)
- memcpy(buf->inptr, src, len_stored);
-
- if (len_stored < len) {
- memcpy(buf->buffer, (char*)src + len_stored, len - len_stored);
- buf->inptr = buf->buffer + (len - len_stored);
- } else {
- buf->inptr += len_stored;
- }
-
- buf->bufused += len;
-}
-
-gsize purple_circ_buffer_get_max_read(const PurpleCircBuffer *buf) {
- gsize max_read;
-
- g_return_val_if_fail(buf != NULL, 0);
-
- if (buf->bufused == 0)
- max_read = 0;
- else if ((buf->outptr - buf->inptr) >= 0)
- max_read = buf->buflen - (buf->outptr - buf->buffer);
- else
- max_read = buf->inptr - buf->outptr;
-
- return max_read;
-}
-
-gboolean purple_circ_buffer_mark_read(PurpleCircBuffer *buf, gsize len) {
- g_return_val_if_fail(buf != NULL, FALSE);
- g_return_val_if_fail(purple_circ_buffer_get_max_read(buf) >= len, FALSE);
-
- buf->outptr += len;
- buf->bufused -= len;
- /* wrap to the start if we're at the end */
- if ((buf->outptr - buf->buffer) == buf->buflen)
- buf->outptr = buf->buffer;
-
- return TRUE;
-}
-
diff --git a/libpurple/circularbuffer.c b/libpurple/circularbuffer.c
new file mode 100644
index 0000000000..fa1e592d46
--- /dev/null
+++ b/libpurple/circularbuffer.c
@@ -0,0 +1,444 @@
+/*
+ * @file circbuffer.h Buffer Utility Functions
+ * @ingroup core
+ */
+
+/* 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
+ */
+#include "internal.h"
+
+#include "circularbuffer.h"
+
+#define DEFAULT_BUF_SIZE 256
+
+#define PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_CIRCULAR_BUFFER, PurpleCircularBufferPrivate))
+
+/******************************************************************************
+ * Structs
+ *****************************************************************************/
+typedef struct {
+ gchar *buffer;
+ gsize growsize;
+ gsize buflen;
+ gsize bufused;
+ gchar *input;
+ gchar *output;
+} PurpleCircularBufferPrivate;
+
+/******************************************************************************
+ * Enums
+ *****************************************************************************/
+enum {
+ PROP_ZERO,
+ PROP_GROW_SIZE,
+ PROP_BUFFER_USED,
+ PROP_INPUT,
+ PROP_OUTPUT,
+ PROP_LAST,
+};
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+static GObjectClass *parent_class = NULL;
+
+/******************************************************************************
+ * Circular Buffer Implementation
+ *****************************************************************************/
+static void
+purple_circular_buffer_real_grow(PurpleCircularBuffer *buffer, gsize len) {
+ PurpleCircularBufferPrivate *priv = NULL;
+ gint in_offset = 0, out_offset = 0;
+ gint start_buflen;
+
+ priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
+
+ start_buflen = priv->buflen;
+
+ while((priv->buflen - priv->bufused) < len)
+ priv->buflen += priv->growsize;
+
+ if(priv->input != NULL) {
+ in_offset = priv->input - priv->buffer;
+ out_offset = priv->output - priv->buffer;
+ }
+
+ priv->buffer = g_realloc(priv->buffer, priv->buflen);
+
+ /* adjust the fill and remove pointer locations */
+ if(priv->input == NULL) {
+ priv->input = priv->output = priv->buffer;
+ } else {
+ priv->input = priv->buffer + in_offset;
+ priv->output = priv->buffer + out_offset;
+ }
+
+ /* If the fill pointer is wrapped to before the remove
+ * pointer, we need to shift the data */
+ if(in_offset < out_offset
+ || (in_offset == out_offset && priv->bufused > 0))
+ {
+ gint shift_n = MIN(priv->buflen - start_buflen, in_offset);
+ memcpy(priv->buffer + start_buflen, priv->buffer, shift_n);
+
+ /* If we couldn't fit the wrapped read buffer at the end */
+ if (shift_n < in_offset) {
+ memmove(priv->buffer, priv->buffer + shift_n, in_offset - shift_n);
+ priv->input = priv->buffer + (in_offset - shift_n);
+ } else {
+ priv->input = priv->buffer + start_buflen + in_offset;
+ }
+ }
+}
+
+static void
+purple_circular_buffer_real_append(PurpleCircularBuffer *buffer,
+ gconstpointer src, gsize len)
+{
+ PurpleCircularBufferPrivate *priv = NULL;
+ gint len_stored;
+
+ priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
+
+ /* Grow the buffer, if necessary */
+ if((priv->buflen - priv->bufused) < len)
+ purple_circular_buffer_grow(buffer, len);
+
+ /* If there is not enough room to copy all of src before hitting
+ * the end of the buffer then we will need to do two copies.
+ * One copy from input to the end of the buffer, and the
+ * second copy from the start of the buffer to the end of src. */
+ if(priv->input >= priv->output)
+ len_stored = MIN(len, priv->buflen - (priv->input - priv->buffer));
+ else
+ len_stored = len;
+
+ if(len_stored > 0)
+ memcpy(priv->input, src, len_stored);
+
+ if(len_stored < len) {
+ memcpy(priv->buffer, (char*)src + len_stored, len - len_stored);
+ priv->input = priv->buffer + (len - len_stored);
+ } else {
+ priv->input += len_stored;
+ }
+
+ priv->bufused += len;
+}
+
+static gsize
+purple_circular_buffer_real_max_read_size(const PurpleCircularBuffer *buffer) {
+ PurpleCircularBufferPrivate *priv = NULL;
+ gsize max_read;
+
+ priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
+
+ if(priv->bufused == 0)
+ max_read = 0;
+ else if((priv->output - priv->input) >= 0)
+ max_read = priv->buflen - (priv->output - priv->buffer);
+ else
+ max_read = priv->input - priv->output;
+
+ return max_read;
+}
+
+static gboolean
+purple_circular_buffer_real_mark_read(PurpleCircularBuffer *buffer,
+ gsize len)
+{
+ PurpleCircularBufferPrivate *priv = NULL;
+
+ g_return_val_if_fail(purple_circular_buffer_get_max_read(buffer) >= len, FALSE);
+
+ priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
+
+ priv->output += len;
+ priv->bufused -= len;
+
+ /* wrap to the start if we're at the end */
+ if((priv->output - priv->buffer) == priv->buflen)
+ priv->output = priv->buffer;
+
+ return TRUE;
+}
+
+/******************************************************************************
+ * Private API
+ *****************************************************************************/
+static void
+purple_circular_buffer_set_grow_size(PurpleCircularBuffer *buffer,
+ gsize grow_size)
+{
+ PurpleCircularBufferPrivate *priv =
+ PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
+
+ priv->growsize = (grow_size != 0) ? grow_size : DEFAULT_BUF_SIZE;
+
+ g_object_notify(G_OBJECT(buffer), "grow-size");
+}
+
+/******************************************************************************
+ * Object Stuff
+ *****************************************************************************/
+static void
+purple_circular_buffer_finalize(GObject *obj) {
+ PurpleCircularBufferPrivate *priv =
+ PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(obj);
+
+ g_free(priv->buffer);
+
+ G_OBJECT_CLASS(parent_class)->finalize(obj);
+}
+
+static void
+purple_circular_buffer_get_property(GObject *obj, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ PurpleCircularBuffer *buffer = PURPLE_CIRCULAR_BUFFER(obj);
+
+ switch(param_id) {
+ case PROP_GROW_SIZE:
+ g_value_set_ulong(value,
+ purple_circular_buffer_get_grow_size(buffer));
+ break;
+ case PROP_BUFFER_USED:
+ g_value_set_ulong(value,
+ purple_circular_buffer_get_used(buffer));
+ break;
+ case PROP_INPUT:
+ g_value_set_pointer(value,
+ (void*) purple_circular_buffer_get_input(buffer));
+ break;
+ case PROP_OUTPUT:
+ g_value_set_pointer(value,
+ (void*) purple_circular_buffer_get_output(buffer));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_circular_buffer_set_property(GObject *obj, guint param_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ PurpleCircularBuffer *buffer = PURPLE_CIRCULAR_BUFFER(obj);
+
+ switch(param_id) {
+ case PROP_GROW_SIZE:
+ purple_circular_buffer_set_grow_size(buffer,
+ g_value_get_ulong(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_circular_buffer_class_init(PurpleCircularBufferClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ PurpleCircularBufferClass *buffer_class = PURPLE_CIRCULAR_BUFFER_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ g_type_class_add_private(klass, sizeof(PurpleCircularBufferPrivate));
+
+ obj_class->finalize = purple_circular_buffer_finalize;
+ obj_class->get_property = purple_circular_buffer_get_property;
+ obj_class->set_property = purple_circular_buffer_set_property;
+
+ buffer_class->grow = purple_circular_buffer_real_grow;
+ buffer_class->append = purple_circular_buffer_real_append;
+ buffer_class->max_read_size = purple_circular_buffer_real_max_read_size;
+ buffer_class->mark_read = purple_circular_buffer_real_mark_read;
+
+ /* using a ulong for the gsize properties since there is no
+ * g_param_spec_size, and the ulong should always work. --gk 3/21/11
+ */
+ g_object_class_install_property(obj_class, PROP_GROW_SIZE,
+ g_param_spec_ulong("grow-size", "grow-size",
+ "The grow size of the buffer",
+ 0, G_MAXSIZE, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property(obj_class, PROP_BUFFER_USED,
+ g_param_spec_ulong("buffer-used", "buffer-used",
+ "The amount of the buffer used",
+ 0, G_MAXSIZE, 0,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property(obj_class, PROP_INPUT,
+ g_param_spec_pointer("input", "input",
+ "The input pointer of the buffer",
+ G_PARAM_READABLE));
+
+ g_object_class_install_property(obj_class, PROP_OUTPUT,
+ g_param_spec_pointer("output", "output",
+ "The output pointer of the buffer",
+ G_PARAM_READABLE));
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GType
+purple_circular_buffer_get_type(void) {
+ static GType type = 0;
+
+ if(G_UNLIKELY(type == 0)) {
+ static const GTypeInfo info = {
+ .class_size = sizeof(PurpleCircularBufferClass),
+ .class_init = (GClassInitFunc)purple_circular_buffer_class_init,
+ .instance_size = sizeof(PurpleCircularBuffer),
+ };
+
+ type = g_type_register_static(G_TYPE_OBJECT,
+ "PurpleCircularBuffer",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleCircularBuffer *
+purple_circular_buffer_new(gsize growsize) {
+ return g_object_new(PURPLE_TYPE_CIRCULAR_BUFFER,
+ "grow-size", growsize ? growsize : DEFAULT_BUF_SIZE,
+ NULL);
+}
+
+void
+purple_circular_buffer_grow(PurpleCircularBuffer *buffer, gsize len) {
+ PurpleCircularBufferClass *klass = NULL;
+
+ g_return_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer));
+
+ klass = PURPLE_CIRCULAR_BUFFER_GET_CLASS(buffer);
+ if(klass && klass->grow)
+ klass->grow(buffer, len);
+}
+
+void
+purple_circular_buffer_append(PurpleCircularBuffer *buffer, gconstpointer src,
+ gsize len)
+{
+ PurpleCircularBufferClass *klass = NULL;
+
+ g_return_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer));
+ g_return_if_fail(src != NULL);
+
+ klass = PURPLE_CIRCULAR_BUFFER_GET_CLASS(buffer);
+ if(klass && klass->append)
+ klass->append(buffer, src, len);
+}
+
+gsize
+purple_circular_buffer_get_max_read(const PurpleCircularBuffer *buffer) {
+ PurpleCircularBufferClass *klass = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer), 0);
+
+ klass = PURPLE_CIRCULAR_BUFFER_GET_CLASS(buffer);
+ if(klass && klass->max_read_size)
+ return klass->max_read_size(buffer);
+
+ return 0;
+}
+
+gboolean
+purple_circular_buffer_mark_read(PurpleCircularBuffer *buffer, gsize len) {
+ PurpleCircularBufferClass *klass = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer), FALSE);
+
+ klass = PURPLE_CIRCULAR_BUFFER_CLASS(buffer);
+ if(klass && klass->mark_read)
+ return klass->mark_read(buffer, len);
+
+ return FALSE;
+}
+
+gsize
+purple_circular_buffer_get_grow_size(const PurpleCircularBuffer *buffer) {
+
+ PurpleCircularBufferPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer), 0);
+
+ priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
+
+ return priv->growsize;
+}
+
+gsize
+purple_circular_buffer_get_used(const PurpleCircularBuffer *buffer) {
+ PurpleCircularBufferPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer), 0);
+
+ priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
+
+ return priv->bufused;
+}
+
+const gchar *
+purple_circular_buffer_get_input(const PurpleCircularBuffer *buffer) {
+ PurpleCircularBufferPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer), NULL);
+
+ priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
+
+ return priv->input;
+}
+
+const gchar *
+purple_circular_buffer_get_output(const PurpleCircularBuffer *buffer) {
+ PurpleCircularBufferPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer), NULL);
+
+ priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
+
+ return priv->output;
+}
+
+void
+purple_circular_buffer_reset(PurpleCircularBuffer *buffer) {
+ PurpleCircularBufferPrivate *priv = NULL;
+ GObject *obj = NULL;
+
+ g_return_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer));
+
+ priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
+
+ priv->input = priv->buffer;
+ priv->output = priv->buffer;
+
+ obj = G_OBJECT(buffer);
+ g_object_freeze_notify(obj);
+ g_object_notify(obj, "input");
+ g_object_notify(obj, "output");
+ g_object_thaw_notify(obj);
+}
+
diff --git a/libpurple/circbuffer.h b/libpurple/circularbuffer.h
index 7e9283404c..080c2cf3ff 100644
--- a/libpurple/circbuffer.h
+++ b/libpurple/circularbuffer.h
@@ -21,38 +21,46 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
-#ifndef _CIRCBUFFER_H
-#define _CIRCBUFFER_H
+#ifndef PURPLE_CIRCULAR_BUFFER_H
+#define PURPLE_CIRCULAR_BUFFER_H
#include <glib.h>
-
-typedef struct _PurpleCircBuffer {
-
- /** A pointer to the starting address of our chunk of memory. */
- gchar *buffer;
-
- /** The incremental amount to increase this buffer by when
- * the buffer is not big enough to hold incoming data, in bytes. */
- gsize growsize;
-
- /** The length of this buffer, in bytes. */
- gsize buflen;
-
- /** The number of bytes of this buffer that contain unread data. */
- gsize bufused;
-
- /** A pointer to the next byte where new incoming data is
- * buffered to. */
- gchar *inptr;
-
- /** A pointer to the next byte of buffered data that should be
- * read by the consumer. */
- gchar *outptr;
-
-} PurpleCircBuffer;
+#include <glib-object.h>
+
+#define PURPLE_TYPE_CIRCULAR_BUFFER (purple_circular_buffer_get_type())
+#define PURPLE_CIRCULAR_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_CIRCULAR_BUFFER, PurpleCircularBuffer))
+#define PURPLE_CIRCULAR_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_CIRCULAR_BUFFER, PurpleCircularBufferClass))
+#define PURPLE_IS_CIRCULAR_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_CIRCULAR_BUFFER))
+#define PURPLE_IS_CIRCULAR_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_CIRCULAR_BUFFER))
+#define PURPLE_CIRCULAR_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_CIRCULAR_BUFFER, PurpleCircularBufferClass))
+
+typedef struct _PurpleCircularBuffer PurpleCircularBuffer;
+typedef struct _PurpleCircularBufferClass PurpleCircularBufferClass;
+
+struct _PurpleCircularBuffer {
+ /*< private >*/
+ GObject parent;
+};
+
+struct _PurpleCircularBufferClass {
+ /*< private >*/
+ GObjectClass parent;
+
+ void (*grow)(PurpleCircularBuffer *buffer, gsize len);
+ void (*append)(PurpleCircularBuffer *buffer, gconstpointer src, gsize len);
+ gsize (*max_read_size)(const PurpleCircularBuffer *buffer);
+ gboolean (*mark_read)(PurpleCircularBuffer *buffer, gsize len);
+
+ void (*purple_reserved1)(void);
+ void (*purple_reserved2)(void);
+ void (*purple_reserved3)(void);
+ void (*purple_reserved4)(void);
+};
G_BEGIN_DECLS
+GType purple_circular_buffer_get_type(void);
+
/**
* Creates a new circular buffer. This will not allocate any memory for the
* actual buffer until data is appended to it.
@@ -64,15 +72,7 @@ G_BEGIN_DECLS
* @return The new PurpleCircBuffer. This should be freed with
* purple_circ_buffer_destroy when you are done with it
*/
-PurpleCircBuffer *purple_circ_buffer_new(gsize growsize);
-
-/**
- * Dispose of the PurpleCircBuffer and free any memory used by it (including any
- * memory used by the internal buffer).
- *
- * @param buf The PurpleCircBuffer to free
- */
-void purple_circ_buffer_destroy(PurpleCircBuffer *buf);
+PurpleCircularBuffer *purple_circular_buffer_new(gsize growsize);
/**
* Append data to the PurpleCircBuffer. This will grow the internal
@@ -82,7 +82,7 @@ void purple_circ_buffer_destroy(PurpleCircBuffer *buf);
* @param src pointer to the data to copy into the buffer
* @param len number of bytes to copy into the buffer
*/
-void purple_circ_buffer_append(PurpleCircBuffer *buf, gconstpointer src, gsize len);
+void purple_circular_buffer_append(PurpleCircularBuffer *buf, gconstpointer src, gsize len);
/**
* Determine the maximum number of contiguous bytes that can be read from the
@@ -96,7 +96,7 @@ void purple_circ_buffer_append(PurpleCircBuffer *buf, gconstpointer src, gsize l
*
* @return the number of bytes that can be read from the PurpleCircBuffer
*/
-gsize purple_circ_buffer_get_max_read(const PurpleCircBuffer *buf);
+gsize purple_circular_buffer_get_max_read(const PurpleCircularBuffer *buf);
/**
* Mark the number of bytes that have been read from the buffer.
@@ -107,8 +107,16 @@ gsize purple_circ_buffer_get_max_read(const PurpleCircBuffer *buf);
* @return TRUE if we successfully marked the bytes as having been read, FALSE
* otherwise.
*/
-gboolean purple_circ_buffer_mark_read(PurpleCircBuffer *buf, gsize len);
+gboolean purple_circular_buffer_mark_read(PurpleCircularBuffer *buf, gsize len);
+
+void purple_circular_buffer_grow(PurpleCircularBuffer *buffer, gsize len);
+gsize purple_circular_buffer_get_grow_size(const PurpleCircularBuffer *buffer);
+gsize purple_circular_buffer_get_used(const PurpleCircularBuffer *buffer);
+const gchar *purple_circular_buffer_get_input(const PurpleCircularBuffer *buffer);
+const gchar *purple_circular_buffer_get_output(const PurpleCircularBuffer *buffer);
+void purple_circular_buffer_reset(PurpleCircularBuffer *buffer);
G_END_DECLS
-#endif /* _CIRCBUFFER_H */
+#endif /* PURPLE_CIRCULAR_BUFFER_H */
+
diff --git a/libpurple/cmds.c b/libpurple/cmds.c
index b29e4c4818..8ec906bb58 100644
--- a/libpurple/cmds.c
+++ b/libpurple/cmds.c
@@ -202,7 +202,7 @@ PurpleCmdStatus purple_cmd_do_command(PurpleConversation *conv, const gchar *cmd
PurpleCmd *c;
GList *l;
gchar *err = NULL;
- gboolean is_im;
+ gboolean is_im = TRUE;
gboolean found = FALSE, tried_cmd = FALSE, right_type = FALSE, right_prpl = FALSE;
const gchar *prpl_id;
gchar **args = NULL;
@@ -212,12 +212,8 @@ PurpleCmdStatus purple_cmd_do_command(PurpleConversation *conv, const gchar *cmd
*error = NULL;
prpl_id = purple_account_get_protocol_id(purple_conversation_get_account(conv));
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
- is_im = TRUE;
- else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
+ if (PURPLE_IS_CHAT_CONVERSATION(conv))
is_im = FALSE;
- else
- return PURPLE_CMD_STATUS_FAILED;
rest = strchr(cmdline, ' ');
if (rest) {
@@ -311,10 +307,10 @@ GList *purple_cmd_list(PurpleConversation *conv)
for (l = cmds; l; l = l->next) {
c = l->data;
- if (conv && (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM))
+ if (conv && PURPLE_IS_IM_CONVERSATION(conv))
if (!(c->flags & PURPLE_CMD_FLAG_IM))
continue;
- if (conv && (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT))
+ if (conv && PURPLE_IS_CHAT_CONVERSATION(conv))
if (!(c->flags & PURPLE_CMD_FLAG_CHAT))
continue;
@@ -343,10 +339,10 @@ GList *purple_cmd_help(PurpleConversation *conv, const gchar *cmd)
if (cmd && !purple_strequal(cmd, c->cmd))
continue;
- if (conv && (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM))
+ if (conv && PURPLE_IS_IM_CONVERSATION(conv))
if (!(c->flags & PURPLE_CMD_FLAG_IM))
continue;
- if (conv && (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT))
+ if (conv && PURPLE_IS_CHAT_CONVERSATION(conv))
if (!(c->flags & PURPLE_CMD_FLAG_CHAT))
continue;
@@ -373,13 +369,11 @@ void purple_cmds_init(void)
gpointer handle = purple_cmds_get_handle();
purple_signal_register(handle, "cmd-added",
- purple_marshal_VOID__POINTER_INT_INT, NULL, 3,
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_INT),
- purple_value_new(PURPLE_TYPE_INT));
+ purple_marshal_VOID__POINTER_INT_INT, G_TYPE_NONE, 3,
+ G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT);
purple_signal_register(handle, "cmd-removed",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_STRING));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ G_TYPE_STRING);
}
void purple_cmds_uninit(void)
diff --git a/libpurple/connection.c b/libpurple/connection.c
index 08f97f565b..b03c48e94f 100644
--- a/libpurple/connection.c
+++ b/libpurple/connection.c
@@ -27,10 +27,11 @@
#include "internal.h"
#include "account.h"
-#include "blist.h"
+#include "buddylist.h"
#include "connection.h"
#include "dbus-maybe.h"
#include "debug.h"
+#include "enums.h"
#include "http.h"
#include "log.h"
#include "notify.h"
@@ -43,25 +44,84 @@
#define KEEPALIVE_INTERVAL 30
+#define PURPLE_CONNECTION_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_CONNECTION, PurpleConnectionPrivate))
+
+/** @copydoc _PurpleConnectionPrivate */
+typedef struct _PurpleConnectionPrivate PurpleConnectionPrivate;
+
+/** Private data for a connection */
+struct _PurpleConnectionPrivate
+{
+ PurplePlugin *prpl; /**< The protocol plugin. */
+ PurpleConnectionFlags flags; /**< Connection flags. */
+
+ PurpleConnectionState state; /**< The connection state. */
+
+ PurpleAccount *account; /**< The account being connected to. */
+ char *password; /**< The password used. */
+
+ GSList *active_chats; /**< A list of active chats
+ (#PurpleChatConversation structs). */
+ void *proto_data; /**< Protocol-specific data.
+ TODO Remove this, and use
+ protocol-specific subclasses */
+
+ char *display_name; /**< How you appear to other people. */
+ guint keepalive; /**< Keep-alive. */
+
+ /** 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() to set this for them rather than
+ * setting it themselves.
+ * @see purple_connection_error_is_fatal
+ */
+ gboolean wants_to_die;
+
+ guint disconnect_timeout; /**< Timer used for nasty stack tricks */
+ time_t last_received; /**< When we last received a packet. Set by the
+ prpl to avoid sending unneeded keepalives */
+};
+
+/* GObject property enums */
+enum
+{
+ PROP_0,
+ PROP_PRPL,
+ PROP_FLAGS,
+ PROP_STATE,
+ PROP_ACCOUNT,
+ PROP_PASSWORD,
+ PROP_DISPLAY_NAME,
+ PROP_LAST
+};
+
+static GObjectClass *parent_class;
+
static GList *connections = NULL;
static GList *connections_connecting = NULL;
static PurpleConnectionUiOps *connection_ui_ops = NULL;
static int connections_handle;
+/**************************************************************************
+ * Connection API
+ **************************************************************************/
static gboolean
send_keepalive(gpointer data)
{
PurpleConnection *gc = data;
PurplePluginProtocolInfo *prpl_info;
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
/* Only send keep-alives if we haven't heard from the
* server in a while.
*/
- if ((time(NULL) - gc->last_received) < KEEPALIVE_INTERVAL)
+ if ((time(NULL) - priv->last_received) < KEEPALIVE_INTERVAL)
return TRUE;
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(priv->prpl);
if (prpl_info->keepalive)
prpl_info->keepalive(gc);
@@ -72,228 +132,27 @@ static void
update_keepalive(PurpleConnection *gc, gboolean on)
{
PurplePluginProtocolInfo *prpl_info = NULL;
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
- if (gc != NULL && gc->prpl != NULL)
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ if (priv != NULL && priv->prpl != NULL)
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(priv->prpl);
if (!prpl_info || !prpl_info->keepalive)
return;
- if (on && !gc->keepalive)
+ if (on && !priv->keepalive)
{
purple_debug_info("connection", "Activating keepalive.\n");
- gc->keepalive = purple_timeout_add_seconds(KEEPALIVE_INTERVAL, send_keepalive, gc);
+ priv->keepalive = purple_timeout_add_seconds(KEEPALIVE_INTERVAL, send_keepalive, gc);
}
- else if (!on && gc->keepalive > 0)
+ else if (!on && priv->keepalive > 0)
{
purple_debug_info("connection", "Deactivating keepalive.\n");
- purple_timeout_remove(gc->keepalive);
- gc->keepalive = 0;
- }
-}
-
-void
-_purple_connection_new(PurpleAccount *account, gboolean regist, const char *password)
-{
- PurpleConnection *gc;
- PurplePlugin *prpl;
- PurplePluginProtocolInfo *prpl_info;
-
- g_return_if_fail(account != NULL);
-
- if (!purple_account_is_disconnected(account))
- return;
-
- prpl = purple_find_prpl(purple_account_get_protocol_id(account));
-
- if (prpl != NULL)
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
- else {
- gchar *message;
-
- message = g_strdup_printf(_("Missing protocol plugin for %s"),
- purple_account_get_username(account));
- purple_notify_error(NULL, regist ? _("Registration Error") :
- _("Connection Error"), message, NULL);
- g_free(message);
- return;
- }
-
- if (regist)
- {
- if (prpl_info->register_user == NULL)
- return;
- }
- else
- {
- if (((password == NULL) || (*password == '\0')) &&
- !(prpl_info->options & OPT_PROTO_NO_PASSWORD) &&
- !(prpl_info->options & OPT_PROTO_PASSWORD_OPTIONAL))
- {
- purple_debug_error("connection", "Cannot connect to account %s without "
- "a password.\n", purple_account_get_username(account));
- return;
- }
- }
-
- gc = g_new0(PurpleConnection, 1);
- PURPLE_DBUS_REGISTER_POINTER(gc, PurpleConnection);
-
- gc->prpl = prpl;
- if ((password != NULL) && (*password != '\0'))
- gc->password = g_strdup(password);
- purple_connection_set_account(gc, account);
- purple_connection_set_state(gc, PURPLE_CONNECTING);
- connections = g_list_append(connections, gc);
- purple_account_set_connection(account, gc);
-
- purple_signal_emit(purple_connections_get_handle(), "signing-on", gc);
-
- if (regist)
- {
- purple_debug_info("connection", "Registering. gc = %p\n", gc);
-
- /* set this so we don't auto-reconnect after registering */
- gc->wants_to_die = TRUE;
-
- prpl_info->register_user(account);
- }
- else
- {
- purple_debug_info("connection", "Connecting. gc = %p\n", gc);
-
- purple_signal_emit(purple_accounts_get_handle(), "account-connecting", account);
- prpl_info->login(account);
+ purple_timeout_remove(priv->keepalive);
+ priv->keepalive = 0;
}
}
-void
-_purple_connection_new_unregister(PurpleAccount *account, const char *password, PurpleAccountUnregistrationCb cb, void *user_data)
-{
- /* Lots of copy/pasted code to avoid API changes. You might want to integrate that into the previous function when posssible. */
- PurpleConnection *gc;
- PurplePlugin *prpl;
- PurplePluginProtocolInfo *prpl_info;
-
- g_return_if_fail(account != NULL);
-
- prpl = purple_find_prpl(purple_account_get_protocol_id(account));
-
- if (prpl != NULL)
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
- else {
- gchar *message;
-
- message = g_strdup_printf(_("Missing protocol plugin for %s"),
- purple_account_get_username(account));
- purple_notify_error(NULL, _("Unregistration Error"), message, NULL);
- g_free(message);
- return;
- }
-
- if (!purple_account_is_disconnected(account)) {
- prpl_info->unregister_user(account, cb, user_data);
- return;
- }
-
- if (((password == NULL) || (*password == '\0')) &&
- !(prpl_info->options & OPT_PROTO_NO_PASSWORD) &&
- !(prpl_info->options & OPT_PROTO_PASSWORD_OPTIONAL))
- {
- purple_debug_error("connection", "Cannot connect to account %s without "
- "a password.\n", purple_account_get_username(account));
- return;
- }
-
- gc = g_new0(PurpleConnection, 1);
- PURPLE_DBUS_REGISTER_POINTER(gc, PurpleConnection);
-
- gc->prpl = prpl;
- if ((password != NULL) && (*password != '\0'))
- gc->password = g_strdup(password);
- purple_connection_set_account(gc, account);
- purple_connection_set_state(gc, PURPLE_CONNECTING);
- connections = g_list_append(connections, gc);
- purple_account_set_connection(account, gc);
-
- purple_signal_emit(purple_connections_get_handle(), "signing-on", gc);
-
- purple_debug_info("connection", "Unregistering. gc = %p\n", gc);
-
- prpl_info->unregister_user(account, cb, user_data);
-}
-
-void
-_purple_connection_destroy(PurpleConnection *gc)
-{
- PurpleAccount *account;
- GSList *buddies;
- PurplePluginProtocolInfo *prpl_info = NULL;
- gboolean remove = FALSE;
-
- g_return_if_fail(gc != NULL);
-
- account = purple_connection_get_account(gc);
-
- purple_debug_info("connection", "Disconnecting connection %p\n", gc);
-
- if (purple_connection_get_state(gc) != PURPLE_CONNECTING)
- remove = TRUE;
-
- purple_signal_emit(purple_connections_get_handle(), "signing-off", gc);
-
- while (gc->buddy_chats)
- {
- PurpleConversation *b = gc->buddy_chats->data;
-
- gc->buddy_chats = g_slist_remove(gc->buddy_chats, b);
- purple_conv_chat_left(PURPLE_CONV_CHAT(b));
- }
-
- update_keepalive(gc, FALSE);
-
- purple_http_conn_cancel_all(gc);
- purple_proxy_connect_cancel_with_handle(gc);
-
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
- if (prpl_info->close)
- (prpl_info->close)(gc);
-
- /* Clear out the proto data that was freed in the prpl close method*/
- buddies = purple_find_buddies(account, NULL);
- while (buddies != NULL) {
- PurpleBuddy *buddy = buddies->data;
- purple_buddy_set_protocol_data(buddy, NULL);
- buddies = g_slist_delete_link(buddies, buddies);
- }
-
- connections = g_list_remove(connections, gc);
-
- purple_connection_set_state(gc, PURPLE_DISCONNECTED);
-
- if (remove)
- purple_blist_remove_account(account);
-
- purple_signal_emit(purple_connections_get_handle(), "signed-off", gc);
-
- purple_account_request_close_with_account(account);
- purple_request_close_with_handle(gc);
- purple_notify_close_with_handle(gc);
-
- purple_debug_info("connection", "Destroying connection %p\n", gc);
-
- purple_account_set_connection(account, NULL);
-
- purple_str_wipe(gc->password);
- g_free(gc->display_name);
-
- if (gc->disconnect_timeout > 0)
- purple_timeout_remove(gc->disconnect_timeout);
-
- PURPLE_DBUS_UNREGISTER_POINTER(gc);
- g_free(gc);
-}
-
/*
* d:)->-<
*
@@ -308,24 +167,25 @@ void
purple_connection_set_state(PurpleConnection *gc, PurpleConnectionState state)
{
PurpleConnectionUiOps *ops;
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
- g_return_if_fail(gc != NULL);
+ g_return_if_fail(priv != NULL);
- if (gc->state == state)
+ if (priv->state == state)
return;
- gc->state = state;
+ priv->state = state;
ops = purple_connections_get_ui_ops();
- if (gc->state == PURPLE_CONNECTING) {
+ if (priv->state == PURPLE_CONNECTION_CONNECTING) {
connections_connecting = g_list_append(connections_connecting, gc);
}
else {
connections_connecting = g_list_remove(connections_connecting, gc);
}
- if (gc->state == PURPLE_CONNECTED) {
+ if (priv->state == PURPLE_CONNECTION_CONNECTED) {
PurpleAccount *account;
PurplePresence *presence;
@@ -363,7 +223,7 @@ purple_connection_set_state(PurpleConnection *gc, PurpleConnectionState state)
update_keepalive(gc, TRUE);
}
- else if (gc->state == PURPLE_DISCONNECTED) {
+ else if (priv->state == PURPLE_CONNECTION_DISCONNECTED) {
PurpleAccount *account = purple_connection_get_account(gc);
if (purple_prefs_get_bool("/purple/logging/log_system"))
@@ -391,89 +251,153 @@ purple_connection_set_state(PurpleConnection *gc, PurpleConnectionState state)
void
purple_connection_set_flags(PurpleConnection *gc, PurpleConnectionFlags flags)
{
- g_return_if_fail(gc != NULL);
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
- gc->flags = flags;
+ g_return_if_fail(priv != NULL);
+
+ priv->flags = flags;
}
void
purple_connection_set_account(PurpleConnection *gc, PurpleAccount *account)
{
- g_return_if_fail(gc != NULL);
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
+
+ g_return_if_fail(priv != NULL);
g_return_if_fail(account != NULL);
- gc->account = account;
+ priv->account = account;
}
void
purple_connection_set_display_name(PurpleConnection *gc, const char *name)
{
- g_return_if_fail(gc != NULL);
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
+
+ g_return_if_fail(priv != NULL);
- g_free(gc->display_name);
- gc->display_name = g_strdup(name);
+ g_free(priv->display_name);
+ priv->display_name = g_strdup(name);
}
void
-purple_connection_set_protocol_data(PurpleConnection *connection, void *proto_data) {
- g_return_if_fail(connection != NULL);
+purple_connection_set_protocol_data(PurpleConnection *gc, void *proto_data)
+{
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
+
+ g_return_if_fail(priv != NULL);
- connection->proto_data = proto_data;
+ priv->proto_data = proto_data;
}
PurpleConnectionState
purple_connection_get_state(const PurpleConnection *gc)
{
- g_return_val_if_fail(gc != NULL, PURPLE_DISCONNECTED);
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
- return gc->state;
+ g_return_val_if_fail(priv != NULL, PURPLE_CONNECTION_DISCONNECTED);
+
+ return priv->state;
}
PurpleConnectionFlags
purple_connection_get_flags(const PurpleConnection *gc)
{
- g_return_val_if_fail(gc != NULL, 0);
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
+
+ g_return_val_if_fail(priv != NULL, 0);
- return gc->flags;
+ return priv->flags;
}
PurpleAccount *
purple_connection_get_account(const PurpleConnection *gc)
{
- g_return_val_if_fail(gc != NULL, NULL);
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
- return gc->account;
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->account;
}
PurplePlugin *
purple_connection_get_prpl(const PurpleConnection *gc)
{
- g_return_val_if_fail(gc != NULL, NULL);
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
+
+ g_return_val_if_fail(priv != NULL, NULL);
- return gc->prpl;
+ return priv->prpl;
}
const char *
purple_connection_get_password(const PurpleConnection *gc)
{
- g_return_val_if_fail(gc != NULL, NULL);
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->password;
+}
+
+GSList *
+purple_connection_get_active_chats(const PurpleConnection *gc)
+{
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
- return gc->password;
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->active_chats;
}
const char *
purple_connection_get_display_name(const PurpleConnection *gc)
{
- g_return_val_if_fail(gc != NULL, NULL);
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
+
+ g_return_val_if_fail(priv != NULL, NULL);
- return gc->display_name;
+ return priv->display_name;
}
void *
-purple_connection_get_protocol_data(const PurpleConnection *connection) {
- g_return_val_if_fail(connection != NULL, NULL);
+purple_connection_get_protocol_data(const PurpleConnection *gc)
+{
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
- return connection->proto_data;
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->proto_data;
+}
+
+void
+_purple_connection_add_active_chat(PurpleConnection *gc, PurpleChatConversation *chat)
+{
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->active_chats = g_slist_append(priv->active_chats, chat);
+}
+
+void
+_purple_connection_remove_active_chat(PurpleConnection *gc, PurpleChatConversation *chat)
+{
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->active_chats = g_slist_remove(priv->active_chats, chat);
+}
+
+gboolean
+_purple_connection_wants_to_die(const PurpleConnection *gc)
+{
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
+
+ g_return_val_if_fail(priv != NULL, FALSE);
+
+ return priv->wants_to_die;
}
void
@@ -512,12 +436,14 @@ purple_connection_disconnect_cb(gpointer data)
{
PurpleAccount *account;
PurpleConnection *gc;
+ PurpleConnectionPrivate *priv;
account = data;
gc = purple_account_get_connection(account);
+ priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
- if (gc != NULL)
- gc->disconnect_timeout = 0;
+ if (priv != NULL)
+ priv->disconnect_timeout = 0;
purple_account_disconnect(account);
return FALSE;
@@ -529,8 +455,9 @@ purple_connection_error (PurpleConnection *gc,
const char *description)
{
PurpleConnectionUiOps *ops;
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
- g_return_if_fail(gc != NULL);
+ g_return_if_fail(priv != NULL);
/* This sanity check relies on PURPLE_CONNECTION_ERROR_OTHER_ERROR
* being the last member of the PurpleConnectionError enum in
* connection.h; if other reasons are added after it, this check should
@@ -549,10 +476,10 @@ purple_connection_error (PurpleConnection *gc,
}
/* If we've already got one error, we don't need any more */
- if (gc->disconnect_timeout > 0)
+ if (priv->disconnect_timeout > 0)
return;
- gc->wants_to_die = purple_connection_error_is_fatal (reason);
+ priv->wants_to_die = purple_connection_error_is_fatal (reason);
purple_debug_info("connection", "Connection error on %p (reason: %u description: %s)\n",
gc, reason, description);
@@ -565,7 +492,7 @@ purple_connection_error (PurpleConnection *gc,
purple_signal_emit(purple_connections_get_handle(), "connection-error",
gc, reason, description);
- gc->disconnect_timeout = purple_timeout_add(0, purple_connection_disconnect_cb,
+ priv->disconnect_timeout = purple_timeout_add(0, purple_connection_disconnect_cb,
purple_connection_get_account(gc));
}
@@ -626,21 +553,457 @@ purple_connection_error_is_fatal (PurpleConnectionError reason)
void purple_connection_update_last_received(PurpleConnection *gc)
{
- g_return_if_fail(gc != NULL);
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->last_received = time(NULL);
+}
+
+/**************************************************************************
+ * GBoxed code
+ **************************************************************************/
+static PurpleConnectionErrorInfo *
+purple_connection_error_info_copy(PurpleConnectionErrorInfo *err)
+{
+ PurpleConnectionErrorInfo *newerr;
- gc->last_received = time(NULL);
+ g_return_val_if_fail(err != NULL, NULL);
+
+ newerr = g_new(PurpleConnectionErrorInfo, 1);
+ newerr->type = err->type;
+ newerr->description = g_strdup(err->description);
+
+ return newerr;
+}
+
+static void
+purple_connection_error_info_free(PurpleConnectionErrorInfo *err)
+{
+ g_return_if_fail(err != NULL);
+
+ g_free(err->description);
+ g_free(err);
+}
+
+GType
+purple_connection_error_info_get_type(void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_boxed_type_register_static("PurpleConnectionErrorInfo",
+ (GBoxedCopyFunc)purple_connection_error_info_copy,
+ (GBoxedFreeFunc)purple_connection_error_info_free);
+ }
+
+ return type;
+}
+
+/**************************************************************************
+ * GObject code
+ **************************************************************************/
+/* GObject Property names */
+#define PROP_PRPL_S "prpl"
+#define PROP_FLAGS_S "flags"
+#define PROP_STATE_S "state"
+#define PROP_ACCOUNT_S "account"
+#define PROP_PASSWORD_S "password"
+#define PROP_DISPLAY_NAME_S "display-name"
+
+/* Set method for GObject properties */
+static void
+purple_connection_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleConnection *gc = PURPLE_CONNECTION(obj);
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
+
+ switch (param_id) {
+ case PROP_PRPL:
+#warning TODO: change get_pointer to get_object when prpl is a GObject
+ priv->prpl = g_value_get_pointer(value);
+ break;
+ case PROP_FLAGS:
+ purple_connection_set_flags(gc, g_value_get_flags(value));
+ break;
+ case PROP_STATE:
+ purple_connection_set_state(gc, g_value_get_enum(value));
+ break;
+ case PROP_ACCOUNT:
+ purple_connection_set_account(gc, g_value_get_object(value));
+ break;
+ case PROP_PASSWORD:
+ g_free(priv->password);
+ priv->password = g_strdup(g_value_get_string(value));
+ break;
+ case PROP_DISPLAY_NAME:
+ purple_connection_set_display_name(gc, g_value_get_string(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Get method for GObject properties */
+static void
+purple_connection_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleConnection *gc = PURPLE_CONNECTION(obj);
+
+ switch (param_id) {
+ case PROP_PRPL:
+#warning TODO: change set_pointer to set_object when prpl is a GObject
+ g_value_set_pointer(value, purple_connection_get_prpl(gc));
+ break;
+ case PROP_FLAGS:
+ g_value_set_flags(value, purple_connection_get_flags(gc));
+ break;
+ case PROP_STATE:
+ g_value_set_enum(value, purple_connection_get_state(gc));
+ break;
+ case PROP_ACCOUNT:
+ g_value_set_object(value, purple_connection_get_account(gc));
+ break;
+ case PROP_PASSWORD:
+ g_value_set_string(value, purple_connection_get_password(gc));
+ break;
+ case PROP_DISPLAY_NAME:
+ g_value_set_string(value, purple_connection_get_display_name(gc));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* GObject initialization function */
+static void
+purple_connection_init(GTypeInstance *instance, gpointer klass)
+{
+ PurpleConnection *gc = PURPLE_CONNECTION(instance);
+
+ purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTING);
+ connections = g_list_append(connections, gc);
+
+ PURPLE_DBUS_REGISTER_POINTER(gc, PurpleConnection);
+}
+
+/* Called when done constructing */
+static void
+purple_connection_constructed(GObject *object)
+{
+ PurpleConnection *gc = PURPLE_CONNECTION(object);
+ PurpleAccount *account;
+
+ G_OBJECT_CLASS(parent_class)->constructed(object);
+
+ g_object_get(gc, PROP_ACCOUNT_S, &account, NULL);
+ purple_account_set_connection(account, gc);
+
+ purple_signal_emit(purple_connections_get_handle(), "signing-on", gc);
+}
+
+/* GObject dispose function */
+static void
+purple_connection_dispose(GObject *object)
+{
+ PurpleConnection *gc = PURPLE_CONNECTION(object);
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
+ PurpleAccount *account;
+ GSList *buddies;
+ PurplePluginProtocolInfo *prpl_info = NULL;
+ gboolean remove = FALSE;
+
+ account = purple_connection_get_account(gc);
+
+ purple_debug_info("connection", "Disconnecting connection %p\n", gc);
+
+ if (purple_connection_get_state(gc) != PURPLE_CONNECTION_CONNECTING)
+ remove = TRUE;
+
+ purple_signal_emit(purple_connections_get_handle(), "signing-off", gc);
+
+ while (priv->active_chats)
+ {
+ PurpleChatConversation *b = priv->active_chats->data;
+
+ priv->active_chats = g_slist_remove(priv->active_chats, b);
+ purple_chat_conversation_leave(b);
+ }
+
+ update_keepalive(gc, FALSE);
+
+ purple_http_conn_cancel_all(gc);
+ purple_proxy_connect_cancel_with_handle(gc);
+
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(priv->prpl);
+ if (prpl_info->close)
+ (prpl_info->close)(gc);
+
+ /* Clear out the proto data that was freed in the prpl close method*/
+ buddies = purple_blist_find_buddies(account, NULL);
+ while (buddies != NULL) {
+ PurpleBuddy *buddy = buddies->data;
+ purple_buddy_set_protocol_data(buddy, NULL);
+ buddies = g_slist_delete_link(buddies, buddies);
+ }
+
+ connections = g_list_remove(connections, gc);
+
+ purple_connection_set_state(gc, PURPLE_CONNECTION_DISCONNECTED);
+
+ if (remove)
+ purple_blist_remove_account(account);
+
+ purple_signal_emit(purple_connections_get_handle(), "signed-off", gc);
+
+ purple_account_request_close_with_account(account);
+ purple_request_close_with_handle(gc);
+ purple_notify_close_with_handle(gc);
+
+ purple_debug_info("connection", "Destroying connection %p\n", gc);
+
+ purple_account_set_connection(account, NULL);
+
+ if (priv->disconnect_timeout > 0)
+ purple_timeout_remove(priv->disconnect_timeout);
+
+ PURPLE_DBUS_UNREGISTER_POINTER(gc);
+
+ G_OBJECT_CLASS(parent_class)->dispose(object);
+}
+
+/* GObject finalize function */
+static void
+purple_connection_finalize(GObject *object)
+{
+ PurpleConnectionPrivate *priv = PURPLE_CONNECTION_GET_PRIVATE(object);
+
+ purple_str_wipe(priv->password);
+ g_free(priv->display_name);
+
+ G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+/* Class initializer function */
+static void purple_connection_class_init(PurpleConnectionClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->dispose = purple_connection_dispose;
+ obj_class->finalize = purple_connection_finalize;
+ obj_class->constructed = purple_connection_constructed;
+
+ /* Setup properties */
+ obj_class->get_property = purple_connection_get_property;
+ obj_class->set_property = purple_connection_set_property;
+
+#warning TODO: change spec_pointer to spec_object when prpl is a GObject
+ g_object_class_install_property(obj_class, PROP_PRPL,
+ g_param_spec_pointer(PROP_PRPL_S, _("Protocol plugin"),
+ _("The prpl that is using the connection."),
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)
+ );
+
+ g_object_class_install_property(obj_class, PROP_FLAGS,
+ g_param_spec_flags(PROP_FLAGS_S, _("Connection flags"),
+ _("The flags of the connection."),
+ PURPLE_TYPE_CONNECTION_FLAGS, 0,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, PROP_STATE,
+ g_param_spec_enum(PROP_STATE_S, _("Connection state"),
+ _("The current state of the connection."),
+ PURPLE_TYPE_CONNECTION_STATE, PURPLE_CONNECTION_DISCONNECTED,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, PROP_ACCOUNT,
+ g_param_spec_object(PROP_ACCOUNT_S, _("Account"),
+ _("The account using the connection."), PURPLE_TYPE_ACCOUNT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
+ );
+
+ g_object_class_install_property(obj_class, PROP_PASSWORD,
+ g_param_spec_string(PROP_PASSWORD_S, _("Password"),
+ _("The password used for connection."), NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)
+ );
+
+ g_object_class_install_property(obj_class, PROP_DISPLAY_NAME,
+ g_param_spec_string(PROP_DISPLAY_NAME_S, _("Display name"),
+ _("Your name that appears to other people."), NULL,
+ G_PARAM_READWRITE)
+ );
+
+ g_type_class_add_private(klass, sizeof(PurpleConnectionPrivate));
+}
+
+GType
+purple_connection_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleConnectionClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_connection_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleConnection),
+ 0,
+ (GInstanceInitFunc)purple_connection_init,
+ NULL,
+ };
+
+ type = g_type_register_static(G_TYPE_OBJECT, "PurpleConnection",
+ &info, 0);
+ }
+
+ return type;
+}
+
+void
+_purple_connection_new(PurpleAccount *account, gboolean regist, const char *password)
+{
+ PurpleConnection *gc;
+ PurplePlugin *prpl;
+ PurplePluginProtocolInfo *prpl_info;
+
+ g_return_if_fail(account != NULL);
+
+ if (!purple_account_is_disconnected(account))
+ return;
+
+ prpl = purple_find_prpl(purple_account_get_protocol_id(account));
+
+ if (prpl != NULL)
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
+ else {
+ gchar *message;
+
+ message = g_strdup_printf(_("Missing protocol plugin for %s"),
+ purple_account_get_username(account));
+ purple_notify_error(NULL, regist ? _("Registration Error") :
+ _("Connection Error"), message, NULL);
+ g_free(message);
+ return;
+ }
+
+ if (regist)
+ {
+ if (prpl_info->register_user == NULL)
+ return;
+ }
+ else
+ {
+ if (((password == NULL) || (*password == '\0')) &&
+ !(prpl_info->options & OPT_PROTO_NO_PASSWORD) &&
+ !(prpl_info->options & OPT_PROTO_PASSWORD_OPTIONAL))
+ {
+ purple_debug_error("connection", "Cannot connect to account %s without "
+ "a password.\n", purple_account_get_username(account));
+ return;
+ }
+ }
+
+ gc = g_object_new(PURPLE_TYPE_CONNECTION,
+ PROP_PRPL_S, prpl,
+ PROP_PASSWORD_S, password,
+ PROP_ACCOUNT_S, account,
+ NULL);
+
+ if (regist)
+ {
+ purple_debug_info("connection", "Registering. gc = %p\n", gc);
+
+ /* set this so we don't auto-reconnect after registering */
+ PURPLE_CONNECTION_GET_PRIVATE(gc)->wants_to_die = TRUE;
+
+ prpl_info->register_user(account);
+ }
+ else
+ {
+ purple_debug_info("connection", "Connecting. gc = %p\n", gc);
+
+ purple_signal_emit(purple_accounts_get_handle(), "account-connecting", account);
+ prpl_info->login(account);
+ }
+}
+
+void
+_purple_connection_new_unregister(PurpleAccount *account, const char *password,
+ PurpleAccountUnregistrationCb cb, void *user_data)
+{
+ /* Lots of copy/pasted code to avoid API changes. You might want to integrate that into the previous function when posssible. */
+ PurpleConnection *gc;
+ PurplePlugin *prpl;
+ PurplePluginProtocolInfo *prpl_info;
+
+ g_return_if_fail(account != NULL);
+
+ prpl = purple_find_prpl(purple_account_get_protocol_id(account));
+
+ if (prpl != NULL)
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
+ else {
+ gchar *message;
+
+ message = g_strdup_printf(_("Missing protocol plugin for %s"),
+ purple_account_get_username(account));
+ purple_notify_error(NULL, _("Unregistration Error"), message, NULL);
+ g_free(message);
+ return;
+ }
+
+ if (!purple_account_is_disconnected(account)) {
+ prpl_info->unregister_user(account, cb, user_data);
+ return;
+ }
+
+ if (((password == NULL) || (*password == '\0')) &&
+ !(prpl_info->options & OPT_PROTO_NO_PASSWORD) &&
+ !(prpl_info->options & OPT_PROTO_PASSWORD_OPTIONAL))
+ {
+ purple_debug_error("connection", "Cannot connect to account %s without "
+ "a password.\n", purple_account_get_username(account));
+ return;
+ }
+
+ gc = g_object_new(PURPLE_TYPE_CONNECTION,
+ PROP_PRPL_S, prpl,
+ PROP_PASSWORD_S, password,
+ PROP_ACCOUNT_S, account,
+ NULL);
+
+ purple_debug_info("connection", "Unregistering. gc = %p\n", gc);
+
+ prpl_info->unregister_user(account, cb, user_data);
}
+/**************************************************************************
+ * Connections API
+ **************************************************************************/
void
purple_connections_disconnect_all(void)
{
GList *l;
PurpleConnection *gc;
+ PurpleConnectionPrivate *priv;
while ((l = purple_connections_get_all()) != NULL) {
gc = l->data;
- gc->wants_to_die = TRUE;
- purple_account_disconnect(gc->account);
+ priv = PURPLE_CONNECTION_GET_PRIVATE(gc);
+ priv->wants_to_die = TRUE;
+ purple_account_disconnect(priv->account);
}
}
@@ -674,36 +1037,29 @@ purple_connections_init(void)
void *handle = purple_connections_get_handle();
purple_signal_register(handle, "signing-on",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONNECTION));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_CONNECTION);
purple_signal_register(handle, "signed-on",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONNECTION));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_CONNECTION);
purple_signal_register(handle, "signing-off",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONNECTION));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_CONNECTION);
purple_signal_register(handle, "signed-off",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONNECTION));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_CONNECTION);
purple_signal_register(handle, "connection-error",
- purple_marshal_VOID__POINTER_INT_POINTER, NULL, 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONNECTION),
- purple_value_new(PURPLE_TYPE_ENUM),
- purple_value_new(PURPLE_TYPE_STRING));
+ purple_marshal_VOID__POINTER_INT_POINTER,
+ G_TYPE_NONE, 3, PURPLE_TYPE_CONNECTION,
+ PURPLE_TYPE_CONNECTION_ERROR, G_TYPE_STRING);
purple_signal_register(handle, "autojoin",
- purple_marshal_BOOLEAN__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONNECTION));
+ purple_marshal_BOOLEAN__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_CONNECTION);
}
diff --git a/libpurple/connection.h b/libpurple/connection.h
index 65c88d61b1..abfc31cf5a 100644
--- a/libpurple/connection.h
+++ b/libpurple/connection.h
@@ -27,33 +27,43 @@
#ifndef _PURPLE_CONNECTION_H_
#define _PURPLE_CONNECTION_H_
+#define PURPLE_TYPE_CONNECTION (purple_connection_get_type())
+#define PURPLE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_CONNECTION, PurpleConnection))
+#define PURPLE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_CONNECTION, PurpleConnectionClass))
+#define PURPLE_IS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_CONNECTION))
+#define PURPLE_IS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_CONNECTION))
+#define PURPLE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_CONNECTION, PurpleConnectionClass))
+
+#define PURPLE_TYPE_CONNECTION_ERROR_INFO (purple_connection_error_info_get_type())
+
/** @copydoc _PurpleConnection */
typedef struct _PurpleConnection PurpleConnection;
+/** @copydoc _PurpleConnectionClass */
+typedef struct _PurpleConnectionClass PurpleConnectionClass;
/**
* Flags to change behavior of the client for a given connection.
*/
-typedef enum
+typedef enum /*< flags >*/
{
- PURPLE_CONNECTION_HTML = 0x0001, /**< Connection sends/receives in 'HTML'. */
- PURPLE_CONNECTION_NO_BGCOLOR = 0x0002, /**< Connection does not send/receive
- background colors. */
- PURPLE_CONNECTION_AUTO_RESP = 0x0004, /**< Send auto responses when away. */
- PURPLE_CONNECTION_FORMATTING_WBFO = 0x0008, /**< The text buffer must be formatted as a whole */
- PURPLE_CONNECTION_NO_NEWLINES = 0x0010, /**< No new lines are allowed in outgoing messages */
- PURPLE_CONNECTION_NO_FONTSIZE = 0x0020, /**< Connection does not send/receive font sizes */
- PURPLE_CONNECTION_NO_URLDESC = 0x0040, /**< Connection does not support descriptions with links */
- PURPLE_CONNECTION_NO_IMAGES = 0x0080, /**< Connection does not support sending of images */
- PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY = 0x0100, /**< Connection supports sending and receiving custom smileys */
- PURPLE_CONNECTION_SUPPORT_MOODS = 0x0200, /**< Connection supports setting moods */
- PURPLE_CONNECTION_SUPPORT_MOOD_MESSAGES = 0x0400 /**< Connection supports setting a message on moods */
+ PURPLE_CONNECTION_FLAG_HTML = 0x0001, /**< Connection sends/receives in 'HTML' */
+ PURPLE_CONNECTION_FLAG_NO_BGCOLOR = 0x0002, /**< Connection does not send/receive background colors */
+ PURPLE_CONNECTION_FLAG_AUTO_RESP = 0x0004, /**< Send auto responses when away */
+ PURPLE_CONNECTION_FLAG_FORMATTING_WBFO = 0x0008, /**< The text buffer must be formatted as a whole */
+ PURPLE_CONNECTION_FLAG_NO_NEWLINES = 0x0010, /**< No new lines are allowed in outgoing messages */
+ PURPLE_CONNECTION_FLAG_NO_FONTSIZE = 0x0020, /**< Connection does not send/receive font sizes */
+ PURPLE_CONNECTION_FLAG_NO_URLDESC = 0x0040, /**< Connection does not support descriptions with links */
+ PURPLE_CONNECTION_FLAG_NO_IMAGES = 0x0080, /**< Connection does not support sending of images */
+ PURPLE_CONNECTION_FLAG_ALLOW_CUSTOM_SMILEY = 0x0100, /**< Connection supports sending and receiving custom smileys */
+ PURPLE_CONNECTION_FLAG_SUPPORT_MOODS = 0x0200, /**< Connection supports setting moods */
+ PURPLE_CONNECTION_FLAG_SUPPORT_MOOD_MESSAGES = 0x0400 /**< Connection supports setting a message on moods */
} PurpleConnectionFlags;
typedef enum
{
- PURPLE_DISCONNECTED = 0, /**< Disconnected. */
- PURPLE_CONNECTED, /**< Connected. */
- PURPLE_CONNECTING /**< Connecting. */
+ PURPLE_CONNECTION_DISCONNECTED = 0, /**< Disconnected. */
+ PURPLE_CONNECTION_CONNECTED, /**< Connected. */
+ PURPLE_CONNECTION_CONNECTING /**< Connecting. */
} PurpleConnectionState;
@@ -222,40 +232,27 @@ typedef struct
void (*_purple_reserved1)(void);
void (*_purple_reserved2)(void);
void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
} PurpleConnectionUiOps;
-
-/* Represents an active connection on an account. */
+/**
+ * Represents an active connection on an account.
+ */
struct _PurpleConnection
{
- PurplePlugin *prpl; /**< The protocol plugin. */
- PurpleConnectionFlags flags; /**< Connection flags. */
-
- PurpleConnectionState state; /**< The connection state. */
-
- PurpleAccount *account; /**< The account being connected to. */
- char *password; /**< The password used. */
-
- GSList *buddy_chats; /**< A list of active chats
- (#PurpleConversation structs of type
- #PURPLE_CONV_TYPE_CHAT). */
- void *proto_data; /**< Protocol-specific data. */
+ /*< private >*/
+ GObject gparent;
+};
- char *display_name; /**< How you appear to other people. */
- guint keepalive; /**< Keep-alive. */
+/** Base class for all #PurpleConnection's */
+struct _PurpleConnectionClass {
+ /*< private >*/
+ GObjectClass parent_class;
- /** 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() to set this for them rather than
- * setting it themselves.
- * @see purple_connection_error_is_fatal
- */
- gboolean wants_to_die;
-
- guint disconnect_timeout; /**< Timer used for nasty stack tricks */
- time_t last_received; /**< When we last received a packet. Set by the
- prpl to avoid sending unneeded keepalives */
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
};
G_BEGIN_DECLS
@@ -266,8 +263,18 @@ G_BEGIN_DECLS
/*@{*/
/**
+ * Returns the GType for the Connection object.
+ */
+GType purple_connection_get_type(void);
+
+/**
+ * Returns the GType for the PurpleConnectionErrorInfo boxed structure.
+ */
+GType purple_connection_error_info_get_type(void);
+
+/**
* Sets the connection state. PRPLs should call this and pass in
- * the state #PURPLE_CONNECTED when the account is completely
+ * the state #PURPLE_CONNECTION_CONNECTED when the account is completely
* signed on. What does it mean to be completely signed on? If
* the core can call prpl->set_status, and it successfully changes
* your status, then the account is online.
@@ -333,7 +340,7 @@ PurpleConnectionFlags purple_connection_get_flags(const PurpleConnection *gc);
* @return TRUE if the account is connected, otherwise returns FALSE.
*/
#define PURPLE_CONNECTION_IS_CONNECTED(gc) \
- (purple_connection_get_state(gc) == PURPLE_CONNECTED)
+ (purple_connection_get_state(gc) == PURPLE_CONNECTION_CONNECTED)
/**
* Returns the connection's account.
@@ -363,6 +370,15 @@ PurplePlugin * purple_connection_get_prpl(const PurpleConnection *gc);
const char *purple_connection_get_password(const PurpleConnection *gc);
/**
+ * Returns a list of active chat conversations on a connection.
+ *
+ * @param gc The connection.
+ *
+ * @return The active chats on the connection.
+ */
+GSList *purple_connection_get_active_chats(const PurpleConnection *gc);
+
+/**
* Returns the connection's displayed name.
*
* @param gc The connection.
@@ -401,9 +417,7 @@ void purple_connection_notice(PurpleConnection *gc, const char *text);
/**
* 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
- * backwards-compatibility.
+ * error.
*
* @param gc the connection which is closing.
* @param reason why the connection is closing.
@@ -436,8 +450,6 @@ purple_connection_ssl_error (PurpleConnection *gc,
* <tt> purple_connection_error_is_fatal
* (PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED)</tt> is @c TRUE.
*
- * (This function is meant to replace checking PurpleConnection.wants_to_die.)
- *
* @return @c TRUE if the account should not be automatically reconnected, and
* @c FALSE otherwise.
*/
diff --git a/libpurple/conversation.c b/libpurple/conversation.c
index b6a6058675..6e1a2c723d 100644
--- a/libpurple/conversation.c
+++ b/libpurple/conversation.c
@@ -20,11 +20,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include "internal.h"
-#include "blist.h"
+#include "buddylist.h"
#include "cmds.h"
#include "conversation.h"
#include "dbus-maybe.h"
#include "debug.h"
+#include "enums.h"
#include "imgstore.h"
#include "notify.h"
#include "prefs.h"
@@ -33,123 +34,35 @@
#include "signals.h"
#include "util.h"
-#define SEND_TYPED_TIMEOUT_SECONDS 5
+#define PURPLE_CONVERSATION_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_CONVERSATION, PurpleConversationPrivate))
-/**
- * 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;
+/** @copydoc _PurpleConversationPrivate */
+typedef struct _PurpleConversationPrivate PurpleConversationPrivate;
- /**
- * 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
+/** General private data for a conversation */
+struct _PurpleConversationPrivate
{
- 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 */
+ PurpleAccount *account; /**< The user using this conversation. */
- union
- {
- PurpleConvIm *im; /**< IM-specific data. */
- PurpleConvChat *chat; /**< Chat-specific data. */
- void *misc; /**< Misc. data. */
+ char *name; /**< The name of the conversation. */
+ char *title; /**< The window title. */
- } u;
+ gboolean logging; /**< The status of logging. */
- PurpleConversationUiOps *ui_ops; /**< UI-specific operations. */
- void *ui_data; /**< UI-specific data. */
+ GList *logs; /**< This conversation's logs */
- GHashTable *data; /**< Plugin-specific data. */
+ PurpleConversationUiOps *ui_ops; /**< UI-specific operations. */
- PurpleConnectionFlags features; /**< The supported features */
- GList *message_history; /**< Message history, as a GList of PurpleConvMessage's */
+ PurpleConnectionFlags features; /**< The supported features */
+ GList *message_history; /**< Message history, as a GList of
+ PurpleConversationMessage's */
};
/**
* Description of a conversation message
*/
-struct _PurpleConvMessage
+struct _PurpleConversationMessage
{
char *who;
char *what;
@@ -159,124 +72,40 @@ struct _PurpleConvMessage
char *alias;
};
-
-static GList *conversations = NULL;
-static GList *ims = NULL;
-static GList *chats = NULL;
-static PurpleConversationUiOps *default_ops = NULL;
-
-/**
- * A hash table used for efficient lookups of conversations by name.
- * struct _purple_hconv => PurpleConversation*
- */
-static GHashTable *conversation_cache = NULL;
-
-struct _purple_hconv {
- PurpleConversationType type;
- char *name;
- const PurpleAccount *account;
-};
-
-static guint _purple_conversations_hconv_hash(struct _purple_hconv *hc)
-{
- return g_str_hash(hc->name) ^ hc->type ^ g_direct_hash(hc->account);
-}
-
-static guint _purple_conversations_hconv_equal(struct _purple_hconv *hc1, struct _purple_hconv *hc2)
-{
- return (hc1->type == hc2->type &&
- hc1->account == hc2->account &&
- g_str_equal(hc1->name, hc2->name));
-}
-
-static void _purple_conversations_hconv_free_key(struct _purple_hconv *hc)
+/* GObject Property enums */
+enum
{
- g_free(hc->name);
- g_free(hc);
-}
-
-static guint _purple_conversation_user_hash(gconstpointer data)
-{
- const gchar *name = data;
- gchar *collated;
- guint hash;
-
- collated = g_utf8_collate_key(name, -1);
- hash = g_str_hash(collated);
- g_free(collated);
- return hash;
-}
-
-static gboolean _purple_conversation_user_equal(gconstpointer a, gconstpointer b)
-{
- return !g_utf8_collate(a, b);
-}
-
-void
-purple_conversations_set_ui_ops(PurpleConversationUiOps *ops)
-{
- default_ops = ops;
-}
-
-static gboolean
-reset_typing_cb(gpointer data)
-{
- PurpleConversation *c = (PurpleConversation *)data;
- PurpleConvIm *im;
-
- im = PURPLE_CONV_IM(c);
-
- purple_conv_im_set_typing_state(im, PURPLE_NOT_TYPING);
- purple_conv_im_stop_typing_timeout(im);
-
- return FALSE;
-}
-
-static gboolean
-send_typed_cb(gpointer data)
-{
- PurpleConversation *conv = (PurpleConversation *)data;
- PurpleConnection *gc;
- const char *name;
-
- g_return_val_if_fail(conv != NULL, FALSE);
-
- gc = purple_conversation_get_connection(conv);
- name = purple_conversation_get_name(conv);
-
- if (gc != NULL && name != NULL) {
- /* We set this to 1 so that PURPLE_TYPING will be sent
- * if the Purple user types anything else.
- */
- purple_conv_im_set_type_again(PURPLE_CONV_IM(conv), 1);
-
- serv_send_typing(gc, name, PURPLE_TYPED);
+ PROP_0,
+ PROP_ACCOUNT,
+ PROP_NAME,
+ PROP_TITLE,
+ PROP_LOGGING,
+ PROP_FEATURES,
+ PROP_LAST
+};
- purple_debug(PURPLE_DEBUG_MISC, "conversation", "typed...\n");
- }
+static GObjectClass *parent_class;
- return FALSE;
-}
static void
common_send(PurpleConversation *conv, const char *message, PurpleMessageFlags msgflags)
{
- PurpleConversationType type;
PurpleAccount *account;
PurpleConnection *gc;
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
char *displayed = NULL, *sent = NULL;
int err = 0;
+ g_return_if_fail(priv != NULL);
+
if (*message == '\0')
return;
account = purple_conversation_get_account(conv);
- gc = purple_conversation_get_connection(conv);
-
g_return_if_fail(account != NULL);
- g_return_if_fail(gc != NULL);
- type = purple_conversation_get_type(conv);
+ gc = purple_account_get_connection(account);
+ g_return_if_fail(gc != NULL);
/* Always linkfy the text for display, unless we're
* explicitly asked to do otheriwse*/
@@ -287,7 +116,7 @@ common_send(PurpleConversation *conv, const char *message, PurpleMessageFlags ms
displayed = purple_markup_linkify(message);
}
- if (displayed && (conv->features & PURPLE_CONNECTION_HTML) &&
+ if (displayed && (priv->features & PURPLE_CONNECTION_FLAG_HTML) &&
!(msgflags & PURPLE_MESSAGE_RAW)) {
sent = g_strdup(displayed);
} else
@@ -295,9 +124,7 @@ common_send(PurpleConversation *conv, const char *message, PurpleMessageFlags ms
msgflags |= PURPLE_MESSAGE_SEND;
- if (type == PURPLE_CONV_TYPE_IM) {
- PurpleConvIm *im = PURPLE_CONV_IM(conv);
-
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
purple_signal_emit(purple_conversations_get_handle(), "sending-im-msg",
account,
purple_conversation_get_name(conv), &sent);
@@ -308,7 +135,7 @@ common_send(PurpleConversation *conv, const char *message, PurpleMessageFlags ms
sent, msgflags);
if ((err > 0) && (displayed != NULL))
- purple_conv_im_write(im, NULL, displayed, msgflags, time(NULL));
+ purple_conversation_write_message(conv, NULL, displayed, msgflags, time(NULL));
purple_signal_emit(purple_conversations_get_handle(), "sent-im-msg",
account,
@@ -316,16 +143,17 @@ common_send(PurpleConversation *conv, const char *message, PurpleMessageFlags ms
}
}
else {
+ PurpleChatConversation *chat = PURPLE_CHAT_CONVERSATION(conv);
purple_signal_emit(purple_conversations_get_handle(), "sending-chat-msg",
account, &sent,
- purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)));
+ purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv)));
if (sent != NULL && sent[0] != '\0') {
- err = serv_chat_send(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), sent, msgflags);
+ err = serv_chat_send(gc, purple_chat_conversation_get_id(chat), sent, msgflags);
purple_signal_emit(purple_conversations_get_handle(), "sent-chat-msg",
account, sent,
- purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)));
+ purple_chat_conversation_get_id(chat));
}
}
@@ -338,7 +166,7 @@ common_send(PurpleConversation *conv, const char *message, PurpleMessageFlags ms
if (err == -E2BIG) {
msg = _("Unable to send message: The message is too large.");
- if (!purple_conv_present_error(who, account, msg)) {
+ if (!purple_conversation_present_error(who, account, msg)) {
char *msg2 = g_strdup_printf(_("Unable to send message to %s."), who);
purple_notify_error(gc, NULL, msg2, _("The message is too large."));
g_free(msg2);
@@ -351,7 +179,7 @@ common_send(PurpleConversation *conv, const char *message, PurpleMessageFlags ms
else {
msg = _("Unable to send message.");
- if (!purple_conv_present_error(who, account, msg)) {
+ if (!purple_conversation_present_error(who, account, msg)) {
char *msg2 = g_strdup_printf(_("Unable to send message to %s."), who);
purple_notify_error(gc, NULL, msg2, NULL);
g_free(msg2);
@@ -366,33 +194,40 @@ common_send(PurpleConversation *conv, const char *message, PurpleMessageFlags ms
static void
open_log(PurpleConversation *conv)
{
- conv->logs = g_list_append(NULL, purple_log_new(conv->type == PURPLE_CONV_TYPE_CHAT ? PURPLE_LOG_CHAT :
- PURPLE_LOG_IM, conv->name, conv->account,
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->logs = g_list_append(NULL, purple_log_new(PURPLE_IS_CHAT_CONVERSATION(conv) ? PURPLE_LOG_CHAT :
+ PURPLE_LOG_IM, priv->name, priv->account,
conv, time(NULL), NULL));
}
-/* Functions that deal with PurpleConvMessage */
+/* Functions that deal with PurpleConversationMessage */
static void
add_message_to_history(PurpleConversation *conv, const char *who, const char *alias,
const char *message, PurpleMessageFlags flags, time_t when)
{
- PurpleConvMessage *msg;
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+ PurpleConversationMessage *msg;
PurpleConnection *gc;
- gc = purple_account_get_connection(conv->account);
+ g_return_if_fail(priv != NULL);
+
+ gc = purple_account_get_connection(priv->account);
if (flags & PURPLE_MESSAGE_SEND) {
const char *me = NULL;
if (gc)
me = purple_connection_get_display_name(gc);
if (!me)
- me = purple_account_get_username(conv->account);
+ me = purple_account_get_username(priv->account);
who = me;
}
- msg = g_new0(PurpleConvMessage, 1);
- PURPLE_DBUS_REGISTER_POINTER(msg, PurpleConvMessage);
+ msg = g_new0(PurpleConversationMessage, 1);
+ PURPLE_DBUS_REGISTER_POINTER(msg, PurpleConversationMessage);
msg->who = g_strdup(who);
msg->alias = g_strdup(alias);
msg->flags = flags;
@@ -400,11 +235,11 @@ add_message_to_history(PurpleConversation *conv, const char *who, const char *al
msg->when = when;
msg->conv = conv;
- conv->message_history = g_list_prepend(conv->message_history, msg);
+ priv->message_history = g_list_prepend(priv->message_history, msg);
}
static void
-free_conv_message(PurpleConvMessage *msg)
+free_conv_message(PurpleConversationMessage *msg)
{
g_free(msg->who);
g_free(msg->alias);
@@ -423,316 +258,6 @@ message_history_free(GList *list)
/**************************************************************************
* Conversation API
**************************************************************************/
-static void
-purple_conversation_chat_cleanup_for_rejoin(PurpleConversation *conv)
-{
- const char *disp;
- PurpleAccount *account;
- PurpleConnection *gc;
-
- account = purple_conversation_get_account(conv);
-
- purple_conversation_close_logs(conv);
- open_log(conv);
-
- gc = purple_account_get_connection(account);
-
- if ((disp = purple_connection_get_display_name(gc)) != NULL)
- purple_conv_chat_set_nick(PURPLE_CONV_CHAT(conv), disp);
- else
- {
- purple_conv_chat_set_nick(PURPLE_CONV_CHAT(conv),
- purple_account_get_username(account));
- }
-
- purple_conv_chat_clear_users(PURPLE_CONV_CHAT(conv));
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(conv), NULL, NULL);
- PURPLE_CONV_CHAT(conv)->left = FALSE;
-
- purple_conversation_update(conv, PURPLE_CONV_UPDATE_CHATLEFT);
-}
-
-PurpleConversation *
-purple_conversation_new(PurpleConversationType type, PurpleAccount *account,
- const char *name)
-{
- PurpleConversation *conv;
- PurpleConnection *gc;
- PurpleConversationUiOps *ops;
- struct _purple_hconv *hc;
-
- g_return_val_if_fail(type != PURPLE_CONV_TYPE_UNKNOWN, NULL);
- g_return_val_if_fail(account != NULL, NULL);
- g_return_val_if_fail(name != NULL, NULL);
-
- /* Check if this conversation already exists. */
- if ((conv = purple_find_conversation_with_account(type, name, account)) != NULL)
- {
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT &&
- !purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv))) {
- purple_debug_warning("conversation", "Trying to create multiple "
- "chats (%s) with the same name is deprecated and will be "
- "removed in libpurple 3.0.0", name);
- }
-
- /*
- * This hack is necessary because some prpls (MSN) have unnamed chats
- * that all use the same name. A PurpleConversation for one of those
- * is only ever re-used if the user has left, so calls to
- * purple_conversation_new need to fall-through to creating a new
- * chat.
- * TODO 3.0.0: Remove this workaround and mandate unique names.
- */
- if (purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_CHAT ||
- purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)))
- {
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
- purple_conversation_chat_cleanup_for_rejoin(conv);
-
- return conv;
- }
- }
-
- gc = purple_account_get_connection(account);
- g_return_val_if_fail(gc != NULL, NULL);
-
- conv = g_new0(PurpleConversation, 1);
- PURPLE_DBUS_REGISTER_POINTER(conv, PurpleConversation);
-
- conv->type = type;
- conv->account = account;
- conv->name = g_strdup(name);
- conv->title = g_strdup(name);
- conv->data = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, NULL);
- /* copy features from the connection. */
- conv->features = purple_connection_get_flags(gc);
-
- if (type == PURPLE_CONV_TYPE_IM)
- {
- PurpleBuddyIcon *icon;
- conv->u.im = g_new0(PurpleConvIm, 1);
- conv->u.im->conv = conv;
- PURPLE_DBUS_REGISTER_POINTER(conv->u.im, PurpleConvIm);
-
- ims = g_list_prepend(ims, conv);
- if ((icon = purple_buddy_icons_find(account, name)))
- {
- purple_conv_im_set_icon(conv->u.im, icon);
- /* purple_conv_im_set_icon refs the icon. */
- purple_buddy_icon_unref(icon);
- }
-
- if (purple_prefs_get_bool("/purple/logging/log_ims"))
- {
- purple_conversation_set_logging(conv, TRUE);
- open_log(conv);
- }
- }
- else if (type == PURPLE_CONV_TYPE_CHAT)
- {
- const char *disp;
-
- conv->u.chat = g_new0(PurpleConvChat, 1);
- conv->u.chat->conv = conv;
- conv->u.chat->users = g_hash_table_new_full(_purple_conversation_user_hash,
- _purple_conversation_user_equal, g_free, NULL);
- PURPLE_DBUS_REGISTER_POINTER(conv->u.chat, PurpleConvChat);
-
- chats = g_list_prepend(chats, conv);
-
- 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,
- purple_account_get_username(account));
-
- if (purple_prefs_get_bool("/purple/logging/log_chats"))
- {
- purple_conversation_set_logging(conv, TRUE);
- open_log(conv);
- }
- }
-
- conversations = g_list_prepend(conversations, conv);
-
- hc = g_new(struct _purple_hconv, 1);
- hc->name = g_strdup(purple_normalize(account, conv->name));
- hc->account = account;
- hc->type = type;
-
- g_hash_table_insert(conversation_cache, hc, conv);
-
- /* Auto-set the title. */
- purple_conversation_autoset_title(conv);
-
- /* Don't move this.. it needs to be one of the last things done otherwise
- * it causes mysterious crashes on my system.
- * -- Gary
- */
- ops = conv->ui_ops = default_ops;
- if (ops != NULL && ops->create_conversation != NULL)
- ops->create_conversation(conv);
-
- purple_signal_emit(purple_conversations_get_handle(),
- "conversation-created", conv);
-
- return conv;
-}
-
-void
-purple_conversation_destroy(PurpleConversation *conv)
-{
- PurplePluginProtocolInfo *prpl_info = NULL;
- PurpleConversationUiOps *ops;
- PurpleConnection *gc;
- const char *name;
- struct _purple_hconv hc;
-
- g_return_if_fail(conv != NULL);
-
- purple_request_close_with_handle(conv);
-
- ops = purple_conversation_get_ui_ops(conv);
- gc = purple_conversation_get_connection(conv);
- name = purple_conversation_get_name(conv);
-
- if (gc != NULL)
- {
- /* Still connected */
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
-
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
- {
- if (purple_prefs_get_bool("/purple/conversations/im/send_typing"))
- serv_send_typing(gc, name, PURPLE_NOT_TYPING);
-
- if (gc && prpl_info->convo_closed != NULL)
- prpl_info->convo_closed(gc, name);
- }
- else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
- {
- int chat_id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv));
-#if 0
- /*
- * This is unfortunately necessary, because calling
- * serv_chat_leave() calls this purple_conversation_destroy(),
- * which leads to two calls here.. We can't just return after
- * this, because then it'll return on the next pass. So, since
- * serv_got_chat_left(), which is eventually called from the
- * prpl that serv_chat_leave() calls, removes this conversation
- * from the gc's buddy_chats list, we're going to check to see
- * if this exists in the list. If so, we want to return after
- * calling this, because it'll be called again. If not, fall
- * through, because it'll have already been removed, and we'd
- * be on the 2nd pass.
- *
- * Long paragraph. <-- Short sentence.
- *
- * -- ChipX86
- */
-
- if (gc && g_slist_find(gc->buddy_chats, conv) != NULL) {
- serv_chat_leave(gc, chat_id);
-
- return;
- }
-#endif
- /*
- * Instead of all of that, lets just close the window when
- * the user tells us to, and let the prpl deal with the
- * internals on it's own time. Don't do this if the prpl already
- * knows it left the chat.
- */
- if (!purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)))
- serv_chat_leave(gc, chat_id);
-
- /*
- * If they didn't call serv_got_chat_left by now, it's too late.
- * So we better do it for them before we destroy the thing.
- */
- if (!purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)))
- serv_got_chat_left(gc, chat_id);
- }
- }
-
- /* remove from conversations and im/chats lists prior to emit */
- conversations = g_list_remove(conversations, conv);
-
- if(conv->type==PURPLE_CONV_TYPE_IM)
- ims = g_list_remove(ims, conv);
- else if(conv->type==PURPLE_CONV_TYPE_CHAT)
- chats = g_list_remove(chats, conv);
-
- hc.name = (gchar *)purple_normalize(conv->account, conv->name);
- hc.account = conv->account;
- hc.type = conv->type;
-
- g_hash_table_remove(conversation_cache, &hc);
-
- purple_signal_emit(purple_conversations_get_handle(),
- "deleting-conversation", conv);
-
- g_free(conv->name);
- g_free(conv->title);
-
- conv->name = NULL;
- conv->title = NULL;
-
- if (conv->type == PURPLE_CONV_TYPE_IM) {
- purple_conv_im_stop_typing_timeout(conv->u.im);
- purple_conv_im_stop_send_typed_timeout(conv->u.im);
-
- purple_buddy_icon_unref(conv->u.im->icon);
- conv->u.im->icon = NULL;
-
- PURPLE_DBUS_UNREGISTER_POINTER(conv->u.im);
- g_free(conv->u.im);
- conv->u.im = NULL;
- }
- else if (conv->type == PURPLE_CONV_TYPE_CHAT) {
- g_hash_table_destroy(conv->u.chat->users);
- conv->u.chat->users = NULL;
-
- g_list_foreach(conv->u.chat->in_room, (GFunc)purple_conv_chat_cb_destroy, NULL);
- g_list_free(conv->u.chat->in_room);
-
- g_list_foreach(conv->u.chat->ignored, (GFunc)g_free, NULL);
- g_list_free(conv->u.chat->ignored);
-
- conv->u.chat->in_room = NULL;
- conv->u.chat->ignored = NULL;
-
- g_free(conv->u.chat->who);
- conv->u.chat->who = NULL;
-
- g_free(conv->u.chat->topic);
- conv->u.chat->topic = NULL;
-
- g_free(conv->u.chat->nick);
-
- PURPLE_DBUS_UNREGISTER_POINTER(conv->u.chat);
- g_free(conv->u.chat);
- conv->u.chat = NULL;
- }
-
- g_hash_table_destroy(conv->data);
- conv->data = NULL;
-
- if (ops != NULL && ops->destroy_conversation != NULL)
- ops->destroy_conversation(conv);
- conv->ui_data = NULL;
-
- purple_conversation_close_logs(conv);
-
- purple_conversation_clear_message_history(conv);
-
- PURPLE_DBUS_UNREGISTER_POINTER(conv);
- g_free(conv);
- conv = NULL;
-}
-
-
void
purple_conversation_present(PurpleConversation *conv) {
PurpleConversationUiOps *ops;
@@ -744,78 +269,78 @@ purple_conversation_present(PurpleConversation *conv) {
ops->present(conv);
}
-
void
purple_conversation_set_features(PurpleConversation *conv, PurpleConnectionFlags features)
{
- g_return_if_fail(conv != NULL);
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
- conv->features = features;
+ g_return_if_fail(priv != NULL);
- purple_conversation_update(conv, PURPLE_CONV_UPDATE_FEATURES);
+ priv->features = features;
+ purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_FEATURES);
}
-
PurpleConnectionFlags
purple_conversation_get_features(PurpleConversation *conv)
{
- g_return_val_if_fail(conv != NULL, 0);
- return conv->features;
-}
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+ g_return_val_if_fail(priv != NULL, 0);
-PurpleConversationType
-purple_conversation_get_type(const PurpleConversation *conv)
-{
- g_return_val_if_fail(conv != NULL, PURPLE_CONV_TYPE_UNKNOWN);
-
- return conv->type;
+ return priv->features;
}
void
purple_conversation_set_ui_ops(PurpleConversation *conv,
PurpleConversationUiOps *ops)
{
- g_return_if_fail(conv != NULL);
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
- if (conv->ui_ops == ops)
- return;
+ g_return_if_fail(priv != NULL);
- if (conv->ui_ops != NULL && conv->ui_ops->destroy_conversation != NULL)
- conv->ui_ops->destroy_conversation(conv);
+ if (priv->ui_ops == ops)
+ return;
- conv->ui_data = NULL;
+ if (priv->ui_ops != NULL && priv->ui_ops->destroy_conversation != NULL)
+ priv->ui_ops->destroy_conversation(conv);
- conv->ui_ops = ops;
+ priv->ui_ops = ops;
}
PurpleConversationUiOps *
purple_conversation_get_ui_ops(const PurpleConversation *conv)
{
- g_return_val_if_fail(conv != NULL, NULL);
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+
+ g_return_val_if_fail(priv != NULL, NULL);
- return conv->ui_ops;
+ return priv->ui_ops;
}
void
purple_conversation_set_account(PurpleConversation *conv, PurpleAccount *account)
{
- g_return_if_fail(conv != NULL);
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+
+ g_return_if_fail(priv != NULL);
if (account == purple_conversation_get_account(conv))
return;
- conv->account = account;
+ purple_conversations_update_cache(conv, NULL, account);
+ priv->account = account;
- purple_conversation_update(conv, PURPLE_CONV_UPDATE_ACCOUNT);
+ purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_ACCOUNT);
}
PurpleAccount *
purple_conversation_get_account(const PurpleConversation *conv)
{
- g_return_val_if_fail(conv != NULL, NULL);
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+
+ g_return_val_if_fail(priv != NULL, NULL);
- return conv->account;
+ return priv->account;
}
PurpleConnection *
@@ -836,21 +361,25 @@ purple_conversation_get_connection(const PurpleConversation *conv)
void
purple_conversation_set_title(PurpleConversation *conv, const char *title)
{
- g_return_if_fail(conv != NULL);
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+
+ g_return_if_fail(priv != NULL);
g_return_if_fail(title != NULL);
- g_free(conv->title);
- conv->title = g_strdup(title);
+ g_free(priv->title);
+ priv->title = g_strdup(title);
- purple_conversation_update(conv, PURPLE_CONV_UPDATE_TITLE);
+ purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_TITLE);
}
const char *
purple_conversation_get_title(const PurpleConversation *conv)
{
- g_return_val_if_fail(conv != NULL, NULL);
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+
+ g_return_val_if_fail(priv != NULL, NULL);
- return conv->title;
+ return priv->title;
}
void
@@ -866,15 +395,14 @@ purple_conversation_autoset_title(PurpleConversation *conv)
account = purple_conversation_get_account(conv);
name = purple_conversation_get_name(conv);
- if(purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- if(account && ((b = purple_find_buddy(account, name)) != NULL))
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ if (account && ((b = purple_blist_find_buddy(account, name)) != NULL))
text = purple_buddy_get_contact_alias(b);
- } else if(purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
- if(account && ((chat = purple_blist_find_chat(account, name)) != NULL))
+ } else if (PURPLE_IS_CHAT_CONVERSATION(conv)) {
+ if (account && ((chat = purple_blist_find_chat(account, name)) != NULL))
text = purple_chat_get_name(chat);
}
-
if(text == NULL)
text = name;
@@ -882,37 +410,16 @@ purple_conversation_autoset_title(PurpleConversation *conv)
}
void
-purple_conversation_foreach(void (*func)(PurpleConversation *conv))
-{
- PurpleConversation *conv;
- GList *l;
-
- g_return_if_fail(func != NULL);
-
- for (l = purple_get_conversations(); l != NULL; l = l->next) {
- conv = (PurpleConversation *)l->data;
-
- func(conv);
- }
-}
-
-void
purple_conversation_set_name(PurpleConversation *conv, const char *name)
{
- struct _purple_hconv *hc;
- g_return_if_fail(conv != NULL);
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
- hc = g_new(struct _purple_hconv, 1);
- hc->type = conv->type;
- hc->account = conv->account;
- hc->name = (gchar *)purple_normalize(conv->account, conv->name);
+ g_return_if_fail(priv != NULL);
- g_hash_table_remove(conversation_cache, hc);
- g_free(conv->name);
+ purple_conversations_update_cache(conv, name, NULL);
- conv->name = g_strdup(name);
- hc->name = g_strdup(purple_normalize(conv->account, conv->name));
- g_hash_table_insert(conversation_cache, hc, conv);
+ g_free(priv->name);
+ priv->name = g_strdup(name);
purple_conversation_autoset_title(conv);
}
@@ -920,133 +427,50 @@ purple_conversation_set_name(PurpleConversation *conv, const char *name)
const char *
purple_conversation_get_name(const PurpleConversation *conv)
{
- g_return_val_if_fail(conv != NULL, NULL);
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+
+ g_return_val_if_fail(priv != NULL, NULL);
- return conv->name;
+ return priv->name;
}
void
purple_conversation_set_logging(PurpleConversation *conv, gboolean log)
{
- g_return_if_fail(conv != NULL);
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
- if (conv->logging != log)
+ g_return_if_fail(priv != NULL);
+
+ if (priv->logging != log)
{
- conv->logging = log;
- purple_conversation_update(conv, PURPLE_CONV_UPDATE_LOGGING);
+ priv->logging = log;
+ if (log && priv->logs == NULL)
+ open_log(conv);
+
+ purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_LOGGING);
}
}
gboolean
purple_conversation_is_logging(const PurpleConversation *conv)
{
- g_return_val_if_fail(conv != NULL, FALSE);
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
- return conv->logging;
-}
+ g_return_val_if_fail(priv != NULL, FALSE);
-void
-purple_conversation_close_logs(PurpleConversation *conv)
-{
- g_return_if_fail(conv != NULL);
-
- g_list_foreach(conv->logs, (GFunc)purple_log_free, NULL);
- g_list_free(conv->logs);
- conv->logs = NULL;
-}
-
-PurpleConvIm *
-purple_conversation_get_im_data(const PurpleConversation *conv)
-{
- g_return_val_if_fail(conv != NULL, NULL);
-
- if (purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_IM)
- return NULL;
-
- return conv->u.im;
-}
-
-PurpleConvChat *
-purple_conversation_get_chat_data(const PurpleConversation *conv)
-{
- g_return_val_if_fail(conv != NULL, NULL);
-
- if (purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_CHAT)
- return NULL;
-
- return conv->u.chat;
+ return priv->logging;
}
void
-purple_conversation_set_data(PurpleConversation *conv, const char *key,
- gpointer data)
-{
- g_return_if_fail(conv != NULL);
- g_return_if_fail(key != NULL);
-
- g_hash_table_replace(conv->data, g_strdup(key), data);
-}
-
-gpointer
-purple_conversation_get_data(PurpleConversation *conv, const char *key)
-{
- g_return_val_if_fail(conv != NULL, NULL);
- g_return_val_if_fail(key != NULL, NULL);
-
- return g_hash_table_lookup(conv->data, key);
-}
-
-GList *
-purple_get_conversations(void)
-{
- return conversations;
-}
-
-GList *
-purple_get_ims(void)
-{
- return ims;
-}
-
-GList *
-purple_get_chats(void)
-{
- return chats;
-}
-
-
-PurpleConversation *
-purple_find_conversation_with_account(PurpleConversationType type,
- const char *name,
- const PurpleAccount *account)
+purple_conversation_close_logs(PurpleConversation *conv)
{
- PurpleConversation *c = NULL;
- struct _purple_hconv hc;
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
- g_return_val_if_fail(name != NULL, NULL);
+ g_return_if_fail(priv != NULL);
- hc.name = (gchar *)purple_normalize(account, name);
- hc.account = account;
- hc.type = type;
-
- switch (type) {
- case PURPLE_CONV_TYPE_IM:
- case PURPLE_CONV_TYPE_CHAT:
- c = g_hash_table_lookup(conversation_cache, &hc);
- break;
- case PURPLE_CONV_TYPE_ANY:
- hc.type = PURPLE_CONV_TYPE_IM;
- c = g_hash_table_lookup(conversation_cache, &hc);
- if (!c) {
- hc.type = PURPLE_CONV_TYPE_CHAT;
- c = g_hash_table_lookup(conversation_cache, &hc);
- }
- break;
- default:
- g_return_val_if_reached(NULL);
- }
-
- return c;
+ g_list_foreach(priv->logs, (GFunc)purple_log_free, NULL);
+ g_list_free(priv->logs);
+ priv->logs = NULL;
}
void
@@ -1062,26 +486,25 @@ purple_conversation_write(PurpleConversation *conv, const char *who,
char *displayed = NULL;
PurpleBuddy *b;
int plugin_return;
- PurpleConversationType type;
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
/* int logging_font_options = 0; */
- g_return_if_fail(conv != NULL);
+ g_return_if_fail(priv != NULL);
g_return_if_fail(message != NULL);
ops = purple_conversation_get_ui_ops(conv);
account = purple_conversation_get_account(conv);
- type = purple_conversation_get_type(conv);
if (account != NULL)
gc = purple_account_get_connection(account);
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT &&
- (gc != NULL && !g_slist_find(gc->buddy_chats, conv)))
+ if (PURPLE_IS_CHAT_CONVERSATION(conv) &&
+ (gc != NULL && !g_slist_find(purple_connection_get_active_chats(gc), conv)))
return;
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM &&
- !g_list_find(purple_get_conversations(), conv))
+ if (PURPLE_IS_IM_CONVERSATION(conv) &&
+ !g_list_find(purple_conversations_get_all(), conv))
return;
displayed = g_strdup(message);
@@ -1093,7 +516,7 @@ purple_conversation_write(PurpleConversation *conv, const char *who,
plugin_return =
GPOINTER_TO_INT(purple_signal_emit_return_1(
purple_conversations_get_handle(),
- (type == PURPLE_CONV_TYPE_IM ? "writing-im-msg" : "writing-chat-msg"),
+ (PURPLE_IS_IM_CONVERSATION(conv) ? "writing-im-msg" : "writing-chat-msg"),
account, who, &displayed, conv, flags));
if (displayed == NULL)
@@ -1107,15 +530,15 @@ purple_conversation_write(PurpleConversation *conv, const char *who,
if (account != NULL) {
prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(account)));
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM ||
+ if (PURPLE_IS_IM_CONVERSATION(conv) ||
!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
if (flags & PURPLE_MESSAGE_SEND) {
- b = purple_find_buddy(account,
+ b = purple_blist_find_buddy(account,
purple_account_get_username(account));
- if (purple_account_get_alias(account) != NULL)
- alias = purple_account_get_alias(account);
+ if (purple_account_get_private_alias(account) != NULL)
+ alias = purple_account_get_private_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)
@@ -1125,7 +548,7 @@ purple_conversation_write(PurpleConversation *conv, const char *who,
}
else
{
- b = purple_find_buddy(account, who);
+ b = purple_blist_find_buddy(account, who);
if (b != NULL)
alias = purple_buddy_get_contact_alias(b);
@@ -1136,10 +559,7 @@ purple_conversation_write(PurpleConversation *conv, const char *who,
if (!(flags & PURPLE_MESSAGE_NO_LOG) && purple_conversation_is_logging(conv)) {
GList *log;
- if (conv->logs == NULL)
- open_log(conv);
-
- log = conv->logs;
+ log = priv->logs;
while (log != NULL) {
purple_log_write((PurpleLog *)log->data, flags, alias, mtime, displayed);
log = log->next;
@@ -1152,12 +572,42 @@ purple_conversation_write(PurpleConversation *conv, const char *who,
add_message_to_history(conv, who, alias, message, flags, mtime);
purple_signal_emit(purple_conversations_get_handle(),
- (type == PURPLE_CONV_TYPE_IM ? "wrote-im-msg" : "wrote-chat-msg"),
+ (PURPLE_IS_IM_CONVERSATION(conv) ? "wrote-im-msg" : "wrote-chat-msg"),
account, who, displayed, conv, flags);
g_free(displayed);
}
+void
+purple_conversation_write_message(PurpleConversation *conv, const char *who,
+ const char *message, PurpleMessageFlags flags, time_t mtime)
+{
+ PurpleConversationClass *klass = NULL;
+
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+
+ klass = PURPLE_CONVERSATION_GET_CLASS(conv);
+
+ if (klass && klass->write_message)
+ klass->write_message(conv, who, message, flags, mtime);
+}
+
+void
+purple_conversation_send(PurpleConversation *conv, const char *message)
+{
+ purple_conversation_send_with_flags(conv, message, 0);
+}
+
+void
+purple_conversation_send_with_flags(PurpleConversation *conv, const char *message,
+ PurpleMessageFlags flags)
+{
+ g_return_if_fail(conv != NULL);
+ g_return_if_fail(message != NULL);
+
+ common_send(conv, message, flags);
+}
+
gboolean
purple_conversation_has_focus(PurpleConversation *conv)
{
@@ -1181,7 +631,7 @@ purple_conversation_has_focus(PurpleConversation *conv)
* when chats are added/removed from the blist.
*/
void
-purple_conversation_update(PurpleConversation *conv, PurpleConvUpdateType type)
+purple_conversation_update(PurpleConversation *conv, PurpleConversationUpdateType type)
{
g_return_if_fail(conv != NULL);
@@ -1189,194 +639,7 @@ purple_conversation_update(PurpleConversation *conv, PurpleConvUpdateType type)
"conversation-updated", conv, type);
}
-/**************************************************************************
- * IM Conversation API
- **************************************************************************/
-PurpleConversation *
-purple_conv_im_get_conversation(const PurpleConvIm *im)
-{
- g_return_val_if_fail(im != NULL, NULL);
-
- return im->conv;
-}
-
-void
-purple_conv_im_set_icon(PurpleConvIm *im, PurpleBuddyIcon *icon)
-{
- g_return_if_fail(im != NULL);
-
- if (im->icon != icon)
- {
- purple_buddy_icon_unref(im->icon);
-
- im->icon = (icon == NULL ? NULL : purple_buddy_icon_ref(icon));
- }
-
- purple_conversation_update(purple_conv_im_get_conversation(im),
- PURPLE_CONV_UPDATE_ICON);
-}
-
-PurpleBuddyIcon *
-purple_conv_im_get_icon(const PurpleConvIm *im)
-{
- g_return_val_if_fail(im != NULL, NULL);
-
- return im->icon;
-}
-
-void
-purple_conv_im_set_typing_state(PurpleConvIm *im, PurpleTypingState state)
-{
- g_return_if_fail(im != NULL);
-
- if (im->typing_state != state)
- {
- im->typing_state = state;
-
- switch (state)
- {
- case PURPLE_TYPING:
- purple_signal_emit(purple_conversations_get_handle(),
- "buddy-typing", im->conv->account, im->conv->name);
- break;
- case PURPLE_TYPED:
- purple_signal_emit(purple_conversations_get_handle(),
- "buddy-typed", im->conv->account, im->conv->name);
- break;
- case PURPLE_NOT_TYPING:
- purple_signal_emit(purple_conversations_get_handle(),
- "buddy-typing-stopped", im->conv->account, im->conv->name);
- break;
- }
-
- purple_conv_im_update_typing(im);
- }
-}
-
-PurpleTypingState
-purple_conv_im_get_typing_state(const PurpleConvIm *im)
-{
- g_return_val_if_fail(im != NULL, 0);
-
- return im->typing_state;
-}
-
-void
-purple_conv_im_start_typing_timeout(PurpleConvIm *im, int timeout)
-{
- PurpleConversation *conv;
-
- g_return_if_fail(im != NULL);
-
- if (im->typing_timeout > 0)
- purple_conv_im_stop_typing_timeout(im);
-
- conv = purple_conv_im_get_conversation(im);
-
- im->typing_timeout = purple_timeout_add_seconds(timeout, reset_typing_cb, conv);
-}
-
-void
-purple_conv_im_stop_typing_timeout(PurpleConvIm *im)
-{
- g_return_if_fail(im != NULL);
-
- if (im->typing_timeout == 0)
- return;
-
- purple_timeout_remove(im->typing_timeout);
- im->typing_timeout = 0;
-}
-
-guint
-purple_conv_im_get_typing_timeout(const PurpleConvIm *im)
-{
- g_return_val_if_fail(im != NULL, 0);
-
- return im->typing_timeout;
-}
-
-void
-purple_conv_im_set_type_again(PurpleConvIm *im, unsigned int val)
-{
- g_return_if_fail(im != NULL);
-
- if (val == 0)
- im->type_again = 0;
- else
- im->type_again = time(NULL) + val;
-}
-
-time_t
-purple_conv_im_get_type_again(const PurpleConvIm *im)
-{
- g_return_val_if_fail(im != NULL, 0);
-
- return im->type_again;
-}
-
-void
-purple_conv_im_start_send_typed_timeout(PurpleConvIm *im)
-{
- g_return_if_fail(im != NULL);
-
- im->send_typed_timeout = purple_timeout_add_seconds(SEND_TYPED_TIMEOUT_SECONDS,
- send_typed_cb,
- purple_conv_im_get_conversation(im));
-}
-
-void
-purple_conv_im_stop_send_typed_timeout(PurpleConvIm *im)
-{
- g_return_if_fail(im != NULL);
-
- if (im->send_typed_timeout == 0)
- return;
-
- purple_timeout_remove(im->send_typed_timeout);
- im->send_typed_timeout = 0;
-}
-
-guint
-purple_conv_im_get_send_typed_timeout(const PurpleConvIm *im)
-{
- g_return_val_if_fail(im != NULL, 0);
-
- return im->send_typed_timeout;
-}
-
-void
-purple_conv_im_update_typing(PurpleConvIm *im)
-{
- g_return_if_fail(im != NULL);
-
- purple_conversation_update(purple_conv_im_get_conversation(im),
- PURPLE_CONV_UPDATE_TYPING);
-}
-
-void
-purple_conv_im_write(PurpleConvIm *im, const char *who, const char *message,
- PurpleMessageFlags flags, time_t mtime)
-{
- PurpleConversation *c;
-
- g_return_if_fail(im != NULL);
- g_return_if_fail(message != NULL);
-
- c = purple_conv_im_get_conversation(im);
-
- if ((flags & PURPLE_MESSAGE_RECV) == PURPLE_MESSAGE_RECV) {
- purple_conv_im_set_typing_state(im, PURPLE_NOT_TYPING);
- }
-
- /* Pass this on to either the ops structure or the default write func. */
- if (c->ui_ops != NULL && c->ui_ops->write_im != NULL)
- c->ui_ops->write_im(c, who, message, flags, mtime);
- else
- purple_conversation_write(c, who, message, flags, mtime);
-}
-
-gboolean purple_conv_present_error(const char *who, PurpleAccount *account, const char *what)
+gboolean purple_conversation_present_error(const char *who, PurpleAccount *account, const char *what)
{
PurpleConversation *conv;
@@ -1384,7 +647,7 @@ gboolean purple_conv_present_error(const char *who, PurpleAccount *account, cons
g_return_val_if_fail(account !=NULL, FALSE);
g_return_val_if_fail(what != NULL, FALSE);
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, who, account);
+ conv = purple_conversations_find_with_account(who, account);
if (conv != NULL)
purple_conversation_write(conv, NULL, what, PURPLE_MESSAGE_ERROR, time(NULL));
else
@@ -1393,14 +656,8 @@ gboolean purple_conv_present_error(const char *who, PurpleAccount *account, cons
return TRUE;
}
-void
-purple_conv_im_send(PurpleConvIm *im, const char *message)
-{
- purple_conv_im_send_with_flags(im, message, 0);
-}
-
static void
-purple_conv_send_confirm_cb(gpointer *data)
+purple_conversation_send_confirm_cb(gpointer *data)
{
PurpleConversation *conv = data[0];
char *message = data[1];
@@ -1410,17 +667,18 @@ purple_conv_send_confirm_cb(gpointer *data)
}
void
-purple_conv_send_confirm(PurpleConversation *conv, const char *message)
+purple_conversation_send_confirm(PurpleConversation *conv, const char *message)
{
char *text;
gpointer *data;
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
- g_return_if_fail(conv != NULL);
+ g_return_if_fail(priv != NULL);
g_return_if_fail(message != NULL);
- if (conv->ui_ops != NULL && conv->ui_ops->send_confirm != NULL)
+ if (priv->ui_ops != NULL && priv->ui_ops->send_confirm != NULL)
{
- conv->ui_ops->send_confirm(conv, message);
+ priv->ui_ops->send_confirm(conv, message);
return;
}
@@ -1432,32 +690,27 @@ purple_conv_send_confirm(PurpleConversation *conv, const char *message)
purple_request_action(conv, NULL, _("Send Message"), text, 0,
purple_conversation_get_account(conv), NULL, conv,
data, 2,
- _("_Send Message"), G_CALLBACK(purple_conv_send_confirm_cb),
+ _("_Send Message"), G_CALLBACK(purple_conversation_send_confirm_cb),
_("Cancel"), NULL);
}
-void
-purple_conv_im_send_with_flags(PurpleConvIm *im, const char *message, PurpleMessageFlags flags)
-{
- g_return_if_fail(im != NULL);
- g_return_if_fail(message != NULL);
-
- common_send(purple_conv_im_get_conversation(im), message, flags);
-}
-
gboolean
-purple_conv_custom_smiley_add(PurpleConversation *conv, const char *smile,
+purple_conversation_custom_smiley_add(PurpleConversation *conv, const char *smile,
const char *cksum_type, const char *chksum,
gboolean remote)
{
- if (conv == NULL || smile == NULL || !*smile) {
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+
+ g_return_val_if_fail(priv != NULL, FALSE);
+
+ if (smile == NULL || !*smile) {
return FALSE;
}
/* TODO: check if the icon is in the cache and return false if so */
/* TODO: add an icon cache (that doesn't suck) */
- if (conv->ui_ops != NULL && conv->ui_ops->custom_smiley_add !=NULL) {
- return conv->ui_ops->custom_smiley_add(conv, smile, remote);
+ if (priv->ui_ops != NULL && priv->ui_ops->custom_smiley_add !=NULL) {
+ return priv->ui_ops->custom_smiley_add(conv, smile, remote);
} else {
purple_debug_info("conversation", "Could not find add custom smiley function");
return FALSE;
@@ -1466,1390 +719,409 @@ purple_conv_custom_smiley_add(PurpleConversation *conv, const char *smile,
}
void
-purple_conv_custom_smiley_write(PurpleConversation *conv, const char *smile,
+purple_conversation_custom_smiley_write(PurpleConversation *conv, const char *smile,
const guchar *data, gsize size)
{
- g_return_if_fail(conv != NULL);
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+
+ g_return_if_fail(priv != NULL);
g_return_if_fail(smile != NULL && *smile);
- if (conv->ui_ops != NULL && conv->ui_ops->custom_smiley_write != NULL)
- conv->ui_ops->custom_smiley_write(conv, smile, data, size);
+ if (priv->ui_ops != NULL && priv->ui_ops->custom_smiley_write != NULL)
+ priv->ui_ops->custom_smiley_write(conv, smile, data, size);
else
purple_debug_info("conversation", "Could not find the smiley write function");
}
void
-purple_conv_custom_smiley_close(PurpleConversation *conv, const char *smile)
+purple_conversation_custom_smiley_close(PurpleConversation *conv, const char *smile)
{
- g_return_if_fail(conv != NULL);
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+
+ g_return_if_fail(priv != NULL);
g_return_if_fail(smile != NULL && *smile);
- if (conv->ui_ops != NULL && conv->ui_ops->custom_smiley_close != NULL)
- conv->ui_ops->custom_smiley_close(conv, smile);
+ if (priv->ui_ops != NULL && priv->ui_ops->custom_smiley_close != NULL)
+ priv->ui_ops->custom_smiley_close(conv, smile);
else
purple_debug_info("conversation", "Could not find custom smiley close function");
}
-
-/**************************************************************************
- * Chat Conversation API
- **************************************************************************/
-
-PurpleConversation *
-purple_conv_chat_get_conversation(const PurpleConvChat *chat)
-{
- g_return_val_if_fail(chat != NULL, NULL);
-
- return chat->conv;
-}
-
GList *
-purple_conv_chat_get_users(const PurpleConvChat *chat)
-{
- g_return_val_if_fail(chat != NULL, NULL);
-
- return chat->in_room;
-}
-
-void
-purple_conv_chat_ignore(PurpleConvChat *chat, const char *name)
+purple_conversation_get_extended_menu(PurpleConversation *conv)
{
- g_return_if_fail(chat != NULL);
- g_return_if_fail(name != NULL);
+ GList *menu = NULL;
- /* Make sure the user isn't already ignored. */
- if (purple_conv_chat_is_user_ignored(chat, name))
- return;
+ g_return_val_if_fail(conv != NULL, NULL);
- purple_conv_chat_set_ignored(chat,
- g_list_append(chat->ignored, g_strdup(name)));
+ purple_signal_emit(purple_conversations_get_handle(),
+ "conversation-extended-menu", conv, &menu);
+ return menu;
}
-void
-purple_conv_chat_unignore(PurpleConvChat *chat, const char *name)
+void purple_conversation_clear_message_history(PurpleConversation *conv)
{
- GList *item;
+ GList *list;
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
- g_return_if_fail(chat != NULL);
- g_return_if_fail(name != NULL);
-
- /* Make sure the user is actually ignored. */
- if (!purple_conv_chat_is_user_ignored(chat, name))
- return;
+ g_return_if_fail(priv != NULL);
- item = g_list_find(purple_conv_chat_get_ignored(chat),
- purple_conv_chat_get_ignored_user(chat, name));
-
- purple_conv_chat_set_ignored(chat,
- g_list_remove_link(chat->ignored, item));
+ list = priv->message_history;
+ message_history_free(list);
+ priv->message_history = NULL;
- g_free(item->data);
- g_list_free_1(item);
+ purple_signal_emit(purple_conversations_get_handle(),
+ "cleared-message-history", conv);
}
-GList *
-purple_conv_chat_set_ignored(PurpleConvChat *chat, GList *ignored)
+GList *purple_conversation_get_message_history(PurpleConversation *conv)
{
- g_return_val_if_fail(chat != NULL, NULL);
-
- chat->ignored = ignored;
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
- return ignored;
-}
-
-GList *
-purple_conv_chat_get_ignored(const PurpleConvChat *chat)
-{
- g_return_val_if_fail(chat != NULL, NULL);
+ g_return_val_if_fail(priv != NULL, NULL);
- return chat->ignored;
+ return priv->message_history;
}
-const char *
-purple_conv_chat_get_ignored_user(const PurpleConvChat *chat, const char *user)
+const char *purple_conversation_message_get_sender(const PurpleConversationMessage *msg)
{
- GList *ignored;
-
- g_return_val_if_fail(chat != NULL, NULL);
- g_return_val_if_fail(user != NULL, NULL);
-
- for (ignored = purple_conv_chat_get_ignored(chat);
- ignored != NULL;
- ignored = ignored->next) {
-
- const char *ign = (const char *)ignored->data;
-
- if (!purple_utf8_strcasecmp(user, ign) ||
- ((*ign == '+' || *ign == '%') && !purple_utf8_strcasecmp(user, ign + 1)))
- return ign;
-
- if (*ign == '@') {
- ign++;
-
- if ((*ign == '+' && !purple_utf8_strcasecmp(user, ign + 1)) ||
- (*ign != '+' && !purple_utf8_strcasecmp(user, ign)))
- return ign;
- }
- }
-
- return NULL;
+ g_return_val_if_fail(msg, NULL);
+ return msg->who;
}
-gboolean
-purple_conv_chat_is_user_ignored(const PurpleConvChat *chat, const char *user)
+const char *purple_conversation_message_get_message(const PurpleConversationMessage *msg)
{
- g_return_val_if_fail(chat != NULL, FALSE);
- g_return_val_if_fail(user != NULL, FALSE);
-
- return (purple_conv_chat_get_ignored_user(chat, user) != NULL);
+ g_return_val_if_fail(msg, NULL);
+ return msg->what;
}
-void
-purple_conv_chat_set_topic(PurpleConvChat *chat, const char *who, const char *topic)
+PurpleMessageFlags purple_conversation_message_get_flags(const PurpleConversationMessage *msg)
{
- g_return_if_fail(chat != NULL);
-
- g_free(chat->who);
- g_free(chat->topic);
-
- chat->who = g_strdup(who);
- chat->topic = g_strdup(topic);
-
- purple_conversation_update(purple_conv_chat_get_conversation(chat),
- PURPLE_CONV_UPDATE_TOPIC);
-
- purple_signal_emit(purple_conversations_get_handle(), "chat-topic-changed",
- chat->conv, chat->who, chat->topic);
+ g_return_val_if_fail(msg, 0);
+ return msg->flags;
}
-const char *
-purple_conv_chat_get_topic(const PurpleConvChat *chat)
+time_t purple_conversation_message_get_timestamp(const PurpleConversationMessage *msg)
{
- g_return_val_if_fail(chat != NULL, NULL);
-
- return chat->topic;
+ g_return_val_if_fail(msg, 0);
+ return msg->when;
}
-void
-purple_conv_chat_set_id(PurpleConvChat *chat, int id)
+const char *purple_conversation_message_get_alias(const PurpleConversationMessage *msg)
{
- g_return_if_fail(chat != NULL);
-
- chat->id = id;
+ g_return_val_if_fail(msg, NULL);
+ return msg->alias;
}
-int
-purple_conv_chat_get_id(const PurpleConvChat *chat)
+PurpleConversation *purple_conversation_message_get_conversation(const PurpleConversationMessage *msg)
{
- g_return_val_if_fail(chat != NULL, -1);
-
- return chat->id;
+ g_return_val_if_fail(msg, NULL);
+ return msg->conv;
}
-void
-purple_conv_chat_write(PurpleConvChat *chat, const char *who, const char *message,
- PurpleMessageFlags flags, time_t mtime)
+static PurpleConversationMessage *
+purple_conversation_message_copy(PurpleConversationMessage *msg)
{
- PurpleAccount *account;
- PurpleConversation *conv;
- PurpleConnection *gc;
-
- g_return_if_fail(chat != NULL);
- g_return_if_fail(who != NULL);
- g_return_if_fail(message != NULL);
-
- conv = purple_conv_chat_get_conversation(chat);
- gc = purple_conversation_get_connection(conv);
- account = purple_connection_get_account(gc);
-
- /* Don't display this if the person who wrote it is ignored. */
- if (purple_conv_chat_is_user_ignored(chat, who))
- return;
-
- if (!(flags & PURPLE_MESSAGE_WHISPER)) {
- const char *str;
-
- str = purple_normalize(account, who);
-
- if (purple_strequal(str, chat->nick)) {
- flags |= PURPLE_MESSAGE_SEND;
- } else {
- flags |= PURPLE_MESSAGE_RECV;
-
- if (purple_utf8_has_word(message, chat->nick))
- flags |= PURPLE_MESSAGE_NICK;
- }
- }
+ PurpleConversationMessage *newmsg;
- /* Pass this on to either the ops structure or the default write func. */
- if (conv->ui_ops != NULL && conv->ui_ops->write_chat != NULL)
- conv->ui_ops->write_chat(conv, who, message, flags, mtime);
- else
- purple_conversation_write(conv, who, message, flags, mtime);
-}
-
-void
-purple_conv_chat_send(PurpleConvChat *chat, const char *message)
-{
- purple_conv_chat_send_with_flags(chat, message, 0);
-}
+ g_return_val_if_fail(msg != NULL, NULL);
-void
-purple_conv_chat_send_with_flags(PurpleConvChat *chat, const char *message, PurpleMessageFlags flags)
-{
- g_return_if_fail(chat != NULL);
- g_return_if_fail(message != NULL);
+ newmsg = g_new(PurpleConversationMessage, 1);
+ *newmsg = *msg;
+ newmsg->who = g_strdup(msg->who);
+ newmsg->what = g_strdup(msg->what);
+ newmsg->alias = g_strdup(msg->alias);
- common_send(purple_conv_chat_get_conversation(chat), message, flags);
+ return newmsg;
}
-void
-purple_conv_chat_add_user(PurpleConvChat *chat, const char *user,
- const char *extra_msg, PurpleConvChatBuddyFlags flags,
- gboolean new_arrival)
+static void
+purple_conversation_message_free(PurpleConversationMessage *msg)
{
- GList *users = g_list_append(NULL, (char *)user);
- GList *extra_msgs = g_list_append(NULL, (char *)extra_msg);
- GList *flags2 = g_list_append(NULL, GINT_TO_POINTER(flags));
+ g_return_if_fail(msg != NULL);
- purple_conv_chat_add_users(chat, users, extra_msgs, flags2, new_arrival);
+ g_free(msg->who);
+ g_free(msg->what);
+ g_free(msg->alias);
- g_list_free(users);
- g_list_free(extra_msgs);
- g_list_free(flags2);
+ g_free(msg);
}
-static int
-purple_conv_chat_cb_compare(PurpleConvChatBuddy *a, PurpleConvChatBuddy *b)
+GType
+purple_conversation_message_get_type(void)
{
- PurpleConvChatBuddyFlags f1 = 0, f2 = 0;
- char *user1 = NULL, *user2 = NULL;
- gint ret = 0;
-
- if (a) {
- f1 = a->flags;
- if (a->alias_key)
- user1 = a->alias_key;
- else if (a->name)
- user1 = a->name;
- }
+ static GType type = 0;
- if (b) {
- f2 = b->flags;
- if (b->alias_key)
- user2 = b->alias_key;
- else if (b->name)
- user2 = b->name;
- }
-
- if (user1 == NULL || user2 == NULL) {
- if (!(user1 == NULL && user2 == NULL))
- ret = (user1 == NULL) ? -1: 1;
- } else if (f1 != f2) {
- /* sort more important users first */
- ret = (f1 > f2) ? -1 : 1;
- } else if (a->buddy != b->buddy) {
- ret = a->buddy ? -1 : 1;
- } else {
- ret = purple_utf8_strcasecmp(user1, user2);
+ if (type == 0) {
+ type = g_boxed_type_register_static("PurpleConversationMessage",
+ (GBoxedCopyFunc)purple_conversation_message_copy,
+ (GBoxedFreeFunc)purple_conversation_message_free);
}
- return ret;
+ return type;
}
-void
-purple_conv_chat_add_users(PurpleConvChat *chat, GList *users, GList *extra_msgs,
- GList *flags, gboolean new_arrivals)
+void purple_conversation_set_ui_data(PurpleConversation *conv, gpointer ui_data)
{
- PurpleConversation *conv;
- PurpleConversationUiOps *ops;
- PurpleConvChatBuddy *cbuddy;
- PurpleConnection *gc;
- PurplePluginProtocolInfo *prpl_info;
- GList *ul, *fl;
- GList *cbuddies = NULL;
-
- g_return_if_fail(chat != NULL);
- g_return_if_fail(users != NULL);
-
- conv = purple_conv_chat_get_conversation(chat);
- ops = purple_conversation_get_ui_ops(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);
-
- ul = users;
- fl = flags;
- while ((ul != NULL) && (fl != NULL)) {
- const char *user = (const char *)ul->data;
- const char *alias = user;
- gboolean quiet;
- PurpleConvChatBuddyFlags flag = GPOINTER_TO_INT(fl->data);
- const char *extra_msg = (extra_msgs ? extra_msgs->data : NULL);
-
- if(!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
- if (purple_strequal(chat->nick, purple_normalize(conv->account, user))) {
- const char *alias2 = purple_account_get_alias(conv->account);
- if (alias2 != NULL)
- alias = alias2;
- else
- {
- const char *display_name = purple_connection_get_display_name(gc);
- if (display_name != NULL)
- alias = display_name;
- }
- } else {
- PurpleBuddy *buddy;
- if ((buddy = purple_find_buddy(purple_connection_get_account(gc), user)) != NULL)
- alias = purple_buddy_get_contact_alias(buddy);
- }
- }
-
- quiet = GPOINTER_TO_INT(purple_signal_emit_return_1(purple_conversations_get_handle(),
- "chat-buddy-joining", conv, user, flag)) ||
- purple_conv_chat_is_user_ignored(chat, user);
-
- cbuddy = purple_conv_chat_cb_new(user, alias, flag);
- cbuddy->buddy = purple_find_buddy(conv->account, user) != NULL;
-
- chat->in_room = g_list_prepend(chat->in_room, cbuddy);
- g_hash_table_replace(chat->users, g_strdup(cbuddy->name), cbuddy);
-
- cbuddies = g_list_prepend(cbuddies, cbuddy);
-
- if (!quiet && new_arrivals) {
- char *alias_esc = g_markup_escape_text(alias, -1);
- char *tmp;
-
- if (extra_msg == NULL)
- tmp = g_strdup_printf(_("%s entered the room."), alias_esc);
- else {
- char *extra_msg_esc = g_markup_escape_text(extra_msg, -1);
- tmp = g_strdup_printf(_("%s [<I>%s</I>] entered the room."),
- alias_esc, extra_msg_esc);
- g_free(extra_msg_esc);
- }
- g_free(alias_esc);
-
- purple_conversation_write(conv, NULL, tmp,
- PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LINKIFY,
- time(NULL));
- g_free(tmp);
- }
-
- purple_signal_emit(purple_conversations_get_handle(),
- "chat-buddy-joined", conv, user, flag, new_arrivals);
- ul = ul->next;
- fl = fl->next;
- if (extra_msgs != NULL)
- extra_msgs = extra_msgs->next;
- }
-
- cbuddies = g_list_sort(cbuddies, (GCompareFunc)purple_conv_chat_cb_compare);
-
- if (ops != NULL && ops->chat_add_users != NULL)
- ops->chat_add_users(conv, cbuddies, new_arrivals);
+ g_return_if_fail(conv != NULL);
- g_list_free(cbuddies);
+ conv->ui_data = ui_data;
}
-void
-purple_conv_chat_rename_user(PurpleConvChat *chat, const char *old_user,
- const char *new_user)
+gpointer purple_conversation_get_ui_data(const PurpleConversation *conv)
{
- PurpleConversation *conv;
- PurpleConversationUiOps *ops;
- PurpleConnection *gc;
- PurplePluginProtocolInfo *prpl_info;
- PurpleConvChatBuddy *cb;
- PurpleConvChatBuddyFlags flags;
- const char *new_alias = new_user;
- char tmp[BUF_LONG];
- gboolean is_me = FALSE;
-
- g_return_if_fail(chat != NULL);
- g_return_if_fail(old_user != NULL);
- g_return_if_fail(new_user != NULL);
-
- conv = purple_conv_chat_get_conversation(chat);
- ops = purple_conversation_get_ui_ops(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);
-
- if (purple_strequal(chat->nick, purple_normalize(conv->account, old_user))) {
- const char *alias;
-
- /* Note this for later. */
- is_me = TRUE;
-
- if(!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
- alias = purple_account_get_alias(conv->account);
- if (alias != NULL)
- new_alias = alias;
- else
- {
- const char *display_name = purple_connection_get_display_name(gc);
- if (display_name != NULL)
- new_alias = display_name;
- }
- }
- } else if (!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
- PurpleBuddy *buddy;
- if ((buddy = purple_find_buddy(purple_connection_get_account(gc), new_user)) != NULL)
- new_alias = purple_buddy_get_contact_alias(buddy);
- }
-
- flags = purple_conv_chat_user_get_flags(chat, old_user);
- cb = purple_conv_chat_cb_new(new_user, new_alias, flags);
- cb->buddy = purple_find_buddy(conv->account, new_user) != NULL;
-
- chat->in_room = g_list_prepend(chat->in_room, cb);
- g_hash_table_replace(chat->users, g_strdup(cb->name), cb);
-
- if (ops != NULL && ops->chat_rename_user != NULL)
- ops->chat_rename_user(conv, old_user, new_user, new_alias);
-
- cb = purple_conv_chat_cb_find(chat, old_user);
-
- if (cb) {
- chat->in_room = g_list_remove(chat->in_room, cb);
- g_hash_table_remove(chat->users, cb->name);
- purple_conv_chat_cb_destroy(cb);
- }
-
- if (purple_conv_chat_is_user_ignored(chat, old_user)) {
- purple_conv_chat_unignore(chat, old_user);
- purple_conv_chat_ignore(chat, new_user);
- }
- else if (purple_conv_chat_is_user_ignored(chat, new_user))
- purple_conv_chat_unignore(chat, new_user);
-
- if (is_me)
- purple_conv_chat_set_nick(chat, new_user);
-
- if (purple_prefs_get_bool("/purple/conversations/chat/show_nick_change") &&
- !purple_conv_chat_is_user_ignored(chat, new_user)) {
-
- if (is_me) {
- char *escaped = g_markup_escape_text(new_user, -1);
- g_snprintf(tmp, sizeof(tmp),
- _("You are now known as %s"), escaped);
- g_free(escaped);
- } else {
- const char *old_alias = old_user;
- const char *new_alias = new_user;
- char *escaped;
- char *escaped2;
-
- if (!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
- PurpleBuddy *buddy;
-
- 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(purple_connection_get_account(gc), new_user)) != NULL)
- new_alias = purple_buddy_get_contact_alias(buddy);
- }
-
- escaped = g_markup_escape_text(old_alias, -1);
- escaped2 = g_markup_escape_text(new_alias, -1);
- g_snprintf(tmp, sizeof(tmp),
- _("%s is now known as %s"), escaped, escaped2);
- g_free(escaped);
- g_free(escaped2);
- }
+ g_return_val_if_fail(conv != NULL, NULL);
- purple_conversation_write(conv, NULL, tmp,
- PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LINKIFY,
- time(NULL));
- }
+ return conv->ui_data;
}
-void
-purple_conv_chat_remove_user(PurpleConvChat *chat, const char *user, const char *reason)
+gboolean
+purple_conversation_do_command(PurpleConversation *conv, const gchar *cmdline,
+ const gchar *markup, gchar **error)
{
- GList *users = g_list_append(NULL, (char *)user);
-
- purple_conv_chat_remove_users(chat, users, reason);
-
- g_list_free(users);
+ char *mark = (markup && *markup) ? NULL : g_markup_escape_text(cmdline, -1), *err = NULL;
+ PurpleCmdStatus status = purple_cmd_do_command(conv, cmdline, mark ? mark : markup, error ? error : &err);
+ g_free(mark);
+ g_free(err);
+ return (status == PURPLE_CMD_STATUS_OK);
}
-void
-purple_conv_chat_remove_users(PurpleConvChat *chat, GList *users, const char *reason)
-{
- PurpleConversation *conv;
- PurpleConnection *gc;
- PurplePluginProtocolInfo *prpl_info;
- PurpleConversationUiOps *ops;
- PurpleConvChatBuddy *cb;
- GList *l;
- gboolean quiet;
-
- g_return_if_fail(chat != NULL);
- g_return_if_fail(users != NULL);
-
- conv = purple_conv_chat_get_conversation(chat);
-
- 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);
-
- ops = purple_conversation_get_ui_ops(conv);
-
- for (l = users; l != NULL; l = l->next) {
- const char *user = (const char *)l->data;
- quiet = GPOINTER_TO_INT(purple_signal_emit_return_1(purple_conversations_get_handle(),
- "chat-buddy-leaving", conv, user, reason)) |
- purple_conv_chat_is_user_ignored(chat, user);
-
- cb = purple_conv_chat_cb_find(chat, user);
-
- if (cb) {
- chat->in_room = g_list_remove(chat->in_room, cb);
- g_hash_table_remove(chat->users, cb->name);
- purple_conv_chat_cb_destroy(cb);
- }
-
- /* NOTE: Don't remove them from ignored in case they re-enter. */
-
- if (!quiet) {
- const char *alias = user;
- char *alias_esc;
- char *tmp;
-
- if (!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
- PurpleBuddy *buddy;
-
- if ((buddy = purple_find_buddy(purple_connection_get_account(gc), user)) != NULL)
- alias = purple_buddy_get_contact_alias(buddy);
- }
-
- alias_esc = g_markup_escape_text(alias, -1);
-
- if (reason == NULL || !*reason)
- tmp = g_strdup_printf(_("%s left the room."), alias_esc);
- else {
- char *reason_esc = g_markup_escape_text(reason, -1);
- tmp = g_strdup_printf(_("%s left the room (%s)."),
- alias_esc, reason_esc);
- g_free(reason_esc);
- }
- g_free(alias_esc);
+/**************************************************************************
+ * GObject code
+ **************************************************************************/
- purple_conversation_write(conv, NULL, tmp,
- PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LINKIFY,
- time(NULL));
- g_free(tmp);
- }
+/* GObject Property names */
+#define PROP_ACCOUNT_S "account"
+#define PROP_NAME_S "name"
+#define PROP_TITLE_S "title"
+#define PROP_LOGGING_S "logging"
+#define PROP_FEATURES_S "features"
- purple_signal_emit(purple_conversations_get_handle(), "chat-buddy-left",
- conv, user, reason);
+/* Set method for GObject properties */
+static void
+purple_conversation_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleConversation *conv = PURPLE_CONVERSATION(obj);
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+
+ switch (param_id) {
+ /* account, name and title are assigned directly here as
+ * purple_im_conversation_new() and purple_chat_conversation_new()
+ * pass these properties as parameters, and so the conversation hasn't
+ * finished being set up */
+ case PROP_ACCOUNT:
+ priv->account = g_value_get_object(value);
+ break;
+ case PROP_NAME:
+ g_free(priv->name);
+ priv->name = g_strdup(g_value_get_string(value));
+ break;
+ case PROP_TITLE:
+ g_free(priv->title);
+ priv->title = g_strdup(g_value_get_string(value));
+ break;
+ case PROP_LOGGING:
+ purple_conversation_set_logging(conv, g_value_get_boolean(value));
+ break;
+ case PROP_FEATURES:
+ purple_conversation_set_features(conv, g_value_get_flags(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
}
-
- if (ops != NULL && ops->chat_remove_users != NULL)
- ops->chat_remove_users(conv, users);
}
-void
-purple_conv_chat_clear_users(PurpleConvChat *chat)
+/* Get method for GObject properties */
+static void
+purple_conversation_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
{
- PurpleConversation *conv;
- PurpleConversationUiOps *ops;
- GList *users;
- GList *l;
- GList *names = NULL;
-
- g_return_if_fail(chat != NULL);
-
- conv = purple_conv_chat_get_conversation(chat);
- ops = purple_conversation_get_ui_ops(conv);
- users = chat->in_room;
+ PurpleConversation *conv = PURPLE_CONVERSATION(obj);
- if (ops != NULL && ops->chat_remove_users != NULL) {
- for (l = users; l; l = l->next) {
- PurpleConvChatBuddy *cb = l->data;
- names = g_list_prepend(names, cb->name);
- }
- ops->chat_remove_users(conv, names);
- g_list_free(names);
- }
-
- for (l = users; l; l = l->next)
- {
- PurpleConvChatBuddy *cb = l->data;
-
- purple_signal_emit(purple_conversations_get_handle(),
- "chat-buddy-leaving", conv, cb->name, NULL);
- purple_signal_emit(purple_conversations_get_handle(),
- "chat-buddy-left", conv, cb->name, NULL);
-
- purple_conv_chat_cb_destroy(cb);
+ switch (param_id) {
+ case PROP_ACCOUNT:
+ g_value_set_object(value, purple_conversation_get_account(conv));
+ break;
+ case PROP_NAME:
+ g_value_set_string(value, purple_conversation_get_name(conv));
+ break;
+ case PROP_TITLE:
+ g_value_set_string(value, purple_conversation_get_title(conv));
+ break;
+ case PROP_LOGGING:
+ g_value_set_boolean(value, purple_conversation_is_logging(conv));
+ break;
+ case PROP_FEATURES:
+ g_value_set_flags(value, purple_conversation_get_features(conv));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
}
-
- g_hash_table_remove_all(chat->users);
-
- g_list_free(users);
- chat->in_room = NULL;
}
-
-gboolean
-purple_conv_chat_find_user(PurpleConvChat *chat, const char *user)
+/* GObject initialization function */
+static void
+purple_conversation_init(GTypeInstance *instance, gpointer klass)
{
- g_return_val_if_fail(chat != NULL, FALSE);
- g_return_val_if_fail(user != NULL, FALSE);
-
- return (purple_conv_chat_cb_find(chat, user) != NULL);
+ PURPLE_DBUS_REGISTER_POINTER(PURPLE_CONVERSATION(instance), PurpleConversation);
}
-void
-purple_conv_chat_user_set_flags(PurpleConvChat *chat, const char *user,
- PurpleConvChatBuddyFlags flags)
+/* Called when done constructing */
+static void
+purple_conversation_constructed(GObject *object)
{
- PurpleConversation *conv;
+ PurpleConversation *conv = PURPLE_CONVERSATION(object);
+ PurpleAccount *account;
+ PurpleConnection *gc;
PurpleConversationUiOps *ops;
- PurpleConvChatBuddy *cb;
- PurpleConvChatBuddyFlags oldflags;
- g_return_if_fail(chat != NULL);
- g_return_if_fail(user != NULL);
+ parent_class->constructed(object);
- cb = purple_conv_chat_cb_find(chat, user);
-
- if (!cb)
- return;
+ g_object_get(object, PROP_ACCOUNT_S, &account, NULL);
+ gc = purple_account_get_connection(account);
- if (flags == cb->flags)
- return;
+ /* copy features from the connection. */
+ purple_conversation_set_features(conv, purple_connection_get_flags(gc));
- oldflags = cb->flags;
- cb->flags = flags;
+ /* add the conversation to the appropriate lists */
+ purple_conversations_add(conv);
- conv = purple_conv_chat_get_conversation(chat);
- ops = purple_conversation_get_ui_ops(conv);
+ /* Auto-set the title. */
+ purple_conversation_autoset_title(conv);
- if (ops != NULL && ops->chat_update_user != NULL)
- ops->chat_update_user(conv, user);
+ /* Don't move this.. it needs to be one of the last things done otherwise
+ * it causes mysterious crashes on my system.
+ * -- Gary
+ */
+ ops = purple_conversations_get_ui_ops();
+ purple_conversation_set_ui_ops(conv, ops);
+ if (ops != NULL && ops->create_conversation != NULL)
+ ops->create_conversation(conv);
purple_signal_emit(purple_conversations_get_handle(),
- "chat-buddy-flags", conv, user, oldflags, flags);
-}
-
-PurpleConvChatBuddyFlags
-purple_conv_chat_user_get_flags(PurpleConvChat *chat, const char *user)
-{
- PurpleConvChatBuddy *cb;
-
- g_return_val_if_fail(chat != NULL, 0);
- g_return_val_if_fail(user != NULL, 0);
-
- cb = purple_conv_chat_cb_find(chat, user);
-
- if (!cb)
- return PURPLE_CBFLAGS_NONE;
-
- return cb->flags;
-}
-
-void purple_conv_chat_set_nick(PurpleConvChat *chat, const char *nick) {
- g_return_if_fail(chat != NULL);
-
- g_free(chat->nick);
- chat->nick = g_strdup(purple_normalize(chat->conv->account, nick));
-}
-
-const char *purple_conv_chat_get_nick(PurpleConvChat *chat) {
- g_return_val_if_fail(chat != NULL, NULL);
-
- return chat->nick;
-}
-
-PurpleConversation *
-purple_find_chat(const PurpleConnection *gc, int id)
-{
- GList *l;
- PurpleConversation *conv;
-
- for (l = purple_get_chats(); l != NULL; l = l->next) {
- conv = (PurpleConversation *)l->data;
-
- if (purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)) == id &&
- purple_conversation_get_connection(conv) == gc)
- return conv;
- }
-
- return NULL;
-}
-
-void
-purple_conv_chat_left(PurpleConvChat *chat)
-{
- g_return_if_fail(chat != NULL);
-
- chat->left = TRUE;
- purple_conversation_update(chat->conv, PURPLE_CONV_UPDATE_CHATLEFT);
+ "conversation-created", conv);
}
+/* GObject dispose function */
static void
-invite_user_to_chat(gpointer data, PurpleRequestFields *fields)
-{
- PurpleConversation *conv;
- PurpleConvChat *chat;
- const char *user, *message;
-
- conv = data;
- chat = PURPLE_CONV_CHAT(conv);
- user = purple_request_fields_get_string(fields, "screenname");
- message = purple_request_fields_get_string(fields, "message");
-
- serv_chat_invite(purple_conversation_get_connection(conv), chat->id, message, user);
-}
-
-void purple_conv_chat_invite_user(PurpleConvChat *chat, const char *user,
- const char *message, gboolean confirm)
-{
- PurpleAccount *account;
- PurpleConversation *conv;
- PurpleRequestFields *fields;
- PurpleRequestFieldGroup *group;
- PurpleRequestField *field;
-
- g_return_if_fail(chat);
-
- if (!user || !*user || !message || !*message)
- confirm = TRUE;
-
- conv = chat->conv;
- account = conv->account;
-
- if (!confirm) {
- serv_chat_invite(purple_account_get_connection(account),
- purple_conv_chat_get_id(chat), message, user);
- return;
- }
-
- fields = purple_request_fields_new();
- group = purple_request_field_group_new(_("Invite to chat"));
- purple_request_fields_add_group(fields, group);
-
- field = purple_request_field_string_new("screenname", _("Buddy"), user, FALSE);
- purple_request_field_group_add_field(group, field);
- purple_request_field_set_required(field, TRUE);
- purple_request_field_set_type_hint(field, "screenname");
-
- field = purple_request_field_string_new("message", _("Message"), message, FALSE);
- purple_request_field_group_add_field(group, field);
-
- purple_request_fields(conv, _("Invite to chat"), NULL,
- _("Please enter the name of the user you wish to invite, "
- "along with an optional invite message."),
- fields,
- _("Invite"), G_CALLBACK(invite_user_to_chat),
- _("Cancel"), NULL,
- account, user, conv,
- conv);
-}
-
-gboolean
-purple_conv_chat_has_left(PurpleConvChat *chat)
+purple_conversation_dispose(GObject *object)
{
- g_return_val_if_fail(chat != NULL, TRUE);
-
- return chat->left;
-}
-
-PurpleConvChatBuddy *
-purple_conv_chat_cb_new(const char *name, const char *alias, PurpleConvChatBuddyFlags flags)
-{
- PurpleConvChatBuddy *cb;
-
- g_return_val_if_fail(name != NULL, NULL);
+ PurpleConversation *conv = PURPLE_CONVERSATION(object);
- cb = g_new0(PurpleConvChatBuddy, 1);
- cb->name = g_strdup(name);
- cb->flags = flags;
- cb->alias = g_strdup(alias);
- cb->attributes = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, g_free);
-
- PURPLE_DBUS_REGISTER_POINTER(cb, PurpleConvChatBuddy);
- return cb;
-}
-
-PurpleConvChatBuddy *
-purple_conv_chat_cb_find(PurpleConvChat *chat, const char *name)
-{
- g_return_val_if_fail(chat != NULL, NULL);
- g_return_val_if_fail(name != NULL, NULL);
+ g_return_if_fail(conv != NULL);
- return g_hash_table_lookup(chat->users, name);
-}
+ purple_request_close_with_handle(conv);
-void
-purple_conv_chat_cb_destroy(PurpleConvChatBuddy *cb)
-{
- if (cb == NULL)
- return;
+ /* remove from conversations and im/chats lists prior to emit */
+ purple_conversations_remove(conv);
purple_signal_emit(purple_conversations_get_handle(),
- "deleting-chat-buddy", cb);
-
- g_free(cb->alias);
- g_free(cb->alias_key);
- g_free(cb->name);
- g_hash_table_destroy(cb->attributes);
-
- PURPLE_DBUS_UNREGISTER_POINTER(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_alias(const PurpleConvChatBuddy *cb)
-{
- g_return_val_if_fail(cb != NULL, NULL);
+ "deleting-conversation", conv);
- return cb->alias;
-}
+ purple_conversation_close_logs(conv);
+ purple_conversation_clear_message_history(conv);
-const char *
-purple_conv_chat_cb_get_name(const PurpleConvChatBuddy *cb)
-{
- g_return_val_if_fail(cb != NULL, NULL);
+ PURPLE_DBUS_UNREGISTER_POINTER(conv);
- return cb->name;
+ parent_class->dispose(object);
}
-PurpleConvChatBuddyFlags
-purple_conv_chat_cb_get_flags(const PurpleConvChatBuddy *cb)
+/* GObject finalize function */
+static void
+purple_conversation_finalize(GObject *object)
{
- g_return_val_if_fail(cb != NULL, PURPLE_CBFLAGS_NONE);
+ PurpleConversation *conv = PURPLE_CONVERSATION(object);
+ PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+ PurpleConversationUiOps *ops = purple_conversation_get_ui_ops(conv);
- return cb->flags;
-}
+ g_free(priv->name);
+ g_free(priv->title);
-gboolean purple_conv_chat_cb_is_buddy(const PurpleConvChatBuddy *cb)
-{
- g_return_val_if_fail(cb != NULL, FALSE);
+ priv->name = NULL;
+ priv->title = NULL;
- return cb->buddy;
-}
+ if (ops != NULL && ops->destroy_conversation != NULL)
+ ops->destroy_conversation(conv);
-const char *
-purple_conv_chat_cb_get_attribute(PurpleConvChatBuddy *cb, const char *key)
-{
- g_return_val_if_fail(cb != NULL, NULL);
- g_return_val_if_fail(key != NULL, NULL);
-
- return g_hash_table_lookup(cb->attributes, key);
+ parent_class->finalize(object);
}
+/* Class initializer function */
static void
-append_attribute_key(gpointer key, gpointer value, gpointer user_data)
-{
- GList **list = user_data;
- *list = g_list_prepend(*list, key);
-}
-
-GList *
-purple_conv_chat_cb_get_attribute_keys(PurpleConvChatBuddy *cb)
-{
- GList *keys = NULL;
-
- g_return_val_if_fail(cb != NULL, NULL);
-
- g_hash_table_foreach(cb->attributes, (GHFunc)append_attribute_key, &keys);
-
- return keys;
-}
-
-void
-purple_conv_chat_cb_set_attribute(PurpleConvChat *chat, PurpleConvChatBuddy *cb, const char *key, const char *value)
-{
- PurpleConversation *conv;
- PurpleConversationUiOps *ops;
-
- g_return_if_fail(cb != NULL);
- g_return_if_fail(key != NULL);
- g_return_if_fail(value != NULL);
-
- g_hash_table_replace(cb->attributes, g_strdup(key), g_strdup(value));
-
- conv = purple_conv_chat_get_conversation(chat);
- ops = purple_conversation_get_ui_ops(conv);
-
- if (ops != NULL && ops->chat_update_user != NULL)
- ops->chat_update_user(conv, cb->name);
-}
-
-void
-purple_conv_chat_cb_set_attributes(PurpleConvChat *chat, PurpleConvChatBuddy *cb, GList *keys, GList *values)
-{
- PurpleConversation *conv;
- PurpleConversationUiOps *ops;
-
- g_return_if_fail(cb != NULL);
- g_return_if_fail(keys != NULL);
- g_return_if_fail(values != NULL);
-
- while (keys != NULL && values != NULL) {
- g_hash_table_replace(cb->attributes, g_strdup(keys->data), g_strdup(values->data));
- keys = g_list_next(keys);
- values = g_list_next(values);
+purple_conversation_class_init(PurpleConversationClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->dispose = purple_conversation_dispose;
+ obj_class->finalize = purple_conversation_finalize;
+ obj_class->constructed = purple_conversation_constructed;
+
+ /* Setup properties */
+ obj_class->get_property = purple_conversation_get_property;
+ obj_class->set_property = purple_conversation_set_property;
+
+ g_object_class_install_property(obj_class, PROP_ACCOUNT,
+ g_param_spec_object(PROP_ACCOUNT_S, _("Account"),
+ _("The account for the conversation."), PURPLE_TYPE_ACCOUNT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
+ );
+
+ g_object_class_install_property(obj_class, PROP_NAME,
+ g_param_spec_string(PROP_NAME_S, _("Name"),
+ _("The name of the conversation."), NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
+ );
+
+ g_object_class_install_property(obj_class, PROP_TITLE,
+ g_param_spec_string(PROP_TITLE_S, _("Title"),
+ _("The title of the conversation."), NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
+ );
+
+ g_object_class_install_property(obj_class, PROP_LOGGING,
+ g_param_spec_boolean(PROP_LOGGING_S, _("Logging status"),
+ _("Whether logging is enabled or not."), FALSE,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, PROP_FEATURES,
+ g_param_spec_flags(PROP_FEATURES_S, _("Connection features"),
+ _("The connection features of the conversation."),
+ PURPLE_TYPE_CONNECTION_FLAGS, 0,
+ G_PARAM_READWRITE)
+ );
+
+ g_type_class_add_private(klass, sizeof(PurpleConversationPrivate));
+}
+
+GType
+purple_conversation_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleConversationClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_conversation_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleConversation),
+ 0,
+ (GInstanceInitFunc)purple_conversation_init,
+ NULL,
+ };
+
+ type = g_type_register_static(G_TYPE_OBJECT,
+ "PurpleConversation",
+ &info, G_TYPE_FLAG_ABSTRACT);
}
-
- conv = purple_conv_chat_get_conversation(chat);
- ops = purple_conversation_get_ui_ops(conv);
-
- if (ops != NULL && ops->chat_update_user != NULL)
- ops->chat_update_user(conv, cb->name);
-}
-
-GList *
-purple_conversation_get_extended_menu(PurpleConversation *conv)
-{
- GList *menu = NULL;
-
- g_return_val_if_fail(conv != NULL, NULL);
-
- purple_signal_emit(purple_conversations_get_handle(),
- "conversation-extended-menu", conv, &menu);
- return menu;
-}
-
-void purple_conversation_clear_message_history(PurpleConversation *conv)
-{
- GList *list = conv->message_history;
- message_history_free(list);
- conv->message_history = NULL;
-
- purple_signal_emit(purple_conversations_get_handle(),
- "cleared-message-history", conv);
-}
-
-GList *purple_conversation_get_message_history(PurpleConversation *conv)
-{
- return conv->message_history;
-}
-
-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(const PurpleConvMessage *msg)
-{
- g_return_val_if_fail(msg, NULL);
- return msg->what;
-}
-
-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(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;
+ return type;
}
-
-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)
-{
- char *mark = (markup && *markup) ? NULL : g_markup_escape_text(cmdline, -1), *err = NULL;
- PurpleCmdStatus status = purple_cmd_do_command(conv, cmdline, mark ? mark : markup, error ? error : &err);
- g_free(mark);
- g_free(err);
- return (status == PURPLE_CMD_STATUS_OK);
-}
-
-void *
-purple_conversations_get_handle(void)
-{
- static int handle;
-
- return &handle;
-}
-
-void
-purple_conversations_init(void)
-{
- void *handle = purple_conversations_get_handle();
-
- conversation_cache = g_hash_table_new_full((GHashFunc)_purple_conversations_hconv_hash,
- (GEqualFunc)_purple_conversations_hconv_equal,
- (GDestroyNotify)_purple_conversations_hconv_free_key, NULL);
-
- /**********************************************************************
- * Register preferences
- **********************************************************************/
-
- /* Conversations */
- purple_prefs_add_none("/purple/conversations");
-
- /* Conversations -> Chat */
- purple_prefs_add_none("/purple/conversations/chat");
- purple_prefs_add_bool("/purple/conversations/chat/show_nick_change", TRUE);
-
- /* Conversations -> IM */
- purple_prefs_add_none("/purple/conversations/im");
- purple_prefs_add_bool("/purple/conversations/im/send_typing", TRUE);
-
-
- /**********************************************************************
- * Register signals
- **********************************************************************/
- purple_signal_register(handle, "writing-im-msg",
- purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_UINT,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new_outgoing(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_UINT));
-
- purple_signal_register(handle, "wrote-im-msg",
- purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT,
- NULL, 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_UINT));
-
- purple_signal_register(handle, "sent-attention",
- purple_marshal_VOID__POINTER_POINTER_POINTER_UINT,
- NULL, 4,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_UINT));
-
- purple_signal_register(handle, "got-attention",
- purple_marshal_VOID__POINTER_POINTER_POINTER_UINT,
- NULL, 4,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_UINT));
-
- purple_signal_register(handle, "sending-im-msg",
- purple_marshal_VOID__POINTER_POINTER_POINTER,
- NULL, 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new_outgoing(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "sent-im-msg",
- purple_marshal_VOID__POINTER_POINTER_POINTER,
- NULL, 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "receiving-im-msg",
- purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new_outgoing(PURPLE_TYPE_STRING),
- purple_value_new_outgoing(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new_outgoing(PURPLE_TYPE_UINT));
-
- purple_signal_register(handle, "received-im-msg",
- purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT,
- NULL, 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_UINT));
-
- purple_signal_register(handle, "blocked-im-msg",
- purple_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT,
- NULL, 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_UINT),
- purple_value_new(PURPLE_TYPE_UINT));
-
- purple_signal_register(handle, "writing-chat-msg",
- purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_UINT,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new_outgoing(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_UINT));
-
- purple_signal_register(handle, "wrote-chat-msg",
- purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT,
- NULL, 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_UINT));
-
- purple_signal_register(handle, "sending-chat-msg",
- purple_marshal_VOID__POINTER_POINTER_UINT, NULL, 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new_outgoing(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_UINT));
-
- purple_signal_register(handle, "sent-chat-msg",
- purple_marshal_VOID__POINTER_POINTER_UINT, NULL, 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_UINT));
-
- purple_signal_register(handle, "receiving-chat-msg",
- purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new_outgoing(PURPLE_TYPE_STRING),
- purple_value_new_outgoing(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new_outgoing(PURPLE_TYPE_UINT));
-
- purple_signal_register(handle, "received-chat-msg",
- purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT,
- NULL, 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_UINT));
-
- purple_signal_register(handle, "conversation-created",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION));
-
- purple_signal_register(handle, "conversation-updated",
- purple_marshal_VOID__POINTER_UINT, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_UINT));
-
- purple_signal_register(handle, "deleting-conversation",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION));
-
- purple_signal_register(handle, "buddy-typing",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "buddy-typed",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "buddy-typing-stopped",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "chat-buddy-joining",
- purple_marshal_BOOLEAN__POINTER_POINTER_UINT,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_UINT));
-
- purple_signal_register(handle, "chat-buddy-joined",
- purple_marshal_VOID__POINTER_POINTER_UINT_UINT, NULL, 4,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_UINT),
- purple_value_new(PURPLE_TYPE_BOOLEAN));
-
- purple_signal_register(handle, "chat-buddy-flags",
- purple_marshal_VOID__POINTER_POINTER_UINT_UINT, NULL, 4,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_UINT),
- purple_value_new(PURPLE_TYPE_UINT));
-
- purple_signal_register(handle, "chat-buddy-leaving",
- purple_marshal_BOOLEAN__POINTER_POINTER_POINTER,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "chat-buddy-left",
- purple_marshal_VOID__POINTER_POINTER_POINTER, NULL, 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "deleting-chat-buddy",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CHATBUDDY));
-
- purple_signal_register(handle, "chat-inviting-user",
- purple_marshal_VOID__POINTER_POINTER_POINTER, NULL, 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new_outgoing(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "chat-invited-user",
- purple_marshal_VOID__POINTER_POINTER_POINTER, NULL, 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "chat-invited",
- purple_marshal_INT__POINTER_POINTER_POINTER_POINTER_POINTER,
- purple_value_new(PURPLE_TYPE_INT), 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_POINTER));
-
- purple_signal_register(handle, "chat-invite-blocked",
- purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_POINTER,
- NULL, 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_BOXED, "GHashTable *"));
-
- purple_signal_register(handle, "chat-joined",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION));
-
- purple_signal_register(handle, "chat-join-failed",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONNECTION),
- purple_value_new(PURPLE_TYPE_POINTER));
-
- purple_signal_register(handle, "chat-left",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION));
-
- purple_signal_register(handle, "chat-topic-changed",
- purple_marshal_VOID__POINTER_POINTER_POINTER, NULL, 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING));
-
- purple_signal_register(handle, "cleared-message-history",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION));
-
- purple_signal_register(handle, "conversation-extended-menu",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_BOXED, "GList **"));
-}
-
-void
-purple_conversations_uninit(void)
-{
- while (conversations)
- purple_conversation_destroy((PurpleConversation*)conversations->data);
- g_hash_table_destroy(conversation_cache);
- purple_signals_unregister_by_instance(purple_conversations_get_handle());
-}
-
diff --git a/libpurple/conversation.h b/libpurple/conversation.h
index 80262ef809..b8eb85feea 100644
--- a/libpurple/conversation.h
+++ b/libpurple/conversation.h
@@ -1,7 +1,6 @@
/**
- * @file conversation.h Conversation API
+ * @file conversation.h Conversation base class API
* @ingroup core
- * @see @ref conversation-signals
*/
/* purple
@@ -27,128 +26,140 @@
#ifndef _PURPLE_CONVERSATION_H_
#define _PURPLE_CONVERSATION_H_
+#define PURPLE_TYPE_CONVERSATION (purple_conversation_get_type())
+#define PURPLE_CONVERSATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_CONVERSATION, PurpleConversation))
+#define PURPLE_CONVERSATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_CONVERSATION, PurpleConversationClass))
+#define PURPLE_IS_CONVERSATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_CONVERSATION))
+#define PURPLE_IS_CONVERSATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_CONVERSATION))
+#define PURPLE_CONVERSATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_CONVERSATION, PurpleConversationClass))
+
+#define PURPLE_TYPE_CONVERSATION_MESSAGE (purple_conversation_message_get_type())
+
/**************************************************************************/
/** Data Structures */
/**************************************************************************/
-
-/** @copydoc _PurpleConversationUiOps */
-typedef struct _PurpleConversationUiOps PurpleConversationUiOps;
/** @copydoc _PurpleConversation */
-typedef struct _PurpleConversation PurpleConversation;
-/** @copydoc _PurpleConvIm */
-typedef struct _PurpleConvIm PurpleConvIm;
-/** @copydoc _PurpleConvChat */
-typedef struct _PurpleConvChat PurpleConvChat;
-/** @copydoc _PurpleConvChatBuddy */
-typedef struct _PurpleConvChatBuddy PurpleConvChatBuddy;
-/** @copydoc _PurpleConvMessage */
-typedef struct _PurpleConvMessage PurpleConvMessage;
-
-/**
- * A type of conversation.
- */
-typedef enum
-{
- PURPLE_CONV_TYPE_UNKNOWN = 0, /**< Unknown conversation type. */
- PURPLE_CONV_TYPE_IM, /**< Instant Message. */
- PURPLE_CONV_TYPE_CHAT, /**< Chat room. */
- PURPLE_CONV_TYPE_MISC, /**< A misc. conversation. */
- PURPLE_CONV_TYPE_ANY /**< Any type of conversation. */
+typedef struct _PurpleConversation PurpleConversation;
+/** @copydoc _PurpleConversation */
+typedef struct _PurpleConversationClass PurpleConversationClass;
-} PurpleConversationType;
+/** @copydoc _PurpleConversationUiOps */
+typedef struct _PurpleConversationUiOps PurpleConversationUiOps;
+/** @copydoc _PurpleConversationMessage */
+typedef struct _PurpleConversationMessage PurpleConversationMessage;
/**
* Conversation update type.
*/
typedef enum
{
- PURPLE_CONV_UPDATE_ADD = 0, /**< The buddy associated with the conversation
- was added. */
- PURPLE_CONV_UPDATE_REMOVE, /**< The buddy associated with the conversation
- was removed. */
- PURPLE_CONV_UPDATE_ACCOUNT, /**< The purple_account was changed. */
- PURPLE_CONV_UPDATE_TYPING, /**< The typing state was updated. */
- PURPLE_CONV_UPDATE_UNSEEN, /**< The unseen state was updated. */
- PURPLE_CONV_UPDATE_LOGGING, /**< Logging for this conversation was
- enabled or disabled. */
- PURPLE_CONV_UPDATE_TOPIC, /**< The topic for a chat was updated. */
+ PURPLE_CONVERSATION_UPDATE_ADD = 0, /**< The buddy associated with the conversation
+ was added. */
+ PURPLE_CONVERSATION_UPDATE_REMOVE, /**< The buddy associated with the conversation
+ was removed. */
+ PURPLE_CONVERSATION_UPDATE_ACCOUNT, /**< The purple_account was changed. */
+ PURPLE_CONVERSATION_UPDATE_TYPING, /**< The typing state was updated. */
+ PURPLE_CONVERSATION_UPDATE_UNSEEN, /**< The unseen state was updated. */
+ PURPLE_CONVERSATION_UPDATE_LOGGING, /**< Logging for this conversation was
+ enabled or disabled. */
+ PURPLE_CONVERSATION_UPDATE_TOPIC, /**< The topic for a chat was updated. */
/*
* XXX These need to go when we implement a more generic core/UI event
* system.
*/
- PURPLE_CONV_ACCOUNT_ONLINE, /**< One of the user's accounts went online. */
- PURPLE_CONV_ACCOUNT_OFFLINE, /**< One of the user's accounts went offline. */
- PURPLE_CONV_UPDATE_AWAY, /**< The other user went away. */
- PURPLE_CONV_UPDATE_ICON, /**< The other user's buddy icon changed. */
- PURPLE_CONV_UPDATE_TITLE,
- PURPLE_CONV_UPDATE_CHATLEFT,
+ PURPLE_CONVERSATION_ACCOUNT_ONLINE, /**< One of the user's accounts went online. */
+ PURPLE_CONVERSATION_ACCOUNT_OFFLINE, /**< One of the user's accounts went offline. */
+ PURPLE_CONVERSATION_UPDATE_AWAY, /**< The other user went away. */
+ PURPLE_CONVERSATION_UPDATE_ICON, /**< The other user's buddy icon changed. */
+ PURPLE_CONVERSATION_UPDATE_TITLE,
+ PURPLE_CONVERSATION_UPDATE_CHATLEFT,
- PURPLE_CONV_UPDATE_FEATURES /**< The features for a chat have changed */
+ PURPLE_CONVERSATION_UPDATE_FEATURES /**< The features for a chat have changed */
-} PurpleConvUpdateType;
-
-/**
- * The typing state of a user.
- */
-typedef enum
-{
- PURPLE_NOT_TYPING = 0, /**< Not typing. */
- PURPLE_TYPING, /**< Currently typing. */
- PURPLE_TYPED /**< Stopped typing momentarily. */
-
-} PurpleTypingState;
+} PurpleConversationUpdateType;
/**
* Flags applicable to a message. Most will have send, recv or system.
*/
-typedef enum
+typedef enum /*< flags >*/
{
PURPLE_MESSAGE_SEND = 0x0001, /**< Outgoing message. */
PURPLE_MESSAGE_RECV = 0x0002, /**< Incoming message. */
PURPLE_MESSAGE_SYSTEM = 0x0004, /**< System message. */
PURPLE_MESSAGE_AUTO_RESP = 0x0008, /**< Auto response. */
PURPLE_MESSAGE_ACTIVE_ONLY = 0x0010, /**< Hint to the UI that this
- message should not be
- shown in conversations
- which are only open for
- internal UI purposes
- (e.g. for contact-aware
- conversations). */
+ message should not be
+ shown in conversations
+ which are only open for
+ internal UI purposes
+ (e.g. for contact-aware
+ conversations). */
PURPLE_MESSAGE_NICK = 0x0020, /**< Contains your nick. */
PURPLE_MESSAGE_NO_LOG = 0x0040, /**< Do not log. */
PURPLE_MESSAGE_WHISPER = 0x0080, /**< Whispered message. */
PURPLE_MESSAGE_ERROR = 0x0200, /**< Error message. */
PURPLE_MESSAGE_DELAYED = 0x0400, /**< Delayed message. */
PURPLE_MESSAGE_RAW = 0x0800, /**< "Raw" message - don't
- apply formatting */
+ apply formatting */
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 */
+ linkified */
PURPLE_MESSAGE_INVISIBLE = 0x8000 /**< Message should not be displayed */
} PurpleMessageFlags;
+#include <glib.h>
+#include <glib-object.h>
+
+/**************************************************************************/
+/** PurpleConversation */
+/**************************************************************************/
/**
- * Flags applicable to users in Chats.
+ * A core representation of a conversation between two or more people.
+ *
+ * The conversation can be an IM or a chat.
+ *
+ * @note When a conversation is destroyed with the last g_object_unref(), the
+ * specified conversation is removed from the parent window. If this
+ * conversation is the only one contained in the parent window, that
+ * window is also destroyed.
*/
-typedef enum
+struct _PurpleConversation
{
- PURPLE_CBFLAGS_NONE = 0x0000, /**< No flags */
- PURPLE_CBFLAGS_VOICE = 0x0001, /**< Voiced user or "Participant" */
- PURPLE_CBFLAGS_HALFOP = 0x0002, /**< Half-op */
- 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. */
+ /*< private >*/
+ GObject gparent;
-} PurpleConvChatBuddyFlags;
+ /** The UI data associated with this conversation. This is a convenience
+ * field provided to the UIs -- it is not used by the libpurple core.
+ */
+ gpointer ui_data;
+};
+
+/** Base class for all #PurpleConversation's */
+struct _PurpleConversationClass {
+ /*< private >*/
+ GObjectClass parent_class;
+
+ /** Writes a message to a chat or IM conversation.
+ * @see purple_conversation_write_message()
+ */
+ void (*write_message)(PurpleConversation *conv, const char *who,
+ const char *message, PurpleMessageFlags flags, time_t mtime);
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
#include "account.h"
#include "buddyicon.h"
#include "log.h"
-#include "server.h"
+/**************************************************************************/
+/** PurpleConversationUiOps */
+/**************************************************************************/
/**
* Conversation operations and events.
*
@@ -166,16 +177,16 @@ struct _PurpleConversationUiOps
void (*destroy_conversation)(PurpleConversation *conv);
/** Write a message to a chat. If this field is @c NULL, libpurple will
* fall back to using #write_conv.
- * @see purple_conv_chat_write()
+ * @see purple_chat_conversation_write()
*/
- void (*write_chat)(PurpleConversation *conv, const char *who,
- const char *message, PurpleMessageFlags flags,
- time_t mtime);
+ void (*write_chat)(PurpleChatConversation *chat, const char *who,
+ const char *message, PurpleMessageFlags flags,
+ time_t mtime);
/** Write a message to an IM conversation. If this field is @c NULL,
* libpurple will fall back to using #write_conv.
- * @see purple_conv_im_write()
+ * @see purple_im_conversation_write()
*/
- void (*write_im)(PurpleConversation *conv, const char *who,
+ void (*write_im)(PurpleIMConversation *im, const char *who,
const char *message, PurpleMessageFlags flags,
time_t mtime);
/** Write a message to a conversation. This is used rather than the
@@ -194,30 +205,31 @@ struct _PurpleConversationUiOps
time_t mtime);
/** Add @a cbuddies to a chat.
- * @param cbuddies A @c GList of #PurpleConvChatBuddy structs.
+ * @param cbuddies A @c GList of #PurpleChatUser structs.
* @param new_arrivals Whether join notices should be shown.
* (Join notices are actually written to the
- * conversation by #purple_conv_chat_add_users().)
+ * conversation by
+ * #purple_chat_conversation_add_users().)
*/
- void (*chat_add_users)(PurpleConversation *conv,
+ void (*chat_add_users)(PurpleChatConversation *chat,
GList *cbuddies,
gboolean new_arrivals);
/** Rename the user in this chat named @a old_name to @a new_name. (The
* rename message is written to the conversation by libpurple.)
* @param new_alias @a new_name's new alias, if they have one.
- * @see purple_conv_chat_add_users()
+ * @see purple_chat_conversation_add_users()
*/
- void (*chat_rename_user)(PurpleConversation *conv, const char *old_name,
+ void (*chat_rename_user)(PurpleChatConversation *chat, const char *old_name,
const char *new_name, const char *new_alias);
/** Remove @a users from a chat.
* @param users A @c GList of <tt>const char *</tt>s.
- * @see purple_conv_chat_rename_user()
+ * @see purple_chat_conversation_rename_user()
*/
- void (*chat_remove_users)(PurpleConversation *conv, GList *users);
+ void (*chat_remove_users)(PurpleChatConversation *chat, GList *users);
/** Called when a user's flags are changed.
- * @see purple_conv_chat_user_set_flags()
+ * @see purple_chat_user_set_flags()
*/
- void (*chat_update_user)(PurpleConversation *conv, const char *user);
+ void (*chat_update_user)(PurpleChatUser *cb);
/** Present this conversation to the user; for example, by displaying
* the IM dialog.
@@ -231,7 +243,8 @@ struct _PurpleConversationUiOps
gboolean (*has_focus)(PurpleConversation *conv);
/* Custom Smileys */
- gboolean (*custom_smiley_add)(PurpleConversation *conv, const char *smile, gboolean remote);
+ gboolean (*custom_smiley_add)(PurpleConversation *conv, const char *smile,
+ gboolean remote);
void (*custom_smiley_write)(PurpleConversation *conv, const char *smile,
const guchar *data, gsize size);
void (*custom_smiley_close)(PurpleConversation *conv, const char *smile);
@@ -257,31 +270,9 @@ G_BEGIN_DECLS
/*@{*/
/**
- * Creates a new conversation of the specified type.
- *
- * @param type The type of conversation.
- * @param account The account opening the conversation window on the purple
- * user's end.
- * @param name The name of the conversation. For PURPLE_CONV_TYPE_IM,
- * this is the name of the buddy.
- *
- * @return The new conversation.
- */
-PurpleConversation *purple_conversation_new(PurpleConversationType type,
- PurpleAccount *account,
- const char *name);
-
-/**
- * Destroys the specified conversation and removes it from the parent
- * window.
- *
- * If this conversation is the only one contained in the parent window,
- * that window is also destroyed.
- *
- * @param conv The conversation to destroy.
+ * Returns the GType for the Conversation object.
*/
-void purple_conversation_destroy(PurpleConversation *conv);
-
+GType purple_conversation_get_type(void);
/**
* Present a conversation to the user. This allows core code to initiate a
@@ -290,16 +281,6 @@ void purple_conversation_destroy(PurpleConversation *conv);
*/
void purple_conversation_present(PurpleConversation *conv);
-
-/**
- * Returns the specified conversation's type.
- *
- * @param conv The conversation.
- *
- * @return The conversation's type.
- */
-PurpleConversationType purple_conversation_get_type(const PurpleConversation *conv);
-
/**
* Sets the specified conversation's UI operations structure.
*
@@ -310,21 +291,13 @@ void purple_conversation_set_ui_ops(PurpleConversation *conv,
PurpleConversationUiOps *ops);
/**
- * Sets the default conversation UI operations structure.
- *
- * @param ops The UI conversation operations structure.
- */
-void purple_conversations_set_ui_ops(PurpleConversationUiOps *ops);
-
-/**
* Returns the specified conversation's UI operations structure.
*
* @param conv The conversation.
*
* @return The operations structure.
*/
-PurpleConversationUiOps *purple_conversation_get_ui_ops(
- const PurpleConversation *conv);
+PurpleConversationUiOps *purple_conversation_get_ui_ops(const PurpleConversation *conv);
/**
* Sets the specified conversation's purple_account.
@@ -405,46 +378,6 @@ void purple_conversation_set_name(PurpleConversation *conv, const char *name);
const char *purple_conversation_get_name(const PurpleConversation *conv);
/**
- * Get an attribute of a chat buddy
- *
- * @param cb The chat buddy.
- * @param key The key of the attribute.
- *
- * @return The value of the attribute key.
- */
-const char *purple_conv_chat_cb_get_attribute(PurpleConvChatBuddy *cb, const char *key);
-
-/**
- * Get the keys of all atributes of a chat buddy
- *
- * @param cb The chat buddy.
- *
- * @return A list of the attributes of a chat buddy.
- */
-GList *purple_conv_chat_cb_get_attribute_keys(PurpleConvChatBuddy *cb);
-
-/**
- * Set an attribute of a chat buddy
- *
- * @param chat The chat.
- * @param cb The chat buddy.
- * @param key The key of the attribute.
- * @param value The value of the attribute.
- */
-void purple_conv_chat_cb_set_attribute(PurpleConvChat *chat, PurpleConvChatBuddy *cb, const char *key, const char *value);
-
-/**
- * Set attributes of a chat buddy
- *
- * @param chat The chat.
- * @param cb The chat buddy.
- * @param keys A GList of the keys.
- * @param values A GList of the values.
- */
-void
-purple_conv_chat_cb_set_attributes(PurpleConvChat *chat, PurpleConvChatBuddy *cb, GList *keys, GList *values);
-
-/**
* Enables or disables logging for this conversation.
*
* @param conv The conversation.
@@ -473,110 +406,61 @@ gboolean purple_conversation_is_logging(const PurpleConversation *conv);
void purple_conversation_close_logs(PurpleConversation *conv);
/**
- * Returns the specified conversation's IM-specific data.
- *
- * If the conversation type is not PURPLE_CONV_TYPE_IM, this will return @c NULL.
- *
- * @param conv The conversation.
- *
- * @return The IM-specific data.
- */
-PurpleConvIm *purple_conversation_get_im_data(const PurpleConversation *conv);
-
-#define PURPLE_CONV_IM(c) (purple_conversation_get_im_data(c))
-
-/**
- * Returns the specified conversation's chat-specific data.
- *
- * If the conversation type is not PURPLE_CONV_TYPE_CHAT, this will return @c NULL.
- *
- * @param conv The conversation.
- *
- * @return The chat-specific data.
- */
-PurpleConvChat *purple_conversation_get_chat_data(const PurpleConversation *conv);
-
-#define PURPLE_CONV_CHAT(c) (purple_conversation_get_chat_data(c))
-
-/**
- * Sets extra data for a conversation.
- *
- * @param conv The conversation.
- * @param key The unique key.
- * @param data The data to assign.
- */
-void purple_conversation_set_data(PurpleConversation *conv, const char *key,
- gpointer data);
-
-/**
- * Returns extra data in a conversation.
+ * Writes to a conversation window.
*
- * @param conv The conversation.
- * @param key The unqiue key.
+ * This function should not be used to write IM or chat messages. Use
+ * purple_conversation_write_message() instead. This function will
+ * most likely call this anyway, but it may do it's own formatting,
+ * sound playback, etc. depending on whether the conversation is a chat or an
+ * IM.
*
- * @return The data associated with the key.
- */
-gpointer purple_conversation_get_data(PurpleConversation *conv, const char *key);
-
-/**
- * Returns a list of all conversations.
+ * This can be used to write generic messages, such as "so and so closed
+ * the conversation window."
*
- * This list includes both IMs and chats.
+ * @param conv The conversation.
+ * @param who The user who sent the message.
+ * @param message The message.
+ * @param flags The message flags.
+ * @param mtime The time the message was sent.
*
- * @constreturn A GList of all conversations.
+ * @see purple_conversation_write_message()
*/
-GList *purple_get_conversations(void);
+void purple_conversation_write(PurpleConversation *conv, const char *who,
+ const char *message, PurpleMessageFlags flags,
+ time_t mtime);
/**
- * Returns a list of all IMs.
+ * Writes to a chat or an IM.
*
- * @constreturn A GList of all IMs.
+ * @param conv The conversation.
+ * @param who The user who sent the message.
+ * @param message The message to write.
+ * @param flags The message flags.
+ * @param mtime The time the message was sent.
*/
-GList *purple_get_ims(void);
+void purple_conversation_write_message(PurpleConversation *conv,
+ const char *who, const char *message,
+ PurpleMessageFlags flags, time_t mtime);
/**
- * Returns a list of all chats.
+ * Sends a message to this conversation. This function calls
+ * purple_conversation_send_with_flags() with no additional flags.
*
- * @constreturn A GList of all chats.
+ * @param conv The conversation.
+ * @param message The message to send.
*/
-GList *purple_get_chats(void);
+void purple_conversation_send(PurpleConversation *conv, const char *message);
/**
- * Finds a conversation with the specified type, name, and Purple account.
- *
- * @param type The type of the conversation.
- * @param name The name of the conversation.
- * @param account The purple_account associated with the conversation.
- *
- * @return The conversation if found, or @c NULL otherwise.
- */
-PurpleConversation *purple_find_conversation_with_account(
- PurpleConversationType type, const char *name,
- const PurpleAccount *account);
-
-/**
- * Writes to a conversation window.
- *
- * This function should not be used to write IM or chat messages. Use
- * purple_conv_im_write() and purple_conv_chat_write() instead. Those functions will
- * most likely call this anyway, but they may do their own formatting,
- * sound playback, etc.
- *
- * This can be used to write generic messages, such as "so and so closed
- * the conversation window."
+ * Sends a message to this conversation with specified flags.
*
* @param conv The conversation.
- * @param who The user who sent the message.
- * @param message The message.
- * @param flags The message flags.
- * @param mtime The time the message was sent.
- *
- * @see purple_conv_im_write()
- * @see purple_conv_chat_write()
+ * @param message The message to send.
+ * @param flags The PurpleMessageFlags flags to use in addition to
+ * PURPLE_MESSAGE_SEND.
*/
-void purple_conversation_write(PurpleConversation *conv, const char *who,
- const char *message, PurpleMessageFlags flags,
- time_t mtime);
+void purple_conversation_send_with_flags(PurpleConversation *conv, const char *message,
+ PurpleMessageFlags flags);
/**
Set the features as supported for the given conversation.
@@ -609,21 +493,14 @@ gboolean purple_conversation_has_focus(PurpleConversation *conv);
* @param conv The conversation.
* @param type The update type.
*/
-void purple_conversation_update(PurpleConversation *conv, PurpleConvUpdateType type);
-
-/**
- * Calls a function on each conversation.
- *
- * @param func The function.
- */
-void purple_conversation_foreach(void (*func)(PurpleConversation *conv));
+void purple_conversation_update(PurpleConversation *conv, PurpleConversationUpdateType type);
/**
* Retrieve the message history of a conversation.
*
* @param conv The conversation
*
- * @return A GList of PurpleConvMessage's. The must not modify the list or the data within.
+ * @return A GList of PurpleConversationMessage'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.
*/
@@ -637,60 +514,6 @@ GList *purple_conversation_get_message_history(PurpleConversation *conv);
void purple_conversation_clear_message_history(PurpleConversation *conv);
/**
- * Get the sender from a PurpleConvMessage
- *
- * @param msg A PurpleConvMessage
- *
- * @return The name of the sender of the message
- */
-const char *purple_conversation_message_get_sender(const PurpleConvMessage *msg);
-
-/**
- * Get the message from a PurpleConvMessage
- *
- * @param msg A PurpleConvMessage
- *
- * @return The name of the sender of the message
- */
-const char *purple_conversation_message_get_message(const PurpleConvMessage *msg);
-
-/**
- * Get the message-flags of a PurpleConvMessage
- *
- * @param msg A PurpleConvMessage
- *
- * @return The message flags
- */
-PurpleMessageFlags purple_conversation_message_get_flags(const PurpleConvMessage *msg);
-
-/**
- * Get the timestamp of a PurpleConvMessage
- *
- * @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.
@@ -709,175 +532,6 @@ void purple_conversation_set_ui_data(PurpleConversation *conv, gpointer ui_data)
*/
gpointer purple_conversation_get_ui_data(const PurpleConversation *conv);
-/*@}*/
-
-
-/**************************************************************************/
-/** @name IM Conversation API */
-/**************************************************************************/
-/*@{*/
-
-/**
- * Gets an IM's parent conversation.
- *
- * @param im The IM.
- *
- * @return The parent conversation.
- */
-PurpleConversation *purple_conv_im_get_conversation(const PurpleConvIm *im);
-
-/**
- * Sets the IM's buddy icon.
- *
- * This should only be called from within Purple. You probably want to
- * call purple_buddy_icon_set_data().
- *
- * @param im The IM.
- * @param icon The buddy icon.
- *
- * @see purple_buddy_icon_set_data()
- */
-void purple_conv_im_set_icon(PurpleConvIm *im, PurpleBuddyIcon *icon);
-
-/**
- * Returns the IM's buddy icon.
- *
- * @param im The IM.
- *
- * @return The buddy icon.
- */
-PurpleBuddyIcon *purple_conv_im_get_icon(const PurpleConvIm *im);
-
-/**
- * Sets the IM's typing state.
- *
- * @param im The IM.
- * @param state The typing state.
- */
-void purple_conv_im_set_typing_state(PurpleConvIm *im, PurpleTypingState state);
-
-/**
- * Returns the IM's typing state.
- *
- * @param im The IM.
- *
- * @return The IM's typing state.
- */
-PurpleTypingState purple_conv_im_get_typing_state(const PurpleConvIm *im);
-
-/**
- * Starts the IM's typing timeout.
- *
- * @param im The IM.
- * @param timeout The timeout.
- */
-void purple_conv_im_start_typing_timeout(PurpleConvIm *im, int timeout);
-
-/**
- * Stops the IM's typing timeout.
- *
- * @param im The IM.
- */
-void purple_conv_im_stop_typing_timeout(PurpleConvIm *im);
-
-/**
- * Returns the IM's typing timeout.
- *
- * @param im The IM.
- *
- * @return The timeout.
- */
-guint purple_conv_im_get_typing_timeout(const PurpleConvIm *im);
-
-/**
- * Sets the quiet-time when no PURPLE_TYPING messages will be sent.
- * Few protocols need this (maybe only MSN). If the user is still
- * typing after this quiet-period, then another PURPLE_TYPING message
- * will be sent.
- *
- * @param im The IM.
- * @param val The number of seconds to wait before allowing another
- * PURPLE_TYPING message to be sent to the user. Or 0 to
- * not send another PURPLE_TYPING message.
- */
-void purple_conv_im_set_type_again(PurpleConvIm *im, unsigned int val);
-
-/**
- * Returns the time after which another PURPLE_TYPING message should be sent.
- *
- * @param im The IM.
- *
- * @return The time in seconds since the epoch. Or 0 if no additional
- * PURPLE_TYPING message should be sent.
- */
-time_t purple_conv_im_get_type_again(const PurpleConvIm *im);
-
-/**
- * Starts the IM's type again timeout.
- *
- * @param im The IM.
- */
-void purple_conv_im_start_send_typed_timeout(PurpleConvIm *im);
-
-/**
- * Stops the IM's type again timeout.
- *
- * @param im The IM.
- */
-void purple_conv_im_stop_send_typed_timeout(PurpleConvIm *im);
-
-/**
- * Returns the IM's type again timeout interval.
- *
- * @param im The IM.
- *
- * @return The type again timeout interval.
- */
-guint purple_conv_im_get_send_typed_timeout(const PurpleConvIm *im);
-
-/**
- * Updates the visual typing notification for an IM conversation.
- *
- * @param im The IM.
- */
-void purple_conv_im_update_typing(PurpleConvIm *im);
-
-/**
- * Writes to an IM.
- *
- * @param im The IM.
- * @param who The user who sent the message.
- * @param message The message to write.
- * @param flags The message flags.
- * @param mtime The time the message was sent.
- */
-void purple_conv_im_write(PurpleConvIm *im, const char *who,
- const char *message, PurpleMessageFlags flags,
- time_t mtime);
-
-/**
- * Presents an IM-error to the user
- *
- * This is a helper function to find a conversation, write an error to it, and
- * raise the window. If a conversation with this user doesn't already exist,
- * the function will return FALSE and the calling function can attempt to present
- * the error another way (purple_notify_error, most likely)
- *
- * @param who The user this error is about
- * @param account The account this error is on
- * @param what The error
- * @return TRUE if the error was presented, else FALSE
- */
-gboolean purple_conv_present_error(const char *who, PurpleAccount *account, const char *what);
-
-/**
- * Sends a message to this IM conversation.
- *
- * @param im The IM.
- * @param message The message to send.
- */
-void purple_conv_im_send(PurpleConvIm *im, const char *message);
-
/**
* Sends a message to a conversation after confirming with
* the user.
@@ -890,21 +544,12 @@ void purple_conv_im_send(PurpleConvIm *im, const char *message);
* @param conv The conversation.
* @param message The message to send.
*/
-void purple_conv_send_confirm(PurpleConversation *conv, const char *message);
-
-/**
- * Sends a message to this IM conversation with specified flags.
- *
- * @param im The IM.
- * @param message The message to send.
- * @param flags The PurpleMessageFlags flags to use in addition to PURPLE_MESSAGE_SEND.
- */
-void purple_conv_im_send_with_flags(PurpleConvIm *im, const char *message, PurpleMessageFlags flags);
+void purple_conversation_send_confirm(PurpleConversation *conv, const char *message);
/**
* Adds a smiley to the conversation's smiley tree. If this returns
- * @c TRUE you should call purple_conv_custom_smiley_write() one or more
- * times, and then purple_conv_custom_smiley_close(). If this returns
+ * @c TRUE you should call purple_conversation_custom_smiley_write() one or more
+ * times, and then purple_conversation_custom_smiley_close(). If this returns
* @c FALSE, either the conv or smile were invalid, or the icon was
* found in the cache. In either case, calling write or close would
* be an error.
@@ -915,16 +560,15 @@ void purple_conv_im_send_with_flags(PurpleConvIm *im, const char *message, Purpl
* @param chksum The checksum, as a NUL terminated base64 string.
* @param remote @c TRUE if the custom smiley is set by the remote user (buddy).
* @return @c TRUE if an icon is expected, else FALSE. Note that
- * it is an error to never call purple_conv_custom_smiley_close if
+ * it is an error to never call purple_conversation_custom_smiley_close if
* this function returns @c TRUE, but an error to call it if
* @c FALSE is returned.
*/
-gboolean purple_conv_custom_smiley_add(PurpleConversation *conv, const char *smile,
+gboolean purple_conversation_custom_smiley_add(PurpleConversation *conv, const char *smile,
const char *cksum_type, const char *chksum,
gboolean remote);
-
/**
* Updates the image associated with the current smiley.
*
@@ -934,469 +578,134 @@ gboolean purple_conv_custom_smiley_add(PurpleConversation *conv, const char *smi
* @param size The length of the data.
*/
-void purple_conv_custom_smiley_write(PurpleConversation *conv,
+void purple_conversation_custom_smiley_write(PurpleConversation *conv,
const char *smile,
const guchar *data,
gsize size);
/**
* Close the custom smiley, all data has been written with
- * purple_conv_custom_smiley_write, and it is no longer valid
+ * purple_conversation_custom_smiley_write, and it is no longer valid
* to call that function on that smiley.
*
* @param conv The purple conversation associated with the smiley.
* @param smile The text associated with the smiley
*/
-void purple_conv_custom_smiley_close(PurpleConversation *conv, const char *smile);
-
-/*@}*/
-
-
-/**************************************************************************/
-/** @name Chat Conversation API */
-/**************************************************************************/
-/*@{*/
-
-/**
- * Gets a chat's parent conversation.
- *
- * @param chat The chat.
- *
- * @return The parent conversation.
- */
-PurpleConversation *purple_conv_chat_get_conversation(const PurpleConvChat *chat);
-
-/**
- * Returns a list of users in the chat room. The members of the list
- * are PurpleConvChatBuddy objects.
- *
- * @param chat The chat.
- *
- * @constreturn The list of users.
- */
-GList *purple_conv_chat_get_users(const PurpleConvChat *chat);
-
-/**
- * Ignores a user in a chat room.
- *
- * @param chat The chat.
- * @param name The name of the user.
- */
-void purple_conv_chat_ignore(PurpleConvChat *chat, const char *name);
-
-/**
- * Unignores a user in a chat room.
- *
- * @param chat The chat.
- * @param name The name of the user.
- */
-void purple_conv_chat_unignore(PurpleConvChat *chat, const char *name);
-
-/**
- * Sets the list of ignored users in the chat room.
- *
- * @param chat The chat.
- * @param ignored The list of ignored users.
- *
- * @return The list passed.
- */
-GList *purple_conv_chat_set_ignored(PurpleConvChat *chat, GList *ignored);
-
-/**
- * Returns the list of ignored users in the chat room.
- *
- * @param chat The chat.
- *
- * @constreturn The list of ignored users.
- */
-GList *purple_conv_chat_get_ignored(const PurpleConvChat *chat);
-
-/**
- * Returns the actual name of the specified ignored user, if it exists in
- * the ignore list.
- *
- * If the user found contains a prefix, such as '+' or '\@', this is also
- * returned. The username passed to the function does not have to have this
- * formatting.
- *
- * @param chat The chat.
- * @param user The user to check in the ignore list.
- *
- * @return The ignored user if found, complete with prefixes, or @c NULL
- * if not found.
- */
-const char *purple_conv_chat_get_ignored_user(const PurpleConvChat *chat,
- const char *user);
-
-/**
- * Returns @c TRUE if the specified user is ignored.
- *
- * @param chat The chat.
- * @param user The user.
- *
- * @return @c TRUE if the user is in the ignore list; @c FALSE otherwise.
- */
-gboolean purple_conv_chat_is_user_ignored(const PurpleConvChat *chat,
- const char *user);
-
-/**
- * Sets the chat room's topic.
- *
- * @param chat The chat.
- * @param who The user that set the topic.
- * @param topic The topic.
- */
-void purple_conv_chat_set_topic(PurpleConvChat *chat, const char *who,
- const char *topic);
-
-/**
- * Returns the chat room's topic.
- *
- * @param chat The chat.
- *
- * @return The chat's topic.
- */
-const char *purple_conv_chat_get_topic(const PurpleConvChat *chat);
-
-/**
- * Sets the chat room's ID.
- *
- * @param chat The chat.
- * @param id The ID.
- */
-void purple_conv_chat_set_id(PurpleConvChat *chat, int id);
-
-/**
- * Returns the chat room's ID.
- *
- * @param chat The chat.
- *
- * @return The ID.
- */
-int purple_conv_chat_get_id(const PurpleConvChat *chat);
-
-/**
- * Writes to a chat.
- *
- * @param chat The chat.
- * @param who The user who sent the message.
- * @param message The message to write.
- * @param flags The flags.
- * @param mtime The time the message was sent.
- */
-void purple_conv_chat_write(PurpleConvChat *chat, const char *who,
- const char *message, PurpleMessageFlags flags,
- time_t mtime);
-
-/**
- * Sends a message to this chat conversation.
- *
- * @param chat The chat.
- * @param message The message to send.
- */
-void purple_conv_chat_send(PurpleConvChat *chat, const char *message);
-
-/**
- * Sends a message to this chat conversation with specified flags.
- *
- * @param chat The chat.
- * @param message The message to send.
- * @param flags The PurpleMessageFlags flags to use.
- */
-void purple_conv_chat_send_with_flags(PurpleConvChat *chat, const char *message, PurpleMessageFlags flags);
-
-/**
- * Adds a user to a chat.
- *
- * @param chat The chat.
- * @param user The user to add.
- * @param extra_msg An extra message to display with the join message.
- * @param flags The users flags
- * @param new_arrival Decides whether or not to show a join notice.
- */
-void purple_conv_chat_add_user(PurpleConvChat *chat, const char *user,
- const char *extra_msg, PurpleConvChatBuddyFlags flags,
- gboolean new_arrival);
-
-/**
- * Adds a list of users to a chat.
- *
- * The data is copied from @a users, @a extra_msgs, and @a flags, so it is up to
- * the caller to free this list after calling this function.
- *
- * @param chat The chat.
- * @param users The list of users to add.
- * @param extra_msgs An extra message to display with the join message for each
- * user. This list may be shorter than @a users, in which
- * case, the users after the end of extra_msgs will not have
- * an extra message. By extension, this means that extra_msgs
- * can simply be @c NULL and none of the users will have an
- * extra message.
- * @param flags The list of flags for each user.
- * @param new_arrivals Decides whether or not to show join notices.
- */
-void purple_conv_chat_add_users(PurpleConvChat *chat, GList *users, GList *extra_msgs,
- GList *flags, gboolean new_arrivals);
-
-/**
- * Renames a user in a chat.
- *
- * @param chat The chat.
- * @param old_user The old username.
- * @param new_user The new username.
- */
-void purple_conv_chat_rename_user(PurpleConvChat *chat, const char *old_user,
- const char *new_user);
-
-/**
- * Removes a user from a chat, optionally with a reason.
- *
- * It is up to the developer to free this list after calling this function.
- *
- * @param chat The chat.
- * @param user The user that is being removed.
- * @param reason The optional reason given for the removal. Can be @c NULL.
- */
-void purple_conv_chat_remove_user(PurpleConvChat *chat, const char *user,
- const char *reason);
-
-/**
- * Removes a list of users from a chat, optionally with a single reason.
- *
- * @param chat The chat.
- * @param users The users that are being removed.
- * @param reason The optional reason given for the removal. Can be @c NULL.
- */
-void purple_conv_chat_remove_users(PurpleConvChat *chat, GList *users,
- const char *reason);
-
-/**
- * Finds a user in a chat
- *
- * @param chat The chat.
- * @param user The user to look for.
- *
- * @return TRUE if the user is in the chat, FALSE if not
- */
-gboolean purple_conv_chat_find_user(PurpleConvChat *chat, const char *user);
-
-/**
- * Set a users flags in a chat
- *
- * @param chat The chat.
- * @param user The user to update.
- * @param flags The new flags.
- */
-void purple_conv_chat_user_set_flags(PurpleConvChat *chat, const char *user,
- PurpleConvChatBuddyFlags flags);
-
-/**
- * Get the flags for a user in a chat
- *
- * @param chat The chat.
- * @param user The user to find the flags for
- *
- * @return The flags for the user
- */
-PurpleConvChatBuddyFlags purple_conv_chat_user_get_flags(PurpleConvChat *chat,
- const char *user);
-
-/**
- * Clears all users from a chat.
- *
- * @param chat The chat.
- */
-void purple_conv_chat_clear_users(PurpleConvChat *chat);
+void purple_conversation_custom_smiley_close(PurpleConversation *conv, const char *smile);
/**
- * Sets your nickname (used for hilighting) for a chat.
+ * Retrieves the extended menu items for the conversation.
*
- * @param chat The chat.
- * @param nick The nick.
- */
-void purple_conv_chat_set_nick(PurpleConvChat *chat, const char *nick);
-
-/**
- * Gets your nickname (used for hilighting) for a chat.
+ * @param conv The conversation.
*
- * @param chat The chat.
- * @return The nick.
+ * @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.
*/
-const char *purple_conv_chat_get_nick(PurpleConvChat *chat);
+GList * purple_conversation_get_extended_menu(PurpleConversation *conv);
/**
- * Finds a chat with the specified chat ID.
- *
- * @param gc The purple_connection.
- * @param id The chat ID.
+ * Perform a command in a conversation. Similar to @see purple_cmd_do_command
*
- * @return The chat conversation.
- */
-PurpleConversation *purple_find_chat(const PurpleConnection *gc, int id);
-
-/**
- * Lets the core know we left a chat, without destroying it.
- * Called from serv_got_chat_left().
+ * @param conv The conversation.
+ * @param cmdline The entire command including the arguments.
+ * @param markup @c NULL, or the formatted command line.
+ * @param error If the command failed errormsg is filled in with the appropriate error
+ * message, if not @c NULL. It must be freed by the caller with g_free().
*
- * @param chat The chat.
+ * @return @c TRUE if the command was executed successfully, @c FALSE otherwise.
*/
-void purple_conv_chat_left(PurpleConvChat *chat);
+gboolean purple_conversation_do_command(PurpleConversation *conv,
+ const gchar *cmdline, const gchar *markup, gchar **error);
-/**
- * Invite a user to a chat.
- * The user will be prompted to enter the user's name or a message if one is
- * not given.
- *
- * @param chat The chat.
- * @param user The user to invite to the 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.
- */
-void purple_conv_chat_invite_user(PurpleConvChat *chat, const char *user,
- const char *message, gboolean confirm);
+/*@}*/
-/**
- * Returns true if we're no longer in this chat,
- * and just left the window open.
- *
- * @param chat The chat.
- *
- * @return @c TRUE if we left the chat already, @c FALSE if
- * we're still there.
- */
-gboolean purple_conv_chat_has_left(PurpleConvChat *chat);
+/**************************************************************************/
+/** @name Conversation Helper API */
+/**************************************************************************/
+/*@{*/
/**
- * Creates a new chat buddy
+ * Presents an IM-error to the user
*
- * @param name The name.
- * @param alias The alias.
- * @param flags The flags.
+ * This is a helper function to find a conversation, write an error to it, and
+ * raise the window. If a conversation with this user doesn't already exist,
+ * the function will return FALSE and the calling function can attempt to present
+ * the error another way (purple_notify_error, most likely)
*
- * @return The new chat buddy
+ * @param who The user this error is about
+ * @param account The account this error is on
+ * @param what The error
+ * @return TRUE if the error was presented, else FALSE
*/
-PurpleConvChatBuddy *purple_conv_chat_cb_new(const char *name, const char *alias,
- PurpleConvChatBuddyFlags flags);
+gboolean purple_conversation_present_error(const char *who, PurpleAccount *account, const char *what);
-/**
- * Find a chat buddy in a chat
- *
- * @param chat The chat.
- * @param name The name of the chat buddy to find.
- */
-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);
+/**************************************************************************/
+/** @name Conversation Message API */
+/**************************************************************************/
+/*@{*/
/**
- * 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.
+ * Returns the GType for the PurpleConversationMessage boxed structure.
*/
-gpointer purple_conv_chat_cb_get_ui_data(const PurpleConvChatBuddy *conv);
+GType purple_conversation_message_get_type(void);
/**
- * Get the alias of a chat buddy
+ * Get the sender from a PurpleConversationMessage
*
- * @param cb The chat buddy.
+ * @param msg A PurpleConversationMessage
*
- * @return The alias of the chat buddy.
+ * @return The name of the sender of the message
*/
-const char *purple_conv_chat_cb_get_alias(const PurpleConvChatBuddy *cb);
+const char *purple_conversation_message_get_sender(const PurpleConversationMessage *msg);
/**
- * Get the name of a chat buddy
+ * Get the message from a PurpleConversationMessage
*
- * @param cb The chat buddy.
+ * @param msg A PurpleConversationMessage
*
- * @return The name of the chat buddy.
+ * @return The name of the sender of the message
*/
-const char *purple_conv_chat_cb_get_name(const PurpleConvChatBuddy *cb);
+const char *purple_conversation_message_get_message(const PurpleConversationMessage *msg);
/**
- * Get the flags of a chat buddy.
+ * Get the message-flags of a PurpleConversationMessage
*
- * @param cb The chat buddy.
+ * @param msg A PurpleConversationMessage
*
- * @return The flags of the chat buddy.
+ * @return The message flags
*/
-PurpleConvChatBuddyFlags purple_conv_chat_cb_get_flags(const PurpleConvChatBuddy *cb);
+PurpleMessageFlags purple_conversation_message_get_flags(const PurpleConversationMessage *msg);
/**
- * Indicates if this chat buddy is on the buddy list.
+ * Get the timestamp of a PurpleConversationMessage
*
- * @param cb The chat buddy.
+ * @param msg A PurpleConversationMessage
*
- * @return TRUE if the chat buddy is on the buddy list.
+ * @return The timestamp of the message
*/
-gboolean purple_conv_chat_cb_is_buddy(const PurpleConvChatBuddy *cb);
+time_t purple_conversation_message_get_timestamp(const PurpleConversationMessage *msg);
/**
- * Destroys a chat buddy
+ * Get the alias from a PurpleConversationMessage
*
- * @param cb The chat buddy to destroy
- */
-void purple_conv_chat_cb_destroy(PurpleConvChatBuddy *cb);
-
-/**
- * Retrieves the extended menu items for the conversation.
+ * @param msg A PurpleConversationMessage
*
- * @param conv The conversation.
- *
- * @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.
+ * @return The alias of the sender of the message
*/
-GList * purple_conversation_get_extended_menu(PurpleConversation *conv);
+const char *purple_conversation_message_get_alias(const PurpleConversationMessage *msg);
/**
- * Perform a command in a conversation. Similar to @see purple_cmd_do_command
+ * Get the conversation associated with the PurpleConversationMessage
*
- * @param conv The conversation.
- * @param cmdline The entire command including the arguments.
- * @param markup @c NULL, or the formatted command line.
- * @param error If the command failed errormsg is filled in with the appropriate error
- * 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.
- */
-gboolean purple_conversation_do_command(PurpleConversation *conv, const gchar *cmdline, const gchar *markup, gchar **error);
-
-/*@}*/
-
-/**************************************************************************/
-/** @name Conversations Subsystem */
-/**************************************************************************/
-/*@{*/
-
-/**
- * Returns the conversation subsystem handle.
+ * @param msg A PurpleConversationMessage
*
- * @return The conversation subsystem handle.
- */
-void *purple_conversations_get_handle(void);
-
-/**
- * Initializes the conversation subsystem.
- */
-void purple_conversations_init(void);
-
-/**
- * Uninitializes the conversation subsystem.
+ * @return The conversation
*/
-void purple_conversations_uninit(void);
+PurpleConversation *purple_conversation_message_get_conversation(const PurpleConversationMessage *msg);
/*@}*/
diff --git a/libpurple/conversations.c b/libpurple/conversations.c
new file mode 100644
index 0000000000..0a3ded060e
--- /dev/null
+++ b/libpurple/conversations.c
@@ -0,0 +1,478 @@
+/*
+ * 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
+ */
+#include "internal.h"
+#include "conversations.h"
+
+static GList *conversations = NULL;
+static GList *ims = NULL;
+static GList *chats = NULL;
+static PurpleConversationUiOps *default_ops = NULL;
+
+/**
+ * A hash table used for efficient lookups of conversations by name.
+ * struct _purple_hconv => PurpleConversation*
+ */
+static GHashTable *conversation_cache = NULL;
+
+struct _purple_hconv {
+ gboolean im;
+ char *name;
+ const PurpleAccount *account;
+};
+
+static guint
+_purple_conversations_hconv_hash(struct _purple_hconv *hc)
+{
+ return g_str_hash(hc->name) ^ hc->im ^ g_direct_hash(hc->account);
+}
+
+static guint
+_purple_conversations_hconv_equal(struct _purple_hconv *hc1, struct _purple_hconv *hc2)
+{
+ return (hc1->im == hc2->im &&
+ hc1->account == hc2->account &&
+ g_str_equal(hc1->name, hc2->name));
+}
+
+static void
+_purple_conversations_hconv_free_key(struct _purple_hconv *hc)
+{
+ g_free(hc->name);
+ g_free(hc);
+}
+
+void
+purple_conversations_add(PurpleConversation *conv)
+{
+ PurpleAccount *account;
+ struct _purple_hconv *hc;
+
+ g_return_if_fail(conv != NULL);
+
+ if (g_list_find(conversations, conv) != NULL)
+ return;
+
+ conversations = g_list_prepend(conversations, conv);
+
+ if (PURPLE_IS_IM_CONVERSATION(conv))
+ ims = g_list_prepend(ims, conv);
+ else
+ chats = g_list_prepend(chats, conv);
+
+ account = purple_conversation_get_account(conv);
+
+ hc = g_new(struct _purple_hconv, 1);
+ hc->name = g_strdup(purple_normalize(account,
+ purple_conversation_get_name(conv)));
+ hc->account = account;
+ hc->im = PURPLE_IS_IM_CONVERSATION(conv);
+
+ g_hash_table_insert(conversation_cache, hc, conv);
+}
+
+void
+purple_conversations_remove(PurpleConversation *conv)
+{
+ PurpleAccount *account;
+ struct _purple_hconv hc;
+
+ g_return_if_fail(conv != NULL);
+
+ conversations = g_list_remove(conversations, conv);
+
+ if (PURPLE_IS_IM_CONVERSATION(conv))
+ ims = g_list_remove(ims, conv);
+ else
+ chats = g_list_remove(chats, conv);
+
+ account = purple_conversation_get_account(conv);
+
+ hc.name = (gchar *)purple_normalize(account,
+ purple_conversation_get_name(conv));
+ hc.account = account;
+ hc.im = PURPLE_IS_IM_CONVERSATION(conv);
+
+ g_hash_table_remove(conversation_cache, &hc);
+}
+
+void
+purple_conversations_update_cache(PurpleConversation *conv, const char *name,
+ PurpleAccount *account)
+{
+ PurpleAccount *old_account;
+ struct _purple_hconv *hc;
+
+ g_return_if_fail(conv != NULL);
+ g_return_if_fail(account != NULL || name != NULL);
+
+ old_account = purple_conversation_get_account(conv);
+
+ hc = g_new(struct _purple_hconv, 1);
+ hc->im = PURPLE_IS_IM_CONVERSATION(conv);
+ hc->account = old_account;
+ hc->name = (gchar *)purple_normalize(old_account,
+ purple_conversation_get_name(conv));
+
+ g_hash_table_remove(conversation_cache, hc);
+
+ if (account)
+ hc->account = account;
+ if (name)
+ hc->name = g_strdup(purple_normalize(account, name));
+
+ g_hash_table_insert(conversation_cache, hc, conv);
+}
+
+GList *
+purple_conversations_get_all(void)
+{
+ return conversations;
+}
+
+GList *
+purple_conversations_get_ims(void)
+{
+ return ims;
+}
+
+GList *
+purple_conversations_get_chats(void)
+{
+ return chats;
+}
+
+PurpleConversation *
+purple_conversations_find_with_account(const char *name,
+ const PurpleAccount *account)
+{
+ PurpleConversation *c = NULL;
+ struct _purple_hconv hc;
+
+ g_return_val_if_fail(name != NULL, NULL);
+
+ hc.name = (gchar *)purple_normalize(account, name);
+ hc.account = account;
+
+ hc.im = TRUE;
+ c = g_hash_table_lookup(conversation_cache, &hc);
+ if (!c) {
+ hc.im = FALSE;
+ c = g_hash_table_lookup(conversation_cache, &hc);
+ }
+
+ return c;
+}
+
+PurpleIMConversation *
+purple_conversations_find_im_with_account(const char *name,
+ const PurpleAccount *account)
+{
+ PurpleIMConversation *im = NULL;
+ struct _purple_hconv hc;
+
+ g_return_val_if_fail(name != NULL, NULL);
+
+ hc.name = (gchar *)purple_normalize(account, name);
+ hc.account = account;
+ hc.im = TRUE;
+
+ im = g_hash_table_lookup(conversation_cache, &hc);
+
+ return im;
+}
+
+PurpleChatConversation *
+purple_conversations_find_chat_with_account(const char *name,
+ const PurpleAccount *account)
+{
+ PurpleChatConversation *c = NULL;
+ struct _purple_hconv hc;
+
+ g_return_val_if_fail(name != NULL, NULL);
+
+ hc.name = (gchar *)purple_normalize(account, name);
+ hc.account = account;
+ hc.im = FALSE;
+
+ c = g_hash_table_lookup(conversation_cache, &hc);
+
+ return c;
+}
+
+PurpleChatConversation *
+purple_conversations_find_chat(const PurpleConnection *gc, int id)
+{
+ GList *l;
+ PurpleChatConversation *chat;
+
+ for (l = purple_conversations_get_chats(); l != NULL; l = l->next) {
+ chat = (PurpleChatConversation *)l->data;
+
+ if (purple_chat_conversation_get_id(chat) == id &&
+ purple_conversation_get_connection(PURPLE_CONVERSATION(chat)) == gc)
+ return chat;
+ }
+
+ return NULL;
+}
+
+void
+purple_conversations_set_ui_ops(PurpleConversationUiOps *ops)
+{
+ default_ops = ops;
+}
+
+PurpleConversationUiOps *
+purple_conversations_get_ui_ops(void)
+{
+ return default_ops;
+}
+
+void *
+purple_conversations_get_handle(void)
+{
+ static int handle;
+
+ return &handle;
+}
+
+void
+purple_conversations_init(void)
+{
+ void *handle = purple_conversations_get_handle();
+
+ conversation_cache = g_hash_table_new_full((GHashFunc)_purple_conversations_hconv_hash,
+ (GEqualFunc)_purple_conversations_hconv_equal,
+ (GDestroyNotify)_purple_conversations_hconv_free_key, NULL);
+
+ /**********************************************************************
+ * Register preferences
+ **********************************************************************/
+
+ /* Conversations */
+ purple_prefs_add_none("/purple/conversations");
+
+ /* Conversations -> Chat */
+ purple_prefs_add_none("/purple/conversations/chat");
+ purple_prefs_add_bool("/purple/conversations/chat/show_nick_change", TRUE);
+
+ /* Conversations -> IM */
+ purple_prefs_add_none("/purple/conversations/im");
+ purple_prefs_add_bool("/purple/conversations/im/send_typing", TRUE);
+
+
+ /**********************************************************************
+ * Register signals
+ **********************************************************************/
+ purple_signal_register(handle, "writing-im-msg",
+ purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_UINT,
+ G_TYPE_BOOLEAN, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ G_TYPE_POINTER, /* pointer to a string */
+ PURPLE_TYPE_CONVERSATION, G_TYPE_UINT);
+
+ purple_signal_register(handle, "wrote-im-msg",
+ purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT,
+ G_TYPE_NONE, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ G_TYPE_STRING, PURPLE_TYPE_CONVERSATION, G_TYPE_UINT);
+
+ purple_signal_register(handle, "sent-attention",
+ purple_marshal_VOID__POINTER_POINTER_POINTER_UINT,
+ G_TYPE_NONE, 4, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ PURPLE_TYPE_CONVERSATION, G_TYPE_UINT);
+
+ purple_signal_register(handle, "got-attention",
+ purple_marshal_VOID__POINTER_POINTER_POINTER_UINT,
+ G_TYPE_NONE, 4, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ PURPLE_TYPE_CONVERSATION, G_TYPE_UINT);
+
+ purple_signal_register(handle, "sending-im-msg",
+ purple_marshal_VOID__POINTER_POINTER_POINTER,
+ G_TYPE_NONE, 3, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ G_TYPE_POINTER); /* pointer to a string */
+
+ purple_signal_register(handle, "sent-im-msg",
+ purple_marshal_VOID__POINTER_POINTER_POINTER,
+ G_TYPE_NONE, 3, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ G_TYPE_STRING);
+
+ purple_signal_register(handle, "receiving-im-msg",
+ purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER,
+ G_TYPE_BOOLEAN, 5, PURPLE_TYPE_ACCOUNT,
+ G_TYPE_POINTER, /* pointer to a string */
+ G_TYPE_POINTER, /* pointer to a string */
+ PURPLE_TYPE_CONVERSATION,
+ G_TYPE_POINTER); /* pointer to a string */
+
+ purple_signal_register(handle, "received-im-msg",
+ purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT,
+ G_TYPE_NONE, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ G_TYPE_STRING, PURPLE_TYPE_CONVERSATION, G_TYPE_UINT);
+
+ purple_signal_register(handle, "blocked-im-msg",
+ purple_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT,
+ G_TYPE_NONE, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT);
+
+ purple_signal_register(handle, "writing-chat-msg",
+ purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_UINT,
+ G_TYPE_BOOLEAN, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ G_TYPE_POINTER, /* pointer to a string */
+ PURPLE_TYPE_CONVERSATION, G_TYPE_UINT);
+
+ purple_signal_register(handle, "wrote-chat-msg",
+ purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT,
+ G_TYPE_NONE, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ G_TYPE_STRING, PURPLE_TYPE_CONVERSATION, G_TYPE_UINT);
+
+ purple_signal_register(handle, "sending-chat-msg",
+ purple_marshal_VOID__POINTER_POINTER_UINT, G_TYPE_NONE,
+ 3, PURPLE_TYPE_ACCOUNT,
+ G_TYPE_POINTER, /* pointer to a string */
+ G_TYPE_UINT);
+
+ purple_signal_register(handle, "sent-chat-msg",
+ purple_marshal_VOID__POINTER_POINTER_UINT, G_TYPE_NONE,
+ 3, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING, G_TYPE_UINT);
+
+ purple_signal_register(handle, "receiving-chat-msg",
+ purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER,
+ G_TYPE_BOOLEAN, 5, PURPLE_TYPE_ACCOUNT,
+ G_TYPE_POINTER, /* pointer to a string */
+ G_TYPE_POINTER, /* pointer to a string */
+ PURPLE_TYPE_CONVERSATION,
+ G_TYPE_POINTER); /* pointer to an unsigned int */
+
+ purple_signal_register(handle, "received-chat-msg",
+ purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT,
+ G_TYPE_NONE, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ G_TYPE_STRING, PURPLE_TYPE_CONVERSATION, G_TYPE_UINT);
+
+ purple_signal_register(handle, "conversation-created",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_CONVERSATION);
+
+ purple_signal_register(handle, "conversation-updated",
+ purple_marshal_VOID__POINTER_UINT, G_TYPE_NONE, 2,
+ PURPLE_TYPE_CONVERSATION, G_TYPE_UINT);
+
+ purple_signal_register(handle, "deleting-conversation",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_CONVERSATION);
+
+ purple_signal_register(handle, "buddy-typing",
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ PURPLE_TYPE_ACCOUNT, G_TYPE_STRING);
+
+ purple_signal_register(handle, "buddy-typed",
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ PURPLE_TYPE_ACCOUNT, G_TYPE_STRING);
+
+ purple_signal_register(handle, "buddy-typing-stopped",
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ PURPLE_TYPE_ACCOUNT, G_TYPE_STRING);
+
+ purple_signal_register(handle, "chat-user-joining",
+ purple_marshal_BOOLEAN__POINTER_POINTER_UINT,
+ G_TYPE_BOOLEAN, 3, PURPLE_TYPE_CONVERSATION,
+ G_TYPE_STRING, G_TYPE_UINT);
+
+ purple_signal_register(handle, "chat-user-joined",
+ purple_marshal_VOID__POINTER_POINTER_UINT_UINT,
+ G_TYPE_NONE, 4, PURPLE_TYPE_CONVERSATION,
+ G_TYPE_STRING, G_TYPE_UINT, G_TYPE_BOOLEAN);
+
+ purple_signal_register(handle, "chat-user-flags",
+ purple_marshal_VOID__POINTER_UINT_UINT, G_TYPE_NONE, 3,
+ PURPLE_TYPE_CHAT_USER, G_TYPE_UINT, G_TYPE_UINT);
+
+ purple_signal_register(handle, "chat-user-leaving",
+ purple_marshal_BOOLEAN__POINTER_POINTER_POINTER,
+ G_TYPE_BOOLEAN, 3, PURPLE_TYPE_CONVERSATION,
+ G_TYPE_STRING, G_TYPE_STRING);
+
+ purple_signal_register(handle, "chat-user-left",
+ purple_marshal_VOID__POINTER_POINTER_POINTER,
+ G_TYPE_NONE, 3, PURPLE_TYPE_CONVERSATION,
+ G_TYPE_STRING, G_TYPE_STRING);
+
+ purple_signal_register(handle, "deleting-chat-user",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_CHAT_USER);
+
+ purple_signal_register(handle, "chat-inviting-user",
+ purple_marshal_VOID__POINTER_POINTER_POINTER,
+ G_TYPE_NONE, 3, PURPLE_TYPE_CONVERSATION,
+ G_TYPE_STRING,
+ G_TYPE_POINTER); /* pointer to a string */
+
+ purple_signal_register(handle, "chat-invited-user",
+ purple_marshal_VOID__POINTER_POINTER_POINTER,
+ G_TYPE_NONE, 3, PURPLE_TYPE_CONVERSATION,
+ G_TYPE_STRING, G_TYPE_STRING);
+
+ purple_signal_register(handle, "chat-invited",
+ purple_marshal_INT__POINTER_POINTER_POINTER_POINTER_POINTER,
+ G_TYPE_INT, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
+
+ purple_signal_register(handle, "chat-invite-blocked",
+ purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_POINTER,
+ G_TYPE_NONE, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_POINTER); /* (GHashTable *) */
+
+ purple_signal_register(handle, "chat-joined",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_CONVERSATION);
+
+ purple_signal_register(handle, "chat-join-failed",
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ PURPLE_TYPE_CONNECTION, G_TYPE_POINTER);
+
+ purple_signal_register(handle, "chat-left",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_CONVERSATION);
+
+ purple_signal_register(handle, "chat-topic-changed",
+ purple_marshal_VOID__POINTER_POINTER_POINTER,
+ G_TYPE_NONE, 3, PURPLE_TYPE_CONVERSATION,
+ G_TYPE_STRING, G_TYPE_STRING);
+
+ purple_signal_register(handle, "cleared-message-history",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_CONVERSATION);
+
+ purple_signal_register(handle, "conversation-extended-menu",
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ PURPLE_TYPE_CONVERSATION,
+ G_TYPE_POINTER); /* (GList **) */
+}
+
+void
+purple_conversations_uninit(void)
+{
+ while (conversations)
+ g_object_unref(G_OBJECT(conversations->data));
+
+ g_hash_table_destroy(conversation_cache);
+ purple_signals_unregister_by_instance(purple_conversations_get_handle());
+}
diff --git a/libpurple/conversations.h b/libpurple/conversations.h
new file mode 100644
index 0000000000..395e88bda1
--- /dev/null
+++ b/libpurple/conversations.h
@@ -0,0 +1,167 @@
+/**
+ * @file conversations.h Conversations subsystem API
+ * @ingroup core
+ * @see @ref conversation-signals
+ */
+
+/* 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 _PURPLE_CONVERSATIONS_H_
+#define _PURPLE_CONVERSATIONS_H_
+
+#include "conversationtypes.h"
+#include "server.h"
+
+G_BEGIN_DECLS
+
+/**************************************************************************/
+/** @name Conversations Subsystem */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Adds a conversation to the list of conversations.
+ *
+ * @param conv The conversation.
+ */
+void purple_conversations_add(PurpleConversation *conv);
+
+/**
+ * Removes a conversation from the list of conversations.
+ *
+ * @param conv The conversation.
+ */
+void purple_conversations_remove(PurpleConversation *conv);
+
+/**
+ * Updates the conversation cache to use a new conversation name and/or
+ * account. This function only updates the conversation cache. It is the
+ * caller's responsibility to actually update the conversation.
+ *
+ * @param conv The conversation.
+ * @param name The new name. If no change, use @c NULL.
+ * @param account The new account. If no change, use @c NULL.
+ */
+void purple_conversations_update_cache(PurpleConversation *conv,
+ const char *name, PurpleAccount *account);
+
+/**
+ * Returns a list of all conversations.
+ *
+ * This list includes both IMs and chats.
+ *
+ * @constreturn A GList of all conversations.
+ */
+GList *purple_conversations_get_all(void);
+
+/**
+ * Returns a list of all IMs.
+ *
+ * @constreturn A GList of all IMs.
+ */
+GList *purple_conversations_get_ims(void);
+
+/**
+ * Returns a list of all chats.
+ *
+ * @constreturn A GList of all chats.
+ */
+GList *purple_conversations_get_chats(void);
+
+/**
+ * Finds a conversation of any type with the specified name and Purple account.
+ *
+ * @param name The name of the conversation.
+ * @param account The purple_account associated with the conversation.
+ *
+ * @return The conversation if found, or @c NULL otherwise.
+ */
+PurpleConversation *purple_conversations_find_with_account(const char *name,
+ const PurpleAccount *account);
+
+/**
+ * Finds an IM with the specified name and Purple account.
+ *
+ * @param name The name of the conversation.
+ * @param account The purple_account associated with the conversation.
+ *
+ * @return The conversation if found, or @c NULL otherwise.
+ */
+PurpleIMConversation *purple_conversations_find_im_with_account(const char *name,
+ const PurpleAccount *account);
+
+/**
+ * Finds a chat with the specified name and Purple account.
+ *
+ * @param name The name of the conversation.
+ * @param account The purple_account associated with the conversation.
+ *
+ * @return The conversation if found, or @c NULL otherwise.
+ */
+PurpleChatConversation *purple_conversations_find_chat_with_account(const char *name,
+ const PurpleAccount *account);
+
+/**
+ * Finds a chat with the specified chat ID.
+ *
+ * @param gc The purple_connection.
+ * @param id The chat ID.
+ *
+ * @return The chat conversation.
+ */
+PurpleChatConversation *purple_conversations_find_chat(const PurpleConnection *gc, int id);
+
+/**
+ * Sets the default conversation UI operations structure.
+ *
+ * @param ops The UI conversation operations structure.
+ */
+void purple_conversations_set_ui_ops(PurpleConversationUiOps *ops);
+
+/**
+ * Gets the default conversation UI operations structure.
+ *
+ * @return The UI conversation operations structure.
+ */
+PurpleConversationUiOps *purple_conversations_get_ui_ops(void);
+
+/**
+ * Returns the conversation subsystem handle.
+ *
+ * @return The conversation subsystem handle.
+ */
+void *purple_conversations_get_handle(void);
+
+/**
+ * Initializes the conversation subsystem.
+ */
+void purple_conversations_init(void);
+
+/**
+ * Uninitializes the conversation subsystem.
+ */
+void purple_conversations_uninit(void);
+
+/*@}*/
+
+G_END_DECLS
+
+#endif /* _PURPLE_CONVERSATIONS_H_ */
diff --git a/libpurple/conversationtypes.c b/libpurple/conversationtypes.c
new file mode 100644
index 0000000000..2291b57fe3
--- /dev/null
+++ b/libpurple/conversationtypes.c
@@ -0,0 +1,1999 @@
+/*
+ * 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
+ */
+#include "internal.h"
+#include "conversationtypes.h"
+#include "dbus-maybe.h"
+#include "debug.h"
+#include "enums.h"
+
+#define SEND_TYPED_TIMEOUT_SECONDS 5
+
+#define PURPLE_CHAT_CONVERSATION_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_CHAT_CONVERSATION, PurpleChatConversationPrivate))
+
+/** @copydoc _PurpleChatConversationPrivate */
+typedef struct _PurpleChatConversationPrivate PurpleChatConversationPrivate;
+
+#define PURPLE_IM_CONVERSATION_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_IM_CONVERSATION, PurpleIMConversationPrivate))
+
+/** @copydoc _PurpleIMConversationPrivate */
+typedef struct _PurpleIMConversationPrivate PurpleIMConversationPrivate;
+
+#define PURPLE_CHAT_USER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_CHAT_USER, PurpleChatUserPrivate))
+
+/** @copydoc _PurpleChatUserPrivate */
+typedef struct _PurpleChatUserPrivate PurpleChatUserPrivate;
+
+/**
+ * Data specific to Chats.
+ */
+struct _PurpleChatConversationPrivate
+{
+ GList *in_room; /**< The users in the room.
+ @deprecated Will be removed in 3.0.0 TODO */
+ 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. */
+};
+
+/* Chat Property enums */
+enum {
+ CHAT_PROP_0,
+ CHAT_PROP_TOPIC_WHO,
+ CHAT_PROP_TOPIC,
+ CHAT_PROP_ID,
+ CHAT_PROP_NICK,
+ CHAT_PROP_LEFT,
+ CHAT_PROP_LAST
+};
+
+/**
+ * Data specific to Instant Messages.
+ */
+struct _PurpleIMConversationPrivate
+{
+ PurpleIMTypingState 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. */
+};
+
+/* IM Property enums */
+enum {
+ IM_PROP_0,
+ IM_PROP_TYPING_STATE,
+ IM_PROP_ICON,
+ IM_PROP_LAST
+};
+
+/**
+ * Data for "Chat Buddies"
+ */
+struct _PurpleChatUserPrivate
+{
+ PurpleChatConversation *chat; /**< The chat */
+ 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 user will be
+ sorted, or @c NULL if the user 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. */
+ PurpleChatUserFlags flags; /**< A bitwise OR of flags for this
+ participant, such as whether they
+ are a channel operator. */
+};
+
+/* Chat User Property enums */
+enum {
+ CU_PROP_0,
+ CU_PROP_CHAT,
+ CU_PROP_NAME,
+ CU_PROP_ALIAS,
+ CU_PROP_BUDDY,
+ CU_PROP_FLAGS,
+ CU_PROP_LAST
+};
+
+static PurpleConversationClass *parent_class;
+static GObjectClass *cb_parent_class;
+
+static int purple_chat_user_compare(PurpleChatUser *a,
+ PurpleChatUser *b);
+
+/**************************************************************************
+ * IM Conversation API
+ **************************************************************************/
+static gboolean
+reset_typing_cb(gpointer data)
+{
+ PurpleIMConversation *im = (PurpleIMConversation *)data;
+
+ purple_im_conversation_set_typing_state(im, PURPLE_IM_NOT_TYPING);
+ purple_im_conversation_stop_typing_timeout(im);
+
+ return FALSE;
+}
+
+static gboolean
+send_typed_cb(gpointer data)
+{
+ PurpleIMConversation *im = (PurpleIMConversation *)data;
+ PurpleConnection *gc;
+ const char *name;
+
+ g_return_val_if_fail(im != NULL, FALSE);
+
+ gc = purple_conversation_get_connection(PURPLE_CONVERSATION(im));
+ name = purple_conversation_get_name(PURPLE_CONVERSATION(im));
+
+ if (gc != NULL && name != NULL) {
+ /* We set this to 1 so that PURPLE_IM_TYPING will be sent
+ * if the Purple user types anything else.
+ */
+ purple_im_conversation_set_type_again(im, 1);
+
+ serv_send_typing(gc, name, PURPLE_IM_TYPED);
+
+ purple_debug(PURPLE_DEBUG_MISC, "conversation", "typed...\n");
+ }
+
+ return FALSE;
+}
+
+void
+purple_im_conversation_set_icon(PurpleIMConversation *im, PurpleBuddyIcon *icon)
+{
+ PurpleIMConversationPrivate *priv = PURPLE_IM_CONVERSATION_GET_PRIVATE(im);
+
+ g_return_if_fail(priv != NULL);
+
+ if (priv->icon != icon)
+ {
+ purple_buddy_icon_unref(priv->icon);
+
+ priv->icon = (icon == NULL ? NULL : purple_buddy_icon_ref(icon));
+ }
+
+ purple_conversation_update(PURPLE_CONVERSATION(im),
+ PURPLE_CONVERSATION_UPDATE_ICON);
+}
+
+PurpleBuddyIcon *
+purple_im_conversation_get_icon(const PurpleIMConversation *im)
+{
+ PurpleIMConversationPrivate *priv = PURPLE_IM_CONVERSATION_GET_PRIVATE(im);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->icon;
+}
+
+void
+purple_im_conversation_set_typing_state(PurpleIMConversation *im, PurpleIMTypingState state)
+{
+ PurpleAccount *account;
+ const char *name;
+ PurpleIMConversationPrivate *priv = PURPLE_IM_CONVERSATION_GET_PRIVATE(im);
+
+ g_return_if_fail(priv != NULL);
+
+ name = purple_conversation_get_name(PURPLE_CONVERSATION(im));
+ account = purple_conversation_get_account(PURPLE_CONVERSATION(im));
+
+ if (priv->typing_state != state)
+ {
+ priv->typing_state = state;
+
+ switch (state)
+ {
+ case PURPLE_IM_TYPING:
+ purple_signal_emit(purple_conversations_get_handle(),
+ "buddy-typing", account, name);
+ break;
+ case PURPLE_IM_TYPED:
+ purple_signal_emit(purple_conversations_get_handle(),
+ "buddy-typed", account, name);
+ break;
+ case PURPLE_IM_NOT_TYPING:
+ purple_signal_emit(purple_conversations_get_handle(),
+ "buddy-typing-stopped", account, name);
+ break;
+ }
+
+ purple_im_conversation_update_typing(im);
+ }
+}
+
+PurpleIMTypingState
+purple_im_conversation_get_typing_state(const PurpleIMConversation *im)
+{
+ PurpleIMConversationPrivate *priv = PURPLE_IM_CONVERSATION_GET_PRIVATE(im);
+
+ g_return_val_if_fail(priv != NULL, 0);
+
+ return priv->typing_state;
+}
+
+void
+purple_im_conversation_start_typing_timeout(PurpleIMConversation *im, int timeout)
+{
+ PurpleIMConversationPrivate *priv = PURPLE_IM_CONVERSATION_GET_PRIVATE(im);
+
+ g_return_if_fail(priv != NULL);
+
+ if (priv->typing_timeout > 0)
+ purple_im_conversation_stop_typing_timeout(im);
+
+ priv->typing_timeout = purple_timeout_add_seconds(timeout, reset_typing_cb, im);
+}
+
+void
+purple_im_conversation_stop_typing_timeout(PurpleIMConversation *im)
+{
+ PurpleIMConversationPrivate *priv = PURPLE_IM_CONVERSATION_GET_PRIVATE(im);
+
+ g_return_if_fail(priv != NULL);
+
+ if (priv->typing_timeout == 0)
+ return;
+
+ purple_timeout_remove(priv->typing_timeout);
+ priv->typing_timeout = 0;
+}
+
+guint
+purple_im_conversation_get_typing_timeout(const PurpleIMConversation *im)
+{
+ PurpleIMConversationPrivate *priv = PURPLE_IM_CONVERSATION_GET_PRIVATE(im);
+
+ g_return_val_if_fail(priv != NULL, 0);
+
+ return priv->typing_timeout;
+}
+
+void
+purple_im_conversation_set_type_again(PurpleIMConversation *im, unsigned int val)
+{
+ PurpleIMConversationPrivate *priv = PURPLE_IM_CONVERSATION_GET_PRIVATE(im);
+
+ g_return_if_fail(priv != NULL);
+
+ if (val == 0)
+ priv->type_again = 0;
+ else
+ priv->type_again = time(NULL) + val;
+}
+
+time_t
+purple_im_conversation_get_type_again(const PurpleIMConversation *im)
+{
+ PurpleIMConversationPrivate *priv = PURPLE_IM_CONVERSATION_GET_PRIVATE(im);
+
+ g_return_val_if_fail(priv != NULL, 0);
+
+ return priv->type_again;
+}
+
+void
+purple_im_conversation_start_send_typed_timeout(PurpleIMConversation *im)
+{
+ PurpleIMConversationPrivate *priv = PURPLE_IM_CONVERSATION_GET_PRIVATE(im);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->send_typed_timeout = purple_timeout_add_seconds(SEND_TYPED_TIMEOUT_SECONDS,
+ send_typed_cb, im);
+}
+
+void
+purple_im_conversation_stop_send_typed_timeout(PurpleIMConversation *im)
+{
+ PurpleIMConversationPrivate *priv = PURPLE_IM_CONVERSATION_GET_PRIVATE(im);
+
+ g_return_if_fail(priv != NULL);
+
+ if (priv->send_typed_timeout == 0)
+ return;
+
+ purple_timeout_remove(priv->send_typed_timeout);
+ priv->send_typed_timeout = 0;
+}
+
+guint
+purple_im_conversation_get_send_typed_timeout(const PurpleIMConversation *im)
+{
+ PurpleIMConversationPrivate *priv = PURPLE_IM_CONVERSATION_GET_PRIVATE(im);
+
+ g_return_val_if_fail(priv != NULL, 0);
+
+ return priv->send_typed_timeout;
+}
+
+void
+purple_im_conversation_update_typing(PurpleIMConversation *im)
+{
+ g_return_if_fail(im != NULL);
+
+ purple_conversation_update(PURPLE_CONVERSATION(im),
+ PURPLE_CONVERSATION_UPDATE_TYPING);
+}
+
+static void
+im_conversation_write_message(PurpleConversation *conv, const char *who, const char *message,
+ PurpleMessageFlags flags, time_t mtime)
+{
+ PurpleConversationUiOps *ops;
+
+ g_return_if_fail(conv != NULL);
+ g_return_if_fail(message != NULL);
+
+ ops = purple_conversation_get_ui_ops(conv);
+
+ if ((flags & PURPLE_MESSAGE_RECV) == PURPLE_MESSAGE_RECV) {
+ purple_im_conversation_set_typing_state(PURPLE_IM_CONVERSATION(conv),
+ PURPLE_IM_NOT_TYPING);
+ }
+
+ /* Pass this on to either the ops structure or the default write func. */
+ if (ops != NULL && ops->write_im != NULL)
+ ops->write_im(PURPLE_IM_CONVERSATION(conv), who, message, flags, mtime);
+ else
+ purple_conversation_write(conv, who, message, flags, mtime);
+}
+
+/**************************************************************************
+ * GObject code for IMs
+ **************************************************************************/
+
+/* GObject Property names */
+#define IM_PROP_TYPING_STATE_S "typing-state"
+#define IM_PROP_ICON_S "icon"
+
+/* Set method for GObject properties */
+static void
+purple_im_conversation_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleIMConversation *im = PURPLE_IM_CONVERSATION(obj);
+
+ switch (param_id) {
+ case IM_PROP_TYPING_STATE:
+ purple_im_conversation_set_typing_state(im, g_value_get_enum(value));
+ break;
+ case IM_PROP_ICON:
+ purple_im_conversation_set_icon(im, g_value_get_pointer(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Get method for GObject properties */
+static void
+purple_im_conversation_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleIMConversation *im = PURPLE_IM_CONVERSATION(obj);
+
+ switch (param_id) {
+ case IM_PROP_TYPING_STATE:
+ g_value_set_enum(value, purple_im_conversation_get_typing_state(im));
+ break;
+ case IM_PROP_ICON:
+ g_value_set_pointer(value, purple_im_conversation_get_icon(im));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Called when done constructing */
+static void
+purple_im_conversation_constructed(GObject *object)
+{
+ PurpleIMConversation *im = PURPLE_IM_CONVERSATION(object);
+ PurpleAccount *account;
+ PurpleBuddyIcon *icon;
+ gchar *name;
+
+ G_OBJECT_CLASS(parent_class)->constructed(object);
+
+ g_object_get(object,
+ "account", &account,
+ "name", &name,
+ NULL);
+
+ if ((icon = purple_buddy_icons_find(account, name)))
+ {
+ purple_im_conversation_set_icon(im, icon);
+ /* purple_im_conversation_set_icon refs the icon. */
+ purple_buddy_icon_unref(icon);
+ }
+
+ if (purple_prefs_get_bool("/purple/logging/log_ims"))
+ purple_conversation_set_logging(PURPLE_CONVERSATION(im), TRUE);
+
+ g_free(name);
+}
+
+/* GObject dispose function */
+static void
+purple_im_conversation_dispose(GObject *object)
+{
+ PurpleIMConversation *im = PURPLE_IM_CONVERSATION(object);
+ PurpleConnection *gc = purple_conversation_get_connection(PURPLE_CONVERSATION(im));
+ PurplePluginProtocolInfo *prpl_info = NULL;
+ const char *name = purple_conversation_get_name(PURPLE_CONVERSATION(im));
+
+ if (gc != NULL)
+ {
+ /* Still connected */
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
+
+ if (purple_prefs_get_bool("/purple/conversations/im/send_typing"))
+ serv_send_typing(gc, name, PURPLE_IM_NOT_TYPING);
+
+ if (gc && prpl_info->convo_closed != NULL)
+ prpl_info->convo_closed(gc, name);
+ }
+
+ purple_im_conversation_stop_typing_timeout(im);
+ purple_im_conversation_stop_send_typed_timeout(im);
+
+ G_OBJECT_CLASS(parent_class)->dispose(object);
+}
+
+/* GObject finalize function */
+static void
+purple_im_conversation_finalize(GObject *object)
+{
+ PurpleIMConversation *im = PURPLE_IM_CONVERSATION(object);
+ PurpleIMConversationPrivate *priv = PURPLE_IM_CONVERSATION_GET_PRIVATE(im);
+
+ purple_buddy_icon_unref(priv->icon);
+ priv->icon = NULL;
+
+ G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+/* Class initializer function */
+static void purple_im_conversation_class_init(PurpleIMConversationClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ PurpleConversationClass *conv_class = PURPLE_CONVERSATION_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->dispose = purple_im_conversation_dispose;
+ obj_class->finalize = purple_im_conversation_finalize;
+ obj_class->constructed = purple_im_conversation_constructed;
+
+ /* Setup properties */
+ obj_class->get_property = purple_im_conversation_get_property;
+ obj_class->set_property = purple_im_conversation_set_property;
+
+ conv_class->write_message = im_conversation_write_message;
+
+ g_object_class_install_property(obj_class, IM_PROP_TYPING_STATE,
+ g_param_spec_enum(IM_PROP_TYPING_STATE_S, _("Typing state"),
+ _("Status of the user's typing of a message."),
+ PURPLE_TYPE_IM_TYPING_STATE, PURPLE_IM_NOT_TYPING,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, IM_PROP_ICON,
+ g_param_spec_pointer(IM_PROP_ICON_S, _("Buddy icon"),
+ _("The buddy icon for the IM."),
+ G_PARAM_READWRITE)
+ );
+
+ g_type_class_add_private(klass, sizeof(PurpleIMConversationPrivate));
+}
+
+GType
+purple_im_conversation_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleIMConversationClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_im_conversation_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleIMConversation),
+ 0,
+ NULL,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_CONVERSATION,
+ "PurpleIMConversation",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleIMConversation *
+purple_im_conversation_new(PurpleAccount *account, const char *name)
+{
+ PurpleIMConversation *im;
+ PurpleConnection *gc;
+
+ g_return_val_if_fail(account != NULL, NULL);
+ g_return_val_if_fail(name != NULL, NULL);
+
+ /* Check if this conversation already exists. */
+ if ((im = purple_conversations_find_im_with_account(name, account)) != NULL)
+ return im;
+
+ gc = purple_account_get_connection(account);
+ g_return_val_if_fail(gc != NULL, NULL);
+
+ im = g_object_new(PURPLE_TYPE_IM_CONVERSATION,
+ "account", account,
+ "name", name,
+ "title", name,
+ NULL);
+
+ return im;
+}
+
+/**************************************************************************
+ * Chat Conversation API
+ **************************************************************************/
+static guint
+_purple_conversation_user_hash(gconstpointer data)
+{
+ const gchar *name = data;
+ gchar *collated;
+ guint hash;
+
+ collated = g_utf8_collate_key(name, -1);
+ hash = g_str_hash(collated);
+ g_free(collated);
+ return hash;
+}
+
+static gboolean
+_purple_conversation_user_equal(gconstpointer a, gconstpointer b)
+{
+ return !g_utf8_collate(a, b);
+}
+
+GList *
+purple_chat_conversation_get_users(const PurpleChatConversation *chat)
+{
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->in_room;
+}
+
+void
+purple_chat_conversation_ignore(PurpleChatConversation *chat, const char *name)
+{
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(name != NULL);
+
+ /* Make sure the user isn't already ignored. */
+ if (purple_chat_conversation_is_ignored_user(chat, name))
+ return;
+
+ purple_chat_conversation_set_ignored(chat,
+ g_list_append(priv->ignored, g_strdup(name)));
+}
+
+void
+purple_chat_conversation_unignore(PurpleChatConversation *chat, const char *name)
+{
+ GList *item;
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(name != NULL);
+
+ /* Make sure the user is actually ignored. */
+ if (!purple_chat_conversation_is_ignored_user(chat, name))
+ return;
+
+ item = g_list_find(purple_chat_conversation_get_ignored(chat),
+ purple_chat_conversation_get_ignored_user(chat, name));
+
+ purple_chat_conversation_set_ignored(chat,
+ g_list_remove_link(priv->ignored, item));
+
+ g_free(item->data);
+ g_list_free_1(item);
+}
+
+GList *
+purple_chat_conversation_set_ignored(PurpleChatConversation *chat, GList *ignored)
+{
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ priv->ignored = ignored;
+ return ignored;
+}
+
+GList *
+purple_chat_conversation_get_ignored(const PurpleChatConversation *chat)
+{
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->ignored;
+}
+
+const char *
+purple_chat_conversation_get_ignored_user(const PurpleChatConversation *chat, const char *user)
+{
+ GList *ignored;
+
+ g_return_val_if_fail(chat != NULL, NULL);
+ g_return_val_if_fail(user != NULL, NULL);
+
+ for (ignored = purple_chat_conversation_get_ignored(chat);
+ ignored != NULL;
+ ignored = ignored->next) {
+
+ const char *ign = (const char *)ignored->data;
+
+ if (!purple_utf8_strcasecmp(user, ign) ||
+ ((*ign == '+' || *ign == '%') && !purple_utf8_strcasecmp(user, ign + 1)))
+ return ign;
+
+ if (*ign == '@') {
+ ign++;
+
+ if ((*ign == '+' && !purple_utf8_strcasecmp(user, ign + 1)) ||
+ (*ign != '+' && !purple_utf8_strcasecmp(user, ign)))
+ return ign;
+ }
+ }
+
+ return NULL;
+}
+
+gboolean
+purple_chat_conversation_is_ignored_user(const PurpleChatConversation *chat, const char *user)
+{
+ g_return_val_if_fail(chat != NULL, FALSE);
+ g_return_val_if_fail(user != NULL, FALSE);
+
+ return (purple_chat_conversation_get_ignored_user(chat, user) != NULL);
+}
+
+void
+purple_chat_conversation_set_topic(PurpleChatConversation *chat, const char *who, const char *topic)
+{
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_if_fail(priv != NULL);
+
+ g_free(priv->who);
+ g_free(priv->topic);
+
+ priv->who = g_strdup(who);
+ priv->topic = g_strdup(topic);
+
+ purple_conversation_update(PURPLE_CONVERSATION(chat),
+ PURPLE_CONVERSATION_UPDATE_TOPIC);
+
+ purple_signal_emit(purple_conversations_get_handle(), "chat-topic-changed",
+ chat, priv->who, priv->topic);
+}
+
+const char *
+purple_chat_conversation_get_topic(const PurpleChatConversation *chat)
+{
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->topic;
+}
+
+const char *
+purple_chat_conversation_get_topic_who(const PurpleChatConversation *chat)
+{
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->who;
+}
+
+void
+purple_chat_conversation_set_id(PurpleChatConversation *chat, int id)
+{
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->id = id;
+}
+
+int
+purple_chat_conversation_get_id(const PurpleChatConversation *chat)
+{
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_val_if_fail(priv != NULL, -1);
+
+ return priv->id;
+}
+
+static void
+chat_conversation_write_message(PurpleConversation *conv, const char *who, const char *message,
+ PurpleMessageFlags flags, time_t mtime)
+{
+ PurpleAccount *account;
+ PurpleConversationUiOps *ops;
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(conv);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(who != NULL);
+ g_return_if_fail(message != NULL);
+
+ account = purple_conversation_get_account(conv);
+
+ /* Don't display this if the person who wrote it is ignored. */
+ if (purple_chat_conversation_is_ignored_user(PURPLE_CHAT_CONVERSATION(conv), who))
+ return;
+
+ if (!(flags & PURPLE_MESSAGE_WHISPER)) {
+ const char *str;
+
+ str = purple_normalize(account, who);
+
+ if (purple_strequal(str, priv->nick)) {
+ flags |= PURPLE_MESSAGE_SEND;
+ } else {
+ flags |= PURPLE_MESSAGE_RECV;
+
+ if (purple_utf8_has_word(message, priv->nick))
+ flags |= PURPLE_MESSAGE_NICK;
+ }
+ }
+
+ ops = purple_conversation_get_ui_ops(conv);
+
+ /* Pass this on to either the ops structure or the default write func. */
+ if (ops != NULL && ops->write_chat != NULL)
+ ops->write_chat(PURPLE_CHAT_CONVERSATION(conv), who, message, flags, mtime);
+ else
+ purple_conversation_write(conv, who, message, flags, mtime);
+}
+
+void
+purple_chat_conversation_add_user(PurpleChatConversation *chat, const char *user,
+ const char *extra_msg, PurpleChatUserFlags flags,
+ gboolean new_arrival)
+{
+ GList *users = g_list_append(NULL, (char *)user);
+ GList *extra_msgs = g_list_append(NULL, (char *)extra_msg);
+ GList *flags2 = g_list_append(NULL, GINT_TO_POINTER(flags));
+
+ purple_chat_conversation_add_users(chat, users, extra_msgs, flags2, new_arrival);
+
+ g_list_free(users);
+ g_list_free(extra_msgs);
+ g_list_free(flags2);
+}
+
+void
+purple_chat_conversation_add_users(PurpleChatConversation *chat, GList *users, GList *extra_msgs,
+ GList *flags, gboolean new_arrivals)
+{
+ PurpleConversation *conv;
+ PurpleConversationUiOps *ops;
+ PurpleChatUser *chatuser;
+ PurpleChatConversationPrivate *priv;
+ PurpleAccount *account;
+ PurpleConnection *gc;
+ PurplePluginProtocolInfo *prpl_info;
+ GList *ul, *fl;
+ GList *cbuddies = NULL;
+
+ priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(users != NULL);
+
+ conv = PURPLE_CONVERSATION(chat);
+ ops = purple_conversation_get_ui_ops(conv);
+
+ account = purple_conversation_get_account(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);
+
+ ul = users;
+ fl = flags;
+ while ((ul != NULL) && (fl != NULL)) {
+ const char *user = (const char *)ul->data;
+ const char *alias = user;
+ gboolean quiet;
+ PurpleChatUserFlags flag = GPOINTER_TO_INT(fl->data);
+ const char *extra_msg = (extra_msgs ? extra_msgs->data : NULL);
+
+ if(!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
+ if (purple_strequal(priv->nick, purple_normalize(account, user))) {
+ const char *alias2 = purple_account_get_private_alias(account);
+ if (alias2 != NULL)
+ alias = alias2;
+ else
+ {
+ const char *display_name = purple_connection_get_display_name(gc);
+ if (display_name != NULL)
+ alias = display_name;
+ }
+ } else {
+ PurpleBuddy *buddy;
+ if ((buddy = purple_blist_find_buddy(purple_connection_get_account(gc), user)) != NULL)
+ alias = purple_buddy_get_contact_alias(buddy);
+ }
+ }
+
+ quiet = GPOINTER_TO_INT(purple_signal_emit_return_1(purple_conversations_get_handle(),
+ "chat-user-joining", chat, user, flag)) ||
+ purple_chat_conversation_is_ignored_user(chat, user);
+
+ chatuser = purple_chat_user_new(chat, user, alias, flag);
+ purple_chat_user_set_buddy(chatuser, purple_blist_find_buddy(account, user) != NULL);
+
+ priv->in_room = g_list_prepend(priv->in_room, chatuser);
+ g_hash_table_replace(priv->users,
+ g_strdup(purple_chat_user_get_name(chatuser)), chatuser);
+
+ cbuddies = g_list_prepend(cbuddies, chatuser);
+
+ if (!quiet && new_arrivals) {
+ char *alias_esc = g_markup_escape_text(alias, -1);
+ char *tmp;
+
+ if (extra_msg == NULL)
+ tmp = g_strdup_printf(_("%s entered the room."), alias_esc);
+ else {
+ char *extra_msg_esc = g_markup_escape_text(extra_msg, -1);
+ tmp = g_strdup_printf(_("%s [<I>%s</I>] entered the room."),
+ alias_esc, extra_msg_esc);
+ g_free(extra_msg_esc);
+ }
+ g_free(alias_esc);
+
+ purple_conversation_write(conv, NULL, tmp,
+ PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LINKIFY,
+ time(NULL));
+ g_free(tmp);
+ }
+
+ purple_signal_emit(purple_conversations_get_handle(),
+ "chat-user-joined", chat, user, flag, new_arrivals);
+ ul = ul->next;
+ fl = fl->next;
+ if (extra_msgs != NULL)
+ extra_msgs = extra_msgs->next;
+ }
+
+ cbuddies = g_list_sort(cbuddies, (GCompareFunc)purple_chat_user_compare);
+
+ if (ops != NULL && ops->chat_add_users != NULL)
+ ops->chat_add_users(chat, cbuddies, new_arrivals);
+
+ g_list_free(cbuddies);
+}
+
+void
+purple_chat_conversation_rename_user(PurpleChatConversation *chat, const char *old_user,
+ const char *new_user)
+{
+ PurpleConversation *conv;
+ PurpleConversationUiOps *ops;
+ PurpleAccount *account;
+ PurpleConnection *gc;
+ PurplePluginProtocolInfo *prpl_info;
+ PurpleChatUser *cb;
+ PurpleChatUserFlags flags;
+ PurpleChatConversationPrivate *priv;
+ const char *new_alias = new_user;
+ char tmp[BUF_LONG];
+ gboolean is_me = FALSE;
+
+ priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(old_user != NULL);
+ g_return_if_fail(new_user != NULL);
+
+ conv = PURPLE_CONVERSATION(chat);
+ ops = purple_conversation_get_ui_ops(conv);
+ account = purple_conversation_get_account(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);
+
+ if (purple_strequal(priv->nick, purple_normalize(account, old_user))) {
+ const char *alias;
+
+ /* Note this for later. */
+ is_me = TRUE;
+
+ if(!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
+ alias = purple_account_get_private_alias(account);
+ if (alias != NULL)
+ new_alias = alias;
+ else
+ {
+ const char *display_name = purple_connection_get_display_name(gc);
+ if (display_name != NULL)
+ new_alias = display_name;
+ }
+ }
+ } else if (!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
+ PurpleBuddy *buddy;
+ if ((buddy = purple_blist_find_buddy(purple_connection_get_account(gc), new_user)) != NULL)
+ new_alias = purple_buddy_get_contact_alias(buddy);
+ }
+
+ flags = purple_chat_user_get_flags(purple_chat_conversation_find_user(chat, old_user));
+ cb = purple_chat_user_new(chat, new_user, new_alias, flags);
+ purple_chat_user_set_buddy(cb, purple_blist_find_buddy(account, new_user) != NULL);
+
+ priv->in_room = g_list_prepend(priv->in_room, cb);
+ g_hash_table_replace(priv->users,
+ g_strdup(purple_chat_user_get_name(cb)), cb);
+
+ if (ops != NULL && ops->chat_rename_user != NULL)
+ ops->chat_rename_user(chat, old_user, new_user, new_alias);
+
+ cb = purple_chat_conversation_find_user(chat, old_user);
+
+ if (cb) {
+ priv->in_room = g_list_remove(priv->in_room, cb);
+ g_hash_table_remove(priv->users, purple_chat_user_get_name(cb));
+ g_object_unref(cb);
+ }
+
+ if (purple_chat_conversation_is_ignored_user(chat, old_user)) {
+ purple_chat_conversation_unignore(chat, old_user);
+ purple_chat_conversation_ignore(chat, new_user);
+ }
+ else if (purple_chat_conversation_is_ignored_user(chat, new_user))
+ purple_chat_conversation_unignore(chat, new_user);
+
+ if (is_me)
+ purple_chat_conversation_set_nick(chat, new_user);
+
+ if (purple_prefs_get_bool("/purple/conversations/chat/show_nick_change") &&
+ !purple_chat_conversation_is_ignored_user(chat, new_user)) {
+
+ if (is_me) {
+ char *escaped = g_markup_escape_text(new_user, -1);
+ g_snprintf(tmp, sizeof(tmp),
+ _("You are now known as %s"), escaped);
+ g_free(escaped);
+ } else {
+ const char *old_alias = old_user;
+ const char *new_alias = new_user;
+ char *escaped;
+ char *escaped2;
+
+ if (!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
+ PurpleBuddy *buddy;
+
+ if ((buddy = purple_blist_find_buddy(purple_connection_get_account(gc), old_user)) != NULL)
+ old_alias = purple_buddy_get_contact_alias(buddy);
+ if ((buddy = purple_blist_find_buddy(purple_connection_get_account(gc), new_user)) != NULL)
+ new_alias = purple_buddy_get_contact_alias(buddy);
+ }
+
+ escaped = g_markup_escape_text(old_alias, -1);
+ escaped2 = g_markup_escape_text(new_alias, -1);
+ g_snprintf(tmp, sizeof(tmp),
+ _("%s is now known as %s"), escaped, escaped2);
+ g_free(escaped);
+ g_free(escaped2);
+ }
+
+ purple_conversation_write(conv, NULL, tmp,
+ PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LINKIFY,
+ time(NULL));
+ }
+}
+
+void
+purple_chat_conversation_remove_user(PurpleChatConversation *chat, const char *user, const char *reason)
+{
+ GList *users = g_list_append(NULL, (char *)user);
+
+ purple_chat_conversation_remove_users(chat, users, reason);
+
+ g_list_free(users);
+}
+
+void
+purple_chat_conversation_remove_users(PurpleChatConversation *chat, GList *users, const char *reason)
+{
+ PurpleConversation *conv;
+ PurpleConnection *gc;
+ PurplePluginProtocolInfo *prpl_info;
+ PurpleConversationUiOps *ops;
+ PurpleChatUser *cb;
+ PurpleChatConversationPrivate *priv;
+ GList *l;
+ gboolean quiet;
+
+ priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(users != NULL);
+
+ conv = PURPLE_CONVERSATION(chat);
+
+ 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);
+
+ ops = purple_conversation_get_ui_ops(conv);
+
+ for (l = users; l != NULL; l = l->next) {
+ const char *user = (const char *)l->data;
+ quiet = GPOINTER_TO_INT(purple_signal_emit_return_1(purple_conversations_get_handle(),
+ "chat-user-leaving", chat, user, reason)) |
+ purple_chat_conversation_is_ignored_user(chat, user);
+
+ cb = purple_chat_conversation_find_user(chat, user);
+
+ if (cb) {
+ priv->in_room = g_list_remove(priv->in_room, cb);
+ g_hash_table_remove(priv->users, purple_chat_user_get_name(cb));
+ g_object_unref(cb);
+ }
+
+ /* NOTE: Don't remove them from ignored in case they re-enter. */
+
+ if (!quiet) {
+ const char *alias = user;
+ char *alias_esc;
+ char *tmp;
+
+ if (!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
+ PurpleBuddy *buddy;
+
+ if ((buddy = purple_blist_find_buddy(purple_connection_get_account(gc), user)) != NULL)
+ alias = purple_buddy_get_contact_alias(buddy);
+ }
+
+ alias_esc = g_markup_escape_text(alias, -1);
+
+ if (reason == NULL || !*reason)
+ tmp = g_strdup_printf(_("%s left the room."), alias_esc);
+ else {
+ char *reason_esc = g_markup_escape_text(reason, -1);
+ tmp = g_strdup_printf(_("%s left the room (%s)."),
+ alias_esc, reason_esc);
+ g_free(reason_esc);
+ }
+ g_free(alias_esc);
+
+ purple_conversation_write(conv, NULL, tmp,
+ PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LINKIFY,
+ time(NULL));
+ g_free(tmp);
+ }
+
+ purple_signal_emit(purple_conversations_get_handle(), "chat-user-left",
+ conv, user, reason);
+ }
+
+ if (ops != NULL && ops->chat_remove_users != NULL)
+ ops->chat_remove_users(chat, users);
+}
+
+void
+purple_chat_conversation_clear_users(PurpleChatConversation *chat)
+{
+ PurpleConversationUiOps *ops;
+ GList *users;
+ GList *l;
+ GList *names = NULL;
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_if_fail(priv != NULL);
+
+ ops = purple_conversation_get_ui_ops(PURPLE_CONVERSATION(chat));
+ users = priv->in_room;
+
+ if (ops != NULL && ops->chat_remove_users != NULL) {
+ for (l = users; l; l = l->next) {
+ PurpleChatUser *cb = l->data;
+ names = g_list_prepend(names,
+ (gchar *) purple_chat_user_get_name(cb));
+ }
+ ops->chat_remove_users(chat, names);
+ g_list_free(names);
+ }
+
+ for (l = users; l; l = l->next)
+ {
+ PurpleChatUser *cb = l->data;
+ const char *name = purple_chat_user_get_name(cb);
+
+ purple_signal_emit(purple_conversations_get_handle(),
+ "chat-user-leaving", chat, name, NULL);
+ purple_signal_emit(purple_conversations_get_handle(),
+ "chat-user-left", chat, name, NULL);
+
+ g_object_unref(cb);
+ }
+
+ g_hash_table_remove_all(priv->users);
+
+ g_list_free(users);
+ priv->in_room = NULL;
+}
+
+void purple_chat_conversation_set_nick(PurpleChatConversation *chat, const char *nick) {
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_if_fail(priv != NULL);
+
+ g_free(priv->nick);
+ priv->nick = g_strdup(purple_normalize(
+ purple_conversation_get_account(PURPLE_CONVERSATION(chat)), nick));
+}
+
+const char *purple_chat_conversation_get_nick(PurpleChatConversation *chat) {
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->nick;
+}
+
+static void
+invite_user_to_chat(gpointer data, PurpleRequestFields *fields)
+{
+ PurpleConversation *conv;
+ PurpleChatConversationPrivate *priv;
+ const char *user, *message;
+
+ conv = data;
+ priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(conv);
+ user = purple_request_fields_get_string(fields, "screenname");
+ message = purple_request_fields_get_string(fields, "message");
+
+ serv_chat_invite(purple_conversation_get_connection(conv), priv->id, message, user);
+}
+
+void purple_chat_conversation_invite_user(PurpleChatConversation *chat, const char *user,
+ const char *message, gboolean confirm)
+{
+ PurpleAccount *account;
+ PurpleRequestFields *fields;
+ PurpleRequestFieldGroup *group;
+ PurpleRequestField *field;
+
+ g_return_if_fail(chat != NULL);
+
+ if (!user || !*user || !message || !*message)
+ confirm = TRUE;
+
+ account = purple_conversation_get_account(PURPLE_CONVERSATION(chat));
+
+ if (!confirm) {
+ serv_chat_invite(purple_account_get_connection(account),
+ purple_chat_conversation_get_id(chat), message, user);
+ return;
+ }
+
+ fields = purple_request_fields_new();
+ group = purple_request_field_group_new(_("Invite to chat"));
+ purple_request_fields_add_group(fields, group);
+
+ field = purple_request_field_string_new("screenname", _("Buddy"), user, FALSE);
+ purple_request_field_group_add_field(group, field);
+ purple_request_field_set_required(field, TRUE);
+ purple_request_field_set_type_hint(field, "screenname");
+
+ field = purple_request_field_string_new("message", _("Message"), message, FALSE);
+ purple_request_field_group_add_field(group, field);
+
+ purple_request_fields(chat, _("Invite to chat"), NULL,
+ _("Please enter the name of the user you wish to invite, "
+ "along with an optional invite message."),
+ fields,
+ _("Invite"), G_CALLBACK(invite_user_to_chat),
+ _("Cancel"), NULL,
+ account, user, PURPLE_CONVERSATION(chat),
+ chat);
+}
+
+gboolean
+purple_chat_conversation_has_user(PurpleChatConversation *chat, const char *user)
+{
+ g_return_val_if_fail(chat != NULL, FALSE);
+ g_return_val_if_fail(user != NULL, FALSE);
+
+ return (purple_chat_conversation_find_user(chat, user) != NULL);
+}
+
+void
+purple_chat_conversation_leave(PurpleChatConversation *chat)
+{
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->left = TRUE;
+ purple_conversation_update(PURPLE_CONVERSATION(chat), PURPLE_CONVERSATION_UPDATE_CHATLEFT);
+}
+
+gboolean
+purple_chat_conversation_has_left(PurpleChatConversation *chat)
+{
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_val_if_fail(priv != NULL, TRUE);
+
+ return priv->left;
+}
+
+static void
+chat_conversation_cleanup_for_rejoin(PurpleChatConversation *chat)
+{
+ const char *disp;
+ PurpleAccount *account;
+ PurpleConnection *gc;
+ PurpleConversation *conv = PURPLE_CONVERSATION(chat);
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ account = purple_conversation_get_account(conv);
+
+ purple_conversation_close_logs(conv);
+ purple_conversation_set_logging(conv, TRUE);
+
+ gc = purple_account_get_connection(account);
+
+ if ((disp = purple_connection_get_display_name(gc)) != NULL)
+ purple_chat_conversation_set_nick(chat, disp);
+ else
+ {
+ purple_chat_conversation_set_nick(chat,
+ purple_account_get_username(account));
+ }
+
+ purple_chat_conversation_clear_users(chat);
+ purple_chat_conversation_set_topic(chat, NULL, NULL);
+ priv->left = FALSE;
+
+ purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_CHATLEFT);
+}
+
+PurpleChatUser *
+purple_chat_conversation_find_user(PurpleChatConversation *chat, const char *name)
+{
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+ g_return_val_if_fail(name != NULL, NULL);
+
+ return g_hash_table_lookup(priv->users, name);
+}
+
+/**************************************************************************
+ * GObject code for chats
+ **************************************************************************/
+
+/* GObject Property names */
+#define CHAT_PROP_TOPIC_WHO_S "topic-who"
+#define CHAT_PROP_TOPIC_S "topic"
+#define CHAT_PROP_ID_S "chat-id"
+#define CHAT_PROP_NICK_S "nick"
+#define CHAT_PROP_LEFT_S "left"
+
+/* Set method for GObject properties */
+static void
+purple_chat_conversation_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleChatConversation *chat = PURPLE_CHAT_CONVERSATION(obj);
+
+ switch (param_id) {
+ case CHAT_PROP_ID:
+ purple_chat_conversation_set_id(chat, g_value_get_int(value));
+ break;
+ case CHAT_PROP_NICK:
+ purple_chat_conversation_set_nick(chat, g_value_get_string(value));
+ break;
+ case CHAT_PROP_LEFT:
+ {
+ gboolean left = g_value_get_boolean(value);
+ if (left == TRUE)
+ purple_chat_conversation_leave(chat);
+ }
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Get method for GObject properties */
+static void
+purple_chat_conversation_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleChatConversation *chat = PURPLE_CHAT_CONVERSATION(obj);
+
+ switch (param_id) {
+ case CHAT_PROP_TOPIC_WHO:
+ g_value_set_string(value, purple_chat_conversation_get_topic_who(chat));
+ break;
+ case CHAT_PROP_TOPIC:
+ g_value_set_string(value, purple_chat_conversation_get_topic(chat));
+ break;
+ case CHAT_PROP_ID:
+ g_value_set_int(value, purple_chat_conversation_get_id(chat));
+ break;
+ case CHAT_PROP_NICK:
+ g_value_set_string(value, purple_chat_conversation_get_nick(chat));
+ break;
+ case CHAT_PROP_LEFT:
+ g_value_set_boolean(value, purple_chat_conversation_has_left(chat));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* GObject initialization function */
+static void purple_chat_conversation_init(GTypeInstance *instance, gpointer klass)
+{
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(instance);
+
+ priv->users = g_hash_table_new_full(_purple_conversation_user_hash,
+ _purple_conversation_user_equal, g_free, NULL);
+}
+
+/* Called when done constructing */
+static void
+purple_chat_conversation_constructed(GObject *object)
+{
+ PurpleChatConversation *chat = PURPLE_CHAT_CONVERSATION(object);
+ PurpleAccount *account;
+ const char *disp;
+
+ G_OBJECT_CLASS(parent_class)->constructed(object);
+
+ g_object_get(object, "account", &account, NULL);
+
+ if ((disp = purple_connection_get_display_name(purple_account_get_connection(account))))
+ purple_chat_conversation_set_nick(chat, disp);
+ else
+ purple_chat_conversation_set_nick(chat,
+ purple_account_get_username(account));
+
+ if (purple_prefs_get_bool("/purple/logging/log_chats"))
+ purple_conversation_set_logging(PURPLE_CONVERSATION(chat), TRUE);
+}
+
+/* GObject dispose function */
+static void
+purple_chat_conversation_dispose(GObject *object)
+{
+ PurpleChatConversation *chat = PURPLE_CHAT_CONVERSATION(object);
+ PurpleConnection *gc = purple_conversation_get_connection(PURPLE_CONVERSATION(chat));
+
+ if (gc != NULL)
+ {
+ /* Still connected */
+ int chat_id = purple_chat_conversation_get_id(chat);
+#if 0
+ /*
+ * This is unfortunately necessary, because calling
+ * serv_chat_leave() calls this purple_conversation_destroy(),
+ * which leads to two calls here.. We can't just return after
+ * this, because then it'll return on the next pass. So, since
+ * serv_got_chat_left(), which is eventually called from the
+ * prpl that serv_chat_leave() calls, removes this conversation
+ * from the gc's buddy_chats list, we're going to check to see
+ * if this exists in the list. If so, we want to return after
+ * calling this, because it'll be called again. If not, fall
+ * through, because it'll have already been removed, and we'd
+ * be on the 2nd pass.
+ *
+ * Long paragraph. <-- Short sentence.
+ *
+ * -- ChipX86
+ */
+
+ if (gc && g_slist_find(gc->buddy_chats, conv) != NULL) {
+ serv_chat_leave(gc, chat_id);
+
+ return;
+ }
+#endif
+ /*
+ * Instead of all of that, lets just close the window when
+ * the user tells us to, and let the prpl deal with the
+ * internals on it's own time. Don't do this if the prpl already
+ * knows it left the chat.
+ */
+ if (!purple_chat_conversation_has_left(chat))
+ serv_chat_leave(gc, chat_id);
+
+ /*
+ * If they didn't call serv_got_chat_left by now, it's too late.
+ * So we better do it for them before we destroy the thing.
+ */
+ if (!purple_chat_conversation_has_left(chat))
+ serv_got_chat_left(gc, chat_id);
+ }
+
+ G_OBJECT_CLASS(parent_class)->dispose(object);
+}
+
+/* GObject finalize function */
+static void
+purple_chat_conversation_finalize(GObject *object)
+{
+ PurpleChatConversation *chat = PURPLE_CHAT_CONVERSATION(object);
+ PurpleChatConversationPrivate *priv = PURPLE_CHAT_CONVERSATION_GET_PRIVATE(chat);
+
+ g_hash_table_destroy(priv->users);
+ priv->users = NULL;
+
+ g_list_foreach(priv->in_room, (GFunc)g_object_unref, NULL);
+ g_list_free(priv->in_room);
+ priv->in_room = NULL;
+
+ g_list_foreach(priv->ignored, (GFunc)g_free, NULL);
+ g_list_free(priv->ignored);
+ priv->ignored = NULL;
+
+ g_free(priv->who);
+ g_free(priv->topic);
+ g_free(priv->nick);
+
+ priv->who = NULL;
+ priv->topic = NULL;
+ priv->nick = NULL;
+
+ G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+/* Class initializer function */
+static void purple_chat_conversation_class_init(PurpleChatConversationClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ PurpleConversationClass *conv_class = PURPLE_CONVERSATION_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->dispose = purple_chat_conversation_dispose;
+ obj_class->finalize = purple_chat_conversation_finalize;
+ obj_class->constructed = purple_chat_conversation_constructed;
+
+ /* Setup properties */
+ obj_class->get_property = purple_chat_conversation_get_property;
+ obj_class->set_property = purple_chat_conversation_set_property;
+
+ conv_class->write_message = chat_conversation_write_message;
+
+ g_object_class_install_property(obj_class, CHAT_PROP_TOPIC_WHO,
+ g_param_spec_string(CHAT_PROP_TOPIC_WHO_S, _("Who set topic"),
+ _("Who set the chat topic."), NULL,
+ G_PARAM_READABLE)
+ );
+
+ g_object_class_install_property(obj_class, CHAT_PROP_TOPIC,
+ g_param_spec_string(CHAT_PROP_TOPIC_S, _("Topic"),
+ _("Topic of the chat."), NULL,
+ G_PARAM_READABLE)
+ );
+
+ g_object_class_install_property(obj_class, CHAT_PROP_ID,
+ g_param_spec_int(CHAT_PROP_ID_S, _("Chat ID"),
+ _("The ID of the chat."), G_MININT, G_MAXINT, 0,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, CHAT_PROP_NICK,
+ g_param_spec_string(CHAT_PROP_NICK_S, _("Nickname"),
+ _("The nickname of the user in a chat."), NULL,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, CHAT_PROP_LEFT,
+ g_param_spec_boolean(CHAT_PROP_LEFT_S, _("Left the chat"),
+ _("Whether the user has left the chat."), FALSE,
+ G_PARAM_READWRITE)
+ );
+
+ g_type_class_add_private(klass, sizeof(PurpleChatConversationPrivate));
+}
+
+GType
+purple_chat_conversation_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleChatConversationClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_chat_conversation_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleChatConversation),
+ 0,
+ (GInstanceInitFunc)purple_chat_conversation_init,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_CONVERSATION,
+ "PurpleChatConversation",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleChatConversation *
+purple_chat_conversation_new(PurpleAccount *account, const char *name)
+{
+ PurpleChatConversation *chat;
+ PurpleConnection *gc;
+
+ g_return_val_if_fail(account != NULL, NULL);
+ g_return_val_if_fail(name != NULL, NULL);
+
+ /* Check if this conversation already exists. */
+ if ((chat = purple_conversations_find_chat_with_account(name, account)) != NULL)
+ {
+ if (!purple_chat_conversation_has_left(chat)) {
+ purple_debug_warning("conversation", "Trying to create multiple "
+ "chats (%s) with the same name is deprecated and will be "
+ "removed in libpurple 3.0.0", name);
+ } else {
+ /*
+ * This hack is necessary because some prpls (MSN) have unnamed chats
+ * that all use the same name. A PurpleConversation for one of those
+ * is only ever re-used if the user has left, so calls to
+ * purple_conversation_new need to fall-through to creating a new
+ * chat.
+ * TODO 3.0.0: Remove this workaround and mandate unique names.
+ */
+
+ chat_conversation_cleanup_for_rejoin(chat);
+ return chat;
+ }
+ }
+
+ gc = purple_account_get_connection(account);
+ g_return_val_if_fail(gc != NULL, NULL);
+
+ chat = g_object_new(PURPLE_TYPE_CHAT_CONVERSATION,
+ "account", account,
+ "name", name,
+ "title", name,
+ NULL);
+
+ return chat;
+}
+
+/**************************************************************************
+ * Chat Conversation User API
+ **************************************************************************/
+static int
+purple_chat_user_compare(PurpleChatUser *a, PurpleChatUser *b)
+{
+ PurpleChatUserFlags f1 = 0, f2 = 0;
+ PurpleChatUserPrivate *priva, *privb;
+ char *user1 = NULL, *user2 = NULL;
+ gint ret = 0;
+
+ priva = PURPLE_CHAT_USER_GET_PRIVATE(a);
+ privb = PURPLE_CHAT_USER_GET_PRIVATE(b);
+
+ if (priva) {
+ f1 = priva->flags;
+ if (priva->alias_key)
+ user1 = priva->alias_key;
+ else if (priva->name)
+ user1 = priva->name;
+ }
+
+ if (privb) {
+ f2 = privb->flags;
+ if (privb->alias_key)
+ user2 = privb->alias_key;
+ else if (privb->name)
+ user2 = privb->name;
+ }
+
+ if (user1 == NULL || user2 == NULL) {
+ if (!(user1 == NULL && user2 == NULL))
+ ret = (user1 == NULL) ? -1: 1;
+ } else if (f1 != f2) {
+ /* sort more important users first */
+ ret = (f1 > f2) ? -1 : 1;
+ } else if (priva->buddy != privb->buddy) {
+ ret = priva->buddy ? -1 : 1;
+ } else {
+ ret = purple_utf8_strcasecmp(user1, user2);
+ }
+
+ return ret;
+}
+
+const char *
+purple_chat_user_get_alias(const PurpleChatUser *cb)
+{
+ PurpleChatUserPrivate *priv;
+ priv = PURPLE_CHAT_USER_GET_PRIVATE(cb);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->alias;
+}
+
+const char *
+purple_chat_user_get_name(const PurpleChatUser *cb)
+{
+ PurpleChatUserPrivate *priv;
+ priv = PURPLE_CHAT_USER_GET_PRIVATE(cb);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->name;
+}
+
+void
+purple_chat_user_set_flags(PurpleChatUser *cb,
+ PurpleChatUserFlags flags)
+{
+ PurpleConversationUiOps *ops;
+ PurpleChatUserFlags oldflags;
+ PurpleChatUserPrivate *priv;
+ priv = PURPLE_CHAT_USER_GET_PRIVATE(cb);
+
+ g_return_if_fail(priv != NULL);
+
+ if (flags == priv->flags)
+ return;
+
+ oldflags = priv->flags;
+ priv->flags = flags;
+
+ ops = purple_conversation_get_ui_ops(PURPLE_CONVERSATION(priv->chat));
+
+ if (ops != NULL && ops->chat_update_user != NULL)
+ ops->chat_update_user(cb);
+
+ purple_signal_emit(purple_conversations_get_handle(),
+ "chat-user-flags", cb, oldflags, flags);
+}
+
+PurpleChatUserFlags
+purple_chat_user_get_flags(const PurpleChatUser *cb)
+{
+ PurpleChatUserPrivate *priv;
+ priv = PURPLE_CHAT_USER_GET_PRIVATE(cb);
+
+ g_return_val_if_fail(priv != NULL, PURPLE_CHAT_USER_NONE);
+
+ return priv->flags;
+}
+
+void
+purple_chat_user_set_ui_data(PurpleChatUser *cb, gpointer ui_data)
+{
+ g_return_if_fail(cb != NULL);
+
+ cb->ui_data = ui_data;
+}
+
+gpointer
+purple_chat_user_get_ui_data(const PurpleChatUser *cb)
+{
+ g_return_val_if_fail(cb != NULL, NULL);
+
+ return cb->ui_data;
+}
+
+void
+purple_chat_user_set_chat(PurpleChatUser *cb,
+ PurpleChatConversation *chat)
+{
+ PurpleChatUserPrivate *priv;
+ priv = PURPLE_CHAT_USER_GET_PRIVATE(cb);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->chat = chat;
+}
+
+PurpleChatConversation *
+purple_chat_user_get_chat(const PurpleChatUser *cb)
+{
+ PurpleChatUserPrivate *priv;
+ priv = PURPLE_CHAT_USER_GET_PRIVATE(cb);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->chat;
+}
+
+void
+purple_chat_user_set_buddy(const PurpleChatUser *cb,
+ gboolean buddy)
+{
+ PurpleChatUserPrivate *priv;
+ priv = PURPLE_CHAT_USER_GET_PRIVATE(cb);
+
+ g_return_if_fail(priv != NULL);
+
+ priv->buddy = buddy;
+}
+
+gboolean
+purple_chat_user_is_buddy(const PurpleChatUser *cb)
+{
+ PurpleChatUserPrivate *priv;
+ priv = PURPLE_CHAT_USER_GET_PRIVATE(cb);
+
+ g_return_val_if_fail(priv != NULL, FALSE);
+
+ return priv->buddy;
+}
+
+/**************************************************************************
+ * GObject code for chat user
+ **************************************************************************/
+
+/* GObject Property names */
+#define CU_PROP_CHAT_S "chat"
+#define CU_PROP_NAME_S "name"
+#define CU_PROP_ALIAS_S "alias"
+#define CU_PROP_BUDDY_S "buddy"
+#define CU_PROP_FLAGS_S "flags"
+
+/* Set method for GObject properties */
+static void
+purple_chat_user_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleChatUser *cb = PURPLE_CHAT_USER(obj);
+ PurpleChatUserPrivate *priv = PURPLE_CHAT_USER_GET_PRIVATE(cb);
+
+ switch (param_id) {
+ case CU_PROP_CHAT:
+ priv->chat = g_value_get_object(value);
+ break;
+ case CU_PROP_NAME:
+ g_free(priv->name);
+ priv->name = g_strdup(g_value_get_string(value));
+ break;
+ case CU_PROP_ALIAS:
+ g_free(priv->alias);
+ priv->alias = g_strdup(g_value_get_string(value));
+ break;
+ case CU_PROP_BUDDY:
+ priv->buddy = g_value_get_boolean(value);
+ break;
+ case CU_PROP_FLAGS:
+ priv->flags = g_value_get_flags(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Get method for GObject properties */
+static void
+purple_chat_user_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleChatUser *cb = PURPLE_CHAT_USER(obj);
+
+ switch (param_id) {
+ case CU_PROP_CHAT:
+ g_value_set_object(value, purple_chat_user_get_chat(cb));
+ break;
+ case CU_PROP_NAME:
+ g_value_set_string(value, purple_chat_user_get_name(cb));
+ break;
+ case CU_PROP_ALIAS:
+ g_value_set_string(value, purple_chat_user_get_alias(cb));
+ break;
+ case CU_PROP_BUDDY:
+ g_value_set_boolean(value, purple_chat_user_is_buddy(cb));
+ break;
+ case CU_PROP_FLAGS:
+ g_value_set_flags(value, purple_chat_user_get_flags(cb));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* GObject initialization function */
+static void
+purple_chat_user_init(GTypeInstance *instance, gpointer klass)
+{
+ PURPLE_DBUS_REGISTER_POINTER(PURPLE_CHAT_USER(instance), PurpleChatUser);
+}
+
+/* GObject dispose function */
+static void
+purple_chat_user_dispose(GObject *object)
+{
+ PurpleChatUser *cb = PURPLE_CHAT_USER(object);
+
+ purple_signal_emit(purple_conversations_get_handle(),
+ "deleting-chat-user", cb);
+ PURPLE_DBUS_UNREGISTER_POINTER(cb);
+
+ cb_parent_class->dispose(object);
+}
+
+/* GObject finalize function */
+static void
+purple_chat_user_finalize(GObject *object)
+{
+ PurpleChatUserPrivate *priv;
+ priv = PURPLE_CHAT_USER_GET_PRIVATE(object);
+
+ g_free(priv->alias);
+ g_free(priv->alias_key);
+ g_free(priv->name);
+
+ cb_parent_class->finalize(object);
+}
+
+/* Class initializer function */
+static void purple_chat_user_class_init(PurpleChatUserClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ cb_parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->dispose = purple_chat_user_dispose;
+ obj_class->finalize = purple_chat_user_finalize;
+
+ /* Setup properties */
+ obj_class->get_property = purple_chat_user_get_property;
+ obj_class->set_property = purple_chat_user_set_property;
+
+ g_object_class_install_property(obj_class, CU_PROP_CHAT,
+ g_param_spec_object(CU_PROP_CHAT_S, _("Chat"),
+ _("The chat the buddy belongs to."), PURPLE_TYPE_CHAT_CONVERSATION,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
+ );
+
+ g_object_class_install_property(obj_class, CU_PROP_NAME,
+ g_param_spec_string(CU_PROP_NAME_S, _("Name"),
+ _("Name of the chat user."), NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
+ );
+
+ g_object_class_install_property(obj_class, CU_PROP_ALIAS,
+ g_param_spec_string(CU_PROP_ALIAS_S, _("Alias"),
+ _("Alias of the chat user."), NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
+ );
+
+ g_object_class_install_property(obj_class, CU_PROP_BUDDY,
+ g_param_spec_boolean(CU_PROP_BUDDY_S, _("Is buddy"),
+ _("Whether the chat user is in the buddy list."), FALSE,
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, CU_PROP_FLAGS,
+ g_param_spec_flags(CU_PROP_FLAGS_S, _("Buddy flags"),
+ _("The flags for the chat user."),
+ PURPLE_TYPE_CHAT_USER_FLAGS, PURPLE_CHAT_USER_NONE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
+ );
+
+ g_type_class_add_private(klass, sizeof(PurpleChatUserPrivate));
+}
+
+GType
+purple_chat_user_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleChatUserClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_chat_user_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleChatUser),
+ 0,
+ (GInstanceInitFunc)purple_chat_user_init,
+ NULL,
+ };
+
+ type = g_type_register_static(G_TYPE_OBJECT,
+ "PurpleChatUser",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleChatUser *
+purple_chat_user_new(PurpleChatConversation *chat, const char *name,
+ const char *alias, PurpleChatUserFlags flags)
+{
+ PurpleChatUser *cb;
+
+ g_return_val_if_fail(chat != NULL, NULL);
+ g_return_val_if_fail(name != NULL, NULL);
+
+ cb = g_object_new(PURPLE_TYPE_CHAT_USER,
+ CU_PROP_CHAT_S, chat,
+ CU_PROP_NAME_S, name,
+ CU_PROP_ALIAS_S, alias,
+ CU_PROP_FLAGS_S, flags,
+ NULL);
+
+ return cb;
+}
diff --git a/libpurple/conversationtypes.h b/libpurple/conversationtypes.h
new file mode 100644
index 0000000000..050d8cc375
--- /dev/null
+++ b/libpurple/conversationtypes.h
@@ -0,0 +1,707 @@
+/**
+ * @file conversationtypes.h Chat and IM Conversation API
+ * @ingroup core
+ */
+
+/* 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 _PURPLE_CONVERSATION_TYPES_H_
+#define _PURPLE_CONVERSATION_TYPES_H_
+
+/**************************************************************************/
+/** Data Structures */
+/**************************************************************************/
+
+#define PURPLE_TYPE_IM_CONVERSATION (purple_im_conversation_get_type())
+#define PURPLE_IM_CONVERSATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_IM_CONVERSATION, PurpleIMConversation))
+#define PURPLE_IM_CONVERSATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_IM_CONVERSATION, PurpleIMConversationClass))
+#define PURPLE_IS_IM_CONVERSATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_IM_CONVERSATION))
+#define PURPLE_IS_IM_CONVERSATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_IM_CONVERSATION))
+#define PURPLE_IM_CONVERSATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_IM_CONVERSATION, PurpleIMConversationClass))
+
+/** @copydoc _PurpleIMConversation */
+typedef struct _PurpleIMConversation PurpleIMConversation;
+/** @copydoc _PurpleIMConversationClass */
+typedef struct _PurpleIMConversationClass PurpleIMConversationClass;
+
+#define PURPLE_TYPE_CHAT_CONVERSATION (purple_chat_conversation_get_type())
+#define PURPLE_CHAT_CONVERSATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_CHAT_CONVERSATION, PurpleChatConversation))
+#define PURPLE_CHAT_CONVERSATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_CHAT_CONVERSATION, PurpleChatConversationClass))
+#define PURPLE_IS_CHAT_CONVERSATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_CHAT_CONVERSATION))
+#define PURPLE_IS_CHAT_CONVERSATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_CHAT_CONVERSATION))
+#define PURPLE_CHAT_CONVERSATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_CHAT_CONVERSATION, PurpleChatConversationClass))
+
+/** @copydoc _PurpleChatConversation */
+typedef struct _PurpleChatConversation PurpleChatConversation;
+/** @copydoc _PurpleChatConversationClass */
+typedef struct _PurpleChatConversationClass PurpleChatConversationClass;
+
+#define PURPLE_TYPE_CHAT_USER (purple_chat_user_get_type())
+#define PURPLE_CHAT_USER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_CHAT_USER, PurpleChatUser))
+#define PURPLE_CHAT_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_CHAT_USER, PurpleChatUserClass))
+#define PURPLE_IS_CHAT_USER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_CHAT_USER))
+#define PURPLE_IS_CHAT_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_CHAT_USER))
+#define PURPLE_CHAT_USER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_CHAT_USER, PurpleChatUserClass))
+
+/** @copydoc _PurpleChatUser */
+typedef struct _PurpleChatUser PurpleChatUser;
+/** @copydoc _PurpleChatUserClass */
+typedef struct _PurpleChatUserClass PurpleChatUserClass;
+
+/**
+ * The typing state of a user.
+ */
+typedef enum
+{
+ PURPLE_IM_NOT_TYPING = 0, /**< Not typing. */
+ PURPLE_IM_TYPING, /**< Currently typing. */
+ PURPLE_IM_TYPED /**< Stopped typing momentarily. */
+
+} PurpleIMTypingState;
+
+/**
+ * Flags applicable to users in Chats.
+ */
+typedef enum /*< flags >*/
+{
+ PURPLE_CHAT_USER_NONE = 0x0000, /**< No flags */
+ PURPLE_CHAT_USER_VOICE = 0x0001, /**< Voiced user or "Participant" */
+ PURPLE_CHAT_USER_HALFOP = 0x0002, /**< Half-op */
+ PURPLE_CHAT_USER_OP = 0x0004, /**< Channel Op or Moderator */
+ PURPLE_CHAT_USER_FOUNDER = 0x0008, /**< Channel Founder */
+ PURPLE_CHAT_USER_TYPING = 0x0010, /**< Currently typing */
+ PURPLE_CHAT_USER_AWAY = 0x0020 /**< Currently away. */
+
+} PurpleChatUserFlags;
+
+#include "conversation.h"
+
+/**************************************************************************/
+/** PurpleIMConversation */
+/**************************************************************************/
+/** Structure representing an IM conversation instance. */
+struct _PurpleIMConversation
+{
+ /*< private >*/
+ PurpleConversation parent_object;
+};
+
+/** Base class for all #PurpleIMConversation's */
+struct _PurpleIMConversationClass {
+ /*< private >*/
+ PurpleConversationClass parent_class;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+/**************************************************************************/
+/** PurpleChatConversation */
+/**************************************************************************/
+/** Structure representing a chat conversation instance. */
+struct _PurpleChatConversation
+{
+ /*< private >*/
+ PurpleConversation parent_object;
+};
+
+/** Base class for all #PurpleChatConversation's */
+struct _PurpleChatConversationClass {
+ /*< private >*/
+ PurpleConversationClass parent_class;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+/**************************************************************************/
+/** PurpleChatUser */
+/**************************************************************************/
+/** Structure representing a chat user instance. */
+struct _PurpleChatUser
+{
+ /*< private >*/
+ GObject gparent;
+
+ /** The UI data associated with this chat user. This is a convenience
+ * field provided to the UIs -- it is not used by the libpurple core.
+ */
+ gpointer ui_data;
+};
+
+/** Base class for all #PurpleChatUser's */
+struct _PurpleChatUserClass {
+ /*< private >*/
+ GObjectClass parent_class;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+/**************************************************************************/
+/** @name IM Conversation API */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the GType for the IMConversation object.
+ */
+GType purple_im_conversation_get_type(void);
+
+/**
+ * Creates a new IM conversation.
+ *
+ * @param account The account opening the conversation window on the purple
+ * user's end.
+ * @param name Name of the buddy.
+ *
+ * @return The new conversation.
+ */
+PurpleIMConversation *purple_im_conversation_new(PurpleAccount *account,
+ const char *name);
+
+/**
+ * Sets the IM's buddy icon.
+ *
+ * This should only be called from within Purple. You probably want to
+ * call purple_buddy_icon_set_data().
+ *
+ * @param im The IM.
+ * @param icon The buddy icon.
+ *
+ * @see purple_buddy_icon_set_data()
+ */
+void purple_im_conversation_set_icon(PurpleIMConversation *im, PurpleBuddyIcon *icon);
+
+/**
+ * Returns the IM's buddy icon.
+ *
+ * @param im The IM.
+ *
+ * @return The buddy icon.
+ */
+PurpleBuddyIcon *purple_im_conversation_get_icon(const PurpleIMConversation *im);
+
+/**
+ * Sets the IM's typing state.
+ *
+ * @param im The IM.
+ * @param state The typing state.
+ */
+void purple_im_conversation_set_typing_state(PurpleIMConversation *im, PurpleIMTypingState state);
+
+/**
+ * Returns the IM's typing state.
+ *
+ * @param im The IM.
+ *
+ * @return The IM's typing state.
+ */
+PurpleIMTypingState purple_im_conversation_get_typing_state(const PurpleIMConversation *im);
+
+/**
+ * Starts the IM's typing timeout.
+ *
+ * @param im The IM.
+ * @param timeout The timeout.
+ */
+void purple_im_conversation_start_typing_timeout(PurpleIMConversation *im, int timeout);
+
+/**
+ * Stops the IM's typing timeout.
+ *
+ * @param im The IM.
+ */
+void purple_im_conversation_stop_typing_timeout(PurpleIMConversation *im);
+
+/**
+ * Returns the IM's typing timeout.
+ *
+ * @param im The IM.
+ *
+ * @return The timeout.
+ */
+guint purple_im_conversation_get_typing_timeout(const PurpleIMConversation *im);
+
+/**
+ * Sets the quiet-time when no PURPLE_IM_TYPING messages will be sent.
+ * Few protocols need this (maybe only MSN). If the user is still
+ * typing after this quiet-period, then another PURPLE_IM_TYPING message
+ * will be sent.
+ *
+ * @param im The IM.
+ * @param val The number of seconds to wait before allowing another
+ * PURPLE_IM_TYPING message to be sent to the user. Or 0 to
+ * not send another PURPLE_IM_TYPING message.
+ */
+void purple_im_conversation_set_type_again(PurpleIMConversation *im, unsigned int val);
+
+/**
+ * Returns the time after which another PURPLE_IM_TYPING message should be sent.
+ *
+ * @param im The IM.
+ *
+ * @return The time in seconds since the epoch. Or 0 if no additional
+ * PURPLE_IM_TYPING message should be sent.
+ */
+time_t purple_im_conversation_get_type_again(const PurpleIMConversation *im);
+
+/**
+ * Starts the IM's type again timeout.
+ *
+ * @param im The IM.
+ */
+void purple_im_conversation_start_send_typed_timeout(PurpleIMConversation *im);
+
+/**
+ * Stops the IM's type again timeout.
+ *
+ * @param im The IM.
+ */
+void purple_im_conversation_stop_send_typed_timeout(PurpleIMConversation *im);
+
+/**
+ * Returns the IM's type again timeout interval.
+ *
+ * @param im The IM.
+ *
+ * @return The type again timeout interval.
+ */
+guint purple_im_conversation_get_send_typed_timeout(const PurpleIMConversation *im);
+
+/**
+ * Updates the visual typing notification for an IM conversation.
+ *
+ * @param im The IM.
+ */
+void purple_im_conversation_update_typing(PurpleIMConversation *im);
+
+/*@}*/
+
+/**************************************************************************/
+/** @name Chat Conversation API */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the GType for the ChatConversation object.
+ */
+GType purple_chat_conversation_get_type(void);
+
+/**
+ * Creates a new chat conversation.
+ *
+ * @param account The account opening the conversation window on the purple
+ * user's end.
+ * @param name The name of the conversation.
+ *
+ * @return The new conversation.
+ */
+PurpleChatConversation *purple_chat_conversation_new(PurpleAccount *account,
+ const char *name);
+
+/**
+ * Returns a list of users in the chat room. The members of the list
+ * are PurpleChatUser objects.
+ *
+ * @param chat The chat.
+ *
+ * @constreturn The list of users.
+ */
+GList *purple_chat_conversation_get_users(const PurpleChatConversation *chat);
+
+/**
+ * Ignores a user in a chat room.
+ *
+ * @param chat The chat.
+ * @param name The name of the user.
+ */
+void purple_chat_conversation_ignore(PurpleChatConversation *chat, const char *name);
+
+/**
+ * Unignores a user in a chat room.
+ *
+ * @param chat The chat.
+ * @param name The name of the user.
+ */
+void purple_chat_conversation_unignore(PurpleChatConversation *chat, const char *name);
+
+/**
+ * Sets the list of ignored users in the chat room.
+ *
+ * @param chat The chat.
+ * @param ignored The list of ignored users.
+ *
+ * @return The list passed.
+ */
+GList *purple_chat_conversation_set_ignored(PurpleChatConversation *chat, GList *ignored);
+
+/**
+ * Returns the list of ignored users in the chat room.
+ *
+ * @param chat The chat.
+ *
+ * @constreturn The list of ignored users.
+ */
+GList *purple_chat_conversation_get_ignored(const PurpleChatConversation *chat);
+
+/**
+ * Returns the actual name of the specified ignored user, if it exists in
+ * the ignore list.
+ *
+ * If the user found contains a prefix, such as '+' or '\@', this is also
+ * returned. The username passed to the function does not have to have this
+ * formatting.
+ *
+ * @param chat The chat.
+ * @param user The user to check in the ignore list.
+ *
+ * @return The ignored user if found, complete with prefixes, or @c NULL
+ * if not found.
+ */
+const char *purple_chat_conversation_get_ignored_user(const PurpleChatConversation *chat,
+ const char *user);
+
+/**
+ * Returns @c TRUE if the specified user is ignored.
+ *
+ * @param chat The chat.
+ * @param user The user.
+ *
+ * @return @c TRUE if the user is in the ignore list; @c FALSE otherwise.
+ */
+gboolean purple_chat_conversation_is_ignored_user(const PurpleChatConversation *chat,
+ const char *user);
+
+/**
+ * Sets the chat room's topic.
+ *
+ * @param chat The chat.
+ * @param who The user that set the topic.
+ * @param topic The topic.
+ */
+void purple_chat_conversation_set_topic(PurpleChatConversation *chat, const char *who,
+ const char *topic);
+
+/**
+ * Returns the chat room's topic.
+ *
+ * @param chat The chat.
+ *
+ * @return The chat's topic.
+ */
+const char *purple_chat_conversation_get_topic(const PurpleChatConversation *chat);
+
+/**
+ * Returns who set the chat room's topic.
+ *
+ * @param chat The chat.
+ *
+ * @return Who set the topic.
+ */
+const char *purple_chat_conversation_get_topic_who(const PurpleChatConversation *chat);
+
+/**
+ * Sets the chat room's ID.
+ *
+ * @param chat The chat.
+ * @param id The ID.
+ */
+void purple_chat_conversation_set_id(PurpleChatConversation *chat, int id);
+
+/**
+ * Returns the chat room's ID.
+ *
+ * @param chat The chat.
+ *
+ * @return The ID.
+ */
+int purple_chat_conversation_get_id(const PurpleChatConversation *chat);
+
+/**
+ * Adds a user to a chat.
+ *
+ * @param chat The chat.
+ * @param user The user to add.
+ * @param extra_msg An extra message to display with the join message.
+ * @param flags The users flags
+ * @param new_arrival Decides whether or not to show a join notice.
+ */
+void purple_chat_conversation_add_user(PurpleChatConversation *chat, const char *user,
+ const char *extra_msg, PurpleChatUserFlags flags,
+ gboolean new_arrival);
+
+/**
+ * Adds a list of users to a chat.
+ *
+ * The data is copied from @a users, @a extra_msgs, and @a flags, so it is up to
+ * the caller to free this list after calling this function.
+ *
+ * @param chat The chat.
+ * @param users The list of users to add.
+ * @param extra_msgs An extra message to display with the join message for each
+ * user. This list may be shorter than @a users, in which
+ * case, the users after the end of extra_msgs will not have
+ * an extra message. By extension, this means that extra_msgs
+ * can simply be @c NULL and none of the users will have an
+ * extra message.
+ * @param flags The list of flags for each user.
+ * @param new_arrivals Decides whether or not to show join notices.
+ */
+void purple_chat_conversation_add_users(PurpleChatConversation *chat,
+ GList *users, GList *extra_msgs, GList *flags, gboolean new_arrivals);
+
+/**
+ * Renames a user in a chat.
+ *
+ * @param chat The chat.
+ * @param old_user The old username.
+ * @param new_user The new username.
+ */
+void purple_chat_conversation_rename_user(PurpleChatConversation *chat,
+ const char *old_user, const char *new_user);
+
+/**
+ * Removes a user from a chat, optionally with a reason.
+ *
+ * It is up to the developer to free this list after calling this function.
+ *
+ * @param chat The chat.
+ * @param user The user that is being removed.
+ * @param reason The optional reason given for the removal. Can be @c NULL.
+ */
+void purple_chat_conversation_remove_user(PurpleChatConversation *chat,
+ const char *user, const char *reason);
+
+/**
+ * Removes a list of users from a chat, optionally with a single reason.
+ *
+ * @param chat The chat.
+ * @param users The users that are being removed.
+ * @param reason The optional reason given for the removal. Can be @c NULL.
+ */
+void purple_chat_conversation_remove_users(PurpleChatConversation *chat,
+ GList *users, const char *reason);
+
+/**
+ * Checks if a user is in a chat
+ *
+ * @param chat The chat.
+ * @param user The user to look for.
+ *
+ * @return TRUE if the user is in the chat, FALSE if not
+ */
+gboolean purple_chat_conversation_has_user(PurpleChatConversation *chat,
+ const char *user);
+
+/**
+ * Clears all users from a chat.
+ *
+ * @param chat The chat.
+ */
+void purple_chat_conversation_clear_users(PurpleChatConversation *chat);
+
+/**
+ * Sets your nickname (used for hilighting) for a chat.
+ *
+ * @param chat The chat.
+ * @param nick The nick.
+ */
+void purple_chat_conversation_set_nick(PurpleChatConversation *chat,
+ const char *nick);
+
+/**
+ * Gets your nickname (used for hilighting) for a chat.
+ *
+ * @param chat The chat.
+ * @return The nick.
+ */
+const char *purple_chat_conversation_get_nick(PurpleChatConversation *chat);
+
+/**
+ * Lets the core know we left a chat, without destroying it.
+ * Called from serv_got_chat_left().
+ *
+ * @param chat The chat.
+ */
+void purple_chat_conversation_leave(PurpleChatConversation *chat);
+
+/**
+ * Find a chat user in a chat
+ *
+ * @param chat The chat.
+ * @param name The name of the chat user to find.
+ */
+PurpleChatUser *purple_chat_conversation_find_user(PurpleChatConversation *chat,
+ const char *name);
+
+/**
+ * Invite a user to a chat.
+ * The user will be prompted to enter the user's name or a message if one is
+ * not given.
+ *
+ * @param chat The chat.
+ * @param user The user to invite to the 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.
+ */
+void purple_chat_conversation_invite_user(PurpleChatConversation *chat,
+ const char *user, const char *message, gboolean confirm);
+
+/**
+ * Returns true if we're no longer in this chat,
+ * and just left the window open.
+ *
+ * @param chat The chat.
+ *
+ * @return @c TRUE if we left the chat already, @c FALSE if
+ * we're still there.
+ */
+gboolean purple_chat_conversation_has_left(PurpleChatConversation *chat);
+
+/*@}*/
+
+/**************************************************************************/
+/** @name Chat Conversation User API */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the GType for the ChatConversationBuddy object.
+ */
+GType purple_chat_user_get_type(void);
+
+/**
+ * Set the chat conversation associated with this chat user.
+ *
+ * @param cb The chat user
+ * @param chat The chat conversation that the buddy belongs to.
+ */
+void purple_chat_user_set_chat(PurpleChatUser *cb,
+ PurpleChatConversation *chat);
+
+/**
+ * Get the chat conversation associated with this chat user.
+ *
+ * @param cb The chat user.
+ *
+ * @return The chat conversation that the buddy belongs to.
+ */
+PurpleChatConversation *purple_chat_user_get_chat(const PurpleChatUser *cb);
+
+/**
+ * Creates a new chat user
+ *
+ * @param chat The chat that the buddy belongs to.
+ * @param name The name.
+ * @param alias The alias.
+ * @param flags The flags.
+ *
+ * @return The new chat user
+ */
+PurpleChatUser *purple_chat_user_new(PurpleChatConversation *chat,
+ const char *name, const char *alias, PurpleChatUserFlags flags);
+
+/**
+ * Set the UI data associated with this chat user.
+ *
+ * @param cb The chat user
+ * @param ui_data A pointer to associate with this chat user.
+ */
+void purple_chat_user_set_ui_data(PurpleChatUser *cb, gpointer ui_data);
+
+/**
+ * Get the UI data associated with this chat user.
+ *
+ * @param cb The chat user.
+ *
+ * @return The UI data associated with this chat user. This is a
+ * convenience field provided to the UIs--it is not
+ * used by the libpurple core.
+ */
+gpointer purple_chat_user_get_ui_data(const PurpleChatUser *cb);
+
+/**
+ * Get the alias of a chat user
+ *
+ * @param cb The chat user.
+ *
+ * @return The alias of the chat user.
+ */
+const char *purple_chat_user_get_alias(const PurpleChatUser *cb);
+
+/**
+ * Get the name of a chat user
+ *
+ * @param cb The chat user.
+ *
+ * @return The name of the chat user.
+ */
+const char *purple_chat_user_get_name(const PurpleChatUser *cb);
+
+/**
+ * Set the flags of a chat user.
+ *
+ * @param cb The chat user.
+ * @param flags The new flags.
+ */
+void purple_chat_user_set_flags(PurpleChatUser *cb, PurpleChatUserFlags flags);
+
+/**
+ * Get the flags of a chat user.
+ *
+ * @param cb The chat user.
+ *
+ * @return The flags of the chat user.
+ */
+PurpleChatUserFlags purple_chat_user_get_flags(const PurpleChatUser *cb);
+
+/**
+ * Sets if this chat user is on the buddy list.
+ *
+ * @param cb The chat user.
+ * @param buddy TRUE if the chat user is on the buddy list.
+ */
+void purple_chat_user_set_buddy(const PurpleChatUser *cb, gboolean buddy);
+
+/**
+ * Indicates if this chat user is on the buddy list.
+ *
+ * @param cb The chat user.
+ *
+ * @return TRUE if the chat user is on the buddy list.
+ */
+gboolean purple_chat_user_is_buddy(const PurpleChatUser *cb);
+
+/*@}*/
+
+G_END_DECLS
+
+#endif /* _PURPLE_CONVERSATION_TYPES_H_ */
diff --git a/libpurple/core.c b/libpurple/core.c
index 3aa93a8572..0666624f10 100644
--- a/libpurple/core.c
+++ b/libpurple/core.c
@@ -43,7 +43,6 @@
#include "plugin.h"
#include "pounce.h"
#include "prefs.h"
-#include "privacy.h"
#include "proxy.h"
#include "savedstatuses.h"
#include "signals.h"
@@ -135,13 +134,15 @@ purple_core_init(const char *ui)
purple_signal_register(core, "uri-handler",
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 3,
- purple_value_new(PURPLE_TYPE_STRING), /* Protocol */
- purple_value_new(PURPLE_TYPE_STRING), /* Command */
- purple_value_new(PURPLE_TYPE_BOXED, "GHashTable *")); /* Parameters */
+ G_TYPE_BOOLEAN, 3,
+ G_TYPE_STRING, /* Protocol */
+ G_TYPE_STRING, /* Command */
+ G_TYPE_POINTER); /* Parameters (GHashTable *) */
- purple_signal_register(core, "quitting", purple_marshal_VOID, NULL, 0);
- purple_signal_register(core, "core-initialized", purple_marshal_VOID, NULL, 0);
+ purple_signal_register(core, "quitting", purple_marshal_VOID, G_TYPE_NONE,
+ 0);
+ purple_signal_register(core, "core-initialized", purple_marshal_VOID,
+ G_TYPE_NONE, 0);
purple_core_print_version();
@@ -164,7 +165,6 @@ purple_core_init(const char *ui)
purple_dbus_init();
#endif
- purple_ciphers_init();
purple_cmds_init();
/* Since plugins get probed so early we should probably initialize their
@@ -186,7 +186,7 @@ purple_core_init(const char *ui)
/* Accounts use status, buddy icons and connection signals, so
* initialize these before accounts
*/
- purple_status_init();
+ purple_statuses_init();
purple_buddy_icons_init();
purple_connections_init();
@@ -198,7 +198,6 @@ purple_core_init(const char *ui)
purple_blist_init();
purple_log_init();
purple_network_init();
- purple_privacy_init();
purple_pounces_init();
purple_proxy_init();
purple_dnsquery_init();
@@ -265,13 +264,12 @@ purple_core_quit(void)
purple_idle_uninit();
purple_pounces_uninit();
purple_blist_uninit();
- purple_ciphers_uninit();
purple_notify_uninit();
purple_conversations_uninit();
purple_connections_uninit();
purple_buddy_icons_uninit();
purple_savedstatuses_uninit();
- purple_status_uninit();
+ purple_statuses_uninit();
purple_accounts_uninit();
purple_keyring_uninit(); /* after accounts */
purple_sound_uninit();
diff --git a/libpurple/dbus-analyze-functions.py b/libpurple/dbus-analyze-functions.py
index caa07e1187..59191fda4b 100644
--- a/libpurple/dbus-analyze-functions.py
+++ b/libpurple/dbus-analyze-functions.py
@@ -22,10 +22,10 @@ excluded = [\
# functions with untranslatable types are skipped, but this script
# assumes that all non-pointer type names beginning with "Purple"
# are enums, which is not true in this case.
- "purple_conv_placement_add_fnc",
- "purple_conv_placement_get_fnc",
- "purple_conv_placement_get_current_func",
- "purple_conv_placement_set_current_func",
+ "purple_conversation_placement_add_fnc",
+ "purple_conversation_placement_get_fnc",
+ "purple_conversation_placement_get_current_func",
+ "purple_conversation_placement_set_current_func",
# Similar to the above:
"purple_account_set_register_callback",
@@ -70,11 +70,11 @@ constlists = [
"purple_account_option_get_list",
"purple_connections_get_all",
"purple_connections_get_connecting",
- "purple_get_conversations",
- "purple_get_ims",
- "purple_get_chats",
- "purple_conv_chat_get_users",
- "purple_conv_chat_get_ignored",
+ "purple_conversations_get_all",
+ "purple_conversations_get_ims",
+ "purple_conversations_get_chats",
+ "purple_chat_conversation_get_users",
+ "purple_chat_conversation_get_ignored",
"purple_mime_document_get_fields",
"purple_mime_document_get_parts",
"purple_mime_part_get_fields",
diff --git a/libpurple/dbus-define-api.h b/libpurple/dbus-define-api.h
index 7916ec744f..17bcd422ed 100644
--- a/libpurple/dbus-define-api.h
+++ b/libpurple/dbus-define-api.h
@@ -5,21 +5,10 @@
provides type information for the dbus-analyze-functions.py
program, which makes these macros callable by DBUS. */
-/* blist.h */
-gboolean PURPLE_BLIST_NODE_IS_CHAT(PurpleBlistNode *node);
-gboolean PURPLE_BLIST_NODE_IS_BUDDY(PurpleBlistNode *node);
-gboolean PURPLE_BLIST_NODE_IS_CONTACT(PurpleBlistNode *node);
-gboolean PURPLE_BLIST_NODE_IS_GROUP(PurpleBlistNode *node);
+/* buddylist.h */
gboolean PURPLE_BUDDY_IS_ONLINE(PurpleBuddy *buddy);
-gboolean PURPLE_BLIST_NODE_HAS_FLAG(PurpleBlistNode *node, int flags);
-gboolean PURPLE_BLIST_NODE_SHOULD_SAVE(PurpleBlistNode *node);
/* connection.h */
gboolean PURPLE_CONNECTION_IS_CONNECTED(PurpleConnection *connection);
gboolean PURPLE_CONNECTION_IS_VALID(PurpleConnection *connection);
-/* conversation.h */
-PurpleConvIm *PURPLE_CONV_IM(const PurpleConversation *conversation);
-PurpleConvIm *PURPLE_CONV_CHAT(const PurpleConversation *conversation);
-
-
diff --git a/libpurple/dbus-server.c b/libpurple/dbus-server.c
index 63b8b82f5b..6c42592d8a 100644
--- a/libpurple/dbus-server.c
+++ b/libpurple/dbus-server.c
@@ -36,7 +36,7 @@
#include <string.h>
#include "account.h"
-#include "blist.h"
+#include "buddylist.h"
#include "conversation.h"
#include "dbus-purple.h"
#include "dbus-server.h"
@@ -47,7 +47,6 @@
#include "savedstatuses.h"
#include "smiley.h"
#include "util.h"
-#include "value.h"
#include "xmlnode.h"
@@ -628,13 +627,11 @@ purple_dbus_dispatch_init(void)
purple_signal_register(purple_dbus_get_handle(), "dbus-method-called",
purple_marshal_BOOLEAN__POINTER_POINTER,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 2,
- purple_value_new(PURPLE_TYPE_POINTER),
- purple_value_new(PURPLE_TYPE_POINTER));
+ G_TYPE_BOOLEAN, 2, G_TYPE_POINTER, G_TYPE_POINTER);
purple_signal_register(purple_dbus_get_handle(), "dbus-introspect",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new_outgoing(PURPLE_TYPE_POINTER));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ G_TYPE_POINTER); /* pointer to a pointer */
PURPLE_DBUS_REGISTER_BINDINGS(purple_dbus_get_handle());
@@ -677,7 +674,7 @@ purple_dbus_convert_signal_name(const char *purple_name)
static gboolean
purple_dbus_message_append_purple_values(DBusMessageIter *iter,
- int number, PurpleValue **purple_values, va_list data)
+ int number, GType *types, va_list data)
{
int i;
gboolean error = FALSE;
@@ -693,37 +690,36 @@ purple_dbus_message_append_purple_values(DBusMessageIter *iter,
gboolean xboolean;
gpointer ptr = NULL;
gpointer val;
-
+#if 0
if (purple_value_is_outgoing(purple_values[i]))
{
ptr = my_arg(gpointer);
g_return_val_if_fail(ptr, TRUE);
}
-
- switch (purple_value_get_type(purple_values[i]))
+#endif
+ switch (types[i])
{
- case PURPLE_TYPE_INT:
- case PURPLE_TYPE_ENUM:
+ case G_TYPE_INT:
xint = my_arg(gint);
dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &xint);
break;
- case PURPLE_TYPE_UINT:
+ case G_TYPE_UINT:
xuint = my_arg(guint);
dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &xuint);
break;
- case PURPLE_TYPE_INT64:
+ case G_TYPE_INT64:
xint64 = my_arg(gint64);
dbus_message_iter_append_basic(iter, DBUS_TYPE_INT64, &xint64);
break;
- case PURPLE_TYPE_UINT64:
+ case G_TYPE_UINT64:
xuint64 = my_arg(guint64);
dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &xuint64);
break;
- case PURPLE_TYPE_BOOLEAN:
+ case G_TYPE_BOOLEAN:
xboolean = my_arg(gboolean);
dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &xboolean);
break;
- case PURPLE_TYPE_STRING:
+ case G_TYPE_STRING:
str = null_to_empty(my_arg(char*));
if (!g_utf8_validate(str, -1, NULL)) {
gchar *tmp;
@@ -735,19 +731,27 @@ purple_dbus_message_append_purple_values(DBusMessageIter *iter,
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &str);
}
break;
- case PURPLE_TYPE_SUBTYPE: /* registered pointers only! */
- case PURPLE_TYPE_POINTER:
- case PURPLE_TYPE_OBJECT:
- case PURPLE_TYPE_BOXED:
- val = my_arg(gpointer);
- id = purple_dbus_pointer_to_id(val);
- if (id == 0 && val != NULL)
- error = TRUE; /* Some error happened. */
- dbus_message_iter_append_basic(iter,
- (sizeof(id) == sizeof(dbus_int32_t)) ? DBUS_TYPE_INT32 : DBUS_TYPE_INT64, &id);
- break;
- default: /* no conversion implemented */
- g_return_val_if_reached(TRUE);
+ default:
+ if (G_TYPE_IS_OBJECT(types[i]) ||
+ G_TYPE_IS_BOXED(types[i]) ||
+ types[i] == G_TYPE_POINTER )
+ {
+ val = my_arg(gpointer);
+ id = purple_dbus_pointer_to_id(val);
+ if (id == 0 && val != NULL)
+ error = TRUE; /* Some error happened. */
+ dbus_message_iter_append_basic(iter,
+ (sizeof(id) == sizeof(dbus_int32_t)) ? DBUS_TYPE_INT32 : DBUS_TYPE_INT64, &id);
+ }
+ else if (G_TYPE_IS_ENUM(types[i]))
+ {
+ xint = my_arg(gint);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &xint);
+ }
+ else /* no conversion implemented */
+ {
+ g_return_val_if_reached(TRUE);
+ }
}
}
return error;
@@ -757,7 +761,7 @@ purple_dbus_message_append_purple_values(DBusMessageIter *iter,
void
purple_dbus_signal_emit_purple(const char *name, int num_values,
- PurpleValue **values, va_list vargs)
+ GType *types, va_list vargs)
{
DBusMessage *signal;
DBusMessageIter iter;
@@ -784,7 +788,7 @@ purple_dbus_signal_emit_purple(const char *name, int num_values,
signal = dbus_message_new_signal(DBUS_PATH_PURPLE, DBUS_INTERFACE_PURPLE, newname);
dbus_message_iter_init_append(signal, &iter);
- if (purple_dbus_message_append_purple_values(&iter, num_values, values, vargs))
+ if (purple_dbus_message_append_purple_values(&iter, num_values, types, vargs))
if (purple_debug_is_verbose())
purple_debug_warning("dbus",
"The signal \"%s\" caused some dbus error."
diff --git a/libpurple/dbus-server.h b/libpurple/dbus-server.h
index 5810dab8c7..4425dc66e0 100644
--- a/libpurple/dbus-server.h
+++ b/libpurple/dbus-server.h
@@ -29,7 +29,6 @@
#define _PURPLE_DBUS_SERVER_H_
#include "dbus-purple.h"
-#include "value.h"
G_BEGIN_DECLS
@@ -141,12 +140,11 @@ void purple_dbus_unregister_pointer(gpointer node);
@param name The name of the signal ("bla-bla-blaa")
@param num_values The number of parameters.
- @param values Array of pointers to #PurpleValue objects representing
- the types of the parameters.
+ @param types Array of GTypes representing the types of the parameters.
@param vargs A va_list containing the actual parameters.
*/
void purple_dbus_signal_emit_purple(const char *name, int num_values,
- PurpleValue **values, va_list vargs);
+ GType *types, va_list vargs);
/**
* Returns whether Purple's D-BUS subsystem is up and running. If it's
diff --git a/libpurple/dbus-useful.c b/libpurple/dbus-useful.c
index 4a685fc88f..99d456d4f3 100644
--- a/libpurple/dbus-useful.c
+++ b/libpurple/dbus-useful.c
@@ -2,6 +2,7 @@
#include <glib.h>
#include "dbus-useful.h"
+#include "accounts.h"
#include "conversation.h"
#include "util.h"
diff --git a/libpurple/enums.c.template b/libpurple/enums.c.template
new file mode 100644
index 0000000000..dd05073b96
--- /dev/null
+++ b/libpurple/enums.c.template
@@ -0,0 +1,64 @@
+/*** BEGIN file-header ***/
+/* 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
+ */
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include "enums.h"
+
+/*** END file-header ***/
+/*** BEGIN file-production ***/
+
+/* enumerations from "@filename@" */
+#include "@filename@"
+
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType
+@enum_name@_get_type(void) {
+ static volatile gsize g_define_type_id__volatile = 0;
+
+ if(g_once_init_enter(&g_define_type_id__volatile)) {
+ static const G@Type@Value values [] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+
+ GType g_define_type_id =
+ g_@type@_register_static(g_intern_static_string("@EnumName@"), values);
+ g_once_init_leave(&g_define_type_id__volatile, g_define_type_id);
+ }
+
+ return g_define_type_id__volatile;
+}
+
+/*** END value-tail ***/
+
+/*** BEGIN file-tail ***/
+/*** END file-tail ***/
diff --git a/libpurple/enums.h.template b/libpurple/enums.h.template
new file mode 100644
index 0000000000..a29b432b41
--- /dev/null
+++ b/libpurple/enums.h.template
@@ -0,0 +1,45 @@
+/*** BEGIN file-header ***/
+/* 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 PURPLE_ENUM_H
+#define PURPLE_ENUM_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type(void) G_GNUC_CONST;
+#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
+/*** END value-header ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif /* PURPLE_ENUM_H */
+
+/*** END file-tail ***/
+
diff --git a/libpurple/ft.c b/libpurple/ft.c
index 695400837f..22b81c8338 100644
--- a/libpurple/ft.c
+++ b/libpurple/ft.c
@@ -278,7 +278,7 @@ static void
purple_xfer_conversation_write_internal(PurpleXfer *xfer,
const char *message, gboolean is_error, gboolean print_thumbnail)
{
- PurpleConversation *conv = NULL;
+ PurpleIMConversation *im = NULL;
PurpleMessageFlags flags = PURPLE_MESSAGE_SYSTEM;
char *escaped;
gconstpointer thumbnail_data;
@@ -289,10 +289,10 @@ purple_xfer_conversation_write_internal(PurpleXfer *xfer,
thumbnail_data = purple_xfer_get_thumbnail(xfer, &size);
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, xfer->who,
+ im = purple_conversations_find_im_with_account(xfer->who,
purple_xfer_get_account(xfer));
- if (conv == NULL)
+ if (im == NULL)
return;
escaped = g_markup_escape_text(message, -1);
@@ -308,12 +308,13 @@ purple_xfer_conversation_write_internal(PurpleXfer *xfer,
message_with_img =
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_conversation_write(PURPLE_CONVERSATION(im), NULL,
+ message_with_img, flags, time(NULL));
purple_imgstore_unref_by_id(id);
g_free(message_with_img);
} else {
- purple_conversation_write(conv, NULL, escaped, flags, time(NULL));
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, escaped, flags,
+ time(NULL));
}
g_free(escaped);
}
@@ -498,7 +499,7 @@ purple_xfer_ask_recv(PurpleXfer *xfer)
/* If we have already accepted the request, ask the destination file
name directly */
if (purple_xfer_get_status(xfer) != PURPLE_XFER_STATUS_ACCEPTED) {
- PurpleBuddy *buddy = purple_find_buddy(xfer->account, xfer->who);
+ PurpleBuddy *buddy = purple_blist_find_buddy(xfer->account, xfer->who);
if (purple_xfer_get_filename(xfer) != NULL)
{
@@ -558,7 +559,7 @@ static void
purple_xfer_ask_accept(PurpleXfer *xfer)
{
char *buf, *buf2 = NULL;
- PurpleBuddy *buddy = purple_find_buddy(xfer->account, xfer->who);
+ PurpleBuddy *buddy = purple_blist_find_buddy(xfer->account, xfer->who);
buf = g_strdup_printf(_("Accept file transfer request from %s?"),
buddy ? purple_buddy_get_alias(buddy) : xfer->who);
@@ -598,7 +599,7 @@ purple_xfer_request(PurpleXfer *xfer)
purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_ACCEPTED)
{
gchar* message = NULL;
- PurpleBuddy *buddy = purple_find_buddy(xfer->account, xfer->who);
+ PurpleBuddy *buddy = purple_blist_find_buddy(xfer->account, xfer->who);
message = g_strdup_printf(_("%s is offering to send file %s"),
buddy ? purple_buddy_get_alias(buddy) : xfer->who, purple_xfer_get_filename(xfer));
@@ -643,7 +644,7 @@ purple_xfer_request_accepted(PurpleXfer *xfer, const char *filename)
return;
}
- buddy = purple_find_buddy(account, xfer->who);
+ buddy = purple_blist_find_buddy(account, xfer->who);
if (type == PURPLE_XFER_SEND) {
/* Sending a file */
@@ -901,7 +902,7 @@ purple_xfer_set_completed(PurpleXfer *xfer, gboolean completed)
if (completed == TRUE) {
char *msg = NULL;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
purple_xfer_set_status(xfer, PURPLE_XFER_STATUS_DONE);
@@ -924,11 +925,12 @@ purple_xfer_set_completed(PurpleXfer *xfer, gboolean completed)
else
msg = g_strdup(_("File transfer complete"));
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, xfer->who,
+ im = purple_conversations_find_im_with_account(xfer->who,
purple_xfer_get_account(xfer));
- if (conv != NULL)
- purple_conversation_write(conv, NULL, msg, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ if (im != NULL)
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, msg,
+ PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(msg);
}
@@ -1670,7 +1672,7 @@ purple_xfer_cancel_remote(PurpleXfer *xfer)
xfer->end_time = time(NULL);
account = purple_xfer_get_account(xfer);
- buddy = purple_find_buddy(account, xfer->who);
+ buddy = purple_blist_find_buddy(account, xfer->who);
if (purple_xfer_get_filename(xfer) != NULL)
{
@@ -1730,7 +1732,7 @@ purple_xfer_error(PurpleXferType type, PurpleAccount *account, const char *who,
if (account) {
PurpleBuddy *buddy;
- buddy = purple_find_buddy(account, who);
+ buddy = purple_blist_find_buddy(account, who);
if (buddy)
who = purple_buddy_get_alias(buddy);
}
@@ -1834,6 +1836,33 @@ gpointer purple_xfer_get_ui_data(const PurpleXfer *xfer)
return xfer->ui_data;
}
+static PurpleXfer *
+purple_xfer_copy(PurpleXfer *xfer)
+{
+ PurpleXfer *xfer_copy;
+
+ g_return_val_if_fail(xfer != NULL, NULL);
+
+ xfer_copy = g_new(PurpleXfer, 1);
+ *xfer_copy = *xfer;
+
+ return xfer_copy;
+}
+
+GType
+purple_xfer_get_g_type(void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_boxed_type_register_static("PurpleXfer",
+ (GBoxedCopyFunc)purple_xfer_copy,
+ (GBoxedFreeFunc)g_free);
+ }
+
+ return type;
+}
+
/**************************************************************************
* File Transfer Subsystem API
@@ -1854,41 +1883,32 @@ purple_xfers_init(void) {
/* register signals */
purple_signal_register(handle, "file-recv-accept",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_XFER));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_XFER);
purple_signal_register(handle, "file-send-accept",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_XFER));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_XFER);
purple_signal_register(handle, "file-recv-start",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_XFER));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_XFER);
purple_signal_register(handle, "file-send-start",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_XFER));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_XFER);
purple_signal_register(handle, "file-send-cancel",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_XFER));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_XFER);
purple_signal_register(handle, "file-recv-cancel",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_XFER));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_XFER);
purple_signal_register(handle, "file-send-complete",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_XFER));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_XFER);
purple_signal_register(handle, "file-recv-complete",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_XFER));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_XFER);
purple_signal_register(handle, "file-recv-request",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_XFER));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_XFER);
}
void
diff --git a/libpurple/ft.h b/libpurple/ft.h
index 1de8469e50..b48a3a9bbf 100644
--- a/libpurple/ft.h
+++ b/libpurple/ft.h
@@ -27,6 +27,8 @@
#ifndef _PURPLE_FT_H_
#define _PURPLE_FT_H_
+#define PURPLE_TYPE_XFER (purple_xfer_get_g_type())
+
/**************************************************************************/
/** Data Structures */
/**************************************************************************/
@@ -192,6 +194,13 @@ G_BEGIN_DECLS
/*@{*/
/**
+ * Returns the GType for the PurpleXfer boxed structure.
+ * TODO Boxing of PurpleXfer is a temporary solution to having a GType for
+ * file transfers. This should rather be a GObject instead of a GBoxed.
+ */
+GType purple_xfer_get_g_type(void);
+
+/**
* Creates a new file transfer handle.
* This is called by prpls.
* The handle starts with a ref count of 1, and this reference
diff --git a/libpurple/hash.c b/libpurple/hash.c
new file mode 100644
index 0000000000..8858707c27
--- /dev/null
+++ b/libpurple/hash.c
@@ -0,0 +1,268 @@
+/* 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
+ */
+#include "internal.h"
+#include "hash.h"
+#include "debug.h"
+
+/******************************************************************************
+ * Object Stuff
+ *****************************************************************************/
+static void
+purple_hash_class_init(PurpleHashClass *klass) {
+ klass->reset = NULL;
+ klass->reset_state = NULL;
+ klass->append = NULL;
+ klass->digest = NULL;
+ klass->get_digest_size = NULL;
+ klass->get_block_size = NULL;
+ klass->get_name = NULL;
+}
+
+/******************************************************************************
+ * PurpleHash API
+ *****************************************************************************/
+const gchar *
+purple_hash_get_name(PurpleHash *hash) {
+ PurpleHashClass *klass = NULL;
+
+ g_return_val_if_fail(hash, NULL);
+ g_return_val_if_fail(PURPLE_IS_HASH(hash), NULL);
+
+ klass = PURPLE_HASH_GET_CLASS(hash);
+ g_return_val_if_fail(klass->get_name, NULL);
+
+ return klass->get_name(hash);
+}
+
+GType
+purple_hash_get_type(void) {
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleHashClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_hash_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleHash),
+ 0,
+ NULL,
+ NULL
+ };
+
+ type = g_type_register_static(G_TYPE_OBJECT,
+ "PurpleHash",
+ &info, G_TYPE_FLAG_ABSTRACT);
+ }
+
+ return type;
+}
+
+/**
+ * purple_hash_reset:
+ * @hash: The hash to reset
+ *
+ * Resets a hash to it's default value
+ *
+ * @note If you have set an IV you will have to set it after resetting
+ */
+void
+purple_hash_reset(PurpleHash *hash) {
+ PurpleHashClass *klass = NULL;
+
+ g_return_if_fail(PURPLE_IS_HASH(hash));
+
+ klass = PURPLE_HASH_GET_CLASS(hash);
+
+ if(klass && klass->reset)
+ klass->reset(hash);
+ else
+ purple_debug_warning("hash", "the %s hash does not implement the "
+ "reset method\n",
+ klass->get_name ? klass->get_name(hash) : "");
+}
+
+/**
+ * Resets a hash state to it's default value, but doesn't touch stateless
+ * configuration.
+ *
+ * That means, IV and digest context will be wiped out, but keys, ops or salt
+ * will remain untouched.
+ */
+void
+purple_hash_reset_state(PurpleHash *hash) {
+ PurpleHashClass *klass = NULL;
+
+ g_return_if_fail(PURPLE_IS_HASH(hash));
+
+ klass = PURPLE_HASH_GET_CLASS(hash);
+
+ if(klass && klass->reset_state)
+ klass->reset_state(hash);
+ else
+ purple_debug_warning("hash", "the %s hash does not implement the "
+ "reset_state method\n",
+ klass->get_name ? klass->get_name(hash) : "");
+}
+
+/**
+ * purple_hash_append:
+ * @hash: The hash to append data to
+ * @data: The data to append
+ * @len: The length of the data
+ *
+ * Appends data to the hash
+ */
+void
+purple_hash_append(PurpleHash *hash, const guchar *data,
+ size_t len)
+{
+ PurpleHashClass *klass = NULL;
+
+ g_return_if_fail(PURPLE_IS_HASH(hash));
+
+ klass = PURPLE_HASH_GET_CLASS(hash);
+
+ if(klass && klass->append)
+ klass->append(hash, data, len);
+ else
+ purple_debug_warning("hash", "the %s hash does not implement the "
+ "append method\n",
+ klass->get_name ? klass->get_name(hash) : "");
+}
+
+/**
+ * purple_hash_digest:
+ * @hash: The hash to digest
+ * @in_len: The length of the buffer
+ * @digest: The return buffer for the digest
+ * @out_len: The length of the returned value
+ *
+ * Digests a hash
+ *
+ * Return Value: TRUE if the digest was successful, FALSE otherwise.
+ */
+gboolean
+purple_hash_digest(PurpleHash *hash, guchar digest[], size_t len)
+{
+ PurpleHashClass *klass = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_HASH(hash), FALSE);
+
+ klass = PURPLE_HASH_GET_CLASS(hash);
+
+ if(klass && klass->digest)
+ return klass->digest(hash, digest, len);
+ else
+ purple_debug_warning("hash", "the %s hash does not implement the "
+ "digest method\n",
+ klass->get_name ? klass->get_name(hash) : "");
+
+ return FALSE;
+}
+
+/**
+ * purple_hash_digest_to_str:
+ * @hash: The hash to get a digest from
+ * @in_len: The length of the buffer
+ * @digest_s: The return buffer for the string digest
+ * @out_len: The length of the returned value
+ *
+ * Converts a guchar digest into a hex string
+ *
+ * Return Value: TRUE if the digest was successful, FALSE otherwise.
+ */
+gboolean
+purple_hash_digest_to_str(PurpleHash *hash, gchar digest_s[], size_t len)
+{
+ /* 8k is a bit excessive, will tweak later. */
+ guchar digest[BUF_LEN * 4];
+ gint n = 0;
+ size_t digest_size;
+
+ g_return_val_if_fail(hash, FALSE);
+ g_return_val_if_fail(digest_s, FALSE);
+
+ digest_size = purple_hash_get_digest_size(hash);
+
+ g_return_val_if_fail(digest_size <= BUF_LEN * 4, FALSE);
+
+ if(!purple_hash_digest(hash, digest, sizeof(digest)))
+ return FALSE;
+
+ /* Every digest byte occupies 2 chars + the NUL at the end. */
+ g_return_val_if_fail(digest_size * 2 + 1 <= len, FALSE);
+
+ for(n = 0; n < digest_size; n++)
+ sprintf(digest_s + (n * 2), "%02x", digest[n]);
+
+ digest_s[n * 2] = '\0';
+
+ return TRUE;
+}
+
+size_t
+purple_hash_get_digest_size(PurpleHash *hash)
+{
+ PurpleHashClass *klass = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_HASH(hash), FALSE);
+
+ klass = PURPLE_HASH_GET_CLASS(hash);
+
+ if(klass && klass->get_digest_size)
+ return klass->get_digest_size(hash);
+ else
+ purple_debug_warning("hash", "the %s hash does not implement the "
+ "get_digest_size method\n",
+ klass->get_name ? klass->get_name(hash) : "");
+
+ return FALSE;
+}
+
+/**
+ * purple_hash_get_block_size:
+ * @hash: The hash whose block size to get
+ *
+ * Gets the block size of a hash
+ *
+ * Return Value: The block size of the hash
+ */
+size_t
+purple_hash_get_block_size(PurpleHash *hash)
+{
+ PurpleHashClass *klass = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_HASH(hash), -1);
+
+ klass = PURPLE_HASH_GET_CLASS(hash);
+
+ if(klass && klass->get_block_size)
+ return klass->get_block_size(hash);
+ else
+ purple_debug_warning("hash", "the %s hash does not implement the "
+ "get_block_size method\n",
+ klass->get_name ? klass->get_name(hash) : "");
+
+ return -1;
+}
diff --git a/libpurple/hash.h b/libpurple/hash.h
new file mode 100644
index 0000000000..640ebfbfab
--- /dev/null
+++ b/libpurple/hash.h
@@ -0,0 +1,181 @@
+/**
+ * @file hash.h Purple Hash API
+ * @ingroup core
+ * @see @ref hash-signals
+ */
+
+/* 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 PURPLE_HASH_H
+#define PURPLE_HASH_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <string.h>
+
+#include "internal.h"
+
+#define PURPLE_TYPE_HASH (purple_hash_get_type())
+#define PURPLE_HASH(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_HASH, PurpleHash))
+#define PURPLE_HASH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_HASH, PurpleHashClass))
+#define PURPLE_IS_HASH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_HASH))
+#define PURPLE_IS_HASH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_HASH))
+#define PURPLE_HASH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_HASH, PurpleHashClass))
+
+typedef struct _PurpleHash PurpleHash;
+typedef struct _PurpleHashClass PurpleHashClass;
+
+/**
+ * PurpleHash:
+ *
+ * Purple Hash is an opaque data structure and should not be used directly.
+ */
+struct _PurpleHash {
+ /*< private >*/
+ GObject gparent;
+};
+
+/**
+ * PurpleHashClass:
+ *
+ * The base class for all #PurpleHash's.
+ */
+struct _PurpleHashClass {
+ /*< private >*/
+ GObjectClass parent_class;
+
+ /** The reset function */
+ void (*reset)(PurpleHash *hash);
+
+ /** The reset state function */
+ void (*reset_state)(PurpleHash *hash);
+
+ /** The append data function */
+ void (*append)(PurpleHash *hash, const guchar *data, size_t len);
+
+ /** The digest function */
+ gboolean (*digest)(PurpleHash *hash, guchar digest[], size_t len);
+
+ /** The get digest size function */
+ size_t (*get_digest_size)(PurpleHash *hash);
+
+ /** The get block size function */
+ size_t (*get_block_size)(PurpleHash *hash);
+
+ /** The get hash name function */
+ const gchar* (*get_name)(PurpleHash *hash);
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+/*****************************************************************************/
+/** @name PurpleHash API */
+/*****************************************************************************/
+/*@{*/
+
+/**
+ * Returns the GType for the Hash object.
+ */
+GType purple_hash_get_type(void);
+
+/**
+ * Gets a hash's name
+ *
+ * @param hash The hash
+ *
+ * @return The hash's name
+ */
+const gchar *purple_hash_get_name(PurpleHash *hash);
+
+/**
+ * Resets a hash to it's default value
+ * @note If you have set an IV you will have to set it after resetting
+ *
+ * @param hash The hash
+ */
+void purple_hash_reset(PurpleHash *hash);
+
+/**
+ * Resets a hash state to it's default value, but doesn't touch stateless
+ * configuration.
+ *
+ * That means, IV and digest will be wiped out, but keys, ops or salt
+ * will remain untouched.
+ *
+ * @param hash The hash
+ */
+void purple_hash_reset_state(PurpleHash *hash);
+
+/**
+ * Appends data to the hash context
+ *
+ * @param hash The hash
+ * @param data The data to append
+ * @param len The length of the data
+ */
+void purple_hash_append(PurpleHash *hash, const guchar *data, size_t len);
+
+/**
+ * Digests a hash context
+ *
+ * @param hash The hash
+ * @param digest The return buffer for the digest
+ * @param len The length of the buffer
+ */
+gboolean purple_hash_digest(PurpleHash *hash, guchar digest[], size_t len);
+
+/**
+ * Converts a guchar digest into a hex string
+ *
+ * @param hash The hash
+ * @param digest_s The return buffer for the string digest
+ * @param len The length of the buffer
+ */
+gboolean purple_hash_digest_to_str(PurpleHash *hash, gchar digest_s[], size_t len);
+
+/**
+ * Gets the digest size of a hash
+ *
+ * @param hash The hash whose digest size to get
+ *
+ * @return The digest size of the hash
+ */
+size_t purple_hash_get_digest_size(PurpleHash *hash);
+
+/**
+ * Gets the block size of a hash
+ *
+ * @param hash The hash whose block size to get
+ *
+ * @return The block size of the hash
+ */
+size_t purple_hash_get_block_size(PurpleHash *hash);
+
+/*@}*/
+
+G_END_DECLS
+
+#endif /* PURPLE_HASH_H */
diff --git a/libpurple/imgstore.c b/libpurple/imgstore.c
index ec03c54ff0..d608ee55dc 100644
--- a/libpurple/imgstore.c
+++ b/libpurple/imgstore.c
@@ -214,10 +214,8 @@ purple_imgstore_init()
void *handle = purple_imgstore_get_handle();
purple_signal_register(handle, "image-deleting",
- purple_marshal_VOID__POINTER, NULL,
- 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_STORED_IMAGE));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE,
+ 1, PURPLE_TYPE_STORED_IMAGE);
imgstore = g_hash_table_new(g_int_hash, g_int_equal);
}
@@ -229,3 +227,30 @@ purple_imgstore_uninit()
purple_signals_unregister_by_instance(purple_imgstore_get_handle());
}
+
+static PurpleStoredImage *
+purple_imgstore_copy(PurpleStoredImage *img)
+{
+ PurpleStoredImage *img_copy;
+
+ g_return_val_if_fail(img != NULL, NULL);
+
+ img_copy = g_new(PurpleStoredImage, 1);
+ *img_copy = *img;
+
+ return img_copy;
+}
+
+GType
+purple_imgstore_get_type(void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_boxed_type_register_static("PurpleStoredImage",
+ (GBoxedCopyFunc)purple_imgstore_copy,
+ (GBoxedFreeFunc)g_free);
+ }
+
+ return type;
+}
diff --git a/libpurple/imgstore.h b/libpurple/imgstore.h
index 4782ba2cd2..6c640db9c8 100644
--- a/libpurple/imgstore.h
+++ b/libpurple/imgstore.h
@@ -37,9 +37,18 @@
*/
typedef struct _PurpleStoredImage PurpleStoredImage;
+#define PURPLE_TYPE_STORED_IMAGE (purple_imgstore_get_type())
+
G_BEGIN_DECLS
/**
+ * Returns the GType for the PurpleStoredImage boxed structure.
+ * TODO Boxing of PurpleStoredImage is a temporary solution to having a GType
+ * for stored images. This should rather be a GObject instead of a GBoxed.
+ */
+GType purple_imgstore_get_type(void);
+
+/**
* Create a new PurpleStoredImage.
*
* The image is not added to the image store and no ID is assigned. If you
diff --git a/libpurple/internal.h b/libpurple/internal.h
index a7b9d1f35f..2a4c0a65b4 100644
--- a/libpurple/internal.h
+++ b/libpurple/internal.h
@@ -156,7 +156,7 @@
/* INTERNAL FUNCTIONS */
-#include "account.h"
+#include "accounts.h"
#include "connection.h"
/* This is for the accounts code to notify the buddy icon code that
@@ -203,14 +203,36 @@ void _purple_connection_new(PurpleAccount *account, gboolean regist,
void _purple_connection_new_unregister(PurpleAccount *account, const char *password,
PurpleAccountUnregistrationCb cb, void *user_data);
/**
- * Disconnects and destroys a PurpleConnection.
+ * Checks if a connection is disconnecting, and should not attempt to reconnect.
*
- * @note 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.
+ * @note This function should only be called by purple_account_set_enabled()
+ * in account.c.
+ *
+ * @param gc The connection to check
+ */
+gboolean _purple_connection_wants_to_die(const PurpleConnection *gc);
+
+/**
+ * Adds a chat to the active chats list of a connection
+ *
+ * @note This function should only be called by serv_got_joined_chat()
+ * in server.c.
+ *
+ * @param gc The connection
+ * @param chat The chat conversation to add
+ */
+void _purple_connection_add_active_chat(PurpleConnection *gc,
+ PurpleChatConversation *chat);
+/**
+ * Removes a chat from the active chats list of a connection
+ *
+ * @note This function should only be called by serv_got_chat_left()
+ * in server.c.
*
- * @param gc The purple connection to destroy.
+ * @param gc The connection
+ * @param chat The chat conversation to remove
*/
-void _purple_connection_destroy(PurpleConnection *gc);
+void _purple_connection_remove_active_chat(PurpleConnection *gc,
+ PurpleChatConversation *chat);
#endif /* _PURPLE_INTERNAL_H_ */
diff --git a/libpurple/keyring.c b/libpurple/keyring.c
index 5ab9b425a8..abcf0639a0 100644
--- a/libpurple/keyring.c
+++ b/libpurple/keyring.c
@@ -1245,12 +1245,9 @@ purple_keyring_init(void)
* @param keyring_id The keyring ID.
* @param keyring The keyring.
*/
- purple_signal_register(purple_keyring_get_handle(),
- "keyring-register",
- purple_marshal_VOID__POINTER_POINTER,
- NULL, 2,
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_BOXED, "PurpleKeyring *"));
+ purple_signal_register(purple_keyring_get_handle(), "keyring-register",
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2, G_TYPE_STRING,
+ PURPLE_TYPE_KEYRING);
/* void keyring_unregister(const char *keyring_id,
* PurpleKeyring * keyring);
@@ -1260,12 +1257,9 @@ purple_keyring_init(void)
* @param keyring_id The keyring ID.
* @param keyring The keyring.
*/
- purple_signal_register(purple_keyring_get_handle(),
- "keyring-unregister",
- purple_marshal_VOID__POINTER_POINTER,
- NULL, 2,
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_BOXED, "PurpleKeyring *"));
+ purple_signal_register(purple_keyring_get_handle(), "keyring-unregister",
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2, G_TYPE_STRING,
+ PURPLE_TYPE_KEYRING);
/* void password_migration(PurpleAccount* account);
*
@@ -1274,11 +1268,8 @@ purple_keyring_init(void)
*
* @param account The account.
*/
- purple_signal_register(purple_keyring_get_handle(),
- "password-migration",
- purple_marshal_VOID__POINTER,
- NULL, 1,
- purple_value_new(PURPLE_TYPE_BOXED, "PurpleAccount *"));
+ purple_signal_register(purple_keyring_get_handle(), "password-migration",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1, PURPLE_TYPE_ACCOUNT);
touse = purple_prefs_get_string("/purple/keyring/active");
if (touse == NULL) {
@@ -1356,3 +1347,33 @@ purple_keyring_get_handle(void)
return &handle;
}
+
+static PurpleKeyring *
+purple_keyring_copy(PurpleKeyring *keyring)
+{
+ PurpleKeyring *keyring_copy;
+
+ g_return_val_if_fail(keyring != NULL, NULL);
+
+ keyring_copy = purple_keyring_new();
+ *keyring_copy = *keyring;
+
+ keyring_copy->name = g_strdup(keyring->name);
+ keyring_copy->id = g_strdup(keyring->id);
+
+ return keyring_copy;
+}
+
+GType
+purple_keyring_get_type(void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_boxed_type_register_static("PurpleKeyring",
+ (GBoxedCopyFunc)purple_keyring_copy,
+ (GBoxedFreeFunc)purple_keyring_free);
+ }
+
+ return type;
+}
diff --git a/libpurple/keyring.h b/libpurple/keyring.h
index 9bed5fe5e6..059a282cba 100644
--- a/libpurple/keyring.h
+++ b/libpurple/keyring.h
@@ -30,6 +30,8 @@
#include "account.h"
#include "request.h"
+#define PURPLE_TYPE_KEYRING (purple_keyring_get_type())
+
/**
* Default keyring ID.
*/
@@ -358,6 +360,11 @@ purple_keyring_apply_settings(void *notify_handle, PurpleRequestFields *fields);
/*@{*/
/**
+ * Returns the GType for the PurpleKeyring boxed structure.
+ */
+GType purple_keyring_get_type(void);
+
+/**
* Creates a new keyring wrapper.
*/
PurpleKeyring *
diff --git a/libpurple/log.c b/libpurple/log.c
index 523676e501..76bb7e74b8 100644
--- a/libpurple/log.c
+++ b/libpurple/log.c
@@ -700,17 +700,16 @@ void purple_log_init(void)
#else
#error Unknown size of time_t
#endif
- purple_value_new(PURPLE_TYPE_STRING), 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_LOG),
+ G_TYPE_STRING, 3,
+ PURPLE_TYPE_LOG,
#if SIZEOF_TIME_T == 4
- purple_value_new(PURPLE_TYPE_INT),
+ G_TYPE_INT,
#elif SIZEOF_TIME_T == 8
- purple_value_new(PURPLE_TYPE_INT64),
+ G_TYPE_INT64,
#else
# error Unknown size of time_t
#endif
- purple_value_new(PURPLE_TYPE_BOOLEAN));
+ G_TYPE_BOOLEAN);
purple_prefs_connect_callback(NULL, "/purple/logging/format",
logger_pref_cb, NULL);
@@ -745,6 +744,33 @@ purple_log_uninit(void)
g_hash_table_destroy(logsize_users_decayed);
}
+static PurpleLog *
+purple_log_copy(PurpleLog *log)
+{
+ PurpleLog *log_copy;
+
+ g_return_val_if_fail(log != NULL, NULL);
+
+ log_copy = g_new(PurpleLog, 1);
+ *log_copy = *log;
+
+ return log_copy;
+}
+
+GType
+purple_log_get_type(void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_boxed_type_register_static("PurpleLog",
+ (GBoxedCopyFunc)purple_log_copy,
+ (GBoxedFreeFunc)g_free);
+ }
+
+ return type;
+}
+
/****************************************************************************
* LOGGERS ******************************************************************
****************************************************************************/
@@ -1150,7 +1176,7 @@ static void log_get_log_sets_common(GHashTable *sets)
/* Determine if this (account, name) combination exists as a buddy. */
if (account != NULL && *name != '\0')
- set->buddy = (purple_find_buddy(account, name) != NULL);
+ set->buddy = (purple_blist_find_buddy(account, name) != NULL);
else
set->buddy = FALSE;
@@ -2025,14 +2051,14 @@ static void old_logger_get_log_sets(PurpleLogSetCallback cb, GHashTable *sets)
!found && gnode != NULL;
gnode = purple_blist_node_get_sibling_next(gnode))
{
- if (!PURPLE_BLIST_NODE_IS_GROUP(gnode))
+ if (!PURPLE_IS_GROUP(gnode))
continue;
for (cnode = purple_blist_node_get_first_child(gnode);
!found && cnode != NULL;
cnode = purple_blist_node_get_sibling_next(cnode))
{
- if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode))
+ if (!PURPLE_IS_CONTACT(cnode))
continue;
for (bnode = purple_blist_node_get_first_child(cnode);
diff --git a/libpurple/log.h b/libpurple/log.h
index 1e12844d5a..71939ecc9a 100644
--- a/libpurple/log.h
+++ b/libpurple/log.h
@@ -29,6 +29,7 @@
#include <stdio.h>
+#define PURPLE_TYPE_LOG (purple_log_get_type())
/********************************************************
* DATA STRUCTURES **************************************
@@ -189,6 +190,13 @@ G_BEGIN_DECLS
/*@{*/
/**
+ * Returns the GType for the PurpleLog boxed structure.
+ * TODO Boxing of PurpleLog is a temporary solution to having a GType for
+ * logs. This should rather be a GObject instead of a GBoxed.
+ */
+GType purple_log_get_type(void);
+
+/**
* Creates a new log
*
* @param type The type of log this is.
diff --git a/libpurple/media.c b/libpurple/media.c
index d8bba699cf..fd6a981fff 100644
--- a/libpurple/media.c
+++ b/libpurple/media.c
@@ -44,23 +44,6 @@
typedef struct _PurpleMediaSession PurpleMediaSession;
/** @copydoc _PurpleMediaStream */
typedef struct _PurpleMediaStream PurpleMediaStream;
-/** @copydoc _PurpleMediaClass */
-typedef struct _PurpleMediaClass PurpleMediaClass;
-/** @copydoc _PurpleMediaPrivate */
-typedef struct _PurpleMediaPrivate PurpleMediaPrivate;
-
-/** The media class */
-struct _PurpleMediaClass
-{
- GObjectClass parent_class; /**< The parent class. */
-};
-
-/** The media class's private data */
-struct _PurpleMedia
-{
- GObject parent; /**< The parent of this object. */
- PurpleMediaPrivate *priv; /**< The private data of this object. */
-};
struct _PurpleMediaSession
{
@@ -215,9 +198,8 @@ purple_media_class_init (PurpleMediaClass *klass)
G_PARAM_READABLE));
g_object_class_install_property(gobject_class, PROP_ACCOUNT,
- g_param_spec_pointer("account",
- "PurpleAccount",
- "The account this media session is on.",
+ g_param_spec_object("account", "PurpleAccount",
+ "The account this media session is on.", PURPLE_TYPE_ACCOUNT,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
g_object_class_install_property(gobject_class, PROP_CONFERENCE_TYPE,
@@ -377,7 +359,7 @@ purple_media_set_property (GObject *object, guint prop_id, const GValue *value,
media->priv->manager = g_value_dup_object(value);
break;
case PROP_ACCOUNT:
- media->priv->account = g_value_get_pointer(value);
+ media->priv->account = g_value_get_object(value);
break;
case PROP_CONFERENCE_TYPE:
media->priv->conference_type =
@@ -438,7 +420,7 @@ purple_media_get_property (GObject *object, guint prop_id, GValue *value, GParam
g_value_set_object(value, media->priv->backend);
break;
case PROP_ACCOUNT:
- g_value_set_pointer(value, media->priv->account);
+ g_value_set_object(value, media->priv->account);
break;
case PROP_CONFERENCE_TYPE:
g_value_set_string(value,
diff --git a/libpurple/media.h b/libpurple/media.h
index b55ed14f69..243f49691e 100644
--- a/libpurple/media.h
+++ b/libpurple/media.h
@@ -41,12 +41,39 @@
#define PURPLE_IS_MEDIA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_MEDIA))
#define PURPLE_MEDIA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_MEDIA, PurpleMediaClass))
-/** An opaque structure representing a media call. */
+/** A structure representing a media call. */
typedef struct _PurpleMedia PurpleMedia;
#include "signals.h"
#include "util.h"
+#ifdef USE_VV
+
+/** @copydoc _PurpleMediaClass */
+typedef struct _PurpleMediaClass PurpleMediaClass;
+/** @copydoc _PurpleMediaPrivate */
+typedef struct _PurpleMediaPrivate PurpleMediaPrivate;
+
+/** The media instance */
+struct _PurpleMedia
+{
+ GObject parent; /**< The parent of this object. */
+ PurpleMediaPrivate *priv; /**< The private data of this object. */
+};
+
+/** The media class */
+struct _PurpleMediaClass
+{
+ GObjectClass parent_class; /**< The parent class. */
+
+ void (*purple_reserved1)(void);
+ void (*purple_reserved2)(void);
+ void (*purple_reserved3)(void);
+ void (*purple_reserved4)(void);
+};
+
+#endif
+
G_BEGIN_DECLS
/**
diff --git a/libpurple/network.c b/libpurple/network.c
index 4ed7711977..4cae6ad676 100644
--- a/libpurple/network.c
+++ b/libpurple/network.c
@@ -1221,7 +1221,7 @@ purple_network_init(void)
#endif
purple_signal_register(purple_network_get_handle(), "network-configuration-changed",
- purple_marshal_VOID, NULL, 0);
+ purple_marshal_VOID, G_TYPE_NONE, 0);
purple_pmp_init();
purple_upnp_init();
diff --git a/libpurple/notify.c b/libpurple/notify.c
index 7d94b5da2e..c513e96a95 100644
--- a/libpurple/notify.c
+++ b/libpurple/notify.c
@@ -453,7 +453,7 @@ purple_notify_user_info_entry_new(const char *label, const char *value)
return user_info_entry;
}
-static void
+void
purple_notify_user_info_entry_destroy(PurpleNotifyUserInfoEntry *user_info_entry)
{
g_return_if_fail(user_info_entry != NULL);
@@ -692,6 +692,42 @@ purple_notify_user_info_remove_last_item(PurpleNotifyUserInfo *user_info)
purple_notify_user_info_entry_destroy(entry);
}
+static PurpleNotifyUserInfo *
+purple_notify_user_info_copy(PurpleNotifyUserInfo *user_info)
+{
+ PurpleNotifyUserInfo *user_info_copy;
+ GList *l;
+
+ g_return_val_if_fail(user_info != NULL, NULL);
+
+ user_info_copy = purple_notify_user_info_new();
+
+ for (l = user_info->entries.head; l != NULL; l = l->next) {
+ PurpleNotifyUserInfoEntry *new_entry, *user_info_entry = l->data;
+
+ new_entry = purple_notify_user_info_entry_new(user_info_entry->label,
+ user_info_entry->value);
+ new_entry->type = user_info_entry->type;
+ g_queue_push_tail(&user_info_copy->entries, new_entry);
+ }
+
+ return user_info_copy;
+}
+
+GType
+purple_notify_user_info_get_type(void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_boxed_type_register_static("PurpleNotifyUserInfo",
+ (GBoxedCopyFunc)purple_notify_user_info_copy,
+ (GBoxedFreeFunc)purple_notify_user_info_destroy);
+ }
+
+ return type;
+}
+
void *
purple_notify_uri(void *handle, const char *uri)
{
@@ -804,30 +840,22 @@ purple_notify_init(void)
gpointer handle = purple_notify_get_handle();
purple_signal_register(handle, "displaying-email-notification",
- purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER, NULL, 4,
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING));
+ purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER,
+ G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING);
purple_signal_register(handle, "displaying-emails-notification",
- purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT, NULL, 5,
- purple_value_new(PURPLE_TYPE_POINTER),
- purple_value_new(PURPLE_TYPE_POINTER),
- purple_value_new(PURPLE_TYPE_POINTER),
- purple_value_new(PURPLE_TYPE_POINTER),
- purple_value_new(PURPLE_TYPE_UINT));
+ purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT,
+ G_TYPE_NONE, 5, G_TYPE_POINTER, G_TYPE_POINTER,
+ G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_UINT);
purple_signal_register(handle, "displaying-emails-clear",
- purple_marshal_VOID, NULL, 0);
+ purple_marshal_VOID, G_TYPE_NONE, 0);
purple_signal_register(handle, "displaying-userinfo",
- purple_marshal_VOID__POINTER_POINTER_POINTER, NULL, 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_USERINFO));
+ purple_marshal_VOID__POINTER_POINTER_POINTER,
+ G_TYPE_NONE, 3, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ PURPLE_TYPE_NOTIFY_USER_INFO);
}
void
diff --git a/libpurple/notify.h b/libpurple/notify.h
index ea7ab2b7c5..0c8ebc2f18 100644
--- a/libpurple/notify.h
+++ b/libpurple/notify.h
@@ -32,7 +32,10 @@
#include <glib.h>
typedef struct _PurpleNotifyUserInfoEntry PurpleNotifyUserInfoEntry;
+
+#define PURPLE_TYPE_NOTIFY_USER_INFO (purple_notify_user_info_get_type())
typedef struct _PurpleNotifyUserInfo PurpleNotifyUserInfo;
+
/** @copydoc _PurpleNotifySearchColumn */
typedef struct _PurpleNotifySearchColumn PurpleNotifySearchColumn;
@@ -422,6 +425,11 @@ void *purple_notify_userinfo(PurpleConnection *gc, const char *who,
gpointer user_data);
/**
+ * Returns the GType for the PurpleNotifyUserInfo boxed structure.
+ */
+GType purple_notify_user_info_get_type(void);
+
+/**
* Create a new PurpleNotifyUserInfo which is suitable for passing to
* purple_notify_userinfo()
*
@@ -501,21 +509,14 @@ void purple_notify_user_info_prepend_pair_html(PurpleNotifyUserInfo *user_info,
*/
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_)
/**
* Remove a PurpleNotifyUserInfoEntry from a PurpleNotifyUserInfo object
* without freeing the entry.
*
* @param user_info The PurpleNotifyUserInfo
* @param user_info_entry The PurpleNotifyUserInfoEntry
- *
- * @deprecated Nothing is using this function and it should be removed
- * in 3.0.0. Or, if we decide we want to keep it in 3.0.0
- * then we should make purple_notify_user_info_entry_destroy
- * public so that entries can be free'd after they're removed.
*/
void purple_notify_user_info_remove_entry(PurpleNotifyUserInfo *user_info, PurpleNotifyUserInfoEntry *user_info_entry);
-#endif
/**
* Create a new PurpleNotifyUserInfoEntry
@@ -541,6 +542,13 @@ void purple_notify_user_info_remove_entry(PurpleNotifyUserInfo *user_info, Purpl
PurpleNotifyUserInfoEntry *purple_notify_user_info_entry_new(const char *label, const char *value);
/**
+ * Destroy a PurpleNotifyUserInfoEntry
+ *
+ * @param user_info_entry The PurpleNotifyUserInfoEntry
+ */
+void purple_notify_user_info_entry_destroy(PurpleNotifyUserInfoEntry *user_info_entry);
+
+/**
* Add a section break. A UI might display this as a horizontal line.
*
* @param user_info The PurpleNotifyUserInfo
diff --git a/libpurple/ntlm.c b/libpurple/ntlm.c
index 82a865c9b4..0934d92a33 100644
--- a/libpurple/ntlm.c
+++ b/libpurple/ntlm.c
@@ -28,8 +28,11 @@
#include "util.h"
#include "ntlm.h"
-#include "cipher.h"
#include "debug.h"
+
+#include "ciphers/descipher.h"
+#include "ciphers/md4hash.h"
+
#include <string.h>
#define NTLM_NEGOTIATE_NTLM2_KEY 0x00080000
@@ -191,13 +194,11 @@ static void
des_ecb_encrypt(const guint8 *plaintext, guint8 *result, const guint8 *key)
{
PurpleCipher *cipher;
- PurpleCipherContext *context;
- cipher = purple_ciphers_find_cipher("des");
- context = purple_cipher_context_new(cipher, NULL);
- purple_cipher_context_set_key(context, key, 8);
- purple_cipher_context_encrypt(context, plaintext, 8, result, 8);
- purple_cipher_context_destroy(context);
+ cipher = purple_des_cipher_new();
+ purple_cipher_set_key(cipher, key, 8);
+ purple_cipher_encrypt(cipher, plaintext, 8, result, 8);
+ g_object_unref(cipher);
}
/*
@@ -273,8 +274,7 @@ purple_ntlm_gen_type3(const gchar *username, const gchar *passw, const gchar *ho
unsigned char magic[] = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
unsigned char nt_hpw[21];
char nt_pw[128];
- PurpleCipher *cipher;
- PurpleCipherContext *context;
+ PurpleHash *hash;
char *tmp;
int idx;
gchar *ucs2le;
@@ -375,11 +375,10 @@ purple_ntlm_gen_type3(const gchar *username, const gchar *passw, const gchar *ho
nt_pw[2 * idx + 1] = 0;
}
- cipher = purple_ciphers_find_cipher("md4");
- context = purple_cipher_context_new(cipher, NULL);
- purple_cipher_context_append(context, (guint8 *)nt_pw, 2 * lennt);
- purple_cipher_context_digest(context, nt_hpw, sizeof(nt_hpw));
- purple_cipher_context_destroy(context);
+ hash = purple_md4_hash_new();
+ purple_hash_append(hash, (guint8 *)nt_pw, 2 * lennt);
+ purple_hash_digest(hash, nt_hpw, sizeof(nt_hpw));
+ g_object_unref(hash);
memset(nt_hpw + 16, 0, 5);
calc_resp(nt_hpw, nonce, nt_resp);
diff --git a/libpurple/plugin.c b/libpurple/plugin.c
index 1f92c4b34a..40739d518e 100644
--- a/libpurple/plugin.c
+++ b/libpurple/plugin.c
@@ -49,8 +49,8 @@ typedef struct
PurpleSignalMarshalFunc marshal;
int num_params;
- PurpleValue **params;
- PurpleValue *ret_value;
+ GType *param_types;
+ GType ret_type;
} PurplePluginIpcCommand;
@@ -962,26 +962,15 @@ static void
destroy_ipc_info(void *data)
{
PurplePluginIpcCommand *ipc_command = (PurplePluginIpcCommand *)data;
- int i;
-
- if (ipc_command->params != NULL)
- {
- for (i = 0; i < ipc_command->num_params; i++)
- purple_value_destroy(ipc_command->params[i]);
-
- g_free(ipc_command->params);
- }
-
- if (ipc_command->ret_value != NULL)
- purple_value_destroy(ipc_command->ret_value);
+ g_free(ipc_command->param_types);
g_free(ipc_command);
}
gboolean
purple_plugin_ipc_register(PurplePlugin *plugin, const char *command,
PurpleCallback func, PurpleSignalMarshalFunc marshal,
- PurpleValue *ret_value, int num_params, ...)
+ GType ret_type, int num_params, ...)
{
PurplePluginIpcInfo *ipc_info;
PurplePluginIpcCommand *ipc_command;
@@ -1004,19 +993,19 @@ purple_plugin_ipc_register(PurplePlugin *plugin, const char *command,
ipc_command->func = func;
ipc_command->marshal = marshal;
ipc_command->num_params = num_params;
- ipc_command->ret_value = ret_value;
+ ipc_command->ret_type = ret_type;
if (num_params > 0)
{
va_list args;
int i;
- ipc_command->params = g_new0(PurpleValue *, num_params);
+ ipc_command->param_types = g_new0(GType, num_params);
va_start(args, num_params);
for (i = 0; i < num_params; i++)
- ipc_command->params[i] = va_arg(args, PurpleValue *);
+ ipc_command->param_types[i] = va_arg(args, GType);
va_end(args);
}
@@ -1079,9 +1068,9 @@ purple_plugin_ipc_unregister_all(PurplePlugin *plugin)
}
gboolean
-purple_plugin_ipc_get_params(PurplePlugin *plugin, const char *command,
- PurpleValue **ret_value, int *num_params,
- PurpleValue ***params)
+purple_plugin_ipc_get_types(PurplePlugin *plugin, const char *command,
+ GType *ret_type, int *num_params,
+ GType **param_types)
{
PurplePluginIpcInfo *ipc_info;
PurplePluginIpcCommand *ipc_command;
@@ -1105,11 +1094,11 @@ purple_plugin_ipc_get_params(PurplePlugin *plugin, const char *command,
if (num_params != NULL)
*num_params = ipc_command->num_params;
- if (params != NULL)
- *params = ipc_command->params;
+ if (param_types != NULL)
+ *param_types = ipc_command->param_types;
- if (ret_value != NULL)
- *ret_value = ipc_command->ret_value;
+ if (ret_type != NULL)
+ *ret_type = ipc_command->ret_type;
return TRUE;
}
@@ -1170,14 +1159,10 @@ purple_plugins_init(void) {
purple_signal_register(handle, "plugin-load",
purple_marshal_VOID__POINTER,
- NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_PLUGIN));
+ G_TYPE_NONE, 1, PURPLE_TYPE_PLUGIN);
purple_signal_register(handle, "plugin-unload",
purple_marshal_VOID__POINTER,
- NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_PLUGIN));
+ G_TYPE_NONE, 1, PURPLE_TYPE_PLUGIN);
}
void
@@ -1612,3 +1597,30 @@ purple_plugin_action_free(PurplePluginAction *action)
g_free(action->label);
g_free(action);
}
+
+static PurplePlugin *
+purple_plugin_copy(PurplePlugin *plugin)
+{
+ PurplePlugin *plugin_copy;
+
+ g_return_val_if_fail(plugin != NULL, NULL);
+
+ plugin_copy = g_new(PurplePlugin, 1);
+ *plugin_copy = *plugin;
+
+ return plugin_copy;
+}
+
+GType
+purple_plugin_get_type(void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_boxed_type_register_static("PurplePlugin",
+ (GBoxedCopyFunc)purple_plugin_copy,
+ (GBoxedFreeFunc)g_free);
+ }
+
+ return type;
+}
diff --git a/libpurple/plugin.h b/libpurple/plugin.h
index d4b543cadd..6e9b2f5ec4 100644
--- a/libpurple/plugin.h
+++ b/libpurple/plugin.h
@@ -32,7 +32,9 @@
#include <glib.h>
#include <gmodule.h>
#include "signals.h"
-#include "value.h"
+
+/** Returns the GType for the PurplePlugin boxed structure */
+#define PURPLE_TYPE_PLUGIN (purple_plugin_get_type())
/** @copydoc _PurplePlugin */
typedef struct _PurplePlugin PurplePlugin;
@@ -247,6 +249,13 @@ G_BEGIN_DECLS
/*@{*/
/**
+ * Returns the GType for the PurplePlugin boxed structure.
+ * TODO Boxing of PurplePlugin is a temporary solution to having a GType for
+ * plugins. This should rather be a GObject instead of a GBoxed.
+ */
+GType purple_plugin_get_type(void);
+
+/**
* Creates a new plugin structure.
*
* @param native Whether or not the plugin is native.
@@ -437,7 +446,7 @@ const gchar *purple_plugin_get_homepage(const PurplePlugin *plugin);
* @param command The name of the command.
* @param func The function to execute.
* @param marshal The marshalling function.
- * @param ret_value The return value type.
+ * @param ret_type The return type.
* @param num_params The number of parameters.
* @param ... The parameter types.
*
@@ -447,7 +456,7 @@ const gchar *purple_plugin_get_homepage(const PurplePlugin *plugin);
gboolean purple_plugin_ipc_register(PurplePlugin *plugin, const char *command,
PurpleCallback func,
PurpleSignalMarshalFunc marshal,
- PurpleValue *ret_value, int num_params, ...);
+ GType ret_type, int num_params, ...);
/**
* Unregisters an IPC command in a plugin.
@@ -467,17 +476,17 @@ void purple_plugin_ipc_unregister_all(PurplePlugin *plugin);
/**
* Returns a list of value types used for an IPC command.
*
- * @param plugin The plugin.
- * @param command The name of the command.
- * @param ret_value The returned return value.
- * @param num_params The returned number of parameters.
- * @param params The returned list of parameters.
+ * @param plugin The plugin.
+ * @param command The name of the command.
+ * @param ret_type The returned return type.
+ * @param num_params The returned number of parameters.
+ * @param param_types The returned list of parameter types.
*
* @return TRUE if the command was found, or FALSE otherwise.
*/
-gboolean purple_plugin_ipc_get_params(PurplePlugin *plugin, const char *command,
- PurpleValue **ret_value, int *num_params,
- PurpleValue ***params);
+gboolean purple_plugin_ipc_get_types(PurplePlugin *plugin, const char *command,
+ GType *ret_type, int *num_params,
+ GType **param_types);
/**
* Executes an IPC command.
diff --git a/libpurple/plugins/autoaccept.c b/libpurple/plugins/autoaccept.c
index 82b9278912..835574b84b 100644
--- a/libpurple/plugins/autoaccept.c
+++ b/libpurple/plugins/autoaccept.c
@@ -34,7 +34,7 @@
#include <plugin.h>
#include <version.h>
-#include <blist.h>
+#include <buddylist.h>
#include <conversation.h>
#include <ft.h>
#include <request.h>
@@ -73,7 +73,7 @@ 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, purple_xfer_get_remote_user(xfer), purple_xfer_get_account(xfer)))
+ !purple_conversations_find_im_with_account(purple_xfer_get_remote_user(xfer), purple_xfer_get_account(xfer)))
{
char *message = g_strdup_printf(_("Autoaccepted file transfer of \"%s\" from \"%s\" completed."),
purple_xfer_get_filename(xfer), purple_xfer_get_remote_user(xfer));
@@ -94,13 +94,13 @@ file_recv_request_cb(PurpleXfer *xfer, gpointer handle)
int accept_setting;
account = purple_xfer_get_account(xfer);
- node = PURPLE_BLIST_NODE(purple_find_buddy(account, purple_xfer_get_remote_user(xfer)));
+ node = PURPLE_BLIST_NODE(purple_blist_find_buddy(account, purple_xfer_get_remote_user(xfer)));
/* If person is on buddy list, use the buddy setting; otherwise, use the
stranger setting. */
if (node) {
node = purple_blist_node_get_parent(node);
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CONTACT(node));
+ g_return_if_fail(PURPLE_IS_CONTACT(node));
accept_setting = purple_blist_node_get_int(node, "autoaccept");
} else {
accept_setting = purple_prefs_get_int(PREF_STRANGER);
@@ -182,9 +182,9 @@ file_recv_request_cb(PurpleXfer *xfer, gpointer handle)
static void
save_cb(PurpleBlistNode *node, int choice)
{
- if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (PURPLE_IS_BUDDY(node))
node = purple_blist_node_get_parent(node);
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CONTACT(node));
+ g_return_if_fail(PURPLE_IS_CONTACT(node));
purple_blist_node_set_int(node, "autoaccept", choice);
}
@@ -193,12 +193,12 @@ set_auto_accept_settings(PurpleBlistNode *node, gpointer plugin)
{
char *message;
- if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (PURPLE_IS_BUDDY(node))
node = purple_blist_node_get_parent(node);
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CONTACT(node));
+ g_return_if_fail(PURPLE_IS_CONTACT(node));
message = g_strdup_printf(_("When a file-transfer request arrives from %s"),
- purple_contact_get_alias((PurpleContact *)node));
+ purple_contact_get_alias(PURPLE_CONTACT(node)));
purple_request_choice(plugin, _("Set Autoaccept Setting"), message,
NULL, purple_blist_node_get_int(node, "autoaccept"),
_("_Save"), G_CALLBACK(save_cb),
@@ -208,7 +208,7 @@ set_auto_accept_settings(PurpleBlistNode *node, gpointer plugin)
_("Ask"), FT_ASK,
_("Auto Accept"), FT_ACCEPT,
_("Auto Reject"), FT_REJECT,
- NULL, purple_contact_get_alias((PurpleContact *)node), NULL,
+ NULL, purple_contact_get_alias(PURPLE_CONTACT(node)), NULL,
NULL);
g_free(message);
}
@@ -218,8 +218,8 @@ context_menu(PurpleBlistNode *node, GList **menu, gpointer plugin)
{
PurpleMenuAction *action;
- if (!PURPLE_BLIST_NODE_IS_BUDDY(node) && !PURPLE_BLIST_NODE_IS_CONTACT(node) &&
- !(purple_blist_node_get_flags(node) & PURPLE_BLIST_NODE_FLAG_NO_SAVE))
+ if (!PURPLE_IS_BUDDY(node) && !PURPLE_IS_CONTACT(node) &&
+ !purple_blist_node_is_transient(node))
return;
action = purple_menu_action_new(_("Autoaccept File Transfers..."),
diff --git a/libpurple/plugins/buddynote.c b/libpurple/plugins/buddynote.c
index e7d676215a..a44a82c2d9 100644
--- a/libpurple/plugins/buddynote.c
+++ b/libpurple/plugins/buddynote.c
@@ -58,7 +58,7 @@ buddynote_extended_menu_cb(PurpleBlistNode *node, GList **m)
{
PurpleMenuAction *bna = NULL;
- if (purple_blist_node_get_flags(node) & PURPLE_BLIST_NODE_FLAG_NO_SAVE)
+ if (purple_blist_node_is_transient(node))
return;
*m = g_list_append(*m, bna);
diff --git a/libpurple/plugins/ciphertest.c b/libpurple/plugins/ciphertest.c
index 4fb9771b92..dc516ba824 100644
--- a/libpurple/plugins/ciphertest.c
+++ b/libpurple/plugins/ciphertest.c
@@ -32,10 +32,16 @@
#include <glib.h>
#include <string.h>
-#include "cipher.h"
#include "debug.h"
#include "plugin.h"
#include "version.h"
+#include "util.h"
+
+#include "ciphers/aescipher.h"
+#include "ciphers/md5hash.h"
+#include "ciphers/pbkdf2cipher.h"
+#include "ciphers/sha1hash.h"
+#include "ciphers/sha256hash.h"
struct test {
const gchar *question;
@@ -62,14 +68,13 @@ struct test md5_tests[8] = {
static void
cipher_test_md5(void) {
- PurpleCipher *cipher;
- PurpleCipherContext *context;
+ PurpleHash *hash;
gchar digest[33];
gboolean ret;
gint i = 0;
- cipher = purple_ciphers_find_cipher("md5");
- if(!cipher) {
+ hash = purple_md5_hash_new();
+ if(!hash) {
purple_debug_info("cipher-test",
"could not find md5 cipher, not testing\n");
return;
@@ -77,16 +82,14 @@ cipher_test_md5(void) {
purple_debug_info("cipher-test", "Running md5 tests\n");
- context = purple_cipher_context_new(cipher, NULL);
-
while(md5_tests[i].answer) {
purple_debug_info("cipher-test", "Test %02d:\n", i);
purple_debug_info("cipher-test", "Testing '%s'\n", md5_tests[i].question);
- purple_cipher_context_append(context, (guchar *)md5_tests[i].question,
+ purple_hash_append(hash, (guchar *)md5_tests[i].question,
strlen(md5_tests[i].question));
- ret = purple_cipher_context_digest_to_str(context, digest, sizeof(digest));
+ ret = purple_hash_digest_to_str(hash, digest, sizeof(digest));
if(!ret) {
purple_debug_info("cipher-test", "failed\n");
@@ -96,11 +99,11 @@ cipher_test_md5(void) {
md5_tests[i].answer);
}
- purple_cipher_context_reset(context, NULL);
+ purple_hash_reset(hash);
i++;
}
- purple_cipher_context_destroy(context);
+ g_object_unref(hash);
purple_debug_info("cipher-test", "md5 tests completed\n\n");
}
@@ -118,14 +121,13 @@ struct test sha1_tests[5] = {
static void
cipher_test_sha1(void) {
- PurpleCipher *cipher;
- PurpleCipherContext *context;
+ PurpleHash *hash;
gchar digest[41];
gint i = 0;
gboolean ret;
- cipher = purple_ciphers_find_cipher("sha1");
- if(!cipher) {
+ hash = purple_sha1_hash_new();
+ if(!hash) {
purple_debug_info("cipher-test",
"could not find sha1 cipher, not testing\n");
return;
@@ -133,8 +135,6 @@ cipher_test_sha1(void) {
purple_debug_info("cipher-test", "Running sha1 tests\n");
- context = purple_cipher_context_new(cipher, NULL);
-
while(sha1_tests[i].answer) {
purple_debug_info("cipher-test", "Test %02d:\n", i);
purple_debug_info("cipher-test", "Testing '%s'\n",
@@ -142,7 +142,7 @@ cipher_test_sha1(void) {
sha1_tests[i].question : "'a'x1000, 1000 times");
if(sha1_tests[i].question) {
- purple_cipher_context_append(context, (guchar *)sha1_tests[i].question,
+ purple_hash_append(hash, (guchar *)sha1_tests[i].question,
strlen(sha1_tests[i].question));
} else {
gint j;
@@ -151,10 +151,10 @@ cipher_test_sha1(void) {
memset(buff, 'a', 1000);
for(j = 0; j < 1000; j++)
- purple_cipher_context_append(context, buff, 1000);
+ purple_hash_append(hash, buff, 1000);
}
- ret = purple_cipher_context_digest_to_str(context, digest, sizeof(digest));
+ ret = purple_hash_digest_to_str(hash, digest, sizeof(digest));
if(!ret) {
purple_debug_info("cipher-test", "failed\n");
@@ -164,11 +164,11 @@ cipher_test_sha1(void) {
sha1_tests[i].answer);
}
- purple_cipher_context_reset(context, NULL);
+ purple_hash_reset(hash);
i++;
}
- purple_cipher_context_destroy(context);
+ g_object_unref(hash);
purple_debug_info("cipher-test", "sha1 tests completed\n\n");
}
@@ -192,7 +192,7 @@ cipher_test_digest(void)
purple_debug_info("cipher-test", "Running HTTP Digest tests\n");
- session_key = purple_cipher_http_digest_calculate_session_key(
+ session_key = purple_http_digest_calculate_session_key(
algorithm, username, realm, password,
nonce, client_nonce);
@@ -208,7 +208,7 @@ cipher_test_digest(void)
purple_debug_info("cipher-test", "\tsession_key: Got: %s\n", session_key);
purple_debug_info("cipher-test", "\tsession_key: Wanted: %s\n", "939e7578ed9e3c518a452acee763bce9");
- response = purple_cipher_http_digest_calculate_response(
+ response = purple_http_digest_calculate_response(
algorithm, method, digest_uri, qop, entity,
nonce, nonce_count, client_nonce, session_key);
@@ -362,14 +362,13 @@ cipher_pbkdf2_nss_sha1(const gchar *passphrase, const gchar *salt,
static void
cipher_test_pbkdf2(void)
{
- PurpleCipherContext *context;
+ PurpleCipher *cipher;
+ PurpleHash *hash;
int i = 0;
gboolean fail = FALSE;
purple_debug_info("cipher-test", "Running PBKDF2 tests\n");
- context = purple_cipher_context_new_by_name("pbkdf2", NULL);
-
while (!fail && pbkdf2_tests[i].answer) {
pbkdf2_test *test = &pbkdf2_tests[i];
gchar digest[2 * 32 + 1 + 10];
@@ -384,18 +383,28 @@ cipher_test_pbkdf2(void)
test->passphrase, test->salt, test->hash,
test->iter_count);
- purple_cipher_context_set_option(context, "hash", (gpointer)test->hash);
- purple_cipher_context_set_option(context, "iter_count", GUINT_TO_POINTER(test->iter_count));
- purple_cipher_context_set_option(context, "out_len", GUINT_TO_POINTER(test->out_len));
- purple_cipher_context_set_salt(context, (const guchar*)test->salt, test->salt ? strlen(test->salt): 0);
- purple_cipher_context_set_key(context, (const guchar*)test->passphrase, strlen(test->passphrase));
+ if (!strcmp(test->hash, "sha1"))
+ hash = purple_sha1_hash_new();
+ else if (!strcmp(test->hash, "sha256"))
+ hash = purple_sha256_hash_new();
+ else
+ hash = NULL;
+
+ cipher = purple_pbkdf2_cipher_new(hash);
+
+ g_object_set(G_OBJECT(cipher), "iter_count", GUINT_TO_POINTER(test->iter_count), NULL);
+ g_object_set(G_OBJECT(cipher), "out_len", GUINT_TO_POINTER(test->out_len), NULL);
+ purple_cipher_set_salt(cipher, (const guchar*)test->salt, test->salt ? strlen(test->salt): 0);
+ purple_cipher_set_key(cipher, (const guchar*)test->passphrase, strlen(test->passphrase));
- ret = purple_cipher_context_digest_to_str(context, digest, sizeof(digest));
- purple_cipher_context_reset(context, NULL);
+ ret = purple_cipher_digest_to_str(cipher, digest, sizeof(digest));
+ purple_cipher_reset(cipher);
if (!ret) {
purple_debug_info("cipher-test", "\tfailed\n");
fail = TRUE;
+ g_object_unref(cipher);
+ g_object_unref(hash);
continue;
}
@@ -431,9 +440,10 @@ cipher_test_pbkdf2(void)
purple_debug_info("cipher-test", "\twrong answer\n");
fail = TRUE;
}
- }
- purple_cipher_context_destroy(context);
+ g_object_unref(cipher);
+ g_object_unref(hash);
+ }
if (fail)
purple_debug_info("cipher-test", "PBKDF2 tests FAILED\n\n");
@@ -466,14 +476,14 @@ aes_test aes_tests[] = {
static void
cipher_test_aes(void)
{
- PurpleCipherContext *context;
+ PurpleCipher *cipher;
int i = 0;
gboolean fail = FALSE;
purple_debug_info("cipher-test", "Running AES tests\n");
- context = purple_cipher_context_new_by_name("aes", NULL);
- if (context == NULL) {
+ cipher = purple_aes_cipher_new();
+ if (cipher == NULL) {
purple_debug_error("cipher-test", "AES cipher not found\n");
fail = TRUE;
}
@@ -482,7 +492,7 @@ cipher_test_aes(void)
aes_test *test = &aes_tests[i];
gsize key_size;
guchar *key;
- guchar cipher[1024], decipher[1024];
+ guchar cipher_s[1024], decipher_s[1024];
ssize_t cipher_len, decipher_len;
gchar *cipher_b16, *deciphered;
@@ -493,38 +503,38 @@ cipher_test_aes(void)
i++;
- purple_cipher_context_reset(context, NULL);
+ purple_cipher_reset(cipher);
if (test->iv) {
gsize iv_size;
guchar *iv = purple_base16_decode(test->iv, &iv_size);
g_assert(iv != NULL);
- purple_cipher_context_set_iv(context, iv, iv_size);
+ purple_cipher_set_iv(cipher, iv, iv_size);
g_free(iv);
}
key = purple_base16_decode(test->key, &key_size);
g_assert(key != NULL);
- purple_cipher_context_set_key(context, key, key_size);
+ purple_cipher_set_key(cipher, key, key_size);
g_free(key);
- if (purple_cipher_context_get_key_size(context) != key_size) {
+ if (purple_cipher_get_key_size(cipher) != key_size) {
purple_debug_info("cipher-test", "\tinvalid key size\n");
fail = TRUE;
continue;
}
- cipher_len = purple_cipher_context_encrypt(context,
+ cipher_len = purple_cipher_encrypt(cipher,
(const guchar*)(test->plaintext ? test->plaintext : ""),
test->plaintext ? (strlen(test->plaintext) + 1) : 0,
- cipher, sizeof(cipher));
+ cipher_s, sizeof(cipher_s));
if (cipher_len < 0) {
purple_debug_info("cipher-test", "\tencryption failed\n");
fail = TRUE;
continue;
}
- cipher_b16 = purple_base16_encode(cipher, cipher_len);
+ cipher_b16 = purple_base16_encode(cipher_s, cipher_len);
purple_debug_info("cipher-test", "\tGot: %s\n", cipher_b16);
purple_debug_info("cipher-test", "\tWanted: %s\n", test->cipher);
@@ -538,15 +548,15 @@ cipher_test_aes(void)
}
g_free(cipher_b16);
- decipher_len = purple_cipher_context_decrypt(context,
- cipher, cipher_len, decipher, sizeof(decipher));
+ decipher_len = purple_cipher_decrypt(cipher,
+ cipher_s, cipher_len, decipher_s, sizeof(decipher_s));
if (decipher_len < 0) {
purple_debug_info("cipher-test", "\tdecryption failed\n");
fail = TRUE;
continue;
}
- deciphered = (decipher_len > 0) ? (gchar*)decipher : NULL;
+ deciphered = (decipher_len > 0) ? (gchar*)decipher_s : NULL;
if (g_strcmp0(deciphered, test->plaintext) != 0) {
purple_debug_info("cipher-test",
@@ -558,8 +568,8 @@ cipher_test_aes(void)
purple_debug_info("cipher-test", "\tTest OK\n");
}
- if (context != NULL)
- purple_cipher_context_destroy(context);
+ if (cipher != NULL)
+ g_object_unref(cipher);
if (fail)
purple_debug_info("cipher-test", "AES tests FAILED\n\n");
diff --git a/libpurple/plugins/dbus-example.c b/libpurple/plugins/dbus-example.c
index cf9f255382..01a7978a00 100644
--- a/libpurple/plugins/dbus-example.c
+++ b/libpurple/plugins/dbus-example.c
@@ -37,7 +37,7 @@
#include "internal.h"
-#include "blist.h"
+#include "buddylist.h"
#include "notify.h"
#include "plugin.h"
#include "version.h"
diff --git a/libpurple/plugins/idle.c b/libpurple/plugins/idle.c
index 5d320992eb..b7ed73003e 100644
--- a/libpurple/plugins/idle.c
+++ b/libpurple/plugins/idle.c
@@ -28,6 +28,7 @@
#include "debug.h"
#include "notify.h"
#include "plugin.h"
+#include "presence.h"
#include "request.h"
#include "server.h"
#include "status.h"
diff --git a/libpurple/plugins/joinpart.c b/libpurple/plugins/joinpart.c
index 1e55b05228..4dd836b1ff 100644
--- a/libpurple/plugins/joinpart.c
+++ b/libpurple/plugins/joinpart.c
@@ -79,22 +79,22 @@ static void joinpart_key_destroy(struct joinpart_key *key)
static gboolean should_hide_notice(PurpleConversation *conv, const char *name,
GHashTable *users)
{
- PurpleConvChat *chat;
+ PurpleChatConversation *chat;
guint threshold;
struct joinpart_key key;
time_t *last_said;
g_return_val_if_fail(conv != NULL, FALSE);
- g_return_val_if_fail(purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT, FALSE);
+ g_return_val_if_fail(PURPLE_IS_CHAT_CONVERSATION(conv), FALSE);
/* If the room is small, don't bother. */
- chat = PURPLE_CONV_CHAT(conv);
+ chat = PURPLE_CHAT_CONVERSATION(conv);
threshold = purple_prefs_get_int(THRESHOLD_PREF);
- if (g_list_length(purple_conv_chat_get_users(chat)) < threshold)
+ if (g_list_length(purple_chat_conversation_get_users(chat)) < threshold)
return FALSE;
if (!purple_prefs_get_bool(HIDE_BUDDIES_PREF) &&
- purple_find_buddy(purple_conversation_get_account(conv), name))
+ purple_blist_find_buddy(purple_conversation_get_account(conv), name))
return FALSE;
/* Only show the notice if the user has spoken recently. */
@@ -111,14 +111,14 @@ static gboolean should_hide_notice(PurpleConversation *conv, const char *name,
return TRUE;
}
-static gboolean chat_buddy_leaving_cb(PurpleConversation *conv, const char *name,
+static gboolean chat_user_leaving_cb(PurpleConversation *conv, const char *name,
const char *reason, GHashTable *users)
{
return should_hide_notice(conv, name, users);
}
-static gboolean chat_buddy_joining_cb(PurpleConversation *conv, const char *name,
- PurpleConvChatBuddyFlags flags,
+static gboolean chat_user_joining_cb(PurpleConversation *conv, const char *name,
+ PurpleChatUserFlags flags,
GHashTable *users)
{
return should_hide_notice(conv, name, users);
@@ -186,10 +186,10 @@ static gboolean plugin_load(PurplePlugin *plugin)
g_free);
conv_handle = purple_conversations_get_handle();
- purple_signal_connect(conv_handle, "chat-buddy-joining", plugin,
- PURPLE_CALLBACK(chat_buddy_joining_cb), users);
- purple_signal_connect(conv_handle, "chat-buddy-leaving", plugin,
- PURPLE_CALLBACK(chat_buddy_leaving_cb), users);
+ purple_signal_connect(conv_handle, "chat-user-joining", plugin,
+ PURPLE_CALLBACK(chat_user_joining_cb), users);
+ purple_signal_connect(conv_handle, "chat-user-leaving", plugin,
+ PURPLE_CALLBACK(chat_user_leaving_cb), users);
purple_signal_connect(conv_handle, "received-chat-msg", plugin,
PURPLE_CALLBACK(received_chat_msg_cb), users);
diff --git a/libpurple/plugins/keyrings/internalkeyring.c b/libpurple/plugins/keyrings/internalkeyring.c
index f2e9f5d236..46b092f414 100644
--- a/libpurple/plugins/keyrings/internalkeyring.c
+++ b/libpurple/plugins/keyrings/internalkeyring.c
@@ -26,12 +26,15 @@
#include "internal.h"
#include "account.h"
-#include "cipher.h"
#include "debug.h"
#include "keyring.h"
#include "plugin.h"
#include "version.h"
+#include "ciphers/aescipher.h"
+#include "ciphers/pbkdf2cipher.h"
+#include "ciphers/sha256hash.h"
+
#define INTKEYRING_NAME N_("Internal keyring")
#define INTKEYRING_DESCRIPTION N_("This plugin provides the default password " \
"storage behaviour for libpurple.")
@@ -147,30 +150,31 @@ intkeyring_buff_from_base64(const gchar *base64)
static intkeyring_buff_t *
intkeyring_derive_key(const gchar *passphrase, intkeyring_buff_t *salt)
{
- PurpleCipherContext *context;
+ PurpleCipher *cipher;
+ PurpleHash *hash;
gboolean succ;
intkeyring_buff_t *ret;
g_return_val_if_fail(passphrase != NULL, NULL);
- context = purple_cipher_context_new_by_name("pbkdf2", NULL);
- g_return_val_if_fail(context != NULL, NULL);
+ hash = purple_sha256_hash_new();
+ cipher = purple_pbkdf2_cipher_new(hash);
- purple_cipher_context_set_option(context, "hash", "sha256");
- purple_cipher_context_set_option(context, "iter_count",
+ g_object_set(G_OBJECT(cipher), "iter_count",
GUINT_TO_POINTER(purple_prefs_get_int(INTKEYRING_PREFS
- "pbkdf2_iterations")));
- purple_cipher_context_set_option(context, "out_len", GUINT_TO_POINTER(
- INTKEYRING_KEY_LEN));
- purple_cipher_context_set_salt(context, salt->data, salt->len);
- purple_cipher_context_set_key(context, (const guchar*)passphrase,
+ "pbkdf2_iterations")), NULL);
+ g_object_set(G_OBJECT(cipher), "out_len", GUINT_TO_POINTER(
+ INTKEYRING_KEY_LEN), NULL);
+ purple_cipher_set_salt(cipher, salt->data, salt->len);
+ purple_cipher_set_key(cipher, (const guchar*)passphrase,
strlen(passphrase));
ret = intkeyring_buff_new(g_new(guchar, INTKEYRING_KEY_LEN),
INTKEYRING_KEY_LEN);
- succ = purple_cipher_context_digest(context, ret->data, ret->len);
+ succ = purple_cipher_digest(cipher, ret->data, ret->len);
- purple_cipher_context_destroy(context);
+ g_object_unref(cipher);
+ g_object_unref(hash);
if (!succ) {
intkeyring_buff_free(ret);
@@ -229,7 +233,7 @@ intkeyring_gen_salt(size_t len)
static gchar *
intkeyring_encrypt(intkeyring_buff_t *key, const gchar *str)
{
- PurpleCipherContext *context;
+ PurpleCipher *cipher;
intkeyring_buff_t *iv;
guchar plaintext[INTKEYRING_ENCRYPT_BUFF_LEN];
size_t plaintext_len, text_len, verify_len;
@@ -248,30 +252,30 @@ intkeyring_encrypt(intkeyring_buff_t *key, const gchar *str)
g_return_val_if_fail(plaintext_len + verify_len <= sizeof(plaintext),
NULL);
- context = purple_cipher_context_new_by_name("aes", NULL);
- g_return_val_if_fail(context != NULL, NULL);
+ cipher = purple_aes_cipher_new();
+ g_return_val_if_fail(cipher != NULL, NULL);
memset(plaintext, 0, plaintext_len);
memcpy(plaintext, str, text_len);
memcpy(plaintext + plaintext_len, INTKEYRING_VERIFY_STR, verify_len);
plaintext_len += verify_len;
- iv = intkeyring_gen_salt(purple_cipher_context_get_block_size(context));
- purple_cipher_context_set_iv(context, iv->data, iv->len);
- purple_cipher_context_set_key(context, key->data, key->len);
- purple_cipher_context_set_batch_mode(context,
+ iv = intkeyring_gen_salt(purple_cipher_get_block_size(cipher));
+ purple_cipher_set_iv(cipher, iv->data, iv->len);
+ purple_cipher_set_key(cipher, key->data, key->len);
+ purple_cipher_set_batch_mode(cipher,
PURPLE_CIPHER_BATCH_MODE_CBC);
memcpy(encrypted_raw, iv->data, iv->len);
- encrypted_size = purple_cipher_context_encrypt(context,
+ encrypted_size = purple_cipher_encrypt(cipher,
plaintext, plaintext_len, encrypted_raw + iv->len,
sizeof(encrypted_raw) - iv->len);
encrypted_size += iv->len;
memset(plaintext, 0, plaintext_len);
intkeyring_buff_free(iv);
- purple_cipher_context_destroy(context);
+ g_object_unref(cipher);
if (encrypted_size < 0)
return NULL;
@@ -283,7 +287,7 @@ intkeyring_encrypt(intkeyring_buff_t *key, const gchar *str)
static gchar *
intkeyring_decrypt(intkeyring_buff_t *key, const gchar *str)
{
- PurpleCipherContext *context;
+ PurpleCipher *cipher;
guchar *encrypted_raw;
gsize encrypted_size;
size_t iv_len, verify_len, text_len;
@@ -295,29 +299,29 @@ intkeyring_decrypt(intkeyring_buff_t *key, const gchar *str)
g_return_val_if_fail(key != NULL, NULL);
g_return_val_if_fail(str != NULL, NULL);
- context = purple_cipher_context_new_by_name("aes", NULL);
- g_return_val_if_fail(context != NULL, NULL);
+ cipher = purple_aes_cipher_new();
+ g_return_val_if_fail(cipher != NULL, NULL);
encrypted_raw = purple_base64_decode(str, &encrypted_size);
g_return_val_if_fail(encrypted_raw != NULL, NULL);
- iv_len = purple_cipher_context_get_block_size(context);
+ iv_len = purple_cipher_get_block_size(cipher);
if (encrypted_size < iv_len) {
g_free(encrypted_raw);
return NULL;
}
- purple_cipher_context_set_iv(context, encrypted_raw, iv_len);
- purple_cipher_context_set_key(context, key->data, key->len);
- purple_cipher_context_set_batch_mode(context,
+ purple_cipher_set_iv(cipher, encrypted_raw, iv_len);
+ purple_cipher_set_key(cipher, key->data, key->len);
+ purple_cipher_set_batch_mode(cipher,
PURPLE_CIPHER_BATCH_MODE_CBC);
- plaintext_len = purple_cipher_context_decrypt(context,
+ plaintext_len = purple_cipher_decrypt(cipher,
encrypted_raw + iv_len, encrypted_size - iv_len,
plaintext, sizeof(plaintext));
g_free(encrypted_raw);
- purple_cipher_context_destroy(context);
+ g_object_unref(cipher);
verify_len = strlen(INTKEYRING_VERIFY_STR);
/* Don't remove the len > 0 check! */
diff --git a/libpurple/plugins/log_reader.c b/libpurple/plugins/log_reader.c
index 39f52c7c82..3c73b6537d 100644
--- a/libpurple/plugins/log_reader.c
+++ b/libpurple/plugins/log_reader.c
@@ -644,7 +644,7 @@ static GList *msn_logger_list(PurpleLogType type, const char *sn, PurpleAccount
if (!logdir || !*logdir)
return NULL;
- buddy = purple_find_buddy(account, sn);
+ buddy = purple_blist_find_buddy(account, sn);
if ((username = g_strdup(purple_account_get_string(
account, "log_reader_msn_log_folder", NULL)))) {
@@ -662,7 +662,7 @@ static GList *msn_logger_list(PurpleLogType type, const char *sn, PurpleAccount
}
if (buddy) {
- savedfilename = purple_blist_node_get_string((PurpleBlistNode *)buddy,
+ savedfilename = purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy),
"log_reader_msn_log_filename");
}
@@ -824,7 +824,7 @@ static GList *msn_logger_list(PurpleLogType type, const char *sn, PurpleAccount
* detected for both buddies.
*/
if (buddy && logfile) {
- PurpleBlistNode *node = (PurpleBlistNode *)buddy;
+ PurpleBlistNode *node = PURPLE_BLIST_NODE(buddy);
purple_blist_node_set_string(node, "log_reader_msn_log_filename", logfile);
g_free(logfile);
}
@@ -979,14 +979,14 @@ static char * msn_logger_read (PurpleLog *log, PurpleLogReadFlags *flags)
int friendly_name_length = strlen(friendly_name);
const char *alias;
int alias_length;
- PurpleBuddy *buddy = purple_find_buddy(log->account, log->name);
+ PurpleBuddy *buddy = purple_blist_find_buddy(log->account, log->name);
gboolean from_name_matches;
gboolean to_name_matches;
if (buddy)
their_name = purple_buddy_get_alias(buddy);
- alias = purple_account_get_alias(log->account);
+ alias = purple_account_get_private_alias(log->account);
if (alias) {
alias_length = strlen(alias);
} else {
@@ -1111,8 +1111,8 @@ static char * msn_logger_read (PurpleLog *log, PurpleLogReadFlags *flags)
text = g_string_append(text, "<b>");
if (name_guessed == NAME_GUESS_ME) {
- if (purple_account_get_alias(log->account))
- text = g_string_append(text, purple_account_get_alias(log->account));
+ if (purple_account_get_private_alias(log->account))
+ text = g_string_append(text, purple_account_get_private_alias(log->account));
else
text = g_string_append(text, purple_account_get_username(log->account));
}
@@ -1434,7 +1434,7 @@ static char * trillian_logger_read (PurpleLog *log, PurpleLogReadFlags *flags)
}
/* Load miscellaneous data. */
- buddy = purple_find_buddy(log->account, log->name);
+ buddy = purple_blist_find_buddy(log->account, log->name);
escaped = g_markup_escape_text(read, -1);
g_free(read);
@@ -1663,7 +1663,7 @@ static char * trillian_logger_read (PurpleLog *log, PurpleLogReadFlags *flags)
const char *acct_name;
line2++;
line = line2;
- acct_name = purple_account_get_alias(log->account);
+ acct_name = purple_account_get_private_alias(log->account);
if (!acct_name)
acct_name = purple_account_get_username(log->account);
@@ -1964,7 +1964,7 @@ static char *qip_logger_read(PurpleLog *log, PurpleLogReadFlags *flags)
contents = g_markup_escape_text(utf8_string, -1);
g_free(utf8_string);
- buddy = purple_find_buddy(log->account, log->name);
+ buddy = purple_blist_find_buddy(log->account, log->name);
/* Apply formatting... */
formatted = g_string_sized_new(data->length + 2);
@@ -2032,7 +2032,7 @@ static char *qip_logger_read(PurpleLog *log, PurpleLogReadFlags *flags)
}
} else {
const char *acct_name;
- acct_name = purple_account_get_alias(log->account);
+ acct_name = purple_account_get_private_alias(log->account);
if (!acct_name)
acct_name = purple_account_get_username(log->account);
diff --git a/libpurple/plugins/mono/loader/blist-glue.c b/libpurple/plugins/mono/loader/blist-glue.c
index a424914036..303e77da0a 100644
--- a/libpurple/plugins/mono/loader/blist-glue.c
+++ b/libpurple/plugins/mono/loader/blist-glue.c
@@ -1,5 +1,5 @@
#include <string.h>
-#include "blist.h"
+#include "buddylist.h"
#include "mono-helper.h"
#include "mono-glue.h"
@@ -14,7 +14,7 @@ MonoObject* purple_blist_build_buddy_object(void* data)
{
MonoObject *obj = NULL;
- PurpleBuddy *buddy = (PurpleBuddy*)data;
+ PurpleBuddy *buddy = PURPLE_BUDDY(data);
obj = ml_create_api_object("Buddy");
g_return_val_if_fail(obj != NULL, NULL);
diff --git a/libpurple/plugins/mono/loader/mono-helper.c b/libpurple/plugins/mono/loader/mono-helper.c
index 4404544409..bd7d3b7fc0 100644
--- a/libpurple/plugins/mono/loader/mono-helper.c
+++ b/libpurple/plugins/mono/loader/mono-helper.c
@@ -14,7 +14,6 @@
#include <string.h>
#include "mono-helper.h"
#include "mono-glue.h"
-#include "value.h"
#include "debug.h"
static gboolean _runtime_active = FALSE;
diff --git a/libpurple/plugins/mono/loader/mono-helper.h b/libpurple/plugins/mono/loader/mono-helper.h
index 1d454388d5..6fd0dc8902 100644
--- a/libpurple/plugins/mono/loader/mono-helper.h
+++ b/libpurple/plugins/mono/loader/mono-helper.h
@@ -8,7 +8,6 @@
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/tokentype.h>
#include "plugin.h"
-#include "value.h"
#include "debug.h"
typedef struct {
diff --git a/libpurple/plugins/mono/loader/signal-glue.c b/libpurple/plugins/mono/loader/signal-glue.c
index c6b4be01c6..cb65642419 100644
--- a/libpurple/plugins/mono/loader/signal-glue.c
+++ b/libpurple/plugins/mono/loader/signal-glue.c
@@ -1,9 +1,8 @@
#include "mono-glue.h"
#include "mono-helper.h"
#include "debug.h"
-#include "blist.h"
+#include "buddylist.h"
#include "signals.h"
-#include "value.h"
typedef struct {
MonoObject *func;
diff --git a/libpurple/plugins/newline.c b/libpurple/plugins/newline.c
index 25ba535140..1dfdc77596 100644
--- a/libpurple/plugins/newline.c
+++ b/libpurple/plugins/newline.c
@@ -31,9 +31,9 @@ static gboolean
addnewline_msg_cb(PurpleAccount *account, char *sender, char **message,
PurpleConversation *conv, int *flags, void *data)
{
- if (((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) &&
+ if ((PURPLE_IS_IM_CONVERSATION(conv) &&
!purple_prefs_get_bool("/plugins/core/newline/im")) ||
- ((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) &&
+ (PURPLE_IS_CHAT_CONVERSATION(conv) &&
!purple_prefs_get_bool("/plugins/core/newline/chat")))
return FALSE;
diff --git a/libpurple/plugins/offlinemsg.c b/libpurple/plugins/offlinemsg.c
index 1803f82430..56dfe66cad 100644
--- a/libpurple/plugins/offlinemsg.c
+++ b/libpurple/plugins/offlinemsg.c
@@ -29,7 +29,7 @@
/* Purple headers */
#include <version.h>
-#include <blist.h>
+#include <buddylist.h>
#include <conversation.h>
#include <core.h>
#include <debug.h>
@@ -67,9 +67,9 @@ discard_data(OfflineMsg *offline)
static void
cancel_poune(OfflineMsg *offline)
{
- purple_conversation_set_data(offline->conv, "plugin_pack:offlinemsg",
+ g_object_set_data(G_OBJECT(offline->conv), "plugin_pack:offlinemsg",
GINT_TO_POINTER(OFFLINE_MSG_NO));
- purple_conv_im_send_with_flags(PURPLE_CONV_IM(offline->conv), offline->message, 0);
+ purple_conversation_send_with_flags(offline->conv, offline->message, 0);
discard_data(offline);
}
@@ -97,15 +97,15 @@ record_pounce(OfflineMsg *offline)
g_free(temp);
conv = offline->conv;
- if (!purple_conversation_get_data(conv, "plugin_pack:offlinemsg"))
+ if (!g_object_get_data(G_OBJECT(conv), "plugin_pack:offlinemsg"))
purple_conversation_write(conv, NULL, _("The rest of the messages will be saved "
"as pounces. You can edit/delete the pounce from the `Buddy "
"Pounce' dialog."),
PURPLE_MESSAGE_SYSTEM, time(NULL));
- purple_conversation_set_data(conv, "plugin_pack:offlinemsg",
+ g_object_set_data(G_OBJECT(conv), "plugin_pack:offlinemsg",
GINT_TO_POINTER(OFFLINE_MSG_YES));
- purple_conv_im_write(PURPLE_CONV_IM(conv), offline->who, offline->message,
+ purple_conversation_write_message(conv, offline->who, offline->message,
PURPLE_MESSAGE_SEND, time(NULL));
discard_data(offline);
@@ -123,7 +123,7 @@ sending_msg_cb(PurpleAccount *account, const char *who, char **message, gpointer
**message == '\0')
return;
- buddy = purple_find_buddy(account, who);
+ buddy = purple_blist_find_buddy(account, who);
if (!buddy)
return;
@@ -137,13 +137,12 @@ sending_msg_cb(PurpleAccount *account, const char *who, char **message, gpointer
return;
}
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- who, account);
+ conv = PURPLE_CONVERSATION(purple_conversations_find_im_with_account(who, account));
if (!conv)
return;
- setting = GPOINTER_TO_INT(purple_conversation_get_data(conv, "plugin_pack:offlinemsg"));
+ setting = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(conv), "plugin_pack:offlinemsg"));
if (setting == OFFLINE_MSG_NO)
return;
diff --git a/libpurple/plugins/perl/common/Account.xs b/libpurple/plugins/perl/common/Account.xs
index b83f4e9089..ea9b5b56cf 100644
--- a/libpurple/plugins/perl/common/Account.xs
+++ b/libpurple/plugins/perl/common/Account.xs
@@ -1,6 +1,57 @@
#include "module.h"
#include "../perl-handlers.h"
+MODULE = Purple::Account PACKAGE = Purple::Accounts PREFIX = purple_accounts_
+PROTOTYPES: ENABLE
+
+void
+purple_accounts_add(account)
+ Purple::Account account
+
+void
+purple_accounts_remove(account)
+ Purple::Account account
+
+void
+purple_accounts_delete(account)
+ Purple::Account account
+
+void
+purple_accounts_reorder(account, new_index)
+ Purple::Account account
+ size_t new_index
+
+void
+purple_accounts_get_all()
+PREINIT:
+ GList *l;
+PPCODE:
+ for (l = purple_accounts_get_all(); l != NULL; l = l->next) {
+ XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::Account")));
+ }
+
+void
+purple_accounts_get_all_active()
+PREINIT:
+ GList *list, *iter;
+PPCODE:
+ list = purple_accounts_get_all_active();
+ for (iter = list; iter != NULL; iter = iter->next) {
+ XPUSHs(sv_2mortal(purple_perl_bless_object(iter->data, "Purple::Account")));
+ }
+ g_list_free(list);
+
+void
+purple_accounts_restore_current_statuses()
+
+Purple::Account
+purple_accounts_find(name, protocol)
+ const char * name
+ const char * protocol
+
+Purple::Handle
+purple_accounts_get_handle()
+
MODULE = Purple::Account PACKAGE = Purple::Account PREFIX = purple_account_
PROTOTYPES: ENABLE
@@ -16,10 +67,6 @@ purple_account_new(class, username, protocol_id)
username, protocol_id
void
-purple_account_destroy(account)
- Purple::Account account
-
-void
purple_account_connect(account)
Purple::Account account
@@ -54,7 +101,7 @@ CODE:
purple_perl_account_set_password(account, password, func, data);
void
-purple_account_set_alias(account, alias)
+purple_account_set_private_alias(account, alias)
Purple::Account account
const char * alias
@@ -144,7 +191,7 @@ CODE:
purple_perl_account_get_password(account, func, data);
const char *
-purple_account_get_alias(account)
+purple_account_get_private_alias(account)
Purple::Account account
const char *
@@ -273,53 +320,34 @@ purple_account_remove_group(account, group)
Purple::Account account
Purple::BuddyList::Group group
-MODULE = Purple::Account PACKAGE = Purple::Accounts PREFIX = purple_accounts_
+MODULE = Purple::Account PACKAGE = Purple::Account::Privacy PREFIX = purple_account_privacy_
PROTOTYPES: ENABLE
-void
-purple_accounts_add(account)
- Purple::Account account
-
-void
-purple_accounts_remove(account)
- Purple::Account account
-
-void
-purple_accounts_delete(account)
- Purple::Account account
-
-void
-purple_accounts_reorder(account, new_index)
- Purple::Account account
- size_t new_index
-
-void
-purple_accounts_get_all()
-PREINIT:
- GList *l;
-PPCODE:
- for (l = purple_accounts_get_all(); l != NULL; l = l->next) {
- XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::Account")));
- }
+gboolean
+purple_account_privacy_permit_add(account, name, local_only)
+ Purple::Account account
+ const char * name
+ gboolean local_only
-void
-purple_accounts_get_all_active()
-PREINIT:
- GList *list, *iter;
-PPCODE:
- list = purple_accounts_get_all_active();
- for (iter = list; iter != NULL; iter = iter->next) {
- XPUSHs(sv_2mortal(purple_perl_bless_object(iter->data, "Purple::Account")));
- }
- g_list_free(list);
+gboolean
+purple_account_privacy_permit_remove(account, name, local_only)
+ Purple::Account account
+ const char * name
+ gboolean local_only
-void
-purple_accounts_restore_current_statuses()
+gboolean
+purple_account_privacy_deny_add(account, name, local_only)
+ Purple::Account account
+ const char * name
+ gboolean local_only
-Purple::Account
-purple_accounts_find(name, protocol)
- const char * name
- const char * protocol
+gboolean
+purple_account_privacy_deny_remove(account, name, local_only)
+ Purple::Account account
+ const char * name
+ gboolean local_only
-Purple::Handle
-purple_accounts_get_handle()
+gboolean
+purple_account_privacy_check(account, who)
+ Purple::Account account
+ const char * who
diff --git a/libpurple/plugins/perl/common/BuddyList.xs b/libpurple/plugins/perl/common/BuddyList.xs
index 394496b118..518dd3a2bf 100644
--- a/libpurple/plugins/perl/common/BuddyList.xs
+++ b/libpurple/plugins/perl/common/BuddyList.xs
@@ -10,57 +10,6 @@ chat_components_foreach(gpointer key, gpointer value, gpointer user_data)
purple_debug_error("perl", "hv_store failed\n");
}
-MODULE = Purple::BuddyList PACKAGE = Purple PREFIX = purple_
-PROTOTYPES: ENABLE
-
-BOOT:
-{
- HV *stash = gv_stashpv("Purple::BuddyList::Node", 1);
-
- static const constiv *civ, const_iv[] = {
-#define const_iv(name) {#name, (IV)PURPLE_BLIST_##name##_NODE}
- const_iv(GROUP),
- const_iv(CONTACT),
- const_iv(BUDDY),
- const_iv(CHAT),
- const_iv(OTHER),
-#undef const_iv
-#define const_iv(name) {#name, (IV)PURPLE_BLIST_NODE_FLAG_##name}
- const_iv(NO_SAVE),
- };
-
- for (civ = const_iv + sizeof(const_iv) / sizeof(const_iv[0]); civ-- > const_iv; )
- newCONSTSUB(stash, (char *)civ->name, newSViv(civ->iv));
-}
-
-Purple::BuddyList
-purple_get_blist()
-
-MODULE = Purple::BuddyList PACKAGE = Purple::Find PREFIX = purple_find_
-PROTOTYPES: ENABLE
-
-Purple::BuddyList::Buddy
-purple_find_buddy(account, name)
- Purple::Account account
- const char * name
-
-void
-purple_find_buddies(account, name)
- Purple::Account account
- const char * name
-PREINIT:
- GSList *l, *ll;
-PPCODE:
- ll = purple_find_buddies(account, name);
- for (l = ll; l != NULL; l = l->next) {
- XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::BuddyList::Buddy")));
- }
- g_slist_free(ll);
-
-Purple::BuddyList::Group
-purple_find_group(name)
- const char *name
-
MODULE = Purple::BuddyList PACKAGE = Purple::Find PREFIX = purple_
PROTOTYPES: ENABLE
@@ -92,6 +41,11 @@ void
purple_contact_invalidate_priority_buddy(contact)
Purple::BuddyList::Contact contact
+void
+purple_contact_merge(source, node)
+ Purple::BuddyList::Contact source
+ Purple::BuddyList::Node node
+
MODULE = Purple::BuddyList PACKAGE = Purple::BuddyList::Group PREFIX = purple_group_
PROTOTYPES: ENABLE
@@ -116,6 +70,11 @@ purple_group_on_account(group, account)
Purple::BuddyList::Group group
Purple::Account account
+void
+purple_group_set_name(group, name)
+ Purple::BuddyList::Group group
+ const char * name
+
const char *
purple_group_get_name(group)
Purple::BuddyList::Group group
@@ -123,6 +82,31 @@ purple_group_get_name(group)
MODULE = Purple::BuddyList PACKAGE = Purple::BuddyList PREFIX = purple_blist_
PROTOTYPES: ENABLE
+Purple::BuddyList
+purple_blist_get_buddy_list()
+
+Purple::BuddyList::Buddy
+purple_blist_find_buddy(account, name)
+ Purple::Account account
+ const char * name
+
+void
+purple_blist_find_buddies(account, name)
+ Purple::Account account
+ const char * name
+PREINIT:
+ GSList *l, *ll;
+PPCODE:
+ ll = purple_blist_find_buddies(account, name);
+ for (l = ll; l != NULL; l = l->next) {
+ XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::BuddyList::Buddy")));
+ }
+ g_slist_free(ll);
+
+Purple::BuddyList::Group
+purple_blist_find_group(name)
+ const char *name
+
void
purple_blist_add_contact(contact, group, node)
Purple::BuddyList::Contact contact
@@ -130,11 +114,6 @@ purple_blist_add_contact(contact, group, node)
Purple::BuddyList::Node node
void
-purple_blist_merge_contact(source, node)
- Purple::BuddyList::Contact source
- Purple::BuddyList::Node node
-
-void
purple_blist_add_group(group, node)
Purple::BuddyList::Group group
Purple::BuddyList::Node node
@@ -177,43 +156,10 @@ void
purple_blist_show()
void
-purple_blist_destroy();
-
-void
purple_blist_set_visible(show)
gboolean show
void
-purple_blist_update_buddy_status(buddy, old_status)
- Purple::BuddyList::Buddy buddy
- Purple::Status old_status
-
-void
-purple_blist_rename_buddy(buddy, name)
- Purple::BuddyList::Buddy buddy
- const char * name
-
-void
-purple_blist_alias_buddy(buddy, alias)
- Purple::BuddyList::Buddy buddy
- const char * alias
-
-void
-purple_blist_server_alias_buddy(buddy, alias)
- Purple::BuddyList::Buddy buddy
- const char * alias
-
-void
-purple_blist_alias_chat(chat, alias)
- Purple::BuddyList::Chat chat
- const char * alias
-
-void
-purple_blist_rename_group(group, name)
- Purple::BuddyList::Group group
- const char * name
-
-void
purple_blist_add_account(account)
Purple::Account account
@@ -221,15 +167,6 @@ void
purple_blist_remove_account(account)
Purple::Account account
-int
-purple_blist_get_group_size(group, offline)
- Purple::BuddyList::Group group
- gboolean offline
-
-int
-purple_blist_get_group_online_count(group)
- Purple::BuddyList::Group group
-
void
purple_blist_schedule_save()
@@ -287,27 +224,63 @@ purple_blist_node_get_string(node, key)
const char * key
void
+purple_blist_node_set_transient(node, transient)
+ Purple::BuddyList::Node node
+ gboolean transient
+
+gboolean
+purple_blist_node_is_transient(node);
+ Purple::BuddyList::Node node
+
+void
purple_blist_node_remove_setting(node, key)
Purple::BuddyList::Node node
const char * key
+MODULE = Purple::BuddyList PACKAGE = Purple::BuddyList::CountingNode PREFIX = purple_counting_node_
+PROTOTYPES: ENABLE
+
+int
+purple_counting_node_get_total_size(counter);
+ Purple::BuddyList::CountingNode counter
+
+int
+purple_counting_node_get_current_size(counter);
+ Purple::BuddyList::CountingNode counter
+
+int
+purple_counting_node_get_online_count(counter);
+ Purple::BuddyList::CountingNode counter
+
void
-purple_blist_node_set_flags(node, flags)
- Purple::BuddyList::Node node
- Purple::BuddyList::NodeFlags flags
+purple_counting_node_change_total_size(counter, delta);
+ Purple::BuddyList::CountingNode counter
+ int delta
-Purple::BuddyList::NodeFlags
-purple_blist_node_get_flags(node)
- Purple::BuddyList::Node node
+void
+purple_counting_node_change_current_size(counter, delta);
+ Purple::BuddyList::CountingNode counter
+ int delta
-Purple::BuddyList::NodeType
-purple_blist_node_get_type(node)
- Purple::BuddyList::Node node
+void
+purple_counting_node_change_online_count(counter, delta);
+ Purple::BuddyList::CountingNode counter
+ int delta
-Purple::BuddyList::Node
-purple_blist_node_next(node, offline)
- Purple::BuddyList::Node node
- gboolean offline
+void
+purple_counting_node_set_total_size(counter, totalsize);
+ Purple::BuddyList::CountingNode counter
+ int totalsize
+
+void
+purple_counting_node_set_current_size(counter, currentsize);
+ Purple::BuddyList::CountingNode counter
+ int currentsize
+
+void
+purple_counting_node_set_online_count(counter, onlinecount);
+ Purple::BuddyList::CountingNode counter
+ int onlinecount
MODULE = Purple::BuddyList PACKAGE = Purple::BuddyList::Chat PREFIX = purple_chat_
PROTOTYPES: ENABLE
@@ -316,10 +289,19 @@ Purple::BuddyList::Group
purple_chat_get_group(chat)
Purple::BuddyList::Chat chat
+void
+purple_chat_set_alias(chat, alias)
+ Purple::BuddyList::Chat chat
+ const char * alias
+
const char *
purple_chat_get_name(chat)
Purple::BuddyList::Chat chat
+const char *
+purple_chat_get_name_only(chat)
+ Purple::BuddyList::Chat chat
+
HV *
purple_chat_get_components(chat)
Purple::BuddyList::Chat chat
@@ -370,6 +352,26 @@ purple_buddy_new(account, name, alias)
const char *name
const char *alias
+void
+purple_buddy_update_status(buddy, old_status)
+ Purple::BuddyList::Buddy buddy
+ Purple::Status old_status
+
+void
+purple_buddy_set_name(buddy, name)
+ Purple::BuddyList::Buddy buddy
+ const char * name
+
+void
+purple_buddy_set_local_alias(buddy, alias)
+ Purple::BuddyList::Buddy buddy
+ const char * alias
+
+void
+purple_buddy_set_server_alias(buddy, alias)
+ Purple::BuddyList::Buddy buddy
+ const char * alias
+
const char *
purple_buddy_get_server_alias(buddy)
Purple::BuddyList::Buddy buddy
diff --git a/libpurple/plugins/perl/common/Cipher.xs b/libpurple/plugins/perl/common/Cipher.xs
index 2dd723fcd7..2612090ada 100644
--- a/libpurple/plugins/perl/common/Cipher.xs
+++ b/libpurple/plugins/perl/common/Cipher.xs
@@ -6,7 +6,6 @@ PROTOTYPES: ENABLE
BOOT:
{
HV *stash = gv_stashpv("Purple::Cipher::BatchMode", 1);
- HV *cipher_caps = gv_stashpv("Purple::Cipher::Caps", 1);
static const constiv *civ, const_iv[] = {
#define const_iv(name) {#name, (IV)PURPLE_CIPHER_BATCH_MODE_##name}
@@ -15,74 +14,16 @@ BOOT:
#undef const_iv
};
- static const constiv bm_const_iv[] = {
-#define const_iv(name) {#name, (IV)PURPLE_CIPHER_CAPS_##name}
- const_iv(SET_OPT),
- const_iv(GET_OPT),
- const_iv(INIT),
- const_iv(RESET),
- const_iv(UNINIT),
- const_iv(SET_IV),
- const_iv(APPEND),
- const_iv(DIGEST),
- const_iv(GET_DIGEST_SIZE),
- const_iv(ENCRYPT),
- const_iv(DECRYPT),
- const_iv(SET_SALT),
- const_iv(GET_SALT_SIZE),
- const_iv(SET_KEY),
- const_iv(GET_KEY_SIZE),
- const_iv(SET_BATCH_MODE),
- const_iv(GET_BATCH_MODE),
- const_iv(GET_BLOCK_SIZE),
- const_iv(UNKNOWN),
-#undef const_iv
- };
-
for (civ = const_iv + sizeof(const_iv) / sizeof(const_iv[0]); civ-- > const_iv; )
newCONSTSUB(stash, (char *)civ->name, newSViv(civ->iv));
-
- for (civ = bm_const_iv + sizeof(bm_const_iv) / sizeof(bm_const_iv[0]); civ-- > bm_const_iv; )
- newCONSTSUB(cipher_caps, (char *)civ->name, newSViv(civ->iv));
}
const gchar *
purple_cipher_get_name(cipher)
Purple::Cipher cipher
-guint
-purple_cipher_get_capabilities(cipher)
- Purple::Cipher cipher
-
-gboolean
-purple_cipher_digest_region(name, data_sv, data_len, digest)
- const gchar *name
- SV *data_sv
- size_t data_len
- SV *digest
- PREINIT:
- guchar *buff = NULL;
- guchar *data = NULL;
- ssize_t digest_len;
- size_t max_digest_len = 100;
- CODE:
- data = (guchar *)SvPV(data_sv, data_len);
- SvUPGRADE(digest, SVt_PV);
- buff = (guchar *)SvGROW(digest, max_digest_len);
- digest_len = purple_cipher_digest_region(name, data, data_len, buff, max_digest_len);
- if(digest_len == -1) {
- SvSetSV_nosteal(digest, &PL_sv_undef);
- RETVAL = 0;
- } else {
- SvCUR_set(digest, digest_len);
- SvPOK_only(digest);
- RETVAL = 1;
- }
- OUTPUT:
- RETVAL
-
gchar_own*
-purple_cipher_http_digest_calculate_response(algorithm, method, digest_uri, qop, entity, nonce, nonce_count, client_nonce, session_key)
+purple_http_digest_calculate_response(algorithm, method, digest_uri, qop, entity, nonce, nonce_count, client_nonce, session_key)
const gchar* algorithm
const gchar* method
const gchar* digest_uri
@@ -94,7 +35,7 @@ purple_cipher_http_digest_calculate_response(algorithm, method, digest_uri, qop,
const gchar* session_key
gchar_own*
-purple_cipher_http_digest_calculate_session_key(algorithm, username, realm, password, nonce, client_nonce)
+purple_http_digest_calculate_session_key(algorithm, username, realm, password, nonce, client_nonce)
const gchar* algorithm
const gchar* username
const gchar* realm
@@ -102,89 +43,30 @@ purple_cipher_http_digest_calculate_session_key(algorithm, username, realm, pass
const gchar* nonce
const gchar* client_nonce
-MODULE = Purple::Cipher PACKAGE = Purple::Ciphers PREFIX = purple_ciphers_
-PROTOTYPES: ENABLE
-
-Purple::Cipher
-purple_ciphers_find_cipher(name)
- gchar * name
-
-Purple::Cipher
-purple_ciphers_register_cipher(name, ops)
- gchar * name
- Purple::Cipher::Ops ops
-
-gboolean
-purple_ciphers_unregister_cipher(cipher)
- Purple::Cipher cipher
-
void
-purple_ciphers_get_ciphers()
-PREINIT:
- GList *l;
-PPCODE:
- for (l = purple_ciphers_get_ciphers(); l != NULL; l = l->next) {
- XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::Cipher")));
- }
-
-Purple::Handle
-purple_ciphers_get_handle()
-
-MODULE = Purple::Cipher PACKAGE = Purple::Cipher::Context PREFIX = purple_cipher_context_
-PROTOTYPES: ENABLE
-
-void
-purple_cipher_context_set_option(context, name, value)
- Purple::Cipher::Context context
- gchar *name
- gpointer value
-
-gpointer
-purple_cipher_context_get_option(context, name)
- Purple::Cipher::Context context
- gchar *name
-
-Purple::Cipher::Context
-purple_cipher_context_new(klass, cipher, extra = NULL)
+purple_cipher_reset(cipher)
Purple::Cipher cipher
- void *extra
- C_ARGS: cipher, extra
-
-Purple::Cipher::Context
-purple_cipher_context_new_by_name(klass, name, extra = NULL)
- gchar *name
- void *extra
- C_ARGS: name, extra
-
-void
-purple_cipher_context_reset(context, extra = NULL)
- Purple::Cipher::Context context
- gpointer extra
-
-void
-purple_cipher_context_destroy(context)
- Purple::Cipher::Context context
void
-purple_cipher_context_set_iv(Purple::Cipher::Context context, guchar *iv, size_t length(iv))
+purple_cipher_set_iv(Purple::Cipher cipher, guchar *iv, size_t length(iv))
PROTOTYPE: $$
void
-purple_cipher_context_append(Purple::Cipher::Context context, guchar *data, size_t length(data))
+purple_cipher_append(Purple::Cipher cipher, guchar *data, size_t length(data))
PROTOTYPE: $$
gboolean
-purple_cipher_context_digest(context, digest)
- Purple::Cipher::Context context
+purple_cipher_digest(cipher, digest)
+ Purple::Cipher cipher
SV *digest
PREINIT:
guchar *buff = NULL;
size_t digest_size;
CODE:
- digest_size = purple_cipher_context_get_digest_size(context);
+ digest_size = purple_cipher_get_digest_size(cipher);
SvUPGRADE(digest, SVt_PV);
buff = (guchar *)SvGROW(digest, digest_size);
- if (purple_cipher_context_digest(context, buff, digest_size)) {
+ if (purple_cipher_digest(cipher, buff, digest_size)) {
SvCUR_set(digest, digest_size);
SvPOK_only(digest);
RETVAL = 1;
@@ -196,18 +78,18 @@ purple_cipher_context_digest(context, digest)
RETVAL
gboolean
-purple_cipher_context_digest_to_str(context, digest_s)
- Purple::Cipher::Context context
+purple_cipher_digest_to_str(cipher, digest_s)
+ Purple::Cipher cipher
SV *digest_s
PREINIT:
gchar *buff = NULL;
size_t digest_size, str_len;
CODE:
- digest_size = purple_cipher_context_get_digest_size(context);
+ digest_size = purple_cipher_get_digest_size(cipher);
str_len = 2 * digest_size;
SvUPGRADE(digest_s, SVt_PV);
buff = SvGROW(digest_s, str_len + 1);
- if (purple_cipher_context_digest_to_str(context, buff, str_len + 1)) {
+ if (purple_cipher_digest_to_str(cipher, buff, str_len + 1)) {
SvCUR_set(digest_s, str_len);
SvPOK_only(digest_s);
RETVAL = 1;
@@ -219,8 +101,8 @@ purple_cipher_context_digest_to_str(context, digest_s)
RETVAL
gboolean
-purple_cipher_context_encrypt(context, input, output)
- Purple::Cipher::Context context
+purple_cipher_encrypt(cipher, input, output)
+ Purple::Cipher cipher
SV *input
SV *output
PREINIT:
@@ -230,10 +112,10 @@ purple_cipher_context_encrypt(context, input, output)
guchar *data = NULL;
CODE:
data = (guchar *)SvPV(input, input_len);
- output_len = input_len + purple_cipher_context_get_block_size(context);
+ output_len = input_len + purple_cipher_get_block_size(cipher);
SvUPGRADE(output, SVt_PV);
buff = (guchar *)SvGROW(output, output_len);
- ret = purple_cipher_context_encrypt(context, data, input_len, buff, output_len);
+ ret = purple_cipher_encrypt(cipher, data, input_len, buff, output_len);
if (ret >= 0) {
RETVAL = 1;
SvPOK_only(output);
@@ -246,8 +128,8 @@ purple_cipher_context_encrypt(context, input, output)
RETVAL
gboolean
-purple_cipher_context_decrypt(context, input, output)
- Purple::Cipher::Context context
+purple_cipher_decrypt(cipher, input, output)
+ Purple::Cipher cipher
SV *input
SV *output
PREINIT:
@@ -257,10 +139,10 @@ purple_cipher_context_decrypt(context, input, output)
guchar *data = NULL;
CODE:
data = (guchar *)SvPV(input, input_len);
- output_len = input_len + purple_cipher_context_get_block_size(context);
+ output_len = input_len + purple_cipher_get_block_size(cipher);
SvUPGRADE(output, SVt_PV);
buff = (guchar *)SvGROW(output, output_len);
- ret = purple_cipher_context_decrypt(context, data, input_len, buff, output_len);
+ ret = purple_cipher_decrypt(cipher, data, input_len, buff, output_len);
if (ret >= 0) {
RETVAL = 1;
SvPOK_only(output);
@@ -273,44 +155,68 @@ purple_cipher_context_decrypt(context, input, output)
RETVAL
void
-purple_cipher_context_set_salt(context, salt, len)
- Purple::Cipher::Context context
+purple_cipher_set_salt(cipher, salt, len)
+ Purple::Cipher cipher
guchar *salt
size_t len
-size_t
-purple_cipher_context_get_salt_size(context)
- Purple::Cipher::Context context
-
void
-purple_cipher_context_set_key(context, key, len)
- Purple::Cipher::Context context
+purple_cipher_set_key(cipher, key, len)
+ Purple::Cipher cipher
guchar *key
size_t len
size_t
-purple_cipher_context_get_key_size(context)
- Purple::Cipher::Context context
-
-void
-purple_cipher_context_set_data(context, data)
- Purple::Cipher::Context context
- gpointer data
-
-gpointer
-purple_cipher_context_get_data(context)
- Purple::Cipher::Context context
+purple_cipher_get_key_size(cipher)
+ Purple::Cipher cipher
Purple::Cipher::BatchMode
-purple_cipher_context_get_batch_mode(context)
- Purple::Cipher::Context context
+purple_cipher_get_batch_mode(cipher)
+ Purple::Cipher cipher
size_t
-purple_cipher_context_get_block_size(context)
- Purple::Cipher::Context context
+purple_cipher_get_block_size(cipher)
+ Purple::Cipher cipher
void
-purple_cipher_context_set_batch_mode(context, mode)
- Purple::Cipher::Context context
+purple_cipher_set_batch_mode(cipher, mode)
+ Purple::Cipher cipher
Purple::Cipher::BatchMode mode
+MODULE = Purple::Cipher PACKAGE = Purple::AESCipher PREFIX = purple_aes_cipher_
+PROTOTYPES: ENABLE
+
+Purple::Cipher
+purple_aes_cipher_new()
+
+MODULE = Purple::Cipher PACKAGE = Purple::DES3Cipher PREFIX = purple_des3_cipher_
+PROTOTYPES: ENABLE
+
+Purple::Cipher
+purple_des3_cipher_new()
+
+MODULE = Purple::Cipher PACKAGE = Purple::DESCipher PREFIX = purple_des_cipher_
+PROTOTYPES: ENABLE
+
+Purple::Cipher
+purple_des_cipher_new()
+
+MODULE = Purple::Cipher PACKAGE = Purple::HMACCipher PREFIX = purple_hmac_cipher_
+PROTOTYPES: ENABLE
+
+Purple::Cipher
+purple_hmac_cipher_new(hash)
+ Purple::Hash hash
+
+MODULE = Purple::Cipher PACKAGE = Purple::PBKDF2Cipher PREFIX = purple_pbkdf2_cipher_
+PROTOTYPES: ENABLE
+
+Purple::Cipher
+purple_pbkdf2_cipher_new(hash)
+ Purple::Hash hash
+
+MODULE = Purple::Cipher PACKAGE = Purple::RC4Cipher PREFIX = purple_rc4_cipher_
+PROTOTYPES: ENABLE
+
+Purple::Cipher
+purple_rc4_cipher_new()
diff --git a/libpurple/plugins/perl/common/Connection.xs b/libpurple/plugins/perl/common/Connection.xs
index dc0c2660e1..446913fff0 100644
--- a/libpurple/plugins/perl/common/Connection.xs
+++ b/libpurple/plugins/perl/common/Connection.xs
@@ -8,7 +8,7 @@ BOOT:
HV *stash = gv_stashpv("Purple::Connection::State", 1);
static const constiv *civ, const_iv[] = {
-#define const_iv(name) {#name, (IV)PURPLE_##name}
+#define const_iv(name) {#name, (IV)PURPLE_CONNECTION_##name}
const_iv(DISCONNECTED),
const_iv(CONNECTED),
const_iv(CONNECTING),
@@ -26,6 +26,16 @@ const char *
purple_connection_get_password(gc)
Purple::Connection gc
+void
+purple_connection_get_active_chats(gc)
+ Purple::Connection gc
+PREINIT:
+ GSList *l;
+PPCODE:
+ for (l = purple_connection_get_active_chats(gc); l != NULL; l = l->next) {
+ XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::ChatConversation")));
+ }
+
const char *
purple_connection_get_display_name(gc)
Purple::Connection gc
diff --git a/libpurple/plugins/perl/common/Conversation.xs b/libpurple/plugins/perl/common/Conversation.xs
index 3263aafc4c..dfa101cb60 100644
--- a/libpurple/plugins/perl/common/Conversation.xs
+++ b/libpurple/plugins/perl/common/Conversation.xs
@@ -5,23 +5,14 @@ PROTOTYPES: ENABLE
BOOT:
{
- HV *type_stash = gv_stashpv("Purple::Conversation::Type", 1);
- HV *update_stash = gv_stashpv("Purple::Conversation::Update::Type", 1);
- HV *typing_stash = gv_stashpv("Purple::Conversation::TypingState", 1);
- HV *flags_stash = gv_stashpv("Purple::Conversation::Flags", 1);
- HV *cbflags_stash = gv_stashpv("Purple::Conversation::ChatBuddy::Flags", 1);
-
- static const constiv *civ, type_const_iv[] = {
-#define const_iv(name) {#name, (IV)PURPLE_CONV_TYPE_##name}
- const_iv(UNKNOWN),
- const_iv(IM),
- const_iv(CHAT),
- const_iv(MISC),
- const_iv(ANY),
- };
- static const constiv update_const_iv[] = {
+ HV *update_stash = gv_stashpv("Purple::Conversation::UpdateType", 1);
+ HV *typing_stash = gv_stashpv("Purple::IMTypingState", 1);
+ HV *flags_stash = gv_stashpv("Purple::MessageFlags", 1);
+ HV *cbflags_stash = gv_stashpv("Purple::ChatUser::Flags", 1);
+
+ static const constiv *civ, update_const_iv[] = {
#undef const_iv
-#define const_iv(name) {#name, (IV)PURPLE_CONV_UPDATE_##name}
+#define const_iv(name) {#name, (IV)PURPLE_CONVERSATION_UPDATE_##name}
const_iv(ADD),
const_iv(REMOVE),
const_iv(ACCOUNT),
@@ -41,7 +32,7 @@ BOOT:
};
static const constiv typing_const_iv[] = {
#undef const_iv
-#define const_iv(name) {#name, (IV)PURPLE_##name}
+#define const_iv(name) {#name, (IV)PURPLE_IM_##name}
const_iv(NOT_TYPING),
const_iv(TYPING),
const_iv(TYPED),
@@ -66,7 +57,7 @@ BOOT:
};
static const constiv cbflags_const_iv[] = {
#undef const_iv
-#define const_iv(name) {#name, (IV)PURPLE_CBFLAGS_##name}
+#define const_iv(name) {#name, (IV)PURPLE_CHAT_USER_##name}
const_iv(NONE),
const_iv(VOICE),
const_iv(HALFOP),
@@ -75,9 +66,6 @@ BOOT:
const_iv(TYPING),
};
- for (civ = type_const_iv + sizeof(type_const_iv) / sizeof(type_const_iv[0]); civ-- > type_const_iv; )
- newCONSTSUB(type_stash, (char *)civ->name, newSViv(civ->iv));
-
for (civ = update_const_iv + sizeof(update_const_iv) / sizeof(update_const_iv[0]); civ-- > update_const_iv; )
newCONSTSUB(update_stash, (char *)civ->name, newSViv(civ->iv));
@@ -91,56 +79,76 @@ BOOT:
newCONSTSUB(cbflags_stash, (char *)civ->name, newSViv(civ->iv));
}
+MODULE = Purple::Conversation PACKAGE = Purple::Conversations PREFIX = purple_conversations_
+PROTOTYPES: ENABLE
+
+void
+purple_conversations_add(conv)
+ Purple::Conversation conv
+
+void
+purple_conversations_remove(conv)
+ Purple::Conversation conv
+
+void
+purple_conversations_update_cache(conv, name, account)
+ Purple::Conversation conv
+ const char * name
+ Purple::Account account
+
+Purple::Handle
+purple_conversations_get_handle()
+
+Purple::ChatConversation
+purple_conversations_find_chat(gc, id)
+ Purple::Connection gc
+ int id
+
void
-purple_get_ims()
+purple_conversations_get_ims()
PREINIT:
GList *l;
PPCODE:
- for (l = purple_get_ims(); l != NULL; l = l->next) {
- XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::Conversation")));
+ for (l = purple_conversations_get_ims(); l != NULL; l = l->next) {
+ XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::IMConversation")));
}
void
-purple_get_conversations()
+purple_conversations_get_all()
PREINIT:
GList *l;
PPCODE:
- for (l = purple_get_conversations(); l != NULL; l = l->next) {
+ for (l = purple_conversations_get_all(); l != NULL; l = l->next) {
XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::Conversation")));
}
void
-purple_get_chats()
+purple_conversations_get_chats()
PREINIT:
GList *l;
PPCODE:
- for (l = purple_get_chats(); l != NULL; l = l->next) {
- XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::Conversation")));
+ for (l = purple_conversations_get_chats(); l != NULL; l = l->next) {
+ XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::ChatConversation")));
}
Purple::Conversation
-purple_find_conversation_with_account(type, name, account)
- Purple::ConversationType type
+purple_conversations_find_with_account(name, account)
const char *name
Purple::Account account
-MODULE = Purple::Conversation PACKAGE = Purple::Conversations PREFIX = purple_conversations_
-PROTOTYPES: ENABLE
+Purple::ChatConversation
+purple_conversations_find_chat_with_account(name, account)
+ const char *name
+ Purple::Account account
-Purple::Handle
-purple_conversations_get_handle()
+Purple::IMConversation
+purple_conversations_find_im_with_account(name, account)
+ const char *name
+ Purple::Account account
MODULE = Purple::Conversation PACKAGE = Purple::Conversation PREFIX = purple_conversation_
PROTOTYPES: ENABLE
-void
-purple_conversation_destroy(conv)
- Purple::Conversation conv
-
-Purple::ConversationType
-purple_conversation_get_type(conv)
- Purple::Conversation conv
-
Purple::Account
purple_conversation_get_account(conv)
Purple::Conversation conv
@@ -180,19 +188,6 @@ gboolean
purple_conversation_is_logging(conv)
Purple::Conversation conv
-Purple::Conversation::IM
-purple_conversation_get_im_data(conv)
- Purple::Conversation conv
-
-Purple::Conversation::Chat
-purple_conversation_get_chat_data(conv)
- Purple::Conversation conv
-
-gpointer
-purple_conversation_get_data(conv, key)
- Purple::Conversation conv
- const char * key
-
Purple::ConnectionFlags
purple_conversation_get_features(conv)
Purple::Conversation conv
@@ -204,15 +199,7 @@ purple_conversation_has_focus(conv)
void
purple_conversation_update(conv, type)
Purple::Conversation conv
- Purple::ConvUpdateType type
-
-Purple::Conversation
-purple_conversation_new(class, type, account, name)
- Purple::ConversationType type
- Purple::Account account
- const char *name
- C_ARGS:
- type, account, name
+ Purple::Conversation::UpdateType type
void
purple_conversation_set_account(conv, account);
@@ -227,6 +214,25 @@ purple_conversation_write(conv, who, message, flags, mtime)
Purple::MessageFlags flags
time_t mtime
+void
+purple_conversation_write_message(conv, who, message, flags, mtime)
+ Purple::Conversation conv
+ const char *who
+ const char *message
+ Purple::MessageFlags flags
+ time_t mtime
+
+void
+purple_conversation_send(conv, message)
+ Purple::Conversation conv
+ const char *message
+
+void
+purple_conversation_send_with_flags(conv, message, flags)
+ Purple::Conversation conv
+ const char *message
+ Purple::MessageFlags flags
+
gboolean
purple_conversation_do_command(conv, cmdline, markup, error)
Purple::Conversation conv
@@ -234,132 +240,122 @@ purple_conversation_do_command(conv, cmdline, markup, error)
const char *markup
char **error
-MODULE = Purple::Conversation PACKAGE = Purple::Conversation::IM PREFIX = purple_conv_im_
+MODULE = Purple::Conversation PACKAGE = Purple::IMConversation PREFIX = purple_im_conversation_
PROTOTYPES: ENABLE
-Purple::Conversation
-purple_conv_im_get_conversation(im)
- Purple::Conversation::IM im
+Purple::IMConversation
+purple_im_conversation_new(class, account, name)
+ Purple::Account account
+ const char *name
+ C_ARGS:
+ account, name
void
-purple_conv_im_set_icon(im, icon)
- Purple::Conversation::IM im
+purple_im_conversation_set_icon(im, icon)
+ Purple::IMConversation im
Purple::Buddy::Icon icon
Purple::Buddy::Icon
-purple_conv_im_get_icon(im)
- Purple::Conversation::IM im
+purple_im_conversation_get_icon(im)
+ Purple::IMConversation im
void
-purple_conv_im_set_typing_state(im, state)
- Purple::Conversation::IM im
- Purple::TypingState state
+purple_im_conversation_set_typing_state(im, state)
+ Purple::IMConversation im
+ Purple::IMTypingState state
-Purple::TypingState
-purple_conv_im_get_typing_state(im)
- Purple::Conversation::IM im
+Purple::IMTypingState
+purple_im_conversation_get_typing_state(im)
+ Purple::IMConversation im
void
-purple_conv_im_start_typing_timeout(im, timeout)
- Purple::Conversation::IM im
+purple_im_conversation_start_typing_timeout(im, timeout)
+ Purple::IMConversation im
int timeout
void
-purple_conv_im_stop_typing_timeout(im)
- Purple::Conversation::IM im
+purple_im_conversation_stop_typing_timeout(im)
+ Purple::IMConversation im
guint
-purple_conv_im_get_typing_timeout(im)
- Purple::Conversation::IM im
+purple_im_conversation_get_typing_timeout(im)
+ Purple::IMConversation im
void
-purple_conv_im_set_type_again(im, val)
- Purple::Conversation::IM im
+purple_im_conversation_set_type_again(im, val)
+ Purple::IMConversation im
time_t val
time_t
-purple_conv_im_get_type_again(im)
- Purple::Conversation::IM im
+purple_im_conversation_get_type_again(im)
+ Purple::IMConversation im
void
-purple_conv_im_start_send_typed_timeout(im)
- Purple::Conversation::IM im
+purple_im_conversation_start_send_typed_timeout(im)
+ Purple::IMConversation im
void
-purple_conv_im_stop_send_typed_timeout(im)
- Purple::Conversation::IM im
+purple_im_conversation_stop_send_typed_timeout(im)
+ Purple::IMConversation im
guint
-purple_conv_im_get_send_typed_timeout(im)
- Purple::Conversation::IM im
-
-void
-purple_conv_im_update_typing(im)
- Purple::Conversation::IM im
+purple_im_conversation_get_send_typed_timeout(im)
+ Purple::IMConversation im
void
-purple_conv_im_send(im, message)
- Purple::Conversation::IM im
- const char *message
+purple_im_conversation_update_typing(im)
+ Purple::IMConversation im
-void
-purple_conv_im_send_with_flags(im, message, flags)
- Purple::Conversation::IM im
- const char *message
- Purple::MessageFlags flags
-
-void
-purple_conv_im_write(im, who, message, flags, mtime)
- Purple::Conversation::IM im
- const char *who
- const char *message
- Purple::MessageFlags flags
- time_t mtime
-
-MODULE = Purple::Conversation PACKAGE = Purple::Conversation PREFIX = purple_conv_
+MODULE = Purple::Conversation PACKAGE = Purple::Conversation::Helper PREFIX = purple_conversation_helper_
PROTOTYPES: ENABLE
gboolean
-purple_conv_present_error(who, account, what)
+purple_conversation_present_error(who, account, what)
const char *who
Purple::Account account
const char *what
+MODULE = Purple::Conversation PACKAGE = Purple::Conversation PREFIX = purple_conversation_
+PROTOTYPES: ENABLE
+
void
-purple_conv_custom_smiley_close(conv, smile)
+purple_conversation_custom_smiley_close(conv, smile)
Purple::Conversation conv
const char *smile
-MODULE = Purple::Conversation PACKAGE = Purple::Conversation::Chat PREFIX = purple_conv_chat_
+MODULE = Purple::Conversation PACKAGE = Purple::ChatConversation PREFIX = purple_chat_conversation_
PROTOTYPES: ENABLE
-Purple::Conversation
-purple_conv_chat_get_conversation(chat)
- Purple::Conversation::Chat chat
+Purple::ChatConversation
+purple_chat_conversation_new(class, account, name)
+ Purple::Account account
+ const char *name
+ C_ARGS:
+ account, name
void
-purple_conv_chat_get_users(chat)
- Purple::Conversation::Chat chat
+purple_chat_conversation_get_users(chat)
+ Purple::ChatConversation chat
PREINIT:
GList *l;
PPCODE:
- for (l = purple_conv_chat_get_users(chat); l != NULL; l = l->next) {
+ for (l = purple_chat_conversation_get_users(chat); l != NULL; l = l->next) {
XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::ListEntry")));
}
void
-purple_conv_chat_ignore(chat, name)
- Purple::Conversation::Chat chat
+purple_chat_conversation_ignore(chat, name)
+ Purple::ChatConversation chat
const char *name
void
-purple_conv_chat_unignore(chat, name)
- Purple::Conversation::Chat chat
+purple_chat_conversation_unignore(chat, name)
+ Purple::ChatConversation chat
const char *name
void
-purple_conv_chat_set_ignored(chat, ignored)
- Purple::Conversation::Chat chat
+purple_chat_conversation_set_ignored(chat, ignored)
+ Purple::ChatConversation chat
SV * ignored
PREINIT:
GList *l, *t_GL;
@@ -371,55 +367,36 @@ PPCODE:
for (i = 0; i <= t_len; i++)
t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(ignored), i, 0)));
- for (l = purple_conv_chat_set_ignored(chat, t_GL); l != NULL; l = l->next) {
+ for (l = purple_chat_conversation_set_ignored(chat, t_GL); l != NULL; l = l->next) {
XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::ListEntry")));
}
void
-purple_conv_chat_get_ignored(chat)
- Purple::Conversation::Chat chat
+purple_chat_conversation_get_ignored(chat)
+ Purple::ChatConversation chat
PREINIT:
GList *l;
PPCODE:
- for (l = purple_conv_chat_get_ignored(chat); l != NULL; l = l->next) {
+ for (l = purple_chat_conversation_get_ignored(chat); l != NULL; l = l->next) {
XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::ListEntry")));
}
const char *
-purple_conv_chat_get_topic(chat)
- Purple::Conversation::Chat chat
+purple_chat_conversation_get_topic(chat)
+ Purple::ChatConversation chat
void
-purple_conv_chat_set_id(chat, id)
- Purple::Conversation::Chat chat
+purple_chat_conversation_set_id(chat, id)
+ Purple::ChatConversation chat
int id
int
-purple_conv_chat_get_id(chat)
- Purple::Conversation::Chat chat
-
-void
-purple_conv_chat_send(chat, message)
- Purple::Conversation::Chat chat
- const char * message
-
-void
-purple_conv_chat_send_with_flags(chat, message, flags)
- Purple::Conversation::Chat chat
- const char * message
- Purple::MessageFlags flags
+purple_chat_conversation_get_id(chat)
+ Purple::ChatConversation chat
void
-purple_conv_chat_write(chat, who, message, flags, mtime)
- Purple::Conversation::Chat chat
- const char *who
- const char *message
- Purple::MessageFlags flags
- time_t mtime
-
-void
-purple_conv_chat_add_users(chat, users, extra_msgs, flags, new_arrivals)
- Purple::Conversation::Chat chat
+purple_chat_conversation_add_users(chat, users, extra_msgs, flags, new_arrivals)
+ Purple::ChatConversation chat
SV * users
SV * extra_msgs
SV * flags
@@ -446,48 +423,39 @@ PPCODE:
for (i = 0; i <= t_len; i++)
t_GL_extra_msgs = g_list_append(t_GL_extra_msgs, SvPVutf8_nolen(*av_fetch((AV *)SvRV(extra_msgs), i, 0)));
- purple_conv_chat_add_users(chat, t_GL_users, t_GL_extra_msgs, t_GL_flags, new_arrivals);
+ purple_chat_conversation_add_users(chat, t_GL_users, t_GL_extra_msgs, t_GL_flags, new_arrivals);
g_list_free(t_GL_users);
g_list_free(t_GL_extra_msgs);
g_list_free(t_GL_flags);
gboolean
-purple_conv_chat_find_user(chat, user)
- Purple::Conversation::Chat chat
+purple_chat_conversation_has_user(chat, user)
+ Purple::ChatConversation chat
const char * user
-void purple_conv_chat_clear_users(chat)
- Purple::Conversation::Chat chat
+void purple_chat_conversation_clear_users(chat)
+ Purple::ChatConversation chat
-void purple_conv_chat_set_nick(chat, nick)
- Purple::Conversation::Chat chat
+void purple_chat_conversation_set_nick(chat, nick)
+ Purple::ChatConversation chat
const char * nick
const char *
-purple_conv_chat_get_nick(chat)
- Purple::Conversation::Chat chat
+purple_chat_conversation_get_nick(chat)
+ Purple::ChatConversation chat
-Purple::Conversation
-purple_find_chat(gc, id)
- Purple::Connection gc
- int id
+void purple_chat_conversation_leave(chat)
+ Purple::ChatConversation chat
-void purple_conv_chat_left(chat)
- Purple::Conversation::Chat chat
+gboolean purple_chat_conversation_has_left(chat)
+ Purple::ChatConversation chat
-gboolean purple_conv_chat_has_left(chat)
- Purple::Conversation::Chat chat
-
-Purple::Conversation::ChatBuddy
-purple_conv_chat_cb_find(chat, name)
- Purple::Conversation::Chat chat
+Purple::ChatUser
+purple_chat_conversation_find_user(chat, name)
+ Purple::ChatConversation chat
const char *name
const char *
-purple_conv_chat_cb_get_name(cb)
- Purple::Conversation::ChatBuddy cb
-
-void
-purple_conv_chat_cb_destroy(cb);
- Purple::Conversation::ChatBuddy cb
+purple_chat_user_get_name(cb)
+ Purple::ChatUser cb
diff --git a/libpurple/plugins/perl/common/Hash.xs b/libpurple/plugins/perl/common/Hash.xs
new file mode 100644
index 0000000000..33e53b36cf
--- /dev/null
+++ b/libpurple/plugins/perl/common/Hash.xs
@@ -0,0 +1,110 @@
+#include "module.h"
+
+MODULE = Purple::Hash PACKAGE = Purple::Hash PREFIX = purple_hash_
+PROTOTYPES: ENABLE
+
+const gchar *
+purple_hash_get_name(hash)
+ Purple::Hash hash
+
+gchar_own*
+purple_http_digest_calculate_response(algorithm, method, digest_uri, qop, entity, nonce, nonce_count, client_nonce, session_key)
+ const gchar* algorithm
+ const gchar* method
+ const gchar* digest_uri
+ const gchar* qop
+ const gchar* entity
+ const gchar* nonce
+ const gchar* nonce_count
+ const gchar* client_nonce
+ const gchar* session_key
+
+gchar_own*
+purple_http_digest_calculate_session_key(algorithm, username, realm, password, nonce, client_nonce)
+ const gchar* algorithm
+ const gchar* username
+ const gchar* realm
+ const gchar* password
+ const gchar* nonce
+ const gchar* client_nonce
+
+void
+purple_hash_reset(hash)
+ Purple::Hash hash
+
+void
+purple_hash_append(Purple::Hash hash, guchar *data, size_t length(data))
+ PROTOTYPE: $$
+
+gboolean
+purple_hash_digest(hash, digest)
+ Purple::Hash hash
+ SV *digest
+ PREINIT:
+ guchar *buff = NULL;
+ size_t digest_size;
+ CODE:
+ digest_size = purple_hash_get_digest_size(hash);
+ SvUPGRADE(digest, SVt_PV);
+ buff = (guchar *)SvGROW(digest, digest_size);
+ if (purple_hash_digest(hash, buff, digest_size)) {
+ SvCUR_set(digest, digest_size);
+ SvPOK_only(digest);
+ RETVAL = 1;
+ } else {
+ SvSetSV_nosteal(digest, &PL_sv_undef);
+ RETVAL = 0;
+ }
+ OUTPUT:
+ RETVAL
+
+gboolean
+purple_hash_digest_to_str(hash, digest_s)
+ Purple::Hash hash
+ SV *digest_s
+ PREINIT:
+ gchar *buff = NULL;
+ size_t digest_size, str_len;
+ CODE:
+ digest_size = purple_hash_get_digest_size(hash);
+ str_len = 2 * digest_size;
+ SvUPGRADE(digest_s, SVt_PV);
+ buff = SvGROW(digest_s, str_len + 1);
+ if (purple_hash_digest_to_str(hash, buff, str_len + 1)) {
+ SvCUR_set(digest_s, str_len);
+ SvPOK_only(digest_s);
+ RETVAL = 1;
+ } else {
+ SvSetSV_nosteal(digest_s, &PL_sv_undef);
+ RETVAL = 0;
+ }
+ OUTPUT:
+ RETVAL
+
+size_t
+purple_hash_get_block_size(hash)
+ Purple::Hash hash
+
+MODULE = Purple::Hash PACKAGE = Purple::MD4Hash PREFIX = purple_md4_hash_
+PROTOTYPES: ENABLE
+
+Purple::Hash
+purple_md4_hash_new()
+
+MODULE = Purple::Hash PACKAGE = Purple::MD5Hash PREFIX = purple_md5_hash_
+PROTOTYPES: ENABLE
+
+Purple::Hash
+purple_md5_hash_new()
+
+MODULE = Purple::Hash PACKAGE = Purple::SHA1Hash PREFIX = purple_sha1_hash_
+PROTOTYPES: ENABLE
+
+Purple::Hash
+purple_sha1_hash_new()
+
+MODULE = Purple::Hash PACKAGE = Purple::SHA256Hash PREFIX = purple_sha256_hash_
+PROTOTYPES: ENABLE
+
+Purple::Hash
+purple_sha256_hash_new()
diff --git a/libpurple/plugins/perl/common/MANIFEST b/libpurple/plugins/perl/common/MANIFEST
index 75e701224a..645f9d533e 100644
--- a/libpurple/plugins/perl/common/MANIFEST
+++ b/libpurple/plugins/perl/common/MANIFEST
@@ -8,6 +8,7 @@ Connection.xs
Conversation.xs
Debug.xs
FT.xs
+Hash.xs
ImgStore.xs
Log.xs
Makefile.PL
@@ -17,7 +18,7 @@ Plugin.xs
PluginPref.xs
Pounce.xs
Prefs.xs
-Privacy.xs
+Presence.xs
Proxy.xs
Prpl.xs
Purple.pm
diff --git a/libpurple/plugins/perl/common/Makefile.mingw b/libpurple/plugins/perl/common/Makefile.mingw
index 75fd54804e..9afa26dbc3 100644
--- a/libpurple/plugins/perl/common/Makefile.mingw
+++ b/libpurple/plugins/perl/common/Makefile.mingw
@@ -48,6 +48,7 @@ XS_FILES = Account.xs \
Core.xs \
Debug.xs \
FT.xs \
+ Hash.xs \
Idle.xs \
Purple.xs \
ImgStore.xs \
@@ -58,7 +59,7 @@ XS_FILES = Account.xs \
PluginPref.xs \
Pounce.xs \
Prefs.xs \
- Privacy.xs \
+ Presence.xs \
Proxy.xs \
Prpl.xs \
Request.xs \
diff --git a/libpurple/plugins/perl/common/Presence.xs b/libpurple/plugins/perl/common/Presence.xs
new file mode 100644
index 0000000000..8f8bf5530e
--- /dev/null
+++ b/libpurple/plugins/perl/common/Presence.xs
@@ -0,0 +1,102 @@
+#include "module.h"
+
+MODULE = Purple::Presence PACKAGE = Purple::Presence PREFIX = purple_presence_
+PROTOTYPES: ENABLE
+
+Purple::Status
+purple_presence_get_active_status(presence)
+ Purple::Presence presence
+
+time_t
+purple_presence_get_idle_time(presence)
+ Purple::Presence presence
+
+time_t
+purple_presence_get_login_time(presence)
+ Purple::Presence presence
+
+Purple::Status
+purple_presence_get_status(presence, status_id)
+ Purple::Presence presence
+ const char *status_id
+
+void
+purple_presence_get_statuses(presence)
+ Purple::Presence presence
+PREINIT:
+ GList *l;
+PPCODE:
+ for (l = purple_presence_get_statuses(presence); l != NULL; l = l->next) {
+ XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::Status")));
+ }
+
+gboolean
+purple_presence_is_available(presence)
+ Purple::Presence presence
+
+gboolean
+purple_presence_is_idle(presence)
+ Purple::Presence presence
+
+gboolean
+purple_presence_is_online(presence)
+ Purple::Presence presence
+
+gboolean
+purple_presence_is_status_active(presence, status_id)
+ Purple::Presence presence
+ const char *status_id
+
+gboolean
+purple_presence_is_status_primitive_active(presence, primitive)
+ Purple::Presence presence
+ Purple::StatusPrimitive primitive
+
+void
+purple_presence_set_idle(presence, idle, idle_time)
+ Purple::Presence presence
+ gboolean idle
+ time_t idle_time
+
+void
+purple_presence_set_login_time(presence, login_time)
+ Purple::Presence presence
+ time_t login_time
+
+void
+purple_presence_set_status_active(presence, status_id, active)
+ Purple::Presence presence
+ const char *status_id
+ gboolean active
+
+void
+purple_presence_switch_status(presence, status_id)
+ Purple::Presence presence
+ const char *status_id
+
+MODULE = Purple::Presence PACKAGE = Purple::AccountPresence PREFIX = purple_account_presence_
+PROTOTYPES: ENABLE
+
+Purple::Account
+purple_account_presence_get_account(presence)
+ Purple::AccountPresence presence
+
+Purple::AccountPresence
+purple_account_presence_new(account)
+ Purple::Account account
+
+MODULE = Purple::Presence PACKAGE = Purple::BuddyPresence PREFIX = purple_buddy_presence_
+PROTOTYPES: ENABLE
+
+gint
+purple_buddy_presence_compare(presence1, presence2)
+ Purple::BuddyPresence presence1
+ Purple::BuddyPresence presence2
+
+Purple::BuddyList::Buddy
+purple_buddy_presence_get_buddy(presence)
+ Purple::BuddyPresence presence
+
+Purple::BuddyPresence
+purple_buddy_presence_new(buddy)
+ Purple::BuddyList::Buddy buddy
diff --git a/libpurple/plugins/perl/common/Privacy.xs b/libpurple/plugins/perl/common/Privacy.xs
deleted file mode 100644
index dbb63a594d..0000000000
--- a/libpurple/plugins/perl/common/Privacy.xs
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "module.h"
-
-MODULE = Purple::Privacy PACKAGE = Purple::Privacy PREFIX = purple_privacy_
-PROTOTYPES: ENABLE
-
-gboolean
-purple_privacy_permit_add(account, name, local_only)
- Purple::Account account
- const char * name
- gboolean local_only
-
-gboolean
-purple_privacy_permit_remove(account, name, local_only)
- Purple::Account account
- const char * name
- gboolean local_only
-
-gboolean
-purple_privacy_deny_add(account, name, local_only)
- Purple::Account account
- const char * name
- gboolean local_only
-
-gboolean
-purple_privacy_deny_remove(account, name, local_only)
- Purple::Account account
- const char * name
- gboolean local_only
-
-gboolean
-purple_privacy_check(account, who)
- Purple::Account account
- const char * who
diff --git a/libpurple/plugins/perl/common/Prpl.xs b/libpurple/plugins/perl/common/Prpl.xs
index 765ce5d41a..3e13133d21 100644
--- a/libpurple/plugins/perl/common/Prpl.xs
+++ b/libpurple/plugins/perl/common/Prpl.xs
@@ -65,7 +65,7 @@ CODE:
if (!gc)
RETVAL = 0;
else {
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
if (prpl_info && prpl_info->send_raw != NULL) {
RETVAL = prpl_info->send_raw(gc, str, strlen(str));
} else {
diff --git a/libpurple/plugins/perl/common/Server.xs b/libpurple/plugins/perl/common/Server.xs
index 13e2aefcbf..a354029619 100644
--- a/libpurple/plugins/perl/common/Server.xs
+++ b/libpurple/plugins/perl/common/Server.xs
@@ -104,7 +104,7 @@ serv_got_im(gc, who, msg, imflags, mtime)
Purple::MessageFlags imflags
time_t mtime
-Purple::Conversation
+Purple::ChatConversation
serv_got_joined_chat(gc, id, name)
Purple::Connection gc
int id
@@ -115,7 +115,7 @@ serv_got_typing(gc, name, timeout, state)
Purple::Connection gc
const char *name
int timeout
- Purple::TypingState state
+ Purple::IMTypingState state
void
serv_got_typing_stopped(gc, name)
@@ -203,7 +203,7 @@ int
serv_send_typing(con, a, state)
Purple::Connection con
const char * a
- Purple::TypingState state
+ Purple::IMTypingState state
void
serv_set_info(con, a)
diff --git a/libpurple/plugins/perl/common/Status.xs b/libpurple/plugins/perl/common/Status.xs
index 8965870ade..8c50ace626 100644
--- a/libpurple/plugins/perl/common/Status.xs
+++ b/libpurple/plugins/perl/common/Status.xs
@@ -39,22 +39,14 @@ purple_status_set_active_with_attrs(status, active, args)
*/
-MODULE = Purple::Status PACKAGE = Purple::Presence PREFIX = purple_presence_
+MODULE = Purple::Status PACKAGE = Purple::Primitive PREFIX = purple_primitive_
PROTOTYPES: ENABLE
BOOT:
{
- HV *context_stash = gv_stashpv("Purple::Presence::Context", 1);
HV *primitive_stash = gv_stashpv("Purple::Status::Primitive", 1);
- static const constiv *civ, context_const_iv[] = {
-#define const_iv(name) {#name, (IV)PURPLE_PRESENCE_CONTEXT_##name}
- const_iv(UNSET),
- const_iv(ACCOUNT),
- const_iv(CONV),
- const_iv(BUDDY),
- };
- static const constiv primitive_const_iv[] = {
+ static const constiv *civ, primitive_const_iv[] = {
#undef const_iv
#define const_iv(name) {#name, (IV)PURPLE_STATUS_##name}
const_iv(UNSET),
@@ -67,128 +59,10 @@ BOOT:
const_iv(MOBILE),
};
- for (civ = context_const_iv + sizeof(context_const_iv) / sizeof(context_const_iv[0]); civ-- > context_const_iv; )
- newCONSTSUB(context_stash, (char *)civ->name, newSViv(civ->iv));
-
for (civ = primitive_const_iv + sizeof(primitive_const_iv) / sizeof(primitive_const_iv[0]); civ-- > primitive_const_iv; )
newCONSTSUB(primitive_stash, (char *)civ->name, newSViv(civ->iv));
}
-gint
-purple_presence_compare(presence1, presence2)
- Purple::Presence presence1
- Purple::Presence presence2
-
-void
-purple_presence_destroy(presence)
- Purple::Presence presence
-
-Purple::Account
-purple_presence_get_account(presence)
- Purple::Presence presence
-
-Purple::Status
-purple_presence_get_active_status(presence)
- Purple::Presence presence
-
-const char *
-purple_presence_get_chat_user(presence)
- Purple::Presence presence
-
-Purple::PresenceContext
-purple_presence_get_context(presence)
- Purple::Presence presence
-
-Purple::Conversation
-purple_presence_get_conversation(presence)
- Purple::Presence presence
-
-time_t
-purple_presence_get_idle_time(presence)
- Purple::Presence presence
-
-time_t
-purple_presence_get_login_time(presence)
- Purple::Presence presence
-
-Purple::Status
-purple_presence_get_status(presence, status_id)
- Purple::Presence presence
- const char *status_id
-
-void
-purple_presence_get_statuses(presence)
- Purple::Presence presence
-PREINIT:
- GList *l;
-PPCODE:
- for (l = purple_presence_get_statuses(presence); l != NULL; l = l->next) {
- XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::Status")));
- }
-
-gboolean
-purple_presence_is_available(presence)
- Purple::Presence presence
-
-gboolean
-purple_presence_is_idle(presence)
- Purple::Presence presence
-
-gboolean
-purple_presence_is_online(presence)
- Purple::Presence presence
-
-gboolean
-purple_presence_is_status_active(presence, status_id)
- Purple::Presence presence
- const char *status_id
-
-gboolean
-purple_presence_is_status_primitive_active(presence, primitive)
- Purple::Presence presence
- Purple::StatusPrimitive primitive
-
-Purple::Presence
-purple_presence_new(context)
- Purple::PresenceContext context
-
-Purple::Presence
-purple_presence_new_for_account(account)
- Purple::Account account
-
-Purple::Presence
-purple_presence_new_for_buddy(buddy)
- Purple::BuddyList::Buddy buddy
-
-Purple::Presence
-purple_presence_new_for_conv(conv)
- Purple::Conversation conv
-
-void
-purple_presence_set_idle(presence, idle, idle_time)
- Purple::Presence presence
- gboolean idle
- time_t idle_time
-
-void
-purple_presence_set_login_time(presence, login_time)
- Purple::Presence presence
- time_t login_time
-
-void
-purple_presence_set_status_active(presence, status_id, active)
- Purple::Presence presence
- const char *status_id
- gboolean active
-
-void
-purple_presence_switch_status(presence, status_id)
- Purple::Presence presence
- const char *status_id
-
-MODULE = Purple::Status PACKAGE = Purple::Primitive PREFIX = purple_primitive_
-PROTOTYPES: ENABLE
-
const char *
purple_primitive_get_id_from_type(type)
Purple::StatusPrimitive type
@@ -201,30 +75,30 @@ Purple::StatusPrimitive
purple_primitive_get_type_from_id(id)
const char *id
-MODULE = Purple::Status PACKAGE = Purple::StatusAttr PREFIX = purple_status_attr_
+MODULE = Purple::Status PACKAGE = Purple::StatusAttr PREFIX = purple_status_attribute_
PROTOTYPES: ENABLE
void
-purple_status_attr_destroy(attr)
+purple_status_attribute_destroy(attr)
Purple::StatusAttr attr
const char *
-purple_status_attr_get_id(attr)
+purple_status_attribute_get_id(attr)
Purple::StatusAttr attr
const char *
-purple_status_attr_get_name(attr)
+purple_status_attribute_get_name(attr)
Purple::StatusAttr attr
-Purple::Value
-purple_status_attr_get_value(attr)
+GValue *
+purple_status_attribute_get_value(attr)
Purple::StatusAttr attr
Purple::StatusAttr
-purple_status_attr_new(id, name, value_type)
+purple_status_attribute_new(id, name, value_type)
const char *id
const char *name
- Purple::Value value_type
+ GValue *value_type
MODULE = Purple::Status PACKAGE = Purple::Status PREFIX = purple_status_
PROTOTYPES: ENABLE
@@ -234,10 +108,6 @@ purple_status_compare(status1, status2)
Purple::Status status1
Purple::Status status2
-void
-purple_status_destroy(status)
- Purple::Status status
-
gboolean
purple_status_get_attr_boolean(status, id)
Purple::Status status
@@ -253,13 +123,13 @@ purple_status_get_attr_string(status, id)
Purple::Status status
const char *id
-Purple::Value
+GValue *
purple_status_get_attr_value(status, id)
Purple::Status status
const char *id
Purple::Handle
-purple_status_get_handle()
+purple_statuses_get_handle()
const char *
purple_status_get_id(status)
@@ -274,7 +144,7 @@ purple_status_get_presence(status)
Purple::Status status
Purple::StatusType
-purple_status_get_type(status)
+purple_status_get_status_type(status)
Purple::Status status
gboolean
diff --git a/libpurple/plugins/perl/common/module.h b/libpurple/plugins/perl/common/module.h
index f16aa48084..9c4627c339 100644
--- a/libpurple/plugins/perl/common/module.h
+++ b/libpurple/plugins/perl/common/module.h
@@ -19,15 +19,26 @@ typedef struct group *Purple__Group;
#include "../perl-common.h"
-#include "account.h"
+#include "accounts.h"
#include "accountopt.h"
-#include "blist.h"
+#include "buddylist.h"
#include "buddyicon.h"
#include "certificate.h"
#include "cipher.h"
+#include "ciphers/aescipher.h"
+#include "ciphers/des3cipher.h"
+#include "ciphers/descipher.h"
+#include "ciphers/hmaccipher.h"
+#include "ciphers/pbkdf2cipher.h"
+#include "ciphers/rc4cipher.h"
+#include "hash.h"
+#include "ciphers/md4hash.h"
+#include "ciphers/md5hash.h"
+#include "ciphers/sha1hash.h"
+#include "ciphers/sha256hash.h"
#include "cmds.h"
#include "connection.h"
-#include "conversation.h"
+#include "conversations.h"
#include "core.h"
#include "debug.h"
#include "desktopitem.h"
@@ -48,7 +59,7 @@ typedef struct group *Purple__Group;
#include "pluginpref.h"
#include "pounce.h"
#include "prefs.h"
-#include "privacy.h"
+#include "presence.h"
#include "prpl.h"
#include "proxy.h"
#include "request.h"
@@ -63,7 +74,6 @@ typedef struct group *Purple__Group;
#include "stringref.h"
/* Ewww. perl has it's own util.h which is in the include path :( */
#include "libpurple/util.h"
-#include "value.h"
#include "whiteboard.h"
#include "xmlnode.h"
@@ -71,11 +81,11 @@ typedef struct group *Purple__Group;
typedef PurpleAccount * Purple__Account;
typedef PurpleAccountOption * Purple__Account__Option;
typedef PurpleAccountUserSplit * Purple__Account__UserSplit;
+typedef PurpleAccountPrivacyType Purple__Account__PrivacyType;
-/* blist.h */
+/* buddylist.h */
typedef PurpleBlistNode * Purple__BuddyList__Node;
-typedef PurpleBlistNodeFlags Purple__BuddyList__NodeFlags;
-typedef PurpleBlistNodeType Purple__BuddyList__NodeType;
+typedef PurpleCountingNode * Purple__BuddyList__CountingNode;
typedef PurpleBuddyList * Purple__BuddyList;
typedef PurpleBuddy * Purple__BuddyList__Buddy;
typedef PurpleChat * Purple__BuddyList__Chat;
@@ -95,9 +105,6 @@ typedef PurpleCertificateVerificationStatus Purple__Certificate__VerificationSta
/* cipher.h */
typedef PurpleCipher * Purple__Cipher;
-typedef PurpleCipherCaps Purple__CipherCaps;
-typedef PurpleCipherContext * Purple__Cipher__Context;
-typedef PurpleCipherOps * Purple__Cipher__Ops;
typedef PurpleCipherBatchMode Purple__Cipher__BatchMode;
/* cmds.h */
@@ -111,16 +118,15 @@ typedef PurpleConnection * Purple__Connection;
typedef PurpleConnectionFlags Purple__ConnectionFlags;
typedef PurpleConnectionState Purple__ConnectionState;
-/* conversation.h */
-typedef PurpleConversationType Purple__ConversationType;
-typedef PurpleConvUpdateType Purple__ConvUpdateType;
-typedef PurpleTypingState Purple__TypingState;
-typedef PurpleMessageFlags Purple__MessageFlags;
-typedef PurpleConvChatBuddyFlags Purple__ConvChatBuddyFlags;
+/* conversations.h */
+typedef PurpleMessageFlags Purple__MessageFlags;
typedef PurpleConversation * Purple__Conversation;
-typedef PurpleConvIm * Purple__Conversation__IM;
-typedef PurpleConvChat * Purple__Conversation__Chat;
-typedef PurpleConvChatBuddy * Purple__Conversation__ChatBuddy;
+typedef PurpleConversationUpdateType Purple__Conversation__UpdateType;
+typedef PurpleIMConversation * Purple__IMConversation;
+typedef PurpleIMTypingState Purple__IMTypingState;
+typedef PurpleChatConversation * Purple__ChatConversation;
+typedef PurpleChatUser * Purple__ChatUser;
+typedef PurpleChatUserFlags Purple__ChatUser__Flags;
/* core.h */
@@ -168,6 +174,9 @@ typedef GtkTextView * Purple__GTK__TextView;
/* gtkconn.h */
#endif
+/* hash.h */
+typedef PurpleHash * Purple__Hash;
+
/* imgstore.h */
typedef PurpleStoredImage * Purple__StoredImage;
@@ -215,8 +224,10 @@ typedef PurplePounceEvent Purple__PounceEvent;
/* prefs.h */
typedef PurplePrefType Purple__PrefType;
-/* privacy.h */
-typedef PurplePrivacyType Purple__PrivacyType;
+/* presence.h */
+typedef PurplePresence * Purple__Presence;
+typedef PurpleAccountPresence * Purple__AccountPresence;
+typedef PurpleBuddyPresence * Purple__BuddyPresence;
/* proxy.h */
typedef PurpleProxyInfo * Purple__ProxyInfo;
@@ -259,10 +270,8 @@ typedef PurpleSslErrorType Purple__SslErrorType;
typedef PurpleSslOps * Purple__Ssl__Ops;
/* status.h */
-typedef PurplePresence * Purple__Presence;
-typedef PurplePresenceContext Purple__PresenceContext;
typedef PurpleStatus * Purple__Status;
-typedef PurpleStatusAttr * Purple__StatusAttr;
+typedef PurpleStatusAttribute * Purple__StatusAttr;
typedef PurpleStatusPrimitive Purple__StatusPrimitive;
typedef PurpleStatusType * Purple__StatusType;
@@ -273,9 +282,6 @@ typedef PurpleStringref * Purple__Stringref;
typedef PurpleInfoFieldFormatCallback Purple__Util__InfoFieldFormatCallback;
typedef PurpleMenuAction * Purple__Menu__Action;
-/* value.h */
-typedef PurpleValue * Purple__Value;
-
/* whiteboard.h */
typedef PurpleWhiteboard * Purple__Whiteboard;
diff --git a/libpurple/plugins/perl/common/typemap b/libpurple/plugins/perl/common/typemap
index 6f698a220a..5cad01ffc5 100644
--- a/libpurple/plugins/perl/common/typemap
+++ b/libpurple/plugins/perl/common/typemap
@@ -38,10 +38,13 @@ xmlnode * T_PTR
const xmlnode * T_PTR
gssize T_IV
const void * T_PTR
+GValue * T_PTR
+GType T_IV
Purple::Account T_PurpleObj
Purple::Account::Option T_PurpleObj
Purple::Account::UserSplit T_PurpleObj
+Purple::Account::PrivacyType T_IV
Purple::Buddy::Icon T_PurpleObj
Purple::Buddy::Icon::Spec T_PurpleObj
@@ -51,22 +54,15 @@ Purple::BuddyList::Chat T_PurpleObj
Purple::BuddyList::Contact T_PurpleObj
Purple::BuddyList::Group T_PurpleObj
Purple::BuddyList::Node T_PurpleObj
-Purple::BuddyList::NodeFlags T_IV
-Purple::BuddyList::NodeType T_IV
+Purple::BuddyList::CountingNode T_PurpleObj
Purple::Cipher T_PurpleObj
-Purple::CipherCaps T_IV
-Purple::Cipher::Ops T_PurpleObj
-Purple::Cipher::Context T_PurpleObj
+Purple::Hash T_PurpleObj
Purple::Cmd::Flag T_IV
Purple::Cmd::Id T_IV
Purple::Cmd::Priority T_IV
Purple::Cmd::Ret T_IV
Purple::Connection T_PurpleObj
-Purple::Conversation T_PurpleObj
-Purple::Conversation::Chat T_PurpleObj
-Purple::Conversation::ChatBuddy T_PurpleObj
-Purple::Conversation::IM T_PurpleObj
Purple::Core T_PurpleObj
Purple::Desktop::Item T_PurpleObj
@@ -111,8 +107,6 @@ Purple::PluginPrefType T_IV
Purple::PluginPref::Frame T_PurpleObj
Purple::Pounce T_PurpleObj
Purple::PounceEvent T_IV
-Purple::Presence T_PurpleObj
-Purple::PrivacyType T_IV
Purple::ProtocolOptions T_IV
Purple::ProxyInfo T_PurpleObj
Purple::ProxyType T_IV
@@ -141,7 +135,8 @@ Purple::Ssl::Connection T_PurpleObj
Purple::Ssl::Ops T_PurpleObj
Purple::Presence T_PurpleObj
-Purple::PresenceContext T_IV
+Purple::AccountPresence T_PurpleObj
+Purple::BuddyPresence T_PurpleObj
Purple::Smiley T_PurpleObj
Purple::Status T_PurpleObj
Purple::StatusAttr T_PurpleObj
@@ -154,7 +149,6 @@ Purple::String::Format::Type T_IV
Purple::Stringref T_PurpleObj
Purple::Util::FetchUrlData T_PTR
Purple::Util::InfoFieldFormatCallback T_PTR
-Purple::Value T_PurpleObj
Purple::Xfer T_PurpleObj
Purple::XferType T_IV
@@ -181,12 +175,15 @@ Purple::Cipher::BatchMode T_IV
/* debug.h */
Purple::DebugLevel T_IV
-/* conversation.h */
-Purple::ConvChatBuddyFlags T_IV
-Purple::ConvUpdateType T_IV
-Purple::ConversationType T_IV
+/* conversations.h */
+Purple::Conversation T_PurpleObj
+Purple::ChatConversation T_PurpleObj
+Purple::ChatUser T_PurpleObj
+Purple::IMConversation T_PurpleObj
+Purple::ChatUser::Flags T_IV
+Purple::Conversation::UpdateType T_IV
Purple::MessageFlags T_IV
-Purple::TypingState T_IV
+Purple::IMTypingState T_IV
Purple::UnseenState T_IV
/* connection.h */
diff --git a/libpurple/plugins/perl/perl-common.c b/libpurple/plugins/perl/perl-common.c
index 520a8c420a..aa890fa52e 100644
--- a/libpurple/plugins/perl/perl-common.c
+++ b/libpurple/plugins/perl/perl-common.c
@@ -1,8 +1,9 @@
-#include "debug.h"
-#include "value.h"
-
#include "perl-common.h"
+#include "cipher.h"
+#include "debug.h"
+#include "savedstatuses.h"
+
extern PerlInterpreter *my_perl;
static GHashTable *object_stashes = NULL;
@@ -379,102 +380,76 @@ purple_perl_sv_from_value(const PurpleValue *value, va_list list)
#endif
void *
-purple_perl_data_from_sv(PurpleValue *value, SV *sv)
+purple_perl_data_from_sv(GType type, SV *sv)
{
-
- switch (purple_value_get_type(value)) {
- case PURPLE_TYPE_BOOLEAN: return (void *)SvIV(sv);
- case PURPLE_TYPE_INT: return (void *)SvIV(sv);
- case PURPLE_TYPE_UINT: return (void *)SvUV(sv);
- case PURPLE_TYPE_LONG: return (void *)SvIV(sv);
- case PURPLE_TYPE_ULONG: return (void *)SvUV(sv);
- case PURPLE_TYPE_INT64: return (void *)SvIV(sv);
- case PURPLE_TYPE_UINT64: return (void *)SvUV(sv);
- case PURPLE_TYPE_STRING: return g_strdup(SvPVutf8_nolen(sv));
- case PURPLE_TYPE_POINTER: return (void *)SvIV(sv);
- case PURPLE_TYPE_BOXED: return (void *)SvIV(sv);
-
- default:
- return NULL;
+ switch (type) {
+ case G_TYPE_BOOLEAN: return (void *)SvIV(sv);
+ case G_TYPE_INT: return (void *)SvIV(sv);
+ case G_TYPE_UINT: return (void *)SvUV(sv);
+ case G_TYPE_LONG: return (void *)SvIV(sv);
+ case G_TYPE_ULONG: return (void *)SvUV(sv);
+ case G_TYPE_INT64: return (void *)SvIV(sv);
+ case G_TYPE_UINT64: return (void *)SvUV(sv);
+ case G_TYPE_STRING: return g_strdup(SvPVutf8_nolen(sv));
+ case G_TYPE_POINTER: return (void *)SvIV(sv);
}
return NULL;
}
static SV *
-purple_perl_sv_from_subtype(const PurpleValue *value, void *arg)
+purple_perl_sv_from_purple_type(GType type, void *arg)
{
const char *stash = "Purple"; /* ? */
- switch (purple_value_get_subtype(value)) {
- case PURPLE_SUBTYPE_ACCOUNT:
- stash = "Purple::Account";
- break;
- case PURPLE_SUBTYPE_BLIST:
- stash = "Purple::BuddyList";
- break;
- case PURPLE_SUBTYPE_BLIST_BUDDY:
- stash = "Purple::BuddyList::Buddy";
- break;
- case PURPLE_SUBTYPE_BLIST_GROUP:
- stash = "Purple::BuddyList::Group";
- break;
- case PURPLE_SUBTYPE_BLIST_CHAT:
- stash = "Purple::BuddyList::Chat";
- break;
- case PURPLE_SUBTYPE_BUDDY_ICON:
- stash = "Purple::Buddy::Icon";
- break;
- case PURPLE_SUBTYPE_CONNECTION:
- stash = "Purple::Connection";
- break;
- case PURPLE_SUBTYPE_CONVERSATION:
- stash = "Purple::Conversation";
- break;
- case PURPLE_SUBTYPE_PLUGIN:
- stash = "Purple::Plugin";
- break;
- case PURPLE_SUBTYPE_BLIST_NODE:
- stash = "Purple::BuddyList::Node";
- break;
- case PURPLE_SUBTYPE_CIPHER:
- stash = "Purple::Cipher";
- break;
- case PURPLE_SUBTYPE_STATUS:
- stash = "Purple::Status";
- break;
- case PURPLE_SUBTYPE_SAVEDSTATUS:
- stash = "Purple::SavedStatus";
- break;
- case PURPLE_SUBTYPE_LOG:
- stash = "Purple::Log";
- break;
- case PURPLE_SUBTYPE_XFER:
- stash = "Purple::Xfer";
- break;
- case PURPLE_SUBTYPE_XMLNODE:
- stash = "Purple::XMLNode";
- break;
- case PURPLE_SUBTYPE_USERINFO:
- stash = "Purple::NotifyUserInfo";
- break;
- case PURPLE_SUBTYPE_STORED_IMAGE:
- stash = "Purple::StoredImage";
- break;
- case PURPLE_SUBTYPE_CERTIFICATEPOOL:
- stash = "Purple::Certificate::Pool";
- break;
- case PURPLE_SUBTYPE_UNKNOWN:
- stash = "Purple::Unknown";
- break;
- }
+ if (type == PURPLE_TYPE_ACCOUNT)
+ stash = "Purple::Account";
+ else if (type == PURPLE_TYPE_CONTACT)
+ stash = "Purple::BuddyList::Contact";
+ else if (type == PURPLE_TYPE_BUDDY)
+ stash = "Purple::BuddyList::Buddy";
+ else if (type == PURPLE_TYPE_GROUP)
+ stash = "Purple::BuddyList::Group";
+ else if (type == PURPLE_TYPE_CHAT)
+ stash = "Purple::BuddyList::Chat";
+ else if (type == PURPLE_TYPE_BUDDY_ICON)
+ stash = "Purple::Buddy::Icon";
+ else if (type == PURPLE_TYPE_CONNECTION)
+ stash = "Purple::Connection";
+ else if (type == PURPLE_TYPE_CONVERSATION)
+ stash = "Purple::Conversation";
+ else if (type == PURPLE_TYPE_PLUGIN)
+ stash = "Purple::Plugin";
+ else if (type == PURPLE_TYPE_BLIST_NODE)
+ stash = "Purple::BuddyList::Node";
+ else if (type == PURPLE_TYPE_CIPHER)
+ stash = "Purple::Cipher";
+ else if (type == PURPLE_TYPE_STATUS)
+ stash = "Purple::Status";
+ else if (type == PURPLE_TYPE_SAVEDSTATUS)
+ stash = "Purple::SavedStatus";
+ else if (type == PURPLE_TYPE_LOG)
+ stash = "Purple::Log";
+ else if (type == PURPLE_TYPE_XFER)
+ stash = "Purple::Xfer";
+ else if (type == PURPLE_TYPE_XMLNODE)
+ stash = "Purple::XMLNode";
+ else if (type == PURPLE_TYPE_NOTIFY_USER_INFO)
+ stash = "Purple::NotifyUserInfo";
+ else if (type == PURPLE_TYPE_STORED_IMAGE)
+ stash = "Purple::StoredImage";
+ else if (type == PURPLE_TYPE_CERTIFICATE_POOL)
+ stash = "Purple::Certificate::Pool";
+ else
+ stash = "Purple::Unknown";
return sv_2mortal(purple_perl_bless_object(arg, stash));
}
SV *
-purple_perl_sv_from_vargs(const PurpleValue *value, va_list *args, void ***copy_arg)
+purple_perl_sv_from_vargs(GType type, va_list *args, void ***copy_arg)
{
+#if 0
if (purple_value_is_outgoing(value)) {
switch (purple_value_get_type(value)) {
case PURPLE_TYPE_SUBTYPE:
@@ -552,80 +527,60 @@ purple_perl_sv_from_vargs(const PurpleValue *value, va_list *args, void ***copy_
return NULL;
}
} else {
- switch (purple_value_get_type(value)) {
- case PURPLE_TYPE_SUBTYPE:
- if ((*copy_arg = va_arg(*args, void *)) == NULL)
- return &PL_sv_undef;
-
- return purple_perl_sv_from_subtype(value, *copy_arg);
+#endif
+ switch (type) {
+ case G_TYPE_BOOLEAN:
+ *copy_arg = GINT_TO_POINTER( va_arg(*args, gboolean) );
- case PURPLE_TYPE_BOOLEAN:
- *copy_arg = GINT_TO_POINTER( va_arg(*args, gboolean) );
+ return newSViv((gboolean)GPOINTER_TO_INT(*copy_arg));
- return newSViv((gboolean)GPOINTER_TO_INT(*copy_arg));
+ case G_TYPE_INT:
+ *copy_arg = GINT_TO_POINTER( va_arg(*args, int) );
- case PURPLE_TYPE_INT:
- *copy_arg = GINT_TO_POINTER( va_arg(*args, int) );
+ return newSViv(GPOINTER_TO_INT(*copy_arg));
- return newSViv(GPOINTER_TO_INT(*copy_arg));
+ case G_TYPE_UINT:
+ *copy_arg = GUINT_TO_POINTER(va_arg(*args, unsigned int));
- case PURPLE_TYPE_UINT:
- *copy_arg = GUINT_TO_POINTER(va_arg(*args, unsigned int));
+ return newSVuv(GPOINTER_TO_UINT(*copy_arg));
- return newSVuv(GPOINTER_TO_UINT(*copy_arg));
+ case G_TYPE_LONG:
+ *copy_arg = (void *)va_arg(*args, long);
- case PURPLE_TYPE_LONG:
- *copy_arg = (void *)va_arg(*args, long);
+ return newSViv((long)*copy_arg);
- return newSViv((long)*copy_arg);
+ case G_TYPE_ULONG:
+ *copy_arg = (void *)va_arg(*args, unsigned long);
- case PURPLE_TYPE_ULONG:
- *copy_arg = (void *)va_arg(*args, unsigned long);
+ return newSVuv((unsigned long)*copy_arg);
- return newSVuv((unsigned long)*copy_arg);
+ case G_TYPE_INT64:
+ *copy_arg = (void *)va_arg(*args, gint64);
- case PURPLE_TYPE_INT64:
-#if 0
- /* XXX This yells and complains. */
- *copy_arg = va_arg(*args, gint64);
+ return newSViv((gint64)*copy_arg);
- return newSViv(*copy_arg);
-#endif
- break;
+ case G_TYPE_UINT64:
+ *copy_arg = (void *)va_arg(*args, guint64);
- case PURPLE_TYPE_UINT64:
- /* XXX This also yells and complains. */
-#if 0
- *copy_arg = (void *)va_arg(*args, guint64);
+ return newSVuv((guint64)*copy_arg);
- return newSVuv(*copy_arg);
-#endif
- break;
+ case G_TYPE_STRING:
+ if ((*copy_arg = (void *)va_arg(*args, char *)) == NULL)
+ return &PL_sv_undef;
- case PURPLE_TYPE_STRING:
- if ((*copy_arg = (void *)va_arg(*args, char *)) == NULL)
- return &PL_sv_undef;
+ return newSVGChar((char *)*copy_arg);
- return newSVGChar((char *)*copy_arg);
+ case G_TYPE_POINTER:
+ if ((*copy_arg = (void *)va_arg(*args, void *)) == NULL)
+ return &PL_sv_undef;
- case PURPLE_TYPE_POINTER:
- if ((*copy_arg = (void *)va_arg(*args, void *)) == NULL)
- return &PL_sv_undef;
-
- return newSViv((IV)*copy_arg);
-
- case PURPLE_TYPE_BOXED:
- /* Uh.. I dunno. Try this? */
- if ((*copy_arg = (void *)va_arg(*args, void *)) == NULL)
- return &PL_sv_undef;
+ return newSViv((IV)*copy_arg);
- return sv_2mortal(purple_perl_bless_object(*copy_arg,
- purple_value_get_specific_type(value)));
+ default:
+ if ((*copy_arg = va_arg(*args, void *)) == NULL)
+ return &PL_sv_undef;
- default:
- /* If this happens, things are going to get screwed up... */
- return NULL;
- }
+ return purple_perl_sv_from_purple_type(type, *copy_arg);
}
return NULL;
diff --git a/libpurple/plugins/perl/perl-common.h b/libpurple/plugins/perl/perl-common.h
index 677e3bcaba..cda580c054 100644
--- a/libpurple/plugins/perl/perl-common.h
+++ b/libpurple/plugins/perl/perl-common.h
@@ -21,7 +21,6 @@
#undef _WIN32DEP_H_
#endif
#include "plugin.h"
-#include "value.h"
#define is_hvref(o) \
((o) && SvROK(o) && SvRV(o) && (SvTYPE(SvRV(o)) == SVt_PVHV))
@@ -68,8 +67,7 @@ gboolean purple_perl_value_from_sv(PurpleValue *value, SV *sv);
SV *purple_perl_sv_from_value(const PurpleValue *value);
#endif
-void *purple_perl_data_from_sv(PurpleValue *value, SV *sv);
-SV *purple_perl_sv_from_vargs(const PurpleValue *value, va_list *args,
- void ***copy_arg);
+void *purple_perl_data_from_sv(GType type, SV *sv);
+SV *purple_perl_sv_from_vargs(GType type, va_list *args, void ***copy_arg);
SV *purple_perl_sv_from_fun(PurplePlugin *plugin, SV *callback);
#endif /* _PURPLE_PERL_COMMON_H_ */
diff --git a/libpurple/plugins/perl/perl-handlers.c b/libpurple/plugins/perl/perl-handlers.c
index 1e8eb5830d..d87f63cfc7 100644
--- a/libpurple/plugins/perl/perl-handlers.c
+++ b/libpurple/plugins/perl/perl-handlers.c
@@ -285,7 +285,7 @@ perl_signal_cb(va_list args, void *data)
int i;
int count;
int value_count;
- PurpleValue *ret_value, **values;
+ GType ret_type, *value_types;
SV **sv_args;
DATATYPE **copy_args;
@@ -296,14 +296,14 @@ perl_signal_cb(va_list args, void *data)
SAVETMPS;
PUSHMARK(sp);
- purple_signal_get_values(handler->instance, handler->signal,
- &ret_value, &value_count, &values);
+ purple_signal_get_types(handler->instance, handler->signal,
+ &ret_type, &value_count, &value_types);
sv_args = g_new(SV *, value_count);
copy_args = g_new(void **, value_count);
for (i = 0; i < value_count; i++) {
- sv_args[i] = purple_perl_sv_from_vargs(values[i],
+ sv_args[i] = purple_perl_sv_from_vargs(value_types[i],
#ifdef VA_COPY_AS_ARRAY
(va_list*)args,
#else
@@ -318,7 +318,7 @@ perl_signal_cb(va_list args, void *data)
PUTBACK;
- if (ret_value != NULL) {
+ if (ret_type != G_TYPE_NONE) {
count = call_sv(handler->callback, G_EVAL | G_SCALAR);
SPAGAIN;
@@ -326,7 +326,7 @@ perl_signal_cb(va_list args, void *data)
if (count != 1)
croak("Uh oh! call_sv returned %i != 1", i);
else
- ret_val = purple_perl_data_from_sv(ret_value, POPs);
+ ret_val = purple_perl_data_from_sv(ret_type, POPs);
} else {
call_sv(handler->callback, G_EVAL | G_SCALAR);
@@ -339,6 +339,7 @@ perl_signal_cb(va_list args, void *data)
SvPVutf8_nolen(ERRSV));
}
+#if 0
/* See if any parameters changed. */
for (i = 0; i < value_count; i++) {
if (purple_value_is_outgoing(values[i])) {
@@ -401,6 +402,7 @@ perl_signal_cb(va_list args, void *data)
#endif
}
}
+#endif
PUTBACK;
FREETMPS;
diff --git a/libpurple/plugins/psychic.c b/libpurple/plugins/psychic.c
index 787bfd1654..c79cd0ca21 100644
--- a/libpurple/plugins/psychic.c
+++ b/libpurple/plugins/psychic.c
@@ -3,13 +3,12 @@
#include "internal.h"
#include "account.h"
-#include "blist.h"
+#include "buddylist.h"
#include "conversation.h"
#include "debug.h"
#include "signals.h"
#include "status.h"
#include "version.h"
-#include "privacy.h"
#include "plugin.h"
#include "pluginpref.h"
@@ -34,7 +33,7 @@
static void
buddy_typing_cb(PurpleAccount *acct, const char *name, void *data) {
- PurpleConversation *gconv;
+ PurpleIMConversation *im;
if(purple_prefs_get_bool(PREF_STATUS) &&
! purple_status_is_available(purple_account_get_active_status(acct))) {
@@ -43,23 +42,23 @@ buddy_typing_cb(PurpleAccount *acct, const char *name, void *data) {
}
if(purple_prefs_get_bool(PREF_BUDDIES) &&
- ! purple_find_buddy(acct, name)) {
+ ! purple_blist_find_buddy(acct, name)) {
purple_debug_info("psychic", "not in blist, doing nothing\n");
return;
}
- if(FALSE == purple_privacy_check(acct, name)) {
+ if(FALSE == purple_account_privacy_check(acct, name)) {
purple_debug_info("psychic", "user %s is blocked\n", name);
return;
}
- gconv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, name, acct);
- if(! gconv) {
+ im = purple_conversations_find_im_with_account(name, acct);
+ if(! im) {
purple_debug_info("psychic", "no previous conversation exists\n");
- gconv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, name);
+ im = purple_im_conversation_new(acct, name);
if(purple_prefs_get_bool(PREF_RAISE)) {
- purple_conversation_present(gconv);
+ purple_conversation_present(PURPLE_CONVERSATION(im));
}
if(purple_prefs_get_bool(PREF_NOTICE)) {
@@ -68,14 +67,14 @@ buddy_typing_cb(PurpleAccount *acct, const char *name, void *data) {
translate it literally. If you can't find a fitting cultural
reference in your language, consider translating something
like this instead: "You feel a new message coming." */
- purple_conversation_write(gconv, NULL,
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL,
_("You feel a disturbance in the force..."),
PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG | PURPLE_MESSAGE_ACTIVE_ONLY,
time(NULL));
}
/* Necessary because we may be creating a new conversation window. */
- purple_conv_im_set_typing_state(PURPLE_CONV_IM(gconv), PURPLE_TYPING);
+ purple_im_conversation_set_typing_state(im, PURPLE_IM_TYPING);
}
}
diff --git a/libpurple/plugins/signals-test.c b/libpurple/plugins/signals-test.c
index 840b260d11..19ba8afa00 100644
--- a/libpurple/plugins/signals-test.c
+++ b/libpurple/plugins/signals-test.c
@@ -24,7 +24,6 @@
#include <stdio.h>
-#include "cipher.h"
#include "connection.h"
#include "conversation.h"
#include "core.h"
@@ -74,7 +73,7 @@ account_alias_changed(PurpleAccount *account, const char *old, gpointer data)
{
purple_debug_misc("signals test", "account-alias-changed (%s, %s, %s)\n",
purple_account_get_username(account),
- old, purple_account_get_alias(account));
+ old, purple_account_get_private_alias(account));
}
static int
@@ -149,12 +148,12 @@ static void
blist_node_added_cb(PurpleBlistNode *bnode, void *data)
{
const char *name;
- if (PURPLE_BLIST_NODE_IS_GROUP(bnode))
+ if (PURPLE_IS_GROUP(bnode))
name = purple_group_get_name(PURPLE_GROUP(bnode));
- else if (PURPLE_BLIST_NODE_IS_CONTACT(bnode))
+ else if (PURPLE_IS_CONTACT(bnode))
/* Close enough */
name = purple_contact_get_alias(PURPLE_CONTACT(bnode));
- else if (PURPLE_BLIST_NODE_IS_BUDDY(bnode))
+ else if (PURPLE_IS_BUDDY(bnode))
name = purple_buddy_get_name(PURPLE_BUDDY(bnode));
else
name = "(unknown)";
@@ -167,12 +166,12 @@ static void
blist_node_removed_cb(PurpleBlistNode *bnode, void *data)
{
const char *name;
- if (PURPLE_BLIST_NODE_IS_GROUP(bnode))
+ if (PURPLE_IS_GROUP(bnode))
name = purple_group_get_name(PURPLE_GROUP(bnode));
- else if (PURPLE_BLIST_NODE_IS_CONTACT(bnode))
+ else if (PURPLE_IS_CONTACT(bnode))
/* Close enough */
name = purple_contact_get_alias(PURPLE_CONTACT(bnode));
- else if (PURPLE_BLIST_NODE_IS_BUDDY(bnode))
+ else if (PURPLE_IS_BUDDY(bnode))
name = purple_buddy_get_name(PURPLE_BUDDY(bnode));
else
name = "(unknown)";
@@ -184,62 +183,54 @@ blist_node_removed_cb(PurpleBlistNode *bnode, void *data)
static void
blist_node_aliased(PurpleBlistNode *node, const char *old_alias)
{
- PurpleContact *p = (PurpleContact *)node;
- PurpleBuddy *b = (PurpleBuddy *)node;
- PurpleChat *c = (PurpleChat *)node;
- PurpleGroup *g = (PurpleGroup *)node;
+ PurpleContact *p = PURPLE_CONTACT(node);
+ PurpleBuddy *b = PURPLE_BUDDY(node);
+ PurpleChat *c = PURPLE_CHAT(node);
+ PurpleGroup *g = PURPLE_GROUP(node);
- if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if (PURPLE_IS_CONTACT(node)) {
purple_debug_misc("signals test",
"blist-node-aliased (Contact: %s, %s)\n",
purple_contact_get_alias(p), old_alias);
- } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ } else if (PURPLE_IS_BUDDY(node)) {
purple_debug_misc("signals test",
"blist-node-aliased (Buddy: %s, %s)\n",
purple_buddy_get_name(b), old_alias);
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
purple_debug_misc("signals test",
"blist-node-aliased (Chat: %s, %s)\n",
purple_chat_get_name(c), old_alias);
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
purple_debug_misc("signals test",
"blist-node-aliased (Group: %s, %s)\n",
purple_group_get_name(g), old_alias);
- } else {
- purple_debug_misc("signals test",
- "blist-node-aliased (UNKNOWN: %d, %s)\n",
- purple_blist_node_get_type(node), old_alias);
}
}
static void
blist_node_extended_menu_cb(PurpleBlistNode *node, void *data)
{
- PurpleContact *p = (PurpleContact *)node;
- PurpleBuddy *b = (PurpleBuddy *)node;
- PurpleChat *c = (PurpleChat *)node;
- PurpleGroup *g = (PurpleGroup *)node;
+ PurpleContact *p = PURPLE_CONTACT(node);
+ PurpleBuddy *b = PURPLE_BUDDY(node);
+ PurpleChat *c = PURPLE_CHAT(node);
+ PurpleGroup *g = PURPLE_GROUP(node);
- if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if (PURPLE_IS_CONTACT(node)) {
purple_debug_misc("signals test",
"blist-node-extended-menu (Contact: %s)\n",
purple_contact_get_alias(p));
- } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ } else if (PURPLE_IS_BUDDY(node)) {
purple_debug_misc("signals test",
"blist-node-extended-menu (Buddy: %s)\n",
purple_buddy_get_name(b));
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
purple_debug_misc("signals test",
"blist-node-extended-menu (Chat: %s)\n",
purple_chat_get_name(c));
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
purple_debug_misc("signals test",
"blist-node-extended-menu (Group: %s)\n",
purple_group_get_name(g));
- } else {
- purple_debug_misc("signals test",
- "blist-node-extended-menu (UNKNOWN: %d)\n",
- purple_blist_node_get_type(node));
}
}
@@ -429,46 +420,48 @@ buddy_typing_stopped_cb(PurpleAccount *account, const char *name, void *data)
}
static gboolean
-chat_buddy_joining_cb(PurpleConversation *conv, const char *user,
- PurpleConvChatBuddyFlags flags, void *data)
+chat_user_joining_cb(PurpleConversation *conv, const char *user,
+ PurpleChatUserFlags flags, void *data)
{
- purple_debug_misc("signals test", "chat-buddy-joining (%s, %s, %d)\n",
+ purple_debug_misc("signals test", "chat-user-joining (%s, %s, %d)\n",
purple_conversation_get_name(conv), user, flags);
return FALSE;
}
static void
-chat_buddy_joined_cb(PurpleConversation *conv, const char *user,
- PurpleConvChatBuddyFlags flags, gboolean new_arrival, void *data)
+chat_user_joined_cb(PurpleConversation *conv, const char *user,
+ PurpleChatUserFlags flags, gboolean new_arrival, void *data)
{
- purple_debug_misc("signals test", "chat-buddy-joined (%s, %s, %d, %d)\n",
+ purple_debug_misc("signals test", "chat-user-joined (%s, %s, %d, %d)\n",
purple_conversation_get_name(conv), user, flags, new_arrival);
}
static void
-chat_buddy_flags_cb(PurpleConversation *conv, const char *user,
- PurpleConvChatBuddyFlags oldflags, PurpleConvChatBuddyFlags newflags, void *data)
+chat_user_flags_cb(PurpleChatUser *cb, PurpleChatUserFlags oldflags,
+ PurpleChatUserFlags newflags, void *data)
{
- purple_debug_misc("signals test", "chat-buddy-flags (%s, %s, %d, %d)\n",
- purple_conversation_get_name(conv), user, oldflags, newflags);
+ purple_debug_misc("signals test", "chat-user-flags (%s, %s, %d, %d)\n",
+ purple_conversation_get_name(PURPLE_CONVERSATION(
+ purple_chat_user_get_chat(cb))),
+ purple_chat_user_get_name(cb), oldflags, newflags);
}
static gboolean
-chat_buddy_leaving_cb(PurpleConversation *conv, const char *user,
+chat_user_leaving_cb(PurpleConversation *conv, const char *user,
const char *reason, void *data)
{
- purple_debug_misc("signals test", "chat-buddy-leaving (%s, %s, %s)\n",
+ purple_debug_misc("signals test", "chat-user-leaving (%s, %s, %s)\n",
purple_conversation_get_name(conv), user, reason);
return FALSE;
}
static void
-chat_buddy_left_cb(PurpleConversation *conv, const char *user,
+chat_user_left_cb(PurpleConversation *conv, const char *user,
const char *reason, void *data)
{
- purple_debug_misc("signals test", "chat-buddy-left (%s, %s, %s)\n",
+ purple_debug_misc("signals test", "chat-user-left (%s, %s, %s)\n",
purple_conversation_get_name(conv), user, reason);
}
@@ -524,21 +517,6 @@ chat_topic_changed_cb(PurpleConversation *conv, const char *who,
(who) ? who : "unknown");
}
/**************************************************************************
- * Ciphers signal callbacks
- **************************************************************************/
-static void
-cipher_added_cb(PurpleCipher *cipher, void *data) {
- purple_debug_misc("signals test", "cipher %s added\n",
- purple_cipher_get_name(cipher));
-}
-
-static void
-cipher_removed_cb(PurpleCipher *cipher, void *data) {
- purple_debug_misc("signals test", "cipher %s removed\n",
- purple_cipher_get_name(cipher));
-}
-
-/**************************************************************************
* Core signal callbacks
**************************************************************************/
static void
@@ -719,7 +697,6 @@ plugin_load(PurplePlugin *plugin)
void *conn_handle = purple_connections_get_handle();
void *conv_handle = purple_conversations_get_handle();
void *accounts_handle = purple_accounts_get_handle();
- void *ciphers_handle = purple_ciphers_get_handle();
void *ft_handle = purple_xfers_get_handle();
void *sound_handle = purple_sounds_get_handle();
void *notify_handle = purple_notify_get_handle();
@@ -808,16 +785,16 @@ plugin_load(PurplePlugin *plugin)
plugin, PURPLE_CALLBACK(buddy_typing_cb), NULL);
purple_signal_connect(conv_handle, "buddy-typing-stopped",
plugin, PURPLE_CALLBACK(buddy_typing_stopped_cb), NULL);
- purple_signal_connect(conv_handle, "chat-buddy-joining",
- plugin, PURPLE_CALLBACK(chat_buddy_joining_cb), NULL);
- purple_signal_connect(conv_handle, "chat-buddy-joined",
- plugin, PURPLE_CALLBACK(chat_buddy_joined_cb), NULL);
- purple_signal_connect(conv_handle, "chat-buddy-flags",
- plugin, PURPLE_CALLBACK(chat_buddy_flags_cb), NULL);
- purple_signal_connect(conv_handle, "chat-buddy-leaving",
- plugin, PURPLE_CALLBACK(chat_buddy_leaving_cb), NULL);
- purple_signal_connect(conv_handle, "chat-buddy-left",
- plugin, PURPLE_CALLBACK(chat_buddy_left_cb), NULL);
+ purple_signal_connect(conv_handle, "chat-user-joining",
+ plugin, PURPLE_CALLBACK(chat_user_joining_cb), NULL);
+ purple_signal_connect(conv_handle, "chat-user-joined",
+ plugin, PURPLE_CALLBACK(chat_user_joined_cb), NULL);
+ purple_signal_connect(conv_handle, "chat-user-flags",
+ plugin, PURPLE_CALLBACK(chat_user_flags_cb), NULL);
+ purple_signal_connect(conv_handle, "chat-user-leaving",
+ plugin, PURPLE_CALLBACK(chat_user_leaving_cb), NULL);
+ purple_signal_connect(conv_handle, "chat-user-left",
+ plugin, PURPLE_CALLBACK(chat_user_left_cb), NULL);
purple_signal_connect(conv_handle, "chat-inviting-user",
plugin, PURPLE_CALLBACK(chat_inviting_user_cb), NULL);
purple_signal_connect(conv_handle, "chat-invited-user",
@@ -831,12 +808,6 @@ plugin_load(PurplePlugin *plugin)
purple_signal_connect(conv_handle, "chat-topic-changed",
plugin, PURPLE_CALLBACK(chat_topic_changed_cb), NULL);
- /* Ciphers signals */
- purple_signal_connect(ciphers_handle, "cipher-added",
- plugin, PURPLE_CALLBACK(cipher_added_cb), NULL);
- purple_signal_connect(ciphers_handle, "cipher-removed",
- plugin, PURPLE_CALLBACK(cipher_removed_cb), NULL);
-
/* Core signals */
purple_signal_connect(core_handle, "quitting",
plugin, PURPLE_CALLBACK(quitting_cb), NULL);
diff --git a/libpurple/plugins/statenotify.c b/libpurple/plugins/statenotify.c
index ca74854e90..92ead65679 100644
--- a/libpurple/plugins/statenotify.c
+++ b/libpurple/plugins/statenotify.c
@@ -1,6 +1,6 @@
#include "internal.h"
-#include "blist.h"
+#include "buddylist.h"
#include "conversation.h"
#include "debug.h"
#include "signals.h"
@@ -16,7 +16,7 @@ static void
write_status(PurpleBuddy *buddy, const char *message)
{
PurpleAccount *account = NULL;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
const char *who;
char buf[256];
char *escaped;
@@ -25,15 +25,13 @@ write_status(PurpleBuddy *buddy, const char *message)
account = purple_buddy_get_account(buddy);
buddy_name = purple_buddy_get_name(buddy);
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- buddy_name, account);
+ im = purple_conversations_find_im_with_account(buddy_name, account);
- if (conv == NULL)
+ if (im == NULL)
return;
- 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))
+ if (buddy != purple_blist_find_buddy(account, buddy_name))
return;
who = purple_buddy_get_alias(buddy);
@@ -42,7 +40,9 @@ write_status(PurpleBuddy *buddy, const char *message)
g_snprintf(buf, sizeof(buf), message, escaped);
g_free(escaped);
- purple_conv_im_write(PURPLE_CONV_IM(conv), NULL, buf, PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_ACTIVE_ONLY | PURPLE_MESSAGE_NO_LINKIFY, time(NULL));
+ purple_conversation_write_message(PURPLE_CONVERSATION(im), 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 04ed4a3b7c..4a95b4883e 100644
--- a/libpurple/plugins/tcl/tcl_cmds.c
+++ b/libpurple/plugins/tcl/tcl_cmds.c
@@ -29,10 +29,11 @@
#include "account.h"
#include "server.h"
#include "notify.h"
-#include "blist.h"
+#include "buddylist.h"
#include "savedstatuses.h"
#include "debug.h"
#include "prefs.h"
+#include "presence.h"
#include "core.h"
#include "tcl_purple.h"
@@ -70,7 +71,7 @@ static PurpleConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *i
if (convo == NULL)
return NULL;
- for (cur = purple_get_conversations(); cur != NULL; cur = g_list_next(cur)) {
+ for (cur = purple_conversations_get_all(); cur != NULL; cur = g_list_next(cur)) {
if (convo == cur->data)
return convo;
}
@@ -118,7 +119,7 @@ int tcl_cmd_account(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CO
PurpleAccount *account;
PurpleStatus *status;
PurpleStatusType *status_type;
- PurpleValue *value;
+ GValue *value;
char *attr_id;
int error;
int b, i;
@@ -139,7 +140,7 @@ int tcl_cmd_account(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CO
}
if ((account = tcl_validate_account(objv[2], interp)) == NULL)
return TCL_ERROR;
- alias = purple_account_get_alias(account);
+ alias = purple_account_get_private_alias(account);
Tcl_SetObjResult(interp, Tcl_NewStringObj(alias ? (char *)alias : "", -1));
break;
case CMD_ACCOUNT_CONNECT:
@@ -292,27 +293,27 @@ int tcl_cmd_account(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CO
Tcl_SetObjResult(interp, Tcl_NewStringObj("invalid attribute for account", -1));
return TCL_ERROR;
}
- switch (purple_value_get_type(value)) {
- case PURPLE_TYPE_BOOLEAN:
+ switch (G_VALUE_TYPE(value)) {
+ case G_TYPE_BOOLEAN:
error = Tcl_GetBooleanFromObj(interp, objv[i + 1], &b);
if (error != TCL_OK)
return error;
l = g_list_append(l, attr_id);
l = g_list_append(l, GINT_TO_POINTER(b));
break;
- case PURPLE_TYPE_INT:
+ case G_TYPE_INT:
error = Tcl_GetIntFromObj(interp, objv[i + 1], &b);
if (error != TCL_OK)
return error;
l = g_list_append(l, attr_id);
l = g_list_append(l, GINT_TO_POINTER(b));
break;
- case PURPLE_TYPE_STRING:
+ case G_TYPE_STRING:
l = g_list_append(l, attr_id);
l = g_list_append(l, Tcl_GetString(objv[i + 1]));
break;
default:
- Tcl_SetObjResult(interp, Tcl_NewStringObj("unknown PurpleValue type", -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("unknown GValue type", -1));
return TCL_ERROR;
}
}
@@ -401,7 +402,7 @@ static PurpleBlistNode *tcl_list_to_buddy(Tcl_Interp *interp, int count, Tcl_Obj
return NULL;
if (!strcmp(type, "buddy")) {
- node = PURPLE_BLIST_NODE(purple_find_buddy(account, name));
+ node = PURPLE_BLIST_NODE(purple_blist_find_buddy(account, name));
} else if (!strcmp(type, "group")) {
node = PURPLE_BLIST_NODE(purple_blist_find_chat(account, name));
}
@@ -414,7 +415,6 @@ int tcl_cmd_buddy(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONS
Tcl_Obj *list, *tclgroup, *tclgrouplist, *tclcontact, *tclcontactlist, *tclbud, **elems, *result;
const char *cmds[] = { "alias", "handle", "info", "list", NULL };
enum { CMD_BUDDY_ALIAS, CMD_BUDDY_HANDLE, CMD_BUDDY_INFO, CMD_BUDDY_LIST } cmd;
- PurpleBlistNodeType type;
PurpleBlistNode *node, *gnode, *bnode;
PurpleAccount *account;
PurpleBuddy *bud;
@@ -438,13 +438,12 @@ int tcl_cmd_buddy(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONS
return error;
if ((node = tcl_list_to_buddy(interp, count, elems)) == NULL)
return TCL_ERROR;
- type = purple_blist_node_get_type(node);
- if (type == PURPLE_BLIST_CHAT_NODE)
+ if (PURPLE_IS_CHAT(node))
Tcl_SetObjResult(interp,
- Tcl_NewStringObj(purple_chat_get_name((PurpleChat *)node), -1));
- else if (type == PURPLE_BLIST_BUDDY_NODE)
+ Tcl_NewStringObj(purple_chat_get_name(PURPLE_CHAT(node)), -1));
+ else if (PURPLE_IS_BUDDY(node))
Tcl_SetObjResult(interp,
- Tcl_NewStringObj((char *)purple_buddy_get_alias((PurpleBuddy *)node), -1));
+ Tcl_NewStringObj((char *)purple_buddy_get_alias(PURPLE_BUDDY(node)), -1));
return TCL_OK;
break;
case CMD_BUDDY_HANDLE:
@@ -499,14 +498,12 @@ int tcl_cmd_buddy(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONS
tclgroup = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(interp, tclgroup, Tcl_NewStringObj("group", -1));
Tcl_ListObjAppendElement(interp, tclgroup,
- Tcl_NewStringObj(purple_group_get_name((PurpleGroup *)gnode), -1));
+ Tcl_NewStringObj(purple_group_get_name(PURPLE_GROUP(gnode)), -1));
tclgrouplist = Tcl_NewListObj(0, NULL);
for (node = purple_blist_node_get_first_child(gnode); node != NULL; node = purple_blist_node_get_sibling_next(node)) {
PurpleAccount *account;
- type = purple_blist_node_get_type(node);
- switch (type) {
- case PURPLE_BLIST_CONTACT_NODE:
+ if (PURPLE_IS_CONTACT(node)) {
tclcontact = Tcl_NewListObj(0, NULL);
Tcl_IncrRefCount(tclcontact);
Tcl_ListObjAppendElement(interp, tclcontact, Tcl_NewStringObj("contact", -1));
@@ -514,9 +511,9 @@ int tcl_cmd_buddy(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONS
Tcl_IncrRefCount(tclcontactlist);
count = 0;
for (bnode = purple_blist_node_get_first_child(node); bnode != NULL; bnode = purple_blist_node_get_sibling_next(bnode)) {
- if (purple_blist_node_get_type(bnode) != PURPLE_BLIST_BUDDY_NODE)
+ if (!PURPLE_IS_BUDDY(bnode))
continue;
- bud = (PurpleBuddy *)bnode;
+ bud = PURPLE_BUDDY(bnode);
account = purple_buddy_get_account(bud);
if (!all && !purple_account_is_connected(account))
continue;
@@ -533,9 +530,8 @@ int tcl_cmd_buddy(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONS
}
Tcl_DecrRefCount(tclcontact);
Tcl_DecrRefCount(tclcontactlist);
- break;
- case PURPLE_BLIST_CHAT_NODE:
- cnode = (PurpleChat *)node;
+ } else if (PURPLE_IS_CHAT(node)) {
+ cnode = PURPLE_CHAT(node);
account = purple_chat_get_account(cnode);
if (!all && !purple_account_is_connected(account))
continue;
@@ -544,9 +540,8 @@ int tcl_cmd_buddy(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONS
Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(purple_chat_get_name(cnode), -1));
Tcl_ListObjAppendElement(interp, tclbud, purple_tcl_ref_new(PurpleTclRefAccount, account));
Tcl_ListObjAppendElement(interp, tclgrouplist, tclbud);
- break;
- default:
- purple_debug(PURPLE_DEBUG_WARNING, "tcl", "Unexpected buddy type %d", type);
+ } else {
+ purple_debug(PURPLE_DEBUG_WARNING, "tcl", "Unexpected buddy type %s", G_OBJECT_TYPE_NAME(node));
continue;
}
}
@@ -748,13 +743,13 @@ int tcl_cmd_connection(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj
if ((gc = tcl_validate_gc(objv[2], interp)) == NULL)
return TCL_ERROR;
switch (purple_connection_get_state(gc)) {
- case PURPLE_DISCONNECTED:
+ case PURPLE_CONNECTION_DISCONNECTED:
Tcl_SetObjResult(interp, Tcl_NewStringObj("disconnected", -1));
break;
- case PURPLE_CONNECTED:
+ case PURPLE_CONNECTION_CONNECTED:
Tcl_SetObjResult(interp, Tcl_NewStringObj("connected", -1));
break;
- case PURPLE_CONNECTING:
+ case PURPLE_CONNECTION_CONNECTING:
Tcl_SetObjResult(interp, Tcl_NewStringObj("connecting", -1));
break;
}
@@ -775,7 +770,7 @@ int tcl_cmd_conversation(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Ob
enum { CMD_CONV_NEW_CHAT, CMD_CONV_NEW_IM } newopt;
PurpleConversation *convo;
PurpleAccount *account;
- PurpleConversationType type;
+ gboolean is_chat = FALSE;
GList *cur;
char *opt, *from, *what;
int error, argsused, flags = 0;
@@ -797,8 +792,7 @@ int tcl_cmd_conversation(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Ob
account = NULL;
if ((account = tcl_validate_account(objv[2], interp)) == NULL)
return TCL_ERROR;
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY,
- Tcl_GetString(objv[3]),
+ convo = purple_conversations_find_with_account(Tcl_GetString(objv[3]),
account);
Tcl_SetObjResult(interp, purple_tcl_ref_new(PurpleTclRefConversation, convo));
break;
@@ -813,7 +807,7 @@ int tcl_cmd_conversation(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Ob
break;
case CMD_CONV_LIST:
list = Tcl_NewListObj(0, NULL);
- for (cur = purple_get_conversations(); cur != NULL; cur = g_list_next(cur)) {
+ for (cur = purple_conversations_get_all(); cur != NULL; cur = g_list_next(cur)) {
elem = purple_tcl_ref_new(PurpleTclRefConversation, cur->data);
Tcl_ListObjAppendElement(interp, list, elem);
}
@@ -825,7 +819,7 @@ int tcl_cmd_conversation(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Ob
return TCL_ERROR;
}
argsused = 2;
- type = PURPLE_CONV_TYPE_IM;
+ is_chat = FALSE;
while (argsused < objc) {
opt = Tcl_GetString(objv[argsused]);
if (*opt == '-') {
@@ -835,10 +829,10 @@ int tcl_cmd_conversation(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Ob
argsused++;
switch (newopt) {
case CMD_CONV_NEW_CHAT:
- type = PURPLE_CONV_TYPE_CHAT;
+ is_chat = TRUE;
break;
case CMD_CONV_NEW_IM:
- type = PURPLE_CONV_TYPE_IM;
+ is_chat = FALSE;
break;
}
} else {
@@ -851,7 +845,10 @@ int tcl_cmd_conversation(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Ob
}
if ((account = tcl_validate_account(objv[argsused++], interp)) == NULL)
return TCL_ERROR;
- convo = purple_conversation_new(type, account, Tcl_GetString(objv[argsused]));
+ if (is_chat)
+ convo = PURPLE_CONVERSATION(purple_chat_conversation_new(account, Tcl_GetString(objv[argsused])));
+ else
+ convo = PURPLE_CONVERSATION(purple_im_conversation_new(account, Tcl_GetString(objv[argsused])));
Tcl_SetObjResult(interp, purple_tcl_ref_new(PurpleTclRefConversation, convo));
break;
case CMD_CONV_WRITE:
@@ -877,11 +874,7 @@ int tcl_cmd_conversation(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Ob
flags = PURPLE_MESSAGE_SYSTEM;
break;
}
- if (purple_conversation_get_type(convo) == PURPLE_CONV_TYPE_CHAT)
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), from, what, flags, time(NULL));
- else
- purple_conv_im_write(PURPLE_CONV_IM(convo), from, what, flags, time(NULL));
- break;
+ purple_conversation_write_message(convo, from, what, flags, time(NULL));
case CMD_CONV_NAME:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "conversation");
@@ -912,10 +905,7 @@ int tcl_cmd_conversation(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Ob
if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL)
return TCL_ERROR;
what = Tcl_GetString(objv[3]);
- if (purple_conversation_get_type(convo) == PURPLE_CONV_TYPE_CHAT)
- purple_conv_chat_send(PURPLE_CONV_CHAT(convo), what);
- else
- purple_conv_im_send(PURPLE_CONV_IM(convo), what);
+ purple_conversation_send(convo, what);
break;
}
@@ -1179,12 +1169,11 @@ int tcl_cmd_prefs(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONS
int tcl_cmd_presence(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
const char *cmds[] = { "account", "active_status", "available",
- "chat_user", "context", "conversation", "idle",
- "login", "online", "status", "statuses", NULL };
+ "idle", "type", "login", "online", "status",
+ "statuses", NULL };
enum { CMD_PRESENCE_ACCOUNT, CMD_PRESENCE_ACTIVE_STATUS,
- CMD_PRESENCE_AVAILABLE, CMD_PRESENCE_CHAT_USER,
- CMD_PRESENCE_CONTEXT, CMD_PRESENCE_CONVERSATION,
- CMD_PRESENCE_IDLE, CMD_PRESENCE_LOGIN, CMD_PRESENCE_ONLINE,
+ CMD_PRESENCE_AVAILABLE, CMD_PRESENCE_IDLE, CMD_PRESENCE_TYPE,
+ CMD_PRESENCE_LOGIN, CMD_PRESENCE_ONLINE,
CMD_PRESENCE_STATUS, CMD_PRESENCE_STATUSES } cmd;
Tcl_Obj *result;
Tcl_Obj *list, *elem;
@@ -1209,7 +1198,7 @@ int tcl_cmd_presence(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *C
if ((presence = purple_tcl_ref_get(interp, objv[2], PurpleTclRefPresence)) == NULL)
return TCL_ERROR;
Tcl_SetObjResult(interp, purple_tcl_ref_new(PurpleTclRefAccount,
- purple_presence_get_account(presence)));
+ purple_account_presence_get_account(PURPLE_ACCOUNT_PRESENCE(presence))));
break;
case CMD_PRESENCE_ACTIVE_STATUS:
if (objc != 3 && objc != 4 && objc != 5) {
@@ -1260,47 +1249,17 @@ int tcl_cmd_presence(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *C
Tcl_SetObjResult(interp,
Tcl_NewBooleanObj(purple_presence_is_available(presence)));
break;
- case CMD_PRESENCE_CHAT_USER:
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "presence");
- return TCL_ERROR;
- }
- if ((presence = purple_tcl_ref_get(interp, objv[2], PurpleTclRefPresence)) == NULL)
- return TCL_ERROR;
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj(purple_presence_get_chat_user(presence), -1));
- break;
- case CMD_PRESENCE_CONTEXT:
+ case CMD_PRESENCE_TYPE:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "presence");
return TCL_ERROR;
}
if ((presence = purple_tcl_ref_get(interp, objv[2], PurpleTclRefPresence)) == NULL)
return TCL_ERROR;
- switch (purple_presence_get_context(presence)) {
- case PURPLE_PRESENCE_CONTEXT_UNSET:
- Tcl_SetObjResult(interp, Tcl_NewStringObj("unset", -1));
- break;
- case PURPLE_PRESENCE_CONTEXT_ACCOUNT:
+ if (PURPLE_IS_ACCOUNT_PRESENCE(presence))
Tcl_SetObjResult(interp, Tcl_NewStringObj("account", -1));
- break;
- case PURPLE_PRESENCE_CONTEXT_CONV:
- Tcl_SetObjResult(interp, Tcl_NewStringObj("conversation", -1));
- break;
- case PURPLE_PRESENCE_CONTEXT_BUDDY:
+ else if (PURPLE_IS_BUDDY_PRESENCE(presence))
Tcl_SetObjResult(interp, Tcl_NewStringObj("buddy", -1));
- break;
- }
- break;
- case CMD_PRESENCE_CONVERSATION:
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "presence");
- return TCL_ERROR;
- }
- if ((presence = purple_tcl_ref_get(interp, objv[2], PurpleTclRefPresence)) == NULL)
- return TCL_ERROR;
- Tcl_SetObjResult(interp, purple_tcl_ref_new(PurpleTclRefConversation,
- purple_presence_get_conversation(presence)));
break;
case CMD_PRESENCE_IDLE:
if (objc < 3 || objc > 5) {
@@ -1512,7 +1471,7 @@ int tcl_cmd_signal(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CON
int tcl_cmd_status(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
const char *cmds[] = { "attr", "type", NULL };
- enum { CMD_STATUS_ATTR, CMD_STATUS_TYPE } cmd;
+ enum { CMD_STATUS_ATTRIBUTE, CMD_STATUS_TYPE } cmd;
PurpleStatus *status;
PurpleStatusType *status_type;
int error;
@@ -1532,7 +1491,7 @@ int tcl_cmd_status(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CON
return error;
switch (cmd) {
- case CMD_STATUS_ATTR:
+ case CMD_STATUS_ATTRIBUTE:
# if (0)
/* #if !(defined PURPLE_DISABLE_DEPRECATED) */
if (objc != 4 && objc != 5) {
@@ -1589,7 +1548,7 @@ int tcl_cmd_status(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CON
}
if ((status = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatus)) == NULL)
return TCL_ERROR;
- status_type = purple_status_get_type(status);
+ status_type = purple_status_get_status_type(status);
Tcl_SetObjResult(interp, purple_tcl_ref_new(PurpleTclRefStatusType,
status_type));
break;
@@ -1601,8 +1560,8 @@ int tcl_cmd_status(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CON
int tcl_cmd_status_attr(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
const char *cmds[] = { "id", "name", NULL };
- enum { CMD_STATUS_ATTR_ID, CMD_STATUS_ATTR_NAME } cmd;
- PurpleStatusAttr *attr;
+ enum { CMD_STATUS_ATTRIBUTE_ID, CMD_STATUS_ATTRIBUTE_NAME } cmd;
+ PurpleStatusAttribute *attr;
int error;
if (objc < 2) {
@@ -1614,7 +1573,7 @@ int tcl_cmd_status_attr(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj
return error;
switch (cmd) {
- case CMD_STATUS_ATTR_ID:
+ case CMD_STATUS_ATTRIBUTE_ID:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "attr");
return TCL_ERROR;
@@ -1622,9 +1581,9 @@ int tcl_cmd_status_attr(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj
if ((attr = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusAttr)) == NULL)
return TCL_ERROR;
Tcl_SetObjResult(interp,
- Tcl_NewStringObj(purple_status_attr_get_id(attr), -1));
+ Tcl_NewStringObj(purple_status_attribute_get_id(attr), -1));
break;
- case CMD_STATUS_ATTR_NAME:
+ case CMD_STATUS_ATTRIBUTE_NAME:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "attr");
return TCL_ERROR;
@@ -1632,7 +1591,7 @@ int tcl_cmd_status_attr(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj
if ((attr = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusAttr)) == NULL)
return TCL_ERROR;
Tcl_SetObjResult(interp,
- Tcl_NewStringObj(purple_status_attr_get_name(attr), -1));
+ Tcl_NewStringObj(purple_status_attribute_get_name(attr), -1));
break;
}
diff --git a/libpurple/plugins/tcl/tcl_purple.h b/libpurple/plugins/tcl/tcl_purple.h
index ad3092eaea..6662d11aee 100644
--- a/libpurple/plugins/tcl/tcl_purple.h
+++ b/libpurple/plugins/tcl/tcl_purple.h
@@ -28,7 +28,6 @@
#include "internal.h"
#include "cmds.h"
#include "plugin.h"
-#include "value.h"
#include "stringref.h"
struct tcl_signal_handler {
@@ -41,9 +40,9 @@ struct tcl_signal_handler {
Tcl_Obj *args;
Tcl_Obj *proc;
- PurpleValue *returntype;
+ GType returntype;
int nargs;
- PurpleValue **argtypes;
+ GType *argtypes;
};
struct tcl_cmd_handler {
diff --git a/libpurple/plugins/tcl/tcl_signals.c b/libpurple/plugins/tcl/tcl_signals.c
index fb81ea3d5c..56f658604c 100644
--- a/libpurple/plugins/tcl/tcl_signals.c
+++ b/libpurple/plugins/tcl/tcl_signals.c
@@ -29,7 +29,6 @@
#include "conversation.h"
#include "signals.h"
#include "debug.h"
-#include "value.h"
#include "core.h"
static GList *tcl_callbacks;
@@ -74,7 +73,7 @@ gboolean tcl_signal_connect(struct tcl_signal_handler *handler)
{
GString *proc;
- purple_signal_get_values(handler->instance,
+ purple_signal_get_types(handler->instance,
Tcl_GetString(handler->signal),
&handler->returntype, &handler->nargs,
&handler->argtypes);
@@ -136,24 +135,22 @@ void tcl_signal_disconnect(void *instance, const char *signal, Tcl_Interp *inter
tcl_callbacks = g_list_remove_all(tcl_callbacks, NULL);
}
-static PurpleStringref *ref_type(PurpleSubType type)
+static PurpleStringref *ref_purple_type(GType type)
{
- switch (type) {
- case PURPLE_SUBTYPE_ACCOUNT:
+ if (type == PURPLE_TYPE_ACCOUNT)
return PurpleTclRefAccount;
- case PURPLE_SUBTYPE_CONNECTION:
+ else if (type == PURPLE_TYPE_CONNECTION)
return PurpleTclRefConnection;
- case PURPLE_SUBTYPE_CONVERSATION:
+ else if (type == PURPLE_TYPE_CONVERSATION)
return PurpleTclRefConversation;
- case PURPLE_SUBTYPE_PLUGIN:
+ else if (type == PURPLE_TYPE_PLUGIN)
return PurpleTclRefPlugin;
- case PURPLE_SUBTYPE_STATUS:
+ else if (type == PURPLE_TYPE_STATUS)
return PurpleTclRefStatus;
- case PURPLE_SUBTYPE_XFER:
+ else if (type == PURPLE_TYPE_XFER)
return PurpleTclRefXfer;
- default:
+ else
return NULL;
- }
}
static void *tcl_signal_callback(va_list args, struct tcl_signal_handler *handler)
@@ -179,58 +176,57 @@ static void *tcl_signal_callback(va_list args, struct tcl_signal_handler *handle
Tcl_ListObjAppendElement(handler->interp, cmd, arg);
for (i = 0; i < handler->nargs; i++) {
+#if 0
if (purple_value_is_outgoing(handler->argtypes[i]))
g_string_printf(name, "%s::arg%d",
Tcl_GetString(handler->namespace), i);
-
- switch(purple_value_get_type(handler->argtypes[i])) {
- case PURPLE_TYPE_UNKNOWN: /* What? I guess just pass the word ... */
- /* treat this as a pointer, but complain first */
- purple_debug(PURPLE_DEBUG_ERROR, "tcl", "unknown PurpleValue type %d\n",
- purple_value_get_type(handler->argtypes[i]));
- case PURPLE_TYPE_POINTER:
- case PURPLE_TYPE_OBJECT:
- case PURPLE_TYPE_BOXED:
+#endif
+ switch(handler->argtypes[i]) {
+ case G_TYPE_POINTER:
+#if 0
+ case G_TYPE_OBJECT:
+ case G_TYPE_BOXED:
/* These are all "pointer" types to us */
if (purple_value_is_outgoing(handler->argtypes[i]))
purple_debug_error("tcl", "pointer types do not currently support outgoing arguments\n");
+#endif
arg = purple_tcl_ref_new(PurpleTclRefPointer, va_arg(args, void *));
break;
- case PURPLE_TYPE_BOOLEAN:
+ case G_TYPE_BOOLEAN:
+#if 0
if (purple_value_is_outgoing(handler->argtypes[i])) {
vals[i] = va_arg(args, gboolean *);
Tcl_LinkVar(handler->interp, name->str,
(char *)&vals[i], TCL_LINK_BOOLEAN);
arg = Tcl_NewStringObj(name->str, -1);
- } else {
- arg = Tcl_NewBooleanObj(va_arg(args, gboolean));
- }
+ } else
+#endif
+ arg = Tcl_NewBooleanObj(va_arg(args, gboolean));
break;
- case PURPLE_TYPE_CHAR:
- case PURPLE_TYPE_UCHAR:
- case PURPLE_TYPE_SHORT:
- case PURPLE_TYPE_USHORT:
- case PURPLE_TYPE_INT:
- case PURPLE_TYPE_UINT:
- case PURPLE_TYPE_LONG:
- case PURPLE_TYPE_ULONG:
- case PURPLE_TYPE_ENUM:
+ case G_TYPE_CHAR:
+ case G_TYPE_UCHAR:
+ case G_TYPE_INT:
+ case G_TYPE_UINT:
+ case G_TYPE_LONG:
+ case G_TYPE_ULONG:
/* I should really cast these individually to
* preserve as much information as possible ...
* but heh */
+#if 0
if (purple_value_is_outgoing(handler->argtypes[i])) {
vals[i] = va_arg(args, int *);
Tcl_LinkVar(handler->interp, name->str,
vals[i], TCL_LINK_INT);
arg = Tcl_NewStringObj(name->str, -1);
- } else {
- arg = Tcl_NewIntObj(va_arg(args, int));
- }
+ } else
+#endif
+ arg = Tcl_NewIntObj(va_arg(args, int));
break;
- case PURPLE_TYPE_INT64:
- case PURPLE_TYPE_UINT64:
+ case G_TYPE_INT64:
+ case G_TYPE_UINT64:
/* Tcl < 8.4 doesn't have wide ints, so we have ugly
* ifdefs in here */
+#if 0
if (purple_value_is_outgoing(handler->argtypes[i])) {
vals[i] = (void *)va_arg(args, gint64 *);
#if (TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 4)
@@ -245,14 +241,15 @@ static void *tcl_signal_callback(va_list args, struct tcl_signal_handler *handle
#endif /* Tcl >= 8.4 */
arg = Tcl_NewStringObj(name->str, -1);
} else {
- #if (TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 4)
- arg = Tcl_NewWideIntObj(va_arg(args, gint64));
- #else
- arg = Tcl_NewIntObj((int)va_arg(args, int));
- #endif /* Tcl >= 8.4 */
- }
+#endif
+ #if (TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 4)
+ arg = Tcl_NewWideIntObj(va_arg(args, gint64));
+ #else
+ arg = Tcl_NewIntObj((int)va_arg(args, int));
+ #endif /* Tcl >= 8.4 */
break;
- case PURPLE_TYPE_STRING:
+ case G_TYPE_STRING:
+#if 0
if (purple_value_is_outgoing(handler->argtypes[i])) {
strs[i] = va_arg(args, char **);
if (strs[i] == NULL || *strs[i] == NULL) {
@@ -266,70 +263,77 @@ static void *tcl_signal_callback(va_list args, struct tcl_signal_handler *handle
Tcl_LinkVar(handler->interp, name->str,
(char *)&vals[i], TCL_LINK_STRING);
arg = Tcl_NewStringObj(name->str, -1);
- } else {
- arg = Tcl_NewStringObj(va_arg(args, char *), -1);
- }
+ } else
+#endif
+ arg = Tcl_NewStringObj(va_arg(args, char *), -1);
break;
- case PURPLE_TYPE_SUBTYPE:
- switch (purple_value_get_subtype(handler->argtypes[i])) {
- case PURPLE_SUBTYPE_UNKNOWN:
- purple_debug(PURPLE_DEBUG_ERROR, "tcl", "subtype unknown\n");
- case PURPLE_SUBTYPE_ACCOUNT:
- case PURPLE_SUBTYPE_CONNECTION:
- case PURPLE_SUBTYPE_CONVERSATION:
- case PURPLE_SUBTYPE_STATUS:
- case PURPLE_SUBTYPE_PLUGIN:
- case PURPLE_SUBTYPE_XFER:
+ default:
+ if (handler->argtypes[i] == PURPLE_TYPE_ACCOUNT ||
+ handler->argtypes[i] == PURPLE_TYPE_CONNECTION ||
+ handler->argtypes[i] == PURPLE_TYPE_CONVERSATION ||
+ handler->argtypes[i] == PURPLE_TYPE_STATUS ||
+ handler->argtypes[i] == PURPLE_TYPE_PLUGIN ||
+ handler->argtypes[i] == PURPLE_TYPE_XFER )
+ {
+#if 0
if (purple_value_is_outgoing(handler->argtypes[i]))
purple_debug_error("tcl", "pointer subtypes do not currently support outgoing arguments\n");
- arg = purple_tcl_ref_new(ref_type(purple_value_get_subtype(handler->argtypes[i])), va_arg(args, void *));
- break;
- case PURPLE_SUBTYPE_BLIST:
- case PURPLE_SUBTYPE_BLIST_BUDDY:
- case PURPLE_SUBTYPE_BLIST_GROUP:
- case PURPLE_SUBTYPE_BLIST_CHAT:
+#endif
+ arg = purple_tcl_ref_new(ref_purple_type(handler->argtypes[i]), va_arg(args, void *));
+ }
+ else
+ if (handler->argtypes[i] == PURPLE_TYPE_CONTACT ||
+ handler->argtypes[i] == PURPLE_TYPE_BUDDY ||
+ handler->argtypes[i] == PURPLE_TYPE_GROUP ||
+ handler->argtypes[i] == PURPLE_TYPE_CHAT )
+ {
/* We're going to switch again for code-deduping */
+#if 0
if (purple_value_is_outgoing(handler->argtypes[i]))
node = *va_arg(args, PurpleBlistNode **);
else
- node = va_arg(args, PurpleBlistNode *);
- switch (purple_blist_node_get_type(node)) {
- case PURPLE_BLIST_GROUP_NODE:
+#endif
+ node = va_arg(args, PurpleBlistNode *);
+
+ if (PURPLE_IS_GROUP(node)) {
arg = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(handler->interp, arg,
Tcl_NewStringObj("group", -1));
Tcl_ListObjAppendElement(handler->interp, arg,
- Tcl_NewStringObj(purple_group_get_name((PurpleGroup *)node), -1));
- break;
- case PURPLE_BLIST_CONTACT_NODE:
+ Tcl_NewStringObj(purple_group_get_name(PURPLE_GROUP(node)), -1));
+ } else if (PURPLE_IS_CONTACT(node)) {
/* g_string_printf(val, "contact {%s}", Contact Name? ); */
arg = Tcl_NewStringObj("contact", -1);
- break;
- case PURPLE_BLIST_BUDDY_NODE:
+ } else if (PURPLE_IS_BUDDY(node)) {
arg = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(handler->interp, arg,
Tcl_NewStringObj("buddy", -1));
Tcl_ListObjAppendElement(handler->interp, arg,
- Tcl_NewStringObj(purple_buddy_get_name((PurpleBuddy *)node), -1));
+ Tcl_NewStringObj(purple_buddy_get_name(PURPLE_BUDDY(node)), -1));
Tcl_ListObjAppendElement(handler->interp, arg,
purple_tcl_ref_new(PurpleTclRefAccount,
- purple_buddy_get_account((PurpleBuddy *)node)));
- break;
- case PURPLE_BLIST_CHAT_NODE:
+ purple_buddy_get_account(PURPLE_BUDDY(node))));
+ } else if (PURPLE_IS_CHAT(node)) {
arg = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(handler->interp, arg,
Tcl_NewStringObj("chat", -1));
Tcl_ListObjAppendElement(handler->interp, arg,
- Tcl_NewStringObj(purple_chat_get_name((PurpleChat *)node), -1));
+ Tcl_NewStringObj(purple_chat_get_name(PURPLE_CHAT(node)), -1));
Tcl_ListObjAppendElement(handler->interp, arg,
purple_tcl_ref_new(PurpleTclRefAccount,
- purple_chat_get_account((PurpleChat *)node)));
- break;
- case PURPLE_BLIST_OTHER_NODE:
- arg = Tcl_NewStringObj("other", -1);
- break;
+ purple_chat_get_account(PURPLE_CHAT(node))));
}
- break;
+ }
+ else if (G_TYPE_IS_ENUM(handler->argtypes[i]))
+ {
+ arg = Tcl_NewIntObj(va_arg(args, int));
+ }
+ else
+ {
+ /* What? I guess just pass the word ... */
+ /* treat this as a pointer, but complain first */
+ purple_debug(PURPLE_DEBUG_ERROR, "tcl", "unknown GType %lu\n",
+ handler->argtypes[i]);
}
}
Tcl_ListObjAppendElement(handler->interp, cmd, arg);
@@ -343,7 +347,7 @@ static void *tcl_signal_callback(va_list args, struct tcl_signal_handler *handle
result = Tcl_GetObjResult(handler->interp);
/* handle return values -- strings and words only */
if (handler->returntype) {
- if (purple_value_get_type(handler->returntype) == PURPLE_TYPE_STRING) {
+ if (handler->returntype == G_TYPE_STRING) {
retval = (void *)g_strdup(Tcl_GetString(result));
} else {
if (Tcl_GetIntFromObj(handler->interp, result, (int *)&retval) != TCL_OK) {
@@ -359,14 +363,14 @@ static void *tcl_signal_callback(va_list args, struct tcl_signal_handler *handle
for (i = 0; i < handler->nargs; i++) {
g_string_printf(name, "%s::arg%d",
Tcl_GetString(handler->namespace), i);
+#if 0
if (purple_value_is_outgoing(handler->argtypes[i])
- && purple_value_get_type(handler->argtypes[i]) != PURPLE_TYPE_SUBTYPE)
+ && purple_value_get_type(handler->argtypes[i]) != G_TYPE_SUBTYPE)
Tcl_UnlinkVar(handler->interp, name->str);
-
/* We basically only have to deal with strings on the
* way out */
- switch (purple_value_get_type(handler->argtypes[i])) {
- case PURPLE_TYPE_STRING:
+ switch (handler->argtypes[i]) {
+ case G_TYPE_STRING:
if (purple_value_is_outgoing(handler->argtypes[i])) {
if (vals[i] != NULL && *(char **)vals[i] != NULL) {
g_free(*strs[i]);
@@ -379,6 +383,7 @@ static void *tcl_signal_callback(va_list args, struct tcl_signal_handler *handle
/* nothing */
;
}
+#endif
}
g_string_free(name, TRUE);
diff --git a/libpurple/pounce.c b/libpurple/pounce.c
index 641ebb525f..ca9940c226 100644
--- a/libpurple/pounce.c
+++ b/libpurple/pounce.c
@@ -1126,18 +1126,18 @@ buddy_idle_changed_cb(PurpleBuddy *buddy, gboolean old_idle, gboolean idle)
static void
buddy_typing_cb(PurpleAccount *account, const char *name, void *data)
{
- PurpleConversation *conv;
+ PurpleIMConversation *im;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, name, account);
- if (conv != NULL)
+ im = purple_conversations_find_im_with_account(name, account);
+ if (im != NULL)
{
- PurpleTypingState state;
+ PurpleIMTypingState state;
PurplePounceEvent event;
- state = purple_conv_im_get_typing_state(PURPLE_CONV_IM(conv));
- if (state == PURPLE_TYPED)
+ state = purple_im_conversation_get_typing_state(im);
+ if (state == PURPLE_IM_TYPED)
event = PURPLE_POUNCE_TYPED;
- else if (state == PURPLE_NOT_TYPING)
+ else if (state == PURPLE_IM_NOT_TYPING)
event = PURPLE_POUNCE_TYPING_STOPPED;
else
event = PURPLE_POUNCE_TYPING;
diff --git a/libpurple/presence.c b/libpurple/presence.c
new file mode 100644
index 0000000000..4c36647ce7
--- /dev/null
+++ b/libpurple/presence.c
@@ -0,0 +1,996 @@
+/* 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
+ */
+#include "internal.h"
+#include "debug.h"
+#include "dbus-maybe.h"
+#include "presence.h"
+
+#define PURPLE_PRESENCE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_PRESENCE, PurplePresencePrivate))
+
+/** @copydoc _PurplePresencePrivate */
+typedef struct _PurplePresencePrivate PurplePresencePrivate;
+
+#define PURPLE_ACCOUNT_PRESENCE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_ACCOUNT_PRESENCE, PurpleAccountPresencePrivate))
+
+/** @copydoc _PurpleAccountPresencePrivate */
+typedef struct _PurpleAccountPresencePrivate PurpleAccountPresencePrivate;
+
+#define PURPLE_BUDDY_PRESENCE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_BUDDY_PRESENCE, PurpleBuddyPresencePrivate))
+
+/** @copydoc _PurpleBuddyPresencePrivate */
+typedef struct _PurpleBuddyPresencePrivate PurpleBuddyPresencePrivate;
+
+/** Private data for a presence */
+struct _PurplePresencePrivate
+{
+ gboolean idle;
+ time_t idle_time;
+ time_t login_time;
+
+ GList *statuses;
+ GHashTable *status_table;
+
+ PurpleStatus *active_status;
+};
+
+/* Presence property enums */
+enum
+{
+ PRES_PROP_0,
+ PRES_PROP_IDLE,
+ PRES_PROP_IDLE_TIME,
+ PRES_PROP_LOGIN_TIME,
+ PRES_PROP_STATUSES,
+ PRES_PROP_ACTIVE_STATUS,
+ PRES_PROP_LAST
+};
+
+/** Private data for an account presence */
+struct _PurpleAccountPresencePrivate
+{
+ PurpleAccount *account;
+};
+
+/* Account presence property enums */
+enum
+{
+ ACPRES_PROP_0,
+ ACPRES_PROP_ACCOUNT,
+ ACPRES_PROP_LAST
+};
+
+/** Private data for a buddy presence */
+struct _PurpleBuddyPresencePrivate
+{
+ PurpleBuddy *buddy;
+};
+
+/* Buddy presence property enums */
+enum
+{
+ BUDPRES_PROP_0,
+ BUDPRES_PROP_BUDDY,
+ BUDPRES_PROP_LAST
+};
+
+static GObjectClass *parent_class;
+static PurplePresenceClass *presence_class;
+
+int *_purple_get_primitive_scores(void);
+
+/**************************************************************************
+* PurplePresence API
+**************************************************************************/
+
+void
+purple_presence_set_status_active(PurplePresence *presence, const char *status_id,
+ gboolean active)
+{
+ PurpleStatus *status;
+
+ g_return_if_fail(presence != NULL);
+ g_return_if_fail(status_id != NULL);
+
+ status = purple_presence_get_status(presence, status_id);
+
+ g_return_if_fail(status != NULL);
+ /* TODO: Should we do the following? */
+ /* g_return_if_fail(active == status->active); */
+
+ if (purple_status_is_exclusive(status))
+ {
+ if (!active)
+ {
+ purple_debug_warning("status",
+ "Attempted to set a non-independent status "
+ "(%s) inactive. Only independent statuses "
+ "can be specifically marked inactive.",
+ status_id);
+ return;
+ }
+ }
+
+ purple_status_set_active(status, active);
+}
+
+void
+purple_presence_switch_status(PurplePresence *presence, const char *status_id)
+{
+ purple_presence_set_status_active(presence, status_id, TRUE);
+}
+
+void
+purple_presence_set_idle(PurplePresence *presence, gboolean idle, time_t idle_time)
+{
+ gboolean old_idle;
+ PurplePresencePrivate *priv = PURPLE_PRESENCE_GET_PRIVATE(presence);
+ PurplePresenceClass *klass = PURPLE_PRESENCE_GET_CLASS(presence);
+
+ g_return_if_fail(priv != NULL);
+
+ if (priv->idle == idle && priv->idle_time == idle_time)
+ return;
+
+ old_idle = priv->idle;
+ priv->idle = idle;
+ priv->idle_time = (idle ? idle_time : 0);
+
+ if (klass->update_idle)
+ klass->update_idle(presence, old_idle);
+}
+
+void
+purple_presence_set_login_time(PurplePresence *presence, time_t login_time)
+{
+ PurplePresencePrivate *priv = PURPLE_PRESENCE_GET_PRIVATE(presence);
+
+ g_return_if_fail(priv != NULL);
+
+ if (priv->login_time == login_time)
+ return;
+
+ priv->login_time = login_time;
+}
+
+GList *
+purple_presence_get_statuses(const PurplePresence *presence)
+{
+ PurplePresencePrivate *priv = PURPLE_PRESENCE_GET_PRIVATE(presence);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->statuses;
+}
+
+PurpleStatus *
+purple_presence_get_status(const PurplePresence *presence, const char *status_id)
+{
+ PurpleStatus *status;
+ PurplePresencePrivate *priv = PURPLE_PRESENCE_GET_PRIVATE(presence);
+ GList *l = NULL;
+
+ g_return_val_if_fail(priv != NULL, NULL);
+ g_return_val_if_fail(status_id != NULL, NULL);
+
+ /* What's the purpose of this hash table? */
+ status = (PurpleStatus *)g_hash_table_lookup(priv->status_table,
+ status_id);
+
+ if (status == NULL) {
+ for (l = purple_presence_get_statuses(presence);
+ l != NULL && status == NULL; l = l->next)
+ {
+ PurpleStatus *temp_status = l->data;
+
+ if (purple_strequal(status_id, purple_status_get_id(temp_status)))
+ status = temp_status;
+ }
+
+ if (status != NULL)
+ g_hash_table_insert(priv->status_table,
+ g_strdup(purple_status_get_id(status)), status);
+ }
+
+ return status;
+}
+
+PurpleStatus *
+purple_presence_get_active_status(const PurplePresence *presence)
+{
+ PurplePresencePrivate *priv = PURPLE_PRESENCE_GET_PRIVATE(presence);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->active_status;
+}
+
+gboolean
+purple_presence_is_available(const PurplePresence *presence)
+{
+ PurpleStatus *status;
+
+ g_return_val_if_fail(presence != NULL, FALSE);
+
+ status = purple_presence_get_active_status(presence);
+
+ return ((status != NULL && purple_status_is_available(status)) &&
+ !purple_presence_is_idle(presence));
+}
+
+gboolean
+purple_presence_is_online(const PurplePresence *presence)
+{
+ PurpleStatus *status;
+
+ g_return_val_if_fail(presence != NULL, FALSE);
+
+ if ((status = purple_presence_get_active_status(presence)) == NULL)
+ return FALSE;
+
+ return purple_status_is_online(status);
+}
+
+gboolean
+purple_presence_is_status_active(const PurplePresence *presence,
+ const char *status_id)
+{
+ PurpleStatus *status;
+
+ g_return_val_if_fail(presence != NULL, FALSE);
+ g_return_val_if_fail(status_id != NULL, FALSE);
+
+ status = purple_presence_get_status(presence, status_id);
+
+ return (status != NULL && purple_status_is_active(status));
+}
+
+gboolean
+purple_presence_is_status_primitive_active(const PurplePresence *presence,
+ PurpleStatusPrimitive primitive)
+{
+ GList *l;
+
+ g_return_val_if_fail(presence != NULL, FALSE);
+ g_return_val_if_fail(primitive != PURPLE_STATUS_UNSET, FALSE);
+
+ for (l = purple_presence_get_statuses(presence);
+ l != NULL; l = l->next)
+ {
+ PurpleStatus *temp_status = l->data;
+ PurpleStatusType *type = purple_status_get_status_type(temp_status);
+
+ if (purple_status_type_get_primitive(type) == primitive &&
+ purple_status_is_active(temp_status))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean
+purple_presence_is_idle(const PurplePresence *presence)
+{
+ PurplePresencePrivate *priv = PURPLE_PRESENCE_GET_PRIVATE(presence);
+
+ g_return_val_if_fail(priv != NULL, FALSE);
+
+ return purple_presence_is_online(presence) && priv->idle;
+}
+
+time_t
+purple_presence_get_idle_time(const PurplePresence *presence)
+{
+ PurplePresencePrivate *priv = PURPLE_PRESENCE_GET_PRIVATE(presence);
+
+ g_return_val_if_fail(priv != NULL, 0);
+
+ return priv->idle_time;
+}
+
+time_t
+purple_presence_get_login_time(const PurplePresence *presence)
+{
+ PurplePresencePrivate *priv = PURPLE_PRESENCE_GET_PRIVATE(presence);
+
+ g_return_val_if_fail(priv != NULL, 0);
+
+ return purple_presence_is_online(presence) ? priv->login_time : 0;
+}
+
+/**************************************************************************
+ * GObject code for PurplePresence
+ **************************************************************************/
+
+/* GObject Property names */
+#define PRES_PROP_IDLE_S "idle"
+#define PRES_PROP_IDLE_TIME_S "idle-time"
+#define PRES_PROP_LOGIN_TIME_S "login-time"
+#define PRES_PROP_STATUSES_S "statuses"
+#define PRES_PROP_ACTIVE_STATUS_S "active-status"
+
+/* Set method for GObject properties */
+static void
+purple_presence_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurplePresence *presence = PURPLE_PRESENCE(obj);
+ PurplePresencePrivate *priv = PURPLE_PRESENCE_GET_PRIVATE(presence);
+
+ switch (param_id) {
+ case PRES_PROP_IDLE:
+ purple_presence_set_idle(presence, g_value_get_boolean(value), 0);
+ break;
+ case PRES_PROP_IDLE_TIME:
+#if SIZEOF_TIME_T == 4
+ purple_presence_set_idle(presence, TRUE, g_value_get_int(value));
+#elif SIZEOF_TIME_T == 8
+ purple_presence_set_idle(presence, TRUE, g_value_get_int64(value));
+#else
+#error Unknown size of time_t
+#endif
+ break;
+ case PRES_PROP_LOGIN_TIME:
+#if SIZEOF_TIME_T == 4
+ purple_presence_set_login_time(presence, g_value_get_int(value));
+#elif SIZEOF_TIME_T == 8
+ purple_presence_set_login_time(presence, g_value_get_int64(value));
+#else
+#error Unknown size of time_t
+#endif
+ break;
+ case PRES_PROP_ACTIVE_STATUS:
+ priv->active_status = g_value_get_object(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Get method for GObject properties */
+static void
+purple_presence_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurplePresence *presence = PURPLE_PRESENCE(obj);
+
+ switch (param_id) {
+ case PRES_PROP_IDLE:
+ g_value_set_boolean(value, purple_presence_is_idle(presence));
+ break;
+ case PRES_PROP_IDLE_TIME:
+#if SIZEOF_TIME_T == 4
+ g_value_set_int(value, purple_presence_get_idle_time(presence));
+#elif SIZEOF_TIME_T == 8
+ g_value_set_int64(value, purple_presence_get_idle_time(presence));
+#else
+#error Unknown size of time_t
+#endif
+ break;
+ case PRES_PROP_LOGIN_TIME:
+#if SIZEOF_TIME_T == 4
+ g_value_set_int(value, purple_presence_get_login_time(presence));
+#elif SIZEOF_TIME_T == 8
+ g_value_set_int64(value, purple_presence_get_login_time(presence));
+#else
+#error Unknown size of time_t
+#endif
+ break;
+ case PRES_PROP_STATUSES:
+ g_value_set_pointer(value, purple_presence_get_statuses(presence));
+ break;
+ case PRES_PROP_ACTIVE_STATUS:
+ g_value_set_object(value, purple_presence_get_active_status(presence));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* GObject initialization function */
+static void
+purple_presence_init(GTypeInstance *instance, gpointer klass)
+{
+ PURPLE_DBUS_REGISTER_POINTER(PURPLE_PRESENCE(instance), PurplePresence);
+
+ PURPLE_PRESENCE_GET_PRIVATE(instance)->status_table =
+ g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
+}
+
+/* GObject dispose function */
+static void
+purple_presence_dispose(GObject *object)
+{
+ PURPLE_DBUS_UNREGISTER_POINTER(object);
+
+ g_list_foreach(PURPLE_PRESENCE_GET_PRIVATE(object)->statuses,
+ (GFunc)g_object_unref, NULL);
+
+ parent_class->dispose(object);
+}
+
+/* GObject finalize function */
+static void
+purple_presence_finalize(GObject *object)
+{
+ PurplePresencePrivate *priv = PURPLE_PRESENCE_GET_PRIVATE(object);
+
+ g_list_free(priv->statuses);
+ g_hash_table_destroy(priv->status_table);
+
+ parent_class->finalize(object);
+}
+
+/* Class initializer function */
+static void purple_presence_class_init(PurplePresenceClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->dispose = purple_presence_dispose;
+ obj_class->finalize = purple_presence_finalize;
+
+ /* Setup properties */
+ obj_class->get_property = purple_presence_get_property;
+ obj_class->set_property = purple_presence_set_property;
+
+ g_object_class_install_property(obj_class, PRES_PROP_IDLE,
+ g_param_spec_boolean(PRES_PROP_IDLE_S, _("Idle"),
+ _("Whether the presence is in idle state."), FALSE,
+ G_PARAM_READWRITE)
+ );
+
+
+ g_object_class_install_property(obj_class, PRES_PROP_IDLE_TIME,
+#if SIZEOF_TIME_T == 4
+ g_param_spec_int
+#elif SIZEOF_TIME_T == 8
+ g_param_spec_int64
+#else
+#error Unknown size of time_t
+#endif
+ (PRES_PROP_IDLE_TIME_S, _("Idle time"),
+ _("The idle time of the presence"),
+#if SIZEOF_TIME_T == 4
+ G_MININT, G_MAXINT, 0,
+#elif SIZEOF_TIME_T == 8
+ G_MININT64, G_MAXINT64, 0,
+#else
+#error Unknown size of time_t
+#endif
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, PRES_PROP_LOGIN_TIME,
+#if SIZEOF_TIME_T == 4
+ g_param_spec_int
+#elif SIZEOF_TIME_T == 8
+ g_param_spec_int64
+#else
+#error Unknown size of time_t
+#endif
+ (PRES_PROP_LOGIN_TIME_S, _("Login time"),
+ _("The login time of the presence."),
+#if SIZEOF_TIME_T == 4
+ G_MININT, G_MAXINT, 0,
+#elif SIZEOF_TIME_T == 8
+ G_MININT64, G_MAXINT64, 0,
+#else
+#error Unknown size of time_t
+#endif
+ G_PARAM_READWRITE)
+ );
+
+ g_object_class_install_property(obj_class, PRES_PROP_STATUSES,
+ g_param_spec_pointer(PRES_PROP_STATUSES_S, _("Statuses"),
+ _("The list of statuses in the presence."),
+ G_PARAM_READABLE)
+ );
+
+ g_object_class_install_property(obj_class, PRES_PROP_ACTIVE_STATUS,
+ g_param_spec_object(PRES_PROP_ACTIVE_STATUS_S, _("Active status"),
+ _("The active status for the presence."), PURPLE_TYPE_STATUS,
+ G_PARAM_READWRITE)
+ );
+
+ g_type_class_add_private(klass, sizeof(PurplePresencePrivate));
+}
+
+GType
+purple_presence_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurplePresenceClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_presence_class_init,
+ NULL,
+ NULL,
+ sizeof(PurplePresence),
+ 0,
+ (GInstanceInitFunc)purple_presence_init,
+ NULL,
+ };
+
+ type = g_type_register_static(G_TYPE_OBJECT, "PurplePresence",
+ &info, G_TYPE_FLAG_ABSTRACT);
+ }
+
+ return type;
+}
+
+/**************************************************************************
+* PurpleAccountPresence API
+**************************************************************************/
+static void
+purple_account_presence_update_idle(PurplePresence *presence, gboolean old_idle)
+{
+ PurpleAccount *account;
+ PurpleConnection *gc = NULL;
+ PurplePlugin *prpl = NULL;
+ PurplePluginProtocolInfo *prpl_info = NULL;
+ gboolean idle = purple_presence_is_idle(presence);
+ time_t idle_time = purple_presence_get_idle_time(presence);
+ time_t current_time = time(NULL);
+
+ account = purple_account_presence_get_account(PURPLE_ACCOUNT_PRESENCE(presence));
+
+ if (purple_prefs_get_bool("/purple/logging/log_system"))
+ {
+ PurpleLog *log = purple_account_get_log(account, FALSE);
+
+ if (log != NULL)
+ {
+ char *msg, *tmp;
+
+ if (idle)
+ tmp = g_strdup_printf(_("+++ %s became idle"), purple_account_get_username(account));
+ else
+ tmp = g_strdup_printf(_("+++ %s became unidle"), purple_account_get_username(account));
+
+ msg = g_markup_escape_text(tmp, -1);
+ g_free(tmp);
+ purple_log_write(log, PURPLE_MESSAGE_SYSTEM,
+ purple_account_get_username(account),
+ (idle ? idle_time : current_time), msg);
+ g_free(msg);
+ }
+ }
+
+ gc = purple_account_get_connection(account);
+
+ if(gc)
+ prpl = purple_connection_get_prpl(gc);
+
+ if(PURPLE_CONNECTION_IS_CONNECTED(gc) && prpl != NULL)
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
+
+ if (prpl_info && prpl_info->set_idle)
+ prpl_info->set_idle(gc, (idle ? (current_time - idle_time) : 0));
+}
+
+PurpleAccount *
+purple_account_presence_get_account(const PurpleAccountPresence *presence)
+{
+ PurpleAccountPresencePrivate *priv = PURPLE_ACCOUNT_PRESENCE_GET_PRIVATE(presence);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->account;
+}
+
+static int
+purple_buddy_presence_compute_score(const PurpleBuddyPresence *buddy_presence)
+{
+ GList *l;
+ int score = 0;
+ PurplePresence *presence = PURPLE_PRESENCE(buddy_presence);
+ PurpleBuddy *b = purple_buddy_presence_get_buddy(buddy_presence);
+ int *primitive_scores = _purple_get_primitive_scores();
+ int offline_score = purple_prefs_get_int("/purple/status/scores/offline_msg");
+ int idle_score = purple_prefs_get_int("/purple/status/scores/idle");
+
+ for (l = purple_presence_get_statuses(presence); l != NULL; l = l->next) {
+ PurpleStatus *status = (PurpleStatus *)l->data;
+ PurpleStatusType *type = purple_status_get_status_type(status);
+
+ if (purple_status_is_active(status)) {
+ score += primitive_scores[purple_status_type_get_primitive(type)];
+ if (!purple_status_is_online(status)) {
+ if (b && purple_account_supports_offline_message(purple_buddy_get_account(b), b))
+ score += offline_score;
+ }
+ }
+ }
+ score += purple_account_get_int(purple_buddy_get_account(b), "score", 0);
+ if (purple_presence_is_idle(presence))
+ score += idle_score;
+ return score;
+}
+
+gint
+purple_buddy_presence_compare(const PurpleBuddyPresence *buddy_presence1,
+ const PurpleBuddyPresence *buddy_presence2)
+{
+ PurplePresence *presence1 = PURPLE_PRESENCE(buddy_presence1);
+ PurplePresence *presence2 = PURPLE_PRESENCE(buddy_presence2);
+ time_t idle_time_1, idle_time_2;
+ int score1 = 0, score2 = 0;
+ int idle_time_score = purple_prefs_get_int("/purple/status/scores/idle_time");
+
+ if (presence1 == presence2)
+ return 0;
+ else if (presence1 == NULL)
+ return 1;
+ else if (presence2 == NULL)
+ return -1;
+
+ if (purple_presence_is_online(presence1) &&
+ !purple_presence_is_online(presence2))
+ return -1;
+ else if (purple_presence_is_online(presence2) &&
+ !purple_presence_is_online(presence1))
+ return 1;
+
+ /* Compute the score of the first set of statuses. */
+ score1 = purple_buddy_presence_compute_score(buddy_presence1);
+
+ /* Compute the score of the second set of statuses. */
+ score2 = purple_buddy_presence_compute_score(buddy_presence2);
+
+ idle_time_1 = time(NULL) - purple_presence_get_idle_time(presence1);
+ idle_time_2 = time(NULL) - purple_presence_get_idle_time(presence2);
+
+ if (idle_time_1 > idle_time_2)
+ score1 += idle_time_score;
+ else if (idle_time_1 < idle_time_2)
+ score2 += idle_time_score;
+
+ if (score1 < score2)
+ return 1;
+ else if (score1 > score2)
+ return -1;
+
+ return 0;
+}
+
+/**************************************************************************
+ * GObject code for PurpleAccountPresence
+ **************************************************************************/
+
+/* GObject Property names */
+#define ACPRES_PROP_ACCOUNT_S "account"
+
+/* Set method for GObject properties */
+static void
+purple_account_presence_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleAccountPresence *account_presence = PURPLE_ACCOUNT_PRESENCE(obj);
+ PurpleAccountPresencePrivate *priv =
+ PURPLE_ACCOUNT_PRESENCE_GET_PRIVATE(account_presence);
+
+ switch (param_id) {
+ case ACPRES_PROP_ACCOUNT:
+ priv->account = g_value_get_object(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Get method for GObject properties */
+static void
+purple_account_presence_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleAccountPresence *account_presence = PURPLE_ACCOUNT_PRESENCE(obj);
+
+ switch (param_id) {
+ case ACPRES_PROP_ACCOUNT:
+ g_value_set_object(value,
+ purple_account_presence_get_account(account_presence));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Called when done constructing */
+static void
+purple_account_presence_constructed(GObject *object)
+{
+ PurplePresence *presence = PURPLE_PRESENCE(object);
+ PurpleAccountPresencePrivate *priv = PURPLE_ACCOUNT_PRESENCE_GET_PRIVATE(presence);
+
+ G_OBJECT_CLASS(presence_class)->constructed(object);
+
+ PURPLE_PRESENCE_GET_PRIVATE(presence)->statuses =
+ purple_prpl_get_statuses(priv->account, presence);
+}
+
+/* Class initializer function */
+static void purple_account_presence_class_init(PurpleAccountPresenceClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ PURPLE_PRESENCE_CLASS(klass)->update_idle = purple_account_presence_update_idle;
+
+ presence_class = g_type_class_peek_parent(klass);
+
+ obj_class->constructed = purple_account_presence_constructed;
+
+ /* Setup properties */
+ obj_class->get_property = purple_account_presence_get_property;
+ obj_class->set_property = purple_account_presence_set_property;
+
+ g_object_class_install_property(obj_class, ACPRES_PROP_ACCOUNT,
+ g_param_spec_object(ACPRES_PROP_ACCOUNT_S, _("Account"),
+ _("The account that this presence is of."), PURPLE_TYPE_ACCOUNT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)
+ );
+
+ g_type_class_add_private(klass, sizeof(PurpleAccountPresencePrivate));
+}
+
+GType
+purple_account_presence_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleAccountPresenceClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_account_presence_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleAccountPresence),
+ 0,
+ NULL,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_PRESENCE,
+ "PurpleAccountPresence",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleAccountPresence *
+purple_account_presence_new(PurpleAccount *account)
+{
+ g_return_val_if_fail(account != NULL, NULL);
+
+ return g_object_new(PURPLE_TYPE_ACCOUNT_PRESENCE,
+ ACPRES_PROP_ACCOUNT_S, account,
+ NULL);
+}
+
+/**************************************************************************
+* PurpleBuddyPresence API
+**************************************************************************/
+static void
+purple_buddy_presence_update_idle(PurplePresence *presence, gboolean old_idle)
+{
+ PurpleBuddy *buddy = purple_buddy_presence_get_buddy(PURPLE_BUDDY_PRESENCE(presence));
+ time_t current_time = time(NULL);
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ PurpleAccount *account = purple_buddy_get_account(buddy);
+ gboolean idle = purple_presence_is_idle(presence);
+
+ if (!old_idle && idle)
+ {
+ if (purple_prefs_get_bool("/purple/logging/log_system"))
+ {
+ PurpleLog *log = purple_account_get_log(account, FALSE);
+
+ if (log != NULL)
+ {
+ char *tmp, *tmp2;
+ tmp = g_strdup_printf(_("%s became idle"),
+ purple_buddy_get_alias(buddy));
+ tmp2 = g_markup_escape_text(tmp, -1);
+ g_free(tmp);
+
+ purple_log_write(log, PURPLE_MESSAGE_SYSTEM,
+ purple_buddy_get_alias(buddy), current_time, tmp2);
+ g_free(tmp2);
+ }
+ }
+ }
+ else if (old_idle && !idle)
+ {
+ if (purple_prefs_get_bool("/purple/logging/log_system"))
+ {
+ PurpleLog *log = purple_account_get_log(account, FALSE);
+
+ if (log != NULL)
+ {
+ char *tmp, *tmp2;
+ tmp = g_strdup_printf(_("%s became unidle"),
+ purple_buddy_get_alias(buddy));
+ tmp2 = g_markup_escape_text(tmp, -1);
+ g_free(tmp);
+
+ purple_log_write(log, PURPLE_MESSAGE_SYSTEM,
+ purple_buddy_get_alias(buddy), current_time, tmp2);
+ g_free(tmp2);
+ }
+ }
+ }
+
+ if (old_idle != idle)
+ purple_signal_emit(purple_blist_get_handle(), "buddy-idle-changed", buddy,
+ old_idle, idle);
+
+ purple_contact_invalidate_priority_buddy(purple_buddy_get_contact(buddy));
+
+ /* Should this be done here? It'd perhaps make more sense to
+ * connect to buddy-[un]idle signals and update from there
+ */
+
+ if (ops != NULL && ops->update != NULL)
+ ops->update(purple_blist_get_buddy_list(), (PurpleBlistNode *)buddy);
+}
+
+PurpleBuddy *
+purple_buddy_presence_get_buddy(const PurpleBuddyPresence *presence)
+{
+ PurpleBuddyPresencePrivate *priv = PURPLE_BUDDY_PRESENCE_GET_PRIVATE(presence);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+
+ return priv->buddy;
+}
+
+/**************************************************************************
+ * GObject code for PurpleBuddyPresence
+ **************************************************************************/
+
+/* GObject Property names */
+#define BUDPRES_PROP_BUDDY_S "buddy"
+
+/* Set method for GObject properties */
+static void
+purple_buddy_presence_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleBuddyPresence *buddy_presence = PURPLE_BUDDY_PRESENCE(obj);
+ PurpleBuddyPresencePrivate *priv =
+ PURPLE_BUDDY_PRESENCE_GET_PRIVATE(buddy_presence);
+
+ switch (param_id) {
+ case BUDPRES_PROP_BUDDY:
+ priv->buddy = g_value_get_object(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Get method for GObject properties */
+static void
+purple_buddy_presence_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleBuddyPresence *buddy_presence = PURPLE_BUDDY_PRESENCE(obj);
+
+ switch (param_id) {
+ case BUDPRES_PROP_BUDDY:
+ g_value_set_object(value,
+ purple_buddy_presence_get_buddy(buddy_presence));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+/* Called when done constructing */
+static void
+purple_buddy_presence_constructed(GObject *object)
+{
+ PurplePresence *presence = PURPLE_PRESENCE(object);
+ PurpleBuddyPresencePrivate *priv = PURPLE_BUDDY_PRESENCE_GET_PRIVATE(presence);
+ PurpleAccount *account;
+
+ G_OBJECT_CLASS(presence_class)->constructed(object);
+
+ account = purple_buddy_get_account(priv->buddy);
+ PURPLE_PRESENCE_GET_PRIVATE(presence)->statuses =
+ purple_prpl_get_statuses(account, presence);
+}
+
+/* Class initializer function */
+static void purple_buddy_presence_class_init(PurpleBuddyPresenceClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ PURPLE_PRESENCE_CLASS(klass)->update_idle = purple_buddy_presence_update_idle;
+
+ presence_class = g_type_class_peek_parent(klass);
+
+ obj_class->constructed = purple_buddy_presence_constructed;
+
+ /* Setup properties */
+ obj_class->get_property = purple_buddy_presence_get_property;
+ obj_class->set_property = purple_buddy_presence_set_property;
+
+ g_object_class_install_property(obj_class, BUDPRES_PROP_BUDDY,
+ g_param_spec_object(BUDPRES_PROP_BUDDY_S, _("Buddy"),
+ _("The buddy that this presence is of."), PURPLE_TYPE_BUDDY,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)
+ );
+
+ g_type_class_add_private(klass, sizeof(PurpleBuddyPresencePrivate));
+}
+
+GType
+purple_buddy_presence_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleBuddyPresenceClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_buddy_presence_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleBuddyPresence),
+ 0,
+ NULL,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_PRESENCE,
+ "PurpleBuddyPresence",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleBuddyPresence *
+purple_buddy_presence_new(PurpleBuddy *buddy)
+{
+ g_return_val_if_fail(buddy != NULL, NULL);
+
+ return g_object_new(PURPLE_TYPE_BUDDY_PRESENCE,
+ BUDPRES_PROP_BUDDY_S, buddy,
+ NULL);
+}
diff --git a/libpurple/presence.h b/libpurple/presence.h
new file mode 100644
index 0000000000..465a76f802
--- /dev/null
+++ b/libpurple/presence.h
@@ -0,0 +1,387 @@
+/**
+ * @file presence.h Presence, account presence and buddy presence API
+ * @ingroup core
+ */
+/*
+ * 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 _PURPLE_PRESENCE_H_
+#define _PURPLE_PRESENCE_H_
+
+#define PURPLE_TYPE_PRESENCE (purple_presence_get_type())
+#define PURPLE_PRESENCE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_PRESENCE, PurplePresence))
+#define PURPLE_PRESENCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_PRESENCE, PurplePresenceClass))
+#define PURPLE_IS_PRESENCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_PRESENCE))
+#define PURPLE_IS_PRESENCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_PRESENCE))
+#define PURPLE_PRESENCE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_PRESENCE, PurplePresenceClass))
+
+/** @copydoc _PurplePresence */
+typedef struct _PurplePresence PurplePresence;
+/** @copydoc _PurplePresenceClass */
+typedef struct _PurplePresenceClass PurplePresenceClass;
+
+#define PURPLE_TYPE_ACCOUNT_PRESENCE (purple_account_presence_get_type())
+#define PURPLE_ACCOUNT_PRESENCE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_ACCOUNT_PRESENCE, PurpleAccountPresence))
+#define PURPLE_ACCOUNT_PRESENCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_ACCOUNT_PRESENCE, PurpleAccountPresenceClass))
+#define PURPLE_IS_ACCOUNT_PRESENCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_ACCOUNT_PRESENCE))
+#define PURPLE_IS_ACCOUNT_PRESENCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_ACCOUNT_PRESENCE))
+#define PURPLE_ACCOUNT_PRESENCE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_ACCOUNT_PRESENCE, PurpleAccountPresenceClass))
+
+/** @copydoc _PurpleAccountPresence */
+typedef struct _PurpleAccountPresence PurpleAccountPresence;
+/** @copydoc _PurpleAccountPresenceClass */
+typedef struct _PurpleAccountPresenceClass PurpleAccountPresenceClass;
+
+#define PURPLE_TYPE_BUDDY_PRESENCE (purple_buddy_presence_get_type())
+#define PURPLE_BUDDY_PRESENCE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_BUDDY_PRESENCE, PurpleBuddyPresence))
+#define PURPLE_BUDDY_PRESENCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_BUDDY_PRESENCE, PurpleBuddyPresenceClass))
+#define PURPLE_IS_BUDDY_PRESENCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_BUDDY_PRESENCE))
+#define PURPLE_IS_BUDDY_PRESENCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_BUDDY_PRESENCE))
+#define PURPLE_BUDDY_PRESENCE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_BUDDY_PRESENCE, PurpleBuddyPresenceClass))
+
+/** @copydoc _PurpleBuddyPresence */
+typedef struct _PurpleBuddyPresence PurpleBuddyPresence;
+/** @copydoc _PurpleBuddyPresenceClass */
+typedef struct _PurpleBuddyPresenceClass PurpleBuddyPresenceClass;
+
+#include "account.h"
+#include "buddylist.h"
+#include "status.h"
+
+/**
+ * A PurplePresence is like a collection of PurpleStatuses (plus some
+ * other random info). For any buddy, or for any one of your accounts,
+ * or for any person with which you're chatting, you may know various
+ * amounts of information. This information is all contained in
+ * one PurplePresence. If one of your buddies is away and idle,
+ * then the presence contains the PurpleStatus for their awayness,
+ * and it contains their current idle time. PurplePresences are
+ * never saved to disk. The information they contain is only relevant
+ * for the current PurpleSession.
+ *
+ * @note When a presence is destroyed with the last g_object_unref(), all
+ * statuses added to this list will be destroyed along with the presence.
+ */
+struct _PurplePresence
+{
+ /*< private >*/
+ GObject gparent;
+};
+
+/** Base class for all #PurplePresence's */
+struct _PurplePresenceClass {
+ /*< private >*/
+ GObjectClass parent_class;
+
+ /**
+ * Updates the logs and the UI when the idle state or time of the presence
+ * changes.
+ */
+ void (*update_idle)(PurplePresence *presence, gboolean old_idle);
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+/**
+ * A presence for an account
+ */
+struct _PurpleAccountPresence
+{
+ /*< private >*/
+ PurplePresence parent;
+};
+
+/** Base class for all #PurpleAccountPresence's */
+struct _PurpleAccountPresenceClass {
+ /*< private >*/
+ PurplePresenceClass parent_class;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+/**
+ * A presence for a buddy
+ */
+struct _PurpleBuddyPresence
+{
+ /*< private >*/
+ PurplePresence parent;
+};
+
+/** Base class for all #PurpleBuddyPresence's */
+struct _PurpleBuddyPresenceClass {
+ /*< private >*/
+ PurplePresenceClass parent_class;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+/**************************************************************************/
+/** @name PurpleAccountPresence API */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the GType for the PurpleAccountPresence object.
+ */
+GType purple_account_presence_get_type(void);
+
+/**
+ * Creates a presence for an account.
+ *
+ * @param account The account to associate with the presence.
+ *
+ * @return The new presence.
+ */
+PurpleAccountPresence *purple_account_presence_new(PurpleAccount *account);
+
+/**
+ * Returns an account presence's account.
+ *
+ * @param presence The presence.
+ *
+ * @return The presence's account.
+ */
+PurpleAccount *purple_account_presence_get_account(const PurpleAccountPresence *presence);
+
+/*@}*/
+
+/**************************************************************************/
+/** @name PurpleBuddyPresence API */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the GType for the PurpleBuddyPresence object.
+ */
+GType purple_buddy_presence_get_type(void);
+
+/**
+ * Creates a presence for a buddy.
+ *
+ * @param buddy The buddy to associate with the presence.
+ *
+ * @return The new presence.
+ */
+PurpleBuddyPresence *purple_buddy_presence_new(PurpleBuddy *buddy);
+
+/**
+ * Returns the buddy presence's buddy.
+ *
+ * @param presence The presence.
+ *
+ * @return The presence's buddy.
+ */
+PurpleBuddy *purple_buddy_presence_get_buddy(const PurpleBuddyPresence *presence);
+
+/**
+ * Compares two buddy presences for availability.
+ *
+ * @param buddy_presence1 The first presence.
+ * @param buddy_presence2 The second presence.
+ *
+ * @return -1 if @a buddy_presence1 is more available than @a buddy_presence2.
+ * 0 if @a buddy_presence1 is equal to @a buddy_presence2.
+ * 1 if @a buddy_presence1 is less available than @a buddy_presence2.
+ */
+gint purple_buddy_presence_compare(const PurpleBuddyPresence *buddy_presence1,
+ const PurpleBuddyPresence *buddy_presence2);
+
+/*@}*/
+
+/**************************************************************************/
+/** @name PurplePresence API */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the GType for the PurplePresence object.
+ */
+GType purple_presence_get_type(void);
+
+/**
+ * Sets the active state of a status in a presence.
+ *
+ * Only independent statuses can be set unactive. Normal statuses can only
+ * be set active, so if you wish to disable a status, set another
+ * non-independent status to active, or use purple_presence_switch_status().
+ *
+ * @param presence The presence.
+ * @param status_id The ID of the status.
+ * @param active The active state.
+ */
+void purple_presence_set_status_active(PurplePresence *presence,
+ const char *status_id, gboolean active);
+
+/**
+ * Switches the active status in a presence.
+ *
+ * This is similar to purple_presence_set_status_active(), except it won't
+ * activate independent statuses.
+ *
+ * @param presence The presence.
+ * @param status_id The status ID to switch to.
+ */
+void purple_presence_switch_status(PurplePresence *presence,
+ const char *status_id);
+
+/**
+ * Sets the idle state and time on a presence.
+ *
+ * @param presence The presence.
+ * @param idle The idle state.
+ * @param idle_time The idle time, if @a idle is TRUE. This
+ * is the time at which the user became idle,
+ * in seconds since the epoch. If this value is
+ * unknown then 0 should be used.
+ */
+void purple_presence_set_idle(PurplePresence *presence, gboolean idle,
+ time_t idle_time);
+
+/**
+ * Sets the login time on a presence.
+ *
+ * @param presence The presence.
+ * @param login_time The login time.
+ */
+void purple_presence_set_login_time(PurplePresence *presence, time_t login_time);
+
+/**
+ * Returns all the statuses in a presence.
+ *
+ * @param presence The presence.
+ *
+ * @constreturn The statuses.
+ */
+GList *purple_presence_get_statuses(const PurplePresence *presence);
+
+/**
+ * Returns the status with the specified ID from a presence.
+ *
+ * @param presence The presence.
+ * @param status_id The ID of the status.
+ *
+ * @return The status if found, or NULL.
+ */
+PurpleStatus *purple_presence_get_status(const PurplePresence *presence,
+ const char *status_id);
+
+/**
+ * Returns the active exclusive status from a presence.
+ *
+ * @param presence The presence.
+ *
+ * @return The active exclusive status.
+ */
+PurpleStatus *purple_presence_get_active_status(const PurplePresence *presence);
+
+/**
+ * Returns whether or not a presence is available.
+ *
+ * Available presences are online and possibly invisible, but not away or idle.
+ *
+ * @param presence The presence.
+ *
+ * @return TRUE if the presence is available, or FALSE otherwise.
+ */
+gboolean purple_presence_is_available(const PurplePresence *presence);
+
+/**
+ * Returns whether or not a presence is online.
+ *
+ * @param presence The presence.
+ *
+ * @return TRUE if the presence is online, or FALSE otherwise.
+ */
+gboolean purple_presence_is_online(const PurplePresence *presence);
+
+/**
+ * Returns whether or not a status in a presence is active.
+ *
+ * A status is active if itself or any of its sub-statuses are active.
+ *
+ * @param presence The presence.
+ * @param status_id The ID of the status.
+ *
+ * @return TRUE if the status is active, or FALSE.
+ */
+gboolean purple_presence_is_status_active(const PurplePresence *presence,
+ const char *status_id);
+
+/**
+ * Returns whether or not a status with the specified primitive type
+ * in a presence is active.
+ *
+ * A status is active if itself or any of its sub-statuses are active.
+ *
+ * @param presence The presence.
+ * @param primitive The status primitive.
+ *
+ * @return TRUE if the status is active, or FALSE.
+ */
+gboolean purple_presence_is_status_primitive_active(
+ const PurplePresence *presence, PurpleStatusPrimitive primitive);
+
+/**
+ * Returns whether or not a presence is idle.
+ *
+ * @param presence The presence.
+ *
+ * @return TRUE if the presence is idle, or FALSE otherwise.
+ * If the presence is offline (purple_presence_is_online()
+ * returns FALSE) then FALSE is returned.
+ */
+gboolean purple_presence_is_idle(const PurplePresence *presence);
+
+/**
+ * Returns the presence's idle time.
+ *
+ * @param presence The presence.
+ *
+ * @return The presence's idle time.
+ */
+time_t purple_presence_get_idle_time(const PurplePresence *presence);
+
+/**
+ * Returns the presence's login time.
+ *
+ * @param presence The presence.
+ *
+ * @return The presence's login time.
+ */
+time_t purple_presence_get_login_time(const PurplePresence *presence);
+
+/*@}*/
+
+G_END_DECLS
+
+#endif /* _PURPLE_PRESENCE_H_ */
diff --git a/libpurple/privacy.c b/libpurple/privacy.c
deleted file mode 100644
index 9f9d28838f..0000000000
--- a/libpurple/privacy.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/**
- * 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
- */
-#include "internal.h"
-
-#include "account.h"
-#include "privacy.h"
-#include "server.h"
-#include "util.h"
-
-static PurplePrivacyUiOps *privacy_ops = NULL;
-
-gboolean
-purple_privacy_permit_add(PurpleAccount *account, const char *who,
- gboolean local_only)
-{
- GSList *l;
- char *name;
- PurpleBuddy *buddy;
- PurpleBlistUiOps *blist_ops;
-
- g_return_val_if_fail(account != NULL, FALSE);
- g_return_val_if_fail(who != NULL, FALSE);
-
- name = g_strdup(purple_normalize(account, who));
-
- for (l = account->permit; l != NULL; l = l->next) {
- if (g_str_equal(name, l->data))
- /* This buddy already exists */
- break;
- }
-
- if (l != NULL)
- {
- /* This buddy already exists, so bail out */
- g_free(name);
- return FALSE;
- }
-
- account->permit = g_slist_append(account->permit, name);
-
- if (!local_only && purple_account_is_connected(account))
- serv_add_permit(purple_account_get_connection(account), who);
-
- if (privacy_ops != NULL && privacy_ops->permit_added != NULL)
- privacy_ops->permit_added(account, who);
-
- blist_ops = purple_blist_get_ui_ops();
- if (blist_ops != NULL && blist_ops->save_account != NULL)
- blist_ops->save_account(account);
-
- /* This lets the UI know a buddy has had its privacy setting changed */
- buddy = purple_find_buddy(account, name);
- if (buddy != NULL) {
- purple_signal_emit(purple_blist_get_handle(),
- "buddy-privacy-changed", buddy);
- }
- return TRUE;
-}
-
-gboolean
-purple_privacy_permit_remove(PurpleAccount *account, const char *who,
- gboolean local_only)
-{
- GSList *l;
- const char *name;
- PurpleBuddy *buddy;
- char *del;
- PurpleBlistUiOps *blist_ops;
-
- g_return_val_if_fail(account != NULL, FALSE);
- g_return_val_if_fail(who != NULL, FALSE);
-
- name = purple_normalize(account, who);
-
- for (l = account->permit; l != NULL; l = l->next) {
- if (g_str_equal(name, l->data))
- /* We found the buddy we were looking for */
- break;
- }
-
- if (l == NULL)
- /* We didn't find the buddy we were looking for, so bail out */
- return FALSE;
-
- /* We should not free l->data just yet. There can be occasions where
- * l->data == who. In such cases, freeing l->data here can cause crashes
- * later when who is used. */
- del = l->data;
- account->permit = g_slist_delete_link(account->permit, l);
-
- if (!local_only && purple_account_is_connected(account))
- serv_rem_permit(purple_account_get_connection(account), who);
-
- if (privacy_ops != NULL && privacy_ops->permit_removed != NULL)
- privacy_ops->permit_removed(account, who);
-
- blist_ops = purple_blist_get_ui_ops();
- if (blist_ops != NULL && blist_ops->save_account != NULL)
- blist_ops->save_account(account);
-
- buddy = purple_find_buddy(account, name);
- if (buddy != NULL) {
- purple_signal_emit(purple_blist_get_handle(),
- "buddy-privacy-changed", buddy);
- }
- g_free(del);
- return TRUE;
-}
-
-gboolean
-purple_privacy_deny_add(PurpleAccount *account, const char *who,
- gboolean local_only)
-{
- GSList *l;
- char *name;
- PurpleBuddy *buddy;
- PurpleBlistUiOps *blist_ops;
-
- g_return_val_if_fail(account != NULL, FALSE);
- g_return_val_if_fail(who != NULL, FALSE);
-
- name = g_strdup(purple_normalize(account, who));
-
- for (l = account->deny; l != NULL; l = l->next) {
- if (g_str_equal(name, l->data))
- /* This buddy already exists */
- break;
- }
-
- if (l != NULL)
- {
- /* This buddy already exists, so bail out */
- g_free(name);
- return FALSE;
- }
-
- account->deny = g_slist_append(account->deny, name);
-
- if (!local_only && purple_account_is_connected(account))
- serv_add_deny(purple_account_get_connection(account), who);
-
- if (privacy_ops != NULL && privacy_ops->deny_added != NULL)
- privacy_ops->deny_added(account, who);
-
- blist_ops = purple_blist_get_ui_ops();
- if (blist_ops != NULL && blist_ops->save_account != NULL)
- blist_ops->save_account(account);
-
- buddy = purple_find_buddy(account, name);
- if (buddy != NULL) {
- purple_signal_emit(purple_blist_get_handle(),
- "buddy-privacy-changed", buddy);
- }
- return TRUE;
-}
-
-gboolean
-purple_privacy_deny_remove(PurpleAccount *account, const char *who,
- gboolean local_only)
-{
- GSList *l;
- const char *normalized;
- char *name;
- PurpleBuddy *buddy;
- PurpleBlistUiOps *blist_ops;
-
- g_return_val_if_fail(account != NULL, FALSE);
- g_return_val_if_fail(who != NULL, FALSE);
-
- normalized = purple_normalize(account, who);
-
- for (l = account->deny; l != NULL; l = l->next) {
- if (g_str_equal(normalized, l->data))
- /* We found the buddy we were looking for */
- break;
- }
-
- if (l == NULL)
- /* We didn't find the buddy we were looking for, so bail out */
- return FALSE;
-
- buddy = purple_find_buddy(account, normalized);
-
- name = l->data;
- account->deny = g_slist_delete_link(account->deny, l);
-
- if (!local_only && purple_account_is_connected(account))
- serv_rem_deny(purple_account_get_connection(account), name);
-
- if (privacy_ops != NULL && privacy_ops->deny_removed != NULL)
- privacy_ops->deny_removed(account, who);
-
- if (buddy != NULL) {
- purple_signal_emit(purple_blist_get_handle(),
- "buddy-privacy-changed", buddy);
- }
-
- g_free(name);
-
- blist_ops = purple_blist_get_ui_ops();
- if (blist_ops != NULL && blist_ops->save_account != NULL)
- blist_ops->save_account(account);
-
- return TRUE;
-}
-
-/**
- * This makes sure your permit list contains all buddies from your
- * buddy list and ONLY buddies from your buddy list.
- */
-static void
-add_all_buddies_to_permit_list(PurpleAccount *account, gboolean local)
-{
- GSList *list;
-
- /* Remove anyone in the permit list who is not in the buddylist */
- for (list = account->permit; list != NULL; ) {
- char *person = list->data;
- list = list->next;
- if (!purple_find_buddy(account, person))
- purple_privacy_permit_remove(account, person, local);
- }
-
- /* Now make sure everyone in the buddylist is in the permit list */
- list = purple_find_buddies(account, NULL);
- while (list != NULL)
- {
- PurpleBuddy *buddy = list->data;
- const gchar *name = purple_buddy_get_name(buddy);
-
- if (!g_slist_find_custom(account->permit, name, (GCompareFunc)g_utf8_collate))
- purple_privacy_permit_add(account, name, local);
- list = g_slist_delete_link(list, list);
- }
-}
-
-/*
- * TODO: All callers of this function pass in FALSE for local and
- * restore and I don't understand when you would ever want to
- * use TRUE for either of them. I think both parameters could
- * safely be removed in the next major version bump.
- */
-void
-purple_privacy_allow(PurpleAccount *account, const char *who, gboolean local,
- gboolean restore)
-{
- GSList *list;
- PurplePrivacyType type = purple_account_get_privacy_type(account);
-
- switch (type) {
- case PURPLE_PRIVACY_ALLOW_ALL:
- return;
- case PURPLE_PRIVACY_ALLOW_USERS:
- purple_privacy_permit_add(account, who, local);
- break;
- case PURPLE_PRIVACY_DENY_USERS:
- purple_privacy_deny_remove(account, who, local);
- break;
- case PURPLE_PRIVACY_DENY_ALL:
- if (!restore) {
- /* Empty the allow-list. */
- const char *norm = purple_normalize(account, who);
- for (list = account->permit; list != NULL;) {
- char *person = list->data;
- list = list->next;
- if (!purple_strequal(norm, person))
- purple_privacy_permit_remove(account, person, local);
- }
- }
- purple_privacy_permit_add(account, who, local);
- 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);
- purple_account_set_privacy_type(account, PURPLE_PRIVACY_ALLOW_USERS);
- }
- break;
- default:
- g_return_if_reached();
- }
-
- /* Notify the server if the privacy setting was changed */
- if (type != purple_account_get_privacy_type(account) && purple_account_is_connected(account))
- serv_set_permit_deny(purple_account_get_connection(account));
-}
-
-/*
- * TODO: All callers of this function pass in FALSE for local and
- * restore and I don't understand when you would ever want to
- * use TRUE for either of them. I think both parameters could
- * safely be removed in the next major version bump.
- */
-void
-purple_privacy_deny(PurpleAccount *account, const char *who, gboolean local,
- gboolean restore)
-{
- GSList *list;
- PurplePrivacyType type = purple_account_get_privacy_type(account);
-
- switch (type) {
- case PURPLE_PRIVACY_ALLOW_ALL:
- if (!restore) {
- /* Empty the deny-list. */
- const char *norm = purple_normalize(account, who);
- for (list = account->deny; list != NULL; ) {
- char *person = list->data;
- list = list->next;
- if (!purple_strequal(norm, person))
- purple_privacy_deny_remove(account, person, local);
- }
- }
- purple_privacy_deny_add(account, who, local);
- purple_account_set_privacy_type(account, PURPLE_PRIVACY_DENY_USERS);
- break;
- case PURPLE_PRIVACY_ALLOW_USERS:
- purple_privacy_permit_remove(account, who, local);
- break;
- case PURPLE_PRIVACY_DENY_USERS:
- purple_privacy_deny_add(account, who, local);
- break;
- case PURPLE_PRIVACY_DENY_ALL:
- break;
- case PURPLE_PRIVACY_ALLOW_BUDDYLIST:
- if (purple_find_buddy(account, who)) {
- add_all_buddies_to_permit_list(account, local);
- purple_privacy_permit_remove(account, who, local);
- purple_account_set_privacy_type(account, PURPLE_PRIVACY_ALLOW_USERS);
- }
- break;
- default:
- g_return_if_reached();
- }
-
- /* Notify the server if the privacy setting was changed */
- if (type != purple_account_get_privacy_type(account) && purple_account_is_connected(account))
- serv_set_permit_deny(purple_account_get_connection(account));
-}
-
-gboolean
-purple_privacy_check(PurpleAccount *account, const char *who)
-{
- GSList *list;
-
- switch (purple_account_get_privacy_type(account)) {
- case PURPLE_PRIVACY_ALLOW_ALL:
- return TRUE;
-
- case PURPLE_PRIVACY_DENY_ALL:
- return FALSE;
-
- case PURPLE_PRIVACY_ALLOW_USERS:
- who = purple_normalize(account, who);
- for (list=account->permit; list!=NULL; list=list->next) {
- if (g_str_equal(who, list->data))
- return TRUE;
- }
- return FALSE;
-
- case PURPLE_PRIVACY_DENY_USERS:
- who = purple_normalize(account, who);
- for (list=account->deny; list!=NULL; list=list->next) {
- if (g_str_equal(who, list->data))
- return FALSE;
- }
- return TRUE;
-
- case PURPLE_PRIVACY_ALLOW_BUDDYLIST:
- return (purple_find_buddy(account, who) != NULL);
-
- default:
- g_return_val_if_reached(TRUE);
- }
-}
-
-void
-purple_privacy_set_ui_ops(PurplePrivacyUiOps *ops)
-{
- privacy_ops = ops;
-}
-
-PurplePrivacyUiOps *
-purple_privacy_get_ui_ops(void)
-{
- return privacy_ops;
-}
-
-void
-purple_privacy_init(void)
-{
-}
diff --git a/libpurple/privacy.h b/libpurple/privacy.h
deleted file mode 100644
index 19ef9d6494..0000000000
--- a/libpurple/privacy.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/**
- * @file privacy.h Privacy API
- * @ingroup core
- */
-
-/* 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 _PURPLE_PRIVACY_H_
-#define _PURPLE_PRIVACY_H_
-
-/**
- * Privacy data types.
- */
-typedef enum
-{
- PURPLE_PRIVACY_ALLOW_ALL = 1,
- PURPLE_PRIVACY_DENY_ALL,
- PURPLE_PRIVACY_ALLOW_USERS,
- PURPLE_PRIVACY_DENY_USERS,
- PURPLE_PRIVACY_ALLOW_BUDDYLIST
-} PurplePrivacyType;
-
-#include "account.h"
-
-/**
- * Privacy core/UI operations.
- */
-typedef struct
-{
- void (*permit_added)(PurpleAccount *account, const char *name);
- void (*permit_removed)(PurpleAccount *account, const char *name);
- void (*deny_added)(PurpleAccount *account, const char *name);
- void (*deny_removed)(PurpleAccount *account, const char *name);
-
- void (*_purple_reserved1)(void);
- void (*_purple_reserved2)(void);
- void (*_purple_reserved3)(void);
- void (*_purple_reserved4)(void);
-} PurplePrivacyUiOps;
-
-G_BEGIN_DECLS
-
-/**
- * Adds a user to the account's permit list.
- *
- * @param account The account.
- * @param name The name of the user to add to the list.
- * @param local_only If TRUE, only the local list is updated, and not
- * the server.
- *
- * @return TRUE if the user was added successfully, or @c FALSE otherwise.
- */
-gboolean purple_privacy_permit_add(PurpleAccount *account, const char *name,
- gboolean local_only);
-
-/**
- * Removes a user from the account's permit list.
- *
- * @param account The account.
- * @param name The name of the user to add to the list.
- * @param local_only If TRUE, only the local list is updated, and not
- * the server.
- *
- * @return TRUE if the user was removed successfully, or @c FALSE otherwise.
- */
-gboolean purple_privacy_permit_remove(PurpleAccount *account, const char *name,
- gboolean local_only);
-
-/**
- * Adds a user to the account's deny list.
- *
- * @param account The account.
- * @param name The name of the user to add to the list.
- * @param local_only If TRUE, only the local list is updated, and not
- * the server.
- *
- * @return TRUE if the user was added successfully, or @c FALSE otherwise.
- */
-gboolean purple_privacy_deny_add(PurpleAccount *account, const char *name,
- gboolean local_only);
-
-/**
- * Removes a user from the account's deny list.
- *
- * @param account The account.
- * @param name The name of the user to add to the list.
- * @param local_only If TRUE, only the local list is updated, and not
- * the server.
- *
- * @return TRUE if the user was removed successfully, or @c FALSE otherwise.
- */
-gboolean purple_privacy_deny_remove(PurpleAccount *account, const char *name,
- gboolean local_only);
-
-/**
- * Allow a user to send messages. If current privacy setting for the account is:
- * PURPLE_PRIVACY_ALLOW_USERS: The user is added to the allow-list.
- * PURPLE_PRIVACY_DENY_USERS : The user is removed from the deny-list.
- * PURPLE_PRIVACY_ALLOW_ALL : No changes made.
- * PURPLE_PRIVACY_DENY_ALL : The privacy setting is changed to
- * PURPLE_PRIVACY_ALLOW_USERS and the user
- * is added to the allow-list.
- * PURPLE_PRIVACY_ALLOW_BUDDYLIST: No changes made if the user is already in
- * the buddy-list. Otherwise the setting is
- * changed to PURPLE_PRIVACY_ALLOW_USERS, all the
- * buddies are added to the allow-list, and the
- * user is also added to the allow-list.
- *
- * @param account The account.
- * @param who The name of the user.
- * @param local Whether the change is local-only.
- * @param restore Should the previous allow/deny list be restored if the
- * privacy setting is changed.
- */
-void purple_privacy_allow(PurpleAccount *account, const char *who, gboolean local,
- gboolean restore);
-
-/**
- * Block messages from a user. If current privacy setting for the account is:
- * PURPLE_PRIVACY_ALLOW_USERS: The user is removed from the allow-list.
- * PURPLE_PRIVACY_DENY_USERS : The user is added to the deny-list.
- * PURPLE_PRIVACY_DENY_ALL : No changes made.
- * PURPLE_PRIVACY_ALLOW_ALL : The privacy setting is changed to
- * PURPLE_PRIVACY_DENY_USERS and the user is
- * added to the deny-list.
- * PURPLE_PRIVACY_ALLOW_BUDDYLIST: If the user is not in the buddy-list,
- * then no changes made. Otherwise, the setting
- * is changed to PURPLE_PRIVACY_ALLOW_USERS, all
- * the buddies are added to the allow-list, and
- * this user is removed from the list.
- *
- * @param account The account.
- * @param who The name of the user.
- * @param local Whether the change is local-only.
- * @param restore Should the previous allow/deny list be restored if the
- * privacy setting is changed.
- */
-void purple_privacy_deny(PurpleAccount *account, const char *who, gboolean local,
- gboolean restore);
-
-/**
- * Check the privacy-setting for a user.
- *
- * @param account The account.
- * @param who The name of the user.
- *
- * @return @c FALSE if the specified account's privacy settings block the user or @c TRUE otherwise. The meaning of "block" is protocol-dependent and generally relates to status and/or sending of messages.
- */
-gboolean purple_privacy_check(PurpleAccount *account, const char *who);
-
-/**
- * Sets the UI operations structure for the privacy subsystem.
- *
- * @param ops The UI operations structure.
- */
-void purple_privacy_set_ui_ops(PurplePrivacyUiOps *ops);
-
-/**
- * Returns the UI operations structure for the privacy subsystem.
- *
- * @return The UI operations structure.
- */
-PurplePrivacyUiOps *purple_privacy_get_ui_ops(void);
-
-/**
- * Initializes the privacy subsystem.
- */
-void purple_privacy_init(void);
-
-G_END_DECLS
-
-#endif /* _PURPLE_PRIVACY_H_ */
diff --git a/libpurple/protocols/bonjour/bonjour.c b/libpurple/protocols/bonjour/bonjour.c
index 5dc85c47db..d0ceef8bab 100644
--- a/libpurple/protocols/bonjour/bonjour.c
+++ b/libpurple/protocols/bonjour/bonjour.c
@@ -68,11 +68,11 @@ bonjour_removeallfromlocal(PurpleConnection *conn, PurpleGroup *bonjour_group)
/* Go through and remove all buddies that belong to this account */
for (cnode = purple_blist_node_get_first_child((PurpleBlistNode *) bonjour_group); cnode; cnode = cnodenext) {
cnodenext = purple_blist_node_get_sibling_next(cnode);
- if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode))
+ if (!PURPLE_IS_CONTACT(cnode))
continue;
for (bnode = purple_blist_node_get_first_child(cnode); bnode; bnode = bnodenext) {
bnodenext = purple_blist_node_get_sibling_next(bnode);
- if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode))
+ if (!PURPLE_IS_BUDDY(bnode))
continue;
buddy = (PurpleBuddy *) bnode;
if (purple_buddy_get_account(buddy) != account)
@@ -103,7 +103,7 @@ bonjour_login(PurpleAccount *account)
}
#endif /* _WIN32 */
- purple_connection_set_flags(gc, PURPLE_CONNECTION_HTML);
+ purple_connection_set_flags(gc, PURPLE_CONNECTION_FLAG_HTML);
bd = g_new0(BonjourData, 1);
purple_connection_set_protocol_data(gc, bd);
@@ -152,7 +152,7 @@ bonjour_login(PurpleAccount *account)
bonjour_dns_sd_update_buddy_icon(bd->dns_sd_data);
/* Show the buddy list by telling Purple we have already connected */
- purple_connection_set_state(gc, PURPLE_CONNECTED);
+ purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED);
}
static void
@@ -161,7 +161,7 @@ bonjour_close(PurpleConnection *connection)
PurpleGroup *bonjour_group;
BonjourData *bd = purple_connection_get_protocol_data(connection);
- bonjour_group = purple_find_group(BONJOUR_GROUP_NAME);
+ bonjour_group = purple_blist_find_group(BONJOUR_GROUP_NAME);
/* Remove all the bonjour buddies */
bonjour_removeallfromlocal(connection, bonjour_group);
@@ -289,14 +289,14 @@ bonjour_status_types(PurpleAccount *account)
BONJOUR_STATUS_ID_AVAILABLE,
NULL, TRUE, TRUE, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
status_types = g_list_append(status_types, type);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY,
BONJOUR_STATUS_ID_AWAY,
NULL, TRUE, TRUE, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
status_types = g_list_append(status_types, type);
type = purple_status_type_new_full(PURPLE_STATUS_OFFLINE,
@@ -310,7 +310,7 @@ bonjour_status_types(PurpleAccount *account)
static void
bonjour_convo_closed(PurpleConnection *connection, const char *who)
{
- PurpleBuddy *buddy = purple_find_buddy(purple_connection_get_account(connection), who);
+ PurpleBuddy *buddy = purple_blist_find_buddy(purple_connection_get_account(connection), who);
BonjourBuddy *bb;
if (buddy == NULL || (bb = purple_buddy_get_protocol_data(buddy)) == NULL)
@@ -421,26 +421,24 @@ bonjour_tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboole
}
static void
-bonjour_do_group_change(PurpleBuddy *buddy, const char *new_group) {
- PurpleBlistNodeFlags oldflags;
-
+bonjour_do_group_change(PurpleBuddy *buddy, const char *new_group)
+{
if (buddy == NULL)
return;
- oldflags = purple_blist_node_get_flags((PurpleBlistNode *)buddy);
-
/* If we're moving them out of the bonjour group, make them persistent */
if (purple_strequal(new_group, BONJOUR_GROUP_NAME))
- purple_blist_node_set_flags((PurpleBlistNode *)buddy, oldflags | PURPLE_BLIST_NODE_FLAG_NO_SAVE);
+ purple_blist_node_set_transient(PURPLE_BLIST_NODE(buddy), TRUE);
else
- purple_blist_node_set_flags((PurpleBlistNode *)buddy, oldflags ^ PURPLE_BLIST_NODE_FLAG_NO_SAVE);
+ purple_blist_node_set_transient(PURPLE_BLIST_NODE(buddy),
+ !purple_blist_node_is_transient(PURPLE_BLIST_NODE(buddy)));
}
static void
bonjour_group_buddy(PurpleConnection *connection, const char *who, const char *old_group, const char *new_group)
{
- PurpleBuddy *buddy = purple_find_buddy(purple_connection_get_account(connection), who);
+ PurpleBuddy *buddy = purple_blist_find_buddy(purple_connection_get_account(connection), who);
bonjour_do_group_change(buddy, new_group);
@@ -465,7 +463,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(purple_connection_get_account(connection), who);
+ PurpleBuddy *buddy = purple_blist_find_buddy(purple_connection_get_account(connection), who);
return (buddy != NULL && purple_buddy_get_protocol_data(buddy) != NULL);
}
diff --git a/libpurple/protocols/bonjour/bonjour_ft.c b/libpurple/protocols/bonjour/bonjour_ft.c
index 6e704facc4..870e8700ce 100644
--- a/libpurple/protocols/bonjour/bonjour_ft.c
+++ b/libpurple/protocols/bonjour/bonjour_ft.c
@@ -28,7 +28,7 @@
#include "buddy.h"
#include "bonjour.h"
#include "bonjour_ft.h"
-#include "cipher.h"
+#include "ciphers/sha1hash.h"
static void
bonjour_bytestreams_init(PurpleXfer *xfer);
@@ -408,7 +408,7 @@ bonjour_xfer_init(PurpleXfer *xfer)
purple_debug_info("bonjour", "Bonjour-xfer-init.\n");
- buddy = purple_find_buddy(purple_xfer_get_account(xfer), purple_xfer_get_remote_user(xfer));
+ buddy = purple_blist_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;
@@ -1018,6 +1018,7 @@ bonjour_bytestreams_connect(PurpleXfer *xfer)
{
PurpleBuddy *pb;
PurpleAccount *account = NULL;
+ PurpleHash *hash;
XepXfer *xf;
char dstaddr[41];
const gchar *name = NULL;
@@ -1039,8 +1040,12 @@ bonjour_bytestreams_connect(PurpleXfer *xfer)
account = purple_buddy_get_account(pb);
p = g_strdup_printf("%s%s%s", xf->sid, name, bonjour_get_jid(account));
- purple_cipher_digest_region("sha1", (guchar *)p, strlen(p), hashval,
- sizeof(hashval));
+
+ hash = purple_sha1_hash_new();
+ purple_hash_append(hash, (guchar *)p, strlen(p));
+ purple_hash_digest(hash, hashval, sizeof(hashval));
+ g_object_unref(G_OBJECT(hash));
+
g_free(p);
memset(dstaddr, 0, 41);
diff --git a/libpurple/protocols/bonjour/buddy.c b/libpurple/protocols/bonjour/buddy.c
index 890a7e1b09..36eb17caca 100644
--- a/libpurple/protocols/bonjour/buddy.c
+++ b/libpurple/protocols/bonjour/buddy.c
@@ -20,7 +20,7 @@
#include "internal.h"
#include "buddy.h"
#include "account.h"
-#include "blist.h"
+#include "buddylist.h"
#include "bonjour.h"
#include "mdns_interface.h"
#include "debug.h"
@@ -141,7 +141,7 @@ bonjour_buddy_add_to_purple(BonjourBuddy *bonjour_buddy, PurpleBuddy *buddy)
*/
/* Make sure the Bonjour group exists in our buddy list */
- group = purple_find_group(BONJOUR_GROUP_NAME); /* Use the buddy's domain, instead? */
+ group = purple_blist_find_group(BONJOUR_GROUP_NAME); /* Use the buddy's domain, instead? */
if (group == NULL) {
group = purple_group_new(BONJOUR_GROUP_NAME);
purple_blist_add_group(group, NULL);
@@ -149,11 +149,11 @@ bonjour_buddy_add_to_purple(BonjourBuddy *bonjour_buddy, PurpleBuddy *buddy)
/* Make sure the buddy exists in our buddy list */
if (buddy == NULL)
- buddy = purple_find_buddy(account, bonjour_buddy->name);
+ buddy = purple_blist_find_buddy(account, bonjour_buddy->name);
if (buddy == NULL) {
buddy = purple_buddy_new(account, bonjour_buddy->name, NULL);
- purple_blist_node_set_flags((PurpleBlistNode *)buddy, PURPLE_BLIST_NODE_FLAG_NO_SAVE);
+ purple_blist_node_set_transient(PURPLE_BLIST_NODE(buddy), TRUE);
purple_blist_add_buddy(buddy, NULL, group, NULL);
}
@@ -207,14 +207,14 @@ bonjour_buddy_add_to_purple(BonjourBuddy *bonjour_buddy, PurpleBuddy *buddy)
* If the buddy is being saved, mark as offline, otherwise delete
*/
void bonjour_buddy_signed_off(PurpleBuddy *pb) {
- if (PURPLE_BLIST_NODE_SHOULD_SAVE(pb)) {
+ if (purple_blist_node_is_transient(PURPLE_BLIST_NODE(pb))) {
+ purple_account_remove_buddy(purple_buddy_get_account(pb), pb, NULL);
+ purple_blist_remove_buddy(pb);
+ } else {
purple_prpl_got_user_status(purple_buddy_get_account(pb),
purple_buddy_get_name(pb), "offline", NULL);
bonjour_buddy_delete(purple_buddy_get_protocol_data(pb));
purple_buddy_set_protocol_data(pb, NULL);
- } else {
- purple_account_remove_buddy(purple_buddy_get_account(pb), pb, NULL);
- purple_blist_remove_buddy(pb);
}
}
diff --git a/libpurple/protocols/bonjour/jabber.c b/libpurple/protocols/bonjour/jabber.c
index a600b6d023..241abf16be 100644
--- a/libpurple/protocols/bonjour/jabber.c
+++ b/libpurple/protocols/bonjour/jabber.c
@@ -52,7 +52,7 @@
#include "network.h"
#include "eventloop.h"
#include "connection.h"
-#include "blist.h"
+#include "buddylist.h"
#include "xmlnode.h"
#include "debug.h"
#include "notify.h"
@@ -89,7 +89,7 @@ bonjour_jabber_conv_new(PurpleBuddy *pb, PurpleAccount *account, const char *ip)
BonjourJabberConversation *bconv = g_new0(BonjourJabberConversation, 1);
bconv->socket = -1;
- bconv->tx_buf = purple_circ_buffer_new(512);
+ bconv->tx_buf = purple_circular_buffer_new(512);
bconv->tx_handler = 0;
bconv->rx_handler = 0;
bconv->pb = pb;
@@ -280,7 +280,7 @@ _send_data_write_cb(gpointer data, gint source, PurpleInputCondition cond)
BonjourJabberConversation *bconv = bb->conversation;
int ret, writelen;
- writelen = purple_circ_buffer_get_max_read(bconv->tx_buf);
+ writelen = purple_circular_buffer_get_max_read(bconv->tx_buf);
if (writelen == 0) {
purple_input_remove(bconv->tx_handler);
@@ -288,7 +288,7 @@ _send_data_write_cb(gpointer data, gint source, PurpleInputCondition cond)
return;
}
- ret = send(bconv->socket, bconv->tx_buf->outptr, writelen, 0);
+ ret = send(bconv->socket, purple_circular_buffer_get_output(bconv->tx_buf), writelen, 0);
if (ret < 0 && errno == EAGAIN)
return;
@@ -302,7 +302,7 @@ _send_data_write_cb(gpointer data, gint source, PurpleInputCondition cond)
account = purple_buddy_get_account(pb);
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, account);
+ conv = PURPLE_CONVERSATION(purple_conversations_find_im_with_account(bb->name, account));
if (conv != NULL)
purple_conversation_write(conv, NULL,
_("Unable to send message."),
@@ -313,7 +313,7 @@ _send_data_write_cb(gpointer data, gint source, PurpleInputCondition cond)
return;
}
- purple_circ_buffer_mark_read(bconv->tx_buf, ret);
+ purple_circular_buffer_mark_read(bconv->tx_buf, ret);
}
static gint
@@ -329,7 +329,7 @@ _send_data(PurpleBuddy *pb, char *message)
|| bconv->connect_data != NULL
|| bconv->sent_stream_start != FULLY_SENT
|| !bconv->recv_stream_start
- || purple_circ_buffer_get_max_read(bconv->tx_buf) > 0) {
+ || purple_circular_buffer_get_max_read(bconv->tx_buf) > 0) {
ret = -1;
errno = EAGAIN;
} else {
@@ -348,7 +348,7 @@ _send_data(PurpleBuddy *pb, char *message)
account = purple_buddy_get_account(pb);
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, account);
+ conv = PURPLE_CONVERSATION(purple_conversations_find_im_with_account(bb->name, account));
if (conv != NULL)
purple_conversation_write(conv, NULL,
_("Unable to send message."),
@@ -364,7 +364,7 @@ _send_data(PurpleBuddy *pb, char *message)
if (bconv->sent_stream_start == FULLY_SENT && bconv->recv_stream_start && bconv->tx_handler == 0)
bconv->tx_handler = purple_input_add(bconv->socket, PURPLE_INPUT_WRITE,
_send_data_write_cb, pb);
- purple_circ_buffer_append(bconv->tx_buf, message + ret, len - ret);
+ purple_circular_buffer_append(bconv->tx_buf, message + ret, len - ret);
}
return ret;
@@ -396,7 +396,7 @@ static void bonjour_jabber_stream_ended(BonjourJabberConversation *bconv) {
#if 0
if(bconv->pb != NULL) {
PurpleConversation *conv;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bconv->pb->name, bconv->pb->account);
+ conv = purple_conversations_find_im_with_account(bconv->pb->name, bconv->pb->account);
if (conv != NULL) {
char *tmp = g_strdup_printf(_("%s has closed the conversation."), bconv->pb->name);
purple_conversation_write(conv, NULL, tmp, PURPLE_MESSAGE_SYSTEM, time(NULL));
@@ -485,7 +485,7 @@ _start_stream(gpointer data, gint source, PurpleInputCondition condition)
purple_debug_error("bonjour", "Error starting stream with buddy %s at %s error: %s\n",
bname ? bname : "(unknown)", bconv->ip, err ? err : "(null)");
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bname, bconv->account);
+ conv = PURPLE_CONVERSATION(purple_conversations_find_im_with_account(bname, bconv->account));
if (conv != NULL)
purple_conversation_write(conv, NULL,
_("Unable to send the message, the conversation couldn't be started."),
@@ -550,7 +550,7 @@ static gboolean bonjour_jabber_send_stream_init(BonjourJabberConversation *bconv
if (bconv->pb) {
PurpleConversation *conv;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bname, bconv->account);
+ conv = PURPLE_CONVERSATION(purple_conversations_find_im_with_account(bname, bconv->account));
if (conv != NULL)
purple_conversation_write(conv, NULL,
_("Unable to send the message, the conversation couldn't be started."),
@@ -595,7 +595,7 @@ void bonjour_jabber_stream_started(BonjourJabberConversation *bconv) {
if (bconv->pb) {
PurpleConversation *conv;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bname, bconv->account);
+ conv = PURPLE_CONVERSATION(purple_conversations_find_im_with_account(bname, bconv->account));
if (conv != NULL)
purple_conversation_write(conv, NULL,
_("Unable to send the message, the conversation couldn't be started."),
@@ -616,7 +616,7 @@ void bonjour_jabber_stream_started(BonjourJabberConversation *bconv) {
/* If the stream has been completely started and we know who we're talking to, we can start doing stuff. */
/* I don't think the circ_buffer can actually contain anything without a buddy being associated, but lets be explicit. */
if (bconv->sent_stream_start == FULLY_SENT && bconv->recv_stream_start
- && bconv->pb && purple_circ_buffer_get_max_read(bconv->tx_buf) > 0) {
+ && bconv->pb && purple_circular_buffer_get_max_read(bconv->tx_buf) > 0) {
/* Watch for when we can write the buffered messages */
bconv->tx_handler = purple_input_add(bconv->socket, PURPLE_INPUT_WRITE,
_send_data_write_cb, bconv->pb);
@@ -680,7 +680,7 @@ _server_socket_handler(gpointer data, int server_socket, PurpleInputCondition co
mbba = g_new0(struct _match_buddies_by_address_t, 1);
mbba->address = address_text;
- buddies = purple_find_buddies(jdata->account, NULL);
+ buddies = purple_blist_find_buddies(jdata->account, NULL);
g_slist_foreach(buddies, _match_buddies_by_address, mbba);
g_slist_free(buddies);
@@ -872,7 +872,7 @@ _connected_to_buddy(gpointer data, gint source, const gchar *error)
purple_debug_error("bonjour", "No more addresses for buddy %s. Aborting", purple_buddy_get_name(pb));
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, account);
+ conv = PURPLE_CONVERSATION(purple_conversations_find_im_with_account(bb->name, account));
if (conv != NULL)
purple_conversation_write(conv, NULL,
_("Unable to send the message, the conversation couldn't be started."),
@@ -893,7 +893,7 @@ _connected_to_buddy(gpointer data, gint source, const gchar *error)
account = purple_buddy_get_account(pb);
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, account);
+ conv = PURPLE_CONVERSATION(purple_conversations_find_im_with_account(bb->name, account));
if (conv != NULL)
purple_conversation_write(conv, NULL,
_("Unable to send the message, the conversation couldn't be started."),
@@ -919,7 +919,7 @@ bonjour_jabber_conv_match_by_name(BonjourJabberConversation *bconv) {
g_return_if_fail(bconv->ip != NULL);
g_return_if_fail(bconv->pb == NULL);
- pb = purple_find_buddy(bconv->account, bconv->buddy_name);
+ pb = purple_blist_find_buddy(bconv->account, bconv->buddy_name);
if (pb && (bb = purple_buddy_get_protocol_data(pb))) {
const char *ip;
GSList *tmp = bb->ips;
@@ -975,7 +975,7 @@ bonjour_jabber_conv_match_by_ip(BonjourJabberConversation *bconv) {
mbba = g_new0(struct _match_buddies_by_address_t, 1);
mbba->address = bconv->ip;
- buddies = purple_find_buddies(jdata->account, NULL);
+ buddies = purple_blist_find_buddies(jdata->account, NULL);
g_slist_foreach(buddies, _match_buddies_by_address, mbba);
g_slist_free(buddies);
@@ -1024,7 +1024,7 @@ _find_or_start_conversation(BonjourJabber *jdata, const gchar *to)
g_return_val_if_fail(jdata != NULL, NULL);
g_return_val_if_fail(to != NULL, NULL);
- pb = purple_find_buddy(jdata->account, to);
+ pb = purple_blist_find_buddy(jdata->account, to);
if (pb == NULL || (bb = purple_buddy_get_protocol_data(pb)) == NULL)
/* You can not send a message to an offline buddy */
return NULL;
@@ -1189,7 +1189,7 @@ bonjour_jabber_close_conversation(BonjourJabberConversation *bconv)
purple_input_remove(bconv->tx_handler);
/* Free all the data related to the conversation */
- purple_circ_buffer_destroy(bconv->tx_buf);
+ g_object_unref(G_OBJECT(bconv->tx_buf));
if (bconv->connect_data != NULL)
purple_proxy_connect_cancel(bconv->connect_data);
if (bconv->stream_data != NULL) {
@@ -1227,12 +1227,12 @@ bonjour_jabber_stop(BonjourJabber *jdata)
if (!purple_account_is_disconnected(jdata->account)) {
GSList *buddies, *l;
- buddies = purple_find_buddies(jdata->account, NULL);
+ buddies = purple_blist_find_buddies(jdata->account, NULL);
for (l = buddies; l; l = l->next) {
BonjourBuddy *bb = purple_buddy_get_protocol_data((PurpleBuddy*) l->data);
if (bb && bb->conversation) {
/* Any ongoing connection attempt is cancelled
- * by _purple_connection_destroy */
+ * when a connection is destroyed */
bb->conversation->connect_data = NULL;
bonjour_jabber_close_conversation(bb->conversation);
bb->conversation = NULL;
@@ -1303,7 +1303,7 @@ check_if_blocked(PurpleBuddy *pb)
acc = purple_buddy_get_account(pb);
- for(l = acc->deny; l != NULL; l = l->next) {
+ for(l = purple_account_privacy_get_denied(acc); l != NULL; l = l->next) {
const gchar *name = purple_buddy_get_name(pb);
const gchar *username = bonjour_get_jid(acc);
diff --git a/libpurple/protocols/bonjour/jabber.h b/libpurple/protocols/bonjour/jabber.h
index 4096497008..e0a1d0a2cd 100644
--- a/libpurple/protocols/bonjour/jabber.h
+++ b/libpurple/protocols/bonjour/jabber.h
@@ -31,7 +31,7 @@
#include "xmlnode.h"
#include "account.h"
-#include "circbuffer.h"
+#include "circularbuffer.h"
typedef struct _BonjourJabber
{
@@ -50,7 +50,7 @@ typedef struct _BonjourJabberConversation
guint rx_handler;
guint tx_handler;
guint close_timeout;
- PurpleCircBuffer *tx_buf;
+ PurpleCircularBuffer *tx_buf;
int sent_stream_start; /* 0 = Unsent, 1 = Partial, 2 = Complete */
gboolean recv_stream_start;
PurpleProxyConnectData *connect_data;
diff --git a/libpurple/protocols/bonjour/mdns_avahi.c b/libpurple/protocols/bonjour/mdns_avahi.c
index 07dc63e161..b921ce7acf 100644
--- a/libpurple/protocols/bonjour/mdns_avahi.c
+++ b/libpurple/protocols/bonjour/mdns_avahi.c
@@ -122,7 +122,7 @@ _resolver_callback(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtoco
g_return_if_fail(r != NULL);
- pb = purple_find_buddy(account, name);
+ pb = purple_blist_find_buddy(account, name);
bb = (pb != NULL) ? purple_buddy_get_protocol_data(pb) : NULL;
switch (event) {
@@ -266,7 +266,7 @@ _browser_callback(AvahiServiceBrowser *b, AvahiIfIndex interface,
break;
case AVAHI_BROWSER_REMOVE:
purple_debug_info("bonjour", "_browser_callback - Remove service\n");
- pb = purple_find_buddy(account, name);
+ pb = purple_blist_find_buddy(account, name);
if (pb != NULL) {
BonjourBuddy *bb = purple_buddy_get_protocol_data(pb);
AvahiBuddyImplData *b_impl;
diff --git a/libpurple/protocols/bonjour/mdns_win32.c b/libpurple/protocols/bonjour/mdns_win32.c
index d7ee2e8e86..7cade1986b 100644
--- a/libpurple/protocols/bonjour/mdns_win32.c
+++ b/libpurple/protocols/bonjour/mdns_win32.c
@@ -176,7 +176,7 @@ _mdns_resolve_host_callback(DNSServiceRef sdRef, DNSServiceFlags flags,
g_free(args->resolver_query);
args->resolver_query = NULL;
- if ((pb = purple_find_buddy(args->account, args->res_data->name))) {
+ if ((pb = purple_blist_find_buddy(args->account, args->res_data->name))) {
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);
@@ -293,7 +293,7 @@ _mdns_service_resolve_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint3
if (idata->resolvers == NULL) {
PurpleBuddy *pb;
/* See if this is now attached to a PurpleBuddy */
- if ((pb = purple_find_buddy(args->account, args->bb->name)))
+ if ((pb = purple_blist_find_buddy(args->account, args->bb->name)))
bonjour_buddy_signed_off(pb);
else {
/* Remove from the pending list */
@@ -347,7 +347,7 @@ _mdns_service_browse_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32
Win32BuddyImplData *idata;
/* Is there an existing buddy? */
- if ((pb = purple_find_buddy(account, serviceName)))
+ if ((pb = purple_blist_find_buddy(account, serviceName)))
bb = purple_buddy_get_protocol_data(pb);
/* Is there a pending buddy? */
else {
@@ -403,7 +403,7 @@ _mdns_service_browse_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32
serviceName, interfaceIndex, regtype ? regtype : "",
replyDomain ? replyDomain : "");
- pb = purple_find_buddy(account, serviceName);
+ pb = purple_blist_find_buddy(account, serviceName);
if (pb != NULL) {
GSList *l;
/* There may be multiple presences, we should only get rid of this one */
diff --git a/libpurple/protocols/gg/Makefile.am b/libpurple/protocols/gg/Makefile.am
index ecfcd72ca8..6c1904bedd 100644
--- a/libpurple/protocols/gg/Makefile.am
+++ b/libpurple/protocols/gg/Makefile.am
@@ -55,8 +55,8 @@ GGSOURCES = \
utils.c \
confer.h \
confer.c \
- buddylist.h \
- buddylist.c \
+ blist.h \
+ blist.c \
gg.h \
gg.c \
resolver-purple.h \
diff --git a/libpurple/protocols/gg/avatar.c b/libpurple/protocols/gg/avatar.c
index 07a26ccde5..763fa51c87 100644
--- a/libpurple/protocols/gg/avatar.c
+++ b/libpurple/protocols/gg/avatar.c
@@ -191,7 +191,7 @@ static gboolean ggp_avatar_buddy_update_next(PurpleConnection *gc)
pending_update = pending_update_it->data;
avdata->pending_updates = g_list_remove(avdata->pending_updates,
pending_update);
- buddy = purple_find_buddy(account, ggp_uin_to_str(pending_update->uin));
+ buddy = purple_blist_find_buddy(account, ggp_uin_to_str(pending_update->uin));
if (!buddy)
{
@@ -286,7 +286,7 @@ static void ggp_avatar_buddy_update_received(PurpleHttpConnection *http_conn,
}
account = purple_connection_get_account(gc);
- buddy = purple_find_buddy(account, ggp_uin_to_str(pending_update->uin));
+ buddy = purple_blist_find_buddy(account, ggp_uin_to_str(pending_update->uin));
if (!buddy)
{
diff --git a/libpurple/protocols/gg/buddylist.c b/libpurple/protocols/gg/blist.c
index eaeb40305e..72d9e98f12 100644
--- a/libpurple/protocols/gg/buddylist.c
+++ b/libpurple/protocols/gg/blist.c
@@ -26,7 +26,7 @@
#include "gg.h"
#include "utils.h"
-#include "buddylist.h"
+#include "blist.h"
#define F_FIRSTNAME 0
#define F_LASTNAME 1
@@ -48,13 +48,13 @@ void ggp_buddylist_send(PurpleConnection *gc)
int i = 0, ret = 0;
int size;
- buddies = purple_find_buddies(account, NULL);
+ buddies = purple_blist_find_buddies(account, NULL);
size = g_slist_length(buddies);
userlist = g_new(uin_t, size);
types = g_new(gchar, size);
- for (buddies = purple_find_buddies(account, NULL); buddies;
+ for (buddies = purple_blist_find_buddies(account, NULL); buddies;
buddies = g_slist_delete_link(buddies, buddies), ++i)
{
PurpleBuddy *buddy = buddies->data;
@@ -118,7 +118,7 @@ void ggp_buddylist_load(PurpleConnection *gc, char *buddylist)
purple_debug_info("gg", "got buddy: name=%s; show=%s\n", name, show);
- if (purple_find_buddy(purple_connection_get_account(gc), name)) {
+ if (purple_blist_find_buddy(purple_connection_get_account(gc), name)) {
g_strfreev(data_tbl);
continue;
}
@@ -139,7 +139,7 @@ void ggp_buddylist_load(PurpleConnection *gc, char *buddylist)
buddy = purple_buddy_new(purple_connection_get_account(gc), name,
strlen(show) ? show : NULL);
- if (!(group = purple_find_group(g))) {
+ if (!(group = purple_blist_find_group(g))) {
group = purple_group_new(g);
purple_blist_add_group(group, NULL);
}
@@ -163,7 +163,7 @@ char *ggp_buddylist_dump(PurpleAccount *account)
GString *buddylist = g_string_sized_new(1024);
char *ptr;
- for (buddies = purple_find_buddies(account, NULL); buddies;
+ for (buddies = purple_blist_find_buddies(account, NULL); buddies;
buddies = g_slist_delete_link(buddies, buddies)) {
PurpleBuddy *buddy = buddies->data;
PurpleGroup *group = purple_buddy_get_group(buddy);
@@ -189,7 +189,7 @@ char *ggp_buddylist_dump(PurpleAccount *account)
const char * ggp_buddylist_get_buddy_name(PurpleConnection *gc, const uin_t uin)
{
const char *uin_s = ggp_uin_to_str(uin);
- PurpleBuddy *buddy = purple_find_buddy(
+ PurpleBuddy *buddy = purple_blist_find_buddy(
purple_connection_get_account(gc), uin_s);
if (buddy != NULL)
diff --git a/libpurple/protocols/gg/buddylist.h b/libpurple/protocols/gg/blist.h
index 70fdf41692..ca07212328 100644
--- a/libpurple/protocols/gg/buddylist.h
+++ b/libpurple/protocols/gg/blist.h
@@ -1,5 +1,5 @@
/**
- * @file buddylist.h
+ * @file blist.h
*
* purple
*
diff --git a/libpurple/protocols/gg/confer.c b/libpurple/protocols/gg/confer.c
index 25406af301..12007ded23 100644
--- a/libpurple/protocols/gg/confer.c
+++ b/libpurple/protocols/gg/confer.c
@@ -27,12 +27,12 @@
#include "confer.h"
/* PurpleConversation *ggp_confer_find_by_name(PurpleConnection *gc, const gchar *name) {{{ */
-PurpleConversation *ggp_confer_find_by_name(PurpleConnection *gc, const gchar *name)
+PurpleChatConversation *ggp_confer_find_by_name(PurpleConnection *gc, const gchar *name)
{
g_return_val_if_fail(gc != NULL, NULL);
g_return_val_if_fail(name != NULL, NULL);
- return purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, name,
+ return purple_conversations_find_chat_with_account(name,
purple_connection_get_account(gc));
}
/* }}} */
@@ -41,7 +41,7 @@ PurpleConversation *ggp_confer_find_by_name(PurpleConnection *gc, const gchar *n
void ggp_confer_participants_add_uin(PurpleConnection *gc, const gchar *chat_name,
const uin_t uin)
{
- PurpleConversation *conv;
+ PurpleChatConversation *conv;
GGPInfo *info = purple_connection_get_protocol_data(gc);
GGPChat *chat;
GList *l;
@@ -59,8 +59,8 @@ void ggp_confer_participants_add_uin(PurpleConnection *gc, const gchar *chat_nam
str_uin = g_strdup_printf("%lu", (unsigned long int)uin);
conv = ggp_confer_find_by_name(gc, chat_name);
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(conv), str_uin, NULL,
- PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(conv, str_uin, NULL,
+ PURPLE_CHAT_USER_NONE, TRUE);
g_free(str_uin);
}
@@ -85,7 +85,7 @@ void ggp_confer_participants_add(PurpleConnection *gc, const gchar *chat_name,
continue;
for (i = 0; i < count; i++) {
- PurpleConversation *conv;
+ PurpleChatConversation *conv;
if (g_list_find(chat->participants,
GINT_TO_POINTER(recipients[i])) != NULL) {
@@ -97,9 +97,8 @@ void ggp_confer_participants_add(PurpleConnection *gc, const gchar *chat_name,
str_uin = g_strdup_printf("%lu", (unsigned long int)recipients[i]);
conv = ggp_confer_find_by_name(gc, chat_name);
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(conv),
- str_uin, NULL,
- PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(conv, str_uin, NULL,
+ PURPLE_CHAT_USER_NONE, TRUE);
g_free(str_uin);
}
break;
diff --git a/libpurple/protocols/gg/confer.h b/libpurple/protocols/gg/confer.h
index 37e93df128..003b22d77c 100644
--- a/libpurple/protocols/gg/confer.h
+++ b/libpurple/protocols/gg/confer.h
@@ -34,7 +34,7 @@
*
* @return PurpleConversation or NULL if not found.
*/
-PurpleConversation *
+PurpleChatConversation *
ggp_confer_find_by_name(PurpleConnection *gc, const gchar *name);
/**
diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c
index 98087588d5..93fffdba00 100644
--- a/libpurple/protocols/gg/gg.c
+++ b/libpurple/protocols/gg/gg.c
@@ -31,7 +31,7 @@
#include "plugin.h"
#include "version.h"
#include "notify.h"
-#include "blist.h"
+#include "buddylist.h"
#include "accountopt.h"
#include "debug.h"
#include "util.h"
@@ -41,7 +41,7 @@
#include "gg.h"
#include "confer.h"
#include "search.h"
-#include "buddylist.h"
+#include "blist.h"
#include "utils.h"
#include "resolver-purple.h"
#include "account.h"
@@ -273,7 +273,7 @@ static void ggp_rem_deny(PurpleConnection *gc, const char *who)
void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event_msg *ev, gboolean multilogon)
{
GGPInfo *info = purple_connection_get_protocol_data(gc);
- PurpleConversation *conv;
+ PurpleChatConversation *chat;
gchar *from;
gchar *msg;
gchar *tmp;
@@ -415,13 +415,12 @@ void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event_msg *e
purple_debug_warning("gg", "ggp_recv_message_handler: conference multilogon messages are not yet handled\n");
} else if (multilogon) {
PurpleAccount *account = purple_connection_get_account(gc);
- PurpleConversation *conv;
+ PurpleIMConversation *im;
const gchar *who = ggp_uin_to_str(ev->sender); // not really sender
- conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_IM, who, account);
- if (conv == NULL)
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, who);
- purple_conversation_write(conv, purple_account_get_username(account), msg, PURPLE_MESSAGE_SEND, mtime);
+ im = purple_conversations_find_im_with_account(who, account);
+ if (im == NULL)
+ im = purple_im_conversation_new(account, who);
+ purple_conversation_write(PURPLE_CONVERSATION(im), purple_account_get_username(account), msg, PURPLE_MESSAGE_SEND, mtime);
} else if (ev->recipients_count == 0) {
serv_got_im(gc, from, msg, 0, mtime);
} else {
@@ -443,8 +442,8 @@ void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event_msg *e
ev->recipients,
ev->recipients_count);
}
- conv = ggp_confer_find_by_name(gc, chat_name);
- chat_id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv));
+ chat = ggp_confer_find_by_name(gc, chat_name);
+ chat_id = purple_chat_conversation_get_id(chat);
serv_got_chat_in(gc, chat_id,
ggp_buddylist_get_buddy_name(gc, ev->sender),
@@ -459,7 +458,7 @@ static void ggp_typing_notification_handler(PurpleConnection *gc, uin_t uin, int
from = g_strdup_printf("%u", uin);
if (length)
- serv_got_typing(gc, from, 0, PURPLE_TYPING);
+ serv_got_typing(gc, from, 0, PURPLE_IM_TYPING);
else
serv_got_typing_stopped(gc, from);
g_free(from);
@@ -689,7 +688,7 @@ static void ggp_async_login_handler(gpointer _gc, gint fd, PurpleInputCondition
ggp_callback_recv, gc);
purple_connection_update_progress(gc, _("Connected"), 1, 2);
- purple_connection_set_state(gc, PURPLE_CONNECTED);
+ purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED);
ggp_buddylist_send(gc);
ggp_roster_request_update(gc);
@@ -837,7 +836,7 @@ static GList *ggp_blist_node_menu(PurpleBlistNode *node)
PurpleConnection *gc;
GGPInfo *info;
- if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (!PURPLE_IS_BUDDY(node))
return NULL;
account = purple_buddy_get_account((PurpleBuddy *) node);
@@ -1027,7 +1026,7 @@ static int ggp_send_im(PurpleConnection *gc, const char *who, const char *msg,
GData *attribs;
const char *start, *end = NULL, *last;
ggp_buddy_data *buddy_data = ggp_buddy_get_data(
- purple_find_buddy(purple_connection_get_account(gc), who));
+ purple_blist_find_buddy(purple_connection_get_account(gc), who));
if (msg == NULL || *msg == '\0') {
return 0;
@@ -1084,11 +1083,10 @@ static int ggp_send_im(PurpleConnection *gc, const char *who, const char *msg,
}
else if (prepare_result == GGP_IMAGE_PREPARE_TOO_BIG)
{
- PurpleConversation *conv =
- purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_IM, who,
+ PurpleIMConversation *im =
+ purple_conversations_find_im_with_account(who,
purple_connection_get_account(gc));
- purple_conversation_write(conv, "",
+ purple_conversation_write(PURPLE_CONVERSATION(im), "",
_("Image is too large, please try "
"smaller one."), PURPLE_MESSAGE_ERROR,
time(NULL));
@@ -1141,17 +1139,17 @@ static int ggp_send_im(PurpleConnection *gc, const char *who, const char *msg,
return ret;
}
-static unsigned int ggp_send_typing(PurpleConnection *gc, const char *name, PurpleTypingState state)
+static unsigned int ggp_send_typing(PurpleConnection *gc, const char *name, PurpleIMTypingState 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
+ if (state == PURPLE_IM_TYPED) // not supported
return 1;
- if (state == PURPLE_TYPING)
+ if (state == PURPLE_IM_TYPING)
dummy_length = (int)g_random_int();
- else // PURPLE_NOT_TYPING
+ else // PURPLE_IM_NOT_TYPING
dummy_length = 0;
gg_typing_notification(
@@ -1193,7 +1191,7 @@ static void ggp_join_chat(PurpleConnection *gc, GHashTable *data)
GGPChat *chat;
char *chat_name;
GList *l;
- PurpleConversation *conv;
+ PurpleChatConversation *conv;
PurpleAccount *account = purple_connection_get_account(gc);
chat_name = g_hash_table_lookup(data, "name");
@@ -1215,9 +1213,8 @@ static void ggp_join_chat(PurpleConnection *gc, GHashTable *data)
ggp_confer_add_new(gc, chat_name);
conv = serv_got_joined_chat(gc, info->chats_count, chat_name);
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(conv),
- purple_account_get_username(account), NULL,
- PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(conv, purple_account_get_username(account),
+ NULL, PURPLE_CHAT_USER_NONE, TRUE);
}
static char *ggp_get_chat_name(GHashTable *data) {
@@ -1226,7 +1223,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;
+ PurpleChatConversation *conv;
GGPInfo *info = purple_connection_get_protocol_data(gc);
GGPChat *chat = NULL;
GList *l;
@@ -1235,13 +1232,14 @@ static int ggp_chat_send(PurpleConnection *gc, int id, const char *message, Purp
uin_t *uins;
int count = 0;
- if ((conv = purple_find_chat(gc, id)) == NULL)
+ if ((conv = purple_conversations_find_chat(gc, id)) == NULL)
return -EINVAL;
for (l = info->chats; l != NULL; l = l->next) {
chat = l->data;
- if (g_utf8_collate(chat->name, purple_conversation_get_name(conv)) == 0) {
+ if (g_utf8_collate(chat->name, purple_conversation_get_name(
+ PURPLE_CONVERSATION(conv))) == 0) {
break;
}
diff --git a/libpurple/protocols/gg/image.c b/libpurple/protocols/gg/image.c
index 20b26b6be7..f8d3afeb46 100644
--- a/libpurple/protocols/gg/image.c
+++ b/libpurple/protocols/gg/image.c
@@ -290,9 +290,8 @@ void ggp_image_send(PurpleConnection *gc,
purple_imgstore_get_size(image));
purple_imgstore_unref(image);
- conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_IM, pending_image->conv_name,
- purple_connection_get_account(gc));
+ conv = PURPLE_CONVERSATION(purple_conversations_find_im_with_account(
+ pending_image->conv_name, purple_connection_get_account(gc)));
if (conv != NULL)
purple_conversation_write(conv, "", _("Image delivered."),
PURPLE_MESSAGE_NO_LOG | PURPLE_MESSAGE_NOTIFY,
diff --git a/libpurple/protocols/gg/oauth/oauth.c b/libpurple/protocols/gg/oauth/oauth.c
index 3fc3a570c7..7440593e75 100644
--- a/libpurple/protocols/gg/oauth/oauth.c
+++ b/libpurple/protocols/gg/oauth/oauth.c
@@ -26,7 +26,8 @@
#include "oauth.h"
#include "oauth-parameter.h"
-#include <cipher.h>
+#include "ciphers/hmaccipher.h"
+#include "ciphers/sha1hash.h"
char *gg_oauth_static_nonce; /* dla unit testów */
char *gg_oauth_static_timestamp; /* dla unit testów */
@@ -48,15 +49,19 @@ static void gg_oauth_generate_nonce(char *buf, int len)
static gchar *gg_hmac_sha1(const char *key, const char *message)
{
- PurpleCipherContext *context;
+ PurpleCipher *cipher;
+ PurpleHash *hash;
guchar digest[20];
-
- context = purple_cipher_context_new_by_name("hmac", NULL);
- purple_cipher_context_set_option(context, "hash", "sha1");
- purple_cipher_context_set_key(context, (guchar *)key, strlen(key));
- purple_cipher_context_append(context, (guchar *)message, strlen(message));
- purple_cipher_context_digest(context, digest, sizeof(digest));
- purple_cipher_context_destroy(context);
+
+ hash = purple_sha1_hash_new();
+ cipher = purple_hmac_cipher_new(hash);
+
+ purple_cipher_set_key(cipher, (guchar *)key, strlen(key));
+ purple_cipher_append(cipher, (guchar *)message, strlen(message));
+ purple_cipher_digest(cipher, digest, sizeof(digest));
+
+ g_object_unref(cipher);
+ g_object_unref(hash);
return purple_base64_encode(digest, sizeof(digest));
}
diff --git a/libpurple/protocols/gg/pubdir-prpl.c b/libpurple/protocols/gg/pubdir-prpl.c
index 35ecf4b6a6..1065f27a4e 100644
--- a/libpurple/protocols/gg/pubdir-prpl.c
+++ b/libpurple/protocols/gg/pubdir-prpl.c
@@ -389,7 +389,7 @@ static void ggp_pubdir_get_info_prpl_got(PurpleConnection *gc,
g_assert(uin == record->uin);
g_assert(records_count == 1);
- buddy = purple_find_buddy(purple_connection_get_account(gc),
+ buddy = purple_blist_find_buddy(purple_connection_get_account(gc),
ggp_uin_to_str(uin));
if (buddy)
{
@@ -778,8 +778,8 @@ static void ggp_pubdir_search_results_add(PurpleConnection *gc, GList *row,
static void ggp_pubdir_search_results_im(PurpleConnection *gc, GList *row,
gpointer _form)
{
- purple_conversation_present(purple_conversation_new(PURPLE_CONV_TYPE_IM,
- purple_connection_get_account(gc), g_list_nth_data(row, 0)));
+ purple_conversation_present(PURPLE_CONVERSATION(purple_im_conversation_new(
+ purple_connection_get_account(gc), g_list_nth_data(row, 0))));
}
static void ggp_pubdir_search_results_info(PurpleConnection *gc, GList *row,
diff --git a/libpurple/protocols/gg/purplew.c b/libpurple/protocols/gg/purplew.c
index fa96294509..9f134299ae 100644
--- a/libpurple/protocols/gg/purplew.c
+++ b/libpurple/protocols/gg/purplew.c
@@ -103,16 +103,16 @@ GList * ggp_purplew_group_get_buddies(PurpleGroup *group, PurpleAccount *account
gnode = PURPLE_BLIST_NODE(group);
for (cnode = gnode->child; cnode; cnode = cnode->next)
{
- if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode))
+ if (!PURPLE_IS_CONTACT(cnode))
continue;
for (bnode = cnode->child; bnode; bnode = bnode->next)
{
PurpleBuddy *buddy;
- if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode))
+ if (!PURPLE_IS_BUDDY(bnode))
continue;
buddy = PURPLE_BUDDY(bnode);
- if (account == NULL || buddy->account == account)
+ if (account == NULL || purple_buddy_get_account(buddy) == account)
buddies = g_list_append(buddies, buddy);
}
}
@@ -130,7 +130,7 @@ GList * ggp_purplew_account_get_groups(PurpleAccount *account, gboolean exclusiv
GSList *accounts;
gboolean have_specified = FALSE, have_others = FALSE;
- if (!PURPLE_BLIST_NODE_IS_GROUP(bnode))
+ if (!PURPLE_IS_GROUP(bnode))
continue;
group = PURPLE_GROUP(bnode);
diff --git a/libpurple/protocols/gg/roster.c b/libpurple/protocols/gg/roster.c
index 27777014a2..6bf4abdb02 100644
--- a/libpurple/protocols/gg/roster.c
+++ b/libpurple/protocols/gg/roster.c
@@ -361,7 +361,7 @@ void ggp_roster_alias_buddy(PurpleConnection *gc, const char *who,
purple_debug_misc("gg", "ggp_roster_alias_buddy(\"%s\", \"%s\")\n",
who, alias);
- buddy = purple_find_buddy(purple_connection_get_account(gc), who);
+ buddy = purple_blist_find_buddy(purple_connection_get_account(gc), who);
g_return_if_fail(buddy != NULL);
ggp_roster_set_synchronized(gc, buddy, FALSE);
@@ -382,7 +382,7 @@ void ggp_roster_group_buddy(PurpleConnection *gc, const char *who,
"who=\"%s\", group=\"%s\" -> \"%s\")\n",
who, old_group, new_group);
- // purple_find_buddy(..., who) is not accessible at this moment
+ // purple_blist_find_buddy(..., who) is not accessible at this moment
change->type = GGP_ROSTER_CHANGE_CONTACT_UPDATE;
change->data.uin = ggp_str_to_uin(who);
rdata->pending_updates = g_list_append(rdata->pending_updates, change);
@@ -538,7 +538,7 @@ static gboolean ggp_roster_reply_list_read_buddy(PurpleConnection *gc,
}
if (group_name)
{
- group = purple_find_group(group_name);
+ group = purple_blist_find_group(group_name);
if (!group)
{
group = purple_group_new(group_name);
@@ -547,7 +547,7 @@ static gboolean ggp_roster_reply_list_read_buddy(PurpleConnection *gc,
}
// add buddy, if doesn't exists
- buddy = purple_find_buddy(account, ggp_uin_to_str(uin));
+ buddy = purple_blist_find_buddy(account, ggp_uin_to_str(uin));
g_hash_table_remove(remove_buddies, GINT_TO_POINTER(uin));
if (!buddy)
{
@@ -587,7 +587,7 @@ static gboolean ggp_roster_reply_list_read_buddy(PurpleConnection *gc,
purple_buddy_get_alias(buddy), alias,
currentGroup, group, group_name);
if (alias_changed)
- purple_blist_alias_buddy(buddy, alias);
+ purple_buddy_set_local_alias(buddy, alias);
if (currentGroup != group)
purple_blist_add_buddy(buddy, NULL, group, NULL);
@@ -666,7 +666,7 @@ static void ggp_roster_reply_list(PurpleConnection *gc, uint32_t version,
// we will:
// - remove synchronized ones, if not found in list at server
// - upload not synchronized ones
- local_buddies = purple_find_buddies(account, NULL);
+ local_buddies = purple_blist_find_buddies(account, NULL);
remove_buddies = g_hash_table_new(g_direct_hash, g_direct_equal);
while (local_buddies)
{
@@ -733,7 +733,7 @@ static void ggp_roster_reply_list(PurpleConnection *gc, uint32_t version,
{
PurpleGroup *group = it->data;
it = g_list_next(it);
- if (purple_blist_get_group_size(group, TRUE) != 0)
+ if (purple_counting_node_get_total_size(PURPLE_COUNTING_NODE(group)) != 0)
continue;
purple_debug_info("gg", "ggp_roster_reply_list: "
"removing group %s\n", purple_group_get_name(group));
@@ -829,7 +829,7 @@ static gboolean ggp_roster_send_update_contact_update(PurpleConnection *gc,
g_return_val_if_fail(change->type == GGP_ROSTER_CHANGE_CONTACT_UPDATE,
FALSE);
- buddy = purple_find_buddy(account, ggp_uin_to_str(uin));
+ buddy = purple_blist_find_buddy(account, ggp_uin_to_str(uin));
if (!buddy)
return TRUE;
buddy_node = g_hash_table_lookup(content->contact_nodes,
@@ -897,7 +897,7 @@ static gboolean ggp_roster_send_update_contact_remove(PurpleConnection *gc,
g_return_val_if_fail(change->type == GGP_ROSTER_CHANGE_CONTACT_REMOVE,
FALSE);
- buddy = purple_find_buddy(account, ggp_uin_to_str(uin));
+ buddy = purple_blist_find_buddy(account, ggp_uin_to_str(uin));
if (buddy)
{
purple_debug_info("gg", "ggp_roster_send_update_contact_remove:"
@@ -940,7 +940,7 @@ static gboolean ggp_roster_send_update_group_rename(PurpleConnection *gc,
{
PurpleGroup *group;
GList *group_buddies;
- group = purple_find_group(new_name);
+ group = purple_blist_find_group(new_name);
if (!group)
return TRUE;
purple_debug_info("gg", "ggp_roster_send_update_group_rename: "
@@ -1058,7 +1058,7 @@ static void ggp_roster_reply_ack(PurpleConnection *gc, uint32_t version)
if (change->type != GGP_ROSTER_CHANGE_CONTACT_UPDATE)
continue;
- buddy = purple_find_buddy(account,
+ buddy = purple_blist_find_buddy(account,
ggp_uin_to_str(change->data.uin));
if (buddy)
ggp_roster_set_synchronized(gc, buddy, TRUE);
@@ -1076,7 +1076,7 @@ static void ggp_roster_reply_ack(PurpleConnection *gc, uint32_t version)
if (change->type != GGP_ROSTER_CHANGE_CONTACT_UPDATE)
continue;
- buddy = purple_find_buddy(account,
+ buddy = purple_blist_find_buddy(account,
ggp_uin_to_str(change->data.uin));
if (buddy && ggp_roster_is_synchronized(buddy))
ggp_roster_set_synchronized(gc, buddy, FALSE);
diff --git a/libpurple/protocols/gg/status.c b/libpurple/protocols/gg/status.c
index afedd2b70d..af5ead7800 100644
--- a/libpurple/protocols/gg/status.c
+++ b/libpurple/protocols/gg/status.c
@@ -90,32 +90,32 @@ GList * ggp_status_types(PurpleAccount *account)
types = g_list_append(types, purple_status_type_new_with_attrs(
PURPLE_STATUS_AVAILABLE, NULL, NULL,
TRUE, TRUE, FALSE, "message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL));
+ purple_g_value_new(G_TYPE_STRING), NULL));
types = g_list_append(types, purple_status_type_new_with_attrs(
PURPLE_STATUS_AVAILABLE, "freeforchat", _("Chatty"),
TRUE, TRUE, FALSE, "message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL));
+ purple_g_value_new(G_TYPE_STRING), NULL));
types = g_list_append(types, purple_status_type_new_with_attrs(
PURPLE_STATUS_AWAY, NULL, NULL,
TRUE, TRUE, FALSE, "message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL));
+ purple_g_value_new(G_TYPE_STRING), NULL));
types = g_list_append(types, purple_status_type_new_with_attrs(
PURPLE_STATUS_UNAVAILABLE, NULL, NULL,
TRUE, TRUE, FALSE, "message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL));
+ purple_g_value_new(G_TYPE_STRING), NULL));
types = g_list_append(types, purple_status_type_new_with_attrs(
PURPLE_STATUS_INVISIBLE, NULL, NULL,
TRUE, TRUE, FALSE, "message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL));
+ purple_g_value_new(G_TYPE_STRING), NULL));
types = g_list_append(types, purple_status_type_new_with_attrs(
PURPLE_STATUS_OFFLINE, NULL, NULL,
TRUE, TRUE, FALSE, "message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL));
+ purple_g_value_new(G_TYPE_STRING), NULL));
return types;
}
@@ -403,7 +403,7 @@ void ggp_status_got_others_buddy(PurpleConnection *gc, uin_t uin, int status,
const char *descr)
{
PurpleAccount *account = purple_connection_get_account(gc);
- PurpleBuddy *buddy = purple_find_buddy(account, ggp_uin_to_str(uin));
+ PurpleBuddy *buddy = purple_blist_find_buddy(account, ggp_uin_to_str(uin));
const gchar *purple_status = ggp_status_to_purplestatus(status);
gchar *status_message = NULL;
gboolean is_own;
diff --git a/libpurple/protocols/irc/cmds.c b/libpurple/protocols/irc/cmds.c
index 5a704a243f..be88b8519f 100644
--- a/libpurple/protocols/irc/cmds.c
+++ b/libpurple/protocols/irc/cmds.c
@@ -34,17 +34,14 @@ static void irc_do_mode(struct irc_conn *irc, const char *target, const char *si
int irc_cmd_default(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
{
- PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, target, irc->account);
+ PurpleConversation *convo = purple_conversations_find_with_account(target, irc->account);
char *buf;
if (!convo)
return 1;
buf = g_strdup_printf(_("Unknown command: %s"), cmd);
- if (purple_conversation_get_type(convo) == PURPLE_CONV_TYPE_IM)
- purple_conv_im_write(PURPLE_CONV_IM(convo), "", buf, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
- else
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "", buf, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
+ purple_conversation_write_message(convo, "", buf, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
g_free(buf);
return 1;
@@ -132,19 +129,19 @@ int irc_cmd_ctcp_action(struct irc_conn *irc, const char *cmd, const char *targe
g_free(newargs[1]);
g_free(newargs);
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, target, irc->account);
+ convo = purple_conversations_find_with_account(target, irc->account);
if (convo) {
escaped = g_markup_escape_text(args[0], -1);
action = g_strdup_printf("/me %s", escaped);
g_free(escaped);
if (action[strlen(action) - 1] == '\n')
action[strlen(action) - 1] = '\0';
- if (purple_conversation_get_type(convo) == PURPLE_CONV_TYPE_CHAT)
- serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)),
+ if (PURPLE_IS_CHAT_CONVERSATION(convo))
+ serv_got_chat_in(gc, purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(convo)),
purple_connection_get_display_name(gc),
PURPLE_MESSAGE_SEND, action, time(NULL));
else
- purple_conv_im_write(PURPLE_CONV_IM(convo), purple_connection_get_display_name(gc),
+ purple_conversation_write_message(convo, purple_connection_get_display_name(gc),
action, PURPLE_MESSAGE_SEND, time(NULL));
g_free(action);
}
@@ -200,13 +197,11 @@ int irc_cmd_join(struct irc_conn *irc, const char *cmd, const char *target, cons
int irc_cmd_kick(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
{
char *buf;
- PurpleConversation *convo;
if (!args || !args[0])
return 0;
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, target, irc->account);
- if (!convo)
+ if (!purple_conversations_find_chat_with_account(target, irc->account))
return 0;
if (args[1])
@@ -446,20 +441,21 @@ int irc_cmd_quote(struct irc_conn *irc, const char *cmd, const char *target, con
int irc_cmd_query(struct irc_conn *irc, const char *cmd, const char *target, const char **args)
{
- PurpleConversation *convo;
+ PurpleIMConversation *im;
PurpleConnection *gc;
if (!args || !args[0])
return 0;
- convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, irc->account, args[0]);
- purple_conversation_present(convo);
+ im = purple_im_conversation_new(irc->account, args[0]);
+ purple_conversation_present(PURPLE_CONVERSATION(im));
if (args[1]) {
gc = purple_account_get_connection(irc->account);
irc_cmd_privmsg(irc, cmd, target, args);
- purple_conv_im_write(PURPLE_CONV_IM(convo), purple_connection_get_display_name(gc),
- args[1], PURPLE_MESSAGE_SEND, time(NULL));
+ purple_conversation_write_message(PURPLE_CONVERSATION(im),
+ purple_connection_get_display_name(gc), args[1],
+ PURPLE_MESSAGE_SEND, time(NULL));
}
return 0;
@@ -517,17 +513,17 @@ int irc_cmd_topic(struct irc_conn *irc, const char *cmd, const char *target, con
{
char *buf;
const char *topic;
- PurpleConversation *convo;
+ PurpleChatConversation *chat;
if (!args)
return 0;
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, target, irc->account);
- if (!convo)
+ chat = purple_conversations_find_chat_with_account(target, irc->account);
+ if (!chat)
return 0;
if (!args[0]) {
- topic = purple_conv_chat_get_topic (PURPLE_CONV_CHAT(convo));
+ topic = purple_chat_conversation_get_topic (chat);
if (topic) {
char *tmp, *tmp2;
@@ -538,7 +534,8 @@ int irc_cmd_topic(struct irc_conn *irc, const char *cmd, const char *target, con
g_free(tmp2);
} else
buf = g_strdup(_("No topic is set"));
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), target, buf, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), target, buf,
+ PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
g_free(buf);
return 0;
diff --git a/libpurple/protocols/irc/irc.c b/libpurple/protocols/irc/irc.c
index dd287a0b6b..3f56dde06f 100644
--- a/libpurple/protocols/irc/irc.c
+++ b/libpurple/protocols/irc/irc.c
@@ -26,7 +26,7 @@
#include "internal.h"
#include "accountopt.h"
-#include "blist.h"
+#include "buddylist.h"
#include "conversation.h"
#include "debug.h"
#include "notify.h"
@@ -111,8 +111,9 @@ irc_send_cb(gpointer data, gint source, PurpleInputCondition cond)
{
struct irc_conn *irc = data;
int ret, writelen;
+ const gchar *buffer = NULL;
- writelen = purple_circ_buffer_get_max_read(irc->outbuf);
+ writelen = purple_circular_buffer_get_max_read(irc->outbuf);
if (writelen == 0) {
purple_input_remove(irc->writeh);
@@ -120,7 +121,9 @@ irc_send_cb(gpointer data, gint source, PurpleInputCondition cond)
return;
}
- ret = do_send(irc, irc->outbuf->outptr, writelen);
+ buffer = purple_circular_buffer_get_output(irc->outbuf);
+
+ ret = do_send(irc, buffer, writelen);
if (ret < 0 && errno == EAGAIN)
return;
@@ -134,7 +137,7 @@ irc_send_cb(gpointer data, gint source, PurpleInputCondition cond)
return;
}
- purple_circ_buffer_mark_read(irc->outbuf, ret);
+ purple_circular_buffer_mark_read(irc->outbuf, ret);
#if 0
/* We *could* try to write more if we wrote it all */
@@ -183,7 +186,7 @@ int irc_send_len(struct irc_conn *irc, const char *buf, int buflen)
irc->writeh = purple_input_add(
irc->gsc ? irc->gsc->fd : irc->fd,
PURPLE_INPUT_WRITE, irc_send_cb, irc);
- purple_circ_buffer_append(irc->outbuf, tosend + ret,
+ purple_circular_buffer_append(irc->outbuf, tosend + ret,
buflen - ret);
}
g_free(tosend);
@@ -271,7 +274,7 @@ static GList *irc_status_types(PurpleAccount *account)
type = purple_status_type_new_with_attrs(
PURPLE_STATUS_AWAY, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_append(types, type);
@@ -332,7 +335,7 @@ static void irc_login(PurpleAccount *account)
const char *username = purple_account_get_username(account);
gc = purple_account_get_connection(account);
- purple_connection_set_flags(gc, PURPLE_CONNECTION_NO_NEWLINES);
+ purple_connection_set_flags(gc, PURPLE_CONNECTION_FLAG_NO_NEWLINES);
if (strpbrk(username, " \t\v\r\n") != NULL) {
purple_connection_error (gc,
@@ -345,7 +348,7 @@ static void irc_login(PurpleAccount *account)
purple_connection_set_protocol_data(gc, irc);
irc->fd = -1;
irc->account = account;
- irc->outbuf = purple_circ_buffer_new(512);
+ irc->outbuf = purple_circular_buffer_new(512);
userparts = g_strsplit(username, "@", 2);
purple_connection_set_display_name(gc, userparts[0]);
@@ -533,7 +536,7 @@ static void irc_close(PurpleConnection *gc)
if (irc->writeh)
purple_input_remove(irc->writeh);
- purple_circ_buffer_destroy(irc->outbuf);
+ g_object_unref(G_OBJECT(irc->outbuf));
g_free(irc->mode_chars);
g_free(irc->reqnick);
@@ -758,7 +761,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 = purple_connection_get_protocol_data(gc);
- PurpleConversation *convo = purple_find_chat(gc, id);
+ PurpleConversation *convo = PURPLE_CONVERSATION(purple_conversations_find_chat(gc, id));
const char *args[2];
if (!convo) {
@@ -774,7 +777,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 = purple_connection_get_protocol_data(gc);
- PurpleConversation *convo = purple_find_chat(gc, id);
+ PurpleConversation *convo = PURPLE_CONVERSATION(purple_conversations_find_chat(gc, id));
const char *args[2];
if (!convo)
@@ -789,7 +792,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 = purple_connection_get_protocol_data(gc);
- PurpleConversation *convo = purple_find_chat(gc, id);
+ PurpleConversation *convo = PURPLE_CONVERSATION(purple_conversations_find_chat(gc, id));
const char *args[2];
char *tmp;
@@ -843,7 +846,8 @@ static void irc_chat_set_topic(PurpleConnection *gc, int id, const char *topic)
struct irc_conn *irc;
irc = purple_connection_get_protocol_data(gc);
- name = purple_conversation_get_name(purple_find_chat(gc, id));
+ name = purple_conversation_get_name(PURPLE_CONVERSATION(
+ purple_conversations_find_chat(gc, id)));
if (name == NULL)
return;
@@ -990,13 +994,13 @@ static PurplePluginProtocolInfo prpl_info =
static gboolean load_plugin (PurplePlugin *plugin) {
purple_signal_register(plugin, "irc-sending-text",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION),
- purple_value_new_outgoing(PURPLE_TYPE_STRING));
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ PURPLE_TYPE_CONNECTION,
+ G_TYPE_POINTER); /* pointer to a string */
purple_signal_register(plugin, "irc-receiving-text",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION),
- purple_value_new_outgoing(PURPLE_TYPE_STRING));
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ PURPLE_TYPE_CONNECTION,
+ G_TYPE_POINTER); /* pointer to a string */
return TRUE;
}
diff --git a/libpurple/protocols/irc/irc.h b/libpurple/protocols/irc/irc.h
index 3f25002473..43780b7cb0 100644
--- a/libpurple/protocols/irc/irc.h
+++ b/libpurple/protocols/irc/irc.h
@@ -29,7 +29,7 @@
#include <sasl/sasl.h>
#endif
-#include "circbuffer.h"
+#include "circularbuffer.h"
#include "ft.h"
#include "roomlist.h"
#include "sslconn.h"
@@ -89,7 +89,7 @@ struct irc_conn {
gboolean quitting;
- PurpleCircBuffer *outbuf;
+ PurpleCircularBuffer *outbuf;
guint writeh;
time_t recv_time;
diff --git a/libpurple/protocols/irc/msgs.c b/libpurple/protocols/irc/msgs.c
index d6e11cb51a..d81a1564a1 100644
--- a/libpurple/protocols/irc/msgs.c
+++ b/libpurple/protocols/irc/msgs.c
@@ -23,7 +23,7 @@
#include "internal.h"
#include "conversation.h"
-#include "blist.h"
+#include "buddylist.h"
#include "notify.h"
#include "util.h"
#include "debug.h"
@@ -38,7 +38,7 @@
static char *irc_mask_nick(const char *mask);
static char *irc_mask_userhost(const char *mask);
-static void irc_chat_remove_buddy(PurpleConversation *convo, char *data[2]);
+static void irc_chat_remove_buddy(PurpleChatConversation *chat, char *data[2]);
static void irc_buddy_status(char *name, struct irc_buddy *ib, struct irc_conn *irc);
static void irc_connected(struct irc_conn *irc, const char *nick);
@@ -68,7 +68,7 @@ static char *irc_mask_userhost(const char *mask)
return g_strdup(strchr(mask, '!') + 1);
}
-static void irc_chat_remove_buddy(PurpleConversation *convo, char *data[2])
+static void irc_chat_remove_buddy(PurpleChatConversation *chat, char *data[2])
{
char *message, *stripped;
@@ -76,8 +76,8 @@ static void irc_chat_remove_buddy(PurpleConversation *convo, char *data[2])
message = g_strdup_printf("quit: %s", stripped);
g_free(stripped);
- if (purple_conv_chat_find_user(PURPLE_CONV_CHAT(convo), data[0]))
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), data[0], message);
+ if (purple_chat_conversation_has_user(chat, data[0]))
+ purple_chat_conversation_remove_user(chat, data[0], message);
g_free(message);
}
@@ -94,18 +94,18 @@ static void irc_connected(struct irc_conn *irc, const char *nick)
return;
purple_connection_set_display_name(gc, nick);
- purple_connection_set_state(gc, PURPLE_CONNECTED);
+ purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED);
account = purple_connection_get_account(gc);
/* If we're away then set our away message */
status = purple_account_get_active_status(irc->account);
- if (purple_status_type_get_primitive(purple_status_get_type(status)) != PURPLE_STATUS_AVAILABLE) {
+ if (purple_status_type_get_primitive(purple_status_get_status_type(status)) != PURPLE_STATUS_AVAILABLE) {
PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
prpl_info->set_status(irc->account, status);
}
/* this used to be in the core, but it's not now */
- for (buddies = purple_find_buddies(account, NULL); buddies;
+ for (buddies = purple_blist_find_buddies(account, NULL); buddies;
buddies = g_slist_delete_link(buddies, buddies))
{
PurpleBuddy *b = buddies->data;
@@ -161,9 +161,7 @@ void irc_msg_default(struct irc_conn *irc, const char *name, const char *from, c
g_free(tmp);
/* Check for an existing conversation */
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY,
- convname,
- irc->account);
+ convo = purple_conversations_find_with_account(convname, irc->account);
g_free(convname);
if (convo == NULL) {
@@ -267,13 +265,12 @@ void irc_msg_badmode(struct irc_conn *irc, const char *name, const char *from, c
void irc_msg_ban(struct irc_conn *irc, const char *name, const char *from, char **args)
{
- PurpleConversation *convo;
+ PurpleChatConversation *chat;
if (!args || !args[0] || !args[1])
return;
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- args[1], irc->account);
+ chat = purple_conversations_find_chat_with_account(args[1], irc->account);
if (!strcmp(name, "367")) {
char *msg = NULL;
@@ -291,8 +288,8 @@ void irc_msg_ban(struct irc_conn *irc, const char *name, const char *from, char
} else {
msg = g_strdup_printf(_("Ban on %s"), args[2]);
}
- if (convo) {
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "", msg,
+ if (chat) {
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), "", msg,
PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG,
time(NULL));
} else {
@@ -300,10 +297,10 @@ void irc_msg_ban(struct irc_conn *irc, const char *name, const char *from, char
}
g_free(msg);
} else if (!strcmp(name, "368")) {
- if (!convo)
+ if (!chat)
return;
/* End of ban list */
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "",
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), "",
_("End of ban list"),
PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG,
time(NULL));
@@ -325,20 +322,20 @@ void irc_msg_banned(struct irc_conn *irc, const char *name, const char *from, ch
void irc_msg_banfull(struct irc_conn *irc, const char *name, const char *from, char **args)
{
- PurpleConversation *convo;
+ PurpleChatConversation *chat;
char *buf, *nick;
if (!args || !args[0] || !args[1] || !args[2])
return;
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[1], irc->account);
- if (!convo)
+ chat = purple_conversations_find_chat_with_account(args[1], irc->account);
+ if (!chat)
return;
nick = g_markup_escape_text(args[2], -1);
buf = g_strdup_printf(_("Cannot ban %s: banlist is full"), nick);
g_free(nick);
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "", buf,
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), "", buf,
PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG,
time(NULL));
g_free(buf);
@@ -346,19 +343,19 @@ void irc_msg_banfull(struct irc_conn *irc, const char *name, const char *from, c
void irc_msg_chanmode(struct irc_conn *irc, const char *name, const char *from, char **args)
{
- PurpleConversation *convo;
+ PurpleChatConversation *chat;
char *buf, *escaped;
if (!args || !args[1] || !args[2])
return;
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[1], irc->account);
- if (!convo) /* XXX punt on channels we are not in for now */
+ chat = purple_conversations_find_chat_with_account(args[1], irc->account);
+ if (!chat) /* XXX punt on channels we are not in for now */
return;
escaped = (args[3] != NULL) ? g_markup_escape_text(args[3], -1) : NULL;
buf = g_strdup_printf("mode for %s: %s %s", args[1], args[2], escaped ? escaped : "");
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "", buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), "", buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(escaped);
g_free(buf);
@@ -476,14 +473,12 @@ void irc_msg_endwhois(struct irc_conn *irc, const char *name, const char *from,
void irc_msg_who(struct irc_conn *irc, const char *name, const char *from, char **args)
{
if (!strcmp(name, "352")) {
- PurpleConversation *conv;
- PurpleConvChat *chat;
- PurpleConvChatBuddy *cb;
+ PurpleChatConversation *chat;
+ PurpleChatUser *cb;
char *cur, *userhost, *realname;
- PurpleConvChatBuddyFlags flags;
- GList *keys = NULL, *values = NULL;
+ PurpleChatUserFlags flags;
if (!args || !args[0] || !args[1] || !args[2] || !args[3]
|| !args[4] || !args[5] || !args[6] || !args[7]) {
@@ -492,19 +487,17 @@ void irc_msg_who(struct irc_conn *irc, const char *name, const char *from, char
return;
}
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[1], irc->account);
- if (!conv) {
+ chat = purple_conversations_find_chat_with_account(args[1], irc->account);
+ if (!chat) {
purple_debug(PURPLE_DEBUG_ERROR, "irc","Got a WHO response for %s, which doesn't exist\n", args[1]);
return;
}
- cb = purple_conv_chat_cb_find(PURPLE_CONV_CHAT(conv), args[5]);
+ cb = purple_chat_conversation_find_user(chat, args[5]);
if (!cb) {
purple_debug(PURPLE_DEBUG_ERROR, "irc", "Got a WHO response for %s who isn't a buddy.\n", args[5]);
return;
}
-
- chat = PURPLE_CONV_CHAT(conv);
userhost = g_strdup_printf("%s@%s", args[2], args[3]);
@@ -518,30 +511,19 @@ void irc_msg_who(struct irc_conn *irc, const char *name, const char *from, char
}
realname = g_strdup(cur);
- keys = g_list_prepend(keys, "userhost");
- values = g_list_prepend(values, userhost);
-
- keys = g_list_prepend(keys, "realname");
- values = g_list_prepend(values, realname);
-
- purple_conv_chat_cb_set_attributes(chat, cb, keys, values);
-
- g_list_free(keys);
- g_list_free(values);
+ g_object_set_data_full(G_OBJECT(cb), "userhost", userhost, (GDestroyNotify)g_free);
+ g_object_set_data_full(G_OBJECT(cb), "realname", realname, (GDestroyNotify)g_free);
- g_free(userhost);
- g_free(realname);
-
- flags = purple_conv_chat_cb_get_flags(cb);
+ flags = purple_chat_user_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, 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, purple_conv_chat_cb_get_name(cb), flags & ~PURPLE_CBFLAGS_AWAY);
+ if (args[6][0] == 'G' && !(flags & PURPLE_CHAT_USER_AWAY)) {
+ purple_chat_user_set_flags(cb, flags | PURPLE_CHAT_USER_AWAY);
+ } else if(args[6][0] == 'H' && (flags & PURPLE_CHAT_USER_AWAY)) {
+ purple_chat_user_set_flags(cb, flags & ~PURPLE_CHAT_USER_AWAY);
}
}
}
@@ -588,7 +570,7 @@ void irc_msg_list(struct irc_conn *irc, const char *name, const char *from, char
void irc_msg_topic(struct irc_conn *irc, const char *name, const char *from, char **args)
{
char *chan, *topic, *msg, *nick, *tmp, *tmp2;
- PurpleConversation *convo;
+ PurpleChatConversation *chat;
if (!strcmp(name, "topic")) {
if (!args[0] || !args[1])
@@ -602,8 +584,8 @@ void irc_msg_topic(struct irc_conn *irc, const char *name, const char *from, cha
topic = irc_mirc2txt (args[2]);
}
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, chan, irc->account);
- if (!convo) {
+ chat = purple_conversations_find_chat_with_account(chan, irc->account);
+ if (!chat) {
purple_debug(PURPLE_DEBUG_ERROR, "irc", "Got a topic for %s, which doesn't exist\n", chan);
g_free(topic);
return;
@@ -614,28 +596,30 @@ void irc_msg_topic(struct irc_conn *irc, const char *name, const char *from, cha
tmp2 = purple_markup_linkify(tmp);
g_free(tmp);
if (!strcmp(name, "topic")) {
- const char *current_topic = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(convo));
+ const char *current_topic = purple_chat_conversation_get_topic(chat);
if (!(current_topic != NULL && strcmp(tmp2, current_topic) == 0))
{
char *nick_esc;
nick = irc_mask_nick(from);
nick_esc = g_markup_escape_text(nick, -1);
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), nick, topic);
+ purple_chat_conversation_set_topic(chat, nick, topic);
if (*tmp2)
msg = g_strdup_printf(_("%s has changed the topic to: %s"), nick_esc, tmp2);
else
msg = g_strdup_printf(_("%s has cleared the topic."), nick_esc);
g_free(nick_esc);
g_free(nick);
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), from, msg, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), from,
+ msg, PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(msg);
}
} else {
char *chan_esc = g_markup_escape_text(chan, -1);
msg = g_strdup_printf(_("The topic for %s is: %s"), chan_esc, tmp2);
g_free(chan_esc);
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), NULL, topic);
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "", msg, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_chat_conversation_set_topic(chat, NULL, topic);
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), "", msg,
+ PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(msg);
}
g_free(tmp2);
@@ -644,7 +628,7 @@ void irc_msg_topic(struct irc_conn *irc, const char *name, const char *from, cha
void irc_msg_topicinfo(struct irc_conn *irc, const char *name, const char *from, char **args)
{
- PurpleConversation *convo;
+ PurpleChatConversation *chat;
struct tm *tm;
time_t t;
char *msg, *timestamp, *datestamp;
@@ -652,8 +636,8 @@ void irc_msg_topicinfo(struct irc_conn *irc, const char *name, const char *from,
if (!args || !args[1] || !args[2] || !args[3])
return;
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[1], irc->account);
- if (!convo) {
+ chat = purple_conversations_find_chat_with_account(args[1], irc->account);
+ if (!chat) {
purple_debug(PURPLE_DEBUG_ERROR, "irc", "Got topic info for %s, which doesn't exist\n", args[1]);
return;
}
@@ -668,7 +652,8 @@ void irc_msg_topicinfo(struct irc_conn *irc, const char *name, const char *from,
timestamp = g_strdup(purple_time_format(tm));
datestamp = g_strdup(purple_date_format_short(tm));
msg = g_strdup_printf(_("Topic for %s set by %s at %s on %s"), args[1], args[2], timestamp, datestamp);
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "", msg, PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LINKIFY, time(NULL));
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), "", msg,
+ PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LINKIFY, time(NULL));
g_free(timestamp);
g_free(datestamp);
g_free(msg);
@@ -693,7 +678,7 @@ void irc_msg_names(struct irc_conn *irc, const char *name, const char *from, cha
PurpleConversation *convo;
if (!strcmp(name, "366")) {
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, args[1], irc->account);
+ convo = purple_conversations_find_with_account(args[1], irc->account);
if (!convo) {
purple_debug(PURPLE_DEBUG_ERROR, "irc", "Got a NAMES list for %s, which doesn't exist\n", args[1]);
g_string_free(irc->names, TRUE);
@@ -703,35 +688,32 @@ void irc_msg_names(struct irc_conn *irc, const char *name, const char *from, cha
names = cur = g_string_free(irc->names, FALSE);
irc->names = NULL;
- if (purple_conversation_get_data(convo, IRC_NAMES_FLAG)) {
+ if (g_object_get_data(G_OBJECT(convo), IRC_NAMES_FLAG)) {
msg = g_strdup_printf(_("Users on %s: %s"), args[1], names ? names : "");
- if (purple_conversation_get_type(convo) == PURPLE_CONV_TYPE_CHAT)
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "", msg, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
- else
- purple_conv_im_write(PURPLE_CONV_IM(convo), "", msg, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
+ purple_conversation_write_message(convo, "", msg, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
g_free(msg);
} else if (cur != NULL) {
GList *users = NULL;
GList *flags = NULL;
while (*cur) {
- PurpleConvChatBuddyFlags f = PURPLE_CBFLAGS_NONE;
+ PurpleChatUserFlags f = PURPLE_CHAT_USER_NONE;
end = strchr(cur, ' ');
if (!end)
end = cur + strlen(cur);
if (*cur == '@') {
- f = PURPLE_CBFLAGS_OP;
+ f = PURPLE_CHAT_USER_OP;
cur++;
} else if (*cur == '%') {
- f = PURPLE_CBFLAGS_HALFOP;
+ f = PURPLE_CHAT_USER_HALFOP;
cur++;
} else if(*cur == '+') {
- f = PURPLE_CBFLAGS_VOICE;
+ f = PURPLE_CHAT_USER_VOICE;
cur++;
} else if(irc->mode_chars
&& strchr(irc->mode_chars, *cur)) {
if (*cur == '~')
- f = PURPLE_CBFLAGS_FOUNDER;
+ f = PURPLE_CHAT_USER_FOUNDER;
cur++;
}
tmp = g_strndup(cur, end - cur);
@@ -745,7 +727,7 @@ void irc_msg_names(struct irc_conn *irc, const char *name, const char *from, cha
if (users != NULL) {
GList *l;
- purple_conv_chat_add_users(PURPLE_CONV_CHAT(convo), users, NULL, flags, FALSE);
+ purple_chat_conversation_add_users(PURPLE_CHAT_CONVERSATION(convo), users, NULL, flags, FALSE);
for (l = users; l != NULL; l = l->next)
g_free(l->data);
@@ -754,7 +736,7 @@ void irc_msg_names(struct irc_conn *irc, const char *name, const char *from, cha
g_list_free(flags);
}
- purple_conversation_set_data(convo, IRC_NAMES_FLAG,
+ g_object_set_data(G_OBJECT(convo), IRC_NAMES_FLAG,
GINT_TO_POINTER(TRUE));
}
g_free(names);
@@ -837,14 +819,12 @@ void irc_msg_nonick(struct irc_conn *irc, const char *name, const char *from, ch
PurpleConnection *gc;
PurpleConversation *convo;
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, args[1], irc->account);
+ convo = purple_conversations_find_with_account(args[1], irc->account);
if (convo) {
- if (purple_conversation_get_type(convo) == PURPLE_CONV_TYPE_CHAT) /* does this happen? */
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), args[1], _("no such channel"),
- PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
- else
- purple_conv_im_write(PURPLE_CONV_IM(convo), args[1], _("User is not logged in"),
- PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
+ purple_conversation_write_message(convo, args[1],
+ PURPLE_IS_IM_CONVERSATION(convo) ? _("User is not logged in") : _("no such channel"),
+ PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
+
} else {
if ((gc = purple_account_get_connection(irc->account)) == NULL)
return;
@@ -860,11 +840,12 @@ void irc_msg_nonick(struct irc_conn *irc, const char *name, const char *from, ch
void irc_msg_nosend(struct irc_conn *irc, const char *name, const char *from, char **args)
{
PurpleConnection *gc;
- PurpleConversation *convo;
+ PurpleChatConversation *chat;
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[1], irc->account);
- if (convo) {
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), args[1], args[2], PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
+ chat = purple_conversations_find_chat_with_account(args[1], irc->account);
+ if (chat) {
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), args[1], args[2],
+ PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
} else {
if ((gc = purple_account_get_connection(irc->account)) == NULL)
return;
@@ -874,28 +855,29 @@ void irc_msg_nosend(struct irc_conn *irc, const char *name, const char *from, ch
void irc_msg_notinchan(struct irc_conn *irc, const char *name, const char *from, char **args)
{
- PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[1], irc->account);
+ PurpleChatConversation *chat = purple_conversations_find_chat_with_account(args[1], irc->account);
purple_debug(PURPLE_DEBUG_INFO, "irc", "We're apparently not in %s, but tried to use it\n", args[1]);
- if (convo) {
- /*g_slist_remove(irc->gc->buddy_chats, convo);
- purple_conversation_set_account(convo, NULL);*/
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), args[1], args[2], PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
+ if (chat) {
+ /*g_slist_remove(irc->gc->buddy_chats, chat);
+ purple_conversation_set_account(chat, NULL);*/
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), args[1], args[2],
+ PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
}
}
void irc_msg_notop(struct irc_conn *irc, const char *name, const char *from, char **args)
{
- PurpleConversation *convo;
+ PurpleChatConversation *chat;
if (!args || !args[1] || !args[2])
return;
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[1], irc->account);
- if (!convo)
+ chat = purple_conversations_find_chat_with_account(args[1], irc->account);
+ if (!chat)
return;
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "", args[2], PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), "", args[2], PURPLE_MESSAGE_SYSTEM, time(NULL));
}
void irc_msg_invite(struct irc_conn *irc, const char *name, const char *from, char **args)
@@ -957,7 +939,7 @@ void irc_msg_ison(struct irc_conn *irc, const char *name, const char *from, char
static void irc_buddy_status(char *name, struct irc_buddy *ib, struct irc_conn *irc)
{
PurpleConnection *gc = purple_account_get_connection(irc->account);
- PurpleBuddy *buddy = purple_find_buddy(irc->account, name);
+ PurpleBuddy *buddy = purple_blist_find_buddy(irc->account, name);
if (!gc || !buddy)
return;
@@ -974,9 +956,8 @@ static void irc_buddy_status(char *name, struct irc_buddy *ib, struct irc_conn *
void irc_msg_join(struct irc_conn *irc, const char *name, const char *from, char **args)
{
PurpleConnection *gc = purple_account_get_connection(irc->account);
- PurpleConversation *convo;
- PurpleConvChat *chat;
- PurpleConvChatBuddy *cb;
+ PurpleChatConversation *chat;
+ PurpleChatUser *cb;
char *nick = irc_mask_nick(from), *userhost, *buf;
struct irc_buddy *ib;
@@ -991,15 +972,13 @@ void irc_msg_join(struct irc_conn *irc, const char *name, const char *from, char
/* We are joining a channel for the first time */
serv_got_joined_chat(gc, id++, args[0]);
g_free(nick);
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- args[0],
- irc->account);
+ chat = purple_conversations_find_chat_with_account(args[0], irc->account);
- if (convo == NULL) {
+ if (chat == NULL) {
purple_debug_error("irc", "tried to join %s but couldn't\n", args[0]);
return;
}
- purple_conversation_set_data(convo, IRC_NAMES_FLAG,
+ g_object_set_data(G_OBJECT(chat), IRC_NAMES_FLAG,
GINT_TO_POINTER(FALSE));
// Get the real name and user host for all participants.
@@ -1010,26 +989,25 @@ void irc_msg_join(struct irc_conn *irc, const char *name, const char *from, char
/* Until purple_conversation_present does something that
* one would expect in Pidgin, this call produces buggy
* behavior both for the /join and auto-join cases. */
- /* purple_conversation_present(convo); */
+ /* purple_conversation_present(chat); */
return;
}
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[0], irc->account);
- if (convo == NULL) {
+ chat = purple_conversations_find_chat_with_account(args[0], irc->account);
+ if (chat == NULL) {
purple_debug(PURPLE_DEBUG_ERROR, "irc", "JOIN for %s failed\n", args[0]);
g_free(nick);
return;
}
userhost = irc_mask_userhost(from);
- chat = PURPLE_CONV_CHAT(convo);
- purple_conv_chat_add_user(chat, nick, userhost, PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(chat, nick, userhost, PURPLE_CHAT_USER_NONE, TRUE);
- cb = purple_conv_chat_cb_find(chat, nick);
+ cb = purple_chat_conversation_find_user(chat, nick);
if (cb) {
- purple_conv_chat_cb_set_attribute(chat, cb, "userhost", userhost);
+ g_object_set_data_full(G_OBJECT(cb), "userhost", userhost, (GDestroyNotify)g_free);
}
if ((ib = g_hash_table_lookup(irc->buddies, nick)) != NULL) {
@@ -1037,14 +1015,13 @@ void irc_msg_join(struct irc_conn *irc, const char *name, const char *from, char
irc_buddy_status(nick, ib, irc);
}
- g_free(userhost);
g_free(nick);
}
void irc_msg_kick(struct irc_conn *irc, const char *name, const char *from, char **args)
{
PurpleConnection *gc = purple_account_get_connection(irc->account);
- PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[0], irc->account);
+ PurpleChatConversation *chat = purple_conversations_find_chat_with_account(args[0], irc->account);
char *nick = irc_mask_nick(from), *buf;
if (!gc) {
@@ -1052,7 +1029,7 @@ void irc_msg_kick(struct irc_conn *irc, const char *name, const char *from, char
return;
}
- if (!convo) {
+ if (!chat) {
purple_debug(PURPLE_DEBUG_ERROR, "irc", "Received a KICK for unknown channel %s\n", args[0]);
g_free(nick);
return;
@@ -1060,12 +1037,12 @@ void irc_msg_kick(struct irc_conn *irc, const char *name, const char *from, char
if (!purple_utf8_strcasecmp(purple_connection_get_display_name(gc), args[1])) {
buf = g_strdup_printf(_("You have been kicked by %s: (%s)"), nick, args[2]);
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), args[0], buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), args[0], buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(buf);
- serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)));
+ serv_got_chat_left(gc, purple_chat_conversation_get_id(chat));
} else {
buf = g_strdup_printf(_("Kicked by %s (%s)"), nick, args[2]);
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), args[1], buf);
+ purple_chat_conversation_remove_user(chat, args[1], buf);
g_free(buf);
}
@@ -1075,24 +1052,25 @@ void irc_msg_kick(struct irc_conn *irc, const char *name, const char *from, char
void irc_msg_mode(struct irc_conn *irc, const char *name, const char *from, char **args)
{
- PurpleConversation *convo;
+ PurpleChatConversation *chat;
char *nick = irc_mask_nick(from), *buf;
if (*args[0] == '#' || *args[0] == '&') { /* Channel */
char *escaped;
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[0], irc->account);
- if (!convo) {
+ chat = purple_conversations_find_chat_with_account(args[0], irc->account);
+ if (!chat) {
purple_debug(PURPLE_DEBUG_ERROR, "irc", "MODE received for %s, which we are not in\n", args[0]);
g_free(nick);
return;
}
escaped = (args[2] != NULL) ? g_markup_escape_text(args[2], -1) : NULL;
buf = g_strdup_printf(_("mode (%s %s) by %s"), args[1], escaped ? escaped : "", nick);
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), args[0], buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), args[0], buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(escaped);
g_free(buf);
if(args[2]) {
- PurpleConvChatBuddyFlags newflag, flags;
+ PurpleChatUser *cb;
+ PurpleChatUserFlags newflag, flags;
char *mcur, *cur, *end, *user;
gboolean add = FALSE;
mcur = args[1];
@@ -1107,23 +1085,24 @@ void irc_msg_mode(struct irc_conn *irc, const char *name, const char *from, char
if (!end)
end = cur + strlen(cur);
user = g_strndup(cur, end - cur);
- flags = purple_conv_chat_user_get_flags(PURPLE_CONV_CHAT(convo), user);
- newflag = PURPLE_CBFLAGS_NONE;
+ cb = purple_chat_conversation_find_user(chat, user);
+ flags = purple_chat_user_get_flags(cb);
+ newflag = PURPLE_CHAT_USER_NONE;
if (*mcur == 'o')
- newflag = PURPLE_CBFLAGS_OP;
+ newflag = PURPLE_CHAT_USER_OP;
else if (*mcur =='h')
- newflag = PURPLE_CBFLAGS_HALFOP;
+ newflag = PURPLE_CHAT_USER_HALFOP;
else if (*mcur == 'v')
- newflag = PURPLE_CBFLAGS_VOICE;
+ newflag = PURPLE_CHAT_USER_VOICE;
else if(irc->mode_chars
&& strchr(irc->mode_chars, '~') && (*mcur == 'q'))
- newflag = PURPLE_CBFLAGS_FOUNDER;
+ newflag = PURPLE_CHAT_USER_FOUNDER;
if (newflag) {
if (add)
flags |= newflag;
else
flags &= ~newflag;
- purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(convo), user, flags);
+ purple_chat_user_set_flags(cb, flags);
}
g_free(user);
cur = end;
@@ -1141,7 +1120,7 @@ void irc_msg_mode(struct irc_conn *irc, const char *name, const char *from, char
void irc_msg_nick(struct irc_conn *irc, const char *name, const char *from, char **args)
{
PurpleConnection *gc = purple_account_get_connection(irc->account);
- PurpleConversation *conv;
+ PurpleIMConversation *im;
GSList *chats;
char *nick = irc_mask_nick(from);
@@ -1151,24 +1130,24 @@ void irc_msg_nick(struct irc_conn *irc, const char *name, const char *from, char
g_free(nick);
return;
}
- chats = gc->buddy_chats;
+ chats = purple_connection_get_active_chats(gc);
if (!purple_utf8_strcasecmp(nick, purple_connection_get_display_name(gc))) {
purple_connection_set_display_name(gc, args[0]);
}
while (chats) {
- PurpleConvChat *chat = PURPLE_CONV_CHAT(chats->data);
+ PurpleChatConversation *chat = PURPLE_CHAT_CONVERSATION(chats->data);
/* This is ugly ... */
- if (purple_conv_chat_find_user(chat, nick))
- purple_conv_chat_rename_user(chat, nick, args[0]);
+ if (purple_chat_conversation_has_user(chat, nick))
+ purple_chat_conversation_rename_user(chat, nick, args[0]);
chats = chats->next;
}
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, nick,
+ im = purple_conversations_find_im_with_account(nick,
irc->account);
- if (conv != NULL)
- purple_conversation_set_name(conv, args[0]);
+ if (im != NULL)
+ purple_conversation_set_name(PURPLE_CONVERSATION(im), args[0]);
g_free(nick);
}
@@ -1176,7 +1155,7 @@ void irc_msg_nick(struct irc_conn *irc, const char *name, const char *from, char
void irc_msg_badnick(struct irc_conn *irc, const char *name, const char *from, char **args)
{
PurpleConnection *gc = purple_account_get_connection(irc->account);
- if (purple_connection_get_state(gc) == PURPLE_CONNECTED) {
+ if (purple_connection_get_state(gc) == PURPLE_CONNECTION_CONNECTED) {
purple_notify_error(gc, _("Invalid nickname"),
_("Invalid nickname"),
_("Your selected nickname was rejected by the server. It probably contains invalid characters."));
@@ -1196,7 +1175,7 @@ void irc_msg_nickused(struct irc_conn *irc, const char *name, const char *from,
if (!args || !args[1])
return;
- if (gc && purple_connection_get_state(gc) == PURPLE_CONNECTED) {
+ if (gc && purple_connection_get_state(gc) == PURPLE_CONNECTION_CONNECTED) {
/* We only want to do the following dance if the connection
has not been successfully completed. If it has, just
notify the user that their /nick command didn't go. */
@@ -1253,7 +1232,7 @@ void irc_msg_nochangenick(struct irc_conn *irc, const char *name, const char *fr
void irc_msg_part(struct irc_conn *irc, const char *name, const char *from, char **args)
{
PurpleConnection *gc = purple_account_get_connection(irc->account);
- PurpleConversation *convo;
+ PurpleChatConversation *chat;
char *nick, *msg, *channel;
if (!args || !args[0] || !gc)
@@ -1263,8 +1242,8 @@ void irc_msg_part(struct irc_conn *irc, const char *name, const char *from, char
* that I can see. This catches that. */
channel = (args[0][0] == ':') ? &args[0][1] : args[0];
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, channel, irc->account);
- if (!convo) {
+ chat = purple_conversations_find_chat_with_account(channel, irc->account);
+ if (!chat) {
purple_debug(PURPLE_DEBUG_INFO, "irc", "Got a PART on %s, which doesn't exist -- probably closed\n", channel);
return;
}
@@ -1276,12 +1255,12 @@ void irc_msg_part(struct irc_conn *irc, const char *name, const char *from, char
(args[1] && *args[1]) ? ": " : "",
(escaped && *escaped) ? escaped : "");
g_free(escaped);
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), channel, msg, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), channel, msg, PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(msg);
- serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)));
+ serv_got_chat_left(gc, purple_chat_conversation_get_id(chat));
} else {
msg = args[1] ? irc_mirc2txt(args[1]) : NULL;
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), nick, msg);
+ purple_chat_conversation_remove_user(chat, nick, msg);
g_free(msg);
}
g_free(nick);
@@ -1321,13 +1300,10 @@ void irc_msg_pong(struct irc_conn *irc, const char *name, const char *from, char
msg = g_strdup_printf(_("PING reply -- Lag: %lu seconds"), time(NULL) - oldstamp);
}
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, parts[0], irc->account);
+ convo = purple_conversations_find_with_account(parts[0], irc->account);
g_strfreev(parts);
if (convo) {
- if (purple_conversation_get_type (convo) == PURPLE_CONV_TYPE_CHAT)
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "PONG", msg, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
- else
- purple_conv_im_write(PURPLE_CONV_IM(convo), "PONG", msg, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
+ purple_conversation_write_message(convo, "PONG", msg, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
} else {
gc = purple_account_get_connection(irc->account);
if (!gc) {
@@ -1350,7 +1326,7 @@ void irc_msg_privmsg(struct irc_conn *irc, const char *name, const char *from, c
static void irc_msg_handle_privmsg(struct irc_conn *irc, const char *name, const char *from, const char *to, const char *rawmsg, gboolean notice)
{
PurpleConnection *gc = purple_account_get_connection(irc->account);
- PurpleConversation *convo;
+ PurpleChatConversation *chat;
char *tmp;
char *msg;
char *nick;
@@ -1380,9 +1356,9 @@ static void irc_msg_handle_privmsg(struct irc_conn *irc, const char *name, const
if (!purple_utf8_strcasecmp(to, purple_connection_get_display_name(gc))) {
serv_got_im(gc, nick, msg, 0, time(NULL));
} else {
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, irc_nick_skip_mode(irc, to), irc->account);
- if (convo)
- serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)), nick, 0, msg, time(NULL));
+ chat = purple_conversations_find_chat_with_account(irc_nick_skip_mode(irc, to), irc->account);
+ if (chat)
+ serv_got_chat_in(gc, purple_chat_conversation_get_id(chat), nick, 0, msg, time(NULL));
else
purple_debug_error("irc", "Got a %s on %s, which does not exist\n",
notice ? "NOTICE" : "PRIVMSG", to);
@@ -1394,14 +1370,12 @@ static void irc_msg_handle_privmsg(struct irc_conn *irc, const char *name, const
void irc_msg_regonly(struct irc_conn *irc, const char *name, const char *from, char **args)
{
PurpleConnection *gc = purple_account_get_connection(irc->account);
- PurpleConversation *convo;
char *msg;
if (!args || !args[1] || !args[2] || !gc)
return;
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[1], irc->account);
- if (convo) {
+ if (purple_conversations_find_chat_with_account(args[1], irc->account)) {
/* This is a channel we're already in; for some reason,
* freenode feels the need to notify us that in some
* hypothetical other situation this might not have
@@ -1426,7 +1400,8 @@ void irc_msg_quit(struct irc_conn *irc, const char *name, const char *from, char
data[0] = irc_mask_nick(from);
data[1] = args[0];
/* XXX this should have an API, I shouldn't grab this directly */
- g_slist_foreach(gc->buddy_chats, (GFunc)irc_chat_remove_buddy, data);
+ g_slist_foreach(purple_connection_get_active_chats(gc),
+ (GFunc)irc_chat_remove_buddy, data);
if ((ib = g_hash_table_lookup(irc->buddies, data[0])) != NULL) {
ib->new_online_status = FALSE;
diff --git a/libpurple/protocols/jabber/adhoccommands.c b/libpurple/protocols/jabber/adhoccommands.c
index 60dc73305d..23e8286047 100644
--- a/libpurple/protocols/jabber/adhoccommands.c
+++ b/libpurple/protocols/jabber/adhoccommands.c
@@ -224,7 +224,7 @@ jabber_adhoc_parse(JabberStream *js, const char *from,
}
void jabber_adhoc_execute_action(PurpleBlistNode *node, gpointer data) {
- if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if (PURPLE_IS_BUDDY(node)) {
JabberAdHocCommands *cmd = data;
PurpleBuddy *buddy = (PurpleBuddy *) node;
PurpleAccount *account = purple_buddy_get_account(buddy);
diff --git a/libpurple/protocols/jabber/auth.c b/libpurple/protocols/jabber/auth.c
index 7285108b11..df5bdeadc6 100644
--- a/libpurple/protocols/jabber/auth.c
+++ b/libpurple/protocols/jabber/auth.c
@@ -24,7 +24,6 @@
#include "account.h"
#include "debug.h"
-#include "cipher.h"
#include "core.h"
#include "conversation.h"
#include "request.h"
@@ -39,6 +38,9 @@
#include "iq.h"
#include "notify.h"
+#include "ciphers/hmaccipher.h"
+#include "ciphers/md5hash.h"
+
static GSList *auth_mechs = NULL;
static void auth_old_result_cb(JabberStream *js, const char *from,
@@ -276,16 +278,18 @@ static void auth_old_cb(JabberStream *js, const char *from,
*/
const char *challenge;
gchar digest[33];
- PurpleCipherContext *hmac;
+ PurpleCipher *hmac;
+ PurpleHash *md5;
/* Calculate the MHAC-MD5 digest */
+ md5 = purple_md5_hash_new();
+ hmac = purple_hmac_cipher_new(md5);
challenge = xmlnode_get_attrib(x, "challenge");
- hmac = purple_cipher_context_new_by_name("hmac", NULL);
- purple_cipher_context_set_option(hmac, "hash", "md5");
- purple_cipher_context_set_key(hmac, (guchar *)pw, strlen(pw));
- purple_cipher_context_append(hmac, (guchar *)challenge, strlen(challenge));
- purple_cipher_context_digest_to_str(hmac, digest, 33);
- purple_cipher_context_destroy(hmac);
+ purple_cipher_set_key(hmac, (guchar *)pw, strlen(pw));
+ purple_cipher_append(hmac, (guchar *)challenge, strlen(challenge));
+ purple_cipher_digest_to_str(hmac, digest, 33);
+ g_object_unref(hmac);
+ g_object_unref(md5);
/* Create the response query */
iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth");
diff --git a/libpurple/protocols/jabber/auth_digest_md5.c b/libpurple/protocols/jabber/auth_digest_md5.c
index 7d38db7b03..e729cea978 100644
--- a/libpurple/protocols/jabber/auth_digest_md5.c
+++ b/libpurple/protocols/jabber/auth_digest_md5.c
@@ -23,7 +23,7 @@
#include "internal.h"
#include "debug.h"
-#include "cipher.h"
+#include "ciphers/md5hash.h"
#include "util.h"
#include "xmlnode.h"
@@ -106,8 +106,7 @@ static char *
generate_response_value(JabberID *jid, const char *passwd, const char *nonce,
const char *cnonce, const char *a2, const char *realm)
{
- PurpleCipher *cipher;
- PurpleCipherContext *context;
+ PurpleHash *hash;
guchar result[16];
size_t a1len;
@@ -122,35 +121,34 @@ generate_response_value(JabberID *jid, const char *passwd, const char *nonce,
convpasswd = g_strdup(passwd);
}
- cipher = purple_ciphers_find_cipher("md5");
- context = purple_cipher_context_new(cipher, NULL);
+ hash = purple_md5_hash_new();
x = g_strdup_printf("%s:%s:%s", convnode, realm, convpasswd ? convpasswd : "");
- purple_cipher_context_append(context, (const guchar *)x, strlen(x));
- purple_cipher_context_digest(context, result, sizeof(result));
+ purple_hash_append(hash, (const guchar *)x, strlen(x));
+ purple_hash_digest(hash, result, sizeof(result));
a1 = g_strdup_printf("xxxxxxxxxxxxxxxx:%s:%s", nonce, cnonce);
a1len = strlen(a1);
g_memmove(a1, result, 16);
- purple_cipher_context_reset(context, NULL);
- purple_cipher_context_append(context, (const guchar *)a1, a1len);
- purple_cipher_context_digest(context, result, sizeof(result));
+ purple_hash_reset(hash);
+ purple_hash_append(hash, (const guchar *)a1, a1len);
+ purple_hash_digest(hash, result, sizeof(result));
ha1 = purple_base16_encode(result, 16);
- purple_cipher_context_reset(context, NULL);
- purple_cipher_context_append(context, (const guchar *)a2, strlen(a2));
- purple_cipher_context_digest(context, result, sizeof(result));
+ purple_hash_reset(hash);
+ purple_hash_append(hash, (const guchar *)a2, strlen(a2));
+ purple_hash_digest(hash, result, sizeof(result));
ha2 = purple_base16_encode(result, 16);
kd = g_strdup_printf("%s:%s:00000001:%s:auth:%s", ha1, nonce, cnonce, ha2);
- purple_cipher_context_reset(context, NULL);
- purple_cipher_context_append(context, (const guchar *)kd, strlen(kd));
- purple_cipher_context_digest(context, result, sizeof(result));
- purple_cipher_context_destroy(context);
+ purple_hash_reset(hash);
+ purple_hash_append(hash, (const guchar *)kd, strlen(kd));
+ purple_hash_digest(hash, result, sizeof(result));
+ g_object_unref(hash);
z = purple_base16_encode(result, 16);
diff --git a/libpurple/protocols/jabber/auth_scram.c b/libpurple/protocols/jabber/auth_scram.c
index 5fe6bf9539..8c92ed5978 100644
--- a/libpurple/protocols/jabber/auth_scram.c
+++ b/libpurple/protocols/jabber/auth_scram.c
@@ -25,11 +25,12 @@
#include "auth.h"
#include "auth_scram.h"
-#include "cipher.h"
+#include "ciphers/hmaccipher.h"
+#include "ciphers/sha1hash.h"
#include "debug.h"
static const JabberScramHash hashes[] = {
- { "-SHA-1", "sha1", 20 },
+ { "-SHA-1", purple_sha1_hash_new, 20 },
};
static const JabberScramHash *mech_to_hash(const char *mech)
@@ -76,7 +77,8 @@ static const struct {
guchar *jabber_scram_hi(const JabberScramHash *hash, const GString *str,
GString *salt, guint iterations)
{
- PurpleCipherContext *context;
+ PurpleHash *hasher;
+ PurpleCipher *cipher;
guchar *result;
guint i;
guchar *prev, *tmp;
@@ -90,27 +92,28 @@ guchar *jabber_scram_hi(const JabberScramHash *hash, const GString *str,
tmp = g_new0(guint8, hash->size);
result = g_new0(guint8, hash->size);
- context = purple_cipher_context_new_by_name("hmac", NULL);
+ hasher = hash->new_cipher();
+ cipher = purple_hmac_cipher_new(hasher);
+ g_object_unref(G_OBJECT(hasher));
/* Append INT(1), a four-octet encoding of the integer 1, most significant
* octet first. */
g_string_append_len(salt, "\0\0\0\1", 4);
/* Compute U0 */
- purple_cipher_context_set_option(context, "hash", (gpointer)hash->name);
- purple_cipher_context_set_key(context, (guchar *)str->str, str->len);
- purple_cipher_context_append(context, (guchar *)salt->str, salt->len);
- purple_cipher_context_digest(context, result, hash->size);
+ purple_cipher_set_key(cipher, (guchar *)str->str, str->len);
+ purple_cipher_append(cipher, (guchar *)salt->str, salt->len);
+ purple_cipher_digest(cipher, result, hash->size);
memcpy(prev, result, hash->size);
/* Compute U1...Ui */
for (i = 1; i < iterations; ++i) {
guint j;
- purple_cipher_context_set_option(context, "hash", (gpointer)hash->name);
- purple_cipher_context_set_key(context, (guchar *)str->str, str->len);
- purple_cipher_context_append(context, prev, hash->size);
- purple_cipher_context_digest(context, tmp, hash->size);
+ purple_cipher_reset(cipher);
+ purple_cipher_set_key(cipher, (guchar *)str->str, str->len);
+ purple_cipher_append(cipher, prev, hash->size);
+ purple_cipher_digest(cipher, tmp, hash->size);
for (j = 0; j < hash->size; ++j)
result[j] ^= tmp[j];
@@ -118,7 +121,7 @@ guchar *jabber_scram_hi(const JabberScramHash *hash, const GString *str,
memcpy(prev, tmp, hash->size);
}
- purple_cipher_context_destroy(context);
+ g_object_unref(G_OBJECT(cipher));
g_free(tmp);
g_free(prev);
return result;
@@ -136,25 +139,27 @@ guchar *jabber_scram_hi(const JabberScramHash *hash, const GString *str,
static void
hmac(const JabberScramHash *hash, guchar *out, const guchar *key, const gchar *str)
{
- PurpleCipherContext *context;
-
- context = purple_cipher_context_new_by_name("hmac", NULL);
- purple_cipher_context_set_option(context, "hash", (gpointer)hash->name);
- purple_cipher_context_set_key(context, key, hash->size);
- purple_cipher_context_append(context, (guchar *)str, strlen(str));
- purple_cipher_context_digest(context, out, hash->size);
- purple_cipher_context_destroy(context);
+ PurpleHash *hasher;
+ PurpleCipher *cipher;
+
+ hasher = hash->new_cipher();
+ cipher = purple_hmac_cipher_new(hasher);
+ g_object_unref(G_OBJECT(hasher));
+ purple_cipher_set_key(cipher, key, hash->size);
+ purple_cipher_append(cipher, (guchar *)str, strlen(str));
+ purple_cipher_digest(cipher, out, hash->size);
+ g_object_unref(G_OBJECT(cipher));
}
static void
hash(const JabberScramHash *hash, guchar *out, const guchar *data)
{
- PurpleCipherContext *context;
+ PurpleHash *hasher;
- context = purple_cipher_context_new_by_name(hash->name, NULL);
- purple_cipher_context_append(context, data, hash->size);
- purple_cipher_context_digest(context, out, hash->size);
- purple_cipher_context_destroy(context);
+ hasher = hash->new_cipher();
+ purple_hash_append(hasher, data, hash->size);
+ purple_hash_digest(hasher, out, hash->size);
+ g_object_unref(G_OBJECT(hasher));
}
gboolean
diff --git a/libpurple/protocols/jabber/auth_scram.h b/libpurple/protocols/jabber/auth_scram.h
index e1f52d1cbe..84f1cb3e25 100644
--- a/libpurple/protocols/jabber/auth_scram.h
+++ b/libpurple/protocols/jabber/auth_scram.h
@@ -29,12 +29,14 @@
* DO NOT USE ANYTHING HERE OR YOU WILL BE SENT TO THE PIT OF DESPAIR.
*/
+#include "hash.h"
+
/* Per-connection state stored between messages.
* This is stored in js->auth_data_mech.
*/
typedef struct {
const char *mech_substr;
- const char *name;
+ PurpleHash *(*new_cipher)(void);
guint size;
} JabberScramHash;
diff --git a/libpurple/protocols/jabber/buddy.c b/libpurple/protocols/jabber/buddy.c
index 9e22b41973..3a37315fcc 100644
--- a/libpurple/protocols/jabber/buddy.c
+++ b/libpurple/protocols/jabber/buddy.c
@@ -1225,7 +1225,7 @@ static void jabber_vcard_parse(JabberStream *js, const char *from,
PurpleBuddy *b;
/* If we found a serverside alias, set it and tell the core */
serv_got_alias(js->gc, bare_jid, serverside_alias);
- b = purple_find_buddy(account, bare_jid);
+ b = purple_blist_find_buddy(account, bare_jid);
if (b) {
purple_blist_node_set_string((PurpleBlistNode*)b, "servernick", serverside_alias);
}
@@ -1698,7 +1698,7 @@ static void jabber_buddy_make_invisible(PurpleBlistNode *node, gpointer data)
PurpleConnection *gc;
JabberStream *js;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
@@ -1713,7 +1713,7 @@ static void jabber_buddy_make_visible(PurpleBlistNode *node, gpointer data)
PurpleConnection *gc;
JabberStream *js;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
@@ -1745,7 +1745,7 @@ jabber_buddy_cancel_presence_notification(PurpleBlistNode *node,
const gchar *name;
char *msg;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *) node;
name = purple_buddy_get_name(buddy);
@@ -1766,7 +1766,7 @@ static void jabber_buddy_rerequest_auth(PurpleBlistNode *node, gpointer data)
PurpleConnection *gc;
JabberStream *js;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
@@ -1782,7 +1782,7 @@ static void jabber_buddy_unsubscribe(PurpleBlistNode *node, gpointer data)
PurpleConnection *gc;
JabberStream *js;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
@@ -1792,7 +1792,7 @@ static void jabber_buddy_unsubscribe(PurpleBlistNode *node, gpointer data)
}
static void jabber_buddy_login(PurpleBlistNode *node, gpointer data) {
- if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if(PURPLE_IS_BUDDY(node)) {
/* simply create a directed presence of the current status */
PurpleBuddy *buddy = (PurpleBuddy *) node;
PurpleConnection *gc = purple_account_get_connection(purple_buddy_get_account(buddy));
@@ -1818,7 +1818,7 @@ static void jabber_buddy_login(PurpleBlistNode *node, gpointer data) {
}
static void jabber_buddy_logout(PurpleBlistNode *node, gpointer data) {
- if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if(PURPLE_IS_BUDDY(node)) {
/* simply create a directed unavailable presence */
PurpleBuddy *buddy = (PurpleBuddy *) node;
PurpleConnection *gc = purple_account_get_connection(purple_buddy_get_account(buddy));
@@ -1932,7 +1932,7 @@ static GList *jabber_buddy_menu(PurpleBuddy *buddy)
GList *
jabber_blist_node_menu(PurpleBlistNode *node)
{
- if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if(PURPLE_IS_BUDDY(node)) {
return jabber_buddy_menu((PurpleBuddy *) node);
} else {
return NULL;
diff --git a/libpurple/protocols/jabber/caps.c b/libpurple/protocols/jabber/caps.c
index 8b87a4d958..7e084681ee 100644
--- a/libpurple/protocols/jabber/caps.c
+++ b/libpurple/protocols/jabber/caps.c
@@ -25,12 +25,14 @@
#include "debug.h"
#include "caps.h"
-#include "cipher.h"
#include "iq.h"
#include "presence.h"
#include "util.h"
#include "xdata.h"
+#include "ciphers/md5hash.h"
+#include "ciphers/sha1hash.h"
+
#define JABBER_CAPS_FILENAME "xmpp-caps.xml"
typedef struct _JabberDataFormField {
@@ -455,16 +457,18 @@ jabber_caps_client_iqcb(JabberStream *js, const char *from, JabberIqType type,
/* Only validate if these are v1.5 capabilities */
if (userdata->hash) {
gchar *hash = NULL;
+ PurpleHash *hasher = NULL;
/*
* TODO: If you add *any* hash here, make sure the checksum buffer
* size in jabber_caps_calculate_hash is large enough. The cipher API
* doesn't seem to offer a "Get the hash size" function(?).
*/
if (g_str_equal(userdata->hash, "sha-1")) {
- hash = jabber_caps_calculate_hash(info, "sha1");
+ hasher = purple_sha1_hash_new();
} else if (g_str_equal(userdata->hash, "md5")) {
- hash = jabber_caps_calculate_hash(info, "md5");
+ hasher = purple_md5_hash_new();
}
+ hash = jabber_caps_calculate_hash(info, hasher);
if (!hash || !g_str_equal(hash, userdata->ver)) {
purple_debug_warning("jabber", "Could not validate caps info from "
@@ -480,6 +484,7 @@ jabber_caps_client_iqcb(JabberStream *js, const char *from, JabberIqType type,
}
g_free(hash);
+ g_object_unref(hasher);
}
if (!userdata->hash && userdata->node_exts) {
@@ -806,28 +811,33 @@ static GList* jabber_caps_xdata_get_fields(const xmlnode *x)
}
static void
-append_escaped_string(PurpleCipherContext *context, const gchar *str)
+append_escaped_string(PurpleHash *hash, const gchar *str)
{
+ g_return_if_fail(hash != NULL);
+ g_object_ref(hash);
+
if (str && *str) {
char *tmp = g_markup_escape_text(str, -1);
- purple_cipher_context_append(context, (const guchar *)tmp, strlen(tmp));
+ purple_hash_append(hash, (const guchar *)tmp, strlen(tmp));
g_free(tmp);
}
- purple_cipher_context_append(context, (const guchar *)"<", 1);
+ purple_hash_append(hash, (const guchar *)"<", 1);
+ g_object_unref(hash);
}
-gchar *jabber_caps_calculate_hash(JabberCapsClientInfo *info, const char *hash)
+gchar *jabber_caps_calculate_hash(JabberCapsClientInfo *info, PurpleHash *hash)
{
GList *node;
- PurpleCipherContext *context;
guint8 checksum[20];
gsize checksum_size = 20;
gboolean success;
- if (!info || !(context = purple_cipher_context_new_by_name(hash, NULL)))
+ if (!info || !hash)
return NULL;
+ g_object_ref(hash);
+
/* sort identities, features and x-data forms */
info->identities = g_list_sort(info->identities, jabber_identity_compare);
info->features = g_list_sort(info->features, (GCompareFunc)strcmp);
@@ -850,7 +860,7 @@ gchar *jabber_caps_calculate_hash(JabberCapsClientInfo *info, const char *hash)
tmp = g_strconcat(category, "/", type, "/", lang ? lang : "",
"/", name ? name : "", "<", NULL);
- purple_cipher_context_append(context, (const guchar *)tmp, strlen(tmp));
+ purple_hash_append(hash, (const guchar *)tmp, strlen(tmp));
g_free(tmp);
g_free(category);
@@ -861,7 +871,7 @@ gchar *jabber_caps_calculate_hash(JabberCapsClientInfo *info, const char *hash)
/* concat features to the verification string */
for (node = info->features; node; node = node->next) {
- append_escaped_string(context, node->data);
+ append_escaped_string(hash, node->data);
}
/* concat x-data forms to the verification string */
@@ -871,7 +881,7 @@ gchar *jabber_caps_calculate_hash(JabberCapsClientInfo *info, const char *hash)
GList *fields = jabber_caps_xdata_get_fields(data);
/* append FORM_TYPE's field value to the verification string */
- append_escaped_string(context, formtype);
+ append_escaped_string(hash, formtype);
g_free(formtype);
while (fields) {
@@ -879,10 +889,10 @@ gchar *jabber_caps_calculate_hash(JabberCapsClientInfo *info, const char *hash)
if (!g_str_equal(field->var, "FORM_TYPE")) {
/* Append the "var" attribute */
- append_escaped_string(context, field->var);
+ append_escaped_string(hash, field->var);
/* Append <value/> elements' cdata */
while (field->values) {
- append_escaped_string(context, field->values->data);
+ append_escaped_string(hash, field->values->data);
g_free(field->values->data);
field->values = g_list_delete_link(field->values,
field->values);
@@ -900,16 +910,17 @@ gchar *jabber_caps_calculate_hash(JabberCapsClientInfo *info, const char *hash)
}
/* generate hash */
- success = purple_cipher_context_digest(context, checksum, checksum_size);
- checksum_size = purple_cipher_context_get_digest_size(context);
+ success = purple_hash_digest(hash, checksum, checksum_size);
+ checksum_size = purple_hash_get_digest_size(hash);
- purple_cipher_context_destroy(context);
+ g_object_unref(hash);
return (success ? purple_base64_encode(checksum, checksum_size) : NULL);
}
void jabber_caps_calculate_own_hash(JabberStream *js) {
JabberCapsClientInfo info;
+ PurpleHash *hasher;
GList *iter = 0;
GList *features = 0;
@@ -940,7 +951,9 @@ void jabber_caps_calculate_own_hash(JabberStream *js) {
info.forms = NULL;
g_free(js->caps_hash);
- js->caps_hash = jabber_caps_calculate_hash(&info, "sha1");
+ hasher = purple_sha1_hash_new();
+ js->caps_hash = jabber_caps_calculate_hash(&info, hasher);
+ g_object_unref(hasher);
g_list_free(info.identities);
g_list_free(info.features);
}
diff --git a/libpurple/protocols/jabber/caps.h b/libpurple/protocols/jabber/caps.h
index 897754f6d9..b428c577d2 100644
--- a/libpurple/protocols/jabber/caps.h
+++ b/libpurple/protocols/jabber/caps.h
@@ -27,6 +27,7 @@
typedef struct _JabberCapsClientInfo JabberCapsClientInfo;
#include "jabber.h"
+#include "hash.h"
/* Implementation of XEP-0115 - Entity Capabilities */
@@ -98,7 +99,7 @@ void jabber_caps_get_info(JabberStream *js, const char *who, const char *node,
* @param hash Hash cipher to be used. Either sha-1 or md5.
* @return The base64 encoded SHA-1 hash; must be freed by caller
*/
-gchar *jabber_caps_calculate_hash(JabberCapsClientInfo *info, const char *hash);
+gchar *jabber_caps_calculate_hash(JabberCapsClientInfo *info, PurpleHash *hash);
/**
* Calculate SHA1 hash for own featureset.
diff --git a/libpurple/protocols/jabber/chat.c b/libpurple/protocols/jabber/chat.c
index b4a3ec0e89..e9975e853a 100644
--- a/libpurple/protocols/jabber/chat.c
+++ b/libpurple/protocols/jabber/chat.c
@@ -138,16 +138,16 @@ JabberChat *jabber_chat_find_by_id(JabberStream *js, int id)
return chat;
}
-JabberChat *jabber_chat_find_by_conv(PurpleConversation *conv)
+JabberChat *jabber_chat_find_by_conv(PurpleChatConversation *conv)
{
- PurpleAccount *account = purple_conversation_get_account(conv);
+ PurpleAccount *account = purple_conversation_get_account(PURPLE_CONVERSATION(conv));
PurpleConnection *gc = purple_account_get_connection(account);
JabberStream *js;
int id;
if (!gc)
return NULL;
js = purple_connection_get_protocol_data(gc);
- id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv));
+ id = purple_chat_conversation_get_id(conv);
return jabber_chat_find_by_id(js, id);
}
@@ -451,12 +451,12 @@ void jabber_chat_free(JabberChat *chat)
g_free(chat);
}
-gboolean jabber_chat_find_buddy(PurpleConversation *conv, const char *name)
+gboolean jabber_chat_find_buddy(PurpleChatConversation *conv, const char *name)
{
- return purple_conv_chat_find_user(PURPLE_CONV_CHAT(conv), name);
+ return purple_chat_conversation_has_user(conv, name);
}
-char *jabber_chat_buddy_real_name(PurpleConnection *gc, int id, const char *who)
+char *jabber_chat_user_real_name(PurpleConnection *gc, int id, const char *who)
{
JabberStream *js = purple_connection_get_protocol_data(gc);
JabberChat *chat;
@@ -753,7 +753,7 @@ gboolean jabber_chat_change_nick(JabberChat *chat, const char *nick)
int priority;
if(!chat->muc) {
- purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), "",
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat->conv), "",
_("Nick changing not supported in non-MUC chatrooms"),
PURPLE_MESSAGE_SYSTEM, time(NULL));
return FALSE;
@@ -1072,7 +1072,7 @@ jabber_chat_affiliation_list_cb(JabberStream *js, const char *from,
buf = g_string_append_len(buf, _("No users found"), -1);
}
- purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), "", buf->str,
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat->conv), "", buf->str,
PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG, time(NULL));
g_string_free(buf, TRUE);
@@ -1167,7 +1167,7 @@ static void jabber_chat_role_list_cb(JabberStream *js, const char *from,
buf = g_string_append_len(buf, _("No users found"), -1);
}
- purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), "", buf->str,
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat->conv), "", buf->str,
PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG, time(NULL));
g_string_free(buf, TRUE);
diff --git a/libpurple/protocols/jabber/chat.h b/libpurple/protocols/jabber/chat.h
index 203b242734..71174e192b 100644
--- a/libpurple/protocols/jabber/chat.h
+++ b/libpurple/protocols/jabber/chat.h
@@ -45,7 +45,7 @@ typedef struct _JabberChat {
char *handle;
GHashTable *components;
int id;
- PurpleConversation *conv;
+ PurpleChatConversation *conv;
gboolean muc;
gboolean xhtml;
PurpleRequestType config_dialog_type;
@@ -77,14 +77,14 @@ void jabber_chat_join(PurpleConnection *gc, GHashTable *data);
JabberChat *jabber_chat_find(JabberStream *js, const char *room,
const char *server);
JabberChat *jabber_chat_find_by_id(JabberStream *js, int id);
-JabberChat *jabber_chat_find_by_conv(PurpleConversation *conv);
+JabberChat *jabber_chat_find_by_conv(PurpleChatConversation *conv);
void jabber_chat_destroy(JabberChat *chat);
void jabber_chat_free(JabberChat *chat);
-gboolean jabber_chat_find_buddy(PurpleConversation *conv, const char *name);
+gboolean jabber_chat_find_buddy(PurpleChatConversation *conv, const char *name);
void jabber_chat_invite(PurpleConnection *gc, int id, const char *message,
const char *name);
void jabber_chat_leave(PurpleConnection *gc, int id);
-char *jabber_chat_buddy_real_name(PurpleConnection *gc, int id, const char *who);
+char *jabber_chat_user_real_name(PurpleConnection *gc, int id, const char *who);
void jabber_chat_request_room_configure(JabberChat *chat);
void jabber_chat_create_instant_room(JabberChat *chat);
void jabber_chat_register(JabberChat *chat);
diff --git a/libpurple/protocols/jabber/disco.c b/libpurple/protocols/jabber/disco.c
index 1b5a3deac1..82f0f03fa8 100644
--- a/libpurple/protocols/jabber/disco.c
+++ b/libpurple/protocols/jabber/disco.c
@@ -526,8 +526,8 @@ jabber_disco_server_info_result_cb(JabberStream *js, const char *from,
js->pep = TRUE;
purple_connection_set_flags(gc,
purple_connection_get_flags(gc)
- | PURPLE_CONNECTION_SUPPORT_MOODS
- | PURPLE_CONNECTION_SUPPORT_MOOD_MESSAGES);
+ | PURPLE_CONNECTION_FLAG_SUPPORT_MOODS
+ | PURPLE_CONNECTION_FLAG_SUPPORT_MOOD_MESSAGES);
}
if (!category || strcmp(category, "server"))
continue;
diff --git a/libpurple/protocols/jabber/google/google.c b/libpurple/protocols/jabber/google/google.c
index 55cb68cab5..ba79112c14 100644
--- a/libpurple/protocols/jabber/google/google.c
+++ b/libpurple/protocols/jabber/google/google.c
@@ -152,7 +152,7 @@ void google_buddy_node_chat(PurpleBlistNode *node, gpointer data)
gchar *room;
gchar *uuid = purple_uuid_random();
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = PURPLE_BUDDY(node);
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
diff --git a/libpurple/protocols/jabber/google/google_roster.c b/libpurple/protocols/jabber/google/google_roster.c
index b7714b8be6..dcab1a1e2c 100644
--- a/libpurple/protocols/jabber/google/google_roster.c
+++ b/libpurple/protocols/jabber/google/google_roster.c
@@ -28,7 +28,7 @@
void jabber_google_roster_outgoing(JabberStream *js, xmlnode *query, xmlnode *item)
{
PurpleAccount *account = purple_connection_get_account(js->gc);
- GSList *list = account->deny;
+ GSList *list = purple_account_privacy_get_denied(account);
const char *jid = xmlnode_get_attrib(item, "jid");
char *jid_norm = (char *)jabber_normalize(account, jid);
@@ -64,12 +64,12 @@ gboolean jabber_google_roster_incoming(JabberStream *js, xmlnode *item)
jid_norm = g_strdup(jabber_normalize(account, jid));
- on_block_list = NULL != g_slist_find_custom(account->deny, jid_norm,
- (GCompareFunc)strcmp);
+ on_block_list = NULL != g_slist_find_custom(purple_account_privacy_get_denied(account),
+ jid_norm, (GCompareFunc)strcmp);
if (grt && (*grt == 'H' || *grt == 'h')) {
/* Hidden; don't show this buddy. */
- GSList *buddies = purple_find_buddies(account, jid_norm);
+ GSList *buddies = purple_blist_find_buddies(account, jid_norm);
if (buddies) {
purple_debug_info("jabber", "Removing %s from local buddy list\n",
jid_norm);
@@ -86,10 +86,10 @@ gboolean jabber_google_roster_incoming(JabberStream *js, xmlnode *item)
if (!on_block_list && (grt && (*grt == 'B' || *grt == 'b'))) {
purple_debug_info("jabber", "Blocking %s\n", jid_norm);
- purple_privacy_deny_add(account, jid_norm, TRUE);
+ purple_account_privacy_deny_add(account, jid_norm, TRUE);
} else if (on_block_list && (!grt || (*grt != 'B' && *grt != 'b' ))){
purple_debug_info("jabber", "Unblocking %s\n", jid_norm);
- purple_privacy_deny_remove(account, jid_norm, TRUE);
+ purple_account_privacy_deny_remove(account, jid_norm, TRUE);
}
g_free(jid_norm);
@@ -111,7 +111,7 @@ void jabber_google_roster_add_deny(JabberStream *js, const char *who)
jb = jabber_buddy_find(js, who, TRUE);
account = purple_connection_get_account(js->gc);
- buddies = purple_find_buddies(account, who);
+ buddies = purple_blist_find_buddies(account, who);
if(!buddies)
return;
@@ -132,7 +132,7 @@ void jabber_google_roster_add_deny(JabberStream *js, const char *who)
buddies = g_slist_delete_link(buddies, buddies);
} while (buddies);
- balias = purple_buddy_get_local_buddy_alias(b);
+ balias = purple_buddy_get_local_alias(b);
xmlnode_set_attrib(item, "jid", who);
xmlnode_set_attrib(item, "name", balias ? balias : "");
xmlnode_set_attrib(item, "gr:t", "B");
@@ -169,7 +169,7 @@ void jabber_google_roster_rem_deny(JabberStream *js, const char *who)
PurpleBuddy *b;
const char *balias;
- buddies = purple_find_buddies(purple_connection_get_account(js->gc), who);
+ buddies = purple_blist_find_buddies(purple_connection_get_account(js->gc), who);
if(!buddies)
return;
@@ -190,7 +190,7 @@ void jabber_google_roster_rem_deny(JabberStream *js, const char *who)
buddies = g_slist_delete_link(buddies, buddies);
} while (buddies);
- balias = purple_buddy_get_local_buddy_alias(b);
+ balias = purple_buddy_get_local_alias(b);
xmlnode_set_attrib(item, "jid", who);
xmlnode_set_attrib(item, "name", balias ? balias : "");
xmlnode_set_attrib(query, "xmlns:gr", NS_GOOGLE_ROSTER);
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
index 85ee7984d2..f2ca99c993 100644
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -24,7 +24,7 @@
#include "account.h"
#include "accountopt.h"
-#include "blist.h"
+#include "buddylist.h"
#include "core.h"
#include "cmds.h"
#include "connection.h"
@@ -36,7 +36,6 @@
#include "message.h"
#include "notify.h"
#include "pluginpref.h"
-#include "privacy.h"
#include "proxy.h"
#include "prpl.h"
#include "request.h"
@@ -392,8 +391,11 @@ static int jabber_do_send(JabberStream *js, const char *data, int len)
static void jabber_send_cb(gpointer data, gint source, PurpleInputCondition cond)
{
JabberStream *js = data;
+ const gchar *output = NULL;
int ret, writelen;
- writelen = purple_circ_buffer_get_max_read(js->write_buffer);
+
+ writelen = purple_circular_buffer_get_max_read(js->write_buffer);
+ output = purple_circular_buffer_get_output(js->write_buffer);
if (writelen == 0) {
purple_input_remove(js->writeh);
@@ -401,7 +403,7 @@ static void jabber_send_cb(gpointer data, gint source, PurpleInputCondition cond
return;
}
- ret = jabber_do_send(js, js->write_buffer->outptr, writelen);
+ ret = jabber_do_send(js, output, writelen);
if (ret < 0 && errno == EAGAIN)
return;
@@ -414,7 +416,7 @@ static void jabber_send_cb(gpointer data, gint source, PurpleInputCondition cond
return;
}
- purple_circ_buffer_mark_read(js->write_buffer, ret);
+ purple_circular_buffer_mark_read(js->write_buffer, ret);
}
static gboolean do_jabber_send_raw(JabberStream *js, const char *data, int len)
@@ -457,7 +459,7 @@ static gboolean do_jabber_send_raw(JabberStream *js, const char *data, int len)
js->writeh = purple_input_add(
js->gsc ? js->gsc->fd : js->fd,
PURPLE_INPUT_WRITE, jabber_send_cb, js);
- purple_circ_buffer_append(js->write_buffer,
+ purple_circular_buffer_append(js->write_buffer,
data + ret, len - ret);
}
@@ -993,7 +995,7 @@ jabber_stream_new(PurpleAccount *account)
js->chats = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, (GDestroyNotify)jabber_chat_free);
js->next_id = g_random_int();
- js->write_buffer = purple_circ_buffer_new(512);
+ js->write_buffer = purple_circular_buffer_new(512);
js->old_length = 0;
js->keepalive_timeout = 0;
js->max_inactivity = DEFAULT_INACTIVITY_TIME;
@@ -1083,7 +1085,7 @@ jabber_login(PurpleAccount *account)
JabberStream *js;
PurpleStoredImage *image;
- purple_connection_set_flags(gc, PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY);
+ purple_connection_set_flags(gc, PURPLE_CONNECTION_FLAG_HTML | PURPLE_CONNECTION_FLAG_ALLOW_CUSTOM_SMILEY);
js = jabber_stream_new(account);
if (js == NULL)
return;
@@ -1343,7 +1345,7 @@ void jabber_register_parse(JabberStream *js, const char *from, JabberIqType type
if(js->registration) {
/* get rid of the login thingy */
- purple_connection_set_state(js->gc, PURPLE_CONNECTED);
+ purple_connection_set_state(js->gc, PURPLE_CONNECTION_CONNECTED);
}
if(xmlnode_get_child(query, "registered")) {
@@ -1372,9 +1374,10 @@ void jabber_register_parse(JabberStream *js, const char *from, JabberIqType type
g_free(href);
if(js->registration) {
- js->gc->wants_to_die = TRUE;
/* succeeded, but we have no login info */
purple_account_register_completed(account, TRUE);
+ purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ _("Registration completed successfully. Please reconnect to continue."));
jabber_connection_schedule_close(js);
}
return;
@@ -1415,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(purple_connection_get_account(js->gc)), FALSE);
+ purple_account_get_private_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);
@@ -1549,8 +1552,8 @@ void jabber_unregister_account(PurpleAccount *account, PurpleAccountUnregistrati
PurpleConnection *gc = purple_account_get_connection(account);
JabberStream *js;
- if (purple_connection_get_state(gc) != PURPLE_CONNECTED) {
- if (purple_connection_get_state(gc) != PURPLE_CONNECTING)
+ if (purple_connection_get_state(gc) != PURPLE_CONNECTION_CONNECTED) {
+ if (purple_connection_get_state(gc) != PURPLE_CONNECTION_CONNECTING)
jabber_login(account);
js = purple_connection_get_protocol_data(gc);
js->unregistration = TRUE;
@@ -1644,7 +1647,7 @@ void jabber_close(PurpleConnection *gc)
g_free(js->caps_hash);
if (js->write_buffer)
- purple_circ_buffer_destroy(js->write_buffer);
+ g_object_unref(G_OBJECT(js->write_buffer));
if(js->writeh)
purple_input_remove(js->writeh);
if (js->auth_mech && js->auth_mech->dispose)
@@ -1744,7 +1747,7 @@ void jabber_stream_set_state(JabberStream *js, JabberStreamState state)
/* Start up the inactivity timer */
jabber_stream_restart_inactivity_timer(js);
- purple_connection_set_state(js->gc, PURPLE_CONNECTED);
+ purple_connection_set_state(js->gc, PURPLE_CONNECTION_CONNECTED);
break;
}
@@ -1776,6 +1779,7 @@ void jabber_blocklist_parse_push(JabberStream *js, const char *from,
xmlnode *item;
PurpleAccount *account;
gboolean is_block;
+ GSList *deny;
if (!jabber_is_own_account(js, from)) {
xmlnode *error, *x;
@@ -1801,8 +1805,8 @@ void jabber_blocklist_parse_push(JabberStream *js, const char *from,
/* Unblock everyone */
purple_debug_info("jabber", "Received unblock push. Unblocking everyone.\n");
- while (account->deny != NULL) {
- purple_privacy_deny_remove(account, account->deny->data, TRUE);
+ while ((deny = purple_account_privacy_get_denied(account)) != NULL) {
+ purple_account_privacy_deny_remove(account, deny->data, TRUE);
}
} else if (item == NULL) {
/* An empty <block/> is bogus */
@@ -1824,9 +1828,9 @@ void jabber_blocklist_parse_push(JabberStream *js, const char *from,
continue;
if (is_block)
- purple_privacy_deny_add(account, jid, TRUE);
+ purple_account_privacy_deny_add(account, jid, TRUE);
else
- purple_privacy_deny_remove(account, jid, TRUE);
+ purple_account_privacy_deny_remove(account, jid, TRUE);
}
}
@@ -1841,6 +1845,7 @@ static void jabber_blocklist_parse(JabberStream *js, const char *from,
{
xmlnode *blocklist, *item;
PurpleAccount *account;
+ GSList *deny;
blocklist = xmlnode_get_child_with_namespace(packet,
"blocklist", NS_SIMPLE_BLOCKING);
@@ -1850,19 +1855,19 @@ static void jabber_blocklist_parse(JabberStream *js, const char *from,
return;
/* This is the only privacy method supported by XEP-0191 */
- purple_account_set_privacy_type(account, PURPLE_PRIVACY_DENY_USERS);
+ purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_DENY_USERS);
/*
* TODO: When account->deny is something more than a hash table, this can
* be re-written to find the set intersection and difference.
*/
- while (account->deny)
- purple_privacy_deny_remove(account, account->deny->data, TRUE);
+ while ((deny = purple_account_privacy_get_denied(account)))
+ purple_account_privacy_deny_remove(account, deny->data, TRUE);
item = xmlnode_get_child(blocklist, "item");
while (item != NULL) {
const char *jid = xmlnode_get_attrib(item, "jid");
- purple_privacy_deny_add(account, jid, TRUE);
+ purple_account_privacy_deny_add(account, jid, TRUE);
item = xmlnode_get_next_twin(item);
}
}
@@ -2339,21 +2344,21 @@ GList *jabber_status_types(PurpleAccount *account)
{
PurpleStatusType *type;
GList *types = NULL;
- PurpleValue *priority_value;
- PurpleValue *buzz_enabled;
+ GValue *priority_value;
+ GValue *buzz_enabled;
- priority_value = purple_value_new(PURPLE_TYPE_INT);
- purple_value_set_int(priority_value, 1);
- buzz_enabled = purple_value_new(PURPLE_TYPE_BOOLEAN);
- purple_value_set_boolean(buzz_enabled, TRUE);
+ priority_value = purple_g_value_new(G_TYPE_INT);
+ g_value_set_int(priority_value, 1);
+ buzz_enabled = purple_g_value_new(G_TYPE_BOOLEAN);
+ g_value_set_boolean(buzz_enabled, TRUE);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
jabber_buddy_state_get_status_id(JABBER_BUDDY_STATE_ONLINE),
NULL, TRUE, TRUE, FALSE,
"priority", _("Priority"), priority_value,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- "mood", _("Mood"), purple_value_new(PURPLE_TYPE_STRING),
- "moodtext", _("Mood Text"), purple_value_new(PURPLE_TYPE_STRING),
- "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
+ "mood", _("Mood"), purple_g_value_new(G_TYPE_STRING),
+ "moodtext", _("Mood Text"), purple_g_value_new(G_TYPE_STRING),
+ "nick", _("Nickname"), purple_g_value_new(G_TYPE_STRING),
"buzz", _("Allow Buzz"), buzz_enabled,
NULL);
types = g_list_prepend(types, type);
@@ -2361,69 +2366,69 @@ GList *jabber_status_types(PurpleAccount *account)
type = purple_status_type_new_with_attrs(PURPLE_STATUS_MOOD,
"mood", NULL, TRUE, TRUE, TRUE,
- PURPLE_MOOD_NAME, _("Mood Name"), purple_value_new(PURPLE_TYPE_STRING),
- PURPLE_MOOD_COMMENT, _("Mood Comment"), purple_value_new(PURPLE_TYPE_STRING),
+ PURPLE_MOOD_NAME, _("Mood Name"), purple_g_value_new(G_TYPE_STRING),
+ PURPLE_MOOD_COMMENT, _("Mood Comment"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_prepend(types, type);
- priority_value = purple_value_new(PURPLE_TYPE_INT);
- purple_value_set_int(priority_value, 1);
- buzz_enabled = purple_value_new(PURPLE_TYPE_BOOLEAN);
- purple_value_set_boolean(buzz_enabled, TRUE);
+ priority_value = purple_g_value_new(G_TYPE_INT);
+ g_value_set_int(priority_value, 1);
+ buzz_enabled = purple_g_value_new(G_TYPE_BOOLEAN);
+ g_value_set_boolean(buzz_enabled, TRUE);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
jabber_buddy_state_get_status_id(JABBER_BUDDY_STATE_CHAT),
_("Chatty"), TRUE, TRUE, FALSE,
"priority", _("Priority"), priority_value,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- "mood", _("Mood"), purple_value_new(PURPLE_TYPE_STRING),
- "moodtext", _("Mood Text"), purple_value_new(PURPLE_TYPE_STRING),
- "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
+ "mood", _("Mood"), purple_g_value_new(G_TYPE_STRING),
+ "moodtext", _("Mood Text"), purple_g_value_new(G_TYPE_STRING),
+ "nick", _("Nickname"), purple_g_value_new(G_TYPE_STRING),
"buzz", _("Allow Buzz"), buzz_enabled,
NULL);
types = g_list_prepend(types, type);
- priority_value = purple_value_new(PURPLE_TYPE_INT);
- purple_value_set_int(priority_value, 0);
- buzz_enabled = purple_value_new(PURPLE_TYPE_BOOLEAN);
- purple_value_set_boolean(buzz_enabled, TRUE);
+ priority_value = purple_g_value_new(G_TYPE_INT);
+ g_value_set_int(priority_value, 0);
+ buzz_enabled = purple_g_value_new(G_TYPE_BOOLEAN);
+ g_value_set_boolean(buzz_enabled, TRUE);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY,
jabber_buddy_state_get_status_id(JABBER_BUDDY_STATE_AWAY),
NULL, TRUE, TRUE, FALSE,
"priority", _("Priority"), priority_value,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- "mood", _("Mood"), purple_value_new(PURPLE_TYPE_STRING),
- "moodtext", _("Mood Text"), purple_value_new(PURPLE_TYPE_STRING),
- "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
+ "mood", _("Mood"), purple_g_value_new(G_TYPE_STRING),
+ "moodtext", _("Mood Text"), purple_g_value_new(G_TYPE_STRING),
+ "nick", _("Nickname"), purple_g_value_new(G_TYPE_STRING),
"buzz", _("Allow Buzz"), buzz_enabled,
NULL);
types = g_list_prepend(types, type);
- priority_value = purple_value_new(PURPLE_TYPE_INT);
- purple_value_set_int(priority_value, 0);
- buzz_enabled = purple_value_new(PURPLE_TYPE_BOOLEAN);
- purple_value_set_boolean(buzz_enabled, TRUE);
+ priority_value = purple_g_value_new(G_TYPE_INT);
+ g_value_set_int(priority_value, 0);
+ buzz_enabled = purple_g_value_new(G_TYPE_BOOLEAN);
+ g_value_set_boolean(buzz_enabled, TRUE);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_EXTENDED_AWAY,
jabber_buddy_state_get_status_id(JABBER_BUDDY_STATE_XA),
NULL, TRUE, TRUE, FALSE,
"priority", _("Priority"), priority_value,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- "mood", _("Mood"), purple_value_new(PURPLE_TYPE_STRING),
- "moodtext", _("Mood Text"), purple_value_new(PURPLE_TYPE_STRING),
- "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
+ "mood", _("Mood"), purple_g_value_new(G_TYPE_STRING),
+ "moodtext", _("Mood Text"), purple_g_value_new(G_TYPE_STRING),
+ "nick", _("Nickname"), purple_g_value_new(G_TYPE_STRING),
"buzz", _("Allow Buzz"), buzz_enabled,
NULL);
types = g_list_prepend(types, type);
- priority_value = purple_value_new(PURPLE_TYPE_INT);
- purple_value_set_int(priority_value, 0);
+ priority_value = purple_g_value_new(G_TYPE_INT);
+ g_value_set_int(priority_value, 0);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE,
jabber_buddy_state_get_status_id(JABBER_BUDDY_STATE_DND),
_("Do Not Disturb"), TRUE, TRUE, FALSE,
"priority", _("Priority"), priority_value,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- "mood", _("Mood"), purple_value_new(PURPLE_TYPE_STRING),
- "moodtext", _("Mood Text"), purple_value_new(PURPLE_TYPE_STRING),
- "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
+ "mood", _("Mood"), purple_g_value_new(G_TYPE_STRING),
+ "moodtext", _("Mood Text"), purple_g_value_new(G_TYPE_STRING),
+ "nick", _("Nickname"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_prepend(types, type);
@@ -2435,21 +2440,21 @@ GList *jabber_status_types(PurpleAccount *account)
type = purple_status_type_new_with_attrs(PURPLE_STATUS_OFFLINE,
jabber_buddy_state_get_status_id(JABBER_BUDDY_STATE_UNAVAILABLE),
NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_prepend(types, type);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_TUNE,
"tune", NULL, FALSE, TRUE, TRUE,
- PURPLE_TUNE_ARTIST, _("Tune Artist"), purple_value_new(PURPLE_TYPE_STRING),
- PURPLE_TUNE_TITLE, _("Tune Title"), purple_value_new(PURPLE_TYPE_STRING),
- PURPLE_TUNE_ALBUM, _("Tune Album"), purple_value_new(PURPLE_TYPE_STRING),
- PURPLE_TUNE_GENRE, _("Tune Genre"), purple_value_new(PURPLE_TYPE_STRING),
- PURPLE_TUNE_COMMENT, _("Tune Comment"), purple_value_new(PURPLE_TYPE_STRING),
- PURPLE_TUNE_TRACK, _("Tune Track"), purple_value_new(PURPLE_TYPE_STRING),
- PURPLE_TUNE_TIME, _("Tune Time"), purple_value_new(PURPLE_TYPE_INT),
- PURPLE_TUNE_YEAR, _("Tune Year"), purple_value_new(PURPLE_TYPE_INT),
- PURPLE_TUNE_URL, _("Tune URL"), purple_value_new(PURPLE_TYPE_STRING),
+ PURPLE_TUNE_ARTIST, _("Tune Artist"), purple_g_value_new(G_TYPE_STRING),
+ PURPLE_TUNE_TITLE, _("Tune Title"), purple_g_value_new(G_TYPE_STRING),
+ PURPLE_TUNE_ALBUM, _("Tune Album"), purple_g_value_new(G_TYPE_STRING),
+ PURPLE_TUNE_GENRE, _("Tune Genre"), purple_g_value_new(G_TYPE_STRING),
+ PURPLE_TUNE_COMMENT, _("Tune Comment"), purple_g_value_new(G_TYPE_STRING),
+ PURPLE_TUNE_TRACK, _("Tune Track"), purple_g_value_new(G_TYPE_STRING),
+ PURPLE_TUNE_TIME, _("Tune Time"), purple_g_value_new(G_TYPE_INT),
+ PURPLE_TUNE_YEAR, _("Tune Year"), purple_g_value_new(G_TYPE_INT),
+ PURPLE_TUNE_URL, _("Tune URL"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_prepend(types, type);
@@ -2589,7 +2594,7 @@ PurpleChat *jabber_find_blist_chat(PurpleAccount *account, const char *name)
PurpleChat *chat = (PurpleChat*)cnode;
const char *room, *server;
GHashTable *components;
- if(!PURPLE_BLIST_NODE_IS_CHAT(cnode))
+ if(!PURPLE_IS_CHAT(cnode))
continue;
if (purple_chat_get_account(chat) != account)
@@ -2803,7 +2808,7 @@ char *jabber_parse_error(JabberStream *js,
static PurpleCmdRet jabber_cmd_chat_config(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- JabberChat *chat = jabber_chat_find_by_conv(conv);
+ JabberChat *chat = jabber_chat_find_by_conv(PURPLE_CHAT_CONVERSATION(conv));
if (!chat)
return PURPLE_CMD_RET_FAILED;
@@ -2815,7 +2820,7 @@ static PurpleCmdRet jabber_cmd_chat_config(PurpleConversation *conv,
static PurpleCmdRet jabber_cmd_chat_register(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- JabberChat *chat = jabber_chat_find_by_conv(conv);
+ JabberChat *chat = jabber_chat_find_by_conv(PURPLE_CHAT_CONVERSATION(conv));
if (!chat)
return PURPLE_CMD_RET_FAILED;
@@ -2827,7 +2832,7 @@ static PurpleCmdRet jabber_cmd_chat_register(PurpleConversation *conv,
static PurpleCmdRet jabber_cmd_chat_topic(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- JabberChat *chat = jabber_chat_find_by_conv(conv);
+ JabberChat *chat = jabber_chat_find_by_conv(PURPLE_CHAT_CONVERSATION(conv));
if (!chat)
return PURPLE_CMD_RET_FAILED;
@@ -2835,7 +2840,7 @@ static PurpleCmdRet jabber_cmd_chat_topic(PurpleConversation *conv,
if (args && args[0] && *args[0])
jabber_chat_change_topic(chat, args[0]);
else {
- const char *cur = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(conv));
+ const char *cur = purple_chat_conversation_get_topic(PURPLE_CHAT_CONVERSATION(conv));
char *buf, *tmp, *tmp2;
if (cur) {
@@ -2846,7 +2851,7 @@ static PurpleCmdRet jabber_cmd_chat_topic(PurpleConversation *conv,
g_free(tmp2);
} else
buf = g_strdup(_("No topic is set"));
- purple_conv_chat_write(PURPLE_CONV_CHAT(conv), "", buf,
+ purple_conversation_write_message(conv, "", buf,
PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG, time(NULL));
g_free(buf);
}
@@ -2857,7 +2862,7 @@ static PurpleCmdRet jabber_cmd_chat_topic(PurpleConversation *conv,
static PurpleCmdRet jabber_cmd_chat_nick(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- JabberChat *chat = jabber_chat_find_by_conv(conv);
+ JabberChat *chat = jabber_chat_find_by_conv(PURPLE_CHAT_CONVERSATION(conv));
if(!chat || !args || !args[0])
return PURPLE_CMD_RET_FAILED;
@@ -2876,7 +2881,7 @@ static PurpleCmdRet jabber_cmd_chat_nick(PurpleConversation *conv,
static PurpleCmdRet jabber_cmd_chat_part(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- JabberChat *chat = jabber_chat_find_by_conv(conv);
+ JabberChat *chat = jabber_chat_find_by_conv(PURPLE_CHAT_CONVERSATION(conv));
if (!chat)
return PURPLE_CMD_RET_FAILED;
@@ -2888,7 +2893,7 @@ static PurpleCmdRet jabber_cmd_chat_part(PurpleConversation *conv,
static PurpleCmdRet jabber_cmd_chat_ban(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- JabberChat *chat = jabber_chat_find_by_conv(conv);
+ JabberChat *chat = jabber_chat_find_by_conv(PURPLE_CHAT_CONVERSATION(conv));
if(!chat || !args || !args[0])
return PURPLE_CMD_RET_FAILED;
@@ -2904,7 +2909,7 @@ static PurpleCmdRet jabber_cmd_chat_ban(PurpleConversation *conv,
static PurpleCmdRet jabber_cmd_chat_affiliate(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- JabberChat *chat = jabber_chat_find_by_conv(conv);
+ JabberChat *chat = jabber_chat_find_by_conv(PURPLE_CHAT_CONVERSATION(conv));
if (!chat || !args || !args[0])
return PURPLE_CMD_RET_FAILED;
@@ -2940,7 +2945,7 @@ static PurpleCmdRet jabber_cmd_chat_affiliate(PurpleConversation *conv,
static PurpleCmdRet jabber_cmd_chat_role(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- JabberChat *chat = jabber_chat_find_by_conv(conv);
+ JabberChat *chat = jabber_chat_find_by_conv(PURPLE_CHAT_CONVERSATION(conv));
if (!chat || !args || !args[0])
return PURPLE_CMD_RET_FAILED;
@@ -2979,7 +2984,7 @@ static PurpleCmdRet jabber_cmd_chat_invite(PurpleConversation *conv,
return PURPLE_CMD_RET_FAILED;
jabber_chat_invite(purple_conversation_get_connection(conv),
- purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), args[1] ? args[1] : "",
+ purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv)), args[1] ? args[1] : "",
args[0]);
return PURPLE_CMD_RET_OK;
@@ -2988,7 +2993,7 @@ static PurpleCmdRet jabber_cmd_chat_invite(PurpleConversation *conv,
static PurpleCmdRet jabber_cmd_chat_join(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- JabberChat *chat = jabber_chat_find_by_conv(conv);
+ JabberChat *chat = jabber_chat_find_by_conv(PURPLE_CHAT_CONVERSATION(conv));
GHashTable *components;
JabberID *jid = NULL;
const char *room = NULL, *server = NULL, *handle = NULL;
@@ -3035,7 +3040,7 @@ static PurpleCmdRet jabber_cmd_chat_join(PurpleConversation *conv,
static PurpleCmdRet jabber_cmd_chat_kick(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- JabberChat *chat = jabber_chat_find_by_conv(conv);
+ JabberChat *chat = jabber_chat_find_by_conv(PURPLE_CHAT_CONVERSATION(conv));
if(!chat || !args || !args[0])
return PURPLE_CMD_RET_FAILED;
@@ -3051,7 +3056,7 @@ static PurpleCmdRet jabber_cmd_chat_kick(PurpleConversation *conv,
static PurpleCmdRet jabber_cmd_chat_msg(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- JabberChat *chat = jabber_chat_find_by_conv(conv);
+ JabberChat *chat = jabber_chat_find_by_conv(PURPLE_CHAT_CONVERSATION(conv));
char *who;
if (!chat)
@@ -3091,7 +3096,7 @@ static gboolean _jabber_send_buzz(JabberStream *js, const char *username, char *
JabberBuddyResource *jbr;
PurpleConnection *gc = js->gc;
PurpleBuddy *buddy =
- purple_find_buddy(purple_connection_get_account(gc), username);
+ purple_blist_find_buddy(purple_connection_get_account(gc), username);
const gchar *alias =
buddy ? purple_buddy_get_contact_alias(buddy) : username;
@@ -3151,7 +3156,7 @@ static PurpleCmdRet jabber_cmd_buzz(PurpleConversation *conv,
if (!args || !args[0]) {
/* use the buddy from conversation, if it's a one-to-one conversation */
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
who = purple_conversation_get_name(conv);
} else {
return PURPLE_CMD_RET_FAILED;
@@ -3160,7 +3165,7 @@ static PurpleCmdRet jabber_cmd_buzz(PurpleConversation *conv,
who = args[0];
}
- buddy = purple_find_buddy(account, who);
+ buddy = purple_blist_find_buddy(account, who);
if (buddy != NULL)
alias = purple_buddy_get_contact_alias(buddy);
else
@@ -3194,7 +3199,7 @@ gboolean jabber_send_attention(PurpleConnection *gc, const char *username, guint
if (!_jabber_send_buzz(js, username, &error)) {
PurpleAccount *account = purple_connection_get_account(gc);
PurpleConversation *conv =
- purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, username, account);
+ purple_conversations_find_with_account(username, account);
purple_debug_error("jabber", "jabber_send_attention: jabber_cmd_buzz failed with error: %s\n", error ? error : "(NULL)");
if (conv) {
@@ -3938,41 +3943,38 @@ void jabber_plugin_init(PurplePlugin *plugin)
/* IPC functions */
purple_plugin_ipc_register(plugin, "contact_has_feature", PURPLE_CALLBACK(jabber_ipc_contact_has_feature),
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING));
+ G_TYPE_BOOLEAN, 3,
+ PURPLE_TYPE_ACCOUNT, G_TYPE_STRING, G_TYPE_STRING);
purple_plugin_ipc_register(plugin, "add_feature", PURPLE_CALLBACK(jabber_ipc_add_feature),
purple_marshal_VOID__POINTER,
- NULL, 1,
- purple_value_new(PURPLE_TYPE_STRING));
+ G_TYPE_NONE, 1, G_TYPE_STRING);
purple_plugin_ipc_register(plugin, "register_namespace_watcher",
PURPLE_CALLBACK(jabber_iq_signal_register),
purple_marshal_VOID__POINTER_POINTER,
- NULL, 2,
- purple_value_new(PURPLE_TYPE_STRING), /* node */
- purple_value_new(PURPLE_TYPE_STRING)); /* namespace */
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING, /* node */
+ G_TYPE_STRING); /* namespace */
purple_plugin_ipc_register(plugin, "unregister_namespace_watcher",
PURPLE_CALLBACK(jabber_iq_signal_unregister),
purple_marshal_VOID__POINTER_POINTER,
- NULL, 2,
- purple_value_new(PURPLE_TYPE_STRING), /* node */
- purple_value_new(PURPLE_TYPE_STRING)); /* namespace */
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING, /* node */
+ G_TYPE_STRING); /* namespace */
purple_signal_register(plugin, "jabber-register-namespace-watcher",
purple_marshal_VOID__POINTER_POINTER,
- NULL, 2,
- purple_value_new(PURPLE_TYPE_STRING), /* node */
- purple_value_new(PURPLE_TYPE_STRING)); /* namespace */
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING, /* node */
+ G_TYPE_STRING); /* namespace */
purple_signal_register(plugin, "jabber-unregister-namespace-watcher",
purple_marshal_VOID__POINTER_POINTER,
- NULL, 2,
- purple_value_new(PURPLE_TYPE_STRING), /* node */
- purple_value_new(PURPLE_TYPE_STRING)); /* namespace */
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING, /* node */
+ G_TYPE_STRING); /* namespace */
purple_signal_connect(plugin, "jabber-register-namespace-watcher",
plugin, PURPLE_CALLBACK(jabber_iq_signal_register), NULL);
@@ -3981,14 +3983,14 @@ void jabber_plugin_init(PurplePlugin *plugin)
purple_signal_register(plugin, "jabber-receiving-xmlnode",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION),
- purple_value_new_outgoing(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_XMLNODE));
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ PURPLE_TYPE_CONNECTION,
+ G_TYPE_POINTER); /* modifiable xmlnode */
purple_signal_register(plugin, "jabber-sending-xmlnode",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION),
- purple_value_new_outgoing(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_XMLNODE));
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ PURPLE_TYPE_CONNECTION,
+ G_TYPE_POINTER); /* modifiable xmlnode */
/*
* Do not remove this or the plugin will fail. Completely. You have been
@@ -3999,45 +4001,45 @@ void jabber_plugin_init(PurplePlugin *plugin)
NULL, PURPLE_SIGNAL_PRIORITY_HIGHEST);
purple_signal_register(plugin, "jabber-sending-text",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION),
- purple_value_new_outgoing(PURPLE_TYPE_STRING));
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ PURPLE_TYPE_CONNECTION,
+ G_TYPE_POINTER); /* pointer to a string */
purple_signal_register(plugin, "jabber-receiving-message",
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER_POINTER,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 6,
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION),
- purple_value_new(PURPLE_TYPE_STRING), /* type */
- purple_value_new(PURPLE_TYPE_STRING), /* id */
- purple_value_new(PURPLE_TYPE_STRING), /* from */
- purple_value_new(PURPLE_TYPE_STRING), /* to */
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_XMLNODE));
+ G_TYPE_BOOLEAN, 6,
+ PURPLE_TYPE_CONNECTION,
+ G_TYPE_STRING, /* type */
+ G_TYPE_STRING, /* id */
+ G_TYPE_STRING, /* from */
+ G_TYPE_STRING, /* to */
+ PURPLE_TYPE_XMLNODE);
purple_signal_register(plugin, "jabber-receiving-iq",
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION),
- purple_value_new(PURPLE_TYPE_STRING), /* type */
- purple_value_new(PURPLE_TYPE_STRING), /* id */
- purple_value_new(PURPLE_TYPE_STRING), /* from */
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_XMLNODE));
+ G_TYPE_BOOLEAN, 5,
+ PURPLE_TYPE_CONNECTION,
+ G_TYPE_STRING, /* type */
+ G_TYPE_STRING, /* id */
+ G_TYPE_STRING, /* from */
+ PURPLE_TYPE_XMLNODE);
purple_signal_register(plugin, "jabber-watched-iq",
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION),
- purple_value_new(PURPLE_TYPE_STRING), /* type */
- purple_value_new(PURPLE_TYPE_STRING), /* id */
- purple_value_new(PURPLE_TYPE_STRING), /* from */
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_XMLNODE)); /* child */
+ G_TYPE_BOOLEAN, 5,
+ PURPLE_TYPE_CONNECTION,
+ G_TYPE_STRING, /* type */
+ G_TYPE_STRING, /* id */
+ G_TYPE_STRING, /* from */
+ PURPLE_TYPE_XMLNODE); /* child */
purple_signal_register(plugin, "jabber-receiving-presence",
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 4,
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION),
- purple_value_new(PURPLE_TYPE_STRING), /* type */
- purple_value_new(PURPLE_TYPE_STRING), /* from */
- purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_XMLNODE));
+ G_TYPE_BOOLEAN, 4,
+ PURPLE_TYPE_CONNECTION,
+ G_TYPE_STRING, /* type */
+ G_TYPE_STRING, /* from */
+ PURPLE_TYPE_XMLNODE);
}
void jabber_plugin_uninit(PurplePlugin *plugin)
diff --git a/libpurple/protocols/jabber/jabber.h b/libpurple/protocols/jabber/jabber.h
index ffa3556db2..fac856e920 100644
--- a/libpurple/protocols/jabber/jabber.h
+++ b/libpurple/protocols/jabber/jabber.h
@@ -56,7 +56,7 @@ typedef struct _JabberStream JabberStream;
#include <libxml/parser.h>
#include <glib.h>
-#include "circbuffer.h"
+#include "circularbuffer.h"
#include "connection.h"
#include "dnsquery.h"
#include "dnssrv.h"
@@ -191,7 +191,7 @@ struct _JabberStream
GSList *pending_buddy_info_requests;
- PurpleCircBuffer *write_buffer;
+ PurpleCircularBuffer *write_buffer;
guint writeh;
gboolean reinit;
diff --git a/libpurple/protocols/jabber/jutil.c b/libpurple/protocols/jabber/jutil.c
index b02e220197..f3835515b3 100644
--- a/libpurple/protocols/jabber/jutil.c
+++ b/libpurple/protocols/jabber/jutil.c
@@ -22,7 +22,6 @@
*/
#include "internal.h"
#include "account.h"
-#include "cipher.h"
#include "conversation.h"
#include "debug.h"
#include "server.h"
@@ -33,6 +32,10 @@
#include "presence.h"
#include "jutil.h"
+#include "ciphers/md4hash.h"
+#include "ciphers/md5hash.h"
+#include "ciphers/sha1hash.h"
+
#ifdef USE_IDN
#include <idna.h>
#include <stringprep.h>
@@ -736,25 +739,31 @@ char *
jabber_calculate_data_hash(gconstpointer data, size_t len,
const gchar *hash_algo)
{
- PurpleCipherContext *context;
+ PurpleHash *hash = NULL;
static gchar digest[129]; /* 512 bits hex + \0 */
- context = purple_cipher_context_new_by_name(hash_algo, NULL);
- if (context == NULL)
+ /* FIXME: Check the source of this change and what we need here... */
+ if (g_str_equal(hash_algo, "sha1"))
+ hash = purple_sha1_hash_new();
+ else if (g_str_equal(hash_algo, "md4"))
+ hash = purple_md4_hash_new();
+ else if (g_str_equal(hash_algo, "md5"))
+ hash = purple_md5_hash_new();
+ if (hash == NULL)
{
purple_debug_error("jabber", "Could not find %s cipher\n", hash_algo);
g_return_val_if_reached(NULL);
}
/* Hash the data */
- purple_cipher_context_append(context, data, len);
- if (!purple_cipher_context_digest_to_str(context, digest, sizeof(digest)))
+ purple_hash_append(hash, data, len);
+ if (!purple_hash_digest_to_str(hash, digest, sizeof(digest)))
{
purple_debug_error("jabber", "Failed to get digest for %s cipher.\n",
hash_algo);
g_return_val_if_reached(NULL);
}
- purple_cipher_context_destroy(context);
+ g_object_unref(G_OBJECT(hash));
return g_strdup(digest);
}
diff --git a/libpurple/protocols/jabber/libfacebook.c b/libpurple/protocols/jabber/libfacebook.c
index b426eac356..3e3f2299b7 100644
--- a/libpurple/protocols/jabber/libfacebook.c
+++ b/libpurple/protocols/jabber/libfacebook.c
@@ -112,7 +112,7 @@ static PurplePluginProtocolInfo prpl_info =
jabber_normalize, /* normalize */
jabber_set_buddy_icon, /* set_buddy_icon */
NULL, /* remove_group */
- jabber_chat_buddy_real_name, /* get_cb_real_name */
+ jabber_chat_user_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 */
@@ -229,11 +229,11 @@ static gboolean xmpp_uri_handler(const char *proto, const char *user, GHashTable
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);
+ PurpleIMConversation *im =
+ purple_im_conversation_new(acct, user);
+ purple_conversation_present(PURPLE_CONVERSATION(im));
if (body && *body)
- purple_conv_send_confirm(conv, body);
+ purple_conversation_send_confirm(PURPLE_CONVERSATION(im), body);
}
} else if (g_hash_table_lookup_extended(params, "roster", NULL, NULL)) {
char *name = g_hash_table_lookup(params, "name");
diff --git a/libpurple/protocols/jabber/libgtalk.c b/libpurple/protocols/jabber/libgtalk.c
index d52d1842c2..b2e3c3253c 100644
--- a/libpurple/protocols/jabber/libgtalk.c
+++ b/libpurple/protocols/jabber/libgtalk.c
@@ -112,7 +112,7 @@ static PurplePluginProtocolInfo prpl_info =
jabber_normalize, /* normalize */
jabber_set_buddy_icon, /* set_buddy_icon */
NULL, /* remove_group */
- jabber_chat_buddy_real_name, /* get_cb_real_name */
+ jabber_chat_user_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 */
@@ -229,11 +229,11 @@ static gboolean xmpp_uri_handler(const char *proto, const char *user, GHashTable
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);
+ PurpleIMConversation *im =
+ purple_im_conversation_new(acct, user);
+ purple_conversation_present(PURPLE_CONVERSATION(im));
if (body && *body)
- purple_conv_send_confirm(conv, body);
+ purple_conversation_send_confirm(PURPLE_CONVERSATION(im), body);
}
} else if (g_hash_table_lookup_extended(params, "roster", NULL, NULL)) {
char *name = g_hash_table_lookup(params, "name");
diff --git a/libpurple/protocols/jabber/libxmpp.c b/libpurple/protocols/jabber/libxmpp.c
index 53b7b9bd75..c76395640b 100644
--- a/libpurple/protocols/jabber/libxmpp.c
+++ b/libpurple/protocols/jabber/libxmpp.c
@@ -106,7 +106,7 @@ static PurplePluginProtocolInfo prpl_info =
jabber_normalize, /* normalize */
jabber_set_buddy_icon, /* set_buddy_icon */
NULL, /* remove_group */
- jabber_chat_buddy_real_name, /* get_cb_real_name */
+ jabber_chat_user_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 */
@@ -223,11 +223,11 @@ static gboolean xmpp_uri_handler(const char *proto, const char *user, GHashTable
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);
+ PurpleIMConversation *im =
+ purple_im_conversation_new(acct, user);
+ purple_conversation_present(PURPLE_CONVERSATION(im));
if (body && *body)
- purple_conv_send_confirm(conv, body);
+ purple_conversation_send_confirm(PURPLE_CONVERSATION(im), body);
}
} else if (g_hash_table_lookup_extended(params, "roster", NULL, NULL)) {
char *name = g_hash_table_lookup(params, "name");
diff --git a/libpurple/protocols/jabber/message.c b/libpurple/protocols/jabber/message.c
index 4bf17f0b75..8c5ee0eb98 100644
--- a/libpurple/protocols/jabber/message.c
+++ b/libpurple/protocols/jabber/message.c
@@ -79,19 +79,19 @@ static void handle_chat(JabberMessage *jm)
jbr->chat_states = JABBER_CHAT_STATES_SUPPORTED;
if(JM_STATE_COMPOSING == jm->chat_state) {
- serv_got_typing(gc, jm->from, 0, PURPLE_TYPING);
+ serv_got_typing(gc, jm->from, 0, PURPLE_IM_TYPING);
} else if(JM_STATE_PAUSED == jm->chat_state) {
- serv_got_typing(gc, jm->from, 0, PURPLE_TYPED);
+ serv_got_typing(gc, jm->from, 0, PURPLE_IM_TYPED);
} else if(JM_STATE_GONE == jm->chat_state) {
- PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
+ PurpleIMConversation *im = purple_conversations_find_im_with_account(
jm->from, account);
- if (conv && jid->node && jid->domain) {
+ if (im && jid->node && jid->domain) {
char buf[256];
PurpleBuddy *buddy;
g_snprintf(buf, sizeof(buf), "%s@%s", jid->node, jid->domain);
- if ((buddy = purple_find_buddy(account, buf))) {
+ if ((buddy = purple_blist_find_buddy(account, buf))) {
const char *who;
char *escaped;
@@ -105,7 +105,7 @@ static void handle_chat(JabberMessage *jm)
/* At some point when we restructure PurpleConversation,
* this should be able to be implemented by removing the
* user from the conversation like we do with chats now. */
- purple_conversation_write(conv, "", buf,
+ purple_conversation_write(PURPLE_CONVERSATION(im), "", buf,
PURPLE_MESSAGE_SYSTEM, time(NULL));
}
}
@@ -122,18 +122,17 @@ static void handle_chat(JabberMessage *jm)
* resource (i.e. bind/lock the conversation to this
* resource).
*
- * This works because purple_conv_im_send gets the name
+ * This works because purple_im_conversation_send gets the name
* from purple_conversation_get_name()
*/
- PurpleConversation *conv;
+ PurpleIMConversation *im;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- jm->from, account);
- if (conv && !g_str_equal(jm->from,
- purple_conversation_get_name(conv))) {
+ im = purple_conversations_find_im_with_account(jm->from, account);
+ if (im && !g_str_equal(jm->from,
+ purple_conversation_get_name(PURPLE_CONVERSATION(im)))) {
purple_debug_info("jabber", "Binding conversation to %s\n",
jm->from);
- purple_conversation_set_name(conv, jm->from);
+ purple_conversation_set_name(PURPLE_CONVERSATION(im), jm->from);
}
}
@@ -230,7 +229,7 @@ static void handle_groupchat(JabberMessage *jm)
return;
if(jm->subject) {
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(chat->conv), jid->resource,
+ purple_chat_conversation_set_topic(chat->conv, jid->resource,
jm->subject);
messageFlags |= PURPLE_MESSAGE_NO_LOG;
if(!jm->xhtml && !jm->body) {
@@ -241,7 +240,7 @@ static void handle_groupchat(JabberMessage *jm)
msg = g_strdup_printf(_("%s has set the topic to: %s"), jid->resource, tmp2);
else
msg = g_strdup_printf(_("The topic is: %s"), tmp2);
- purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), "", msg, messageFlags | PURPLE_MESSAGE_SYSTEM, jm->sent);
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat->conv), "", msg, messageFlags | PURPLE_MESSAGE_SYSTEM, jm->sent);
g_free(tmp);
g_free(tmp2);
g_free(msg);
@@ -254,7 +253,7 @@ static void handle_groupchat(JabberMessage *jm)
messageFlags | (jm->delayed ? PURPLE_MESSAGE_DELAYED : 0),
jm->xhtml ? jm->xhtml : jm->body, jm->sent);
else if(chat->muc)
- purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), "",
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat->conv), "",
jm->xhtml ? jm->xhtml : jm->body,
messageFlags | PURPLE_MESSAGE_SYSTEM, jm->sent);
}
@@ -310,7 +309,7 @@ static void handle_buzz(JabberMessage *jm) {
account = purple_connection_get_account(jm->js->gc);
- if (purple_find_buddy(account, jm->from) == NULL)
+ if (purple_blist_find_buddy(account, jm->from) == NULL)
return; /* Do not accept buzzes from unknown people */
/* xmpp only has 1 attention type, so index is 0 */
@@ -487,13 +486,13 @@ static void
jabber_message_request_data_cb(JabberData *data, gchar *alt,
gpointer userdata)
{
- PurpleConversation *conv = (PurpleConversation *) userdata;
+ PurpleConversation *conv = PURPLE_CONVERSATION(userdata);
if (data) {
- purple_conv_custom_smiley_write(conv, alt,
+ purple_conversation_custom_smiley_write(conv, alt,
jabber_data_get_data(data),
jabber_data_get_size(data));
- purple_conv_custom_smiley_close(conv, alt);
+ purple_conversation_custom_smiley_close(conv, alt);
}
g_free(alt);
@@ -619,19 +618,17 @@ void jabber_message_parse(JabberStream *js, xmlnode *packet)
if (jid) {
chat = jabber_chat_find(js, jid->node, jid->domain);
if (chat)
- conv = chat->conv;
+ conv = PURPLE_CONVERSATION(chat->conv);
jabber_id_free(jid);
}
} else if (jm->type == JABBER_MESSAGE_NORMAL ||
jm->type == JABBER_MESSAGE_CHAT) {
conv =
- purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY,
- from, account);
+ purple_conversations_find_with_account(from, account);
if (!conv) {
/* we need to create the conversation here */
- conv =
- purple_conversation_new(PURPLE_CONV_TYPE_IM,
- account, from);
+ conv = PURPLE_CONVERSATION(
+ purple_im_conversation_new(account, from));
}
}
}
@@ -662,7 +659,7 @@ void jabber_message_parse(JabberStream *js, xmlnode *packet)
purple_debug_info("jabber",
"about to add custom smiley %s to the conv\n", alt);
- if (purple_conv_custom_smiley_add(conv, alt, "cid", cid,
+ if (purple_conversation_custom_smiley_add(conv, alt, "cid", cid,
TRUE)) {
const JabberData *data =
jabber_data_find_remote_by_cid(js, from, cid);
@@ -670,10 +667,10 @@ void jabber_message_parse(JabberStream *js, xmlnode *packet)
if (data) {
purple_debug_info("jabber",
"data is already known\n");
- purple_conv_custom_smiley_write(conv, alt,
+ purple_conversation_custom_smiley_write(conv, alt,
jabber_data_get_data(data),
jabber_data_get_size(data));
- purple_conv_custom_smiley_close(conv, alt);
+ purple_conversation_custom_smiley_close(conv, alt);
} else {
/* we need to request the smiley (data) */
purple_debug_info("jabber",
@@ -906,30 +903,24 @@ jabber_conv_support_custom_smileys(JabberStream *js,
JabberBuddy *jb;
JabberChat *chat;
- switch (purple_conversation_get_type(conv)) {
- case PURPLE_CONV_TYPE_IM:
- jb = jabber_buddy_find(js, who, FALSE);
- if (jb) {
- return jabber_buddy_has_capability(jb, NS_BOB);
- } else {
- return FALSE;
- }
- break;
- case PURPLE_CONV_TYPE_CHAT:
- chat = jabber_chat_find_by_conv(conv);
- if (chat) {
- /* do not attempt to send custom smileys in a MUC with more than
- 10 people, to avoid getting too many BoB requests */
- return jabber_chat_get_num_participants(chat) <= 10 &&
- jabber_chat_all_participants_have_capability(chat,
- NS_BOB);
- } else {
- return FALSE;
- }
- break;
- default:
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ jb = jabber_buddy_find(js, who, FALSE);
+ if (jb) {
+ return jabber_buddy_has_capability(jb, NS_BOB);
+ } else {
return FALSE;
- break;
+ }
+ } else {
+ chat = jabber_chat_find_by_conv(PURPLE_CHAT_CONVERSATION(conv));
+ if (chat) {
+ /* do not attempt to send custom smileys in a MUC with more than
+ 10 people, to avoid getting too many BoB requests */
+ return jabber_chat_get_num_participants(chat) <= 10 &&
+ jabber_chat_all_participants_have_capability(chat,
+ NS_BOB);
+ } else {
+ return FALSE;
+ }
}
}
@@ -938,7 +929,7 @@ jabber_message_smileyfy_xhtml(JabberMessage *jm, const char *xhtml)
{
PurpleAccount *account = purple_connection_get_account(jm->js->gc);
PurpleConversation *conv =
- purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, jm->to,
+ purple_conversations_find_with_account(jm->to,
account);
if (jabber_conv_support_custom_smileys(jm->js, conv, jm->to)) {
@@ -1248,7 +1239,7 @@ int jabber_message_send_chat(PurpleConnection *gc, int id, const char *msg, Purp
return 1;
}
-unsigned int jabber_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state)
+unsigned int jabber_send_typing(PurpleConnection *gc, const char *who, PurpleIMTypingState state)
{
JabberStream *js;
JabberMessage *jm;
@@ -1282,9 +1273,9 @@ unsigned int jabber_send_typing(PurpleConnection *gc, const char *who, PurpleTyp
jm->to = g_strdup(who);
jm->id = jabber_get_next_id(jm->js);
- if(PURPLE_TYPING == state)
+ if(PURPLE_IM_TYPING == state)
jm->chat_state = JM_STATE_COMPOSING;
- else if(PURPLE_TYPED == state)
+ else if(PURPLE_IM_TYPED == state)
jm->chat_state = JM_STATE_PAUSED;
else
jm->chat_state = JM_STATE_ACTIVE;
diff --git a/libpurple/protocols/jabber/message.h b/libpurple/protocols/jabber/message.h
index 555f8f94b7..ee943f0117 100644
--- a/libpurple/protocols/jabber/message.h
+++ b/libpurple/protocols/jabber/message.h
@@ -73,7 +73,7 @@ int jabber_message_send_im(PurpleConnection *gc, const char *who, const char *ms
PurpleMessageFlags flags);
int jabber_message_send_chat(PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags);
-unsigned int jabber_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state);
+unsigned int jabber_send_typing(PurpleConnection *gc, const char *who, PurpleIMTypingState state);
gboolean jabber_buzz_isenabled(JabberStream *js, const gchar *namespace);
diff --git a/libpurple/protocols/jabber/parser.c b/libpurple/protocols/jabber/parser.c
index d407c634fc..8141df13c6 100644
--- a/libpurple/protocols/jabber/parser.c
+++ b/libpurple/protocols/jabber/parser.c
@@ -308,7 +308,10 @@ void jabber_parser_process(JabberStream *js, const char *buf, int len)
}
if (js->protocol_version.major == 0 && js->protocol_version.minor == 9 &&
+#if 0
+ /* FIXME Is this required here? */
!js->gc->disconnect_timeout &&
+#endif
(js->state == JABBER_STREAM_INITIALIZING ||
js->state == JABBER_STREAM_INITIALIZING_ENCRYPTION)) {
/*
diff --git a/libpurple/protocols/jabber/presence.c b/libpurple/protocols/jabber/presence.c
index 4421514a5b..5cc6633176 100644
--- a/libpurple/protocols/jabber/presence.c
+++ b/libpurple/protocols/jabber/presence.c
@@ -130,7 +130,7 @@ void jabber_presence_fake_to_self(JabberStream *js, PurpleStatus *status)
* While we need to track the status of this resource, the core
* only cares if we're on our own buddy list.
*/
- if (purple_find_buddy(account, username)) {
+ if (purple_blist_find_buddy(account, username)) {
jbr = jabber_buddy_find_resource(jb, NULL);
if (jbr) {
purple_prpl_got_user_status(account, username,
@@ -166,7 +166,7 @@ void jabber_set_status(PurpleAccount *account, PurpleStatus *status)
js = purple_connection_get_protocol_data(gc);
/* it's a mood update */
- if (purple_status_type_get_primitive(purple_status_get_type(status)) == PURPLE_STATUS_MOOD) {
+ if (purple_status_type_get_primitive(purple_status_get_status_type(status)) == PURPLE_STATUS_MOOD) {
const char *mood =
purple_status_get_attr_string(status, PURPLE_MOOD_NAME);
const char *mood_text =
@@ -540,7 +540,7 @@ static gboolean
handle_presence_chat(JabberStream *js, JabberPresence *presence, xmlnode *packet)
{
static int i = 1;
- PurpleConvChatBuddyFlags flags = PURPLE_CBFLAGS_NONE;
+ PurpleChatUserFlags flags = PURPLE_CHAT_USER_NONE;
JabberChat *chat = presence->chat;
if (presence->state == JABBER_BUDDY_STATE_ERROR) {
@@ -600,7 +600,7 @@ handle_presence_chat(JabberStream *js, JabberPresence *presence, xmlnode *packet
" you like to configure it, or"
" accept the default settings?"),
/* Default Action */ 1,
- purple_connection_get_account(js->gc), NULL, chat->conv,
+ purple_connection_get_account(js->gc), NULL, PURPLE_CONVERSATION(chat->conv),
chat, 2,
_("_Configure Room"), G_CALLBACK(jabber_chat_request_room_configure),
_("_Accept Defaults"), G_CALLBACK(jabber_chat_create_instant_room));
@@ -613,19 +613,19 @@ handle_presence_chat(JabberStream *js, JabberPresence *presence, xmlnode *packet
}
if (purple_strequal(affiliation, "owner"))
- flags |= PURPLE_CBFLAGS_FOUNDER;
+ flags |= PURPLE_CHAT_USER_FOUNDER;
if (role) {
if (g_str_equal(role, "moderator"))
- flags |= PURPLE_CBFLAGS_OP;
+ flags |= PURPLE_CHAT_USER_OP;
else if (g_str_equal(role, "participant"))
- flags |= PURPLE_CBFLAGS_VOICE;
+ flags |= PURPLE_CHAT_USER_VOICE;
}
if(!chat->conv) {
char *room_jid = g_strdup_printf("%s@%s", presence->jid_from->node, presence->jid_from->domain);
chat->id = i++;
chat->conv = serv_got_joined_chat(js->gc, chat->id, room_jid);
- purple_conv_chat_set_nick(PURPLE_CONV_CHAT(chat->conv), chat->handle);
+ purple_chat_conversation_set_nick(chat->conv, chat->handle);
jabber_chat_disco_traffic(chat);
g_free(room_jid);
@@ -637,10 +637,10 @@ handle_presence_chat(JabberStream *js, JabberPresence *presence, xmlnode *packet
jabber_chat_track_handle(chat, presence->jid_from->resource, jid, affiliation, role);
if(!jabber_chat_find_buddy(chat->conv, presence->jid_from->resource))
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(chat->conv), presence->jid_from->resource,
+ purple_chat_conversation_add_user(chat->conv, presence->jid_from->resource,
jid, flags, chat->joined > 0 && ((!presence->delayed) || (presence->sent > chat->joined)));
else
- purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(chat->conv), presence->jid_from->resource,
+ purple_chat_user_set_flags(purple_chat_conversation_find_user(chat->conv, presence->jid_from->resource),
flags);
if (is_our_resource && chat->joined == 0)
@@ -700,7 +700,7 @@ handle_presence_chat(JabberStream *js, JabberPresence *presence, xmlnode *packet
chat->handle = g_strdup(nick);
}
- purple_conv_chat_rename_user(PURPLE_CONV_CHAT(chat->conv),
+ purple_chat_conversation_rename_user(chat->conv,
presence->jid_from->resource,
nick);
jabber_chat_remove_handle(chat,
@@ -783,13 +783,13 @@ handle_presence_chat(JabberStream *js, JabberPresence *presence, xmlnode *packet
if(!nick_change) {
if (is_our_resource) {
if (kick)
- purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), presence->jid_from->resource,
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat->conv), presence->jid_from->resource,
presence->status, PURPLE_MESSAGE_SYSTEM, time(NULL));
serv_got_chat_left(js->gc, chat->id);
jabber_chat_destroy(chat);
} else {
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(chat->conv), presence->jid_from->resource,
+ purple_chat_conversation_remove_user(chat->conv, presence->jid_from->resource,
presence->status);
jabber_chat_remove_handle(chat, presence->jid_from->resource);
}
@@ -806,24 +806,23 @@ handle_presence_contact(JabberStream *js, JabberPresence *presence)
PurpleAccount *account;
PurpleBuddy *b;
char *buddy_name;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
buddy_name = jabber_id_get_bare_jid(presence->jid_from);
account = purple_connection_get_account(js->gc);
- b = purple_find_buddy(account, buddy_name);
+ b = purple_blist_find_buddy(account, buddy_name);
/*
* Unbind/unlock from sending messages to a specific resource on
* presence changes. This is locked to a specific resource when
* receiving a message (in message.c).
*/
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- buddy_name, account);
- if (conv) {
+ im = purple_conversations_find_im_with_account(buddy_name, account);
+ if (im) {
purple_debug_info("jabber", "Changed conversation binding from %s to %s\n",
- purple_conversation_get_name(conv), buddy_name);
- purple_conversation_set_name(conv, buddy_name);
+ purple_conversation_get_name(PURPLE_CONVERSATION(im)), buddy_name);
+ purple_conversation_set_name(PURPLE_CONVERSATION(im), buddy_name);
}
if (b == NULL) {
@@ -958,7 +957,7 @@ void jabber_presence_parse(JabberStream *js, xmlnode *packet)
xmlnode *nick;
account = purple_connection_get_account(js->gc);
- buddy = purple_find_buddy(account, presence.from);
+ buddy = purple_blist_find_buddy(account, presence.from);
nick = xmlnode_get_child_with_namespace(packet, "nick", "http://jabber.org/protocol/nick");
if (nick)
presence.nickname = xmlnode_get_data(nick);
diff --git a/libpurple/protocols/jabber/roster.c b/libpurple/protocols/jabber/roster.c
index 1dd565be35..8a4f4ccce9 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(purple_connection_get_account(js->gc), jid);
+ buddies = purple_blist_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(purple_connection_get_account(js->gc), jid);
+ buddies = purple_blist_find_buddies(purple_connection_get_account(js->gc), jid);
if(!groups) {
if(!buddies)
@@ -146,7 +146,7 @@ static void add_purple_buddy_to_groups(JabberStream *js, const char *jid,
serv_got_alias(js->gc, jid, servernick);
/* Alias from our roster retrieval */
- balias = purple_buddy_get_local_buddy_alias(b);
+ balias = purple_buddy_get_local_alias(b);
if(alias && !purple_strequal(alias, balias))
purple_serv_got_private_alias(js->gc, jid, alias);
g_free(l->data);
@@ -169,7 +169,7 @@ static void add_purple_buddy_to_groups(JabberStream *js, const char *jid,
}
while(groups) {
- PurpleGroup *g = purple_find_group(groups->data);
+ PurpleGroup *g = purple_blist_find_group(groups->data);
PurpleBuddy *b = purple_buddy_new(account, jid, alias);
if(!g) {
@@ -178,7 +178,7 @@ static void add_purple_buddy_to_groups(JabberStream *js, const char *jid,
}
purple_blist_add_buddy(b, NULL, g, NULL);
- purple_blist_alias_buddy(b, alias);
+ purple_buddy_set_local_alias(b, alias);
g_free(groups->data);
groups = g_slist_delete_link(groups, groups);
@@ -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(purple_connection_get_account(js->gc), name)))
+ if(!(b = purple_blist_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(purple_connection_get_account(js->gc), name);
+ GSList *buddies = purple_blist_find_buddies(purple_connection_get_account(js->gc), name);
char *tmp;
if(!buddies)
@@ -339,7 +339,7 @@ static void jabber_roster_update(JabberStream *js, const char *name,
xmlnode_set_attrib(item, "jid", name);
- balias = purple_buddy_get_local_buddy_alias(b);
+ balias = purple_buddy_get_local_alias(b);
xmlnode_set_attrib(item, "name", balias ? balias : "");
for(l = groups; l; l = l->next) {
@@ -378,7 +378,7 @@ void jabber_roster_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
return;
}
- /* Adding a chat room or a chat buddy to the roster is *not* supported. */
+ /* Adding a chat room or a chat user to the roster is *not* supported. */
if (jid->node && jabber_chat_find(js, jid->node, jid->domain) != NULL) {
/*
* This is the same thing Bonjour does. If it causes problems, move
@@ -399,7 +399,7 @@ void jabber_roster_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
* If the buddy name added contains a resource, strip that off and
* rename the buddy.
*/
- purple_blist_rename_buddy(buddy, who);
+ purple_buddy_set_name(buddy, who);
}
jb = jabber_buddy_find(js, who, FALSE);
@@ -423,10 +423,10 @@ 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(purple_connection_get_account(gc), name);
+ PurpleBuddy *b = purple_blist_find_buddy(purple_connection_get_account(gc), name);
if(b != NULL) {
- purple_blist_alias_buddy(b, alias);
+ purple_buddy_set_local_alias(b, alias);
purple_debug_info("jabber", "jabber_roster_alias_change(): Aliased %s to %s\n",
name, alias ? alias : "(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(purple_connection_get_account(gc), name);
+ buddies = purple_blist_find_buddies(purple_connection_get_account(gc), name);
while(buddies) {
b = buddies->data;
g = purple_buddy_get_group(b);
@@ -478,7 +478,7 @@ void jabber_roster_group_rename(PurpleConnection *gc, const char *old_name,
void jabber_roster_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
PurpleGroup *group) {
const char *name = purple_buddy_get_name(buddy);
- GSList *buddies = purple_find_buddies(purple_connection_get_account(gc), name);
+ GSList *buddies = purple_blist_find_buddies(purple_connection_get_account(gc), name);
buddies = g_slist_remove(buddies, buddy);
if(buddies != NULL) {
diff --git a/libpurple/protocols/jabber/si.c b/libpurple/protocols/jabber/si.c
index f36b28f060..dd039e6d63 100644
--- a/libpurple/protocols/jabber/si.c
+++ b/libpurple/protocols/jabber/si.c
@@ -24,7 +24,7 @@
#include "internal.h"
-#include "blist.h"
+#include "buddylist.h"
#include "debug.h"
#include "ft.h"
#include "request.h"
@@ -71,7 +71,7 @@ typedef struct _JabberSIXfer {
JabberIBBSession *ibb_session;
guint ibb_timeout_handle;
- PurpleCircBuffer *ibb_buffer;
+ PurpleCircularBuffer *ibb_buffer;
} JabberSIXfer;
/* some forward declarations */
@@ -1011,7 +1011,7 @@ jabber_si_xfer_ibb_recv_data_cb(JabberIBBSession *sess, gpointer data,
if (size <= purple_xfer_get_bytes_remaining(xfer)) {
purple_debug_info("jabber", "about to write %" G_GSIZE_FORMAT " bytes from IBB stream\n",
size);
- purple_circ_buffer_append(jsx->ibb_buffer, data, size);
+ purple_circular_buffer_append(jsx->ibb_buffer, data, size);
purple_xfer_prpl_ready(xfer);
} else {
/* trying to write past size of file transfers negotiated size,
@@ -1028,15 +1028,15 @@ jabber_si_xfer_ibb_read(guchar **out_buffer, PurpleXfer *xfer)
{
JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer);
guchar *buffer;
- gsize size;
+ gsize size = purple_circular_buffer_get_used(jsx->ibb_buffer);
gsize tmp;
- size = jsx->ibb_buffer->bufused;
*out_buffer = buffer = g_malloc(size);
- while ((tmp = purple_circ_buffer_get_max_read(jsx->ibb_buffer))) {
- memcpy(buffer, jsx->ibb_buffer->outptr, tmp);
+ while ((tmp = purple_circular_buffer_get_max_read(jsx->ibb_buffer))) {
+ const gchar *output = purple_circular_buffer_get_output(jsx->ibb_buffer);
+ memcpy(buffer, output, tmp);
buffer += tmp;
- purple_circ_buffer_mark_read(jsx->ibb_buffer, tmp);
+ purple_circular_buffer_mark_read(jsx->ibb_buffer, tmp);
}
return size;
@@ -1069,7 +1069,7 @@ jabber_si_xfer_ibb_open_cb(JabberStream *js, const char *who, const char *id,
clients interpreting the block-size attribute as that
(see also remark in ibb.c) */
jsx->ibb_buffer =
- purple_circ_buffer_new(jabber_ibb_session_get_block_size(sess));
+ purple_circular_buffer_new(jabber_ibb_session_get_block_size(sess));
/* set up read function */
purple_xfer_set_read_fnc(xfer, jabber_si_xfer_ibb_read);
@@ -1157,7 +1157,7 @@ jabber_si_xfer_ibb_send_init(JabberStream *js, PurpleXfer *xfer)
purple_xfer_set_write_fnc(xfer, jabber_si_xfer_ibb_write);
jsx->ibb_buffer =
- purple_circ_buffer_new(jabber_ibb_session_get_max_data_size(jsx->ibb_session));
+ purple_circular_buffer_new(jabber_ibb_session_get_max_data_size(jsx->ibb_session));
/* open the IBB session */
jabber_ibb_session_open(jsx->ibb_session);
@@ -1334,7 +1334,7 @@ static void jabber_si_xfer_free(PurpleXfer *xfer)
}
if (jsx->ibb_buffer) {
- purple_circ_buffer_destroy(jsx->ibb_buffer);
+ g_object_unref(G_OBJECT(jsx->ibb_buffer));
}
purple_debug_info("jabber", "jabber_si_xfer_free(): freeing jsx %p\n", jsx);
diff --git a/libpurple/protocols/jabber/useravatar.c b/libpurple/protocols/jabber/useravatar.c
index 914f257589..6f982bac13 100644
--- a/libpurple/protocols/jabber/useravatar.c
+++ b/libpurple/protocols/jabber/useravatar.c
@@ -325,7 +325,7 @@ do_buddy_avatar_update_data(JabberStream *js, const char *from, xmlnode *items)
static void
update_buddy_metadata(JabberStream *js, const char *from, xmlnode *items)
{
- PurpleBuddy *buddy = purple_find_buddy(purple_connection_get_account(js->gc), from);
+ PurpleBuddy *buddy = purple_blist_find_buddy(purple_connection_get_account(js->gc), from);
const char *checksum;
xmlnode *item, *metadata;
if(!buddy)
diff --git a/libpurple/protocols/msn/contact.c b/libpurple/protocols/msn/contact.c
index e5f18c230f..375b4a6855 100644
--- a/libpurple/protocols/msn/contact.c
+++ b/libpurple/protocols/msn/contact.c
@@ -616,7 +616,7 @@ msn_parse_addressbook_groups(MsnSession *session, xmlnode *node)
msn_group_new(session->userlist, group_id, group_name);
purple_debug_info("msn", "AB group_id: %s, name: %s\n", group_id, group_name ? group_name : "(null)");
- if ((purple_find_group(group_name)) == NULL) {
+ if ((purple_blist_find_group(group_name)) == NULL) {
PurpleGroup *g = purple_group_new(group_name);
purple_blist_add_group(g, NULL);
}
@@ -936,7 +936,7 @@ msn_parse_addressbook(MsnSession *session, xmlnode *node)
MSN_INDIVIDUALS_GROUP_NAME);
purple_debug_misc("msn", "AB group_id:%s name:%s\n",
MSN_INDIVIDUALS_GROUP_ID, MSN_INDIVIDUALS_GROUP_NAME);
- if ((purple_find_group(MSN_INDIVIDUALS_GROUP_NAME)) == NULL){
+ if ((purple_blist_find_group(MSN_INDIVIDUALS_GROUP_NAME)) == NULL){
PurpleGroup *g = purple_group_new(MSN_INDIVIDUALS_GROUP_NAME);
purple_blist_add_group(g, NULL);
}
@@ -944,7 +944,7 @@ msn_parse_addressbook(MsnSession *session, xmlnode *node)
/* Add a "Non-IM Contacts" group */
msn_group_new(session->userlist, MSN_NON_IM_GROUP_ID, MSN_NON_IM_GROUP_NAME);
purple_debug_misc("msn", "AB group_id:%s name:%s\n", MSN_NON_IM_GROUP_ID, MSN_NON_IM_GROUP_NAME);
- if ((purple_find_group(MSN_NON_IM_GROUP_NAME)) == NULL) {
+ if ((purple_blist_find_group(MSN_NON_IM_GROUP_NAME)) == NULL) {
PurpleGroup *g = purple_group_new(MSN_NON_IM_GROUP_NAME);
purple_blist_add_group(g, NULL);
}
@@ -1067,7 +1067,7 @@ msn_add_contact_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
purple_debug_error("msn", "Contact is from a federated domain, but don't know what to do yet!\n");
} else if (errorcode && !strcmp(errorcode, "InvalidPassportUser")) {
- PurpleBuddy *buddy = purple_find_buddy(session->account, state->who);
+ PurpleBuddy *buddy = purple_blist_find_buddy(session->account, state->who);
char *str = g_strdup_printf(_("Unable to add \"%s\"."), state->who);
purple_notify_error(state->session, _("Buddy Add error"), str,
_("The username specified does not exist."));
@@ -1163,7 +1163,7 @@ msn_add_contact_to_group_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
purple_debug_error("msn", "Contact is from a federated domain, but don't know what to do yet!\n");
} else if (errorcode && !strcmp(errorcode, "InvalidPassportUser")) {
- PurpleBuddy *buddy = purple_find_buddy(session->account, state->who);
+ PurpleBuddy *buddy = purple_blist_find_buddy(session->account, state->who);
char *str = g_strdup_printf(_("Unable to add \"%s\"."), state->who);
purple_notify_error(session, _("Buddy Add error"), str,
_("The username specified does not exist."));
@@ -1664,10 +1664,10 @@ msn_del_contact_from_list_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
msn_add_contact_to_list(session, new_state, state->who, MSN_LIST_RL);
return;
} else if (state->list_id == MSN_LIST_AL) {
- purple_privacy_permit_remove(session->account, state->who, TRUE);
+ purple_account_privacy_permit_remove(session->account, state->who, TRUE);
msn_add_contact_to_list(session, NULL, state->who, MSN_LIST_BL);
} else if (state->list_id == MSN_LIST_BL) {
- purple_privacy_deny_remove(session->account, state->who, TRUE);
+ purple_account_privacy_deny_remove(session->account, state->who, TRUE);
msn_add_contact_to_list(session, NULL, state->who, MSN_LIST_AL);
}
@@ -1764,9 +1764,9 @@ msn_add_contact_to_list_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
if (state->action & MSN_DENIED_BUDDY) {
msn_add_contact_to_list(state->session, NULL, state->who, MSN_LIST_BL);
} else if (state->list_id == MSN_LIST_AL) {
- purple_privacy_permit_add(state->session->account, state->who, TRUE);
+ purple_account_privacy_permit_add(state->session->account, state->who, TRUE);
} else if (state->list_id == MSN_LIST_BL) {
- purple_privacy_deny_add(state->session->account, state->who, TRUE);
+ purple_account_privacy_deny_add(state->session->account, state->who, TRUE);
}
}
}
diff --git a/libpurple/protocols/msn/directconn.c b/libpurple/protocols/msn/directconn.c
index f68e973f06..a22f34d9b8 100644
--- a/libpurple/protocols/msn/directconn.c
+++ b/libpurple/protocols/msn/directconn.c
@@ -23,7 +23,7 @@
*/
#include "internal.h"
-#include "cipher.h"
+#include "ciphers/sha1hash.h"
#include "debug.h"
#include "msn.h"
@@ -44,11 +44,10 @@ msn_dc_calculate_nonce_hash(MsnDirectConnNonceType type,
guchar digest[20];
if (type == DC_NONCE_SHA1) {
- PurpleCipher *cipher = purple_ciphers_find_cipher("sha1");
- PurpleCipherContext *context = purple_cipher_context_new(cipher, NULL);
- purple_cipher_context_append(context, nonce, nonce_len);
- purple_cipher_context_digest(context, digest, sizeof(digest));
- purple_cipher_context_destroy(context);
+ PurpleHash *hash = purple_sha1_hash_new();
+ purple_hash_append(hash, nonce, nonce_len);
+ purple_hash_digest(hash, digest, sizeof(digest));
+ g_object_unref(hash);
} else if (type == DC_NONCE_PLAIN) {
memcpy(digest, nonce, nonce_len);
} else {
diff --git a/libpurple/protocols/msn/directconn.h b/libpurple/protocols/msn/directconn.h
index 41a05d274e..ffffcc43e6 100644
--- a/libpurple/protocols/msn/directconn.h
+++ b/libpurple/protocols/msn/directconn.h
@@ -28,7 +28,7 @@ typedef struct _MsnDirectConn MsnDirectConn;
#include "network.h"
#include "proxy.h"
-#include "circbuffer.h"
+#include "circularbuffer.h"
#include "slp.h"
#include "slplink.h"
diff --git a/libpurple/protocols/msn/error.c b/libpurple/protocols/msn/error.c
index 18df67a8d5..df8bf1459e 100644
--- a/libpurple/protocols/msn/error.c
+++ b/libpurple/protocols/msn/error.c
@@ -290,12 +290,12 @@ msn_complete_sync_issue(MsnAddRemData *data)
PurpleGroup *group = NULL;
if (data->group != NULL)
- group = purple_find_group(data->group);
+ group = purple_blist_find_group(data->group);
if (group != NULL)
- buddy = purple_find_buddy_in_group(data->session->account, data->who, group);
+ buddy = purple_blist_find_buddy_in_group(data->session->account, data->who, group);
else
- buddy = purple_find_buddy(data->session->account, data->who);
+ buddy = purple_blist_find_buddy(data->session->account, data->who);
if (buddy != NULL)
purple_blist_remove_buddy(buddy);
diff --git a/libpurple/protocols/msn/msg.c b/libpurple/protocols/msn/msg.c
index 755bf0b21d..0d3f65b5a6 100644
--- a/libpurple/protocols/msn/msg.c
+++ b/libpurple/protocols/msn/msg.c
@@ -705,7 +705,7 @@ msn_plain_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
if (swboard->current_users > 1 ||
((swboard->conv != NULL) &&
- purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))
+ PURPLE_IS_CHAT_CONVERSATION(swboard->conv)))
{
/* If current_users is always ok as it should then there is no need to
* check if this is a chat. */
@@ -717,7 +717,7 @@ msn_plain_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
time(NULL));
if (swboard->conv == NULL)
{
- swboard->conv = purple_find_chat(gc, swboard->chat_id);
+ swboard->conv = PURPLE_CONVERSATION(purple_conversations_find_chat(gc, swboard->chat_id));
swboard->flag |= MSN_SB_FLAG_IM;
}
}
@@ -727,8 +727,8 @@ msn_plain_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
serv_got_im(gc, passport, body_final, 0, time(NULL));
if (swboard->conv == NULL)
{
- swboard->conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- passport, purple_connection_get_account(gc));
+ swboard->conv = PURPLE_CONVERSATION(purple_conversations_find_im_with_account(
+ passport, purple_connection_get_account(gc)));
swboard->flag |= MSN_SB_FLAG_IM;
}
}
@@ -758,12 +758,12 @@ msn_control_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
if (swboard->current_users == 1)
{
serv_got_typing(gc, passport, MSN_TYPING_RECV_TIMEOUT,
- PURPLE_TYPING);
+ PURPLE_IM_TYPING);
}
} else {
serv_got_typing(gc, passport, MSN_TYPING_RECV_TIMEOUT,
- PURPLE_TYPING);
+ PURPLE_IM_TYPING);
}
}
@@ -780,7 +780,7 @@ datacast_inform_user(MsnSwitchBoard *swboard, const char *who,
account = swboard->session->account;
pc = purple_account_get_connection(account);
- if ((b = purple_find_buddy(account, who)) != NULL)
+ if ((b = purple_blist_find_buddy(account, who)) != NULL)
username = g_markup_escape_text(purple_buddy_get_alias(b), -1);
else
username = g_markup_escape_text(who, -1);
@@ -795,18 +795,19 @@ datacast_inform_user(MsnSwitchBoard *swboard, const char *who,
if (swboard->conv == NULL) {
if (chat)
- swboard->conv = purple_find_chat(purple_account_get_connection(account), swboard->chat_id);
+ swboard->conv = PURPLE_CONVERSATION(purple_conversations_find_chat(
+ purple_account_get_connection(account), swboard->chat_id));
else {
- swboard->conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- who, account);
+ swboard->conv = PURPLE_CONVERSATION(purple_conversations_find_im_with_account(
+ who, account));
if (swboard->conv == NULL)
- swboard->conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, who);
+ swboard->conv = PURPLE_CONVERSATION(purple_im_conversation_new(account, who));
}
}
if (chat)
serv_got_chat_in(pc,
- purple_conv_chat_get_id(PURPLE_CONV_CHAT(swboard->conv)),
+ purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(swboard->conv)),
who, PURPLE_MESSAGE_RECV|PURPLE_MESSAGE_SYSTEM, str,
time(NULL));
else
@@ -921,8 +922,8 @@ got_emoticon(MsnSlpCall *slpcall,
instead of all at once, calling write multiple times and
close once at the very end
*/
- purple_conv_custom_smiley_write(conv, slpcall->data_info, data, size);
- purple_conv_custom_smiley_close(conv, slpcall->data_info );
+ purple_conversation_custom_smiley_write(conv, slpcall->data_info, data, size);
+ purple_conversation_custom_smiley_close(conv, slpcall->data_info );
}
if (purple_debug_is_verbose())
purple_debug_info("msn", "Got smiley: %s\n", slpcall->data_info);
@@ -996,10 +997,10 @@ void msn_emoticon_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
* the conversation doesn't exist then we cannot associate the new
* smiley with its GtkIMHtml widget. */
if (!conv) {
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, session->account, who);
+ conv = PURPLE_CONVERSATION(purple_im_conversation_new(session->account, who));
}
- if (purple_conv_custom_smiley_add(conv, smile, "sha1", sha1, TRUE)) {
+ if (purple_conversation_custom_smiley_add(conv, smile, "sha1", sha1, TRUE)) {
msn_slplink_request_object(slplink, smile, got_emoticon, NULL, obj);
}
@@ -1034,7 +1035,7 @@ msn_datacast_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
MsnSwitchBoard *swboard = cmdproc->data;
if (swboard->current_users > 1 ||
((swboard->conv != NULL) &&
- purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))
+ PURPLE_IS_CHAT_CONVERSATION(swboard->conv)))
purple_prpl_got_attention_in_chat(gc, swboard->chat_id, user, MSN_NUDGE);
else
@@ -1140,21 +1141,20 @@ msn_invite_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
purple_debug_info("msn", "Computer call\n");
if (cmdproc->session) {
- PurpleConversation *conv = NULL;
+ PurpleIMConversation *im = NULL;
gchar *from = msg->remote_user;
gchar *buf = NULL;
if (from)
- conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_IM, from,
- cmdproc->session->account);
- if (conv)
+ im = purple_conversations_find_im_with_account(
+ from, cmdproc->session->account);
+ if (im)
buf = g_strdup_printf(
_("%s sent you a voice chat "
"invite, which is not yet "
"supported."), from);
if (buf) {
- purple_conversation_write(conv, NULL, buf,
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, buf,
PURPLE_MESSAGE_SYSTEM |
PURPLE_MESSAGE_NOTIFY,
time(NULL));
diff --git a/libpurple/protocols/msn/msn.c b/libpurple/protocols/msn/msn.c
index b15424f91b..1210ff3051 100644
--- a/libpurple/protocols/msn/msn.c
+++ b/libpurple/protocols/msn/msn.c
@@ -778,7 +778,7 @@ show_send_to_mobile_cb(PurpleBlistNode *node, gpointer ignored)
PurpleAccount *account;
const char *name;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *) node;
account = purple_buddy_get_account(buddy);
@@ -814,8 +814,8 @@ msn_send_privacy(PurpleConnection *gc)
session = purple_connection_get_protocol_data(gc);
cmdproc = session->notification->cmdproc;
- if (purple_account_get_privacy_type(account) == PURPLE_PRIVACY_ALLOW_ALL ||
- purple_account_get_privacy_type(account) == PURPLE_PRIVACY_DENY_USERS)
+ if (purple_account_get_privacy_type(account) == PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL ||
+ purple_account_get_privacy_type(account) == PURPLE_ACCOUNT_PRIVACY_DENY_USERS)
trans = msn_transaction_new(cmdproc, "BLP", "%s", "AL");
else
trans = msn_transaction_new(cmdproc, "BLP", "%s", "BL");
@@ -835,7 +835,7 @@ initiate_chat_cb(PurpleBlistNode *node, gpointer data)
const char *alias;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *) node;
account = purple_buddy_get_account(buddy);
@@ -849,16 +849,17 @@ initiate_chat_cb(PurpleBlistNode *node, gpointer data)
/* TODO: This might move somewhere else, after USR might be */
swboard->chat_id = msn_switchboard_get_chat_id();
- swboard->conv = serv_got_joined_chat(gc, swboard->chat_id, "MSN Chat");
+ swboard->conv = PURPLE_CONVERSATION(serv_got_joined_chat(gc,
+ swboard->chat_id, "MSN Chat"));
swboard->flag = MSN_SB_FLAG_IM;
/* Local alias > Display name > Username */
- if ((alias = purple_account_get_alias(account)) == NULL)
+ if ((alias = purple_account_get_private_alias(account)) == NULL)
if ((alias = purple_connection_get_display_name(gc)) == NULL)
alias = purple_account_get_username(account);
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv),
- alias, NULL, PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(PURPLE_CHAT_CONVERSATION(swboard->conv),
+ alias, NULL, PURPLE_CHAT_USER_NONE, TRUE);
}
static void
@@ -1151,35 +1152,35 @@ msn_status_types(PurpleAccount *account)
status = purple_status_type_new_with_attrs(
PURPLE_STATUS_AVAILABLE, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_append(types, status);
status = purple_status_type_new_with_attrs(
PURPLE_STATUS_AWAY, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_append(types, status);
status = purple_status_type_new_with_attrs(
PURPLE_STATUS_AWAY, "brb", _("Be Right Back"), TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_append(types, status);
status = purple_status_type_new_with_attrs(
PURPLE_STATUS_UNAVAILABLE, "busy", _("Busy"), TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_append(types, status);
status = purple_status_type_new_with_attrs(
PURPLE_STATUS_UNAVAILABLE, "phone", _("On the Phone"), TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_append(types, status);
status = purple_status_type_new_with_attrs(
PURPLE_STATUS_AWAY, "lunch", _("Out to Lunch"), TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_append(types, status);
@@ -1197,11 +1198,11 @@ msn_status_types(PurpleAccount *account)
status = purple_status_type_new_with_attrs(PURPLE_STATUS_TUNE,
"tune", NULL, FALSE, TRUE, TRUE,
- PURPLE_TUNE_ARTIST, _("Tune Artist"), purple_value_new(PURPLE_TYPE_STRING),
- PURPLE_TUNE_ALBUM, _("Tune Album"), purple_value_new(PURPLE_TYPE_STRING),
- PURPLE_TUNE_TITLE, _("Tune Title"), purple_value_new(PURPLE_TYPE_STRING),
- "game", _("Game Title"), purple_value_new(PURPLE_TYPE_STRING),
- "office", _("Office Title"), purple_value_new(PURPLE_TYPE_STRING),
+ PURPLE_TUNE_ARTIST, _("Tune Artist"), purple_g_value_new(G_TYPE_STRING),
+ PURPLE_TUNE_ALBUM, _("Tune Album"), purple_g_value_new(G_TYPE_STRING),
+ PURPLE_TUNE_TITLE, _("Tune Title"), purple_g_value_new(G_TYPE_STRING),
+ "game", _("Game Title"), purple_g_value_new(G_TYPE_STRING),
+ "office", _("Office Title"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_append(types, status);
@@ -1313,7 +1314,7 @@ msn_buddy_menu(PurpleBuddy *buddy)
static GList *
msn_blist_node_menu(PurpleBlistNode *node)
{
- if(PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if(PURPLE_IS_BUDDY(node))
{
return msn_buddy_menu((PurpleBuddy *) node);
}
@@ -1356,8 +1357,8 @@ msn_login(PurpleAccount *account)
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);
+ PURPLE_CONNECTION_FLAG_HTML | PURPLE_CONNECTION_FLAG_FORMATTING_WBFO | PURPLE_CONNECTION_FLAG_NO_BGCOLOR |
+ PURPLE_CONNECTION_FLAG_NO_FONTSIZE | PURPLE_CONNECTION_FLAG_NO_URLDESC | PURPLE_CONNECTION_FLAG_ALLOW_CUSTOM_SMILEY);
msn_session_set_login_step(session, MSN_LOGIN_STEP_START);
@@ -1528,7 +1529,7 @@ msn_send_im(PurpleConnection *gc, const char *who, const char *message,
PurpleMessageFlags flags)
{
PurpleAccount *account;
- PurpleBuddy *buddy = purple_find_buddy(purple_connection_get_account(gc), who);
+ PurpleBuddy *buddy = purple_blist_find_buddy(purple_connection_get_account(gc), who);
MsnSession *session;
MsnSwitchBoard *swboard;
MsnMessage *msg;
@@ -1639,7 +1640,7 @@ msn_send_im(PurpleConnection *gc, const char *who, const char *message,
}
static unsigned int
-msn_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state)
+msn_send_typing(PurpleConnection *gc, const char *who, PurpleIMTypingState state)
{
PurpleAccount *account;
MsnSession *session;
@@ -1650,17 +1651,17 @@ msn_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state)
session = purple_connection_get_protocol_data(gc);
/*
- * TODO: I feel like this should be "if (state != PURPLE_TYPING)"
+ * TODO: I feel like this should be "if (state != PURPLE_IM_TYPING)"
* but this is how it was before, and I don't want to break
* anything. --KingAnt
*/
- if (state == PURPLE_NOT_TYPING)
+ if (state == PURPLE_IM_NOT_TYPING)
return 0;
if (!g_ascii_strcasecmp(who, purple_account_get_username(account)))
{
/* We'll just fake it, since we're sending to ourself. */
- serv_got_typing(gc, who, MSN_TYPING_RECV_TIMEOUT, PURPLE_TYPING);
+ serv_got_typing(gc, who, MSN_TYPING_RECV_TIMEOUT, PURPLE_IM_TYPING);
return MSN_TYPING_SEND_TIMEOUT;
}
@@ -1785,7 +1786,7 @@ msn_add_buddy(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group, cons
if (!msn_email_is_valid(bname)) {
gchar *buf;
buf = g_strdup_printf(_("Unable to add the buddy %s because the username is invalid. Usernames must be valid email addresses."), bname);
- if (!purple_conv_present_error(bname, account, buf))
+ if (!purple_conversation_present_error(bname, account, buf))
purple_notify_error(pc, NULL, _("Unable to Add"), buf);
g_free(buf);
@@ -1796,7 +1797,7 @@ msn_add_buddy(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group, cons
}
/* Make sure name is normalized */
- purple_blist_rename_buddy(buddy, bname);
+ purple_buddy_set_name(buddy, bname);
userlist = session->userlist;
user = msn_userlist_find_user(userlist, bname);
@@ -1970,7 +1971,7 @@ msn_chat_invite(PurpleConnection *gc, int id, const char *msg,
swboard = msn_switchboard_new(session);
msn_switchboard_request(swboard);
swboard->chat_id = id;
- swboard->conv = purple_find_chat(gc, id);
+ swboard->conv = PURPLE_CONVERSATION(purple_conversations_find_chat(gc, id));
}
swboard->flag |= MSN_SB_FLAG_IM;
@@ -2052,14 +2053,14 @@ msn_chat_send(PurpleConnection *gc, int id, const char *message, PurpleMessageFl
while (smileys) {
smile = (MsnEmoticon *)smileys->data;
emoticons = msn_msg_emoticon_add(emoticons, smile);
- if (purple_conv_custom_smiley_add(swboard->conv, smile->smile,
+ if (purple_conversation_custom_smiley_add(swboard->conv, smile->smile,
"sha1", purple_smiley_get_checksum(smile->ps),
FALSE)) {
gconstpointer data;
size_t len;
data = purple_smiley_get_data(smile->ps, &len);
- purple_conv_custom_smiley_write(swboard->conv, smile->smile, data, len);
- purple_conv_custom_smiley_close(swboard->conv, smile->smile);
+ purple_conversation_custom_smiley_write(swboard->conv, smile->smile, data, len);
+ purple_conversation_custom_smiley_close(swboard->conv, smile->smile);
}
msn_emoticon_destroy(smile);
smileys = g_slist_delete_link(smileys, smileys);
@@ -2228,7 +2229,7 @@ msn_tooltip_extract_info_text(PurpleNotifyUserInfo *user_info, MsnGetInfoData *i
{
PurpleBuddy *b;
- b = purple_find_buddy(purple_connection_get_account(info_data->gc),
+ b = purple_blist_find_buddy(purple_connection_get_account(info_data->gc),
info_data->name);
if (b)
@@ -2236,7 +2237,7 @@ msn_tooltip_extract_info_text(PurpleNotifyUserInfo *user_info, MsnGetInfoData *i
char *tmp;
const char *alias;
- alias = purple_buddy_get_local_buddy_alias(b);
+ alias = purple_buddy_get_local_alias(b);
if (alias && alias[0])
{
purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), alias);
@@ -2688,7 +2689,7 @@ msn_got_info(PurpleHttpConnection *http_conn,
char *p = strstr(url_buffer, "form id=\"SpacesSearch\" name=\"SpacesSearch\"");
* Let's see how long this one holds out for ... */
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
+ PurpleBuddy *b = purple_blist_find_buddy
(purple_connection_get_account(info_data->gc), info_data->name);
purple_notify_user_info_add_pair_html(user_info,
_("Error retrieving profile"), NULL);
@@ -2859,11 +2860,11 @@ static gboolean msn_uri_handler(const char *proto, const char *cmd, GHashTable *
if (!g_ascii_strcasecmp(cmd, "Chat")) {
char *sname = g_hash_table_lookup(params, "contact");
if (sname) {
- PurpleConversation *conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_IM, sname, acct);
- if (conv == NULL)
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, sname);
- purple_conversation_present(conv);
+ PurpleIMConversation *im = purple_conversations_find_im_with_account(
+ sname, acct);
+ if (im == NULL)
+ im = purple_im_conversation_new(acct, sname);
+ purple_conversation_present(PURPLE_CONVERSATION(im));
}
/*else
**If pidgindialogs_im() was in the core, we could use it here.
diff --git a/libpurple/protocols/msn/msnutils.c b/libpurple/protocols/msn/msnutils.c
index 38a2ffd760..9904a3efd5 100644
--- a/libpurple/protocols/msn/msnutils.c
+++ b/libpurple/protocols/msn/msnutils.c
@@ -27,7 +27,7 @@
#include "msn.h"
#include "msnutils.h"
-#include "cipher.h"
+#include "ciphers/md5hash.h"
/**************************************************************************
* Util
@@ -542,8 +542,7 @@ msn_email_is_valid(const char *passport)
void
msn_handle_chl(char *input, char *output)
{
- PurpleCipher *cipher;
- PurpleCipherContext *context;
+ PurpleHash *hash;
const guchar productKey[] = MSNP15_WLM_PRODUCT_KEY;
const guchar productID[] = MSNP15_WLM_PRODUCT_ID;
const char hexChars[] = "0123456789abcdef";
@@ -560,13 +559,12 @@ msn_handle_chl(char *input, char *output)
int i;
/* Create the MD5 hash by using Purple MD5 algorithm */
- cipher = purple_ciphers_find_cipher("md5");
- context = purple_cipher_context_new(cipher, NULL);
+ hash = purple_md5_hash_new();
- purple_cipher_context_append(context, (guchar *)input, strlen(input));
- purple_cipher_context_append(context, productKey, sizeof(productKey) - 1);
- purple_cipher_context_digest(context, md5Hash, sizeof(md5Hash));
- purple_cipher_context_destroy(context);
+ purple_hash_append(hash, (guchar *)input, strlen(input));
+ purple_hash_append(hash, productKey, sizeof(productKey) - 1);
+ purple_hash_digest(hash, md5Hash, sizeof(md5Hash));
+ g_object_unref(hash);
/* Split it into four integers */
md5Parts = (unsigned int *)md5Hash;
diff --git a/libpurple/protocols/msn/nexus.c b/libpurple/protocols/msn/nexus.c
index 576fbf6c14..de61681fd8 100644
--- a/libpurple/protocols/msn/nexus.c
+++ b/libpurple/protocols/msn/nexus.c
@@ -23,7 +23,6 @@
*/
#include "internal.h"
-#include "cipher.h"
#include "debug.h"
#include "msnutils.h"
@@ -31,6 +30,10 @@
#include "nexus.h"
#include "notification.h"
+#include "ciphers/des3cipher.h"
+#include "ciphers/hmaccipher.h"
+#include "ciphers/sha1hash.h"
+
/**************************************************************************
* Valid Ticket Tokens
**************************************************************************/
@@ -99,35 +102,37 @@ rps_create_key(const char *key, int key_len, const char *data, size_t data_len)
const guchar magic[] = "WS-SecureConversation";
const int magic_len = sizeof(magic) - 1;
- PurpleCipherContext *hmac;
+ PurpleCipher *hmac;
+ PurpleHash *hash;
guchar hash1[20], hash2[20], hash3[20], hash4[20];
char *result;
- hmac = purple_cipher_context_new_by_name("hmac", NULL);
- purple_cipher_context_set_option(hmac, "hash", "sha1");
- purple_cipher_context_set_key(hmac, (guchar *)key, key_len);
+ hash = purple_sha1_hash_new();
+ hmac = purple_hmac_cipher_new(hash);
+ purple_cipher_set_key(hmac, (guchar *)key, key_len);
- purple_cipher_context_append(hmac, magic, magic_len);
- purple_cipher_context_append(hmac, (guchar *)data, data_len);
- purple_cipher_context_digest(hmac, hash1, sizeof(hash1));
+ purple_cipher_append(hmac, magic, magic_len);
+ purple_cipher_append(hmac, (guchar *)data, data_len);
+ purple_cipher_digest(hmac, hash1, sizeof(hash1));
- purple_cipher_context_reset_state(hmac, NULL);
- purple_cipher_context_append(hmac, hash1, 20);
- purple_cipher_context_append(hmac, magic, magic_len);
- purple_cipher_context_append(hmac, (guchar *)data, data_len);
- purple_cipher_context_digest(hmac, hash2, sizeof(hash2));
+ purple_cipher_reset_state(hmac);
+ purple_cipher_append(hmac, hash1, 20);
+ purple_cipher_append(hmac, magic, magic_len);
+ purple_cipher_append(hmac, (guchar *)data, data_len);
+ purple_cipher_digest(hmac, hash2, sizeof(hash2));
- purple_cipher_context_reset_state(hmac, NULL);
- purple_cipher_context_append(hmac, hash1, 20);
- purple_cipher_context_digest(hmac, hash3, sizeof(hash3));
+ purple_cipher_reset_state(hmac);
+ purple_cipher_append(hmac, hash1, 20);
+ purple_cipher_digest(hmac, hash3, sizeof(hash3));
- purple_cipher_context_reset_state(hmac, NULL);
- purple_cipher_context_append(hmac, hash3, sizeof(hash3));
- purple_cipher_context_append(hmac, magic, magic_len);
- purple_cipher_context_append(hmac, (guchar *)data, data_len);
- purple_cipher_context_digest(hmac, hash4, sizeof(hash4));
+ purple_cipher_reset_state(hmac);
+ purple_cipher_append(hmac, hash3, sizeof(hash3));
+ purple_cipher_append(hmac, magic, magic_len);
+ purple_cipher_append(hmac, (guchar *)data, data_len);
+ purple_cipher_digest(hmac, hash4, sizeof(hash4));
- purple_cipher_context_destroy(hmac);
+ g_object_unref(hmac);
+ g_object_unref(hash);
result = g_malloc(24);
memcpy(result, hash2, sizeof(hash2));
@@ -139,21 +144,21 @@ rps_create_key(const char *key, int key_len, const char *data, size_t data_len)
static char *
des3_cbc(const char *key, const char *iv, const char *data, int len, gboolean decrypt)
{
- PurpleCipherContext *des3;
+ PurpleCipher *des3;
char *out;
- des3 = purple_cipher_context_new_by_name("des3", NULL);
- purple_cipher_context_set_key(des3, (guchar *)key, 24);
- purple_cipher_context_set_batch_mode(des3, PURPLE_CIPHER_BATCH_MODE_CBC);
- purple_cipher_context_set_iv(des3, (guchar *)iv, 8);
+ des3 = purple_des3_cipher_new();
+ purple_cipher_set_key(des3, (guchar *)key, 24);
+ purple_cipher_set_batch_mode(des3, PURPLE_CIPHER_BATCH_MODE_CBC);
+ purple_cipher_set_iv(des3, (guchar *)iv, 8);
out = g_malloc(len);
if (decrypt)
- purple_cipher_context_decrypt(des3, (guchar *)data, len, (guchar *)out, len);
+ purple_cipher_decrypt(des3, (guchar *)data, len, (guchar *)out, len);
else
- purple_cipher_context_encrypt(des3, (guchar *)data, len, (guchar *)out, len);
+ purple_cipher_encrypt(des3, (guchar *)data, len, (guchar *)out, len);
- purple_cipher_context_destroy(des3);
+ g_object_unref(des3);
return out;
}
@@ -168,7 +173,8 @@ msn_rps_encrypt(MsnNexus *nexus)
char usr_key_base[MSN_USER_KEY_SIZE], *usr_key;
const char magic1[] = "SESSION KEY HASH";
const char magic2[] = "SESSION KEY ENCRYPTION";
- PurpleCipherContext *hmac;
+ PurpleCipher *hmac;
+ PurpleHash *hasher;
size_t len;
guchar *hash;
char *key1, *key2, *key3;
@@ -199,12 +205,13 @@ msn_rps_encrypt(MsnNexus *nexus)
key3 = rps_create_key(key1, key1_len, magic2, sizeof(magic2) - 1);
len = strlen(nexus->nonce);
- hmac = purple_cipher_context_new_by_name("hmac", NULL);
- purple_cipher_context_set_option(hmac, "hash", "sha1");
- purple_cipher_context_set_key(hmac, (guchar *)key2, 24);
- purple_cipher_context_append(hmac, (guchar *)nexus->nonce, len);
- purple_cipher_context_digest(hmac, hash, 20);
- purple_cipher_context_destroy(hmac);
+ hasher = purple_sha1_hash_new();
+ hmac = purple_hmac_cipher_new(hasher);
+ purple_cipher_set_key(hmac, (guchar *)key2, 24);
+ purple_cipher_append(hmac, (guchar *)nexus->nonce, len);
+ purple_cipher_digest(hmac, hash, 20);
+ g_object_unref(hmac);
+ g_object_unref(hasher);
/* We need to pad this to 72 bytes, apparently */
nonce_fixed = g_malloc(len + 8);
@@ -507,8 +514,8 @@ msn_nexus_update_token(MsnNexus *nexus, int id, GSourceFunc cb, gpointer data)
MsnSession *session = nexus->session;
MsnNexusUpdateData *ud;
MsnNexusUpdateCallback *update;
- PurpleCipherContext *sha1;
- PurpleCipherContext *hmac;
+ PurpleHash *sha1;
+ PurpleCipher *hmac;
char *key;
@@ -558,7 +565,7 @@ msn_nexus_update_token(MsnNexus *nexus, int id, GSourceFunc cb, gpointer data)
ud->nexus = nexus;
ud->id = id;
- sha1 = purple_cipher_context_new_by_name("sha1", NULL);
+ sha1 = purple_sha1_hash_new();
domain = g_strdup_printf(MSN_SSO_RST_TEMPLATE,
id,
@@ -566,8 +573,8 @@ msn_nexus_update_token(MsnNexus *nexus, int id, GSourceFunc cb, gpointer data)
ticket_domains[id][SSO_VALID_TICKET_POLICY] != NULL ?
ticket_domains[id][SSO_VALID_TICKET_POLICY] :
nexus->policy);
- purple_cipher_context_append(sha1, (guchar *)domain, strlen(domain));
- purple_cipher_context_digest(sha1, digest, 20);
+ purple_hash_append(sha1, (guchar *)domain, strlen(domain));
+ purple_hash_digest(sha1, digest, 20);
domain_b64 = purple_base64_encode(digest, 20);
now = time(NULL);
@@ -578,13 +585,13 @@ msn_nexus_update_token(MsnNexus *nexus, int id, GSourceFunc cb, gpointer data)
timestamp = g_strdup_printf(MSN_SSO_TIMESTAMP_TEMPLATE,
now_str,
purple_utf8_strftime("%Y-%m-%dT%H:%M:%SZ", tm));
- purple_cipher_context_reset(sha1, NULL);
- purple_cipher_context_append(sha1, (guchar *)timestamp, strlen(timestamp));
- purple_cipher_context_digest(sha1, digest, 20);
+ purple_hash_reset(sha1);
+ purple_hash_append(sha1, (guchar *)timestamp, strlen(timestamp));
+ purple_hash_digest(sha1, digest, 20);
timestamp_b64 = purple_base64_encode(digest, 20);
g_free(now_str);
- purple_cipher_context_destroy(sha1);
+ purple_hash_reset(sha1);
signedinfo = g_strdup_printf(MSN_SSO_SIGNEDINFO_TEMPLATE,
id,
@@ -596,12 +603,14 @@ msn_nexus_update_token(MsnNexus *nexus, int id, GSourceFunc cb, gpointer data)
nonce_b64 = purple_base64_encode((guchar *)&nonce, sizeof(nonce));
key = rps_create_key(nexus->secret, 24, (char *)nonce, sizeof(nonce));
- hmac = purple_cipher_context_new_by_name("hmac", NULL);
- purple_cipher_context_set_option(hmac, "hash", "sha1");
- purple_cipher_context_set_key(hmac, (guchar *)key, 24);
- purple_cipher_context_append(hmac, (guchar *)signedinfo, strlen(signedinfo));
- purple_cipher_context_digest(hmac, signature, 20);
- purple_cipher_context_destroy(hmac);
+ hmac = purple_hmac_cipher_new(sha1);
+ purple_cipher_set_key(hmac, (guchar *)key, 24);
+ purple_cipher_append(hmac, (guchar *)signedinfo, strlen(signedinfo));
+ purple_cipher_digest(hmac, signature, 20);
+
+ g_object_unref(hmac);
+ g_object_unref(sha1);
+
signature_b64 = purple_base64_encode(signature, 20);
request = g_strdup_printf(MSN_SSO_TOKEN_UPDATE_TEMPLATE,
diff --git a/libpurple/protocols/msn/notification.c b/libpurple/protocols/msn/notification.c
index 969e6af088..37c99c9373 100644
--- a/libpurple/protocols/msn/notification.c
+++ b/libpurple/protocols/msn/notification.c
@@ -23,7 +23,7 @@
*/
#include "internal.h"
-#include "cipher.h"
+#include "ciphers/md5hash.h"
#include "core.h"
#include "debug.h"
@@ -1202,8 +1202,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, purple_connection_get_account(gc));
+ = purple_conversations_find_with_account(who, purple_connection_get_account(gc));
if (conv != NULL) {
const char *error;
if (!strcmp(id, "407"))
@@ -1394,7 +1393,7 @@ url_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
PurpleAccount *account;
const char *rru;
const char *url;
- PurpleCipherContext *cipher;
+ PurpleHash *hash;
gchar creds[33];
char *buf;
@@ -1415,10 +1414,10 @@ url_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
tmp_timestamp,
purple_connection_get_password(gc));
- cipher = purple_cipher_context_new_by_name("md5", NULL);
- purple_cipher_context_append(cipher, (const guchar *)buf, strlen(buf));
- purple_cipher_context_digest_to_str(cipher, creds, sizeof(creds));
- purple_cipher_context_destroy(cipher);
+ hash = purple_md5_hash_new();
+ purple_hash_append(hash, (const guchar *)buf, strlen(buf));
+ purple_hash_digest_to_str(hash, creds, sizeof(creds));
+ g_object_unref(hash);
g_free(buf);
g_free(session->passport_info.mail_url);
diff --git a/libpurple/protocols/msn/object.c b/libpurple/protocols/msn/object.c
index 7952f82838..c20065c4c9 100644
--- a/libpurple/protocols/msn/object.c
+++ b/libpurple/protocols/msn/object.c
@@ -26,7 +26,7 @@
#include "object.h"
#include "debug.h"
/* Sha1 stuff */
-#include "cipher.h"
+#include "ciphers/sha1hash.h"
/* Base64 stuff */
#include "util.h"
@@ -130,7 +130,7 @@ msn_object_new_from_image(PurpleStoredImage *img, const char *location,
{
MsnObject *msnobj;
- PurpleCipherContext *ctx;
+ PurpleHash *hash;
char *buf;
gconstpointer data;
size_t size;
@@ -157,9 +157,9 @@ msn_object_new_from_image(PurpleStoredImage *img, const char *location,
/* Compute the SHA1D field. */
memset(digest, 0, sizeof(digest));
- ctx = purple_cipher_context_new_by_name("sha1", NULL);
- purple_cipher_context_append(ctx, data, size);
- purple_cipher_context_digest(ctx, digest, sizeof(digest));
+ hash = purple_sha1_hash_new();
+ purple_hash_append(hash, data, size);
+ purple_hash_digest(hash, digest, sizeof(digest));
base64 = purple_base64_encode(digest, sizeof(digest));
msn_object_set_sha1d(msnobj, base64);
@@ -179,10 +179,10 @@ msn_object_new_from_image(PurpleStoredImage *img, const char *location,
memset(digest, 0, sizeof(digest));
- purple_cipher_context_reset(ctx, NULL);
- purple_cipher_context_append(ctx, (const guchar *)buf, strlen(buf));
- purple_cipher_context_digest(ctx, digest, sizeof(digest));
- purple_cipher_context_destroy(ctx);
+ purple_hash_reset(hash);
+ purple_hash_append(hash, (const guchar *)buf, strlen(buf));
+ purple_hash_digest(hash, digest, sizeof(digest));
+ g_object_unref(hash);
g_free(buf);
base64 = purple_base64_encode(digest, sizeof(digest));
diff --git a/libpurple/protocols/msn/servconn.c b/libpurple/protocols/msn/servconn.c
index 8a2eb3e463..8427a8564f 100644
--- a/libpurple/protocols/msn/servconn.c
+++ b/libpurple/protocols/msn/servconn.c
@@ -53,7 +53,7 @@ msn_servconn_new(MsnSession *session, MsnServConnType type)
servconn->num = session->servconns_count++;
- servconn->tx_buf = purple_circ_buffer_new(MSN_BUF_LEN);
+ servconn->tx_buf = purple_circular_buffer_new(MSN_BUF_LEN);
servconn->tx_handler = 0;
servconn->timeout_sec = 0;
servconn->timeout_handle = 0;
@@ -84,7 +84,7 @@ msn_servconn_destroy(MsnServConn *servconn)
g_free(servconn->host);
- purple_circ_buffer_destroy(servconn->tx_buf);
+ g_object_unref(G_OBJECT(servconn->tx_buf));
if (servconn->tx_handler > 0)
purple_input_remove(servconn->tx_handler);
if (servconn->timeout_handle > 0)
@@ -331,8 +331,10 @@ servconn_write_cb(gpointer data, gint source, PurpleInputCondition cond)
MsnServConn *servconn = data;
gssize ret;
int writelen;
+ const gchar *output = NULL;
- writelen = purple_circ_buffer_get_max_read(servconn->tx_buf);
+ writelen = purple_circular_buffer_get_max_read(servconn->tx_buf);
+ output = purple_circular_buffer_get_output(servconn->tx_buf);
if (writelen == 0) {
purple_input_remove(servconn->tx_handler);
@@ -340,7 +342,7 @@ servconn_write_cb(gpointer data, gint source, PurpleInputCondition cond)
return;
}
- ret = write(servconn->fd, servconn->tx_buf->outptr, writelen);
+ ret = write(servconn->fd, output, writelen);
if (ret < 0 && errno == EAGAIN)
return;
@@ -349,7 +351,7 @@ servconn_write_cb(gpointer data, gint source, PurpleInputCondition cond)
return;
}
- purple_circ_buffer_mark_read(servconn->tx_buf, ret);
+ purple_circular_buffer_mark_read(servconn->tx_buf, ret);
servconn_timeout_renew(servconn);
}
@@ -391,7 +393,7 @@ msn_servconn_write(MsnServConn *servconn, const char *buf, size_t len)
servconn->tx_handler = purple_input_add(
servconn->fd, PURPLE_INPUT_WRITE,
servconn_write_cb, servconn);
- purple_circ_buffer_append(servconn->tx_buf, buf + ret,
+ purple_circular_buffer_append(servconn->tx_buf, buf + ret,
len - ret);
}
}
diff --git a/libpurple/protocols/msn/servconn.h b/libpurple/protocols/msn/servconn.h
index 88e6d32133..833a457137 100644
--- a/libpurple/protocols/msn/servconn.h
+++ b/libpurple/protocols/msn/servconn.h
@@ -24,7 +24,7 @@
#ifndef MSN_SERVCONN_H
#define MSN_SERVCONN_H
-#include "circbuffer.h"
+#include "circularbuffer.h"
typedef struct _MsnServConn MsnServConn;
@@ -87,7 +87,7 @@ struct _MsnServConn
It's only set when we've received a command that
has a payload. */
- PurpleCircBuffer *tx_buf;
+ PurpleCircularBuffer *tx_buf;
guint tx_handler;
guint timeout_sec;
guint timeout_handle;
diff --git a/libpurple/protocols/msn/session.c b/libpurple/protocols/msn/session.c
index 01cac2ae20..76a016342d 100644
--- a/libpurple/protocols/msn/session.c
+++ b/libpurple/protocols/msn/session.c
@@ -174,21 +174,20 @@ msn_session_find_swboard(MsnSession *session, const char *username)
return NULL;
}
-static PurpleConversation *
-msn_session_get_conv(MsnSession *session,const char *passport)
+static PurpleIMConversation *
+msn_session_get_im(MsnSession *session,const char *passport)
{
PurpleAccount *account;
- PurpleConversation * conv;
+ PurpleIMConversation * im;
g_return_val_if_fail(session != NULL, NULL);
account = session->account;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- passport, account);
- if(conv == NULL){
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, passport);
+ im = purple_conversations_find_im_with_account(passport, account);
+ if(im == NULL){
+ im = purple_im_conversation_new(account, passport);
}
- return conv;
+ return im;
}
/* put Message to User Conversation
@@ -198,10 +197,10 @@ msn_session_get_conv(MsnSession *session,const char *passport)
void
msn_session_report_user(MsnSession *session,const char *passport,const char *msg,PurpleMessageFlags flags)
{
- PurpleConversation * conv;
+ PurpleIMConversation * im;
- if ((conv = msn_session_get_conv(session,passport)) != NULL){
- purple_conversation_write(conv, NULL, msg, flags, time(NULL));
+ if ((im = msn_session_get_im(session,passport)) != NULL){
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, msg, flags, time(NULL));
}
}
@@ -309,7 +308,7 @@ msn_session_sync_users(MsnSession *session)
* being logged in. This no longer happens, so we manually iterate
* over the whole buddy list to identify sync issues.
*/
- for (buddies = purple_find_buddies(session->account, NULL); buddies;
+ for (buddies = purple_blist_find_buddies(session->account, NULL); buddies;
buddies = g_slist_delete_link(buddies, buddies)) {
PurpleBuddy *buddy = buddies->data;
const gchar *buddy_name = purple_buddy_get_name(buddy);
@@ -483,7 +482,7 @@ msn_session_finish_login(MsnSession *session)
purple_imgstore_unref(img);
session->logged_in = TRUE;
- purple_connection_set_state(gc, PURPLE_CONNECTED);
+ purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED);
/* Sync users */
msn_session_sync_users(session);
diff --git a/libpurple/protocols/msn/slpcall.c b/libpurple/protocols/msn/slpcall.c
index 2a98e80384..c1eb81aeb6 100644
--- a/libpurple/protocols/msn/slpcall.c
+++ b/libpurple/protocols/msn/slpcall.c
@@ -566,18 +566,17 @@ got_sessionreq(MsnSlpCall *slpcall, const char *branch,
} else if (!strcmp(euf_guid, MSN_CAM_REQUEST_GUID)) {
purple_debug_info("msn", "Cam request.\n");
if (slpcall->slplink && slpcall->slplink->session) {
- PurpleConversation *conv;
+ PurpleIMConversation *im;
gchar *from = slpcall->slplink->remote_user;
- conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_IM, from,
- slpcall->slplink->session->account);
- if (conv) {
+ im = purple_conversations_find_im_with_account(
+ from, slpcall->slplink->session->account);
+ if (im) {
char *buf;
buf = g_strdup_printf(
_("%s requests to view your "
"webcam, but this request is "
"not yet supported."), from);
- purple_conversation_write(conv, NULL, buf,
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, buf,
PURPLE_MESSAGE_SYSTEM |
PURPLE_MESSAGE_NOTIFY,
time(NULL));
@@ -588,17 +587,16 @@ got_sessionreq(MsnSlpCall *slpcall, const char *branch,
} else if (!strcmp(euf_guid, MSN_CAM_GUID)) {
purple_debug_info("msn", "Cam invite.\n");
if (slpcall->slplink && slpcall->slplink->session) {
- PurpleConversation *conv;
+ PurpleIMConversation *im;
gchar *from = slpcall->slplink->remote_user;
- conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_IM, from,
- slpcall->slplink->session->account);
- if (conv) {
+ im = purple_conversations_find_im_with_account(
+ from, slpcall->slplink->session->account);
+ if (im) {
char *buf;
buf = g_strdup_printf(
_("%s invited you to view his/her webcam, but "
"this is not yet supported."), from);
- purple_conversation_write(conv, NULL, buf,
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, buf,
PURPLE_MESSAGE_SYSTEM |
PURPLE_MESSAGE_NOTIFY,
time(NULL));
diff --git a/libpurple/protocols/msn/switchboard.c b/libpurple/protocols/msn/switchboard.c
index 74d684a1aa..efc939660a 100644
--- a/libpurple/protocols/msn/switchboard.c
+++ b/libpurple/protocols/msn/switchboard.c
@@ -288,18 +288,17 @@ msn_switchboard_add_user(MsnSwitchBoard *swboard, const char *user)
return;
}
- if ((swboard->conv != NULL) &&
- (purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))
+ if ((swboard->conv != NULL) && (PURPLE_IS_CHAT_CONVERSATION(swboard->conv)))
{
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv), msnuser->passport, NULL,
- PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(PURPLE_CHAT_CONVERSATION(swboard->conv),
+ msnuser->passport, NULL, PURPLE_CHAT_USER_NONE, TRUE);
msn_servconn_set_idle_timeout(swboard->servconn, 0);
}
else if (swboard->current_users > 1)
{
msn_servconn_set_idle_timeout(swboard->servconn, 0);
if (swboard->conv == NULL ||
- purple_conversation_get_type(swboard->conv) != PURPLE_CONV_TYPE_CHAT)
+ PURPLE_IS_IM_CONVERSATION(swboard->conv))
{
GList *l;
@@ -312,9 +311,9 @@ 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(purple_account_get_connection(account),
+ swboard->conv = PURPLE_CONVERSATION(serv_got_joined_chat(purple_account_get_connection(account),
swboard->chat_id,
- "MSN Chat");
+ "MSN Chat"));
for (l = swboard->users; l != NULL; l = l->next)
{
@@ -322,13 +321,13 @@ msn_switchboard_add_user(MsnSwitchBoard *swboard, const char *user)
tmp_user = ((MsnUser*)l->data)->passport;
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv),
- tmp_user, NULL, PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(PURPLE_CHAT_CONVERSATION(swboard->conv),
+ tmp_user, NULL, PURPLE_CHAT_USER_NONE, TRUE);
}
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv),
+ purple_chat_conversation_add_user(PURPLE_CHAT_CONVERSATION(swboard->conv),
purple_account_get_username(account),
- NULL, PURPLE_CBFLAGS_NONE, TRUE);
+ NULL, PURPLE_CHAT_USER_NONE, TRUE);
g_free(swboard->im_user);
swboard->im_user = NULL;
@@ -336,8 +335,8 @@ msn_switchboard_add_user(MsnSwitchBoard *swboard, const char *user)
}
else if (swboard->conv == NULL)
{
- swboard->conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- msnuser->passport, account);
+ swboard->conv = PURPLE_CONVERSATION(purple_conversations_find_im_with_account(
+ msnuser->passport, account));
}
else
{
@@ -359,8 +358,8 @@ msn_switchboard_get_conv(MsnSwitchBoard *swboard)
account = swboard->session->account;
- return (swboard->conv = purple_conversation_new(PURPLE_CONV_TYPE_IM,
- account, swboard->im_user));
+ return (swboard->conv = PURPLE_CONVERSATION(purple_im_conversation_new(
+ account, swboard->im_user)));
}
static void
@@ -618,11 +617,11 @@ bye_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
msn_switchboard_destroy(swboard);
}
else if ((swboard->current_users > 1) ||
- (purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))
+ PURPLE_IS_CHAT_CONVERSATION(swboard->conv))
{
GList *passport;
/* This is a switchboard used for a chat */
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(swboard->conv), user, NULL);
+ purple_chat_conversation_remove_user(PURPLE_CHAT_CONVERSATION(swboard->conv), user, NULL);
passport = g_list_find_custom(swboard->users, user, (GCompareFunc)strcmp);
if (passport)
@@ -833,7 +832,7 @@ msn_switchboard_show_ink(MsnSwitchBoard *swboard, const char *passport,
if (swboard->current_users > 1 ||
((swboard->conv != NULL) &&
- purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))
+ PURPLE_IS_CHAT_CONVERSATION(swboard->conv)))
serv_got_chat_in(gc, swboard->chat_id, passport, 0, image_msg,
time(NULL));
else
diff --git a/libpurple/protocols/msn/user.c b/libpurple/protocols/msn/user.c
index ab86b5974f..70ab08b8c9 100644
--- a/libpurple/protocols/msn/user.c
+++ b/libpurple/protocols/msn/user.c
@@ -369,7 +369,7 @@ msn_user_add_group_id(MsnUser *user, const char* group_id)
purple_debug_info("msn", "User: group id:%s,name:%s,user:%s\n", group_id, group_name, passport);
- g = purple_find_group(group_name);
+ g = purple_blist_find_group(group_name);
if ((group_id == NULL) && (g == NULL))
{
@@ -377,7 +377,7 @@ msn_user_add_group_id(MsnUser *user, const char* group_id)
purple_blist_add_group(g, NULL);
}
- b = purple_find_buddy_in_group(account, passport, g);
+ b = purple_blist_find_buddy_in_group(account, passport, g);
if (b == NULL)
{
b = purple_buddy_new(account, passport, NULL);
@@ -393,7 +393,7 @@ msn_user_is_online(PurpleAccount *account, const char *name)
{
PurpleBuddy *buddy;
- buddy = purple_find_buddy(account, name);
+ buddy = purple_blist_find_buddy(account, name);
return PURPLE_BUDDY_IS_ONLINE(buddy);
}
@@ -530,7 +530,7 @@ buddy_icon_cached(PurpleConnection *gc, MsnObject *obj)
account = purple_connection_get_account(gc);
- buddy = purple_find_buddy(account, msn_object_get_creator(obj));
+ buddy = purple_blist_find_buddy(account, msn_object_get_creator(obj));
if (buddy == NULL)
return FALSE;
diff --git a/libpurple/protocols/msn/userlist.c b/libpurple/protocols/msn/userlist.c
index 769d6579bf..b7304c4acb 100644
--- a/libpurple/protocols/msn/userlist.c
+++ b/libpurple/protocols/msn/userlist.c
@@ -59,8 +59,8 @@ msn_accept_add_cb(const char *message, gpointer data)
PurpleAccount *account = purple_connection_get_account(pa->gc);
msn_userlist_add_buddy_to_list(userlist, pa->who, MSN_LIST_AL);
- purple_privacy_deny_remove(account, pa->who, TRUE);
- purple_privacy_permit_add(account, pa->who, TRUE);
+ purple_account_privacy_deny_remove(account, pa->who, TRUE);
+ purple_account_privacy_permit_add(account, pa->who, TRUE);
msn_del_contact_from_list(session, NULL, pa->who, MSN_LIST_PL);
}
@@ -107,7 +107,7 @@ got_new_entry(PurpleConnection *gc, const char *passport, const char *friendly,
acct = purple_connection_get_account(gc);
purple_account_request_authorization(acct, passport, NULL, friendly, message,
- purple_find_buddy(acct, passport) != NULL,
+ purple_blist_find_buddy(acct, passport) != NULL,
msn_accept_add_cb, msn_cancel_add_cb, pa);
}
@@ -152,15 +152,15 @@ msn_got_lst_user(MsnSession *session, MsnUser *user,
if (list_op & MSN_LIST_AL_OP)
{
/* These are users who are allowed to see our status. */
- purple_privacy_deny_remove(account, passport, TRUE);
- purple_privacy_permit_add(account, passport, TRUE);
+ purple_account_privacy_deny_remove(account, passport, TRUE);
+ purple_account_privacy_permit_add(account, passport, TRUE);
}
if (list_op & MSN_LIST_BL_OP)
{
/* These are users who are not allowed to see our status. */
- purple_privacy_permit_remove(account, passport, TRUE);
- purple_privacy_deny_add(account, passport, TRUE);
+ purple_account_privacy_permit_remove(account, passport, TRUE);
+ purple_account_privacy_deny_add(account, passport, TRUE);
}
if (list_op & MSN_LIST_RL_OP)
@@ -733,7 +733,7 @@ msn_userlist_load(MsnSession *session)
g_return_if_fail(gc != NULL);
- for (l = purple_find_buddies(account, NULL); l != NULL;
+ for (l = purple_blist_find_buddies(account, NULL); l != NULL;
l = g_slist_delete_link(l, l)) {
PurpleBuddy *buddy = l->data;
@@ -742,13 +742,13 @@ msn_userlist_load(MsnSession *session)
purple_buddy_set_protocol_data(buddy, user);
msn_user_set_op(user, MSN_LIST_FL_OP);
}
- for (l = session->account->permit; l != NULL; l = l->next)
+ for (l = purple_account_privacy_get_permitted(session->account); l != NULL; l = l->next)
{
user = msn_userlist_find_add_user(session->userlist,
(char *)l->data,NULL);
msn_user_set_op(user, MSN_LIST_AL_OP);
}
- for (l = session->account->deny; l != NULL; l = l->next)
+ for (l = purple_account_privacy_get_denied(session->account); l != NULL; l = l->next)
{
user = msn_userlist_find_add_user(session->userlist,
(char *)l->data,NULL);
diff --git a/libpurple/protocols/mxit/formcmds.c b/libpurple/protocols/mxit/formcmds.c
index 3d3938d175..7defe9059a 100644
--- a/libpurple/protocols/mxit/formcmds.c
+++ b/libpurple/protocols/mxit/formcmds.c
@@ -227,11 +227,11 @@ static GHashTable* command_tokenize(char* cmd)
*/
static void command_clear(struct MXitSession* session, const char* from, GHashTable* hash)
{
- PurpleConversation *conv;
+ PurpleIMConversation *im;
char* clearmsgscreen;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, from, session->acc);
- if (conv == NULL) {
+ im = purple_conversations_find_im_with_account(from, session->acc);
+ if (im == NULL) {
purple_debug_error(MXIT_PLUGIN_ID, _( "Conversation with '%s' not found\n" ), from);
return;
}
@@ -239,7 +239,7 @@ static void command_clear(struct MXitSession* session, const char* from, GHashTa
clearmsgscreen = g_hash_table_lookup(hash, "clearmsgscreen");
if ( (clearmsgscreen) && (strcmp(clearmsgscreen, "true") == 0) ) {
/* this is a command to clear the chat screen */
- purple_conversation_clear_message_history(conv);
+ purple_conversation_clear_message_history(PURPLE_CONVERSATION(im));
}
}
diff --git a/libpurple/protocols/mxit/login.c b/libpurple/protocols/mxit/login.c
index f5d2443ed2..546cb02fce 100644
--- a/libpurple/protocols/mxit/login.c
+++ b/libpurple/protocols/mxit/login.c
@@ -73,10 +73,10 @@ static struct MXitSession* mxit_create_object( PurpleAccount* 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
+ PURPLE_CONNECTION_FLAG_NO_BGCOLOR
+ | PURPLE_CONNECTION_FLAG_NO_URLDESC
+ | PURPLE_CONNECTION_FLAG_HTML
+ | PURPLE_CONNECTION_FLAG_SUPPORT_MOODS
);
/* configure the session (reference: "libpurple/account.h") */
diff --git a/libpurple/protocols/mxit/multimx.c b/libpurple/protocols/mxit/multimx.c
index 606fe40253..b259a14d57 100644
--- a/libpurple/protocols/mxit/multimx.c
+++ b/libpurple/protocols/mxit/multimx.c
@@ -179,11 +179,11 @@ static void room_remove(struct MXitSession* session, struct multimx* multimx)
* @param convo The Conversation object
* @param nickname The nickname of the user who joined the room
*/
-static void member_added(PurpleConversation* convo, const char* nickname)
+static void member_added(PurpleChatConversation* chat, const char* nickname)
{
purple_debug_info(MXIT_PLUGIN_ID, "member_added: '%s'\n", nickname);
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(convo), nickname, NULL, PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(chat, nickname, NULL, PURPLE_CHAT_USER_NONE, TRUE);
}
@@ -193,11 +193,11 @@ static void member_added(PurpleConversation* convo, const char* nickname)
* @param convo The Conversation object
* @param nickname The nickname of the user who left the room
*/
-static void member_removed(PurpleConversation* convo, const char* nickname)
+static void member_removed(PurpleChatConversation* chat, const char* nickname)
{
purple_debug_info(MXIT_PLUGIN_ID, "member_removed: '%s'\n", nickname);
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), nickname, NULL);
+ purple_chat_conversation_remove_user(chat, nickname, NULL);
}
@@ -207,11 +207,11 @@ static void member_removed(PurpleConversation* convo, const char* nickname)
* @param convo The Conversation object
* @param nickname The nickname of the user who was kicked
*/
-static void member_kicked(PurpleConversation* convo, const char* nickname)
+static void member_kicked(PurpleChatConversation* chat, const char* nickname)
{
purple_debug_info(MXIT_PLUGIN_ID, "member_kicked: '%s'\n", nickname);
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), nickname, _("was kicked"));
+ purple_chat_conversation_remove_user(chat, nickname, _("was kicked"));
}
@@ -222,12 +222,12 @@ static void member_kicked(PurpleConversation* convo, const char* nickname)
* @param session The MXit session object
* @param multimx The MultiMX room object
*/
-static void you_kicked(PurpleConversation* convo, struct MXitSession* session, struct multimx* multimx)
+static void you_kicked(PurpleChatConversation* chat, struct MXitSession* session, struct multimx* multimx)
{
purple_debug_info(MXIT_PLUGIN_ID, "you_kicked\n");
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "MXit", _("You have been kicked from this MultiMX."), PURPLE_MESSAGE_SYSTEM, time(NULL));
- purple_conv_chat_clear_users(PURPLE_CONV_CHAT(convo));
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), "MXit", _("You have been kicked from this MultiMX."), PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_chat_conversation_clear_users(chat);
serv_got_chat_left(session->con, multimx->chatid);
}
@@ -238,7 +238,7 @@ static void you_kicked(PurpleConversation* convo, struct MXitSession* session, s
* @param convo The Conversation object
* @param data The nicknames of the users in the room (separated by \n)
*/
-static void member_update(PurpleConversation* convo, char* data)
+static void member_update(PurpleChatConversation* chat, char* data)
{
gchar** userlist;
int i = 0;
@@ -246,14 +246,14 @@ static void member_update(PurpleConversation* convo, char* data)
purple_debug_info(MXIT_PLUGIN_ID, "member_update: '%s'\n", data);
/* Clear list */
- purple_conv_chat_clear_users(PURPLE_CONV_CHAT(convo));
+ purple_chat_conversation_clear_users(chat);
/* Add each member */
data = g_strstrip(data); /* string leading & trailing whitespace */
userlist = g_strsplit(data, "\n", 0); /* tokenize string */
while (userlist[i] != NULL) {
purple_debug_info(MXIT_PLUGIN_ID, "member_update - adding: '%s'\n", userlist[i]);
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(convo), userlist[i], NULL, PURPLE_CBFLAGS_NONE, FALSE);
+ purple_chat_conversation_add_user(chat, userlist[i], NULL, PURPLE_CHAT_USER_NONE, FALSE);
i++;
}
g_strfreev(userlist);
@@ -377,8 +377,8 @@ void multimx_message_received(struct RXMsgData* mx, char* msg, int msglen, short
/* Must be a service message */
char* ofs;
- PurpleConversation* convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, multimx->roomname, mx->session->acc);
- if (convo == NULL) {
+ PurpleChatConversation* chat = purple_conversations_find_chat_with_account(multimx->roomname, mx->session->acc);
+ if (chat == NULL) {
purple_debug_error(MXIT_PLUGIN_ID, "Conversation '%s' not found\n", multimx->roomname);
return;
}
@@ -387,28 +387,28 @@ void multimx_message_received(struct RXMsgData* mx, char* msg, int msglen, short
if ((ofs = strstr(msg, " has joined")) != NULL) {
/* Somebody has joined */
*ofs = '\0';
- member_added(convo, msg);
+ member_added(chat, msg);
mx->processed = TRUE;
}
else if ((ofs = strstr(msg, " has left")) != NULL) {
/* Somebody has left */
*ofs = '\0';
- member_removed(convo, msg);
+ member_removed(chat, msg);
mx->processed = TRUE;
}
else if ((ofs = strstr(msg, " has been kicked")) != NULL) {
/* Somebody has been kicked */
*ofs = '\0';
- member_kicked(convo, msg);
+ member_kicked(chat, msg);
mx->processed = TRUE;
}
else if (strcmp(msg, "You have been kicked.") == 0) {
/* You have been kicked */
- you_kicked(convo, mx->session, multimx);
+ you_kicked(chat, mx->session, multimx);
mx->processed = TRUE;
}
else if (g_str_has_prefix(msg, "The following users are in this MultiMx:") == TRUE) {
- member_update(convo, msg + strlen("The following users are in this MultiMx:") + 1);
+ member_update(chat, msg + strlen("The following users are in this MultiMx:") + 1);
mx->processed = TRUE;
}
else {
@@ -544,7 +544,7 @@ void mxit_chat_invite(PurpleConnection *gc, int id, const char *msg, const char
struct MXitSession* session = purple_connection_get_protocol_data(gc);
struct multimx* multimx = NULL;
PurpleBuddy* buddy;
- PurpleConversation *convo;
+ PurpleChatConversation *chat;
char* tmp;
purple_debug_info(MXIT_PLUGIN_ID, "Groupchat invite to '%s'\n", username);
@@ -559,22 +559,22 @@ void mxit_chat_invite(PurpleConnection *gc, int id, const char *msg, const char
/* Send invite to MXit */
mxit_send_groupchat_invite(session, multimx->roomid, 1, &username);
- /* Find the buddy information for this contact (reference: "libpurple/blist.h") */
- buddy = purple_find_buddy(session->acc, username);
+ /* Find the buddy information for this contact (reference: "libpurple/buddylist.h") */
+ buddy = purple_blist_find_buddy(session->acc, username);
if (!buddy) {
purple_debug_warning(MXIT_PLUGIN_ID, "mxit_chat_invite: unable to find the buddy '%s'\n", username);
return;
}
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, multimx->roomname, session->acc);
- if (convo == NULL) {
+ chat = purple_conversations_find_chat_with_account(multimx->roomname, session->acc);
+ if (chat == NULL) {
purple_debug_error(MXIT_PLUGIN_ID, "Conversation '%s' not found\n", multimx->roomname);
return;
}
/* Display system message in chat window */
tmp = g_strdup_printf("%s: %s", _("You have invited"), purple_buddy_get_alias(buddy));
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "MXit", tmp, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), "MXit", tmp, PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(tmp);
}
@@ -638,7 +638,7 @@ int mxit_chat_send(PurpleConnection *gc, int id, const char *message, PurpleMess
if (multimx->nickname)
nickname = multimx->nickname;
else
- nickname = purple_account_get_alias(purple_connection_get_account(gc)); /* local alias */
+ nickname = purple_account_get_private_alias(purple_connection_get_account(gc)); /* local alias */
/* Display message in chat window */
serv_got_chat_in(gc, id, nickname, flags, message, time(NULL));
diff --git a/libpurple/protocols/mxit/mxit.c b/libpurple/protocols/mxit/mxit.c
index 119b0b7648..d4ce14203b 100644
--- a/libpurple/protocols/mxit/mxit.c
+++ b/libpurple/protocols/mxit/mxit.c
@@ -180,7 +180,7 @@ static void mxit_cb_chat_created( PurpleConversation* conv, struct MXitSession*
/* not our conversation */
return;
}
- else if ( purple_conversation_get_type( conv ) != PURPLE_CONV_TYPE_IM ) {
+ else if ( PURPLE_IS_CHAT_CONVERSATION( conv ) ) {
/* wrong type of conversation */
return;
}
@@ -193,7 +193,7 @@ static void mxit_cb_chat_created( PurpleConversation* conv, struct MXitSession*
purple_debug_info( MXIT_PLUGIN_ID, "Conversation started with '%s'\n", who );
/* find the buddy object */
- buddy = purple_find_buddy( session->acc, who );
+ buddy = purple_blist_find_buddy( session->acc, who );
if ( !buddy )
return;
@@ -426,7 +426,7 @@ static void mxit_set_status( PurpleAccount* account, PurpleStatus* status )
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_status_type( status ) ) == PURPLE_STATUS_MOOD ) {
const char* moodid = purple_status_get_attr_string( status, PURPLE_MOOD_NAME );
int mood;
@@ -564,8 +564,8 @@ static void mxit_get_info( PurpleConnection *gc, const char *who )
purple_debug_info( MXIT_PLUGIN_ID, "mxit_get_info: '%s'\n", who );
- /* find the buddy information for this contact (reference: "libpurple/blist.h") */
- buddy = purple_find_buddy( session->acc, who );
+ /* find the buddy information for this contact (reference: "libpurple/buddylist.h") */
+ buddy = purple_blist_find_buddy( session->acc, who );
if ( buddy ) {
/* user is in our contact-list, so it's not an invite */
contact = purple_buddy_get_protocol_data( buddy );
@@ -633,7 +633,7 @@ static GList* mxit_blist_menu( PurpleBlistNode *node )
GList* m = NULL;
PurpleMenuAction* act;
- if ( !PURPLE_BLIST_NODE_IS_BUDDY( node ) )
+ if ( !PURPLE_IS_BUDDY( node ) )
return NULL;
buddy = (PurpleBuddy *) node;
@@ -669,7 +669,7 @@ static GHashTable *mxit_chat_info_defaults( PurpleConnection *gc, const char *ch
* @param name The username of the contact
* @param state The typing state to be reported.
*/
-static unsigned int mxit_send_typing( PurpleConnection *gc, const char *name, PurpleTypingState state )
+static unsigned int mxit_send_typing( PurpleConnection *gc, const char *name, PurpleIMTypingState state )
{
PurpleAccount* account = purple_connection_get_account( gc );
struct MXitSession* session = purple_connection_get_protocol_data( gc );
@@ -677,8 +677,8 @@ static unsigned int mxit_send_typing( PurpleConnection *gc, const char *name, Pu
struct contact* contact;
gchar* messageId = NULL;
- /* find the buddy information for this contact (reference: "libpurple/blist.h") */
- buddy = purple_find_buddy( account, name );
+ /* find the buddy information for this contact (reference: "libpurple/buddylist.h") */
+ buddy = purple_blist_find_buddy( account, name );
if ( !buddy ) {
purple_debug_warning( MXIT_PLUGIN_ID, "mxit_send_typing: unable to find the buddy '%s'\n", name );
return 0;
@@ -695,12 +695,12 @@ static unsigned int mxit_send_typing( PurpleConnection *gc, const char *name, Pu
messageId = purple_uuid_random(); /* generate a unique message id */
switch ( state ) {
- case PURPLE_TYPING : /* currently typing */
+ case PURPLE_IM_TYPING : /* currently typing */
mxit_send_msgevent( session, name, messageId, CP_MSGEVENT_TYPING );
break;
- case PURPLE_TYPED : /* stopped typing */
- case PURPLE_NOT_TYPING : /* not typing / erased all text */
+ case PURPLE_IM_TYPED : /* stopped typing */
+ case PURPLE_IM_NOT_TYPING : /* not typing / erased all text */
mxit_send_msgevent( session, name, messageId, CP_MSGEVENT_STOPPED );
break;
diff --git a/libpurple/protocols/mxit/profile.c b/libpurple/protocols/mxit/profile.c
index 0fc5b49788..8d7568480f 100644
--- a/libpurple/protocols/mxit/profile.c
+++ b/libpurple/protocols/mxit/profile.c
@@ -201,7 +201,7 @@ void mxit_show_profile( struct MXitSession* session, const char* username, struc
PurpleBuddy* buddy;
gchar* tmp = NULL;
- buddy = purple_find_buddy( session->acc, username );
+ buddy = purple_blist_find_buddy( session->acc, username );
if ( buddy ) {
purple_notify_user_info_add_pair_plaintext( info, _( "Alias" ), purple_buddy_get_alias( buddy ) );
purple_notify_user_info_add_section_break( info );
diff --git a/libpurple/protocols/mxit/protocol.c b/libpurple/protocols/mxit/protocol.c
index ba879d80e2..39d151ddef 100644
--- a/libpurple/protocols/mxit/protocol.c
+++ b/libpurple/protocols/mxit/protocol.c
@@ -1444,7 +1444,7 @@ static void mxit_parse_cmd_login( struct MXitSession* session, struct record** r
/* we were not yet logged in so we need to complete the login sequence here */
session->flags |= MXIT_FLAG_LOGGEDIN;
purple_connection_update_progress( session->con, _( "Successfully Logged In..." ), 3, 4 );
- purple_connection_set_state( session->con, PURPLE_CONNECTED );
+ purple_connection_set_state( session->con, PURPLE_CONNECTION_CONNECTED );
/* save extra info if this is a HTTP connection */
if ( session->http ) {
@@ -1535,7 +1535,7 @@ static void mxit_parse_cmd_message( struct MXitSession* session, struct record**
const char* name;
char msg[128];
- buddy = purple_find_buddy( session->acc, sender );
+ buddy = purple_blist_find_buddy( session->acc, sender );
if ( buddy )
name = purple_buddy_get_alias( buddy );
else
@@ -1938,7 +1938,7 @@ static void mxit_parse_cmd_extprofile( struct MXitSession* session, struct recor
/* update the status message */
PurpleBuddy* buddy = NULL;
- buddy = purple_find_buddy( session->acc, mxitId );
+ buddy = purple_blist_find_buddy( session->acc, mxitId );
if ( buddy ) {
contact = purple_buddy_get_protocol_data( buddy );
if ( contact ) {
@@ -2068,7 +2068,7 @@ static void mxit_parse_cmd_msgevent( struct MXitSession* session, struct record*
switch ( event ) {
case CP_MSGEVENT_TYPING : /* user is typing */
case CP_MSGEVENT_ANGRY : /* user is typing angrily */
- serv_got_typing( session->con, records[0]->fields[0]->data, 0, PURPLE_TYPING );
+ serv_got_typing( session->con, records[0]->fields[0]->data, 0, PURPLE_IM_TYPING );
break;
case CP_MSGEVENT_STOPPED : /* user has stopped typing */
diff --git a/libpurple/protocols/mxit/roster.c b/libpurple/protocols/mxit/roster.c
index 82281a7257..814b88d620 100644
--- a/libpurple/protocols/mxit/roster.c
+++ b/libpurple/protocols/mxit/roster.c
@@ -75,7 +75,7 @@ GList* mxit_status_types( PurpleAccount* account )
/* add mxit status (reference: "libpurple/status.h") */
type = purple_status_type_new_with_attrs( status->primitive, status->id, _( status->name ), TRUE, TRUE, FALSE,
- "message", _( "Message" ), purple_value_new( PURPLE_TYPE_STRING ),
+ "message", _( "Message" ), purple_g_value_new( G_TYPE_STRING ),
NULL );
statuslist = g_list_append( statuslist, type );
@@ -83,7 +83,7 @@ GList* mxit_status_types( PurpleAccount* account )
/* add Mood option */
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 ),
+ PURPLE_MOOD_NAME, _( "Mood Name" ), purple_g_value_new( G_TYPE_STRING ),
NULL );
statuslist = g_list_append( statuslist, type );
@@ -377,17 +377,17 @@ void mxit_update_contact( struct MXitSession* session, struct contact* contact )
}
/* find or create a group for this contact */
- group = purple_find_group( contact->groupname );
+ group = purple_blist_find_group( contact->groupname );
if ( !group )
group = purple_group_new( contact->groupname );
/* see if the buddy is not in the group already */
- buddy = purple_find_buddy_in_group( session->acc, contact->username, group );
+ buddy = purple_blist_find_buddy_in_group( session->acc, contact->username, group );
if ( !buddy ) {
/* buddy not found in the group */
/* lets try finding him in all groups */
- buddy = purple_find_buddy( session->acc, contact->username );
+ buddy = purple_blist_find_buddy( session->acc, contact->username );
if ( buddy ) {
/* ok, so we found him in another group. to switch him between groups we must delete him and add him again. */
purple_blist_remove_buddy( buddy );
@@ -407,7 +407,7 @@ void mxit_update_contact( struct MXitSession* session, struct contact* contact )
gpointer data = NULL;
/* now update the buddy's alias */
- purple_blist_alias_buddy( buddy, contact->alias );
+ purple_buddy_set_local_alias( buddy, contact->alias );
/* replace the buddy's contact struct */
if ( ( data = purple_buddy_get_protocol_data( buddy ) ) )
@@ -458,8 +458,8 @@ void mxit_update_buddy_presence( struct MXitSession* session, const char* userna
return; /* ignore packet */
}
- /* find the buddy information for this contact (reference: "libpurple/blist.h") */
- buddy = purple_find_buddy( session->acc, username );
+ /* find the buddy information for this contact (reference: "libpurple/buddylist.h") */
+ buddy = purple_blist_find_buddy( session->acc, username );
if ( !buddy ) {
purple_debug_warning( MXIT_PLUGIN_ID, "mxit_update_buddy_presence: unable to find the buddy '%s'\n", username );
return;
@@ -517,8 +517,8 @@ void mxit_update_buddy_avatar( struct MXitSession* session, const char* username
purple_debug_info( MXIT_PLUGIN_ID, "mxit_update_buddy_avatar: user='%s' avatar='%s'\n", username, avatarId );
- /* find the buddy information for this contact (reference: "libpurple/blist.h") */
- buddy = purple_find_buddy( session->acc, username );
+ /* find the buddy information for this contact (reference: "libpurple/buddylist.h") */
+ buddy = purple_blist_find_buddy( session->acc, username );
if ( !buddy ) {
purple_debug_warning( MXIT_PLUGIN_ID, "mxit_update_buddy_presence: unable to find the buddy '%s'\n", username );
return;
@@ -558,7 +558,7 @@ void mxit_update_blist( struct MXitSession* session )
/* remove all buddies we did not receive a roster update for.
* these contacts must have been removed from another client */
- list = purple_find_buddies( session->acc, NULL );
+ list = purple_blist_find_buddies( session->acc, NULL );
for ( i = 0; i < g_slist_length( list ); i++ ) {
buddy = g_slist_nth_data( list, i );
@@ -700,7 +700,7 @@ gboolean is_mxit_chatroom_contact( struct MXitSession* session, const char* user
struct contact* contact = NULL;
/* find the buddy */
- buddy = purple_find_buddy( session->acc, username );
+ buddy = purple_blist_find_buddy( session->acc, username );
if ( !buddy ) {
purple_debug_warning( MXIT_PLUGIN_ID, "is_mxit_chatroom_contact: unable to find the buddy '%s'\n", username );
return FALSE;
@@ -738,7 +738,7 @@ void mxit_add_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* grou
purple_debug_info( MXIT_PLUGIN_ID, "mxit_add_buddy '%s' (group='%s')\n", buddy_name, group_name );
- list = purple_find_buddies( session->acc, buddy_name );
+ list = purple_blist_find_buddies( session->acc, buddy_name );
if ( g_slist_length( list ) == 1 ) {
purple_debug_info( MXIT_PLUGIN_ID, "mxit_add_buddy (scenario 1) (list:%i)\n", g_slist_length( list ) );
/*
@@ -773,7 +773,7 @@ void mxit_add_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* grou
/* this is our REAL MXit buddy! */
/* now update the buddy's alias */
- purple_blist_alias_buddy( mxbuddy, buddy_alias );
+ purple_buddy_set_local_alias( mxbuddy, buddy_alias );
/* now update the buddy's group */
// mxbuddy = mxit_update_buddy_group( session, mxbuddy, group );
@@ -831,7 +831,7 @@ void mxit_buddy_alias( PurpleConnection* gc, const char* who, const char* alias
purple_debug_info( MXIT_PLUGIN_ID, "mxit_buddy_alias '%s' to '%s\n", who, alias );
/* find the buddy */
- buddy = purple_find_buddy( session->acc, who );
+ buddy = purple_blist_find_buddy( session->acc, who );
if ( !buddy ) {
purple_debug_warning( MXIT_PLUGIN_ID, "mxit_buddy_alias: unable to find the buddy '%s'\n", who );
return;
@@ -864,7 +864,7 @@ void mxit_buddy_group( PurpleConnection* gc, const char* who, const char* old_gr
purple_debug_info( MXIT_PLUGIN_ID, "mxit_buddy_group from '%s' to '%s'\n", old_group, new_group );
/* find the buddy */
- buddy = purple_find_buddy( session->acc, who );
+ buddy = purple_blist_find_buddy( session->acc, who );
if ( !buddy ) {
purple_debug_warning( MXIT_PLUGIN_ID, "mxit_buddy_group: unable to find the buddy '%s'\n", who );
return;
diff --git a/libpurple/protocols/mxit/voicevideo.c b/libpurple/protocols/mxit/voicevideo.c
index aa30dc31b6..a254044b85 100644
--- a/libpurple/protocols/mxit/voicevideo.c
+++ b/libpurple/protocols/mxit/voicevideo.c
@@ -75,8 +75,8 @@ PurpleMediaCaps mxit_media_caps(PurpleAccount *account, const char *who)
if (!*session->voip_server)
return PURPLE_MEDIA_CAPS_NONE;
- /* find the buddy information for this contact (reference: "libpurple/blist.h") */
- buddy = purple_find_buddy(account, who);
+ /* find the buddy information for this contact (reference: "libpurple/buddylist.h") */
+ buddy = purple_blist_find_buddy(account, who);
if (!buddy) {
purple_debug_warning(MXIT_PLUGIN_ID, "mxit_media_caps: unable to find the buddy '%s'\n", who);
return PURPLE_MEDIA_CAPS_NONE;
diff --git a/libpurple/protocols/myspace/myspace.c b/libpurple/protocols/myspace/myspace.c
index 8ac44c247a..3b469e537c 100644
--- a/libpurple/protocols/myspace/myspace.c
+++ b/libpurple/protocols/myspace/myspace.c
@@ -36,8 +36,6 @@
#include "myspace.h"
-#include "privacy.h"
-
static void msim_set_status(PurpleAccount *account, PurpleStatus *status);
static void msim_set_idle(PurpleConnection *gc, int time);
@@ -134,7 +132,7 @@ msim_postprocess_outgoing_cb(MsimSession *session, const MsimMessage *userinfo,
gchar *msg;
msg = g_strdup_printf(_("No such user: %s"), username);
- if (!purple_conv_present_error(username, session->account, msg)) {
+ if (!purple_conversation_present_error(username, session->account, msg)) {
purple_notify_error(NULL, NULL, _("User lookup"), msg);
}
@@ -200,7 +198,7 @@ msim_postprocess_outgoing(MsimSession *session, MsimMessage *msg,
uid = atol(username);
} else {
/* Next, see if on buddy list and know uid. */
- buddy = purple_find_buddy(session->account, username);
+ buddy = purple_blist_find_buddy(session->account, username);
if (buddy) {
uid = purple_blist_node_get_int(PURPLE_BLIST_NODE(buddy), "UserID");
} else {
@@ -291,7 +289,7 @@ msim_uid2username_from_blist(PurpleAccount *account, guint wanted_uid)
GSList *buddies, *cur;
const gchar *ret;
- buddies = purple_find_buddies(account, NULL);
+ buddies = purple_blist_find_buddies(account, NULL);
if (!buddies)
{
@@ -473,7 +471,7 @@ msim_status_types(PurpleAccount *acct)
/* Attributes - each status can have a message. */ \
"message", \
_("Message"), \
- purple_value_new(PURPLE_TYPE_STRING), \
+ purple_g_value_new(G_TYPE_STRING), \
NULL); \
\
\
@@ -494,8 +492,8 @@ msim_status_types(PurpleAccount *acct)
TRUE, /* should be user_settable some day */
TRUE, /* independent */
- PURPLE_TUNE_ARTIST, _("Tune Artist"), purple_value_new(PURPLE_TYPE_STRING),
- PURPLE_TUNE_TITLE, _("Tune Title"), purple_value_new(PURPLE_TYPE_STRING),
+ PURPLE_TUNE_ARTIST, _("Tune Artist"), purple_g_value_new(G_TYPE_STRING),
+ PURPLE_TUNE_TITLE, _("Tune Title"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_append(types, status);
@@ -530,9 +528,8 @@ static gchar *
msim_compute_login_response(const gchar nonce[2 * NONCE_SIZE],
const gchar *email, const gchar *password, guint *response_len)
{
- PurpleCipherContext *key_context;
- PurpleCipher *sha1;
- PurpleCipherContext *rc4;
+ PurpleHash *sha1;
+ PurpleCipher *rc4;
guchar hash_pw[HASH_SIZE];
guchar key[HASH_SIZE];
@@ -581,8 +578,11 @@ msim_compute_login_response(const gchar nonce[2 * NONCE_SIZE],
}
/* Compute password hash */
- purple_cipher_digest_region("sha1", (guchar *)password_utf16le,
- conv_bytes_written, hash_pw, sizeof(hash_pw));
+ sha1 = purple_sha1_hash_new();
+ purple_hash_append(sha1, (guchar *)password_utf16le,
+ conv_bytes_written);
+ purple_hash_digest(sha1, hash_pw, sizeof(hash_pw));
+ purple_hash_reset(sha1);
g_free(password_utf16le);
#ifdef MSIM_DEBUG_LOGIN_CHALLENGE
@@ -593,12 +593,10 @@ msim_compute_login_response(const gchar nonce[2 * NONCE_SIZE],
#endif
/* key = sha1(sha1(pw) + nonce2) */
- sha1 = purple_ciphers_find_cipher("sha1");
- key_context = purple_cipher_context_new(sha1, NULL);
- purple_cipher_context_append(key_context, hash_pw, HASH_SIZE);
- purple_cipher_context_append(key_context, (guchar *)(nonce + NONCE_SIZE), NONCE_SIZE);
- purple_cipher_context_digest(key_context, key, sizeof(key));
- purple_cipher_context_destroy(key_context);
+ purple_hash_append(sha1, hash_pw, HASH_SIZE);
+ purple_hash_append(sha1, (guchar *)(nonce + NONCE_SIZE), NONCE_SIZE);
+ purple_hash_digest(sha1, key, sizeof(key));
+ g_object_unref(sha1);
#ifdef MSIM_DEBUG_LOGIN_CHALLENGE
purple_debug_info("msim", "key = ");
@@ -608,11 +606,11 @@ msim_compute_login_response(const gchar nonce[2 * NONCE_SIZE],
purple_debug_info("msim", "\n");
#endif
- rc4 = purple_cipher_context_new_by_name("rc4", NULL);
+ rc4 = purple_rc4_cipher_new();
/* Note: 'key' variable is 0x14 bytes (from SHA-1 hash),
* but only first 0x10 used for the RC4 key. */
- purple_cipher_context_set_key(rc4, key, 0x10);
+ purple_cipher_set_key(rc4, key, 0x10);
/* rc4 encrypt:
* nonce1+email+IP list */
@@ -638,9 +636,9 @@ msim_compute_login_response(const gchar nonce[2 * NONCE_SIZE],
data_out = g_new0(guchar, data->len);
- data_out_len = purple_cipher_context_encrypt(rc4,
+ data_out_len = purple_cipher_encrypt(rc4,
(const guchar *)data->str, data->len, data_out, data->len);
- purple_cipher_context_destroy(rc4);
+ g_object_unref(rc4);
if (data_out_len != data->len) {
purple_debug_info("msim", "msim_compute_login_response: "
@@ -1006,7 +1004,7 @@ msim_add_contact_from_server_cb(MsimSession *session, const MsimMessage *user_lo
group_name = g_strdup(_("IM Friends"));
purple_debug_info("myspace", "No GroupName specified, defaulting to '%s'.\n", group_name);
}
- group = purple_find_group(group_name);
+ group = purple_blist_find_group(group_name);
if (!group) {
group = purple_group_new(group_name);
/* Add group to beginning. See #2752. */
@@ -1017,7 +1015,7 @@ msim_add_contact_from_server_cb(MsimSession *session, const MsimMessage *user_lo
visibility = msim_msg_get_integer(contact_info, "Visibility");
if (visibility == 2) {
/* This buddy is blocked (and therefore not on our buddy list */
- purple_privacy_deny_add(session->account, username, TRUE);
+ purple_account_privacy_deny_add(session->account, username, TRUE);
msim_msg_free(contact_info);
g_free(username);
g_free(display_name);
@@ -1025,7 +1023,7 @@ msim_add_contact_from_server_cb(MsimSession *session, const MsimMessage *user_lo
}
/* 2. Get or create buddy */
- buddy = purple_find_buddy(session->account, username);
+ buddy = purple_blist_find_buddy(session->account, username);
if (!buddy) {
purple_debug_info("msim_add_contact_from_server_cb",
"creating new buddy: %s\n", username);
@@ -1152,7 +1150,7 @@ msim_got_contact_list(MsimSession *session, const MsimMessage *reply, gpointer u
* signedOn signal, so clients can now do anything with msimprpl, and
* we're ready for it (session key, userid, username all setup). */
purple_connection_update_progress(session->gc, _("Connected"), 3, 4);
- purple_connection_set_state(session->gc, PURPLE_CONNECTED);
+ purple_connection_set_state(session->gc, PURPLE_CONNECTION_CONNECTED);
break;
}
@@ -1488,10 +1486,10 @@ msim_incoming_im(MsimSession *session, MsimMessage *msg, const gchar *username)
gchar *msg_msim_markup, *msg_purple_markup;
gchar *userid;
time_t time_received;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
/* I know this isn't really a string... but we need it to be one for
- * purple_find_conversation_with_account(). */
+ * purple_conversations_find_with_account(). */
userid = msim_msg_get_string(msg, "f");
purple_debug_info("msim_incoming_im", "UserID is %s", userid);
@@ -1502,11 +1500,11 @@ msim_incoming_im(MsimSession *session, MsimMessage *msg, const gchar *username)
return FALSE;
}
- /* See if a conversation with their UID already exists...*/
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, userid, session->account);
- if (conv) {
- /* Since the conversation exists... We need to normalize it */
- purple_conversation_set_name(conv, username);
+ /* See if an IM with their UID already exists...*/
+ im = purple_conversations_find_im_with_account(userid, session->account);
+ if (im) {
+ /* Since the IM exists... We need to normalize it */
+ purple_conversation_set_name(PURPLE_CONVERSATION(im), username);
}
msg_msim_markup = msim_msg_get_string(msg, "msg");
@@ -1555,7 +1553,7 @@ msim_incoming_action_or_im(MsimSession *session, MsimMessage *msg)
msg_text, username);
if (g_str_equal(msg_text, "%typing%")) {
- serv_got_typing(session->gc, username, 0, PURPLE_TYPING);
+ serv_got_typing(session->gc, username, 0, PURPLE_IM_TYPING);
rc = TRUE;
} else if (g_str_equal(msg_text, "%stoptyping%")) {
serv_got_typing_stopped(session->gc, username);
@@ -1613,7 +1611,7 @@ msim_incoming_media(MsimSession *session, MsimMessage *msg)
/* Media messages are sent when the user opens a window to someone.
* Tell libpurple they started typing and stopped typing, to inform the Psychic
* Mode plugin so it too can open a window to the user. */
- serv_got_typing(session->gc, username, 0, PURPLE_TYPING);
+ serv_got_typing(session->gc, username, 0, PURPLE_IM_TYPING);
serv_got_typing_stopped(session->gc, username);
g_free(username);
@@ -2177,6 +2175,7 @@ msim_login(PurpleAccount *acct)
{
PurpleConnection *gc;
const gchar *host;
+ GSList *deny;
int port;
g_return_if_fail(acct != NULL);
@@ -2186,15 +2185,15 @@ msim_login(PurpleAccount *acct)
gc = purple_account_get_connection(acct);
purple_connection_set_protocol_data(gc, msim_session_new(acct));
- purple_connection_set_flags(gc, PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_URLDESC);
+ purple_connection_set_flags(gc, PURPLE_CONNECTION_FLAG_HTML | PURPLE_CONNECTION_FLAG_NO_URLDESC);
/*
* Lets wipe out our local list of blocked buddies. We'll get a
* list of all blocked buddies from the server, and we shouldn't
* have stuff in the local list that isn't on the server list.
*/
- while (acct->deny != NULL)
- purple_privacy_deny_remove(acct, acct->deny->data, TRUE);
+ while ((deny = purple_account_privacy_get_denied(acct)) != NULL)
+ purple_account_privacy_deny_remove(acct, deny->data, TRUE);
/* 1. connect to server */
purple_connection_update_progress(gc, _("Connecting"),
@@ -2247,7 +2246,7 @@ msim_close(PurpleConnection *gc)
* should call our buddy_free prpl callback so that we don't need to do
* this... but it doesn't, so we do.
*/
- buddies = purple_find_buddies(purple_connection_get_account(gc), NULL);
+ buddies = purple_blist_find_buddies(purple_connection_get_account(gc), NULL);
while (buddies != NULL) {
msim_buddy_free(buddies->data);
buddies = g_slist_delete_link(buddies, buddies);
@@ -2325,13 +2324,13 @@ msim_send_im(PurpleConnection *gc, const gchar *who, const gchar *message,
*
* @param gc
* @param name The buddy name to which our user is typing to
- * @param state PURPLE_TYPING, PURPLE_TYPED, PURPLE_NOT_TYPING
+ * @param state PURPLE_IM_TYPING, PURPLE_IM_TYPED, PURPLE_IM_NOT_TYPING
*
* @return 0
*/
static unsigned int
msim_send_typing(PurpleConnection *gc, const gchar *name,
- PurpleTypingState state)
+ PurpleIMTypingState state)
{
const gchar *typing_str;
MsimSession *session;
@@ -2342,12 +2341,12 @@ msim_send_typing(PurpleConnection *gc, const gchar *name,
session = purple_connection_get_protocol_data(gc);
switch (state) {
- case PURPLE_TYPING:
+ case PURPLE_IM_TYPING:
typing_str = "%typing%";
break;
- case PURPLE_TYPED:
- case PURPLE_NOT_TYPING:
+ case PURPLE_IM_TYPED:
+ case PURPLE_IM_NOT_TYPING:
default:
typing_str = "%stoptyping%";
break;
@@ -2493,7 +2492,7 @@ msim_set_status(PurpleAccount *account, PurpleStatus *status)
session = purple_connection_get_protocol_data(gc);
- type = purple_status_get_type(status);
+ type = purple_status_get_status_type(status);
pres = purple_status_get_presence(status);
switch (purple_status_type_get_primitive(type)) {
@@ -3089,16 +3088,6 @@ static PurplePluginProtocolInfo prpl_info = {
static gboolean
msim_load(PurplePlugin *plugin)
{
- /* If compiled to use RC4 from libpurple, check if it is really there. */
- if (!purple_ciphers_find_cipher("rc4")) {
- purple_debug_error("msim", "rc4 not in libpurple, but it is required - not loading MySpaceIM plugin!\n");
- purple_notify_error(plugin, _("Missing Cipher"),
- _("The RC4 cipher could not be found"),
- _("Upgrade "
- "to a libpurple with RC4 support (>= 2.0.1). MySpaceIM "
- "plugin will not be loaded."));
- return FALSE;
- }
return TRUE;
}
@@ -3404,7 +3393,7 @@ msim_uri_handler_addContact_cb(MsimSession *session, MsimMessage *userinfo, gpoi
static void
msim_uri_handler_sendIM_cb(MsimSession *session, MsimMessage *userinfo, gpointer data)
{
- PurpleConversation *conv;
+ PurpleIMConversation *im;
MsimMessage *body;
gchar *username;
@@ -3422,14 +3411,14 @@ msim_uri_handler_sendIM_cb(MsimSession *session, MsimMessage *userinfo, gpointer
}
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, username, session->account);
- if (!conv) {
+ im = purple_conversations_find_im_with_account(username, session->account);
+ if (!im) {
purple_debug_info("msim_uri_handler", "creating new conversation for %s\n", username);
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, session->account, username);
+ im = purple_im_conversation_new(session->account, username);
}
/* Just open the window so the user can send an IM. */
- purple_conversation_present(conv);
+ purple_conversation_present(PURPLE_CONVERSATION(im));
g_free(username);
}
diff --git a/libpurple/protocols/myspace/myspace.h b/libpurple/protocols/myspace/myspace.h
index 8f5c975708..fd9a149fd3 100644
--- a/libpurple/protocols/myspace/myspace.h
+++ b/libpurple/protocols/myspace/myspace.h
@@ -42,7 +42,6 @@
#include "plugin.h"
#include "accountopt.h"
#include "version.h"
-#include "cipher.h" /* for SHA-1 */
#include "util.h" /* for base64 */
#include "debug.h" /* for purple_debug_info */
#include "request.h" /* For dialogs used in setting the username */
@@ -50,6 +49,10 @@
#include "core.h"
#include "conversation.h" /* For late normalization */
+/* Ciphers */
+#include "ciphers/rc4cipher.h"
+#include "ciphers/sha1hash.h"
+
/* MySpaceIM includes */
#include "persist.h"
#include "message.h"
diff --git a/libpurple/protocols/myspace/user.c b/libpurple/protocols/myspace/user.c
index a0775a1af1..b5ee54d2b2 100644
--- a/libpurple/protocols/myspace/user.c
+++ b/libpurple/protocols/myspace/user.c
@@ -93,7 +93,7 @@ msim_find_user(MsimSession *session, const gchar *username)
{
PurpleBuddy *buddy;
- buddy = purple_find_buddy(session->account, username);
+ buddy = purple_blist_find_buddy(session->account, username);
if (!buddy) {
return NULL;
}
diff --git a/libpurple/protocols/myspace/zap.c b/libpurple/protocols/myspace/zap.c
index 653b4d9f34..09dcf49bd1 100644
--- a/libpurple/protocols/myspace/zap.c
+++ b/libpurple/protocols/myspace/zap.c
@@ -143,7 +143,7 @@ msim_send_attention(PurpleConnection *gc, const gchar *username, guint code)
return FALSE;
}
- buddy = purple_find_buddy(session->account, username);
+ buddy = purple_blist_find_buddy(session->account, username);
if (!buddy) {
return FALSE;
}
@@ -163,12 +163,12 @@ msim_send_zap_from_menu(PurpleBlistNode *node, gpointer zap_num_ptr)
MsimSession *session;
guint zap;
- if (!PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if (!PURPLE_IS_BUDDY(node)) {
/* Only know about buddies for now. */
return;
}
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *)node;
@@ -191,7 +191,7 @@ msim_blist_node_menu(PurpleBlistNode *node)
PurpleMenuAction *act;
guint i;
- if (!PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if (!PURPLE_IS_BUDDY(node)) {
/* Only know about buddies for now. */
return NULL;
}
diff --git a/libpurple/protocols/novell/novell.c b/libpurple/protocols/novell/novell.c
index d0148c0cdb..7c366b3670 100644
--- a/libpurple/protocols/novell/novell.c
+++ b/libpurple/protocols/novell/novell.c
@@ -29,7 +29,6 @@
#include "sslconn.h"
#include "request.h"
#include "network.h"
-#include "privacy.h"
#include "status.h"
#include "version.h"
@@ -102,16 +101,16 @@ _login_resp_cb(NMUser * user, NMERR_T ret_code,
if (ret_code == NM_OK) {
/* Set alias for user if not set (use Full Name) */
- alias = purple_account_get_alias(user->client_data);
+ alias = purple_account_get_private_alias(user->client_data);
if (alias == NULL || *alias == '\0') {
alias = nm_user_record_get_full_name(user->user_record);
if (alias)
- purple_account_set_alias(user->client_data, alias);
+ purple_account_set_private_alias(user->client_data, alias);
}
/* Tell Purple that we are connected */
- purple_connection_set_state(gc, PURPLE_CONNECTED);
+ purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED);
_sync_contact_list(user);
@@ -165,7 +164,7 @@ _get_status_resp_cb(NMUser * user, NMERR_T ret_code,
const char *name = nm_user_record_get_display_id(user_record);
if (name) {
- buddies = purple_find_buddies((PurpleAccount *) user->client_data, name);
+ buddies = purple_blist_find_buddies((PurpleAccount *) user->client_data, name);
for (bnode = buddies; bnode; bnode = bnode->next) {
buddy = (PurpleBuddy *) bnode->data;
if (buddy) {
@@ -217,9 +216,8 @@ _get_details_resp_send_msg(NMUser * user, NMERR_T ret_code,
if (user_record) {
/* Set the title for the conversation */
- /* XXX - Should this be PURPLE_CONV_TYPE_IM? */
- gconv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY,
- nm_user_record_get_display_id(user_record),
+ /* XXX - Should this be find_im_with_account? */
+ gconv = purple_conversations_find_with_account(nm_user_record_get_display_id(user_record),
(PurpleAccount *) user->client_data);
if (gconv) {
@@ -289,12 +287,12 @@ _get_details_resp_setup_buddy(NMUser * user, NMERR_T ret_code,
nm_contact_set_user_record(contact, user_record);
/* Set the display id */
- purple_blist_rename_buddy(buddy,
+ purple_buddy_set_name(buddy,
nm_user_record_get_display_id(user_record));
alias = purple_buddy_get_alias(buddy);
if (alias == NULL || *alias == '\0' || (strcmp(alias, purple_buddy_get_name(buddy)) == 0)) {
- purple_blist_alias_buddy(buddy,
+ purple_buddy_set_local_alias(buddy,
nm_user_record_get_full_name(user_record));
/* Tell the server about the new display name */
@@ -351,7 +349,7 @@ _create_contact_resp_cb(NMUser * user, NMERR_T ret_code,
folder_name = NM_ROOT_FOLDER_NAME;
/* Re-add the buddy now that we got the okay from the server */
- if (folder_name && (group = purple_find_group(folder_name))) {
+ if (folder_name && (group = purple_blist_find_group(folder_name))) {
const char *alias = nm_contact_get_display_name(tmp_contact);
const char *display_id = nm_contact_get_display_id(new_contact);
@@ -373,7 +371,7 @@ _create_contact_resp_cb(NMUser * user, NMERR_T ret_code,
}
/* Add it to the purple buddy list if it is not there */
- buddy = purple_find_buddy_in_group(user->client_data, display_id, group);
+ buddy = purple_blist_find_buddy_in_group(user->client_data, display_id, group);
if (buddy == NULL) {
buddy = purple_buddy_new(user->client_data, display_id, alias);
purple_blist_add_buddy(buddy, NULL, group, NULL);
@@ -654,7 +652,7 @@ static void
_join_conf_resp_cb(NMUser * user, NMERR_T ret_code,
gpointer resp_data, gpointer user_data)
{
- PurpleConversation *chat;
+ PurpleChatConversation *chat;
PurpleConnection *gc;
NMUserRecord *ur;
NMConference *conference = user_data;
@@ -678,8 +676,8 @@ _join_conf_resp_cb(NMUser * user, NMERR_T ret_code,
ur = nm_conference_get_participant(conference, i);
if (ur) {
name = nm_user_record_get_display_id(ur);
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(chat), name, NULL,
- PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(chat, name, NULL,
+ PURPLE_CHAT_USER_NONE, TRUE);
}
}
}
@@ -726,6 +724,7 @@ _get_details_resp_add_privacy_item(NMUser *user, NMERR_T ret_code,
gpointer resp_data, gpointer user_data)
{
PurpleConnection *gc;
+ PurpleAccount *account;
NMUserRecord *user_record = resp_data;
char *err;
gboolean allowed = GPOINTER_TO_INT(user_data);
@@ -736,21 +735,22 @@ _get_details_resp_add_privacy_item(NMUser *user, NMERR_T ret_code,
gc = purple_account_get_connection(user->client_data);
display_id = nm_user_record_get_display_id(user_record);
+ account = purple_connection_get_account(gc);
if (ret_code == NM_OK) {
if (allowed) {
- if (!g_slist_find_custom(purple_connection_get_account(gc)->permit,
+ if (!g_slist_find_custom(purple_account_privacy_get_denied(account),
display_id, (GCompareFunc)purple_utf8_strcasecmp)) {
- purple_privacy_permit_add(purple_connection_get_account(gc), display_id, TRUE);
+ purple_account_privacy_permit_add(account, display_id, TRUE);
}
} else {
- if (!g_slist_find_custom(purple_connection_get_account(gc)->permit,
+ if (!g_slist_find_custom(purple_account_privacy_get_denied(account),
display_id, (GCompareFunc)purple_utf8_strcasecmp)) {
- purple_privacy_deny_add(purple_connection_get_account(gc), display_id, TRUE);
+ purple_account_privacy_deny_add(account, display_id, TRUE);
}
}
@@ -770,6 +770,7 @@ _create_privacy_item_deny_resp_cb(NMUser *user, NMERR_T ret_code,
gpointer resp_data, gpointer user_data)
{
PurpleConnection *gc;
+ PurpleAccount *account;
NMUserRecord *user_record;
char *who = user_data;
char *err;
@@ -780,6 +781,7 @@ _create_privacy_item_deny_resp_cb(NMUser *user, NMERR_T ret_code,
return;
gc = purple_account_get_connection(user->client_data);
+ account = purple_connection_get_account(gc);
if (ret_code == NM_OK) {
@@ -789,10 +791,10 @@ _create_privacy_item_deny_resp_cb(NMUser *user, NMERR_T ret_code,
if (display_id) {
- if (!g_slist_find_custom(purple_connection_get_account(gc)->deny,
+ if (!g_slist_find_custom(purple_account_privacy_get_denied(account),
display_id, (GCompareFunc)purple_utf8_strcasecmp)) {
- purple_privacy_deny_add(purple_connection_get_account(gc), display_id, TRUE);
+ purple_account_privacy_deny_add(account, display_id, TRUE);
}
} else {
@@ -821,6 +823,7 @@ _create_privacy_item_permit_resp_cb(NMUser *user, NMERR_T ret_code,
gpointer resp_data, gpointer user_data)
{
PurpleConnection *gc;
+ PurpleAccount *account;
NMUserRecord *user_record;
char *who = user_data;
char *err;
@@ -831,6 +834,7 @@ _create_privacy_item_permit_resp_cb(NMUser *user, NMERR_T ret_code,
return;
gc = purple_account_get_connection(user->client_data);
+ account = purple_connection_get_account(gc);
if (ret_code == NM_OK) {
@@ -840,11 +844,11 @@ _create_privacy_item_permit_resp_cb(NMUser *user, NMERR_T ret_code,
if (display_id) {
- if (!g_slist_find_custom(purple_connection_get_account(gc)->permit,
+ if (!g_slist_find_custom(purple_account_privacy_get_permitted(account),
display_id,
(GCompareFunc)purple_utf8_strcasecmp)) {
- purple_privacy_permit_add(purple_connection_get_account(gc), display_id, TRUE);
+ purple_account_privacy_permit_add(account, display_id, TRUE);
}
} else {
@@ -979,7 +983,7 @@ _get_details_resp_send_invite(NMUser *user, NMERR_T ret_code,
for (cnode = user->conferences; cnode != NULL; cnode = cnode->next) {
conference = cnode->data;
if (conference && (chat = nm_conference_get_data(conference))) {
- if (purple_conv_chat_get_id(PURPLE_CONV_CHAT(chat)) == id) {
+ if (purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(chat)) == id) {
rc = nm_send_conference_invite(user, conference, user_record,
NULL, _sendinvite_resp_cb, NULL);
_check_for_disconnect(user, rc);
@@ -1236,19 +1240,19 @@ _remove_purple_buddies(NMUser *user)
for (gnode = purple_blist_get_root(); gnode;
gnode = purple_blist_node_get_sibling_next(gnode)) {
- if (!PURPLE_BLIST_NODE_IS_GROUP(gnode))
+ if (!PURPLE_IS_GROUP(gnode))
continue;
group = (PurpleGroup *) gnode;
gname = purple_group_get_name(group);
for (cnode = purple_blist_node_get_first_child(gnode);
cnode;
cnode = purple_blist_node_get_sibling_next(cnode)) {
- if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode))
+ if (!PURPLE_IS_CONTACT(cnode))
continue;
for (bnode = purple_blist_node_get_first_child(cnode);
bnode;
bnode = purple_blist_node_get_sibling_next(bnode)) {
- if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode))
+ if (!PURPLE_IS_BUDDY(bnode))
continue;
buddy = (PurpleBuddy *) bnode;
if (purple_buddy_get_account(buddy) == user->client_data) {
@@ -1294,7 +1298,7 @@ _add_contacts_to_purple_blist(NMUser * user, NMFolder * folder)
}
/* Does the Purple group exist already? */
- group = purple_find_group(fname);
+ group = purple_blist_find_group(fname);
if (group == NULL) {
group = purple_group_new(fname);
purple_blist_add_group(group, NULL);
@@ -1309,7 +1313,7 @@ _add_contacts_to_purple_blist(NMUser * user, NMFolder * folder)
name = nm_contact_get_display_id(contact);
if (name) {
- buddy = purple_find_buddy_in_group(user->client_data, name, group);
+ buddy = purple_blist_find_buddy_in_group(user->client_data, name, group);
if (buddy == NULL) {
/* Add it to the purple buddy list */
buddy = purple_buddy_new(user->client_data,
@@ -1386,6 +1390,7 @@ _sync_privacy_lists(NMUser *user)
{
GSList *node = NULL, *rem_list = NULL;
PurpleConnection *gc;
+ PurpleAccount *account;
const char *name, *dn;
NMUserRecord *user_record;
@@ -1396,18 +1401,20 @@ _sync_privacy_lists(NMUser *user)
if (gc == NULL)
return;
+ account = purple_connection_get_account(gc);
+
/* Set the Purple privacy setting */
if (user->default_deny) {
if (user->allow_list == NULL) {
- purple_account_set_privacy_type(purple_connection_get_account(gc), PURPLE_PRIVACY_DENY_ALL);
+ purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_DENY_ALL);
} else {
- purple_account_set_privacy_type(purple_connection_get_account(gc), PURPLE_PRIVACY_ALLOW_USERS);
+ purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS);
}
} else {
if (user->deny_list == NULL) {
- purple_account_set_privacy_type(purple_connection_get_account(gc), PURPLE_PRIVACY_ALLOW_ALL);
+ purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL);
} else {
- purple_account_set_privacy_type(purple_connection_get_account(gc), PURPLE_PRIVACY_DENY_USERS);
+ purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_DENY_USERS);
}
}
@@ -1419,9 +1426,9 @@ _sync_privacy_lists(NMUser *user)
else
name =(char *)node->data;
- if (!g_slist_find_custom(purple_connection_get_account(gc)->permit,
+ if (!g_slist_find_custom(purple_account_privacy_get_permitted(account),
name, (GCompareFunc)purple_utf8_strcasecmp)) {
- purple_privacy_permit_add(purple_connection_get_account(gc), name , TRUE);
+ purple_account_privacy_permit_add(account, name , TRUE);
}
}
@@ -1432,15 +1439,15 @@ _sync_privacy_lists(NMUser *user)
else
name =(char *)node->data;
- if (!g_slist_find_custom(purple_connection_get_account(gc)->deny,
+ if (!g_slist_find_custom(purple_account_privacy_get_denied(account),
name, (GCompareFunc)purple_utf8_strcasecmp)) {
- purple_privacy_deny_add(purple_connection_get_account(gc), name, TRUE);
+ purple_account_privacy_deny_add(account, name, TRUE);
}
}
/* Remove stuff */
- for (node = purple_connection_get_account(gc)->permit; node; node = node->next) {
+ for (node = purple_account_privacy_get_permitted(account); node; node = node->next) {
dn = nm_lookup_dn(user, (char *)node->data);
if (dn != NULL &&
!g_slist_find_custom(user->allow_list,
@@ -1451,13 +1458,13 @@ _sync_privacy_lists(NMUser *user)
if (rem_list) {
for (node = rem_list; node; node = node->next) {
- purple_privacy_permit_remove(purple_connection_get_account(gc), (char *)node->data, TRUE);
+ purple_account_privacy_permit_remove(account, (char *)node->data, TRUE);
}
g_slist_free(rem_list);
rem_list = NULL;
}
- for (node = purple_connection_get_account(gc)->deny; node; node = node->next) {
+ for (node = purple_account_privacy_get_denied(account); node; node = node->next) {
dn = nm_lookup_dn(user, (char *)node->data);
if (dn != NULL &&
!g_slist_find_custom(user->deny_list,
@@ -1468,7 +1475,7 @@ _sync_privacy_lists(NMUser *user)
if (rem_list) {
for (node = rem_list; node; node = node->next) {
- purple_privacy_deny_remove(purple_connection_get_account(gc), (char *)node->data, TRUE);
+ purple_account_privacy_deny_remove(account, (char *)node->data, TRUE);
}
g_slist_free(rem_list);
}
@@ -1615,11 +1622,11 @@ _initiate_conference_cb(PurpleBlistNode *node, gpointer ignored)
NMUser *user;
const char *conf_name;
- PurpleConversation *chat = NULL;
+ PurpleChatConversation *chat = NULL;
NMUserRecord *user_record;
NMConference *conference;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
@@ -1767,7 +1774,7 @@ _evt_receive_message(NMUser * user, NMEvent * event)
{
NMUserRecord *user_record = NULL;
NMContact *contact = NULL;
- PurpleConversation *gconv;
+ PurpleIMConversation *im;
NMConference *conference;
PurpleMessageFlags flags;
char *text = NULL;
@@ -1777,7 +1784,7 @@ _evt_receive_message(NMUser * user, NMEvent * event)
conference = nm_event_get_conference(event);
if (conference) {
- PurpleConversation *chat = nm_conference_get_data(conference);
+ PurpleChatConversation *chat = nm_conference_get_data(conference);
/* Is this a single person 'conversation' or a conference? */
if (chat == NULL && nm_conference_get_participant_count(conference) == 1) {
@@ -1794,16 +1801,16 @@ _evt_receive_message(NMUser * user, NMEvent * event)
text, flags,
nm_event_get_gmt(event));
- gconv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
+ im = purple_conversations_find_im_with_account(
nm_user_record_get_display_id(user_record),
(PurpleAccount *) user->client_data);
- if (gconv) {
+ if (im) {
contact = nm_find_contact(user, nm_event_get_source(event));
if (contact) {
- purple_conversation_set_title(
- gconv, nm_contact_get_display_name(contact));
+ purple_conversation_set_title(PURPLE_CONVERSATION(im),
+ nm_contact_get_display_name(contact));
} else {
@@ -1814,7 +1821,7 @@ _evt_receive_message(NMUser * user, NMEvent * event)
if (name == NULL)
name = nm_user_record_get_userid(user_record);
- purple_conversation_set_title(gconv, name);
+ purple_conversation_set_title(PURPLE_CONVERSATION(im), name);
}
}
@@ -1845,7 +1852,7 @@ _evt_receive_message(NMUser * user, NMEvent * event)
}
serv_got_chat_in(purple_account_get_connection(user->client_data),
- purple_conv_chat_get_id(PURPLE_CONV_CHAT(chat)),
+ purple_chat_conversation_get_id(chat),
name, 0, text, nm_event_get_gmt(event));
}
}
@@ -1857,7 +1864,7 @@ _evt_receive_message(NMUser * user, NMEvent * event)
static void
_evt_conference_left(NMUser * user, NMEvent * event)
{
- PurpleConversation *chat;
+ PurpleChatConversation *chat;
NMConference *conference;
conference = nm_event_get_conference(event);
@@ -1868,7 +1875,7 @@ _evt_conference_left(NMUser * user, NMEvent * event)
nm_event_get_source(event));
if (ur)
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(chat),
+ purple_chat_conversation_remove_user(chat,
nm_user_record_get_display_id(ur),
NULL);
}
@@ -1945,7 +1952,7 @@ _evt_conference_invite(NMUser * user, NMEvent * event)
static void
_evt_conference_joined(NMUser * user, NMEvent * event)
{
- PurpleConversation *chat = NULL;
+ PurpleChatConversation *chat = NULL;
PurpleConnection *gc;
NMConference *conference = NULL;
NMUserRecord *ur = NULL;
@@ -1970,8 +1977,8 @@ _evt_conference_joined(NMUser * user, NMEvent * event)
nm_conference_set_data(conference, (gpointer) chat);
name = nm_user_record_get_display_id(ur);
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(chat), name, NULL,
- PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(chat, name, NULL,
+ PURPLE_CHAT_USER_NONE, TRUE);
}
}
@@ -1981,9 +1988,9 @@ _evt_conference_joined(NMUser * user, NMEvent * event)
ur = nm_find_user_record(user, nm_event_get_source(event));
if (ur) {
name = nm_user_record_get_display_id(ur);
- if (!purple_conv_chat_find_user(PURPLE_CONV_CHAT(chat), name)) {
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(chat), name, NULL,
- PURPLE_CBFLAGS_NONE, TRUE);
+ if (!purple_chat_conversation_has_user(chat, name)) {
+ purple_chat_conversation_add_user(chat, name, NULL,
+ PURPLE_CHAT_USER_NONE, TRUE);
}
}
}
@@ -2008,7 +2015,7 @@ _evt_status_change(NMUser * user, NMEvent * event)
/* Update status for buddy in all folders */
display_id = nm_user_record_get_display_id(user_record);
- buddies = purple_find_buddies(user->client_data, display_id);
+ buddies = purple_blist_find_buddies(user->client_data, display_id);
for (bnode = buddies; bnode; bnode = bnode->next) {
buddy = (PurpleBuddy *) bnode->data;
if (buddy) {
@@ -2049,7 +2056,7 @@ _evt_user_typing(NMUser * user, NMEvent * event)
user_record = nm_find_user_record(user, nm_event_get_source(event));
if (user_record) {
serv_got_typing(gc, nm_user_record_get_display_id(user_record),
- 30, PURPLE_TYPING);
+ 30, PURPLE_IM_TYPING);
}
}
}
@@ -2081,8 +2088,7 @@ _evt_undeliverable_status(NMUser * user, NMEvent * event)
if (ur) {
/* XXX - Should this be PURPLE_CONV_TYPE_IM? */
gconv =
- purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY,
- nm_user_record_get_display_id(ur),
+ purple_conversations_find_with_account(nm_user_record_get_display_id(ur),
user->client_data);
if (gconv) {
const char *name = nm_user_record_get_full_name(ur);
@@ -2337,7 +2343,7 @@ novell_send_im(PurpleConnection * gc, const char *name,
}
static unsigned int
-novell_send_typing(PurpleConnection * gc, const char *name, PurpleTypingState state)
+novell_send_typing(PurpleConnection * gc, const char *name, PurpleIMTypingState state)
{
NMConference *conf = NULL;
NMUser *user;
@@ -2360,7 +2366,7 @@ novell_send_typing(PurpleConnection * gc, const char *name, PurpleTypingState st
if (conf) {
rc = nm_send_typing(user, conf,
- ((state == PURPLE_TYPING) ? TRUE : FALSE), NULL);
+ ((state == PURPLE_IM_TYPING) ? TRUE : FALSE), NULL);
_check_for_disconnect(user, rc);
}
@@ -2396,7 +2402,7 @@ novell_chat_leave(PurpleConnection * gc, int id)
{
NMConference *conference;
NMUser *user;
- PurpleConversation *chat;
+ PurpleChatConversation *chat;
GSList *cnode;
NMERR_T rc = NM_OK;
@@ -2410,7 +2416,7 @@ novell_chat_leave(PurpleConnection * gc, int id)
for (cnode = user->conferences; cnode != NULL; cnode = cnode->next) {
conference = cnode->data;
if (conference && (chat = nm_conference_get_data(conference))) {
- if (purple_conv_chat_get_id(PURPLE_CONV_CHAT(chat)) == id) {
+ if (purple_chat_conversation_get_id(chat) == id) {
rc = nm_send_leave_conference(user, conference, NULL, NULL);
_check_for_disconnect(user, rc);
break;
@@ -2427,7 +2433,7 @@ novell_chat_invite(PurpleConnection *gc, int id,
{
NMConference *conference;
NMUser *user;
- PurpleConversation *chat;
+ PurpleChatConversation *chat;
GSList *cnode;
NMERR_T rc = NM_OK;
NMUserRecord *user_record = NULL;
@@ -2449,7 +2455,7 @@ novell_chat_invite(PurpleConnection *gc, int id,
for (cnode = user->conferences; cnode != NULL; cnode = cnode->next) {
conference = cnode->data;
if (conference && (chat = nm_conference_get_data(conference))) {
- if (purple_conv_chat_get_id(PURPLE_CONV_CHAT(chat)) == id) {
+ if (purple_chat_conversation_get_id(chat) == id) {
rc = nm_send_conference_invite(user, conference, user_record,
message, _sendinvite_resp_cb, NULL);
_check_for_disconnect(user, rc);
@@ -2463,7 +2469,7 @@ static int
novell_chat_send(PurpleConnection * gc, int id, const char *text, PurpleMessageFlags flags)
{
NMConference *conference;
- PurpleConversation *chat;
+ PurpleChatConversation *chat;
GSList *cnode;
NMMessage *message;
NMUser *user;
@@ -2485,7 +2491,7 @@ novell_chat_send(PurpleConnection * gc, int id, const char *text, PurpleMessageF
for (cnode = user->conferences; cnode != NULL; cnode = cnode->next) {
conference = cnode->data;
if (conference && (chat = nm_conference_get_data(conference))) {
- if (purple_conv_chat_get_id(PURPLE_CONV_CHAT(chat)) == id) {
+ if (purple_chat_conversation_get_id(chat) == id) {
nm_message_set_conference(message, conference);
@@ -2502,7 +2508,7 @@ novell_chat_send(PurpleConnection * gc, int id, const char *text, PurpleMessageF
if (!_check_for_disconnect(user, rc)) {
/* Use the account alias if it is set */
- name = purple_account_get_alias(user->client_data);
+ name = purple_account_get_private_alias(user->client_data);
if (name == NULL || *name == '\0') {
/* If there is no account alias, try full name */
@@ -2525,11 +2531,12 @@ novell_chat_send(PurpleConnection * gc, int id, const char *text, PurpleMessageF
/* The conference was not found, must be closed */
- chat = purple_find_chat(gc, id);
+ chat = purple_conversations_find_chat(gc, id);
if (chat) {
str = g_strdup(_("This conference has been closed."
" No more messages can be sent."));
- purple_conversation_write(chat, NULL, str, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_conversation_write(PURPLE_CONVERSATION(chat), NULL, str,
+ PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(str);
}
@@ -2691,16 +2698,16 @@ novell_alias_buddy(PurpleConnection * gc, const char *name, const char *alias)
if (*fname == '\0') {
fname = NM_ROOT_FOLDER_NAME;
}
- group = purple_find_group(fname);
+ group = purple_blist_find_group(fname);
}
if (group) {
const char *balias;
- buddy = purple_find_buddy_in_group(user->client_data,
+ buddy = purple_blist_find_buddy_in_group(user->client_data,
name, group);
- balias = buddy ? purple_buddy_get_local_buddy_alias(buddy) : NULL;
+ balias = buddy ? purple_buddy_get_local_alias(buddy) : NULL;
if (balias && strcmp(balias, alias))
- purple_blist_alias_buddy(buddy, alias);
+ purple_buddy_set_local_alias(buddy, alias);
}
/* Tell the server to alias the contact */
@@ -2793,7 +2800,7 @@ novell_rename_group(PurpleConnection * gc, const char *old_name,
const char *gname = purple_group_get_name(group);
/* Does new folder exist already? */
if (nm_find_folder(user, gname)) {
- /* purple_blist_rename_group() adds the buddies
+ /* purple_group_set_name() adds the buddies
* to the new group and removes the old group...
* so there is nothing more to do here.
*/
@@ -2975,19 +2982,19 @@ novell_status_types(PurpleAccount *account)
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, NOVELL_STATUS_TYPE_AVAILABLE,
NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
status_types = g_list_append(status_types, type);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY, NOVELL_STATUS_TYPE_AWAY,
NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
status_types = g_list_append(status_types, type);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE, NOVELL_STATUS_TYPE_BUSY,
_("Busy"), TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
status_types = g_list_append(status_types, type);
@@ -3017,7 +3024,7 @@ novell_set_status(PurpleAccount *account, PurpleStatus *status)
connected = purple_account_is_connected(account);
presence = purple_status_get_presence(status);
- type = purple_status_get_type(status);
+ type = purple_status_get_status_type(status);
primitive = purple_status_type_get_primitive(type);
/*
@@ -3086,7 +3093,7 @@ novell_add_permit(PurpleConnection *gc, const char *who)
/* Remove first -- we will add it back in when we get
* the okay from the server
*/
- purple_privacy_permit_remove(purple_connection_get_account(gc), who, TRUE);
+ purple_account_privacy_permit_remove(purple_connection_get_account(gc), who, TRUE);
if (nm_user_is_privacy_locked(user)) {
_show_privacy_locked_error(gc, user);
@@ -3130,7 +3137,7 @@ novell_add_deny(PurpleConnection *gc, const char *who)
/* Remove first -- we will add it back in when we get
* the okay from the server
*/
- purple_privacy_deny_remove(purple_connection_get_account(gc), who, TRUE);
+ purple_account_privacy_deny_remove(purple_connection_get_account(gc), who, TRUE);
if (nm_user_is_privacy_locked(user)) {
_show_privacy_locked_error(gc, user);
@@ -3228,10 +3235,13 @@ novell_set_permit_deny(PurpleConnection *gc)
int i, j, num_contacts, num_folders;
NMContact *contact;
NMFolder *folder = NULL;
+ PurpleAccount *account;
if (gc == NULL)
return;
+ account = purple_connection_get_account(gc);
+
user = purple_connection_get_protocol_data(gc);
if (user == NULL)
return;
@@ -3248,9 +3258,9 @@ novell_set_permit_deny(PurpleConnection *gc)
return;
}
- switch (purple_account_get_privacy_type(purple_connection_get_account(gc))) {
+ switch (purple_account_get_privacy_type(account)) {
- case PURPLE_PRIVACY_ALLOW_ALL:
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL:
rc = nm_send_set_privacy_default(user, FALSE,
_set_privacy_default_resp_cb, NULL);
_check_for_disconnect(user, rc);
@@ -3270,7 +3280,7 @@ novell_set_permit_deny(PurpleConnection *gc)
}
break;
- case PURPLE_PRIVACY_DENY_ALL:
+ case PURPLE_ACCOUNT_PRIVACY_DENY_ALL:
rc = nm_send_set_privacy_default(user, TRUE,
_set_privacy_default_resp_cb, NULL);
_check_for_disconnect(user, rc);
@@ -3290,7 +3300,7 @@ novell_set_permit_deny(PurpleConnection *gc)
}
break;
- case PURPLE_PRIVACY_ALLOW_USERS:
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS:
rc = nm_send_set_privacy_default(user, TRUE,
_set_privacy_default_resp_cb, NULL);
@@ -3304,14 +3314,14 @@ novell_set_permit_deny(PurpleConnection *gc)
if (user_record) {
name = nm_user_record_get_display_id(user_record);
- if (!g_slist_find_custom(purple_connection_get_account(gc)->permit,
+ if (!g_slist_find_custom(purple_account_privacy_get_permitted(account),
name, (GCompareFunc)purple_utf8_strcasecmp)) {
- purple_privacy_permit_add(purple_connection_get_account(gc), name , TRUE);
+ purple_account_privacy_permit_add(account, name , TRUE);
}
}
}
- for (node = purple_connection_get_account(gc)->permit; node; node = node->next) {
+ for (node = purple_account_privacy_get_permitted(account); node; node = node->next) {
dn = nm_lookup_dn(user, (char *)node->data);
if (dn) {
@@ -3322,13 +3332,13 @@ novell_set_permit_deny(PurpleConnection *gc)
g_strdup(dn));
}
} else {
- purple_privacy_permit_remove(purple_connection_get_account(gc), (char *)node->data, TRUE);
+ purple_account_privacy_permit_remove(account, (char *)node->data, TRUE);
}
}
}
break;
- case PURPLE_PRIVACY_DENY_USERS:
+ case PURPLE_ACCOUNT_PRIVACY_DENY_USERS:
/* set to default allow */
rc = nm_send_set_privacy_default(user, FALSE,
@@ -3343,14 +3353,14 @@ novell_set_permit_deny(PurpleConnection *gc)
if (user_record) {
name = nm_user_record_get_display_id(user_record);
- if (!g_slist_find_custom(purple_connection_get_account(gc)->deny,
+ if (!g_slist_find_custom(purple_account_privacy_get_denied(account),
name, (GCompareFunc)purple_utf8_strcasecmp)) {
- purple_privacy_deny_add(purple_connection_get_account(gc), name , TRUE);
+ purple_account_privacy_deny_add(account, name , TRUE);
}
}
}
- for (node = purple_connection_get_account(gc)->deny; node; node = node->next) {
+ for (node = purple_account_privacy_get_denied(account); node; node = node->next) {
name = NULL;
dn = nm_lookup_dn(user, (char *)node->data);
@@ -3365,14 +3375,14 @@ novell_set_permit_deny(PurpleConnection *gc)
g_strdup(name));
}
} else {
- purple_privacy_deny_remove(purple_connection_get_account(gc), (char *)node->data, TRUE);
+ purple_account_privacy_deny_remove(account, (char *)node->data, TRUE);
}
}
}
break;
- case PURPLE_PRIVACY_ALLOW_BUDDYLIST:
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST:
/* remove users from allow list that are not in buddy list */
copy = g_slist_copy(user->allow_list);
@@ -3438,7 +3448,7 @@ novell_blist_node_menu(PurpleBlistNode *node)
GList *list = NULL;
PurpleMenuAction *act;
- if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if(PURPLE_IS_BUDDY(node)) {
act = purple_menu_action_new(_("Initiate _Chat"),
PURPLE_CALLBACK(_initiate_conference_cb),
NULL, NULL);
diff --git a/libpurple/protocols/null/nullprpl.c b/libpurple/protocols/null/nullprpl.c
index 8516f728ab..139ea20ffe 100644
--- a/libpurple/protocols/null/nullprpl.c
+++ b/libpurple/protocols/null/nullprpl.c
@@ -54,13 +54,12 @@
#include "account.h"
#include "accountopt.h"
-#include "blist.h"
+#include "buddylist.h"
#include "cmds.h"
#include "conversation.h"
#include "connection.h"
#include "debug.h"
#include "notify.h"
-#include "privacy.h"
#include "prpl.h"
#include "roomlist.h"
#include "status.h"
@@ -104,7 +103,7 @@ typedef struct {
static PurpleConnection *get_nullprpl_gc(const char *username) {
PurpleAccount *acct = purple_accounts_find(username, NULLPRPL_ID);
if (acct && purple_account_is_connected(acct))
- return acct->gc;
+ return purple_account_get_connection(acct);
else
return NULL;
}
@@ -125,12 +124,12 @@ static void foreach_nullprpl_gc(GcFunc fn, PurpleConnection *from,
}
-typedef void(*ChatFunc)(PurpleConvChat *from, PurpleConvChat *to,
+typedef void(*ChatFunc)(PurpleChatConversation *from, PurpleChatConversation *to,
int id, const char *room, gpointer userdata);
typedef struct {
ChatFunc fn;
- PurpleConvChat *from_chat;
+ PurpleChatConversation *from_chat;
gpointer userdata;
} ChatFuncData;
@@ -138,19 +137,18 @@ static void call_chat_func(gpointer data, gpointer userdata) {
PurpleConnection *to = (PurpleConnection *)data;
ChatFuncData *cfdata = (ChatFuncData *)userdata;
- 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, purple_conversation_get_name(conv), cfdata->userdata);
- }
+ int id = purple_chat_conversation_get_id(cfdata->from_chat);
+ PurpleChatConversation *chat = purple_conversations_find_chat(to, id);
+ if (chat)
+ cfdata->fn(cfdata->from_chat, chat, id,
+ purple_conversation_get_name(PURPLE_CONVERSATION(chat)), cfdata->userdata);
}
static void foreach_gc_in_chat(ChatFunc fn, PurpleConnection *from,
int id, gpointer userdata) {
- PurpleConversation *conv = purple_find_chat(from, id);
+ PurpleChatConversation *chat = purple_conversations_find_chat(from, id);
ChatFuncData cfdata = { fn,
- purple_conversation_get_chat_data(conv),
+ chat,
userdata };
g_list_foreach(purple_connections_get_all(), call_chat_func,
@@ -163,7 +161,7 @@ static void discover_status(PurpleConnection *from, PurpleConnection *to,
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(purple_connection_get_account(from), to_username)) {
+ if (purple_blist_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");
@@ -225,9 +223,10 @@ 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, purple_account_get_username(buddy->account));
+ purple_buddy_get_name(buddy),
+ purple_account_get_username(purple_buddy_get_account(buddy)));
- if (purple_find_buddy(buddy->account, buddy->name)) {
+ if (purple_blist_find_buddy(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy))) {
PurplePresence *presence = purple_buddy_get_presence(buddy);
PurpleStatus *status = purple_presence_get_active_status(presence);
const char *name = purple_status_get_name(status);
@@ -239,11 +238,12 @@ static char *nullprpl_status_text(PurpleBuddy *buddy) {
else
text = g_strdup(name);
- purple_debug_info("nullprpl", "%s's status text is %s\n", buddy->name, text);
+ purple_debug_info("nullprpl", "%s's status text is %s\n",
+ purple_buddy_get_name(buddy), text);
return text;
} else {
- purple_debug_info("nullprpl", "...but %s is not logged in\n", buddy->name);
+ purple_debug_info("nullprpl", "...but %s is not logged in\n", purple_buddy_get_name(buddy));
return g_strdup("Not logged in");
}
}
@@ -251,7 +251,7 @@ static char *nullprpl_status_text(PurpleBuddy *buddy) {
static void nullprpl_tooltip_text(PurpleBuddy *buddy,
PurpleNotifyUserInfo *info,
gboolean full) {
- PurpleConnection *gc = get_nullprpl_gc(buddy->name);
+ PurpleConnection *gc = get_nullprpl_gc(purple_buddy_get_name(buddy));
if (gc) {
/* they're logged in */
@@ -278,7 +278,7 @@ static void nullprpl_tooltip_text(PurpleBuddy *buddy,
}
purple_debug_info("nullprpl", "showing %s tooltip for %s\n",
- (full) ? "full" : "short", buddy->name);
+ (full) ? "full" : "short", purple_buddy_get_name(buddy));
}
static GList *nullprpl_status_types(PurpleAccount *acct)
@@ -292,19 +292,19 @@ static GList *nullprpl_status_types(PurpleAccount *acct)
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
NULL_STATUS_ONLINE, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_prepend(types, type);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY,
NULL_STATUS_AWAY, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_prepend(types, type);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_OFFLINE,
NULL_STATUS_OFFLINE, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_prepend(types, type);
@@ -313,7 +313,7 @@ static GList *nullprpl_status_types(PurpleAccount *acct)
static void blist_example_menu_item(PurpleBlistNode *node, gpointer userdata) {
purple_debug_info("nullprpl", "example menu item clicked on user %s\n",
- ((PurpleBuddy *)node)->name);
+ purple_buddy_get_name(PURPLE_BUDDY(node)));
purple_notify_info(NULL, /* plugin handle or PurpleConnection */
_("Primary title"),
@@ -324,7 +324,7 @@ static void blist_example_menu_item(PurpleBlistNode *node, gpointer userdata) {
static GList *nullprpl_blist_node_menu(PurpleBlistNode *node) {
purple_debug_info("nullprpl", "providing buddy list context menu item\n");
- if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if (PURPLE_IS_BUDDY(node)) {
PurpleMenuAction *action = purple_menu_action_new(
_("Nullprpl example menu item"),
PURPLE_CALLBACK(blist_example_menu_item),
@@ -375,7 +375,7 @@ static void nullprpl_login(PurpleAccount *acct)
purple_connection_update_progress(gc, _("Connected"),
1, /* which connection step this is */
2); /* total number of steps */
- purple_connection_set_state(gc, PURPLE_CONNECTED);
+ purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED);
/* tell purple about everyone on our buddy list who's connected */
foreach_nullprpl_gc(discover_status, gc, NULL);
@@ -423,13 +423,14 @@ 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, purple_account_get_username(purple_connection_get_account(gc)))) {
+ if (to_acct &&
+ !purple_account_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, purple_connection_get_account(gc), msg);
+ purple_conversation_present_error(who, purple_connection_get_account(gc), msg);
g_free(msg);
return 0;
}
@@ -464,11 +465,11 @@ static void nullprpl_set_info(PurpleConnection *gc, const char *info) {
purple_account_get_username(purple_connection_get_account(gc)), info);
}
-static const char *typing_state_to_string(PurpleTypingState typing) {
+static const char *typing_state_to_string(PurpleIMTypingState typing) {
switch (typing) {
- case PURPLE_NOT_TYPING: return "is not typing";
- case PURPLE_TYPING: return "is typing";
- case PURPLE_TYPED: return "stopped typing momentarily";
+ case PURPLE_IM_NOT_TYPING: return "is not typing";
+ case PURPLE_IM_TYPING: return "is typing";
+ case PURPLE_IM_TYPED: return "stopped typing momentarily";
default: return "unknown typing state";
}
}
@@ -476,19 +477,19 @@ static const char *typing_state_to_string(PurpleTypingState typing) {
static void notify_typing(PurpleConnection *from, PurpleConnection *to,
gpointer typing) {
const char *from_username = purple_account_get_username(purple_connection_get_account(from));
- const char *action = typing_state_to_string((PurpleTypingState)typing);
+ const char *action = typing_state_to_string((PurpleIMTypingState)typing);
purple_debug_info("nullprpl", "notifying %s that %s %s\n",
purple_account_get_username(purple_connection_get_account(to)), from_username, action);
serv_got_typing(to,
from_username,
0, /* if non-zero, a timeout in seconds after which to
- * reset the typing status to PURPLE_NOT_TYPING */
- (PurpleTypingState)typing);
+ * reset the typing status to PURPLE_IM_NOT_TYPING */
+ (PurpleIMTypingState)typing);
}
static unsigned int nullprpl_send_typing(PurpleConnection *gc, const char *name,
- PurpleTypingState typing) {
+ PurpleIMTypingState typing) {
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);
@@ -551,9 +552,9 @@ static void nullprpl_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
PurpleGroup *group, const char *message)
{
const char *username = purple_account_get_username(purple_connection_get_account(gc));
- PurpleConnection *buddy_gc = get_nullprpl_gc(buddy->name);
+ PurpleConnection *buddy_gc = get_nullprpl_gc(purple_buddy_get_name(buddy));
- purple_debug_info("nullprpl", "adding %s to %s's buddy list\n", buddy->name,
+ purple_debug_info("nullprpl", "adding %s to %s's buddy list\n", purple_buddy_get_name(buddy),
username);
if (buddy_gc) {
@@ -561,12 +562,12 @@ static void nullprpl_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
discover_status(gc, buddy_gc, NULL);
- if (purple_find_buddy(buddy_acct, username)) {
+ if (purple_blist_find_buddy(buddy_acct, username)) {
purple_debug_info("nullprpl", "%s is already on %s's buddy list\n",
- username, buddy->name);
+ username, purple_buddy_get_name(buddy));
} else {
purple_debug_info("nullprpl", "asking %s if they want to add %s\n",
- buddy->name, username);
+ purple_buddy_get_name(buddy), username);
purple_account_request_add(buddy_acct,
username,
NULL, /* local account id (rarely used) */
@@ -594,7 +595,8 @@ 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, purple_account_get_username(purple_connection_get_account(gc)));
+ purple_buddy_get_name(buddy),
+ purple_account_get_username(purple_connection_get_account(gc)));
}
static void nullprpl_remove_buddies(PurpleConnection *gc, GList *buddies,
@@ -644,25 +646,25 @@ static void nullprpl_set_permit_deny(PurpleConnection *gc) {
*/
}
-static void joined_chat(PurpleConvChat *from, PurpleConvChat *to,
+static void joined_chat(PurpleChatConversation *from, PurpleChatConversation *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",
- purple_conv_chat_get_nick(to), purple_conv_chat_get_nick(from), room);
- purple_conv_chat_add_user(to,
- purple_conv_chat_get_nick(from),
+ purple_chat_conversation_get_nick(to), purple_chat_conversation_get_nick(from), room);
+ purple_chat_conversation_add_user(to,
+ purple_chat_conversation_get_nick(from),
NULL, /* user-provided join message, IRC style */
- PURPLE_CBFLAGS_NONE,
+ PURPLE_CHAT_USER_NONE,
TRUE); /* show a join message */
if (from != to) {
/* add them to our chat window */
purple_debug_info("nullprpl", "%s sees that %s is in chat room %s\n",
- purple_conv_chat_get_nick(from), purple_conv_chat_get_nick(to), room);
- purple_conv_chat_add_user(from,
- purple_conv_chat_get_nick(to),
+ purple_chat_conversation_get_nick(from), purple_chat_conversation_get_nick(to), room);
+ purple_chat_conversation_add_user(from,
+ purple_chat_conversation_get_nick(to),
NULL, /* user-provided join message, IRC style */
- PURPLE_CBFLAGS_NONE,
+ PURPLE_CHAT_USER_NONE,
FALSE); /* show a join message */
}
}
@@ -673,7 +675,7 @@ static void nullprpl_join_chat(PurpleConnection *gc, GHashTable *components) {
int chat_id = g_str_hash(room);
purple_debug_info("nullprpl", "%s is joining chat room %s\n", username, room);
- if (!purple_find_chat(gc, chat_id)) {
+ if (!purple_conversations_find_chat(gc, chat_id)) {
serv_got_joined_chat(gc, chat_id, room);
/* tell everyone that we joined, and add them if they're already there */
@@ -720,15 +722,15 @@ 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 = purple_account_get_username(purple_connection_get_account(gc));
- PurpleConversation *conv = purple_find_chat(gc, id);
- const char *room = purple_conversation_get_name(conv);
+ PurpleChatConversation *chat = purple_conversations_find_chat(gc, id);
+ const char *room = purple_conversation_get_name(PURPLE_CONVERSATION(chat));
PurpleAccount *to_acct = purple_accounts_find(who, NULLPRPL_ID);
purple_debug_info("nullprpl", "%s is inviting %s to join chat room %s\n",
username, who, room);
if (to_acct) {
- PurpleConversation *to_conv = purple_find_chat(to_acct->gc, id);
+ PurpleChatConversation *to_conv = purple_conversations_find_chat(purple_account_get_connection(to_acct), id);
if (to_conv) {
char *tmp = g_strdup_printf("%s is already in chat room %s.", who, room);
purple_debug_info("nullprpl",
@@ -742,27 +744,28 @@ static void nullprpl_chat_invite(PurpleConnection *gc, int id,
components = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
g_hash_table_replace(components, "room", g_strdup(room));
g_hash_table_replace(components, "invited_by", g_strdup(username));
- serv_got_chat_invite(to_acct->gc, room, username, message, components);
+ serv_got_chat_invite(purple_account_get_connection(to_acct), room, username, message, components);
}
}
}
-static void left_chat_room(PurpleConvChat *from, PurpleConvChat *to,
+static void left_chat_room(PurpleChatConversation *from, PurpleChatConversation *to,
int id, const char *room, gpointer userdata) {
if (from != to) {
/* tell their chat window that we left */
purple_debug_info("nullprpl", "%s sees that %s left chat room %s\n",
- purple_conv_chat_get_nick(to), purple_conv_chat_get_nick(from), room);
- purple_conv_chat_remove_user(to,
- purple_conv_chat_get_nick(from),
+ purple_chat_conversation_get_nick(to), purple_chat_conversation_get_nick(from), room);
+ purple_chat_conversation_remove_user(to,
+ purple_chat_conversation_get_nick(from),
NULL); /* user-provided message, IRC style */
}
}
static void nullprpl_chat_leave(PurpleConnection *gc, int id) {
- PurpleConversation *conv = purple_find_chat(gc, id);
+ PurpleChatConversation *chat = purple_conversations_find_chat(gc, id);
purple_debug_info("nullprpl", "%s is leaving chat room %s\n",
- purple_account_get_username(purple_connection_get_account(gc)), purple_conversation_get_name(conv));
+ purple_account_get_username(purple_connection_get_account(gc)),
+ purple_conversation_get_name(PURPLE_CONVERSATION(chat)));
/* tell everyone that we left */
foreach_gc_in_chat(left_chat_room, gc, id, NULL);
@@ -773,8 +776,7 @@ static PurpleCmdRet send_whisper(PurpleConversation *conv, const gchar *cmd,
const char *to_username;
const char *message;
const char *from_username;
- PurpleConvChat *chat;
- PurpleConvChatBuddy *chat_buddy;
+ PurpleChatUser *chat_user;
PurpleConnection *to;
/* parse args */
@@ -791,13 +793,13 @@ static PurpleCmdRet send_whisper(PurpleConversation *conv, const gchar *cmd,
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, purple_conversation_get_name(conv), 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);
+ chat_user = purple_chat_conversation_find_user(PURPLE_CHAT_CONVERSATION(conv), to_username);
to = get_nullprpl_gc(to_username);
- if (!chat_buddy) {
+ if (!chat_user) {
/* this will be freed by the caller */
*error = g_strdup_printf(_("%s is not logged in."), to_username);
return PURPLE_CMD_RET_FAILED;
@@ -807,13 +809,14 @@ static PurpleCmdRet send_whisper(PurpleConversation *conv, const gchar *cmd,
} else {
/* write the whisper in the sender's chat window */
char *message_to = g_strdup_printf("%s (to %s)", message, to_username);
- purple_conv_chat_write(chat, from_username, message_to,
- PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_WHISPER,
- time(NULL));
+ purple_conversation_write_message(conv, from_username, message_to,
+ PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_WHISPER,
+ time(NULL));
g_free(message_to);
/* send the whisper */
- serv_chat_whisper(to, purple_conv_chat_get_id(chat), from_username, message);
+ serv_chat_whisper(to, purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv)),
+ from_username, message);
return PURPLE_CMD_RET_OK;
}
@@ -822,37 +825,38 @@ 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 = purple_account_get_username(purple_connection_get_account(gc));
- PurpleConversation *conv = purple_find_chat(gc, id);
+ PurpleChatConversation *chat = purple_conversations_find_chat(gc, id);
purple_debug_info("nullprpl",
"%s receives whisper from %s in chat room %s: %s\n",
- username, who, purple_conversation_get_name(conv), message);
+ username, who, purple_conversation_get_name(PURPLE_CONVERSATION(chat)),
+ message);
/* receive whisper on recipient's account */
serv_got_chat_in(gc, id, who, PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_WHISPER,
message, time(NULL));
}
-static void receive_chat_message(PurpleConvChat *from, PurpleConvChat *to,
+static void receive_chat_message(PurpleChatConversation *from, PurpleChatConversation *to,
int id, const char *room, gpointer userdata) {
const char *message = (const char *)userdata;
- PurpleConnection *to_gc = get_nullprpl_gc(purple_conv_chat_get_nick(to));
+ PurpleConnection *to_gc = get_nullprpl_gc(purple_chat_conversation_get_nick(to));
purple_debug_info("nullprpl",
"%s receives message from %s in chat room %s: %s\n",
- 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,
+ purple_chat_conversation_get_nick(to), purple_chat_conversation_get_nick(from), room, message);
+ serv_got_chat_in(to_gc, id, purple_chat_conversation_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 = purple_account_get_username(purple_connection_get_account(gc));
- PurpleConversation *conv = purple_find_chat(gc, id);
+ PurpleChatConversation *chat = purple_conversations_find_chat(gc, id);
- if (conv) {
+ if (chat) {
purple_debug_info("nullprpl",
"%s is sending message to chat room %s: %s\n", username,
- purple_conversation_get_name(conv), message);
+ purple_conversation_get_name(PURPLE_CONVERSATION(chat)), message);
/* send message to everyone in the chat room */
foreach_gc_in_chat(receive_chat_message, gc, id, (gpointer)message);
@@ -872,10 +876,11 @@ static void nullprpl_register_user(PurpleAccount *acct) {
}
static void nullprpl_get_cb_info(PurpleConnection *gc, int id, const char *who) {
- PurpleConversation *conv = purple_find_chat(gc, id);
+ PurpleChatConversation *chat = purple_conversations_find_chat(gc, id);
purple_debug_info("nullprpl",
"retrieving %s's info for %s in chat room %s\n", who,
- purple_account_get_username(purple_connection_get_account(gc)), purple_conversation_get_name(conv));
+ purple_account_get_username(purple_connection_get_account(gc)),
+ purple_conversation_get_name(PURPLE_CONVERSATION(chat)));
nullprpl_get_info(gc, who);
}
@@ -896,7 +901,8 @@ static void nullprpl_group_buddy(PurpleConnection *gc, const char *who,
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",
- purple_account_get_username(purple_connection_get_account(gc)), old_name, group->name);
+ purple_account_get_username(purple_connection_get_account(gc)), old_name,
+ purple_group_get_name(group));
}
static void nullprpl_convo_closed(PurpleConnection *gc, const char *who) {
@@ -921,42 +927,43 @@ static void nullprpl_set_buddy_icon(PurpleConnection *gc,
static void nullprpl_remove_group(PurpleConnection *gc, PurpleGroup *group) {
purple_debug_info("nullprpl", "%s has removed group %s\n",
- purple_account_get_username(purple_connection_get_account(gc)), group->name);
+ purple_account_get_username(purple_connection_get_account(gc)),
+ purple_group_get_name(group));
}
-static void set_chat_topic_fn(PurpleConvChat *from, PurpleConvChat *to,
+static void set_chat_topic_fn(PurpleChatConversation *from, PurpleChatConversation *to,
int id, const char *room, gpointer userdata) {
const char *topic = (const char *)userdata;
- const char *username = purple_account_get_username(purple_conversation_get_account(purple_conv_chat_get_conversation(from)));
+ const char *username = purple_account_get_username(purple_conversation_get_account(PURPLE_CONVERSATION(from)));
char *msg;
- purple_conv_chat_set_topic(to, username, topic);
+ purple_chat_conversation_set_topic(to, username, topic);
if (topic && *topic)
msg = g_strdup_printf(_("%s sets topic to: %s"), username, topic);
else
msg = g_strdup_printf(_("%s clears topic"), username);
- purple_conv_chat_write(to, username, msg,
- PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG,
- time(NULL));
+ purple_conversation_write_message(PURPLE_CONVERSATION(to), username, msg,
+ PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG,
+ time(NULL));
g_free(msg);
}
static void nullprpl_set_chat_topic(PurpleConnection *gc, int id,
const char *topic) {
- PurpleConversation *conv = purple_find_chat(gc, id);
- PurpleConvChat *chat = purple_conversation_get_chat_data(conv);
+ PurpleChatConversation *chat = purple_conversations_find_chat(gc, id);
const char *last_topic;
if (!chat)
return;
purple_debug_info("nullprpl", "%s sets topic of chat room '%s' to '%s'\n",
- purple_account_get_username(purple_connection_get_account(gc)), purple_conversation_get_name(conv), topic);
+ purple_account_get_username(purple_connection_get_account(gc)),
+ purple_conversation_get_name(PURPLE_CONVERSATION(chat)), topic);
- last_topic = purple_conv_chat_get_topic(chat);
+ last_topic = purple_chat_conversation_get_topic(chat);
if ((!topic && !last_topic) ||
(topic && last_topic && !strcmp(topic, last_topic)))
return; /* topic is unchanged, this is a noop */
@@ -991,11 +998,11 @@ static PurpleRoomlist *nullprpl_roomlist_get_list(PurpleConnection *gc) {
/* add each chat room. the chat ids are cached in seen_ids so that each room
* is only returned once, even if multiple users are in it. */
- for (chats = purple_get_chats(); chats; chats = g_list_next(chats)) {
- PurpleConversation *conv = (PurpleConversation *)chats->data;
+ for (chats = purple_conversations_get_chats(); chats; chats = g_list_next(chats)) {
+ PurpleChatConversation *chat = PURPLE_CHAT_CONVERSATION(chats->data);
PurpleRoomlistRoom *room;
- const char *name = purple_conversation_get_name(conv);
- int id = purple_conv_chat_get_id(purple_conversation_get_chat_data(conv));
+ const char *name = purple_conversation_get_name(PURPLE_CONVERSATION(chat));
+ int id = purple_chat_conversation_get_id(chat);
/* have we already added this room? */
if (g_list_find_custom(seen_ids, name, (GCompareFunc)strcmp))
@@ -1041,7 +1048,7 @@ static gboolean nullprpl_can_receive_file(PurpleConnection *gc,
static gboolean nullprpl_offline_message(const PurpleBuddy *buddy) {
purple_debug_info("nullprpl",
"reporting that offline messages are supported for %s\n",
- buddy->name);
+ purple_buddy_get_name(buddy));
return TRUE;
}
diff --git a/libpurple/protocols/oscar/authorization.c b/libpurple/protocols/oscar/authorization.c
index e2c2e65623..22a43b65b4 100644
--- a/libpurple/protocols/oscar/authorization.c
+++ b/libpurple/protocols/oscar/authorization.c
@@ -37,7 +37,7 @@ oscar_auth_sendrequest(PurpleConnection *gc, const char *bname, const char *msg)
od = purple_connection_get_protocol_data(gc);
account = purple_connection_get_account(gc);
- buddy = purple_find_buddy(account, bname);
+ buddy = purple_blist_find_buddy(account, bname);
if (buddy != NULL)
group = purple_buddy_get_group(buddy);
else
@@ -96,7 +96,7 @@ oscar_auth_sendrequest_menu(PurpleBlistNode *node, gpointer ignored)
PurpleBuddy *buddy;
PurpleConnection *gc;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
@@ -115,6 +115,6 @@ oscar_auth_recvrequest(PurpleConnection *gc, gchar *name, gchar *nick, gchar *re
data->nick = nick;
purple_account_request_authorization(account, data->name, NULL, data->nick,
- reason, purple_find_buddy(account, data->name) != NULL,
+ reason, purple_blist_find_buddy(account, data->name) != NULL,
oscar_auth_grant, oscar_auth_dontgrant, data);
}
diff --git a/libpurple/protocols/oscar/clientlogin.c b/libpurple/protocols/oscar/clientlogin.c
index dbc0c28008..ffdd296c54 100644
--- a/libpurple/protocols/oscar/clientlogin.c
+++ b/libpurple/protocols/oscar/clientlogin.c
@@ -38,10 +38,11 @@
#include "oscar.h"
#include "oscarcommon.h"
-
-#include "cipher.h"
#include "core.h"
+#include "ciphers/hmaccipher.h"
+#include "ciphers/sha256hash.h"
+
#define AIM_LOGIN_HOST "api.screenname.aol.com"
#define ICQ_LOGIN_HOST "api.login.icq.net"
@@ -128,15 +129,17 @@ static gchar *generate_error_message(xmlnode *resp, const char *url)
*/
static gchar *hmac_sha256(const char *key, const char *message)
{
- PurpleCipherContext *context;
+ PurpleCipher *cipher;
+ PurpleHash *hash;
guchar digest[32];
- context = purple_cipher_context_new_by_name("hmac", NULL);
- purple_cipher_context_set_option(context, "hash", "sha256");
- purple_cipher_context_set_key(context, (guchar *)key, strlen(key));
- purple_cipher_context_append(context, (guchar *)message, strlen(message));
- purple_cipher_context_digest(context, digest, sizeof(digest));
- purple_cipher_context_destroy(context);
+ hash = purple_sha256_hash_new();
+ cipher = purple_hmac_cipher_new(hash);
+ purple_cipher_set_key(cipher, (guchar *)key, strlen(key));
+ purple_cipher_append(cipher, (guchar *)message, strlen(message));
+ purple_cipher_digest(cipher, digest, sizeof(digest));
+ g_object_unref(cipher);
+ g_object_unref(hash);
return purple_base64_encode(digest, sizeof(digest));
}
diff --git a/libpurple/protocols/oscar/family_auth.c b/libpurple/protocols/oscar/family_auth.c
index b5d3762697..14657a4eda 100644
--- a/libpurple/protocols/oscar/family_auth.c
+++ b/libpurple/protocols/oscar/family_auth.c
@@ -31,7 +31,7 @@
#include <ctype.h>
-#include "cipher.h"
+#include "ciphers/md5hash.h"
/* #define USE_XOR_FOR_ICQ */
@@ -75,14 +75,14 @@ aim_encode_password(const char *password, guint8 *encoded)
static int
aim_encode_password_md5(const char *password, size_t password_len, const char *key, guint8 *digest)
{
- PurpleCipherContext *context;
+ PurpleHash *hash;
- context = purple_cipher_context_new_by_name("md5", NULL);
- purple_cipher_context_append(context, (const guchar *)key, strlen(key));
- purple_cipher_context_append(context, (const guchar *)password, password_len);
- purple_cipher_context_append(context, (const guchar *)AIM_MD5_STRING, strlen(AIM_MD5_STRING));
- purple_cipher_context_digest(context, 16, digest, NULL);
- purple_cipher_context_destroy(context);
+ hash = purple_md5_hash_new();
+ purple_hash_append(hash, (const guchar *)key, strlen(key));
+ purple_hash_append(hash, (const guchar *)password, password_len);
+ purple_hash_append(hash, (const guchar *)AIM_MD5_STRING, strlen(AIM_MD5_STRING));
+ purple_hash_digest(hash, 16, digest, NULL);
+ g_object_unref(hash);
return 0;
}
@@ -90,23 +90,19 @@ aim_encode_password_md5(const char *password, size_t password_len, const char *k
static int
aim_encode_password_md5(const char *password, size_t password_len, const char *key, guint8 *digest)
{
- PurpleCipher *cipher;
- PurpleCipherContext *context;
+ PurpleHash *hash;
guchar passdigest[16];
- cipher = purple_ciphers_find_cipher("md5");
+ hash = purple_md5_hash_new();
+ purple_hash_append(hash, (const guchar *)password, password_len);
+ purple_hash_digest(hash, passdigest, sizeof(passdigest));
+ purple_hash_reset(hash);
- context = purple_cipher_context_new(cipher, NULL);
- purple_cipher_context_append(context, (const guchar *)password, password_len);
- purple_cipher_context_digest(context, passdigest, sizeof(passdigest));
- purple_cipher_context_destroy(context);
-
- context = purple_cipher_context_new(cipher, NULL);
- purple_cipher_context_append(context, (const guchar *)key, strlen(key));
- purple_cipher_context_append(context, passdigest, 16);
- purple_cipher_context_append(context, (const guchar *)AIM_MD5_STRING, strlen(AIM_MD5_STRING));
- purple_cipher_context_digest(context, digest, 16);
- purple_cipher_context_destroy(context);
+ purple_hash_append(hash, (const guchar *)key, strlen(key));
+ purple_hash_append(hash, passdigest, 16);
+ purple_hash_append(hash, (const guchar *)AIM_MD5_STRING, strlen(AIM_MD5_STRING));
+ purple_hash_digest(hash, digest, 16);
+ g_object_unref(hash);
return 0;
}
diff --git a/libpurple/protocols/oscar/family_buddy.c b/libpurple/protocols/oscar/family_buddy.c
index a58232a058..3d38323032 100644
--- a/libpurple/protocols/oscar/family_buddy.c
+++ b/libpurple/protocols/oscar/family_buddy.c
@@ -113,7 +113,7 @@ buddychange(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *f
if (snac->subtype == SNAC_SUBTYPE_BUDDY_ONCOMING &&
userinfo.capabilities & OSCAR_CAPABILITY_XTRAZ) {
PurpleAccount *account = purple_connection_get_account(od->gc);
- PurpleBuddy *buddy = purple_find_buddy(account, userinfo.bn);
+ PurpleBuddy *buddy = purple_blist_find_buddy(account, userinfo.bn);
if (buddy) {
PurplePresence *presence = purple_buddy_get_presence(buddy);
diff --git a/libpurple/protocols/oscar/family_icbm.c b/libpurple/protocols/oscar/family_icbm.c
index d87d8af017..2c90f9c37f 100644
--- a/libpurple/protocols/oscar/family_icbm.c
+++ b/libpurple/protocols/oscar/family_icbm.c
@@ -174,7 +174,7 @@ error(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame,
else
buf = g_strdup_printf(_("Unable to send message: %s"), reason_str);
- if (!purple_conv_present_error(bn, purple_connection_get_account(gc), buf)) {
+ if (!purple_conversation_present_error(bn, purple_connection_get_account(gc), buf)) {
g_free(buf);
if (errcode != 0 && errcode < errcodereasonlen)
buf = g_strdup_printf(_("Unable to send message to %s: %s (%s)"),
@@ -1723,7 +1723,7 @@ static int clientautoresp(OscarData *od, FlapConnection *conn, aim_module_t *mod
if (*unescaped_xstatus) {
purple_debug_misc("oscar", "X-Status reply: %s\n", unescaped_xstatus);
account = purple_connection_get_account(od->gc);
- buddy = purple_find_buddy(account, bn);
+ buddy = purple_blist_find_buddy(account, bn);
presence = purple_buddy_get_presence(buddy);
status = purple_presence_get_status(presence, "mood");
if (status) {
diff --git a/libpurple/protocols/oscar/family_icq.c b/libpurple/protocols/oscar/family_icq.c
index dac6b10b54..a78b2d75aa 100644
--- a/libpurple/protocols/oscar/family_icq.c
+++ b/libpurple/protocols/oscar/family_icq.c
@@ -424,7 +424,7 @@ gotalias(OscarData *od, struct aim_icq_info *info)
gchar who[16];
g_snprintf(who, sizeof(who), "%u", info->uin);
serv_got_alias(gc, who, utf8);
- if ((b = purple_find_buddy(account, who))) {
+ if ((b = purple_blist_find_buddy(account, who))) {
purple_blist_node_set_string((PurpleBlistNode*)b, "servernick", utf8);
}
}
@@ -624,7 +624,7 @@ icqresponse(OscarData *od, aim_modsnac_t *snac, ByteStream *bs)
PurpleStatus *status;
account = purple_connection_get_account(od->gc);
- buddy = purple_find_buddy(account, uin);
+ buddy = purple_blist_find_buddy(account, uin);
presence = purple_buddy_get_presence(buddy);
status = purple_presence_get_active_status(presence);
diff --git a/libpurple/protocols/oscar/family_oservice.c b/libpurple/protocols/oscar/family_oservice.c
index bb57b10061..bd11ee1b8a 100644
--- a/libpurple/protocols/oscar/family_oservice.c
+++ b/libpurple/protocols/oscar/family_oservice.c
@@ -25,7 +25,7 @@
#include "oscar.h"
-#include "cipher.h"
+#include "ciphers/md5hash.h"
/*
* Each time we make a FLAP connection to an oscar server the server gives
diff --git a/libpurple/protocols/oscar/flap_connection.c b/libpurple/protocols/oscar/flap_connection.c
index a592a4e753..9a7eaf98b8 100644
--- a/libpurple/protocols/oscar/flap_connection.c
+++ b/libpurple/protocols/oscar/flap_connection.c
@@ -336,7 +336,7 @@ flap_connection_new(OscarData *od, int type)
conn = g_new0(FlapConnection, 1);
conn->od = od;
- conn->buffer_outgoing = purple_circ_buffer_new(0);
+ conn->buffer_outgoing = purple_circular_buffer_new(0);
conn->fd = -1;
conn->subtype = -1;
conn->type = type;
@@ -410,7 +410,7 @@ flap_connection_close(OscarData *od, FlapConnection *conn)
g_free(conn->buffer_incoming.data.data);
conn->buffer_incoming.data.data = NULL;
- purple_circ_buffer_destroy(conn->buffer_outgoing);
+ g_object_unref(G_OBJECT(conn->buffer_outgoing));
conn->buffer_outgoing = NULL;
}
@@ -1020,9 +1020,11 @@ send_cb(gpointer data, gint source, PurpleInputCondition cond)
{
FlapConnection *conn;
int writelen, ret;
+ const gchar *output = NULL;
conn = data;
- writelen = purple_circ_buffer_get_max_read(conn->buffer_outgoing);
+ writelen = purple_circular_buffer_get_max_read(conn->buffer_outgoing);
+ output = purple_circular_buffer_get_output(conn->buffer_outgoing);
if (writelen == 0)
{
@@ -1032,10 +1034,9 @@ send_cb(gpointer data, gint source, PurpleInputCondition cond)
}
if (conn->gsc)
- ret = purple_ssl_write(conn->gsc, conn->buffer_outgoing->outptr,
- writelen);
+ ret = purple_ssl_write(conn->gsc, output, writelen);
else
- ret = send(conn->fd, conn->buffer_outgoing->outptr, writelen, 0);
+ ret = send(conn->fd, output, writelen, 0);
if (ret <= 0)
{
if (ret < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
@@ -1057,7 +1058,7 @@ send_cb(gpointer data, gint source, PurpleInputCondition cond)
return;
}
- purple_circ_buffer_mark_read(conn->buffer_outgoing, ret);
+ purple_circular_buffer_mark_read(conn->buffer_outgoing, ret);
}
static void
@@ -1074,7 +1075,7 @@ flap_connection_send_byte_stream(ByteStream *bs, FlapConnection *conn, size_t co
return;
/* Add everything to our outgoing buffer */
- purple_circ_buffer_append(conn->buffer_outgoing, bs->data, count);
+ purple_circular_buffer_append(conn->buffer_outgoing, bs->data, count);
/* If we haven't already started writing stuff, then start the cycle */
if (conn->watcher_outgoing == 0)
diff --git a/libpurple/protocols/oscar/odc.c b/libpurple/protocols/oscar/odc.c
index c276e38aa2..ced7c18313 100644
--- a/libpurple/protocols/oscar/odc.c
+++ b/libpurple/protocols/oscar/odc.c
@@ -60,11 +60,12 @@ peer_odc_close(PeerConnection *conn)
if (tmp != NULL)
{
PurpleAccount *account;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
account = purple_connection_get_account(conn->od->gc);
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->bn);
- purple_conversation_write(conv, NULL, tmp, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ im = purple_im_conversation_new(account, conn->bn);
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, tmp,
+ PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(tmp);
}
@@ -149,16 +150,16 @@ peer_odc_send_cookie(PeerConnection *conn)
* Send client-to-client typing notification over an established direct connection.
*/
void
-peer_odc_send_typing(PeerConnection *conn, PurpleTypingState typing)
+peer_odc_send_typing(PeerConnection *conn, PurpleIMTypingState typing)
{
OdcFrame frame;
memset(&frame, 0, sizeof(OdcFrame));
frame.type = 0x0001;
frame.subtype = 0x0006;
- if (typing == PURPLE_TYPING)
+ if (typing == PURPLE_IM_TYPING)
frame.flags = 0x0002 | 0x0008;
- else if (typing == PURPLE_TYPED)
+ else if (typing == PURPLE_IM_TYPED)
frame.flags = 0x0002 | 0x0004;
else
frame.flags = 0x0002;
@@ -524,7 +525,7 @@ peer_odc_recv_frame(PeerConnection *conn, ByteStream *bs)
*/
PurpleAccount *account;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
if (conn->flags & PEER_CONNECTION_FLAG_IS_INCOMING)
{
@@ -565,8 +566,8 @@ peer_odc_recv_frame(PeerConnection *conn, ByteStream *bs)
/* Tell the local user that we are connected */
account = purple_connection_get_account(gc);
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->bn);
- purple_conversation_write(conv, NULL, _("Direct IM established"),
+ im = purple_im_conversation_new(account, conn->bn);
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, _("Direct IM established"),
PURPLE_MESSAGE_SYSTEM, time(NULL));
}
@@ -584,11 +585,11 @@ peer_odc_recv_frame(PeerConnection *conn, ByteStream *bs)
purple_debug_info("oscar", "ohmigod! %s has started typing "
"(DirectIM). He's going to send you a message! "
"*squeal*\n", conn->bn);
- serv_got_typing(gc, conn->bn, 0, PURPLE_TYPING);
+ serv_got_typing(gc, conn->bn, 0, PURPLE_IM_TYPING);
}
else if (frame->flags & 0x0004)
{
- serv_got_typing(gc, conn->bn, 0, PURPLE_TYPED);
+ serv_got_typing(gc, conn->bn, 0, PURPLE_IM_TYPED);
}
else
{
@@ -601,7 +602,7 @@ peer_odc_recv_frame(PeerConnection *conn, ByteStream *bs)
{
gchar *tmp, *size1, *size2;
PurpleAccount *account;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
size1 = purple_str_size_to_units(frame->payload.len);
size2 = purple_str_size_to_units(DIRECTIM_MAX_FILESIZE);
@@ -610,8 +611,8 @@ peer_odc_recv_frame(PeerConnection *conn, ByteStream *bs)
g_free(size2);
account = purple_connection_get_account(conn->od->gc);
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->bn);
- purple_conversation_write(conv, NULL, tmp, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ im = purple_im_conversation_new(account, conn->bn);
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, tmp, PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(tmp);
peer_connection_destroy(conn, OSCAR_DISCONNECT_LOCAL_CLOSED, NULL);
diff --git a/libpurple/protocols/oscar/oft.c b/libpurple/protocols/oscar/oft.c
index 49cbcb06da..c3cf730000 100644
--- a/libpurple/protocols/oscar/oft.c
+++ b/libpurple/protocols/oscar/oft.c
@@ -360,7 +360,7 @@ start_transfer_when_done_sending_data(gpointer data)
conn = data;
- if (purple_circ_buffer_get_max_read(conn->buffer_outgoing) == 0)
+ if (purple_circular_buffer_get_max_read(conn->buffer_outgoing) == 0)
{
int fd = conn->fd;
conn->sending_data_timer = 0;
@@ -385,7 +385,7 @@ destroy_connection_when_done_sending_data(gpointer data)
conn = data;
- if (purple_circ_buffer_get_max_read(conn->buffer_outgoing) == 0)
+ if (purple_circular_buffer_get_max_read(conn->buffer_outgoing) == 0)
{
conn->sending_data_timer = 0;
peer_connection_destroy(conn, conn->disconnect_reason, NULL);
diff --git a/libpurple/protocols/oscar/oscar.c b/libpurple/protocols/oscar/oscar.c
index 9a8ecda387..4eb7c9ad1e 100644
--- a/libpurple/protocols/oscar/oscar.c
+++ b/libpurple/protocols/oscar/oscar.c
@@ -33,7 +33,7 @@
#include "account.h"
#include "accountopt.h"
#include "buddyicon.h"
-#include "cipher.h"
+#include "ciphers/md5hash.h"
#include "conversation.h"
#include "core.h"
#include "debug.h"
@@ -41,7 +41,6 @@
#include "imgstore.h"
#include "network.h"
#include "notify.h"
-#include "privacy.h"
#include "prpl.h"
#include "proxy.h"
#include "request.h"
@@ -97,10 +96,10 @@ static int purple_parse_misses (OscarData *, FlapConnection *, FlapFrame *,
static int purple_parse_clientauto (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_parse_motd (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_chatnav_info (OscarData *, FlapConnection *, FlapFrame *, ...);
-static int purple_conv_chat_join (OscarData *, FlapConnection *, FlapFrame *, ...);
-static int purple_conv_chat_leave (OscarData *, FlapConnection *, FlapFrame *, ...);
-static int purple_conv_chat_info_update (OscarData *, FlapConnection *, FlapFrame *, ...);
-static int purple_conv_chat_incoming_msg(OscarData *, FlapConnection *, FlapFrame *, ...);
+static int purple_chat_conversation_join (OscarData *, FlapConnection *, FlapFrame *, ...);
+static int purple_chat_conversation_left (OscarData *, FlapConnection *, FlapFrame *, ...);
+static int purple_chat_conversation_info_update (OscarData *, FlapConnection *, FlapFrame *, ...);
+static int purple_chat_conversation_incoming_msg(OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_email_parseupdate(OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_icon_parseicon (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_parse_searcherror(OscarData *, FlapConnection *, FlapFrame *, ...);
@@ -243,7 +242,7 @@ find_oscar_chat_by_conn(PurpleConnection *gc, FlapConnection *conn)
}
static struct chat_connection *
-find_oscar_chat_by_conv(PurpleConnection *gc, PurpleConversation *conv)
+find_oscar_chat_by_conv(PurpleConnection *gc, PurpleChatConversation *conv)
{
OscarData *od = purple_connection_get_protocol_data(gc);
GSList *cur;
@@ -273,7 +272,7 @@ oscar_chat_kill(PurpleConnection *gc, struct chat_connection *cc)
OscarData *od = purple_connection_get_protocol_data(gc);
/* Notify the conversation window that we've left the chat */
- serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(cc->conv)));
+ serv_got_chat_left(gc, purple_chat_conversation_get_id(cc->conv));
/* Destroy the chat_connection */
od->oscar_chats = g_slist_remove(od->oscar_chats, cc);
@@ -668,10 +667,10 @@ oscar_login(PurpleAccount *account)
oscar_data_addhandler(od, SNAC_FAMILY_BUDDY, SNAC_SUBTYPE_BUDDY_ONCOMING, purple_parse_oncoming, 0);
oscar_data_addhandler(od, SNAC_FAMILY_BUDDY, SNAC_SUBTYPE_BUDDY_OFFGOING, purple_parse_offgoing, 0);
oscar_data_addhandler(od, SNAC_FAMILY_CHAT, 0x0001, purple_parse_genericerr, 0);
- oscar_data_addhandler(od, SNAC_FAMILY_CHAT, SNAC_SUBTYPE_CHAT_USERJOIN, purple_conv_chat_join, 0);
- oscar_data_addhandler(od, SNAC_FAMILY_CHAT, SNAC_SUBTYPE_CHAT_USERLEAVE, purple_conv_chat_leave, 0);
- oscar_data_addhandler(od, SNAC_FAMILY_CHAT, SNAC_SUBTYPE_CHAT_ROOMINFOUPDATE, purple_conv_chat_info_update, 0);
- oscar_data_addhandler(od, SNAC_FAMILY_CHAT, SNAC_SUBTYPE_CHAT_INCOMINGMSG, purple_conv_chat_incoming_msg, 0);
+ oscar_data_addhandler(od, SNAC_FAMILY_CHAT, SNAC_SUBTYPE_CHAT_USERJOIN, purple_chat_conversation_join, 0);
+ oscar_data_addhandler(od, SNAC_FAMILY_CHAT, SNAC_SUBTYPE_CHAT_USERLEAVE, purple_chat_conversation_left, 0);
+ oscar_data_addhandler(od, SNAC_FAMILY_CHAT, SNAC_SUBTYPE_CHAT_ROOMINFOUPDATE, purple_chat_conversation_info_update, 0);
+ oscar_data_addhandler(od, SNAC_FAMILY_CHAT, SNAC_SUBTYPE_CHAT_INCOMINGMSG, purple_chat_conversation_incoming_msg, 0);
oscar_data_addhandler(od, SNAC_FAMILY_CHATNAV, 0x0001, purple_parse_genericerr, 0);
oscar_data_addhandler(od, SNAC_FAMILY_CHATNAV, SNAC_SUBTYPE_CHATNAV_INFO, purple_chatnav_info, 0);
oscar_data_addhandler(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_ERROR, purple_ssi_parseerr, 0);
@@ -719,17 +718,17 @@ oscar_login(PurpleAccount *account)
return;
}
- flags = PURPLE_CONNECTION_HTML;
+ flags = PURPLE_CONNECTION_FLAG_HTML;
if (g_str_equal(purple_account_get_protocol_id(account), "prpl-icq")) {
od->icq = TRUE;
} else {
- flags |= PURPLE_CONNECTION_AUTO_RESP;
+ flags |= PURPLE_CONNECTION_FLAG_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"))
- flags |= PURPLE_CONNECTION_SUPPORT_MOODS;
+ flags |= PURPLE_CONNECTION_FLAG_SUPPORT_MOODS;
purple_connection_set_flags(gc, flags);
@@ -1176,7 +1175,7 @@ static int purple_parse_oncoming(OscarData *od, FlapConnection *conn, FlapFrame
g_return_val_if_fail(info != NULL, 1);
g_return_val_if_fail(info->bn != NULL, 1);
- buddy = purple_find_buddy(account, info->bn);
+ buddy = purple_blist_find_buddy(account, info->bn);
if (buddy) {
previous_status = purple_presence_get_active_status(purple_buddy_get_presence(buddy));
}
@@ -1305,7 +1304,7 @@ static int purple_parse_oncoming(OscarData *od, FlapConnection *conn, FlapFrame
PurpleBuddy *b = NULL;
b16 = purple_base16_encode(info->iconcsum, info->iconcsumlen);
- b = purple_find_buddy(account, info->bn);
+ b = purple_blist_find_buddy(account, info->bn);
if (b != NULL)
saved_b16 = purple_buddy_icons_get_checksum_for_user(b);
@@ -2035,7 +2034,7 @@ static int purple_parse_misses(OscarData *od, FlapConnection *conn, FlapFrame *f
break;
}
- if (!purple_conv_present_error(userinfo->bn, account, buf))
+ if (!purple_conversation_present_error(userinfo->bn, account, buf))
purple_notify_error(od->gc, NULL, buf, NULL);
g_free(buf);
@@ -2199,11 +2198,11 @@ static int purple_parse_mtn(OscarData *od, FlapConnection *conn, FlapFrame *fr,
} break;
case 0x0001: { /* Paused typing */
- serv_got_typing(gc, bn, 0, PURPLE_TYPED);
+ serv_got_typing(gc, bn, 0, PURPLE_IM_TYPED);
} break;
case 0x0002: { /* Typing */
- serv_got_typing(gc, bn, 0, PURPLE_TYPING);
+ serv_got_typing(gc, bn, 0, PURPLE_IM_TYPING);
} break;
case 0x000f: { /* Closed IM window */
@@ -2317,7 +2316,7 @@ static int purple_chatnav_info(OscarData *od, FlapConnection *conn, FlapFrame *f
return 1;
}
-static int purple_conv_chat_join(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
+static int purple_chat_conversation_join(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
va_list ap;
int count, i;
aim_userinfo_t *info;
@@ -2335,12 +2334,12 @@ static int purple_conv_chat_join(OscarData *od, FlapConnection *conn, FlapFrame
return 1;
for (i = 0; i < count; i++)
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(c->conv), info[i].bn, NULL, PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(c->conv, info[i].bn, NULL, PURPLE_CHAT_USER_NONE, TRUE);
return 1;
}
-static int purple_conv_chat_leave(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
+static int purple_chat_conversation_left(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
va_list ap;
int count, i;
aim_userinfo_t *info;
@@ -2358,12 +2357,12 @@ static int purple_conv_chat_leave(OscarData *od, FlapConnection *conn, FlapFrame
return 1;
for (i = 0; i < count; i++)
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(c->conv), info[i].bn, NULL);
+ purple_chat_conversation_remove_user(c->conv, info[i].bn, NULL);
return 1;
}
-static int purple_conv_chat_info_update(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
+static int purple_chat_conversation_info_update(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
va_list ap;
guint16 maxmsglen, maxvisiblemsglen;
PurpleConnection *gc = od->gc;
@@ -2387,7 +2386,7 @@ static int purple_conv_chat_info_update(OscarData *od, FlapConnection *conn, Fla
return 1;
}
-static int purple_conv_chat_incoming_msg(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
+static int purple_chat_conversation_incoming_msg(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
PurpleConnection *gc = od->gc;
struct chat_connection *ccon = find_oscar_chat_by_conn(gc, conn);
gchar *utf8;
@@ -2556,14 +2555,14 @@ static int purple_connerr(OscarData *od, FlapConnection *conn, FlapFrame *fr, ..
if (conn->type == SNAC_FAMILY_CHAT) {
struct chat_connection *cc;
- PurpleConversation *conv = NULL;
+ PurpleChatConversation *chat = NULL;
cc = find_oscar_chat_by_conn(gc, conn);
if (cc != NULL)
{
- conv = purple_find_chat(gc, cc->id);
+ chat = purple_conversations_find_chat(gc, cc->id);
- if (conv != NULL)
+ if (chat != NULL)
{
/*
* TOOD: Have flap_connection_destroy_cb() send us the
@@ -2573,7 +2572,8 @@ static int purple_connerr(OscarData *od, FlapConnection *conn, FlapFrame *fr, ..
gchar *buf;
buf = g_strdup_printf(_("You have been disconnected from chat "
"room %s."), cc->name);
- purple_conversation_write(conv, NULL, buf, PURPLE_MESSAGE_ERROR, time(NULL));
+ purple_conversation_write(PURPLE_CONVERSATION(chat), NULL, buf,
+ PURPLE_MESSAGE_ERROR, time(NULL));
g_free(buf);
}
oscar_chat_kill(gc, cc);
@@ -2753,7 +2753,7 @@ static int purple_bosrights(OscarData *od, FlapConnection *conn, FlapFrame *fr,
/* Request offline messages for AIM and ICQ */
aim_im_reqofflinemsgs(od);
- purple_connection_set_state(gc, PURPLE_CONNECTED);
+ purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED);
}
return 1;
@@ -2944,7 +2944,7 @@ oscar_keepalive(PurpleConnection *gc)
}
unsigned int
-oscar_send_typing(PurpleConnection *gc, const char *name, PurpleTypingState state)
+oscar_send_typing(PurpleConnection *gc, const char *name, PurpleIMTypingState state)
{
OscarData *od;
PeerConnection *conn;
@@ -2958,14 +2958,16 @@ oscar_send_typing(PurpleConnection *gc, const char *name, PurpleTypingState stat
}
else {
/* Don't send if this turkey is in our deny list */
+ PurpleAccount *account = purple_connection_get_account(gc);
GSList *list;
- for (list=purple_connection_get_account(gc)->deny; (list && oscar_util_name_compare(name, list->data)); list=list->next);
+
+ for (list=purple_account_privacy_get_denied(account); (list && oscar_util_name_compare(name, list->data)); list=list->next);
if (!list) {
- struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(purple_connection_get_account(gc), name));
+ struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, name));
if (bi && bi->typingnot) {
- if (state == PURPLE_TYPING)
+ if (state == PURPLE_IM_TYPING)
aim_im_sendmtn(od, 0x0001, name, 0x0002);
- else if (state == PURPLE_TYPED)
+ else if (state == PURPLE_IM_TYPED)
aim_im_sendmtn(od, 0x0001, name, 0x0001);
else
aim_im_sendmtn(od, 0x0001, name, 0x0000);
@@ -3106,19 +3108,19 @@ oscar_send_im(PurpleConnection *gc, const char *name, const char *message, Purpl
} else {
struct buddyinfo *bi;
struct aim_sendimext_args args;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
PurpleStoredImage *img;
PurpleBuddy *buddy;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, name, account);
+ im = purple_conversations_find_im_with_account(name, account);
if (strstr(tmp1, "<IMG "))
- purple_conversation_write(conv, "",
+ purple_conversation_write(PURPLE_CONVERSATION(im), "",
_("Your IM Image was not sent. "
"You must be Direct Connected to send IM Images."),
PURPLE_MESSAGE_ERROR, time(NULL));
- buddy = purple_find_buddy(account, name);
+ buddy = purple_blist_find_buddy(account, name);
bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, name));
if (!bi) {
@@ -3332,7 +3334,7 @@ oscar_set_info_and_status(PurpleAccount *account, gboolean setinfo, const char *
char *status_text = NULL;
const char *itmsurl = NULL;
- status_type = purple_status_get_type(status);
+ status_type = purple_status_get_status_type(status);
primitive = purple_status_type_get_primitive(status_type);
if (!setinfo)
@@ -3439,12 +3441,12 @@ oscar_set_icq_permdeny(PurpleAccount *account)
/*
* For ICQ the permit/deny setting controls who can see you
- * online. Mimicking the official client's behavior, we use PURPLE_PRIVACY_ALLOW_USERS
- * when our status is "invisible" and PURPLE_PRIVACY_DENY_USERS otherwise.
+ * online. Mimicking the official client's behavior, we use PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS
+ * when our status is "invisible" and PURPLE_ACCOUNT_PRIVACY_DENY_USERS otherwise.
* In the former case, we are visible only to buddies on our "permanently visible" list.
* In the latter, we are invisible only to buddies on our "permanently invisible" list.
*/
- aim_ssi_setpermdeny(od, invisible ? PURPLE_PRIVACY_ALLOW_USERS : PURPLE_PRIVACY_DENY_USERS);
+ aim_ssi_setpermdeny(od, invisible ? PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS : PURPLE_ACCOUNT_PRIVACY_DENY_USERS);
}
void
@@ -3467,7 +3469,7 @@ oscar_set_status(PurpleAccount *account, PurpleStatus *status)
od = purple_connection_get_protocol_data(pc);
/* There's no need to do the stuff below for mood updates. */
- if (purple_status_type_get_primitive(purple_status_get_type(status)) == PURPLE_STATUS_MOOD) {
+ if (purple_status_type_get_primitive(purple_status_get_status_type(status)) == PURPLE_STATUS_MOOD) {
aim_locate_setcaps(od, purple_caps);
return;
}
@@ -3496,7 +3498,7 @@ oscar_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, co
if (!oscar_util_valid_name(bname)) {
gchar *buf;
buf = g_strdup_printf(_("Unable to add the buddy %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."), bname);
- if (!purple_conv_present_error(bname, account, buf))
+ if (!purple_conversation_present_error(bname, account, buf))
purple_notify_error(gc, NULL, _("Unable to Add"), buf);
g_free(buf);
@@ -3708,7 +3710,7 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
/* Buddies */
cur = NULL;
- for (buddies = purple_find_buddies(account, NULL);
+ for (buddies = purple_blist_find_buddies(account, NULL);
buddies;
buddies = g_slist_delete_link(buddies, buddies))
{
@@ -3731,7 +3733,7 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
/* Store local alias on server */
alias = aim_ssi_getalias(&od->ssi.local, gname, bname);
- balias = purple_buddy_get_local_buddy_alias(b);
+ balias = purple_buddy_get_local_alias(b);
if (!alias && balias && *balias)
aim_ssi_aliasbuddy(od, gname, bname, balias);
g_free(alias);
@@ -3749,27 +3751,27 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
/* Permit list (ICQ doesn't have one) */
if (!od->icq) {
- next = account->permit;
+ next = purple_account_privacy_get_permitted(account);
while (next != NULL) {
cur = next;
next = next->next;
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);
+ purple_account_privacy_permit_remove(account, cur->data, TRUE);
}
}
}
/* Deny list */
- next = account->deny;
+ next = purple_account_privacy_get_denied(account);
while (next != NULL) {
cur = next;
next = next->next;
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);
+ purple_account_privacy_deny_remove(account, cur->data, TRUE);
}
}
@@ -3810,7 +3812,7 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
gname = groupitem ? groupitem->name : NULL;
gname_utf8 = oscar_utf8_try_convert(account, od, gname);
- g = purple_find_group(gname_utf8 ? gname_utf8 : _("Buddies"));
+ g = purple_blist_find_group(gname_utf8 ? gname_utf8 : _("Buddies"));
if (g == NULL) {
g = purple_group_new(gname_utf8 ? gname_utf8 : _("Buddies"));
purple_blist_add_group(g, NULL);
@@ -3819,10 +3821,10 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
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);
+ b = purple_blist_find_buddy_in_group(account, curitem->name, g);
if (b) {
/* Get server stored alias */
- purple_blist_alias_buddy(b, alias_utf8);
+ purple_buddy_set_local_alias(b, alias_utf8);
} else {
b = purple_buddy_new(account, curitem->name, alias_utf8);
@@ -3848,7 +3850,7 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
} break;
case AIM_SSI_TYPE_GROUP: { /* Group */
- if (curitem->name != NULL && purple_find_group(curitem->name) == NULL) {
+ if (curitem->name != NULL && purple_blist_find_group(curitem->name) == NULL) {
g = purple_group_new(curitem->name);
purple_blist_add_group(g, NULL);
}
@@ -3856,11 +3858,11 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
case AIM_SSI_TYPE_PERMIT: { /* Permit buddy (unless we're on ICQ) */
if (!od->icq && curitem->name) {
- for (cur = account->permit; (cur && oscar_util_name_compare(curitem->name, cur->data)); cur = cur->next);
+ for (cur = purple_account_privacy_get_permitted(account); (cur && oscar_util_name_compare(curitem->name, cur->data)); cur = cur->next);
if (!cur) {
purple_debug_info("oscar",
"ssi: adding permit buddy %s to local list\n", curitem->name);
- purple_privacy_permit_add(account, curitem->name, TRUE);
+ purple_account_privacy_permit_add(account, curitem->name, TRUE);
}
}
} break;
@@ -3868,11 +3870,11 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
case AIM_SSI_TYPE_ICQDENY:
case AIM_SSI_TYPE_DENY: { /* Deny buddy */
if (curitem->type == deny_entry_type && curitem->name) {
- for (cur = account->deny; (cur && oscar_util_name_compare(curitem->name, cur->data)); cur = cur->next);
+ for (cur = purple_account_privacy_get_denied(account); (cur && oscar_util_name_compare(curitem->name, cur->data)); cur = cur->next);
if (!cur) {
purple_debug_info("oscar",
"ssi: adding deny buddy %s to local list\n", curitem->name);
- purple_privacy_deny_add(account, curitem->name, TRUE);
+ purple_account_privacy_deny_add(account, curitem->name, TRUE);
}
}
} break;
@@ -3935,7 +3937,7 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
/* Request offline messages for AIM and ICQ */
aim_im_reqofflinemsgs(od);
- purple_connection_set_state(gc, PURPLE_CONNECTED);
+ purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED);
}
return 1;
@@ -3962,7 +3964,7 @@ static int purple_ssi_parseack(OscarData *od, FlapConnection *conn, FlapFrame *f
case 0x000c: { /* you are over the limit, the cheat is to the limit, come on fhqwhgads */
gchar *buf;
buf = g_strdup_printf(_("Unable to add the buddy %s because you have too many buddies in your buddy list. Please remove one and try again."), (retval->name ? retval->name : _("(no name)")));
- if ((retval->name != NULL) && !purple_conv_present_error(retval->name, purple_connection_get_account(gc), buf))
+ if ((retval->name != NULL) && !purple_conversation_present_error(retval->name, purple_connection_get_account(gc), buf))
purple_notify_error(gc, NULL, _("Unable to Add"), buf);
g_free(buf);
} break;
@@ -3977,7 +3979,7 @@ static int purple_ssi_parseack(OscarData *od, FlapConnection *conn, FlapFrame *f
purple_debug_error("oscar", "ssi: Action 0x%04hx was unsuccessful with error 0x%04hx\n", retval->action, retval->ack);
buf = g_strdup_printf(_("Unable to add the buddy %s for an unknown reason."),
(retval->name ? retval->name : _("(no name)")));
- if ((retval->name != NULL) && !purple_conv_present_error(retval->name, purple_connection_get_account(gc), buf))
+ if ((retval->name != NULL) && !purple_conversation_present_error(retval->name, purple_connection_get_account(gc), buf))
purple_notify_error(gc, NULL, _("Unable to Add"), buf);
g_free(buf);
} break;
@@ -4021,14 +4023,14 @@ purple_ssi_parseaddmod(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
alias_utf8 = oscar_utf8_try_convert(account, od, alias);
g_free(alias);
- b = purple_find_buddy(account, name);
+ b = purple_blist_find_buddy(account, name);
if (b) {
/*
* You're logged in somewhere else and you aliased one
* of your buddies, so update our local buddy list with
* the person's new alias.
*/
- purple_blist_alias_buddy(b, alias_utf8);
+ purple_buddy_set_local_alias(b, alias_utf8);
} else if (snac_subtype == 0x0008) {
/*
* You're logged in somewhere else and you added a buddy to
@@ -4036,7 +4038,7 @@ 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 : _("Buddies")))) {
+ if (!(g = purple_blist_find_group(gname_utf8 ? gname_utf8 : _("Buddies")))) {
g = purple_group_new(gname_utf8 ? gname_utf8 : _("Buddies"));
purple_blist_add_group(g, NULL);
}
@@ -4086,7 +4088,7 @@ static int purple_ssi_authgiven(OscarData *od, FlapConnection *conn, FlapFrame *
purple_debug_info("oscar",
"ssi: %s has given you permission to add him to your buddy list\n", bn);
- buddy = purple_find_buddy(purple_connection_get_account(gc), bn);
+ buddy = purple_blist_find_buddy(purple_connection_get_account(gc), bn);
if (buddy && (purple_buddy_get_alias_only(buddy)))
nombre = g_strdup_printf("%s (%s)", bn, purple_buddy_get_alias_only(buddy));
else
@@ -4155,7 +4157,7 @@ static int purple_ssi_authreply(OscarData *od, FlapConnection *conn, FlapFrame *
purple_debug_info("oscar",
"ssi: received authorization reply from %s. Reply is 0x%04hx\n", bn, reply);
- buddy = purple_find_buddy(purple_connection_get_account(gc), bn);
+ buddy = purple_blist_find_buddy(purple_connection_get_account(gc), bn);
if (buddy && (purple_buddy_get_alias_only(buddy)))
nombre = g_strdup_printf("%s (%s)", bn, purple_buddy_get_alias_only(buddy));
else
@@ -4187,7 +4189,7 @@ static int purple_ssi_gotadded(OscarData *od, FlapConnection *conn, FlapFrame *f
bn = va_arg(ap, char *);
va_end(ap);
- buddy = purple_find_buddy(account, bn);
+ buddy = purple_blist_find_buddy(account, bn);
purple_debug_info("oscar", "ssi: %s added you to their buddy list\n", bn);
purple_account_notify_added(account, bn, NULL,
(buddy ? purple_buddy_get_alias_only(buddy) : NULL), NULL);
@@ -4287,17 +4289,17 @@ oscar_chat_invite(PurpleConnection *gc, int id, const char *message, const char
void
oscar_chat_leave(PurpleConnection *gc, int id)
{
- PurpleConversation *conv;
+ PurpleChatConversation *conv;
struct chat_connection *cc;
- conv = purple_find_chat(gc, id);
+ conv = purple_conversations_find_chat(gc, id);
g_return_if_fail(conv != NULL);
purple_debug_info("oscar", "Leaving chat room %s\n",
- purple_conversation_get_name(conv));
+ purple_conversation_get_name(PURPLE_CONVERSATION(conv)));
- cc = find_oscar_chat(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)));
+ cc = find_oscar_chat(gc, purple_chat_conversation_get_id(conv));
flap_connection_schedule_destroy(cc->conn, OSCAR_DISCONNECT_DONE, NULL);
oscar_chat_kill(gc, cc);
}
@@ -4305,14 +4307,14 @@ oscar_chat_leave(PurpleConnection *gc, int id)
int oscar_send_chat(PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags)
{
OscarData *od = purple_connection_get_protocol_data(gc);
- PurpleConversation *conv = NULL;
+ PurpleChatConversation *conv = NULL;
struct chat_connection *c = NULL;
char *buf, *buf2, *buf3;
guint16 charset;
char *charsetstr;
gsize len;
- if (!(conv = purple_find_chat(gc, id)))
+ if (!(conv = purple_conversations_find_chat(gc, id)))
return -EINVAL;
if (!(c = find_oscar_chat_by_conv(gc, conv)))
@@ -4321,7 +4323,7 @@ int oscar_send_chat(PurpleConnection *gc, int id, const char *message, PurpleMes
buf = purple_strdup_withhtml(message);
if (strstr(buf, "<IMG "))
- purple_conversation_write(conv, "",
+ purple_conversation_write(PURPLE_CONVERSATION(conv), "",
_("Your IM Image was not sent. "
"You cannot send IM Images in AIM chats."),
PURPLE_MESSAGE_ERROR, time(NULL));
@@ -4558,16 +4560,16 @@ oscar_status_types(PurpleAccount *account)
OSCAR_STATUS_ID_AVAILABLE,
NULL, TRUE, TRUE, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING),
+ purple_g_value_new(G_TYPE_STRING),
"itmsurl", _("iTunes Music Store Link"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
status_types = g_list_prepend(status_types, type);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
OSCAR_STATUS_ID_FREE4CHAT,
_("Free For Chat"), TRUE, is_icq, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
status_types = g_list_prepend(status_types, type);
@@ -4575,7 +4577,7 @@ oscar_status_types(PurpleAccount *account)
OSCAR_STATUS_ID_EVIL,
_("Evil"), TRUE, is_icq, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
status_types = g_list_prepend(status_types, type);
@@ -4583,7 +4585,7 @@ oscar_status_types(PurpleAccount *account)
OSCAR_STATUS_ID_DEPRESSION,
_("Depression"), TRUE, is_icq, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
status_types = g_list_prepend(status_types, type);
@@ -4591,7 +4593,7 @@ oscar_status_types(PurpleAccount *account)
OSCAR_STATUS_ID_ATHOME,
_("At home"), TRUE, is_icq, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
status_types = g_list_prepend(status_types, type);
@@ -4599,7 +4601,7 @@ oscar_status_types(PurpleAccount *account)
OSCAR_STATUS_ID_ATWORK,
_("At work"), TRUE, is_icq, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
status_types = g_list_prepend(status_types, type);
@@ -4608,7 +4610,7 @@ oscar_status_types(PurpleAccount *account)
OSCAR_STATUS_ID_LUNCH,
_("Lunch"), TRUE, is_icq, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
status_types = g_list_prepend(status_types, type);
@@ -4616,14 +4618,14 @@ oscar_status_types(PurpleAccount *account)
OSCAR_STATUS_ID_AWAY,
NULL, TRUE, TRUE, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
status_types = g_list_prepend(status_types, type);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_INVISIBLE,
OSCAR_STATUS_ID_INVISIBLE,
NULL, TRUE, TRUE, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
status_types = g_list_prepend(status_types, type);
@@ -4635,21 +4637,21 @@ oscar_status_types(PurpleAccount *account)
OSCAR_STATUS_ID_OCCUPIED,
_("Occupied"), TRUE, is_icq, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
status_types = g_list_prepend(status_types, type);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE,
OSCAR_STATUS_ID_DND,
_("Do Not Disturb"), TRUE, is_icq, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
status_types = g_list_prepend(status_types, type);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_EXTENDED_AWAY,
OSCAR_STATUS_ID_NA,
_("Not Available"), TRUE, is_icq, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
status_types = g_list_prepend(status_types, type);
type = purple_status_type_new_full(PURPLE_STATUS_OFFLINE,
@@ -4659,8 +4661,8 @@ oscar_status_types(PurpleAccount *account)
type = purple_status_type_new_with_attrs(PURPLE_STATUS_MOOD,
"mood", NULL, TRUE, is_icq, TRUE,
- PURPLE_MOOD_NAME, _("Mood Name"), purple_value_new(PURPLE_TYPE_STRING),
- PURPLE_MOOD_COMMENT, _("Mood Comment"), purple_value_new(PURPLE_TYPE_STRING),
+ PURPLE_MOOD_NAME, _("Mood Name"), purple_g_value_new(G_TYPE_STRING),
+ PURPLE_MOOD_COMMENT, _("Mood Comment"), purple_g_value_new(G_TYPE_STRING),
NULL);
status_types = g_list_prepend(status_types, type);
@@ -4678,7 +4680,7 @@ static void oscar_ssi_editcomment(struct name_data *data, const char *text) {
od = purple_connection_get_protocol_data(gc);
account = purple_connection_get_account(gc);
- b = purple_find_buddy(account, data->name);
+ b = purple_blist_find_buddy(account, data->name);
if (b == NULL) {
oscar_free_name_data(data);
return;
@@ -4707,7 +4709,7 @@ static void oscar_buddycb_edit_comment(PurpleBlistNode *node, gpointer ignore) {
PurpleAccount *account;
const char *name;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *) node;
name = purple_buddy_get_name(buddy);
@@ -4768,7 +4770,7 @@ oscar_ask_directim(gpointer object, gpointer ignored)
node = object;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *)node;
account = purple_buddy_get_account(buddy);
@@ -4799,14 +4801,14 @@ oscar_close_directim(gpointer object, gpointer ignored)
PurpleBuddy *buddy;
PurpleAccount *account;
PurpleConnection *gc;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
OscarData *od;
PeerConnection *conn;
const char *name;
node = object;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy*)node;
name = purple_buddy_get_name(buddy);
@@ -4824,8 +4826,8 @@ oscar_close_directim(gpointer object, gpointer ignored)
/* OSCAR_DISCONNECT_LOCAL_CLOSED doesn't write anything to the convo
* window. Let the user know that we cancelled the Direct IM. */
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, name);
- purple_conversation_write(conv, NULL, _("You closed the connection."),
+ im = purple_im_conversation_new(account, name);
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, _("You closed the connection."),
PURPLE_MESSAGE_SYSTEM, time(NULL));
}
}
@@ -4838,7 +4840,7 @@ static void oscar_get_icqxstatusmsg(PurpleBlistNode *node, gpointer ignore)
PurpleAccount *account;
const char *bname;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *)node;
bname = purple_buddy_get_name(buddy);
@@ -4858,7 +4860,7 @@ oscar_get_aim_info_cb(PurpleBlistNode *node, gpointer ignore)
PurpleBuddy *buddy;
PurpleConnection *gc;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *)node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
@@ -4958,7 +4960,7 @@ oscar_buddy_menu(PurpleBuddy *buddy) {
GList *oscar_blist_node_menu(PurpleBlistNode *node) {
- if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if(PURPLE_IS_BUDDY(node)) {
return oscar_buddy_menu((PurpleBuddy *) node);
} else {
return NULL;
@@ -5084,7 +5086,7 @@ static void oscar_show_awaitingauth(PurplePluginAction *action)
GSList *buddies, *filtered_buddies, *cur;
gchar *text;
- buddies = purple_find_buddies(account, NULL);
+ buddies = purple_blist_find_buddies(account, NULL);
filtered_buddies = NULL;
for (cur = buddies; cur != NULL; cur = cur->next) {
PurpleBuddy *buddy;
@@ -5176,15 +5178,15 @@ void oscar_set_icon(PurpleConnection *gc, PurpleStoredImage *img)
if (img == NULL) {
aim_ssi_delicon(od);
} else {
- PurpleCipherContext *context;
+ PurpleHash *hash;
guchar md5[16];
gconstpointer data = purple_imgstore_get_data(img);
size_t len = purple_imgstore_get_size(img);
- context = purple_cipher_context_new_by_name("md5", NULL);
- purple_cipher_context_append(context, data, len);
- purple_cipher_context_digest(context, md5, sizeof(md5));
- purple_cipher_context_destroy(context);
+ hash = purple_md5_hash_new();
+ purple_hash_append(hash, data, len);
+ purple_hash_digest(hash, md5, sizeof(md5));
+ g_object_unref(hash);
aim_ssi_seticon(od, md5, 16);
}
@@ -5483,16 +5485,16 @@ static gboolean oscar_uri_handler(const char *proto, const char *cmd, GHashTable
if (bname) {
char *message = g_hash_table_lookup(params, "message");
- PurpleConversation *conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_IM, bname, acct);
- if (conv == NULL)
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, bname);
- purple_conversation_present(conv);
+ PurpleIMConversation *im = purple_conversations_find_im_with_account(
+ bname, acct);
+ if (im == NULL)
+ im = purple_im_conversation_new(acct, bname);
+ purple_conversation_present(PURPLE_CONVERSATION(im));
if (message) {
/* Spaces are encoded as '+' */
g_strdelimit(message, "+", ' ');
- purple_conv_send_confirm(conv, message);
+ purple_conversation_send_confirm(PURPLE_CONVERSATION(im), message);
}
}
/*else
diff --git a/libpurple/protocols/oscar/oscar.h b/libpurple/protocols/oscar/oscar.h
index 7da1d44b16..ea74414ffb 100644
--- a/libpurple/protocols/oscar/oscar.h
+++ b/libpurple/protocols/oscar/oscar.h
@@ -30,7 +30,7 @@
#define _OSCAR_H_
#include "internal.h"
-#include "circbuffer.h"
+#include "circularbuffer.h"
#include "debug.h"
#include "eventloop.h"
#include "http.h"
@@ -280,7 +280,7 @@ struct _FlapConnection
guint8 header[6];
gssize header_received;
FlapFrame buffer_incoming;
- PurpleCircBuffer *buffer_outgoing;
+ PurpleCircularBuffer *buffer_outgoing;
guint watcher_incoming;
guint watcher_outgoing;
@@ -602,7 +602,7 @@ struct chat_connection
FlapConnection *conn;
int id;
PurpleConnection *gc;
- PurpleConversation *conv;
+ PurpleChatConversation *conv;
guint16 maxlen;
guint16 maxvis;
};
diff --git a/libpurple/protocols/oscar/oscarcommon.h b/libpurple/protocols/oscar/oscarcommon.h
index a0647dfe44..a3cadfc0ae 100644
--- a/libpurple/protocols/oscar/oscarcommon.h
+++ b/libpurple/protocols/oscar/oscarcommon.h
@@ -74,7 +74,7 @@ void oscar_login(PurpleAccount *account);
void oscar_close(PurpleConnection *gc);
int oscar_send_im(PurpleConnection *gc, const char *name, const char *message, PurpleMessageFlags imflags);
void oscar_set_info(PurpleConnection *gc, const char *rawinfo);
-unsigned int oscar_send_typing(PurpleConnection *gc, const char *name, PurpleTypingState state);
+unsigned int oscar_send_typing(PurpleConnection *gc, const char *name, PurpleIMTypingState state);
void oscar_get_info(PurpleConnection *gc, const char *name);
void oscar_set_status(PurpleAccount *account, PurpleStatus *status);
void oscar_set_idle(PurpleConnection *gc, int time);
diff --git a/libpurple/protocols/oscar/peer.c b/libpurple/protocols/oscar/peer.c
index 93ed217c46..699781e9aa 100644
--- a/libpurple/protocols/oscar/peer.c
+++ b/libpurple/protocols/oscar/peer.c
@@ -115,7 +115,7 @@ peer_connection_new(OscarData *od, guint64 type, const char *bn)
conn->od = od;
conn->type = type;
conn->bn = g_strdup(bn);
- conn->buffer_outgoing = purple_circ_buffer_new(0);
+ conn->buffer_outgoing = purple_circular_buffer_new(0);
conn->listenerfd = -1;
conn->fd = -1;
conn->lastactivity = time(NULL);
@@ -189,8 +189,8 @@ peer_connection_close(PeerConnection *conn)
conn->buffer_incoming.len = 0;
conn->buffer_incoming.offset = 0;
- purple_circ_buffer_destroy(conn->buffer_outgoing);
- conn->buffer_outgoing = purple_circ_buffer_new(0);
+ g_object_unref(G_OBJECT(conn->buffer_outgoing));
+ conn->buffer_outgoing = purple_circular_buffer_new(0);
conn->flags &= ~PEER_CONNECTION_FLAG_IS_INCOMING;
}
@@ -234,7 +234,7 @@ peer_connection_destroy_cb(gpointer data)
g_free(conn->clientip);
g_free(conn->verifiedip);
g_free(conn->xferdata.name);
- purple_circ_buffer_destroy(conn->buffer_outgoing);
+ g_object_unref(G_OBJECT(conn->buffer_outgoing));
conn->od->peer_connections = g_slist_remove(conn->od->peer_connections, conn);
@@ -408,9 +408,10 @@ send_cb(gpointer data, gint source, PurpleInputCondition cond)
PeerConnection *conn;
gsize writelen;
gssize wrotelen;
+ const gchar *output = NULL;
conn = data;
- writelen = purple_circ_buffer_get_max_read(conn->buffer_outgoing);
+ writelen = purple_circular_buffer_get_max_read(conn->buffer_outgoing);
if (writelen == 0)
{
@@ -433,12 +434,13 @@ send_cb(gpointer data, gint source, PurpleInputCondition cond)
* file transfer. Somebody should teach those guys how to
* write good TCP code.
*/
- conn->buffer_outgoing->inptr = conn->buffer_outgoing->buffer;
- conn->buffer_outgoing->outptr = conn->buffer_outgoing->buffer;
+ purple_circular_buffer_reset(conn->buffer_outgoing);
return;
}
- wrotelen = send(conn->fd, conn->buffer_outgoing->outptr, writelen, 0);
+ output = purple_circular_buffer_get_output(conn->buffer_outgoing);
+
+ wrotelen = send(conn->fd, output, writelen, 0);
if (wrotelen <= 0)
{
if (wrotelen < 0 && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))
@@ -465,7 +467,7 @@ send_cb(gpointer data, gint source, PurpleInputCondition cond)
return;
}
- purple_circ_buffer_mark_read(conn->buffer_outgoing, wrotelen);
+ purple_circular_buffer_mark_read(conn->buffer_outgoing, wrotelen);
conn->lastactivity = time(NULL);
}
@@ -478,7 +480,7 @@ void
peer_connection_send(PeerConnection *conn, ByteStream *bs)
{
/* Add everything to our outgoing buffer */
- purple_circ_buffer_append(conn->buffer_outgoing, bs->data, bs->len);
+ purple_circular_buffer_append(conn->buffer_outgoing, bs->data, bs->len);
/* If we haven't already started writing stuff, then start the cycle */
if ((conn->watcher_outgoing == 0) && (conn->fd >= 0))
@@ -686,7 +688,7 @@ peer_connection_establish_listener_cb(int listenerfd, gpointer data)
OscarData *od;
PurpleConnection *gc;
PurpleAccount *account;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
char *tmp;
FlapConnection *bos_conn;
const char *listener_ip;
@@ -750,10 +752,11 @@ peer_connection_establish_listener_cb(int listenerfd, gpointer data)
listener_port, ++conn->lastrequestnumber);
/* Print a message to a local conversation window */
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->bn);
+ im = purple_im_conversation_new(account, conn->bn);
tmp = g_strdup_printf(_("Asking %s to connect to us at %s:%hu for "
"Direct IM."), conn->bn, listener_ip, listener_port);
- purple_conversation_write(conv, NULL, tmp, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, tmp,
+ PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(tmp);
}
else if (conn->type == OSCAR_CAPABILITY_SENDFILE)
@@ -835,11 +838,11 @@ peer_connection_trynext(PeerConnection *conn)
if (conn->type == OSCAR_CAPABILITY_DIRECTIM)
{
gchar *tmp;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
tmp = g_strdup_printf(_("Attempting to connect to %s:%hu."),
conn->verifiedip, conn->port);
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->bn);
- purple_conversation_write(conv, NULL, tmp,
+ im = purple_im_conversation_new(account, conn->bn);
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, tmp,
PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(tmp);
}
@@ -909,10 +912,10 @@ peer_connection_trynext(PeerConnection *conn)
if (conn->type == OSCAR_CAPABILITY_DIRECTIM)
{
gchar *tmp;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
tmp = g_strdup(_("Attempting to connect via proxy server."));
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->bn);
- purple_conversation_write(conv, NULL, tmp,
+ im = purple_im_conversation_new(account, conn->bn);
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, tmp,
PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(tmp);
}
@@ -950,15 +953,14 @@ peer_connection_propose(OscarData *od, guint64 type, const char *bn)
if (conn->ready)
{
PurpleAccount *account;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
purple_debug_info("oscar", "Already have a direct IM "
"session with %s.\n", bn);
account = purple_connection_get_account(od->gc);
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- bn, account);
- if (conv != NULL)
- purple_conversation_present(conv);
+ im = purple_conversations_find_im_with_account(bn, account);
+ if (im != NULL)
+ purple_conversation_present(PURPLE_CONVERSATION(im));
return;
}
diff --git a/libpurple/protocols/oscar/peer.h b/libpurple/protocols/oscar/peer.h
index a706c3ff31..ccada7ab4b 100644
--- a/libpurple/protocols/oscar/peer.h
+++ b/libpurple/protocols/oscar/peer.h
@@ -184,7 +184,7 @@ struct _PeerConnection
guint8 proxy_header[12];
gssize proxy_header_received;
ByteStream buffer_incoming;
- PurpleCircBuffer *buffer_outgoing;
+ PurpleCircularBuffer *buffer_outgoing;
guint watcher_incoming;
guint watcher_outgoing;
@@ -251,7 +251,7 @@ void peer_connection_got_proposition(OscarData *od, const gchar *bn, const gchar
void peer_odc_close(PeerConnection *conn);
void peer_odc_recv_frame(PeerConnection *conn, ByteStream *bs);
void peer_odc_send_cookie(PeerConnection *conn);
-void peer_odc_send_typing(PeerConnection *conn, PurpleTypingState typing);
+void peer_odc_send_typing(PeerConnection *conn, PurpleIMTypingState typing);
void peer_odc_send_im(PeerConnection *conn, const char *msg, int len, int encoding, gboolean autoreply);
/*
diff --git a/libpurple/protocols/oscar/userinfo.c b/libpurple/protocols/oscar/userinfo.c
index 177263deaa..399797aca2 100644
--- a/libpurple/protocols/oscar/userinfo.c
+++ b/libpurple/protocols/oscar/userinfo.c
@@ -189,7 +189,7 @@ oscar_user_info_append_status(PurpleConnection *gc, PurpleNotifyUserInfo *user_i
return;
if (b == NULL)
- b = purple_find_buddy(purple_connection_get_account(gc), userinfo->bn);
+ b = purple_blist_find_buddy(purple_connection_get_account(gc), userinfo->bn);
else
userinfo = aim_locate_finduserinfo(od, purple_buddy_get_name(b));
@@ -322,7 +322,7 @@ oscar_user_info_append_extra_info(PurpleConnection *gc, PurpleNotifyUserInfo *us
userinfo = aim_locate_finduserinfo(od, purple_buddy_get_name(b));
if (b == NULL)
- b = purple_find_buddy(account, userinfo->bn);
+ b = purple_blist_find_buddy(account, userinfo->bn);
if (b != NULL) {
bname = purple_buddy_get_name(b);
@@ -369,7 +369,7 @@ oscar_user_info_display_error(OscarData *od, guint16 error_reason, gchar *buddy)
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);
+ purple_conversation_present_error(buddy, purple_connection_get_account(od->gc), buf);
g_free(buf);
}
@@ -389,7 +389,7 @@ oscar_user_info_display_icq(OscarData *od, struct aim_icq_info *info)
user_info = purple_notify_user_info_new();
g_snprintf(who, sizeof(who), "%u", info->uin);
- buddy = purple_find_buddy(account, who);
+ buddy = purple_blist_find_buddy(account, who);
if (buddy != NULL)
bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, purple_buddy_get_name(buddy)));
else
diff --git a/libpurple/protocols/oscar/visibility.c b/libpurple/protocols/oscar/visibility.c
index 3c091a9781..123f14a595 100644
--- a/libpurple/protocols/oscar/visibility.c
+++ b/libpurple/protocols/oscar/visibility.c
@@ -94,7 +94,7 @@ show_private_list(PurplePluginAction *action, guint16 list_type, const gchar *ti
GSList *buddies, *filtered_buddies, *cur;
gchar *text, *secondary;
- buddies = purple_find_buddies(account, NULL);
+ buddies = purple_blist_find_buddies(account, NULL);
filtered_buddies = NULL;
for (cur = buddies; cur != NULL; cur = cur->next) {
PurpleBuddy *buddy;
diff --git a/libpurple/protocols/sametime/sametime.c b/libpurple/protocols/sametime/sametime.c
index d395bf2d11..3f0bdc9a2c 100644
--- a/libpurple/protocols/sametime/sametime.c
+++ b/libpurple/protocols/sametime/sametime.c
@@ -33,7 +33,7 @@
/* purple includes */
#include "account.h"
#include "accountopt.h"
-#include "circbuffer.h"
+#include "circularbuffer.h"
#include "conversation.h"
#include "debug.h"
#include "ft.h"
@@ -41,7 +41,6 @@
#include "mime.h"
#include "notify.h"
#include "plugin.h"
-#include "privacy.h"
#include "prpl.h"
#include "request.h"
#include "util.h"
@@ -221,7 +220,7 @@ struct mwPurplePluginData {
gint outpa; /* like inpa, but the other way */
/** circular buffer for outgoing data */
- PurpleCircBuffer *sock_buf;
+ PurpleCircularBuffer *sock_buf;
PurpleConnection *gc;
};
@@ -296,7 +295,7 @@ static void convo_data_free(struct convo_data *conv);
static void convo_features(struct mwConversation *conv);
-static PurpleConversation *convo_get_gconv(struct mwConversation *conv);
+static PurpleIMConversation *convo_get_im(struct mwConversation *conv);
/* name and id */
@@ -343,7 +342,7 @@ static PurpleConnection *session_to_gc(struct mwSession *session) {
static void write_cb(gpointer data, gint source, PurpleInputCondition cond) {
struct mwPurplePluginData *pd = data;
- PurpleCircBuffer *circ = pd->sock_buf;
+ PurpleCircularBuffer *circ = pd->sock_buf;
gsize avail;
int ret;
@@ -351,17 +350,17 @@ static void write_cb(gpointer data, gint source, PurpleInputCondition cond) {
g_return_if_fail(circ != NULL);
- avail = purple_circ_buffer_get_max_read(circ);
+ avail = purple_circular_buffer_get_max_read(circ);
if(BUF_LONG < avail) avail = BUF_LONG;
while(avail) {
- ret = write(pd->socket, circ->outptr, avail);
+ ret = write(pd->socket, purple_circular_buffer_get_output(circ), avail);
if(ret <= 0)
break;
- purple_circ_buffer_mark_read(circ, ret);
- avail = purple_circ_buffer_get_max_read(circ);
+ purple_circular_buffer_mark_read(circ, ret);
+ avail = purple_circular_buffer_get_max_read(circ);
if(BUF_LONG < avail) avail = BUF_LONG;
}
@@ -386,7 +385,7 @@ static int mw_session_io_write(struct mwSession *session,
if(pd->outpa) {
DEBUG_INFO("already pending INPUT_WRITE, buffering\n");
- purple_circ_buffer_append(pd->sock_buf, buf, len);
+ purple_circular_buffer_append(pd->sock_buf, buf, len);
return 0;
}
@@ -406,7 +405,7 @@ static int mw_session_io_write(struct mwSession *session,
if(err == EAGAIN) {
/* append remainder to circular buffer */
DEBUG_INFO("EAGAIN\n");
- purple_circ_buffer_append(pd->sock_buf, buf, len);
+ purple_circular_buffer_append(pd->sock_buf, buf, len);
pd->outpa = purple_input_add(pd->socket, PURPLE_INPUT_WRITE, write_cb, pd);
} else if(len > 0) {
@@ -477,7 +476,7 @@ static void blist_resolve_alias_cb(struct mwServiceResolve *srvc,
match = result->matches->data;
g_return_if_fail(match != NULL);
- purple_blist_server_alias_buddy(data, match->name);
+ purple_buddy_set_server_alias(data, match->name);
purple_blist_node_set_string(data, BUDDY_KEY_NAME, match->name);
}
@@ -569,7 +568,7 @@ static void mw_aware_list_on_aware(struct mwAwareList *list,
PurpleBlistNode *bnode;
group = g_hash_table_lookup(pd->group_list_map, list);
- buddy = purple_find_buddy_in_group(acct, id, group);
+ buddy = purple_blist_find_buddy_in_group(acct, id, group);
bnode = (PurpleBlistNode *) buddy;
if(! buddy) {
@@ -677,7 +676,7 @@ static void blist_export(PurpleConnection *gc, struct mwSametimeList *stlist) {
enum mwSametimeGroupType gtype;
gboolean gopen;
- if(! PURPLE_BLIST_NODE_IS_GROUP(gn)) continue;
+ if(! PURPLE_IS_GROUP(gn)) continue;
grp = (PurpleGroup *) gn;
/* the group's type (normal or dynamic) */
@@ -713,13 +712,13 @@ static void blist_export(PurpleConnection *gc, struct mwSametimeList *stlist) {
for(cn = purple_blist_node_get_first_child(gn);
cn;
cn = purple_blist_node_get_sibling_next(cn)) {
- if(! PURPLE_BLIST_NODE_IS_CONTACT(cn)) continue;
+ if(! PURPLE_IS_CONTACT(cn)) continue;
for(bn = purple_blist_node_get_first_child(cn);
bn;
bn = purple_blist_node_get_sibling_next(bn)) {
- if(! PURPLE_BLIST_NODE_IS_BUDDY(bn)) continue;
- if(! PURPLE_BLIST_NODE_SHOULD_SAVE(bn)) continue;
+ if(! PURPLE_IS_BUDDY(bn)) continue;
+ if(purple_blist_node_is_transient(bn)) continue;
bdy = (PurpleBuddy *) bn;
@@ -734,7 +733,7 @@ static void blist_export(PurpleConnection *gc, struct mwSametimeList *stlist) {
stu = mwSametimeUser_new(stg, utype, &idb);
mwSametimeUser_setShortName(stu, purple_buddy_get_server_alias(bdy));
- mwSametimeUser_setAlias(stu, purple_buddy_get_local_buddy_alias(bdy));
+ mwSametimeUser_setAlias(stu, purple_buddy_get_local_alias(bdy));
}
}
}
@@ -861,7 +860,7 @@ static PurpleBuddy *buddy_ensure(PurpleConnection *gc, PurpleGroup *group,
g_return_val_if_fail(id != NULL, NULL);
g_return_val_if_fail(*id, NULL);
- buddy = purple_find_buddy_in_group(acct, id, group);
+ buddy = purple_blist_find_buddy_in_group(acct, id, group);
if(! buddy) {
buddy = purple_buddy_new(acct, id, alias);
@@ -869,8 +868,8 @@ static PurpleBuddy *buddy_ensure(PurpleConnection *gc, PurpleGroup *group,
buddy_add(pd, buddy);
}
- purple_blist_alias_buddy(buddy, alias);
- purple_blist_server_alias_buddy(buddy, name);
+ purple_buddy_set_local_alias(buddy, alias);
+ purple_buddy_set_server_alias(buddy, name);
purple_blist_node_set_string((PurpleBlistNode *) buddy, BUDDY_KEY_NAME, name);
purple_blist_node_set_int((PurpleBlistNode *) buddy, BUDDY_KEY_TYPE, type);
@@ -913,7 +912,7 @@ static PurpleGroup *group_ensure(PurpleConnection *gc,
acct = purple_connection_get_account(gc);
owner = purple_account_get_username(acct);
- blist = purple_get_blist();
+ blist = purple_blist_get_buddy_list();
g_return_val_if_fail(blist != NULL, NULL);
name = mwSametimeGroup_getName(stgroup);
@@ -937,7 +936,7 @@ static PurpleGroup *group_ensure(PurpleConnection *gc,
for(gn = purple_blist_get_root(); gn;
gn = purple_blist_node_get_sibling_next(gn)) {
const char *n, *o;
- if(! PURPLE_BLIST_NODE_IS_GROUP(gn)) continue;
+ if(! PURPLE_IS_GROUP(gn)) continue;
n = purple_blist_node_get_string(gn, GROUP_KEY_NAME);
o = purple_blist_node_get_string(gn, GROUP_KEY_OWNER);
@@ -955,7 +954,7 @@ static PurpleGroup *group_ensure(PurpleConnection *gc,
/* try again, by alias */
if(! group) {
DEBUG_INFO("searching for group by alias %s\n", NSTR(alias));
- group = purple_find_group(alias);
+ group = purple_blist_find_group(alias);
}
/* oh well, no such group. Let's create it! */
@@ -1024,14 +1023,14 @@ static void group_clear(PurpleGroup *group, PurpleAccount *acct, gboolean del) {
for(cn = purple_blist_node_get_first_child(gn);
cn;
cn = purple_blist_node_get_sibling_next(cn)) {
- if(! PURPLE_BLIST_NODE_IS_CONTACT(cn)) continue;
+ if(! PURPLE_IS_CONTACT(cn)) continue;
for(bn = purple_blist_node_get_first_child(cn);
bn;
bn = purple_blist_node_get_sibling_next(bn)) {
PurpleBuddy *gb = (PurpleBuddy *) bn;
- if(! PURPLE_BLIST_NODE_IS_BUDDY(bn)) continue;
+ if(! PURPLE_IS_BUDDY(bn)) continue;
if(purple_buddy_get_account(gb) == acct) {
DEBUG_INFO("clearing %s from group\n", NSTR(purple_buddy_get_name(gb)));
@@ -1051,7 +1050,7 @@ static void group_clear(PurpleGroup *group, PurpleAccount *acct, gboolean del) {
DEBUG_INFO("cleared buddies\n");
/* optionally remove group from blist */
- if(del && !purple_blist_get_group_size(group, TRUE)) {
+ if(del && !purple_counting_node_get_total_size(PURPLE_COUNTING_NODE(group))) {
DEBUG_INFO("removing empty group\n");
purple_blist_remove_group(group);
}
@@ -1093,14 +1092,14 @@ static void group_prune(PurpleConnection *gc, PurpleGroup *group,
for(cn = purple_blist_node_get_first_child(gn);
cn;
cn = purple_blist_node_get_sibling_next(cn)) {
- if(! PURPLE_BLIST_NODE_IS_CONTACT(cn)) continue;
+ if(! PURPLE_IS_CONTACT(cn)) continue;
for(bn = purple_blist_node_get_first_child(cn);
bn;
bn = purple_blist_node_get_sibling_next(bn)) {
PurpleBuddy *gb = (PurpleBuddy *) bn;
- if(! PURPLE_BLIST_NODE_IS_BUDDY(bn)) continue;
+ if(! PURPLE_IS_BUDDY(bn)) continue;
/* if the account is correct and they're not in our table, mark
them for pruning */
@@ -1146,7 +1145,7 @@ static void blist_sync(PurpleConnection *gc, struct mwSametimeList *stlist) {
acct_n = purple_account_get_username(acct);
- blist = purple_get_blist();
+ blist = purple_blist_get_buddy_list();
g_return_if_fail(blist != NULL);
/* build a hash table for quick lookup while pruning the local
@@ -1167,7 +1166,7 @@ static void blist_sync(PurpleConnection *gc, struct mwSametimeList *stlist) {
const char *gname, *owner;
struct mwSametimeGroup *stgrp;
- if(! PURPLE_BLIST_NODE_IS_GROUP(gn)) continue;
+ if(! PURPLE_IS_GROUP(gn)) continue;
/* group not belonging to this account */
if(! purple_group_on_account(grp, acct))
@@ -1280,7 +1279,7 @@ static void conversation_created_cb(PurpleConversation *g_conv,
if(pd->gc != gc)
return; /* not ours */
- if(purple_conversation_get_type(g_conv) != PURPLE_CONV_TYPE_IM)
+ if(PURPLE_IS_CHAT_CONVERSATION(g_conv))
return; /* wrong type */
who.user = (char *) purple_conversation_get_name(g_conv);
@@ -1308,7 +1307,7 @@ static void blist_menu_nab(PurpleBlistNode *node, gpointer data) {
gc = pd->gc;
g_return_if_fail(gc != NULL);
- g_return_if_fail(PURPLE_BLIST_NODE_IS_GROUP(node));
+ g_return_if_fail(PURPLE_IS_GROUP(node));
str = g_string_new(NULL);
@@ -1338,7 +1337,7 @@ static void blist_node_menu_cb(PurpleBlistNode *node,
PurpleMenuAction *act;
/* we only want groups */
- if(! PURPLE_BLIST_NODE_IS_GROUP(node)) return;
+ if(! PURPLE_IS_GROUP(node)) return;
acct = purple_connection_get_account(pd->gc);
g_return_if_fail(acct != NULL);
@@ -1376,18 +1375,18 @@ static void blist_init(PurpleAccount *acct) {
for(gnode = purple_blist_get_root(); gnode;
gnode = purple_blist_node_get_sibling_next(gnode)) {
- if(! PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue;
+ if(! PURPLE_IS_GROUP(gnode)) continue;
for(cnode = purple_blist_node_get_first_child(gnode);
cnode;
cnode = purple_blist_node_get_sibling_next(cnode)) {
- if(! PURPLE_BLIST_NODE_IS_CONTACT(cnode))
+ if(! PURPLE_IS_CONTACT(cnode))
continue;
for(bnode = purple_blist_node_get_first_child(cnode);
bnode;
bnode = purple_blist_node_get_sibling_next(bnode)) {
PurpleBuddy *b;
- if(!PURPLE_BLIST_NODE_IS_BUDDY(bnode))
+ if(!PURPLE_IS_BUDDY(bnode))
continue;
b = (PurpleBuddy *)bnode;
@@ -1427,7 +1426,7 @@ static void services_starting(struct mwPurplePluginData *pd) {
enum mwSametimeGroupType gt;
const char *owner;
- if(! PURPLE_BLIST_NODE_IS_GROUP(l)) continue;
+ if(! PURPLE_IS_GROUP(l)) continue;
/* if the group is ownerless, or has an owner and we're not it,
skip it */
@@ -1574,7 +1573,7 @@ static void mw_session_stateChange(struct mwSession *session,
msg = _("Connected");
purple_connection_update_progress(gc, msg, 10, MW_CONNECT_STEPS);
- purple_connection_set_state(gc, PURPLE_CONNECTED);
+ purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED);
break;
case mwSession_STOPPING:
@@ -1634,7 +1633,7 @@ static void mw_session_setPrivacyInfo(struct mwSession *session) {
PurpleConnection *gc;
PurpleAccount *acct;
struct mwPrivacyInfo *privacy;
- GSList *l, **ll;
+ GSList *list;
guint count;
DEBUG_INFO("privacy information set from server\n");
@@ -1653,16 +1652,25 @@ static void mw_session_setPrivacyInfo(struct mwSession *session) {
privacy = mwSession_getPrivacyInfo(session);
count = privacy->count;
- ll = (privacy->deny)? &acct->deny: &acct->permit;
- for(l = *ll; l; l = l->next) g_free(l->data);
- g_slist_free(*ll);
- l = *ll = NULL;
-
- while(count--) {
- struct mwUserItem *u = privacy->users + count;
- l = g_slist_prepend(l, g_strdup(u->id));
+ if (privacy->deny) {
+ while ((list = purple_account_privacy_get_denied(acct))) {
+ g_free(list->data);
+ purple_account_privacy_deny_remove(acct, list->data, TRUE);
+ }
+ while (count--) {
+ struct mwUserItem *u = privacy->users + count;
+ purple_account_privacy_deny_add(acct, u->id, TRUE);
+ }
+ } else {
+ while ((list = purple_account_privacy_get_permitted(acct))) {
+ g_free(list->data);
+ purple_account_privacy_permit_remove(acct, list->data, TRUE);
+ }
+ while (count--) {
+ struct mwUserItem *u = privacy->users + count;
+ purple_account_privacy_permit_add(acct, u->id, TRUE);
+ }
}
- *ll = l;
}
@@ -1827,23 +1835,24 @@ static void mw_session_announce(struct mwSession *s,
const char *text) {
struct mwPurplePluginData *pd;
PurpleAccount *acct;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
PurpleBuddy *buddy;
char *who = from->user_id;
char *msg;
pd = mwSession_getClientData(s);
acct = purple_connection_get_account(pd->gc);
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acct);
- if(! conv) conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, who);
+ im = purple_conversations_find_im_with_account(who, acct);
+ if(! im) im = purple_im_conversation_new(acct, who);
- buddy = purple_find_buddy(acct, who);
+ buddy = purple_blist_find_buddy(acct, who);
if(buddy) who = (char *) purple_buddy_get_contact_alias(buddy);
who = g_strdup_printf(_("Announcement from %s"), who);
msg = purple_markup_linkify(text);
- purple_conversation_write(conv, who, msg ? msg : "", PURPLE_MESSAGE_RECV, time(NULL));
+ purple_conversation_write(PURPLE_CONVERSATION(im), who, msg ? msg : "",
+ PURPLE_MESSAGE_RECV, time(NULL));
g_free(who);
g_free(msg);
}
@@ -1929,14 +1938,14 @@ static void mw_conf_invited(struct mwConference *conf,
}
-/* The following mess helps us relate a mwConference to a PurpleConvChat
+/* The following mess helps us relate a mwConference to a PurpleChatConversation
in the various forms by which either may be indicated */
#define CONF_TO_ID(conf) (GPOINTER_TO_INT(conf))
#define ID_TO_CONF(pd, id) (conf_find_by_id((pd), (id)))
-#define CHAT_TO_ID(chat) (purple_conv_chat_get_id(chat))
-#define ID_TO_CHAT(id) (purple_find_chat(id))
+#define CHAT_TO_ID(chat) (purple_chat_conversation_get_id(chat))
+#define ID_TO_CHAT(id) (purple_conversations_find_chat(id))
#define CHAT_TO_CONF(pd, chat) (ID_TO_CONF((pd), CHAT_TO_ID(chat)))
#define CONF_TO_CHAT(conf) (ID_TO_CHAT(CONF_TO_ID(conf)))
@@ -1952,7 +1961,7 @@ conf_find_by_id(struct mwPurplePluginData *pd, int id) {
ll = mwServiceConference_getConferences(srvc);
for(l = ll; l; l = l->next) {
struct mwConference *c = l->data;
- PurpleConvChat *h = mwConference_getClientData(c);
+ PurpleChatConversation *h = mwConference_getClientData(c);
if(CHAT_TO_ID(h) == id) {
conf = c;
@@ -1970,7 +1979,7 @@ static void mw_conf_opened(struct mwConference *conf, GList *members) {
struct mwSession *session;
struct mwPurplePluginData *pd;
PurpleConnection *gc;
- PurpleConversation *g_conf;
+ PurpleChatConversation *g_conf;
const char *n = mwConference_getName(conf);
const char *t = mwConference_getTitle(conf);
@@ -1986,12 +1995,12 @@ static void mw_conf_opened(struct mwConference *conf, GList *members) {
if(! t) t = "(no title)";
g_conf = serv_got_joined_chat(gc, CONF_TO_ID(conf), t);
- mwConference_setClientData(conf, PURPLE_CONV_CHAT(g_conf), NULL);
+ mwConference_setClientData(conf, g_conf, NULL);
for(; members; members = members->next) {
struct mwLoginInfo *peer = members->data;
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(g_conf), peer->user_id,
- NULL, PURPLE_CBFLAGS_NONE, FALSE);
+ purple_chat_conversation_add_user(g_conf, peer->user_id,
+ NULL, PURPLE_CHAT_USER_NONE, FALSE);
}
}
@@ -2022,7 +2031,7 @@ static void mw_conf_closed(struct mwConference *conf, guint32 reason) {
static void mw_conf_peer_joined(struct mwConference *conf,
struct mwLoginInfo *peer) {
- PurpleConvChat *g_conf;
+ PurpleChatConversation *g_conf;
const char *n = mwConference_getName(conf);
@@ -2031,15 +2040,15 @@ static void mw_conf_peer_joined(struct mwConference *conf,
g_conf = mwConference_getClientData(conf);
g_return_if_fail(g_conf != NULL);
- purple_conv_chat_add_user(g_conf, peer->user_id,
- NULL, PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(g_conf, peer->user_id,
+ NULL, PURPLE_CHAT_USER_NONE, TRUE);
}
static void mw_conf_peer_parted(struct mwConference *conf,
struct mwLoginInfo *peer) {
- PurpleConvChat *g_conf;
+ PurpleChatConversation *g_conf;
const char *n = mwConference_getName(conf);
@@ -2048,7 +2057,7 @@ static void mw_conf_peer_parted(struct mwConference *conf,
g_conf = mwConference_getClientData(conf);
g_return_if_fail(g_conf != NULL);
- purple_conv_chat_remove_user(g_conf, peer->user_id, NULL);
+ purple_chat_conversation_remove_user(g_conf, peer->user_id, NULL);
}
@@ -2400,7 +2409,7 @@ static void convo_data_new(struct mwConversation *conv) {
}
-static PurpleConversation *convo_get_gconv(struct mwConversation *conv) {
+static PurpleIMConversation *convo_get_im(struct mwConversation *conv) {
struct mwServiceIm *srvc;
struct mwSession *session;
struct mwPurplePluginData *pd;
@@ -2417,8 +2426,7 @@ static PurpleConversation *convo_get_gconv(struct mwConversation *conv) {
idb = mwConversation_getTarget(conv);
- return purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- idb->user, acct);
+ return purple_conversations_find_im_with_account(idb->user, acct);
}
@@ -2452,7 +2460,7 @@ static void convo_queue(struct mwConversation *conv,
/* Does what it takes to get an error displayed for a conversation */
static void convo_error(struct mwConversation *conv, guint32 err) {
- PurpleConversation *gconv;
+ PurpleIMConversation *im;
char *tmp, *text;
struct mwIdBlock *idb;
@@ -2461,13 +2469,15 @@ static void convo_error(struct mwConversation *conv, guint32 err) {
tmp = mwError(err);
text = g_strconcat(_("Unable to send message: "), tmp, NULL);
- gconv = convo_get_gconv(conv);
- if(gconv && !purple_conv_present_error(idb->user, purple_conversation_get_account(gconv), text)) {
+ im = convo_get_im(conv);
+ if(im && !purple_conversation_present_error(idb->user,
+ purple_conversation_get_account(PURPLE_CONVERSATION(im)), 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(purple_conversation_get_account(gconv)),
+ purple_notify_error(purple_account_get_connection(
+ purple_conversation_get_account(PURPLE_CONVERSATION(im))),
NULL, text, tmp);
}
@@ -2499,16 +2509,17 @@ static void convo_queue_send(struct mwConversation *conv) {
inform the purple conversation that it's unsafe to offer any *cool*
features. */
static void convo_nofeatures(struct mwConversation *conv) {
- PurpleConversation *gconv;
+ PurpleIMConversation *im;
PurpleConnection *gc;
- gconv = convo_get_gconv(conv);
- if(! gconv) return;
+ im = convo_get_im(conv);
+ if(! im) return;
- gc = purple_conversation_get_connection(gconv);
+ gc = purple_conversation_get_connection(PURPLE_CONVERSATION(im));
if(! gc) return;
- purple_conversation_set_features(gconv, purple_connection_get_flags(gc));
+ purple_conversation_set_features(PURPLE_CONVERSATION(im),
+ purple_connection_get_flags(gc));
}
@@ -2516,29 +2527,29 @@ static void convo_nofeatures(struct mwConversation *conv) {
to inform the purple conversation of what features to offer the
user */
static void convo_features(struct mwConversation *conv) {
- PurpleConversation *gconv;
+ PurpleIMConversation *im;
PurpleConnectionFlags feat;
- gconv = convo_get_gconv(conv);
- if(! gconv) return;
+ im = convo_get_im(conv);
+ if(! im) return;
- feat = purple_conversation_get_features(gconv);
+ feat = purple_conversation_get_features(PURPLE_CONVERSATION(im));
if(mwConversation_isOpen(conv)) {
if(mwConversation_supports(conv, mwImSend_HTML)) {
- feat |= PURPLE_CONNECTION_HTML;
+ feat |= PURPLE_CONNECTION_FLAG_HTML;
} else {
- feat &= ~PURPLE_CONNECTION_HTML;
+ feat &= ~PURPLE_CONNECTION_FLAG_HTML;
}
if(mwConversation_supports(conv, mwImSend_MIME)) {
- feat &= ~PURPLE_CONNECTION_NO_IMAGES;
+ feat &= ~PURPLE_CONNECTION_FLAG_NO_IMAGES;
} else {
- feat |= PURPLE_CONNECTION_NO_IMAGES;
+ feat |= PURPLE_CONNECTION_FLAG_NO_IMAGES;
}
DEBUG_INFO("conversation features set to 0x%04x\n", feat);
- purple_conversation_set_features(gconv, feat);
+ purple_conversation_set_features(PURPLE_CONVERSATION(im), feat);
} else {
convo_nofeatures(conv);
@@ -2566,7 +2577,7 @@ static void mw_conversation_opened(struct mwConversation *conv) {
if(cd) {
convo_queue_send(conv);
- if(! convo_get_gconv(conv)) {
+ if(! convo_get_im(conv)) {
mwConversation_free(conv);
return;
}
@@ -2580,7 +2591,7 @@ static void mw_conversation_opened(struct mwConversation *conv) {
struct mwLoginInfo *info;
info = mwConversation_getTargetInfo(conv);
- buddy = purple_find_buddy(acct, info->user_id);
+ buddy = purple_blist_find_buddy(acct, info->user_id);
if(buddy) {
purple_blist_node_set_int((PurpleBlistNode *) buddy,
BUDDY_KEY_CLIENT, info->type);
@@ -2652,7 +2663,7 @@ static void im_recv_typing(struct mwConversation *conv,
idb = mwConversation_getTarget(conv);
serv_got_typing(pd->gc, idb->user, 0,
- typing? PURPLE_TYPING: PURPLE_NOT_TYPING);
+ typing? PURPLE_IM_TYPING: PURPLE_IM_NOT_TYPING);
}
@@ -2937,7 +2948,7 @@ static struct mwServiceIm *mw_srvc_im_new(struct mwSession *s) {
}
-/* The following helps us relate a mwPlace to a PurpleConvChat in the
+/* The following helps us relate a mwPlace to a PurpleChatConversation in the
various forms by which either may be indicated. Uses some of
the similar macros from the conference service above */
@@ -2957,7 +2968,7 @@ place_find_by_id(struct mwPurplePluginData *pd, int id) {
l = (GList *) mwServicePlace_getPlaces(srvc);
for(; l; l = l->next) {
struct mwPlace *p = l->data;
- PurpleConvChat *h = PURPLE_CONV_CHAT(mwPlace_getClientData(p));
+ PurpleChatConversation *h = mwPlace_getClientData(p);
if(CHAT_TO_ID(h) == id) {
place = p;
@@ -2974,7 +2985,7 @@ static void mw_place_opened(struct mwPlace *place) {
struct mwSession *session;
struct mwPurplePluginData *pd;
PurpleConnection *gc;
- PurpleConversation *gconf;
+ PurpleChatConversation *gconf;
GList *members, *l;
@@ -2998,8 +3009,8 @@ static void mw_place_opened(struct mwPlace *place) {
for(l = members; l; l = l->next) {
struct mwIdBlock *idb = l->data;
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(gconf), idb->user,
- NULL, PURPLE_CBFLAGS_NONE, FALSE);
+ purple_chat_conversation_add_user(gconf, idb->user,
+ NULL, PURPLE_CHAT_USER_NONE, FALSE);
}
g_list_free(members);
}
@@ -3030,7 +3041,7 @@ static void mw_place_closed(struct mwPlace *place, guint32 code) {
static void mw_place_peerJoined(struct mwPlace *place,
const struct mwIdBlock *peer) {
- PurpleConversation *gconf;
+ PurpleChatConversation *gconf;
const char *n = mwPlace_getName(place);
@@ -3039,14 +3050,14 @@ static void mw_place_peerJoined(struct mwPlace *place,
gconf = mwPlace_getClientData(place);
g_return_if_fail(gconf != NULL);
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(gconf), peer->user,
- NULL, PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(gconf, peer->user,
+ NULL, PURPLE_CHAT_USER_NONE, TRUE);
}
static void mw_place_peerParted(struct mwPlace *place,
const struct mwIdBlock *peer) {
- PurpleConversation *gconf;
+ PurpleChatConversation *gconf;
const char *n = mwPlace_getName(place);
@@ -3055,7 +3066,7 @@ static void mw_place_peerParted(struct mwPlace *place,
gconf = mwPlace_getClientData(place);
g_return_if_fail(gconf != NULL);
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(gconf), peer->user, NULL);
+ purple_chat_conversation_remove_user(gconf, peer->user, NULL);
}
@@ -3150,7 +3161,7 @@ static struct mwPurplePluginData *mwPurplePluginData_new(PurpleConnection *gc) {
pd->srvc_resolve = mw_srvc_resolve_new(pd->session);
pd->srvc_store = mw_srvc_store_new(pd->session);
pd->group_list_map = g_hash_table_new(g_direct_hash, g_direct_equal);
- pd->sock_buf = purple_circ_buffer_new(0);
+ pd->sock_buf = purple_circular_buffer_new(0);
mwSession_addService(pd->session, MW_SERVICE(pd->srvc_aware));
mwSession_addService(pd->session, MW_SERVICE(pd->srvc_conf));
@@ -3197,7 +3208,7 @@ static void mwPurplePluginData_free(struct mwPurplePluginData *pd) {
mwSession_free(pd->session);
g_hash_table_destroy(pd->group_list_map);
- purple_circ_buffer_destroy(pd->sock_buf);
+ g_object_unref(G_OBJECT(pd->sock_buf));
g_free(pd);
}
@@ -3330,19 +3341,19 @@ static GList *mw_prpl_status_types(PurpleAccount *acct)
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
MW_STATE_ACTIVE, NULL, TRUE, TRUE, FALSE,
- MW_STATE_MESSAGE, _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ MW_STATE_MESSAGE, _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_append(types, type);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY,
MW_STATE_AWAY, NULL, TRUE, TRUE, FALSE,
- MW_STATE_MESSAGE, _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ MW_STATE_MESSAGE, _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_append(types, type);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE,
MW_STATE_BUSY, _("Do Not Disturb"), TRUE, TRUE, FALSE,
- MW_STATE_MESSAGE, _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ MW_STATE_MESSAGE, _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_append(types, type);
@@ -3533,7 +3544,7 @@ static void blist_menu_conf(PurpleBlistNode *node, gpointer data) {
GList *l;
g_return_if_fail(node != NULL);
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
acct = purple_buddy_get_account(buddy);
g_return_if_fail(acct != NULL);
@@ -3572,7 +3583,7 @@ static void blist_menu_announce(PurpleBlistNode *node, gpointer data) {
GList *rcpt;
g_return_if_fail(node != NULL);
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
acct = buddy->account;
g_return_if_fail(acct != NULL);
@@ -3601,7 +3612,7 @@ static GList *mw_prpl_blist_node_menu(PurpleBlistNode *node) {
GList *l = NULL;
PurpleMenuAction *act;
- if(! PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if(! PURPLE_IS_BUDDY(node))
return l;
l = g_list_append(l, NULL);
@@ -3668,7 +3679,7 @@ static void mw_prpl_login(PurpleAccount *account) {
pd = mwPurplePluginData_new(gc);
/* while we do support images, the default is to not offer it */
- purple_connection_set_flags(gc, PURPLE_CONNECTION_NO_IMAGES);
+ purple_connection_set_flags(gc, PURPLE_CONNECTION_FLAG_NO_IMAGES);
user = g_strdup(purple_account_get_username(account));
@@ -4015,7 +4026,7 @@ static int mw_prpl_send_im(PurpleConnection *gc,
static unsigned int mw_prpl_send_typing(PurpleConnection *gc,
const char *name,
- PurpleTypingState state) {
+ PurpleIMTypingState state) {
struct mwPurplePluginData *pd;
struct mwIdBlock who = { (char *) name, NULL };
@@ -4033,7 +4044,7 @@ static unsigned int mw_prpl_send_typing(PurpleConnection *gc,
if(mwConversation_isOpen(conv)) {
mwConversation_send(conv, mwImSend_TYPING, t);
- } else if((state == PURPLE_TYPING) || (state == PURPLE_TYPED)) {
+ } else if((state == PURPLE_IM_TYPING) || (state == PURPLE_IM_TYPED)) {
/* only open a channel for sending typing notification, not for
when typing has stopped. There's no point in re-opening a
channel just to tell someone that this side isn't typing. */
@@ -4123,7 +4134,7 @@ static void mw_prpl_get_info(PurpleConnection *gc, const char *who) {
pd = purple_connection_get_protocol_data(gc);
acct = purple_connection_get_account(gc);
- b = purple_find_buddy(acct, who);
+ b = purple_blist_find_buddy(acct, who);
user_info = purple_notify_user_info_new();
if(purple_str_has_prefix(who, "@E ")) {
@@ -4266,14 +4277,14 @@ static void mw_prpl_set_idle(PurpleConnection *gc, int t) {
static void notify_im(PurpleConnection *gc, GList *row, void *user_data) {
PurpleAccount *acct;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
char *id;
acct = purple_connection_get_account(gc);
id = g_list_nth_data(row, 1);
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, id, acct);
- if(! conv) conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, id);
- purple_conversation_present(conv);
+ im = purple_conversations_find_im_with_account(id, acct);
+ if(! im) im = purple_im_conversation_new(acct, id);
+ purple_conversation_present(PURPLE_CONVERSATION(im));
}
@@ -4385,7 +4396,7 @@ static void add_buddy_resolved(struct mwServiceResolve *srvc,
} else {
/* same person, set the server alias */
- purple_blist_server_alias_buddy(buddy, match->name);
+ purple_buddy_set_server_alias(buddy, match->name);
purple_blist_node_set_string((PurpleBlistNode *) buddy,
BUDDY_KEY_NAME, match->name);
@@ -4516,7 +4527,7 @@ static void mw_prpl_add_buddies(PurpleConnection *gc,
/* nab the saved server alias and stick it on the buddy */
fn = purple_blist_node_get_string((PurpleBlistNode *) b, BUDDY_KEY_NAME);
- purple_blist_server_alias_buddy(b, fn);
+ purple_buddy_set_server_alias(b, fn);
/* convert PurpleBuddy into a mwAwareIdBlock */
idb->type = mwAware_USER;
@@ -4604,25 +4615,25 @@ static void mw_prpl_set_permit_deny(PurpleConnection *gc) {
g_return_if_fail(session != NULL);
switch(purple_account_get_privacy_type(acct)) {
- case PURPLE_PRIVACY_DENY_USERS:
- DEBUG_INFO("PURPLE_PRIVACY_DENY_USERS\n");
- privacy_fill(&privacy, acct->deny);
+ case PURPLE_ACCOUNT_PRIVACY_DENY_USERS:
+ DEBUG_INFO("PURPLE_ACCOUNT_PRIVACY_DENY_USERS\n");
+ privacy_fill(&privacy, purple_account_privacy_get_denied(acct));
privacy.deny = TRUE;
break;
- case PURPLE_PRIVACY_ALLOW_ALL:
- DEBUG_INFO("PURPLE_PRIVACY_ALLOW_ALL\n");
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL:
+ DEBUG_INFO("PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL\n");
privacy.deny = TRUE;
break;
- case PURPLE_PRIVACY_ALLOW_USERS:
- DEBUG_INFO("PURPLE_PRIVACY_ALLOW_USERS\n");
- privacy_fill(&privacy, acct->permit);
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS:
+ DEBUG_INFO("PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS\n");
+ privacy_fill(&privacy, purple_account_privacy_get_permitted(acct));
privacy.deny = FALSE;
break;
- case PURPLE_PRIVACY_DENY_ALL:
- DEBUG_INFO("PURPLE_PRIVACY_DENY_ALL\n");
+ case PURPLE_ACCOUNT_PRIVACY_DENY_ALL:
+ DEBUG_INFO("PURPLE_ACCOUNT_PRIVACY_DENY_ALL\n");
privacy.deny = FALSE;
break;
@@ -4876,12 +4887,12 @@ static void mw_prpl_group_buddy(PurpleConnection *gc,
struct mwAwareList *list;
/* add who to new_group's aware list */
- group = purple_find_group(new_group);
+ group = purple_blist_find_group(new_group);
list = list_ensure(pd, group);
mwAwareList_addAware(list, gl);
/* remove who from old_group's aware list */
- group = purple_find_group(old_group);
+ group = purple_blist_find_group(old_group);
list = list_ensure(pd, group);
mwAwareList_removeAware(list, gl);
@@ -4985,7 +4996,7 @@ static gboolean mw_prpl_can_receive_file(PurpleConnection *gc,
acct = purple_connection_get_account(gc);
g_return_val_if_fail(acct != NULL, FALSE);
- return purple_find_buddy(acct, who) &&
+ return purple_blist_find_buddy(acct, who) &&
user_supports(srvc, who, mwAttribute_FILE_TRANSFER);
}
@@ -5317,7 +5328,7 @@ static void remote_group_done(struct mwPurplePluginData *pd,
acct = purple_connection_get_account(gc);
/* collision checking */
- group = purple_find_group(name);
+ group = purple_blist_find_group(name);
if(group) {
const char *msgA;
const char *msgB;
diff --git a/libpurple/protocols/silc/buddy.c b/libpurple/protocols/silc/buddy.c
index ad9dc050c2..ac169e9ea5 100644
--- a/libpurple/protocols/silc/buddy.c
+++ b/libpurple/protocols/silc/buddy.c
@@ -91,15 +91,15 @@ silcpurple_buddy_keyagr_cb(SilcClient client,
/* Open IM window */
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
+ convo = purple_conversations_find_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));
+ purple_conversation_window_show(purple_conversation_get_window(convo));
*/
} else {
- convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, sg->account,
+ convo = purple_im_conversation_new(sg->account,
client_entry->nickname);
}
g_snprintf(tmp, sizeof(tmp), "%s [private key]", client_entry->nickname);
@@ -342,7 +342,7 @@ silcpurple_buddy_resetkey(PurpleBlistNode *node, gpointer data)
SilcPurple sg;
SilcDList clients;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
b = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(b));
@@ -468,7 +468,7 @@ silcpurple_buddy_privkey_menu(PurpleBlistNode *node, gpointer data)
PurpleBuddy *buddy;
PurpleConnection *gc;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
@@ -597,7 +597,7 @@ silcpurple_buddy_getkey_menu(PurpleBlistNode *node, gpointer data)
PurpleBuddy *buddy;
PurpleConnection *gc;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
@@ -614,7 +614,7 @@ silcpurple_buddy_showkey(PurpleBlistNode *node, gpointer data)
SilcPublicKey public_key;
const char *pkfile;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
b = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(b));
@@ -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(purple_connection_get_account(gc), nick);
+ b = purple_blist_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. */
@@ -1413,7 +1413,7 @@ void silcpurple_send_buddylist(PurpleConnection *gc)
account = purple_connection_get_account(gc);
- for (buddies = purple_find_buddies(account, NULL); buddies;
+ for (buddies = purple_blist_find_buddies(account, NULL); buddies;
buddies = g_slist_delete_link(buddies, buddies))
{
PurpleBuddy *buddy = buddies->data;
@@ -1621,7 +1621,7 @@ silcpurple_buddy_kill(PurpleBlistNode *node, gpointer data)
PurpleConnection *gc;
SilcPurple sg;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
b = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(b));
diff --git a/libpurple/protocols/silc/chat.c b/libpurple/protocols/silc/chat.c
index 764f0fcf7f..9eff2c5dad 100644
--- a/libpurple/protocols/silc/chat.c
+++ b/libpurple/protocols/silc/chat.c
@@ -496,7 +496,7 @@ silcpurple_chat_chauth(PurpleBlistNode *node, gpointer data)
PurpleConnection *gc;
SilcPurple sg;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
+ g_return_if_fail(PURPLE_IS_CHAT(node));
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
@@ -583,7 +583,7 @@ silcpurple_chat_prv(PurpleBlistNode *node, gpointer data)
PurpleRequestField *f;
char tmp[512];
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
+ g_return_if_fail(PURPLE_IS_CHAT(node));
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
@@ -633,7 +633,7 @@ silcpurple_chat_permanent_reset(PurpleBlistNode *node, gpointer data)
PurpleConnection *gc;
SilcPurple sg;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
+ g_return_if_fail(PURPLE_IS_CHAT(node));
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
@@ -652,7 +652,7 @@ silcpurple_chat_permanent(PurpleBlistNode *node, gpointer data)
SilcPurple sg;
const char *channel;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
+ g_return_if_fail(PURPLE_IS_CHAT(node));
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
@@ -729,7 +729,7 @@ silcpurple_chat_ulimit(PurpleBlistNode *node, gpointer data)
char *ch;
char tmp[32];
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
+ g_return_if_fail(PURPLE_IS_CHAT(node));
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
@@ -764,7 +764,7 @@ silcpurple_chat_resettopic(PurpleBlistNode *node, gpointer data)
PurpleConnection *gc;
SilcPurple sg;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
+ g_return_if_fail(PURPLE_IS_CHAT(node));
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
@@ -782,7 +782,7 @@ silcpurple_chat_settopic(PurpleBlistNode *node, gpointer data)
PurpleConnection *gc;
SilcPurple sg;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
+ g_return_if_fail(PURPLE_IS_CHAT(node));
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
@@ -800,7 +800,7 @@ silcpurple_chat_resetprivate(PurpleBlistNode *node, gpointer data)
PurpleConnection *gc;
SilcPurple sg;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
+ g_return_if_fail(PURPLE_IS_CHAT(node));
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
@@ -818,7 +818,7 @@ silcpurple_chat_setprivate(PurpleBlistNode *node, gpointer data)
PurpleConnection *gc;
SilcPurple sg;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
+ g_return_if_fail(PURPLE_IS_CHAT(node));
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
@@ -836,7 +836,7 @@ silcpurple_chat_resetsecret(PurpleBlistNode *node, gpointer data)
PurpleConnection *gc;
SilcPurple sg;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
+ g_return_if_fail(PURPLE_IS_CHAT(node));
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
@@ -854,7 +854,7 @@ silcpurple_chat_setsecret(PurpleBlistNode *node, gpointer data)
PurpleConnection *gc;
SilcPurple sg;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
+ g_return_if_fail(PURPLE_IS_CHAT(node));
chat = (PurpleChat *) node;
gc = purple_account_get_connection(purple_chat_get_account(chat));
diff --git a/libpurple/protocols/silc/ops.c b/libpurple/protocols/silc/ops.c
index c1b7337733..cfebb3c0b3 100644
--- a/libpurple/protocols/silc/ops.c
+++ b/libpurple/protocols/silc/ops.c
@@ -195,13 +195,13 @@ silcpurple_mime_message(SilcClient client, SilcClientConnection conn,
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,
+ convo = purple_conversations_find_with_account(PURPLE_CONV_TYPE_CHAT,
prv->channel, sg->account);
break;
}
}
if (channel && !convo)
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
+ convo = purple_conversations_find_with_account(PURPLE_CONV_TYPE_CHAT,
channel->channel_name, sg->account);
if (channel && !convo)
goto out;
@@ -214,7 +214,7 @@ silcpurple_mime_message(SilcClient client, SilcClientConnection conn,
imgid);
if (channel)
- serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)),
+ serv_got_chat_in(gc, purple_chat_conversation_get_id(PURPLE_CONV_CHAT(convo)),
sender->nickname, cflags,
tmp, time(NULL));
else
@@ -275,13 +275,13 @@ silc_channel_message(SilcClient client, SilcClientConnection conn,
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,
+ convo = purple_conversations_find_with_account(PURPLE_CONV_TYPE_CHAT,
prv->channel, sg->account);
break;
}
}
if (!convo)
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
+ convo = purple_conversations_find_with_account(PURPLE_CONV_TYPE_CHAT,
channel->channel_name, sg->account);
if (!convo)
return;
@@ -308,7 +308,7 @@ silc_channel_message(SilcClient client, SilcClientConnection conn,
tmp = g_markup_escape_text(msg, -1);
/* Send to Purple */
- serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)),
+ serv_got_chat_in(gc, purple_chat_conversation_get_id(PURPLE_CONV_CHAT(convo)),
sender->nickname, 0, tmp, time(NULL));
g_free(tmp);
g_free(msg);
@@ -337,7 +337,7 @@ silc_channel_message(SilcClient client, SilcClientConnection conn,
}
tmp = g_markup_escape_text(msg, -1);
/* Send to Purple */
- serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)),
+ serv_got_chat_in(gc, purple_chat_conversation_get_id(PURPLE_CONV_CHAT(convo)),
sender->nickname, 0, tmp, time(NULL));
g_free(salvaged);
g_free(tmp);
@@ -366,7 +366,7 @@ silc_private_message(SilcClient client, SilcClientConnection conn,
return;
/* XXX - Should this be PURPLE_CONV_TYPE_IM? */
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY,
+ convo = purple_conversations_find_with_account(PURPLE_CONV_TYPE_ANY,
sender->nickname, sg->account);
if (flags & SILC_MESSAGE_FLAG_SIGNED &&
@@ -486,7 +486,7 @@ silc_notify(SilcClient client, SilcClientConnection conn,
if (client_entry == conn->local_entry)
break;
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
+ convo = purple_conversations_find_with_account(PURPLE_CONV_TYPE_CHAT,
channel->channel_name, sg->account);
if (!convo)
break;
@@ -494,8 +494,8 @@ silc_notify(SilcClient client, SilcClientConnection conn,
/* 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),
- client_entry->nickname, buf, PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(PURPLE_CONV_CHAT(convo),
+ client_entry->nickname, buf, PURPLE_CHAT_USER_NONE, TRUE);
break;
@@ -503,13 +503,13 @@ silc_notify(SilcClient client, SilcClientConnection conn,
client_entry = va_arg(va, SilcClientEntry);
channel = va_arg(va, SilcChannelEntry);
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
+ convo = purple_conversations_find_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),
+ purple_chat_conversation_remove_user(PURPLE_CONV_CHAT(convo),
client_entry->nickname, NULL);
break;
@@ -521,11 +521,11 @@ silc_notify(SilcClient client, SilcClientConnection conn,
/* 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,
+ convo = purple_conversations_find_with_account(PURPLE_CONV_TYPE_CHAT,
chu->channel->channel_name, sg->account);
if (!convo)
continue;
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo),
+ purple_chat_conversation_remove_user(PURPLE_CONV_CHAT(convo),
client_entry->nickname,
tmp);
}
@@ -541,7 +541,7 @@ silc_notify(SilcClient client, SilcClientConnection conn,
tmp = va_arg(va, char *);
channel = va_arg(va, SilcChannelEntry);
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
+ convo = purple_conversations_find_with_account(PURPLE_CONV_TYPE_CHAT,
channel->channel_name, sg->account);
if (!convo)
break;
@@ -558,30 +558,30 @@ silc_notify(SilcClient client, SilcClientConnection conn,
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,
+ purple_chat_conversation_write_message(PURPLE_CONV_CHAT(convo), client_entry->nickname,
buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo),
+ purple_chat_conversation_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,
+ purple_chat_conversation_write_message(PURPLE_CONV_CHAT(convo), server_entry->server_name,
buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo),
+ purple_chat_conversation_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,
+ purple_chat_conversation_write_message(PURPLE_CONV_CHAT(convo), channel->channel_name,
buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo),
+ purple_chat_conversation_set_topic(PURPLE_CONV_CHAT(convo),
channel->channel_name, tmp);
} else {
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), NULL, tmp);
+ purple_chat_conversation_set_topic(PURPLE_CONV_CHAT(convo), NULL, tmp);
}
g_free(tmp2);
@@ -600,12 +600,12 @@ silc_notify(SilcClient client, SilcClientConnection conn,
/* Change nick on 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,
+ convo = purple_conversations_find_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),
+ if (purple_chat_conversation_has_user(PURPLE_CONV_CHAT(convo), client_entry->nickname))
+ purple_chat_conversation_rename_user(PURPLE_CONV_CHAT(convo),
tmp, name);
}
silc_hash_table_list_reset(&htl);
@@ -623,7 +623,7 @@ silc_notify(SilcClient client, SilcClientConnection conn,
(void)va_arg(va, SilcDList);
channel = va_arg(va, SilcChannelEntry);
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
+ convo = purple_conversations_find_with_account(PURPLE_CONV_TYPE_CHAT,
channel->channel_name, sg->account);
if (!convo)
break;
@@ -647,20 +647,20 @@ silc_notify(SilcClient client, SilcClientConnection conn,
_("<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,
+ purple_chat_conversation_write_message(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;
+ PurpleChatUserFlags flags = PURPLE_CHAT_USER_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,
+ convo = purple_conversations_find_with_account(PURPLE_CONV_TYPE_CHAT,
channel->channel_name, sg->account);
if (!convo)
break;
@@ -680,17 +680,17 @@ silc_notify(SilcClient client, SilcClientConnection conn,
_("<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;
+ flags |= PURPLE_CHAT_USER_FOUNDER;
if (mode & SILC_CHANNEL_UMODE_CHANOP)
- flags |= PURPLE_CBFLAGS_OP;
+ flags |= PURPLE_CHAT_USER_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,
+ purple_chat_conversation_write_message(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);
+ purple_chat_conversation_user_set_flags(PURPLE_CONV_CHAT(convo), client_entry2->nickname, flags);
break;
}
@@ -706,7 +706,7 @@ silc_notify(SilcClient client, SilcClientConnection conn,
client_entry2 = va_arg(va, SilcClientEntry);
channel = va_arg(va, SilcChannelEntry);
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
+ convo = purple_conversations_find_with_account(PURPLE_CONV_TYPE_CHAT,
channel->channel_name, sg->account);
if (!convo)
break;
@@ -717,14 +717,14 @@ silc_notify(SilcClient client, SilcClientConnection conn,
_("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,
+ purple_chat_conversation_write_message(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)));
+ serv_got_chat_left(gc, purple_chat_conversation_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),
+ purple_chat_conversation_remove_user(PURPLE_CONV_CHAT(convo),
client_entry->nickname,
buf);
}
@@ -758,13 +758,13 @@ silc_notify(SilcClient client, SilcClientConnection conn,
/* 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,
+ convo = purple_conversations_find_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,
+ purple_chat_conversation_write_message(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)));
+ serv_got_chat_left(gc, purple_chat_conversation_get_id(PURPLE_CONV_CHAT(convo)));
}
silc_hash_table_list_reset(&htl);
@@ -789,11 +789,11 @@ silc_notify(SilcClient client, SilcClientConnection conn,
/* 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,
+ convo = purple_conversations_find_with_account(PURPLE_CONV_TYPE_CHAT,
chu->channel->channel_name, sg->account);
if (!convo)
continue;
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo),
+ purple_chat_conversation_remove_user(PURPLE_CONV_CHAT(convo),
client_entry->nickname, tmp);
}
silc_hash_table_list_reset(&htl);
@@ -813,11 +813,11 @@ silc_notify(SilcClient client, SilcClientConnection conn,
/* 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,
+ convo = purple_conversations_find_with_account(PURPLE_CONV_TYPE_CHAT,
chu->channel->channel_name, sg->account);
if (!convo)
continue;
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo),
+ purple_chat_conversation_remove_user(PURPLE_CONV_CHAT(convo),
client_entry->nickname,
_("Server signoff"));
}
@@ -868,7 +868,7 @@ silc_notify(SilcClient client, SilcClientConnection conn,
silc_free(pk);
/* Find buddy by associated public key */
- for (buddies = purple_find_buddies(account, NULL); buddies;
+ for (buddies = purple_blist_find_buddies(account, NULL); buddies;
buddies = g_slist_delete_link(buddies, buddies)) {
b = buddies->data;
f = purple_blist_node_get_string(PURPLE_BLIST_NODE(b), "public-key");
@@ -880,7 +880,7 @@ silc_notify(SilcClient client, SilcClientConnection conn,
cont:
if (!b) {
/* Find buddy by nickname */
- b = purple_find_buddy(sg->account, client_entry->nickname);
+ b = purple_blist_find_buddy(sg->account, client_entry->nickname);
if (!b) {
purple_debug_warning("silc", "WATCH for %s, unknown buddy\n",
client_entry->nickname);
@@ -1116,20 +1116,20 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
/* 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,
+ convo = purple_conversations_find_with_account(PURPLE_CONV_TYPE_CHAT,
channel->channel_name, sg->account);
if (!convo)
return;
/* Add all users to channel */
while (silc_hash_table_get(user_list, NULL, (void *)&chu)) {
- PurpleConvChatBuddyFlags f = PURPLE_CBFLAGS_NONE;
+ PurpleChatUserFlags f = PURPLE_CHAT_USER_NONE;
chu->context = SILC_32_TO_PTR(sg->channel_ids);
if (chu->mode & SILC_CHANNEL_UMODE_CHANFO)
- f |= PURPLE_CBFLAGS_FOUNDER;
+ f |= PURPLE_CHAT_USER_FOUNDER;
if (chu->mode & SILC_CHANNEL_UMODE_CHANOP)
- f |= PURPLE_CBFLAGS_OP;
+ f |= PURPLE_CHAT_USER_OP;
users = g_list_append(users, chu->client->nickname);
flags = g_list_append(flags, GINT_TO_POINTER(f));
@@ -1148,16 +1148,16 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
}
}
- purple_conv_chat_add_users(PURPLE_CONV_CHAT(convo), users, NULL, flags, FALSE);
+ purple_chat_conversation_add_users(PURPLE_CONV_CHAT(convo), users, NULL, flags, FALSE);
g_list_free(users);
g_list_free(flags);
/* Set topic */
if (topic)
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), NULL, topic);
+ purple_chat_conversation_set_topic(PURPLE_CONV_CHAT(convo), NULL, topic);
/* Set nick */
- purple_conv_chat_set_nick(PURPLE_CONV_CHAT(convo), conn->local_entry->nickname);
+ purple_chat_conversation_set_nick(PURPLE_CONV_CHAT(convo), conn->local_entry->nickname);
}
break;
@@ -1412,7 +1412,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
channel = va_arg(ap, SilcChannelEntry);
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
+ convo = purple_conversations_find_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",
@@ -1422,7 +1422,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
/* Set topic */
if (channel->topic)
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), NULL, channel->topic);
+ purple_chat_conversation_set_topic(PURPLE_CONV_CHAT(convo), NULL, channel->topic);
}
break;
@@ -1445,15 +1445,15 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
/* 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,
+ convo = purple_conversations_find_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));
+ oldnick = purple_chat_conversation_get_nick(PURPLE_CONV_CHAT(convo));
if (strcmp(oldnick, purple_normalize(purple_conversation_get_account(convo), newnick))) {
- purple_conv_chat_rename_user(PURPLE_CONV_CHAT(convo),
+ purple_chat_conversation_rename_user(PURPLE_CONV_CHAT(convo),
oldnick, newnick);
- purple_conv_chat_set_nick(PURPLE_CONV_CHAT(convo), newnick);
+ purple_chat_conversation_set_nick(PURPLE_CONV_CHAT(convo), newnick);
}
}
silc_hash_table_list_reset(&htl);
diff --git a/libpurple/protocols/silc/silc.c b/libpurple/protocols/silc/silc.c
index a55bcf4923..40e6954244 100644
--- a/libpurple/protocols/silc/silc.c
+++ b/libpurple/protocols/silc/silc.c
@@ -260,7 +260,7 @@ silcpurple_connect_cb(SilcClient client, SilcClientConnection conn,
sg->conn = conn;
/* Connection created successfully */
- purple_connection_set_state(gc, PURPLE_CONNECTED);
+ purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED);
/* Send the server our buddy list */
silcpurple_send_buddylist(gc);
@@ -1368,7 +1368,7 @@ silcpurple_send_im_resolved(SilcClient client,
SilcDList list;
gboolean free_list = FALSE;
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, im->nick,
+ convo = purple_conversations_find_im_with_account(im->nick,
sg->account);
if (!convo)
return;
@@ -1405,7 +1405,7 @@ silcpurple_send_im_resolved(SilcClient client,
buf->data,
silc_buffer_len(buf));
silc_mime_partial_free(list);
- purple_conv_im_write(PURPLE_CONV_IM(convo), conn->local_entry->nickname,
+ purple_im_conversation_write_message(PURPLE_CONV_IM(convo), conn->local_entry->nickname,
im->message, 0, time(NULL));
goto out;
}
@@ -1414,7 +1414,7 @@ silcpurple_send_im_resolved(SilcClient client,
/* Send the message */
silc_client_send_private_message(client, conn, client_entry, im->flags,
sg->sha1hash, (unsigned char *)im->message, im->message_len);
- purple_conv_im_write(PURPLE_CONV_IM(convo), conn->local_entry->nickname,
+ purple_im_conversation_write_message(PURPLE_CONV_IM(convo), conn->local_entry->nickname,
im->message, 0, time(NULL));
goto out;
@@ -1533,9 +1533,9 @@ silcpurple_send_im(PurpleConnection *gc, const char *who, const char *message,
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)) {
+ if(PURPLE_IS_CHAT(node)) {
return silcpurple_chat_menu((PurpleChat *) node);
- } else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ } else if(PURPLE_IS_BUDDY(node)) {
return silcpurple_buddy_menu((PurpleBuddy *) node);
} else {
g_return_val_if_reached(NULL);
@@ -1557,11 +1557,11 @@ static PurpleCmdRet silcpurple_cmd_chat_part(PurpleConversation *conv,
return PURPLE_CMD_RET_FAILED;
if(args && args[0])
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[0],
+ convo = purple_conversations_find_chat_with_account(args[0],
purple_connection_get_account(gc));
if (convo != NULL)
- id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo));
+ id = purple_chat_conversation_get_id(PURPLE_CONV_CHAT(convo));
if (id == 0)
return PURPLE_CMD_RET_FAILED;
@@ -1581,13 +1581,13 @@ static PurpleCmdRet silcpurple_cmd_chat_topic(PurpleConversation *conv,
const char *topic;
gc = purple_conversation_get_connection(conv);
- id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv));
+ id = purple_chat_conversation_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));
+ topic = purple_chat_conversation_get_topic (PURPLE_CONV_CHAT(conv));
if (topic) {
tmp = g_markup_escape_text(topic, -1);
tmp2 = purple_markup_linkify(tmp);
@@ -1596,7 +1596,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), purple_account_get_username(purple_connection_get_account(gc)), buf,
+ purple_chat_conversation_write_message(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);
@@ -1695,11 +1695,11 @@ static PurpleCmdRet silcpurple_cmd_query(PurpleConversation *conv,
account = purple_connection_get_account(gc);
- convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, args[0]);
+ convo = purple_im_conversation_new(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),
+ purple_im_conversation_write_message(PURPLE_CONV_IM(convo), purple_connection_get_display_name(gc),
args[1], PURPLE_MESSAGE_SEND, time(NULL));
}
@@ -1795,7 +1795,7 @@ static PurpleCmdRet silcpurple_cmd_cmode(PurpleConversation *conv,
} else {
msg = g_strdup_printf(_("no channel modes are set on %s"), chname);
}
- purple_conv_chat_write(PURPLE_CONV_CHAT(conv), "",
+ purple_chat_conversation_write_message(PURPLE_CONV_CHAT(conv), "",
msg, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL));
g_free(msg);
return PURPLE_CMD_RET_OK;
diff --git a/libpurple/protocols/simple/simple.c b/libpurple/protocols/simple/simple.c
index 10ff4be7da..8937990be9 100644
--- a/libpurple/protocols/simple/simple.c
+++ b/libpurple/protocols/simple/simple.c
@@ -27,12 +27,11 @@
#include "internal.h"
#include "accountopt.h"
-#include "blist.h"
+#include "buddylist.h"
#include "conversation.h"
#include "dnsquery.h"
#include "debug.h"
#include "notify.h"
-#include "privacy.h"
#include "prpl.h"
#include "plugin.h"
#include "util.h"
@@ -101,7 +100,7 @@ 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));
+ PurpleStatusPrimitive primitive = purple_status_type_get_primitive(purple_status_get_status_type(status));
struct simple_account_data *sip = NULL;
if (!purple_status_is_active(status))
@@ -200,7 +199,7 @@ static void simple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGro
const char *name = purple_buddy_get_name(buddy);
if(strncmp(name, "sip:", 4)) {
gchar *buf = g_strdup_printf("sip:%s", name);
- purple_blist_rename_buddy(buddy, buf);
+ purple_buddy_set_name(buddy, buf);
g_free(buf);
}
if(!g_hash_table_lookup(sip->buddies, name)) {
@@ -220,7 +219,7 @@ static void simple_get_buddies(PurpleConnection *gc) {
purple_debug_info("simple", "simple_get_buddies\n");
account = purple_connection_get_account(gc);
- buddies = purple_find_buddies(account, NULL);
+ buddies = purple_blist_find_buddies(account, NULL);
while (buddies) {
PurpleBuddy *buddy = buddies->data;
simple_add_buddy(gc, buddy, purple_buddy_get_group(buddy), NULL);
@@ -245,7 +244,7 @@ static GList *simple_status_types(PurpleAccount *acc) {
type = purple_status_type_new_with_attrs(
PURPLE_STATUS_AVAILABLE, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_append(types, type);
@@ -274,7 +273,7 @@ static gchar *auth_header(struct simple_account_data *sip,
if(auth->type == 1) { /* Digest */
sprintf(noncecount, "%08d", auth->nc++);
- response = purple_cipher_http_digest_calculate_response(
+ response = purple_http_digest_calculate_response(
"md5", method, target, NULL, NULL,
auth->nonce, noncecount, NULL, auth->digest_session_key);
purple_debug(PURPLE_DEBUG_MISC, "simple", "response %s\n", response);
@@ -295,7 +294,7 @@ static gchar *auth_header(struct simple_account_data *sip,
}
sprintf(noncecount, "%08d", auth->nc++);
- response = purple_cipher_http_digest_calculate_response(
+ response = purple_http_digest_calculate_response(
"md5", method, target, NULL, NULL,
auth->nonce, noncecount, NULL, auth->digest_session_key);
purple_debug(PURPLE_DEBUG_MISC, "simple", "response %s\n", response);
@@ -399,7 +398,7 @@ static void fill_auth(struct simple_account_data *sip, const gchar *hdr, struct
auth->realm ? auth->realm : "(null)");
if(auth->realm) {
- auth->digest_session_key = purple_cipher_http_digest_calculate_session_key(
+ auth->digest_session_key = purple_http_digest_calculate_session_key(
"md5", authuser, auth->realm, sip->password, auth->nonce, NULL);
auth->nc = 1;
@@ -416,8 +415,9 @@ static void simple_canwrite_cb(gpointer data, gint source, PurpleInputCondition
struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
gsize max_write;
gssize written;
+ const gchar *output = NULL;
- max_write = purple_circ_buffer_get_max_read(sip->txbuf);
+ max_write = purple_circular_buffer_get_max_read(sip->txbuf);
if(max_write == 0) {
purple_input_remove(sip->tx_handler);
@@ -425,7 +425,9 @@ static void simple_canwrite_cb(gpointer data, gint source, PurpleInputCondition
return;
}
- written = write(sip->fd, sip->txbuf->outptr, max_write);
+ output = purple_circular_buffer_get_output(sip->txbuf);
+
+ written = write(sip->fd, output, max_write);
if(written < 0 && errno == EAGAIN)
written = 0;
@@ -439,7 +441,7 @@ static void simple_canwrite_cb(gpointer data, gint source, PurpleInputCondition
return;
}
- purple_circ_buffer_mark_read(sip->txbuf, written);
+ purple_circular_buffer_mark_read(sip->txbuf, written);
}
static void simple_input_cb(gpointer data, gint source, PurpleInputCondition cond);
@@ -465,7 +467,7 @@ static void send_later_cb(gpointer data, gint source, const gchar *error_message
simple_canwrite_cb(gc, sip->fd, PURPLE_INPUT_WRITE);
/* If there is more to write now, we need to register a handler */
- if(sip->txbuf->bufused > 0)
+ if(purple_circular_buffer_get_used(sip->txbuf) > 0)
sip->tx_handler = purple_input_add(sip->fd, PURPLE_INPUT_WRITE,
simple_canwrite_cb, gc);
@@ -485,10 +487,10 @@ static void sendlater(PurpleConnection *gc, const char *buf) {
sip->connecting = TRUE;
}
- if(purple_circ_buffer_get_max_read(sip->txbuf) > 0)
- purple_circ_buffer_append(sip->txbuf, "\r\n", 2);
+ if(purple_circular_buffer_get_max_read(sip->txbuf) > 0)
+ purple_circular_buffer_append(sip->txbuf, "\r\n", 2);
- purple_circ_buffer_append(sip->txbuf, buf, strlen(buf));
+ purple_circular_buffer_append(sip->txbuf, buf, strlen(buf));
}
static void sendout_pkt(PurpleConnection *gc, const char *buf) {
@@ -529,10 +531,10 @@ static void sendout_pkt(PurpleConnection *gc, const char *buf) {
/* XXX: is it OK to do this? You might get part of a request sent
with part of another. */
- if(sip->txbuf->bufused > 0)
- purple_circ_buffer_append(sip->txbuf, "\r\n", 2);
+ if(purple_circular_buffer_get_used(sip->txbuf) > 0)
+ purple_circular_buffer_append(sip->txbuf, "\r\n", 2);
- purple_circ_buffer_append(sip->txbuf, buf + ret,
+ purple_circular_buffer_append(sip->txbuf, buf + ret,
writelen - ret);
}
}
@@ -889,13 +891,13 @@ static gboolean simple_add_lcs_contacts(struct simple_account_data *sip, struct
if ((group = xmlnode_get_child(isc, "group"))) {
name_group = xmlnode_get_attrib(group, "name");
purple_debug_info("simple", "name_group->%s\n", name_group);
- g = purple_find_group(name_group);
+ g = purple_blist_find_group(name_group);
if(!g)
g = purple_group_new(name_group);
}
if (!g) {
- g = purple_find_group("Buddies");
+ g = purple_blist_find_group("Buddies");
if(!g)
g = purple_group_new("Buddies");
}
@@ -911,14 +913,14 @@ static gboolean simple_add_lcs_contacts(struct simple_account_data *sip, struct
buddy_name = g_strdup_printf("sip:%s", uri);
- b = purple_find_buddy(sip->account, buddy_name);
+ b = purple_blist_find_buddy(sip->account, buddy_name);
if(!b){
b = purple_buddy_new(sip->account, buddy_name, uri);
}
g_free(buddy_name);
purple_blist_add_buddy(b, NULL, g, NULL);
- purple_blist_alias_buddy(b, uri);
+ purple_buddy_set_local_alias(b, uri);
bs = g_new0(struct simple_buddy, 1);
bs->name = g_strdup(purple_buddy_get_name(b));
g_hash_table_insert(sip->buddies, bs->name, bs);
@@ -1076,7 +1078,7 @@ static void process_incoming_message(struct simple_account_data *sip, struct sip
statedata = xmlnode_get_data(state);
if(statedata) {
if(strstr(statedata, "active"))
- serv_got_typing(sip->gc, from, 0, PURPLE_TYPING);
+ serv_got_typing(sip->gc, from, 0, PURPLE_IM_TYPING);
else
serv_got_typing_stopped(sip->gc, from);
@@ -1105,7 +1107,7 @@ gboolean process_register_response(struct simple_account_data *sip, struct sipms
}
}
sip->registerstatus = SIMPLE_REGISTER_COMPLETE;
- purple_connection_set_state(sip->gc, PURPLE_CONNECTED);
+ purple_connection_set_state(sip->gc, PURPLE_CONNECTION_CONNECTED);
/* get buddies from blist */
simple_get_buddies(sip->gc);
@@ -1285,7 +1287,7 @@ static void process_incoming_notify(struct simple_account_data *sip, struct sipm
send_sip_response(sip->gc, msg, 200, "OK", NULL);
}
-static unsigned int simple_typing(PurpleConnection *gc, const char *name, PurpleTypingState state) {
+static unsigned int simple_typing(PurpleConnection *gc, const char *name, PurpleIMTypingState state) {
struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
gchar *xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
@@ -1297,11 +1299,11 @@ static unsigned int simple_typing(PurpleConnection *gc, const char *name, Purple
"<refresh>60</refresh>\n"
"</isComposing>";
gchar *recv = g_strdup(name);
- if(state == PURPLE_TYPING) {
+ if(state == PURPLE_IM_TYPING) {
gchar *msg = g_strdup_printf(xml, "active");
simple_send_message(sip, recv, msg, "application/im-iscomposing+xml");
g_free(msg);
- } else /* TODO: Only if (state == PURPLE_TYPED) ? */ {
+ } else /* TODO: Only if (state == PURPLE_IM_TYPED) ? */ {
gchar *msg = g_strdup_printf(xml, "idle");
simple_send_message(sip, recv, msg, "application/im-iscomposing+xml");
g_free(msg);
@@ -1309,7 +1311,7 @@ static unsigned int simple_typing(PurpleConnection *gc, const char *name, Purple
g_free(recv);
/*
* TODO: Is this right? It will cause the core to call
- * serv_send_typing(gc, who, PURPLE_TYPING) once every second
+ * serv_send_typing(gc, who, PURPLE_IM_TYPING) once every second
* until the user stops typing. If that's not desired,
* then return 0 instead.
*/
@@ -1452,7 +1454,7 @@ static void process_incoming_subscribe(struct simple_account_data *sip, struct s
if(!watcher) { /* new subscription */
const gchar *acceptheader = sipmsg_find_header(msg, "Accept");
gboolean needsxpidf = FALSE;
- if(!purple_privacy_check(sip->account, from)) {
+ if(!purple_account_privacy_check(sip->account, from)) {
send_sip_response(sip->gc, msg, 202, "Ok", NULL);
goto privend;
}
@@ -1941,7 +1943,7 @@ static void simple_login(PurpleAccount *account)
sip->udp = purple_account_get_bool(account, "udp", FALSE);
/* TODO: is there a good default grow size? */
if(!sip->udp)
- sip->txbuf = purple_circ_buffer_new(0);
+ sip->txbuf = purple_circular_buffer_new(0);
userserver = g_strsplit(username, "@", 2);
if (userserver[1] == NULL || userserver[1][0] == '\0') {
@@ -2037,7 +2039,7 @@ static void simple_close(PurpleConnection *gc)
transactions_remove(sip, sip->transactions->data);
g_free(sip->publish_etag);
if (sip->txbuf)
- purple_circ_buffer_destroy(sip->txbuf);
+ g_object_unref(G_OBJECT(sip->txbuf));
g_free(sip->realhostname);
g_free(sip);
diff --git a/libpurple/protocols/simple/simple.h b/libpurple/protocols/simple/simple.h
index 8f15e4d792..caffe2fcd4 100644
--- a/libpurple/protocols/simple/simple.h
+++ b/libpurple/protocols/simple/simple.h
@@ -27,7 +27,7 @@
#include <time.h>
#include "cipher.h"
-#include "circbuffer.h"
+#include "circularbuffer.h"
#include "dnsquery.h"
#include "dnssrv.h"
#include "network.h"
@@ -101,7 +101,7 @@ struct simple_account_data {
guint resendtimeout;
gboolean connecting;
PurpleAccount *account;
- PurpleCircBuffer *txbuf;
+ PurpleCircularBuffer *txbuf;
guint tx_handler;
gchar *regcallid;
GSList *transactions;
diff --git a/libpurple/protocols/simple/sipmsg.c b/libpurple/protocols/simple/sipmsg.c
index 51411de2f0..1ae47fa5ff 100644
--- a/libpurple/protocols/simple/sipmsg.c
+++ b/libpurple/protocols/simple/sipmsg.c
@@ -23,7 +23,7 @@
#include "internal.h"
#include "accountopt.h"
-#include "blist.h"
+#include "buddylist.h"
#include "conversation.h"
#include "debug.h"
#include "notify.h"
diff --git a/libpurple/protocols/yahoo/libyahoo.c b/libpurple/protocols/yahoo/libyahoo.c
index 5c58ad072c..7424584e2a 100644
--- a/libpurple/protocols/yahoo/libyahoo.c
+++ b/libpurple/protocols/yahoo/libyahoo.c
@@ -112,16 +112,16 @@ static gboolean yahoo_uri_handler(const char *proto, const char *cmd, GHashTable
if (sname) {
char *message = g_hash_table_lookup(params, "m");
- PurpleConversation *conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_IM, sname, acct);
- if (conv == NULL)
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, sname);
- purple_conversation_present(conv);
+ PurpleIMConversation *im = purple_conversations_find_im_with_account(
+ sname, acct);
+ if (im == NULL)
+ im = purple_im_conversation_new(acct, sname);
+ purple_conversation_present(PURPLE_CONVERSATION(im));
if (message) {
/* Spaces are encoded as '+' */
g_strdelimit(message, "+", ' ');
- purple_conv_send_confirm(conv, message);
+ purple_conversation_send_confirm(PURPLE_CONVERSATION(im), message);
}
}
/* else
diff --git a/libpurple/protocols/yahoo/libymsg.c b/libpurple/protocols/yahoo/libymsg.c
index 74bc7b97fc..8cc96c8ec1 100644
--- a/libpurple/protocols/yahoo/libymsg.c
+++ b/libpurple/protocols/yahoo/libymsg.c
@@ -25,15 +25,14 @@
#include "account.h"
#include "accountopt.h"
-#include "blist.h"
-#include "cipher.h"
+#include "buddylist.h"
+#include "ciphers/md5hash.h"
#include "cmds.h"
#include "core.h"
#include "debug.h"
#include "http.h"
#include "network.h"
#include "notify.h"
-#include "privacy.h"
#include "prpl.h"
#include "proxy.h"
#include "request.h"
@@ -80,7 +79,7 @@ static void yahoo_update_status(PurpleConnection *gc, const char *name, YahooFri
{
char *status = NULL;
- if (!gc || !name || !f || !purple_find_buddy(purple_connection_get_account(gc), name))
+ if (!gc || !name || !f || !purple_blist_find_buddy(purple_connection_get_account(gc), name))
return;
switch (f->status) {
@@ -343,7 +342,7 @@ static void yahoo_process_status(PurpleConnection *gc, struct yahoo_packet *pkt)
if (!name)
break;
- b = purple_find_buddy(purple_connection_get_account(gc), name);
+ b = purple_blist_find_buddy(purple_connection_get_account(gc), name);
if (!cksum || (cksum == -1)) {
if (f)
@@ -413,7 +412,7 @@ static void yahoo_do_group_check(PurpleAccount *account, GHashTable *ht, const c
if (g_hash_table_lookup_extended(ht, name, (gpointer *)&oname, (gpointer *)&list))
g_hash_table_steal(ht, oname);
else
- list = purple_find_buddies(account, name);
+ list = purple_blist_find_buddies(account, name);
for (i = list; i; i = i->next) {
b = i->data;
@@ -430,7 +429,7 @@ static void yahoo_do_group_check(PurpleAccount *account, GHashTable *ht, const c
if (!onlist) {
purple_debug_misc("yahoo",
"Uhoh, %s isn't on the list (or not in this group), adding him to group %s.\n", name, group);
- if (!(g = purple_find_group(group))) {
+ if (!(g = purple_blist_find_group(group))) {
g = purple_group_new(group);
purple_blist_add_group(g, NULL);
}
@@ -553,10 +552,10 @@ static void yahoo_process_list_15(PurpleConnection *gc, struct yahoo_packet *pkt
if (yd->current_list15_grp) {
/* This buddy is in a group */
f = yahoo_friend_find_or_new(gc, norm_bud);
- if (!purple_find_buddy(account, norm_bud)) {
+ if (!purple_blist_find_buddy(account, norm_bud)) {
PurpleBuddy *b;
PurpleGroup *g;
- if (!(g = purple_find_group(yd->current_list15_grp))) {
+ if (!(g = purple_blist_find_group(yd->current_list15_grp))) {
g = purple_group_new(yd->current_list15_grp);
purple_blist_add_group(g, NULL);
}
@@ -580,7 +579,7 @@ static void yahoo_process_list_15(PurpleConnection *gc, struct yahoo_packet *pkt
} 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", purple_account_get_username(account), norm_bud);
- purple_privacy_deny_add(account, norm_bud, 1);
+ purple_account_privacy_deny_add(account, norm_bud, 1);
}
g_free(norm_bud);
@@ -626,7 +625,7 @@ static void yahoo_process_list_15(PurpleConnection *gc, struct yahoo_packet *pkt
purple_connection_set_display_name(gc, purple_normalize(account, purple_account_get_username(account)));
yd->logged_in = TRUE;
purple_debug_info("yahoo","Authentication: Connection established\n");
- purple_connection_set_state(gc, PURPLE_CONNECTED);
+ purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED);
if (yd->picture_upload_todo) {
yahoo_buddy_icon_upload(gc, yd->picture_upload_todo);
yd->picture_upload_todo = NULL;
@@ -708,10 +707,10 @@ static void yahoo_process_list(PurpleConnection *gc, struct yahoo_packet *pkt)
norm_bud = g_strdup(purple_normalize(account, *bud));
f = yahoo_friend_find_or_new(gc, norm_bud);
- if (!purple_find_buddy(account, norm_bud)) {
+ if (!purple_blist_find_buddy(account, norm_bud)) {
PurpleBuddy *b;
PurpleGroup *g;
- if (!(g = purple_find_group(grp))) {
+ if (!(g = purple_blist_find_group(grp))) {
g = purple_group_new(grp);
purple_blist_add_group(g, NULL);
}
@@ -743,7 +742,7 @@ static void yahoo_process_list(PurpleConnection *gc, struct yahoo_packet *pkt)
for (bud = buddies; bud && *bud; bud++) {
/* The server is already ignoring the user */
got_serv_list = TRUE;
- purple_privacy_deny_add(account, *bud, 1);
+ purple_account_privacy_deny_add(account, *bud, 1);
}
g_strfreev(buddies);
@@ -752,12 +751,12 @@ static void yahoo_process_list(PurpleConnection *gc, struct yahoo_packet *pkt)
}
if (got_serv_list &&
- ((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)))
+ ((purple_account_get_privacy_type(account) != PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST) &&
+ (purple_account_get_privacy_type(account) != PURPLE_ACCOUNT_PRIVACY_DENY_ALL) &&
+ (purple_account_get_privacy_type(account) != PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS)))
{
- purple_account_set_privacy_type(account, PURPLE_PRIVACY_DENY_USERS);
- purple_debug_info("yahoo", "%s privacy defaulting to PURPLE_PRIVACY_DENY_USERS.\n",
+ purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_DENY_USERS);
+ purple_debug_info("yahoo", "%s privacy defaulting to PURPLE_ACCOUNT_PRIVACY_DENY_USERS.\n",
purple_account_get_username(account));
}
@@ -825,7 +824,7 @@ static void yahoo_process_notify(PurpleConnection *gc, struct yahoo_packet *pkt,
}
if (!g_ascii_strncasecmp(msg, "TYPING", strlen("TYPING"))
- && (purple_privacy_check(account, from)))
+ && (purple_account_privacy_check(account, from)))
{
char *fed_from = from;
switch (fed) {
@@ -847,7 +846,7 @@ static void yahoo_process_notify(PurpleConnection *gc, struct yahoo_packet *pkt,
}
if (stat && *stat == '1')
- serv_got_typing(gc, fed_from, 0, PURPLE_TYPING);
+ serv_got_typing(gc, fed_from, 0, PURPLE_IM_TYPING);
else
serv_got_typing_stopped(gc, fed_from);
@@ -855,7 +854,7 @@ static void yahoo_process_notify(PurpleConnection *gc, struct yahoo_packet *pkt,
g_free(fed_from);
} else if (!g_ascii_strncasecmp(msg, "GAME", strlen("GAME"))) {
- PurpleBuddy *bud = purple_find_buddy(account, from);
+ PurpleBuddy *bud = purple_blist_find_buddy(account, from);
if (!bud) {
purple_debug_warning("yahoo",
@@ -874,9 +873,9 @@ static void yahoo_process_notify(PurpleConnection *gc, struct yahoo_packet *pkt,
yahoo_update_status(gc, from, f);
}
} else if (!g_ascii_strncasecmp(msg, "WEBCAMINVITE", strlen("WEBCAMINVITE"))) {
- PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, from, account);
+ PurpleIMConversation *im = purple_conversations_find_im_with_account(from, account);
char *buf = g_strdup_printf(_("%s has sent you a webcam invite, which is not yet supported."), from);
- purple_conversation_write(conv, NULL, buf, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NOTIFY, time(NULL));
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, buf, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NOTIFY, time(NULL));
g_free(buf);
}
}
@@ -933,11 +932,11 @@ static void yahoo_process_sms_message(PurpleConnection *gc, struct yahoo_packet
if( (pkt->status == -1) || (pkt->status == YAHOO_STATUS_DISCONNECTED) ) {
if (server_msg) {
- PurpleConversation *c;
- c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, sms->from, account);
- if (c == NULL)
- c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sms->from);
- purple_conversation_write(c, NULL, server_msg, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ PurpleIMConversation *im;
+ im = purple_conversations_find_im_with_account(sms->from, account);
+ if (im == NULL)
+ im = purple_im_conversation_new(account, sms->from);
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, server_msg, PURPLE_MESSAGE_SYSTEM, time(NULL));
}
else
purple_notify_error(gc, NULL, _("Your SMS was not delivered"), NULL);
@@ -1049,7 +1048,7 @@ static void yahoo_process_message(PurpleConnection *gc, struct yahoo_packet *pkt
{
PurpleWhiteboard *wb;
- if (!purple_privacy_check(account, im->from)) {
+ if (!purple_account_privacy_check(account, im->from)) {
purple_debug_info("yahoo", "Doodle request from %s dropped.\n",
im->from);
g_free(im->fed_from);
@@ -1095,7 +1094,7 @@ static void yahoo_process_message(PurpleConnection *gc, struct yahoo_packet *pkt
continue;
}
- if (!purple_privacy_check(account, im->fed_from)) {
+ if (!purple_account_privacy_check(account, im->fed_from)) {
purple_debug_info("yahoo", "Message from %s dropped.\n", im->fed_from);
return;
}
@@ -1414,7 +1413,7 @@ static void yahoo_buddy_auth_req_15(PurpleConnection *gc, struct yahoo_packet *p
if (add_req->id && add_req->who) {
char *alias = NULL, *dec_msg = NULL;
- if (!purple_privacy_check(account, add_req->who))
+ if (!purple_account_privacy_check(account, add_req->who))
{
purple_debug_misc("yahoo", "Auth. request from %s dropped and automatically denied due to privacy settings!\n",
add_req->who);
@@ -1437,7 +1436,7 @@ static void yahoo_buddy_auth_req_15(PurpleConnection *gc, struct yahoo_packet *p
*/
purple_account_request_authorization(account, add_req->who, add_req->id,
alias, dec_msg,
- purple_find_buddy(account, add_req->who) != NULL,
+ purple_blist_find_buddy(account, add_req->who) != NULL,
yahoo_buddy_add_authorize_cb,
yahoo_buddy_add_deny_cb,
add_req);
@@ -1487,7 +1486,7 @@ static void yahoo_buddy_added_us(PurpleConnection *gc, struct yahoo_packet *pkt)
if (add_req->id && add_req->who) {
char *dec_msg = NULL;
- if (!purple_privacy_check(account, add_req->who)) {
+ if (!purple_account_privacy_check(account, add_req->who)) {
purple_debug_misc("yahoo", "Auth. request from %s dropped and automatically denied due to privacy settings!\n",
add_req->who);
yahoo_buddy_add_deny_cb(NULL, add_req);
@@ -1502,7 +1501,7 @@ static void yahoo_buddy_added_us(PurpleConnection *gc, struct yahoo_packet *pkt)
*/
purple_account_request_authorization(account, add_req->who, add_req->id,
NULL, dec_msg,
- purple_find_buddy(account,add_req->who) != NULL,
+ purple_blist_find_buddy(account,add_req->who) != NULL,
yahoo_buddy_add_authorize_cb,
yahoo_buddy_add_deny_cb, add_req);
g_free(dec_msg);
@@ -1697,8 +1696,7 @@ static void yahoo_auth16_stage3(PurpleConnection *gc, const char *crypt)
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;
- PurpleCipherContext *md5_ctx;
+ PurpleHash *md5_hash;
guchar md5_digest[16];
gchar base64_string[25];
struct yahoo_packet *pkt;
@@ -1707,10 +1705,9 @@ static void yahoo_auth16_stage3(PurpleConnection *gc, const char *crypt)
g_return_if_fail(crypt != NULL);
- md5_cipher = purple_ciphers_find_cipher("md5");
- md5_ctx = purple_cipher_context_new(md5_cipher, NULL);
- purple_cipher_context_append(md5_ctx, (guchar *)crypt, strlen(crypt));
- purple_cipher_context_digest(md5_ctx, md5_digest, sizeof(md5_digest));
+ md5_hash = purple_md5_hash_new();
+ purple_hash_append(md5_hash, (guchar *)crypt, strlen(crypt));
+ purple_hash_digest(md5_hash, md5_digest, sizeof(md5_digest));
to_y64(base64_string, md5_digest, 16);
@@ -1748,7 +1745,7 @@ static void yahoo_auth16_stage3(PurpleConnection *gc, const char *crypt)
yahoo_packet_hash_int(pkt, 192, yd->picture_checksum);
yahoo_packet_send_and_free(pkt, yd);
- purple_cipher_context_destroy(md5_ctx);
+ g_object_unref(md5_hash);
}
static void yahoo_auth16_stage2(PurpleHttpConnection *http_conn,
@@ -2078,7 +2075,7 @@ static void ignore_buddy(PurpleBuddy *buddy) {
static void keep_buddy(PurpleBuddy *b)
{
- purple_privacy_deny_remove(purple_buddy_get_account(b),
+ purple_account_privacy_deny_remove(purple_buddy_get_account(b),
purple_buddy_get_name(b), 1);
}
@@ -2122,7 +2119,7 @@ static void yahoo_process_ignore(PurpleConnection *gc, struct yahoo_packet *pkt)
who, (ignore ? "ignoring" : "unignoring"));
if (ignore) {
- b = purple_find_buddy(purple_connection_get_account(gc), who);
+ b = purple_blist_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);
@@ -2328,7 +2325,7 @@ static void yahoo_process_addbuddy(PurpleConnection *gc, struct yahoo_packet *pk
decoded_group = yahoo_string_decode(gc, group, FALSE);
buf = g_strdup_printf(_("Unable to add buddy %s to group %s to the server list on account %s."),
who, decoded_group, purple_connection_get_display_name(gc));
- if (!purple_conv_present_error(who, purple_connection_get_account(gc), buf))
+ if (!purple_conversation_present_error(who, purple_connection_get_account(gc), buf))
purple_notify_error(gc, NULL, _("Unable to add buddy to server list"), buf);
g_free(buf);
g_free(decoded_group);
@@ -2930,7 +2927,7 @@ static void yahoo_process_audible(PurpleConnection *gc, struct yahoo_packet *pkt
purple_debug_misc("yahoo", "Warning, nonutf8 audible, ignoring!\n");
return;
}
- if (!purple_privacy_check(account, who)) {
+ if (!purple_account_privacy_check(account, who)) {
purple_debug_misc("yahoo", "Audible message from %s for %s dropped!\n",
purple_account_get_username(account), who);
return;
@@ -3358,7 +3355,6 @@ yahoo_login_page_cb(PurpleHttpConnection *http_conn,
char md5[33], *hashp = md5, *chal;
int i;
PurpleCipher *cipher;
- PurpleCipherContext *context;
guchar digest[16];
PurpleHttpRequest *req;
@@ -3372,20 +3368,19 @@ yahoo_login_page_cb(PurpleHttpConnection *http_conn,
got_data = purple_http_response_get_data(response, &len);
hash = yahoo_login_page_hash(got_data, len);
- cipher = purple_ciphers_find_cipher("md5");
- context = purple_cipher_context_new(cipher, NULL);
+ cipher = purple_md5_cipher_new();
- purple_cipher_context_append(context, (const guchar *)pass, strlen(pass));
- purple_cipher_context_digest(context, digest, sizeof(digest));
+ purple_cipher_append(cipher, (const guchar *)pass, strlen(pass));
+ purple_cipher_digest(cipher, digest, sizeof(digest));
for (i = 0; i < 16; ++i) {
g_snprintf(hashp, 3, "%02x", digest[i]);
hashp += 2;
}
chal = g_strconcat(md5, g_hash_table_lookup(hash, ".challenge"), NULL);
- purple_cipher_context_reset(context, NULL);
- purple_cipher_context_append(context, (const guchar *)chal, strlen(chal));
- purple_cipher_context_digest(context, digest, sizeof(digest));
+ purple_cipher_reset(cipher);
+ purple_cipher_append(cipher, (const guchar *)chal, strlen(chal));
+ purple_cipher_digest(cipher, digest, sizeof(digest));
hashp = md5;
for (i = 0; i < 16; ++i) {
g_snprintf(hashp, 3, "%02x", digest[i]);
@@ -3395,9 +3390,9 @@ yahoo_login_page_cb(PurpleHttpConnection *http_conn,
* I dunno why this is here and commented out.. but in case it's needed
* I updated it..
- purple_cipher_context_reset(context, NULL);
- purple_cipher_context_append(context, md5, strlen(md5));
- purple_cipher_context_digest(context, sizeof(digest), digest, NULL);
+ purple_cipher_reset(cipher);
+ purple_cipher_append(cipher, md5, strlen(md5));
+ purple_cipher_digest(cipher, sizeof(digest), digest, NULL);
hashp = md5;
for (i = 0; i < 16; ++i) {
g_snprintf(hashp, 3, "%02x", digest[i]);
@@ -3412,7 +3407,7 @@ yahoo_login_page_cb(PurpleHttpConnection *http_conn,
url = g_string_append(url, "&.hash=1&.md5=1");
g_hash_table_destroy(hash);
- purple_cipher_context_destroy(context);
+ g_object_unref(cipher);
req = purple_http_request_new(g_string_free(url, FALSE));
purple_http_request_set_max_redirects(req, 0);
@@ -3550,7 +3545,7 @@ void yahoo_login(PurpleAccount *account) {
PurpleStatus *status = purple_account_get_active_status(account);
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_set_flags(gc, PURPLE_CONNECTION_FLAG_HTML | PURPLE_CONNECTION_FLAG_NO_BGCOLOR | PURPLE_CONNECTION_FLAG_NO_URLDESC);
purple_connection_update_progress(gc, _("Connecting"), 1, 2);
@@ -3562,7 +3557,7 @@ void yahoo_login(PurpleAccount *account) {
yd->fd = -1;
yd->txhandler = 0;
/* TODO: Is there a good grow size for the buffer? */
- yd->txbuf = purple_circ_buffer_new(0);
+ yd->txbuf = purple_circular_buffer_new(0);
yd->http_reqs = purple_http_connection_set_new();
yd->friends = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_friend_free);
yd->imvironments = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
@@ -3605,11 +3600,11 @@ void yahoo_close(PurpleConnection *gc) {
yd->http_reqs = NULL;
for (l = yd->confs; l; l = l->next) {
- PurpleConversation *conv = l->data;
+ PurpleChatConversation *conv = l->data;
- yahoo_conf_leave(yd, purple_conversation_get_name(conv),
+ yahoo_conf_leave(yd, purple_conversation_get_name(PURPLE_CONVERSATION(conv)),
purple_connection_get_display_name(gc),
- purple_conv_chat_get_users(PURPLE_CONV_CHAT(conv)));
+ purple_chat_conversation_get_users(conv));
}
g_slist_free(yd->confs);
@@ -3653,7 +3648,7 @@ void yahoo_close(PurpleConnection *gc) {
if (yd->txhandler)
purple_input_remove(yd->txhandler);
- purple_circ_buffer_destroy(yd->txbuf);
+ g_object_unref(G_OBJECT(yd->txbuf));
if (yd->fd >= 0)
close(yd->fd);
@@ -3759,7 +3754,7 @@ static void yahoo_initiate_conference(PurpleBlistNode *node, gpointer data) {
YahooData *yd;
int id;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
@@ -3799,7 +3794,7 @@ static void yahoo_game(PurpleBlistNode *node, gpointer data) {
char url[256];
YahooFriend *f;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
@@ -3921,7 +3916,7 @@ static void yahoo_addbuddyfrommenu_cb(PurpleBlistNode *node, gpointer data)
PurpleBuddy *buddy;
PurpleConnection *gc;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
@@ -3935,7 +3930,7 @@ static void yahoo_chat_goto_menu(PurpleBlistNode *node, gpointer data)
PurpleBuddy *buddy;
PurpleConnection *gc;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
@@ -4086,7 +4081,7 @@ static GList *yahoo_buddy_menu(PurpleBuddy *buddy)
GList *yahoo_blist_node_menu(PurpleBlistNode *node)
{
- if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if(PURPLE_IS_BUDDY(node)) {
return yahoo_buddy_menu((PurpleBuddy *) node);
} else {
return NULL;
@@ -4256,10 +4251,11 @@ static void yahoo_get_sms_carrier_cb(PurpleHttpConnection *http_conn,
char *status = NULL;
char *carrier = NULL;
PurpleAccount *account = purple_connection_get_account(gc);
- PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, sms_cb_data->who, account);
+ PurpleIMConversation *im = purple_conversations_find_im_with_account(sms_cb_data->who, account);
if (!purple_http_response_is_successful(response)) {
- purple_conversation_write(conv, NULL, _("Can't send SMS. Unable to obtain mobile carrier."), PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL,
+ _("Can't send SMS. Unable to obtain mobile carrier."), PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(sms_cb_data->who);
g_free(sms_cb_data->what);
@@ -4288,7 +4284,7 @@ static void yahoo_get_sms_carrier_cb(PurpleHttpConnection *http_conn,
} else {
g_hash_table_insert(yd->sms_carrier,
g_strdup_printf("+%s", mobile_no), g_strdup("Unknown"));
- purple_conversation_write(conv, NULL,
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL,
_("Can't send SMS. Unknown mobile carrier."),
PURPLE_MESSAGE_SYSTEM, time(NULL));
}
@@ -4384,7 +4380,7 @@ int yahoo_send_im(PurpleConnection *gc, const char *who, const char *what, Purpl
gchar *carrier = NULL;
const char *alias = NULL;
PurpleAccount *account = purple_connection_get_account(gc);
- PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, account);
+ PurpleIMConversation *im = purple_conversations_find_im_with_account(who, account);
carrier = g_hash_table_lookup(yd->sms_carrier, who);
if (!carrier) {
@@ -4394,7 +4390,7 @@ int yahoo_send_im(PurpleConnection *gc, const char *who, const char *what, Purpl
sms_cb_data->who = g_strdup(who);
sms_cb_data->what = g_strdup(what);
- purple_conversation_write(conv, NULL, _("Getting mobile carrier to send the SMS."), PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, _("Getting mobile carrier to send the SMS."), PURPLE_MESSAGE_SYSTEM, time(NULL));
yahoo_get_sms_carrier(gc, sms_cb_data);
@@ -4403,14 +4399,14 @@ int yahoo_send_im(PurpleConnection *gc, const char *who, const char *what, Purpl
return ret;
}
else if( strcmp(carrier,"Unknown") == 0 ) {
- purple_conversation_write(conv, NULL, _("Can't send SMS. Unknown mobile carrier."), PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, _("Can't send SMS. Unknown mobile carrier."), PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(msg);
g_free(msg2);
return -1;
}
- alias = purple_account_get_alias(account);
+ alias = purple_account_get_private_alias(account);
pkt = yahoo_packet_new(YAHOO_SERVICE_SMS_MSG, YAHOO_STATUS_AVAILABLE, yd->session_id);
yahoo_packet_hash(pkt, "sssss",
1, purple_connection_get_display_name(gc),
@@ -4503,7 +4499,7 @@ int yahoo_send_im(PurpleConnection *gc, const char *who, const char *what, Purpl
return ret;
}
-unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state)
+unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleIMTypingState state)
{
YahooData *yd = purple_connection_get_protocol_data(gc);
struct yahoo_p2p_data *p2p_data;
@@ -4521,7 +4517,7 @@ unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypi
/* check to see if p2p link exists, send through it */
if( (p2p_data = g_hash_table_lookup(yd->peers, who)) && !fed) {
yahoo_packet_hash(pkt, "sssssis", 49, "TYPING", 1, purple_connection_get_display_name(gc),
- 14, " ", 13, state == PURPLE_TYPING ? "1" : "0",
+ 14, " ", 13, state == PURPLE_IM_TYPING ? "1" : "0",
5, who, 11, p2p_data->session_id, 1002, "1"); /* To-do: key 15 to be sent in case of p2p */
yahoo_p2p_write_pkt(p2p_data->source, pkt);
yahoo_packet_free(pkt);
@@ -4542,7 +4538,7 @@ unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypi
}
yahoo_packet_hash(pkt, "ssssss", 49, "TYPING", 1, purple_connection_get_display_name(gc),
- 14, " ", 13, state == PURPLE_TYPING ? "1" : "0",
+ 14, " ", 13, state == PURPLE_IM_TYPING ? "1" : "0",
5, fed_who, 1002, "1");
if (fed)
yahoo_packet_hash_int(pkt, 241, fed);
@@ -4706,13 +4702,13 @@ GList *yahoo_status_types(PurpleAccount *account)
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, YAHOO_STATUS_TYPE_AVAILABLE,
NULL, TRUE, TRUE, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
types = g_list_append(types, type);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY, YAHOO_STATUS_TYPE_AWAY,
NULL, TRUE, TRUE, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
types = g_list_append(types, type);
type = purple_status_type_new(PURPLE_STATUS_AWAY, YAHOO_STATUS_TYPE_BRB, _("Be Right Back"), TRUE);
@@ -4721,7 +4717,7 @@ GList *yahoo_status_types(PurpleAccount *account)
type = purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE, YAHOO_STATUS_TYPE_BUSY,
_("Busy"), TRUE, TRUE, FALSE,
"message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ purple_g_value_new(G_TYPE_STRING), NULL);
types = g_list_append(types, type);
type = purple_status_type_new(PURPLE_STATUS_AWAY, YAHOO_STATUS_TYPE_NOTATHOME, _("Not at Home"), TRUE);
@@ -4806,7 +4802,7 @@ void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g, c
return;
fed_bname = bname = purple_buddy_get_name(buddy);
- if (!purple_privacy_check(purple_connection_get_account(gc), bname))
+ if (!purple_account_privacy_check(purple_connection_get_account(gc), bname))
return;
fed = yahoo_get_federation_from_name(bname);
@@ -4874,7 +4870,7 @@ void yahoo_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g
fed = f->fed;
gname = purple_group_get_name(group);
- buddies = purple_find_buddies(purple_connection_get_account(gc), bname);
+ buddies = purple_blist_find_buddies(purple_connection_get_account(gc), bname);
for (l = buddies; l; l = l->next) {
g = purple_buddy_get_group(l->data);
if (purple_utf8_strcasecmp(gname, purple_group_get_name(g))) {
@@ -4966,16 +4962,16 @@ void yahoo_set_permit_deny(PurpleConnection *gc)
switch (purple_account_get_privacy_type(account))
{
- case PURPLE_PRIVACY_ALLOW_ALL:
- for (deny = account->deny; deny; deny = deny->next)
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL:
+ for (deny = purple_account_privacy_get_denied(account); deny; deny = deny->next)
yahoo_rem_deny(gc, deny->data);
break;
- case PURPLE_PRIVACY_ALLOW_BUDDYLIST:
- case PURPLE_PRIVACY_ALLOW_USERS:
- case PURPLE_PRIVACY_DENY_USERS:
- case PURPLE_PRIVACY_DENY_ALL:
- for (deny = account->deny; deny; deny = deny->next)
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST:
+ case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS:
+ case PURPLE_ACCOUNT_PRIVACY_DENY_USERS:
+ case PURPLE_ACCOUNT_PRIVACY_DENY_ALL:
+ for (deny = purple_account_privacy_get_denied(account); deny; deny = deny->next)
yahoo_add_deny(gc, deny->data);
break;
}
@@ -5106,16 +5102,16 @@ gboolean yahoo_offline_message(const PurpleBuddy *buddy)
gboolean yahoo_send_attention(PurpleConnection *gc, const char *username, guint type)
{
- PurpleConversation *c;
+ PurpleIMConversation *im;
- c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- username, purple_connection_get_account(gc));
+ im = purple_conversations_find_im_with_account(username,
+ purple_connection_get_account(gc));
- g_return_val_if_fail(c != NULL, FALSE);
+ g_return_val_if_fail(im != NULL, FALSE);
purple_debug_info("yahoo", "Sending <ding> on account %s to buddy %s.\n",
- username, purple_conversation_get_name(c));
- purple_conv_im_send_with_flags(PURPLE_CONV_IM(c), "<ding>", PURPLE_MESSAGE_INVISIBLE);
+ username, purple_conversation_get_name(PURPLE_CONVERSATION(im)));
+ purple_conversation_send_with_flags(PURPLE_CONVERSATION(im), "<ding>", PURPLE_MESSAGE_INVISIBLE);
return TRUE;
}
diff --git a/libpurple/protocols/yahoo/libymsg.h b/libpurple/protocols/yahoo/libymsg.h
index 5f1fc9b17a..ba042b6d55 100644
--- a/libpurple/protocols/yahoo/libymsg.h
+++ b/libpurple/protocols/yahoo/libymsg.h
@@ -25,7 +25,7 @@
#ifndef _LIBYMSG_H_
#define _LIBYMSG_H_
-#include "circbuffer.h"
+#include "circularbuffer.h"
#include "cmds.h"
#include "http.h"
#include "prpl.h"
@@ -189,7 +189,7 @@ typedef struct {
guint inpa;
guchar *rxqueue;
int rxlen;
- PurpleCircBuffer *txbuf;
+ PurpleCircularBuffer *txbuf;
guint txhandler;
GHashTable *friends;
@@ -367,7 +367,7 @@ GList *yahoo_blist_node_menu(PurpleBlistNode *node);
void yahoo_login(PurpleAccount *account);
void yahoo_close(PurpleConnection *gc);
int yahoo_send_im(PurpleConnection *gc, const char *who, const char *what, PurpleMessageFlags flags);
-unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state);
+unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleIMTypingState 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, const char *message);
diff --git a/libpurple/protocols/yahoo/yahoo_aliases.c b/libpurple/protocols/yahoo/yahoo_aliases.c
index 91a91ae476..db9e53db26 100644
--- a/libpurple/protocols/yahoo/yahoo_aliases.c
+++ b/libpurple/protocols/yahoo/yahoo_aliases.c
@@ -26,7 +26,7 @@
#include "account.h"
#include "accountopt.h"
-#include "blist.h"
+#include "buddylist.h"
#include "debug.h"
#include "http.h"
#include "util.h"
@@ -143,7 +143,7 @@ yahoo_fetch_aliases_cb(PurpleHttpConnection *http_conn,
/* Find the local buddy that matches */
f = yahoo_friend_find(gc, yid);
- b = purple_find_buddy(account, yid);
+ b = purple_blist_find_buddy(account, yid);
/* If we don't find a matching buddy, ignore the alias !! */
if (f != NULL && b != NULL) {
diff --git a/libpurple/protocols/yahoo/yahoo_aliases.h b/libpurple/protocols/yahoo/yahoo_aliases.h
index 0eb7fef1b3..ef5cb78f77 100644
--- a/libpurple/protocols/yahoo/yahoo_aliases.h
+++ b/libpurple/protocols/yahoo/yahoo_aliases.h
@@ -26,7 +26,7 @@
#include "account.h"
#include "accountopt.h"
-#include "blist.h"
+#include "buddylist.h"
#include "debug.h"
#include "util.h"
#include "version.h"
diff --git a/libpurple/protocols/yahoo/yahoo_doodle.c b/libpurple/protocols/yahoo/yahoo_doodle.c
index ca64961c28..f1778bb491 100644
--- a/libpurple/protocols/yahoo/yahoo_doodle.c
+++ b/libpurple/protocols/yahoo/yahoo_doodle.c
@@ -28,12 +28,11 @@
#include "account.h"
#include "accountopt.h"
-#include "blist.h"
+#include "buddylist.h"
#include "cipher.h"
#include "cmds.h"
#include "debug.h"
#include "notify.h"
-#include "privacy.h"
#include "prpl.h"
#include "proxy.h"
#include "request.h"
@@ -94,7 +93,7 @@ PurpleCmdRet yahoo_doodle_purple_cmd_start(PurpleConversation *conv, const char
/* Write a local message to this conversation showing that a request for a
* Doodle session has been made
*/
- purple_conv_im_write(PURPLE_CONV_IM(conv), "", _("Sent Doodle request."),
+ purple_conversation_write_message(conv, "", _("Sent Doodle request."),
PURPLE_MESSAGE_NICK | PURPLE_MESSAGE_RECV, time(NULL));
return PURPLE_CMD_RET_OK;
diff --git a/libpurple/protocols/yahoo/yahoo_packet.c b/libpurple/protocols/yahoo/yahoo_packet.c
index 605009a681..0e08b69de6 100644
--- a/libpurple/protocols/yahoo/yahoo_packet.c
+++ b/libpurple/protocols/yahoo/yahoo_packet.c
@@ -287,8 +287,9 @@ yahoo_packet_send_can_write(gpointer data, gint source, PurpleInputCondition con
{
YahooData *yd = data;
int ret, writelen;
+ const gchar *output = NULL;
- writelen = purple_circ_buffer_get_max_read(yd->txbuf);
+ writelen = purple_circular_buffer_get_max_read(yd->txbuf);
if (writelen == 0) {
purple_input_remove(yd->txhandler);
@@ -296,7 +297,9 @@ yahoo_packet_send_can_write(gpointer data, gint source, PurpleInputCondition con
return;
}
- ret = write(yd->fd, yd->txbuf->outptr, writelen);
+ output = purple_circular_buffer_get_output(yd->txbuf);
+
+ ret = write(yd->fd, output, writelen);
if (ret < 0 && errno == EAGAIN)
return;
@@ -307,7 +310,7 @@ yahoo_packet_send_can_write(gpointer data, gint source, PurpleInputCondition con
return;
}
- purple_circ_buffer_mark_read(yd->txbuf, ret);
+ purple_circular_buffer_mark_read(yd->txbuf, ret);
}
@@ -374,7 +377,7 @@ int yahoo_packet_send(struct yahoo_packet *pkt, YahooData *yd)
if (yd->txhandler == 0)
yd->txhandler = purple_input_add(yd->fd, PURPLE_INPUT_WRITE,
yahoo_packet_send_can_write, yd);
- purple_circ_buffer_append(yd->txbuf, data + ret, len - ret);
+ purple_circular_buffer_append(yd->txbuf, data + ret, len - ret);
}
g_free(data);
diff --git a/libpurple/protocols/yahoo/yahoo_picture.c b/libpurple/protocols/yahoo/yahoo_picture.c
index 34ee19aa78..5c0336da41 100644
--- a/libpurple/protocols/yahoo/yahoo_picture.c
+++ b/libpurple/protocols/yahoo/yahoo_picture.c
@@ -25,10 +25,9 @@
#include "account.h"
#include "accountopt.h"
-#include "blist.h"
+#include "buddylist.h"
#include "debug.h"
#include "http.h"
-#include "privacy.h"
#include "prpl.h"
#include "proxy.h"
#include "util.h"
@@ -114,7 +113,7 @@ void yahoo_process_picture(PurpleConnection *gc, struct yahoo_packet *pkt)
if (!who)
return;
- if (!purple_privacy_check(purple_connection_get_account(gc), who)) {
+ if (!purple_account_privacy_check(purple_connection_get_account(gc), who)) {
purple_debug_info("yahoo", "Picture packet from %s dropped.\n", who);
return;
}
@@ -160,7 +159,7 @@ void yahoo_process_picture_checksum(PurpleConnection *gc, struct yahoo_packet *p
}
if (who) {
- PurpleBuddy *b = purple_find_buddy(purple_connection_get_account(gc), who);
+ PurpleBuddy *b = purple_blist_find_buddy(purple_connection_get_account(gc), who);
const char *locksum = NULL;
/* FIXME: Cleanup this strtol() stuff if possible. */
diff --git a/libpurple/protocols/yahoo/yahoo_profile.c b/libpurple/protocols/yahoo/yahoo_profile.c
index cfb30737f3..82dc5e0775 100644
--- a/libpurple/protocols/yahoo/yahoo_profile.c
+++ b/libpurple/protocols/yahoo/yahoo_profile.c
@@ -696,11 +696,11 @@ static void yahoo_extract_user_info_text(PurpleNotifyUserInfo *user_info, YahooG
PurpleBuddy *b;
YahooFriend *f;
- b = purple_find_buddy(purple_connection_get_account(info_data->gc),
+ b = purple_blist_find_buddy(purple_connection_get_account(info_data->gc),
info_data->name);
if (b) {
- const char *balias = purple_buddy_get_local_buddy_alias(b);
+ const char *balias = purple_buddy_get_local_alias(b);
if(balias && balias[0]) {
purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), balias);
}
@@ -1196,7 +1196,7 @@ yahoo_got_photo(PurpleHttpConnection *http_conn, PurpleHttpResponse *response,
"or format that is not supported at this time.");
} else if (profile_state == PROFILE_STATE_NOT_FOUND) {
- PurpleBuddy *b = purple_find_buddy
+ PurpleBuddy *b = purple_blist_find_buddy
(purple_connection_get_account(info_data->gc),
info_data->name);
YahooFriend *f = NULL;
diff --git a/libpurple/protocols/yahoo/yahoochat.c b/libpurple/protocols/yahoo/yahoochat.c
index ee695b357f..be7a80a7db 100644
--- a/libpurple/protocols/yahoo/yahoochat.c
+++ b/libpurple/protocols/yahoo/yahoochat.c
@@ -34,7 +34,6 @@
#include "debug.h"
#include "http.h"
-#include "privacy.h"
#include "prpl.h"
#include "conversation.h"
@@ -78,26 +77,26 @@ static void yahoo_chat_online(PurpleConnection *gc)
}
/* this is slow, and different from the purple_* version in that it (hopefully) won't add a user twice */
-void yahoo_chat_add_users(PurpleConvChat *chat, GList *newusers)
+void yahoo_chat_add_users(PurpleChatConversation *chat, GList *newusers)
{
GList *i;
for (i = newusers; i; i = i->next) {
- if (purple_conv_chat_find_user(chat, i->data))
+ if (purple_chat_conversation_has_user(chat, i->data))
continue;
- purple_conv_chat_add_user(chat, i->data, NULL, PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(chat, i->data, NULL, PURPLE_CHAT_USER_NONE, TRUE);
}
}
-void yahoo_chat_add_user(PurpleConvChat *chat, const char *user, const char *reason)
+void yahoo_chat_add_user(PurpleChatConversation *chat, const char *user, const char *reason)
{
- if (purple_conv_chat_find_user(chat, user))
+ if (purple_chat_conversation_has_user(chat, user))
return;
- purple_conv_chat_add_user(chat, user, reason, PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(chat, user, reason, PURPLE_CHAT_USER_NONE, TRUE);
}
-static PurpleConversation *yahoo_find_conference(PurpleConnection *gc, const char *name)
+static PurpleChatConversation *yahoo_find_conference(PurpleConnection *gc, const char *name)
{
YahooData *yd;
GSList *l;
@@ -105,8 +104,8 @@ static PurpleConversation *yahoo_find_conference(PurpleConnection *gc, const cha
yd = purple_connection_get_protocol_data(gc);
for (l = yd->confs; l; l = l->next) {
- PurpleConversation *c = l->data;
- if (!purple_utf8_strcasecmp(purple_conversation_get_name(c), name))
+ PurpleChatConversation *c = l->data;
+ if (!purple_utf8_strcasecmp(purple_conversation_get_name(PURPLE_CONVERSATION(c)), name))
return c;
}
return NULL;
@@ -182,7 +181,7 @@ void yahoo_process_conference_invite(PurpleConnection *gc, struct yahoo_packet *
return;
}
- if (!purple_privacy_check(account, who) ||
+ if (!purple_account_privacy_check(account, who) ||
(purple_account_get_bool(account, "ignore_invites", FALSE)))
{
purple_debug_info("yahoo",
@@ -209,7 +208,7 @@ void yahoo_process_conference_decline(PurpleConnection *gc, struct yahoo_packet
char *room = NULL;
char *who = NULL;
char *msg = NULL;
- PurpleConversation *c = NULL;
+ PurpleChatConversation *c = NULL;
int utf8 = 0;
for (l = pkt->hash; l; l = l->next) {
@@ -232,7 +231,7 @@ void yahoo_process_conference_decline(PurpleConnection *gc, struct yahoo_packet
break;
}
}
- if (!purple_privacy_check(purple_connection_get_account(gc), who))
+ if (!purple_account_privacy_check(purple_connection_get_account(gc), who))
{
g_free(room);
g_free(msg);
@@ -247,13 +246,14 @@ void yahoo_process_conference_decline(PurpleConnection *gc, struct yahoo_packet
{
msg_tmp = yahoo_string_decode(gc, msg, utf8);
msg = yahoo_codes_to_html(msg_tmp);
- serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)), who, 0, msg, time(NULL));
+ serv_got_chat_in(gc, purple_chat_conversation_get_id(c), who, 0, msg, time(NULL));
g_free(msg_tmp);
g_free(msg);
}
tmp = g_strdup_printf(_("%s has declined to join."), who);
- purple_conversation_write(c, NULL, tmp, PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LINKIFY, time(NULL));
+ purple_conversation_write(PURPLE_CONVERSATION(c), NULL, tmp,
+ PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LINKIFY, time(NULL));
g_free(tmp);
}
@@ -267,7 +267,7 @@ void yahoo_process_conference_logon(PurpleConnection *gc, struct yahoo_packet *p
GSList *l;
char *room = NULL;
char *who = NULL;
- PurpleConversation *c;
+ PurpleChatConversation *c;
for (l = pkt->hash; l; l = l->next) {
struct yahoo_pair *pair = l->data;
@@ -287,8 +287,8 @@ void yahoo_process_conference_logon(PurpleConnection *gc, struct yahoo_packet *p
c = yahoo_find_conference(gc, room);
if (c)
{ /* Prevent duplicate users in the chat */
- if( !purple_conv_chat_find_user(PURPLE_CONV_CHAT(c), who) )
- yahoo_chat_add_user(PURPLE_CONV_CHAT(c), who, NULL);
+ if( !purple_chat_conversation_has_user(c, who) )
+ yahoo_chat_add_user(c, who, NULL);
}
g_free(room);
}
@@ -299,7 +299,7 @@ void yahoo_process_conference_logoff(PurpleConnection *gc, struct yahoo_packet *
GSList *l;
char *room = NULL;
char *who = NULL;
- PurpleConversation *c;
+ PurpleChatConversation *c;
for (l = pkt->hash; l; l = l->next) {
struct yahoo_pair *pair = l->data;
@@ -318,7 +318,7 @@ void yahoo_process_conference_logoff(PurpleConnection *gc, struct yahoo_packet *
if (who && room) {
c = yahoo_find_conference(gc, room);
if (c)
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(c), who, NULL);
+ purple_chat_conversation_remove_user(c, who, NULL);
g_free(room);
}
}
@@ -330,7 +330,7 @@ void yahoo_process_conference_message(PurpleConnection *gc, struct yahoo_packet
char *who = NULL;
char *msg = NULL;
int utf8 = 0;
- PurpleConversation *c;
+ PurpleChatConversation *c;
for (l = pkt->hash; l; l = l->next) {
struct yahoo_pair *pair = l->data;
@@ -363,7 +363,7 @@ void yahoo_process_conference_message(PurpleConnection *gc, struct yahoo_packet
msg2 = yahoo_string_decode(gc, msg, utf8);
msg = yahoo_codes_to_html(msg2);
- serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)), who, 0, msg, time(NULL));
+ serv_got_chat_in(gc, purple_chat_conversation_get_id(c), who, 0, msg, time(NULL));
g_free(msg);
g_free(msg2);
}
@@ -464,7 +464,7 @@ void yahoo_process_chat_join(PurpleConnection *gc, struct yahoo_packet *pkt)
{
PurpleAccount *account = purple_connection_get_account(gc);
YahooData *yd = purple_connection_get_protocol_data(gc);
- PurpleConversation *c = NULL;
+ PurpleChatConversation *c = NULL;
GSList *l;
GList *members = NULL;
GList *roomies = NULL;
@@ -541,63 +541,63 @@ void yahoo_process_chat_join(PurpleConnection *gc, struct yahoo_packet *pkt)
yahoo_chat_leave(gc, room,
purple_connection_get_display_name(gc), FALSE);
- c = purple_find_chat(gc, YAHOO_CHAT_ID);
+ c = purple_conversations_find_chat(gc, YAHOO_CHAT_ID);
- if (room && (!c || purple_conv_chat_has_left(PURPLE_CONV_CHAT(c))) &&
+ if (room && (!c || purple_chat_conversation_has_left(c)) &&
members && (members->next ||
!g_ascii_strcasecmp(members->data, purple_connection_get_display_name(gc)))) {
GList *l;
GList *flags = NULL;
for (l = members; l; l = l->next)
- flags = g_list_prepend(flags, GINT_TO_POINTER(PURPLE_CBFLAGS_NONE));
- if (c && purple_conv_chat_has_left(PURPLE_CONV_CHAT(c))) {
+ flags = g_list_prepend(flags, GINT_TO_POINTER(PURPLE_CHAT_USER_NONE));
+ if (c && purple_chat_conversation_has_left(c)) {
/* this might be a hack, but oh well, it should nicely */
char *tmpmsg;
- purple_conversation_set_name(c, room);
+ purple_conversation_set_name(PURPLE_CONVERSATION(c), room);
c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room);
if (topic) {
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), NULL, topic);
+ purple_chat_conversation_set_topic(c, NULL, topic);
/* Also print the topic to the backlog so that the captcha link is clickable */
- purple_conv_chat_write(PURPLE_CONV_CHAT(c), "", topic, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_conversation_write_message(PURPLE_CONVERSATION(c), "", topic, PURPLE_MESSAGE_SYSTEM, time(NULL));
}
yd->in_chat = 1;
yd->chat_name = g_strdup(room);
- purple_conv_chat_add_users(PURPLE_CONV_CHAT(c), members, NULL, flags, FALSE);
+ purple_chat_conversation_add_users(c, members, NULL, flags, FALSE);
tmpmsg = g_strdup_printf(_("You are now chatting in %s."), room);
- purple_conv_chat_write(PURPLE_CONV_CHAT(c), "", tmpmsg, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_conversation_write_message(PURPLE_CONVERSATION(c), "", tmpmsg, PURPLE_MESSAGE_SYSTEM, time(NULL));
g_free(tmpmsg);
} else {
c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room);
if (topic) {
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), NULL, topic);
+ purple_chat_conversation_set_topic(c, NULL, topic);
/* Also print the topic to the backlog so that the captcha link is clickable */
- purple_conv_chat_write(PURPLE_CONV_CHAT(c), "", topic, PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_conversation_write_message(PURPLE_CONVERSATION(c), "", topic, PURPLE_MESSAGE_SYSTEM, time(NULL));
}
yd->in_chat = 1;
yd->chat_name = g_strdup(room);
- purple_conv_chat_add_users(PURPLE_CONV_CHAT(c), members, NULL, flags, FALSE);
+ purple_chat_conversation_add_users(c, members, NULL, flags, FALSE);
}
g_list_free(flags);
} else if (c) {
if (topic) {
- const char *cur_topic = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(c));
+ const char *cur_topic = purple_chat_conversation_get_topic(c);
if (cur_topic == NULL || strcmp(cur_topic, topic) != 0)
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), NULL, topic);
+ purple_chat_conversation_set_topic(c, NULL, topic);
}
- yahoo_chat_add_users(PURPLE_CONV_CHAT(c), members);
+ yahoo_chat_add_users(c, members);
}
- if (account->deny && c) {
- PurpleConversationUiOps *ops = purple_conversation_get_ui_ops(c);
- for (l = account->deny; l != NULL; l = l->next) {
+ if (purple_account_privacy_get_denied(account) && c) {
+ PurpleConversationUiOps *ops = purple_conversation_get_ui_ops(PURPLE_CONVERSATION(c));
+ for (l = purple_account_privacy_get_denied(account); l != NULL; l = l->next) {
for (roomies = members; roomies; roomies = roomies->next) {
if (!purple_utf8_strcasecmp((char *)l->data, roomies->data)) {
purple_debug_info("yahoo", "Ignoring room member %s in room %s\n" , (char *)roomies->data, room ? room : "");
- purple_conv_chat_ignore(PURPLE_CONV_CHAT(c),roomies->data);
- ops->chat_update_user(c, roomies->data);
+ purple_chat_conversation_ignore(c,roomies->data);
+ ops->chat_update_user(purple_chat_conversation_find_user(c, roomies->data));
}
}
}
@@ -626,9 +626,10 @@ void yahoo_process_chat_exit(PurpleConnection *gc, struct yahoo_packet *pkt)
}
if (who && room) {
- PurpleConversation *c = purple_find_chat(gc, YAHOO_CHAT_ID);
- if (c && !purple_utf8_strcasecmp(purple_conversation_get_name(c), room))
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(c), who, NULL);
+ PurpleChatConversation *c = purple_conversations_find_chat(gc, YAHOO_CHAT_ID);
+ if (c && !purple_utf8_strcasecmp(purple_conversation_get_name(
+ PURPLE_CONVERSATION(c)), room))
+ purple_chat_conversation_remove_user(c, who, NULL);
}
g_free(room);
@@ -638,7 +639,7 @@ void yahoo_process_chat_message(PurpleConnection *gc, struct yahoo_packet *pkt)
{
char *room = NULL, *who = NULL, *msg = NULL, *msg2;
int msgtype = 1, utf8 = 1; /* default to utf8 */
- PurpleConversation *c = NULL;
+ PurpleChatConversation *c = NULL;
GSList *l;
for (l = pkt->hash; l; l = l->next) {
@@ -665,7 +666,7 @@ void yahoo_process_chat_message(PurpleConnection *gc, struct yahoo_packet *pkt)
}
}
- c = purple_find_chat(gc, YAHOO_CHAT_ID);
+ c = purple_conversations_find_chat(gc, YAHOO_CHAT_ID);
if (!who || !c) {
if (room)
g_free(room);
@@ -730,7 +731,7 @@ void yahoo_process_chat_addinvite(PurpleConnection *gc, struct yahoo_packet *pkt
if (room && who) {
GHashTable *components;
- if (!purple_privacy_check(account, who) ||
+ if (!purple_account_privacy_check(account, who) ||
(purple_account_get_bool(account, "ignore_invites", FALSE)))
{
purple_debug_info("yahoo", "Invite to room %s from %s has been dropped.\n", room, who);
@@ -771,7 +772,7 @@ void yahoo_conf_leave(YahooData *yd, const char *room, const char *dn, GList *wh
yahoo_packet_hash_str(pkt, 1, dn);
for (w = who; w; w = w->next) {
- const char *name = purple_conv_chat_cb_get_name(w->data);
+ const char *name = purple_chat_user_get_name(w->data);
yahoo_packet_hash_str(pkt, 3, name);
}
@@ -795,7 +796,7 @@ static int yahoo_conf_send(PurpleConnection *gc, const char *dn, const char *roo
yahoo_packet_hash_str(pkt, 1, dn);
for (who = members; who; who = who->next) {
- const char *name = purple_conv_chat_cb_get_name(who->data);
+ const char *name = purple_chat_user_get_name(who->data);
yahoo_packet_hash_str(pkt, 53, name);
}
yahoo_packet_hash(pkt, "ss", 57, room, 14, msg2);
@@ -809,7 +810,7 @@ static int yahoo_conf_send(PurpleConnection *gc, const char *dn, const char *roo
return 0;
}
-static void yahoo_conf_join(YahooData *yd, PurpleConversation *c, const char *dn, const char *room,
+static void yahoo_conf_join(YahooData *yd, PurpleChatConversation *c, const char *dn, const char *room,
const char *topic, const char *members)
{
struct yahoo_packet *pkt;
@@ -827,7 +828,7 @@ static void yahoo_conf_join(YahooData *yd, PurpleConversation *c, const char *dn
if (!strcmp(memarr[i], "") || !strcmp(memarr[i], dn))
continue;
yahoo_packet_hash_str(pkt, 3, memarr[i]);
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(c), memarr[i], NULL, PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(c, memarr[i], NULL, PURPLE_CHAT_USER_NONE, TRUE);
}
}
yahoo_packet_send_and_free(pkt, yd);
@@ -836,7 +837,7 @@ static void yahoo_conf_join(YahooData *yd, PurpleConversation *c, const char *dn
g_strfreev(memarr);
}
-static void yahoo_conf_invite(PurpleConnection *gc, PurpleConversation *c,
+static void yahoo_conf_invite(PurpleConnection *gc, PurpleChatConversation *c,
const char *dn, const char *buddy, const char *room, const char *msg)
{
YahooData *yd = purple_connection_get_protocol_data(gc);
@@ -847,13 +848,13 @@ static void yahoo_conf_invite(PurpleConnection *gc, PurpleConversation *c,
if (msg)
msg2 = yahoo_string_encode(gc, msg, NULL);
- members = purple_conv_chat_get_users(PURPLE_CONV_CHAT(c));
+ members = purple_chat_conversation_get_users(c);
pkt = yahoo_packet_new(YAHOO_SERVICE_CONFADDINVITE, YAHOO_STATUS_AVAILABLE, yd->session_id);
yahoo_packet_hash(pkt, "sssss", 1, dn, 51, buddy, 57, room, 58, msg?msg2:"", 13, "0");
for(; members; members = members->next) {
- const char *name = purple_conv_chat_cb_get_name(members->data);
+ const char *name = purple_chat_user_get_name(members->data);
if (!strcmp(name, dn))
continue;
yahoo_packet_hash(pkt, "ss", 52, name, 53, name);
@@ -895,7 +896,7 @@ static void yahoo_chat_leave(PurpleConnection *gc, const char *room, const char
yd->chat_name = NULL;
}
- if (purple_find_chat(gc, YAHOO_CHAT_ID) != NULL)
+ if (purple_conversations_find_chat(gc, YAHOO_CHAT_ID) != NULL)
serv_got_chat_left(gc, YAHOO_CHAT_ID);
if (!logout)
@@ -1026,21 +1027,22 @@ void yahoo_chat_goto(PurpleConnection *gc, const char *name)
void yahoo_c_leave(PurpleConnection *gc, int id)
{
YahooData *yd = purple_connection_get_protocol_data(gc);
- PurpleConversation *c;
+ PurpleChatConversation *c;
if (!yd)
return;
- c = purple_find_chat(gc, id);
+ c = purple_conversations_find_chat(gc, id);
if (!c)
return;
if (id != YAHOO_CHAT_ID) {
- yahoo_conf_leave(yd, purple_conversation_get_name(c),
- purple_connection_get_display_name(gc), purple_conv_chat_get_users(PURPLE_CONV_CHAT(c)));
+ yahoo_conf_leave(yd, purple_conversation_get_name(PURPLE_CONVERSATION(c)),
+ purple_connection_get_display_name(gc), purple_chat_conversation_get_users(c));
yd->confs = g_slist_remove(yd->confs, c);
} else {
- yahoo_chat_leave(gc, purple_conversation_get_name(c), purple_connection_get_display_name(gc), TRUE);
+ yahoo_chat_leave(gc, purple_conversation_get_name(PURPLE_CONVERSATION(c)),
+ purple_connection_get_display_name(gc), TRUE);
}
serv_got_chat_left(gc, id);
@@ -1048,7 +1050,7 @@ void yahoo_c_leave(PurpleConnection *gc, int id)
int yahoo_c_send(PurpleConnection *gc, int id, const char *what, PurpleMessageFlags flags)
{
- PurpleConversation *c;
+ PurpleChatConversation *c;
int ret;
YahooData *yd;
@@ -1056,18 +1058,19 @@ int yahoo_c_send(PurpleConnection *gc, int id, const char *what, PurpleMessageFl
if (!yd)
return -1;
- c = purple_find_chat(gc, id);
+ c = purple_conversations_find_chat(gc, id);
if (!c)
return -1;
if (id != YAHOO_CHAT_ID) {
ret = yahoo_conf_send(gc, purple_connection_get_display_name(gc),
- purple_conversation_get_name(c), purple_conv_chat_get_users(PURPLE_CONV_CHAT(c)), what);
+ purple_conversation_get_name(PURPLE_CONVERSATION(c)),
+ purple_chat_conversation_get_users(c), what);
} else {
ret = yahoo_chat_send(gc, purple_connection_get_display_name(gc),
- purple_conversation_get_name(c), what, flags);
+ purple_conversation_get_name(PURPLE_CONVERSATION(c)), what, flags);
if (!ret)
- serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)),
+ serv_got_chat_in(gc, purple_chat_conversation_get_id(c),
purple_connection_get_display_name(gc), flags, what, time(NULL));
}
return ret;
@@ -1108,7 +1111,7 @@ void yahoo_c_join(PurpleConnection *gc, GHashTable *data)
{
YahooData *yd;
char *room, *topic, *type;
- PurpleConversation *c;
+ PurpleChatConversation *c;
yd = purple_connection_get_protocol_data(gc);
if (!yd)
@@ -1128,7 +1131,7 @@ void yahoo_c_join(PurpleConnection *gc, GHashTable *data)
id = yd->conf_id++;
c = serv_got_joined_chat(gc, id, room);
yd->confs = g_slist_prepend(yd->confs, c);
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), purple_connection_get_display_name(gc), topic);
+ purple_chat_conversation_set_topic(c, purple_connection_get_display_name(gc), topic);
yahoo_conf_join(yd, c, purple_connection_get_display_name(gc), room, topic, members);
return;
} else {
@@ -1159,18 +1162,18 @@ void yahoo_c_join(PurpleConnection *gc, GHashTable *data)
void yahoo_c_invite(PurpleConnection *gc, int id, const char *msg, const char *name)
{
- PurpleConversation *c;
+ PurpleChatConversation *c;
- c = purple_find_chat(gc, id);
- if (!c || !purple_conversation_get_name(c))
+ c = purple_conversations_find_chat(gc, id);
+ if (!c || !purple_conversation_get_name(PURPLE_CONVERSATION(c)))
return;
if (id != YAHOO_CHAT_ID) {
yahoo_conf_invite(gc, c, purple_connection_get_display_name(gc), name,
- purple_conversation_get_name(c), msg);
+ purple_conversation_get_name(PURPLE_CONVERSATION(c)), msg);
} else {
yahoo_chat_invite(gc, purple_connection_get_display_name(gc), name,
- purple_conversation_get_name(c), msg);
+ purple_conversation_get_name(PURPLE_CONVERSATION(c)), msg);
}
}
diff --git a/libpurple/protocols/yahoo/yahoochat.h b/libpurple/protocols/yahoo/yahoochat.h
index 061be7760f..09b76e3e7d 100644
--- a/libpurple/protocols/yahoo/yahoochat.h
+++ b/libpurple/protocols/yahoo/yahoochat.h
@@ -60,7 +60,7 @@ void yahoo_roomlist_cancel(PurpleRoomlist *list);
void yahoo_roomlist_expand_category(PurpleRoomlist *list, PurpleRoomlistRoom *category);
/* util */
-void yahoo_chat_add_users(PurpleConvChat *chat, GList *newusers);
-void yahoo_chat_add_user(PurpleConvChat *chat, const char *user, const char *reason);
+void yahoo_chat_add_users(PurpleChatConversation *chat, GList *newusers);
+void yahoo_chat_add_user(PurpleChatConversation *chat, const char *user, const char *reason);
#endif /* _YAHOO_CHAT_H_ */
diff --git a/libpurple/protocols/yahoo/ycht.c b/libpurple/protocols/yahoo/ycht.c
index c6dc7b80cd..70b634be19 100644
--- a/libpurple/protocols/yahoo/ycht.c
+++ b/libpurple/protocols/yahoo/ycht.c
@@ -78,7 +78,7 @@ static void ycht_process_chatjoin(YchtConn *ycht, YchtPkt *pkt)
{
char *room, *topic;
PurpleConnection *gc = ycht->gc;
- PurpleConversation *c = NULL;
+ PurpleChatConversation *c = NULL;
gboolean new_room = FALSE;
char **members;
int i;
@@ -105,19 +105,19 @@ static void ycht_process_chatjoin(YchtConn *ycht, YchtPkt *pkt)
ycht->changing_rooms = FALSE;
c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room);
} else {
- c = purple_find_chat(gc, YAHOO_CHAT_ID);
+ c = purple_conversations_find_chat(gc, YAHOO_CHAT_ID);
}
if (topic)
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), NULL, topic);
+ purple_chat_conversation_set_topic(c, NULL, topic);
for (i = 0; members[i]; i++) {
if (new_room) {
/*if (!strcmp(members[i], purple_connection_get_display_name(ycht->gc)))
continue;*/
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(c), members[i], NULL, PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(c, members[i], NULL, PURPLE_CHAT_USER_NONE, TRUE);
} else {
- yahoo_chat_add_user(PURPLE_CONV_CHAT(c), members[i], NULL);
+ yahoo_chat_add_user(c, members[i], NULL);
}
}
@@ -132,9 +132,9 @@ static void ycht_process_chatpart(YchtConn *ycht, YchtPkt *pkt)
who = g_list_nth_data(pkt->data, 1);
if (who && room) {
- PurpleConversation *c = purple_find_chat(ycht->gc, YAHOO_CHAT_ID);
- if (c && !purple_utf8_strcasecmp(purple_conversation_get_name(c), room))
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(c), who, NULL);
+ PurpleChatConversation *c = purple_conversations_find_chat(ycht->gc, YAHOO_CHAT_ID);
+ if (c && !purple_utf8_strcasecmp(purple_conversation_get_name(PURPLE_CONVERSATION(c)), room))
+ purple_chat_conversation_remove_user(c, who, NULL);
}
}
@@ -142,7 +142,7 @@ static void ycht_process_chatpart(YchtConn *ycht, YchtPkt *pkt)
static void ycht_progress_chatmsg(YchtConn *ycht, YchtPkt *pkt)
{
char *who, *what, *msg;
- PurpleConversation *c;
+ PurpleChatConversation *c;
PurpleConnection *gc = ycht->gc;
who = g_list_nth_data(pkt->data, 1);
@@ -151,7 +151,7 @@ static void ycht_progress_chatmsg(YchtConn *ycht, YchtPkt *pkt)
if (!who || !what)
return;
- c = purple_find_chat(gc, YAHOO_CHAT_ID);
+ c = purple_conversations_find_chat(gc, YAHOO_CHAT_ID);
if (!c)
return;
@@ -267,8 +267,9 @@ static void ycht_packet_send_write_cb(gpointer data, gint source, PurpleInputCon
{
YchtConn *ycht = data;
int ret, writelen;
+ const gchar *output = NULL;
- writelen = purple_circ_buffer_get_max_read(ycht->txbuf);
+ writelen = purple_circular_buffer_get_max_read(ycht->txbuf);
if (writelen == 0) {
purple_input_remove(ycht->tx_handler);
@@ -276,7 +277,9 @@ static void ycht_packet_send_write_cb(gpointer data, gint source, PurpleInputCon
return;
}
- ret = write(ycht->fd, ycht->txbuf->outptr, writelen);
+ output = purple_circular_buffer_get_output(ycht->txbuf);
+
+ ret = write(ycht->fd, output, writelen);
if (ret < 0 && errno == EAGAIN)
return;
@@ -292,7 +295,7 @@ static void ycht_packet_send_write_cb(gpointer data, gint source, PurpleInputCon
return;
}
- purple_circ_buffer_mark_read(ycht->txbuf, ret);
+ purple_circular_buffer_mark_read(ycht->txbuf, ret);
}
@@ -345,7 +348,7 @@ static void ycht_packet_send(YchtConn *ycht, YchtPkt *pkt)
ycht->tx_handler = purple_input_add(ycht->fd,
PURPLE_INPUT_WRITE, ycht_packet_send_write_cb,
ycht);
- purple_circ_buffer_append(ycht->txbuf, buf + written,
+ purple_circular_buffer_append(ycht->txbuf, buf + written,
len - written);
}
@@ -444,7 +447,7 @@ void ycht_connection_close(YchtConn *ycht)
if (ycht->tx_handler)
purple_input_remove(ycht->tx_handler);
- purple_circ_buffer_destroy(ycht->txbuf);
+ g_object_unref(G_OBJECT(ycht->txbuf));
g_free(ycht->rxqueue);
diff --git a/libpurple/protocols/yahoo/ycht.h b/libpurple/protocols/yahoo/ycht.h
index 325745ceeb..0d4fc7efd9 100644
--- a/libpurple/protocols/yahoo/ycht.h
+++ b/libpurple/protocols/yahoo/ycht.h
@@ -73,7 +73,7 @@ typedef struct _YchtConn {
gboolean changing_rooms;
guchar *rxqueue;
guint rxlen;
- PurpleCircBuffer *txbuf;
+ PurpleCircularBuffer *txbuf;
guint tx_handler;
} YchtConn;
diff --git a/libpurple/protocols/zephyr/zephyr.c b/libpurple/protocols/zephyr/zephyr.c
index da304e257f..91e32f7aed 100644
--- a/libpurple/protocols/zephyr/zephyr.c
+++ b/libpurple/protocols/zephyr/zephyr.c
@@ -35,7 +35,6 @@
#include "server.h"
#include "util.h"
#include "cmds.h"
-#include "privacy.h"
#include "version.h"
#include "internal.h"
@@ -777,9 +776,9 @@ static void handle_message(PurpleConnection *gc,ZNotice_t notice)
if (ZParseLocations(&notice, NULL, &nlocs, &user) != ZERR_NONE)
return;
- if ((b = purple_find_buddy(purple_connection_get_account(gc), user)) == NULL) {
+ if ((b = purple_blist_find_buddy(purple_connection_get_account(gc), user)) == NULL) {
char* stripped_user = zephyr_strip_local_realm(zephyr,user);
- b = purple_find_buddy(purple_connection_get_account(gc),stripped_user);
+ b = purple_blist_find_buddy(purple_connection_get_account(gc),stripped_user);
g_free(stripped_user);
}
@@ -794,7 +793,7 @@ static void handle_message(PurpleConnection *gc,ZNotice_t notice)
/* 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);
+ balias = purple_buddy_get_local_alias(b);
if (b && balias)
purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), balias);
@@ -825,8 +824,7 @@ static void handle_message(PurpleConnection *gc,ZNotice_t notice)
} else {
char *buf, *buf2, *buf3;
char *send_inst;
- PurpleConversation *gconv1;
- PurpleConvChat *gcc;
+ PurpleChatConversation *gcc;
char *ptr = (char *) notice.z_message + (strlen(notice.z_message) + 1);
int len;
char *stripped_sender;
@@ -864,7 +862,7 @@ static void handle_message(PurpleConnection *gc,ZNotice_t notice)
flags |= PURPLE_MESSAGE_AUTO_RESP;
if (!g_ascii_strcasecmp(notice.z_opcode,"PING"))
- serv_got_typing(gc,stripped_sender,ZEPHYR_TYPING_RECV_TIMEOUT, PURPLE_TYPING);
+ serv_got_typing(gc,stripped_sender,ZEPHYR_TYPING_RECV_TIMEOUT, PURPLE_IM_TYPING);
else
serv_got_im(gc, stripped_sender, buf3, flags, time(NULL));
@@ -898,20 +896,19 @@ static void handle_message(PurpleConnection *gc,ZNotice_t notice)
}
}
- gconv1 = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
+ gcc = purple_conversations_find_chat_with_account(
zt2->name, purple_connection_get_account(gc));
- gcc = purple_conversation_get_chat_data(gconv1);
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
#endif
- if (!purple_conv_chat_find_user(gcc, stripped_sender)) {
+ if (!purple_chat_conversation_has_user(gcc, stripped_sender)) {
gchar ipaddr[INET_ADDRSTRLEN];
#ifdef HAVE_INET_NTOP
inet_ntop(AF_INET, &notice.z_sender_addr.s_addr, ipaddr, sizeof(ipaddr));
#else
memcpy(ipaddr,inet_ntoa(notice.z_sender_addr),sizeof(ipaddr));
#endif
- purple_conv_chat_add_user(gcc, stripped_sender, ipaddr, PURPLE_CBFLAGS_NONE, TRUE);
+ purple_chat_conversation_add_user(gcc, stripped_sender, ipaddr, PURPLE_CHAT_USER_NONE, TRUE);
}
serv_got_chat_in(gc, zt2->id, send_inst_utf8, 0, buf3, time(NULL));
g_free(send_inst_utf8);
@@ -1158,9 +1155,9 @@ static gint check_notify_tzc(gpointer data)
gchar *locval;
user = tree_child(find_node(newparsetree,"user"),2)->contents;
- if ((b = purple_find_buddy(purple_connection_get_account(gc), user)) == NULL) {
+ if ((b = purple_blist_find_buddy(purple_connection_get_account(gc), user)) == NULL) {
gchar *stripped_user = zephyr_strip_local_realm(zephyr,user);
- b = purple_find_buddy(purple_connection_get_account(gc), stripped_user);
+ b = purple_blist_find_buddy(purple_connection_get_account(gc), stripped_user);
g_free(stripped_user);
}
locations = find_node(newparsetree,"locations");
@@ -1182,7 +1179,7 @@ static gint check_notify_tzc(gpointer data)
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;
+ balias = b ? purple_buddy_get_local_alias(b) : NULL;
if (balias)
purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), balias);
@@ -1272,7 +1269,7 @@ static gint check_loc(gpointer data)
int numlocs;
int one = 1;
- for (buddies = purple_find_buddies(account, NULL); buddies;
+ for (buddies = purple_blist_find_buddies(account, NULL); buddies;
buddies = g_slist_delete_link(buddies, buddies)) {
PurpleBuddy *b = buddies->data;
char *chk;
@@ -1307,7 +1304,7 @@ static gint check_loc(gpointer data)
ald.version = NULL;
}
- for (buddies = purple_find_buddies(account, NULL); buddies;
+ for (buddies = purple_blist_find_buddies(account, NULL); buddies;
buddies = g_slist_delete_link(buddies, buddies)) {
PurpleBuddy *b = buddies->data;
@@ -1514,7 +1511,7 @@ static void process_anyone(PurpleConnection *gc)
PurpleGroup *g;
PurpleBuddy *b;
- if (!(g = purple_find_group(_("Anyone")))) {
+ if (!(g = purple_blist_find_group(_("Anyone")))) {
g = purple_group_new(_("Anyone"));
purple_blist_add_group(g, NULL);
}
@@ -1524,10 +1521,10 @@ static void process_anyone(PurpleConnection *gc)
while (fgets(buff, BUFSIZ, fd)) {
strip_comments(buff);
if (buff[0]) {
- if (!purple_find_buddy(purple_connection_get_account(gc), buff)) {
+ if (!purple_blist_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 (!purple_find_buddy(purple_connection_get_account(gc),stripped_user)) {
+ if (!purple_blist_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);
}
@@ -1574,7 +1571,7 @@ static void zephyr_login(PurpleAccount * account)
#ifdef WIN32
username = purple_account_get_username(account);
#endif
- purple_connection_set_flags(gc, PURPLE_CONNECTION_AUTO_RESP | PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC);
+ purple_connection_set_flags(gc, PURPLE_CONNECTION_FLAG_AUTO_RESP | PURPLE_CONNECTION_FLAG_HTML | PURPLE_CONNECTION_FLAG_NO_BGCOLOR | PURPLE_CONNECTION_FLAG_NO_URLDESC);
zephyr = g_new0(zephyr_account, 1);
purple_connection_set_protocol_data(gc, zephyr);
@@ -1855,7 +1852,7 @@ static void zephyr_login(PurpleAccount * account)
return;
}
- purple_connection_set_state(gc, PURPLE_CONNECTED);
+ purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED);
if (read_anyone)
process_anyone(gc);
@@ -1954,7 +1951,7 @@ static void write_anyone(zephyr_account *zephyr)
}
account = zephyr->account;
- for (buddies = purple_find_buddies(account, NULL); buddies;
+ for (buddies = purple_blist_find_buddies(account, NULL); buddies;
buddies = g_slist_delete_link(buddies, buddies)) {
PurpleBuddy *b = buddies->data;
gchar *stripped_user = zephyr_strip_local_realm(zephyr, purple_buddy_get_name(b));
@@ -2041,8 +2038,7 @@ static int zephyr_chat_send(PurpleConnection * gc, int id, const char *im, Purpl
{
zephyr_triple *zt;
const char *sig;
- PurpleConversation *gconv1;
- PurpleConvChat *gcc;
+ PurpleChatConversation *gcc;
char *inst;
char *recipient;
zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
@@ -2054,11 +2050,10 @@ 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,
+ gcc = purple_conversations_find_chat_with_account(zt->name,
purple_connection_get_account(gc));
- gcc = purple_conversation_get_chat_data(gconv1);
- if (!(inst = (char *)purple_conv_chat_get_topic(gcc)))
+ if (!(inst = (char *)purple_chat_conversation_get_topic(gcc)))
inst = g_strdup("PERSONAL");
if (!g_ascii_strcasecmp(zt->recipient, "*"))
@@ -2290,7 +2285,7 @@ static void zephyr_set_status(PurpleAccount *account, PurpleStatus *status) {
size_t result;
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));
+ PurpleStatusPrimitive primitive = purple_status_type_get_primitive(purple_status_get_status_type(status));
if (zephyr->away) {
g_free(zephyr->away);
@@ -2357,7 +2352,7 @@ static GList *zephyr_status_types(PurpleAccount *account)
type = purple_status_type_new_with_attrs(
PURPLE_STATUS_AWAY, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ "message", _("Message"), purple_g_value_new(G_TYPE_STRING),
NULL);
types = g_list_append(types, type);
@@ -2509,7 +2504,7 @@ static PurpleChat *zephyr_find_blist_chat(PurpleAccount *account, const char *na
char *zclass, *inst, *recip;
char** triple;
GHashTable *components;
- if(!PURPLE_BLIST_NODE_IS_CHAT(cnode))
+ if(!PURPLE_IS_CHAT(cnode))
continue;
if(purple_chat_get_account(chat) != account)
continue;
@@ -2534,13 +2529,13 @@ static const char *zephyr_list_icon(PurpleAccount * a, PurpleBuddy * b)
return "zephyr";
}
-static unsigned int zephyr_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state) {
+static unsigned int zephyr_send_typing(PurpleConnection *gc, const char *who, PurpleIMTypingState state) {
gchar *recipient;
zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
if (use_tzc(zephyr))
return 0;
- if (state == PURPLE_NOT_TYPING)
+ if (state == PURPLE_IM_NOT_TYPING)
return 0;
/* XXX We probably should care if this fails. Or maybe we don't want to */
@@ -2564,7 +2559,7 @@ static unsigned int zephyr_send_typing(PurpleConnection *gc, const char *who, Pu
/*
* TODO: Is this correct? It means we will call
- * serv_send_typing(gc, who, PURPLE_TYPING) once every 15 seconds
+ * serv_send_typing(gc, who, PURPLE_IM_TYPING) once every 15 seconds
* until the Purple user stops typing.
*/
return ZEPHYR_TYPING_SEND_TIMEOUT;
@@ -2575,8 +2570,7 @@ static unsigned int zephyr_send_typing(PurpleConnection *gc, const char *who, Pu
static void zephyr_chat_set_topic(PurpleConnection * gc, int id, const char *topic)
{
zephyr_triple *zt;
- PurpleConversation *gconv;
- PurpleConvChat *gcc;
+ PurpleChatConversation *gcc;
gchar *topic_utf8;
zephyr_account* zephyr = purple_connection_get_protocol_data(gc);
char *sender = (char *)zephyr->username;
@@ -2585,12 +2579,11 @@ static void zephyr_chat_set_topic(PurpleConnection * gc, int id, const char *top
/* find_sub_by_id can return NULL */
if (!zt)
return;
- gconv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, zt->name,
+ gcc = purple_conversations_find_chat_with_account(zt->name,
purple_connection_get_account(gc));
- gcc = purple_conversation_get_chat_data(gconv);
topic_utf8 = zephyr_recv_convert(gc,(gchar *)topic);
- purple_conv_chat_set_topic(gcc,sender,topic_utf8);
+ purple_chat_conversation_set_topic(gcc,sender,topic_utf8);
g_free(topic_utf8);
return;
}
@@ -2636,9 +2629,9 @@ static PurpleCmdRet zephyr_purple_cmd_instance(PurpleConversation *conv,
* all. This might not be the best thing to do, though having
* one word isn't ideal either. */
- PurpleConvChat *gcc = purple_conversation_get_chat_data(conv);
const char* instance = args[0];
- zephyr_chat_set_topic(purple_conversation_get_connection(conv),purple_conv_chat_get_id(gcc),instance);
+ zephyr_chat_set_topic(purple_conversation_get_connection(conv),
+ purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv)),instance);
return PURPLE_CMD_RET_OK;
}
diff --git a/libpurple/proxy.c b/libpurple/proxy.c
index 1d9a7aa2a6..c7250d6360 100644
--- a/libpurple/proxy.c
+++ b/libpurple/proxy.c
@@ -32,7 +32,7 @@
#define _PURPLE_PROXY_C_
#include "internal.h"
-#include "cipher.h"
+#include "ciphers/md5hash.h"
#include "debug.h"
#include "dnsquery.h"
#include "http.h"
@@ -1678,23 +1678,21 @@ s5_readauth(gpointer data, gint source, PurpleInputCondition cond)
static void
hmacmd5_chap(const unsigned char * challenge, int challen, const char * passwd, unsigned char * response)
{
- PurpleCipher *cipher;
- PurpleCipherContext *ctx;
+ PurpleHash *hash;
int i;
unsigned char Kxoripad[65];
unsigned char Kxoropad[65];
size_t pwlen;
- cipher = purple_ciphers_find_cipher("md5");
- ctx = purple_cipher_context_new(cipher, NULL);
+ hash = purple_md5_hash_new();
memset(Kxoripad,0,sizeof(Kxoripad));
memset(Kxoropad,0,sizeof(Kxoropad));
pwlen=strlen(passwd);
if (pwlen>64) {
- purple_cipher_context_append(ctx, (const guchar *)passwd, strlen(passwd));
- purple_cipher_context_digest(ctx, Kxoripad, sizeof(Kxoripad));
+ purple_hash_append(hash, (const guchar *)passwd, strlen(passwd));
+ purple_hash_digest(hash, Kxoripad, sizeof(Kxoripad));
pwlen=16;
} else {
memcpy(Kxoripad, passwd, pwlen);
@@ -1706,17 +1704,17 @@ hmacmd5_chap(const unsigned char * challenge, int challen, const char * passwd,
Kxoropad[i]^=0x5c;
}
- purple_cipher_context_reset(ctx, NULL);
- purple_cipher_context_append(ctx, Kxoripad, 64);
- purple_cipher_context_append(ctx, challenge, challen);
- purple_cipher_context_digest(ctx, Kxoripad, sizeof(Kxoripad));
+ purple_hash_reset(hash);
+ purple_hash_append(hash, Kxoripad, 64);
+ purple_hash_append(hash, challenge, challen);
+ purple_hash_digest(hash, Kxoripad, sizeof(Kxoripad));
- purple_cipher_context_reset(ctx, NULL);
- purple_cipher_context_append(ctx, Kxoropad, 64);
- purple_cipher_context_append(ctx, Kxoripad, 16);
- purple_cipher_context_digest(ctx, response, 16);
+ purple_hash_reset(hash);
+ purple_hash_append(hash, Kxoropad, 64);
+ purple_hash_append(hash, Kxoripad, 16);
+ purple_hash_digest(hash, response, 16);
- purple_cipher_context_destroy(ctx);
+ g_object_unref(hash);
}
static void
diff --git a/libpurple/prpl.c b/libpurple/prpl.c
index 09edc76682..42de14ae85 100644
--- a/libpurple/prpl.c
+++ b/libpurple/prpl.c
@@ -214,7 +214,7 @@ purple_prpl_got_user_idle(PurpleAccount *account, const char *name,
g_return_if_fail(name != NULL);
g_return_if_fail(purple_account_is_connected(account) || purple_account_is_connecting(account));
- if ((list = purple_find_buddies(account, name)) == NULL)
+ if ((list = purple_blist_find_buddies(account, name)) == NULL)
return;
while (list) {
@@ -234,7 +234,7 @@ purple_prpl_got_user_login_time(PurpleAccount *account, const char *name,
g_return_if_fail(account != NULL);
g_return_if_fail(name != NULL);
- if ((list = purple_find_buddies(account, name)) == NULL)
+ if ((list = purple_blist_find_buddies(account, name)) == NULL)
return;
if (login_time == 0)
@@ -270,7 +270,7 @@ purple_prpl_got_user_status(PurpleAccount *account, const char *name,
g_return_if_fail(status_id != NULL);
g_return_if_fail(purple_account_is_connected(account) || purple_account_is_connecting(account));
- if((list = purple_find_buddies(account, name)) == NULL)
+ if((list = purple_blist_find_buddies(account, name)) == NULL)
return;
for(l = list; l != NULL; l = l->next) {
@@ -292,7 +292,7 @@ purple_prpl_got_user_status(PurpleAccount *account, const char *name,
purple_status_set_active_with_attrs(status, TRUE, args);
va_end(args);
- purple_blist_update_buddy_status(buddy, old_status);
+ purple_buddy_update_status(buddy, old_status);
}
g_slist_free(list);
@@ -318,7 +318,7 @@ void purple_prpl_got_user_status_deactive(PurpleAccount *account, const char *na
g_return_if_fail(status_id != NULL);
g_return_if_fail(purple_account_is_connected(account) || purple_account_is_connecting(account));
- if((list = purple_find_buddies(account, name)) == NULL)
+ if((list = purple_blist_find_buddies(account, name)) == NULL)
return;
for(l = list; l != NULL; l = l->next) {
@@ -332,7 +332,7 @@ void purple_prpl_got_user_status_deactive(PurpleAccount *account, const char *na
if (purple_status_is_active(status)) {
purple_status_set_active(status, FALSE);
- purple_blist_update_buddy_status(buddy, status);
+ purple_buddy_update_status(buddy, status);
}
}
@@ -437,7 +437,7 @@ purple_prpl_send_attention(PurpleConnection *gc, const char *who, guint type_cod
PurpleAttentionType *attn;
PurpleMessageFlags flags;
PurplePlugin *prpl;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
gboolean (*send_attention)(PurpleConnection *, const char *, guint);
PurpleBuddy *buddy;
const char *alias;
@@ -455,7 +455,7 @@ purple_prpl_send_attention(PurpleConnection *gc, const char *who, guint type_cod
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)
+ if ((buddy = purple_blist_find_buddy(purple_connection_get_account(gc), who)) != NULL)
alias = purple_buddy_get_contact_alias(buddy);
else
alias = who;
@@ -474,9 +474,9 @@ 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, 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));
+ im = purple_im_conversation_new(purple_connection_get_account(gc), who);
+ purple_conversation_write_message(PURPLE_CONVERSATION(im), NULL, description, flags, mtime);
+ purple_prpl_attention(PURPLE_CONVERSATION(im), who, type_code, PURPLE_MESSAGE_SEND, time(NULL));
g_free(description);
}
@@ -501,7 +501,7 @@ got_attention(PurpleConnection *gc, int id, const char *who, guint type_code)
/* TODO: if (attn->icon_name) is non-null, use it to lookup an emoticon and display
* it next to the attention command. And if it is null, display a generic icon. */
- if ((buddy = purple_find_buddy(purple_connection_get_account(gc), who)) != NULL)
+ if ((buddy = purple_blist_find_buddy(purple_connection_get_account(gc), who)) != NULL)
alias = purple_buddy_get_contact_alias(buddy);
else
alias = who;
@@ -533,7 +533,7 @@ purple_prpl_got_attention(PurpleConnection *gc, const char *who, guint type_code
got_attention(gc, -1, who, type_code);
conv =
- purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, who, account);
+ purple_conversations_find_with_account(who, account);
if (conv)
purple_prpl_attention(conv, who, type_code, PURPLE_MESSAGE_RECV,
time(NULL));
@@ -602,7 +602,7 @@ purple_prpl_got_media_caps(PurpleAccount *account, const char *name)
g_return_if_fail(account != NULL);
g_return_if_fail(name != NULL);
- if ((list = purple_find_buddies(account, name)) == NULL)
+ if ((list = purple_blist_find_buddies(account, name)) == NULL)
return;
while (list) {
diff --git a/libpurple/prpl.h b/libpurple/prpl.h
index 683d9a335c..44fa9e13f1 100644
--- a/libpurple/prpl.h
+++ b/libpurple/prpl.h
@@ -71,8 +71,8 @@ typedef struct _PurpleThumbnailSpec PurpleThumbnailSpec;
#include <unistd.h>
#endif
-#include "blist.h"
-#include "conversation.h"
+#include "buddylist.h"
+#include "conversations.h"
#include "ft.h"
#include "imgstore.h"
#include "media.h"
@@ -332,13 +332,13 @@ struct _PurplePluginProtocolInfo
void (*set_info)(PurpleConnection *, const char *info);
/**
- * @return If this protocol requires the PURPLE_TYPING message to
+ * @return If this protocol requires the PURPLE_IM_TYPING message to
* be sent repeatedly to signify that the user is still
* typing, then the PRPL should return the number of
* seconds to wait before sending a subsequent notification.
* Otherwise the PRPL should return 0.
*/
- unsigned int (*send_typing)(PurpleConnection *, const char *name, PurpleTypingState state);
+ unsigned int (*send_typing)(PurpleConnection *, const char *name, PurpleIMTypingState state);
/**
* Should arrange for purple_notify_userinfo() to be called with
diff --git a/libpurple/purple-client.h b/libpurple/purple-client.h
index 87378d35ce..5746dbe841 100644
--- a/libpurple/purple-client.h
+++ b/libpurple/purple-client.h
@@ -2,6 +2,7 @@
#define _PURPLE_CLIENT_H_INCLUDED_
#include <glib.h>
+#include <glib-object.h>
#include "purple-client-bindings.h"
G_BEGIN_DECLS
diff --git a/libpurple/purple.h.in b/libpurple/purple.h.in
index 327bea0f9c..22114942d0 100644
--- a/libpurple/purple.h.in
+++ b/libpurple/purple.h.in
@@ -44,16 +44,16 @@
@PLUGINS_DEFINE@
-#include <account.h>
+#include <accounts.h>
#include <accountopt.h>
-#include <blist.h>
+#include <buddylist.h>
#include <buddyicon.h>
#include <certificate.h>
#include <cipher.h>
-#include <circbuffer.h>
+#include <circularbuffer.h>
#include <cmds.h>
#include <connection.h>
-#include <conversation.h>
+#include <conversations.h>
#include <core.h>
#include <debug.h>
#include <desktopitem.h>
@@ -75,7 +75,7 @@
#include <pluginpref.h>
#include <pounce.h>
#include <prefs.h>
-#include <privacy.h>
+#include <presence.h>
#include <proxy.h>
#include <prpl.h>
#include <request.h>
@@ -96,7 +96,6 @@
#include <theme-manager.h>
#include <upnp.h>
#include <util.h>
-#include <value.h>
#include <version.h>
#include <whiteboard.h>
#include <xmlnode.h>
diff --git a/libpurple/savedstatuses.c b/libpurple/savedstatuses.c
index eaee07ee68..924a88cdba 100644
--- a/libpurple/savedstatuses.c
+++ b/libpurple/savedstatuses.c
@@ -1172,6 +1172,33 @@ purple_savedstatus_activate_for_account(const PurpleSavedStatus *saved_status,
}
}
+static PurpleSavedStatus *
+purple_savedstatus_copy(PurpleSavedStatus *savedstatus)
+{
+ PurpleSavedStatus *savedstatus_copy;
+
+ g_return_val_if_fail(savedstatus != NULL, NULL);
+
+ savedstatus_copy = g_new(PurpleSavedStatus, 1);
+ *savedstatus_copy = *savedstatus;
+
+ return savedstatus_copy;
+}
+
+GType
+purple_savedstatus_get_g_type(void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_boxed_type_register_static("PurpleSavedStatus",
+ (GBoxedCopyFunc)purple_savedstatus_copy,
+ (GBoxedFreeFunc)g_free);
+ }
+
+ return type;
+}
+
void *
purple_savedstatuses_get_handle(void)
{
@@ -1204,26 +1231,20 @@ purple_savedstatuses_init(void)
load_statuses();
purple_signal_register(handle, "savedstatus-changed",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_SAVEDSTATUS),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_SAVEDSTATUS));
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ PURPLE_TYPE_SAVEDSTATUS, PURPLE_TYPE_SAVEDSTATUS);
purple_signal_register(handle, "savedstatus-added",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_SAVEDSTATUS));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_SAVEDSTATUS);
purple_signal_register(handle, "savedstatus-deleted",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_SAVEDSTATUS));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_SAVEDSTATUS);
purple_signal_register(handle, "savedstatus-modified",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_SAVEDSTATUS));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_SAVEDSTATUS);
purple_signal_connect(purple_accounts_get_handle(), "account-removed",
handle,
diff --git a/libpurple/savedstatuses.h b/libpurple/savedstatuses.h
index 53be07cd55..0e2686588a 100644
--- a/libpurple/savedstatuses.h
+++ b/libpurple/savedstatuses.h
@@ -54,6 +54,7 @@
* something we should look into once the status box gets fleshed
* out more.
*/
+#define PURPLE_TYPE_SAVEDSTATUS (purple_savedstatus_get_g_type())
typedef struct _PurpleSavedStatus PurpleSavedStatus;
typedef struct _PurpleSavedStatusSub PurpleSavedStatusSub;
@@ -68,6 +69,13 @@ G_BEGIN_DECLS
/*@{*/
/**
+ * Returns the GType for the PurpleSavedStatus boxed structure.
+ * TODO Boxing of PurpleSavedStatus is a temporary solution to having a GType
+ * for saved statuses. This should rather be a GObject instead of a GBoxed.
+ */
+GType purple_savedstatus_get_g_type(void);
+
+/**
* Create a new saved status. This will add the saved status to the
* list of saved statuses and writes the revised list to status.xml.
*
diff --git a/libpurple/server.c b/libpurple/server.c
index ded5f084ae..96130529a3 100644
--- a/libpurple/server.c
+++ b/libpurple/server.c
@@ -24,13 +24,12 @@
/* This file is the fullcrap */
#include "internal.h"
-#include "blist.h"
+#include "buddylist.h"
#include "conversation.h"
#include "debug.h"
#include "log.h"
#include "notify.h"
#include "prefs.h"
-#include "privacy.h"
#include "prpl.h"
#include "request.h"
#include "signals.h"
@@ -42,7 +41,7 @@
#define SEX_BEFORE_RESENDING_AUTORESPONSE "Only after you're married"
unsigned int
-serv_send_typing(PurpleConnection *gc, const char *name, PurpleTypingState state)
+serv_send_typing(PurpleConnection *gc, const char *name, PurpleIMTypingState state)
{
PurplePlugin *prpl;
PurplePluginProtocolInfo *prpl_info;
@@ -120,7 +119,7 @@ get_last_auto_response(PurpleConnection *gc, const char *name)
int serv_send_im(PurpleConnection *gc, const char *name, const char *message,
PurpleMessageFlags flags)
{
- PurpleConversation *conv = NULL;
+ PurpleIMConversation *im = NULL;
PurpleAccount *account = NULL;
PurplePresence *presence = NULL;
PurplePlugin *prpl = NULL;
@@ -139,7 +138,7 @@ int serv_send_im(PurpleConnection *gc, const char *name, const char *message,
account = purple_connection_get_account(gc);
presence = purple_account_get_presence(account);
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, name, account);
+ im = purple_conversations_find_im_with_account(name, account);
if (prpl_info->send_im)
val = prpl_info->send_im(gc, name, message, flags);
@@ -149,7 +148,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((purple_connection_get_flags(gc) & PURPLE_CONNECTION_AUTO_RESP) &&
+ if((purple_connection_get_flags(gc) & PURPLE_CONNECTION_FLAG_AUTO_RESP) &&
!purple_presence_is_available(presence) &&
!purple_strequal(auto_reply_pref, "never")) {
@@ -158,8 +157,8 @@ int serv_send_im(PurpleConnection *gc, const char *name, const char *message,
lar->sent = time(NULL);
}
- if(conv && purple_conv_im_get_send_typed_timeout(PURPLE_CONV_IM(conv)))
- purple_conv_im_stop_send_typed_timeout(PURPLE_CONV_IM(conv));
+ if(im && purple_im_conversation_get_send_typed_timeout(im))
+ purple_im_conversation_stop_send_typed_timeout(im);
return val;
}
@@ -226,7 +225,7 @@ void serv_alias_buddy(PurpleBuddy *b)
if (prpl_info->alias_buddy)
prpl_info->alias_buddy(gc,
purple_buddy_get_name(b),
- purple_buddy_get_local_buddy_alias(b));
+ purple_buddy_get_local_alias(b));
}
}
}
@@ -238,10 +237,10 @@ serv_got_alias(PurpleConnection *gc, const char *who, const char *alias)
PurpleAccount *account;
GSList *buddies;
PurpleBuddy *b;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
account = purple_connection_get_account(gc);
- buddies = purple_find_buddies(account, who);
+ buddies = purple_blist_find_buddies(account, who);
while (buddies != NULL)
{
@@ -255,17 +254,17 @@ serv_got_alias(PurpleConnection *gc, const char *who, const char *alias)
if (purple_strequal(server_alias, alias))
continue;
- purple_blist_server_alias_buddy(b, alias);
+ purple_buddy_set_server_alias(b, alias);
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(b), account);
- if (conv != NULL && alias != NULL && !purple_strequal(alias, who))
+ im = purple_conversations_find_im_with_account(purple_buddy_get_name(b), account);
+ if (im != NULL && alias != NULL && !purple_strequal(alias, who))
{
char *escaped = g_markup_escape_text(who, -1);
char *escaped2 = g_markup_escape_text(alias, -1);
char *tmp = g_strdup_printf(_("%s is now known as %s.\n"),
escaped, escaped2);
- purple_conversation_write(conv, NULL, tmp,
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, tmp,
PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LINKIFY,
time(NULL));
@@ -284,7 +283,7 @@ purple_serv_got_private_alias(PurpleConnection *gc, const char *who, const char
PurpleBuddy *b = NULL;
account = purple_connection_get_account(gc);
- buddies = purple_find_buddies(account, who);
+ buddies = purple_blist_find_buddies(account, who);
while(buddies != NULL) {
const char *balias;
@@ -292,11 +291,11 @@ purple_serv_got_private_alias(PurpleConnection *gc, const char *who, const char
buddies = g_slist_delete_link(buddies, buddies);
- balias = purple_buddy_get_local_buddy_alias(b);
+ balias = purple_buddy_get_local_alias(b);
if (purple_strequal(balias, alias))
continue;
- purple_blist_alias_buddy(b, alias);
+ purple_buddy_set_local_alias(b, alias);
}
}
@@ -467,12 +466,12 @@ void serv_chat_invite(PurpleConnection *gc, int id, const char *message, const c
{
PurplePlugin *prpl = NULL;
PurplePluginProtocolInfo *prpl_info = NULL;
- PurpleConversation *conv;
+ PurpleChatConversation *chat;
char *buffy = message && *message ? g_strdup(message) : NULL;
- conv = purple_find_chat(gc, id);
+ chat = purple_conversations_find_chat(gc, id);
- if(conv == NULL)
+ if(chat == NULL)
return;
if(gc)
@@ -482,18 +481,18 @@ void serv_chat_invite(PurpleConnection *gc, int id, const char *message, const c
prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
purple_signal_emit(purple_conversations_get_handle(), "chat-inviting-user",
- conv, name, &buffy);
+ chat, name, &buffy);
if (prpl_info && prpl_info->chat_invite)
prpl_info->chat_invite(gc, id, buffy, name);
purple_signal_emit(purple_conversations_get_handle(), "chat-invited-user",
- conv, name, buffy);
+ chat, name, buffy);
g_free(buffy);
}
-/* Ya know, nothing uses this except purple_conversation_destroy(),
+/* Ya know, nothing uses this except purple_chat_conversation_dispose(),
* I think I'll just merge it into that later...
* Then again, something might want to use this, from outside prpl-land
* to leave a chat without destroying the conversation.
@@ -546,7 +545,7 @@ void serv_got_im(PurpleConnection *gc, const char *who, const char *msg,
PurpleMessageFlags flags, time_t mtime)
{
PurpleAccount *account;
- PurpleConversation *conv;
+ PurpleIMConversation *im;
char *message, *name;
char *angel, *buffy;
int plugin_return;
@@ -560,7 +559,7 @@ void serv_got_im(PurpleConnection *gc, const char *who, const char *msg,
*/
flags |= PURPLE_MESSAGE_RECV;
- if (!purple_privacy_check(account, who)) {
+ if (!purple_account_privacy_check(account, who)) {
purple_signal_emit(purple_conversations_get_handle(), "blocked-im-msg",
account, who, msg, flags, (unsigned int)mtime);
return;
@@ -570,7 +569,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, purple_connection_get_account(gc));
+ im = purple_conversations_find_im_with_account(who, purple_connection_get_account(gc));
/*
* Make copies of the message and the sender in case plugins want
@@ -582,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", purple_connection_get_account(gc),
- &angel, &buffy, conv, &flags));
+ &angel, &buffy, im, &flags));
if (!buffy || !angel || plugin_return) {
g_free(buffy);
@@ -594,16 +593,16 @@ void serv_got_im(PurpleConnection *gc, const char *who, const char *msg,
message = buffy;
purple_signal_emit(purple_conversations_get_handle(), "received-im-msg", purple_connection_get_account(gc),
- name, message, conv, flags);
+ name, message, im, 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, purple_connection_get_account(gc));
+ if (im == NULL)
+ im = purple_conversations_find_im_with_account(name, purple_connection_get_account(gc));
- if (conv == NULL)
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, name);
+ if (im == NULL)
+ im = purple_im_conversation_new(account, name);
- purple_conv_im_write(PURPLE_CONV_IM(conv), name, message, flags, mtime);
+ purple_conversation_write_message(PURPLE_CONVERSATION(im), name, message, flags, mtime);
g_free(message);
/*
@@ -615,7 +614,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 (purple_connection_get_flags(gc) & PURPLE_CONNECTION_AUTO_RESP)
+ if (purple_connection_get_flags(gc) & PURPLE_CONNECTION_FLAG_AUTO_RESP)
{
PurplePresence *presence;
PurpleStatus *status;
@@ -629,7 +628,7 @@ void serv_got_im(PurpleConnection *gc, const char *who, const char *msg,
presence = purple_account_get_presence(account);
status = purple_presence_get_active_status(presence);
- status_type = purple_status_get_type(status);
+ status_type = purple_status_get_status_type(status);
primitive = purple_status_type_get_primitive(status_type);
mobile = purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_MOBILE);
if ((primitive == PURPLE_STATUS_AVAILABLE) ||
@@ -642,7 +641,7 @@ void serv_got_im(PurpleConnection *gc, const char *who, const char *msg,
return;
}
- away_msg = purple_value_get_string(
+ away_msg = g_value_get_string(
purple_status_get_attr_value(status, "message"));
if ((away_msg != NULL) && (*away_msg != '\0')) {
@@ -672,7 +671,7 @@ void serv_got_im(PurpleConnection *gc, const char *who, const char *msg,
{
serv_send_im(gc, name, away_msg, PURPLE_MESSAGE_AUTO_RESP);
- purple_conv_im_write(PURPLE_CONV_IM(conv), NULL, away_msg,
+ purple_conversation_write_message(PURPLE_CONVERSATION(im), NULL, away_msg,
PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_AUTO_RESP,
mtime);
}
@@ -684,52 +683,46 @@ void serv_got_im(PurpleConnection *gc, const char *who, const char *msg,
}
void serv_got_typing(PurpleConnection *gc, const char *name, int timeout,
- PurpleTypingState state) {
- PurpleConversation *conv;
- PurpleConvIm *im = NULL;
+ PurpleIMTypingState state) {
+ PurpleIMConversation *im;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, name, purple_connection_get_account(gc));
- if (conv != NULL) {
- im = PURPLE_CONV_IM(conv);
-
- purple_conv_im_set_typing_state(im, state);
+ im = purple_conversations_find_im_with_account(name, purple_connection_get_account(gc));
+ if (im != NULL) {
+ purple_im_conversation_set_typing_state(im, state);
} else {
switch (state)
{
- case PURPLE_TYPING:
+ case PURPLE_IM_TYPING:
purple_signal_emit(purple_conversations_get_handle(),
"buddy-typing", purple_connection_get_account(gc), name);
break;
- case PURPLE_TYPED:
+ case PURPLE_IM_TYPED:
purple_signal_emit(purple_conversations_get_handle(),
"buddy-typed", purple_connection_get_account(gc), name);
break;
- case PURPLE_NOT_TYPING:
+ case PURPLE_IM_NOT_TYPING:
purple_signal_emit(purple_conversations_get_handle(),
"buddy-typing-stopped", purple_connection_get_account(gc), name);
break;
}
}
- if (conv != NULL && timeout > 0)
- purple_conv_im_start_typing_timeout(im, timeout);
+ if (im != NULL && timeout > 0)
+ purple_im_conversation_start_typing_timeout(im, timeout);
}
void serv_got_typing_stopped(PurpleConnection *gc, const char *name) {
- PurpleConversation *conv;
- PurpleConvIm *im;
+ PurpleIMConversation *im;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, name, purple_connection_get_account(gc));
- if (conv != NULL)
+ im = purple_conversations_find_im_with_account(name, purple_connection_get_account(gc));
+ if (im != NULL)
{
- im = PURPLE_CONV_IM(conv);
-
- if (purple_conv_im_get_typing_state(im) == PURPLE_NOT_TYPING)
+ if (purple_im_conversation_get_typing_state(im) == PURPLE_IM_NOT_TYPING)
return;
- purple_conv_im_stop_typing_timeout(im);
- purple_conv_im_set_typing_state(im, PURPLE_NOT_TYPING);
+ purple_im_conversation_stop_typing_timeout(im);
+ purple_im_conversation_set_typing_state(im, PURPLE_IM_NOT_TYPING);
}
else
{
@@ -778,7 +771,7 @@ void serv_got_chat_invite(PurpleConnection *gc, const char *name,
g_return_if_fail(who != NULL);
account = purple_connection_get_account(gc);
- if (!purple_privacy_check(account, who)) {
+ if (!purple_account_privacy_check(account, who)) {
purple_signal_emit(purple_conversations_get_handle(), "chat-invite-blocked",
account, who, name, message, data);
return;
@@ -818,11 +811,10 @@ void serv_got_chat_invite(PurpleConnection *gc, const char *name,
chat_invite_reject(cid);
}
-PurpleConversation *serv_got_joined_chat(PurpleConnection *gc,
+PurpleChatConversation *serv_got_joined_chat(PurpleConnection *gc,
int id, const char *name)
{
- PurpleConversation *conv;
- PurpleConvChat *chat;
+ PurpleChatConversation *chat;
PurpleAccount *account;
account = purple_connection_get_account(gc);
@@ -830,49 +822,39 @@ PurpleConversation *serv_got_joined_chat(PurpleConnection *gc,
g_return_val_if_fail(account != NULL, NULL);
g_return_val_if_fail(name != NULL, NULL);
- conv = purple_conversation_new(PURPLE_CONV_TYPE_CHAT, account, name);
- g_return_val_if_fail(conv != NULL, NULL);
-
- chat = PURPLE_CONV_CHAT(conv);
+ chat = purple_chat_conversation_new(account, name);
+ g_return_val_if_fail(chat != NULL, NULL);
- if (!g_slist_find(gc->buddy_chats, conv))
- gc->buddy_chats = g_slist_append(gc->buddy_chats, conv);
+ if (!g_slist_find(purple_connection_get_active_chats(gc), chat))
+ _purple_connection_add_active_chat(gc, chat);
- purple_conv_chat_set_id(chat, id);
+ purple_chat_conversation_set_id(chat, id);
- purple_signal_emit(purple_conversations_get_handle(), "chat-joined", conv);
+ purple_signal_emit(purple_conversations_get_handle(), "chat-joined", chat);
- return conv;
+ return chat;
}
void serv_got_chat_left(PurpleConnection *g, int id)
{
GSList *bcs;
- PurpleConversation *conv = NULL;
- PurpleConvChat *chat = NULL;
+ PurpleChatConversation *chat = NULL;
- for (bcs = g->buddy_chats; bcs != NULL; bcs = bcs->next) {
- conv = (PurpleConversation *)bcs->data;
+ for (bcs = purple_connection_get_active_chats(g); bcs != NULL; bcs = bcs->next) {
+ chat = PURPLE_CHAT_CONVERSATION(bcs->data);
- chat = PURPLE_CONV_CHAT(conv);
-
- if (purple_conv_chat_get_id(chat) == id)
+ if (purple_chat_conversation_get_id(chat) == id)
break;
-
- conv = NULL;
}
- if (!conv)
- return;
-
purple_debug(PURPLE_DEBUG_INFO, "server", "Leaving room: %s\n",
- purple_conversation_get_name(conv));
+ purple_conversation_get_name(PURPLE_CONVERSATION(chat)));
- g->buddy_chats = g_slist_remove(g->buddy_chats, conv);
+ _purple_connection_remove_active_chat(g, chat);
- purple_conv_chat_left(PURPLE_CONV_CHAT(conv));
+ purple_chat_conversation_leave(chat);
- purple_signal_emit(purple_conversations_get_handle(), "chat-left", conv);
+ purple_signal_emit(purple_conversations_get_handle(), "chat-left", chat);
}
void purple_serv_got_join_chat_failed(PurpleConnection *gc, GHashTable *data)
@@ -885,31 +867,24 @@ void serv_got_chat_in(PurpleConnection *g, int id, const char *who,
PurpleMessageFlags flags, const char *message, time_t mtime)
{
GSList *bcs;
- PurpleConversation *conv = NULL;
- PurpleConvChat *chat = NULL;
+ PurpleChatConversation *chat = NULL;
char *buffy, *angel;
int plugin_return;
g_return_if_fail(who != NULL);
g_return_if_fail(message != NULL);
- for (bcs = g->buddy_chats; bcs != NULL; bcs = bcs->next) {
- conv = (PurpleConversation *)bcs->data;
-
- chat = PURPLE_CONV_CHAT(conv);
+ for (bcs = purple_connection_get_active_chats(g); bcs != NULL; bcs = bcs->next) {
+ chat = PURPLE_CHAT_CONVERSATION(bcs->data);
- if (purple_conv_chat_get_id(chat) == id)
+ if (purple_chat_conversation_get_id(chat) == id)
break;
-
- conv = NULL;
}
- if (!conv)
- return;
-
/* Did I send the message? */
- if (purple_strequal(purple_conv_chat_get_nick(chat),
- purple_normalize(purple_conversation_get_account(conv), who))) {
+ if (purple_strequal(purple_chat_conversation_get_nick(chat),
+ purple_normalize(purple_conversation_get_account(
+ PURPLE_CONVERSATION(chat)), who))) {
flags |= PURPLE_MESSAGE_SEND;
flags &= ~PURPLE_MESSAGE_RECV; /* Just in case some prpl sets it! */
} else {
@@ -926,7 +901,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", purple_connection_get_account(g),
- &angel, &buffy, conv, &flags));
+ &angel, &buffy, chat, &flags));
if (!buffy || !angel || plugin_return) {
g_free(buffy);
@@ -938,9 +913,9 @@ void serv_got_chat_in(PurpleConnection *g, int id, const char *who,
message = buffy;
purple_signal_emit(purple_conversations_get_handle(), "received-chat-msg", purple_connection_get_account(g),
- who, message, conv, flags);
+ who, message, chat, flags);
- purple_conv_chat_write(chat, who, message, flags, mtime);
+ purple_conversation_write_message(PURPLE_CONVERSATION(chat), who, message, flags, mtime);
g_free(angel);
g_free(buffy);
diff --git a/libpurple/server.h b/libpurple/server.h
index d80b05d224..66c40288a2 100644
--- a/libpurple/server.h
+++ b/libpurple/server.h
@@ -26,8 +26,8 @@
#ifndef _PURPLE_SERVER_H_
#define _PURPLE_SERVER_H_
-#include "account.h"
-#include "conversation.h"
+#include "accounts.h"
+#include "conversations.h"
#include "prpl.h"
G_BEGIN_DECLS
@@ -39,16 +39,16 @@ G_BEGIN_DECLS
*
* @param gc The connection over which to send the typing notification.
* @param name The user to send the typing notification to.
- * @param state One of PURPLE_TYPING, PURPLE_TYPED, or PURPLE_NOT_TYPING.
+ * @param state One of PURPLE_IM_TYPING, PURPLE_IM_TYPED, or PURPLE_IM_NOT_TYPING.
* @return A quiet-period, specified in seconds, where Purple will not
* send any additional typing notification messages. Most
* protocols should return 0, which means that no additional
- * PURPLE_TYPING messages need to be sent. If this is 5, for
+ * PURPLE_IM_TYPING messages need to be sent. If this is 5, for
* example, then Purple will wait five seconds, and if the Purple
- * user is still typing then Purple will send another PURPLE_TYPING
+ * user is still typing then Purple will send another PURPLE_IM_TYPING
* message.
*/
-unsigned int serv_send_typing(PurpleConnection *gc, const char *name, PurpleTypingState state);
+unsigned int serv_send_typing(PurpleConnection *gc, const char *name, PurpleIMTypingState state);
void serv_move_buddy(PurpleBuddy *, PurpleGroup *, PurpleGroup *);
int serv_send_im(PurpleConnection *, const char *, const char *, PurpleMessageFlags flags);
@@ -87,8 +87,8 @@ void purple_serv_got_private_alias(PurpleConnection *gc, const char *who, const
/**
- * Receive a typing message from a remote user. Either PURPLE_TYPING
- * or PURPLE_TYPED. If the user has stopped typing then use
+ * Receive a typing message from a remote user. Either PURPLE_IM_TYPING
+ * or PURPLE_IM_TYPED. If the user has stopped typing then use
* serv_got_typing_stopped instead.
*
* TODO: Could probably move this into the conversation API.
@@ -97,13 +97,13 @@ void purple_serv_got_private_alias(PurpleConnection *gc, const char *who, const
* @param name The name of the remote user.
* @param timeout If this is a number greater than 0, then
* Purple will wait this number of seconds and then
- * set this buddy to the PURPLE_NOT_TYPING state. This
+ * set this buddy to the PURPLE_IM_NOT_TYPING state. This
* is used by protocols that send repeated typing messages
* while the user is composing the message.
* @param state The typing state received
*/
void serv_got_typing(PurpleConnection *gc, const char *name, int timeout,
- PurpleTypingState state);
+ PurpleIMTypingState state);
/**
* TODO: Could probably move this into the conversation API.
@@ -148,7 +148,7 @@ void serv_got_chat_invite(PurpleConnection *gc, const char *name,
* @param name The name of the chat.
* @return The resulting conversation
*/
-PurpleConversation *serv_got_joined_chat(PurpleConnection *gc,
+PurpleChatConversation *serv_got_joined_chat(PurpleConnection *gc,
int id, const char *name);
/**
* Called by a prpl when an attempt to join a chat via serv_join_chat()
diff --git a/libpurple/signals.c b/libpurple/signals.c
index 60d7d2d7f1..d9cf2737fc 100644
--- a/libpurple/signals.c
+++ b/libpurple/signals.c
@@ -28,7 +28,6 @@
#include "dbus-maybe.h"
#include "debug.h"
#include "signals.h"
-#include "value.h"
/* must include this to use G_VA_COPY */
#include <string.h>
@@ -51,8 +50,8 @@ typedef struct
PurpleSignalMarshalFunc marshal;
int num_values;
- PurpleValue **values;
- PurpleValue *ret_value;
+ GType *value_types;
+ GType ret_type;
GList *handlers;
size_t handler_count;
@@ -87,25 +86,14 @@ destroy_signal_data(PurpleSignalData *signal_data)
g_list_foreach(signal_data->handlers, (GFunc)g_free, NULL);
g_list_free(signal_data->handlers);
- if (signal_data->values != NULL)
- {
- int i;
-
- for (i = 0; i < signal_data->num_values; i++)
- purple_value_destroy((PurpleValue *)signal_data->values[i]);
-
- g_free(signal_data->values);
- }
-
- if (signal_data->ret_value != NULL)
- purple_value_destroy(signal_data->ret_value);
+ g_free(signal_data->value_types);
g_free(signal_data);
}
gulong
purple_signal_register(void *instance, const char *signal,
PurpleSignalMarshalFunc marshal,
- PurpleValue *ret_value, int num_values, ...)
+ GType ret_type, int num_values, ...)
{
PurpleInstanceData *instance_data;
PurpleSignalData *signal_data;
@@ -136,19 +124,19 @@ purple_signal_register(void *instance, const char *signal,
signal_data->id = instance_data->next_signal_id;
signal_data->marshal = marshal;
signal_data->next_handler_id = 1;
- signal_data->ret_value = ret_value;
+ signal_data->ret_type = ret_type;
signal_data->num_values = num_values;
if (num_values > 0)
{
int i;
- signal_data->values = g_new0(PurpleValue *, num_values);
+ signal_data->value_types = g_new0(GType, num_values);
va_start(args, num_values);
for (i = 0; i < num_values; i++)
- signal_data->values[i] = va_arg(args, PurpleValue *);
+ signal_data->value_types[i] = va_arg(args, GType);
va_end(args);
}
@@ -203,17 +191,17 @@ purple_signals_unregister_by_instance(void *instance)
}
void
-purple_signal_get_values(void *instance, const char *signal,
- PurpleValue **ret_value,
- int *num_values, PurpleValue ***values)
+purple_signal_get_types(void *instance, const char *signal,
+ GType *ret_type,
+ int *num_values, GType **value_types)
{
PurpleInstanceData *instance_data;
PurpleSignalData *signal_data;
- g_return_if_fail(instance != NULL);
- g_return_if_fail(signal != NULL);
- g_return_if_fail(num_values != NULL);
- g_return_if_fail(values != NULL);
+ g_return_if_fail(instance != NULL);
+ g_return_if_fail(signal != NULL);
+ g_return_if_fail(num_values != NULL);
+ g_return_if_fail(value_types != NULL);
/* Get the instance data */
instance_data =
@@ -227,11 +215,11 @@ purple_signal_get_values(void *instance, const char *signal,
g_return_if_fail(signal_data != NULL);
- *num_values = signal_data->num_values;
- *values = signal_data->values;
+ *num_values = signal_data->num_values;
+ *value_types = signal_data->value_types;
- if (ret_value != NULL)
- *ret_value = signal_data->ret_value;
+ if (ret_type != NULL)
+ *ret_type = signal_data->ret_type;
}
static gint handler_priority(void * a, void * b) {
@@ -488,7 +476,7 @@ purple_signal_emit_vargs(void *instance, const char *signal, va_list args)
#ifdef HAVE_DBUS
purple_dbus_signal_emit_purple(signal, signal_data->num_values,
- signal_data->values, args);
+ signal_data->value_types, args);
#endif /* HAVE_DBUS */
}
@@ -540,7 +528,7 @@ purple_signal_emit_vargs_return_1(void *instance, const char *signal,
#ifdef HAVE_DBUS
G_VA_COPY(tmp, args);
purple_dbus_signal_emit_purple(signal, signal_data->num_values,
- signal_data->values, tmp);
+ signal_data->value_types, tmp);
va_end(tmp);
#endif /* HAVE_DBUS */
@@ -693,6 +681,17 @@ purple_marshal_VOID__POINTER_POINTER_UINT_UINT(PurpleCallback cb, va_list args,
}
void
+purple_marshal_VOID__POINTER_UINT_UINT(PurpleCallback cb, va_list args,
+ void *data, void **return_val)
+{
+ void *arg1 = va_arg(args, void *);
+ guint arg2 = va_arg(args, guint);
+ guint arg3 = va_arg(args, guint);
+
+ ((void (*)(void *, guint, guint, void *))cb)(arg1, arg2, arg3, data);
+}
+
+void
purple_marshal_VOID__POINTER_POINTER_POINTER(PurpleCallback cb, va_list args,
void *data, void **return_val)
{
diff --git a/libpurple/signals.h b/libpurple/signals.h
index aa732050ef..19e506f8d6 100644
--- a/libpurple/signals.h
+++ b/libpurple/signals.h
@@ -27,7 +27,7 @@
#define _PURPLE_SIGNALS_H_
#include <glib.h>
-#include "value.h"
+#include <glib-object.h>
#define PURPLE_CALLBACK(func) ((PurpleCallback)func)
@@ -68,18 +68,16 @@ G_BEGIN_DECLS
* @param instance The instance to register the signal for.
* @param signal The signal name.
* @param marshal The marshal function.
- * @param ret_value The return value type, or NULL for no return value.
+ * @param ret_type The return type, or G_TYPE_NONE for no return type.
* @param num_values The number of values to be passed to the callbacks.
* @param ... The values to pass to the callbacks.
*
* @return The signal ID local to that instance, or 0 if the signal
* couldn't be registered.
- *
- * @see PurpleValue
*/
gulong purple_signal_register(void *instance, const char *signal,
PurpleSignalMarshalFunc marshal,
- PurpleValue *ret_value, int num_values, ...);
+ GType ret_type, int num_values, ...);
/**
* Unregisters a signal in an instance.
@@ -99,15 +97,15 @@ void purple_signals_unregister_by_instance(void *instance);
/**
* Returns a list of value types used for a signal.
*
- * @param instance The instance the signal is registered to.
- * @param signal The signal.
- * @param ret_value The return value from the last signal handler.
- * @param num_values The returned number of values.
- * @param values The returned list of values.
+ * @param instance The instance the signal is registered to.
+ * @param signal The signal.
+ * @param ret_type The return type.
+ * @param num_values The returned number of values.
+ * @param value_types The returned list of values.
*/
-void purple_signal_get_values(void *instance, const char *signal,
- PurpleValue **ret_value,
- int *num_values, PurpleValue ***values);
+void purple_signal_get_types(void *instance, const char *signal,
+ GType *ret_type, int *num_values,
+ GType **value_types);
/**
* Connects a signal handler to a signal for a particular object.
@@ -309,6 +307,8 @@ void purple_marshal_VOID__POINTER_POINTER_UINT(
PurpleCallback cb, va_list args, void *data, void **return_val);
void purple_marshal_VOID__POINTER_POINTER_UINT_UINT(
PurpleCallback cb, va_list args, void *data, void **return_val);
+void purple_marshal_VOID__POINTER_UINT_UINT(
+ PurpleCallback cb, va_list args, void *data, void **return_val);
void purple_marshal_VOID__POINTER_POINTER_POINTER(
PurpleCallback cb, va_list args, void *data, void **return_val);
void purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER(
diff --git a/libpurple/smiley.c b/libpurple/smiley.c
index 6d5131129d..9a3fbfdf79 100644
--- a/libpurple/smiley.c
+++ b/libpurple/smiley.c
@@ -32,25 +32,21 @@
#include "util.h"
#include "xmlnode.h"
+#define PURPLE_SMILEY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_SMILEY, PurpleSmileyPrivate))
+
/**************************************************************************/
-/* Main structures, members and constants */
+/* Structs */
/**************************************************************************/
-struct _PurpleSmiley
-{
- GObject parent;
+typedef struct {
PurpleStoredImage *img; /**< The id of the stored image with the
the smiley data. */
char *shortcut; /**< Shortcut associated with the custom
smiley. This field will work as a
unique key by this API. */
char *checksum; /**< The smiley checksum. */
-};
-
-struct _PurpleSmileyClass
-{
- GObjectClass parent_class;
-};
+} PurpleSmileyPrivate;
static GHashTable *smiley_shortcut_index = NULL; /* shortcut (char *) => smiley (PurpleSmiley*) */
static GHashTable *smiley_checksum_index = NULL; /* checksum (char *) => smiley (PurpleSmiley*) */
@@ -134,6 +130,7 @@ purple_smiley_data_unstore(const char *filename);
static xmlnode *
smiley_to_xmlnode(PurpleSmiley *smiley)
{
+ PurpleSmileyPrivate *priv = NULL;
xmlnode *smiley_node = NULL;
smiley_node = xmlnode_new(XML_SMILEY_TAG);
@@ -141,14 +138,16 @@ smiley_to_xmlnode(PurpleSmiley *smiley)
if (!smiley_node)
return NULL;
+ priv = PURPLE_SMILEY_GET_PRIVATE(smiley);
+
xmlnode_set_attrib(smiley_node, XML_SHORTCUT_ATTRIB_TAG,
- smiley->shortcut);
+ priv->shortcut);
xmlnode_set_attrib(smiley_node, XML_CHECKSUM_ATRIB_TAG,
- smiley->checksum);
+ priv->checksum);
xmlnode_set_attrib(smiley_node, XML_FILENAME_ATRIB_TAG,
- purple_imgstore_get_filename(smiley->img));
+ purple_imgstore_get_filename(priv->img));
return smiley_node;
}
@@ -310,12 +309,14 @@ purple_smiley_get_property(GObject *object, guint param_id, GValue *value,
GParamSpec *spec)
{
PurpleSmiley *smiley = PURPLE_SMILEY(object);
+ PurpleSmileyPrivate *priv = PURPLE_SMILEY_GET_PRIVATE(smiley);
+
switch (param_id) {
case PROP_SHORTCUT:
- g_value_set_string(value, smiley->shortcut);
+ g_value_set_string(value, priv->shortcut);
break;
case PROP_IMGSTORE:
- g_value_set_pointer(value, smiley->img);
+ g_value_set_pointer(value, priv->img);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, spec);
@@ -328,6 +329,8 @@ purple_smiley_set_property(GObject *object, guint param_id, const GValue *value,
GParamSpec *spec)
{
PurpleSmiley *smiley = PURPLE_SMILEY(object);
+ PurpleSmileyPrivate *priv = PURPLE_SMILEY_GET_PRIVATE(smiley);
+
switch (param_id) {
case PROP_SHORTCUT:
{
@@ -339,18 +342,18 @@ purple_smiley_set_property(GObject *object, guint param_id, const GValue *value,
{
PurpleStoredImage *img = g_value_get_pointer(value);
- purple_imgstore_unref(smiley->img);
- g_free(smiley->checksum);
+ purple_imgstore_unref(priv->img);
+ g_free(priv->checksum);
- smiley->img = img;
+ priv->img = img;
if (img) {
- smiley->checksum = g_compute_checksum_for_data(
+ priv->checksum = g_compute_checksum_for_data(
G_CHECKSUM_SHA1,
purple_imgstore_get_data(img),
purple_imgstore_get_size(img));
purple_smiley_data_store(img);
} else {
- smiley->checksum = NULL;
+ priv->checksum = NULL;
}
g_object_notify(object, PROP_IMGSTORE_S);
@@ -366,17 +369,18 @@ static void
purple_smiley_finalize(GObject *obj)
{
PurpleSmiley *smiley = PURPLE_SMILEY(obj);
+ PurpleSmileyPrivate *priv = PURPLE_SMILEY_GET_PRIVATE(smiley);
- if (g_hash_table_lookup(smiley_shortcut_index, smiley->shortcut)) {
- g_hash_table_remove(smiley_shortcut_index, smiley->shortcut);
- g_hash_table_remove(smiley_checksum_index, smiley->checksum);
+ if (g_hash_table_lookup(smiley_shortcut_index, priv->shortcut)) {
+ g_hash_table_remove(smiley_shortcut_index, priv->shortcut);
+ g_hash_table_remove(smiley_checksum_index, priv->checksum);
}
- g_free(smiley->shortcut);
- g_free(smiley->checksum);
- if (smiley->img)
- purple_smiley_data_unstore(purple_imgstore_get_filename(smiley->img));
- purple_imgstore_unref(smiley->img);
+ g_free(priv->shortcut);
+ g_free(priv->checksum);
+ if (priv->img)
+ purple_smiley_data_unstore(purple_imgstore_get_filename(priv->img));
+ purple_imgstore_unref(priv->img);
PURPLE_DBUS_UNREGISTER_POINTER(smiley);
@@ -398,6 +402,8 @@ purple_smiley_class_init(PurpleSmileyClass *klass)
parent_class = g_type_class_peek_parent(klass);
+ g_type_class_add_private(klass, sizeof(PurpleSmileyPrivate));
+
gobj_class->get_property = purple_smiley_get_property;
gobj_class->set_property = purple_smiley_set_property;
gobj_class->finalize = purple_smiley_finalize;
@@ -473,6 +479,7 @@ static void
purple_smiley_load_file(const char *shortcut, const char *checksum, const char *filename)
{
PurpleSmiley *smiley = NULL;
+ PurpleSmileyPrivate *priv = NULL;
guchar *smiley_data;
size_t smiley_data_len;
char *fullpath = NULL;
@@ -493,7 +500,9 @@ purple_smiley_load_file(const char *shortcut, const char *checksum, const char *
return;
}
- smiley->checksum = g_strdup(checksum);
+ priv = PURPLE_SMILEY_GET_PRIVATE(smiley);
+
+ priv->checksum = g_strdup(checksum);
if (read_smiley_file(fullpath, &smiley_data, &smiley_data_len))
purple_smiley_set_data_impl(smiley, smiley_data,
@@ -616,6 +625,7 @@ static void
purple_smiley_set_data_impl(PurpleSmiley *smiley, guchar *smiley_data,
size_t smiley_data_len)
{
+ PurpleSmileyPrivate *priv = NULL;
PurpleStoredImage *old_img, *new_img;
const char *old_filename = NULL;
const char *new_filename = NULL;
@@ -624,7 +634,9 @@ purple_smiley_set_data_impl(PurpleSmiley *smiley, guchar *smiley_data,
g_return_if_fail(smiley_data != NULL);
g_return_if_fail(smiley_data_len > 0);
- old_img = smiley->img;
+ priv = PURPLE_SMILEY_GET_PRIVATE(smiley);
+
+ old_img = priv->img;
new_img = purple_smiley_data_new(smiley_data, smiley_data_len);
@@ -636,7 +648,7 @@ purple_smiley_set_data_impl(PurpleSmiley *smiley, guchar *smiley_data,
return;
old_filename = purple_imgstore_get_filename(old_img);
- new_filename = purple_imgstore_get_filename(smiley->img);
+ new_filename = purple_imgstore_get_filename(priv->img);
if (g_ascii_strcasecmp(old_filename, new_filename))
purple_smiley_data_unstore(old_filename);
@@ -683,7 +695,8 @@ static PurpleSmiley *
purple_smiley_new_from_stream(const char *shortcut, guchar *smiley_data,
size_t smiley_data_len)
{
- PurpleSmiley *smiley;
+ PurpleSmiley *smiley = NULL;
+ PurpleSmileyPrivate *priv = NULL;
g_return_val_if_fail(shortcut != NULL, NULL);
g_return_val_if_fail(smiley_data != NULL, NULL);
@@ -698,9 +711,10 @@ purple_smiley_new_from_stream(const char *shortcut, guchar *smiley_data,
if (!smiley)
return NULL;
- purple_smiley_set_data_impl(smiley, smiley_data, smiley_data_len);
+ priv = PURPLE_SMILEY_GET_PRIVATE(smiley);
- purple_smiley_data_store(smiley->img);
+ purple_smiley_set_data_impl(smiley, smiley_data, smiley_data_len);
+ purple_smiley_data_store(priv->img);
return smiley;
}
@@ -734,6 +748,8 @@ purple_smiley_delete(PurpleSmiley *smiley)
gboolean
purple_smiley_set_shortcut(PurpleSmiley *smiley, const char *shortcut)
{
+ PurpleSmileyPrivate *priv = NULL;
+
g_return_val_if_fail(smiley != NULL, FALSE);
g_return_val_if_fail(shortcut != NULL, FALSE);
@@ -741,15 +757,17 @@ purple_smiley_set_shortcut(PurpleSmiley *smiley, const char *shortcut)
if (g_hash_table_lookup(smiley_shortcut_index, shortcut))
return FALSE;
+ priv = PURPLE_SMILEY_GET_PRIVATE(smiley);
+
/* Remove the old shortcut. */
- if (smiley->shortcut)
- g_hash_table_remove(smiley_shortcut_index, smiley->shortcut);
+ if (priv->shortcut)
+ g_hash_table_remove(smiley_shortcut_index, priv->shortcut);
/* Insert the new shortcut. */
g_hash_table_insert(smiley_shortcut_index, g_strdup(shortcut), smiley);
- g_free(smiley->shortcut);
- smiley->shortcut = g_strdup(shortcut);
+ g_free(priv->shortcut);
+ priv->shortcut = g_strdup(shortcut);
g_object_notify(G_OBJECT(smiley), PROP_SHORTCUT_S);
@@ -762,18 +780,22 @@ void
purple_smiley_set_data(PurpleSmiley *smiley, guchar *smiley_data,
size_t smiley_data_len)
{
+ PurpleSmileyPrivate *priv = NULL;
+
g_return_if_fail(smiley != NULL);
g_return_if_fail(smiley_data != NULL);
g_return_if_fail(smiley_data_len > 0);
+ priv = PURPLE_SMILEY_GET_PRIVATE(smiley);
+
/* Remove the previous entry */
- g_hash_table_remove(smiley_checksum_index, smiley->checksum);
+ g_hash_table_remove(smiley_checksum_index, priv->checksum);
/* Update the file data. This also updates the checksum. */
purple_smiley_set_data_impl(smiley, smiley_data, smiley_data_len);
/* Reinsert the index item. */
- g_hash_table_insert(smiley_checksum_index, g_strdup(smiley->checksum), smiley);
+ g_hash_table_insert(smiley_checksum_index, g_strdup(priv->checksum), smiley);
purple_smileys_save();
}
@@ -781,34 +803,45 @@ purple_smiley_set_data(PurpleSmiley *smiley, guchar *smiley_data,
PurpleStoredImage *
purple_smiley_get_stored_image(const PurpleSmiley *smiley)
{
- return purple_imgstore_ref(smiley->img);
+ PurpleSmileyPrivate *priv = PURPLE_SMILEY_GET_PRIVATE(smiley);
+ return purple_imgstore_ref(priv->img);
}
const char *purple_smiley_get_shortcut(const PurpleSmiley *smiley)
{
+ PurpleSmileyPrivate *priv = NULL;
+
g_return_val_if_fail(smiley != NULL, NULL);
- return smiley->shortcut;
+ priv = PURPLE_SMILEY_GET_PRIVATE(smiley);
+ return priv->shortcut;
}
const char *
purple_smiley_get_checksum(const PurpleSmiley *smiley)
{
+ PurpleSmileyPrivate *priv = NULL;
+
g_return_val_if_fail(smiley != NULL, NULL);
- return smiley->checksum;
+ priv = PURPLE_SMILEY_GET_PRIVATE(smiley);
+ return priv->checksum;
}
gconstpointer
purple_smiley_get_data(const PurpleSmiley *smiley, size_t *len)
{
+ PurpleSmileyPrivate *priv = NULL;
+
g_return_val_if_fail(smiley != NULL, NULL);
- if (smiley->img) {
+ priv = PURPLE_SMILEY_GET_PRIVATE(smiley);
+
+ if (priv->img) {
if (len != NULL)
- *len = purple_imgstore_get_size(smiley->img);
+ *len = purple_imgstore_get_size(priv->img);
- return purple_imgstore_get_data(smiley->img);
+ return purple_imgstore_get_data(priv->img);
}
return NULL;
@@ -817,20 +850,26 @@ purple_smiley_get_data(const PurpleSmiley *smiley, size_t *len)
const char *
purple_smiley_get_extension(const PurpleSmiley *smiley)
{
- if (smiley->img != NULL)
- return purple_imgstore_get_extension(smiley->img);
+ PurpleSmileyPrivate *priv = PURPLE_SMILEY_GET_PRIVATE(smiley);
+
+ if (priv->img != NULL)
+ return purple_imgstore_get_extension(priv->img);
return NULL;
}
char *purple_smiley_get_full_path(PurpleSmiley *smiley)
{
+ PurpleSmileyPrivate *priv = NULL;
+
g_return_val_if_fail(smiley != NULL, NULL);
- if (smiley->img == NULL)
+ priv = PURPLE_SMILEY_GET_PRIVATE(smiley);
+
+ if (priv->img == NULL)
return NULL;
- return get_file_full_path(purple_imgstore_get_filename(smiley->img));
+ return get_file_full_path(purple_imgstore_get_filename(priv->img));
}
static void add_smiley_to_list(gpointer key, gpointer value, gpointer user_data)
diff --git a/libpurple/smiley.h b/libpurple/smiley.h
index c297d1daf0..d2e3cc2a36 100644
--- a/libpurple/smiley.h
+++ b/libpurple/smiley.h
@@ -50,6 +50,23 @@ 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))
+struct _PurpleSmiley
+{
+ /*< private >*/
+ GObject parent;
+};
+
+struct _PurpleSmileyClass
+{
+ /*< private >*/
+ GObjectClass parent_class;
+
+ void (*purple_reserved1)(void);
+ void (*purple_reserved2)(void);
+ void (*purple_reserved3)(void);
+ void (*purple_reserved4)(void);
+};
+
G_BEGIN_DECLS
/**************************************************************************/
diff --git a/libpurple/sound-theme-loader.h b/libpurple/sound-theme-loader.h
index 9eb927b156..f17b049e0e 100644
--- a/libpurple/sound-theme-loader.h
+++ b/libpurple/sound-theme-loader.h
@@ -48,12 +48,19 @@ typedef struct _PurpleSoundThemeLoaderClass PurpleSoundThemeLoaderClass;
struct _PurpleSoundThemeLoader
{
+ /*< private >*/
PurpleThemeLoader parent;
};
struct _PurpleSoundThemeLoaderClass
{
+ /*< private >*/
PurpleThemeLoaderClass parent_class;
+
+ void (*purple_reserved1)(void);
+ void (*purple_reserved2)(void);
+ void (*purple_reserved3)(void);
+ void (*purple_reserved4)(void);
};
/**************************************************************************/
diff --git a/libpurple/sound-theme.h b/libpurple/sound-theme.h
index adde4fddea..007640264e 100644
--- a/libpurple/sound-theme.h
+++ b/libpurple/sound-theme.h
@@ -50,12 +50,19 @@ typedef struct _PurpleSoundThemeClass PurpleSoundThemeClass;
struct _PurpleSoundTheme
{
+ /*< private >*/
PurpleTheme parent;
};
struct _PurpleSoundThemeClass
{
+ /*< private >*/
PurpleThemeClass parent_class;
+
+ void (*purple_reserved1)(void);
+ void (*purple_reserved2)(void);
+ void (*purple_reserved3)(void);
+ void (*purple_reserved4)(void);
};
/**************************************************************************/
diff --git a/libpurple/sound.c b/libpurple/sound.c
index 4cb4ebb013..25b22c964c 100644
--- a/libpurple/sound.c
+++ b/libpurple/sound.c
@@ -22,7 +22,7 @@
*/
#include "internal.h"
-#include "blist.h"
+#include "buddylist.h"
#include "prefs.h"
#include "sound.h"
#include "sound-theme-loader.h"
@@ -128,10 +128,7 @@ purple_sound_init()
purple_signal_register(handle, "playing-sound-event",
purple_marshal_BOOLEAN__INT_POINTER,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 2,
- purple_value_new(PURPLE_TYPE_INT),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT));
+ G_TYPE_BOOLEAN, 2, G_TYPE_INT, PURPLE_TYPE_ACCOUNT);
purple_prefs_add_none("/purple/sound");
purple_prefs_add_int("/purple/sound/while_status", STATUS_AVAILABLE);
diff --git a/libpurple/status.c b/libpurple/status.c
index 9d43446efb..c508a36aae 100644
--- a/libpurple/status.c
+++ b/libpurple/status.c
@@ -1,8 +1,3 @@
-/**
- * @file status.c Status API
- * @ingroup core
- */
-
/* purple
*
* Purple is the legal property of its developers, whose names are too numerous
@@ -23,11 +18,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
-#define _PURPLE_STATUS_C_
-
#include "internal.h"
-
-#include "blist.h"
+#include "buddylist.h"
#include "core.h"
#include "dbus-maybe.h"
#include "debug.h"
@@ -35,6 +27,12 @@
#include "prefs.h"
#include "status.h"
+#define PURPLE_STATUS_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_STATUS, PurpleStatusPrivate))
+
+/** @copydoc _PurpleStatusPrivate */
+typedef struct _PurpleStatusPrivate PurpleStatusPrivate;
+
/**
* A type of status.
*/
@@ -55,57 +53,19 @@ struct _PurpleStatusType
/**
* A status attribute.
*/
-struct _PurpleStatusAttr
+struct _PurpleStatusAttribute
{
char *id;
char *name;
- PurpleValue *value_type;
-};
-
-/**
- * A list of statuses.
- */
-struct _PurplePresence
-{
- PurplePresenceContext context;
-
- gboolean idle;
- time_t idle_time;
- time_t login_time;
-
- GList *statuses;
- GHashTable *status_table;
-
- PurpleStatus *active_status;
-
- union
- {
- PurpleAccount *account;
-
- struct
- {
- PurpleConversation *conv;
- char *user;
-
- } chat;
-
- struct
- {
- PurpleAccount *account;
- char *name;
- PurpleBuddy *buddy;
-
- } buddy;
-
- } u;
+ GValue *value_type;
};
/**
- * An active status.
+ * Private data for PurpleStatus
*/
-struct _PurpleStatus
+struct _PurpleStatusPrivate
{
- PurpleStatusType *type;
+ PurpleStatusType *status_type;
PurplePresence *presence;
gboolean active;
@@ -114,17 +74,29 @@ struct _PurpleStatus
* The current values of the attributes for this status. The
* key is a string containing the name of the attribute. It is
* a borrowed reference from the list of attrs in the
- * PurpleStatusType. The value is a PurpleValue.
+ * PurpleStatusType. The value is a GValue.
*/
GHashTable *attr_values;
};
+/* GObject property enums */
+enum
+{
+ PROP_0,
+ PROP_STATUS_TYPE,
+ PROP_PRESENCE,
+ PROP_ACTIVE,
+ PROP_LAST
+};
+
typedef struct
{
PurpleAccount *account;
char *name;
} PurpleStatusBuddyKey;
+static GObjectClass *parent_class;
+
static int primitive_scores[] =
{
0, /* unset */
@@ -146,6 +118,8 @@ static int primitive_scores[] =
#define SCORE_IDLE_TIME 10
#define SCORE_OFFLINE_MESSAGE 11
+int *_purple_get_primitive_scores(void);
+
/**************************************************************************
* PurpleStatusPrimitive API
**************************************************************************/
@@ -169,6 +143,12 @@ static struct PurpleStatusPrimitiveMap
{ PURPLE_STATUS_MOOD, "mood", N_("Feeling") },
};
+int *
+_purple_get_primitive_scores(void)
+{
+ return primitive_scores;
+}
+
const char *
purple_primitive_get_id_from_type(PurpleStatusPrimitive type)
{
@@ -259,16 +239,16 @@ purple_status_type_new(PurpleStatusPrimitive primitive, const char *id,
static void
status_type_add_attr(PurpleStatusType *status_type, const char *id,
- const char *name, PurpleValue *value)
+ const char *name, GValue *value)
{
- PurpleStatusAttr *attr;
+ PurpleStatusAttribute *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);
+ attr = purple_status_attribute_new(id, name, value);
status_type->attrs = g_list_append(status_type->attrs, attr);
}
@@ -277,7 +257,7 @@ static void
status_type_add_attrs_vargs(PurpleStatusType *status_type, va_list args)
{
const char *id, *name;
- PurpleValue *value;
+ GValue *value;
g_return_if_fail(status_type != NULL);
@@ -286,7 +266,7 @@ status_type_add_attrs_vargs(PurpleStatusType *status_type, va_list args)
name = va_arg(args, const char *);
g_return_if_fail(name != NULL);
- value = va_arg(args, PurpleValue *);
+ value = va_arg(args, GValue *);
g_return_if_fail(value != NULL);
status_type_add_attr(status_type, id, name, value);
@@ -298,7 +278,7 @@ purple_status_type_new_with_attrs(PurpleStatusPrimitive primitive,
const char *id, const char *name,
gboolean saveable, gboolean user_settable,
gboolean independent, const char *attr_id,
- const char *attr_name, PurpleValue *attr_value,
+ const char *attr_name, GValue *attr_value,
...)
{
PurpleStatusType *status_type;
@@ -330,7 +310,7 @@ purple_status_type_destroy(PurpleStatusType *status_type)
g_free(status_type->id);
g_free(status_type->name);
- g_list_foreach(status_type->attrs, (GFunc)purple_status_attr_destroy, NULL);
+ g_list_foreach(status_type->attrs, (GFunc)purple_status_attribute_destroy, NULL);
g_list_free(status_type->attrs);
PURPLE_DBUS_UNREGISTER_POINTER(status_type);
@@ -405,7 +385,7 @@ purple_status_type_is_available(const PurpleStatusType *status_type)
return (primitive == PURPLE_STATUS_AVAILABLE);
}
-PurpleStatusAttr *
+PurpleStatusAttribute *
purple_status_type_get_attr(const PurpleStatusType *status_type, const char *id)
{
GList *l;
@@ -415,9 +395,9 @@ purple_status_type_get_attr(const PurpleStatusType *status_type, const char *id)
for (l = status_type->attrs; l != NULL; l = l->next)
{
- PurpleStatusAttr *attr = (PurpleStatusAttr *)l->data;
+ PurpleStatusAttribute *attr = (PurpleStatusAttribute *)l->data;
- if (purple_strequal(purple_status_attr_get_id(attr), id))
+ if (purple_strequal(purple_status_attribute_get_id(attr), id))
return attr;
}
@@ -454,19 +434,19 @@ purple_status_type_find_with_id(GList *status_types, const char *id)
/**************************************************************************
-* PurpleStatusAttr API
+* PurpleStatusAttribute API
**************************************************************************/
-PurpleStatusAttr *
-purple_status_attr_new(const char *id, const char *name, PurpleValue *value_type)
+PurpleStatusAttribute *
+purple_status_attribute_new(const char *id, const char *name, GValue *value_type)
{
- PurpleStatusAttr *attr;
+ PurpleStatusAttribute *attr;
g_return_val_if_fail(id != NULL, NULL);
g_return_val_if_fail(name != NULL, NULL);
g_return_val_if_fail(value_type != NULL, NULL);
- attr = g_new0(PurpleStatusAttr, 1);
- PURPLE_DBUS_REGISTER_POINTER(attr, PurpleStatusAttr);
+ attr = g_new0(PurpleStatusAttribute, 1);
+ PURPLE_DBUS_REGISTER_POINTER(attr, PurpleStatusAttribute);
attr->id = g_strdup(id);
attr->name = g_strdup(name);
@@ -476,21 +456,21 @@ purple_status_attr_new(const char *id, const char *name, PurpleValue *value_type
}
void
-purple_status_attr_destroy(PurpleStatusAttr *attr)
+purple_status_attribute_destroy(PurpleStatusAttribute *attr)
{
g_return_if_fail(attr != NULL);
g_free(attr->id);
g_free(attr->name);
- purple_value_destroy(attr->value_type);
+ purple_g_value_free(attr->value_type);
PURPLE_DBUS_UNREGISTER_POINTER(attr);
g_free(attr);
}
const char *
-purple_status_attr_get_id(const PurpleStatusAttr *attr)
+purple_status_attribute_get_id(const PurpleStatusAttribute *attr)
{
g_return_val_if_fail(attr != NULL, NULL);
@@ -498,15 +478,15 @@ purple_status_attr_get_id(const PurpleStatusAttr *attr)
}
const char *
-purple_status_attr_get_name(const PurpleStatusAttr *attr)
+purple_status_attribute_get_name(const PurpleStatusAttribute *attr)
{
g_return_val_if_fail(attr != NULL, NULL);
return attr->name;
}
-PurpleValue *
-purple_status_attr_get_value(const PurpleStatusAttr *attr)
+GValue *
+purple_status_attribute_get_value(const PurpleStatusAttribute *attr)
{
g_return_val_if_fail(attr != NULL, NULL);
@@ -517,54 +497,6 @@ purple_status_attr_get_value(const PurpleStatusAttr *attr)
/**************************************************************************
* PurpleStatus API
**************************************************************************/
-PurpleStatus *
-purple_status_new(PurpleStatusType *status_type, PurplePresence *presence)
-{
- PurpleStatus *status;
- GList *l;
-
- g_return_val_if_fail(status_type != NULL, NULL);
- g_return_val_if_fail(presence != NULL, NULL);
-
- status = g_new0(PurpleStatus, 1);
- PURPLE_DBUS_REGISTER_POINTER(status, PurpleStatus);
-
- status->type = status_type;
- status->presence = presence;
-
- status->attr_values =
- g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
- (GDestroyNotify)purple_value_destroy);
-
- for (l = purple_status_type_get_attrs(status_type); l != NULL; l = l->next)
- {
- PurpleStatusAttr *attr = (PurpleStatusAttr *)l->data;
- PurpleValue *value = purple_status_attr_get_value(attr);
- PurpleValue *new_value = purple_value_dup(value);
-
- g_hash_table_insert(status->attr_values,
- (char *)purple_status_attr_get_id(attr),
- new_value);
- }
-
- return status;
-}
-
-/*
- * TODO: If the PurpleStatus is in a PurplePresence, then
- * remove it from the PurplePresence?
- */
-void
-purple_status_destroy(PurpleStatus *status)
-{
- g_return_if_fail(status != NULL);
-
- g_hash_table_destroy(status->attr_values);
-
- PURPLE_DBUS_UNREGISTER_POINTER(status);
- g_free(status);
-}
-
static void
notify_buddy_status_update(PurpleBuddy *buddy, PurplePresence *presence,
PurpleStatus *old_status, PurpleStatus *new_status)
@@ -620,11 +552,10 @@ static void
notify_status_update(PurplePresence *presence, PurpleStatus *old_status,
PurpleStatus *new_status)
{
- PurplePresenceContext context = purple_presence_get_context(presence);
-
- if (context == PURPLE_PRESENCE_CONTEXT_ACCOUNT)
+ if (PURPLE_IS_ACCOUNT_PRESENCE(presence))
{
- PurpleAccount *account = purple_presence_get_account(presence);
+ PurpleAccount *account = purple_account_presence_get_account(
+ PURPLE_ACCOUNT_PRESENCE(presence));
PurpleAccountUiOps *ops = purple_accounts_get_ui_ops();
if (purple_account_get_enabled(account, purple_core_get_ui()))
@@ -635,10 +566,11 @@ notify_status_update(PurplePresence *presence, PurpleStatus *old_status,
ops->status_changed(account, new_status);
}
}
- else if (context == PURPLE_PRESENCE_CONTEXT_BUDDY)
+ else if (PURPLE_IS_BUDDY_PRESENCE(presence))
{
- notify_buddy_status_update(purple_presence_get_buddy(presence), presence,
- old_status, new_status);
+ notify_buddy_status_update(purple_buddy_presence_get_buddy(
+ PURPLE_BUDDY_PRESENCE(presence)), presence, old_status,
+ new_status);
}
}
@@ -659,8 +591,8 @@ status_has_changed(PurpleStatus *status)
{
old_status = purple_presence_get_active_status(presence);
if (old_status != NULL && (old_status != status))
- old_status->active = FALSE;
- presence->active_status = status;
+ PURPLE_STATUS_GET_PRIVATE(old_status)->active = FALSE;
+ g_object_set(presence, "active-status", status, NULL);
}
else
old_status = NULL;
@@ -672,7 +604,7 @@ static void
status_set_attr_boolean(PurpleStatus *status, const char *id,
gboolean value)
{
- PurpleValue *attr_value;
+ GValue *attr_value;
g_return_if_fail(status != NULL);
g_return_if_fail(id != NULL);
@@ -680,15 +612,15 @@ status_set_attr_boolean(PurpleStatus *status, const char *id,
/* 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);
+ g_return_if_fail(G_VALUE_TYPE(attr_value) == G_TYPE_BOOLEAN);
- purple_value_set_boolean(attr_value, value);
+ g_value_set_boolean(attr_value, value);
}
static void
status_set_attr_int(PurpleStatus *status, const char *id, int value)
{
- PurpleValue *attr_value;
+ GValue *attr_value;
g_return_if_fail(status != NULL);
g_return_if_fail(id != NULL);
@@ -696,16 +628,16 @@ status_set_attr_int(PurpleStatus *status, const char *id, int value)
/* 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);
+ g_return_if_fail(G_VALUE_TYPE(attr_value) == G_TYPE_INT);
- purple_value_set_int(attr_value, value);
+ g_value_set_int(attr_value, value);
}
static void
status_set_attr_string(PurpleStatus *status, const char *id,
const char *value)
{
- PurpleValue *attr_value;
+ GValue *attr_value;
g_return_if_fail(status != NULL);
g_return_if_fail(id != NULL);
@@ -720,14 +652,14 @@ status_set_attr_string(PurpleStatus *status, const char *id,
"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)));
+ purple_status_type_get_name(purple_status_get_status_type(status)));
return;
}
- g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_STRING);
+ g_return_if_fail(G_VALUE_TYPE(attr_value) == G_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);
+ g_value_set_string(attr_value, value);
}
void
@@ -767,8 +699,9 @@ purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active,
GList *l;
GList *specified_attr_ids = NULL;
PurpleStatusType *status_type;
+ PurpleStatusPrivate *priv = PURPLE_STATUS_GET_PRIVATE(status);
- g_return_if_fail(status != NULL);
+ g_return_if_fail(priv != NULL);
if (!active && purple_status_is_exclusive(status))
{
@@ -778,19 +711,19 @@ purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active,
return;
}
- if (status->active != active)
+ if (priv->active != active)
{
changed = TRUE;
}
- status->active = active;
+ priv->active = active;
/* Set any attributes */
l = attrs;
while (l != NULL)
{
const gchar *id;
- PurpleValue *value;
+ GValue *value;
id = l->data;
l = l->next;
@@ -798,7 +731,7 @@ purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active,
if (value == NULL)
{
purple_debug_warning("status", "The attribute \"%s\" on the status \"%s\" is "
- "not supported.\n", id, status->type->name);
+ "not supported.\n", id, priv->status_type->name);
/* Skip over the data and move on to the next attribute */
l = l->next;
continue;
@@ -806,29 +739,29 @@ purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active,
specified_attr_ids = g_list_prepend(specified_attr_ids, (gpointer)id);
- if (purple_value_get_type(value) == PURPLE_TYPE_STRING)
+ if (G_VALUE_TYPE(value) == G_TYPE_STRING)
{
const gchar *string_data = l->data;
l = l->next;
- if (purple_strequal(string_data, purple_value_get_string(value)))
+ if (purple_strequal(string_data, g_value_get_string(value)))
continue;
status_set_attr_string(status, id, string_data);
changed = TRUE;
}
- else if (purple_value_get_type(value) == PURPLE_TYPE_INT)
+ else if (G_VALUE_TYPE(value) == G_TYPE_INT)
{
int int_data = GPOINTER_TO_INT(l->data);
l = l->next;
- if (int_data == purple_value_get_int(value))
+ if (int_data == g_value_get_int(value))
continue;
status_set_attr_int(status, id, int_data);
changed = TRUE;
}
- else if (purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN)
+ else if (G_VALUE_TYPE(value) == G_TYPE_BOOLEAN)
{
gboolean boolean_data = GPOINTER_TO_INT(l->data);
l = l->next;
- if (boolean_data == purple_value_get_boolean(value))
+ if (boolean_data == g_value_get_boolean(value))
continue;
status_set_attr_boolean(status, id, boolean_data);
changed = TRUE;
@@ -841,20 +774,20 @@ purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active,
}
/* Reset any unspecified attributes to their default value */
- status_type = purple_status_get_type(status);
+ status_type = purple_status_get_status_type(status);
l = purple_status_type_get_attrs(status_type);
while (l != NULL) {
- PurpleStatusAttr *attr;
+ PurpleStatusAttribute *attr;
attr = l->data;
l = l->next;
if (!g_list_find_custom(specified_attr_ids, attr->id, (GCompareFunc)strcmp)) {
- PurpleValue *default_value;
- default_value = purple_status_attr_get_value(attr);
- if (purple_value_get_type(default_value) == PURPLE_TYPE_STRING) {
+ GValue *default_value;
+ default_value = purple_status_attribute_get_value(attr);
+ if (G_VALUE_TYPE(default_value) == G_TYPE_STRING) {
const char *cur = purple_status_get_attr_string(status, attr->id);
- const char *def = purple_value_get_string(default_value);
+ const char *def = g_value_get_string(default_value);
if ((cur == NULL && def == NULL)
|| (cur != NULL && def != NULL
&& !strcmp(cur, def))) {
@@ -862,16 +795,16 @@ purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active,
}
status_set_attr_string(status, attr->id, def);
- } else if (purple_value_get_type(default_value) == PURPLE_TYPE_INT) {
+ } else if (G_VALUE_TYPE(default_value) == G_TYPE_INT) {
int cur = purple_status_get_attr_int(status, attr->id);
- int def = purple_value_get_int(default_value);
+ int def = g_value_get_int(default_value);
if (cur == def)
continue;
status_set_attr_int(status, attr->id, def);
- } else if (purple_value_get_type(default_value) == PURPLE_TYPE_BOOLEAN) {
+ } else if (G_VALUE_TYPE(default_value) == G_TYPE_BOOLEAN) {
gboolean cur = purple_status_get_attr_boolean(status, attr->id);
- gboolean def = purple_value_get_boolean(default_value);
+ gboolean def = g_value_get_boolean(default_value);
if (cur == def)
continue;
@@ -888,19 +821,23 @@ purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active,
}
PurpleStatusType *
-purple_status_get_type(const PurpleStatus *status)
+purple_status_get_status_type(const PurpleStatus *status)
{
- g_return_val_if_fail(status != NULL, NULL);
+ PurpleStatusPrivate *priv = PURPLE_STATUS_GET_PRIVATE(status);
+
+ g_return_val_if_fail(priv != NULL, NULL);
- return status->type;
+ return priv->status_type;
}
PurplePresence *
purple_status_get_presence(const PurpleStatus *status)
{
- g_return_val_if_fail(status != NULL, NULL);
+ PurpleStatusPrivate *priv = PURPLE_STATUS_GET_PRIVATE(status);
+
+ g_return_val_if_fail(priv != NULL, NULL);
- return status->presence;
+ return priv->presence;
}
const char *
@@ -908,7 +845,7 @@ purple_status_get_id(const PurpleStatus *status)
{
g_return_val_if_fail(status != NULL, NULL);
- return purple_status_type_get_id(purple_status_get_type(status));
+ return purple_status_type_get_id(purple_status_get_status_type(status));
}
const char *
@@ -916,7 +853,7 @@ purple_status_get_name(const PurpleStatus *status)
{
g_return_val_if_fail(status != NULL, NULL);
- return purple_status_type_get_name(purple_status_get_type(status));
+ return purple_status_type_get_name(purple_status_get_status_type(status));
}
gboolean
@@ -924,7 +861,7 @@ purple_status_is_independent(const PurpleStatus *status)
{
g_return_val_if_fail(status != NULL, FALSE);
- return purple_status_type_is_independent(purple_status_get_type(status));
+ return purple_status_type_is_independent(purple_status_get_status_type(status));
}
gboolean
@@ -932,7 +869,7 @@ purple_status_is_exclusive(const PurpleStatus *status)
{
g_return_val_if_fail(status != NULL, FALSE);
- return purple_status_type_is_exclusive(purple_status_get_type(status));
+ return purple_status_type_is_exclusive(purple_status_get_status_type(status));
}
gboolean
@@ -940,15 +877,17 @@ purple_status_is_available(const PurpleStatus *status)
{
g_return_val_if_fail(status != NULL, FALSE);
- return purple_status_type_is_available(purple_status_get_type(status));
+ return purple_status_type_is_available(purple_status_get_status_type(status));
}
gboolean
purple_status_is_active(const PurpleStatus *status)
{
- g_return_val_if_fail(status != NULL, FALSE);
+ PurpleStatusPrivate *priv = PURPLE_STATUS_GET_PRIVATE(status);
- return status->active;
+ g_return_val_if_fail(priv != NULL, FALSE);
+
+ return priv->active;
}
gboolean
@@ -958,25 +897,27 @@ purple_status_is_online(const PurpleStatus *status)
g_return_val_if_fail( status != NULL, FALSE);
- primitive = purple_status_type_get_primitive(purple_status_get_type(status));
+ primitive = purple_status_type_get_primitive(purple_status_get_status_type(status));
return (primitive != PURPLE_STATUS_UNSET &&
primitive != PURPLE_STATUS_OFFLINE);
}
-PurpleValue *
+GValue *
purple_status_get_attr_value(const PurpleStatus *status, const char *id)
{
- g_return_val_if_fail(status != NULL, NULL);
- g_return_val_if_fail(id != NULL, NULL);
+ PurpleStatusPrivate *priv = PURPLE_STATUS_GET_PRIVATE(status);
+
+ g_return_val_if_fail(priv != NULL, NULL);
+ g_return_val_if_fail(id != NULL, NULL);
- return (PurpleValue *)g_hash_table_lookup(status->attr_values, id);
+ return (GValue *)g_hash_table_lookup(priv->attr_values, id);
}
gboolean
purple_status_get_attr_boolean(const PurpleStatus *status, const char *id)
{
- const PurpleValue *value;
+ const GValue *value;
g_return_val_if_fail(status != NULL, FALSE);
g_return_val_if_fail(id != NULL, FALSE);
@@ -984,15 +925,15 @@ purple_status_get_attr_boolean(const PurpleStatus *status, const char *id)
if ((value = purple_status_get_attr_value(status, id)) == NULL)
return FALSE;
- g_return_val_if_fail(purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN, FALSE);
+ g_return_val_if_fail(G_VALUE_TYPE(value) == G_TYPE_BOOLEAN, FALSE);
- return purple_value_get_boolean(value);
+ return g_value_get_boolean(value);
}
int
purple_status_get_attr_int(const PurpleStatus *status, const char *id)
{
- const PurpleValue *value;
+ const GValue *value;
g_return_val_if_fail(status != NULL, 0);
g_return_val_if_fail(id != NULL, 0);
@@ -1000,15 +941,15 @@ purple_status_get_attr_int(const PurpleStatus *status, const char *id)
if ((value = purple_status_get_attr_value(status, id)) == NULL)
return 0;
- g_return_val_if_fail(purple_value_get_type(value) == PURPLE_TYPE_INT, 0);
+ g_return_val_if_fail(G_VALUE_TYPE(value) == G_TYPE_INT, 0);
- return purple_value_get_int(value);
+ return g_value_get_int(value);
}
const char *
purple_status_get_attr_string(const PurpleStatus *status, const char *id)
{
- const PurpleValue *value;
+ const GValue *value;
g_return_val_if_fail(status != NULL, NULL);
g_return_val_if_fail(id != NULL, NULL);
@@ -1016,9 +957,9 @@ purple_status_get_attr_string(const PurpleStatus *status, const char *id)
if ((value = purple_status_get_attr_value(status, id)) == NULL)
return NULL;
- g_return_val_if_fail(purple_value_get_type(value) == PURPLE_TYPE_STRING, NULL);
+ g_return_val_if_fail(G_VALUE_TYPE(value) == G_TYPE_STRING, NULL);
- return purple_value_get_string(value);
+ return g_value_get_string(value);
}
gint
@@ -1037,8 +978,8 @@ purple_status_compare(const PurpleStatus *status1, const PurpleStatus *status2)
else if (status2 == NULL)
return -1;
- type1 = purple_status_get_type(status1);
- type2 = purple_status_get_type(status2);
+ type1 = purple_status_get_status_type(status1);
+ type2 = purple_status_get_status_type(status2);
if (purple_status_is_active(status1))
score1 = primitive_scores[purple_status_type_get_primitive(type1)];
@@ -1056,525 +997,302 @@ purple_status_compare(const PurpleStatus *status1, const PurpleStatus *status2)
/**************************************************************************
-* PurplePresence API
+* GBoxed code for PurpleStatusType
**************************************************************************/
-PurplePresence *
-purple_presence_new(PurplePresenceContext context)
-{
- PurplePresence *presence;
-
- g_return_val_if_fail(context != PURPLE_PRESENCE_CONTEXT_UNSET, NULL);
-
- presence = g_new0(PurplePresence, 1);
- PURPLE_DBUS_REGISTER_POINTER(presence, PurplePresence);
-
- presence->context = context;
-
- presence->status_table =
- g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, NULL);
-
- return presence;
-}
-
-PurplePresence *
-purple_presence_new_for_account(PurpleAccount *account)
+static PurpleStatusType *
+purple_status_type_copy(PurpleStatusType *status_type)
{
- PurplePresence *presence = NULL;
- g_return_val_if_fail(account != NULL, NULL);
-
- presence = purple_presence_new(PURPLE_PRESENCE_CONTEXT_ACCOUNT);
- presence->u.account = account;
- presence->statuses = purple_prpl_get_statuses(account, presence);
-
- return presence;
-}
-
-PurplePresence *
-purple_presence_new_for_conv(PurpleConversation *conv)
-{
- PurplePresence *presence;
-
- g_return_val_if_fail(conv != NULL, NULL);
-
- presence = purple_presence_new(PURPLE_PRESENCE_CONTEXT_CONV);
- presence->u.chat.conv = conv;
- /* presence->statuses = purple_prpl_get_statuses(purple_conversation_get_account(conv), presence); ? */
-
- return presence;
-}
-
-PurplePresence *
-purple_presence_new_for_buddy(PurpleBuddy *buddy)
-{
- PurplePresence *presence;
- PurpleAccount *account;
-
- g_return_val_if_fail(buddy != NULL, NULL);
- account = purple_buddy_get_account(buddy);
-
- presence = purple_presence_new(PURPLE_PRESENCE_CONTEXT_BUDDY);
+ PurpleStatusType *status_type_copy;
+ GList *l;
- presence->u.buddy.name = g_strdup(purple_buddy_get_name(buddy));
- presence->u.buddy.account = account;
- presence->statuses = purple_prpl_get_statuses(account, presence);
+ g_return_val_if_fail(status_type != NULL, NULL);
- presence->u.buddy.buddy = buddy;
+ status_type_copy = purple_status_type_new_full(status_type->primitive,
+ status_type->id,
+ status_type->name,
+ status_type->saveable,
+ status_type->user_settable,
+ status_type->independent);
- return presence;
-}
+ for (l = status_type->attrs; l != NULL; l = l->next) {
+ PurpleStatusAttribute *new_attr, *attr = l->data;
-void
-purple_presence_destroy(PurplePresence *presence)
-{
- g_return_if_fail(presence != NULL);
-
- if (purple_presence_get_context(presence) == PURPLE_PRESENCE_CONTEXT_BUDDY)
- {
- g_free(presence->u.buddy.name);
+ new_attr = g_boxed_copy(PURPLE_TYPE_STATUS_ATTRIBUTE, attr);
+ status_type_copy->attrs = g_list_append(status_type_copy->attrs, new_attr);
}
- else if (purple_presence_get_context(presence) == PURPLE_PRESENCE_CONTEXT_CONV)
- {
- g_free(presence->u.chat.user);
- }
-
- g_list_foreach(presence->statuses, (GFunc)purple_status_destroy, NULL);
- g_list_free(presence->statuses);
-
- g_hash_table_destroy(presence->status_table);
- PURPLE_DBUS_UNREGISTER_POINTER(presence);
- g_free(presence);
+ return status_type_copy;
}
-void
-purple_presence_set_status_active(PurplePresence *presence, const char *status_id,
- gboolean active)
+GType
+purple_status_type_get_type(void)
{
- PurpleStatus *status;
-
- g_return_if_fail(presence != NULL);
- g_return_if_fail(status_id != NULL);
+ static GType type = 0;
- status = purple_presence_get_status(presence, status_id);
-
- g_return_if_fail(status != NULL);
- /* TODO: Should we do the following? */
- /* g_return_if_fail(active == status->active); */
-
- if (purple_status_is_exclusive(status))
- {
- if (!active)
- {
- purple_debug_warning("status",
- "Attempted to set a non-independent status "
- "(%s) inactive. Only independent statuses "
- "can be specifically marked inactive.",
- status_id);
- return;
- }
+ if (type == 0) {
+ type = g_boxed_type_register_static("PurpleStatusType",
+ (GBoxedCopyFunc)purple_status_type_copy,
+ (GBoxedFreeFunc)purple_status_type_destroy);
}
- purple_status_set_active(status, active);
-}
-
-void
-purple_presence_switch_status(PurplePresence *presence, const char *status_id)
-{
- purple_presence_set_status_active(presence, status_id, TRUE);
+ return type;
}
-static void
-update_buddy_idle(PurpleBuddy *buddy, PurplePresence *presence,
- time_t current_time, gboolean old_idle, gboolean idle)
+/**************************************************************************
+* GBoxed code for PurpleStatusAttribute
+**************************************************************************/
+static PurpleStatusAttribute *
+purple_status_attribute_copy(PurpleStatusAttribute *status_attr)
{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- PurpleAccount *account = purple_buddy_get_account(buddy);
-
- if (!old_idle && idle)
- {
- if (purple_prefs_get_bool("/purple/logging/log_system"))
- {
- PurpleLog *log = purple_account_get_log(account, FALSE);
-
- if (log != NULL)
- {
- char *tmp, *tmp2;
- tmp = g_strdup_printf(_("%s became idle"),
- purple_buddy_get_alias(buddy));
- tmp2 = g_markup_escape_text(tmp, -1);
- g_free(tmp);
-
- purple_log_write(log, PURPLE_MESSAGE_SYSTEM,
- purple_buddy_get_alias(buddy), current_time, tmp2);
- g_free(tmp2);
- }
- }
- }
- else if (old_idle && !idle)
- {
- if (purple_prefs_get_bool("/purple/logging/log_system"))
- {
- PurpleLog *log = purple_account_get_log(account, FALSE);
+ g_return_val_if_fail(status_attr != NULL, NULL);
- if (log != NULL)
- {
- char *tmp, *tmp2;
- tmp = g_strdup_printf(_("%s became unidle"),
- purple_buddy_get_alias(buddy));
- tmp2 = g_markup_escape_text(tmp, -1);
- g_free(tmp);
-
- purple_log_write(log, PURPLE_MESSAGE_SYSTEM,
- purple_buddy_get_alias(buddy), current_time, tmp2);
- g_free(tmp2);
- }
- }
- }
-
- if (old_idle != idle)
- purple_signal_emit(purple_blist_get_handle(), "buddy-idle-changed", buddy,
- old_idle, idle);
-
- purple_contact_invalidate_priority_buddy(purple_buddy_get_contact(buddy));
-
- /* Should this be done here? It'd perhaps make more sense to
- * connect to buddy-[un]idle signals and update from there
- */
-
- if (ops != NULL && ops->update != NULL)
- ops->update(purple_get_blist(), (PurpleBlistNode *)buddy);
+ return purple_status_attribute_new(status_attr->id,
+ status_attr->name,
+ purple_g_value_dup(status_attr->value_type));
}
-void
-purple_presence_set_idle(PurplePresence *presence, gboolean idle, time_t idle_time)
+GType
+purple_status_attribute_get_type(void)
{
- gboolean old_idle;
- time_t current_time;
-
- g_return_if_fail(presence != NULL);
-
- if (presence->idle == idle && presence->idle_time == idle_time)
- return;
-
- old_idle = presence->idle;
- presence->idle = idle;
- presence->idle_time = (idle ? idle_time : 0);
-
- current_time = time(NULL);
-
- if (purple_presence_get_context(presence) == PURPLE_PRESENCE_CONTEXT_BUDDY)
- {
- update_buddy_idle(purple_presence_get_buddy(presence), presence, current_time,
- old_idle, idle);
- }
- else if (purple_presence_get_context(presence) == PURPLE_PRESENCE_CONTEXT_ACCOUNT)
- {
- PurpleAccount *account;
- PurpleConnection *gc = NULL;
- PurplePlugin *prpl = NULL;
- PurplePluginProtocolInfo *prpl_info = NULL;
-
- account = purple_presence_get_account(presence);
-
- if (purple_prefs_get_bool("/purple/logging/log_system"))
- {
- PurpleLog *log = purple_account_get_log(account, FALSE);
-
- if (log != NULL)
- {
- char *msg, *tmp;
-
- if (idle)
- tmp = g_strdup_printf(_("+++ %s became idle"), purple_account_get_username(account));
- else
- tmp = g_strdup_printf(_("+++ %s became unidle"), purple_account_get_username(account));
-
- msg = g_markup_escape_text(tmp, -1);
- g_free(tmp);
- purple_log_write(log, PURPLE_MESSAGE_SYSTEM,
- purple_account_get_username(account),
- (idle ? idle_time : current_time), msg);
- g_free(msg);
- }
- }
-
- gc = purple_account_get_connection(account);
-
- if(gc)
- prpl = purple_connection_get_prpl(gc);
+ static GType type = 0;
- if(PURPLE_CONNECTION_IS_CONNECTED(gc) && prpl != NULL)
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
-
- if (prpl_info && prpl_info->set_idle)
- prpl_info->set_idle(gc, (idle ? (current_time - idle_time) : 0));
+ if (type == 0) {
+ type = g_boxed_type_register_static("PurpleStatusAttribute",
+ (GBoxedCopyFunc)purple_status_attribute_copy,
+ (GBoxedFreeFunc)purple_status_attribute_destroy);
}
-}
-
-void
-purple_presence_set_login_time(PurplePresence *presence, time_t login_time)
-{
- g_return_if_fail(presence != NULL);
-
- if (presence->login_time == login_time)
- return;
-
- presence->login_time = login_time;
-}
-
-PurplePresenceContext
-purple_presence_get_context(const PurplePresence *presence)
-{
- g_return_val_if_fail(presence != NULL, PURPLE_PRESENCE_CONTEXT_UNSET);
-
- return presence->context;
-}
-
-PurpleAccount *
-purple_presence_get_account(const PurplePresence *presence)
-{
- PurplePresenceContext context;
-
- g_return_val_if_fail(presence != NULL, NULL);
-
- context = purple_presence_get_context(presence);
- g_return_val_if_fail(context == PURPLE_PRESENCE_CONTEXT_ACCOUNT ||
- context == PURPLE_PRESENCE_CONTEXT_BUDDY, NULL);
-
- return presence->u.account;
+ return type;
}
-PurpleConversation *
-purple_presence_get_conversation(const PurplePresence *presence)
+/**************************************************************************
+* GBoxed code for PurpleMood
+**************************************************************************/
+static PurpleMood *
+purple_mood_copy(PurpleMood *mood)
{
- g_return_val_if_fail(presence != NULL, NULL);
- g_return_val_if_fail(purple_presence_get_context(presence) ==
- PURPLE_PRESENCE_CONTEXT_CONV, NULL);
+ PurpleMood *mood_copy;
- return presence->u.chat.conv;
-}
+ g_return_val_if_fail(mood != NULL, NULL);
-const char *
-purple_presence_get_chat_user(const PurplePresence *presence)
-{
- g_return_val_if_fail(presence != NULL, NULL);
- g_return_val_if_fail(purple_presence_get_context(presence) ==
- PURPLE_PRESENCE_CONTEXT_CONV, NULL);
-
- return presence->u.chat.user;
-}
+ mood_copy = g_new(PurpleMood, 1);
-PurpleBuddy *
-purple_presence_get_buddy(const PurplePresence *presence)
-{
- g_return_val_if_fail(presence != NULL, NULL);
- g_return_val_if_fail(purple_presence_get_context(presence) ==
- PURPLE_PRESENCE_CONTEXT_BUDDY, NULL);
+ mood_copy->mood = g_strdup(mood->mood);
+ mood_copy->description = g_strdup(mood->description);
- return presence->u.buddy.buddy;
+ return mood_copy;
}
-GList *
-purple_presence_get_statuses(const PurplePresence *presence)
+static void
+purple_mood_free(PurpleMood *mood)
{
- g_return_val_if_fail(presence != NULL, NULL);
+ g_free((gchar *)mood->mood);
+ g_free((gchar *)mood->description);
- return presence->statuses;
+ g_free(mood);
}
-PurpleStatus *
-purple_presence_get_status(const PurplePresence *presence, const char *status_id)
+GType
+purple_mood_get_type(void)
{
- PurpleStatus *status;
- GList *l = NULL;
-
- g_return_val_if_fail(presence != NULL, NULL);
- g_return_val_if_fail(status_id != NULL, NULL);
+ static GType type = 0;
- /* What's the purpose of this hash table? */
- status = (PurpleStatus *)g_hash_table_lookup(presence->status_table,
- status_id);
-
- if (status == NULL) {
- for (l = purple_presence_get_statuses(presence);
- l != NULL && status == NULL; l = l->next)
- {
- PurpleStatus *temp_status = l->data;
-
- if (purple_strequal(status_id, purple_status_get_id(temp_status)))
- status = temp_status;
- }
-
- if (status != NULL)
- g_hash_table_insert(presence->status_table,
- g_strdup(purple_status_get_id(status)), status);
+ if (type == 0) {
+ type = g_boxed_type_register_static("PurpleMood",
+ (GBoxedCopyFunc)purple_mood_copy,
+ (GBoxedFreeFunc)purple_mood_free);
}
- return status;
+ return type;
}
-PurpleStatus *
-purple_presence_get_active_status(const PurplePresence *presence)
-{
- g_return_val_if_fail(presence != NULL, NULL);
-
- return presence->active_status;
-}
-gboolean
-purple_presence_is_available(const PurplePresence *presence)
-{
- PurpleStatus *status;
-
- g_return_val_if_fail(presence != NULL, FALSE);
+/**************************************************************************
+* GObject code
+**************************************************************************/
- status = purple_presence_get_active_status(presence);
+/* GObject Property names */
+#define PROP_STATUS_TYPE_S "status-type"
+#define PROP_PRESENCE_S "presence"
+#define PROP_ACTIVE_S "active"
- return ((status != NULL && purple_status_is_available(status)) &&
- !purple_presence_is_idle(presence));
+/* Set method for GObject properties */
+static void
+purple_status_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleStatus *status = PURPLE_STATUS(obj);
+ PurpleStatusPrivate *priv = PURPLE_STATUS_GET_PRIVATE(status);
+
+ switch (param_id) {
+ case PROP_STATUS_TYPE:
+ priv->status_type = g_value_get_pointer(value);
+ break;
+ case PROP_PRESENCE:
+ priv->presence = g_value_get_object(value);
+ break;
+ case PROP_ACTIVE:
+ purple_status_set_active(status, g_value_get_boolean(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
}
-gboolean
-purple_presence_is_online(const PurplePresence *presence)
-{
- PurpleStatus *status;
-
- g_return_val_if_fail(presence != NULL, FALSE);
-
- if ((status = purple_presence_get_active_status(presence)) == NULL)
- return FALSE;
-
- return purple_status_is_online(status);
+/* Get method for GObject properties */
+static void
+purple_status_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleStatus *status = PURPLE_STATUS(obj);
+
+ switch (param_id) {
+ case PROP_STATUS_TYPE:
+ g_value_set_pointer(value, purple_status_get_status_type(status));
+ break;
+ case PROP_PRESENCE:
+ g_value_set_object(value, purple_status_get_presence(status));
+ break;
+ case PROP_ACTIVE:
+ g_value_set_boolean(value, purple_status_is_active(status));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
}
-gboolean
-purple_presence_is_status_active(const PurplePresence *presence,
- const char *status_id)
+/* GObject initialization function */
+static void
+purple_status_init(GTypeInstance *instance, gpointer klass)
{
- PurpleStatus *status;
+ PurpleStatus *status = PURPLE_STATUS(instance);
- g_return_val_if_fail(presence != NULL, FALSE);
- g_return_val_if_fail(status_id != NULL, FALSE);
-
- status = purple_presence_get_status(presence, status_id);
+ PURPLE_DBUS_REGISTER_POINTER(status, PurpleStatus);
- return (status != NULL && purple_status_is_active(status));
+ PURPLE_STATUS_GET_PRIVATE(status)->attr_values =
+ g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify)purple_g_value_free);
}
-gboolean
-purple_presence_is_status_primitive_active(const PurplePresence *presence,
- PurpleStatusPrimitive primitive)
+/* Called when done constructing */
+static void
+purple_status_constructed(GObject *object)
{
GList *l;
+ PurpleStatusPrivate *priv = PURPLE_STATUS_GET_PRIVATE(object);
- g_return_val_if_fail(presence != NULL, FALSE);
- g_return_val_if_fail(primitive != PURPLE_STATUS_UNSET, FALSE);
+ parent_class->constructed(object);
- for (l = purple_presence_get_statuses(presence);
- l != NULL; l = l->next)
+ for (l = purple_status_type_get_attrs(priv->status_type); l != NULL; l = l->next)
{
- PurpleStatus *temp_status = l->data;
- PurpleStatusType *type = purple_status_get_type(temp_status);
+ PurpleStatusAttribute *attr = (PurpleStatusAttribute *)l->data;
+ GValue *value = purple_status_attribute_get_value(attr);
+ GValue *new_value = purple_g_value_dup(value);
- if (purple_status_type_get_primitive(type) == primitive &&
- purple_status_is_active(temp_status))
- return TRUE;
+ g_hash_table_insert(priv->attr_values,
+ (char *)purple_status_attribute_get_id(attr),
+ new_value);
}
- return FALSE;
-}
-
-gboolean
-purple_presence_is_idle(const PurplePresence *presence)
-{
- g_return_val_if_fail(presence != NULL, FALSE);
-
- return purple_presence_is_online(presence) && presence->idle;
}
-time_t
-purple_presence_get_idle_time(const PurplePresence *presence)
+/*
+ * GObject dispose function
+ * TODO: If the PurpleStatus is in a PurplePresence, then
+ * remove it from the PurplePresence?
+ */
+static void
+purple_status_dispose(GObject *object)
{
- g_return_val_if_fail(presence != NULL, 0);
+ PURPLE_DBUS_UNREGISTER_POINTER(object);
- return presence->idle_time;
+ parent_class->dispose(object);
}
-time_t
-purple_presence_get_login_time(const PurplePresence *presence)
+/* GObject finalize function */
+static void
+purple_status_finalize(GObject *object)
{
- g_return_val_if_fail(presence != NULL, 0);
+ g_hash_table_destroy(PURPLE_STATUS_GET_PRIVATE(object)->attr_values);
- return purple_presence_is_online(presence) ? presence->login_time : 0;
+ parent_class->finalize(object);
}
-static int
-purple_presence_compute_score(const PurplePresence *presence)
-{
- GList *l;
- int score = 0;
-
- for (l = purple_presence_get_statuses(presence); l != NULL; l = l->next) {
- PurpleStatus *status = (PurpleStatus *)l->data;
- PurpleStatusType *type = purple_status_get_type(status);
-
- if (purple_status_is_active(status)) {
- score += primitive_scores[purple_status_type_get_primitive(type)];
- if (!purple_status_is_online(status)) {
- PurpleBuddy *b = purple_presence_get_buddy(presence);
- if (b && purple_account_supports_offline_message(purple_buddy_get_account(b), b))
- score += primitive_scores[SCORE_OFFLINE_MESSAGE];
- }
- }
+/* Class initializer function */
+static void
+purple_status_class_init(PurpleStatusClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->dispose = purple_status_dispose;
+ obj_class->finalize = purple_status_finalize;
+ obj_class->constructed = purple_status_constructed;
+
+ /* Setup properties */
+ obj_class->get_property = purple_status_get_property;
+ obj_class->set_property = purple_status_set_property;
+
+ g_object_class_install_property(obj_class, PROP_STATUS_TYPE,
+ g_param_spec_pointer(PROP_STATUS_TYPE_S, _("Status type"),
+ _("The PurpleStatusType of the status."),
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)
+ );
+
+ g_object_class_install_property(obj_class, PROP_PRESENCE,
+ g_param_spec_object(PROP_PRESENCE_S, _("Presence"),
+ _("The presence that the status belongs to."), PURPLE_TYPE_PRESENCE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)
+ );
+
+ g_object_class_install_property(obj_class, PROP_ACTIVE,
+ g_param_spec_boolean(PROP_ACTIVE_S, _("Active"),
+ _("Whether the status is active or not."), FALSE,
+ G_PARAM_READWRITE)
+ );
+
+ g_type_class_add_private(klass, sizeof(PurpleStatusPrivate));
+}
+
+GType
+purple_status_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleStatusClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_status_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleStatus),
+ 0,
+ (GInstanceInitFunc)purple_status_init,
+ NULL,
+ };
+
+ type = g_type_register_static(G_TYPE_OBJECT,
+ "PurpleStatus",
+ &info, 0);
}
- score += purple_account_get_int(purple_presence_get_account(presence), "score", 0);
- if (purple_presence_is_idle(presence))
- score += primitive_scores[SCORE_IDLE];
- return score;
+
+ return type;
}
-gint
-purple_presence_compare(const PurplePresence *presence1,
- const PurplePresence *presence2)
+PurpleStatus *
+purple_status_new(PurpleStatusType *status_type, PurplePresence *presence)
{
- time_t idle_time_1, idle_time_2;
- int score1 = 0, score2 = 0;
-
- if (presence1 == presence2)
- return 0;
- else if (presence1 == NULL)
- return 1;
- else if (presence2 == NULL)
- return -1;
-
- if (purple_presence_is_online(presence1) &&
- !purple_presence_is_online(presence2))
- return -1;
- else if (purple_presence_is_online(presence2) &&
- !purple_presence_is_online(presence1))
- return 1;
-
- /* Compute the score of the first set of statuses. */
- score1 = purple_presence_compute_score(presence1);
-
- /* Compute the score of the second set of statuses. */
- score2 = purple_presence_compute_score(presence2);
-
- idle_time_1 = time(NULL) - purple_presence_get_idle_time(presence1);
- idle_time_2 = time(NULL) - purple_presence_get_idle_time(presence2);
-
- if (idle_time_1 > idle_time_2)
- score1 += primitive_scores[SCORE_IDLE_TIME];
- else if (idle_time_1 < idle_time_2)
- score2 += primitive_scores[SCORE_IDLE_TIME];
-
- if (score1 < score2)
- return 1;
- else if (score1 > score2)
- return -1;
+ g_return_val_if_fail(status_type != NULL, NULL);
+ g_return_val_if_fail(presence != NULL, NULL);
- return 0;
+ return g_object_new(PURPLE_TYPE_STATUS,
+ PROP_STATUS_TYPE_S, status_type,
+ PROP_PRESENCE_S, presence,
+ NULL);
}
@@ -1591,16 +1309,16 @@ score_pref_changed_cb(const char *name, PurplePrefType type,
}
void *
-purple_status_get_handle(void) {
+purple_statuses_get_handle(void) {
static int handle;
return &handle;
}
void
-purple_status_init(void)
+purple_statuses_init(void)
{
- void *handle = purple_status_get_handle();
+ void *handle = purple_statuses_get_handle();
purple_prefs_add_none("/purple/status");
purple_prefs_add_none("/purple/status/scores");
@@ -1617,6 +1335,8 @@ purple_status_init(void)
primitive_scores[PURPLE_STATUS_EXTENDED_AWAY]);
purple_prefs_add_int("/purple/status/scores/idle",
primitive_scores[SCORE_IDLE]);
+ purple_prefs_add_int("/purple/status/scores/idle_time",
+ primitive_scores[SCORE_IDLE_TIME]);
purple_prefs_add_int("/purple/status/scores/offline_msg",
primitive_scores[SCORE_OFFLINE_MESSAGE]);
@@ -1638,6 +1358,9 @@ purple_status_init(void)
purple_prefs_connect_callback(handle, "/purple/status/scores/idle",
score_pref_changed_cb,
GINT_TO_POINTER(SCORE_IDLE));
+ purple_prefs_connect_callback(handle, "/purple/status/scores/idle_time",
+ score_pref_changed_cb,
+ GINT_TO_POINTER(SCORE_IDLE_TIME));
purple_prefs_connect_callback(handle, "/purple/status/scores/offline_msg",
score_pref_changed_cb,
GINT_TO_POINTER(SCORE_OFFLINE_MESSAGE));
@@ -1648,11 +1371,12 @@ purple_status_init(void)
purple_prefs_trigger_callback("/purple/status/scores/away");
purple_prefs_trigger_callback("/purple/status/scores/extended_away");
purple_prefs_trigger_callback("/purple/status/scores/idle");
+ purple_prefs_trigger_callback("/purple/status/scores/idle_time");
purple_prefs_trigger_callback("/purple/status/scores/offline_msg");
}
void
-purple_status_uninit(void)
+purple_statuses_uninit(void)
{
purple_prefs_disconnect_by_handle(purple_prefs_get_handle());
}
diff --git a/libpurple/status.h b/libpurple/status.h
index 6c7e525776..694948b180 100644
--- a/libpurple/status.h
+++ b/libpurple/status.h
@@ -1,3 +1,7 @@
+/**
+ * @file status.h Status API
+ * @ingroup core
+ */
/*
* purple
*
@@ -22,10 +26,7 @@
#ifndef _PURPLE_STATUS_H_
#define _PURPLE_STATUS_H_
-/**
- * @file status.h Status API
- * @ingroup core
- *
+/*
* A brief explanation of the status API:
*
* PurpleStatusType's are created by each PRPL. They outline the
@@ -54,7 +55,6 @@
* If "saveable" is set to FALSE then the status is NEVER saved.
* All PurpleStatuses should be inside a PurplePresence.
*
- *
* A PurpleStatus is either "independent" or "exclusive."
* Independent statuses can be active or inactive and they don't
* affect anything else. However, you can only have one exclusive
@@ -62,14 +62,9 @@
* then the previous exclusive status is automatically deactivated.
*
* A PurplePresence is like a collection of PurpleStatuses (plus some
- * other random info). For any buddy, or for any one of your accounts,
- * or for any person with which you're chatting, you may know various
- * amounts of information. This information is all contained in
- * one PurplePresence. If one of your buddies is away and idle,
- * then the presence contains the PurpleStatus for their awayness,
- * and it contains their current idle time. PurplePresences are
- * never saved to disk. The information they contain is only relevant
- * for the current PurpleSession.
+ * other random info).
+ *
+ * @see presence.h
*/
/**
@@ -82,10 +77,27 @@
* hardcoded in each PRPL and will not change often. And because
* they are hardcoded, they do not need to be saved to any XML file.
*/
-typedef struct _PurpleStatusType PurpleStatusType;
-typedef struct _PurpleStatusAttr PurpleStatusAttr;
-typedef struct _PurplePresence PurplePresence;
-typedef struct _PurpleStatus PurpleStatus;
+#define PURPLE_TYPE_STATUS (purple_status_get_type())
+#define PURPLE_STATUS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_STATUS, PurpleStatus))
+#define PURPLE_STATUS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_STATUS, PurpleStatusClass))
+#define PURPLE_IS_STATUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_STATUS))
+#define PURPLE_IS_STATUS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_STATUS))
+#define PURPLE_STATUS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_STATUS, PurpleStatusClass))
+
+/** @copydoc _PurpleStatus */
+typedef struct _PurpleStatus PurpleStatus;
+/** @copydoc _PurpleStatusClass */
+typedef struct _PurpleStatusClass PurpleStatusClass;
+
+#define PURPLE_TYPE_STATUS_TYPE (purple_status_type_get_type())
+
+typedef struct _PurpleStatusType PurpleStatusType;
+
+#define PURPLE_TYPE_STATUS_ATTRIBUTE (purple_status_attribute_get_type())
+
+typedef struct _PurpleStatusAttribute PurpleStatusAttribute;
+
+#define PURPLE_TYPE_MOOD (purple_mood_get_type())
typedef struct _PurpleMood {
const char *mood;
@@ -94,20 +106,6 @@ typedef struct _PurpleMood {
} PurpleMood;
/**
- * A context for a presence.
- *
- * The context indicates to what the presence applies.
- */
-typedef enum
-{
- PURPLE_PRESENCE_CONTEXT_UNSET = 0,
- PURPLE_PRESENCE_CONTEXT_ACCOUNT,
- PURPLE_PRESENCE_CONTEXT_CONV,
- PURPLE_PRESENCE_CONTEXT_BUDDY
-
-} PurplePresenceContext;
-
-/**
* A primitive defining the basic structure of a status type.
*/
/*
@@ -129,10 +127,7 @@ typedef enum
PURPLE_STATUS_NUM_PRIMITIVES
} PurpleStatusPrimitive;
-#include "account.h"
-#include "blist.h"
-#include "conversation.h"
-#include "value.h"
+#include "presence.h"
#define PURPLE_TUNE_ARTIST "tune_artist"
#define PURPLE_TUNE_TITLE "tune_title"
@@ -148,6 +143,26 @@ typedef enum
#define PURPLE_MOOD_NAME "mood"
#define PURPLE_MOOD_COMMENT "moodtext"
+/**
+ * Represents an active status.
+ */
+struct _PurpleStatus
+{
+ /*< private >*/
+ GObject gparent;
+};
+
+/** Base class for all #PurpleStatus's */
+struct _PurpleStatusClass {
+ /*< private >*/
+ GObjectClass parent_class;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
G_BEGIN_DECLS
/**************************************************************************/
@@ -194,6 +209,11 @@ PurpleStatusPrimitive purple_primitive_get_type_from_id(const char *id);
/*@{*/
/**
+ * Returns the GType for the PurpleStatusType boxed structure.
+ */
+GType purple_status_type_get_type(void);
+
+/**
* Creates a new status type.
*
* @param primitive The primitive status type.
@@ -247,7 +267,7 @@ PurpleStatusType *purple_status_type_new(PurpleStatusPrimitive primitive,
* status type.
* @param attr_id The ID of the first attribute.
* @param attr_name The name of the first attribute.
- * @param attr_value The value type of the first attribute attribute.
+ * @param attr_value The value type of the first attribute.
* @param ... Additional attribute information.
*
* @return A new status type.
@@ -260,7 +280,7 @@ PurpleStatusType *purple_status_type_new_with_attrs(PurpleStatusPrimitive primit
gboolean independent,
const char *attr_id,
const char *attr_name,
- PurpleValue *attr_value, ...) G_GNUC_NULL_TERMINATED;
+ GValue *attr_value, ...) G_GNUC_NULL_TERMINATED;
/**
* Destroys a status type.
@@ -358,7 +378,7 @@ gboolean purple_status_type_is_available(const PurpleStatusType *status_type);
*
* @return The attribute, if found. NULL otherwise.
*/
-PurpleStatusAttr *purple_status_type_get_attr(const PurpleStatusType *status_type,
+PurpleStatusAttribute *purple_status_type_get_attr(const PurpleStatusType *status_type,
const char *id);
/**
@@ -385,11 +405,16 @@ const PurpleStatusType *purple_status_type_find_with_id(GList *status_types,
/*@}*/
/**************************************************************************/
-/** @name PurpleStatusAttr API */
+/** @name PurpleStatusAttribute API */
/**************************************************************************/
/*@{*/
/**
+ * Returns the GType for the PurpleStatusAttribute boxed structure.
+ */
+GType purple_status_attribute_get_type(void);
+
+/**
* Creates a new status attribute.
*
* @param id The ID of the attribute.
@@ -398,15 +423,15 @@ const PurpleStatusType *purple_status_type_find_with_id(GList *status_types,
*
* @return A new status attribute.
*/
-PurpleStatusAttr *purple_status_attr_new(const char *id, const char *name,
- PurpleValue *value_type);
+PurpleStatusAttribute *purple_status_attribute_new(const char *id, const char *name,
+ GValue *value_type);
/**
* Destroys a status attribute.
*
* @param attr The status attribute to destroy.
*/
-void purple_status_attr_destroy(PurpleStatusAttr *attr);
+void purple_status_attribute_destroy(PurpleStatusAttribute *attr);
/**
* Returns the ID of a status attribute.
@@ -415,7 +440,7 @@ void purple_status_attr_destroy(PurpleStatusAttr *attr);
*
* @return The status attribute's ID.
*/
-const char *purple_status_attr_get_id(const PurpleStatusAttr *attr);
+const char *purple_status_attribute_get_id(const PurpleStatusAttribute *attr);
/**
* Returns the name of a status attribute.
@@ -424,7 +449,7 @@ const char *purple_status_attr_get_id(const PurpleStatusAttr *attr);
*
* @return The status attribute's name.
*/
-const char *purple_status_attr_get_name(const PurpleStatusAttr *attr);
+const char *purple_status_attribute_get_name(const PurpleStatusAttribute *attr);
/**
* Returns the value of a status attribute.
@@ -433,16 +458,33 @@ const char *purple_status_attr_get_name(const PurpleStatusAttr *attr);
*
* @return The status attribute's value.
*/
-PurpleValue *purple_status_attr_get_value(const PurpleStatusAttr *attr);
+GValue *purple_status_attribute_get_value(const PurpleStatusAttribute *attr);
/*@}*/
/**************************************************************************/
-/** @name PurpleStatus API */
+/** @name PurpleMood API */
/**************************************************************************/
/*@{*/
/**
+ * Returns the GType for the PurpleMood boxed structure.
+ */
+GType purple_mood_get_type(void);
+
+/*@}*/
+
+/**************************************************************************/
+/** @name PurpleStatus API */
+/**************************************************************************/
+/*@{*/
+
+/**
+ * Returns the GType for the Status object.
+ */
+GType purple_status_get_type(void);
+
+/**
* Creates a new status.
*
* @param status_type The type of status.
@@ -454,13 +496,6 @@ PurpleStatus *purple_status_new(PurpleStatusType *status_type,
PurplePresence *presence);
/**
- * Destroys a status.
- *
- * @param status The status to destroy.
- */
-void purple_status_destroy(PurpleStatus *status);
-
-/**
* Sets whether or not a status is active.
*
* This should only be called by the account, conversation, and buddy APIs.
@@ -507,7 +542,7 @@ void purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean act
*
* @return The status's type.
*/
-PurpleStatusType *purple_status_get_type(const PurpleStatus *status);
+PurpleStatusType *purple_status_get_status_type(const PurpleStatus *status);
/**
* Returns the status's presence.
@@ -606,7 +641,7 @@ gboolean purple_status_is_online(const PurpleStatus *status);
*
* @return The value of the attribute.
*/
-PurpleValue *purple_status_get_attr_value(const PurpleStatus *status,
+GValue *purple_status_get_attr_value(const PurpleStatus *status,
const char *id);
/**
@@ -656,271 +691,7 @@ gint purple_status_compare(const PurpleStatus *status1, const PurpleStatus *stat
/*@}*/
/**************************************************************************/
-/** @name PurplePresence API */
-/**************************************************************************/
-/*@{*/
-
-/**
- * Creates a new presence.
- *
- * @param context The presence context.
- *
- * @return A new presence.
- */
-PurplePresence *purple_presence_new(PurplePresenceContext context);
-
-/**
- * Creates a presence for an account.
- *
- * @param account The account.
- *
- * @return The new presence.
- */
-PurplePresence *purple_presence_new_for_account(PurpleAccount *account);
-
-/**
- * Creates a presence for a conversation.
- *
- * @param conv The conversation.
- *
- * @return The new presence.
- */
-PurplePresence *purple_presence_new_for_conv(PurpleConversation *conv);
-
-/**
- * Creates a presence for a buddy.
- *
- * @param buddy The buddy.
- *
- * @return The new presence.
- */
-PurplePresence *purple_presence_new_for_buddy(PurpleBuddy *buddy);
-
-/**
- * Destroys a presence.
- *
- * All statuses added to this list will be destroyed along with
- * the presence.
- *
- * @param presence The presence to destroy.
- */
-void purple_presence_destroy(PurplePresence *presence);
-
-/**
- * Sets the active state of a status in a presence.
- *
- * Only independent statuses can be set unactive. Normal statuses can only
- * be set active, so if you wish to disable a status, set another
- * non-independent status to active, or use purple_presence_switch_status().
- *
- * @param presence The presence.
- * @param status_id The ID of the status.
- * @param active The active state.
- */
-void purple_presence_set_status_active(PurplePresence *presence,
- const char *status_id, gboolean active);
-
-/**
- * Switches the active status in a presence.
- *
- * This is similar to purple_presence_set_status_active(), except it won't
- * activate independent statuses.
- *
- * @param presence The presence.
- * @param status_id The status ID to switch to.
- */
-void purple_presence_switch_status(PurplePresence *presence,
- const char *status_id);
-
-/**
- * Sets the idle state and time on a presence.
- *
- * @param presence The presence.
- * @param idle The idle state.
- * @param idle_time The idle time, if @a idle is TRUE. This
- * is the time at which the user became idle,
- * in seconds since the epoch. If this value is
- * unknown then 0 should be used.
- */
-void purple_presence_set_idle(PurplePresence *presence, gboolean idle,
- time_t idle_time);
-
-/**
- * Sets the login time on a presence.
- *
- * @param presence The presence.
- * @param login_time The login time.
- */
-void purple_presence_set_login_time(PurplePresence *presence, time_t login_time);
-
-
-/**
- * Returns the presence's context.
- *
- * @param presence The presence.
- *
- * @return The presence's context.
- */
-PurplePresenceContext purple_presence_get_context(const PurplePresence *presence);
-
-/**
- * Returns a presence's account.
- *
- * @param presence The presence.
- *
- * @return The presence's account.
- */
-PurpleAccount *purple_presence_get_account(const PurplePresence *presence);
-
-/**
- * Returns a presence's conversation.
- *
- * @param presence The presence.
- *
- * @return The presence's conversation.
- */
-PurpleConversation *purple_presence_get_conversation(const PurplePresence *presence);
-
-/**
- * Returns a presence's chat user.
- *
- * @param presence The presence.
- *
- * @return The chat's user.
- */
-const char *purple_presence_get_chat_user(const PurplePresence *presence);
-
-/**
- * Returns the presence's buddy.
- *
- * @param presence The presence.
- *
- * @return The presence's buddy.
- */
-PurpleBuddy *purple_presence_get_buddy(const PurplePresence *presence);
-
-/**
- * Returns all the statuses in a presence.
- *
- * @param presence The presence.
- *
- * @constreturn The statuses.
- */
-GList *purple_presence_get_statuses(const PurplePresence *presence);
-
-/**
- * Returns the status with the specified ID from a presence.
- *
- * @param presence The presence.
- * @param status_id The ID of the status.
- *
- * @return The status if found, or NULL.
- */
-PurpleStatus *purple_presence_get_status(const PurplePresence *presence,
- const char *status_id);
-
-/**
- * Returns the active exclusive status from a presence.
- *
- * @param presence The presence.
- *
- * @return The active exclusive status.
- */
-PurpleStatus *purple_presence_get_active_status(const PurplePresence *presence);
-
-/**
- * Returns whether or not a presence is available.
- *
- * Available presences are online and possibly invisible, but not away or idle.
- *
- * @param presence The presence.
- *
- * @return TRUE if the presence is available, or FALSE otherwise.
- */
-gboolean purple_presence_is_available(const PurplePresence *presence);
-
-/**
- * Returns whether or not a presence is online.
- *
- * @param presence The presence.
- *
- * @return TRUE if the presence is online, or FALSE otherwise.
- */
-gboolean purple_presence_is_online(const PurplePresence *presence);
-
-/**
- * Returns whether or not a status in a presence is active.
- *
- * A status is active if itself or any of its sub-statuses are active.
- *
- * @param presence The presence.
- * @param status_id The ID of the status.
- *
- * @return TRUE if the status is active, or FALSE.
- */
-gboolean purple_presence_is_status_active(const PurplePresence *presence,
- const char *status_id);
-
-/**
- * Returns whether or not a status with the specified primitive type
- * in a presence is active.
- *
- * A status is active if itself or any of its sub-statuses are active.
- *
- * @param presence The presence.
- * @param primitive The status primitive.
- *
- * @return TRUE if the status is active, or FALSE.
- */
-gboolean purple_presence_is_status_primitive_active(
- const PurplePresence *presence, PurpleStatusPrimitive primitive);
-
-/**
- * Returns whether or not a presence is idle.
- *
- * @param presence The presence.
- *
- * @return TRUE if the presence is idle, or FALSE otherwise.
- * If the presence is offline (purple_presence_is_online()
- * returns FALSE) then FALSE is returned.
- */
-gboolean purple_presence_is_idle(const PurplePresence *presence);
-
-/**
- * Returns the presence's idle time.
- *
- * @param presence The presence.
- *
- * @return The presence's idle time.
- */
-time_t purple_presence_get_idle_time(const PurplePresence *presence);
-
-/**
- * Returns the presence's login time.
- *
- * @param presence The presence.
- *
- * @return The presence's login time.
- */
-time_t purple_presence_get_login_time(const PurplePresence *presence);
-
-/**
- * Compares two presences for availability.
- *
- * @param presence1 The first presence.
- * @param presence2 The second presence.
- *
- * @return -1 if @a presence1 is more available than @a presence2.
- * 0 if @a presence1 is equal to @a presence2.
- * 1 if @a presence1 is less available than @a presence2.
- */
-gint purple_presence_compare(const PurplePresence *presence1,
- const PurplePresence *presence2);
-
-/*@}*/
-
-/**************************************************************************/
-/** @name Status subsystem */
+/** @name Statuses subsystem */
/**************************************************************************/
/*@{*/
@@ -929,17 +700,17 @@ gint purple_presence_compare(const PurplePresence *presence1,
*
* @return the handle to the status subsystem
*/
-void *purple_status_get_handle(void);
+void *purple_statuses_get_handle(void);
/**
* Initializes the status subsystem.
*/
-void purple_status_init(void);
+void purple_statuses_init(void);
/**
* Uninitializes the status subsystem.
*/
-void purple_status_uninit(void);
+void purple_statuses_uninit(void);
/*@}*/
diff --git a/libpurple/tests/test_cipher.c b/libpurple/tests/test_cipher.c
index f686f07f64..8f21a6935c 100644
--- a/libpurple/tests/test_cipher.c
+++ b/libpurple/tests/test_cipher.c
@@ -7,28 +7,32 @@
#include "tests.h"
-#include "../cipher.h"
+#include "../ciphers/des3cipher.h"
+#include "../ciphers/descipher.h"
+#include "../ciphers/hmaccipher.h"
+#include "../ciphers/md4hash.h"
+#include "../ciphers/md5hash.h"
+#include "../ciphers/sha1hash.h"
+#include "../ciphers/sha256hash.h"
/******************************************************************************
* MD4 Tests
*****************************************************************************/
#define MD4_TEST(data, digest) { \
- PurpleCipher *cipher = NULL; \
- PurpleCipherContext *context = NULL; \
+ PurpleHash *hash = NULL; \
gchar cdigest[33]; \
gboolean ret = FALSE; \
\
- cipher = purple_ciphers_find_cipher("md4"); \
- context = purple_cipher_context_new(cipher, NULL); \
- purple_cipher_context_append(context, (guchar *)(data), strlen((data))); \
+ hash = purple_md4_hash_new(); \
+ purple_hash_append(hash, (guchar *)(data), strlen((data))); \
\
- ret = purple_cipher_context_digest_to_str(context, cdigest, sizeof(cdigest)); \
+ ret = purple_hash_digest_to_str(hash, cdigest, sizeof(cdigest)); \
\
fail_unless(ret == TRUE, NULL); \
\
fail_unless(strcmp((digest), cdigest) == 0, NULL); \
\
- purple_cipher_context_destroy(context); \
+ g_object_unref(hash); \
}
START_TEST(test_md4_empty_string) {
@@ -75,22 +79,20 @@ END_TEST
* MD5 Tests
*****************************************************************************/
#define MD5_TEST(data, digest) { \
- PurpleCipher *cipher = NULL; \
- PurpleCipherContext *context = NULL; \
+ PurpleHash *hash = NULL; \
gchar cdigest[33]; \
gboolean ret = FALSE; \
\
- cipher = purple_ciphers_find_cipher("md5"); \
- context = purple_cipher_context_new(cipher, NULL); \
- purple_cipher_context_append(context, (guchar *)(data), strlen((data))); \
+ hash = purple_md5_hash_new(); \
+ purple_hash_append(hash, (guchar *)(data), strlen((data))); \
\
- ret = purple_cipher_context_digest_to_str(context, cdigest, sizeof(cdigest)); \
+ ret = purple_hash_digest_to_str(hash, cdigest, sizeof(cdigest)); \
\
fail_unless(ret == TRUE, NULL); \
\
fail_unless(strcmp((digest), cdigest) == 0, NULL); \
\
- purple_cipher_context_destroy(context); \
+ g_object_unref(hash); \
}
START_TEST(test_md5_empty_string) {
@@ -136,17 +138,15 @@ END_TEST
* SHA-1 Tests
*****************************************************************************/
#define SHA1_TEST(data, digest) { \
- PurpleCipher *cipher = NULL; \
- PurpleCipherContext *context = NULL; \
+ PurpleHash *hash = NULL; \
gchar cdigest[41]; \
gboolean ret = FALSE; \
gchar *input = data; \
\
- cipher = purple_ciphers_find_cipher("sha1"); \
- context = purple_cipher_context_new(cipher, NULL); \
+ hash = purple_sha1_hash_new(); \
\
if (input) { \
- purple_cipher_context_append(context, (guchar *)input, strlen(input)); \
+ purple_hash_append(hash, (guchar *)input, strlen(input)); \
} else { \
gint j; \
guchar buff[1000]; \
@@ -154,16 +154,16 @@ END_TEST
memset(buff, 'a', 1000); \
\
for(j = 0; j < 1000; j++) \
- purple_cipher_context_append(context, buff, 1000); \
+ purple_hash_append(hash, buff, 1000); \
} \
\
- ret = purple_cipher_context_digest_to_str(context, cdigest, sizeof(cdigest)); \
+ ret = purple_hash_digest_to_str(hash, cdigest, sizeof(cdigest)); \
\
fail_unless(ret == TRUE, NULL); \
\
fail_unless(strcmp((digest), cdigest) == 0, NULL); \
\
- purple_cipher_context_destroy(context); \
+ g_object_unref(hash); \
}
START_TEST(test_sha1_empty_string) {
@@ -196,17 +196,15 @@ END_TEST
* SHA-256 Tests
*****************************************************************************/
#define SHA256_TEST(data, digest) { \
- PurpleCipher *cipher = NULL; \
- PurpleCipherContext *context = NULL; \
+ PurpleHash *hash = NULL; \
gchar cdigest[65]; \
gboolean ret = FALSE; \
gchar *input = data; \
\
- cipher = purple_ciphers_find_cipher("sha256"); \
- context = purple_cipher_context_new(cipher, NULL); \
+ hash = purple_sha256_hash_new(); \
\
if (input) { \
- purple_cipher_context_append(context, (guchar *)input, strlen(input)); \
+ purple_hash_append(hash, (guchar *)input, strlen(input)); \
} else { \
gint j; \
guchar buff[1000]; \
@@ -214,16 +212,16 @@ END_TEST
memset(buff, 'a', 1000); \
\
for(j = 0; j < 1000; j++) \
- purple_cipher_context_append(context, buff, 1000); \
+ purple_hash_append(hash, buff, 1000); \
} \
\
- ret = purple_cipher_context_digest_to_str(context, cdigest, sizeof(cdigest)); \
+ ret = purple_hash_digest_to_str(hash, cdigest, sizeof(cdigest)); \
\
fail_unless(ret == TRUE, NULL); \
\
fail_unless(strcmp((digest), cdigest) == 0, NULL); \
\
- purple_cipher_context_destroy(context); \
+ g_object_unref(hash); \
}
START_TEST(test_sha256_empty_string) {
@@ -257,26 +255,24 @@ END_TEST
*****************************************************************************/
#define DES_TEST(in, keyz, out, len) { \
PurpleCipher *cipher = NULL; \
- PurpleCipherContext *context = NULL; \
guchar answer[len+1]; \
gint ret = 0; \
guchar decrypt[len+1] = in; \
guchar key[8+1] = keyz;\
guchar encrypt[len+1] = out;\
\
- cipher = purple_ciphers_find_cipher("des"); \
- context = purple_cipher_context_new(cipher, NULL); \
- purple_cipher_context_set_key(context, key, 8); \
+ cipher = purple_des_cipher_new(); \
+ purple_cipher_set_key(cipher, key, 8); \
\
- ret = purple_cipher_context_encrypt(context, decrypt, len, answer, len); \
+ ret = purple_cipher_encrypt(cipher, decrypt, len, answer, len); \
fail_unless(ret == len, NULL); \
fail_unless(memcmp(encrypt, answer, len) == 0, NULL); \
\
- ret = purple_cipher_context_decrypt(context, encrypt, len, answer, len); \
+ ret = purple_cipher_decrypt(cipher, encrypt, len, answer, len); \
fail_unless(ret == len, NULL); \
fail_unless(memcmp(decrypt, answer, len) == 0, NULL); \
\
- purple_cipher_context_destroy(context); \
+ g_object_unref(cipher); \
}
START_TEST(test_des_12345678) {
@@ -303,28 +299,25 @@ END_TEST
#define DES3_TEST(in, key, iv, out, len, mode) { \
PurpleCipher *cipher = NULL; \
- PurpleCipherContext *context = NULL; \
guchar answer[len+1]; \
guchar decrypt[len+1] = in; \
guchar encrypt[len+1] = out; \
gint ret = 0; \
\
- cipher = purple_ciphers_find_cipher("des3"); \
- context = purple_cipher_context_new(cipher, NULL); \
- purple_cipher_context_set_key(context, (guchar *)key, 24); \
- purple_cipher_context_set_batch_mode(context, (mode)); \
- purple_cipher_context_set_iv(context, (guchar *)iv, 8); \
+ cipher = purple_des3_cipher_new(); \
+ purple_cipher_set_key(cipher, (guchar *)key, 24); \
+ purple_cipher_set_batch_mode(cipher, (mode)); \
+ purple_cipher_set_iv(cipher, (guchar *)iv, 8); \
\
- fprintf(stderr, "len: %lu\n", len); \
- ret = purple_cipher_context_encrypt(context, decrypt, len, answer, len); \
+ ret = purple_cipher_encrypt(cipher, decrypt, len, answer, len); \
fail_unless(ret == len, NULL); \
fail_unless(memcmp(encrypt, answer, len) == 0, NULL); \
\
- ret = purple_cipher_context_decrypt(context, encrypt, len, answer, len); \
+ ret = purple_cipher_decrypt(cipher, encrypt, len, answer, len); \
fail_unless(ret == len, NULL); \
fail_unless(memcmp(decrypt, answer, len) == 0, NULL); \
\
- purple_cipher_context_destroy(context); \
+ g_object_unref(cipher); \
}
START_TEST(test_des3_ecb_nist1) {
@@ -472,22 +465,22 @@ END_TEST
#define HMAC_TEST(data, data_len, key, key_len, type, digest) { \
PurpleCipher *cipher = NULL; \
- PurpleCipherContext *context = NULL; \
+ PurpleHash *hash = NULL; \
gchar cdigest[41]; \
gboolean ret = FALSE; \
\
- cipher = purple_ciphers_find_cipher("hmac"); \
- context = purple_cipher_context_new(cipher, NULL); \
- purple_cipher_context_set_option(context, "hash", type); \
- purple_cipher_context_set_key(context, (guchar *)key, (key_len)); \
+ hash = purple_##type##_hash_new(); \
+ cipher = purple_hmac_cipher_new(hash); \
+ purple_cipher_set_key(cipher, (guchar *)key, (key_len)); \
\
- purple_cipher_context_append(context, (guchar *)(data), (data_len)); \
- ret = purple_cipher_context_digest_to_str(context, cdigest, sizeof(cdigest)); \
+ purple_cipher_append(cipher, (guchar *)(data), (data_len)); \
+ ret = purple_cipher_digest_to_str(cipher, cdigest, sizeof(cdigest)); \
\
fail_unless(ret == TRUE, NULL); \
fail_unless(strcmp((digest), cdigest) == 0, NULL); \
\
- purple_cipher_context_destroy(context); \
+ g_object_unref(cipher); \
+ g_object_unref(hash); \
}
/* HMAC MD5 */
@@ -497,7 +490,7 @@ START_TEST(test_hmac_md5_Hi) {
8,
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
16,
- "md5",
+ md5,
"9294727a3638bb1c13f48ef8158bfc9d");
}
END_TEST
@@ -507,7 +500,7 @@ START_TEST(test_hmac_md5_what) {
28,
"Jefe",
4,
- "md5",
+ md5,
"750c783e6ab0b503eaa86e310a5db738");
}
END_TEST
@@ -521,7 +514,7 @@ START_TEST(test_hmac_md5_dd) {
50,
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
16,
- "md5",
+ md5,
"56be34521d144c88dbb8c733f0e8b3f6");
}
END_TEST
@@ -537,7 +530,7 @@ START_TEST(test_hmac_md5_cd) {
"\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
"\x15\x16\x17\x18\x19",
25,
- "md5",
+ md5,
"697eaf0aca3a3aea3a75164746ffaa79");
}
END_TEST
@@ -547,7 +540,7 @@ START_TEST(test_hmac_md5_truncation) {
20,
"\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
16,
- "md5",
+ md5,
"56461ef2342edc00f9bab995690efd4c");
}
END_TEST
@@ -564,7 +557,7 @@ START_TEST(test_hmac_md5_large_key) {
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
80,
- "md5",
+ md5,
"6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd");
}
END_TEST
@@ -581,7 +574,7 @@ START_TEST(test_hmac_md5_large_key_and_data) {
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
80,
- "md5",
+ md5,
"6f630fad67cda0ee1fb1f562db3aa53e");
}
END_TEST
@@ -592,7 +585,7 @@ START_TEST(test_hmac_md5_null_key) {
"\x0a\x0b\x00\x0d\x0e\x0f\x1a\x2f\x0b\x0b"
"\x0b\x00\x00\x0b\x0b\x49\x5f\x6e\x0b\x0b",
20,
- "md5",
+ md5,
"597bfd644b797a985561eeb03a169e59");
}
END_TEST
@@ -603,7 +596,7 @@ START_TEST(test_hmac_md5_null_text) {
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
20,
- "md5",
+ md5,
"70be8e1b7b50dfcc335d6cd7992c564f");
}
END_TEST
@@ -614,7 +607,7 @@ START_TEST(test_hmac_md5_null_key_and_text) {
"\x0c\x0d\x00\x0f\x10\x1a\x3a\x3a\xe6\x34"
"\x0b\x00\x00\x0b\x0b\x49\x5f\x6e\x0b\x0b",
20,
- "md5",
+ md5,
"b31bcbba35a33a067cbba9131cba4889");
}
END_TEST
@@ -627,7 +620,7 @@ START_TEST(test_hmac_sha1_Hi) {
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
20,
- "sha1",
+ sha1,
"b617318655057264e28bc0b6fb378c8ef146be00");
}
END_TEST
@@ -637,7 +630,7 @@ START_TEST(test_hmac_sha1_what) {
28,
"Jefe",
4,
- "sha1",
+ sha1,
"effcdf6ae5eb2fa2d27416d5f184df9c259a7c79");
}
END_TEST
@@ -652,7 +645,7 @@ START_TEST(test_hmac_sha1_dd) {
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
20,
- "sha1",
+ sha1,
"125d7342b9ac11cd91a39af48aa17b4f63f175d3");
}
END_TEST
@@ -668,7 +661,7 @@ START_TEST(test_hmac_sha1_cd) {
"\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
"\x15\x16\x17\x18\x19",
25,
- "sha1",
+ sha1,
"4c9007f4026250c6bc8414f9bf50c86c2d7235da");
}
END_TEST
@@ -679,7 +672,7 @@ START_TEST(test_hmac_sha1_truncation) {
"\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
"\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
20,
- "sha1",
+ sha1,
"4c1a03424b55e07fe7f27be1d58bb9324a9a5a04");
}
END_TEST
@@ -696,7 +689,7 @@ START_TEST(test_hmac_sha1_large_key) {
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
80,
- "sha1",
+ sha1,
"aa4ae5e15272d00e95705637ce8a3b55ed402112");
}
END_TEST
@@ -713,7 +706,7 @@ START_TEST(test_hmac_sha1_large_key_and_data) {
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
80,
- "sha1",
+ sha1,
"e8e99d0f45237d786d6bbaa7965c7808bbff1a91");
}
END_TEST
@@ -724,7 +717,7 @@ START_TEST(test_hmac_sha1_null_key) {
"\x0a\x0b\x00\x0d\x0e\x0f\x1a\x2f\x0b\x0b"
"\x0b\x00\x00\x0b\x0b\x49\x5f\x6e\x0b\x0b",
20,
- "sha1",
+ sha1,
"eb62a2e0e33d300be669c52aab3f591bc960aac5");
}
END_TEST
@@ -735,7 +728,7 @@ START_TEST(test_hmac_sha1_null_text) {
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
20,
- "sha1",
+ sha1,
"31ca58d849e971e418e3439de2c6f83144b6abb7");
}
END_TEST
@@ -746,7 +739,7 @@ START_TEST(test_hmac_sha1_null_key_and_text) {
"\x0c\x0d\x00\x0f\x10\x1a\x3a\x3a\xe6\x34"
"\x0b\x00\x00\x0b\x0b\x49\x5f\x6e\x0b\x0b",
20,
- "sha1",
+ sha1,
"e6b8e2fede87aa09dcb13e554df1435e056eae36");
}
END_TEST
diff --git a/libpurple/tests/test_jabber_caps.c b/libpurple/tests/test_jabber_caps.c
index 6af180b658..c0d4cd1893 100644
--- a/libpurple/tests/test_jabber_caps.c
+++ b/libpurple/tests/test_jabber_caps.c
@@ -3,6 +3,8 @@
#include "tests.h"
#include "../xmlnode.h"
#include "../protocols/jabber/caps.h"
+#include "../ciphers/md5hash.h"
+#include "../ciphers/sha1hash.h"
START_TEST(test_parse_invalid)
{
@@ -25,14 +27,22 @@ END_TEST
#define assert_caps_calculate_match(hash_func, hash, str) { \
xmlnode *query = xmlnode_from_str((str), -1); \
+ PurpleHash *hasher = NULL; \
JabberCapsClientInfo *info = jabber_caps_parse_client_info(query); \
- gchar *got_hash = jabber_caps_calculate_hash(info, (hash_func)); \
+ gchar *got_hash; \
+ if (g_str_equal(hash_func, "sha-1")) { \
+ hasher = purple_sha1_hash_new(); \
+ } else if (g_str_equal(hash_func, "md5")) { \
+ hasher = purple_md5_hash_new(); \
+ } \
+ got_hash = jabber_caps_calculate_hash(info, hasher); \
+ g_object_unref(hasher); \
assert_string_equal_free((hash), got_hash); \
}
START_TEST(test_calculate_caps)
{
- assert_caps_calculate_match("sha1", "GNjxthSckUNvAIoCCJFttjl6VL8=",
+ assert_caps_calculate_match("sha-1", "GNjxthSckUNvAIoCCJFttjl6VL8=",
"<query xmlns='http://jabber.org/protocol/disco#info' node='http://tkabber.jabber.ru/#GNjxthSckUNvAIoCCJFttjl6VL8='><identity category='client' type='pc' name='Tkabber'/><x xmlns='jabber:x:data' type='result'><field var='FORM_TYPE' type='hidden'><value>urn:xmpp:dataforms:softwareinfo</value></field><field var='software'><value>Tkabber</value></field><field var='software_version'><value> ( 8.5.5 )</value></field><field var='os'><value>ATmega640-16AU</value></field><field var='os_version'><value/></field></x><feature var='games:board'/><feature var='google:mail:notify'/><feature var='http://jabber.org/protocol/activity'/><feature var='http://jabber.org/protocol/bytestreams'/><feature var='http://jabber.org/protocol/chatstates'/><feature var='http://jabber.org/protocol/commands'/><feature var='http://jabber.org/protocol/commands'/><feature var='http://jabber.org/protocol/disco#info'/><feature var='http://jabber.org/protocol/disco#items'/><feature var='http://jabber.org/protocol/feature-neg'/><feature var='http://jabber.org/protocol/geoloc'/><feature var='http://jabber.org/protocol/ibb'/><feature var='http://jabber.org/protocol/iqibb'/><feature var='http://jabber.org/protocol/mood'/><feature var='http://jabber.org/protocol/muc'/><feature var='http://jabber.org/protocol/mute#ancestor'/><feature var='http://jabber.org/protocol/mute#editor'/><feature var='http://jabber.org/protocol/rosterx'/><feature var='http://jabber.org/protocol/si'/><feature var='http://jabber.org/protocol/si/profile/file-transfer'/><feature var='http://jabber.org/protocol/tune'/><feature var='jabber:iq:avatar'/><feature var='jabber:iq:browse'/><feature var='jabber:iq:dtcp'/><feature var='jabber:iq:filexfer'/><feature var='jabber:iq:ibb'/><feature var='jabber:iq:inband'/><feature var='jabber:iq:jidlink'/><feature var='jabber:iq:last'/><feature var='jabber:iq:oob'/><feature var='jabber:iq:privacy'/><feature var='jabber:iq:time'/><feature var='jabber:iq:version'/><feature var='jabber:x:data'/><feature var='jabber:x:event'/><feature var='jabber:x:oob'/><feature var='urn:xmpp:ping'/><feature var='urn:xmpp:receipts'/><feature var='urn:xmpp:time'/></query>");
}
END_TEST
diff --git a/libpurple/tests/test_jabber_scram.c b/libpurple/tests/test_jabber_scram.c
index 512bc05a29..bb440100a5 100644
--- a/libpurple/tests/test_jabber_scram.c
+++ b/libpurple/tests/test_jabber_scram.c
@@ -4,8 +4,9 @@
#include "../util.h"
#include "../protocols/jabber/auth_scram.h"
#include "../protocols/jabber/jutil.h"
+#include "../ciphers/sha1hash.h"
-static JabberScramHash sha1_mech = { "-SHA-1", "sha1", 20 };
+static JabberScramHash sha1_mech = { "-SHA-1", purple_sha1_hash_new, 20 };
#define assert_pbkdf2_equal(password, salt, count, expected) { \
GString *p = g_string_new(password); \
diff --git a/libpurple/theme-loader.h b/libpurple/theme-loader.h
index dedef39d9f..ec9f99c896 100644
--- a/libpurple/theme-loader.h
+++ b/libpurple/theme-loader.h
@@ -49,14 +49,22 @@ typedef struct _PurpleThemeLoaderClass PurpleThemeLoaderClass;
struct _PurpleThemeLoader
{
+ /*< private >*/
GObject parent;
};
struct _PurpleThemeLoaderClass
{
+ /*< private >*/
GObjectClass parent_class;
+
PurpleTheme *((*purple_theme_loader_build)(const gchar*));
gboolean (*probe_directory)(const gchar *);
+
+ void (*purple_reserved1)(void);
+ void (*purple_reserved2)(void);
+ void (*purple_reserved3)(void);
+ void (*purple_reserved4)(void);
};
/**************************************************************************/
diff --git a/libpurple/theme-manager.h b/libpurple/theme-manager.h
index f7273394c0..6c31e81065 100644
--- a/libpurple/theme-manager.h
+++ b/libpurple/theme-manager.h
@@ -45,11 +45,18 @@ typedef struct _PurpleThemeManagerClass PurpleThemeManagerClass;
#define PURPLE_GET_THEME_MANAGER_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_THEME_MANAGER, PurpleThemeManagerClass))
struct _PurpleThemeManager {
+ /*< private >*/
GObject parent;
};
struct _PurpleThemeManagerClass {
+ /*< private >*/
GObjectClass parent_class;
+
+ void (*purple_reserved1)(void);
+ void (*purple_reserved2)(void);
+ void (*purple_reserved3)(void);
+ void (*purple_reserved4)(void);
};
/**************************************************************************/
diff --git a/libpurple/theme.h b/libpurple/theme.h
index 9f4b0bc8f1..dfc4ea6f21 100644
--- a/libpurple/theme.h
+++ b/libpurple/theme.h
@@ -48,12 +48,19 @@ typedef struct _PurpleThemeClass PurpleThemeClass;
struct _PurpleTheme
{
+ /*< private >*/
GObject parent;
};
struct _PurpleThemeClass
{
+ /*< private >*/
GObjectClass parent_class;
+
+ void (*purple_reserved1)(void);
+ void (*purple_reserved2)(void);
+ void (*purple_reserved3)(void);
+ void (*purple_reserved4)(void);
};
/**************************************************************************/
diff --git a/libpurple/util.c b/libpurple/util.c
index 1294ec6e78..b2abccb94e 100644
--- a/libpurple/util.c
+++ b/libpurple/util.c
@@ -23,7 +23,7 @@
*/
#include "internal.h"
-#include "cipher.h"
+#include "ciphers/md5hash.h"
#include "conversation.h"
#include "core.h"
#include "debug.h"
@@ -4748,3 +4748,197 @@ purple_uuid_random(void)
b,
(tmp >> 16) & 0xFFFF, g_random_int());
}
+
+GValue *
+purple_g_value_new(GType type)
+{
+ GValue *ret;
+
+ g_return_val_if_fail(type != G_TYPE_NONE, NULL);
+
+ ret = g_new0(GValue, 1);
+ g_value_init(ret, type);
+
+ return ret;
+}
+
+GValue *
+purple_g_value_dup(GValue *value)
+{
+ GValue *ret;
+
+ g_return_val_if_fail(value != NULL, NULL);
+
+ ret = g_new0(GValue, 1);
+ g_value_init(ret, G_VALUE_TYPE(value));
+ g_value_copy(value, ret);
+
+ return ret;
+}
+
+void
+purple_g_value_free(GValue *value)
+{
+ g_return_if_fail(value != NULL);
+
+ g_value_unset(value);
+ g_free(value);
+}
+
+gchar *purple_http_digest_calculate_session_key(
+ const gchar *algorithm,
+ const gchar *username,
+ const gchar *realm,
+ const gchar *password,
+ const gchar *nonce,
+ const gchar *client_nonce)
+{
+ PurpleHash *hasher;
+ gchar hash[33]; /* We only support MD5. */
+
+ g_return_val_if_fail(username != NULL, NULL);
+ g_return_val_if_fail(realm != NULL, NULL);
+ g_return_val_if_fail(password != NULL, NULL);
+ g_return_val_if_fail(nonce != NULL, NULL);
+
+ /* Check for a supported algorithm. */
+ g_return_val_if_fail(algorithm == NULL ||
+ *algorithm == '\0' ||
+ g_ascii_strcasecmp(algorithm, "MD5") ||
+ g_ascii_strcasecmp(algorithm, "MD5-sess"), NULL);
+
+ hasher = purple_md5_hash_new();
+ g_return_val_if_fail(hash != NULL, NULL);
+
+ purple_hash_append(hasher, (guchar *)username, strlen(username));
+ purple_hash_append(hasher, (guchar *)":", 1);
+ purple_hash_append(hasher, (guchar *)realm, strlen(realm));
+ purple_hash_append(hasher, (guchar *)":", 1);
+ purple_hash_append(hasher, (guchar *)password, strlen(password));
+
+ if (algorithm != NULL && !g_ascii_strcasecmp(algorithm, "MD5-sess"))
+ {
+ guchar digest[16];
+
+ if (client_nonce == NULL)
+ {
+ g_object_unref(hasher);
+ purple_debug_error("hash", "Required client_nonce missing for MD5-sess digest calculation.\n");
+ return NULL;
+ }
+
+ purple_hash_digest(hasher, digest, sizeof(digest));
+
+ purple_hash_reset(hasher);
+ purple_hash_append(hasher, digest, sizeof(digest));
+ purple_hash_append(hasher, (guchar *)":", 1);
+ purple_hash_append(hasher, (guchar *)nonce, strlen(nonce));
+ purple_hash_append(hasher, (guchar *)":", 1);
+ purple_hash_append(hasher, (guchar *)client_nonce, strlen(client_nonce));
+ }
+
+ purple_hash_digest_to_str(hasher, hash, sizeof(hash));
+ g_object_unref(hasher);
+
+ return g_strdup(hash);
+}
+
+gchar *purple_http_digest_calculate_response(
+ const gchar *algorithm,
+ const gchar *method,
+ const gchar *digest_uri,
+ const gchar *qop,
+ const gchar *entity,
+ const gchar *nonce,
+ const gchar *nonce_count,
+ const gchar *client_nonce,
+ const gchar *session_key)
+{
+ PurpleHash *hash;
+ static gchar hash2[33]; /* We only support MD5. */
+
+ g_return_val_if_fail(method != NULL, NULL);
+ g_return_val_if_fail(digest_uri != NULL, NULL);
+ g_return_val_if_fail(nonce != NULL, NULL);
+ g_return_val_if_fail(session_key != NULL, NULL);
+
+ /* Check for a supported algorithm. */
+ g_return_val_if_fail(algorithm == NULL ||
+ *algorithm == '\0' ||
+ g_ascii_strcasecmp(algorithm, "MD5") ||
+ g_ascii_strcasecmp(algorithm, "MD5-sess"), NULL);
+
+ /* Check for a supported "quality of protection". */
+ g_return_val_if_fail(qop == NULL ||
+ *qop == '\0' ||
+ g_ascii_strcasecmp(qop, "auth") ||
+ g_ascii_strcasecmp(qop, "auth-int"), NULL);
+
+ hash = purple_md5_hash_new();
+ g_return_val_if_fail(hash != NULL, NULL);
+
+ purple_hash_append(hash, (guchar *)method, strlen(method));
+ purple_hash_append(hash, (guchar *)":", 1);
+ purple_hash_append(hash, (guchar *)digest_uri, strlen(digest_uri));
+
+ if (qop != NULL && !g_ascii_strcasecmp(qop, "auth-int"))
+ {
+ PurpleHash *hash2;
+ gchar entity_hash[33];
+
+ if (entity == NULL)
+ {
+ g_object_unref(hash);
+ purple_debug_error("hash", "Required entity missing for auth-int digest calculation.\n");
+ return NULL;
+ }
+
+ hash2 = purple_md5_hash_new();
+ purple_hash_append(hash2, (guchar *)entity, strlen(entity));
+ purple_hash_digest_to_str(hash2, entity_hash, sizeof(entity_hash));
+ g_object_unref(hash2);
+
+ purple_hash_append(hash, (guchar *)":", 1);
+ purple_hash_append(hash, (guchar *)entity_hash, strlen(entity_hash));
+ }
+
+ purple_hash_digest_to_str(hash, hash2, sizeof(hash2));
+ purple_hash_reset(hash);
+
+ purple_hash_append(hash, (guchar *)session_key, strlen(session_key));
+ purple_hash_append(hash, (guchar *)":", 1);
+ purple_hash_append(hash, (guchar *)nonce, strlen(nonce));
+ purple_hash_append(hash, (guchar *)":", 1);
+
+ if (qop != NULL && *qop != '\0')
+ {
+ if (nonce_count == NULL)
+ {
+ g_object_unref(hash);
+ purple_debug_error("hash", "Required nonce_count missing for digest calculation.\n");
+ return NULL;
+ }
+
+ if (client_nonce == NULL)
+ {
+ g_object_unref(hash);
+ purple_debug_error("hash", "Required client_nonce missing for digest calculation.\n");
+ return NULL;
+ }
+
+ purple_hash_append(hash, (guchar *)nonce_count, strlen(nonce_count));
+ purple_hash_append(hash, (guchar *)":", 1);
+ purple_hash_append(hash, (guchar *)client_nonce, strlen(client_nonce));
+ purple_hash_append(hash, (guchar *)":", 1);
+
+ purple_hash_append(hash, (guchar *)qop, strlen(qop));
+
+ purple_hash_append(hash, (guchar *)":", 1);
+ }
+
+ purple_hash_append(hash, (guchar *)hash2, strlen(hash2));
+ purple_hash_digest_to_str(hash, hash2, sizeof(hash2));
+ g_object_unref(hash);
+
+ return g_strdup(hash2);
+}
diff --git a/libpurple/util.h b/libpurple/util.h
index a8e9ab0cd8..c4e2d7ef07 100644
--- a/libpurple/util.h
+++ b/libpurple/util.h
@@ -1431,6 +1431,73 @@ const gchar *purple_get_host_name(void);
*/
gchar *purple_uuid_random(void);
+/**
+ * Creates a new GValue of the specified type.
+ *
+ * @param type The type of data to be held by the GValue
+ *
+ * @return The created GValue
+ */
+GValue *purple_g_value_new(GType type);
+
+/**
+ * Duplicates a GValue.
+ *
+ * @param value The GValue to duplicate
+ *
+ * @return The duplicated GValue
+ */
+GValue *purple_g_value_dup(GValue *value);
+
+/**
+ * Frees a GValue.
+ *
+ * @param value The GValue to free.
+ */
+void purple_g_value_free(GValue *value);
+
+/**
+ * Calculates a session key for HTTP Digest authentation
+ *
+ * See RFC 2617 for more information.
+ *
+ * @param algorithm The hash algorithm to use
+ * @param username The username provided by the user
+ * @param realm The authentication realm provided by the server
+ * @param password The password provided by the user
+ * @param nonce The nonce provided by the server
+ * @param client_nonce The nonce provided by the client
+ *
+ * @return The session key, or @c NULL if an error occurred.
+ */
+gchar *purple_http_digest_calculate_session_key(
+ const gchar *algorithm, const gchar *username,
+ const gchar *realm, const gchar *password,
+ const gchar *nonce, const gchar *client_nonce);
+
+/** Calculate a response for HTTP Digest authentication
+ *
+ * See RFC 2617 for more information.
+ *
+ * @param algorithm The hash algorithm to use
+ * @param method The HTTP method in use
+ * @param digest_uri The URI from the initial request
+ * @param qop The "quality of protection"
+ * @param entity The entity body
+ * @param nonce The nonce provided by the server
+ * @param nonce_count The nonce count
+ * @param client_nonce The nonce provided by the client
+ * @param session_key The session key from purple_cipher_http_digest_calculate_session_key()
+ *
+ * @return The hashed response, or @c NULL if an error occurred.
+ */
+gchar *purple_http_digest_calculate_response(
+ const gchar *algorithm, const gchar *method,
+ const gchar *digest_uri, const gchar *qop,
+ const gchar *entity, const gchar *nonce,
+ const gchar *nonce_count, const gchar *client_nonce,
+ const gchar *session_key);
+
G_END_DECLS
#endif /* _PURPLE_UTIL_H_ */
diff --git a/libpurple/value.c b/libpurple/value.c
deleted file mode 100644
index 34ed57baa5..0000000000
--- a/libpurple/value.c
+++ /dev/null
@@ -1,526 +0,0 @@
-/**
- * @file value.c Value wrapper API
- * @ingroup core
- */
-
-/* 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
- */
-#include "internal.h"
-
-#include "value.h"
-
-#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, ...)
-{
- PurpleValue *value;
- va_list args;
-
- g_return_val_if_fail(type != PURPLE_TYPE_UNKNOWN, NULL);
-
- value = g_new0(PurpleValue, 1);
-
- value->type = type;
-
- va_start(args, type);
-
- if (type == PURPLE_TYPE_SUBTYPE)
- value->u.subtype = va_arg(args, int);
- else if (type == PURPLE_TYPE_BOXED)
- value->u.specific_type = g_strdup(va_arg(args, char *));
-
- va_end(args);
-
- return value;
-}
-
-PurpleValue *
-purple_value_new_outgoing(PurpleType type, ...)
-{
- PurpleValue *value;
- va_list args;
-
- g_return_val_if_fail(type != PURPLE_TYPE_UNKNOWN, NULL);
-
- value = g_new0(PurpleValue, 1);
-
- value->type = type;
-
- va_start(args, type);
-
- if (type == PURPLE_TYPE_SUBTYPE)
- value->u.subtype = va_arg(args, int);
- else if (type == PURPLE_TYPE_BOXED)
- value->u.specific_type = g_strdup(va_arg(args, char *));
-
- va_end(args);
-
- value->flags |= OUTGOING_FLAG;
-
- return value;
-}
-
-void
-purple_value_destroy(PurpleValue *value)
-{
- g_return_if_fail(value != NULL);
-
- if (purple_value_get_type(value) == PURPLE_TYPE_BOXED)
- {
- g_free(value->u.specific_type);
- }
- else if (purple_value_get_type(value) == PURPLE_TYPE_STRING)
- {
- g_free(value->data.string_data);
- }
-
- g_free(value);
-}
-
-PurpleValue *
-purple_value_dup(const PurpleValue *value)
-{
- PurpleValue *new_value;
- PurpleType type;
-
- g_return_val_if_fail(value != NULL, NULL);
-
- type = purple_value_get_type(value);
-
- if (type == PURPLE_TYPE_SUBTYPE)
- {
- new_value = purple_value_new(PURPLE_TYPE_SUBTYPE,
- purple_value_get_subtype(value));
- }
- else if (type == PURPLE_TYPE_BOXED)
- {
- new_value = purple_value_new(PURPLE_TYPE_BOXED,
- purple_value_get_specific_type(value));
- }
- else
- new_value = purple_value_new(type);
-
- new_value->flags = value->flags;
-
- switch (type)
- {
- case PURPLE_TYPE_CHAR:
- purple_value_set_char(new_value, purple_value_get_char(value));
- break;
-
- case PURPLE_TYPE_UCHAR:
- purple_value_set_uchar(new_value, purple_value_get_uchar(value));
- break;
-
- case PURPLE_TYPE_BOOLEAN:
- purple_value_set_boolean(new_value, purple_value_get_boolean(value));
- break;
-
- case PURPLE_TYPE_SHORT:
- purple_value_set_short(new_value, purple_value_get_short(value));
- break;
-
- case PURPLE_TYPE_USHORT:
- purple_value_set_ushort(new_value, purple_value_get_ushort(value));
- break;
-
- case PURPLE_TYPE_INT:
- purple_value_set_int(new_value, purple_value_get_int(value));
- break;
-
- case PURPLE_TYPE_UINT:
- purple_value_set_uint(new_value, purple_value_get_uint(value));
- break;
-
- case PURPLE_TYPE_LONG:
- purple_value_set_long(new_value, purple_value_get_long(value));
- break;
-
- case PURPLE_TYPE_ULONG:
- purple_value_set_ulong(new_value, purple_value_get_ulong(value));
- break;
-
- case PURPLE_TYPE_INT64:
- purple_value_set_int64(new_value, purple_value_get_int64(value));
- break;
-
- case PURPLE_TYPE_UINT64:
- purple_value_set_uint64(new_value, purple_value_get_uint64(value));
- break;
-
- case PURPLE_TYPE_STRING:
- purple_value_set_string(new_value, purple_value_get_string(value));
- break;
-
- case PURPLE_TYPE_OBJECT:
- purple_value_set_object(new_value, purple_value_get_object(value));
- break;
-
- case PURPLE_TYPE_POINTER:
- purple_value_set_pointer(new_value, purple_value_get_pointer(value));
- break;
-
- case PURPLE_TYPE_ENUM:
- purple_value_set_enum(new_value, purple_value_get_enum(value));
- break;
-
- case PURPLE_TYPE_BOXED:
- purple_value_set_boxed(new_value, purple_value_get_boxed(value));
- break;
-
- default:
- break;
- }
-
- return new_value;
-}
-
-PurpleType
-purple_value_get_type(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, PURPLE_TYPE_UNKNOWN);
-
- return value->type;
-}
-
-unsigned int
-purple_value_get_subtype(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, 0);
- g_return_val_if_fail(purple_value_get_type(value) == PURPLE_TYPE_SUBTYPE, 0);
-
- return value->u.subtype;
-}
-
-const char *
-purple_value_get_specific_type(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, NULL);
- g_return_val_if_fail(purple_value_get_type(value) == PURPLE_TYPE_BOXED, NULL);
-
- return value->u.specific_type;
-}
-
-gboolean
-purple_value_is_outgoing(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, FALSE);
-
- return (value->flags & OUTGOING_FLAG);
-}
-
-void
-purple_value_set_char(PurpleValue *value, char data)
-{
- g_return_if_fail(value != NULL);
-
- value->data.char_data = data;
-}
-
-void
-purple_value_set_uchar(PurpleValue *value, unsigned char data)
-{
- g_return_if_fail(value != NULL);
-
- value->data.uchar_data = data;
-}
-
-void
-purple_value_set_boolean(PurpleValue *value, gboolean data)
-{
- g_return_if_fail(value != NULL);
-
- value->data.boolean_data = data;
-}
-
-void
-purple_value_set_short(PurpleValue *value, short data)
-{
- g_return_if_fail(value != NULL);
-
- value->data.short_data = data;
-}
-
-void
-purple_value_set_ushort(PurpleValue *value, unsigned short data)
-{
- g_return_if_fail(value != NULL);
-
- value->data.ushort_data = data;
-}
-
-void
-purple_value_set_int(PurpleValue *value, int data)
-{
- g_return_if_fail(value != NULL);
-
- value->data.int_data = data;
-}
-
-void
-purple_value_set_uint(PurpleValue *value, unsigned int data)
-{
- g_return_if_fail(value != NULL);
-
- value->data.int_data = data;
-}
-
-void
-purple_value_set_long(PurpleValue *value, long data)
-{
- g_return_if_fail(value != NULL);
-
- value->data.long_data = data;
-}
-
-void
-purple_value_set_ulong(PurpleValue *value, unsigned long data)
-{
- g_return_if_fail(value != NULL);
-
- value->data.long_data = data;
-}
-
-void
-purple_value_set_int64(PurpleValue *value, gint64 data)
-{
- g_return_if_fail(value != NULL);
-
- value->data.int64_data = data;
-}
-
-void
-purple_value_set_uint64(PurpleValue *value, guint64 data)
-{
- g_return_if_fail(value != NULL);
-
- value->data.uint64_data = data;
-}
-
-void
-purple_value_set_string(PurpleValue *value, const char *data)
-{
- g_return_if_fail(value != NULL);
- g_return_if_fail(data == NULL || g_utf8_validate(data, -1, NULL));
-
- g_free(value->data.string_data);
- value->data.string_data = g_strdup(data);
-}
-
-void
-purple_value_set_object(PurpleValue *value, void *data)
-{
- g_return_if_fail(value != NULL);
-
- value->data.object_data = data;
-}
-
-void
-purple_value_set_pointer(PurpleValue *value, void *data)
-{
- g_return_if_fail(value != NULL);
-
- value->data.pointer_data = data;
-}
-
-void
-purple_value_set_enum(PurpleValue *value, int data)
-{
- g_return_if_fail(value != NULL);
-
- value->data.enum_data = data;
-}
-
-void
-purple_value_set_boxed(PurpleValue *value, void *data)
-{
- g_return_if_fail(value != NULL);
-
- value->data.boxed_data = data;
-}
-
-char
-purple_value_get_char(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, 0);
-
- return value->data.char_data;
-}
-
-unsigned char
-purple_value_get_uchar(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, 0);
-
- return value->data.uchar_data;
-}
-
-gboolean
-purple_value_get_boolean(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, FALSE);
-
- return value->data.boolean_data;
-}
-
-short
-purple_value_get_short(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, 0);
-
- return value->data.short_data;
-}
-
-unsigned short
-purple_value_get_ushort(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, 0);
-
- return value->data.ushort_data;
-}
-
-int
-purple_value_get_int(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, 0);
-
- return value->data.int_data;
-}
-
-unsigned int
-purple_value_get_uint(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, 0);
-
- return value->data.int_data;
-}
-
-long
-purple_value_get_long(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, 0);
-
- return value->data.long_data;
-}
-
-unsigned long
-purple_value_get_ulong(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, 0);
-
- return value->data.long_data;
-}
-
-gint64
-purple_value_get_int64(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, 0);
-
- return value->data.int64_data;
-}
-
-guint64
-purple_value_get_uint64(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, 0);
-
- return value->data.uint64_data;
-}
-
-const char *
-purple_value_get_string(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, NULL);
-
- return value->data.string_data;
-}
-
-void *
-purple_value_get_object(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, NULL);
-
- return value->data.object_data;
-}
-
-void *
-purple_value_get_pointer(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, NULL);
-
- return value->data.pointer_data;
-}
-
-int
-purple_value_get_enum(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, -1);
-
- return value->data.enum_data;
-}
-
-void *
-purple_value_get_boxed(const PurpleValue *value)
-{
- g_return_val_if_fail(value != NULL, NULL);
-
- return value->data.boxed_data;
-}
-
diff --git a/libpurple/value.h b/libpurple/value.h
deleted file mode 100644
index 5cd26afbc9..0000000000
--- a/libpurple/value.h
+++ /dev/null
@@ -1,467 +0,0 @@
-/**
- * @file value.h Value wrapper API
- * @ingroup core
- */
-
-/* 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 _PURPLE_VALUE_H_
-#define _PURPLE_VALUE_H_
-
-#include <glib.h>
-
-/**
- * Specific value types.
- */
-typedef enum
-{
- PURPLE_TYPE_UNKNOWN = 0, /**< Unknown type. */
- PURPLE_TYPE_SUBTYPE, /**< Subtype. */
- PURPLE_TYPE_CHAR, /**< Character. */
- PURPLE_TYPE_UCHAR, /**< Unsigned character. */
- PURPLE_TYPE_BOOLEAN, /**< Boolean. */
- PURPLE_TYPE_SHORT, /**< Short integer. */
- PURPLE_TYPE_USHORT, /**< Unsigned short integer. */
- PURPLE_TYPE_INT, /**< Integer. */
- PURPLE_TYPE_UINT, /**< Unsigned integer. */
- PURPLE_TYPE_LONG, /**< Long integer. */
- PURPLE_TYPE_ULONG, /**< Unsigned long integer. */
- PURPLE_TYPE_INT64, /**< 64-bit integer. */
- PURPLE_TYPE_UINT64, /**< 64-bit unsigned integer. */
- PURPLE_TYPE_STRING, /**< String. */
- PURPLE_TYPE_OBJECT, /**< Object pointer. */
- PURPLE_TYPE_POINTER, /**< Generic pointer. */
- PURPLE_TYPE_ENUM, /**< Enum. */
- PURPLE_TYPE_BOXED /**< Boxed pointer with specific type. */
-
-} PurpleType;
-
-
-/**
- * Purple-specific subtype values.
- */
-typedef enum
-{
- PURPLE_SUBTYPE_UNKNOWN = 0,
- PURPLE_SUBTYPE_ACCOUNT,
- PURPLE_SUBTYPE_BLIST,
- PURPLE_SUBTYPE_BLIST_BUDDY,
- PURPLE_SUBTYPE_BLIST_GROUP,
- PURPLE_SUBTYPE_BLIST_CHAT,
- PURPLE_SUBTYPE_BUDDY_ICON,
- PURPLE_SUBTYPE_CONNECTION,
- PURPLE_SUBTYPE_CONVERSATION,
- PURPLE_SUBTYPE_PLUGIN,
- PURPLE_SUBTYPE_BLIST_NODE,
- PURPLE_SUBTYPE_CIPHER,
- PURPLE_SUBTYPE_STATUS,
- PURPLE_SUBTYPE_LOG,
- PURPLE_SUBTYPE_XFER,
- PURPLE_SUBTYPE_SAVEDSTATUS,
- PURPLE_SUBTYPE_XMLNODE,
- PURPLE_SUBTYPE_USERINFO,
- PURPLE_SUBTYPE_STORED_IMAGE,
- PURPLE_SUBTYPE_CERTIFICATEPOOL,
- PURPLE_SUBTYPE_CHATBUDDY
-} PurpleSubType;
-
-/**
- * A wrapper for a type, subtype, and specific type of value.
- */
-typedef struct _PurpleValue PurpleValue;
-
-G_BEGIN_DECLS
-
-/**
- * Creates a new PurpleValue.
- *
- * This function takes a type and, depending on that type, a sub-type
- * or specific type.
- *
- * If @a type is PURPLE_TYPE_BOXED, the next parameter must be a
- * string representing the specific type.
- *
- * If @a type is PURPLE_TYPE_SUBTYPE, the next parameter must be a
- * integer or enum representing the sub-type.
- *
- * If the subtype or specific type is not set when required, random
- * errors may occur. You have been warned.
- *
- * @param type The type.
- *
- * @return The new value.
- */
-PurpleValue *purple_value_new(PurpleType type, ...);
-
-/**
- * Creates a new outgoing PurpleValue. If a value is an "outgoing" value
- * it means the value can be modified by plugins and scripts.
- *
- * This function takes a type and, depending on that type, a sub-type
- * or specific type.
- *
- * If @a type is PURPLE_TYPE_BOXED, the next parameter must be a
- * string representing the specific type.
- *
- * If @a type is PURPLE_TYPE_SUBTYPE, the next parameter must be a
- * integer or enum representing the sub-type.
- *
- * If the sub-type or specific type is not set when required, random
- * errors may occur. You have been warned.
- *
- * @param type The type.
- *
- * @return The new value.
- */
-PurpleValue *purple_value_new_outgoing(PurpleType type, ...);
-
-/**
- * Destroys a PurpleValue.
- *
- * @param value The value to destroy.
- */
-void purple_value_destroy(PurpleValue *value);
-
-/**
- * Duplicated a PurpleValue.
- *
- * @param value The value to duplicate.
- *
- * @return The duplicate value.
- */
-PurpleValue *purple_value_dup(const PurpleValue *value);
-
-/**
- * Returns a value's type.
- *
- * @param value The value whose type you want.
- *
- * @return The value's type.
- */
-PurpleType purple_value_get_type(const PurpleValue *value);
-
-/**
- * Returns a value's subtype.
- *
- * If the value's type is not PURPLE_TYPE_SUBTYPE, this will return 0.
- * Subtypes should never have a subtype of 0.
- *
- * @param value The value whose subtype you want.
- *
- * @return The value's subtype, or 0 if @a type is not PURPLE_TYPE_SUBTYPE.
- */
-unsigned int purple_value_get_subtype(const PurpleValue *value);
-
-/**
- * Returns a value's specific type.
- *
- * If the value's type is not PURPLE_TYPE_BOXED, this will return @c NULL.
- *
- * @param value The value whose specific type you want.
- *
- * @return The value's specific type, or @a NULL if not PURPLE_TYPE_BOXED.
- */
-const char *purple_value_get_specific_type(const PurpleValue *value);
-
-/**
- * Returns whether or not the value is an outgoing value.
- *
- * @param value The value.
- *
- * @return TRUE if the value is outgoing, or FALSE otherwise.
- */
-gboolean purple_value_is_outgoing(const PurpleValue *value);
-
-/**
- * Sets the value's character data.
- *
- * @param value The value.
- * @param data The character data.
- */
-void purple_value_set_char(PurpleValue *value, char data);
-
-/**
- * Sets the value's unsigned character data.
- *
- * @param value The value.
- * @param data The unsigned character data.
- */
-void purple_value_set_uchar(PurpleValue *value, unsigned char data);
-
-/**
- * Sets the value's boolean data.
- *
- * @param value The value.
- * @param data The boolean data.
- */
-void purple_value_set_boolean(PurpleValue *value, gboolean data);
-
-/**
- * Sets the value's short integer data.
- *
- * @param value The value.
- * @param data The short integer data.
- */
-void purple_value_set_short(PurpleValue *value, short data);
-
-/**
- * Sets the value's unsigned short integer data.
- *
- * @param value The value.
- * @param data The unsigned short integer data.
- */
-void purple_value_set_ushort(PurpleValue *value, unsigned short data);
-
-/**
- * Sets the value's integer data.
- *
- * @param value The value.
- * @param data The integer data.
- */
-void purple_value_set_int(PurpleValue *value, int data);
-
-/**
- * Sets the value's unsigned integer data.
- *
- * @param value The value.
- * @param data The unsigned integer data.
- */
-void purple_value_set_uint(PurpleValue *value, unsigned int data);
-
-/**
- * Sets the value's long integer data.
- *
- * @param value The value.
- * @param data The long integer data.
- */
-void purple_value_set_long(PurpleValue *value, long data);
-
-/**
- * Sets the value's unsigned long integer data.
- *
- * @param value The value.
- * @param data The unsigned long integer data.
- */
-void purple_value_set_ulong(PurpleValue *value, unsigned long data);
-
-/**
- * Sets the value's 64-bit integer data.
- *
- * @param value The value.
- * @param data The 64-bit integer data.
- */
-void purple_value_set_int64(PurpleValue *value, gint64 data);
-
-/**
- * Sets the value's unsigned 64-bit integer data.
- *
- * @param value The value.
- * @param data The unsigned 64-bit integer data.
- */
-void purple_value_set_uint64(PurpleValue *value, guint64 data);
-
-/**
- * Sets the value's string data.
- *
- * @param value The value.
- * @param data The string data.
- */
-void purple_value_set_string(PurpleValue *value, const char *data);
-
-/**
- * Sets the value's object data.
- *
- * @param value The value.
- * @param data The object data.
- */
-void purple_value_set_object(PurpleValue *value, void *data);
-
-/**
- * Sets the value's pointer data.
- *
- * @param value The value.
- * @param data The pointer data.
- */
-void purple_value_set_pointer(PurpleValue *value, void *data);
-
-/**
- * Sets the value's enum data.
- *
- * @param value The value.
- * @param data The enum data.
- */
-void purple_value_set_enum(PurpleValue *value, int data);
-
-/**
- * Sets the value's boxed data.
- *
- * @param value The value.
- * @param data The boxed data.
- */
-void purple_value_set_boxed(PurpleValue *value, void *data);
-
-/**
- * Returns the value's character data.
- *
- * @param value The value.
- *
- * @return The character data.
- */
-char purple_value_get_char(const PurpleValue *value);
-
-/**
- * Returns the value's unsigned character data.
- *
- * @param value The value.
- *
- * @return The unsigned character data.
- */
-unsigned char purple_value_get_uchar(const PurpleValue *value);
-
-/**
- * Returns the value's boolean data.
- *
- * @param value The value.
- *
- * @return The boolean data.
- */
-gboolean purple_value_get_boolean(const PurpleValue *value);
-
-/**
- * Returns the value's short integer data.
- *
- * @param value The value.
- *
- * @return The short integer data.
- */
-short purple_value_get_short(const PurpleValue *value);
-
-/**
- * Returns the value's unsigned short integer data.
- *
- * @param value The value.
- *
- * @return The unsigned short integer data.
- */
-unsigned short purple_value_get_ushort(const PurpleValue *value);
-
-/**
- * Returns the value's integer data.
- *
- * @param value The value.
- *
- * @return The integer data.
- */
-int purple_value_get_int(const PurpleValue *value);
-
-/**
- * Returns the value's unsigned integer data.
- *
- * @param value The value.
- *
- * @return The unsigned integer data.
- */
-unsigned int purple_value_get_uint(const PurpleValue *value);
-
-/**
- * Returns the value's long integer data.
- *
- * @param value The value.
- *
- * @return The long integer data.
- */
-long purple_value_get_long(const PurpleValue *value);
-
-/**
- * Returns the value's unsigned long integer data.
- *
- * @param value The value.
- *
- * @return The unsigned long integer data.
- */
-unsigned long purple_value_get_ulong(const PurpleValue *value);
-
-/**
- * Returns the value's 64-bit integer data.
- *
- * @param value The value.
- *
- * @return The 64-bit integer data.
- */
-gint64 purple_value_get_int64(const PurpleValue *value);
-
-/**
- * Returns the value's unsigned 64-bit integer data.
- *
- * @param value The value.
- *
- * @return The unsigned 64-bit integer data.
- */
-guint64 purple_value_get_uint64(const PurpleValue *value);
-
-/**
- * Returns the value's string data.
- *
- * @param value The value.
- *
- * @return The string data.
- */
-const char *purple_value_get_string(const PurpleValue *value);
-
-/**
- * Returns the value's object data.
- *
- * @param value The value.
- *
- * @return The object data.
- */
-void *purple_value_get_object(const PurpleValue *value);
-
-/**
- * Returns the value's pointer data.
- *
- * @param value The value.
- *
- * @return The pointer data.
- */
-void *purple_value_get_pointer(const PurpleValue *value);
-
-/**
- * Returns the value's enum data.
- *
- * @param value The value.
- *
- * @return The enum data.
- */
-int purple_value_get_enum(const PurpleValue *value);
-
-/**
- * Returns the value's boxed data.
- *
- * @param value The value.
- *
- * @return The boxed data.
- */
-void *purple_value_get_boxed(const PurpleValue *value);
-
-G_END_DECLS
-
-#endif /* _PURPLE_VALUE_H_ */
diff --git a/libpurple/xmlnode.c b/libpurple/xmlnode.c
index 81285a514f..3c5cbbcae2 100644
--- a/libpurple/xmlnode.c
+++ b/libpurple/xmlnode.c
@@ -967,3 +967,17 @@ xmlnode_get_next_twin(xmlnode *node)
return NULL;
}
+
+GType
+xmlnode_get_type(void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_boxed_type_register_static("xmlnode",
+ (GBoxedCopyFunc)xmlnode_copy,
+ (GBoxedFreeFunc)xmlnode_free);
+ }
+
+ return type;
+}
diff --git a/libpurple/xmlnode.h b/libpurple/xmlnode.h
index 29a768ba20..b4011a3298 100644
--- a/libpurple/xmlnode.h
+++ b/libpurple/xmlnode.h
@@ -27,6 +27,9 @@
#define _PURPLE_XMLNODE_H_
#include <glib.h>
+#include <glib-object.h>
+
+#define PURPLE_TYPE_XMLNODE (xmlnode_get_type())
/**
* The valid types for an xmlnode
@@ -60,6 +63,11 @@ struct _xmlnode
G_BEGIN_DECLS
/**
+ * Returns the GType for the xmlnode boxed structure.
+ */
+GType xmlnode_get_type(void);
+
+/**
* Creates a new xmlnode.
*
* @param name The name of the node.
diff --git a/pidgin/gtkaccount.c b/pidgin/gtkaccount.c
index 574cc1e751..041baa1a56 100644
--- a/pidgin/gtkaccount.c
+++ b/pidgin/gtkaccount.c
@@ -165,6 +165,10 @@ static void add_account_to_liststore(PurpleAccount *account, gpointer user_data)
static void set_account(GtkListStore *store, GtkTreeIter *iter,
PurpleAccount *account, GdkPixbuf *global_buddyicon);
+/* privacy UI ops */
+void pidgin_permit_added_removed(PurpleAccount *account, const char *name);
+void pidgin_deny_added_removed(PurpleAccount *account, const char *name);
+
/**************************************************************************
* Add/Modify Account dialog
**************************************************************************/
@@ -859,9 +863,9 @@ add_user_options(AccountPrefsDialog *dialog, GtkWidget *parent)
gpointer data = NULL;
size_t len = 0;
- if (purple_account_get_alias(dialog->account))
+ if (purple_account_get_private_alias(dialog->account))
gtk_entry_set_text(GTK_ENTRY(dialog->alias_entry),
- purple_account_get_alias(dialog->account));
+ purple_account_get_private_alias(dialog->account));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->new_mail_check),
purple_account_get_check_mail(dialog->account));
@@ -1401,7 +1405,7 @@ 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);
+ purple_signal_emit(pidgin_accounts_get_handle(), "account-modified", account);
if (saved_status != NULL && purple_account_get_remember_password(account)) {
purple_savedstatus_activate_for_account(saved_status, account);
@@ -1485,9 +1489,9 @@ ok_account_prefs_cb(GtkWidget *w, AccountPrefsDialog *dialog)
value = gtk_entry_get_text(GTK_ENTRY(dialog->alias_entry));
if (*value != '\0')
- purple_account_set_alias(account, value);
+ purple_account_set_private_alias(account, value);
else
- purple_account_set_alias(account, NULL);
+ purple_account_set_private_alias(account, NULL);
/* Buddy Icon */
if (dialog->prpl_info != NULL && dialog->prpl_info->icon_spec.format != NULL)
@@ -1668,7 +1672,7 @@ ok_account_prefs_cb(GtkWidget *w, AccountPrefsDialog *dialog)
if (new_acct)
purple_accounts_add(account);
else
- purple_signal_emit(pidgin_account_get_handle(), "account-modified", account);
+ purple_signal_emit(pidgin_accounts_get_handle(), "account-modified", account);
/* If this is a new account, then sign on! */
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->register_button))) {
@@ -2556,7 +2560,7 @@ pidgin_accounts_window_show(void)
/* Close button */
pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_CLOSE, G_CALLBACK(close_accounts_cb), dialog);
- purple_signal_connect(pidgin_account_get_handle(), "account-modified",
+ purple_signal_connect(pidgin_accounts_get_handle(), "account-modified",
accounts_window,
PURPLE_CALLBACK(account_modified_cb), accounts_window);
purple_prefs_connect_callback(accounts_window,
@@ -2902,10 +2906,11 @@ static PurpleAccountUiOps ui_ops =
pidgin_accounts_request_add,
pidgin_accounts_request_authorization,
pidgin_accounts_request_close,
- NULL,
- NULL,
- NULL,
- NULL
+ pidgin_permit_added_removed,
+ pidgin_permit_added_removed,
+ pidgin_deny_added_removed,
+ pidgin_deny_added_removed,
+ NULL, NULL, NULL, NULL
};
PurpleAccountUiOps *
@@ -2915,14 +2920,14 @@ pidgin_accounts_get_ui_ops(void)
}
void *
-pidgin_account_get_handle(void) {
+pidgin_accounts_get_handle(void) {
static int handle;
return &handle;
}
void
-pidgin_account_init(void)
+pidgin_accounts_init(void)
{
char *default_avatar = NULL;
purple_prefs_add_none(PIDGIN_PREFS_ROOT "/accounts");
@@ -2942,29 +2947,28 @@ pidgin_account_init(void)
purple_prefs_add_path(PIDGIN_PREFS_ROOT "/accounts/buddyicon", default_avatar);
g_free(default_avatar);
- purple_signal_register(pidgin_account_get_handle(), "account-modified",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT));
+ purple_signal_register(pidgin_accounts_get_handle(), "account-modified",
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_ACCOUNT);
/* Setup some purple signal handlers. */
purple_signal_connect(purple_connections_get_handle(), "signed-on",
- pidgin_account_get_handle(),
+ pidgin_accounts_get_handle(),
PURPLE_CALLBACK(signed_on_off_cb), NULL);
purple_signal_connect(purple_connections_get_handle(), "signed-off",
- pidgin_account_get_handle(),
+ pidgin_accounts_get_handle(),
PURPLE_CALLBACK(signed_on_off_cb), NULL);
purple_signal_connect(purple_accounts_get_handle(), "account-added",
- pidgin_account_get_handle(),
+ pidgin_accounts_get_handle(),
PURPLE_CALLBACK(add_account_to_liststore), NULL);
purple_signal_connect(purple_accounts_get_handle(), "account-removed",
- pidgin_account_get_handle(),
+ pidgin_accounts_get_handle(),
PURPLE_CALLBACK(account_removed_cb), NULL);
purple_signal_connect(purple_accounts_get_handle(), "account-disabled",
- pidgin_account_get_handle(),
+ pidgin_accounts_get_handle(),
PURPLE_CALLBACK(account_abled_cb), GINT_TO_POINTER(FALSE));
purple_signal_connect(purple_accounts_get_handle(), "account-enabled",
- pidgin_account_get_handle(),
+ pidgin_accounts_get_handle(),
PURPLE_CALLBACK(account_abled_cb), GINT_TO_POINTER(TRUE));
account_pref_wins =
@@ -2972,7 +2976,7 @@ pidgin_account_init(void)
}
void
-pidgin_account_uninit(void)
+pidgin_accounts_uninit(void)
{
/*
* TODO: Need to free all the dialogs in here. Could probably create
@@ -2981,7 +2985,7 @@ pidgin_account_uninit(void)
*/
g_hash_table_destroy(account_pref_wins);
- purple_signals_disconnect_by_handle(pidgin_account_get_handle());
- purple_signals_unregister_by_instance(pidgin_account_get_handle());
+ purple_signals_disconnect_by_handle(pidgin_accounts_get_handle());
+ purple_signals_unregister_by_instance(pidgin_accounts_get_handle());
}
diff --git a/pidgin/gtkaccount.h b/pidgin/gtkaccount.h
index 8410d8817d..14df316e65 100644
--- a/pidgin/gtkaccount.h
+++ b/pidgin/gtkaccount.h
@@ -27,7 +27,7 @@
#ifndef _PIDGINACCOUNT_H_
#define _PIDGINACCOUNT_H_
-#include "account.h"
+#include "accounts.h"
typedef enum
{
@@ -70,17 +70,17 @@ PurpleAccountUiOps *pidgin_accounts_get_ui_ops(void);
*
* @return The handle to the GTK+ account system
*/
-void *pidgin_account_get_handle(void);
+void *pidgin_accounts_get_handle(void);
/**
* Initializes the GTK+ account system
*/
-void pidgin_account_init(void);
+void pidgin_accounts_init(void);
/**
* Uninitializes the GTK+ account system
*/
-void pidgin_account_uninit(void);
+void pidgin_accounts_uninit(void);
G_END_DECLS
diff --git a/pidgin/gtkblist.c b/pidgin/gtkblist.c
index 57bf8327bc..bd41d25103 100644
--- a/pidgin/gtkblist.c
+++ b/pidgin/gtkblist.c
@@ -203,7 +203,7 @@ static gboolean gtk_blist_visibility_cb(GtkWidget *w, GdkEventVisibility *event,
old_state != GDK_VISIBILITY_FULLY_OBSCURED) {
/* no longer fully obscured */
- pidgin_blist_refresh_timer(purple_get_blist());
+ pidgin_blist_refresh_timer(purple_blist_get_buddy_list());
}
/* continue to handle event normally */
@@ -217,7 +217,7 @@ static gboolean gtk_blist_window_state_cb(GtkWidget *w, GdkEventWindowState *eve
purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_visible", FALSE);
else {
purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_visible", TRUE);
- pidgin_blist_refresh_timer(purple_get_blist());
+ pidgin_blist_refresh_timer(purple_blist_get_buddy_list());
}
}
@@ -231,7 +231,7 @@ static gboolean gtk_blist_window_state_cb(GtkWidget *w, GdkEventWindowState *eve
/* Refresh gtkblist if un-iconifying */
if (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED){
if (!(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED))
- pidgin_blist_refresh_timer(purple_get_blist());
+ pidgin_blist_refresh_timer(purple_blist_get_buddy_list());
}
return FALSE;
@@ -376,9 +376,8 @@ find_conversation_with_buddy(PurpleBuddy *buddy)
PidginBlistNode *ui = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy));
if (ui)
return ui->conv.conv;
- return purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- purple_buddy_get_name(buddy),
- purple_buddy_get_account(buddy));
+ return PURPLE_CONVERSATION(purple_conversations_find_im_with_account(
+ purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)));
}
static void gtk_blist_join_chat(PurpleChat *chat)
@@ -405,8 +404,8 @@ static void gtk_blist_join_chat(PurpleChat *chat)
else
name = purple_chat_get_name(chat);
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, name,
- account);
+ conv = PURPLE_CONVERSATION(purple_conversations_find_chat_with_account(name,
+ account));
if (conv != NULL) {
pidgin_conv_attach_to_conversation(conv);
@@ -444,22 +443,16 @@ static void gtk_blist_renderer_editing_started_cb(GtkCellRenderer *renderer,
gtk_tree_path_free (path);
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1);
- switch (purple_blist_node_get_type(node)) {
- case PURPLE_BLIST_CONTACT_NODE:
+ if (PURPLE_IS_CONTACT(node))
text = purple_contact_get_alias(PURPLE_CONTACT(node));
- break;
- case PURPLE_BLIST_BUDDY_NODE:
+ else if (PURPLE_IS_BUDDY(node))
text = purple_buddy_get_alias(PURPLE_BUDDY(node));
- break;
- case PURPLE_BLIST_GROUP_NODE:
+ else if (PURPLE_IS_GROUP(node))
text = purple_group_get_name(PURPLE_GROUP(node));
- break;
- case PURPLE_BLIST_CHAT_NODE:
+ else if (PURPLE_IS_CHAT(node))
text = purple_chat_get_name(PURPLE_CHAT(node));
- break;
- default:
+ else
g_return_if_reached();
- }
if (GTK_IS_ENTRY (editable)) {
GtkEntry *entry = GTK_ENTRY (editable);
@@ -482,17 +475,12 @@ gtk_blist_do_personize(GList *merges)
for (tmp = merges; tmp; tmp = tmp->next) {
PurpleBlistNode *node = tmp->data;
PurpleBlistNode *b;
- PurpleBlistNodeType type;
int i = 0;
- type = purple_blist_node_get_type(node);
-
- if (type == PURPLE_BLIST_BUDDY_NODE) {
+ if (PURPLE_IS_BUDDY(node))
node = purple_blist_node_get_parent(node);
- type = purple_blist_node_get_type(node);
- }
- if (type != PURPLE_BLIST_CONTACT_NODE)
+ if (!PURPLE_IS_CONTACT(node))
continue;
for (b = purple_blist_node_get_first_child(node);
@@ -514,13 +502,13 @@ gtk_blist_do_personize(GList *merges)
/* Merge all those buddies into this contact */
for (tmp = merges; tmp; tmp = tmp->next) {
PurpleBlistNode *node = tmp->data;
- if (purple_blist_node_get_type(node) == PURPLE_BLIST_BUDDY_NODE)
+ if (PURPLE_IS_BUDDY(node))
node = purple_blist_node_get_parent(node);
if (node == contact)
continue;
- purple_blist_merge_contact((PurpleContact *)node, contact);
+ purple_contact_merge((PurpleContact *)node, contact);
}
/* And show the expanded contact, so the people know what's going on */
@@ -541,7 +529,7 @@ gtk_blist_auto_personize(PurpleBlistNode *group, const char *alias)
contact != NULL;
contact = purple_blist_node_get_sibling_next(contact)) {
char *node_alias;
- if (purple_blist_node_get_type(contact) != PURPLE_BLIST_CONTACT_NODE)
+ if (!PURPLE_IS_CONTACT(contact))
continue;
node_alias = g_utf8_casefold(purple_contact_get_alias((PurpleContact *)contact), -1);
@@ -557,7 +545,7 @@ gtk_blist_auto_personize(PurpleBlistNode *group, const char *alias)
buddy;
buddy = purple_blist_node_get_sibling_next(buddy))
{
- if (purple_blist_node_get_type(buddy) != PURPLE_BLIST_BUDDY_NODE)
+ if (!PURPLE_IS_BUDDY(buddy))
continue;
node_alias = g_utf8_casefold(purple_buddy_get_alias(PURPLE_BUDDY(buddy)), -1);
@@ -590,6 +578,7 @@ static void gtk_blist_renderer_edited_cb(GtkCellRendererText *text_rend, char *a
GtkTreePath *path;
PurpleBlistNode *node;
PurpleGroup *dest;
+ gchar *alias;
editing_blist = FALSE;
path = gtk_tree_path_new_from_string (arg1);
@@ -599,56 +588,46 @@ static void gtk_blist_renderer_edited_cb(GtkCellRendererText *text_rend, char *a
gtk_tree_view_set_enable_search (GTK_TREE_VIEW(gtkblist->treeview), TRUE);
g_object_set(G_OBJECT(gtkblist->text_rend), "editable", FALSE, NULL);
- switch (purple_blist_node_get_type(node))
- {
- case PURPLE_BLIST_CONTACT_NODE:
- {
- PurpleContact *contact = PURPLE_CONTACT(node);
- struct _pidgin_blist_node *gtknode =
- (struct _pidgin_blist_node *)purple_blist_node_get_ui_data(node);
+ if (PURPLE_IS_CONTACT(node)) {
+ PurpleContact *contact = PURPLE_CONTACT(node);
+ struct _pidgin_blist_node *gtknode =
+ (struct _pidgin_blist_node *)purple_blist_node_get_ui_data(node);
- /*
- * XXX Using purple_contact_get_alias here breaks because we
- * specifically want to check the contact alias only (i.e. not
- * the priority buddy, which purple_contact_get_alias does).
- * Adding yet another get_alias is evil, so figure this out
- * later :-P
- */
- if (contact->alias || gtknode->contact_expanded) {
- purple_blist_alias_contact(contact, arg2);
- gtk_blist_auto_personize(purple_blist_node_get_parent(node), arg2);
- } else {
- PurpleBuddy *buddy = purple_contact_get_priority_buddy(contact);
- purple_blist_alias_buddy(buddy, arg2);
- serv_alias_buddy(buddy);
- gtk_blist_auto_personize(purple_blist_node_get_parent(node), arg2);
- }
- }
- break;
-
- case PURPLE_BLIST_BUDDY_NODE:
- {
- PurpleGroup *group = purple_buddy_get_group(PURPLE_BUDDY(node));
+ /*
+ * Using purple_contact_get_alias here breaks because we
+ * specifically want to check the contact alias only (i.e. not
+ * the priority buddy, which purple_contact_get_alias does).
+ * The "alias" GObject property gives us just the alias.
+ */
+ g_object_get(contact, "alias", &alias, NULL);
- purple_blist_alias_buddy(PURPLE_BUDDY(node), arg2);
- serv_alias_buddy(PURPLE_BUDDY(node));
- gtk_blist_auto_personize(PURPLE_BLIST_NODE(group), arg2);
- }
- break;
- case PURPLE_BLIST_GROUP_NODE:
- dest = purple_find_group(arg2);
- if (dest != NULL && purple_utf8_strcasecmp(arg2, purple_group_get_name(PURPLE_GROUP(node)))) {
- pidgin_dialogs_merge_groups(PURPLE_GROUP(node), arg2);
- } else {
- purple_blist_rename_group(PURPLE_GROUP(node), arg2);
- }
- break;
- case PURPLE_BLIST_CHAT_NODE:
- purple_blist_alias_chat(PURPLE_CHAT(node), arg2);
- break;
- default:
- break;
+ if (alias || gtknode->contact_expanded) {
+ purple_contact_set_alias(contact, arg2);
+ gtk_blist_auto_personize(purple_blist_node_get_parent(node), arg2);
+ } else {
+ PurpleBuddy *buddy = purple_contact_get_priority_buddy(contact);
+ purple_buddy_set_local_alias(buddy, arg2);
+ serv_alias_buddy(buddy);
+ gtk_blist_auto_personize(purple_blist_node_get_parent(node), arg2);
+ }
+ } else if (PURPLE_IS_BUDDY(node)) {
+ PurpleGroup *group = purple_buddy_get_group(PURPLE_BUDDY(node));
+
+ purple_buddy_set_local_alias(PURPLE_BUDDY(node), arg2);
+ serv_alias_buddy(PURPLE_BUDDY(node));
+ gtk_blist_auto_personize(PURPLE_BLIST_NODE(group), arg2);
+ } else if (PURPLE_IS_GROUP(node)) {
+ dest = purple_blist_find_group(arg2);
+ if (dest != NULL && purple_utf8_strcasecmp(arg2, purple_group_get_name(PURPLE_GROUP(node)))) {
+ pidgin_dialogs_merge_groups(PURPLE_GROUP(node), arg2);
+ } else {
+ purple_group_set_name(PURPLE_GROUP(node), arg2);
+ }
+ } else if (PURPLE_IS_CHAT(node)) {
+ purple_chat_set_alias(PURPLE_CHAT(node), arg2);
}
+
+ g_free(alias);
pidgin_blist_refresh(list);
}
@@ -762,12 +741,12 @@ static void gtk_blist_menu_showlog_cb(GtkWidget *w, PurpleBlistNode *node)
pidgin_set_cursor(gtkblist->window, GDK_WATCH);
- if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if (PURPLE_IS_BUDDY(node)) {
PurpleBuddy *b = (PurpleBuddy*) node;
type = PURPLE_LOG_IM;
name = g_strdup(purple_buddy_get_name(b));
account = purple_buddy_get_account(b);
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
PurpleChat *c = PURPLE_CHAT(node);
PurplePluginProtocolInfo *prpl_info = NULL;
type = PURPLE_LOG_CHAT;
@@ -776,7 +755,7 @@ static void gtk_blist_menu_showlog_cb(GtkWidget *w, PurpleBlistNode *node)
if (prpl_info && prpl_info->get_chat_name) {
name = prpl_info->get_chat_name(purple_chat_get_components(c));
}
- } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ } else if (PURPLE_IS_CONTACT(node)) {
pidgin_log_show_contact(PURPLE_CONTACT(node));
pidgin_clear_cursor(gtkblist->window);
return;
@@ -798,13 +777,13 @@ static void gtk_blist_menu_showlog_cb(GtkWidget *w, PurpleBlistNode *node)
static void gtk_blist_menu_showoffline_cb(GtkWidget *w, PurpleBlistNode *node)
{
- if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (PURPLE_IS_BUDDY(node))
{
purple_blist_node_set_bool(node, "show_offline",
!purple_blist_node_get_bool(node, "show_offline"));
- pidgin_blist_update(purple_get_blist(), node);
+ pidgin_blist_update(purple_blist_get_buddy_list(), node);
}
- else if (PURPLE_BLIST_NODE_IS_CONTACT(node))
+ else if (PURPLE_IS_CONTACT(node))
{
PurpleBlistNode *bnode;
gboolean setting = !purple_blist_node_get_bool(node, "show_offline");
@@ -815,9 +794,9 @@ static void gtk_blist_menu_showoffline_cb(GtkWidget *w, PurpleBlistNode *node)
bnode = purple_blist_node_get_sibling_next(bnode))
{
purple_blist_node_set_bool(bnode, "show_offline", setting);
- pidgin_blist_update(purple_get_blist(), bnode);
+ pidgin_blist_update(purple_blist_get_buddy_list(), bnode);
}
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
PurpleBlistNode *cnode, *bnode;
gboolean setting = !purple_blist_node_get_bool(node, "show_offline");
@@ -832,7 +811,7 @@ static void gtk_blist_menu_showoffline_cb(GtkWidget *w, PurpleBlistNode *node)
bnode = purple_blist_node_get_sibling_next(bnode))
{
purple_blist_node_set_bool(bnode, "show_offline", setting);
- pidgin_blist_update(purple_get_blist(), bnode);
+ pidgin_blist_update(purple_blist_get_buddy_list(), bnode);
}
}
}
@@ -960,7 +939,7 @@ pidgin_blist_update_privacy_cb(PurpleBuddy *buddy)
struct _pidgin_blist_node *ui_data = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy));
if (ui_data == NULL || ui_data->row == NULL)
return;
- pidgin_blist_update_buddy(purple_get_blist(), PURPLE_BLIST_NODE(buddy), TRUE);
+ pidgin_blist_update_buddy(purple_blist_get_buddy_list(), PURPLE_BLIST_NODE(buddy), TRUE);
}
static gboolean
@@ -1011,7 +990,7 @@ make_blist_request_dialog(PidginBlistRequestData *data, PurpleAccount *account,
img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION,
gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE));
- gtkblist = PIDGIN_BLIST(purple_get_blist());
+ gtkblist = PIDGIN_BLIST(purple_blist_get_buddy_list());
blist_window = gtkblist ? GTK_WINDOW(gtkblist->window) : NULL;
data->window = gtk_dialog_new();
@@ -1194,7 +1173,7 @@ static void gtk_blist_row_expanded_cb(GtkTreeView *tv, GtkTreeIter *iter, GtkTre
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), iter, NODE_COLUMN, &node, -1);
- if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ if (PURPLE_IS_GROUP(node)) {
char *title;
title = pidgin_get_group_title(node, TRUE);
@@ -1216,7 +1195,7 @@ static void gtk_blist_row_collapsed_cb(GtkTreeView *tv, GtkTreeIter *iter, GtkTr
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), iter, NODE_COLUMN, &node, -1);
- if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ if (PURPLE_IS_GROUP(node)) {
char *title;
struct _pidgin_blist_node *gtknode;
PurpleBlistNode *cnode;
@@ -1232,7 +1211,7 @@ static void gtk_blist_row_collapsed_cb(GtkTreeView *tv, GtkTreeIter *iter, GtkTr
purple_blist_node_set_bool(node, "collapsed", TRUE);
for(cnode = purple_blist_node_get_first_child(node); cnode; cnode = purple_blist_node_get_sibling_next(cnode)) {
- if (PURPLE_BLIST_NODE_IS_CONTACT(cnode)) {
+ if (PURPLE_IS_CONTACT(cnode)) {
gtknode = purple_blist_node_get_ui_data(cnode);
if (!gtknode->contact_expanded)
continue;
@@ -1241,7 +1220,7 @@ static void gtk_blist_row_collapsed_cb(GtkTreeView *tv, GtkTreeIter *iter, GtkTr
}
}
pidgin_blist_tooltip_destroy();
- } else if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ } else if(PURPLE_IS_CONTACT(node)) {
pidgin_blist_collapse_contact_cb(NULL, node);
}
}
@@ -1253,18 +1232,18 @@ static void gtk_blist_row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTr
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);
- if(PURPLE_BLIST_NODE_IS_CONTACT(node) || PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if(PURPLE_IS_CONTACT(node) || PURPLE_IS_BUDDY(node)) {
PurpleBuddy *buddy;
- if(PURPLE_BLIST_NODE_IS_CONTACT(node))
+ if(PURPLE_IS_CONTACT(node))
buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
else
buddy = (PurpleBuddy*)node;
pidgin_dialogs_im_with_user(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy));
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
gtk_blist_join_chat((PurpleChat *)node);
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
/* if (gtk_tree_view_row_expanded(tv, path))
gtk_tree_view_collapse_row(tv, path);
else
@@ -1280,11 +1259,11 @@ static void pidgin_blist_add_chat_cb(void)
if(gtk_tree_selection_get_selected(sel, NULL, &iter)){
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1);
- if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (PURPLE_IS_BUDDY(node))
purple_blist_request_add_chat(NULL, purple_buddy_get_group(PURPLE_BUDDY(node)), NULL, NULL);
- if (PURPLE_BLIST_NODE_IS_CONTACT(node) || PURPLE_BLIST_NODE_IS_CHAT(node))
+ if (PURPLE_IS_CONTACT(node) || PURPLE_IS_CHAT(node))
purple_blist_request_add_chat(NULL, purple_contact_get_group(PURPLE_CONTACT(node)), NULL, NULL);
- else if (PURPLE_BLIST_NODE_IS_GROUP(node))
+ else if (PURPLE_IS_GROUP(node))
purple_blist_request_add_chat(NULL, (PurpleGroup*)node, NULL, NULL);
}
else {
@@ -1300,13 +1279,13 @@ static void pidgin_blist_add_buddy_cb(void)
if(gtk_tree_selection_get_selected(sel, NULL, &iter)){
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1);
- if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if (PURPLE_IS_BUDDY(node)) {
PurpleGroup *group = purple_buddy_get_group(PURPLE_BUDDY(node));
purple_blist_request_add_buddy(NULL, NULL, purple_group_get_name(group), NULL);
- } else if (PURPLE_BLIST_NODE_IS_CONTACT(node) || PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CONTACT(node) || PURPLE_IS_CHAT(node)) {
PurpleGroup *group = purple_contact_get_group(PURPLE_CONTACT(node));
purple_blist_request_add_buddy(NULL, NULL, purple_group_get_name(group), NULL);
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
purple_blist_request_add_buddy(NULL, NULL, purple_group_get_name(PURPLE_GROUP(node)), NULL);
}
}
@@ -1318,13 +1297,13 @@ static void pidgin_blist_add_buddy_cb(void)
static void
pidgin_blist_remove_cb (GtkWidget *w, PurpleBlistNode *node)
{
- if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if (PURPLE_IS_BUDDY(node)) {
pidgin_dialogs_remove_buddy((PurpleBuddy*)node);
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
pidgin_dialogs_remove_chat((PurpleChat*)node);
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
pidgin_dialogs_remove_group((PurpleGroup*)node);
- } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ } else if (PURPLE_IS_CONTACT(node)) {
pidgin_dialogs_remove_contact((PurpleContact*)node);
}
}
@@ -1356,7 +1335,7 @@ pidgin_blist_expand_contact_cb(GtkWidget *w, PurpleBlistNode *node)
PurpleBlistNode *bnode;
GtkTreePath *path;
- if(!PURPLE_BLIST_NODE_IS_CONTACT(node))
+ if(!PURPLE_IS_CONTACT(node))
return;
gtknode = purple_blist_node_get_ui_data(node);
@@ -1389,7 +1368,7 @@ pidgin_blist_collapse_contact_cb(GtkWidget *w, PurpleBlistNode *node)
PurpleBlistNode *bnode;
struct _pidgin_blist_node *gtknode;
- if(!PURPLE_BLIST_NODE_IS_CONTACT(node))
+ if(!PURPLE_IS_CONTACT(node))
return;
gtknode = purple_blist_node_get_ui_data(node);
@@ -1409,23 +1388,23 @@ toggle_privacy(GtkWidget *widget, PurpleBlistNode *node)
gboolean permitted;
const char *name;
- if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (!PURPLE_IS_BUDDY(node))
return;
buddy = (PurpleBuddy *)node;
account = purple_buddy_get_account(buddy);
name = purple_buddy_get_name(buddy);
- permitted = purple_privacy_check(account, name);
+ permitted = purple_account_privacy_check(account, name);
/* XXX: Perhaps ask whether to restore the previous lists where appropirate? */
if (permitted)
- purple_privacy_deny(account, name, FALSE, FALSE);
+ purple_account_privacy_deny(account, name);
else
- purple_privacy_allow(account, name, FALSE, FALSE);
+ purple_account_privacy_allow(account, name);
- pidgin_blist_update(purple_get_blist(), node);
+ pidgin_blist_update(purple_blist_get_buddy_list(), node);
}
void pidgin_append_blist_node_privacy_menu(GtkWidget *menu, PurpleBlistNode *node)
@@ -1435,7 +1414,7 @@ void pidgin_append_blist_node_privacy_menu(GtkWidget *menu, PurpleBlistNode *nod
gboolean permitted;
account = purple_buddy_get_account(buddy);
- permitted = purple_privacy_check(account, purple_buddy_get_name(buddy));
+ permitted = purple_account_privacy_check(account, purple_buddy_get_name(buddy));
pidgin_new_item_from_stock(menu, permitted ? _("_Block") : _("Un_block"),
permitted ? PIDGIN_STOCK_TOOLBAR_BLOCK : PIDGIN_STOCK_TOOLBAR_UNBLOCK, G_CALLBACK(toggle_privacy),
@@ -1488,7 +1467,7 @@ pidgin_append_blist_node_move_to_menu(GtkWidget *menu, PurpleBlistNode *node)
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
for (group = purple_blist_get_root(); group; group = purple_blist_node_get_sibling_next(group)) {
- if (!PURPLE_BLIST_NODE_IS_GROUP(group))
+ if (!PURPLE_IS_GROUP(group))
continue;
if (group == purple_blist_node_get_parent(node))
continue;
@@ -1577,7 +1556,7 @@ pidgin_blist_make_buddy_menu(GtkWidget *menu, PurpleBuddy *buddy, gboolean sub)
G_CALLBACK(gtk_blist_menu_showlog_cb), buddy, 0, 0, NULL);
}
- if (!PURPLE_BLIST_NODE_HAS_FLAG(node, PURPLE_BLIST_NODE_FLAG_NO_SAVE)) {
+ if (!purple_blist_node_is_transient(node)) {
gboolean show_offline = purple_blist_node_get_bool(node, "show_offline");
pidgin_new_item_from_stock(menu, show_offline ? _("Hide When Offline") : _("Show When Offline"),
NULL, G_CALLBACK(gtk_blist_menu_showoffline_cb), node, 0, 0, NULL);
@@ -1628,9 +1607,9 @@ gtk_blist_key_press_cb(GtkWidget *tv, GdkEventKey *event, gpointer data)
(event->keyval == 'o' || event->keyval == 'O')) {
PurpleBuddy *buddy;
- if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if(PURPLE_IS_CONTACT(node)) {
buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
- } else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ } else if(PURPLE_IS_BUDDY(node)) {
buddy = (PurpleBuddy*)node;
} else {
return FALSE;
@@ -1669,11 +1648,11 @@ gtk_blist_key_press_cb(GtkWidget *tv, GdkEventKey *event, gpointer data)
path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter);
if (!gtk_tree_view_row_expanded(GTK_TREE_VIEW(tv), path)) {
/* Expand the Group */
- if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if (PURPLE_IS_CONTACT(node)) {
pidgin_blist_expand_contact_cb(NULL, node);
gtk_tree_path_free(path);
return TRUE;
- } else if (!PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ } else if (!PURPLE_IS_BUDDY(node)) {
gtk_tree_view_expand_row(GTK_TREE_VIEW(tv), path, FALSE);
gtk_tree_path_free(path);
return TRUE;
@@ -1757,7 +1736,7 @@ create_group_menu (PurpleBlistNode *node, PurpleGroup *g)
G_CALLBACK(pidgin_blist_remove_cb), node, 0, 0, NULL);
pidgin_new_item_from_stock(menu, _("_Rename"), NULL,
G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL);
- if (!(purple_blist_node_get_flags(node) & PURPLE_BLIST_NODE_FLAG_NO_SAVE)) {
+ if (!purple_blist_node_is_transient(node)) {
gboolean show_offline = purple_blist_node_get_bool(node, "show_offline");
pidgin_new_item_from_stock(menu, show_offline ? _("Hide When Offline") : _("Show When Offline"),
NULL, G_CALLBACK(gtk_blist_menu_showoffline_cb), node, 0, 0, NULL);
@@ -1847,7 +1826,7 @@ create_buddy_menu(PurpleBlistNode *node, PurpleBuddy *b)
menu = gtk_menu_new();
pidgin_blist_make_buddy_menu(menu, b, FALSE);
- if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if(PURPLE_IS_CONTACT(node)) {
pidgin_separator(menu);
add_buddy_icon_menu_items(menu, node);
@@ -1912,20 +1891,20 @@ pidgin_blist_show_context_menu(PurpleBlistNode *node,
gboolean handled = FALSE;
/* Create a menu based on the thing we right-clicked on */
- if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ if (PURPLE_IS_GROUP(node)) {
PurpleGroup *g = (PurpleGroup *)node;
menu = create_group_menu(node, g);
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
PurpleChat *c = (PurpleChat *)node;
menu = create_chat_menu(node, c);
- } else if ((PURPLE_BLIST_NODE_IS_CONTACT(node)) && (gtknode->contact_expanded)) {
+ } else if ((PURPLE_IS_CONTACT(node)) && (gtknode->contact_expanded)) {
menu = create_contact_menu(node);
- } else if (PURPLE_BLIST_NODE_IS_CONTACT(node) || PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ } else if (PURPLE_IS_CONTACT(node) || PURPLE_IS_BUDDY(node)) {
PurpleBuddy *b;
- if (PURPLE_BLIST_NODE_IS_CONTACT(node))
+ if (PURPLE_IS_CONTACT(node))
b = purple_contact_get_priority_buddy((PurpleContact*)node);
else
b = (PurpleBuddy *)node;
@@ -1980,7 +1959,7 @@ gtk_blist_button_press_cb(GtkWidget *tv, GdkEventButton *event, gpointer user_da
/* CTRL+middle click expands or collapse a contact */
} else if ((event->button == 2) && (event->type == GDK_BUTTON_PRESS) &&
- (event->state & GDK_CONTROL_MASK) && (PURPLE_BLIST_NODE_IS_CONTACT(node))) {
+ (event->state & GDK_CONTROL_MASK) && (PURPLE_IS_CONTACT(node))) {
if (gtknode->contact_expanded)
pidgin_blist_collapse_contact_cb(NULL, node);
else
@@ -1989,9 +1968,9 @@ gtk_blist_button_press_cb(GtkWidget *tv, GdkEventButton *event, gpointer user_da
/* Double middle click gets info */
} else if ((event->button == 2) && (event->type == GDK_2BUTTON_PRESS) &&
- ((PURPLE_BLIST_NODE_IS_CONTACT(node)) || (PURPLE_BLIST_NODE_IS_BUDDY(node)))) {
+ ((PURPLE_IS_CONTACT(node)) || (PURPLE_IS_BUDDY(node)))) {
PurpleBuddy *b;
- if(PURPLE_BLIST_NODE_IS_CONTACT(node))
+ if(PURPLE_IS_CONTACT(node))
b = purple_contact_get_priority_buddy((PurpleContact*)node);
else
b = (PurpleBuddy *)node;
@@ -2316,11 +2295,11 @@ static void pidgin_blist_drag_data_get_cb(GtkWidget *widget,
sourcerow);
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1);
- if (PURPLE_BLIST_NODE_IS_CONTACT(node))
+ if (PURPLE_IS_CONTACT(node))
{
buddy = purple_contact_get_priority_buddy((PurpleContact *)node);
}
- else if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
+ else if (!PURPLE_IS_BUDDY(node))
{
gtk_tree_path_free(sourcerow);
return;
@@ -2351,11 +2330,11 @@ static void pidgin_blist_drag_data_get_cb(GtkWidget *widget,
protocol,
purple_buddy_get_name(buddy));
- if (purple_buddy_get_local_buddy_alias(buddy) != NULL)
+ if (purple_buddy_get_local_alias(buddy) != NULL)
{
g_string_append_printf(str,
"X-IM-Alias: %s\r\n",
- purple_buddy_get_local_buddy_alias(buddy));
+ purple_buddy_get_local_alias(buddy));
}
g_string_append(str, "\r\n");
@@ -2399,12 +2378,12 @@ static void pidgin_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc,
&iter, NODE_COLUMN, &node, -1);
gtknode = purple_blist_node_get_ui_data(node);
- if (PURPLE_BLIST_NODE_IS_CONTACT(n)) {
+ if (PURPLE_IS_CONTACT(n)) {
PurpleContact *c = (PurpleContact*)n;
- if (PURPLE_BLIST_NODE_IS_CONTACT(node) && gtknode->contact_expanded) {
- purple_blist_merge_contact(c, node);
- } else if (PURPLE_BLIST_NODE_IS_CONTACT(node) ||
- PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ if (PURPLE_IS_CONTACT(node) && gtknode->contact_expanded) {
+ purple_contact_merge(c, node);
+ } else if (PURPLE_IS_CONTACT(node) ||
+ PURPLE_IS_CHAT(node)) {
switch(position) {
case GTK_TREE_VIEW_DROP_AFTER:
case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
@@ -2417,14 +2396,14 @@ static void pidgin_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc,
node->prev);
break;
}
- } else if(PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if(PURPLE_IS_GROUP(node)) {
purple_blist_add_contact(c, (PurpleGroup*)node, NULL);
- } else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
- purple_blist_merge_contact(c, node);
+ } else if(PURPLE_IS_BUDDY(node)) {
+ purple_contact_merge(c, node);
}
- } else if (PURPLE_BLIST_NODE_IS_BUDDY(n)) {
+ } else if (PURPLE_IS_BUDDY(n)) {
PurpleBuddy *b = (PurpleBuddy*)n;
- if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if (PURPLE_IS_BUDDY(node)) {
switch(position) {
case GTK_TREE_VIEW_DROP_AFTER:
case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
@@ -2438,12 +2417,12 @@ static void pidgin_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc,
node->prev);
break;
}
- } else if(PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if(PURPLE_IS_CHAT(node)) {
purple_blist_add_buddy(b, NULL, (PurpleGroup*)node->parent,
NULL);
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
purple_blist_add_buddy(b, NULL, (PurpleGroup*)node, NULL);
- } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ } else if (PURPLE_IS_CONTACT(node)) {
if(gtknode->contact_expanded) {
switch(position) {
case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
@@ -2472,9 +2451,9 @@ static void pidgin_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc,
}
}
}
- } else if (PURPLE_BLIST_NODE_IS_CHAT(n)) {
+ } else if (PURPLE_IS_CHAT(n)) {
PurpleChat *chat = (PurpleChat *)n;
- if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if (PURPLE_IS_BUDDY(node)) {
switch(position) {
case GTK_TREE_VIEW_DROP_AFTER:
case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
@@ -2485,8 +2464,8 @@ static void pidgin_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc,
node->parent);
break;
}
- } else if(PURPLE_BLIST_NODE_IS_CONTACT(node) ||
- PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if(PURPLE_IS_CONTACT(node) ||
+ PURPLE_IS_CHAT(node)) {
switch(position) {
case GTK_TREE_VIEW_DROP_AFTER:
case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
@@ -2497,12 +2476,12 @@ static void pidgin_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc,
purple_blist_add_chat(chat, (PurpleGroup*)node->parent, node->prev);
break;
}
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
purple_blist_add_chat(chat, (PurpleGroup*)node, NULL);
}
- } else if (PURPLE_BLIST_NODE_IS_GROUP(n)) {
+ } else if (PURPLE_IS_GROUP(n)) {
PurpleGroup *g = (PurpleGroup*)n;
- if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ if (PURPLE_IS_GROUP(node)) {
switch (position) {
case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
case GTK_TREE_VIEW_DROP_AFTER:
@@ -2513,10 +2492,10 @@ static void pidgin_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc,
purple_blist_add_group(g, node->prev);
break;
}
- } else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ } else if(PURPLE_IS_BUDDY(node)) {
purple_blist_add_group(g, node->parent->parent);
- } else if(PURPLE_BLIST_NODE_IS_CONTACT(node) ||
- PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if(PURPLE_IS_CONTACT(node) ||
+ PURPLE_IS_CHAT(node)) {
purple_blist_add_group(g, node->parent);
}
}
@@ -2545,16 +2524,16 @@ static void pidgin_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc,
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel),
&iter, NODE_COLUMN, &node, -1);
- if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (PURPLE_IS_BUDDY(node))
{
group = (PurpleGroup *)node->parent->parent;
}
- else if (PURPLE_BLIST_NODE_IS_CHAT(node) ||
- PURPLE_BLIST_NODE_IS_CONTACT(node))
+ else if (PURPLE_IS_CHAT(node) ||
+ PURPLE_IS_CONTACT(node))
{
group = (PurpleGroup *)node->parent;
}
- else if (PURPLE_BLIST_NODE_IS_GROUP(node))
+ else if (PURPLE_IS_GROUP(node))
{
group = (PurpleGroup *)node;
}
@@ -2605,16 +2584,16 @@ static void pidgin_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc,
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel),
&iter, NODE_COLUMN, &node, -1);
- if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (PURPLE_IS_BUDDY(node))
{
group = (PurpleGroup *)node->parent->parent;
}
- else if (PURPLE_BLIST_NODE_IS_CHAT(node) ||
- PURPLE_BLIST_NODE_IS_CONTACT(node))
+ else if (PURPLE_IS_CHAT(node) ||
+ PURPLE_IS_CONTACT(node))
{
group = (PurpleGroup *)node->parent;
}
- else if (PURPLE_BLIST_NODE_IS_GROUP(node))
+ else if (PURPLE_IS_GROUP(node))
{
group = (PurpleGroup *)node;
}
@@ -2639,8 +2618,8 @@ static void pidgin_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc,
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel),
&iter, NODE_COLUMN, &node, -1);
- 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));
+ if (PURPLE_IS_BUDDY(node) || PURPLE_IS_CONTACT(node)) {
+ PurpleBuddy *b = PURPLE_IS_BUDDY(node) ? PURPLE_BUDDY(node) : purple_contact_get_priority_buddy(PURPLE_CONTACT(node));
pidgin_dnd_file_manage(sd, purple_buddy_get_account(b), purple_buddy_get_name(b));
gtk_drag_finish(dc, TRUE,
gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
@@ -2696,15 +2675,15 @@ static GdkPixbuf *pidgin_blist_get_buddy_icon(PurpleBlistNode *node,
PurplePluginProtocolInfo *prpl_info = NULL;
gint orig_width, orig_height, scale_width, scale_height;
- if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if (PURPLE_IS_CONTACT(node)) {
buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
contact = (PurpleContact*)node;
- } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ } else if (PURPLE_IS_BUDDY(node)) {
buddy = (PurpleBuddy*)node;
contact = purple_buddy_get_contact(buddy);
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
group = (PurpleGroup*)node;
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
/* We don't need to do anything here. We just need to not fall
* into the else block and return. */
} else {
@@ -2776,7 +2755,7 @@ static GdkPixbuf *pidgin_blist_get_buddy_icon(PurpleBlistNode *node,
if (purple_presence_is_idle(presence))
idle = TRUE;
} else if (group) {
- if (purple_blist_get_group_online_count(group) == 0)
+ if (purple_counting_node_get_online_count(PURPLE_COUNTING_NODE(group)) == 0)
offline = TRUE;
}
@@ -2911,9 +2890,9 @@ static struct tooltip_data * create_tip_for_node(PurpleBlistNode *node, gboolean
PurpleAccount *account = NULL;
char *tmp = NULL, *node_name = NULL, *tooltip_text = NULL;
- if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if (PURPLE_IS_BUDDY(node)) {
account = purple_buddy_get_account((PurpleBuddy*)(node));
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
account = purple_chat_get_account((PurpleChat*)(node));
}
@@ -2928,11 +2907,11 @@ static struct tooltip_data * create_tip_for_node(PurpleBlistNode *node, gboolean
td->layout = create_pango_layout(tooltip_text, &td->width, &td->height);
}
- if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if (PURPLE_IS_BUDDY(node)) {
tmp = g_markup_escape_text(purple_buddy_get_name((PurpleBuddy*)node), -1);
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if (PURPLE_IS_CHAT(node)) {
tmp = g_markup_escape_text(purple_chat_get_name((PurpleChat*)node), -1);
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
tmp = g_markup_escape_text(purple_group_get_name((PurpleGroup*)node), -1);
} else {
/* I don't believe this can happen currently, I think
@@ -3201,12 +3180,12 @@ pidgin_blist_create_tooltip_for_node(GtkWidget *widget, gpointer data, int *w, i
}
gtkblist->tipwindow = widget;
- if (PURPLE_BLIST_NODE_IS_CHAT(node) ||
- PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if (PURPLE_IS_CHAT(node) ||
+ PURPLE_IS_BUDDY(node)) {
struct tooltip_data *td = create_tip_for_node(node, TRUE);
pidgin_blist_align_tooltip(td, gtkblist->tipwindow);
gtkblist->tooltipdata = g_list_append(gtkblist->tooltipdata, td);
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
PurpleGroup *group = (PurpleGroup*)node;
GSList *accounts;
struct tooltip_data *td = create_tip_for_node(node, TRUE);
@@ -3221,13 +3200,13 @@ pidgin_blist_create_tooltip_for_node(GtkWidget *widget, gpointer data, int *w, i
td = create_tip_for_account(account);
gtkblist->tooltipdata = g_list_append(gtkblist->tooltipdata, td);
}
- } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ } else if (PURPLE_IS_CONTACT(node)) {
PurpleBlistNode *child;
PurpleBuddy *b = purple_contact_get_priority_buddy((PurpleContact *)node);
for(child = node->child; child; child = child->next)
{
- if(PURPLE_BLIST_NODE_IS_BUDDY(child) && buddy_is_displayable((PurpleBuddy*)child)) {
+ if(PURPLE_IS_BUDDY(child) && buddy_is_displayable((PurpleBuddy*)child)) {
struct tooltip_data *td = create_tip_for_node(child, (b == (PurpleBuddy*)child));
pidgin_blist_align_tooltip(td, gtkblist->tipwindow);
if (b == (PurpleBuddy *)child) {
@@ -3274,7 +3253,7 @@ static gboolean pidgin_blist_expand_timeout(GtkWidget *tv)
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);
- if(!PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if(!PURPLE_IS_CONTACT(node)) {
gtk_tree_path_free(path);
return FALSE;
}
@@ -3490,7 +3469,7 @@ edit_mood_cb(PurpleConnection *gc, PurpleRequestFields *fields)
const char *text;
PurpleAccount *account = purple_connection_get_account(gc);
- if (purple_connection_get_flags(gc) & PURPLE_CONNECTION_SUPPORT_MOOD_MESSAGES) {
+ if (purple_connection_get_flags(gc) & PURPLE_CONNECTION_FLAG_SUPPORT_MOOD_MESSAGES) {
PurpleRequestField *text_field;
text_field = purple_request_fields_get_field(fields, "text");
text = purple_request_field_string_get_value(text_field);
@@ -3506,7 +3485,7 @@ edit_mood_cb(PurpleConnection *gc, PurpleRequestFields *fields)
PurpleAccount *account = (PurpleAccount *) accounts->data;
PurpleConnection *gc = purple_account_get_connection(account);
- if (gc && (purple_connection_get_flags(gc) & PURPLE_CONNECTION_SUPPORT_MOODS)) {
+ if (gc && (purple_connection_get_flags(gc) & PURPLE_CONNECTION_FLAG_SUPPORT_MOODS)) {
update_status_with_mood(account, mood, NULL);
}
}
@@ -3541,12 +3520,12 @@ get_global_moods(void)
if (purple_account_is_connected(account)) {
PurpleConnection *gc = purple_account_get_connection(account);
- if (purple_connection_get_flags(gc) & PURPLE_CONNECTION_SUPPORT_MOODS) {
+ if (purple_connection_get_flags(gc) & PURPLE_CONNECTION_FLAG_SUPPORT_MOODS) {
PurplePluginProtocolInfo *prpl_info =
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
+ /* PURPLE_CONNECTION_FLAG_SUPPORT_MOODS would not be set if the prpl doesn't
* have get_moods, so using PURPLE_PROTOCOL_PLUGIN_HAS_FUNC isn't necessary
* here */
for (mood = prpl_info->get_moods(account) ;
@@ -3602,7 +3581,7 @@ get_global_mood_status(void)
if (purple_account_is_connected(account) &&
(purple_connection_get_flags(purple_account_get_connection(account)) &
- PURPLE_CONNECTION_SUPPORT_MOODS)) {
+ PURPLE_CONNECTION_FLAG_SUPPORT_MOODS)) {
PurplePresence *presence = purple_account_get_presence(account);
PurpleStatus *status = purple_presence_get_status(presence, "mood");
const gchar *curr_mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME);
@@ -3676,7 +3655,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 && (purple_connection_get_flags(gc) & PURPLE_CONNECTION_SUPPORT_MOOD_MESSAGES)) {
+ if (gc && (purple_connection_get_flags(gc) & PURPLE_CONNECTION_FLAG_SUPPORT_MOOD_MESSAGES)) {
g = purple_request_field_group_new(NULL);
f = purple_request_field_string_new("text",
_("Message (optional)"), NULL, FALSE);
@@ -3829,14 +3808,14 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
PurplePluginProtocolInfo *prpl_info = NULL;
char *tmp;
- if (PURPLE_BLIST_NODE_IS_CHAT(node))
+ if (PURPLE_IS_CHAT(node))
{
PurpleChat *chat;
GList *connections;
GList *cur;
struct proto_chat_entry *pce;
char *name, *value;
- PurpleConversation *conv;
+ PurpleChatConversation *conv;
PidginBlistNode *bnode = purple_blist_node_get_ui_data(node);
chat = (PurpleChat *)node;
@@ -3852,7 +3831,7 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
}
if (bnode && bnode->conv.conv) {
- conv = bnode->conv.conv;
+ conv = PURPLE_CHAT_CONVERSATION(bnode->conv.conv);
} else {
char *chat_name;
if (prpl_info && prpl_info->get_chat_name)
@@ -3860,17 +3839,17 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
else
chat_name = g_strdup(purple_chat_get_name(chat));
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, chat_name,
+ conv = purple_conversations_find_chat_with_account(chat_name,
purple_chat_get_account(chat));
g_free(chat_name);
}
- if (conv && !purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv))) {
+ if (conv && !purple_chat_conversation_has_left(conv)) {
g_string_append_printf(str, _("\n<b>Occupants:</b> %d"),
- g_list_length(purple_conv_chat_get_users(PURPLE_CONV_CHAT(conv))));
+ g_list_length(purple_chat_conversation_get_users(conv)));
if (prpl_info && (prpl_info->options & OPT_PROTO_CHAT_TOPIC)) {
- const char *chattopic = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(conv));
+ const char *chattopic = purple_chat_conversation_get_topic(conv);
char *topic = chattopic ? g_markup_escape_text(chattopic, -1) : NULL;
g_string_append_printf(str, _("\n<b>Topic:</b> %s"), topic ? topic : _("(no topic set)"));
g_free(topic);
@@ -3904,7 +3883,7 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
cur = g_list_delete_link(cur, cur);
}
}
- else if (PURPLE_BLIST_NODE_IS_CONTACT(node) || PURPLE_BLIST_NODE_IS_BUDDY(node))
+ else if (PURPLE_IS_CONTACT(node) || PURPLE_IS_BUDDY(node))
{
/* NOTE: THIS FUNCTION IS NO LONGER CALLED FOR CONTACTS.
* It is only called by create_tip_for_node(), and create_tip_for_node() is never called for a contact.
@@ -3915,9 +3894,10 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
PurpleNotifyUserInfo *user_info;
GList *connections;
char *tmp;
+ gchar *alias;
time_t idle_secs, signon;
- if (PURPLE_BLIST_NODE_IS_CONTACT(node))
+ if (PURPLE_IS_CONTACT(node))
{
c = (PurpleContact *)node;
b = purple_contact_get_priority_buddy(c);
@@ -3945,12 +3925,13 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
/* 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 && 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, purple_buddy_get_local_buddy_alias(b)) != 0)
+ g_object_get(c, "alias", &alias, NULL);
+ if (full && c && purple_buddy_get_local_alias(b) != NULL && purple_buddy_get_local_alias(b)[0] != '\0' &&
+ (alias != NULL && alias[0] != '\0') &&
+ strcmp(alias, purple_buddy_get_local_alias(b)) != 0)
{
purple_notify_user_info_add_pair_plaintext(user_info,
- _("Buddy Alias"), purple_buddy_get_local_buddy_alias(b));
+ _("Buddy Alias"), purple_buddy_get_local_alias(b));
}
/* Nickname/Server Alias */
@@ -4000,7 +3981,7 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
PurpleBlistNode *bnode;
int lastseen = 0;
- if (gtknode && (!gtknode->contact_expanded || PURPLE_BLIST_NODE_IS_CONTACT(node)))
+ if (gtknode && (!gtknode->contact_expanded || PURPLE_IS_CONTACT(node)))
{
/* We're either looking at a buddy for a collapsed contact or
* an expanded contact itself so we show the most recent
@@ -4054,16 +4035,17 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
tmp = purple_notify_user_info_get_text_with_newline(user_info, "\n");
g_string_append(str, tmp);
g_free(tmp);
+ g_free(alias);
purple_notify_user_info_destroy(user_info);
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+ } else if (PURPLE_IS_GROUP(node)) {
gint count;
PurpleGroup *group = (PurpleGroup*)node;
PurpleNotifyUserInfo *user_info;
user_info = purple_notify_user_info_new();
- count = purple_blist_get_group_online_count(group);
+ count = purple_counting_node_get_online_count(PURPLE_COUNTING_NODE(group));
if (count != 0) {
/* Online buddies in group */
char tmp2[12];
@@ -4072,7 +4054,7 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
_("Online Buddies"), tmp2);
}
- count = purple_blist_get_group_size(group, FALSE);
+ count = purple_counting_node_get_current_size(PURPLE_COUNTING_NODE(group));
if (count != 0) {
/* Total buddies (from online accounts) in group */
char tmp2[12];
@@ -4133,11 +4115,11 @@ pidgin_blist_get_emblem(PurpleBlistNode *node)
PurplePresence *p = NULL;
PurpleStatus *tune;
- if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if(PURPLE_IS_CONTACT(node)) {
if(!gtknode->contact_expanded) {
buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
}
- } else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ } else if(PURPLE_IS_BUDDY(node)) {
buddy = (PurpleBuddy*)node;
p = purple_buddy_get_presence(buddy);
if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) {
@@ -4159,7 +4141,7 @@ pidgin_blist_get_emblem(PurpleBlistNode *node)
g_return_val_if_fail(buddy != NULL, NULL);
- if (!purple_privacy_check(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy))) {
+ if (!purple_account_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);
}
@@ -4239,16 +4221,16 @@ pidgin_blist_get_status_icon(PurpleBlistNode *node, PidginStatusIconSize size)
GtkIconSize icon_size = gtk_icon_size_from_name((size == PIDGIN_STATUS_ICON_LARGE) ? PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL :
PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC);
- if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if(PURPLE_IS_CONTACT(node)) {
if(!gtknode->contact_expanded) {
buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
if (buddy != NULL)
gtkbuddynode = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy));
}
- } else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ } else if(PURPLE_IS_BUDDY(node)) {
buddy = (PurpleBuddy*)node;
gtkbuddynode = purple_blist_node_get_ui_data(node);
- } else if(PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if(PURPLE_IS_CHAT(node)) {
chat = (PurpleChat*)node;
} else {
return NULL;
@@ -4358,6 +4340,7 @@ pidgin_blist_get_name_markup(PurpleBuddy *b, gboolean selected, gboolean aliased
gboolean biglist = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons");
PidginThemeFont *statusfont = NULL, *namefont = NULL;
PidginBlistTheme *theme;
+ gchar *contact_alias;
if (conv != NULL) {
PidginBlistNode *ui = purple_blist_node_get_ui_data(&(b->node));
@@ -4375,9 +4358,11 @@ pidgin_blist_get_name_markup(PurpleBuddy *b, gboolean selected, gboolean aliased
if(contact)
gtkcontactnode = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(contact));
+ g_object_get(contact, "alias", &contact_alias, NULL);
+
/* Name */
- if (gtkcontactnode && !gtkcontactnode->contact_expanded && contact->alias)
- name = contact->alias;
+ if (gtkcontactnode && !gtkcontactnode->contact_expanded && contact_alias)
+ name = contact_alias;
else
name = purple_buddy_get_alias(b);
@@ -4531,6 +4516,7 @@ pidgin_blist_get_name_markup(PurpleBuddy *b, gboolean selected, gboolean aliased
g_free(nametext);
g_free(statustext);
g_free(idletime);
+ g_free(contact_alias);
if (hidden_conv) {
char *tmp = text;
@@ -4584,10 +4570,10 @@ static gboolean pidgin_blist_refresh_timer(PurpleBuddyList *list)
return TRUE;
for(gnode = list->root; gnode; gnode = gnode->next) {
- if(!PURPLE_BLIST_NODE_IS_GROUP(gnode))
+ if(!PURPLE_IS_GROUP(gnode))
continue;
for(cnode = gnode->child; cnode; cnode = cnode->next) {
- if(PURPLE_BLIST_NODE_IS_CONTACT(cnode)) {
+ if(PURPLE_IS_CONTACT(cnode)) {
PurpleBuddy *buddy;
buddy = purple_contact_get_priority_buddy((PurpleContact*)cnode);
@@ -4615,8 +4601,8 @@ static void pidgin_blist_hide_node(PurpleBuddyList *list, PurpleBlistNode *node,
gtkblist->selected_node = NULL;
if (get_iter_from_node(node, &iter)) {
gtk_tree_store_remove(gtkblist->treemodel, &iter);
- if(update && (PURPLE_BLIST_NODE_IS_CONTACT(node) ||
- PURPLE_BLIST_NODE_IS_BUDDY(node) || PURPLE_BLIST_NODE_IS_CHAT(node))) {
+ if(update && (PURPLE_IS_CONTACT(node) ||
+ PURPLE_IS_BUDDY(node) || PURPLE_IS_CHAT(node))) {
pidgin_blist_update(list, node->parent);
}
}
@@ -4697,11 +4683,9 @@ unseen_conv_menu(void)
menu = NULL;
}
- ims = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_IM,
- PIDGIN_UNSEEN_TEXT, FALSE, 0);
+ ims = pidgin_conversations_get_unseen_ims(PIDGIN_UNSEEN_TEXT, FALSE, 0);
- chats = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_CHAT,
- PIDGIN_UNSEEN_NICK, FALSE, 0);
+ chats = pidgin_conversations_get_unseen_chats(PIDGIN_UNSEEN_NICK, FALSE, 0);
if(ims && chats)
convs = g_list_concat(ims, chats);
@@ -4730,12 +4714,10 @@ menutray_press_cb(GtkWidget *widget, GdkEventButton *event)
switch (event->button) {
case 1:
- convs = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_IM,
- PIDGIN_UNSEEN_TEXT, FALSE, 1);
+ convs = pidgin_conversations_get_unseen_ims(PIDGIN_UNSEEN_TEXT, FALSE, 1);
if(!convs)
- convs = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_CHAT,
- PIDGIN_UNSEEN_NICK, FALSE, 1);
+ convs = pidgin_conversations_get_unseen_chats(PIDGIN_UNSEEN_NICK, FALSE, 1);
if (convs) {
pidgin_conv_present_conversation((PurpleConversation*)convs->data);
g_list_free(convs);
@@ -4749,7 +4731,7 @@ menutray_press_cb(GtkWidget *widget, GdkEventButton *event)
}
static void
-conversation_updated_cb(PurpleConversation *conv, PurpleConvUpdateType type,
+conversation_updated_cb(PurpleConversation *conv, PurpleConversationUpdateType type,
PidginBuddyList *gtkblist)
{
PurpleAccount *account = purple_conversation_get_account(conv);
@@ -4757,11 +4739,11 @@ conversation_updated_cb(PurpleConversation *conv, PurpleConvUpdateType type,
GList *ims, *chats;
GList *l = NULL;
- if (type != PURPLE_CONV_UPDATE_UNSEEN)
+ if (type != PURPLE_CONVERSATION_UPDATE_UNSEEN)
return;
if(account != NULL && purple_conversation_get_name(conv) != NULL) {
- PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv));
+ PurpleBuddy *buddy = purple_blist_find_buddy(account, purple_conversation_get_name(conv));
if(buddy != NULL)
pidgin_blist_update_buddy(NULL, PURPLE_BLIST_NODE(buddy), TRUE);
}
@@ -4771,11 +4753,9 @@ conversation_updated_cb(PurpleConversation *conv, PurpleConvUpdateType type,
gtkblist->menutrayicon = NULL;
}
- ims = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_IM,
- PIDGIN_UNSEEN_TEXT, FALSE, 0);
+ ims = pidgin_conversations_get_unseen_ims(PIDGIN_UNSEEN_TEXT, FALSE, 0);
- chats = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_CHAT,
- PIDGIN_UNSEEN_NICK, FALSE, 0);
+ chats = pidgin_conversations_get_unseen_chats(PIDGIN_UNSEEN_NICK, FALSE, 0);
if(ims && chats)
convs = g_list_concat(ims, chats);
@@ -4796,8 +4776,8 @@ conversation_updated_cb(PurpleConversation *conv, PurpleConvUpdateType type,
if(gtkconv)
count = gtkconv->unseen_count;
- else if(purple_conversation_get_data(l->data, "unseen-count"))
- count = GPOINTER_TO_INT(purple_conversation_get_data(l->data, "unseen-count"));
+ else if(g_object_get_data(G_OBJECT(l->data), "unseen-count"))
+ count = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(l->data), "unseen-count"));
g_string_append_printf(tooltip_text,
ngettext("%d unread message from %s\n", "%d unread messages from %s\n", count),
@@ -4826,7 +4806,7 @@ conversation_updated_cb(PurpleConversation *conv, PurpleConvUpdateType type,
static void
conversation_deleting_cb(PurpleConversation *conv, PidginBuddyList *gtkblist)
{
- conversation_updated_cb(conv, PURPLE_CONV_UPDATE_UNSEEN, gtkblist);
+ conversation_updated_cb(conv, PURPLE_CONVERSATION_UPDATE_UNSEEN, gtkblist);
}
static void
@@ -4848,12 +4828,11 @@ written_msg_update_ui_cb(PurpleAccount *account, const char *who, const char *me
!(flag & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_RECV)))
return;
ui->conv.flags |= PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE;
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT
- && (flag & PURPLE_MESSAGE_NICK))
+ if (PURPLE_IS_CHAT_CONVERSATION(conv) && (flag & PURPLE_MESSAGE_NICK))
ui->conv.flags |= PIDGIN_BLIST_CHAT_HAS_PENDING_MESSAGE_WITH_NICK;
ui->conv.last_message = time(NULL); /* XXX: for lack of better data */
- pidgin_blist_update(purple_get_blist(), node);
+ pidgin_blist_update(purple_blist_get_buddy_list(), node);
}
static void
@@ -4864,7 +4843,7 @@ displayed_msg_update_ui_cb(PidginConversation *gtkconv, PurpleBlistNode *node)
return;
ui->conv.flags &= ~(PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE |
PIDGIN_BLIST_CHAT_HAS_PENDING_MESSAGE_WITH_NICK);
- pidgin_blist_update(purple_get_blist(), node);
+ pidgin_blist_update(purple_blist_get_buddy_list(), node);
}
static void
@@ -4872,50 +4851,41 @@ conversation_created_cb(PurpleConversation *conv, PidginBuddyList *gtkblist)
{
PurpleAccount *account = purple_conversation_get_account(conv);
- switch (purple_conversation_get_type(conv)) {
- case PURPLE_CONV_TYPE_IM:
- {
- GSList *buddies = purple_find_buddies(account, purple_conversation_get_name(conv));
- while (buddies) {
- PurpleBlistNode *buddy = buddies->data;
- struct _pidgin_blist_node *ui = purple_blist_node_get_ui_data(buddy);
- buddies = g_slist_delete_link(buddies, buddies);
- if (!ui)
- continue;
- ui->conv.conv = conv;
- ui->conv.flags = 0;
- ui->conv.last_message = 0;
- purple_signal_connect(purple_conversations_get_handle(), "deleting-conversation",
- ui, PURPLE_CALLBACK(conversation_deleted_update_ui_cb), ui);
- purple_signal_connect(purple_conversations_get_handle(), "wrote-im-msg",
- ui, PURPLE_CALLBACK(written_msg_update_ui_cb), buddy);
- purple_signal_connect(pidgin_conversations_get_handle(), "conversation-displayed",
- ui, PURPLE_CALLBACK(displayed_msg_update_ui_cb), buddy);
- }
- }
- break;
- case PURPLE_CONV_TYPE_CHAT:
- {
- PurpleChat *chat = purple_blist_find_chat(account, purple_conversation_get_name(conv));
- struct _pidgin_blist_node *ui;
- if (!chat)
- break;
- ui = purple_blist_node_get_ui_data(&(chat->node));
- if (!ui)
- break;
- ui->conv.conv = conv;
- ui->conv.flags = 0;
- ui->conv.last_message = 0;
- purple_signal_connect(purple_conversations_get_handle(), "deleting-conversation",
- ui, PURPLE_CALLBACK(conversation_deleted_update_ui_cb), ui);
- purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg",
- ui, PURPLE_CALLBACK(written_msg_update_ui_cb), chat);
- purple_signal_connect(pidgin_conversations_get_handle(), "conversation-displayed",
- ui, PURPLE_CALLBACK(displayed_msg_update_ui_cb), chat);
- }
- break;
- default:
- break;
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ GSList *buddies = purple_blist_find_buddies(account, purple_conversation_get_name(conv));
+ while (buddies) {
+ PurpleBlistNode *buddy = buddies->data;
+ struct _pidgin_blist_node *ui = purple_blist_node_get_ui_data(buddy);
+ buddies = g_slist_delete_link(buddies, buddies);
+ if (!ui)
+ continue;
+ ui->conv.conv = conv;
+ ui->conv.flags = 0;
+ ui->conv.last_message = 0;
+ purple_signal_connect(purple_conversations_get_handle(), "deleting-conversation",
+ ui, PURPLE_CALLBACK(conversation_deleted_update_ui_cb), ui);
+ purple_signal_connect(purple_conversations_get_handle(), "wrote-im-msg",
+ ui, PURPLE_CALLBACK(written_msg_update_ui_cb), buddy);
+ purple_signal_connect(pidgin_conversations_get_handle(), "conversation-displayed",
+ ui, PURPLE_CALLBACK(displayed_msg_update_ui_cb), buddy);
+ }
+ } else {
+ PurpleChat *chat = purple_blist_find_chat(account, purple_conversation_get_name(conv));
+ struct _pidgin_blist_node *ui;
+ if (!chat)
+ return;
+ ui = purple_blist_node_get_ui_data(&(chat->node));
+ if (!ui)
+ return;
+ ui->conv.conv = conv;
+ ui->conv.flags = 0;
+ ui->conv.last_message = 0;
+ purple_signal_connect(purple_conversations_get_handle(), "deleting-conversation",
+ ui, PURPLE_CALLBACK(conversation_deleted_update_ui_cb), ui);
+ purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg",
+ ui, PURPLE_CALLBACK(written_msg_update_ui_cb), chat);
+ purple_signal_connect(pidgin_conversations_get_handle(), "conversation-displayed",
+ ui, PURPLE_CALLBACK(displayed_msg_update_ui_cb), chat);
}
}
@@ -4940,13 +4910,13 @@ static void pidgin_blist_new_node(PurpleBlistNode *node)
gboolean pidgin_blist_node_is_contact_expanded(PurpleBlistNode *node)
{
- if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+ if (PURPLE_IS_BUDDY(node)) {
node = node->parent;
if (node == NULL)
return FALSE;
}
- g_return_val_if_fail(PURPLE_BLIST_NODE_IS_CONTACT(node), FALSE);
+ g_return_val_if_fail(PURPLE_IS_CONTACT(node), FALSE);
return ((struct _pidgin_blist_node *)purple_blist_node_get_ui_data(node))->contact_expanded;
}
@@ -4990,7 +4960,7 @@ static void _prefs_change_redo_list(const char *name, PurplePrefType type,
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1);
}
- redo_buddy_list(purple_get_blist(), FALSE, FALSE);
+ redo_buddy_list(purple_blist_get_buddy_list(), FALSE, FALSE);
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(gtkblist->treeview));
if (node)
@@ -5882,12 +5852,12 @@ pidgin_blist_search_equal_func(GtkTreeModel *model, gint column,
return TRUE;
compare = NULL;
- if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if (PURPLE_IS_CONTACT(node)) {
PurpleBuddy *b = purple_contact_get_priority_buddy(PURPLE_CONTACT(node));
- if (!purple_buddy_get_local_buddy_alias(b))
+ if (!purple_buddy_get_local_alias(b))
compare = purple_buddy_get_name(b);
- } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
- if (!purple_buddy_get_local_buddy_alias(PURPLE_BUDDY(node)))
+ } else if (PURPLE_IS_BUDDY(node)) {
+ if (!purple_buddy_get_local_alias(PURPLE_BUDDY(node)))
compare = purple_buddy_get_name(PURPLE_BUDDY(node));
}
@@ -6308,7 +6278,7 @@ static void pidgin_blist_show(PurpleBuddyList *list)
purple_signal_connect(handle, "account-actions-changed", gtkblist,
PURPLE_CALLBACK(account_actions_changed), NULL);
- handle = pidgin_account_get_handle();
+ handle = pidgin_accounts_get_handle();
purple_signal_connect(handle, "account-modified", gtkblist,
PURPLE_CALLBACK(account_modified), gtkblist);
@@ -6359,14 +6329,14 @@ static void redo_buddy_list(PurpleBuddyList *list, gboolean remove, gboolean rer
/* This is only needed when we're reverting to a non-GTK+ sorted
* status. We shouldn't need to remove otherwise.
*/
- if (remove && !PURPLE_BLIST_NODE_IS_GROUP(node))
+ if (remove && !PURPLE_IS_GROUP(node))
pidgin_blist_hide_node(list, node, FALSE);
- if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (PURPLE_IS_BUDDY(node))
pidgin_blist_update_buddy(list, node, rerender);
- else if (PURPLE_BLIST_NODE_IS_CHAT(node))
+ else if (PURPLE_IS_CHAT(node))
pidgin_blist_update(list, node);
- else if (PURPLE_BLIST_NODE_IS_GROUP(node))
+ else if (PURPLE_IS_GROUP(node))
pidgin_blist_update(list, node);
node = purple_blist_node_next(node, FALSE);
}
@@ -6384,8 +6354,8 @@ pidgin_blist_update_refresh_timeout()
PurpleBuddyList *blist;
PidginBuddyList *gtkblist;
- blist = purple_get_blist();
- gtkblist = PIDGIN_BLIST(purple_get_blist());
+ blist = purple_blist_get_buddy_list();
+ gtkblist = PIDGIN_BLIST(purple_blist_get_buddy_list());
gtkblist->refresh_timer = purple_timeout_add_seconds(30,(GSourceFunc)pidgin_blist_refresh_timer, blist);
}
@@ -6479,7 +6449,7 @@ static void pidgin_blist_selection_changed(GtkTreeSelection *selection, gpointer
* but we don't do it for groups, because it causes total bizarness -
* the previously selected buddy node might rendered at half height.
*/
- if ((new_selection != NULL) && PURPLE_BLIST_NODE_IS_GROUP(new_selection)) {
+ if ((new_selection != NULL) && PURPLE_IS_GROUP(new_selection)) {
do_selection_changed(new_selection);
} else {
g_timeout_add(0, (GSourceFunc)do_selection_changed, new_selection);
@@ -6501,7 +6471,7 @@ static gboolean insert_node(PurpleBuddyList *list, PurpleBlistNode *node, GtkTre
if(get_iter_from_node(node, &cur))
curptr = &cur;
- if(PURPLE_BLIST_NODE_IS_CONTACT(node) || PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ if(PURPLE_IS_CONTACT(node) || PURPLE_IS_CHAT(node)) {
current_sort_method->func(node, list, parent_iter, curptr, iter);
} else {
sort_method_none(node, list, parent_iter, curptr, iter);
@@ -6531,10 +6501,10 @@ static gboolean insert_node(PurpleBuddyList *list, PurpleBlistNode *node, GtkTre
GtkTreePath *expand = NULL;
struct _pidgin_blist_node *gtkparentnode = purple_blist_node_get_ui_data(node->parent);
- if(PURPLE_BLIST_NODE_IS_GROUP(node->parent)) {
+ if(PURPLE_IS_GROUP(node->parent)) {
if(!purple_blist_node_get_bool(node->parent, "collapsed"))
expand = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &parent_iter);
- } else if(PURPLE_BLIST_NODE_IS_CONTACT(node->parent) &&
+ } else if(PURPLE_IS_CONTACT(node->parent) &&
gtkparentnode->contact_expanded) {
expand = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &parent_iter);
}
@@ -6553,7 +6523,7 @@ static gboolean pidgin_blist_group_has_show_offline_buddy(PurpleGroup *group)
gnode = PURPLE_BLIST_NODE(group);
for(cnode = gnode->child; cnode; cnode = cnode->next) {
- if(PURPLE_BLIST_NODE_IS_CONTACT(cnode)) {
+ if(PURPLE_IS_CONTACT(cnode)) {
for(bnode = cnode->child; bnode; bnode = bnode->next) {
PurpleBuddy *buddy = (PurpleBuddy *)bnode;
if (purple_account_is_connected(purple_buddy_get_account(buddy)) &&
@@ -6581,11 +6551,11 @@ static void pidgin_blist_update_group(PurpleBuddyList *list,
if (editing_blist)
return;
- if (PURPLE_BLIST_NODE_IS_GROUP(node))
+ if (PURPLE_IS_GROUP(node))
gnode = node;
- else if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ else if (PURPLE_IS_BUDDY(node))
gnode = node->parent->parent;
- else if (PURPLE_BLIST_NODE_IS_CONTACT(node) || PURPLE_BLIST_NODE_IS_CHAT(node))
+ else if (PURPLE_IS_CONTACT(node) || PURPLE_IS_CHAT(node))
gnode = node->parent;
else
return;
@@ -6595,13 +6565,13 @@ static void pidgin_blist_update_group(PurpleBuddyList *list,
show_offline = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies");
if(show_offline)
- count = purple_blist_get_group_size(group, FALSE);
+ count = purple_counting_node_get_current_size(PURPLE_COUNTING_NODE(group));
else
- count = purple_blist_get_group_online_count(group);
+ count = purple_counting_node_get_online_count(PURPLE_COUNTING_NODE(group));
if (count > 0 || purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_empty_groups"))
show = TRUE;
- else if (PURPLE_BLIST_NODE_IS_BUDDY(node) && buddy_is_displayable((PurpleBuddy*)node)) { /* Or chat? */
+ else if (PURPLE_IS_BUDDY(node) && buddy_is_displayable((PurpleBuddy*)node)) { /* Or chat? */
show = TRUE;
} else if (!show_offline) {
show = pidgin_blist_group_has_show_offline_buddy(group);
@@ -6680,8 +6650,8 @@ static char *pidgin_get_group_title(PurpleBlistNode *gnode, gboolean expanded)
if (!expanded) {
g_snprintf(group_count, sizeof(group_count), "%d/%d",
- purple_blist_get_group_online_count(group),
- purple_blist_get_group_size(group, FALSE));
+ purple_counting_node_get_online_count(PURPLE_COUNTING_NODE(group)),
+ purple_counting_node_get_current_size(PURPLE_COUNTING_NODE(group)));
}
theme = pidgin_blist_get_theme();
@@ -6836,15 +6806,15 @@ static void pidgin_blist_update_contact(PurpleBuddyList *list, PurpleBlistNode *
if (editing_blist)
return;
- if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (PURPLE_IS_BUDDY(node))
cnode = node->parent;
else
cnode = node;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CONTACT(cnode));
+ g_return_if_fail(PURPLE_IS_CONTACT(cnode));
/* First things first, update the group */
- if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (PURPLE_IS_BUDDY(node))
pidgin_blist_update_group(list, node);
else
pidgin_blist_update_group(list, cnode->parent);
@@ -6926,7 +6896,7 @@ static void pidgin_blist_update_buddy(PurpleBuddyList *list, PurpleBlistNode *no
PurpleBuddy *buddy;
struct _pidgin_blist_node *gtkparentnode;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ g_return_if_fail(PURPLE_IS_BUDDY(node));
if (node->parent == NULL)
return;
@@ -6957,7 +6927,7 @@ static void pidgin_blist_update_chat(PurpleBuddyList *list, PurpleBlistNode *nod
{
PurpleChat *chat;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node));
+ g_return_if_fail(PURPLE_IS_CHAT(node));
if (editing_blist)
return;
@@ -7075,23 +7045,14 @@ static void pidgin_blist_update(PurpleBuddyList *list, PurpleBlistNode *node)
if (purple_blist_node_get_ui_data(node) == NULL)
pidgin_blist_new_node(node);
- switch (purple_blist_node_get_type(node)) {
- case PURPLE_BLIST_GROUP_NODE:
- pidgin_blist_update_group(list, node);
- break;
- case PURPLE_BLIST_CONTACT_NODE:
- pidgin_blist_update_contact(list, node);
- break;
- case PURPLE_BLIST_BUDDY_NODE:
- pidgin_blist_update_buddy(list, node, TRUE);
- break;
- case PURPLE_BLIST_CHAT_NODE:
- pidgin_blist_update_chat(list, node);
- break;
- case PURPLE_BLIST_OTHER_NODE:
- return;
- }
-
+ if (PURPLE_IS_GROUP(node))
+ pidgin_blist_update_group(list, node);
+ else if (PURPLE_IS_CONTACT(node))
+ pidgin_blist_update_contact(list, node);
+ else if (PURPLE_IS_BUDDY(node))
+ pidgin_blist_update_buddy(list, node, TRUE);
+ else if (PURPLE_IS_CHAT(node))
+ pidgin_blist_update_chat(list, node);
}
static void pidgin_blist_destroy(PurpleBuddyList *list)
@@ -7179,17 +7140,17 @@ groups_tree(void)
g_list_free(list);
list = NULL;
- if (purple_get_blist()->root == NULL)
+ if (purple_blist_get_buddy_list()->root == NULL)
{
list = g_list_append(list, (gpointer)_("Buddies"));
}
else
{
- for (gnode = purple_get_blist()->root;
+ for (gnode = purple_blist_get_buddy_list()->root;
gnode != NULL;
gnode = gnode->next)
{
- if (PURPLE_BLIST_NODE_IS_GROUP(gnode))
+ if (PURPLE_IS_GROUP(gnode))
{
g = (PurpleGroup *)gnode;
list = g_list_append(list, (char *) purple_group_get_name(g));
@@ -7238,7 +7199,7 @@ add_buddy_cb(GtkWidget *w, int resp, PidginAddBuddyData *data)
PurpleAccount *account;
PurpleGroup *g;
PurpleBuddy *b;
- PurpleConversation *c;
+ PurpleIMConversation *im;
PurpleBuddyIcon *icon;
if (resp == GTK_RESPONSE_OK)
@@ -7257,15 +7218,15 @@ add_buddy_cb(GtkWidget *w, int resp, PidginAddBuddyData *data)
g = NULL;
if ((grp != NULL) && (*grp != '\0'))
{
- if ((g = purple_find_group(grp)) == NULL)
+ if ((g = purple_blist_find_group(grp)) == NULL)
{
g = purple_group_new(grp);
purple_blist_add_group(g, NULL);
}
- b = purple_find_buddy_in_group(account, who, g);
+ b = purple_blist_find_buddy_in_group(account, who, g);
}
- else if ((b = purple_find_buddy(account, who)) != NULL)
+ else if ((b = purple_blist_find_buddy(account, who)) != NULL)
{
g = purple_buddy_get_group(b);
}
@@ -7297,9 +7258,9 @@ add_buddy_cb(GtkWidget *w, int resp, PidginAddBuddyData *data)
* Or something. --Mark
*/
- c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, data->rq_data.account);
- if (c != NULL) {
- icon = purple_conv_im_get_icon(PURPLE_CONV_IM(c));
+ im = purple_conversations_find_im_with_account(who, data->rq_data.account);
+ if (im != NULL) {
+ icon = purple_im_conversation_get_icon(im);
if (icon != NULL)
purple_buddy_icon_update(icon);
}
@@ -7419,7 +7380,7 @@ add_chat_cb(GtkWidget *w, PidginAddChatData *data)
group = NULL;
if ((group_name != NULL) && (*group_name != '\0') &&
- ((group = purple_find_group(group_name)) == NULL))
+ ((group = purple_blist_find_group(group_name)) == NULL))
{
group = purple_group_new(group_name);
purple_blist_add_group(group, NULL);
@@ -7672,15 +7633,15 @@ static gboolean autojoin_cb(PurpleConnection *gc, gpointer data)
{
PurpleAccount *account = purple_connection_get_account(gc);
PurpleBlistNode *gnode, *cnode;
- for(gnode = purple_get_blist()->root; gnode; gnode = gnode->next)
+ for(gnode = purple_blist_get_buddy_list()->root; gnode; gnode = gnode->next)
{
- if(!PURPLE_BLIST_NODE_IS_GROUP(gnode))
+ if(!PURPLE_IS_GROUP(gnode))
continue;
for(cnode = gnode->child; cnode; cnode = cnode->next)
{
PurpleChat *chat;
- if(!PURPLE_BLIST_NODE_IS_CHAT(cnode))
+ if(!PURPLE_IS_CHAT(cnode))
continue;
chat = (PurpleChat *)cnode;
@@ -7713,6 +7674,7 @@ static gboolean buddy_signonoff_timeout_cb(PurpleBuddy *buddy)
pidgin_blist_update(NULL, PURPLE_BLIST_NODE(buddy));
+ g_object_unref(buddy);
return FALSE;
}
@@ -7730,6 +7692,8 @@ static void buddy_signonoff_cb(PurpleBuddy *buddy)
if(gtknode->recent_signonoff_timer > 0)
purple_timeout_remove(gtknode->recent_signonoff_timer);
+
+ g_object_ref(buddy);
gtknode->recent_signonoff_timer = purple_timeout_add_seconds(10,
(GSourceFunc)buddy_signonoff_timeout_cb, buddy);
}
@@ -7738,7 +7702,7 @@ void
pidgin_blist_set_theme(PidginBlistTheme *theme)
{
PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist);
- PurpleBuddyList *list = purple_get_blist();
+ PurpleBuddyList *list = purple_blist_get_buddy_list();
if (theme != NULL)
purple_prefs_set_string(PIDGIN_PREFS_ROOT "/blist/theme",
@@ -7791,32 +7755,26 @@ void pidgin_blist_init(void)
/* Register our signals */
purple_signal_register(gtk_blist_handle, "gtkblist-hiding",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_BUDDY_LIST);
purple_signal_register(gtk_blist_handle, "gtkblist-unhiding",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_BUDDY_LIST);
purple_signal_register(gtk_blist_handle, "gtkblist-created",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_BUDDY_LIST);
purple_signal_register(gtk_blist_handle, "drawing-tooltip",
- purple_marshal_VOID__POINTER_POINTER_UINT, NULL, 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST_NODE),
- purple_value_new_outgoing(PURPLE_TYPE_BOXED, "GString *"),
- purple_value_new(PURPLE_TYPE_BOOLEAN));
+ purple_marshal_VOID__POINTER_POINTER_UINT, G_TYPE_NONE,
+ 3, PURPLE_TYPE_BLIST_NODE,
+ G_TYPE_POINTER, /* pointer to a (GString *) */
+ G_TYPE_BOOLEAN);
purple_signal_register(gtk_blist_handle, "drawing-buddy",
purple_marshal_POINTER__POINTER,
- purple_value_new(PURPLE_TYPE_STRING), 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_BLIST_BUDDY));
+ G_TYPE_STRING, 1, PURPLE_TYPE_BUDDY);
purple_signal_connect(purple_blist_get_handle(), "buddy-signed-on",
gtk_blist_handle, PURPLE_CALLBACK(buddy_signonoff_cb), NULL);
@@ -7899,9 +7857,9 @@ void pidgin_blist_sort_method_set(const char *id){
return;
}
if (!strcmp(id, "none")) {
- redo_buddy_list(purple_get_blist(), TRUE, FALSE);
+ redo_buddy_list(purple_blist_get_buddy_list(), TRUE, FALSE);
} else {
- redo_buddy_list(purple_get_blist(), FALSE, FALSE);
+ redo_buddy_list(purple_blist_get_buddy_list(), FALSE, FALSE);
}
}
@@ -7934,9 +7892,9 @@ static void sort_method_alphabetical(PurpleBlistNode *node, PurpleBuddyList *bli
const char *my_name;
- if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if(PURPLE_IS_CONTACT(node)) {
my_name = purple_contact_get_alias((PurpleContact*)node);
- } else if(PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if(PURPLE_IS_CHAT(node)) {
my_name = purple_chat_get_name((PurpleChat*)node);
} else {
sort_method_none(node, blist, groupiter, cur, iter);
@@ -7955,9 +7913,9 @@ static void sort_method_alphabetical(PurpleBlistNode *node, PurpleBuddyList *bli
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, NODE_COLUMN, &n, -1);
- if(PURPLE_BLIST_NODE_IS_CONTACT(n)) {
+ if(PURPLE_IS_CONTACT(n)) {
this_name = purple_contact_get_alias((PurpleContact*)n);
- } else if(PURPLE_BLIST_NODE_IS_CHAT(n)) {
+ } else if(PURPLE_IS_CHAT(n)) {
this_name = purple_chat_get_name((PurpleChat*)n);
} else {
this_name = NULL;
@@ -7994,9 +7952,9 @@ static void sort_method_status(PurpleBlistNode *node, PurpleBuddyList *blist, Gt
PurpleBuddy *my_buddy, *this_buddy;
- if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if(PURPLE_IS_CONTACT(node)) {
my_buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
- } else if(PURPLE_BLIST_NODE_IS_CHAT(node)) {
+ } else if(PURPLE_IS_CHAT(node)) {
if (cur != NULL) {
*iter = *cur;
return;
@@ -8022,7 +7980,7 @@ static void sort_method_status(PurpleBlistNode *node, PurpleBuddyList *blist, Gt
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, NODE_COLUMN, &n, -1);
- if(PURPLE_BLIST_NODE_IS_CONTACT(n)) {
+ if(PURPLE_IS_CONTACT(n)) {
this_buddy = purple_contact_get_priority_buddy((PurpleContact*)n);
} else {
this_buddy = NULL;
@@ -8034,9 +7992,9 @@ static void sort_method_status(PurpleBlistNode *node, PurpleBuddyList *blist, Gt
? purple_contact_get_alias(purple_buddy_get_contact(this_buddy))
: NULL));
- presence_cmp = purple_presence_compare(
- purple_buddy_get_presence(my_buddy),
- this_buddy ? purple_buddy_get_presence(this_buddy) : NULL);
+ presence_cmp = purple_buddy_presence_compare(
+ PURPLE_BUDDY_PRESENCE(purple_buddy_get_presence(my_buddy)),
+ this_buddy ? PURPLE_BUDDY_PRESENCE(purple_buddy_get_presence(this_buddy)) : NULL);
if (this_buddy == NULL ||
(presence_cmp < 0 ||
@@ -8082,7 +8040,7 @@ static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *bli
return;
}
- if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+ if(PURPLE_IS_CONTACT(node)) {
PurpleBlistNode *n;
PurpleBuddy *buddy;
for (n = node->child; n; n = n->next) {
@@ -8090,7 +8048,7 @@ static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *bli
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)) {
+ } else if(PURPLE_IS_CHAT(node)) {
/* we don't have a reliable way of getting the log filename
* from the chat info in the blist, yet */
if (cur != NULL) {
@@ -8120,7 +8078,7 @@ static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *bli
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, NODE_COLUMN, &n, -1);
this_log_activity_score = 0;
- if(PURPLE_BLIST_NODE_IS_CONTACT(n)) {
+ if(PURPLE_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, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy));
@@ -8132,7 +8090,7 @@ static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *bli
cmp = purple_utf8_strcasecmp(buddy_name, this_buddy_name);
- if (!PURPLE_BLIST_NODE_IS_CONTACT(n) || activity_score > this_log_activity_score ||
+ if (!PURPLE_IS_CONTACT(n) || activity_score > this_log_activity_score ||
((activity_score == this_log_activity_score) &&
(cmp < 0 || (cmp == 0 && node < n)))) {
if (cur != NULL) {
@@ -8357,7 +8315,7 @@ pidgin_blist_update_accounts_menu(void)
(PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_moods) ||
PURPLE_PLUGIN_HAS_ACTIONS(plugin))) {
if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_moods) &&
- (purple_connection_get_flags(gc) & PURPLE_CONNECTION_SUPPORT_MOODS)) {
+ (purple_connection_get_flags(gc) & PURPLE_CONNECTION_FLAG_SUPPORT_MOODS)) {
if (purple_account_get_status(account, "mood")) {
menuitem = gtk_menu_item_new_with_mnemonic(_("Set _Mood..."));
diff --git a/pidgin/gtkblist.h b/pidgin/gtkblist.h
index 209f45a1d2..49bbb3578c 100644
--- a/pidgin/gtkblist.h
+++ b/pidgin/gtkblist.h
@@ -59,7 +59,7 @@ typedef enum {
} PidginStatusIconSize;
#include "pidgin.h"
-#include "blist.h"
+#include "buddylist.h"
#include "gtkblist-theme.h"
/**************************************************************************
diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c
index b2860cedd8..7ba25b3a70 100644
--- a/pidgin/gtkconv.c
+++ b/pidgin/gtkconv.c
@@ -170,7 +170,7 @@ typedef struct {
GtkWidget *entry;
GtkWidget *message;
- PurpleConversation *conv;
+ PurpleChatConversation *chat;
} InviteBuddyInfo;
@@ -200,9 +200,9 @@ static gboolean infopane_entry_activate(PidginConversation *gtkconv);
static void got_typing_keypress(PidginConversation *gtkconv, gboolean first);
#endif
static void gray_stuff_out(PidginConversation *gtkconv);
-static void add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const char *old_name);
+static void add_chat_user_common(PurpleChatConversation *chat, PurpleChatUser *cb, const char *old_name);
static gboolean tab_complete(PurpleConversation *conv);
-static void pidgin_conv_updated(PurpleConversation *conv, PurpleConvUpdateType type);
+static void pidgin_conv_updated(PurpleConversation *conv, PurpleConversationUpdateType type);
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);
@@ -210,7 +210,7 @@ static void update_typing_message(PidginConversation *gtkconv, const char *messa
gboolean pidgin_conv_has_focus(PurpleConversation *conv);
static GArray* generate_nick_colors(guint numcolors, GdkColor background);
static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast);
-static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag, gboolean create);
+static GtkTextTag *get_buddy_tag(PurpleChatConversation *chat, const char *who, PurpleMessageFlags flag, gboolean create);
static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields);
static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win);
static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv);
@@ -247,17 +247,13 @@ 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(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(account, purple_conversation_get_name(conv)));
- break;
- default:
- break;
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ node = PURPLE_BLIST_NODE(purple_blist_find_buddy(account, purple_conversation_get_name(conv)));
+ node = node ? node->parent : NULL;
+ } else {
+ node = PURPLE_BLIST_NODE(purple_blist_find_chat(account, purple_conversation_get_name(conv)));
}
+
return node;
}
@@ -270,7 +266,7 @@ close_this_sucker(gpointer data)
{
PidginConversation *gtkconv = data;
GList *list = g_list_copy(gtkconv->convs);
- g_list_foreach(list, (GFunc)purple_conversation_destroy, NULL);
+ g_list_foreach(list, (GFunc)g_object_unref, NULL);
g_list_free(list);
return FALSE;
}
@@ -287,27 +283,18 @@ close_conv_cb(GtkButton *button, PidginConversation *gtkconv)
PurpleAccount *account = purple_conversation_get_account(conv);
const char *name = purple_conversation_get_name(conv);
- switch (purple_conversation_get_type(conv)) {
- case PURPLE_CONV_TYPE_IM:
- {
- if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/close_immediately"))
- close_this_sucker(gtkconv);
- else
- hide_conv(gtkconv, TRUE);
- break;
- }
- case PURPLE_CONV_TYPE_CHAT:
- {
- PurpleChat *chat = purple_blist_find_chat(account, name);
- if (!chat ||
- !purple_blist_node_get_bool(&chat->node, "gtk-persistent"))
- close_this_sucker(gtkconv);
- else
- hide_conv(gtkconv, FALSE);
- break;
- }
- default:
- ;
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/close_immediately"))
+ close_this_sucker(gtkconv);
+ else
+ hide_conv(gtkconv, TRUE);
+ } else {
+ PurpleChat *chat = purple_blist_find_chat(account, name);
+ if (!chat ||
+ !purple_blist_node_get_bool(&chat->node, "gtk-persistent"))
+ close_this_sucker(gtkconv);
+ else
+ hide_conv(gtkconv, FALSE);
}
return TRUE;
@@ -361,10 +348,7 @@ static PurpleCmdRet
say_command_cb(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
- purple_conv_im_send(PURPLE_CONV_IM(conv), args[0]);
- else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
- purple_conv_chat_send(PURPLE_CONV_CHAT(conv), args[0]);
+ purple_conversation_send(conv, args[0]);
return PURPLE_CMD_RET_OK;
}
@@ -376,11 +360,7 @@ me_command_cb(PurpleConversation *conv,
char *tmp;
tmp = g_strdup_printf("/me %s", args[0]);
-
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
- purple_conv_im_send(PURPLE_CONV_IM(conv), tmp);
- else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
- purple_conv_chat_send(PURPLE_CONV_CHAT(conv), tmp);
+ purple_conversation_send(conv, tmp);
g_free(tmp);
return PURPLE_CMD_RET_OK;
@@ -444,10 +424,7 @@ debug_command_cb(PurpleConversation *conv,
}
markup = g_markup_escape_text(tmp, -1);
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
- purple_conv_im_send(PURPLE_CONV_IM(conv), markup);
- else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
- purple_conv_chat_send(PURPLE_CONV_CHAT(conv), markup);
+ purple_conversation_send(conv, markup);
g_free(tmp);
g_free(markup);
@@ -477,7 +454,10 @@ static PurpleCmdRet
clearall_command_cb(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
- purple_conversation_foreach(purple_conversation_clear_message_history);
+ GList *l;
+ for (l = purple_conversations_get_all(); l != NULL; l = l->next)
+ purple_conversation_clear_message_history(PURPLE_CONVERSATION(l->data));
+
return PURPLE_CMD_RET_OK;
}
@@ -607,7 +587,7 @@ check_for_and_do_command(PurpleConversation *conv)
retval = TRUE;
break;
case PURPLE_CMD_STATUS_WRONG_TYPE:
- if(purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
+ if(PURPLE_IS_IM_CONVERSATION(conv))
purple_conversation_write(conv, "", _("That command only works in chats, not IMs."),
PURPLE_MESSAGE_NO_LOG, time(NULL));
else
@@ -644,8 +624,8 @@ send_cb(GtkWidget *widget, PidginConversation *gtkconv)
return;
}
- if ((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) &&
- purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)))
+ if (PURPLE_IS_CHAT_CONVERSATION(conv) &&
+ purple_chat_conversation_has_left(PURPLE_CHAT_CONVERSATION(conv)))
return;
if (!purple_account_is_connected(account))
@@ -672,7 +652,7 @@ send_cb(GtkWidget *widget, PidginConversation *gtkconv)
#endif
gc = NULL/*purple_account_get_connection(account)*/;
- if (gc && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_NO_NEWLINES)) {
+ if (gc && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_FLAG_NO_NEWLINES)) {
#if 0
/* TODO WebKit */
char **bufs;
@@ -681,10 +661,7 @@ send_cb(GtkWidget *widget, PidginConversation *gtkconv)
bufs = gtk_webview_get_markup_lines(GTK_WEBVIEW(gtkconv->entry));
for (i = 0; bufs[i]; i++) {
send_history_add(gtkconv, bufs[i]);
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
- purple_conv_im_send_with_flags(PURPLE_CONV_IM(conv), bufs[i], flags);
- else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
- purple_conv_chat_send_with_flags(PURPLE_CONV_CHAT(conv), bufs[i], flags);
+ purple_conversation_send_with_flags(conv, bufs[i], flags);
}
g_strfreev(bufs);
@@ -692,10 +669,7 @@ send_cb(GtkWidget *widget, PidginConversation *gtkconv)
} else {
send_history_add(gtkconv, buf);
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
- purple_conv_im_send_with_flags(PURPLE_CONV_IM(conv), buf, flags);
- else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
- purple_conv_chat_send_with_flags(PURPLE_CONV_CHAT(conv), buf, flags);
+ purple_conversation_send_with_flags(conv, buf, flags);
}
g_free(clean);
@@ -716,15 +690,15 @@ add_remove_cb(GtkWidget *widget, PidginConversation *gtkconv)
account = purple_conversation_get_account(conv);
name = purple_conversation_get_name(conv);
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
PurpleBuddy *b;
- b = purple_find_buddy(account, name);
+ b = purple_blist_find_buddy(account, name);
if (b != NULL)
pidgin_dialogs_remove_buddy(b);
else if (account != NULL && purple_account_is_connected(account))
purple_blist_request_add_buddy(account, (char *)name, NULL, NULL);
- } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
+ } else {
PurpleChat *c;
c = purple_blist_find_chat(account, name);
@@ -739,11 +713,11 @@ add_remove_cb(GtkWidget *widget, PidginConversation *gtkconv)
static void chat_do_info(PidginConversation *gtkconv, const char *who)
{
- PurpleConversation *conv = gtkconv->active_conv;
+ PurpleChatConversation *chat = PURPLE_CHAT_CONVERSATION(gtkconv->active_conv);
PurpleConnection *gc;
- if ((gc = purple_conversation_get_connection(conv))) {
- pidgin_retrieve_user_info_in_chat(gc, who, purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)));
+ if ((gc = purple_conversation_get_connection(gtkconv->active_conv))) {
+ pidgin_retrieve_user_info_in_chat(gc, who, purple_chat_conversation_get_id(chat));
}
}
@@ -753,11 +727,11 @@ info_cb(GtkWidget *widget, PidginConversation *gtkconv)
{
PurpleConversation *conv = gtkconv->active_conv;
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
+ if (PURPLE_IS_IM_CONVERSATION(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) {
+ } else {
/* Get info of the person currently selected in the GtkTreeView */
PidginChatPane *gtkchat;
GtkTreeIter iter;
@@ -831,9 +805,9 @@ static void
do_invite(GtkWidget *w, int resp, InviteBuddyInfo *info)
{
const char *buddy, *message;
- PurpleConversation *conv;
+ PurpleChatConversation *chat;
- conv = info->conv;
+ chat = info->chat;
if (resp == GTK_RESPONSE_OK) {
buddy = gtk_entry_get_text(GTK_ENTRY(info->entry));
@@ -842,8 +816,8 @@ do_invite(GtkWidget *w, int resp, InviteBuddyInfo *info)
if (!g_ascii_strcasecmp(buddy, ""))
return;
- serv_chat_invite(purple_conversation_get_connection(conv),
- purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)),
+ serv_chat_invite(purple_conversation_get_connection(PURPLE_CONVERSATION(chat)),
+ purple_chat_conversation_get_id(chat),
message, buddy);
}
@@ -861,7 +835,8 @@ invite_dnd_recv(GtkWidget *widget, GdkDragContext *dc, gint x, gint y,
const char *convprotocol;
gboolean success = TRUE;
- convprotocol = purple_account_get_protocol_id(purple_conversation_get_account(info->conv));
+ convprotocol = purple_account_get_protocol_id(
+ purple_conversation_get_account(PURPLE_CONVERSATION(info->chat)));
if (dnd_info == PIDGIN_DRAG_BLIST_NODE)
{
@@ -871,16 +846,16 @@ invite_dnd_recv(GtkWidget *widget, GdkDragContext *dc, gint x, gint y,
memcpy(&node, data, sizeof(node));
- if (PURPLE_BLIST_NODE_IS_CONTACT(node))
+ if (PURPLE_IS_CONTACT(node))
buddy = purple_contact_get_priority_buddy((PurpleContact *)node);
- else if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ else if (PURPLE_IS_BUDDY(node))
buddy = (PurpleBuddy *)node;
else
return;
if (strcmp(convprotocol, purple_account_get_protocol_id(purple_buddy_get_account(buddy))))
{
- purple_notify_error(PIDGIN_CONVERSATION(info->conv), NULL,
+ purple_notify_error(PIDGIN_CONVERSATION(PURPLE_CONVERSATION(info->chat)), NULL,
_("That buddy is not on the same protocol as this "
"chat."), NULL);
success = FALSE;
@@ -902,13 +877,13 @@ invite_dnd_recv(GtkWidget *widget, GdkDragContext *dc, gint x, gint y,
{
if (account == NULL)
{
- purple_notify_error(PIDGIN_CONVERSATION(info->conv), NULL,
+ purple_notify_error(PIDGIN_CONVERSATION(PURPLE_CONVERSATION(info->chat)), NULL,
_("You are not currently signed on with an account that "
"can invite that buddy."), NULL);
}
else if (strcmp(convprotocol, purple_account_get_protocol_id(account)))
{
- purple_notify_error(PIDGIN_CONVERSATION(info->conv), NULL,
+ purple_notify_error(PIDGIN_CONVERSATION(PURPLE_CONVERSATION(info->chat)), NULL,
_("That buddy is not on the same protocol as this "
"chat."), NULL);
success = FALSE;
@@ -930,7 +905,7 @@ invite_dnd_recv(GtkWidget *widget, GdkDragContext *dc, gint x, gint y,
static void
invite_cb(GtkWidget *widget, PidginConversation *gtkconv)
{
- PurpleConversation *conv = gtkconv->active_conv;
+ PurpleChatConversation *chat = PURPLE_CHAT_CONVERSATION(gtkconv->active_conv);
InviteBuddyInfo *info = NULL;
if (invite_dialog == NULL) {
@@ -944,7 +919,7 @@ invite_cb(GtkWidget *widget, PidginConversation *gtkconv)
gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE));
info = g_new0(InviteBuddyInfo, 1);
- info->conv = conv;
+ info->chat = chat;
gtkwin = pidgin_conv_get_window(gtkconv);
@@ -1007,7 +982,7 @@ invite_cb(GtkWidget *widget, PidginConversation *gtkconv)
/* Now the Buddy drop-down entry field. */
info->entry = gtk_entry_new();
pidgin_setup_screenname_autocomplete(info->entry, NULL, chat_invite_filter,
- purple_conversation_get_account(conv));
+ purple_conversation_get_account(PURPLE_CONVERSATION(chat)));
gtk_table_attach_defaults(GTK_TABLE(table), info->entry, 1, 2, 0, 1);
gtk_label_set_mnemonic_widget(GTK_LABEL(label), info->entry);
@@ -1113,7 +1088,7 @@ menu_save_as_cb(GtkAction *action, gpointer data)
PidginWindow *win = data;
PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
PurpleAccount *account = purple_conversation_get_account(conv);
- PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv));
+ PurpleBuddy *buddy = purple_blist_find_buddy(account, purple_conversation_get_name(conv));
const char *name;
gchar *buf;
gchar *c;
@@ -1151,13 +1126,7 @@ menu_view_log_cb(GtkAction *action, gpointer data)
GSList *cur;
conv = pidgin_conv_window_get_active_conversation(win);
-
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
- type = PURPLE_LOG_IM;
- else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
- type = PURPLE_LOG_CHAT;
- else
- return;
+ type = PURPLE_IS_IM_CONVERSATION(conv) ? PURPLE_LOG_IM : PURPLE_LOG_CHAT;
gtkblist = pidgin_blist_get_default_gtk_blist();
@@ -1167,7 +1136,7 @@ menu_view_log_cb(GtkAction *action, gpointer data)
name = purple_conversation_get_name(conv);
account = purple_conversation_get_account(conv);
- buddies = purple_find_buddies(account, name);
+ buddies = purple_blist_find_buddies(account, name);
for (cur = buddies; cur != NULL; cur = cur->next)
{
PurpleBlistNode *node = cur->data;
@@ -1230,7 +1199,7 @@ 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) {
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
serv_send_file(purple_conversation_get_connection(conv), purple_conversation_get_name(conv), NULL);
}
@@ -1242,7 +1211,7 @@ 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) {
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
int index;
if ((GtkAction *)obj == win->menu.get_attention)
index = 0;
@@ -1303,13 +1272,13 @@ menu_alias_cb(GtkAction *action, gpointer data)
account = purple_conversation_get_account(conv);
name = purple_conversation_get_name(conv);
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
PurpleBuddy *b;
- b = purple_find_buddy(account, name);
+ b = purple_blist_find_buddy(account, name);
if (b != NULL)
pidgin_dialogs_alias_buddy(b);
- } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
+ } else {
PurpleChat *c;
c = purple_blist_find_chat(account, name);
@@ -1376,7 +1345,7 @@ menu_add_remove_cb(GtkAction *action, gpointer data)
static gboolean
close_already(gpointer data)
{
- purple_conversation_destroy(data);
+ g_object_unref(data);
return FALSE;
}
@@ -1391,11 +1360,11 @@ hide_conv(PidginConversation *gtkconv, gboolean closetimer)
for (list = g_list_copy(gtkconv->convs); list; list = g_list_delete_link(list, list)) {
PurpleConversation *conv = list->data;
if (closetimer) {
- guint timer = GPOINTER_TO_INT(purple_conversation_get_data(conv, "close-timer"));
+ guint timer = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(conv), "close-timer"));
if (timer)
purple_timeout_remove(timer);
timer = purple_timeout_add_seconds(CLOSE_CONV_TIMEOUT_SECS, close_already, conv);
- purple_conversation_set_data(conv, "close-timer", GINT_TO_POINTER(timer));
+ g_object_set_data(G_OBJECT(conv), "close-timer", GINT_TO_POINTER(timer));
}
#if 0
/* I will miss you */
@@ -1457,24 +1426,16 @@ menu_logging_cb(GtkAction *action, gpointer data)
}
/* Save the setting IFF it's different than the pref. */
- switch (purple_conversation_get_type(conv))
- {
- case PURPLE_CONV_TYPE_IM:
- if (logging == purple_prefs_get_bool("/purple/logging/log_ims"))
- purple_blist_node_remove_setting(node, "enable-logging");
- else
- purple_blist_node_set_bool(node, "enable-logging", logging);
- break;
-
- case PURPLE_CONV_TYPE_CHAT:
- if (logging == purple_prefs_get_bool("/purple/logging/log_chats"))
- purple_blist_node_remove_setting(node, "enable-logging");
- else
- purple_blist_node_set_bool(node, "enable-logging", logging);
- break;
-
- default:
- break;
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ if (logging == purple_prefs_get_bool("/purple/logging/log_ims"))
+ purple_blist_node_remove_setting(node, "enable-logging");
+ else
+ purple_blist_node_set_bool(node, "enable-logging", logging);
+ } else {
+ if (logging == purple_prefs_get_bool("/purple/logging/log_chats"))
+ purple_blist_node_remove_setting(node, "enable-logging");
+ else
+ purple_blist_node_set_bool(node, "enable-logging", logging);
}
}
@@ -1526,7 +1487,7 @@ chat_do_im(PidginConversation *gtkconv, const char *who)
if (prpl_info && prpl_info->get_cb_real_name)
real_who = prpl_info->get_cb_real_name(gc,
- purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who);
+ purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv)), who);
if(!who && !real_who)
return;
@@ -1536,27 +1497,25 @@ chat_do_im(PidginConversation *gtkconv, const char *who)
g_free(real_who);
}
-static void pidgin_conv_chat_update_user(PurpleConversation *conv, const char *user);
+static void pidgin_conv_chat_update_user(PurpleChatUser *chatuser);
static void
ignore_cb(GtkWidget *w, PidginConversation *gtkconv)
{
- PurpleConversation *conv = gtkconv->active_conv;
- PurpleConvChat *chat;
+ PurpleChatConversation *chat = PURPLE_CHAT_CONVERSATION(gtkconv->active_conv);
const char *name;
- chat = PURPLE_CONV_CHAT(conv);
name = g_object_get_data(G_OBJECT(w), "user_data");
if (name == NULL)
return;
- if (purple_conv_chat_is_user_ignored(chat, name))
- purple_conv_chat_unignore(chat, name);
+ if (purple_chat_conversation_is_ignored_user(chat, name))
+ purple_chat_conversation_unignore(chat, name);
else
- purple_conv_chat_ignore(chat, name);
+ purple_chat_conversation_ignore(chat, name);
- pidgin_conv_chat_update_user(conv, name);
+ pidgin_conv_chat_update_user(purple_chat_conversation_find_user(chat, name));
}
static void
@@ -1582,7 +1541,7 @@ menu_chat_send_file_cb(GtkWidget *w, PidginConversation *gtkconv)
if (prpl_info && prpl_info->get_cb_real_name)
real_who = prpl_info->get_cb_real_name(gc,
- purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who);
+ purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv)), who);
serv_send_file(gc, real_who ? real_who : who, NULL);
g_free(real_who);
@@ -1608,7 +1567,7 @@ menu_chat_add_remove_cb(GtkWidget *w, PidginConversation *gtkconv)
account = purple_conversation_get_account(conv);
name = g_object_get_data(G_OBJECT(w), "user_data");
- b = purple_find_buddy(account, name);
+ b = purple_blist_find_buddy(account, name);
if (b != NULL)
pidgin_dialogs_remove_buddy(b);
@@ -1666,11 +1625,11 @@ menu_last_said_cb(GtkWidget *w, PidginConversation *gtkconv)
}
static GtkWidget *
-create_chat_menu(PurpleConversation *conv, const char *who, PurpleConnection *gc)
+create_chat_menu(PurpleChatConversation *chat, const char *who, PurpleConnection *gc)
{
static GtkWidget *menu = NULL;
PurplePluginProtocolInfo *prpl_info = NULL;
- PurpleConvChat *chat = PURPLE_CONV_CHAT(conv);
+ PurpleConversation *conv = PURPLE_CONVERSATION(chat);
PurpleAccount *account = purple_conversation_get_account(conv);
gboolean is_me = FALSE;
GtkWidget *button;
@@ -1686,7 +1645,7 @@ create_chat_menu(PurpleConversation *conv, const char *who, PurpleConnection *gc
if (menu)
gtk_widget_destroy(menu);
- if (!strcmp(purple_conv_chat_get_nick(chat), purple_normalize(account, who)))
+ if (!strcmp(purple_chat_conversation_get_nick(chat), purple_normalize(account, who)))
is_me = TRUE;
menu = gtk_menu_new();
@@ -1715,7 +1674,7 @@ create_chat_menu(PurpleConversation *conv, const char *who, PurpleConnection *gc
gchar *real_who = NULL;
if (prpl_info->get_cb_real_name)
real_who = prpl_info->get_cb_real_name(gc,
- purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who);
+ purple_chat_conversation_get_id(chat), who);
if (!(!prpl_info->can_receive_file || prpl_info->can_receive_file(gc, real_who ? real_who : who)))
can_receive_file = FALSE;
g_free(real_who);
@@ -1728,7 +1687,7 @@ create_chat_menu(PurpleConversation *conv, const char *who, PurpleConnection *gc
}
- if (purple_conv_chat_is_user_ignored(PURPLE_CONV_CHAT(conv), who))
+ if (purple_chat_conversation_is_ignored_user(chat, who))
button = pidgin_new_item_from_stock(menu, _("Un-Ignore"), PIDGIN_STOCK_IGNORE,
G_CALLBACK(ignore_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL);
else
@@ -1752,7 +1711,7 @@ create_chat_menu(PurpleConversation *conv, const char *who, PurpleConnection *gc
}
if (!is_me && prpl_info && !(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
- if ((buddy = purple_find_buddy(account, who)) != NULL)
+ if ((buddy = purple_blist_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
@@ -1809,7 +1768,7 @@ gtkconv_chat_popup_menu_cb(GtkWidget *widget, PidginConversation *gtkconv)
return FALSE;
gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1);
- menu = create_chat_menu (conv, who, gc);
+ menu = create_chat_menu (PURPLE_CHAT_CONVERSATION(conv), who, gc);
gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
pidgin_treeview_popup_menu_position_func, widget,
0, GDK_CURRENT_TIME);
@@ -1874,7 +1833,7 @@ right_click_chat_cb(GtkWidget *widget, GdkEventButton *event,
webkit_dom_element_scroll_into_view(WEBKIT_DOM_ELEMENT(node), TRUE);
} else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) {
- GtkWidget *menu = create_chat_menu (conv, who, gc);
+ GtkWidget *menu = create_chat_menu (PURPLE_CHAT_CONVERSATION(conv), who, gc);
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
event->button, event->time);
}
@@ -1943,7 +1902,7 @@ static gboolean
gtkconv_cycle_focus(PidginConversation *gtkconv, GtkDirectionType dir)
{
PurpleConversation *conv = gtkconv->active_conv;
- gboolean chat = purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT;
+ gboolean chat = PURPLE_IS_CHAT_CONVERSATION(conv);
GtkWidget *next = NULL;
struct {
GtkWidget *from;
@@ -2332,10 +2291,10 @@ pidgin_conv_switch_active_conversation(PurpleConversation *conv)
gtk_webview_set_protocol_name(GTK_WEBVIEW(gtkconv->webview), protocol_name);
features = purple_conversation_get_features(conv);
- if (!(features & PURPLE_CONNECTION_HTML))
+ if (!(features & PURPLE_CONNECTION_FLAG_HTML))
gtk_webview_clear_formatting(GTK_WEBVIEW(gtkconv->entry));
- else if (features & PURPLE_CONNECTION_FORMATTING_WBFO &&
- !(purple_conversation_get_features(old_conv) & PURPLE_CONNECTION_FORMATTING_WBFO))
+ else if (features & PURPLE_CONNECTION_FLAG_FORMATTING_WBFO &&
+ !(purple_conversation_get_features(old_conv) & PURPLE_CONNECTION_FLAG_FORMATTING_WBFO))
{
/* The old conversation allowed formatting on parts of the
* buffer, but the new one only allows it on the whole
@@ -2383,12 +2342,12 @@ pidgin_conv_switch_active_conversation(PurpleConversation *conv)
gtk_webview_toggle_fontface(entry, fontface);
- if (!(features & PURPLE_CONNECTION_NO_FONTSIZE))
+ if (!(features & PURPLE_CONNECTION_FLAG_NO_FONTSIZE))
gtk_webview_font_set_size(entry, fontsize);
gtk_webview_toggle_forecolor(entry, forecolor);
- if (!(features & PURPLE_CONNECTION_NO_BGCOLOR))
+ if (!(features & PURPLE_CONNECTION_FLAG_NO_BGCOLOR))
{
gtk_webview_toggle_backcolor(entry, backcolor);
#if 0
@@ -2410,7 +2369,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_webview_set_whole_buffer_formatting_only(entry,
- (features & PURPLE_CONNECTION_FORMATTING_WBFO));
+ (features & PURPLE_CONNECTION_FLAG_FORMATTING_WBFO));
}
purple_signal_emit(pidgin_conversations_get_handle(), "conversation-switched", conv);
@@ -2429,13 +2388,13 @@ menu_conv_sel_send_cb(GObject *m, gpointer data)
{
PurpleAccount *account = g_object_get_data(m, "purple_account");
gchar *name = g_object_get_data(m, "purple_buddy_name");
- PurpleConversation *conv;
+ PurpleIMConversation *im;
if (gtk_check_menu_item_get_active((GtkCheckMenuItem*) m) == FALSE)
return;
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, name);
- pidgin_conv_switch_active_conversation(conv);
+ im = purple_im_conversation_new(account, name);
+ pidgin_conv_switch_active_conversation(PURPLE_CONVERSATION(im));
}
#if 0
@@ -2460,7 +2419,7 @@ delete_text_cb(GtkTextBuffer *textbuffer, GtkTextIter *start_pos,
{
PidginConversation *gtkconv = (PidginConversation *)user_data;
PurpleConversation *conv;
- PurpleConvIm *im;
+ PurpleIMConversation *im;
g_return_if_fail(gtkconv != NULL);
@@ -2474,11 +2433,11 @@ delete_text_cb(GtkTextBuffer *textbuffer, GtkTextIter *start_pos,
if (gtk_text_iter_is_start(start_pos) && gtk_text_iter_is_end(end_pos)) {
/* We deleted all the text, so turn off typing. */
- purple_conv_im_stop_send_typed_timeout(im);
+ purple_im_conversation_stop_send_typed_timeout(im);
serv_send_typing(purple_conversation_get_connection(conv),
purple_conversation_get_name(conv),
- PURPLE_NOT_TYPING);
+ PURPLE_IM_NOT_TYPING);
}
else {
/* We're deleting, but not all of it, so it counts as typing. */
@@ -2524,8 +2483,8 @@ pidgin_conv_get_tab_icons(PurpleConversation *conv)
g_return_val_if_fail(name != NULL, NULL);
/* Use the buddy icon, if possible */
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- PurpleBuddy *b = purple_find_buddy(account, name);
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ PurpleBuddy *b = purple_blist_find_buddy(account, name);
if (b != NULL) {
PurplePresence *p;
p = purple_buddy_get_presence(b);
@@ -2557,15 +2516,15 @@ pidgin_conv_get_icon_stock(PurpleConversation *conv)
g_return_val_if_fail(account != NULL, NULL);
/* Use the buddy icon, if possible */
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
const char *name = NULL;
PurpleBuddy *b;
name = purple_conversation_get_name(conv);
- b = purple_find_buddy(account, name);
+ b = purple_blist_find_buddy(account, name);
if (b != NULL) {
PurplePresence *p = purple_buddy_get_presence(b);
PurpleStatus *active = purple_presence_get_active_status(p);
- PurpleStatusType *type = purple_status_get_type(active);
+ PurpleStatusType *type = purple_status_get_status_type(active);
PurpleStatusPrimitive prim = purple_status_type_get_primitive(type);
stock = pidgin_stock_id_from_status_primitive(prim);
} else {
@@ -2597,8 +2556,8 @@ pidgin_conv_get_icon(PurpleConversation *conv, GtkWidget *parent, const char *ic
g_return_val_if_fail(name != NULL, NULL);
/* Use the buddy icon, if possible */
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- PurpleBuddy *b = purple_find_buddy(account, name);
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ PurpleBuddy *b = purple_blist_find_buddy(account, name);
if (b != NULL) {
/* I hate this hack. It fixes a bug where the pending message icon
* displays in the conv tab even though it shouldn't.
@@ -2641,8 +2600,8 @@ 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(purple_conversation_get_account(conv), purple_conversation_get_name(conv));
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ PurpleBuddy *b = purple_blist_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv));
if (b)
emblem = pidgin_blist_get_emblem((PurpleBlistNode*)b);
}
@@ -2679,8 +2638,7 @@ update_tab_icon(PurpleConversation *conv)
gtk_widget_queue_draw(gtkconv->infopane);
if (pidgin_conv_window_is_active_conversation(conv) &&
- (purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_IM ||
- gtkconv->u.im->anim == NULL))
+ (PURPLE_IS_CHAT_CONVERSATION(conv) || gtkconv->u.im->anim == NULL))
{
l = pidgin_conv_get_tab_icons(conv);
@@ -2824,12 +2782,12 @@ static void
saveicon_writefile_cb(void *user_data, const char *filename)
{
PidginConversation *gtkconv = (PidginConversation *)user_data;
- PurpleConversation *conv = gtkconv->active_conv;
+ PurpleIMConversation *im = PURPLE_IM_CONVERSATION(gtkconv->active_conv);
PurpleBuddyIcon *icon;
const void *data;
size_t len;
- icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv));
+ icon = purple_im_conversation_get_icon(im);
data = purple_buddy_icon_get_data(icon, &len);
if ((len <= 0) || (data == NULL) || !purple_util_write_data_to_file_absolute(filename, data, len)) {
@@ -2849,7 +2807,7 @@ custom_icon_sel_cb(const char *filename, gpointer data)
PurpleAccount *account = purple_conversation_get_account(conv);
name = purple_conversation_get_name(conv);
- buddy = purple_find_buddy(account, name);
+ buddy = purple_blist_find_buddy(account, name);
if (!buddy) {
purple_debug_info("custom-icon", "You can only set custom icons for people on your buddylist.\n");
return;
@@ -2884,9 +2842,9 @@ change_size_cb(GtkWidget *widget, PidginConversation *gtkconv)
}
gtk_widget_set_size_request(gtkconv->u.im->icon_container, -1, size);
- pidgin_conv_update_buddy_icon(conv);
+ pidgin_conv_update_buddy_icon(PURPLE_IM_CONVERSATION(conv));
- buddies = purple_find_buddies(purple_conversation_get_account(conv),
+ buddies = purple_blist_find_buddies(purple_conversation_get_account(conv),
purple_conversation_get_name(conv));
for (; buddies; buddies = g_slist_delete_link(buddies, buddies)) {
PurpleBuddy *buddy = buddies->data;
@@ -2906,7 +2864,7 @@ remove_custom_icon_cb(GtkWidget *widget, PidginConversation *gtkconv)
account = purple_conversation_get_account(conv);
name = purple_conversation_get_name(conv);
- buddy = purple_find_buddy(account, name);
+ buddy = purple_blist_find_buddy(account, name);
if (!buddy) {
return;
}
@@ -2924,7 +2882,7 @@ icon_menu_save_cb(GtkWidget *widget, PidginConversation *gtkconv)
g_return_if_fail(conv != NULL);
- ext = purple_buddy_icon_get_extension(purple_conv_im_get_icon(PURPLE_CONV_IM(conv)));
+ ext = purple_buddy_icon_get_extension(purple_im_conversation_get_icon(PURPLE_IM_CONVERSATION(conv)));
buf = g_strdup_printf("%s.%s", purple_normalize(purple_conversation_get_account(conv), purple_conversation_get_name(conv)), ext);
@@ -3008,7 +2966,7 @@ icon_menu(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv)
/* Is there a custom icon for this person? */
conv = gtkconv->active_conv;
- buddy = purple_find_buddy(purple_conversation_get_account(conv),
+ buddy = purple_blist_find_buddy(purple_conversation_get_account(conv),
purple_conversation_get_name(conv));
if (buddy)
{
@@ -3046,24 +3004,15 @@ pidgin_conv_present_conversation(PurpleConversation *conv)
gtk_window_present(GTK_WINDOW(gtkconv->win->window));
}
-GList *
-pidgin_conversations_find_unseen_list(PurpleConversationType type,
- PidginUnseenState min_state,
- gboolean hidden_only,
- guint max_count)
+static GList *
+pidgin_conversations_get_unseen(GList *l,
+ PidginUnseenState min_state,
+ gboolean hidden_only,
+ guint max_count)
{
- GList *l;
GList *r = NULL;
guint c = 0;
- if (type == PURPLE_CONV_TYPE_IM) {
- l = purple_get_ims();
- } else if (type == PURPLE_CONV_TYPE_CHAT) {
- l = purple_get_chats();
- } else {
- l = purple_get_conversations();
- }
-
for (; l != NULL && (max_count == 0 || c < max_count); l = l->next) {
PurpleConversation *conv = (PurpleConversation*)l->data;
PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
@@ -3083,6 +3032,33 @@ pidgin_conversations_find_unseen_list(PurpleConversationType type,
return r;
}
+GList *
+pidgin_conversations_get_unseen_all(PidginUnseenState min_state,
+ gboolean hidden_only,
+ guint max_count)
+{
+ return pidgin_conversations_get_unseen(purple_conversations_get_all(),
+ min_state, hidden_only, max_count);
+}
+
+GList *
+pidgin_conversations_get_unseen_ims(PidginUnseenState min_state,
+ gboolean hidden_only,
+ guint max_count)
+{
+ return pidgin_conversations_get_unseen(purple_conversations_get_ims(),
+ min_state, hidden_only, max_count);
+}
+
+GList *
+pidgin_conversations_get_unseen_chats(PidginUnseenState min_state,
+ gboolean hidden_only,
+ guint max_count)
+{
+ return pidgin_conversations_get_unseen(purple_conversations_get_chats(),
+ min_state, hidden_only, max_count);
+}
+
static void
unseen_conv_menu_cb(GtkMenuItem *item, PurpleConversation *conv)
{
@@ -3283,7 +3259,7 @@ populate_menu_with_options(GtkWidget *menu, PidginConversation *gtkconv, gboolea
conv = gtkconv->active_conv;
account = purple_conversation_get_account(conv);
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
+ if (PURPLE_IS_CHAT_CONVERSATION(conv)) {
chat = purple_blist_find_chat(account, purple_conversation_get_name(conv));
if ((chat == NULL) && (gtkconv->webview != NULL)) {
@@ -3306,8 +3282,7 @@ populate_menu_with_options(GtkWidget *menu, PidginConversation *gtkconv, gboolea
g_strdup(purple_conversation_get_name(conv)));
}
chat = purple_chat_new(account, NULL, components);
- purple_blist_node_set_flags((PurpleBlistNode *)chat,
- PURPLE_BLIST_NODE_FLAG_NO_SAVE);
+ purple_blist_node_set_transient((PurpleBlistNode *)chat, TRUE);
g_object_set_data_full(G_OBJECT(gtkconv->webview), "transient_chat",
chat, (GDestroyNotify)purple_blist_remove_chat);
}
@@ -3315,16 +3290,15 @@ populate_menu_with_options(GtkWidget *menu, PidginConversation *gtkconv, gboolea
if (!purple_account_is_connected(account))
return FALSE;
- buddy = purple_find_buddy(account, purple_conversation_get_name(conv));
+ buddy = purple_blist_find_buddy(account, purple_conversation_get_name(conv));
if (!buddy && gtkconv->webview) {
buddy = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_buddy");
if (!buddy) {
buddy = purple_buddy_new(account, purple_conversation_get_name(conv), NULL);
- purple_blist_node_set_flags((PurpleBlistNode *)buddy,
- PURPLE_BLIST_NODE_FLAG_NO_SAVE);
+ purple_blist_node_set_transient((PurpleBlistNode *)buddy, TRUE);
g_object_set_data_full(G_OBJECT(gtkconv->webview), "transient_buddy",
- buddy, (GDestroyNotify)purple_buddy_destroy);
+ buddy, (GDestroyNotify)g_object_unref);
}
}
}
@@ -3383,8 +3357,7 @@ regenerate_media_items(PidginWindow *win)
* Check if account support voice and/or calls, and
* if the current buddy supports it.
*/
- if (account != NULL && purple_conversation_get_type(conv)
- == PURPLE_CONV_TYPE_IM) {
+ if (account != NULL && PURPLE_IS_IM_CONVERSATION(conv)) {
PurpleMediaCaps caps =
purple_prpl_get_media_caps(account,
purple_conversation_get_name(conv));
@@ -3398,8 +3371,7 @@ regenerate_media_items(PidginWindow *win)
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) {
+ } else if (PURPLE_IS_CHAT_CONVERSATION(conv)) {
/* for now, don't care about chats... */
gtk_action_set_sensitive(win->menu.audio_call, FALSE);
gtk_action_set_sensitive(win->menu.video_call, FALSE);
@@ -3743,27 +3715,27 @@ static void
got_typing_keypress(PidginConversation *gtkconv, gboolean first)
{
PurpleConversation *conv = gtkconv->active_conv;
- PurpleConvIm *im;
+ PurpleIMConversation *im;
/*
* We know we got something, so we at least have to make sure we don't
- * send PURPLE_TYPED any time soon.
+ * send PURPLE_IM_TYPED any time soon.
*/
im = PURPLE_CONV_IM(conv);
- purple_conv_im_stop_send_typed_timeout(im);
- purple_conv_im_start_send_typed_timeout(im);
+ purple_im_conversation_stop_send_typed_timeout(im);
+ purple_im_conversation_start_send_typed_timeout(im);
- /* Check if we need to send another PURPLE_TYPING message */
- if (first || (purple_conv_im_get_type_again(im) != 0 &&
- time(NULL) > purple_conv_im_get_type_again(im)))
+ /* Check if we need to send another PURPLE_IM_TYPING message */
+ if (first || (purple_im_conversation_get_type_again(im) != 0 &&
+ time(NULL) > purple_im_conversation_get_type_again(im)))
{
unsigned int timeout;
timeout = serv_send_typing(purple_conversation_get_connection(conv),
purple_conversation_get_name(conv),
- PURPLE_TYPING);
- purple_conv_im_set_type_again(im, timeout);
+ PURPLE_IM_TYPING);
+ purple_im_conversation_set_type_again(im, timeout);
}
}
@@ -3850,17 +3822,13 @@ update_typing_message(PidginConversation *gtkconv, const char *message)
static void
update_typing_icon(PidginConversation *gtkconv)
{
- PurpleConvIm *im = NULL;
- PurpleConversation *conv = gtkconv->active_conv;
+ PurpleIMConversation *im = PURPLE_IM_CONVERSATION(gtkconv->active_conv);
char *message = NULL;
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
- im = PURPLE_CONV_IM(conv);
-
if (im == NULL)
return;
- if (purple_conv_im_get_typing_state(im) == PURPLE_NOT_TYPING) {
+ if (purple_im_conversation_get_typing_state(im) == PURPLE_IM_NOT_TYPING) {
#ifdef RESERVE_LINE
update_typing_message(gtkconv, NULL);
#else
@@ -3869,10 +3837,10 @@ update_typing_icon(PidginConversation *gtkconv)
return;
}
- if (purple_conv_im_get_typing_state(im) == PURPLE_TYPING) {
- message = g_strdup_printf(_("\n%s is typing..."), purple_conversation_get_title(conv));
+ if (purple_im_conversation_get_typing_state(im) == PURPLE_IM_TYPING) {
+ message = g_strdup_printf(_("\n%s is typing..."), purple_conversation_get_title(PURPLE_CONVERSATION(im)));
} else {
- message = g_strdup_printf(_("\n%s has stopped typing"), purple_conversation_get_title(conv));
+ message = g_strdup_printf(_("\n%s has stopped typing"), purple_conversation_get_title(PURPLE_CONVERSATION(im)));
}
update_typing_message(gtkconv, message);
@@ -3901,7 +3869,7 @@ update_send_to_selection(PidginWindow *win)
if (win->menu.send_to == NULL)
return FALSE;
- if (!(b = purple_find_buddy(account, purple_conversation_get_name(conv))))
+ if (!(b = purple_blist_find_buddy(account, purple_conversation_get_name(conv))))
return FALSE;
gtk_widget_show(win->menu.send_to);
@@ -3917,7 +3885,7 @@ update_send_to_selection(PidginWindow *win)
PurpleAccount *item_account = g_object_get_data(G_OBJECT(item), "purple_account");
gchar *buddy_name = g_object_get_data(G_OBJECT(item),
"purple_buddy_name");
- item_buddy = purple_find_buddy(item_account, buddy_name);
+ item_buddy = purple_blist_find_buddy(item_account, buddy_name);
if (b == item_buddy) {
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
@@ -4023,8 +3991,8 @@ compare_buddy_presence(PurplePresence *p1, PurplePresence *p2)
/* This is necessary because multiple PurpleBuddy's don't share the same
* PurplePresence anymore.
*/
- PurpleBuddy *b1 = purple_presence_get_buddy(p1);
- PurpleBuddy *b2 = purple_presence_get_buddy(p2);
+ PurpleBuddy *b1 = purple_buddy_presence_get_buddy(PURPLE_BUDDY_PRESENCE(p1));
+ PurpleBuddy *b2 = purple_buddy_presence_get_buddy(PURPLE_BUDDY_PRESENCE(p2));
if (purple_buddy_get_account(b1) == purple_buddy_get_account(b2) &&
strcmp(purple_buddy_get_name(b1), purple_buddy_get_name(b2)) == 0)
return FALSE;
@@ -4060,8 +4028,8 @@ generate_send_to_items(PidginWindow *win)
gtk_widget_show(menu);
- 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 (PURPLE_IS_IM_CONVERSATION(gtkconv->active_conv)) {
+ buds = purple_blist_find_buddies(purple_conversation_get_account(gtkconv->active_conv), purple_conversation_get_name(gtkconv->active_conv));
if (buds == NULL)
{
@@ -4081,7 +4049,7 @@ generate_send_to_items(PidginWindow *win)
PurpleBuddy *buddy = (PurpleBuddy *)node;
PurpleAccount *account;
- if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (!PURPLE_IS_BUDDY(node))
continue;
account = purple_buddy_get_account(buddy);
@@ -4102,7 +4070,7 @@ generate_send_to_items(PidginWindow *win)
* since we did a g_list_prepend() earlier. */
for (iter = g_list_last(list); iter != NULL; iter = iter->prev) {
PurplePresence *pre = iter->data;
- PurpleBuddy *buddy = purple_presence_get_buddy(pre);
+ PurpleBuddy *buddy = purple_buddy_presence_get_buddy(PURPLE_BUDDY_PRESENCE(pre));
create_sendto_item(menu, sg, &group, buddy,
purple_buddy_get_account(buddy), purple_buddy_get_name(buddy));
}
@@ -4122,19 +4090,19 @@ generate_send_to_items(PidginWindow *win)
}
static const char *
-get_chat_buddy_status_icon(PurpleConvChat *chat, const char *name, PurpleConvChatBuddyFlags flags)
+get_chat_user_status_icon(PurpleChatConversation *chat, const char *name, PurpleChatUserFlags flags)
{
const char *image = NULL;
- if (flags & PURPLE_CBFLAGS_FOUNDER) {
+ if (flags & PURPLE_CHAT_USER_FOUNDER) {
image = PIDGIN_STOCK_STATUS_FOUNDER;
- } else if (flags & PURPLE_CBFLAGS_OP) {
+ } else if (flags & PURPLE_CHAT_USER_OP) {
image = PIDGIN_STOCK_STATUS_OPERATOR;
- } else if (flags & PURPLE_CBFLAGS_HALFOP) {
+ } else if (flags & PURPLE_CHAT_USER_HALFOP) {
image = PIDGIN_STOCK_STATUS_HALFOP;
- } else if (flags & PURPLE_CBFLAGS_VOICE) {
+ } else if (flags & PURPLE_CHAT_USER_VOICE) {
image = PIDGIN_STOCK_STATUS_VOICE;
- } else if ((!flags) && purple_conv_chat_is_user_ignored(chat, name)) {
+ } else if ((!flags) && purple_chat_conversation_is_ignored_user(chat, name)) {
image = PIDGIN_STOCK_STATUS_IGNORED;
} else {
return NULL;
@@ -4143,22 +4111,22 @@ get_chat_buddy_status_icon(PurpleConvChat *chat, const char *name, PurpleConvCha
}
static void
-deleting_chat_buddy_cb(PurpleConvChatBuddy *cb)
+deleting_chat_user_cb(PurpleChatUser *cb)
{
- GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cb);
+ GtkTreeRowReference *ref = purple_chat_user_get_ui_data(cb);
if (ref) {
gtk_tree_row_reference_free(ref);
- purple_conv_chat_cb_set_ui_data(cb, NULL);
+ purple_chat_user_set_ui_data(cb, NULL);
}
}
static void
-add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const char *old_name)
+add_chat_user_common(PurpleChatConversation *chat, PurpleChatUser *cb, const char *old_name)
{
PidginConversation *gtkconv;
+ PurpleConversation *conv;
PidginChatPane *gtkchat;
- PurpleConvChat *chat;
PurpleConnection *gc;
PurplePluginProtocolInfo *prpl_info;
GtkTreeModel *tm;
@@ -4170,14 +4138,14 @@ add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const c
gboolean is_buddy;
const gchar *name, *alias;
gchar *tmp, *alias_key;
- PurpleConvChatBuddyFlags flags;
+ PurpleChatUserFlags flags;
GdkColor *color = NULL;
- alias = purple_conv_chat_cb_get_alias(cb);
- name = purple_conv_chat_cb_get_name(cb);
- flags = purple_conv_chat_cb_get_flags(cb);
+ alias = purple_chat_user_get_alias(cb);
+ name = purple_chat_user_get_name(cb);
+ flags = purple_chat_user_get_flags(cb);
- chat = PURPLE_CONV_CHAT(conv);
+ conv = PURPLE_CONVERSATION(chat);
gtkconv = PIDGIN_CONVERSATION(conv);
gtkchat = gtkconv->u.chat;
gc = purple_conversation_get_connection(conv);
@@ -4188,12 +4156,12 @@ add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const c
tm = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
ls = GTK_LIST_STORE(tm);
- stock = get_chat_buddy_status_icon(chat, name, flags);
+ stock = get_chat_user_status_icon(chat, name, flags);
- if (!strcmp(purple_conv_chat_get_nick(chat), purple_normalize(purple_conversation_get_account(conv), old_name != NULL ? old_name : name)))
+ if (!strcmp(purple_chat_conversation_get_nick(chat), purple_normalize(purple_conversation_get_account(conv), old_name != NULL ? old_name : name)))
is_me = TRUE;
- is_buddy = purple_conv_chat_cb_is_buddy(cb);
+ is_buddy = purple_chat_user_is_buddy(cb);
tmp = g_utf8_casefold(alias, -1);
alias_key = g_utf8_collate_key(tmp, -1);
@@ -4209,9 +4177,9 @@ add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const c
#endif /* if 0 */
} else {
GtkTextTag *tag;
- if ((tag = get_buddy_tag(conv, name, 0, FALSE)))
+ if ((tag = get_buddy_tag(chat, name, 0, FALSE)))
g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_NORMAL, NULL);
- if ((tag = get_buddy_tag(conv, name, PURPLE_MESSAGE_NICK, FALSE)))
+ if ((tag = get_buddy_tag(chat, name, PURPLE_MESSAGE_NICK, FALSE)))
g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_NORMAL, NULL);
color = (GdkColor*)get_nick_color(gtkconv, name);
}
@@ -4234,13 +4202,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 (purple_conv_chat_cb_get_ui_data(cb)) {
- GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cb);
+ if (purple_chat_user_get_ui_data(cb)) {
+ GtkTreeRowReference *ref = purple_chat_user_get_ui_data(cb);
gtk_tree_row_reference_free(ref);
}
newpath = gtk_tree_model_get_path(tm, &iter);
- purple_conv_chat_cb_set_ui_data(cb, gtk_tree_row_reference_new(tm, newpath));
+ purple_chat_user_set_ui_data(cb, gtk_tree_row_reference_new(tm, newpath));
gtk_tree_path_free(newpath);
if (is_me && color)
@@ -4333,7 +4301,7 @@ tab_complete(PurpleConversation *conv)
/* if there's nothing there just return */
if (!gtk_text_iter_compare(&cursor, &start_buffer))
- return (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) ? TRUE : FALSE;
+ return PURPLE_IS_CHAT_CONVERSATION(conv);
text = gtk_text_buffer_get_text(gtkconv->entry_buffer, &start_buffer,
&cursor, FALSE);
@@ -4371,7 +4339,7 @@ tab_complete(PurpleConversation *conv)
if (!g_utf8_strlen(entered, -1)) {
g_free(entered);
- return (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) ? TRUE : FALSE;
+ return PURPLE_IS_CHAT_CONVERSATION(conv);
}
nick_partial = g_malloc0(entered_bytes + 1);
@@ -4386,9 +4354,9 @@ tab_complete(PurpleConversation *conv)
&matches, l->data);
}
g_list_free(list);
- } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
- PurpleConvChat *chat = PURPLE_CONV_CHAT(conv);
- GList *l = purple_conv_chat_get_users(chat);
+ } else if (PURPLE_IS_CHAT_CONVERSATION(conv)) {
+ PurpleChatConversation *chat = PURPLE_CONV_CHAT(conv);
+ GList *l = purple_chat_conversation_get_users(chat);
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(PIDGIN_CONVERSATION(conv)->u.chat->list));
GtkTreeIter iter;
int f;
@@ -4396,7 +4364,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, purple_conv_chat_cb_get_name((PurpleConvChatBuddy *)l->data));
+ &matches, purple_chat_user_get_name((PurpleChatUser *)l->data));
}
@@ -4435,7 +4403,7 @@ tab_complete(PurpleConversation *conv)
if (!matches) {
/* if matches isn't set partials won't be either */
g_free(entered);
- return (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) ? TRUE : FALSE;
+ return PURPLE_IS_CHAT_CONVERSATION(conv);
}
gtk_text_buffer_delete(gtkconv->entry_buffer, &word_start, &cursor);
@@ -4505,7 +4473,7 @@ static void topic_callback(GtkWidget *w, PidginConversation *gtkconv)
gtkconv = PIDGIN_CONVERSATION(conv);
gtkchat = gtkconv->u.chat;
new_topic = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtkchat->topic_text)));
- current_topic = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(conv));
+ current_topic = purple_chat_conversation_get_topic(PURPLE_CHAT_CONVERSATION(conv));
if(current_topic && !g_utf8_collate(new_topic, current_topic)){
g_free(new_topic);
@@ -4517,7 +4485,7 @@ static void topic_callback(GtkWidget *w, PidginConversation *gtkconv)
else
gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), "");
- prpl_info->set_chat_topic(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)),
+ prpl_info->set_chat_topic(gc, purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv)),
new_topic);
g_free(new_topic);
@@ -4526,7 +4494,7 @@ static void topic_callback(GtkWidget *w, PidginConversation *gtkconv)
static gint
sort_chat_users(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata)
{
- PurpleConvChatBuddyFlags f1 = 0, f2 = 0;
+ PurpleChatUserFlags f1 = 0, f2 = 0;
char *user1 = NULL, *user2 = NULL;
gboolean buddy1 = FALSE, buddy2 = FALSE;
gint ret = 0;
@@ -4543,10 +4511,10 @@ sort_chat_users(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer us
-1);
/* Only sort by membership levels */
- f1 &= PURPLE_CBFLAGS_VOICE | PURPLE_CBFLAGS_HALFOP | PURPLE_CBFLAGS_OP |
- PURPLE_CBFLAGS_FOUNDER;
- f2 &= PURPLE_CBFLAGS_VOICE | PURPLE_CBFLAGS_HALFOP | PURPLE_CBFLAGS_OP |
- PURPLE_CBFLAGS_FOUNDER;
+ f1 &= PURPLE_CHAT_USER_VOICE | PURPLE_CHAT_USER_HALFOP | PURPLE_CHAT_USER_OP |
+ PURPLE_CHAT_USER_FOUNDER;
+ f2 &= PURPLE_CHAT_USER_VOICE | PURPLE_CHAT_USER_HALFOP | PURPLE_CHAT_USER_OP |
+ PURPLE_CHAT_USER_FOUNDER;
if (user1 == NULL || user2 == NULL) {
if (!(user1 == NULL && user2 == NULL))
@@ -4567,18 +4535,17 @@ sort_chat_users(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer us
}
static void
-update_chat_alias(PurpleBuddy *buddy, PurpleConversation *conv, PurpleConnection *gc, PurplePluginProtocolInfo *prpl_info)
+update_chat_alias(PurpleBuddy *buddy, PurpleChatConversation *chat, PurpleConnection *gc, PurplePluginProtocolInfo *prpl_info)
{
- PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
- PurpleConvChat *chat = PURPLE_CONV_CHAT(conv);
- PurpleAccount *account = purple_conversation_get_account(conv);
+ PidginConversation *gtkconv = PIDGIN_CONVERSATION(PURPLE_CONVERSATION(chat));
+ PurpleAccount *account = purple_conversation_get_account(PURPLE_CONVERSATION(chat));
GtkTreeModel *model;
char *normalized_name;
GtkTreeIter iter;
int f;
g_return_if_fail(buddy != NULL);
- g_return_if_fail(conv != NULL);
+ g_return_if_fail(chat != NULL);
/* This is safe because this callback is only used in chats, not IMs. */
model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkconv->u.chat->list));
@@ -4599,10 +4566,10 @@ update_chat_alias(PurpleBuddy *buddy, PurpleConversation *conv, PurpleConnection
char *alias_key = NULL;
PurpleBuddy *buddy2;
- if (strcmp(purple_conv_chat_get_nick(chat), purple_normalize(account, name))) {
+ if (strcmp(purple_chat_conversation_get_nick(chat), purple_normalize(account, name))) {
/* This user is not me, so look into updating the alias. */
- if ((buddy2 = purple_find_buddy(account, name)) != NULL) {
+ if ((buddy2 = purple_blist_find_buddy(account, name)) != NULL) {
alias = purple_buddy_get_contact_alias(buddy2);
}
@@ -4629,10 +4596,11 @@ update_chat_alias(PurpleBuddy *buddy, PurpleConversation *conv, PurpleConnection
}
static void
-blist_node_aliased_cb(PurpleBlistNode *node, const char *old_alias, PurpleConversation *conv)
+blist_node_aliased_cb(PurpleBlistNode *node, const char *old_alias, PurpleChatConversation *chat)
{
PurpleConnection *gc;
PurplePluginProtocolInfo *prpl_info;
+ PurpleConversation *conv = PURPLE_CONVERSATION(chat);
g_return_if_fail(node != NULL);
g_return_if_fail(conv != NULL);
@@ -4645,21 +4613,21 @@ blist_node_aliased_cb(PurpleBlistNode *node, const char *old_alias, PurpleConver
if (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)
return;
- if (PURPLE_BLIST_NODE_IS_CONTACT(node))
+ if (PURPLE_IS_CONTACT(node))
{
PurpleBlistNode *bnode;
for(bnode = node->child; bnode; bnode = bnode->next) {
- if(!PURPLE_BLIST_NODE_IS_BUDDY(bnode))
+ if(!PURPLE_IS_BUDDY(bnode))
continue;
- update_chat_alias((PurpleBuddy *)bnode, conv, gc, prpl_info);
+ update_chat_alias((PurpleBuddy *)bnode, chat, gc, prpl_info);
}
}
- 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) &&
+ else if (PURPLE_IS_BUDDY(node))
+ update_chat_alias((PurpleBuddy *)node, chat, gc, prpl_info);
+ else if (PURPLE_IS_CHAT(node) &&
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)
@@ -4668,12 +4636,13 @@ blist_node_aliased_cb(PurpleBlistNode *node, const char *old_alias, PurpleConver
}
static void
-buddy_cb_common(PurpleBuddy *buddy, PurpleConversation *conv, gboolean is_buddy)
+buddy_cb_common(PurpleBuddy *buddy, PurpleChatConversation *chat, gboolean is_buddy)
{
GtkTreeModel *model;
char *normalized_name;
GtkTreeIter iter;
GtkTextTag *texttag;
+ PurpleConversation *conv = PURPLE_CONVERSATION(chat);
int f;
g_return_if_fail(buddy != NULL);
@@ -4710,35 +4679,35 @@ buddy_cb_common(PurpleBuddy *buddy, PurpleConversation *conv, gboolean is_buddy)
g_free(normalized_name);
- blist_node_aliased_cb((PurpleBlistNode *)buddy, NULL, conv);
+ blist_node_aliased_cb((PurpleBlistNode *)buddy, NULL, chat);
- texttag = get_buddy_tag(conv, purple_buddy_get_name(buddy), 0, FALSE); /* XXX: do we want the normalized name? */
+ texttag = get_buddy_tag(chat, purple_buddy_get_name(buddy), 0, FALSE); /* XXX: do we want the normalized name? */
if (texttag) {
g_object_set(texttag, "weight", is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, NULL);
}
}
static void
-buddy_added_cb(PurpleBlistNode *node, PurpleConversation *conv)
+buddy_added_cb(PurpleBlistNode *node, PurpleChatConversation *chat)
{
- if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (!PURPLE_IS_BUDDY(node))
return;
- buddy_cb_common(PURPLE_BUDDY(node), conv, TRUE);
+ buddy_cb_common(PURPLE_BUDDY(node), chat, TRUE);
}
static void
-buddy_removed_cb(PurpleBlistNode *node, PurpleConversation *conv)
+buddy_removed_cb(PurpleBlistNode *node, PurpleChatConversation *chat)
{
- if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (!PURPLE_IS_BUDDY(node))
return;
/* If there's another buddy for the same "dude" on the list, do nothing. */
- if (purple_find_buddy(purple_buddy_get_account(PURPLE_BUDDY(node)),
+ if (purple_blist_find_buddy(purple_buddy_get_account(PURPLE_BUDDY(node)),
purple_buddy_get_name(PURPLE_BUDDY(node))) != NULL)
return;
- buddy_cb_common(PURPLE_BUDDY(node), conv, FALSE);
+ buddy_cb_common(PURPLE_BUDDY(node), chat, FALSE);
}
static void
@@ -4845,7 +4814,7 @@ minimum_entry_lines_pref_cb(const char *name,
gconstpointer value,
gpointer data)
{
- GList *l = purple_get_conversations();
+ GList *l = purple_conversations_get_all();
PurpleConversation *conv;
while (l != NULL)
{
@@ -4913,7 +4882,7 @@ 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(purple_connection_get_prpl(purple_account_get_connection(account)));
- node = (PurpleBlistNode*)(purple_find_buddy(purple_conversation_get_account(conv), who));
+ node = (PurpleBlistNode*)(purple_blist_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);
@@ -5027,12 +4996,12 @@ pidgin_conv_create_tooltip(GtkWidget *tipwindow, gpointer userdata, int *w, int
PidginConversation *gtkconv = userdata;
conv = gtkconv->active_conv;
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
+ if (PURPLE_IS_CHAT_CONVERSATION(conv)) {
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->webview), "transient_chat");
} else {
- node = (PurpleBlistNode*)(purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv)));
+ node = (PurpleBlistNode*)(purple_blist_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)
@@ -5136,12 +5105,12 @@ replace_header_tokens(PurpleConversation *conv, const char *text)
replace = purple_conversation_get_name(conv);
} else if (g_str_has_prefix(cur, "%sourceName%")) {
- replace = purple_account_get_alias(account);
+ replace = purple_account_get_private_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));
+ PurpleBuddy *buddy = purple_blist_find_buddy(account, purple_conversation_get_name(conv));
if (buddy) {
replace = purple_buddy_get_alias(buddy);
} else {
@@ -5149,7 +5118,7 @@ replace_header_tokens(PurpleConversation *conv, const char *text)
}
} else if (g_str_has_prefix(cur, "%incomingIconPath%")) {
- PurpleBuddyIcon *icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv));
+ PurpleBuddyIcon *icon = purple_im_conversation_get_icon(PURPLE_IM_CONVERSATION(conv));
if (icon)
replace = purple_buddy_icon_get_full_path(icon);
@@ -5335,7 +5304,7 @@ load_conv_theme(PidginConversation *gtkconv)
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)
+ if (PURPLE_IS_CHAT_CONVERSATION(gtkconv->active_conv))
gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview),
"document.getElementById('Chat').className = 'groupchat'");
@@ -5355,7 +5324,7 @@ setup_common_pane(PidginConversation *gtkconv)
GtkTreePath *path;
PurpleConversation *conv = gtkconv->active_conv;
PurpleBuddy *buddy;
- gboolean chat = (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT);
+ gboolean chat = PURPLE_IS_CHAT_CONVERSATION(conv);
int buddyicon_size = 0;
/* Setup the top part of the pane */
@@ -5404,7 +5373,7 @@ setup_common_pane(PidginConversation *gtkconv)
else {
gtkconv->u.im->icon_container = gtk_vbox_new(FALSE, 0);
- if ((buddy = purple_find_buddy(purple_conversation_get_account(conv),
+ if ((buddy = purple_blist_find_buddy(purple_conversation_get_account(conv),
purple_conversation_get_name(conv))) != NULL) {
PurpleContact *contact = purple_buddy_get_contact(buddy);
if (contact) {
@@ -5541,7 +5510,7 @@ conv_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
{
PurpleConversation *conv = gtkconv->active_conv;
PidginWindow *win = gtkconv->win;
- PurpleConversation *c;
+ PurpleIMConversation *im;
PurpleAccount *convaccount = purple_conversation_get_account(conv);
PurpleConnection *gc = purple_account_get_connection(convaccount);
PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)) : NULL;
@@ -5557,9 +5526,9 @@ conv_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
n = *(PurpleBlistNode **) data;
- if (PURPLE_BLIST_NODE_IS_CONTACT(n))
+ if (PURPLE_IS_CONTACT(n))
b = purple_contact_get_priority_buddy((PurpleContact*)n);
- else if (PURPLE_BLIST_NODE_IS_BUDDY(n))
+ else if (PURPLE_IS_BUDDY(n))
b = (PurpleBuddy*)n;
else
return;
@@ -5570,29 +5539,29 @@ conv_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
* If a buddy is dragged to a chat window of the same protocol,
* invite him to the chat.
*/
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT &&
+ if (PURPLE_IS_CHAT_CONVERSATION(conv) &&
prpl_info && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, chat_invite) &&
strcmp(purple_account_get_protocol_id(convaccount),
purple_account_get_protocol_id(buddyaccount)) == 0) {
- purple_conv_chat_invite_user(PURPLE_CONV_CHAT(conv), buddyname, NULL, TRUE);
+ purple_chat_conversation_invite_user(PURPLE_CHAT_CONVERSATION(conv), buddyname, NULL, TRUE);
} else {
/*
* If we already have an open conversation with this buddy, then
* just move the conv to this window. Otherwise, create a new
* conv and add it to this window.
*/
- c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddyname, buddyaccount);
- if (c != NULL) {
+ im = purple_conversations_find_im_with_account(buddyname, buddyaccount);
+ if (im != NULL) {
PidginWindow *oldwin;
- gtkconv = PIDGIN_CONVERSATION(c);
+ gtkconv = PIDGIN_CONVERSATION(PURPLE_CONVERSATION(im));
oldwin = gtkconv->win;
if (oldwin != win) {
pidgin_conv_window_remove_gtkconv(oldwin, gtkconv);
pidgin_conv_window_add_gtkconv(win, gtkconv);
}
} else {
- c = purple_conversation_new(PURPLE_CONV_TYPE_IM, buddyaccount, buddyname);
- gtkconv = PIDGIN_CONVERSATION(c);
+ im = purple_im_conversation_new(buddyaccount, buddyname);
+ gtkconv = PIDGIN_CONVERSATION(PURPLE_CONVERSATION(im));
if (gtkconv->win != win) {
pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv);
pidgin_conv_window_add_gtkconv(win, gtkconv);
@@ -5626,13 +5595,13 @@ conv_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
* If a buddy is dragged to a chat window of the same protocol,
* invite him to the chat.
*/
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT &&
+ if (PURPLE_IS_CHAT_CONVERSATION(conv) &&
prpl_info && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, chat_invite) &&
strcmp(purple_account_get_protocol_id(convaccount), protocol) == 0) {
- purple_conv_chat_invite_user(PURPLE_CONV_CHAT(conv), username, NULL, TRUE);
+ purple_chat_conversation_invite_user(PURPLE_CHAT_CONVERSATION(conv), username, NULL, TRUE);
} else {
- c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, username);
- gtkconv = PIDGIN_CONVERSATION(c);
+ im = purple_im_conversation_new(account, username);
+ gtkconv = PIDGIN_CONVERSATION(PURPLE_CONVERSATION(im));
if (gtkconv->win != win) {
pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv);
pidgin_conv_window_add_gtkconv(win, gtkconv);
@@ -5648,7 +5617,7 @@ conv_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
}
else if (info == WEBKIT_WEB_VIEW_TARGET_INFO_URI_LIST) {
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
+ if (PURPLE_IS_IM_CONVERSATION(conv))
pidgin_dnd_file_manage(sd, convaccount, purple_conversation_get_name(conv));
gtk_drag_finish(dc, TRUE,
gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
@@ -5661,7 +5630,7 @@ conv_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
static PidginConversation *
pidgin_conv_find_gtkconv(PurpleConversation * conv)
{
- PurpleBuddy *bud = purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv));
+ PurpleBuddy *bud = purple_blist_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv));
PurpleContact *c;
PurpleBlistNode *cn, *bn;
@@ -5674,10 +5643,10 @@ pidgin_conv_find_gtkconv(PurpleConversation * conv)
cn = PURPLE_BLIST_NODE(c);
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, purple_buddy_get_name(b), purple_buddy_get_account(b)))) {
- if (PIDGIN_CONVERSATION(conv))
- return PIDGIN_CONVERSATION(conv);
+ PurpleIMConversation *im;
+ if ((im = purple_conversations_find_im_with_account(purple_buddy_get_name(b), purple_buddy_get_account(b)))) {
+ if (PIDGIN_CONVERSATION(PURPLE_CONVERSATION(im)))
+ return PIDGIN_CONVERSATION(PURPLE_CONVERSATION(im));
}
}
@@ -5690,7 +5659,7 @@ buddy_update_cb(PurpleBlistNode *bnode, gpointer null)
GList *list;
g_return_if_fail(bnode);
- if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode))
+ if (!PURPLE_IS_BUDDY(bnode))
return;
for (list = pidgin_conv_windows_get_list(); list; list = list->next)
@@ -5698,7 +5667,7 @@ buddy_update_cb(PurpleBlistNode *bnode, gpointer null)
PidginWindow *win = list->data;
PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
- if (purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_IM)
+ if (PURPLE_IS_CHAT_CONVERSATION(conv))
continue;
pidgin_conv_update_fields(conv, PIDGIN_CONV_MENU);
@@ -5763,13 +5732,13 @@ private_gtkconv_new(PurpleConversation *conv, gboolean hidden)
PidginConversation *gtkconv;
const char *theme_name;
PurpleTheme *theme = NULL;
- PurpleConversationType conv_type = purple_conversation_get_type(conv);
+ gboolean is_chat = PURPLE_IS_CHAT_CONVERSATION(conv);
GtkWidget *pane = NULL;
GtkWidget *tab_cont;
PurpleBlistNode *convnode;
GtkTargetList *targets;
- if (conv_type == PURPLE_CONV_TYPE_IM && (gtkconv = pidgin_conv_find_gtkconv(conv))) {
+ if (!is_chat && (gtkconv = pidgin_conv_find_gtkconv(conv))) {
purple_conversation_set_ui_data(conv, gtkconv);
if (!g_list_find(gtkconv->convs, conv))
gtkconv->convs = g_list_prepend(gtkconv->convs, conv);
@@ -5795,17 +5764,17 @@ private_gtkconv_new(PurpleConversation *conv, gboolean hidden)
gtkconv->last_flags = 0;
- if (conv_type == PURPLE_CONV_TYPE_IM) {
+ if (!is_chat) {
gtkconv->u.im = g_malloc0(sizeof(PidginImPane));
- } else if (conv_type == PURPLE_CONV_TYPE_CHAT) {
+ } else {
gtkconv->u.chat = g_malloc0(sizeof(PidginChatPane));
}
pane = setup_common_pane(gtkconv);
if (pane == NULL) {
- if (conv_type == PURPLE_CONV_TYPE_CHAT)
+ if (is_chat)
g_free(gtkconv->u.chat);
- else if (conv_type == PURPLE_CONV_TYPE_IM)
+ else
g_free(gtkconv->u.im);
g_free(gtkconv);
@@ -5901,7 +5870,7 @@ private_gtkconv_new(PurpleConversation *conv, gboolean hidden)
gtkconv->nick_colors = g_array_ref(generated_nick_colors);
}
- if (purple_conversation_get_features(conv) & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)
+ if (purple_conversation_get_features(conv) & PURPLE_CONNECTION_FLAG_ALLOW_CUSTOM_SMILEY)
pidgin_themes_smiley_themeize_custom(gtkconv->entry);
}
@@ -5947,16 +5916,16 @@ received_im_msg_cb(PurpleAccount *account, char *sender, char *message,
if (hide) {
ui_ops->create_conversation = pidgin_conv_new_hidden;
- purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender);
+ purple_im_conversation_new(account, sender);
ui_ops->create_conversation = pidgin_conv_new;
}
/* Somebody wants to keep this conversation around, so don't time it out */
if (conv) {
- timer = GPOINTER_TO_INT(purple_conversation_get_data(conv, "close-timer"));
+ timer = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(conv), "close-timer"));
if (timer) {
purple_timeout_remove(timer);
- purple_conversation_set_data(conv, "close-timer", GINT_TO_POINTER(0));
+ g_object_set_data(G_OBJECT(conv), "close-timer", GINT_TO_POINTER(0));
}
}
}
@@ -5972,7 +5941,7 @@ pidgin_conv_destroy(PurpleConversation *conv)
/* Make sure the destroyed conversation is not the active one */
if (gtkconv->active_conv == conv) {
gtkconv->active_conv = gtkconv->convs->data;
- purple_conversation_update(gtkconv->active_conv, PURPLE_CONV_UPDATE_FEATURES);
+ purple_conversation_update(gtkconv->active_conv, PURPLE_CONVERSATION_UPDATE_FEATURES);
}
return;
}
@@ -5986,7 +5955,7 @@ pidgin_conv_destroy(PurpleConversation *conv)
gtk_widget_destroy(gtkconv->tab_cont);
g_object_unref(gtkconv->tab_cont);
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
if (gtkconv->u.im->icon_timer != 0)
g_source_remove(gtkconv->u.im->icon_timer);
@@ -5997,7 +5966,7 @@ pidgin_conv_destroy(PurpleConversation *conv)
g_source_remove(gtkconv->u.im->typing_timer);
g_free(gtkconv->u.im);
- } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
+ } else {
purple_signals_disconnect_by_handle(gtkconv->u.chat);
g_free(gtkconv->u.chat);
}
@@ -6021,11 +5990,12 @@ pidgin_conv_destroy(PurpleConversation *conv)
static void
-pidgin_conv_write_im(PurpleConversation *conv, const char *who,
+pidgin_conv_write_im(PurpleIMConversation *im, const char *who,
const char *message, PurpleMessageFlags flags,
time_t mtime)
{
PidginConversation *gtkconv;
+ PurpleConversation *conv = PURPLE_CONVERSATION(im);
gtkconv = PIDGIN_CONVERSATION(conv);
@@ -6033,7 +6003,7 @@ pidgin_conv_write_im(PurpleConversation *conv, const char *who,
flags & PURPLE_MESSAGE_ACTIVE_ONLY)
{
/* Plugins that want these messages suppressed should be
- * calling purple_conv_im_write(), so they get suppressed here,
+ * calling purple_im_conversation_write_message(), so they get suppressed here,
* before being written to the log. */
purple_debug_info("gtkconv",
"Suppressing message for an inactive conversation in pidgin_conv_write_im()\n");
@@ -6134,7 +6104,7 @@ static gboolean buddytag_event(GtkTextTag *tag, GObject *imhtml,
}
#endif
-static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag,
+static GtkTextTag *get_buddy_tag(PurpleChatConversation *chat, const char *who, PurpleMessageFlags flag,
gboolean create)
{
/* TODO WEBKIT */
@@ -6161,7 +6131,7 @@ static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, Purp
buddytag = gtk_text_buffer_create_tag(
buffer, str,
"foreground-gdk", get_nick_color(gtkconv, who),
- "weight", purple_find_buddy(purple_conversation_get_account(conv), who) ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL,
+ "weight", purple_blist_find_buddy(purple_conversation_get_account(conv), who) ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL,
NULL);
g_object_set_data(G_OBJECT(buddytag), "cursor", "");
@@ -6308,7 +6278,7 @@ replace_message_tokens(
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));
+ PurpleBuddyIcon *icon = purple_im_conversation_get_icon(PURPLE_IM_CONVERSATION(conv));
if (icon)
replace = purple_buddy_icon_get_full_path(icon);
if (replace == NULL || !g_file_test(replace, G_FILE_TEST_EXISTS)) {
@@ -6391,7 +6361,6 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
char *sml_attrib = NULL;
size_t length;
#endif
- PurpleConversationType type;
char *displaying;
gboolean plugin_return;
#if 0
@@ -6425,7 +6394,7 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
{
/* Unless this had PURPLE_MESSAGE_NO_LOG, this message
* was logged. Plugin writers: if this isn't what
- * you wanted, call purple_conv_im_write() instead of
+ * you wanted, call purple_im_conversation_write_message() instead of
* purple_conversation_write(). */
purple_debug_info("gtkconv",
"Suppressing message for an inactive conversation in pidgin_conv_write_conv()\n");
@@ -6438,7 +6407,6 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
pidgin_conv_switch_active_conversation(conv);
}
- type = purple_conversation_get_type(conv);
account = purple_conversation_get_account(conv);
g_return_if_fail(account != NULL);
gc = purple_account_get_connection(account);
@@ -6451,7 +6419,7 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
displaying = purple_markup_linkify(message);
plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1(
- pidgin_conversations_get_handle(), (type == PURPLE_CONV_TYPE_IM ?
+ pidgin_conversations_get_handle(), (PURPLE_IS_IM_CONVERSATION(conv) ?
"displaying-im-msg" : "displaying-chat-msg"),
account, name, &displaying, conv, flags));
if (plugin_return)
@@ -6475,7 +6443,7 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
} else if ((flags & PURPLE_MESSAGE_RECV) && (old_flags & PURPLE_MESSAGE_RECV)) {
GList *history = purple_conversation_get_message_history(gtkconv->last_conversed);
- PurpleConvMessage *last_msg = history ? (PurpleConvMessage *)history->data : NULL;
+ PurpleConversationMessage *last_msg = history ? (PurpleConversationMessage *)history->data : NULL;
g_assert(history != NULL);
g_assert(last_msg != NULL);
@@ -6564,7 +6532,7 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
gtk_font_options |= GTK_IMHTML_USE_POINTSIZE;
}
- if (!(flags & PURPLE_MESSAGE_RECV) && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY))
+ if (!(flags & PURPLE_MESSAGE_RECV) && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_FLAG_ALLOW_CUSTOM_SMILEY))
{
/* We want to see our own smileys. Need to revert it after send*/
pidgin_themes_smiley_themeize_custom(gtkconv->webview);
@@ -6726,7 +6694,7 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
}
#if 0
- if (!(flags & PURPLE_MESSAGE_RECV) && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY))
+ if (!(flags & PURPLE_MESSAGE_RECV) && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_FLAG_ALLOW_CUSTOM_SMILEY))
{
/* Restore the smiley-data */
pidgin_themes_smiley_themeize(gtkconv->webview);
@@ -6736,7 +6704,7 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
/* on rejoin only request message history from after this message */
if (flags & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_RECV) &&
- purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
+ PURPLE_IS_CHAT_CONVERSATION(conv)) {
PurpleChat *chat = purple_blist_find_chat(
purple_conversation_get_account(conv),
purple_conversation_get_name(conv));
@@ -6775,13 +6743,13 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
}
purple_signal_emit(pidgin_conversations_get_handle(),
- (type == PURPLE_CONV_TYPE_IM ? "displayed-im-msg" : "displayed-chat-msg"),
+ (PURPLE_IS_IM_CONVERSATION(conv) ? "displayed-im-msg" : "displayed-chat-msg"),
account, name, displaying, conv, flags);
g_free(displaying);
update_typing_message(gtkconv, NULL);
}
-static gboolean get_iter_from_chatbuddy(PurpleConvChatBuddy *cb, GtkTreeIter *iter)
+static gboolean get_iter_from_chatuser(PurpleChatUser *cb, GtkTreeIter *iter)
{
GtkTreeRowReference *ref;
GtkTreePath *path;
@@ -6789,7 +6757,7 @@ static gboolean get_iter_from_chatbuddy(PurpleConvChatBuddy *cb, GtkTreeIter *it
g_return_val_if_fail(cb != NULL, FALSE);
- ref = purple_conv_chat_cb_get_ui_data(cb);
+ ref = purple_chat_user_get_ui_data(cb);
if (!ref)
return FALSE;
@@ -6807,9 +6775,8 @@ static gboolean get_iter_from_chatbuddy(PurpleConvChatBuddy *cb, GtkTreeIter *it
}
static void
-pidgin_conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gboolean new_arrivals)
+pidgin_conv_chat_add_users(PurpleChatConversation *chat, GList *cbuddies, gboolean new_arrivals)
{
- PurpleConvChat *chat;
PidginConversation *gtkconv;
PidginChatPane *gtkchat;
GtkListStore *ls;
@@ -6818,11 +6785,10 @@ pidgin_conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gboolean n
char tmp[BUF_LONG];
int num_users;
- chat = PURPLE_CONV_CHAT(conv);
- gtkconv = PIDGIN_CONVERSATION(conv);
+ gtkconv = PIDGIN_CONVERSATION(PURPLE_CONVERSATION(chat));
gtkchat = gtkconv->u.chat;
- num_users = g_list_length(purple_conv_chat_get_users(chat));
+ num_users = g_list_length(purple_chat_conversation_get_users(chat));
g_snprintf(tmp, sizeof(tmp),
ngettext("%d person in room", "%d people in room",
@@ -6838,7 +6804,7 @@ pidgin_conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gboolean n
l = cbuddies;
while (l != NULL) {
- add_chat_buddy_common(conv, (PurpleConvChatBuddy *)l->data, NULL);
+ add_chat_user_common(chat, (PurpleChatUser *)l->data, NULL);
l = l->next;
}
@@ -6850,19 +6816,17 @@ pidgin_conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gboolean n
}
static void
-pidgin_conv_chat_rename_user(PurpleConversation *conv, const char *old_name,
+pidgin_conv_chat_rename_user(PurpleChatConversation *chat, const char *old_name,
const char *new_name, const char *new_alias)
{
- PurpleConvChat *chat;
PidginConversation *gtkconv;
PidginChatPane *gtkchat;
- PurpleConvChatBuddy *old_cbuddy, *new_cbuddy;
+ PurpleChatUser *old_chatuser, *new_chatuser;
GtkTreeIter iter;
GtkTreeModel *model;
GtkTextTag *tag;
- chat = PURPLE_CONV_CHAT(conv);
- gtkconv = PIDGIN_CONVERSATION(conv);
+ gtkconv = PIDGIN_CONVERSATION(PURPLE_CONVERSATION(chat));
gtkchat = gtkconv->u.chat;
model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
@@ -6870,34 +6834,33 @@ pidgin_conv_chat_rename_user(PurpleConversation *conv, const char *old_name,
if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter))
return;
- if ((tag = get_buddy_tag(conv, old_name, 0, FALSE)))
+ if ((tag = get_buddy_tag(chat, old_name, 0, FALSE)))
g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL);
- if ((tag = get_buddy_tag(conv, old_name, PURPLE_MESSAGE_NICK, FALSE)))
+ if ((tag = get_buddy_tag(chat, old_name, PURPLE_MESSAGE_NICK, FALSE)))
g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL);
- old_cbuddy = purple_conv_chat_cb_find(chat, old_name);
- if (!old_cbuddy)
+ old_chatuser = purple_chat_conversation_find_user(chat, old_name);
+ if (!old_chatuser)
return;
- if (get_iter_from_chatbuddy(old_cbuddy, &iter)) {
- GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(old_cbuddy);
+ if (get_iter_from_chatuser(old_chatuser, &iter)) {
+ GtkTreeRowReference *ref = purple_chat_user_get_ui_data(old_chatuser);
gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
gtk_tree_row_reference_free(ref);
- purple_conv_chat_cb_set_ui_data(old_cbuddy, NULL);
+ purple_chat_user_set_ui_data(old_chatuser, NULL);
}
g_return_if_fail(new_alias != NULL);
- new_cbuddy = purple_conv_chat_cb_find(chat, new_name);
+ new_chatuser = purple_chat_conversation_find_user(chat, new_name);
- add_chat_buddy_common(conv, new_cbuddy, old_name);
+ add_chat_user_common(chat, new_chatuser, old_name);
}
static void
-pidgin_conv_chat_remove_users(PurpleConversation *conv, GList *users)
+pidgin_conv_chat_remove_users(PurpleChatConversation *chat, GList *users)
{
- PurpleConvChat *chat;
PidginConversation *gtkconv;
PidginChatPane *gtkchat;
GtkTreeIter iter;
@@ -6908,11 +6871,10 @@ pidgin_conv_chat_remove_users(PurpleConversation *conv, GList *users)
gboolean f;
GtkTextTag *tag;
- chat = PURPLE_CONV_CHAT(conv);
- gtkconv = PIDGIN_CONVERSATION(conv);
+ gtkconv = PIDGIN_CONVERSATION(PURPLE_CONVERSATION(chat));
gtkchat = gtkconv->u.chat;
- num_users = g_list_length(purple_conv_chat_get_users(chat));
+ num_users = g_list_length(purple_chat_conversation_get_users(chat));
for (l = users; l != NULL; l = l->next) {
model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
@@ -6936,9 +6898,9 @@ pidgin_conv_chat_remove_users(PurpleConversation *conv, GList *users)
g_free(val);
} while (f);
- if ((tag = get_buddy_tag(conv, l->data, 0, FALSE)))
+ if ((tag = get_buddy_tag(chat, l->data, 0, FALSE)))
g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL);
- if ((tag = get_buddy_tag(conv, l->data, PURPLE_MESSAGE_NICK, FALSE)))
+ if ((tag = get_buddy_tag(chat, l->data, PURPLE_MESSAGE_NICK, FALSE)))
g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL);
}
@@ -6950,17 +6912,19 @@ pidgin_conv_chat_remove_users(PurpleConversation *conv, GList *users)
}
static void
-pidgin_conv_chat_update_user(PurpleConversation *conv, const char *user)
+pidgin_conv_chat_update_user(PurpleChatUser *chatuser)
{
- PurpleConvChat *chat;
- PurpleConvChatBuddy *cbuddy;
+ PurpleChatConversation *chat;
PidginConversation *gtkconv;
PidginChatPane *gtkchat;
GtkTreeIter iter;
GtkTreeModel *model;
- chat = PURPLE_CONV_CHAT(conv);
- gtkconv = PIDGIN_CONVERSATION(conv);
+ if (!chatuser)
+ return;
+
+ chat = purple_chat_user_get_chat(chatuser);
+ gtkconv = PIDGIN_CONVERSATION(PURPLE_CONVERSATION(chat));
gtkchat = gtkconv->u.chat;
model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
@@ -6968,19 +6932,15 @@ pidgin_conv_chat_update_user(PurpleConversation *conv, const char *user)
if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter))
return;
- cbuddy = purple_conv_chat_cb_find(chat, user);
- if (!cbuddy)
- return;
-
- if (get_iter_from_chatbuddy(cbuddy, &iter)) {
- GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cbuddy);
+ if (get_iter_from_chatuser(chatuser, &iter)) {
+ GtkTreeRowReference *ref = purple_chat_user_get_ui_data(chatuser);
gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
gtk_tree_row_reference_free(ref);
- purple_conv_chat_cb_set_ui_data(cbuddy, NULL);
+ purple_chat_user_set_ui_data(chatuser, NULL);
}
- if (cbuddy)
- add_chat_buddy_common(conv, cbuddy, NULL);
+ if (chatuser)
+ add_chat_user_common(chat, chatuser, NULL);
}
gboolean
@@ -7190,7 +7150,7 @@ gray_stuff_out(PidginConversation *gtkconv)
* supports it or not--that only affects if the button or menu item
* is sensitive or not.
*/
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
/* Show stuff that applies to IMs, hide stuff that applies to chats */
/* Deal with menu items */
@@ -7201,7 +7161,7 @@ gray_stuff_out(PidginConversation *gtkconv)
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))) {
+ if (purple_account_privacy_check(account, purple_conversation_get_name(conv))) {
gtk_action_set_visible(win->menu.unblock, FALSE);
gtk_action_set_visible(win->menu.block, TRUE);
} else {
@@ -7209,7 +7169,7 @@ gray_stuff_out(PidginConversation *gtkconv)
gtk_action_set_visible(win->menu.unblock, TRUE);
}
- if (purple_find_buddy(account, purple_conversation_get_name(conv)) == NULL) {
+ if (purple_blist_find_buddy(account, purple_conversation_get_name(conv)) == NULL) {
gtk_action_set_visible(win->menu.add, TRUE);
gtk_action_set_visible(win->menu.remove, FALSE);
} else {
@@ -7219,7 +7179,7 @@ gray_stuff_out(PidginConversation *gtkconv)
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) {
+ } else {
/* Show stuff that applies to Chats, hide stuff that applies to IMs */
/* Deal with menu items */
@@ -7252,38 +7212,38 @@ gray_stuff_out(PidginConversation *gtkconv)
* and what features that account supports.
*/
if ((gc != NULL) &&
- ((purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_CHAT) ||
- !purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)) ))
+ (PURPLE_IS_IM_CONVERSATION(conv) ||
+ !purple_chat_conversation_has_left(PURPLE_CHAT_CONVERSATION(conv)) ))
{
PurpleConnectionFlags features = purple_conversation_get_features(conv);
/* Account is online */
/* Deal with the toolbar */
- if (features & PURPLE_CONNECTION_HTML)
+ if (features & PURPLE_CONNECTION_FLAG_HTML)
{
buttons = GTK_WEBVIEW_ALL; /* Everything on */
- if (features & PURPLE_CONNECTION_NO_BGCOLOR)
+ if (features & PURPLE_CONNECTION_FLAG_NO_BGCOLOR)
buttons &= ~GTK_WEBVIEW_BACKCOLOR;
- if (features & PURPLE_CONNECTION_NO_FONTSIZE)
+ if (features & PURPLE_CONNECTION_FLAG_NO_FONTSIZE)
{
buttons &= ~GTK_WEBVIEW_GROW;
buttons &= ~GTK_WEBVIEW_SHRINK;
}
- if (features & PURPLE_CONNECTION_NO_URLDESC)
+ if (features & PURPLE_CONNECTION_FLAG_NO_URLDESC)
buttons &= ~GTK_WEBVIEW_LINKDESC;
} else {
buttons = GTK_WEBVIEW_SMILEY | GTK_WEBVIEW_IMAGE;
}
if (!(prpl_info->options & OPT_PROTO_IM_IMAGE)
- && !(features & PURPLE_CONNECTION_NO_IMAGES)) {
- features |= PURPLE_CONNECTION_NO_IMAGES;
+ && !(features & PURPLE_CONNECTION_FLAG_NO_IMAGES)) {
+ features |= PURPLE_CONNECTION_FLAG_NO_IMAGES;
purple_conversation_set_features(conv, features);
}
- if (features & PURPLE_CONNECTION_NO_IMAGES)
+ if (features & PURPLE_CONNECTION_FLAG_NO_IMAGES)
buttons &= ~GTK_WEBVIEW_IMAGE;
- if (features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)
+ if (features & PURPLE_CONNECTION_FLAG_ALLOW_CUSTOM_SMILEY)
buttons |= GTK_WEBVIEW_CUSTOM_SMILEY;
else
buttons &= ~GTK_WEBVIEW_CUSTOM_SMILEY;
@@ -7297,10 +7257,10 @@ gray_stuff_out(PidginConversation *gtkconv)
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));
+ gtk_action_set_sensitive(win->menu.insert_link, (features & PURPLE_CONNECTION_FLAG_HTML));
+ gtk_action_set_sensitive(win->menu.insert_image, !(features & PURPLE_CONNECTION_FLAG_NO_IMAGES));
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
+ if (PURPLE_IS_IM_CONVERSATION(conv))
{
gtk_action_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL));
gtk_action_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL));
@@ -7310,9 +7270,9 @@ gray_stuff_out(PidginConversation *gtkconv)
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));
+ (purple_blist_find_buddy(account, purple_conversation_get_name(conv)) != NULL));
}
- else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
+ else
{
gtk_action_set_sensitive(win->menu.add, (prpl_info->join_chat != NULL));
gtk_action_set_sensitive(win->menu.remove, (prpl_info->join_chat != NULL));
@@ -7345,10 +7305,10 @@ gray_stuff_out(PidginConversation *gtkconv)
if (pidgin_conv_window_is_active_conversation(conv))
{
GList *l = NULL;
- if ((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) &&
+ if (PURPLE_IS_IM_CONVERSATION(conv) &&
(gtkconv->u.im->anim))
{
- PurpleBuddy *buddy = purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv));
+ PurpleBuddy *buddy = purple_blist_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv));
window_icon =
gdk_pixbuf_animation_get_static_image(gtkconv->u.im->anim);
@@ -7388,8 +7348,8 @@ pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields)
if (fields & PIDGIN_CONV_BUDDY_ICON)
{
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
- pidgin_conv_update_buddy_icon(conv);
+ if (PURPLE_IS_IM_CONVERSATION(conv))
+ pidgin_conv_update_buddy_icon(PURPLE_IM_CONVERSATION(conv));
}
if (fields & PIDGIN_CONV_MENU)
@@ -7406,15 +7366,14 @@ pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields)
}
if ((fields & PIDGIN_CONV_TOPIC) &&
- purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
+ PURPLE_IS_CHAT_CONVERSATION(conv))
{
const char *topic;
- PurpleConvChat *chat = PURPLE_CONV_CHAT(conv);
PidginChatPane *gtkchat = gtkconv->u.chat;
if (gtkchat->topic_text != NULL)
{
- topic = purple_conv_chat_get_topic(chat);
+ topic = purple_chat_conversation_get_topic(PURPLE_CHAT_CONVERSATION(conv));
gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), topic ? topic : "");
gtk_widget_set_tooltip_text(gtkchat->topic_text,
@@ -7432,7 +7391,7 @@ pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields)
(fields & PIDGIN_CONV_TOPIC))
{
char *title;
- PurpleConvIm *im = NULL;
+ PurpleIMConversation *im = NULL;
PurpleAccount *account = purple_conversation_get_account(conv);
PurpleBuddy *buddy = NULL;
char *markup = NULL;
@@ -7440,25 +7399,25 @@ pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields)
/* I think this is a little longer than it needs to be but I'm lazy. */
char *style;
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
- im = PURPLE_CONV_IM(conv);
+ if (PURPLE_IS_IM_CONVERSATION(conv))
+ im = PURPLE_IM_CONVERSATION(conv);
if ((account == NULL) ||
!purple_account_is_connected(account) ||
- ((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
- && purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv))))
+ (PURPLE_IS_CHAT_CONVERSATION(conv)
+ && purple_chat_conversation_has_left(PURPLE_CHAT_CONVERSATION(conv))))
title = g_strdup_printf("(%s)", purple_conversation_get_title(conv));
else
title = g_strdup(purple_conversation_get_title(conv));
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- buddy = purple_find_buddy(account, purple_conversation_get_name(conv));
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ buddy = purple_blist_find_buddy(account, purple_conversation_get_name(conv));
if (buddy) {
markup = pidgin_blist_get_name_markup(buddy, FALSE, FALSE);
} else {
markup = title;
}
- } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
+ } else if (PURPLE_IS_CHAT_CONVERSATION(conv)) {
const char *topic = gtkconv->u.chat->topic_text
? gtk_entry_get_text(GTK_ENTRY(gtkconv->u.chat->topic_text))
: NULL;
@@ -7498,11 +7457,11 @@ pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields)
accessibility_obj = gtk_widget_get_accessible(gtkconv->tab_cont);
if (im != NULL &&
- purple_conv_im_get_typing_state(im) == PURPLE_TYPING) {
+ purple_im_conversation_get_typing_state(im) == PURPLE_IM_TYPING) {
atk_object_set_description(accessibility_obj, _("Typing"));
style = "tab-label-typing";
} else if (im != NULL &&
- purple_conv_im_get_typing_state(im) == PURPLE_TYPED) {
+ purple_im_conversation_get_typing_state(im) == PURPLE_IM_TYPED) {
atk_object_set_description(accessibility_obj, _("Stopped Typing"));
style = "tab-label-typed";
} else if (gtkconv->unseen_state == PIDGIN_UNSEEN_NICK) {
@@ -7510,7 +7469,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 (purple_conversation_get_type(gtkconv->active_conv) == PURPLE_CONV_TYPE_CHAT)
+ if (PURPLE_IS_CHAT_CONVERSATION(gtkconv->active_conv))
style = "tab-label-unreadchat";
else
style = "tab-label-attention";
@@ -7553,46 +7512,46 @@ pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields)
}
static void
-pidgin_conv_updated(PurpleConversation *conv, PurpleConvUpdateType type)
+pidgin_conv_updated(PurpleConversation *conv, PurpleConversationUpdateType type)
{
PidginConvFields flags = 0;
g_return_if_fail(conv != NULL);
- if (type == PURPLE_CONV_UPDATE_ACCOUNT)
+ if (type == PURPLE_CONVERSATION_UPDATE_ACCOUNT)
{
flags = PIDGIN_CONV_ALL;
}
- else if (type == PURPLE_CONV_UPDATE_TYPING ||
- type == PURPLE_CONV_UPDATE_UNSEEN ||
- type == PURPLE_CONV_UPDATE_TITLE)
+ else if (type == PURPLE_CONVERSATION_UPDATE_TYPING ||
+ type == PURPLE_CONVERSATION_UPDATE_UNSEEN ||
+ type == PURPLE_CONVERSATION_UPDATE_TITLE)
{
flags = PIDGIN_CONV_COLORIZE_TITLE;
}
- else if (type == PURPLE_CONV_UPDATE_TOPIC)
+ else if (type == PURPLE_CONVERSATION_UPDATE_TOPIC)
{
flags = PIDGIN_CONV_TOPIC;
}
- else if (type == PURPLE_CONV_ACCOUNT_ONLINE ||
- type == PURPLE_CONV_ACCOUNT_OFFLINE)
+ else if (type == PURPLE_CONVERSATION_ACCOUNT_ONLINE ||
+ type == PURPLE_CONVERSATION_ACCOUNT_OFFLINE)
{
flags = PIDGIN_CONV_MENU | PIDGIN_CONV_TAB_ICON | PIDGIN_CONV_SET_TITLE;
}
- else if (type == PURPLE_CONV_UPDATE_AWAY)
+ else if (type == PURPLE_CONVERSATION_UPDATE_AWAY)
{
flags = PIDGIN_CONV_TAB_ICON;
}
- else if (type == PURPLE_CONV_UPDATE_ADD ||
- type == PURPLE_CONV_UPDATE_REMOVE ||
- type == PURPLE_CONV_UPDATE_CHATLEFT)
+ else if (type == PURPLE_CONVERSATION_UPDATE_ADD ||
+ type == PURPLE_CONVERSATION_UPDATE_REMOVE ||
+ type == PURPLE_CONVERSATION_UPDATE_CHATLEFT)
{
flags = PIDGIN_CONV_SET_TITLE | PIDGIN_CONV_MENU;
}
- else if (type == PURPLE_CONV_UPDATE_ICON)
+ else if (type == PURPLE_CONVERSATION_UPDATE_ICON)
{
flags = PIDGIN_CONV_BUDDY_ICON;
}
- else if (type == PURPLE_CONV_UPDATE_FEATURES)
+ else if (type == PURPLE_CONVERSATION_UPDATE_FEATURES)
{
flags = PIDGIN_CONV_MENU;
}
@@ -7657,9 +7616,10 @@ pidgin_conversations_get_conv_ui_ops(void)
* Public conversation utility functions
**************************************************************************/
void
-pidgin_conv_update_buddy_icon(PurpleConversation *conv)
+pidgin_conv_update_buddy_icon(PurpleIMConversation *im)
{
PidginConversation *gtkconv;
+ PurpleConversation *conv;
PidginWindow *win;
PurpleBuddy *buddy;
@@ -7680,9 +7640,10 @@ pidgin_conv_update_buddy_icon(PurpleConversation *conv)
PurpleBuddyIcon *icon;
+ conv = PURPLE_CONVERSATION(im);
+
g_return_if_fail(conv != NULL);
g_return_if_fail(PIDGIN_IS_PIDGIN_CONVERSATION(conv));
- g_return_if_fail(purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM);
gtkconv = PIDGIN_CONVERSATION(conv);
win = gtkconv->win;
@@ -7725,7 +7686,7 @@ pidgin_conv_update_buddy_icon(PurpleConversation *conv)
if (purple_conversation_get_connection(conv) == NULL)
return;
- buddy = purple_find_buddy(account, purple_conversation_get_name(conv));
+ buddy = purple_blist_find_buddy(account, purple_conversation_get_name(conv));
if (buddy)
{
PurpleContact *contact = purple_buddy_get_contact(buddy);
@@ -7740,7 +7701,7 @@ pidgin_conv_update_buddy_icon(PurpleConversation *conv)
}
if (data == NULL) {
- icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv));
+ icon = purple_im_conversation_get_icon(im);
if (icon == NULL)
{
gtk_widget_set_size_request(gtkconv->u.im->icon_container,
@@ -7934,7 +7895,7 @@ close_on_tabs_pref_cb(const char *name, PurplePrefType type,
PurpleConversation *conv;
PidginConversation *gtkconv;
- for (l = purple_get_conversations(); l != NULL; l = l->next) {
+ for (l = purple_conversations_get_all(); l != NULL; l = l->next) {
conv = (PurpleConversation *)l->data;
if (!PIDGIN_IS_PIDGIN_CONVERSATION(conv))
@@ -7957,7 +7918,7 @@ spellcheck_pref_cb(const char *name, PurplePrefType type,
PurpleConversation *conv;
PidginConversation *gtkconv;
- for (cl = purple_get_conversations(); cl != NULL; cl = cl->next) {
+ for (cl = purple_conversations_get_all(); cl != NULL; cl = cl->next) {
conv = (PurpleConversation *)cl->data;
@@ -7999,7 +7960,7 @@ show_formatting_toolbar_pref_cb(const char *name, PurplePrefType type,
PidginConversation *gtkconv;
PidginWindow *win;
- for (l = purple_get_conversations(); l != NULL; l = l->next)
+ for (l = purple_conversations_get_all(); l != NULL; l = l->next)
{
conv = (PurpleConversation *)l->data;
@@ -8035,7 +7996,7 @@ animate_buddy_icons_pref_cb(const char *name, PurplePrefType type,
return;
/* Set the "animate" flag for each icon based on the new preference */
- for (l = purple_get_ims(); l != NULL; l = l->next) {
+ for (l = purple_conversations_get_ims(); l != NULL; l = l->next) {
conv = (PurpleConversation *)l->data;
gtkconv = PIDGIN_CONVERSATION(conv);
if (gtkconv)
@@ -8046,7 +8007,7 @@ animate_buddy_icons_pref_cb(const char *name, PurplePrefType type,
for (l = pidgin_conv_windows_get_list(); l != NULL; l = l->next) {
win = l->data;
conv = pidgin_conv_window_get_active_conversation(win);
- pidgin_conv_update_buddy_icon(conv);
+ pidgin_conv_update_buddy_icon(PURPLE_IM_CONVERSATION(conv));
}
}
@@ -8056,7 +8017,7 @@ show_buddy_icons_pref_cb(const char *name, PurplePrefType type,
{
GList *l;
- for (l = purple_get_conversations(); l != NULL; l = l->next) {
+ for (l = purple_conversations_get_all(); l != NULL; l = l->next) {
PurpleConversation *conv = l->data;
if (!PIDGIN_CONVERSATION(conv))
continue;
@@ -8065,8 +8026,8 @@ show_buddy_icons_pref_cb(const char *name, PurplePrefType type,
else
gtk_widget_hide(PIDGIN_CONVERSATION(conv)->infopane_hbox);
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- pidgin_conv_update_buddy_icon(conv);
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ pidgin_conv_update_buddy_icon(PURPLE_IM_CONVERSATION(conv));
}
}
@@ -8084,7 +8045,7 @@ show_protocol_icons_pref_cb(const char *name, PurplePrefType type,
gconstpointer value, gpointer data)
{
GList *l;
- for (l = purple_get_conversations(); l != NULL; l = l->next) {
+ for (l = purple_conversations_get_all(); l != NULL; l = l->next) {
PurpleConversation *conv = l->data;
if (PIDGIN_CONVERSATION(conv))
update_tab_icon(conv);
@@ -8117,7 +8078,7 @@ account_status_changed_cb(PurpleAccount *account, PurpleStatus *oldstatus,
l = l->next;
conv = gtkconv->active_conv;
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT ||
+ if (PURPLE_IS_CHAT_CONVERSATION(conv) ||
account != purple_conversation_get_account(conv))
continue;
@@ -8125,7 +8086,7 @@ account_status_changed_cb(PurpleAccount *account, PurpleStatus *oldstatus,
/* TODO: do we need to do anything for any other conversations that are in the same gtkconv here?
* I'm a little concerned that not doing so will cause the "pending" indicator in the gtkblist not to be cleared. -DAA*/
- purple_conversation_update(conv, PURPLE_CONV_UPDATE_UNSEEN);
+ purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_UNSEEN);
}
}
@@ -8154,7 +8115,7 @@ hide_new_pref_cb(const char *name, PurplePrefType type,
conv = gtkconv->active_conv;
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT ||
+ if (PURPLE_IS_CHAT_CONVERSATION(conv) ||
gtkconv->unseen_count == 0 ||
(when_away && !purple_status_is_available(
purple_account_get_active_status(
@@ -8193,10 +8154,10 @@ get_gtkconv_with_contact(PurpleContact *contact)
for (; node; node = node->next)
{
PurpleBuddy *buddy = (PurpleBuddy*)node;
- PurpleConversation *conv;
- 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);
+ PurpleIMConversation *im;
+ im = purple_conversations_find_im_with_account(purple_buddy_get_name(buddy), purple_buddy_get_account(buddy));
+ if (im)
+ return PIDGIN_CONVERSATION(PURPLE_CONVERSATION(im));
}
return NULL;
}
@@ -8206,7 +8167,7 @@ account_signed_off_cb(PurpleConnection *gc, gpointer event)
{
GList *iter;
- for (iter = purple_get_conversations(); iter; iter = iter->next)
+ for (iter = purple_conversations_get_all(); iter; iter = iter->next)
{
PurpleConversation *conv = iter->data;
@@ -8219,9 +8180,9 @@ account_signed_off_cb(PurpleConnection *gc, gpointer event)
PIDGIN_CONV_MENU | PIDGIN_CONV_COLORIZE_TITLE);
if (PURPLE_CONNECTION_IS_CONNECTED(gc) &&
- purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT &&
+ PURPLE_IS_CHAT_CONVERSATION(conv) &&
purple_conversation_get_account(conv) == purple_connection_get_account(gc) &&
- purple_conversation_get_data(conv, "want-to-rejoin")) {
+ g_object_get_data(G_OBJECT(conv), "want-to-rejoin")) {
GHashTable *comps = NULL;
PurpleChat *chat = purple_blist_find_chat(purple_conversation_get_account(conv), purple_conversation_get_name(conv));
if (chat == NULL) {
@@ -8242,16 +8203,16 @@ account_signed_off_cb(PurpleConnection *gc, gpointer event)
static void
account_signing_off(PurpleConnection *gc)
{
- GList *list = purple_get_chats();
+ GList *list = purple_conversations_get_chats();
PurpleAccount *account = purple_connection_get_account(gc);
/* We are about to sign off. See which chats we are currently in, and mark
* them for rejoin on reconnect. */
while (list) {
PurpleConversation *conv = list->data;
- if (!purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)) &&
+ if (!purple_chat_conversation_has_left(PURPLE_CHAT_CONVERSATION(conv)) &&
purple_conversation_get_account(conv) == account) {
- purple_conversation_set_data(conv, "want-to-rejoin", GINT_TO_POINTER(TRUE));
+ g_object_set_data(G_OBJECT(conv), "want-to-rejoin", GINT_TO_POINTER(TRUE));
purple_conversation_write(conv, NULL, _("The account has disconnected and you are no "
"longer in this chat. You will automatically rejoin the chat when "
"the account reconnects."),
@@ -8295,21 +8256,21 @@ update_buddy_privacy_changed(PurpleBuddy *buddy)
static void
update_buddy_idle_changed(PurpleBuddy *buddy, gboolean old, gboolean newidle)
{
- PurpleConversation *conv;
+ PurpleIMConversation *im;
- 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);
+ im = purple_conversations_find_im_with_account(purple_buddy_get_name(buddy), purple_buddy_get_account(buddy));
+ if (im)
+ pidgin_conv_update_fields(PURPLE_CONVERSATION(im), PIDGIN_CONV_TAB_ICON);
}
static void
update_buddy_icon(PurpleBuddy *buddy)
{
- PurpleConversation *conv;
+ PurpleIMConversation *im;
- 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);
+ im = purple_conversations_find_im_with_account(purple_buddy_get_name(buddy), purple_buddy_get_account(buddy));
+ if (im)
+ pidgin_conv_update_fields(PURPLE_CONVERSATION(im), PIDGIN_CONV_BUDDY_ICON);
}
static void
@@ -8343,7 +8304,7 @@ update_buddy_typing(PurpleAccount *account, const char *who)
PurpleConversation *conv;
PidginConversation *gtkconv;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, account);
+ conv = PURPLE_CONVERSATION(purple_conversations_find_im_with_account(who, account));
if (!conv)
return;
@@ -8353,25 +8314,25 @@ update_buddy_typing(PurpleAccount *account, const char *who)
}
static void
-update_chat(PurpleConversation *conv)
+update_chat(PurpleChatConversation *chat)
{
- pidgin_conv_update_fields(conv, PIDGIN_CONV_TOPIC |
+ pidgin_conv_update_fields(PURPLE_CONVERSATION(chat), PIDGIN_CONV_TOPIC |
PIDGIN_CONV_MENU | PIDGIN_CONV_SET_TITLE);
}
static void
-update_chat_topic(PurpleConversation *conv, const char *old, const char *new)
+update_chat_topic(PurpleChatConversation *chat, const char *old, const char *new)
{
- pidgin_conv_update_fields(conv, PIDGIN_CONV_TOPIC);
+ pidgin_conv_update_fields(PURPLE_CONVERSATION(chat), PIDGIN_CONV_TOPIC);
}
/* Message history stuff */
-/* Compare two PurpleConvMessage's, according to time in ascending order. */
+/* Compare two PurpleConversationMessage's, according to time in ascending order. */
static int
message_compare(gconstpointer p1, gconstpointer p2)
{
- const PurpleConvMessage *m1 = p1, *m2 = p2;
+ const PurpleConversationMessage *m1 = p1, *m2 = p2;
return (purple_conversation_message_get_timestamp(m1) > purple_conversation_message_get_timestamp(m2));
}
@@ -8384,18 +8345,18 @@ add_message_history_to_gtkconv(gpointer data)
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 = (purple_conversation_get_type(gtkconv->active_conv) == PURPLE_CONV_TYPE_IM);
+ gboolean im = (PURPLE_IS_IM_CONVERSATION(gtkconv->active_conv));
gtkconv->attach.timer = 0;
while (gtkconv->attach.current && count < 100) { /* XXX: 100 is a random value here */
- PurpleConvMessage *msg = gtkconv->attach.current->data;
+ PurpleConversationMessage *msg = gtkconv->attach.current->data;
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(
- purple_conversation_message_get_conv(msg),
+ purple_conversation_message_get_conversation(msg),
purple_conversation_message_get_sender(msg),
purple_conversation_message_get_alias(msg),
purple_conversation_message_get_message(msg),
@@ -8422,16 +8383,16 @@ add_message_history_to_gtkconv(gpointer data)
PurpleConversation *conv = iter->data;
GList *history = purple_conversation_get_message_history(conv);
for (; history; history = history->next) {
- PurpleConvMessage *msg = history->data;
+ PurpleConversationMessage *msg = history->data;
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;
+ PurpleConversationMessage *msg = msgs->data;
pidgin_conv_write_conv(
- purple_conversation_message_get_conv(msg),
+ purple_conversation_message_get_conversation(msg),
purple_conversation_message_get_sender(msg),
purple_conversation_message_get_alias(msg),
purple_conversation_message_get_message(msg),
@@ -8453,15 +8414,15 @@ static void
pidgin_conv_attach(PurpleConversation *conv)
{
int timer;
- purple_conversation_set_data(conv, "unseen-count", NULL);
- purple_conversation_set_data(conv, "unseen-state", NULL);
+ g_object_set_data(G_OBJECT(conv), "unseen-count", NULL);
+ g_object_set_data(G_OBJECT(conv), "unseen-state", NULL);
purple_conversation_set_ui_ops(conv, pidgin_conversations_get_conv_ui_ops());
- if (!PIDGIN_CONVERSATION(conv))
- private_gtkconv_new(conv, FALSE);
- timer = GPOINTER_TO_INT(purple_conversation_get_data(conv, "close-timer"));
+ purple_conversation_set_ui_data(conv, NULL);
+ private_gtkconv_new(conv, FALSE);
+ timer = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(conv), "close-timer"));
if (timer) {
purple_timeout_remove(timer);
- purple_conversation_set_data(conv, "close-timer", NULL);
+ g_object_set_data(G_OBJECT(conv), "close-timer", NULL);
}
}
@@ -8492,39 +8453,34 @@ gboolean pidgin_conv_attach_to_conversation(PurpleConversation *conv)
list = purple_conversation_get_message_history(conv);
if (list) {
- switch (purple_conversation_get_type(conv)) {
- case PURPLE_CONV_TYPE_IM:
- {
- GList *convs;
- list = g_list_copy(list);
- for (convs = purple_get_ims(); convs; convs = convs->next)
- if (convs->data != conv &&
- pidgin_conv_find_gtkconv(convs->data) == gtkconv) {
- pidgin_conv_attach(convs->data);
- list = g_list_concat(list, g_list_copy(purple_conversation_get_message_history(convs->data)));
- }
- list = g_list_sort(list, message_compare);
- gtkconv->attach.current = list;
- list = g_list_last(list);
- break;
- }
- case PURPLE_CONV_TYPE_CHAT:
- gtkconv->attach.current = g_list_last(list);
- break;
- default:
- g_return_val_if_reached(TRUE);
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ GList *convs;
+ list = g_list_copy(list);
+ for (convs = purple_conversations_get_ims(); convs; convs = convs->next)
+ if (convs->data != conv &&
+ pidgin_conv_find_gtkconv(convs->data) == gtkconv) {
+ pidgin_conv_attach(convs->data);
+ list = g_list_concat(list, g_list_copy(purple_conversation_get_message_history(convs->data)));
+ }
+ list = g_list_sort(list, message_compare);
+ gtkconv->attach.current = list;
+ list = g_list_last(list);
+ } else {
+ gtkconv->attach.current = g_list_last(list);
}
+
g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time",
- GINT_TO_POINTER(purple_conversation_message_get_timestamp((PurpleConvMessage*)(list->data))));
+ GINT_TO_POINTER(purple_conversation_message_get_timestamp((PurpleConversationMessage*)(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 (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
+ if (PURPLE_IS_CHAT_CONVERSATION(conv)) {
+ PurpleChatConversation *chat = PURPLE_CHAT_CONVERSATION(conv);
pidgin_conv_update_fields(conv, PIDGIN_CONV_TOPIC);
- pidgin_conv_chat_add_users(conv, purple_conv_chat_get_users(PURPLE_CONV_CHAT(conv)), TRUE);
+ pidgin_conv_chat_add_users(chat, purple_chat_conversation_get_users(chat), TRUE);
}
return TRUE;
@@ -8647,11 +8603,9 @@ pidgin_conversations_init(void)
* Register signals
**********************************************************************/
purple_signal_register(handle, "conversation-dragging",
- purple_marshal_VOID__POINTER_POINTER, NULL, 2,
- purple_value_new(PURPLE_TYPE_BOXED,
- "PidginWindow *"),
- purple_value_new(PURPLE_TYPE_BOXED,
- "PidginWindow *"));
+ purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
+ G_TYPE_POINTER, /* pointer to a (PidginWindow *) */
+ G_TYPE_POINTER); /* pointer to a (PidginWindow *) */
purple_signal_register(handle, "conversation-timestamp",
#if SIZEOF_TIME_T == 4
@@ -8661,90 +8615,58 @@ pidgin_conversations_init(void)
#else
#error Unkown size of time_t
#endif
- purple_value_new(PURPLE_TYPE_STRING), 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
+ G_TYPE_STRING, 3, PURPLE_TYPE_CONVERSATION,
#if SIZEOF_TIME_T == 4
- purple_value_new(PURPLE_TYPE_INT),
+ G_TYPE_INT,
#elif SIZEOF_TIME_T == 8
- purple_value_new(PURPLE_TYPE_INT64),
+ G_TYPE_INT64,
#else
# error Unknown size of time_t
#endif
- purple_value_new(PURPLE_TYPE_BOOLEAN));
+ G_TYPE_BOOLEAN);
purple_signal_register(handle, "displaying-im-msg",
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new_outgoing(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_INT));
+ G_TYPE_BOOLEAN, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ G_TYPE_POINTER, /* pointer to a string */
+ PURPLE_TYPE_CONVERSATION, G_TYPE_INT);
purple_signal_register(handle, "displayed-im-msg",
purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT,
- NULL, 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_INT));
+ G_TYPE_NONE, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ G_TYPE_STRING, PURPLE_TYPE_CONVERSATION, G_TYPE_INT);
purple_signal_register(handle, "displaying-chat-msg",
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new_outgoing(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_INT));
+ G_TYPE_BOOLEAN, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ G_TYPE_POINTER, /* pointer to a string */
+ PURPLE_TYPE_CONVERSATION, G_TYPE_INT);
purple_signal_register(handle, "displayed-chat-msg",
purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT,
- NULL, 5,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_ACCOUNT),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_INT));
+ G_TYPE_NONE, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
+ G_TYPE_STRING, PURPLE_TYPE_CONVERSATION, G_TYPE_INT);
purple_signal_register(handle, "conversation-switched",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ PURPLE_TYPE_CONVERSATION);
purple_signal_register(handle, "conversation-hiding",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_BOXED,
- "PidginConversation *"));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ G_TYPE_POINTER); /* (PidginConversation *) */
purple_signal_register(handle, "conversation-displayed",
- purple_marshal_VOID__POINTER, NULL, 1,
- purple_value_new(PURPLE_TYPE_BOXED,
- "PidginConversation *"));
+ purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+ G_TYPE_POINTER); /* (PidginConversation *) */
purple_signal_register(handle, "chat-nick-autocomplete",
purple_marshal_BOOLEAN__POINTER_BOOLEAN,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 1,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION));
+ G_TYPE_BOOLEAN, 1, PURPLE_TYPE_CONVERSATION);
purple_signal_register(handle, "chat-nick-clicked",
purple_marshal_BOOLEAN__POINTER_POINTER_UINT,
- purple_value_new(PURPLE_TYPE_BOOLEAN), 3,
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_CONVERSATION),
- purple_value_new(PURPLE_TYPE_STRING),
- purple_value_new(PURPLE_TYPE_UINT));
+ G_TYPE_BOOLEAN, 3, PURPLE_TYPE_CONVERSATION,
+ G_TYPE_STRING, G_TYPE_UINT);
/**********************************************************************
@@ -8775,10 +8697,10 @@ pidgin_conversations_init(void)
purple_signal_connect(purple_connections_get_handle(), "signed-on", handle,
G_CALLBACK(account_signed_off_cb),
- GINT_TO_POINTER(PURPLE_CONV_ACCOUNT_ONLINE));
+ GINT_TO_POINTER(PURPLE_CONVERSATION_ACCOUNT_ONLINE));
purple_signal_connect(purple_connections_get_handle(), "signed-off", handle,
G_CALLBACK(account_signed_off_cb),
- GINT_TO_POINTER(PURPLE_CONV_ACCOUNT_OFFLINE));
+ GINT_TO_POINTER(PURPLE_CONVERSATION_ACCOUNT_OFFLINE));
purple_signal_connect(purple_connections_get_handle(), "signing-off", handle,
G_CALLBACK(account_signing_off), NULL);
@@ -8787,8 +8709,8 @@ pidgin_conversations_init(void)
purple_signal_connect(purple_conversations_get_handle(), "cleared-message-history",
handle, G_CALLBACK(clear_conversation_scrollback_cb), NULL);
- purple_signal_connect(purple_conversations_get_handle(), "deleting-chat-buddy",
- handle, G_CALLBACK(deleting_chat_buddy_cb), NULL);
+ purple_signal_connect(purple_conversations_get_handle(), "deleting-chat-user",
+ handle, G_CALLBACK(deleting_chat_user_cb), NULL);
purple_conversations_set_ui_ops(&conversation_ui_ops);
@@ -9035,7 +8957,7 @@ close_win_cb(GtkWidget *w, GdkEventAny *e, gpointer d)
l != NULL; l = l->next)
{
PidginConversation *gtkconv = l->data;
- if (purple_conversation_get_type(gtkconv->active_conv) == PURPLE_CONV_TYPE_IM &&
+ if (PURPLE_IS_IM_CONVERSATION(gtkconv->active_conv) &&
gtkconv->unseen_state >= PIDGIN_UNSEEN_TEXT)
{
build_warn_close_dialog(win);
@@ -9056,11 +8978,11 @@ conv_set_unseen(PurpleConversation *conv, PidginUnseenState state)
int unseen_count = 0;
PidginUnseenState unseen_state = PIDGIN_UNSEEN_NONE;
- if(purple_conversation_get_data(conv, "unseen-count"))
- unseen_count = GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count"));
+ if(g_object_get_data(G_OBJECT(conv), "unseen-count"))
+ unseen_count = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(conv), "unseen-count"));
- if(purple_conversation_get_data(conv, "unseen-state"))
- unseen_state = GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-state"));
+ if(g_object_get_data(G_OBJECT(conv), "unseen-state"))
+ unseen_state = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(conv), "unseen-state"));
if (state == PIDGIN_UNSEEN_NONE)
{
@@ -9076,10 +8998,10 @@ conv_set_unseen(PurpleConversation *conv, PidginUnseenState state)
unseen_state = state;
}
- purple_conversation_set_data(conv, "unseen-count", GINT_TO_POINTER(unseen_count));
- purple_conversation_set_data(conv, "unseen-state", GINT_TO_POINTER(unseen_state));
+ g_object_set_data(G_OBJECT(conv), "unseen-count", GINT_TO_POINTER(unseen_count));
+ g_object_set_data(G_OBJECT(conv), "unseen-state", GINT_TO_POINTER(unseen_state));
- purple_conversation_update(conv, PURPLE_CONV_UPDATE_UNSEEN);
+ purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_UNSEEN);
}
static void
@@ -9099,10 +9021,10 @@ gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state)
gtkconv->unseen_state = state;
}
- purple_conversation_set_data(gtkconv->active_conv, "unseen-count", GINT_TO_POINTER(gtkconv->unseen_count));
- purple_conversation_set_data(gtkconv->active_conv, "unseen-state", GINT_TO_POINTER(gtkconv->unseen_state));
+ g_object_set_data(G_OBJECT(gtkconv->active_conv), "unseen-count", GINT_TO_POINTER(gtkconv->unseen_count));
+ g_object_set_data(G_OBJECT(gtkconv->active_conv), "unseen-state", GINT_TO_POINTER(gtkconv->unseen_state));
- purple_conversation_update(gtkconv->active_conv, PURPLE_CONV_UPDATE_UNSEEN);
+ purple_conversation_update(gtkconv->active_conv, PURPLE_CONVERSATION_UPDATE_UNSEEN);
}
/*
@@ -9560,7 +9482,7 @@ before_switch_conv_cb(GtkNotebook *notebook, GtkWidget *page, gint page_num,
g_return_if_fail(conv != NULL);
- if (purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_IM)
+ if (PURPLE_IS_CHAT_CONVERSATION(conv))
return;
gtkconv = PIDGIN_CONVERSATION(conv);
@@ -9778,14 +9700,14 @@ alias_cb(GtkEntry *entry, gpointer user_data)
account = purple_conversation_get_account(conv);
name = purple_conversation_get_name(conv);
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
PurpleBuddy *buddy;
- buddy = purple_find_buddy(account, name);
+ buddy = purple_blist_find_buddy(account, name);
if (buddy != NULL) {
- purple_blist_alias_buddy(buddy, gtk_entry_get_text(entry));
+ purple_buddy_set_local_alias(buddy, gtk_entry_get_text(entry));
}
serv_alias_buddy(buddy);
- } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
+ } else {
gtk_entry_set_text(GTK_ENTRY(gtkconv->u.chat->topic_text), gtk_entry_get_text(entry));
topic_callback(NULL, gtkconv);
}
@@ -9809,14 +9731,14 @@ infopane_entry_activate(PidginConversation *gtkconv)
return FALSE;
}
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- PurpleBuddy *buddy = purple_find_buddy(purple_conversation_get_account(gtkconv->active_conv), purple_conversation_get_name(gtkconv->active_conv));
+ if (PURPLE_IS_IM_CONVERSATION(conv)) {
+ PurpleBuddy *buddy = purple_blist_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;
text = purple_buddy_get_contact_alias(buddy);
- } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
+ } else {
PurpleConnection *gc;
PurplePluginProtocolInfo *prpl_info = NULL;
@@ -9827,7 +9749,7 @@ infopane_entry_activate(PidginConversation *gtkconv)
/* This protocol doesn't support setting the chat room topic */
return FALSE;
- text = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(conv));
+ text = purple_chat_conversation_get_topic(PURPLE_CHAT_CONVERSATION(conv));
}
/* alias label */
@@ -9904,7 +9826,7 @@ switch_conv_cb(GtkNotebook *notebook, GtkWidget *page, gint page_num,
* We pause icons when they are not visible. If this icon should
* be animated then start it back up again.
*/
- if ((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) &&
+ if (PURPLE_IS_IM_CONVERSATION(conv) &&
(gtkconv->u.im->animate))
start_anim(NULL, gtkconv);
@@ -10293,11 +10215,8 @@ pidgin_conv_window_add_gtkconv(PidginWindow *win, PidginConversation *gtkconv)
PurpleConversation *conv = gtkconv->active_conv;
PidginConversation *focus_gtkconv;
GtkWidget *tab_cont = gtkconv->tab_cont;
- PurpleConversationType conv_type;
const gchar *tmp_lab;
- conv_type = purple_conversation_get_type(conv);
-
win->gtkconvs = g_list_append(win->gtkconvs, gtkconv);
gtkconv->win = win;
@@ -10342,8 +10261,8 @@ pidgin_conv_window_add_gtkconv(PidginWindow *win, PidginConversation *gtkconv)
gtk_widget_show(gtkconv->menu_tabby);
- if (conv_type == PURPLE_CONV_TYPE_IM)
- pidgin_conv_update_buddy_icon(conv);
+ if (PURPLE_IS_IM_CONVERSATION(conv))
+ pidgin_conv_update_buddy_icon(PURPLE_IM_CONVERSATION(conv));
/* Build and set conversations tab */
pidgin_conv_tab_pack(win, gtkconv);
@@ -10581,15 +10500,12 @@ pidgin_conv_window_get_gtkconv_count(PidginWindow *win)
}
PidginWindow *
-pidgin_conv_window_first_with_type(PurpleConversationType type)
+pidgin_conv_window_first_im(void)
{
GList *wins, *convs;
PidginWindow *win;
PidginConversation *conv;
- if (type == PURPLE_CONV_TYPE_UNKNOWN)
- return NULL;
-
for (wins = pidgin_conv_windows_get_list(); wins != NULL; wins = wins->next) {
win = wins->data;
@@ -10599,7 +10515,7 @@ pidgin_conv_window_first_with_type(PurpleConversationType type)
conv = convs->data;
- if (purple_conversation_get_type(conv->active_conv) == type)
+ if (PURPLE_IS_IM_CONVERSATION(conv->active_conv))
return win;
}
}
@@ -10608,14 +10524,62 @@ pidgin_conv_window_first_with_type(PurpleConversationType type)
}
PidginWindow *
-pidgin_conv_window_last_with_type(PurpleConversationType type)
+pidgin_conv_window_last_im(void)
{
GList *wins, *convs;
PidginWindow *win;
PidginConversation *conv;
- if (type == PURPLE_CONV_TYPE_UNKNOWN)
- return NULL;
+ for (wins = g_list_last(pidgin_conv_windows_get_list());
+ wins != NULL;
+ wins = wins->prev) {
+
+ win = wins->data;
+
+ for (convs = win->gtkconvs;
+ convs != NULL;
+ convs = convs->next) {
+
+ conv = convs->data;
+
+ if (PURPLE_IS_IM_CONVERSATION(conv->active_conv))
+ return win;
+ }
+ }
+
+ return NULL;
+}
+
+PidginWindow *
+pidgin_conv_window_first_chat(void)
+{
+ GList *wins, *convs;
+ PidginWindow *win;
+ PidginConversation *conv;
+
+ for (wins = pidgin_conv_windows_get_list(); wins != NULL; wins = wins->next) {
+ win = wins->data;
+
+ for (convs = win->gtkconvs;
+ convs != NULL;
+ convs = convs->next) {
+
+ conv = convs->data;
+
+ if (PURPLE_IS_CHAT_CONVERSATION(conv->active_conv))
+ return win;
+ }
+ }
+
+ return NULL;
+}
+
+PidginWindow *
+pidgin_conv_window_last_chat(void)
+{
+ GList *wins, *convs;
+ PidginWindow *win;
+ PidginConversation *conv;
for (wins = g_list_last(pidgin_conv_windows_get_list());
wins != NULL;
@@ -10629,7 +10593,7 @@ pidgin_conv_window_last_with_type(PurpleConversationType type)
conv = convs->data;
- if (purple_conversation_get_type(conv->active_conv) == type)
+ if (PURPLE_IS_CHAT_CONVERSATION(conv->active_conv))
return win;
}
}
@@ -10680,7 +10644,6 @@ conv_placement_last_created_win_type_configured_cb(GtkWidget *w,
GdkEventConfigure *event, PidginConversation *conv)
{
int x, y;
- PurpleConversationType type = purple_conversation_get_type(conv->active_conv);
GList *all;
if (gtk_widget_get_visible(w))
@@ -10701,18 +10664,18 @@ conv_placement_last_created_win_type_configured_cb(GtkWidget *w,
return FALSE; /* carry on normally */
for (all = conv->convs; all != NULL; all = all->next) {
- if (type != purple_conversation_get_type(all->data)) {
+ if (PURPLE_IS_IM_CONVERSATION(conv->active_conv) != PURPLE_IS_IM_CONVERSATION(all->data)) {
/* this window has different types of conversation, don't save */
return FALSE;
}
}
- if (type == PURPLE_CONV_TYPE_IM) {
+ if (PURPLE_IS_IM_CONVERSATION(conv->active_conv)) {
purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/im/x", x);
purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/im/y", y);
purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/im/width", event->width);
purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/im/height", event->height);
- } else if (type == PURPLE_CONV_TYPE_CHAT) {
+ } else {
purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/chat/x", x);
purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/chat/y", y);
purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/chat/width", event->width);
@@ -10727,19 +10690,22 @@ conv_placement_last_created_win_type(PidginConversation *conv)
{
PidginWindow *win;
- win = pidgin_conv_window_last_with_type(purple_conversation_get_type(conv->active_conv));
+ if (PURPLE_IS_IM_CONVERSATION(conv->active_conv))
+ win = pidgin_conv_window_last_im();
+ else
+ win = pidgin_conv_window_last_chat();
if (win == NULL) {
win = pidgin_conv_window_new();
- if (PURPLE_CONV_TYPE_IM == purple_conversation_get_type(conv->active_conv) ||
+ if (PURPLE_IS_IM_CONVERSATION(conv->active_conv) ||
purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/width") == 0) {
pidgin_conv_set_position_size(win,
purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/x"),
purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/y"),
purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/width"),
purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/height"));
- } else if (PURPLE_CONV_TYPE_CHAT == purple_conversation_get_type(conv->active_conv)) {
+ } else if (PURPLE_IS_CHAT_CONVERSATION(conv->active_conv)) {
pidgin_conv_set_position_size(win,
purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/x"),
purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/y"),
@@ -10777,16 +10743,16 @@ conv_get_group(PidginConversation *conv)
{
PurpleGroup *group = NULL;
- if (purple_conversation_get_type(conv->active_conv) == PURPLE_CONV_TYPE_IM) {
+ if (PURPLE_IS_IM_CONVERSATION(conv->active_conv)) {
PurpleBuddy *buddy;
- buddy = purple_find_buddy(purple_conversation_get_account(conv->active_conv),
+ buddy = purple_blist_find_buddy(purple_conversation_get_account(conv->active_conv),
purple_conversation_get_name(conv->active_conv));
if (buddy != NULL)
group = purple_buddy_get_group(buddy);
- } else if (purple_conversation_get_type(conv->active_conv) == PURPLE_CONV_TYPE_CHAT) {
+ } else {
PurpleChat *chat;
chat = purple_blist_find_chat(purple_conversation_get_account(conv->active_conv),
diff --git a/pidgin/gtkconv.h b/pidgin/gtkconv.h
index f82eb7fc58..94d09bca4e 100644
--- a/pidgin/gtkconv.h
+++ b/pidgin/gtkconv.h
@@ -178,7 +178,7 @@ PurpleTheme *pidgin_conversations_get_default_theme(void);
*
* @param conv The conversation.
*/
-void pidgin_conv_update_buddy_icon(PurpleConversation *conv);
+void pidgin_conv_update_buddy_icon(PurpleIMConversation *im);
/**
* Sets the active conversation within a GTK-conversation.
@@ -195,14 +195,13 @@ void pidgin_conv_switch_active_conversation(PurpleConversation *conv);
void pidgin_conv_update_buttons_by_protocol(PurpleConversation *conv);
/**
- * Returns a list of conversations of the given type which have an unseen
+ * Returns a list of conversations of any type which have an unseen
* state greater than or equal to the specified minimum state. Using the
* hidden_only parameter, this search can be limited to hidden
* conversations. The max_count parameter will limit the total number of
* converations returned if greater than zero. The returned list should
* be freed by the caller.
*
- * @param type The type of conversation.
* @param min_state The minimum unseen state.
* @param hidden_only If TRUE, only consider hidden conversations.
* @param max_count Maximum number of conversations to return, or 0 for
@@ -210,8 +209,47 @@ void pidgin_conv_update_buttons_by_protocol(PurpleConversation *conv);
* @return List of PurpleConversation matching criteria, or NULL.
*/
GList *
-pidgin_conversations_find_unseen_list(PurpleConversationType type,
- PidginUnseenState min_state,
+pidgin_conversations_get_unseen_all(PidginUnseenState min_state,
+ gboolean hidden_only,
+ guint max_count);
+
+/**
+ * Returns a list of IM conversations which have an unseen state greater
+ * than or equal to the specified minimum state. Using the hidden_only
+ * parameter, this search can be limited to hidden IM conversations. The
+ * max_count parameter will limit the total number of IM converations
+ * returned if greater than zero. The returned list should be freed by the
+ * caller.
+ *
+ * @param min_state The minimum unseen state.
+ * @param hidden_only If TRUE, only consider hidden conversations.
+ * @param max_count Maximum number of conversations to return, or 0 for
+ * no maximum.
+ * @return List of PurpleIMConversation matching criteria,
+ * or NULL.
+ */
+GList *
+pidgin_conversations_get_unseen_ims(PidginUnseenState min_state,
+ gboolean hidden_only,
+ guint max_count);
+
+/**
+ * Returns a list of chat conversations which have an unseen state greater
+ * than or equal to the specified minimum state. Using the hidden_only
+ * parameter, this search can be limited to hidden chat conversations. The
+ * max_count parameter will limit the total number of chat converations
+ * returned if greater than zero. The returned list should be freed by the
+ * caller.
+ *
+ * @param min_state The minimum unseen state.
+ * @param hidden_only If TRUE, only consider hidden conversations.
+ * @param max_count Maximum number of conversations to return, or 0 for
+ * no maximum.
+ * @return List of PurpleChatConversation matching criteria,
+ * or NULL.
+ */
+GList *
+pidgin_conversations_get_unseen_chats(PidginUnseenState min_state,
gboolean hidden_only,
guint max_count);
diff --git a/pidgin/gtkconvwin.h b/pidgin/gtkconvwin.h
index 078c47f3ae..6b192cbcba 100644
--- a/pidgin/gtkconvwin.h
+++ b/pidgin/gtkconvwin.h
@@ -123,8 +123,10 @@ PidginWindow *pidgin_conv_window_get_at_event(GdkEvent *event);
GList *pidgin_conv_window_get_gtkconvs(PidginWindow *win);
guint pidgin_conv_window_get_gtkconv_count(PidginWindow *win);
-PidginWindow *pidgin_conv_window_first_with_type(PurpleConversationType type);
-PidginWindow *pidgin_conv_window_last_with_type(PurpleConversationType type);
+PidginWindow *pidgin_conv_window_first_im(void);
+PidginWindow *pidgin_conv_window_last_im(void);
+PidginWindow *pidgin_conv_window_first_chat(void);
+PidginWindow *pidgin_conv_window_last_chat(void);
/*@}*/
diff --git a/pidgin/gtkdialogs.c b/pidgin/gtkdialogs.c
index afac1a3d3c..d175f34577 100644
--- a/pidgin/gtkdialogs.c
+++ b/pidgin/gtkdialogs.c
@@ -938,7 +938,7 @@ pidgin_dialogs_im(void)
purple_request_field_set_required(field, TRUE);
purple_request_field_group_add_field(group, field);
- purple_request_fields(purple_get_blist(), _("New Instant Message"),
+ purple_request_fields(purple_blist_get_buddy_list(), _("New Instant Message"),
NULL,
_("Please enter the username or alias of the person "
"you would like to IM."),
@@ -952,18 +952,18 @@ pidgin_dialogs_im(void)
void
pidgin_dialogs_im_with_user(PurpleAccount *account, const char *username)
{
- PurpleConversation *conv;
+ PurpleIMConversation *im;
g_return_if_fail(account != NULL);
g_return_if_fail(username != NULL);
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, username, account);
+ im = purple_conversations_find_im_with_account(username, account);
- if (conv == NULL)
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, username);
+ if (im == NULL)
+ im = purple_im_conversation_new(account, username);
- pidgin_conv_attach_to_conversation(conv);
- purple_conversation_present(conv);
+ pidgin_conv_attach_to_conversation(PURPLE_CONVERSATION(im));
+ purple_conversation_present(PURPLE_CONVERSATION(im));
}
static gboolean
@@ -1078,7 +1078,7 @@ pidgin_dialogs_info(void)
purple_request_field_set_required(field, TRUE);
purple_request_field_group_add_field(group, field);
- purple_request_fields(purple_get_blist(), _("Get User Info"),
+ purple_request_fields(purple_blist_get_buddy_list(), _("Get User Info"),
NULL,
_("Please enter the username or alias of the person "
"whose info you would like to view."),
@@ -1108,7 +1108,7 @@ pidgin_dialogs_log_cb(gpointer data, PurpleRequestFields *fields)
pidgin_set_cursor(gtkblist->window, GDK_WATCH);
- buddies = purple_find_buddies(account, username);
+ buddies = purple_blist_find_buddies(account, username);
for (cur = buddies; cur != NULL; cur = cur->next)
{
PurpleBlistNode *node = cur->data;
@@ -1170,7 +1170,7 @@ pidgin_dialogs_log(void)
purple_request_field_set_required(field, TRUE);
purple_request_field_group_add_field(group, field);
- purple_request_fields(purple_get_blist(), _("View User Log"),
+ purple_request_fields(purple_blist_get_buddy_list(), _("View User Log"),
NULL,
_("Please enter the username or alias of the person "
"whose log you would like to view."),
@@ -1184,7 +1184,7 @@ pidgin_dialogs_log(void)
static void
pidgin_dialogs_alias_buddy_cb(PurpleBuddy *buddy, const char *new_alias)
{
- purple_blist_alias_buddy(buddy, new_alias);
+ purple_buddy_set_local_alias(buddy, new_alias);
serv_alias_buddy(buddy);
}
@@ -1198,7 +1198,7 @@ pidgin_dialogs_alias_buddy(PurpleBuddy *buddy)
secondary = g_strdup_printf(_("Enter an alias for %s."), purple_buddy_get_name(buddy));
purple_request_input(NULL, _("Alias Buddy"), NULL,
- secondary, purple_buddy_get_local_buddy_alias(buddy), FALSE, FALSE, NULL,
+ secondary, purple_buddy_get_local_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,
@@ -1210,17 +1210,21 @@ pidgin_dialogs_alias_buddy(PurpleBuddy *buddy)
static void
pidgin_dialogs_alias_chat_cb(PurpleChat *chat, const char *new_alias)
{
- purple_blist_alias_chat(chat, new_alias);
+ purple_chat_set_alias(chat, new_alias);
}
void
pidgin_dialogs_alias_chat(PurpleChat *chat)
{
+ gchar *alias;
+
g_return_if_fail(chat != NULL);
+ g_object_get(chat, "alias", &alias, NULL);
+
purple_request_input(NULL, _("Alias Chat"), NULL,
_("Enter an alias for this chat."),
- chat->alias, FALSE, FALSE, NULL,
+ alias, FALSE, FALSE, NULL,
_("Alias"), G_CALLBACK(pidgin_dialogs_alias_chat_cb),
_("Cancel"), NULL,
purple_chat_get_account(chat), NULL, NULL,
@@ -1256,6 +1260,7 @@ pidgin_dialogs_remove_contact(PurpleContact *contact)
pidgin_dialogs_remove_buddy(buddy);
} else {
gchar *text;
+ int contact_size = purple_counting_node_get_total_size(PURPLE_COUNTING_NODE(contact));
text = g_strdup_printf(
ngettext(
"You are about to remove the contact containing %s "
@@ -1263,8 +1268,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?", purple_contact_get_contact_size(contact, TRUE) - 1),
- purple_buddy_get_name(buddy), purple_contact_get_contact_size(contact, TRUE) - 1);
+ "want to continue?", contact_size - 1),
+ purple_buddy_get_name(buddy), contact_size - 1);
purple_request_action(contact, NULL, _("Remove Contact"), text, 0,
NULL, purple_contact_get_alias(contact), NULL,
@@ -1286,7 +1291,7 @@ static void free_ggmo(struct _PidginGroupMergeObject *ggp)
static void
pidgin_dialogs_merge_groups_cb(struct _PidginGroupMergeObject *GGP)
{
- purple_blist_rename_group(GGP->parent, GGP->new_name);
+ purple_group_set_name(GGP->parent, GGP->new_name);
free_ggmo(GGP);
}
@@ -1324,12 +1329,12 @@ pidgin_dialogs_remove_group_cb(PurpleGroup *group)
cnode = ((PurpleBlistNode*)group)->child;
while (cnode) {
- if (PURPLE_BLIST_NODE_IS_CONTACT(cnode)) {
+ if (PURPLE_IS_CONTACT(cnode)) {
bnode = cnode->child;
cnode = cnode->next;
while (bnode) {
PurpleBuddy *buddy;
- if (PURPLE_BLIST_NODE_IS_BUDDY(bnode)) {
+ if (PURPLE_IS_BUDDY(bnode)) {
buddy = (PurpleBuddy*)bnode;
bnode = bnode->next;
if (purple_account_is_connected(purple_buddy_get_account(buddy))) {
@@ -1340,7 +1345,7 @@ pidgin_dialogs_remove_group_cb(PurpleGroup *group)
bnode = bnode->next;
}
}
- } else if (PURPLE_BLIST_NODE_IS_CHAT(cnode)) {
+ } else if (PURPLE_IS_CHAT(cnode)) {
PurpleChat *chat = (PurpleChat *)cnode;
cnode = cnode->next;
if (purple_account_is_connected(purple_chat_get_account(chat)))
diff --git a/pidgin/gtkdocklet.c b/pidgin/gtkdocklet.c
index e5ec27b0d8..5033cab1d8 100644
--- a/pidgin/gtkdocklet.c
+++ b/pidgin/gtkdocklet.c
@@ -132,15 +132,13 @@ get_pending_list(guint max)
{
GList *l_im, *l_chat;
- l_im = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_IM,
- PIDGIN_UNSEEN_TEXT,
- FALSE, max);
+ l_im = pidgin_conversations_get_unseen_ims(PIDGIN_UNSEEN_TEXT, FALSE, max);
/* Short circuit if we have our information already */
if (max == 1 && l_im != NULL)
return l_im;
- l_chat = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_CHAT,
+ l_chat = pidgin_conversations_get_unseen_chats(
purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/notification_chat"),
FALSE, max);
@@ -202,8 +200,8 @@ docklet_update_status(void)
} 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")),
+ GPOINTER_TO_INT(g_object_get_data(G_OBJECT(conv), "unseen-count"))),
+ GPOINTER_TO_INT(g_object_get_data(G_OBJECT(conv), "unseen-count")),
purple_conversation_get_title(conv));
}
}
@@ -289,9 +287,9 @@ docklet_update_status_cb(void *data)
}
static void
-docklet_conv_updated_cb(PurpleConversation *conv, PurpleConvUpdateType type)
+docklet_conv_updated_cb(PurpleConversation *conv, PurpleConversationUpdateType type)
{
- if (type == PURPLE_CONV_UPDATE_UNSEEN)
+ if (type == PURPLE_CONVERSATION_UPDATE_UNSEEN)
docklet_update_status();
}
diff --git a/pidgin/gtkimhtml.c b/pidgin/gtkimhtml.c
index 40288e62cd..0599c456cf 100644
--- a/pidgin/gtkimhtml.c
+++ b/pidgin/gtkimhtml.c
@@ -5713,20 +5713,20 @@ void gtk_imhtml_setup_entry(GtkIMHtml *imhtml, PurpleConnectionFlags flags)
{
GtkIMHtmlButtons buttons;
- if (flags & PURPLE_CONNECTION_HTML) {
+ if (flags & PURPLE_CONNECTION_FLAG_HTML) {
char color[8];
GdkColor fg_color, bg_color;
buttons = GTK_IMHTML_ALL;
- if (flags & PURPLE_CONNECTION_NO_BGCOLOR)
+ if (flags & PURPLE_CONNECTION_FLAG_NO_BGCOLOR)
buttons &= ~GTK_IMHTML_BACKCOLOR;
- if (flags & PURPLE_CONNECTION_NO_FONTSIZE)
+ if (flags & PURPLE_CONNECTION_FLAG_NO_FONTSIZE)
{
buttons &= ~GTK_IMHTML_GROW;
buttons &= ~GTK_IMHTML_SHRINK;
}
- if (flags & PURPLE_CONNECTION_NO_URLDESC)
+ if (flags & PURPLE_CONNECTION_FLAG_NO_URLDESC)
buttons &= ~GTK_IMHTML_LINKDESC;
gtk_imhtml_set_format_functions(imhtml, GTK_IMHTML_ALL);
@@ -5742,7 +5742,7 @@ void gtk_imhtml_setup_entry(GtkIMHtml *imhtml, PurpleConnectionFlags flags)
gtk_imhtml_toggle_fontface(imhtml,
purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/font_face"));
- if (!(flags & PURPLE_CONNECTION_NO_FONTSIZE))
+ if (!(flags & PURPLE_CONNECTION_FLAG_NO_FONTSIZE))
{
int size = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/font_size");
@@ -5764,7 +5764,7 @@ void gtk_imhtml_setup_entry(GtkIMHtml *imhtml, PurpleConnectionFlags flags)
gtk_imhtml_toggle_forecolor(imhtml, color);
- if(!(flags & PURPLE_CONNECTION_NO_BGCOLOR) &&
+ if(!(flags & PURPLE_CONNECTION_FLAG_NO_BGCOLOR) &&
strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor"), "") != 0)
{
gdk_color_parse(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor"),
@@ -5778,7 +5778,7 @@ void gtk_imhtml_setup_entry(GtkIMHtml *imhtml, PurpleConnectionFlags flags)
gtk_imhtml_toggle_background(imhtml, color);
- if (flags & PURPLE_CONNECTION_FORMATTING_WBFO)
+ if (flags & PURPLE_CONNECTION_FLAG_FORMATTING_WBFO)
gtk_imhtml_set_whole_buffer_formatting_only(imhtml, TRUE);
else
gtk_imhtml_set_whole_buffer_formatting_only(imhtml, FALSE);
@@ -5787,10 +5787,10 @@ void gtk_imhtml_setup_entry(GtkIMHtml *imhtml, PurpleConnectionFlags flags)
imhtml_clear_formatting(imhtml);
}
- if (flags & PURPLE_CONNECTION_NO_IMAGES)
+ if (flags & PURPLE_CONNECTION_FLAG_NO_IMAGES)
buttons &= ~GTK_IMHTML_IMAGE;
- if (flags & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)
+ if (flags & PURPLE_CONNECTION_FLAG_ALLOW_CUSTOM_SMILEY)
buttons |= GTK_IMHTML_CUSTOM_SMILEY;
else
buttons &= ~GTK_IMHTML_CUSTOM_SMILEY;
diff --git a/pidgin/gtkimhtmltoolbar.c b/pidgin/gtkimhtmltoolbar.c
index 5e7cf1bb19..6f6bdf167e 100644
--- a/pidgin/gtkimhtmltoolbar.c
+++ b/pidgin/gtkimhtmltoolbar.c
@@ -1600,7 +1600,7 @@ void gtk_imhtmltoolbar_switch_active_conversation(GtkIMHtmlToolbar *toolbar,
/* 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(toolbar->attention,
- conv && prpl && purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM &&
+ conv && prpl && PURPLE_IS_IM_CONVERSATION(conv) &&
PURPLE_PLUGIN_PROTOCOL_INFO(prpl)->send_attention != NULL);
}
diff --git a/pidgin/gtklog.c b/pidgin/gtklog.c
index 3872340b7e..ae03abc897 100644
--- a/pidgin/gtklog.c
+++ b/pidgin/gtklog.c
@@ -282,7 +282,7 @@ static void log_delete_log_cb(GtkWidget *menuitem, gpointer *data)
if (log->type == PURPLE_LOG_IM)
{
- PurpleBuddy *buddy = purple_find_buddy(log->account, log->name);
+ PurpleBuddy *buddy = purple_blist_find_buddy(log->account, log->name);
if (buddy != NULL)
name = purple_buddy_get_contact_alias(buddy);
else
@@ -720,7 +720,7 @@ void pidgin_log_show(PurpleLogType type, const char *buddyname, PurpleAccount *a
} else {
PurpleBuddy *buddy;
- buddy = purple_find_buddy(account, buddyname);
+ buddy = purple_blist_find_buddy(account, buddyname);
if (buddy != NULL)
name = purple_buddy_get_contact_alias(buddy);
@@ -769,7 +769,7 @@ void pidgin_log_show_contact(PurpleContact *contact) {
const char *buddy_name;
PurpleAccount *account;
- if (!PURPLE_BLIST_NODE_IS_BUDDY(child))
+ if (!PURPLE_IS_BUDDY(child))
continue;
buddy_name = purple_buddy_get_name((PurpleBuddy *)child);
@@ -790,17 +790,16 @@ void pidgin_log_show_contact(PurpleContact *contact) {
image = NULL;
}
- if (contact->alias != NULL)
- name = contact->alias;
- else if (contact->priority != NULL)
- name = purple_buddy_get_contact_alias(contact->priority);
+ name = purple_contact_get_alias(contact);
/* This will happen if the contact doesn't have an alias,
* and none of the contact's buddies are online.
* There is probably a better way to deal with this. */
if (name == NULL) {
- if (contact->node.child != NULL && PURPLE_BLIST_NODE_IS_BUDDY(contact->node.child))
- name = purple_buddy_get_contact_alias((PurpleBuddy *) contact->node.child);
+ if (PURPLE_BLIST_NODE(contact)->child != NULL &&
+ PURPLE_IS_BUDDY(PURPLE_BLIST_NODE(contact)->child))
+ name = purple_buddy_get_contact_alias(PURPLE_BUDDY(
+ PURPLE_BLIST_NODE(contact)->child));
if (name == NULL)
name = "";
}
@@ -851,11 +850,9 @@ void pidgin_log_init(void)
purple_signal_register(handle, "log-displaying",
purple_marshal_VOID__POINTER_POINTER,
- NULL, 2,
- purple_value_new(PURPLE_TYPE_BOXED,
- "PidginLogViewer *"),
- purple_value_new(PURPLE_TYPE_SUBTYPE,
- PURPLE_SUBTYPE_LOG));
+ G_TYPE_NONE, 2,
+ G_TYPE_POINTER, /* (PidginLogViewer *) */
+ PURPLE_TYPE_LOG);
}
void
diff --git a/pidgin/gtkmain.c b/pidgin/gtkmain.c
index 76b9a54e14..f1b8658bd7 100644
--- a/pidgin/gtkmain.c
+++ b/pidgin/gtkmain.c
@@ -265,7 +265,6 @@ pidgin_ui_init(void)
purple_xfers_set_ui_ops(pidgin_xfers_get_ui_ops());
purple_blist_set_ui_ops(pidgin_blist_get_ui_ops());
purple_notify_set_ui_ops(pidgin_notify_get_ui_ops());
- purple_privacy_set_ui_ops(pidgin_privacy_get_ui_ops());
purple_request_set_ui_ops(pidgin_request_get_ui_ops());
purple_sound_set_ui_ops(pidgin_sound_get_ui_ops());
purple_connections_set_ui_ops(pidgin_connections_get_ui_ops());
@@ -274,7 +273,7 @@ pidgin_ui_init(void)
purple_idle_set_ui_ops(pidgin_idle_get_ui_ops());
#endif
- pidgin_account_init();
+ pidgin_accounts_init();
pidgin_connection_init();
pidgin_blist_init();
pidgin_status_init();
@@ -310,7 +309,7 @@ pidgin_quit(void)
pidgin_docklet_uninit();
pidgin_blist_uninit();
pidgin_connection_uninit();
- pidgin_account_uninit();
+ pidgin_accounts_uninit();
pidgin_xfers_uninit();
pidgin_debug_uninit();
diff --git a/pidgin/gtkmedia.c b/pidgin/gtkmedia.c
index 468f01dd8c..5aa574e351 100644
--- a/pidgin/gtkmedia.c
+++ b/pidgin/gtkmedia.c
@@ -522,8 +522,8 @@ pidgin_media_finalize(GObject *media)
static void
pidgin_media_emit_message(PidginMedia *gtkmedia, const char *msg)
{
- PurpleConversation *conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_ANY, gtkmedia->priv->screenname,
+ PurpleConversation *conv = purple_conversations_find_with_account(
+ gtkmedia->priv->screenname,
purple_media_get_account(gtkmedia->priv->media));
if (conv != NULL)
purple_conversation_write(conv, NULL, msg,
@@ -595,8 +595,8 @@ realize_cb(GtkWidget *widget, PidginMediaRealizeData *data)
static void
pidgin_media_error_cb(PidginMedia *media, const char *error, PidginMedia *gtkmedia)
{
- PurpleConversation *conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_ANY, gtkmedia->priv->screenname,
+ PurpleConversation *conv = purple_conversations_find_with_account(
+ gtkmedia->priv->screenname,
purple_media_get_account(gtkmedia->priv->media));
if (conv != NULL)
purple_conversation_write(conv, NULL, error,
@@ -637,7 +637,7 @@ pidgin_request_timeout_cb(PidginMedia *gtkmedia)
gchar *message = NULL;
account = purple_media_get_account(gtkmedia->priv->media);
- buddy = purple_find_buddy(account, gtkmedia->priv->screenname);
+ buddy = purple_blist_find_buddy(account, gtkmedia->priv->screenname);
alias = buddy ? purple_buddy_get_contact_alias(buddy) :
gtkmedia->priv->screenname;
type = gtkmedia->priv->request_type;
@@ -1045,7 +1045,7 @@ pidgin_media_new_cb(PurpleMediaManager *manager, PurpleMedia *media,
{
PidginMedia *gtkmedia = PIDGIN_MEDIA(
pidgin_media_new(media, screenname));
- PurpleBuddy *buddy = purple_find_buddy(account, screenname);
+ PurpleBuddy *buddy = purple_blist_find_buddy(account, screenname);
const gchar *alias = buddy ?
purple_buddy_get_contact_alias(buddy) : screenname;
gtk_window_set_title(GTK_WINDOW(gtkmedia), alias);
diff --git a/pidgin/gtknotify.c b/pidgin/gtknotify.c
index 14b18764e9..0406352728 100644
--- a/pidgin/gtknotify.c
+++ b/pidgin/gtknotify.c
@@ -192,11 +192,10 @@ open_im_foreach(GtkTreeModel *model, GtkTreePath *path,
-1);
if (pounce_data != NULL) {
- PurpleConversation *conv;
+ PurpleIMConversation *im;
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM,
- pounce_data->account, pounce_data->pouncee);
- purple_conversation_present(conv);
+ im = purple_im_conversation_new(pounce_data->account, pounce_data->pouncee);
+ purple_conversation_present(PURPLE_CONVERSATION(im));
}
}
diff --git a/pidgin/gtkpounce.c b/pidgin/gtkpounce.c
index 8a308fc047..2f53345e8c 100644
--- a/pidgin/gtkpounce.c
+++ b/pidgin/gtkpounce.c
@@ -435,9 +435,9 @@ pounce_dnd_recv(GtkWidget *widget, GdkDragContext *dc, gint x, gint y,
memcpy(&node, sd_data, sizeof(node));
- if (PURPLE_BLIST_NODE_IS_CONTACT(node))
+ if (PURPLE_IS_CONTACT(node))
buddy = purple_contact_get_priority_buddy((PurpleContact *)node);
- else if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ else if (PURPLE_IS_BUDDY(node))
buddy = (PurpleBuddy *)node;
else
return;
@@ -493,7 +493,7 @@ reset_send_msg_entry(PidginPounceDialog *dialog, GtkWidget *dontcare)
{
PurpleAccount *account = pidgin_account_option_menu_get_selected(dialog->account_menu);
gtk_webview_setup_entry(GTK_WEBVIEW(dialog->send_msg_entry),
- (account && purple_account_get_connection(account)) ? purple_connection_get_flags(purple_account_get_connection(account)) : PURPLE_CONNECTION_HTML);
+ (account && purple_account_get_connection(account)) ? purple_connection_get_flags(purple_account_get_connection(account)) : PURPLE_CONNECTION_FLAG_HTML);
}
void
@@ -974,7 +974,7 @@ pidgin_pounce_editor_show(PurpleAccount *account, const char *name,
PurpleBuddy *buddy = NULL;
if (name != NULL)
- buddy = purple_find_buddy(account, name);
+ buddy = purple_blist_find_buddy(account, name);
/* Set some defaults */
if (buddy == NULL)
@@ -1412,7 +1412,7 @@ pidgin_pounces_manager_hide(void)
static void
pounce_cb(PurplePounce *pounce, PurplePounceEvent events, void *data)
{
- PurpleConversation *conv;
+ PurpleIMConversation *im;
PurpleAccount *account;
PurpleBuddy *buddy;
const char *pouncee;
@@ -1421,7 +1421,7 @@ pounce_cb(PurplePounce *pounce, PurplePounceEvent events, void *data)
pouncee = purple_pounce_get_pouncee(pounce);
account = purple_pounce_get_pouncer(pounce);
- buddy = purple_find_buddy(account, pouncee);
+ buddy = purple_blist_find_buddy(account, pouncee);
if (buddy != NULL)
{
alias = purple_buddy_get_alias(buddy);
@@ -1433,8 +1433,8 @@ pounce_cb(PurplePounce *pounce, PurplePounceEvent events, void *data)
if (purple_pounce_action_is_enabled(pounce, "open-window"))
{
- if (!purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, pouncee, account))
- purple_conversation_new(PURPLE_CONV_TYPE_IM, account, pouncee);
+ if (!purple_conversations_find_im_with_account(pouncee, account))
+ purple_im_conversation_new(account, pouncee);
}
if (purple_pounce_action_is_enabled(pounce, "popup-notify"))
@@ -1487,12 +1487,12 @@ pounce_cb(PurplePounce *pounce, PurplePounceEvent events, void *data)
if (message != NULL)
{
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, pouncee, account);
+ im = purple_conversations_find_im_with_account(pouncee, account);
- if (conv == NULL)
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, pouncee);
+ if (im == NULL)
+ im = purple_im_conversation_new(account, pouncee);
- purple_conversation_write(conv, NULL, message,
+ purple_conversation_write(PURPLE_CONVERSATION(im), NULL, message,
PURPLE_MESSAGE_SEND, time(NULL));
serv_send_im(purple_account_get_connection(account), (char *)pouncee, (char *)message, 0);
diff --git a/pidgin/gtkprefs.c b/pidgin/gtkprefs.c
index 556e6ad53e..afdbcb0d17 100644
--- a/pidgin/gtkprefs.c
+++ b/pidgin/gtkprefs.c
@@ -1395,7 +1395,7 @@ prefs_set_status_icon_theme_cb(GtkComboBox *combo_box, gpointer user_data)
g_free(name);
pidgin_stock_load_status_icon_theme(theme);
- pidgin_blist_refresh(purple_get_blist());
+ pidgin_blist_refresh(purple_blist_get_buddy_list());
}
}
@@ -1957,8 +1957,8 @@ conv_page(void)
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
gtk_webview_setup_entry(GTK_WEBVIEW(webview),
- PURPLE_CONNECTION_HTML |
- PURPLE_CONNECTION_FORMATTING_WBFO);
+ PURPLE_CONNECTION_FLAG_HTML |
+ PURPLE_CONNECTION_FLAG_FORMATTING_WBFO);
g_signal_connect_after(G_OBJECT(webview), "format-toggled",
G_CALLBACK(formatting_toggle_cb), NULL);
diff --git a/pidgin/gtkprivacy.c b/pidgin/gtkprivacy.c
index 9455b4a7f9..a6cc03232d 100644
--- a/pidgin/gtkprivacy.c
+++ b/pidgin/gtkprivacy.c
@@ -28,7 +28,6 @@
#include "connection.h"
#include "debug.h"
-#include "privacy.h"
#include "request.h"
#include "util.h"
@@ -80,17 +79,20 @@ static struct
} const menu_entries[] =
{
- { N_("Allow all users to contact me"), PURPLE_PRIVACY_ALLOW_ALL },
- { N_("Allow only the users on my buddy list"), PURPLE_PRIVACY_ALLOW_BUDDYLIST },
- { N_("Allow only the users below"), PURPLE_PRIVACY_ALLOW_USERS },
- { N_("Block all users"), PURPLE_PRIVACY_DENY_ALL },
- { N_("Block only the users below"), PURPLE_PRIVACY_DENY_USERS }
+ { N_("Allow all users to contact me"), PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL },
+ { N_("Allow only the users on my buddy list"), PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST },
+ { N_("Allow only the users below"), PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS },
+ { N_("Block all users"), PURPLE_ACCOUNT_PRIVACY_DENY_ALL },
+ { N_("Block only the users below"), PURPLE_ACCOUNT_PRIVACY_DENY_USERS }
};
static const size_t menu_entry_count = sizeof(menu_entries) / sizeof(*menu_entries);
static PidginPrivacyDialog *privacy_dialog = NULL;
+void pidgin_permit_added_removed(PurpleAccount *account, const char *name);
+void pidgin_deny_added_removed(PurpleAccount *account, const char *name);
+
static void
rebuild_allow_list(PidginPrivacyDialog *dialog)
{
@@ -99,7 +101,7 @@ rebuild_allow_list(PidginPrivacyDialog *dialog)
gtk_list_store_clear(dialog->allow_store);
- for (l = dialog->account->permit; l != NULL; l = l->next) {
+ for (l = purple_account_privacy_get_permitted(dialog->account); l != NULL; l = l->next) {
gtk_list_store_append(dialog->allow_store, &iter);
gtk_list_store_set(dialog->allow_store, &iter, 0, l->data, -1);
}
@@ -113,7 +115,7 @@ rebuild_block_list(PidginPrivacyDialog *dialog)
gtk_list_store_clear(dialog->block_store);
- for (l = dialog->account->deny; l != NULL; l = l->next) {
+ for (l = purple_account_privacy_get_denied(dialog->account); l != NULL; l = l->next) {
gtk_list_store_append(dialog->block_store, &iter);
gtk_list_store_set(dialog->block_store, &iter, 0, l->data, -1);
}
@@ -239,12 +241,12 @@ type_changed_cb(GtkComboBox *combo, PidginPrivacyDialog *dialog)
gtk_widget_hide(dialog->block_widget);
gtk_widget_hide(dialog->button_box);
- if (new_type == PURPLE_PRIVACY_ALLOW_USERS) {
+ if (new_type == PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS) {
gtk_widget_show(dialog->allow_widget);
gtk_widget_show_all(dialog->button_box);
dialog->in_allow_list = TRUE;
}
- else if (new_type == PURPLE_PRIVACY_DENY_USERS) {
+ else if (new_type == PURPLE_ACCOUNT_PRIVACY_DENY_USERS) {
gtk_widget_show(dialog->block_widget);
gtk_widget_show_all(dialog->button_box);
dialog->in_allow_list = FALSE;
@@ -254,7 +256,7 @@ type_changed_cb(GtkComboBox *combo, PidginPrivacyDialog *dialog)
gtk_widget_show(dialog->button_box);
purple_blist_schedule_save();
- pidgin_blist_refresh(purple_get_blist());
+ pidgin_blist_refresh(purple_blist_get_buddy_list());
}
static void
@@ -295,9 +297,9 @@ remove_cb(GtkWidget *button, PidginPrivacyDialog *dialog)
return;
if (dialog->in_allow_list)
- purple_privacy_permit_remove(dialog->account, name, FALSE);
+ purple_account_privacy_permit_remove(dialog->account, name, FALSE);
else
- purple_privacy_deny_remove(dialog->account, name, FALSE);
+ purple_account_privacy_deny_remove(dialog->account, name, FALSE);
g_free(name);
}
@@ -307,17 +309,17 @@ removeall_cb(GtkWidget *button, PidginPrivacyDialog *dialog)
{
GSList *l;
if (dialog->in_allow_list)
- l = dialog->account->permit;
+ l = purple_account_privacy_get_permitted(dialog->account);
else
- l = dialog->account->deny;
+ l = purple_account_privacy_get_denied(dialog->account);
while (l) {
char *user;
user = l->data;
l = l->next;
if (dialog->in_allow_list)
- purple_privacy_permit_remove(dialog->account, user, FALSE);
+ purple_account_privacy_permit_remove(dialog->account, user, FALSE);
else
- purple_privacy_deny_remove(dialog->account, user, FALSE);
+ purple_account_privacy_deny_remove(dialog->account, user, FALSE);
}
}
@@ -413,12 +415,12 @@ privacy_dialog_new(void)
type_changed_cb(GTK_COMBO_BOX(dialog->type_menu), dialog);
#if 0
- if (purple_account_get_privacy_type(dialog->account) == PURPLE_PRIVACY_ALLOW_USERS) {
+ if (purple_account_get_privacy_type(dialog->account) == PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS) {
gtk_widget_show(dialog->allow_widget);
gtk_widget_show(dialog->button_box);
dialog->in_allow_list = TRUE;
}
- else if (purple_account_get_privacy_type(dialog->account) == PURPLE_PRIVACY_DENY_USERS) {
+ else if (purple_account_get_privacy_type(dialog->account) == PURPLE_ACCOUNT_PRIVACY_DENY_USERS) {
gtk_widget_show(dialog->block_widget);
gtk_widget_show(dialog->button_box);
dialog->in_allow_list = FALSE;
@@ -462,9 +464,9 @@ static void
confirm_permit_block_cb(PidginPrivacyRequestData *data, int option)
{
if (data->block)
- purple_privacy_deny(data->account, data->name, FALSE, FALSE);
+ purple_account_privacy_deny(data->account, data->name);
else
- purple_privacy_allow(data->account, data->name, FALSE, FALSE);
+ purple_account_privacy_allow(data->account, data->name);
destroy_request_data(data);
}
@@ -558,38 +560,20 @@ pidgin_request_add_block(PurpleAccount *account, const char *name)
}
}
-static void
+void
pidgin_permit_added_removed(PurpleAccount *account, const char *name)
{
if (privacy_dialog != NULL)
rebuild_allow_list(privacy_dialog);
}
-static void
+void
pidgin_deny_added_removed(PurpleAccount *account, const char *name)
{
if (privacy_dialog != NULL)
rebuild_block_list(privacy_dialog);
}
-static PurplePrivacyUiOps privacy_ops =
-{
- pidgin_permit_added_removed,
- pidgin_permit_added_removed,
- pidgin_deny_added_removed,
- pidgin_deny_added_removed,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-PurplePrivacyUiOps *
-pidgin_privacy_get_ui_ops(void)
-{
- return &privacy_ops;
-}
-
void
pidgin_privacy_init(void)
{
diff --git a/pidgin/gtkprivacy.h b/pidgin/gtkprivacy.h
index 6ee81a4745..ebc6962371 100644
--- a/pidgin/gtkprivacy.h
+++ b/pidgin/gtkprivacy.h
@@ -26,7 +26,7 @@
#ifndef _PIDGINPRIVACY_H_
#define _PIDGINPRIVACY_H_
-#include "privacy.h"
+#include "account.h"
G_BEGIN_DECLS
@@ -67,13 +67,6 @@ void pidgin_request_add_permit(PurpleAccount *account, const char *name);
*/
void pidgin_request_add_block(PurpleAccount *account, const char *name);
-/**
- * Returns the UI operations structure for the GTK+ privacy subsystem.
- *
- * @return The GTK+ UI privacy operations structure.
- */
-PurplePrivacyUiOps *pidgin_privacy_get_ui_ops(void);
-
G_END_DECLS
#endif /* _PIDGINPRIVACY_H_ */
diff --git a/pidgin/gtksession.c b/pidgin/gtksession.c
index 462a0e6b82..1e5094841b 100644
--- a/pidgin/gtksession.c
+++ b/pidgin/gtksession.c
@@ -376,7 +376,7 @@ pidgin_session_init(gchar *argv0, gchar *previous_id, gchar *config_dir)
g_free(tmp);
session_set_gchar(session, SmRestartStyleHint, (gchar) SmRestartIfRunning);
- session_set_string(session, SmProgram, g_get_prgname());
+ session_set_string(session, SmProgram, (gchar *) g_get_prgname());
myself = g_strdup(argv0);
purple_debug(PURPLE_DEBUG_MISC, "Session Management",
diff --git a/pidgin/gtksound.c b/pidgin/gtksound.c
index a9349bbafb..b59e0a250f 100644
--- a/pidgin/gtksound.c
+++ b/pidgin/gtksound.c
@@ -85,19 +85,19 @@ unmute_login_sounds_cb(gpointer data)
}
static gboolean
-chat_nick_matches_name(PurpleConversation *conv, const char *aname)
+chat_nick_matches_name(PurpleChatConversation *chat, const char *aname)
{
- PurpleConvChat *chat = NULL;
char *nick = NULL;
char *name = NULL;
gboolean ret = FALSE;
- chat = purple_conversation_get_chat_data(conv);
if (chat==NULL)
return ret;
- 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));
+ nick = g_strdup(purple_normalize(purple_conversation_get_account(
+ PURPLE_CONVERSATION(chat)), purple_chat_conversation_get_nick(chat)));
+ name = g_strdup(purple_normalize(purple_conversation_get_account(
+ PURPLE_CONVERSATION(chat)), aname));
if (g_utf8_collate(nick, name) == 0)
ret = TRUE;
@@ -158,26 +158,26 @@ static void
im_msg_sent_cb(PurpleAccount *account, const char *receiver,
const char *message, PurpleSoundEventID event)
{
- PurpleConversation *conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_IM, receiver, account);
+ PurpleConversation *conv = PURPLE_CONVERSATION(
+ purple_conversations_find_im_with_account(receiver, account));
play_conv_event(conv, event);
}
static void
-chat_buddy_join_cb(PurpleConversation *conv, const char *name,
- PurpleConvChatBuddyFlags flags, gboolean new_arrival,
+chat_user_join_cb(PurpleChatConversation *chat, const char *name,
+ PurpleChatUserFlags flags, gboolean new_arrival,
PurpleSoundEventID event)
{
- if (new_arrival && !chat_nick_matches_name(conv, name))
- play_conv_event(conv, event);
+ if (new_arrival && !chat_nick_matches_name(chat, name))
+ play_conv_event(PURPLE_CONVERSATION(chat), event);
}
static void
-chat_buddy_left_cb(PurpleConversation *conv, const char *name,
+chat_user_left_cb(PurpleChatConversation *chat, const char *name,
const char *reason, PurpleSoundEventID event)
{
- if (!chat_nick_matches_name(conv, name))
- play_conv_event(conv, event);
+ if (!chat_nick_matches_name(chat, name))
+ play_conv_event(PURPLE_CONVERSATION(chat), event);
}
static void
@@ -188,31 +188,29 @@ chat_msg_sent_cb(PurpleAccount *account, const char *message,
PurpleConversation *conv = NULL;
if (conn!=NULL)
- conv = purple_find_chat(conn,id);
+ conv = PURPLE_CONVERSATION(purple_conversations_find_chat(conn,id));
play_conv_event(conv, event);
}
static void
chat_msg_received_cb(PurpleAccount *account, char *sender,
- char *message, PurpleConversation *conv,
+ char *message, PurpleChatConversation *chat,
PurpleMessageFlags flags, PurpleSoundEventID event)
{
- PurpleConvChat *chat;
-
+ PurpleConversation *conv = PURPLE_CONVERSATION(chat);
if (flags & PURPLE_MESSAGE_DELAYED || flags & PURPLE_MESSAGE_NOTIFY)
return;
- chat = purple_conversation_get_chat_data(conv);
- g_return_if_fail(chat != NULL);
+ g_return_if_fail(conv != NULL);
- if (purple_conv_chat_is_user_ignored(chat, sender))
+ if (purple_chat_conversation_is_ignored_user(chat, sender))
return;
- if (chat_nick_matches_name(conv, sender))
+ if (chat_nick_matches_name(chat, sender))
return;
- if (flags & PURPLE_MESSAGE_NICK || purple_utf8_has_word(message, purple_conv_chat_get_nick(chat)))
+ if (flags & PURPLE_MESSAGE_NICK || purple_utf8_has_word(message, purple_chat_conversation_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);
@@ -343,11 +341,11 @@ pidgin_sound_init(void)
purple_signal_connect(conv_handle, "sent-im-msg",
gtk_sound_handle, PURPLE_CALLBACK(im_msg_sent_cb),
GINT_TO_POINTER(PURPLE_SOUND_SEND));
- purple_signal_connect(conv_handle, "chat-buddy-joined",
- gtk_sound_handle, PURPLE_CALLBACK(chat_buddy_join_cb),
+ purple_signal_connect(conv_handle, "chat-user-joined",
+ gtk_sound_handle, PURPLE_CALLBACK(chat_user_join_cb),
GINT_TO_POINTER(PURPLE_SOUND_CHAT_JOIN));
- purple_signal_connect(conv_handle, "chat-buddy-left",
- gtk_sound_handle, PURPLE_CALLBACK(chat_buddy_left_cb),
+ purple_signal_connect(conv_handle, "chat-user-left",
+ gtk_sound_handle, PURPLE_CALLBACK(chat_user_left_cb),
GINT_TO_POINTER(PURPLE_SOUND_CHAT_LEAVE));
purple_signal_connect(conv_handle, "sent-chat-msg",
gtk_sound_handle, PURPLE_CALLBACK(chat_msg_sent_cb),
diff --git a/pidgin/gtkstatusbox.c b/pidgin/gtkstatusbox.c
index 715a2acd12..73598a3c05 100644
--- a/pidgin/gtkstatusbox.c
+++ b/pidgin/gtkstatusbox.c
@@ -254,7 +254,7 @@ update_to_reflect_account_status(PidginStatusBox *status_box, PurpleAccount *acc
const char *message;
statustype = purple_status_type_find_with_id((GList *)purple_account_get_status_types(account),
- (char *)purple_status_type_get_id(purple_status_get_type(newstatus)));
+ (char *)purple_status_type_get_id(purple_status_get_status_type(newstatus)));
for (l = purple_account_get_status_types(account); l != NULL; l = l->next) {
PurpleStatusType *status_type = (PurpleStatusType *)l->data;
@@ -702,7 +702,7 @@ pidgin_status_box_refresh(PidginStatusBox *status_box)
PurpleStatusType *status_type;
PurpleStatusPrimitive prim;
if (account_status) {
- status_type = purple_status_get_type(purple_account_get_active_status(acct));
+ status_type = purple_status_get_status_type(purple_account_get_active_status(acct));
prim = purple_status_type_get_primitive(status_type);
} else {
prim = purple_savedstatus_get_type(saved_status);
diff --git a/pidgin/gtkthemes.c b/pidgin/gtkthemes.c
index 4e3ceb7a87..10ca5c0e44 100644
--- a/pidgin/gtkthemes.c
+++ b/pidgin/gtkthemes.c
@@ -341,7 +341,7 @@ void pidgin_themes_load_smiley_theme(const char *file, gboolean load)
pidgin_themes_destroy_smiley_theme_smileys(current_smiley_theme);
current_smiley_theme = theme;
- for (cnv = purple_get_conversations(); cnv != NULL; cnv = cnv->next) {
+ for (cnv = purple_conversations_get_all(); cnv != NULL; cnv = cnv->next) {
PurpleConversation *conv = cnv->data;
if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) {
diff --git a/pidgin/gtkutils.c b/pidgin/gtkutils.c
index 66c9d3a743..32c64ace78 100644
--- a/pidgin/gtkutils.c
+++ b/pidgin/gtkutils.c
@@ -730,10 +730,10 @@ create_account_menu(PurpleAccount *default_account,
gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE);
}
- if (purple_account_get_alias(account)) {
+ if (purple_account_get_private_alias(account)) {
g_snprintf(buf, sizeof(buf), "%s (%s) (%s)",
purple_account_get_username(account),
- purple_account_get_alias(account),
+ purple_account_get_private_alias(account),
purple_account_get_protocol_name(account));
} else {
g_snprintf(buf, sizeof(buf), "%s (%s)",
@@ -1378,7 +1378,7 @@ static void dnd_image_ok_callback(_DndData *data, int choice)
break;
}
- buddy = purple_find_buddy(data->account, data->who);
+ buddy = purple_blist_find_buddy(data->account, data->who);
if (!buddy) {
purple_debug_info("custom-icon", "You can only set custom icons for people on your buddylist.\n");
break;
@@ -1390,7 +1390,7 @@ static void dnd_image_ok_callback(_DndData *data, int choice)
serv_send_file(purple_account_get_connection(data->account), data->who, data->filename);
break;
case DND_IM_IMAGE:
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, data->account, data->who);
+ conv = PURPLE_CONVERSATION(purple_im_conversation_new(data->account, data->who));
gtkconv = PIDGIN_CONVERSATION(conv);
if (!g_file_get_contents(data->filename, &filedata, &size,
@@ -1570,7 +1570,7 @@ pidgin_dnd_file_manage(GtkSelectionData *sd, PurpleAccount *account, const char
PidginConversation *gtkconv;
case PURPLE_DESKTOP_ITEM_TYPE_LINK:
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, who);
+ conv = PURPLE_CONVERSATION(purple_im_conversation_new(account, who));
gtkconv = PIDGIN_CONVERSATION(conv);
gtk_webview_insert_link(GTK_WEBVIEW(gtkconv->entry),
purple_desktop_item_get_string(item, "URL"),
@@ -1685,7 +1685,7 @@ pidgin_stock_id_from_presence(PurplePresence *presence)
g_return_val_if_fail(presence, NULL);
status = purple_presence_get_active_status(presence);
- type = purple_status_get_type(status);
+ type = purple_status_get_status_type(status);
prim = purple_status_type_get_primitive(type);
idle = purple_presence_is_idle(presence);
@@ -1965,19 +1965,22 @@ add_completion_list(PidginCompletionData *data)
PidginFilterBuddyCompletionEntryFunc filter_func = data->filter_func;
gpointer user_data = data->filter_func_user_data;
GHashTable *sets;
+ gchar *alias;
gtk_list_store_clear(data->store);
- for (gnode = purple_get_blist()->root; gnode != NULL; gnode = gnode->next)
+ for (gnode = purple_blist_get_buddy_list()->root; gnode != NULL; gnode = gnode->next)
{
- if (!PURPLE_BLIST_NODE_IS_GROUP(gnode))
+ if (!PURPLE_IS_GROUP(gnode))
continue;
for (cnode = gnode->child; cnode != NULL; cnode = cnode->next)
{
- if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode))
+ if (!PURPLE_IS_CONTACT(cnode))
continue;
+ g_object_get(cnode, "alias", &alias, NULL);
+
for (bnode = cnode->child; bnode != NULL; bnode = bnode->next)
{
PidginBuddyCompletionEntry entry;
@@ -1986,13 +1989,15 @@ add_completion_list(PidginCompletionData *data)
if (filter_func(&entry, user_data)) {
add_buddyname_autocomplete_entry(data->store,
- ((PurpleContact *)cnode)->alias,
+ alias,
purple_buddy_get_contact_alias(entry.entry.buddy),
purple_buddy_get_account(entry.entry.buddy),
purple_buddy_get_name(entry.entry.buddy)
);
}
}
+
+ g_free(alias);
}
}
diff --git a/pidgin/gtkwebview.c b/pidgin/gtkwebview.c
index 3ad89f73a7..67a1a5a703 100644
--- a/pidgin/gtkwebview.c
+++ b/pidgin/gtkwebview.c
@@ -1783,19 +1783,19 @@ gtk_webview_setup_entry(GtkWebView *webview, PurpleConnectionFlags flags)
g_return_if_fail(webview != NULL);
- if (flags & PURPLE_CONNECTION_HTML) {
+ if (flags & PURPLE_CONNECTION_FLAG_HTML) {
gboolean bold, italic, underline, strike;
buttons = GTK_WEBVIEW_ALL;
- if (flags & PURPLE_CONNECTION_NO_BGCOLOR)
+ if (flags & PURPLE_CONNECTION_FLAG_NO_BGCOLOR)
buttons &= ~GTK_WEBVIEW_BACKCOLOR;
- if (flags & PURPLE_CONNECTION_NO_FONTSIZE)
+ if (flags & PURPLE_CONNECTION_FLAG_NO_FONTSIZE)
{
buttons &= ~GTK_WEBVIEW_GROW;
buttons &= ~GTK_WEBVIEW_SHRINK;
}
- if (flags & PURPLE_CONNECTION_NO_URLDESC)
+ if (flags & PURPLE_CONNECTION_FLAG_NO_URLDESC)
buttons &= ~GTK_WEBVIEW_LINKDESC;
gtk_webview_get_current_format(webview, &bold, &italic, &underline, &strike);
@@ -1816,7 +1816,7 @@ gtk_webview_setup_entry(GtkWebView *webview, PurpleConnectionFlags flags)
gtk_webview_toggle_fontface(webview,
purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/font_face"));
- if (!(flags & PURPLE_CONNECTION_NO_FONTSIZE))
+ if (!(flags & PURPLE_CONNECTION_FLAG_NO_FONTSIZE))
{
int size = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/font_size");
@@ -1828,14 +1828,14 @@ gtk_webview_setup_entry(GtkWebView *webview, PurpleConnectionFlags flags)
gtk_webview_toggle_forecolor(webview,
purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/fgcolor"));
- if (!(flags & PURPLE_CONNECTION_NO_BGCOLOR)) {
+ if (!(flags & PURPLE_CONNECTION_FLAG_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)
+ if (flags & PURPLE_CONNECTION_FLAG_FORMATTING_WBFO)
gtk_webview_set_whole_buffer_formatting_only(webview, TRUE);
else
gtk_webview_set_whole_buffer_formatting_only(webview, FALSE);
@@ -1844,10 +1844,10 @@ gtk_webview_setup_entry(GtkWebView *webview, PurpleConnectionFlags flags)
webview_clear_formatting(webview);
}
- if (flags & PURPLE_CONNECTION_NO_IMAGES)
+ if (flags & PURPLE_CONNECTION_FLAG_NO_IMAGES)
buttons &= ~GTK_WEBVIEW_IMAGE;
- if (flags & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)
+ if (flags & PURPLE_CONNECTION_FLAG_ALLOW_CUSTOM_SMILEY)
buttons |= GTK_WEBVIEW_CUSTOM_SMILEY;
else
buttons &= ~GTK_WEBVIEW_CUSTOM_SMILEY;
diff --git a/pidgin/gtkwebviewtoolbar.c b/pidgin/gtkwebviewtoolbar.c
index 9258d68ce1..b8be27ee0b 100644
--- a/pidgin/gtkwebviewtoolbar.c
+++ b/pidgin/gtkwebviewtoolbar.c
@@ -1632,7 +1632,7 @@ gtk_webviewtoolbar_switch_active_conversation(GtkWebViewToolbar *toolbar,
/* 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 &&
+ conv && prpl && PURPLE_IS_IM_CONVERSATION(conv) &&
PURPLE_PLUGIN_PROTOCOL_INFO(prpl)->send_attention != NULL);
gtk_action_set_sensitive(priv->smiley,
diff --git a/pidgin/gtkwhiteboard.c b/pidgin/gtkwhiteboard.c
index 47e4987d9e..dd6df9f325 100644
--- a/pidgin/gtkwhiteboard.c
+++ b/pidgin/gtkwhiteboard.c
@@ -22,7 +22,7 @@
*/
#include "internal.h"
-#include "blist.h"
+#include "buddylist.h"
#include "debug.h"
#include "gtkwhiteboard.h"
@@ -156,7 +156,7 @@ 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(purple_whiteboard_get_account(wb), purple_whiteboard_get_who(wb));
+ buddy = purple_blist_find_buddy(purple_whiteboard_get_account(wb), purple_whiteboard_get_who(wb));
window = pidgin_create_window(buddy != NULL ? purple_buddy_get_contact_alias(buddy) : purple_whiteboard_get_who(wb), 0, NULL, FALSE);
gtkwb->window = window;
@@ -351,7 +351,7 @@ static void pidginwhiteboard_button_start_press(GtkButton *button, gpointer data
/* XXXX because otherwise gettext will see this string, even though it's
* in an #if 0 block. Remove the XXXX if you want to use this code.
* But, it really shouldn't be a Yahoo-specific string. ;) */
- purple_conv_im_write(PURPLE_CONV_IM(conv), "", XXXX_("Sent Doodle request."),
+ purple_im_conversation_write_message(PURPLE_CONV_IM(conv), "", XXXX_("Sent Doodle request."),
PURPLE_MESSAGE_NICK | PURPLE_MESSAGE_RECV, time(NULL));
yahoo_doodle_command_send_request(gc, to);
diff --git a/pidgin/plugins/cap/cap.c b/pidgin/plugins/cap/cap.c
index d5faffa23b..f9a9122713 100644
--- a/pidgin/plugins/cap/cap.c
+++ b/pidgin/plugins/cap/cap.c
@@ -349,7 +349,7 @@ static void sent_im_msg(PurpleAccount *account, const char *receiver, const char
guint interval, words;
CapStatistics *stats = NULL;
- buddy = purple_find_buddy(account, receiver);
+ buddy = purple_blist_find_buddy(account, receiver);
if (buddy == NULL)
return;
@@ -378,7 +378,7 @@ received_im_msg(PurpleAccount *account, char *sender, char *message, PurpleConve
if (flags & PURPLE_MESSAGE_AUTO_RESP)
return;
- buddy = purple_find_buddy(account, sender);
+ buddy = purple_blist_find_buddy(account, sender);
if (buddy == NULL)
return;
@@ -439,7 +439,7 @@ static void buddy_signed_off(PurpleBuddy *buddy) {
/* drawing-tooltip */
static void drawing_tooltip(PurpleBlistNode *node, GString *text, gboolean full) {
if(node->type == PURPLE_BLIST_BUDDY_NODE) {
- PurpleBuddy *buddy = (PurpleBuddy *)node;
+ PurpleBuddy *buddy = PURPLE_BUDDY(node);
CapStatistics *stats = get_stats_for(buddy);
/* get the probability that this buddy will respond and add to the tooltip */
if(stats->prediction->probability >= 0.0) {
diff --git a/pidgin/plugins/cap/cap.h b/pidgin/plugins/cap/cap.h
index 3832b3f901..d4adc47d69 100644
--- a/pidgin/plugins/cap/cap.h
+++ b/pidgin/plugins/cap/cap.h
@@ -32,7 +32,7 @@
#include "gtkplugin.h"
#include "gtkutils.h"
-#include "blist.h"
+#include "buddylist.h"
#include "notify.h"
#include "version.h"
#include "debug.h"
diff --git a/pidgin/plugins/cap/cap_statistics.h b/pidgin/plugins/cap/cap_statistics.h
index f52495efdc..85a11da3d5 100644
--- a/pidgin/plugins/cap/cap_statistics.h
+++ b/pidgin/plugins/cap/cap_statistics.h
@@ -22,7 +22,7 @@
#ifndef _CAP_STATISTICS_H_
#define _CAP_STATISTICS_H_
-#include "blist.h"
+#include "buddylist.h"
#include <gdk/gdk.h>
#include <glib.h>
#include <time.h>
diff --git a/pidgin/plugins/convcolors.c b/pidgin/plugins/convcolors.c
index 391dbf611a..8f8627cabb 100644
--- a/pidgin/plugins/convcolors.c
+++ b/pidgin/plugins/convcolors.c
@@ -113,10 +113,8 @@ displaying_msg(PurpleAccount *account, const char *who, char **displaying,
g_snprintf(tmp, sizeof(tmp), "%s/enabled", formats[i].prefix);
if (!purple_prefs_get_bool(tmp) ||
- (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM &&
- !purple_prefs_get_bool(PREF_IMS)) ||
- (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT &&
- !purple_prefs_get_bool(PREF_CHATS)))
+ (PURPLE_IS_IM_CONVERSATION(conv) && !purple_prefs_get_bool(PREF_IMS)) ||
+ (PURPLE_IS_CHAT_CONVERSATION(conv) && !purple_prefs_get_bool(PREF_CHATS)))
return FALSE;
g_snprintf(tmp, sizeof(tmp), "%s/color", formats[i].prefix);
diff --git a/pidgin/plugins/crazychat/cc_network.c b/pidgin/plugins/crazychat/cc_network.c
index a80e580c18..45c30eab14 100644
--- a/pidgin/plugins/crazychat/cc_network.c
+++ b/pidgin/plugins/crazychat/cc_network.c
@@ -97,22 +97,22 @@ void cc_net_send_invite(struct crazychat *cc, char *name, PurpleAccount *account
{
struct cc_session *session;
PurpleConversation *conv;
- PurpleConvIm *im;
+ PurpleIMConversation *im;
char buf[BUFSIZ];
session = cc_find_session(cc, name);
if (session) return; /* already have a session with this guy */
session = cc_add_session(cc, name);
session->state = INVITE;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, name, account);
+ conv = purple_conversations_find_with_account(name, account);
if (!conv) {
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, name);
+ conv = purple_im_conversation_new(account, name);
}
im = purple_conversation_get_im_data(conv);
snprintf(buf, BUFSIZ, "%s%s!%d", CRAZYCHAT_INVITE_CODE,
purple_network_get_my_ip(-1), cc->tcp_port);
Debug("Sent invite to %s for port: %d\n", name, cc->tcp_port);
- purple_conv_im_send(im, buf);
+ purple_im_conversation_send(im, buf);
}
void cc_net_recv_invite(PurpleAccount *account, struct crazychat *cc, char *name,
@@ -131,7 +131,7 @@ void cc_net_recv_invite(PurpleAccount *account, struct crazychat *cc, char *name
session = cc_find_session(cc, name);
if (!session) {
Debug("Creating a CrazyChat session invite dialog box!\n");
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, name, account);
+ conv = purple_conversations_find_with_account(name, account);
if (conv) convwin = purple_conversation_get_window(conv);
else convwin = NULL;
/* pop gtk window asking if want to accept */
@@ -206,15 +206,15 @@ static void cc_net_send_ready(PurpleAccount *account, struct cc_session *session
/* socket created, send the ready message */
PurpleConversation *conv;
- PurpleConvIm *im;
+ PurpleIMConversation *im;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, session->name, account);
+ conv = purple_conversations_find_with_account(session->name, account);
if (!conv) {
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account,
+ conv = purple_im_conversation_new(account,
session->name);
}
im = purple_conversation_get_im_data(conv);
- purple_conv_im_send(im, CRAZYCHAT_READY_CODE);
+ purple_im_conversation_send(im, CRAZYCHAT_READY_CODE);
/* register timer callback for checking socket connection */
args = (struct sock_accept_args*)malloc(sizeof(*args));
@@ -260,7 +260,7 @@ static void invite_handler(GtkDialog *dialog, gint response, struct accept_args
struct cc_session *session;
char buf[BUFSIZ];
PurpleConversation *conv;
- PurpleConvIm *im;
+ PurpleIMConversation *im;
if (response == GTK_RESPONSE_ACCEPT) {
assert(args);
@@ -272,14 +272,14 @@ static void invite_handler(GtkDialog *dialog, gint response, struct accept_args
session->peer_port = args->peer_port;
snprintf(buf, BUFSIZ, "%s%s", CRAZYCHAT_ACCEPT_CODE,
purple_network_get_my_ip(-1));
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, args->name,
+ conv = purple_conversations_find_with_account(args->name,
args->account);
if (!conv) {
conv = purple_conversation_new(PURPLE_CONV_TYPE_IM,
args->account, args->name);
}
im = purple_conversation_get_im_data(conv);
- purple_conv_im_send(im, buf);
+ purple_im_conversation_send(im, buf);
}
free(args->name);
free(args);
diff --git a/pidgin/plugins/crazychat/cc_pidgin_plugin.c b/pidgin/plugins/crazychat/cc_pidgin_plugin.c
index 6219d5f615..c88750c807 100644
--- a/pidgin/plugins/crazychat/cc_pidgin_plugin.c
+++ b/pidgin/plugins/crazychat/cc_pidgin_plugin.c
@@ -413,7 +413,7 @@ static gboolean cc_signed_on(PurpleConnection *gc, void *plugin)
(purple_connections_get_handle(), "signed-on",
plugin, PURPLE_CALLBACK(cc_signed_on));
purple_signal_connect(PIDGIN_BLIST
- (purple_get_blist()),
+ (purple_blist_get_buddy_list()),
"drawing-menu", plugin,
PURPLE_CALLBACK(cc_buddy_menu), NULL);
conv_handle = purple_conversations_get_handle();
@@ -433,7 +433,7 @@ static gboolean plugin_load(PurplePlugin *plugin)
return FALSE;
cc_init(&cc_info);
- buddy_list = purple_get_blist();
+ buddy_list = purple_blist_get_buddy_list();
if (buddy_list) {
purple_signal_connect(PIDGIN_BLIST
(buddy_list),
@@ -464,7 +464,7 @@ static gboolean plugin_unload(PurplePlugin *plugin)
cc_destroy(extra);
conv_handle = purple_conversations_get_handle();
purple_signal_disconnect(PIDGIN_BLIST
- (purple_get_blist()),
+ (purple_blist_get_buddy_list()),
"drawing-menu", plugin,
PURPLE_CALLBACK(cc_buddy_menu));
purple_signal_disconnect(conv_handle, "received-im", plugin,
diff --git a/pidgin/plugins/extplacement.c b/pidgin/plugins/extplacement.c
index 494e0849d2..bb387311f3 100644
--- a/pidgin/plugins/extplacement.c
+++ b/pidgin/plugins/extplacement.c
@@ -35,7 +35,8 @@ conv_placement_by_number(PidginConversation *conv)
GList *wins = NULL;
if (purple_prefs_get_bool("/plugins/gtk/extplacement/placement_number_separate"))
- win = pidgin_conv_window_last_with_type(purple_conversation_get_type(conv->active_conv));
+ win = PURPLE_IS_IM_CONVERSATION(conv->active_conv) ?
+ pidgin_conv_window_last_im() : pidgin_conv_window_last_chat();
else if ((wins = pidgin_conv_windows_get_list()) != NULL)
win = g_list_last(wins)->data;
@@ -57,7 +58,7 @@ conv_placement_by_number(PidginConversation *conv)
win = l->data;
if (purple_prefs_get_bool("/plugins/gtk/extplacement/placement_number_separate") &&
- purple_conversation_get_type(pidgin_conv_window_get_active_conversation(win)) != purple_conversation_get_type(conv->active_conv))
+ PURPLE_IS_IM_CONVERSATION(pidgin_conv_window_get_active_conversation(win)) != PURPLE_IS_IM_CONVERSATION(conv->active_conv))
continue;
count = pidgin_conv_window_get_gtkconv_count(win);
diff --git a/pidgin/plugins/gestures/gestures.c b/pidgin/plugins/gestures/gestures.c
index 51c13f011e..da43ecc342 100644
--- a/pidgin/plugins/gestures/gestures.c
+++ b/pidgin/plugins/gestures/gestures.c
@@ -49,7 +49,7 @@ stroke_close(GtkWidget *widget, void *data)
gtkconv = PIDGIN_CONVERSATION(conv);
gstroke_cleanup(gtkconv->webview);
- purple_conversation_destroy(conv);
+ g_object_unref(conv);
}
static void
@@ -174,7 +174,7 @@ plugin_load(PurplePlugin *plugin)
PurpleConversation *conv;
GList *l;
- for (l = purple_get_conversations(); l != NULL; l = l->next) {
+ for (l = purple_conversations_get_all(); l != NULL; l = l->next) {
conv = (PurpleConversation *)l->data;
if (!PIDGIN_IS_PIDGIN_CONVERSATION(conv))
@@ -197,7 +197,7 @@ plugin_unload(PurplePlugin *plugin)
PidginConversation *gtkconv;
GList *l;
- for (l = purple_get_conversations(); l != NULL; l = l->next) {
+ for (l = purple_conversations_get_all(); l != NULL; l = l->next) {
conv = (PurpleConversation *)l->data;
if (!PIDGIN_IS_PIDGIN_CONVERSATION(conv))
diff --git a/pidgin/plugins/gevolution/add_buddy_dialog.c b/pidgin/plugins/gevolution/add_buddy_dialog.c
index 4570726936..eb376bc2ad 100644
--- a/pidgin/plugins/gevolution/add_buddy_dialog.c
+++ b/pidgin/plugins/gevolution/add_buddy_dialog.c
@@ -192,7 +192,7 @@ add_ims(GevoAddBuddyDialog *dialog, EContact *contact, const char *name,
if (account_name == NULL)
continue;
- if (purple_find_buddy(dialog->account, account_name) != NULL)
+ if (purple_blist_find_buddy(dialog->account, account_name) != NULL)
continue;
gtk_list_store_append(dialog->model, &iter);
diff --git a/pidgin/plugins/gevolution/gevo-util.c b/pidgin/plugins/gevolution/gevo-util.c
index 77d31a4ffe..3d8ed1ca63 100644
--- a/pidgin/plugins/gevolution/gevo-util.c
+++ b/pidgin/plugins/gevolution/gevo-util.c
@@ -33,16 +33,16 @@ gevo_add_buddy(PurpleAccount *account, const char *group_name,
PurpleBuddy *buddy;
PurpleGroup *group;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy_name, account);
+ conv = purple_conversations_find_im_with_account(buddy_name, account);
- group = purple_find_group(group_name);
+ group = purple_blist_find_group(group_name);
if (group == NULL)
{
group = purple_group_new(group_name);
purple_blist_add_group(group, NULL);
}
- buddy = purple_find_buddy_in_group(account, buddy_name, group);
+ buddy = purple_blist_find_buddy_in_group(account, buddy_name, group);
if (buddy == NULL)
{
buddy = purple_buddy_new(account, buddy_name, alias);
@@ -53,8 +53,8 @@ gevo_add_buddy(PurpleAccount *account, const char *group_name,
if (conv != NULL)
{
- purple_buddy_icon_update(purple_conv_im_get_icon(PURPLE_CONV_IM(conv)));
- purple_conversation_update(conv, PURPLE_CONV_UPDATE_ADD);
+ purple_buddy_icon_update(purple_im_conversation_get_icon(PURPLE_CONV_IM(conv)));
+ purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_ADD);
}
}
@@ -68,19 +68,19 @@ gevo_get_groups(void)
g_list_free(list);
list = NULL;
- if (purple_get_blist()->root == NULL)
+ if (purple_blist_get_buddy_list()->root == NULL)
{
list = g_list_append(list, (gpointer)_("Buddies"));
}
else
{
- for (gnode = purple_get_blist()->root;
+ for (gnode = purple_blist_get_buddy_list()->root;
gnode != NULL;
gnode = gnode->next)
{
- if (PURPLE_BLIST_NODE_IS_GROUP(gnode))
+ if (PURPLE_IS_GROUP(gnode))
{
- g = (PurpleGroup *)gnode;
+ g = PURPLE_GROUP(gnode);
list = g_list_append(list, g->name);
}
}
diff --git a/pidgin/plugins/gevolution/gevolution.c b/pidgin/plugins/gevolution/gevolution.c
index 9398393b23..244460738e 100644
--- a/pidgin/plugins/gevolution/gevolution.c
+++ b/pidgin/plugins/gevolution/gevolution.c
@@ -99,7 +99,7 @@ update_ims_from_contact(EContact *contact, const char *name,
me = g_strdup(purple_normalize(account, purple_account_get_username(account)));
for (l2 = ims; l2 != NULL; l2 = l2->next)
{
- if (purple_find_buddy(account, l2->data) != NULL ||
+ if (purple_blist_find_buddy(account, l2->data) != NULL ||
!strcmp(me, purple_normalize(account, l2->data)))
continue;
@@ -220,14 +220,14 @@ signed_on_cb(PurpleConnection *gc)
static void
menu_item_activate_cb(PurpleBlistNode *node, gpointer user_data)
{
- PurpleBuddy *buddy = (PurpleBuddy *)node;
+ PurpleBuddy *buddy = PURPLE_BUDDY(node);
gevo_associate_buddy_dialog_new(buddy);
}
static void
menu_item_send_mail_activate_cb(PurpleBlistNode *node, gpointer user_data)
{
- PurpleBuddy *buddy = (PurpleBuddy *)node;
+ PurpleBuddy *buddy = PURPLE_BUDDY(node);
char *mail = NULL;
mail = gevo_get_email_for_buddy(buddy);
@@ -268,10 +268,10 @@ blist_node_extended_menu_cb(PurpleBlistNode *node, GList **menu)
EContact *contact;
char *mail;
- if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (!PURPLE_IS_BUDDY(node))
return;
- buddy = (PurpleBuddy *)node;
+ buddy = PURPLE_BUDDY(node);
account = purple_buddy_get_account(buddy);
if (!gevo_prpl_is_supported(account, buddy))
diff --git a/pidgin/plugins/gtk-signals-test.c b/pidgin/plugins/gtk-signals-test.c
index a1cf84bf25..f61f50a28d 100644
--- a/pidgin/plugins/gtk-signals-test.c
+++ b/pidgin/plugins/gtk-signals-test.c
@@ -110,7 +110,7 @@ conversation_switched_cb(PurpleConversation *conv, void *data)
static gboolean
plugin_load(PurplePlugin *plugin)
{
- void *accounts_handle = pidgin_account_get_handle();
+ void *accounts_handle = pidgin_accounts_get_handle();
void *blist_handle = pidgin_blist_get_handle();
void *conv_handle = pidgin_conversations_get_handle();
diff --git a/pidgin/plugins/history.c b/pidgin/plugins/history.c
index f2d1d913d0..faea163a68 100644
--- a/pidgin/plugins/history.c
+++ b/pidgin/plugins/history.c
@@ -34,7 +34,6 @@ static void historize(PurpleConversation *c)
{
PurpleAccount *account = purple_conversation_get_account(c);
const char *name = purple_conversation_get_name(c);
- PurpleConversationType convtype;
GList *logs = NULL;
const char *alias = name;
guint flags;
@@ -52,13 +51,12 @@ static void historize(PurpleConversation *c)
char *escaped_alias;
const char *header_date;
- convtype = purple_conversation_get_type(c);
gtkconv = PIDGIN_CONVERSATION(c);
g_return_if_fail(gtkconv != NULL);
/* An IM which is the first active conversation. */
g_return_if_fail(gtkconv->convs != NULL);
- if (convtype == PURPLE_CONV_TYPE_IM && !gtkconv->convs->next)
+ if (PURPLE_IS_IM_CONVERSATION(c) && !gtkconv->convs->next)
{
GSList *buddies;
GSList *cur;
@@ -69,11 +67,11 @@ static void historize(PurpleConversation *c)
return;
/* Find buddies for this conversation. */
- buddies = purple_find_buddies(account, name);
+ buddies = purple_blist_find_buddies(account, name);
/* If we found at least one buddy, save the first buddy's alias. */
if (buddies != NULL)
- alias = purple_buddy_get_contact_alias((PurpleBuddy *)buddies->data);
+ alias = purple_buddy_get_contact_alias(PURPLE_BUDDY(buddies->data));
for (cur = buddies; cur != NULL; cur = cur->next)
{
@@ -86,7 +84,7 @@ static void historize(PurpleConversation *c)
PurpleBlistNode *parent = purple_blist_node_get_parent(node);
PurpleBlistNode *child = purple_blist_node_get_first_child(parent);
- alias = purple_buddy_get_contact_alias((PurpleBuddy *)node);
+ alias = purple_buddy_get_contact_alias(PURPLE_BUDDY(node));
/* We've found a buddy that matches this conversation. It's part of a
* PurpleContact with more than one PurpleBuddy. Loop through the PurpleBuddies
@@ -94,8 +92,8 @@ static void historize(PurpleConversation *c)
for (node2 = child ; node2 != NULL ; node2 = purple_blist_node_get_sibling_next(node2))
{
logs = g_list_concat(purple_log_get_logs(PURPLE_LOG_IM,
- purple_buddy_get_name((PurpleBuddy *)node2),
- purple_buddy_get_account((PurpleBuddy *)node2)),
+ purple_buddy_get_name(PURPLE_BUDDY(node2)),
+ purple_buddy_get_account(PURPLE_BUDDY(node2))),
logs);
}
break;
@@ -108,7 +106,7 @@ static void historize(PurpleConversation *c)
else
logs = g_list_sort(logs, purple_log_compare);
}
- else if (convtype == PURPLE_CONV_TYPE_CHAT)
+ else if (PURPLE_IS_CHAT_CONVERSATION(c))
{
/* If we're not logging, don't show anything.
* Otherwise, we might show a very old log. */
diff --git a/pidgin/plugins/mailchk.c b/pidgin/plugins/mailchk.c
index ed279b5ecf..c9bf0e9f55 100644
--- a/pidgin/plugins/mailchk.c
+++ b/pidgin/plugins/mailchk.c
@@ -55,7 +55,7 @@ static gboolean
check_timeout(gpointer data)
{
gint count = check_mail();
- PurpleBuddyList *list = purple_get_blist();
+ PurpleBuddyList *list = purple_blist_get_buddy_list();
if (count == -1)
return FALSE;
@@ -90,7 +90,7 @@ check_timeout(gpointer data)
static void
signon_cb(PurpleConnection *gc)
{
- PurpleBuddyList *list = purple_get_blist();
+ PurpleBuddyList *list = purple_blist_get_buddy_list();
if (list && PURPLE_IS_GTK_BLIST(list) && !timer) {
check_timeout(NULL); /* we want the box to be drawn immediately */
timer = purple_timeout_add_seconds(2, check_timeout, NULL);
@@ -100,7 +100,7 @@ signon_cb(PurpleConnection *gc)
static void
signoff_cb(PurpleConnection *gc)
{
- PurpleBuddyList *list = purple_get_blist();
+ PurpleBuddyList *list = purple_blist_get_buddy_list();
if ((!list || !PURPLE_IS_GTK_BLIST(list) || !PIDGIN_BLIST(list)->vbox) && timer) {
purple_timeout_remove(timer);
timer = 0;
@@ -114,7 +114,7 @@ signoff_cb(PurpleConnection *gc)
static gboolean
plugin_load(PurplePlugin *plugin)
{
- PurpleBuddyList *list = purple_get_blist();
+ PurpleBuddyList *list = purple_blist_get_buddy_list();
void *conn_handle = purple_connections_get_handle();
if (!check_timeout(NULL)) {
diff --git a/pidgin/plugins/markerline.c b/pidgin/plugins/markerline.c
index 461da4fd61..bf1e552187 100644
--- a/pidgin/plugins/markerline.c
+++ b/pidgin/plugins/markerline.c
@@ -45,15 +45,13 @@ static void
update_marker_for_gtkconv(PidginConversation *gtkconv)
{
PurpleConversation *conv;
- PurpleConversationType type;
g_return_if_fail(gtkconv != NULL);
conv = gtkconv->active_conv;
- 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)))
+ if ((PURPLE_IS_CHAT_CONVERSATION(conv) && !purple_prefs_get_bool(PREF_CHATS)) ||
+ (PURPLE_IS_IM_CONVERSATION(conv) && !purple_prefs_get_bool(PREF_IMS)))
return;
gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview),
@@ -166,9 +164,8 @@ jump_to_markerline(PurpleConversation *conv, gpointer null)
static void
conv_menu_cb(PurpleConversation *conv, GList **list)
{
- PurpleConversationType type = purple_conversation_get_type(conv);
- gboolean enabled = ((type == PURPLE_CONV_TYPE_IM && purple_prefs_get_bool(PREF_IMS)) ||
- (type == PURPLE_CONV_TYPE_CHAT && purple_prefs_get_bool(PREF_CHATS)));
+ gboolean enabled = ((PURPLE_IS_IM_CONVERSATION(conv) && purple_prefs_get_bool(PREF_IMS)) ||
+ (PURPLE_IS_CHAT_CONVERSATION(conv) && purple_prefs_get_bool(PREF_CHATS)));
PurpleMenuAction *action = purple_menu_action_new(_("Jump to markerline"),
enabled ? PURPLE_CALLBACK(jump_to_markerline) : NULL, NULL, NULL);
*list = g_list_append(*list, action);
diff --git a/pidgin/plugins/musicmessaging/musicmessaging.c b/pidgin/plugins/musicmessaging/musicmessaging.c
index dd157d0262..0a481a5908 100644
--- a/pidgin/plugins/musicmessaging/musicmessaging.c
+++ b/pidgin/plugins/musicmessaging/musicmessaging.c
@@ -111,7 +111,7 @@ void music_messaging_change_request(const int session, const char *command, cons
GString *to_send = g_string_new("");
g_string_append_printf(to_send, "##MM## request %s %s##MM##", command, parameters);
- purple_conv_im_send(PURPLE_CONV_IM(mmconv->conv), to_send->str);
+ purple_conversation_send(mmconv->conv, to_send->str);
purple_debug_misc("musicmessaging", "Sent request: %s\n", to_send->str);
}
@@ -131,7 +131,7 @@ void music_messaging_change_confirmed(const int session, const char *command, co
GString *to_send = g_string_new("");
g_string_append_printf(to_send, "##MM## confirm %s %s##MM##", command, parameters);
- purple_conv_im_send(PURPLE_CONV_IM(mmconv->conv), to_send->str);
+ purple_conversation_send(mmconv->conv, to_send->str);
} else
{
/* Do nothing. If they aren't the originator, then they can't confirm. */
@@ -154,7 +154,7 @@ void music_messaging_change_failed(const int session, const char *id, const char
GString *to_send = g_string_new("");
g_string_append_printf(to_send, "##MM## failed %s %s %s##MM##", id, command, parameters);
- purple_conv_im_send(PURPLE_CONV_IM(mmconv->conv), to_send->str);
+ purple_conversation_send(mmconv->conv, to_send->str);
} else
{
/* Do nothing. If they aren't the originator, then they can't confirm. */
@@ -261,6 +261,7 @@ mmconv_from_conv(PurpleConversation *conv)
static gboolean
plugin_load(PurplePlugin *plugin) {
void *conv_list_handle;
+ GList *l;
PURPLE_DBUS_RETURN_FALSE_IF_DISABLED(plugin);
@@ -273,7 +274,8 @@ plugin_load(PurplePlugin *plugin) {
plugin_pointer = plugin;
/* Add the button to all the current conversations */
- purple_conversation_foreach (init_conversation);
+ for (l = purple_conversations_get_all(); l != NULL; l = l->next)
+ init_conversation((PurpleConversation *)l->data);
/* Listen for any new conversations */
conv_list_handle = purple_conversations_get_handle();
diff --git a/pidgin/plugins/notify.c b/pidgin/plugins/notify.c
index d8d6101e13..6a651ecf75 100644
--- a/pidgin/plugins/notify.c
+++ b/pidgin/plugins/notify.c
@@ -150,7 +150,7 @@ count_messages(PidginWindow *purplewin)
for (convs = purplewin->gtkconvs; convs != NULL; convs = convs->next) {
PidginConversation *conv = convs->data;
for (l = conv->convs; l != NULL; l = l->next) {
- count += GPOINTER_TO_INT(purple_conversation_get_data(l->data, "notify-message-count"));
+ count += GPOINTER_TO_INT(g_object_get_data(G_OBJECT(l->data), "notify-message-count"));
}
}
@@ -173,9 +173,9 @@ notify(PurpleConversation *conv, gboolean increment)
purplewin = PIDGIN_CONVERSATION(conv)->win;
/* If we aren't doing notifications for this type of conversation, return */
- if (((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) &&
+ if ((PURPLE_IS_IM_CONVERSATION(conv) &&
!purple_prefs_get_bool("/plugins/gtk/X11/notify/type_im")) ||
- ((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) &&
+ (PURPLE_IS_CHAT_CONVERSATION(conv) &&
!purple_prefs_get_bool("/plugins/gtk/X11/notify/type_chat")))
return 0;
@@ -185,9 +185,9 @@ notify(PurpleConversation *conv, gboolean increment)
if (purple_prefs_get_bool("/plugins/gtk/X11/notify/type_focused") ||
!has_focus) {
if (increment) {
- count = GPOINTER_TO_INT(purple_conversation_get_data(conv, "notify-message-count"));
+ count = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(conv), "notify-message-count"));
count++;
- purple_conversation_set_data(conv, "notify-message-count", GINT_TO_POINTER(count));
+ g_object_set_data(G_OBJECT(conv), "notify-message-count", GINT_TO_POINTER(count));
}
notify_win(purplewin, conv);
@@ -237,7 +237,7 @@ unnotify(PurpleConversation *conv, gboolean reset)
* removing it just to have it readded in re-notify is an
* unnecessary couple extra RTs to the server */
handle_urgent(purplewin, FALSE);
- purple_conversation_set_data(conv, "notify-message-count", GINT_TO_POINTER(0));
+ g_object_set_data(G_OBJECT(conv), "notify-message-count", GINT_TO_POINTER(0));
/* Same logic as for the urgent hint, xprops are also a RT.
* This needs to go here so that it gets the updated message
* count. */
@@ -250,7 +250,7 @@ unnotify(PurpleConversation *conv, gboolean reset)
static int
unnotify_cb(GtkWidget *widget, gpointer data, PurpleConversation *conv)
{
- if (GPOINTER_TO_INT(purple_conversation_get_data(conv, "notify-message-count")) != 0)
+ if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(conv), "notify-message-count")) != 0)
unnotify(conv, TRUE);
return 0;
@@ -260,7 +260,7 @@ static gboolean
message_displayed_cb(PurpleAccount *account, const char *who, char *message,
PurpleConversation *conv, PurpleMessageFlags flags)
{
- if ((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT &&
+ if ((PURPLE_IS_CHAT_CONVERSATION(conv) &&
purple_prefs_get_bool("/plugins/gtk/X11/notify/type_chat_nick") &&
!(flags & PURPLE_MESSAGE_NICK)))
return FALSE;
@@ -274,22 +274,22 @@ message_displayed_cb(PurpleAccount *account, const char *who, char *message,
static void
im_sent_im(PurpleAccount *account, const char *receiver, const char *message)
{
- PurpleConversation *conv = NULL;
+ PurpleIMConversation *im = NULL;
if (purple_prefs_get_bool("/plugins/gtk/X11/notify/notify_send")) {
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, receiver, account);
- unnotify(conv, TRUE);
+ im = purple_conversations_find_im_with_account(receiver, account);
+ unnotify(PURPLE_CONVERSATION(im), TRUE);
}
}
static void
chat_sent_im(PurpleAccount *account, const char *message, int id)
{
- PurpleConversation *conv = NULL;
+ PurpleChatConversation *chat = NULL;
if (purple_prefs_get_bool("/plugins/gtk/X11/notify/notify_send")) {
- conv = purple_find_chat(purple_account_get_connection(account), id);
- unnotify(conv, TRUE);
+ chat = purple_conversations_find_chat(purple_account_get_connection(account), id);
+ unnotify(PURPLE_CONVERSATION(chat), TRUE);
}
}
@@ -339,8 +339,8 @@ attach_signals(PurpleConversation *conv)
entry_ids = g_slist_append(entry_ids, GUINT_TO_POINTER(id));
}
- purple_conversation_set_data(conv, "notify-webview-signals", webview_ids);
- purple_conversation_set_data(conv, "notify-entry-signals", entry_ids);
+ g_object_set_data(G_OBJECT(conv), "notify-webview-signals", webview_ids);
+ g_object_set_data(G_OBJECT(conv), "notify-entry-signals", entry_ids);
return 0;
}
@@ -355,26 +355,26 @@ detach_signals(PurpleConversation *conv)
if (!gtkconv)
return;
- ids = purple_conversation_get_data(conv, "notify-webview-signals");
+ ids = g_object_get_data(G_OBJECT(conv), "notify-webview-signals");
for (l = ids; l != NULL; l = l->next)
g_signal_handler_disconnect(gtkconv->webview, GPOINTER_TO_INT(l->data));
g_slist_free(ids);
- ids = purple_conversation_get_data(conv, "notify-entry-signals");
+ ids = g_object_get_data(G_OBJECT(conv), "notify-entry-signals");
for (l = ids; l != NULL; l = l->next)
g_signal_handler_disconnect(gtkconv->entry, GPOINTER_TO_INT(l->data));
g_slist_free(ids);
- purple_conversation_set_data(conv, "notify-message-count", GINT_TO_POINTER(0));
+ g_object_set_data(G_OBJECT(conv), "notify-message-count", GINT_TO_POINTER(0));
- purple_conversation_set_data(conv, "notify-webview-signals", NULL);
- purple_conversation_set_data(conv, "notify-entry-signals", NULL);
+ g_object_set_data(G_OBJECT(conv), "notify-webview-signals", NULL);
+ g_object_set_data(G_OBJECT(conv), "notify-entry-signals", NULL);
}
static void
conv_created(PurpleConversation *conv)
{
- purple_conversation_set_data(conv, "notify-message-count",
+ g_object_set_data(G_OBJECT(conv), "notify-message-count",
GINT_TO_POINTER(0));
/* always attach the signals, notify() will take care of conversation
@@ -423,7 +423,7 @@ deleting_conv(PurpleConversation *conv)
purplewin = gtkconv->win;
handle_urgent(purplewin, FALSE);
- purple_conversation_set_data(conv, "notify-message-count", GINT_TO_POINTER(0));
+ g_object_set_data(G_OBJECT(conv), "notify-message-count", GINT_TO_POINTER(0));
return;
@@ -454,7 +454,7 @@ conversation_dragging(PurpleConversation *active_conv,
printf("if else count = %d\n", count_messages(old_purplewin));
/*
PurpleConversation *old_active_conv = NULL;
- old_active_conv = purple_conv_window_get_active_conversation(new_purplewin);
+ old_active_conv = purple_conversation_window_get_active_conversation(new_purplewin);
purple_conversation_autoset_title(old_active_conv);
handle_urgent(old_purplewin, FALSE);
@@ -636,14 +636,14 @@ apply_method()
{
GList *convs;
- for (convs = purple_get_conversations(); convs != NULL;
+ for (convs = purple_conversations_get_all(); convs != NULL;
convs = convs->next) {
PurpleConversation *conv = (PurpleConversation *)convs->data;
/* remove notifications */
unnotify(conv, FALSE);
- if (GPOINTER_TO_INT(purple_conversation_get_data(conv, "notify-message-count")) != 0)
+ if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(conv), "notify-message-count")) != 0)
/* reattach appropriate notifications */
notify(conv, FALSE);
}
@@ -652,7 +652,7 @@ apply_method()
static void
apply_notify()
{
- GList *convs = purple_get_conversations();
+ GList *convs = purple_conversations_get_all();
while (convs) {
PurpleConversation *conv = (PurpleConversation *)convs->data;
@@ -836,7 +836,7 @@ get_config_frame(PurplePlugin *plugin)
static gboolean
plugin_load(PurplePlugin *plugin)
{
- GList *convs = purple_get_conversations();
+ GList *convs = purple_conversations_get_all();
void *conv_handle = purple_conversations_get_handle();
void *gtk_conv_handle = pidgin_conversations_get_handle();
@@ -876,7 +876,7 @@ plugin_load(PurplePlugin *plugin)
static gboolean
plugin_unload(PurplePlugin *plugin)
{
- GList *convs = purple_get_conversations();
+ GList *convs = purple_conversations_get_all();
while (convs) {
PurpleConversation *conv = (PurpleConversation *)convs->data;
diff --git a/pidgin/plugins/perl/common/GtkAccount.xs b/pidgin/plugins/perl/common/GtkAccount.xs
index 9a8eb69c5b..8f1195384c 100644
--- a/pidgin/plugins/perl/common/GtkAccount.xs
+++ b/pidgin/plugins/perl/common/GtkAccount.xs
@@ -4,7 +4,7 @@ MODULE = Pidgin::Account PACKAGE = Pidgin::Account PREFIX = pidgin_account_
PROTOTYPES: ENABLE
Purple::Handle
-pidgin_account_get_handle()
+pidgin_accounts_get_handle()
MODULE = Pidgin::Account PACKAGE = Pidgin::Account::Dialog PREFIX = pidgin_account_dialog_
PROTOTYPES: ENABLE
diff --git a/pidgin/plugins/perl/common/GtkConv.xs b/pidgin/plugins/perl/common/GtkConv.xs
index 042a43c871..6ec68b6710 100644
--- a/pidgin/plugins/perl/common/GtkConv.xs
+++ b/pidgin/plugins/perl/common/GtkConv.xs
@@ -4,8 +4,8 @@ MODULE = Pidgin::Conversation PACKAGE = Pidgin::Conversation PREFIX = pidgin_c
PROTOTYPES: ENABLE
void
-pidgin_conv_update_buddy_icon(conv)
- Purple::Conversation conv
+pidgin_conv_update_buddy_icon(im)
+ Purple::IMConversation im
void
pidgin_conv_switch_active_conversation(conv)
@@ -46,8 +46,19 @@ MODULE = Pidgin::Conversation PACKAGE = Pidgin::Conversations PREFIX = pidgin_
PROTOTYPES: ENABLE
void
-pidgin_conversations_find_unseen_list(type, min_state, hidden_only, max_count)
- Purple::ConversationType type
+pidgin_conversations_get_unseen_all(min_state, hidden_only, max_count)
+ Pidgin::UnseenState min_state
+ gboolean hidden_only
+ guint max_count
+
+void
+pidgin_conversations_get_unseen_ims(min_state, hidden_only, max_count)
+ Pidgin::UnseenState min_state
+ gboolean hidden_only
+ guint max_count
+
+void
+pidgin_conversations_get_unseen_chats(min_state, hidden_only, max_count)
Pidgin::UnseenState min_state
gboolean hidden_only
guint max_count
diff --git a/pidgin/plugins/perl/common/GtkConvWin.xs b/pidgin/plugins/perl/common/GtkConvWin.xs
index 1fc71ffdce..948daf438f 100644
--- a/pidgin/plugins/perl/common/GtkConvWin.xs
+++ b/pidgin/plugins/perl/common/GtkConvWin.xs
@@ -74,12 +74,16 @@ pidgin_conv_window_get_gtkconv_count(win)
Pidgin::Conversation::Window win
Pidgin::Conversation::Window
-pidgin_conv_window_first_with_type(type)
- Purple::ConversationType type
+pidgin_conv_window_first_im()
Pidgin::Conversation::Window
-pidgin_conv_window_last_with_type(type)
- Purple::ConversationType type
+pidgin_conv_window_last_im()
+
+Pidgin::Conversation::Window
+pidgin_conv_window_first_chat()
+
+Pidgin::Conversation::Window
+pidgin_conv_window_last_chat()
MODULE = Pidgin::Conversation::Window PACKAGE = Pidgin::Conversation::Placement PREFIX = pidgin_conv_placement_
PROTOTYPES: ENABLE
diff --git a/pidgin/plugins/pidgininc.c b/pidgin/plugins/pidgininc.c
index 7e03243371..8078c5ba55 100644
--- a/pidgin/plugins/pidgininc.c
+++ b/pidgin/plugins/pidgininc.c
@@ -49,9 +49,9 @@ static void
bud(PurpleBuddy *who)
{
PurpleAccount *acct = who->account;
- PurpleConversation *conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, who->name);
+ PurpleConversation *conv = purple_im_conversation_new(acct, who->name);
- purple_conv_im_send(PURPLE_CONV_IM(conv), "Hello!");
+ purple_im_conversation_send(PURPLE_CONV_IM(conv), "Hello!");
}
/*
diff --git a/pidgin/plugins/sendbutton.c b/pidgin/plugins/sendbutton.c
index 943ee0568a..8fdc4eb383 100644
--- a/pidgin/plugins/sendbutton.c
+++ b/pidgin/plugins/sendbutton.c
@@ -117,7 +117,7 @@ conversation_displayed_cb(PidginConversation *gtkconv)
static gboolean
plugin_load(PurplePlugin *plugin)
{
- GList *convs = purple_get_conversations();
+ GList *convs = purple_conversations_get_all();
void *gtk_conv_handle = pidgin_conversations_get_handle();
purple_signal_connect(gtk_conv_handle, "conversation-displayed", plugin,
@@ -145,7 +145,7 @@ plugin_load(PurplePlugin *plugin)
static gboolean
plugin_unload(PurplePlugin *plugin)
{
- GList *convs = purple_get_conversations();
+ GList *convs = purple_conversations_get_all();
while (convs) {
PurpleConversation *conv = (PurpleConversation *)convs->data;
diff --git a/pidgin/plugins/spellchk.c b/pidgin/plugins/spellchk.c
index 54eda50439..40b345c1c3 100644
--- a/pidgin/plugins/spellchk.c
+++ b/pidgin/plugins/spellchk.c
@@ -2119,7 +2119,7 @@ plugin_load(PurplePlugin *plugin)
load_conf();
/* Attach to existing conversations */
- for (convs = purple_get_conversations(); convs != NULL; convs = convs->next)
+ for (convs = purple_conversations_get_all(); convs != NULL; convs = convs->next)
{
spellchk_new_attach((PurpleConversation *)convs->data);
}
@@ -2136,7 +2136,7 @@ plugin_unload(PurplePlugin *plugin)
GList *convs;
/* Detach from existing conversations */
- for (convs = purple_get_conversations(); convs != NULL; convs = convs->next)
+ for (convs = purple_conversations_get_all(); convs != NULL; convs = convs->next)
{
PidginConversation *gtkconv = PIDGIN_CONVERSATION((PurpleConversation *)convs->data);
spellchk *spell = g_object_get_data(G_OBJECT(gtkconv->entry), SPELLCHK_OBJECT_KEY);
diff --git a/pidgin/plugins/themeedit-icon.c b/pidgin/plugins/themeedit-icon.c
index 252423f7d4..9d54051614 100644
--- a/pidgin/plugins/themeedit-icon.c
+++ b/pidgin/plugins/themeedit-icon.c
@@ -180,7 +180,7 @@ use_icon_theme(GtkWidget *w, GtkWidget *window)
PidginStatusIconTheme *theme = create_icon_theme(window);
pidgin_stock_load_status_icon_theme(PIDGIN_STATUS_ICON_THEME(theme));
pidgin_stock_load_stock_icon_theme((PidginStockIconTheme *)theme);
- pidgin_blist_refresh(purple_get_blist());
+ pidgin_blist_refresh(purple_blist_get_buddy_list());
g_object_unref(theme);
}
diff --git a/pidgin/plugins/themeedit.c b/pidgin/plugins/themeedit.c
index 3263f4225e..36f0f1d690 100644
--- a/pidgin/plugins/themeedit.c
+++ b/pidgin/plugins/themeedit.c
@@ -98,7 +98,7 @@ theme_font_face_selected(GtkWidget *dialog, gint response, gpointer font)
if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) {
const char *fontname = gtk_font_chooser_get_font(GTK_FONT_CHOOSER(dialog));
pidgin_theme_font_set_font_face(font, fontname);
- pidgin_blist_refresh(purple_get_blist());
+ pidgin_blist_refresh(purple_blist_get_buddy_list());
}
gtk_widget_destroy(dialog);
}
diff --git a/pidgin/plugins/ticker/ticker.c b/pidgin/plugins/ticker/ticker.c
index ea26d0fb88..c91e1a82b5 100644
--- a/pidgin/plugins/ticker/ticker.c
+++ b/pidgin/plugins/ticker/ticker.c
@@ -27,7 +27,7 @@
#include "internal.h"
#include "pidgin.h"
-#include "blist.h"
+#include "buddylist.h"
#include "conversation.h"
#include "debug.h"
#include "prpl.h"
@@ -92,10 +92,9 @@ static gboolean buddy_click_cb(GtkWidget *widget, GdkEventButton *event, gpointe
PurpleContact *contact = user_data;
PurpleBuddy *b = purple_contact_get_priority_buddy(contact);
- PurpleConversation *conv = purple_conversation_new(PURPLE_CONV_TYPE_IM,
- purple_buddy_get_account(b),
- purple_buddy_get_name(b));
- purple_conversation_present(conv);
+ PurpleIMConversation *im = purple_im_conversation_new(purple_buddy_get_account(b),
+ purple_buddy_get_name(b));
+ purple_conversation_present(PURPLE_CONVERSATION(im));
return TRUE;
}
@@ -235,21 +234,21 @@ static void buddy_ticker_show(void)
gnode;
gnode = purple_blist_node_get_sibling_next(gnode))
{
- if(!PURPLE_BLIST_NODE_IS_GROUP(gnode))
+ if(!PURPLE_IS_GROUP(gnode))
continue;
for(cnode = purple_blist_node_get_first_child(gnode);
cnode;
cnode = purple_blist_node_get_sibling_next(cnode))
{
- if(!PURPLE_BLIST_NODE_IS_CONTACT(cnode))
+ if(!PURPLE_IS_CONTACT(cnode))
continue;
for(bnode = purple_blist_node_get_first_child(cnode);
bnode;
bnode = purple_blist_node_get_sibling_next(bnode))
{
- if(!PURPLE_BLIST_NODE_IS_BUDDY(bnode))
+ if(!PURPLE_IS_BUDDY(bnode))
continue;
- b = (PurpleBuddy *)bnode;
+ b = PURPLE_BUDDY(bnode);
if(PURPLE_BUDDY_IS_ONLINE(b))
buddy_ticker_add_buddy(b);
}
diff --git a/pidgin/plugins/win32/transparency/win2ktrans.c b/pidgin/plugins/win32/transparency/win2ktrans.c
index 4e2eb82d05..efade65b7a 100644
--- a/pidgin/plugins/win32/transparency/win2ktrans.c
+++ b/pidgin/plugins/win32/transparency/win2ktrans.c
@@ -43,9 +43,9 @@
*/
#define WINTRANS_PLUGIN_ID "gtk-win-trans"
-#define blist (purple_get_blist() \
- ? (PIDGIN_BLIST(purple_get_blist()) \
- ? ((PIDGIN_BLIST(purple_get_blist()))->window) \
+#define blist (purple_blist_get_buddy_list() \
+ ? (PIDGIN_BLIST(purple_blist_get_buddy_list()) \
+ ? ((PIDGIN_BLIST(purple_blist_get_buddy_list()))->window) \
: NULL) \
: NULL)
@@ -386,11 +386,11 @@ static void update_convs_wintrans(GtkWidget *toggle_btn, const char *pref) {
}
static void
-conv_updated_cb(PurpleConversation *conv, PurpleConvUpdateType type) {
+conv_updated_cb(PurpleConversation *conv, PurpleConversationUpdateType type) {
PidginConversation *pconv = PIDGIN_CONVERSATION(conv);
PidginWindow *win = pidgin_conv_get_window(pconv);
- if (type == PURPLE_CONV_UPDATE_UNSEEN && !pidgin_conv_is_hidden(pconv)
+ if (type == PURPLE_CONVERSATION_UPDATE_UNSEEN && !pidgin_conv_is_hidden(pconv)
&& pconv->unseen_state == PIDGIN_UNSEEN_NONE
&& pidgin_conv_window_get_gtkconv_count(win) == 1) {
GtkWidget *window = win->window;
diff --git a/pidgin/plugins/win32/winprefs/winprefs.c b/pidgin/plugins/win32/winprefs/winprefs.c
index e92c718729..cc3d3a1414 100644
--- a/pidgin/plugins/win32/winprefs/winprefs.c
+++ b/pidgin/plugins/win32/winprefs/winprefs.c
@@ -88,7 +88,7 @@ static void blist_set_ontop(gboolean val) {
if(!blist)
return;
- gtk_window_set_keep_above(GTK_WINDOW(PIDGIN_BLIST(purple_get_blist())->window), val);
+ gtk_window_set_keep_above(GTK_WINDOW(PIDGIN_BLIST(purple_blist_get_buddy_list())->window), val);
}
static void blist_dock_cb(gboolean val) {
@@ -233,9 +233,9 @@ static gboolean plugin_load(PurplePlugin *plugin) {
handle = plugin;
/* blist docking init */
- if(purple_get_blist() && PIDGIN_BLIST(purple_get_blist())
- && PIDGIN_BLIST(purple_get_blist())->window) {
- blist_create_cb(purple_get_blist(), NULL);
+ if(purple_blist_get_buddy_list() && PIDGIN_BLIST(purple_blist_get_buddy_list())
+ && PIDGIN_BLIST(purple_blist_get_buddy_list())->window) {
+ blist_create_cb(purple_blist_get_buddy_list(), NULL);
}
/* This really shouldn't happen anymore generally, but if for some strange